/* ==========================================================================
   MICHIGAN SECURITY SYSTEMS — 2026 EDITORIAL DESIGN SYSTEM
   Author: MSS site rebuild. Loads last; supersedes all legacy page styles.
   Self-hosted type. No external requests.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. TYPE
   -------------------------------------------------------------------------- */
@font-face{font-family:'Archivo';src:url('../fonts/archivo-latin-600-normal.woff2') format('woff2');font-weight:600;font-style:normal;font-display:swap;}
@font-face{font-family:'Archivo';src:url('../fonts/archivo-latin-700-normal.woff2') format('woff2');font-weight:700;font-style:normal;font-display:swap;}
@font-face{font-family:'Archivo';src:url('../fonts/archivo-latin-800-normal.woff2') format('woff2');font-weight:800;font-style:normal;font-display:swap;}
@font-face{font-family:'Plex';src:url('../fonts/ibm-plex-sans-latin-400-normal.woff2') format('woff2');font-weight:400;font-style:normal;font-display:swap;}
@font-face{font-family:'Plex';src:url('../fonts/ibm-plex-sans-latin-500-normal.woff2') format('woff2');font-weight:500;font-style:normal;font-display:swap;}
@font-face{font-family:'Plex';src:url('../fonts/ibm-plex-sans-latin-600-normal.woff2') format('woff2');font-weight:600;font-style:normal;font-display:swap;}
@font-face{font-family:'PlexMono';src:url('../fonts/ibm-plex-mono-latin-500-normal.woff2') format('woff2');font-weight:500;font-style:normal;font-display:swap;}
@font-face{font-family:'PlexMono';src:url('../fonts/ibm-plex-mono-latin-600-normal.woff2') format('woff2');font-weight:600;font-style:normal;font-display:swap;}

/* --------------------------------------------------------------------------
   2. TOKENS — redefining these re-skins every legacy component site-wide
   -------------------------------------------------------------------------- */
:root{
  /* ground */
  --navy:#0A1926;        /* ink — primary dark ground */
  --navy2:#102A3F;       /* raised ink */
  --navy3:#1A3C55;       /* ink accent */
  --ink-deep:#060F18;
  --ink-warm:#12212E;

  /* brand */
  --blue:#1F5B92;
  --blue2:#2A72B4;
  --blue3:#4192D6;
  --accent:#DFA13E;      /* brass */
  --accent2:#F0C078;
  --brass-ink:#6E4407;   /* brass legible on light (8.2:1 on paper) */
  --red:#C24634;
  --green:#3E7D5A;

  /* paper */
  --white:#FFFFFF;
  --off-white:#F4F1EA;   /* warm paper — replaces the old cold #F4F7FC */
  --paper-2:#EBE6DC;
  --gray:#E7E1D6;
  --border:#DED7CA;
  --border-ink:rgba(255,255,255,.13);

  /* text */
  --text:#12202E;
  --text-light:#3D4A5D;
  --text-ink:#FBF8F3;
  --text-ink-dim:rgba(251,248,243,.90);

  /* form */
  --radius:3px;
  --radius-lg:4px;
  --shadow:0 1px 2px rgba(10,25,38,.05);
  --shadow-lg:0 18px 44px rgba(10,25,38,.14);

  /* type */
  --f-display:'Archivo',"Helvetica Neue",Arial,sans-serif;
  --f-body:'Plex',-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
  --f-mono:'PlexMono',ui-monospace,SFMono-Regular,Menlo,monospace;

  /* rhythm */
  --band:clamp(64px,7.5vw,116px);
  --gutter:clamp(20px,4vw,56px);
  --measure:74ch;
}

/* --------------------------------------------------------------------------
   3. BASE
   -------------------------------------------------------------------------- */
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;}
body{
  font-family:var(--f-body);
  font-size:17px;
  line-height:1.65;
  color:var(--text);
  background-color:var(--off-white);
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  letter-spacing:-.005em;
  overflow-x:hidden;
}
*,*::before,*::after{box-sizing:border-box;}
img{max-width:100%;}

h1,h2,h3,h4,h5,.stat-num,.about-stat-num,.accolade-num,.hero h1,.section-title{
  font-family:var(--f-display);
  font-weight:800;
  letter-spacing:-.028em;
  line-height:1.06;
  text-wrap:balance;
}
h3,h4,h5{font-weight:700;letter-spacing:-.018em;line-height:1.18;}
h1{font-size:clamp(2.5rem,5.4vw,4.55rem);}
h2{font-size:clamp(1.85rem,3.3vw,3rem);margin-bottom:.5em;}
h3{font-size:clamp(1.18rem,1.55vw,1.5rem);}
h4{font-size:1.06rem;}
p{max-width:var(--measure);}
strong,b{font-weight:600;}
a{color:inherit;}
::selection{background-color:var(--accent);color:var(--navy);}

/* focus — accessible and on-brand */
a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible,[tabindex]:focus-visible{
  outline:2px solid var(--accent);outline-offset:3px;border-radius:2px;
}

.container{max-width:1240px;margin:0 auto;padding-left:var(--gutter);padding-right:var(--gutter);width:100%;}

/* --------------------------------------------------------------------------
   4. SECTION BANDS — the editorial light/dark rhythm
   -------------------------------------------------------------------------- */
section{position:relative;}
section[data-band]{padding:var(--band) 0;}
section[data-band="paper"]{background-color:var(--off-white);color:var(--text);}
section[data-band="white"]{background-color:var(--white);color:var(--text);}
section[data-band="ink"]{background-color:var(--navy);color:var(--text-ink);}
section[data-band="ink2"]{background-color:var(--navy2);color:var(--text-ink);}

/* hairline seams instead of heavy borders */
section[data-band="paper"] + section[data-band="white"],
section[data-band="white"] + section[data-band="paper"]{border-top:1px solid var(--border);}

/* ink bands: subtle engineered texture, never flat */
section[data-band="ink"]::before,section[data-band="ink2"]::before{
  content:"";position:absolute;inset:0;pointer-events:none;opacity:.5;
  background-image:linear-gradient(rgba(255,255,255,.028) 1px,transparent 1px),
                   linear-gradient(90deg,rgba(255,255,255,.028) 1px,transparent 1px);
  background-size:78px 78px;
  -webkit-mask-image:radial-gradient(ellipse 85% 70% at 50% 0%,#000 0%,transparent 78%);
          mask-image:radial-gradient(ellipse 85% 70% at 50% 0%,#000 0%,transparent 78%);
}
section[data-band] > *{position:relative;z-index:1;}

/* text colour inside ink bands */
section[data-band="ink"],section[data-band="ink2"],
section[data-band="ink"] p,section[data-band="ink2"] p,
section[data-band="ink"] li,section[data-band="ink2"] li{color:var(--text-ink-dim);}
section[data-band="ink"] h1,section[data-band="ink"] h2,section[data-band="ink"] h3,section[data-band="ink"] h4,
section[data-band="ink2"] h1,section[data-band="ink2"] h2,section[data-band="ink2"] h3,section[data-band="ink2"] h4{color:var(--text-ink);}

/* legacy band classes kept in step */
.section{background-color:var(--white);padding:var(--band) 0;}
.section-alt{background-color:var(--off-white);padding:var(--band) 0;}
.section-dark,.section-dark2{background-color:var(--navy);color:var(--text-ink);padding:var(--band) 0;}
.section-dark h2,.section-dark h3,.section-dark2 h2,.section-dark2 h3{color:var(--text-ink);}

/* --------------------------------------------------------------------------
   5. SECTION HEADERS — mono eyebrow + rule, oversized display heading
   -------------------------------------------------------------------------- */
.section-tag,.eyebrow,.ab-eyebrow,.pg-eyebrow,.ct-eyebrow,.rv-eyebrow,.con-eyebrow,
.sec-label,.hero-badge,.proc-head-tag,.blog-cat,.art-cat,.a-tag,.s-tag,.stag,.cpro-kick{
  font-family:var(--f-mono) !important;
  font-size:.685rem !important;
  font-weight:600 !important;
  letter-spacing:.19em !important;
  text-transform:uppercase !important;
  color:var(--brass-ink) !important;
  background:none !important;
  border:0 !important;
  border-radius:0 !important;
  padding:0 0 0 34px !important;
  position:relative;
  display:inline-block;
  line-height:1.4 !important;
  margin-bottom:18px;
}
.section-tag::before,.eyebrow::before,.ab-eyebrow::before,.pg-eyebrow::before,.ct-eyebrow::before,
.rv-eyebrow::before,.con-eyebrow::before,.sec-label::before,.hero-badge::before,
.proc-head-tag::before,.cpro-kick::before{
  content:"";position:absolute;left:0;top:.62em;width:24px;height:2px;background-color:var(--accent);
}
section[data-band="ink"] .section-tag,section[data-band="ink2"] .section-tag,
.section-dark .section-tag,.hero .hero-badge,section[data-band="ink"] .eyebrow,
section[data-band="ink2"] .eyebrow,section[data-band="ink"] .sec-label{color:var(--accent2) !important;}

.section-head,.section-header,.proc-head,.ind-head,.pg-gallery-head,.rv-sec-head,.city-links-head,.gallery-header{
  max-width:900px;margin:0 0 clamp(34px,4vw,58px);text-align:left !important;
}
.section-head p,.section-header p,.section-intro{font-size:1.075rem;color:var(--text-light);max-width:66ch;}
section[data-band="ink"] .section-head p,section[data-band="ink2"] .section-head p,
.section-dark .section-head p{color:var(--text-ink-dim);}

[data-mss-slim]{background-color:var(--ink-deep) !important;padding:0 !important;border-bottom:1px solid rgba(255,255,255,.08);}
[data-mss-slim] > div{
  max-width:1400px !important;margin:0 auto !important;padding:0 var(--gutter) !important;
  min-height:36px;gap:0 !important;justify-content:flex-start !important;flex-wrap:wrap !important;
}
[data-mss-slim] span,[data-mss-slim] a{
  font-family:var(--f-mono) !important;font-size:.66rem !important;font-weight:500 !important;
  letter-spacing:.13em !important;text-transform:uppercase !important;
  color:rgba(251,248,243,.62) !important;padding:9px 16px !important;
}
[data-mss-slim] > div > span:first-child{padding-left:0 !important;}
[data-mss-slim] span[style*="width:1px"]{
  background-color:rgba(255,255,255,.14) !important;padding:0 !important;height:11px !important;align-self:center;
}
[data-mss-slim] svg{fill:var(--accent) !important;width:12px !important;height:12px !important;}
[data-mss-slim] a[href^="tel"]{color:var(--accent) !important;font-weight:600 !important;margin-left:auto;padding-right:0 !important;}
[data-mss-slim] span > a{padding:0 !important;color:inherit !important;}

/* --------------------------------------------------------------------------
   6. HEADER — three stacked bars collapsed into one refined bar
   -------------------------------------------------------------------------- */
.gold-bar{
  background-color:var(--ink-deep) !important;
  border-bottom:1px solid rgba(255,255,255,.08);
  padding:0 !important;box-shadow:none !important;
}
.gold-bar-inner{
  max-width:1400px;margin:0 auto;padding:0 var(--gutter) !important;
  height:36px;display:flex;align-items:center;gap:0;
  font-family:var(--f-mono);font-size:.66rem;letter-spacing:.13em;text-transform:uppercase;
}
.gold-bar-text{
  color:rgba(251,248,243,.62) !important;font-size:.66rem !important;font-weight:500 !important;
  letter-spacing:.13em !important;text-transform:uppercase;display:flex;align-items:center;gap:8px;
  padding:0 18px !important;background:none !important;
}
.gold-bar-text:first-child{padding-left:0 !important;}
.gold-bar-text svg{width:12px;height:12px;fill:var(--accent);opacity:.9;}
.gold-bar-divider{width:1px;height:11px;background-color:rgba(255,255,255,.14) !important;margin:0 !important;}
.gold-bar-cta{
  margin-left:auto;color:var(--accent) !important;background:none !important;border:0 !important;
  padding:0 !important;font-family:var(--f-mono);font-weight:600;font-size:.68rem !important;
  letter-spacing:.13em;display:flex;align-items:center;gap:8px;text-decoration:none;
}
.gold-bar-cta svg{width:12px;height:12px;fill:currentColor;}
.gold-bar-cta:hover{color:var(--accent2) !important;}

#site-header,header#site-header{
  background-color:var(--navy) !important;
  border-bottom:1px solid rgba(255,255,255,.09);
  box-shadow:none !important;
  position:sticky;top:0;z-index:900;
  display:flex;align-items:center;gap:clamp(16px,2vw,34px);
  padding:0 var(--gutter) !important;
  min-height:74px;
  max-width:none;
}
#site-header .header-main,#site-header .nav-row{display:contents;}

#site-header .logo-wrap{
  display:flex;align-items:center;gap:13px;text-decoration:none;
  padding:12px 0 !important;order:1;flex:0 0 auto;
}
#site-header .logo-img{height:42px;width:auto;}
#site-header .logo-textcol{display:flex;flex-direction:column;gap:2px;}
#site-header .logo-text-main{display:flex;align-items:center;gap:9px;}
#site-header .logo-name{
  font-family:var(--f-display) !important;font-weight:800 !important;font-size:1.02rem !important;letter-spacing:-.028em;
  color:var(--text-ink) !important;line-height:1.1;
}
#site-header .logo-name em{font-style:normal;color:var(--accent) !important;}
#site-header .logo-badge{
  font-family:var(--f-mono);font-size:.53rem;font-weight:600;letter-spacing:.15em;text-transform:uppercase;
  color:var(--accent) !important;background:none !important;border:1px solid rgba(223,161,62,.4) !important;
  border-radius:2px !important;padding:2px 6px !important;
}
#site-header .logo-text-sub{
  font-family:var(--f-mono);font-size:.585rem;letter-spacing:.15em;text-transform:uppercase;
  color:rgba(251,248,243,.44) !important;
}

#site-header nav{
  order:2;flex:1 1 auto;display:flex;align-items:center;gap:2px;justify-content:flex-end;
  min-width:0;
}
#site-header .nav-link{
  font-family:var(--f-body) !important;font-size:.875rem !important;font-weight:500 !important;letter-spacing:-.005em;
  color:rgba(251,248,243,.8) !important;text-decoration:none;
  padding:26px 9px !important;background:none !important;border:0 !important;border-radius:0 !important;
  position:relative;white-space:nowrap;transition:color .18s ease;
}
#site-header .nav-link::after{
  content:"";position:absolute;left:9px;right:9px;bottom:20px;height:2px;
  background-color:var(--accent);transform:scaleX(0);transform-origin:left;transition:transform .22s cubic-bezier(.2,.7,.3,1);
}
#site-header .nav-link:hover{color:var(--text-ink) !important;}
#site-header .nav-link:hover::after,#site-header .nav-dropdown:hover > .nav-link::after{transform:scaleX(1);}
#site-header .nav-dropdown{position:relative;}

/* dropdowns — dark navy mega-menu matching the live site's look & feel */
#site-header .nav-dropdown-menu{
  background-color:#0D2240 !important;background-image:none !important;
  border:1px solid rgba(255,255,255,.1) !important;border-top:1px solid rgba(255,255,255,.1) !important;
  border-radius:10px !important;box-shadow:0 14px 34px rgba(0,0,0,.45) !important;
  padding:8px !important;margin-top:0 !important;min-width:240px;
  opacity:0;transform:translateY(4px);transition:opacity .18s ease,transform .18s ease;
}
#site-header .nav-dropdown:hover > .nav-dropdown-menu,
#site-header .nav-dropdown:focus-within > .nav-dropdown-menu{opacity:1;transform:translateY(0);}
#site-header .nav-dropdown-item{
  color:rgba(255,255,255,.85) !important;font-size:.94rem;font-weight:600;padding:10px 14px !important;
  border-radius:7px !important;background:none !important;border:0 !important;
  display:block;text-decoration:none;white-space:nowrap;transition:background .15s ease,color .15s ease;
}
#site-header .nav-dropdown-item:hover{background-color:rgba(255,255,255,.09) !important;color:#fff !important;}
#site-header .nav-drop-heading{
  font-family:var(--f-mono);font-size:.62rem;font-weight:700;letter-spacing:.15em;text-transform:uppercase;
  color:var(--accent) !important;padding:2px 10px 6px !important;border-bottom:1px solid rgba(255,255,255,.14);
  margin-bottom:6px;
}
#site-header .nav-dropdown-grouped{display:flex !important;flex-direction:row;gap:8px;padding:16px 18px !important;min-width:560px;}
#site-header .nav-dropdown-grouped .nav-drop-col{display:flex;flex-direction:column;min-width:168px;flex:1;}
#site-header .nav-dropdown-grouped .nav-dropdown-item{padding:6px 8px !important;font-size:.87rem;white-space:nowrap;}
#site-header .nav-drop-col{min-width:190px;}
@media(max-width:900px){
  #site-header .nav-dropdown-grouped{flex-direction:column;min-width:0;gap:4px;}
  #site-header .nav-dropdown-grouped .nav-drop-heading{margin-top:8px;}
}

/* header phone + CTAs */
#site-header .header-contact{display:contents;}
#site-header .hc-phone{
  order:3;font-family:var(--f-display);font-weight:700;font-size:1.02rem;letter-spacing:-.02em;
  color:var(--text-ink) !important;text-decoration:none;white-space:nowrap;
  padding-left:clamp(8px,1.4vw,18px);margin-left:4px;border-left:1px solid rgba(255,255,255,.13);
}
#site-header .hc-phone:hover{color:var(--accent) !important;}
#site-header .hc-email,#site-header .hc-loc{display:none !important;}

#site-header .nav-cta2{
  order:4;font-family:var(--f-body);font-weight:600;font-size:.82rem;
  color:var(--text-ink) !important;background:none !important;
  border:1px solid rgba(255,255,255,.25) !important;border-radius:var(--radius) !important;
  padding:10px 16px !important;white-space:nowrap;text-decoration:none;transition:.18s ease;
}
#site-header .nav-cta2::after{display:none;}
#site-header .nav-cta2:hover{border-color:var(--accent) !important;color:var(--accent) !important;}
#site-header .nav-cta{
  order:5;font-family:var(--f-body);font-weight:600;font-size:.82rem;
  background-color:var(--accent) !important;color:var(--navy) !important;border:1px solid var(--accent) !important;
  border-radius:var(--radius) !important;padding:10px 18px !important;white-space:nowrap;text-decoration:none;
  transition:.18s ease;
}
#site-header .nav-cta::after{display:none;}
#site-header .nav-cta:hover{background-color:var(--accent2) !important;border-color:var(--accent2) !important;}
#site-header .hamburger{order:6;}

/* scrolled state */
#site-header.scrolled{min-height:64px;box-shadow:0 10px 30px rgba(10,25,38,.22) !important;}
#site-header.scrolled .nav-link{padding-top:21px !important;padding-bottom:21px !important;}

/* --------------------------------------------------------------------------
   7. HERO — split-bleed: editorial type on ink, photography off the right edge
   -------------------------------------------------------------------------- */
.hero{
  background-color:var(--navy) !important;color:var(--text-ink);
  padding:0 !important;position:relative;overflow:hidden;
  display:block !important;align-items:normal !important;min-height:0 !important;
  max-height:none !important;height:auto !important;
}
/* the ink-edge separator only makes sense on the solid/ink split-bleed hero —
   a hero with its own full-bleed photo background (inline style contains url())
   already has a hard photo edge, so the separator would show as a stray line
   drawn across the middle of the photo; excluded there. */
.hero:not([style*="url("]){
  border-bottom:1px solid rgba(255,255,255,.09);
}
/* several pages cap the hero at a fixed height and clip whatever overflows */
.hero,.pg-hero,.ab-hero,.rv-hero,.ct-hero,.con-hero,.cpro-hero,.legal-hero,.blog-hero,.page-hero{
  max-height:none !important;height:auto !important;
}
.hero-bg{
  position:absolute;inset:0;
  background:
    radial-gradient(ellipse 60% 90% at 8% 0%,rgba(42,114,180,.20) 0%,transparent 62%),
    radial-gradient(ellipse 70% 60% at 0% 100%,rgba(223,161,62,.10) 0%,transparent 60%) !important;
}
.hero-grid,.hero-grid-overlay,.hero-city-overlay{
  position:absolute;inset:0;pointer-events:none;opacity:.6;
  background-image:linear-gradient(rgba(255,255,255,.03) 1px,transparent 1px),
                   linear-gradient(90deg,rgba(255,255,255,.03) 1px,transparent 1px) !important;
  background-size:78px 78px !important;
  -webkit-mask-image:linear-gradient(100deg,#000 0%,transparent 58%);
          mask-image:linear-gradient(100deg,#000 0%,transparent 58%);
}
.hero-content{
  position:relative;z-index:2;max-width:none;margin:0;width:100%;
  display:grid;grid-template-columns:minmax(0,1.04fr) minmax(0,.96fr);
  gap:0;align-items:stretch;padding:0 !important;
}
/* one page builds its hero as a single stacked block rather than two columns.
   It is not a split-bleed hero and must not be forced into that grid. */
.hero-inner{
  position:relative;z-index:2;display:block;width:100%;
  max-width:1400px;margin:0 auto;text-align:left;
  padding:clamp(52px,6vw,96px) var(--gutter) clamp(52px,6vw,88px) !important;
}
.hero-inner > *{margin-left:0 !important;margin-right:0 !important;text-align:left !important;}
.hero-inner > h1{max-width:19ch;}
.hero-inner > p{max-width:64ch;}
.hero-inner .eyebrow{display:inline-block !important;margin:0 0 18px !important;}
.hero-content > div:first-child,.hero-left{
  padding:clamp(52px,6vw,96px) clamp(28px,4vw,72px) clamp(52px,6vw,88px)
          max(var(--gutter),calc((100vw - 1400px) / 2 + var(--gutter)));
  display:flex;flex-direction:column;justify-content:center;align-self:center;min-width:0;
}
.hero h1{
  font-size:clamp(2.5rem,4.5vw,4.15rem) !important;
  line-height:1.02 !important;letter-spacing:-.035em !important;
  color:var(--text-ink) !important;margin:0 0 22px !important;max-width:17ch;
  font-weight:800 !important;
}
.hero h1 em,.hero h1 span{font-style:normal;color:var(--accent) !important;}
.hero-desc,.hero p{
  font-size:clamp(1rem,1.15vw,1.115rem) !important;line-height:1.62 !important;
  color:var(--text-ink-dim) !important;max-width:56ch;margin:0 0 30px !important;
}
.hero-desc strong{color:var(--text-ink) !important;font-weight:600;}

.hero-actions{display:flex;flex-wrap:wrap;gap:12px;margin:0 0 26px !important;}

/* live-status chip — hairline, not a box */
.mss-hero-live{
  display:inline-flex !important;align-items:center;gap:12px;
  background:none !important;border:0 !important;border-left:2px solid var(--accent) !important;
  border-radius:0 !important;padding:2px 0 2px 14px !important;margin:0 0 30px !important;width:auto !important;
}
.mss-live-top{
  font-family:var(--f-mono) !important;font-size:.68rem !important;font-weight:600 !important;
  letter-spacing:.16em !important;text-transform:uppercase;color:var(--text-ink) !important;
  display:flex;align-items:center;gap:8px;
}
.mss-live-sub{
  font-family:var(--f-mono) !important;font-size:.62rem !important;letter-spacing:.14em !important;
  text-transform:uppercase;color:rgba(251,248,243,.5) !important;
}
.mss-live-dot{width:6px;height:6px;border-radius:50%;background-color:var(--accent);box-shadow:0 0 0 3px rgba(223,161,62,.22);}

/* hero stats — hairline-divided row, oversized numerals */
.hero-stats{
  display:grid !important;grid-template-columns:repeat(4,minmax(0,1fr));gap:0 !important;
  border-top:1px solid rgba(255,255,255,.14);padding-top:26px !important;margin-top:8px !important;
  max-width:640px;
}
.hero-stats .stat-card{
  background:none !important;border:0 !important;border-left:1px solid rgba(255,255,255,.11) !important;
  border-radius:0 !important;padding:2px 0 2px 16px !important;box-shadow:none !important;
  display:flex;flex-direction:column;gap:5px;min-width:0;
}
.hero-stats .stat-card:first-child{border-left:0 !important;padding-left:0 !important;}
.hero-stats .stat-num,.stat-num{
  font-family:var(--f-display) !important;font-weight:800 !important;
  font-size:clamp(1.5rem,2.1vw,2.05rem) !important;letter-spacing:-.04em !important;
  color:var(--text-ink) !important;line-height:1 !important;font-variant-numeric:tabular-nums;
}
.hero-stats .stat-label,.stat-label{
  font-family:var(--f-mono) !important;font-size:.61rem !important;font-weight:500 !important;
  letter-spacing:.14em !important;text-transform:uppercase !important;
  color:rgba(251,248,243,.5) !important;line-height:1.4 !important;
}

/* right column bleeds to the viewport edge, full height */
.hero-right-col,.hero-content > .hero-panel{
  position:relative;min-width:0;align-self:stretch;
  display:flex;flex-direction:column;gap:0;
  background:none !important;border:0 !important;border-radius:0 !important;
  box-shadow:none !important;padding:0 !important;
  /* City-page hero photos carry an inline transform:scale(1.06) for a subtle
     zoom. The <span> that wraps the <img> is display:contents (no box of its
     own), so nothing was clipping that 6% overscale — it bled ~20px past the
     column's left edge, over the dark text panel, showing a mis-matched sliver
     of the same photo at a different crop and reading as a second photo. */
  overflow:hidden;
}
.hero .hero-carousel::after,.hero .photo-slot::after,.hero-photo-placeholder::after,
.hero-photo-wrap::after,.hero-right-col > span::after{
  content:"";position:absolute;inset:0;z-index:3;pointer-events:none;
  background:linear-gradient(90deg,var(--navy) 0%,rgba(10,25,38,.5) 14%,transparent 38%);
}
.hero-right-col > span{position:relative;display:block;flex:1 1 auto;min-height:clamp(320px,36vw,470px);}
.hero-right-col > *,.hero-content > .hero-panel > *{min-height:0;}
.hero-right-col .hero-panel{margin:0 !important;width:100% !important;}
.hero .hero-carousel,.hero-right-col .hero-carousel{
  flex:1 1 auto;min-height:clamp(360px,44vw,560px);border-radius:0 !important;border:0 !important;
  box-shadow:none !important;overflow:hidden;position:relative;background-color:var(--ink-deep) !important;
}
.hero .carousel-slide img,.hero-right-col img,.hero .photo-slot img,
.hero-truck-img,.hero-photo-wrap img,.hero-photo-placeholder img,.hero .product-img-wrap img{
  width:100% !important;height:100% !important;object-fit:cover !important;display:block !important;
  border-radius:0 !important;
}
.hero .photo-slot,.hero-photo-placeholder,.hero-photo-wrap,.hero .product-img-wrap{
  border-radius:0 !important;border:0 !important;box-shadow:none !important;padding:0 !important;
  height:auto !important;min-height:clamp(300px,30vw,430px);background-color:var(--ink-deep) !important;
  overflow:hidden;position:relative;flex:1 1 auto;display:block !important;
}
/* service/industry heroes: panel content aligns to the grid, photo still bleeds */
.hero-content > .hero-panel{padding:0 var(--hero-pad-r) 0 0 !important;gap:0 !important;}
.hero-content > .hero-panel > .photo-slot{margin:0 calc(-1 * var(--hero-pad-r)) 22px 0 !important;width:auto !important;}
.hero-content > .hero-panel > div:not(.photo-slot){padding-left:0 !important;}
.hero .slide-caption{
  background:linear-gradient(0deg,rgba(6,15,24,.92),transparent) !important;
  padding:44px 34px 26px !important;border:0 !important;
}
.hero .slide-caption,.hero .slide-caption *{
  font-family:var(--f-mono) !important;font-size:.68rem !important;letter-spacing:.13em !important;
  text-transform:uppercase;color:rgba(251,248,243,.82) !important;font-weight:500 !important;
}
.hero .carousel-arrow{
  background-color:rgba(6,15,24,.55) !important;border:1px solid rgba(255,255,255,.22) !important;
  border-radius:0 !important;color:var(--text-ink) !important;width:40px;height:40px;
}
.hero .carousel-arrow:hover{background-color:var(--accent) !important;color:var(--navy) !important;border-color:var(--accent) !important;}
.hero .carousel-dots{bottom:16px;}
.hero .carousel-dots > *{border-radius:0 !important;height:3px !important;}

/* homepage service index below the hero photo */
.hero .hero-panel-title{
  font-family:var(--f-mono) !important;font-size:.66rem !important;font-weight:600 !important;
  letter-spacing:.19em !important;text-transform:uppercase;color:var(--accent2) !important;
  padding:22px var(--hero-pad-r) 12px 34px !important;background-color:var(--ink-deep) !important;
  margin:0 !important;border:0 !important;
}
.hero{--hero-pad-r:max(var(--gutter),calc((100vw - 1400px) / 2));}
.hero .service-pill-grid{padding-right:var(--hero-pad-r) !important;background:none !important;}
.hero .hero-call-block{padding-right:var(--hero-pad-r) !important;}
.hero .service-pill-grid{
  display:grid !important;grid-template-columns:repeat(2,minmax(0,1fr));gap:1px !important;
  padding:0 !important;border-top:1px solid rgba(255,255,255,.09);
}
.hero .hero-panel{background-color:var(--ink-deep) !important;}
.hero .service-pill{
  background-color:var(--ink-deep) !important;border:0 !important;border-radius:0 !important;
  padding:15px 18px !important;display:flex;align-items:center;gap:12px;box-shadow:none !important;
  transition:background .18s ease;
}
.hero .service-pill:hover{background-color:var(--navy2) !important;}
.hero .pill-icon{
  background:none !important;border:0 !important;border-radius:0 !important;
  color:var(--accent) !important;width:20px;height:20px;padding:0 !important;flex:0 0 auto;
}
.hero .pill-icon svg{width:18px;height:18px;fill:currentColor;}
.hero .pill-text{font-family:var(--f-body);font-weight:600;font-size:.855rem;color:var(--text-ink) !important;}
.hero .pill-sub{
  font-family:var(--f-mono) !important;font-size:.585rem !important;letter-spacing:.11em !important;
  text-transform:uppercase;color:rgba(251,248,243,.45) !important;
}
.hero-call-block{
  background-color:var(--ink-deep) !important;border:0 !important;border-top:1px solid rgba(255,255,255,.09);
  border-radius:0 !important;padding:18px 34px !important;display:flex;align-items:center;
  justify-content:space-between;gap:18px;flex-wrap:wrap;
}
.hero-call-label{
  font-family:var(--f-mono) !important;font-size:.6rem !important;letter-spacing:.17em !important;
  text-transform:uppercase;color:rgba(251,248,243,.5) !important;
}
.hero-call-num{
  font-family:var(--f-display) !important;font-weight:800 !important;font-size:1.5rem !important;
  letter-spacing:-.03em !important;color:var(--accent) !important;
}

/* secondary hero variants (about / projects / reviews / contact / legal / blog) */
.pg-hero,.ab-hero,.rv-hero,.ct-hero,.con-hero,.cpro-hero,.legal-hero,.blog-hero,.page-hero{
  background-color:var(--navy) !important;color:var(--text-ink) !important;
  padding:clamp(64px,7vw,104px) 0 clamp(56px,6vw,88px) !important;
  border-bottom:1px solid rgba(255,255,255,.09);position:relative;overflow:hidden;
}
.pg-hero h1,.ab-hero h1,.rv-hero h1,.ct-hero h1,.con-hero h1,.cpro-hero h1,.legal-hero h1,.blog-hero h1,.page-hero h1{
  color:var(--text-ink) !important;font-size:clamp(2.3rem,4.4vw,3.9rem) !important;
  letter-spacing:-.035em !important;line-height:1.03 !important;max-width:19ch;
}
.pg-hero p,.ab-hero p,.rv-hero p,.ct-hero p,.con-hero p,.cpro-hero p,.legal-hero p,.blog-hero p{
  color:var(--text-ink-dim) !important;font-size:1.075rem !important;max-width:60ch;
}
.pg-hero-inner,.ab-hero-inner,.rv-hero-inner,.ct-hero-inner,.con-hero-inner,.legal-hero-inner{
  max-width:1240px;margin:0 auto;padding:0 var(--gutter);text-align:left !important;
}

/* --------------------------------------------------------------------------
   8. BUTTONS
   -------------------------------------------------------------------------- */
.btn-primary,.btn,.btnp,.pg-cta-btn,.ab-cta-btn,.rv-cta-btn,.con-btn-gold,.cpro-btn-gold,
.form-submit,.hero-call-btn,.proc-cta-btn,.gr-write-btn,.googrev-write-btn,.contact-call-btn,
.map-call-btn,.csl-call-btn,.btn-call,.callbtn,.msb-call,.msb-assess,.cta-btn,.sp-btn{
  display:inline-flex !important;align-items:center;justify-content:center;gap:9px;
  font-family:var(--f-body) !important;font-weight:600 !important;font-size:.925rem !important;
  letter-spacing:-.005em !important;line-height:1.2 !important;
  background-color:var(--accent) !important;color:var(--navy) !important;
  border:1px solid var(--accent) !important;border-radius:var(--radius) !important;
  padding:14px 24px !important;text-decoration:none !important;cursor:pointer;
  box-shadow:none !important;text-transform:none !important;
  transition:background .18s ease,border-color .18s ease,transform .18s ease;
}
.btn-primary:hover,.btn:hover,.btnp:hover,.pg-cta-btn:hover,.ab-cta-btn:hover,.rv-cta-btn:hover,
.con-btn-gold:hover,.cpro-btn-gold:hover,.form-submit:hover,.hero-call-btn:hover,
.proc-cta-btn:hover,.contact-call-btn:hover,.map-call-btn:hover,.btn-call:hover{
  background-color:var(--accent2) !important;border-color:var(--accent2) !important;transform:translateY(-1px);
}
.btn-secondary,.btn-outline,.btno,.btn-outline-blue,.con-btn-ghost,.svc-b-ghost-btn,.cpro-btn,
.blog-back-btn,.gallery-back-btn,.art-back,.back-to-services,.related-btn,.btn-share,.btn-print,
.btn-restart,.rc-btn,.pg-feature-btn,.project-view-btn,.mss-visit-btn,.con-btn{
  display:inline-flex !important;align-items:center;justify-content:center;gap:9px;
  font-family:var(--f-body) !important;font-weight:600 !important;font-size:.925rem !important;
  background-color:transparent !important;color:inherit !important;
  border:1px solid currentColor !important;border-radius:var(--radius) !important;
  padding:13px 22px !important;text-decoration:none !important;cursor:pointer;
  box-shadow:none !important;opacity:.92;transition:.18s ease;
}
.btn-secondary:hover,.btn-outline:hover,.btno:hover,.con-btn-ghost:hover,.cpro-btn:hover,
.blog-back-btn:hover,.rc-btn:hover,.pg-feature-btn:hover,.project-view-btn:hover{
  opacity:1;background-color:rgba(223,161,62,.1) !important;border-color:var(--accent) !important;color:var(--accent) !important;
}
section[data-band="paper"] .btn-secondary,section[data-band="white"] .btn-secondary,
.section .btn-secondary,.section-alt .btn-secondary{color:var(--text) !important;}
/* ...except inside the .cta-banner/.ab-cta/.pg-cta/.rv-cta "same-element dark
   island" shape (§ hand the contract back) — those are genuinely dark navy CTA
   bands that merely happen to carry data-band="paper"/"white" (their background
   comes from a CSS class transform.py's inline-only sniffer never saw), so a
   .btn-secondary/.related-btn inside one needs to stay light, not flip dark. */
section[data-band]:is(.cta-banner,.ab-cta,.pg-cta,.rv-cta) :is(.btn-secondary,.btn-outline,.related-btn){
  color:var(--text-ink) !important;
}
/* .btn-outline was left out of the list above even though it shares the exact
   same unconditional "color:inherit" base rule as .btn-secondary — on a few
   "Get Started Today" CTA sections (monitored-video-surveillance,
   security-system-repair-service, security-system-cost, starlink-business-
   internet) that ends up inheriting a light ambient color meant for a dark
   ground, rendering as a near-invisible near-white outline button on a light
   band. Give it the same light-band correction. */
section[data-band="paper"] .btn-outline,section[data-band="white"] .btn-outline,
.section .btn-outline,.section-alt .btn-outline{color:var(--text) !important;}
.btn-blue{background-color:var(--blue) !important;border-color:var(--blue) !important;color:#fff !important;}
.btn-blue:hover{background-color:var(--blue2) !important;border-color:var(--blue2) !important;}

/* --------------------------------------------------------------------------
   9. CARDS — hairline + image-led, no floating boxes
   -------------------------------------------------------------------------- */
.service-card,.industry-card,.blog-card,.proj-card,.project-card,.a-card,.feature-card,
.mfr-detail-card,.brands-cat-card,.ind-hub-card,.svc-hub-card,.pt-card,.eq-card,.camtype-card,
.product-card,.con-why-card,.con-aud-card,.ab-card,.rv-card,.gr-card,.googrev-card,.proc-card,
.dw-feature-card,.backlink-card,.cpro-card,.hiw-card,.ct-office,.office-card-new,.ct-faq-card,
.con-faq-card,.bc-body,.stat-box,.cd2,.mss-brand-card,.why-pdk-card,.why-ai-card,
.why-ax-card,.why-hw-card,.why-hik-card,.why-bog-card,.why-cdvi-card,.industry-detail-card{
  background-color:var(--white) !important;
  border:1px solid var(--border) !important;
  border-radius:var(--radius) !important;
  box-shadow:none !important;
  overflow:hidden;position:relative;
  transition:border-color .2s ease,transform .2s ease,box-shadow .2s ease;
}
.service-card:hover,.industry-card:hover,.blog-card:hover,.proj-card:hover,.project-card:hover,
.a-card:hover,.feature-card:hover,.mfr-detail-card:hover,.ind-hub-card:hover,.svc-hub-card:hover,
.camtype-card:hover,.product-card:hover,.con-why-card:hover,.backlink-card:hover,.cpro-card:hover{
  border-color:var(--accent) !important;transform:translateY(-3px);
  box-shadow:0 14px 34px rgba(10,25,38,.10) !important;
}
/* cards sitting on ink bands */
section[data-band="ink"] .service-card,section[data-band="ink2"] .service-card,
section[data-band="ink"] .industry-card,section[data-band="ink2"] .industry-card,
section[data-band="ink"] .feature-card,section[data-band="ink2"] .feature-card,
.section-dark .service-card,.section-dark .industry-card,.section-dark .feature-card,
section[data-band="ink"] .proc-card,section[data-band="ink2"] .proc-card,
section[data-band="ink"] .camtype-card,section[data-band="ink2"] .camtype-card,
section[data-band="ink"] .eq-card,section[data-band="ink2"] .eq-card{
  background-color:rgba(255,255,255,.035) !important;border:1px solid rgba(255,255,255,.13) !important;
  color:var(--text-ink-dim) !important;
}
section[data-band="ink"] .service-card h3,section[data-band="ink2"] .service-card h3,
section[data-band="ink"] .industry-card h3,section[data-band="ink2"] .industry-card h3,
section[data-band="ink"] .feature-card h3,section[data-band="ink2"] .feature-card h3{color:var(--text-ink) !important;}

/* card imagery — full-bleed top, subtle zoom on hover */
.service-card-img-wrap,.blog-thumb,.project-card-photo,.proj-card > .photo-slot,
.pg-feature-photo,.a-card .photo-slot,.mfr-card-head,.blog-hero-img{
  border-radius:0 !important;overflow:hidden;position:relative;background-color:var(--paper-2);
}
img.service-card-img,.blog-thumb img,.project-card-photo img,.blog-img img,
.service-card-img-wrap img,.pg-feature-photo img{
  width:100% !important;height:100% !important;object-fit:cover !important;display:block;
  border-radius:0 !important;transition:transform .5s cubic-bezier(.2,.7,.3,1);
}
/* img.service-card-img (not bare .service-card-img): on 194 of 195 pages
   "service-card-img" is the class on the <img> itself (wrapped in a
   .service-card-img-wrap <figure>), so the img-stretch rule above is meant
   for it. But access-control alone reuses "service-card-img" as its own
   WRAPPER <div> class (<div class="service-card-img"><img></div>, no class
   on the inner img) -- a leftover from an older card pattern the redesign
   never fully migrated. The bare selector matched that div too, forcing
   height:100% !important on it; since its flex/grid parent has no fixed
   height, the div stretched to fill the ENTIRE remaining card height
   (photo slot + what should have been the text body), painting its own
   navy placeholder background over the h3/p/link-arrow text sitting right
   below it in the DOM -- text present and correctly colored, just
   physically covered. access-control's own local <style> already sizes
   its wrapper (height:175px) and its inner img (width/height:100%,
   object-fit:cover) correctly on its own, so this scope-down is enough:
   no separate rule is needed for that page's img. */
.service-card:hover img.service-card-img,.blog-card:hover .blog-thumb img,
.project-card:hover .project-card-photo img,.a-card:hover img,.proj-card:hover img{transform:scale(1.05);}

.service-card-top,.service-card-body,.blog-card-body,.project-content,.a-body,.proj-body,
.mfr-card-body,.brands-cat-body,.dw-feat-body{padding:clamp(20px,2.2vw,28px) !important;}
.service-card-foot,.proj-card-cta,.bc-foot{
  padding:0 clamp(20px,2.2vw,28px) clamp(20px,2.2vw,28px) !important;
  border-top:0 !important;background:none !important;
}
.svc-card-h3-link,.blog-title,.project-title,.a-card h3{
  font-family:var(--f-display) !important;font-weight:700 !important;letter-spacing:-.022em !important;
  color:inherit !important;text-decoration:none !important;
}
.service-cta-link,.service-cta-text,.rc-link,.link-arrow,.svc-readmore,.blog-read,.art-cta{
  font-family:var(--f-mono) !important;font-size:.68rem !important;font-weight:600 !important;
  letter-spacing:.15em !important;text-transform:uppercase !important;
  color:var(--brass-ink) !important;text-decoration:none !important;
  display:inline-flex;align-items:center;gap:8px;background:none !important;border:0 !important;padding:0 !important;
  white-space:nowrap;
}
section[data-band="ink"] .service-cta-link,section[data-band="ink2"] .service-cta-link,
.section-dark .service-cta-link{color:var(--accent2) !important;}

/* icon tiles — one consistent brass-on-ink mark, never a rainbow */
.service-icon,.industry-icon,.pill-icon,.feat-icon,.svc-b-icon,.bsc-icon,.ind-hub-icon,
.brands-cat-icon,.con-aud-icon,.ab-card-icon,.backlink-icon,.dw-feat-icon,.mss-brand-icon,
.office-card-icon,.ct-info-ico,.brand-pill-icon,.c-icon,.cd2-icon,.gr-card-icon,.svc-b-cta-icon{
  background-color:rgba(223,161,62,.1) !important;color:var(--brass-ink) !important;
  border:1px solid rgba(223,161,62,.28) !important;border-radius:var(--radius) !important;
  box-shadow:none !important;display:inline-flex !important;align-items:center;justify-content:center;
  width:44px;height:44px;flex:0 0 auto;
}
.service-icon svg,.industry-icon svg,.feat-icon svg,.svc-b-icon svg,.ind-hub-icon svg,
.brands-cat-icon svg,.con-aud-icon svg,.office-card-icon svg,.ct-info-ico svg{
  width:20px;height:20px;fill:currentColor;
}
section[data-band="ink"] .service-icon,section[data-band="ink2"] .service-icon,
section[data-band="ink"] .industry-icon,section[data-band="ink2"] .industry-icon,
section[data-band="ink"] .feat-icon,section[data-band="ink2"] .feat-icon,
.section-dark .service-icon,.section-dark .industry-icon,.section-dark .feat-icon{
  background-color:rgba(223,161,62,.13) !important;color:var(--accent) !important;
  border-color:rgba(223,161,62,.3) !important;
}

/* --------------------------------------------------------------------------
   10. STATS, TRUST STRIPS, LOGO BARS
   -------------------------------------------------------------------------- */
.trust-bar,.trust-strip,.accolade-bar,.hero-accent-bar,.mss-pg-strip,.hq-strip,.ct-quickbar{
  background-color:var(--ink-deep) !important;border:0 !important;
  border-bottom:1px solid rgba(255,255,255,.08);padding:0 !important;box-shadow:none !important;
}
.trust-bar-inner,.trust-inner,.accolade-inner,.hero-accent-bar-inner,.ct-quickbar-inner{
  max-width:1240px;margin:0 auto;padding:14px var(--gutter) !important;
  display:flex;flex-wrap:wrap;align-items:center;gap:0;justify-content:space-between;
}
.trust-item,.accolade-item,.hq-item{
  font-family:var(--f-mono) !important;font-size:.655rem !important;font-weight:500 !important;
  letter-spacing:.14em !important;text-transform:uppercase !important;
  color:rgba(251,248,243,.62) !important;background:none !important;border:0 !important;
  padding:0 16px !important;display:flex;align-items:center;gap:9px;
}
.trust-item svg,.accolade-item svg{width:13px;height:13px;fill:var(--accent);opacity:.9;}
.trust-item:first-child{padding-left:0 !important;}
.trust-item:last-child{padding-right:0 !important;}
/* .ct-quickbar (contact page) used to be a gold/amber bar — its 3 .ct-quick
   items still carry a stroke="var(--navy)" icon and plain (browser-default
   link blue / inherited dark) text meant for that gold ground. Now that the
   bar above is forced to the dark var(--ink-deep) background like the other
   trust bars, that navy icon + dark text render invisible on the near-black
   bar. Reassert light values to match. */
.ct-quick{color:rgba(251,248,243,.92) !important;display:flex;align-items:center;gap:9px;}
.ct-quick a,.ct-quick span,.ct-quick a:hover{color:rgba(251,248,243,.92) !important;text-decoration:none !important;}
.ct-quick svg{stroke:var(--accent) !important;}

.stat-card,.about-stat,.ab-stat,.con-stat,.cpro-stat,.pg-hstat,.stat-box,.accolade-num{
  background:none !important;border:0 !important;box-shadow:none !important;border-radius:0 !important;
}
.about-stat-num,.ab-stat strong,.con-stat strong,.cpro-stat strong,.pg-hstat strong,.s-num{
  font-family:var(--f-display) !important;font-weight:800 !important;letter-spacing:-.04em !important;
  font-size:clamp(2rem,3.4vw,3.2rem) !important;line-height:1 !important;font-variant-numeric:tabular-nums;
}
/* .accolade-num (the "26+ / 4.9★ / MI·OH·IN / W-2 Only / 24/7 / Free" bar on
   /alarm-systems/, §10) shared this rule with the big standalone "about page"
   stat callouts above -- clamp(2rem,3.4vw,3.2rem) is 32-51px, meant for a
   large feature-stat block, not a compact single-line horizontal bar item
   sitting next to a tiny .accolade-label underneath it. That mismatch is
   Mike's "the letters are too big or something" report: at 47.6px rendered,
   "26+"/"4.9★"/"MI·OH·IN" towered over their own labels and forced "Free
   Site Assessment" to wrap onto its own row, breaking the bar's layout.
   Given its own modest size here instead, matching the item row it lives in
   (.accolade-item, §10 above, .655rem/uppercase/mono) rather than a
   full-page hero stat. */
.accolade-num{
  font-family:'Barlow Condensed',var(--f-display),sans-serif !important;
  font-weight:800 !important;letter-spacing:.01em !important;
  font-size:1.2rem !important;line-height:1.15 !important;font-variant-numeric:tabular-nums;
}
.about-stat-label,.accolade-label,.s-lbl,.cd2-label,.rc-label{
  font-family:var(--f-mono) !important;font-size:.62rem !important;font-weight:500 !important;
  letter-spacing:.15em !important;text-transform:uppercase !important;color:var(--text-light) !important;
}
/* .cql-label ("Brivo Services — Quick Links" etc., manufacturer contact
   sections) excluded above and given its own rule for the same reason as
   .cql-pill near the CITY TICKER / PILLS block: it lives inside
   .contact-left, a dark gradient CSS-class panel nested in a
   section[data-band="white"] contact section, so the generic dark
   var(--text-light) label color was invisible on it. */
.cql-label{
  font-family:var(--f-mono) !important;font-size:.62rem !important;font-weight:500 !important;
  letter-spacing:.15em !important;text-transform:uppercase !important;color:rgba(251,248,243,.66) !important;
}
.about-stat-grid,.ab-stats-grid,.stats-row,.stat-band-grid,.con-hero-stats,.cpro-statbar,.pg-hero-stats{
  display:grid !important;gap:0 !important;border-top:1px solid var(--border);
}
.about-stat-box{
  background:none !important;border:0 !important;border-left:1px solid var(--border) !important;
  border-radius:0 !important;box-shadow:none !important;padding:26px 0 26px 26px !important;
}
.about-stat-box:first-child{border-left:0 !important;padding-left:0 !important;}
/* .about-stat-box loses its dark navy-gradient card background above (flattened to a
   plain light-band bordered stat row), but each page's own local stylesheet still hard-codes
   .about-stat .num{color:var(--accent)} and .about-stat p{color:rgba(255,255,255,.78)} for the
   old dark design -- neither is an inline style, so none of the [style*=...] band-flip rules
   catch it. Always confirmed on a light ("white"/"paper") band across all 134 pages that use it. */
.about-stat .num{color:var(--brass-ink) !important;}
.about-stat p{color:var(--text-light) !important;}

/* client logo belt */
.clb,.brands-strip,.clients-grid,.mss-photo-strip{
  background-color:var(--white) !important;border-top:1px solid var(--border);border-bottom:1px solid var(--border);
  padding:34px 0 !important;
}
.clb-hdr,.brands-strip-hdr{max-width:1240px;margin:0 auto;padding:0 var(--gutter);text-align:center;}
.clb-hdr p,.brands-strip-hdr p{max-width:none !important;}
.clb-hdr p:first-child,.brands-strip-title,.clients-include-title{
  font-family:var(--f-mono) !important;font-size:.655rem !important;font-weight:600 !important;
  letter-spacing:.19em !important;text-transform:uppercase !important;color:var(--text-light) !important;
  text-align:center;margin:0 0 22px !important;
}
.clb-hdr p:not(:first-child){
  font-family:var(--f-body) !important;font-size:.95rem !important;font-weight:400 !important;
  letter-spacing:normal !important;text-transform:none !important;color:var(--text-light) !important;
  text-align:center;max-width:70ch;margin:0 auto 20px !important;
}
.clb-item{padding:0 26px !important;}
.clb-ph{background:none !important;border:0 !important;box-shadow:none !important;border-radius:0 !important;}
.clb-ph img,.client-logo img{
  filter:none;opacity:1;transition:.25s ease;max-height:44px;width:auto;
}
.clb-item:hover .clb-ph img,.client-logo:hover img{filter:grayscale(1) contrast(.9);opacity:.5;}

/* city ticker / pills — .bschip (brand-strip chips) gets its own richer
   treatment below instead of this generic tiny mono-uppercase pill, so it is
   deliberately left out of this shared list. .msa-city-pill (/alarm-systems/
   only) is ALSO left out: unlike the other pills here it doesn't live on a
   light section — its "Michigan Cities We Serve" strip is a plain <div>
   with its own inline background:#0a1f38 (dark navy), not a
   section[data-band], so this generic rule's var(--text-light) (dark) text
   was invisible on it. Its own legacy <style> block already has the
   correct light-on-dark colors; it just needs to be excluded here so
   those aren't overridden. .cql-pill (manufacturer-page "Quick Links" pills,
   ~20 pages) is excluded for the same reason: it lives inside
   .contact-left, a dark gradient CSS-class panel nested in a
   section[data-band="white"] contact section, so this rule's dark
   var(--text-light) text was landing on that dark panel — see the
   dedicated .contact-left .cql-pill rule below. */
.city-link-pill,.city-tag,.footer-city-link,.svc-ind-chip,
.brand-chip-pill,.chip,.ab-client-chip,.a-chip,.proc-chip,.compliance-badge,.eq-badge,
.ct-badge,.ab-loc-badge,.service-pill,.brand-pill,.qls .quick-link-item{
  font-family:var(--f-mono) !important;font-size:.665rem !important;font-weight:500 !important;
  letter-spacing:.11em !important;text-transform:uppercase !important;
  background:none !important;border:1px solid var(--border) !important;border-radius:2px !important;
  padding:7px 12px !important;color:var(--text-light) !important;text-decoration:none !important;
  box-shadow:none !important;transition:.16s ease;display:inline-flex;align-items:center;gap:7px;
}
.cql-pill{
  font-family:var(--f-mono) !important;font-size:.665rem !important;font-weight:500 !important;
  letter-spacing:.11em !important;text-transform:uppercase !important;
  background:none !important;border-radius:2px !important;
  padding:7px 12px !important;text-decoration:none !important;
  box-shadow:none !important;transition:.16s ease;display:inline-flex;align-items:center;gap:7px;
  border:1px solid rgba(255,255,255,.22) !important;color:rgba(251,248,243,.82) !important;
}
.city-link-pill:hover,.city-tag:hover,.footer-city-link:hover,
.brand-chip-pill:hover{
  border-color:var(--accent) !important;color:var(--brass-ink) !important;background-color:rgba(223,161,62,.07) !important;
}
.cql-pill:hover{
  border-color:var(--accent) !important;color:var(--accent2) !important;background-color:rgba(223,161,62,.12) !important;
}
section[data-band="ink"] .city-link-pill,section[data-band="ink2"] .city-link-pill,
section[data-band="ink"] .city-ticker-pill,section[data-band="ink2"] .city-ticker-pill,
.section-dark .city-link-pill,footer .city-ticker-pill,.footer-city-link{
  border-color:rgba(255,255,255,.16) !important;color:rgba(251,248,243,.66) !important;
}
section[data-band="ink"] .city-link-pill:hover,.footer-city-link:hover{
  border-color:var(--accent) !important;color:var(--accent) !important;background-color:rgba(223,161,62,.1) !important;
}

/* --------------------------------------------------------------------------
   10b. CITY TICKER — dedicated treatment (Mike: "I do not like how this
   looks... if we keep it can you make it look better?")
   Every usage lives inside .map-section (the "Find Us" contact/map block),
   which mss-2026.css flattens to a plain off-white band (background-color:
   var(--off-white) !important, see §9 CARDS above) with no data-band
   attribute (its background comes from a CSS class, invisible to
   transform.py's inline-only band sniffer — the same recurring blind spot
   as everywhere else in this file). But the ticker's own page-local <style>
   block (copy-pasted near-identically across all ~101 pages that use it)
   was written for the OLD dark-navy version of this section: pills styled
   as translucent-white-on-navy, and a fade mask
   (.city-ticker-wrap::before/::after) that fades to var(--navy). Once the
   section went light, the sitewide generic-chip rule above (now excluding
   .city-ticker-pill) was overriding the pill to the tiny flat mono chip
   used for footer/brand tags -- technically readable, but cramped and
   generic -- while the fade mask kept fading to navy, painting a dark smudge
   at each end of the strip that doesn't match the page's actual off-white
   background at all. This block gives the ticker its own light-band-
   appropriate "pill card" look instead, and fixes the fade mask color. */
.city-ticker-label{
  font-family:var(--f-mono) !important;font-size:.72rem !important;font-weight:600 !important;
  letter-spacing:.16em !important;text-transform:uppercase !important;
  color:var(--brass-ink) !important;text-align:center;position:relative;
  margin:0 0 22px !important;padding-top:20px;
}
.city-ticker-label::before{
  content:"";position:absolute;top:0;left:50%;transform:translateX(-50%);
  width:34px;height:2px;background-color:var(--accent);
}
.city-ticker-wrap::before{background:linear-gradient(90deg,var(--off-white),transparent) !important;}
.city-ticker-wrap::after{background:linear-gradient(-90deg,var(--off-white),transparent) !important;}
.city-ticker-pill{
  font-family:'Barlow Condensed',var(--f-display),sans-serif !important;
  font-size:.98rem !important;font-weight:700 !important;letter-spacing:.01em !important;
  text-transform:none !important;
  background:var(--white) !important;border:1px solid var(--border) !important;
  border-radius:30px !important;padding:9px 20px !important;
  color:var(--text) !important;text-decoration:none !important;
  box-shadow:0 2px 10px rgba(10,25,38,.07) !important;
  transition:.2s ease;display:inline-flex;align-items:center;gap:7px;
}
.city-ticker-pill:hover{
  border-color:var(--accent) !important;color:var(--brass-ink) !important;
  background-color:rgba(223,161,62,.08) !important;
  box-shadow:0 5px 16px rgba(223,161,62,.2) !important;
  transform:translateY(-1px);
}

/* --------------------------------------------------------------------------
   11. FAQ / ACCORDION
   -------------------------------------------------------------------------- */
.faq-item,.faq-u,.ct-faq-card,.con-faq-card,.bfaq-grid > *{
  background-color:var(--white) !important;border:0 !important;border-top:1px solid var(--border) !important;
  border-radius:0 !important;box-shadow:none !important;margin:0 !important;
}
.faq-grid,.faq-list,.faq-2col,.ct-faq-grid,.con-faq-grid,.bfaq-grid{
  border-bottom:1px solid var(--border);background-color:var(--white);
}
.faq-q,.faq-u-tog{
  font-family:var(--f-display) !important;font-weight:700 !important;
  font-size:clamp(1rem,1.25vw,1.15rem) !important;letter-spacing:-.018em !important;
  color:var(--text) !important;padding:24px 52px 24px 26px !important;
  background:none !important;border:0 !important;cursor:pointer;display:block;position:relative;
}
.faq-q-arrow{
  position:absolute;right:24px;top:50%;transform:translateY(-50%);color:var(--accent) !important;
  background:none !important;border:0 !important;transition:transform .25s ease;
}
.faq-answer-panel,.faq-a,.faq-u-ans{background:none !important;border:0 !important;}
.faq-answer-panel-inner,.faq-a,.faq-u-ans{
  padding:0 26px 26px !important;color:var(--text-light) !important;font-size:1rem;line-height:1.7;
}
section[data-band="ink"] :is(.faq-item,.faq-u),section[data-band="ink2"] :is(.faq-item,.faq-u),
.section-dark :is(.faq-item,.faq-u),.faq-dark-section :is(.faq-item,.faq-u){
  background-color:rgba(255,255,255,.03) !important;border-top-color:rgba(255,255,255,.12) !important;
}
/* .faq-grid (the wrapping list, not the individual .faq-item rows) is ALSO
   hardcoded to background-color:var(--white) above with no ink-band exception
   — only .faq-item itself was given the flip. Since .faq-item's own dark
   overlay is only 3% alpha, it barely tints .faq-grid's opaque white showing
   through underneath, so on an ink-band FAQ section (e.g. the manufacturer
   pages' plain <h4>/<p> FAQ markup, which has no .faq-q/.faq-answer-panel-inner
   wrapper to pick up their dedicated ink-band text-color rules and instead
   relies on the sitewide "headings/body on ink" rules for white text) the
   actual rendered background stayed white while the heading text turned
   white too — invisible. */
section[data-band="ink"] :is(.faq-grid,.faq-list,.faq-2col,.ct-faq-grid,.con-faq-grid,.bfaq-grid),
section[data-band="ink2"] :is(.faq-grid,.faq-list,.faq-2col,.ct-faq-grid,.con-faq-grid,.bfaq-grid),
.section-dark :is(.faq-grid,.faq-list,.faq-2col,.ct-faq-grid,.con-faq-grid,.bfaq-grid),
.faq-dark-section :is(.faq-grid,.faq-list,.faq-2col,.ct-faq-grid,.con-faq-grid,.bfaq-grid){
  background-color:transparent !important;border-bottom-color:rgba(255,255,255,.12) !important;
}
section[data-band="ink"] :is(.faq-q,.faq-u-tog),.section-dark :is(.faq-q,.faq-u-tog),
.faq-dark-section :is(.faq-q,.faq-u-tog){color:var(--text-ink) !important;}
section[data-band="ink"] :is(.faq-answer-panel-inner,.faq-a,.faq-u-ans),
.section-dark :is(.faq-answer-panel-inner,.faq-a,.faq-u-ans),
.faq-dark-section :is(.faq-answer-panel-inner,.faq-a,.faq-u-ans){color:var(--text-ink-dim) !important;}

/* --------------------------------------------------------------------------
   12. FORMS
   -------------------------------------------------------------------------- */
.contact-form-box,.contact-form-card,.ct-form-panel,.lead-form-wrap,.contact-panel,
.contact-split-panel,.builder,.report{
  background-color:var(--white) !important;border:1px solid var(--border) !important;
  border-radius:var(--radius) !important;box-shadow:none !important;padding:clamp(26px,3vw,40px) !important;
}
/* .hpanel (only /alarm-systems/) is not a form panel — it's a translucent
   frosted-glass card meant to sit on the dark hero photo, with its own gold
   heading (.hpt) and light pill text (.apn) designed for that dark ground.
   It got swept into the generic "form panel = solid white card" rule above
   by name-pattern coincidence, which forced its background fully opaque
   white — turning both the gold heading and white pill text invisible. Its
   own legacy <style> block already declares the correct translucent
   background/border, so it only needs to be excluded here. */
.form-group{margin-bottom:18px !important;}
.form-group label,.hp-field label,.captcha-label{
  font-family:var(--f-mono) !important;font-size:.63rem !important;font-weight:600 !important;
  letter-spacing:.15em !important;text-transform:uppercase !important;color:var(--text-light) !important;
  display:block;margin-bottom:7px;
}
input[type=text],input[type=email],input[type=tel],input[type=number],input[type=date],
input[type=search],select,textarea{
  font-family:var(--f-body) !important;font-size:.98rem !important;color:var(--text) !important;
  background-color:var(--white) !important;border:1px solid var(--border) !important;
  border-radius:var(--radius) !important;padding:13px 14px !important;width:100%;box-shadow:none !important;
  transition:border-color .16s ease,box-shadow .16s ease;
}
input:focus,select:focus,textarea:focus{
  border-color:var(--accent) !important;box-shadow:0 0 0 3px rgba(223,161,62,.16) !important;outline:none !important;
}
::placeholder{color:#9AA5B4;}
.form-note,.free-note,.fineprint,.disclaimer,.req-note{
  font-size:.82rem !important;color:var(--text-light) !important;
}
.captcha-box,.captcha-wrap{
  background-color:var(--off-white) !important;border:1px solid var(--border) !important;
  border-radius:var(--radius) !important;box-shadow:none !important;
}
.form-success{
  background-color:rgba(62,125,90,.08) !important;border:1px solid rgba(62,125,90,.35) !important;
  border-radius:var(--radius) !important;color:#2E5F44 !important;
}
.form-error,.captcha-error-msg{color:var(--red) !important;font-size:.85rem !important;}

/* --------------------------------------------------------------------------
   13. GRIDS — asymmetric, editorial
   -------------------------------------------------------------------------- */
.services-grid,.industries-grid,.blog-grid,.projects-grid,.proj-grid,.a-grid,.features-grid,
.feature-grid,.mfr-detail-grid,.brands-cat-grid,.ind-hub-grid,.svc-hub-grid,.pt-grid,.eq-grid,
.camtype-grid,.product-grid,.con-why-grid,.ab-why-grid,.gr-cards,.googrev-cards,.proc-grid,
.process-grid,.backlinks-grid,.cpro-cards,.hiw-grid,.ct-office-grid,.gallery-grid,.photo-grid-2{
  display:grid !important;gap:clamp(16px,1.9vw,26px) !important;
  grid-template-columns:repeat(auto-fit,minmax(clamp(250px,26vw,320px),1fr)) !important;
  align-items:stretch;
}
.city-links-grid,.city-tags,.brand-chips,.ab-client-chips,.cql-pills,.footer-city-link{gap:8px !important;}
.city-links-grid{display:flex !important;flex-wrap:wrap !important;}
/* the "every city we serve" grids sit on data-band="ink" (see transform.py) so
   they inherit the same dark-band colour contract as everything else — this
   just rounds the chip into the same fully-pill shape as the footer's own
   "Service Areas" list, which is the one look-and-feel Mike asked to match. */
.city-links-grid .city-link-pill{border-radius:20px !important;padding:8px 16px !important;}
.split-grid,.content-grid,.hgrid,.ct-split,.contact-layout,.seo-content-grid,.about-grid,.svc-b-row{
  display:grid !important;gap:clamp(30px,4vw,68px) !important;align-items:start;
  grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr) !important;
}
.split-img img,.about-img img,.img-frame img,.svc-photo img,.con-bid-photo img,.about-photo-wrap img{
  width:100%;height:100%;object-fit:cover;border-radius:var(--radius);display:block;
}
.img-frame,.split-img,.about-photo-wrap,.svc-photo,.con-bid-photo{
  border-radius:var(--radius);overflow:hidden;background-color:var(--paper-2);border:0 !important;box-shadow:none !important;
}
.img-caption,.photo-caption,.svc-photo-label,.pv-aerial-label,.gallery-label{
  font-family:var(--f-mono) !important;font-size:.62rem !important;letter-spacing:.14em !important;
  text-transform:uppercase !important;color:var(--text-light) !important;padding-top:10px;
}

/* feature/spec lists — hairline rows, mono labels */
.feature-item,.feature-check,.spec-row,.info-row,.checklist li,.svc-list li,.feature-list li,
.eq-list li,.driver-list li,.faq-list li,.hours-row{
  display:flex;align-items:flex-start;gap:11px;padding:11px 0 !important;
  border-bottom:1px solid var(--border);background:none !important;border-radius:0 !important;
  font-size:.965rem;color:var(--text-light);
}
.feature-item:last-child,.spec-row:last-child,.info-row:last-child{border-bottom:0;}
.feature-check,.info-dot,.check-icon,.compare-check,.ck,.chk,.eq-ck{
  color:var(--accent) !important;background:none !important;border:0 !important;flex:0 0 auto;
}
section[data-band="ink"] .feature-item,section[data-band="ink2"] .feature-item,
.section-dark .feature-item,section[data-band="ink"] .spec-row,section[data-band="ink2"] .spec-row{
  border-bottom-color:rgba(255,255,255,.11) !important;color:var(--text-ink-dim) !important;
}

/* tables */
table,.cmp-table,.compare-table{
  width:100%;border-collapse:collapse;background-color:var(--white);
  border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;font-size:.94rem;
}
th{
  font-family:var(--f-mono) !important;font-size:.63rem !important;font-weight:600 !important;
  letter-spacing:.15em !important;text-transform:uppercase !important;
  background-color:var(--navy) !important;color:var(--text-ink) !important;
  padding:14px 16px !important;text-align:left;border:0 !important;
}
td{padding:13px 16px !important;border-top:1px solid var(--border) !important;color:var(--text-light);vertical-align:top;}
tbody tr:nth-child(even) td{background-color:var(--off-white);}
.cmp-table-wrap,.compare-wrap,.cmp-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch;}
/* several service pages (alarm-monitoring, gate-perimeter-access, video-intercom,
   wireless-networks, why-choose-us, network-cabling, audio-video, security-cameras)
   build a comparison table INSIDE a section[data-band="ink"] with each <td> carrying
   its own light inline color (e.g. color:#F5A623 / color:#dfe6ef) meant to sit
   directly on the dark section behind it — but table/.cmp-table/.compare-table above
   paints an unconditional solid white background regardless of context (same bug
   family as .faq-grid), and tbody tr:nth-child(even) td adds an off-white stripe on
   top of that. That opaque white box floats over the dark section, and the inline
   light td text (which the stylesheet never touches, since inline colors already
   beat the non-!important td{color:var(--text-light)} rule) goes from
   light-on-dark to light-on-white — nearly invisible. Make the table transparent so
   the section's own dark background shows through, like the ink-band .faq-item fix. */
section[data-band="ink"] :is(table,.cmp-table,.compare-table),
section[data-band="ink2"] :is(table,.cmp-table,.compare-table){
  background-color:transparent !important;border-color:rgba(255,255,255,.15) !important;
}
section[data-band="ink"] td,
section[data-band="ink2"] td{border-top-color:rgba(255,255,255,.1) !important;}
section[data-band="ink"] tbody tr:nth-child(even) td,
section[data-band="ink2"] tbody tr:nth-child(even) td{
  background-color:rgba(255,255,255,.035) !important;
}
/* why-choose-us's "Four Ways to Secure Your Business" table is the OPPOSITE shape from
   the transparent-table fix just above: its table sits inside its own inline
   overflow-x:auto;background:var(--white) wrapper div -- a genuine solid white card
   floating inside this section[data-band="ink"], not inline light text meant to read
   directly against the dark section. That wrapper div is untouched by the table-tag-only
   transparent rule above, so the ink-band blanket td/th color rule (and the inline
   color:var(--navy) safety net elsewhere in this file) both still force light text here,
   which goes invisible on the actual white card. Give plain <td>s their ordinary
   light-band color back, and let any color:var(--navy) td keep its navy. */
section[data-band="ink"] [style*="background:var(--white)"] td,
section[data-band="ink2"] [style*="background:var(--white)"] td{color:var(--text-light) !important;}
/* the duplicated data-band attribute below is a specificity bump, not a typo: a later
   fix in this file (section 25/26's "self-contained button" guard) added a
   :not([style*="background:"]) to the plain section[data-band="ink"] [style*="color:
   var(--navy)"] rule, which — because :not()'s specificity equals its argument's —
   pushed that rule up to the same (0,3,1) as this one, and source order (it comes
   later in the file) then let it win, silently re-breaking the exact why-choose-us
   navy-td-on-white-card case this rule exists to fix. One extra attribute-selector
   point here keeps this the unconditional winner regardless of what gets added below. */
section[data-band="ink"][data-band="ink"] [style*="background:var(--white)"] [style*="color:var(--navy)"],
section[data-band="ink2"][data-band="ink2"] [style*="background:var(--white)"] [style*="color:var(--navy)"]{color:var(--navy) !important;}
/* the color:var(--text-light) fix just above only works once --text-light itself resolves
   to something dark again -- but the TOKEN CONTRACT section further down in this file sets
   section[data-band="ink"] *{--text-light:rgba(251,248,243,.90)!important}, and because
   that universal "*" selector matches this <td> directly (not merely by inheritance from
   its <tr>), it wins regardless of what the <tr>/<table> ancestors resolved to. Reset the
   custom properties themselves for this card and everything inside it, same fix shape as
   the #FFF8E8 callout box below, so every var(--text)/var(--text-light) reference in its
   subtree (not just the ones explicitly listed above) comes out dark automatically. Scoped
   to tbody only (not the whole wrapper/table): this table's own <thead> row is a genuine
   navy-background dark island (inline background:var(--navy)) and is already handled
   correctly by the sitewide th{color:var(--text-ink)!important} rule -- resetting
   --text-light for it too would feed that same dark value into the separate "dark island
   inside a light [wrapper]" contract further down this file, which also renders its text
   via var(--text-light), turning the thead's own light text dark-on-dark. */
section[data-band="ink"] [style*="background:var(--white)"],
section[data-band="ink2"] [style*="background:var(--white)"],
section[data-band="ink"] [style*="background:var(--white)"] tbody,
section[data-band="ink2"] [style*="background:var(--white)"] tbody,
section[data-band="ink"] [style*="background:var(--white)"] tbody *,
section[data-band="ink2"] [style*="background:var(--white)"] tbody *{
  --text:#12202E !important;--text-light:#3D4A5D !important;
}

/* --------------------------------------------------------------------------
   14. FOOTER
   -------------------------------------------------------------------------- */
footer,.site-foot{
  background-color:var(--ink-deep) !important;color:rgba(251,248,243,.6) !important;
  border-top:3px solid var(--accent);padding:clamp(56px,6vw,84px) 0 0 !important;
}
.footer-grid{
  max-width:1240px;margin:0 auto;padding:0 var(--gutter) !important;
  display:grid !important;gap:clamp(28px,3.4vw,52px) !important;
  grid-template-columns:minmax(0,1.5fr) repeat(auto-fit,minmax(160px,1fr)) !important;
}
.footer-col h4,.footer-col > strong,.footer-division{
  font-family:var(--f-mono) !important;font-size:.645rem !important;font-weight:600 !important;
  letter-spacing:.18em !important;text-transform:uppercase !important;
  color:var(--accent) !important;margin-bottom:16px !important;padding-bottom:11px;
  border-bottom:1px solid rgba(255,255,255,.1);display:block;
}
.footer-link,.footer-col a{
  color:rgba(251,248,243,.62) !important;text-decoration:none !important;font-size:.9rem;
  display:block;padding:5px 0;transition:color .16s ease,padding-left .16s ease;
}
.footer-link:hover,.footer-col a:hover{color:var(--accent) !important;padding-left:5px;}
.footer-brand p{color:rgba(251,248,243,.55) !important;font-size:.92rem;max-width:42ch;}
.footer-logo-img{height:46px;width:auto;}
.footer-logo-text{font-family:var(--f-display);font-weight:800;color:var(--text-ink) !important;letter-spacing:-.028em;}
.footer-social{display:flex;gap:9px;margin-top:18px;}
.social-btn{
  width:38px;height:38px;display:inline-flex;align-items:center;justify-content:center;
  background:none !important;border:1px solid rgba(255,255,255,.16) !important;
  border-radius:var(--radius) !important;color:rgba(251,248,243,.7) !important;transition:.16s ease;
}
.social-btn:hover{border-color:var(--accent) !important;color:var(--accent) !important;background-color:rgba(223,161,62,.09) !important;}
.footer-bottom,.fbot{
  max-width:1240px;margin:clamp(40px,4vw,60px) auto 0;padding:22px var(--gutter) !important;
  border-top:1px solid rgba(255,255,255,.1);
  font-family:var(--f-mono);font-size:.64rem;letter-spacing:.11em;text-transform:uppercase;
  color:rgba(251,248,243,.42) !important;
  display:flex;flex-wrap:wrap;gap:14px;justify-content:space-between;align-items:center;
}
.footer-legal-link{color:rgba(251,248,243,.42) !important;text-decoration:none !important;}
.footer-legal-link:hover{color:var(--accent) !important;}

/* --------------------------------------------------------------------------
   15. MISC COMPONENTS
   -------------------------------------------------------------------------- */
.breadcrumb,.breadcrumb-nav{
  font-family:var(--f-mono) !important;font-size:.63rem !important;letter-spacing:.13em !important;
  text-transform:uppercase !important;color:var(--text-light) !important;padding:16px 0 !important;
}
.breadcrumb a,.breadcrumb-nav a{color:var(--text-light) !important;text-decoration:none;}
.breadcrumb a:hover{color:var(--brass-ink) !important;}
.map-section,.ct-map-sec,.map-embed-wrap{background-color:var(--off-white) !important;}
.map-embed-wrap,.ct-map,.aerial-map{border-radius:var(--radius);overflow:hidden;border:1px solid var(--border);}
.cta-banner,.pg-cta,.ab-cta,.rv-cta,.proc-cta,.final-cta,.cta-final,.industry-cta,.svc-cta,.blog-article-cta{
  background-color:var(--navy) !important;color:var(--text-ink) !important;border-radius:0 !important;
  border:0 !important;border-top:3px solid var(--accent) !important;padding:clamp(46px,5vw,76px) 0 !important;
}
.cta-banner h2,.pg-cta h2,.ab-cta h2,.proc-cta h2,.final-cta h2,.industry-cta h2,.svc-cta h2{color:var(--text-ink) !important;}
.cta-banner p,.pg-cta p,.ab-cta p,.proc-cta p,.final-cta p{color:var(--text-ink-dim) !important;}
.emergency-box,.law-callout,.note,.fnote,.eq-note{
  background-color:rgba(223,161,62,.07) !important;border:0 !important;border-left:3px solid var(--accent) !important;
  border-radius:0 !important;padding:20px 24px !important;box-shadow:none !important;color:var(--text-light) !important;
}
/* .info-box was previously grouped with the light amber note/callout boxes above (and
   with section 9's white "CARD TEXT CONTRACT" cards), but a full audit of every page
   that actually uses class="info-box" (86 of them: all ~85 city pages' "Contact
   Michigan Security Systems" sidebar box, plus digital-watchdog's) found not one
   genuine light-callout usage -- every single one defines .info-box locally as a
   solid dark navy card (background:var(--navy) or a navy gradient; color:white) with
   var(--accent)/rgba(255,255,255,.NN) inline text made for that dark ground. So .info-
   box is a sitewide dark island by construction, never a light one; it's been removed
   from both those class lists above/below and gets its own dark-card contract here
   instead of the light-card treatment it was wrongly inheriting. */
.info-box{
  background-color:var(--navy) !important;border:0 !important;color:#fff !important;
  --text:#FBF8F3 !important;--text-light:rgba(251,248,243,.85) !important;
}
.info-box *{--text:#FBF8F3 !important;--text-light:rgba(251,248,243,.85) !important;}
/* .info-box.info-box duplicated-class bump: the sitewide section[data-band="paper"/"white"]
   :is(h1..h6) / :is(p,li,...) light-band rules below (same (0,2,0)+!important specificity)
   come later in source order and would otherwise win the tie, repainting these dark-card
   headings/paragraphs navy-on-navy -- same specificity trap as the why-choose-us and
   #FFF8E8 fixes above. */
.info-box.info-box :is(h1,h2,h3,h4,h5,h6){color:#fff !important;}
.info-box.info-box :is(p,li,span,div,small){color:rgba(255,255,255,.82) !important;}
/* an inline color:var(--accent) contact link inside the card normally reads fine on
   its dark navy -- except two sitewide rules also match a classless accent-colored
   anchor sitting somewhere in the page's light-band ancestry (one flips it to
   var(--blue), the other to brass-ink for a light card) and between them the
   var(--blue) one wins on specificity. The worst offender is
   "section[data-band=paper] a:not([class]):not([style*=background:]):not([style*=color:rgba(255,255,255])"
   at (0,4,2) -- the same specificity trap .faq-uni-ans hit elsewhere in this file --
   so it takes 5x duplication (0,6,0) to clear it with margin, regardless of source order. */
.info-box.info-box.info-box.info-box.info-box [style*="color:var(--accent)"]{
  color:var(--accent) !important;
}
.article,.blog-article,.legal-body,.art-body,.blog-body,.report-body{
  background-color:var(--white) !important;
}
.article h2,.blog-article h2,.art-body h2{margin-top:1.9em;}
.article p,.blog-article p,.art-body p,.legal-body p{font-size:1.075rem;line-height:1.75;color:#2A3648;}
/* :not([style*="background:"]) — a handful of blog posts have a mid-article
   CTA callout with its own "Get Your Free Assessment" button that already
   carries a matched inline color+background (e.g. gold button, navy text);
   the blanket in-body link color below was overriding just its color half,
   leaving mismatched button colors. Anchors that paint their own background
   are self-contained and should be left alone. */
.article a:not([style*="background:"]),.blog-article a:not([style*="background:"]),
.art-body a:not([style*="background:"]){color:var(--blue) !important;text-decoration:underline;text-underline-offset:3px;text-decoration-thickness:1px;}
/* ...and the CTA box's plain "or call ###-###-####" phone link (no
   background of its own, sitting directly on the box's inline
   background:var(--navy)) still needs to be forced light, since it falls
   outside the exclusion above and would otherwise inherit the surrounding
   dark card's paragraph color.
   :not(.law-callout etc.) — .law-callout/.emergency-box/.info-box/.note/.fnote/
   .eq-note carry the same literal inline "background:var(--navy)" text on some
   blog posts, but section 14's box rule (.emergency-box,.law-callout,...) always
   force-flattens their actual rendered background to a light amber-tinted card
   regardless of that inline attribute — so a plain link inside one of THOSE never
   really sits on navy and must not be forced white here (it already gets a
   correct dark link color from the .article a rule above). */
.article div[style*="background:var(--navy)"]:not(.law-callout):not(.emergency-box):not(.info-box):not(.note):not(.fnote):not(.eq-note) a:not([style*="background:"]),
.blog-article div[style*="background:var(--navy)"]:not(.law-callout):not(.emergency-box):not(.info-box):not(.note):not(.fnote):not(.eq-note) a:not([style*="background:"]){
  color:#fff !important;text-decoration:underline;
}
.stars,.rv-card-stars,.gr-card-stars,.googrev-stars,.rv-sum-stars{color:var(--accent) !important;letter-spacing:.08em;}
.gallery-item img{border-radius:var(--radius);}
hr,.brands-divider,.proc-divider,.rv-sum-divider,.sep{border:0;border-top:1px solid var(--border);height:0;background:none;}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;}

/* --------------------------------------------------------------------------
   16. MOTION — restrained, respects reduced-motion
   -------------------------------------------------------------------------- */
/* Motion only — never opacity. Content must stay visible to crawlers and to any
   browser where the observer does not run. */
@media (prefers-reduced-motion:no-preference){
  [data-reveal]{transform:translateY(15px);transition:transform .55s cubic-bezier(.2,.7,.3,1);}
  [data-reveal].is-in{transform:none;}
}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms !important;transition-duration:.001ms !important;scroll-behavior:auto !important;}
  [data-reveal]{transform:none !important;}
  /* Forcing an "infinite" marquee to a near-zero duration (rather than actually
     stopping it) leaves the animation still iterating thousands of times a
     second — on real hardware this reliably shows up as the scrolling client-
     logo / city-name / review strips freezing mid-cycle and going blank, since
     the browser is landing on an arbitrary, uncommitted point of the transform
     every repaint instead of a clean frame. Stop these outright instead. */
  .clb-track,.city-ticker-track,.reviews-marquee-track{animation:none !important;}
}

/* --------------------------------------------------------------------------
   17. RESPONSIVE
   -------------------------------------------------------------------------- */
@media (max-width:1180px){
  #site-header .nav-link{padding-left:9px !important;padding-right:9px !important;font-size:.83rem;}
  #site-header .hc-phone{font-size:.94rem;}
  #site-header .logo-text-sub{display:none;}
}
@media (max-width:1024px){
  .hero-content{grid-template-columns:1fr !important;padding:0 !important;}
  .hero-content > div:first-child,.hero-left{
    padding:clamp(40px,6vw,64px) var(--gutter) clamp(34px,4vw,48px) !important;
  }
  .hero h1{max-width:none;font-size:clamp(2.25rem,6vw,3.2rem) !important;}
  .hero-right-col,.hero .hero-panel{margin-right:0 !important;}
  .hero-right-col::before,.hero-content > .hero-panel::before{
    background:linear-gradient(0deg,transparent 60%,rgba(10,25,38,.35) 100%);
  }
  .hero .hero-carousel,.hero .photo-slot,.hero-photo-placeholder,.hero-photo-wrap{min-height:340px !important;}
  .split-grid,.content-grid,.hgrid,.ct-split,.contact-layout,.seo-content-grid,.about-grid,.svc-b-row{
    grid-template-columns:1fr !important;
  }
  .footer-grid{grid-template-columns:repeat(auto-fit,minmax(180px,1fr)) !important;}
}
@media (max-width:820px){
  /* header collapses to logo + phone + hamburger. Lowered from 1080px (Sept
     2026): tested with the real 11-item nav (incl. 3 dropdowns + CTA) via
     headless-browser width sweep — the row renders with no wrap/overflow
     down to 780px, so 820px keeps the full clickable nav visible on real
     laptop/tablet-landscape traffic and only collapses for genuinely narrow
     (phone/tablet-portrait) viewports. */
  #site-header nav{display:none !important;}
  #site-header{min-height:64px;gap:12px;}
  #site-header .logo-img{height:36px;}
  #site-header .logo-name{font-size:.92rem;}
  #site-header .hc-phone{order:3;margin-left:auto;border-left:0;padding-left:0;}
  #site-header .nav-cta2{display:none !important;}
  #site-header .nav-cta{order:4;padding:9px 14px !important;font-size:.78rem;}
  #site-header .hamburger{
    order:5;display:inline-flex !important;align-items:center;justify-content:center;
    width:42px;height:42px;background:none !important;border:1px solid rgba(255,255,255,.2) !important;
    border-radius:var(--radius) !important;color:var(--text-ink) !important;cursor:pointer;
  }
  .gold-bar-inner{height:auto;flex-wrap:wrap;padding:8px var(--gutter) !important;gap:6px 0;justify-content:center;}
  .gold-bar-text:nth-child(n+5),.gold-bar-divider{display:none !important;}
  .gold-bar-cta{margin-left:0;}
  .trust-bar-inner,.trust-inner,.accolade-inner{justify-content:center;gap:8px 0;}
  .trust-item,.accolade-item{padding:5px 12px !important;font-size:.6rem !important;}
  .accolade-num{font-size:1.05rem !important;}
}
@media (max-width:760px){
  body{font-size:16px;}
  :root{--band:clamp(48px,10vw,68px);}
  h1{font-size:clamp(2rem,8vw,2.7rem);}
  h2{font-size:clamp(1.55rem,6.2vw,2.05rem);}
  .hero h1{font-size:clamp(2rem,8.2vw,2.7rem) !important;}
  .hero-stats{grid-template-columns:repeat(2,minmax(0,1fr)) !important;gap:20px 0 !important;max-width:none;}
  .hero-stats .stat-card:nth-child(odd){border-left:0 !important;padding-left:0 !important;}
  .hero-actions{flex-direction:column;align-items:stretch;}
  .hero-actions > *{width:100%;}
  .hero .service-pill-grid{grid-template-columns:1fr !important;}
  .services-grid,.industries-grid,.blog-grid,.projects-grid,.proj-grid,.a-grid,.features-grid,
  .feature-grid,.mfr-detail-grid,.brands-cat-grid,.ind-hub-grid,.svc-hub-grid,.pt-grid,.eq-grid,
  .camtype-grid,.product-grid,.con-why-grid,.ab-why-grid,.gr-cards,.googrev-cards,.proc-grid,
  .process-grid,.backlinks-grid,.cpro-cards,.hiw-grid,.ct-office-grid,.gallery-grid,.photo-grid-2{
    grid-template-columns:1fr !important;
  }
  .about-stat-grid,.ab-stats-grid,.stats-row,.stat-band-grid,.con-hero-stats,.cpro-statbar,.pg-hero-stats{
    grid-template-columns:repeat(2,minmax(0,1fr)) !important;
  }
  .about-stat-box:nth-child(odd){border-left:0 !important;padding-left:0 !important;}
  .footer-grid{grid-template-columns:1fr !important;}
  .footer-bottom,.fbot{flex-direction:column;align-items:flex-start;text-align:left;}
  .faq-q,.faq-u-tog{padding:20px 46px 20px 18px !important;font-size:1rem !important;}
  .faq-answer-panel-inner{padding:0 18px 20px !important;}
  .service-card-top,.service-card-body,.blog-card-body,.project-content,.a-body,.proj-body{padding:20px !important;}
  .hero-call-block{padding:16px 20px !important;}
  .hero .hero-panel-title{padding:18px 20px 10px !important;}
  .hero .service-pill{padding:13px 20px !important;}
}

/* --------------------------------------------------------------------------
   18. OVERFLOW GUARDS — no page may scroll sideways
   -------------------------------------------------------------------------- */
html{overflow-x:clip;}
img,svg,video,iframe,table,pre{max-width:100%;}
.contact-split-panel,.contact-split-left,.contact-split-right,.csl-logo,.csl-details,
.city-ticker-wrap,.city-ticker-track,.rm-clip,.hero-panel,.service-pill-grid{min-width:0;max-width:100%;}
.hero-actions > *,.cta-btns > *,.ab-cta-btns > *,.pg-cta-btns > *,.rv-cta-btns > *,.ctabtns > *{max-width:100%;}
.container,section,.section,.section-alt,.section-dark,footer,header{max-width:100vw;}
.clb,.clb-wrap,.city-ticker-wrap,.city-ticker-track,.a-carousel,.brands-strip,.mss-cty-strip,
.mss-photo-strip,.hero-carousel,.carousel-track{overflow:hidden !important;max-width:100%;}
.cmp-table-wrap,.compare-wrap,.cmp-wrap{overflow-x:auto;max-width:100%;}
h1,h2,h3,h4,p,li,td,th,a{overflow-wrap:break-word;}

/* print */
@media print{
  #site-header,.gold-bar,.trust-bar,.mobile-menu,.mobile-sticky-bar,footer .footer-social{display:none !important;}
  body{background-color:#fff;font-size:11pt;}
  section[data-band]{background-color:#fff !important;color:#000 !important;padding:14px 0 !important;}
}

/* --------------------------------------------------------------------------
   19. LEGACY OVERRIDES — supersede the old fixed two-row header shell
   -------------------------------------------------------------------------- */
body{padding-top:0 !important;}
#site-header,header#site-header{
  position:sticky !important;top:0 !important;left:auto !important;width:auto !important;
  z-index:900 !important;
}
#site-header .header-main,#site-header .nav-row{
  max-width:none !important;margin:0 !important;padding:0 !important;
  display:contents !important;background:none !important;box-shadow:none !important;border:0 !important;
}
#site-header .logo-img,.logo-img{
  height:42px !important;width:auto !important;max-width:132px !important;min-width:0 !important;
  object-fit:contain !important;flex-shrink:0 !important;
}
#site-header nav{justify-content:flex-end !important;}
#site-header .nav-link.active,#site-header .nav-cta2.active{
  background:none !important;color:var(--text-ink) !important;box-shadow:none !important;
}
#site-header .nav-link.active::after{display:block !important;content:"" !important;transform:scaleX(1) !important;}
#site-header .nav-cta2{margin-left:0 !important;margin-right:0 !important;border-radius:var(--radius) !important;}
#site-header .nav-cta{background-color:var(--accent) !important;color:var(--navy) !important;border-radius:var(--radius) !important;}
#site-header .nav-cta.active{background-color:var(--accent2) !important;color:var(--navy) !important;}
#site-header .nav-link:not(.nav-cta):hover{color:var(--text-ink) !important;background-color:transparent !important;}
.section-dark,.section-dark2{color:var(--text-ink) !important;}
.section-dark p,.section-dark2 p,.section-dark li,.section-dark2 li{color:var(--text-ink-dim) !important;}
.section-dark .section-head h2,.section-dark2 .section-head h2,
.section-dark .section-head h3,.section-dark2 .section-head h3{color:var(--text-ink) !important;}
.mobile-nav{background-color:var(--navy) !important;}
.mobile-nav-link{
  font-family:var(--f-body) !important;font-weight:600 !important;font-size:1rem !important;
  color:var(--text-ink) !important;border-bottom:1px solid rgba(255,255,255,.09) !important;
}
.mobile-nav-link:hover{color:var(--accent) !important;}
.mobile-nav-sub{
  font-family:var(--f-mono) !important;font-size:.62rem !important;letter-spacing:.15em !important;
  text-transform:uppercase !important;color:var(--accent) !important;
}
@media(max-width:768px){
  p,li,.lead{font-size:1rem !important;line-height:1.65 !important;}
  #site-header .logo-img,.logo-img{height:34px !important;max-width:100px !important;}
}
/* old rounded/glassy chrome removed globally */
.hero-panel,.hero-photo-placeholder,.photo-slot,.product-img-wrap,.hero-carousel{backdrop-filter:none !important;}

/* --------------------------------------------------------------------------
   20. DROPDOWN VISIBILITY — legacy sheets force these open; restore hover/focus
   -------------------------------------------------------------------------- */
#site-header .nav-dropdown > .nav-dropdown-menu{
  display:none !important;position:absolute;top:100%;left:0;z-index:1200;
}
#site-header .nav-dropdown:hover > .nav-dropdown-menu,
#site-header .nav-dropdown:focus-within > .nav-dropdown-menu{display:block !important;}
/* grouped mega-menu (Manufacturers) must stay a flex row even once toggled visible —
   this needs to out-specificity the display:block rule directly above */
#site-header .nav-dropdown:hover > .nav-dropdown-menu.nav-dropdown-grouped,
#site-header .nav-dropdown:focus-within > .nav-dropdown-menu.nav-dropdown-grouped{display:flex !important;}
#site-header .nav-dropdown:last-of-type > .nav-dropdown-menu,
#site-header .nav-dropdown:nth-last-of-type(2) > .nav-dropdown-menu{left:auto;right:0;}
#site-header .nav-dropdown > .nav-link{cursor:pointer;}
/* keep the header above hero art at all times */
.gold-bar{position:relative;z-index:950;}

/* --------------------------------------------------------------------------
   21. HEADER FIT — the nav must never overflow back across the logo
   -------------------------------------------------------------------------- */
#site-header nav{flex-wrap:nowrap;overflow:visible;}
@media (max-width:1560px){ #site-header .hc-phone{display:none !important;} }
@media (max-width:1900px){ #site-header .logo-text-sub{display:none !important;} }
@media (max-width:1780px){
  #site-header .logo-badge{display:none !important;}
  #site-header .nav-link{padding-left:8px !important;padding-right:8px !important;font-size:.845rem !important;}
  #site-header .nav-link::after{left:8px;right:8px;}
}
@media (max-width:1440px){
  #site-header .nav-link{padding-left:6px !important;padding-right:6px !important;font-size:.815rem !important;}
  #site-header .nav-link::after{left:6px;right:6px;}
  #site-header .nav-cta2,#site-header .nav-cta{padding:9px 13px !important;font-size:.79rem !important;}
  #site-header .logo-name{font-size:.95rem !important;}
}
@media (max-width:1300px){
  #site-header .nav-cta2{display:none !important;}
  #site-header .nav-link{padding-left:5px !important;padding-right:5px !important;font-size:.78rem !important;}
  #site-header .nav-link::after{left:5px;right:5px;}
  #site-header .logo-img,.logo-img{height:36px !important;}
  #site-header .logo-name{font-size:.9rem !important;}
}
@media (max-width:1160px){
  #site-header .logo-textcol{display:none !important;}
}

/* live-status chip: left-aligned, hugs its content */
.mss-hero-live{
  flex-direction:column !important;align-items:flex-start !important;justify-content:center !important;
  width:auto !important;max-width:max-content !important;text-align:left !important;gap:3px !important;
}
.mss-live-top,.mss-live-sub{justify-content:flex-start !important;text-align:left !important;width:auto !important;}

/* hero proportions — keep the fold useful */
.hero .hero-carousel,.hero-right-col .hero-carousel{max-height:none;}
.hero-content > div:first-child,.hero-left{padding-top:clamp(44px,4.6vw,68px);padding-bottom:clamp(44px,4.6vw,68px);}
.hero .photo-slot,.hero-photo-placeholder,.hero-photo-wrap,.hero .product-img-wrap{min-height:clamp(300px,30vw,430px);}
.hero .hero-carousel,.hero-right-col .hero-carousel{min-height:clamp(340px,38vw,500px);}

/* --------------------------------------------------------------------------
   22. BAND TEXT CONTRACT
   Legacy page stylesheets colour body text for a dark ground. Any band that is
   now light must assert dark text — then hand it back to genuinely dark boxes
   nested inside it.
   -------------------------------------------------------------------------- */
section[data-band="paper"],section[data-band="white"]{color:var(--text);}
section[data-band="paper"] :is(p,li,dd,dt,figcaption,blockquote,label,small,em,strong,b),
section[data-band="white"] :is(p,li,dd,dt,figcaption,blockquote,label,small,em,strong,b){
  color:var(--text-light) !important;
}
section[data-band="paper"] :is(h1,h2,h3,h4,h5,h6),
section[data-band="white"] :is(h1,h2,h3,h4,h5,h6){color:var(--text) !important;}
section[data-band="paper"] :is(.stat-num,.about-stat-num,.accolade-num,.s-num,.hero-call-num),
section[data-band="white"] :is(.stat-num,.about-stat-num,.accolade-num,.s-num,.hero-call-num){
  color:var(--brass-ink) !important;
}
section[data-band="paper"] :is(.stat-label,.about-stat-label,.accolade-label,.s-lbl),
section[data-band="white"] :is(.stat-label,.about-stat-label,.accolade-label,.s-lbl){
  color:var(--text-light) !important;
}
/* eyebrows, brass rules and links keep their own colour */
section[data-band="paper"] :is(.section-tag,.eyebrow,.sec-label,.hero-badge,.service-cta-link,
  .link-arrow,.svc-readmore,.blog-read,.art-cta,.rc-link,.feature-check,.info-dot,.check-icon,
  .compare-check,.stars,.ck,.chk,.eq-ck,.ab-sub),
section[data-band="white"] :is(.section-tag,.eyebrow,.sec-label,.hero-badge,.service-cta-link,
  .link-arrow,.svc-readmore,.blog-read,.art-cta,.rc-link,.feature-check,.info-dot,.check-icon,
  .compare-check,.stars,.ck,.chk,.eq-ck,.ab-sub){color:var(--brass-ink) !important;}

/* ---- hand the contract back to boxes that are still genuinely dark ---- */
/* [style*="background:linear-gradient(135deg,#4a0"] added sitewide (all 6 copies of this
   dark-island allowlist below): catches #4a0d0d,#992020 (Ira Township's Fire Dept project
   card) and #4a0a1a,#8a1a35 (the same dark-maroon "featured/urgent" project-card gradient
   reused on ~79 city pages) -- both are genuinely dark, but neither hex prefix ("4a...")
   was in the original #08/#0A/#0B/#0D/#10/#12 navy-family allowlist, so a .proj-addr/h3
   nested in one of these cards fell through to the light-card .proj-card CARD TEXT
   CONTRACT rule (var(--text-light), dark-on-dark). Scoped to this specific hex prefix
   rather than broadening to all "#4..." gradients, since plenty of *bright* badge
   gradients on this site also start with #4 (e.g. Google-blue #4285F4). */
section[data-band] :is(
  .section-dark,.section-dark2,.cta-banner,.hero-panel,.faq-dark-section,.related-brands-section,
  .emergency-box,.proc-cta,.cta-final,.final-cta,.industry-cta,.svc-cta,.blog-article-cta,
  .ab-cta,.pg-cta,.rv-cta,.con-div-card,
  [style*="background:var(--navy"],[style*="background: var(--navy"],
  [style*="background:#08"],[style*="background:#0A"],[style*="background:#0a"],
  [style*="background:#0B"],[style*="background:#0b"],[style*="background:#0D"],[style*="background:#0d"],
  [style*="background:#10"],[style*="background:#12"],
  [style*="background:linear-gradient(135deg,#0"],[style*="background:linear-gradient(135deg,#4a0"],[style*="background:linear-gradient(160deg,#0"]
){color:var(--text-ink) !important;background-color:inherit;}
section[data-band] :is(
  .section-dark,.section-dark2,.cta-banner,.hero-panel,.faq-dark-section,.related-brands-section,
  .proc-cta,.cta-final,.final-cta,.industry-cta,.svc-cta,.blog-article-cta,.ab-cta,.pg-cta,.rv-cta,.con-div-card,
  [style*="background:var(--navy"],[style*="background: var(--navy"],
  [style*="background:#08"],[style*="background:#0A"],[style*="background:#0a"],
  [style*="background:#0B"],[style*="background:#0b"],[style*="background:#0D"],[style*="background:#0d"],
  [style*="background:#10"],[style*="background:#12"],
  [style*="background:linear-gradient(135deg,#0"],[style*="background:linear-gradient(135deg,#4a0"],[style*="background:linear-gradient(160deg,#0"]
) :is(p,li,dd,dt,figcaption,blockquote,small,em,strong,b,span,div){color:var(--text-ink-dim) !important;}
section[data-band] :is(
  .section-dark,.section-dark2,.cta-banner,.hero-panel,.faq-dark-section,.related-brands-section,
  .proc-cta,.cta-final,.final-cta,.industry-cta,.svc-cta,.blog-article-cta,.ab-cta,.pg-cta,.rv-cta,.con-div-card,
  [style*="background:var(--navy"],[style*="background: var(--navy"],
  [style*="background:#08"],[style*="background:#0A"],[style*="background:#0a"],
  [style*="background:#0B"],[style*="background:#0b"],[style*="background:#0D"],[style*="background:#0d"],
  [style*="background:#10"],[style*="background:#12"],
  [style*="background:linear-gradient(135deg,#0"],[style*="background:linear-gradient(135deg,#4a0"],[style*="background:linear-gradient(160deg,#0"]
) :is(h1,h2,h3,h4,h5,h6){color:var(--text-ink) !important;}

/* ---- same-element case: .cta-banner/.ab-cta/.pg-cta/.rv-cta are always used as the
   class on the <section data-band="..."> element itself (e.g. access-control and
   digital-watchdog's <section class="cta-banner" data-band="paper">, about's
   <section class="ab-cta" data-band="paper">, projects' .pg-cta, reviews' .rv-cta) —
   never as a nested div. Every "hand the contract back" rule above needs a class-
   matching element that is a DESCENDANT of section[data-band]; a node can never be a
   descendant of itself, so those rules can never match this shape, and these four
   classes' own dark background (declared unconditionally via CSS class, never seen by
   transform.py's inline-only band sniffer, so the section lands on data-band="paper"/
   "white") never got its text-contract exception. Give this shape its own compound-
   selector version. (.proc-cta/.cta-final/.final-cta/.industry-cta/.svc-cta/
   .blog-article-cta/.hero-panel/.emergency-box are never used as a section's own
   class sitewide — always a nested div — so they don't need this.) */
section[data-band]:is(.cta-banner,.ab-cta,.pg-cta,.rv-cta){
  color:var(--text-ink) !important;
}
section[data-band]:is(.cta-banner,.ab-cta,.pg-cta,.rv-cta) :is(p,li,dd,dt,figcaption,blockquote,small,em,strong,b,span,div){
  color:var(--text-ink-dim) !important;
}
section[data-band]:is(.cta-banner,.ab-cta,.pg-cta,.rv-cta) :is(h1,h2,h3,h4,h5,h6){
  color:var(--text-ink) !important;
}

/* .mss-partner-section ("A Division of Michigan Security Systems" trust strip, 20
   pages) is the same "class directly on section[data-band]" shape as the CTA family
   above, with one more wrinkle: its own linear-gradient background gets stripped
   entirely by the sitewide "bands are flat by design" safety net further down in
   this file (section[data-band]:not([style*="url("]){background-image:none!important}),
   since that gradient is declared via CSS class rather than inline and isn't a hero
   photo. With no background-image left, section[data-band="white"]'s flat
   background-color wins (higher specificity than the single .mss-partner-section
   class), so the section rendered flat white while its own child rules (.mss-pill,
   .mss-badge, .mss-partner-tag, the h3/p color rules) still assumed a dark backdrop.
   Give it a flat navy background instead of trying to keep the gradient alive — the
   .mss-pill/.mss-badge/.mss-partner-tag spans already carry their own colors
   designed for exactly this dark backdrop and don't need any further override. */
section[data-band]:is(.mss-partner-section){background-color:var(--navy) !important;}
section[data-band]:is(.mss-partner-section) :is(h1,h2,h3,h4,h5,h6){color:var(--text-ink) !important;}
section[data-band]:is(.mss-partner-section) p{color:var(--text-ink-dim) !important;}

/* .ab-stats (about page's "Years in Business / States Served / ..." stat strip) is
   the same shape again: <section class="ab-stats" data-band="paper"> with its own
   background:var(--navy) losing to section[data-band="paper"]'s flat off-white
   (higher specificity), while its own .ab-stat b/span keep their light-on-dark
   colors unchanged. Restore the real background. */
section[data-band]:is(.ab-stats){background-color:var(--navy) !important;}
/* .ab-stat b (the "25+ / 3 / 3 / 100%" big numbers) is a <b> tag, and the sitewide
   light-band rule above (section[data-band="paper"] :is(...,strong,b){color:var(
   --text-light)!important}) outranks .ab-stat b's own amber color, which needs to
   stay amber now that the strip's real navy background is restored. */
section[data-band]:is(.ab-stats) b{color:var(--accent) !important;}

/* ink bands: same contract, inverted */
section[data-band="ink"] :is(p,li,dd,dt,figcaption,blockquote,small),
section[data-band="ink2"] :is(p,li,dd,dt,figcaption,blockquote,small){color:var(--text-ink-dim) !important;}
section[data-band="ink"] :is(h1,h2,h3,h4,h5,h6),
section[data-band="ink2"] :is(h1,h2,h3,h4,h5,h6){color:var(--text-ink) !important;}
section[data-band="ink"] :is(.stat-num,.about-stat-num,.accolade-num,.s-num),
section[data-band="ink2"] :is(.stat-num,.about-stat-num,.accolade-num,.s-num){color:var(--accent) !important;}
/* light cards dropped onto an ink band keep dark text */
section[data-band="ink"] :is([style*="background:var(--white"],[style*="background:#fff"],
  [style*="background:#FFF"],[style*="background:var(--off-white"]),
section[data-band="ink2"] :is([style*="background:var(--white"],[style*="background:#fff"],
  [style*="background:#FFF"],[style*="background:var(--off-white"]){color:var(--text) !important;}
section[data-band="ink"] :is([style*="background:var(--white"],[style*="background:#fff"],
  [style*="background:#FFF"],[style*="background:var(--off-white"]) :is(p,li,span,div,small),
section[data-band="ink2"] :is([style*="background:var(--white"],[style*="background:#fff"],
  [style*="background:#FFF"],[style*="background:var(--off-white"]) :is(p,li,span,div,small){
  color:var(--text-light) !important;
}
/* same specificity trap as the why-choose-us navy-td fix above: section 25/26's later
   :not([style*="background:"]) guard on the plain [style*="color:var(--text-light)"]
   rule reaches (0,3,1), edging past this rule's (0,2,2) and re-breaking a light-card-
   in-ink-band <p> that hardcodes inline color:var(--text-light) (e.g. why-choose-us's
   "Tell us about your business..." lead-form paragraph). Duplicate an attribute here
   too so this stays the unconditional winner. */
section[data-band="ink"] :is([style*="background:var(--white"],[style*="background:#fff"],
  [style*="background:#FFF"],[style*="background:var(--off-white"]) [style*="color:var(--text-light)"][style*="color:var(--text-light)"],
section[data-band="ink2"] :is([style*="background:var(--white"],[style*="background:#fff"],
  [style*="background:#FFF"],[style*="background:var(--off-white"]) [style*="color:var(--text-light)"][style*="color:var(--text-light)"]{
  color:var(--text-light) !important;
}

/* --------------------------------------------------------------------------
   23. TOKEN CONTRACT PER BAND
   The legacy sheets re-point --text / --text-light per container. Bands now own
   those tokens; genuinely dark boxes nested inside still declare their own and
   a direct declaration always beats an inherited one.
   -------------------------------------------------------------------------- */
section[data-band="paper"],section[data-band="white"],
section[data-band="paper"] > *,section[data-band="white"] > *{
  --text:#12202E !important;
  --text-light:#3D4A5D !important;
  --white:#FFFFFF !important;
  --off-white:#F4F1EA !important;
}
section[data-band="ink"],section[data-band="ink2"],
section[data-band="ink"] > *,section[data-band="ink2"] > *{
  --text:#FBF8F3 !important;
  --text-light:rgba(251,248,243,.90) !important;
}

/* literal light colours that legacy markup hard-codes for a dark ground */
section[data-band="paper"] :is(.bcp-name,.bn,.bs,.office-card-label,.office-card-value,
  .office-card-sub,.mss-brand-text-main,.mss-brand-text-sub,.brands-strip-title,.cd2-label,
  .cd2-val,.csl-detail-label,.csl-detail-val,.rc-label,.rc-sub,.a-loc,.proj-addr,.natlead,
  .brand-pill-name,.brand-pill-sub,.pill-text,.pill-sub,.hq-label,.hq-value,.trust-item,
  .clb-hdr p,.gr-reviewer-name,.googrev-name,.rv-card-author,.rv-disclaimer,.legal-meta),
section[data-band="white"] :is(.bcp-name,.bn,.bs,.office-card-label,.office-card-value,
  .office-card-sub,.mss-brand-text-main,.mss-brand-text-sub,.brands-strip-title,.cd2-label,
  .cd2-val,.csl-detail-label,.csl-detail-val,.rc-label,.rc-sub,.a-loc,.proj-addr,.natlead,
  .brand-pill-name,.brand-pill-sub,.pill-text,.pill-sub,.hq-label,.hq-value,.trust-item,
  .clb-hdr p,.gr-reviewer-name,.googrev-name,.rv-card-author,.rv-disclaimer,.legal-meta){
  color:var(--text-light) !important;
}
section[data-band="paper"] :is(.bcp-name,.bn,.office-card-value,.mss-brand-text-main,
  .cd2-val,.csl-detail-val,.brand-pill-name,.gr-reviewer-name,.googrev-name,.hq-value),
section[data-band="white"] :is(.bcp-name,.bn,.office-card-value,.mss-brand-text-main,
  .cd2-val,.csl-detail-val,.brand-pill-name,.gr-reviewer-name,.googrev-name,.hq-value){
  color:var(--text) !important;font-weight:600;
}

/* links stay legible on every ground. The :not([style*="background:"]) guard
   excludes a classless anchor that already paints its OWN opaque background
   inline (e.g. the "Write a Review"/"Leave Us a Review" mini-buttons, which
   set color:white + background:var(--blue) together) — without it this rule
   forced those buttons' text to the same blue as their own background,
   making them invisible. Plain inline text links have no such background
   and are unaffected. The same :not([style*="background:"]) guard is needed
   on the p a/li a variants too: a data-band="paper" section can still
   contain a nested dark card/panel (e.g. .svc-contact-info, .ibox) whose own
   <p>/<li> text links carry an inline rgba(255,255,255,.NN) color meant to
   be legible on that panel's dark background — without the guard this rule
   overrode them all to the light-ground blue, invisible on the dark panel. */
section[data-band="paper"] a:not([class]):not([style*="background:"]):not([style*="color:rgba(255,255,255"]),
section[data-band="white"] a:not([class]):not([style*="background:"]):not([style*="color:rgba(255,255,255"]),
section[data-band="paper"] p a:not([style*="background:"]):not([style*="color:rgba(255,255,255"]),
section[data-band="white"] p a:not([style*="background:"]):not([style*="color:rgba(255,255,255"]),
section[data-band="paper"] li a:not([style*="background:"]):not([style*="color:rgba(255,255,255"]),
section[data-band="white"] li a:not([style*="background:"]):not([style*="color:rgba(255,255,255"]){
  color:var(--blue) !important;text-decoration:underline;text-underline-offset:3px;
  text-decoration-thickness:1px;text-decoration-color:rgba(31,91,146,.4);
}
section[data-band="paper"] :is(p,li) a:hover,section[data-band="white"] :is(p,li) a:hover{
  color:var(--brass-ink) !important;text-decoration-color:var(--accent);
}
section[data-band="ink"] :is(p,li) a,section[data-band="ink2"] :is(p,li) a{
  color:var(--accent2) !important;text-decoration:underline;text-underline-offset:3px;
  text-decoration-color:rgba(240,192,120,.45);
}
/* the top utility strip is always ink, whatever markup it uses */
[data-mss-slim] :is(span,a,div,strong,b){color:rgba(251,248,243,.62) !important;}
[data-mss-slim] a[href^="tel"],[data-mss-slim] a[href^="mailto"]{color:var(--accent) !important;}
[data-mss-slim] span > a{color:inherit !important;}

/* --------------------------------------------------------------------------
   24. TOKEN CONTRACT — full depth, with dark islands honoured
   -------------------------------------------------------------------------- */
section[data-band="paper"] *,section[data-band="white"] *{
  --text:#12202E !important;--text-light:#3D4A5D !important;
}
section[data-band="ink"] *,section[data-band="ink2"] *{
  --text:#FBF8F3 !important;--text-light:rgba(251,248,243,.90) !important;
}
/* dark islands inside a light band keep light tokens (higher specificity wins) */
section[data-band] :is(.section-dark,.section-dark2,.cta-banner,.hero-panel,.faq-dark-section,
  .related-brands-section,.proc-cta,.cta-final,.final-cta,.industry-cta,.svc-cta,.blog-article-cta,
  .ab-cta,.pg-cta,.rv-cta,.con-div-card,
  [style*="background:var(--navy"],[style*="background: var(--navy"],[style*="background:var(--blue"],
  [style*="background:#08"],[style*="background:#0A"],[style*="background:#0a"],[style*="background:#0B"],
  [style*="background:#0b"],[style*="background:#0D"],[style*="background:#0d"],[style*="background:#10"],
  [style*="background:#12"],[style*="background:#11"],[style*="background:linear-gradient(135deg,#0"],[style*="background:linear-gradient(135deg,#4a0"],
  [style*="background:linear-gradient(160deg,#0"]),
section[data-band] :is(.section-dark,.section-dark2,.cta-banner,.hero-panel,.faq-dark-section,
  .related-brands-section,.proc-cta,.cta-final,.final-cta,.industry-cta,.svc-cta,.blog-article-cta,
  .ab-cta,.pg-cta,.rv-cta,.con-div-card,
  [style*="background:var(--navy"],[style*="background: var(--navy"],[style*="background:var(--blue"],
  [style*="background:#08"],[style*="background:#0A"],[style*="background:#0a"],[style*="background:#0B"],
  [style*="background:#0b"],[style*="background:#0D"],[style*="background:#0d"],[style*="background:#10"],
  [style*="background:#12"],[style*="background:#11"],[style*="background:linear-gradient(135deg,#0"],[style*="background:linear-gradient(135deg,#4a0"],
  [style*="background:linear-gradient(160deg,#0"]) *{
  --text:#FBF8F3 !important;--text-light:rgba(251,248,243,.90) !important;
}
section[data-band] :is(.section-dark,.cta-banner,.faq-dark-section,.related-brands-section,
  .proc-cta,.cta-final,.final-cta,.industry-cta,.svc-cta,.blog-article-cta,.ab-cta,.pg-cta,.rv-cta,.con-div-card,
  [style*="background:var(--navy"],[style*="background:var(--blue"],[style*="background:#08"],
  [style*="background:#0A"],[style*="background:#0a"],[style*="background:#0B"],[style*="background:#0b"],
  [style*="background:#0D"],[style*="background:#0d"],[style*="background:#10"],[style*="background:#11"],
  [style*="background:#12"]) :is(p,li,span,div,small,strong,em,td,th,label,a:not([class]):not([style*="background:"])){
  color:var(--text-light) !important;
}
/* the a:not([class]):not([style*="background:"]) guard above matters here too: a
   self-contained button link (its own inline background + a color already chosen to match
   it, e.g. the "Build my free security plan" amber CTA reused across several service pages)
   isn't a plain in-body link and shouldn't be repainted var(--text-light) just because it
   happens to be classless inside a dark callout box -- that forced the poisoned light
   dark-island text color onto a button that is locally amber, not navy, cutting contrast to
   as low as 1.91:1 instead of the button's own intended near-black #081829. */
section[data-band] :is(.section-dark,.cta-banner,.faq-dark-section,.related-brands-section,
  .proc-cta,.cta-final,.final-cta,.industry-cta,.svc-cta,.blog-article-cta,.ab-cta,.pg-cta,.rv-cta,.con-div-card,
  [style*="background:var(--navy"],[style*="background:var(--blue"],[style*="background:#08"],
  [style*="background:#0A"],[style*="background:#0a"],[style*="background:#0B"],[style*="background:#0b"],
  [style*="background:#0D"],[style*="background:#0d"],[style*="background:#10"],[style*="background:#11"],
  [style*="background:#12"]) :is(h1,h2,h3,h4,h5,h6,.a-tag,.s-tag,.stag,.section-tag,.eyebrow){
  color:var(--text-ink) !important;
}

/* "honest note" amber-tint callout boxes (alarm-monitoring, gate-perimeter-access,
   video-intercom, wireless-networks, vape-detection-systems) are a light #FFF8E8 box
   with an inline color:var(--text) <p>, sometimes nested inside a genuinely dark
   section[data-band="ink"]. The ink-band blanket "section[data-band='ink'] *{--text:...}"
   rule above reassigns --text to a light value for every descendant regardless, so the
   inline color:var(--text) on this p resolved to near-white on its own light box —
   same "flat light box not detected inside a dark section" bug family as the other
   lightbox patterns, just a color transform.py's inline-only sniffer never learned. */
section[data-band="ink"] [style*="background:#FFF8E8"],
section[data-band="ink2"] [style*="background:#FFF8E8"],
section[data-band="ink"] [style*="background:#FFF8E8"] *,
section[data-band="ink2"] [style*="background:#FFF8E8"] *{
  --text:#12202E !important;--text-light:#3D4A5D !important;
}
/* the custom-property reset above only works if the "honest note" <p>'s own inline
   color:var(--text) is actually left to resolve that variable — but section 25/26's
   later "self-contained button" guard rules (section[data-band="ink"]
   [style*="color:var(--navy)/--text/--text-light"]:not([style*="background:"])) hard-
   code a literal !important color instead of going through the variable, and their
   extra :not() bumps them to a higher specificity than a plain descendant selector,
   so they win over this box's reset and force the inline text light again. Reassert
   the correct literal color here, scoped to inside the box, at higher specificity
   still so it wins regardless of what those later rules add. */
section[data-band="ink"] [style*="background:#FFF8E8"] [style*="color:var(--navy)"]:not([style*="background:"]),
section[data-band="ink2"] [style*="background:#FFF8E8"] [style*="color:var(--navy)"]:not([style*="background:"]),
section[data-band="ink"] [style*="background:#FFF8E8"] [style*="color:var(--text)"]:not([style*="background:"]),
section[data-band="ink2"] [style*="background:#FFF8E8"] [style*="color:var(--text)"]:not([style*="background:"]){
  color:#12202E !important;
}
section[data-band="ink"] [style*="background:#FFF8E8"] [style*="color:var(--text-light)"]:not([style*="background:"]),
section[data-band="ink2"] [style*="background:#FFF8E8"] [style*="color:var(--text-light)"]:not([style*="background:"]){
  color:#3D4A5D !important;
}

/* --------------------------------------------------------------------------
   25. CARD TEXT CONTRACT — cards are white unless they sit on an ink band
   -------------------------------------------------------------------------- */
:is(.service-card,.industry-card,.blog-card,.proj-card,.project-card,.a-card,.feature-card,
.mfr-detail-card,.brands-cat-card,.ind-hub-card,.svc-hub-card,.pt-card,.eq-card,.camtype-card,
.product-card,.con-why-card,.con-aud-card,.ab-card,.rv-card,.gr-card,.googrev-card,.proc-card,
.dw-feature-card,.backlink-card,.cpro-card,.hiw-card,.ct-office,.office-card-new,.ct-faq-card,
.con-faq-card,.stat-box,.cd2,.mss-brand-card,.brand-chip-pill,.brand-pill,.why-pdk-card,
.why-ai-card,.why-ax-card,.why-hw-card,.why-hik-card,.why-bog-card,.why-cdvi-card,
.industry-detail-card,.mfr-card-body,.bsc,.eq-card-head){
  --text:#12202E !important;--text-light:#3D4A5D !important;
}
:is(.service-card,.industry-card,.blog-card,.proj-card,.project-card,.a-card,.feature-card,
.mfr-detail-card,.brands-cat-card,.ind-hub-card,.svc-hub-card,.pt-card,.eq-card,.camtype-card,
.product-card,.con-why-card,.con-aud-card,.ab-card,.rv-card,.gr-card,.googrev-card,.proc-card,
.dw-feature-card,.backlink-card,.cpro-card,.hiw-card,.ct-office,.office-card-new,.ct-faq-card,
.con-faq-card,.stat-box,.cd2,.mss-brand-card,.brand-chip-pill,.brand-pill,.why-pdk-card,
.why-ai-card,.why-ax-card,.why-hw-card,.why-hik-card,.why-bog-card,.why-cdvi-card,
.industry-detail-card,.bsc) :is(div:not([style*="background:"]):not(.hiw-num),span:not([style*="background:"]):not(.hiw-num),p,li,small,strong,em,h3,h4,h5,a:not([class])){
  color:var(--text-light) !important;
}
/* .hiw-num (the numbered circle badge in the "How We Install"/process 4-step
   component, 33 pages) is a plain <div class="hiw-num"> with NO inline
   style="background:..." attribute -- its navy circle + accent-gold numeral
   both come from its own CSS class rule (background:var(--navy);
   color:var(--accent), set in each page's own local <style>). The CARD TEXT
   CONTRACT rule above only excludes a div/span from its dark-text override
   when the background lives on an inline style attribute, so a
   class-styled dark badge like this one slipped through and got its gold
   numeral repainted var(--text-light) (a dark navy-gray meant for body copy
   on a white card) -- a low-contrast dark-on-dark numeral, exactly Mike's
   "the numbers and stuff is hard to read" report on /alarm-systems/. Same
   recurring bug family as the v122 city-ticker/family-strip notes: a
   dark/light island painted via a CSS CLASS, not an inline style, is
   invisible to a guard that only checks inline style. Excluded .hiw-num by
   name instead of broadening the inline-style guard, since it's the only
   badge of this shape reused inside the affected card-family list. */
:is(.mss-brand-card,.backlink-card,.brand-chip-pill,.brand-pill,.cd2,.ct-office,.office-card-new,.bsc)
  :is(.mss-brand-text-main,.backlink-text-main,.bcp-name,.brand-pill-name,.cd2-val,.bn,.n,
      .office-card-value,.bsc-name,.csl-detail-val){
  color:var(--text) !important;font-weight:600;
}
/* .project-card has a second life on access-control (and any other page reusing
   this "recent projects" gallery markup): a photo card with a dark gradient scrim
   (.project-overlay) caption, not the standard plain-white card the CARD TEXT
   CONTRACT above assumes for every .project-card. Give its .project-tag/.project-
   title caption text back its original light-on-dark-photo colors, beating the
   contract's :is(LIST) :is(div,span,...) rule with one more class level. */
.project-card .project-overlay .project-tag{color:var(--accent) !important;}
.project-card .project-overlay .project-title{color:#fff !important;}
/* on ink bands those same cards go translucent and take light text back */
section[data-band="ink"] :is(.service-card,.industry-card,.feature-card,.proc-card,.camtype-card,
.eq-card,.blog-card,.a-card,.pt-card,.product-card,.ind-hub-card,.svc-hub-card,.mss-brand-card,
.backlink-card,.brand-chip-pill,.brand-pill,.cd2,.stat-box,.hiw-card,.con-why-card),
section[data-band="ink2"] :is(.service-card,.industry-card,.feature-card,.proc-card,.camtype-card,
.eq-card,.blog-card,.a-card,.pt-card,.product-card,.ind-hub-card,.svc-hub-card,.mss-brand-card,
.backlink-card,.brand-chip-pill,.brand-pill,.cd2,.stat-box,.hiw-card,.con-why-card){
  --text:#FBF8F3 !important;--text-light:rgba(251,248,243,.90) !important;
  background-color:rgba(255,255,255,.035) !important;border-color:rgba(255,255,255,.13) !important;
}
/* the .why-*-card family (manufacturer-page "Why choose us" feature cards) plus
   every other CARDS-section class (§9) that was deliberately left OUT of the
   translucent-flip list above — .proj-card/.project-card, .mfr-detail-card,
   .brands-cat-card, .con-aud-card, .ab-card, .rv-card, .gr-card/.googrev-card
   ("GR Benefit Cards" on manufacturer pages), .dw-feature-card, .cpro-card,
   .ct-office/.office-card-new, .ct-faq-card/.con-faq-card, .bc-body,
   .industry-detail-card — all stay a solid white box (CARDS section,
   unconditional background:var(--white)) even on an ink-band section, by
   design. But the TOKEN CONTRACT rule
   (section[data-band="ink"] *{--text-light:rgba(...,.90)!important}) has
   specificity (0,1,1) — a type+attribute selector — which beats a bare-class
   :is(.why-cdvi-card,...) selector at (0,1,0) regardless of source order, so
   these cards' own local dark tokens (set earlier in the CARD TEXT CONTRACT)
   were losing and their h4/p text rendered near-white on their own white
   background (confirmed on /brivo-access-control/'s "GR Benefit Cards" grid,
   same bug as .why-cdvi-card). Re-assert the dark local tokens with
   section[data-band]-matching specificity so they win inside ink bands too. */
section[data-band="ink"] :is(.why-pdk-card,.why-ai-card,.why-ax-card,.why-hw-card,
.why-hik-card,.why-bog-card,.why-cdvi-card,.proj-card,.project-card,.mfr-detail-card,
.brands-cat-card,.con-aud-card,.ab-card,.rv-card,.gr-card,.googrev-card,.dw-feature-card,
.cpro-card,.ct-office,.office-card-new,.ct-faq-card,.con-faq-card,.bc-body,
.industry-detail-card),
section[data-band="ink2"] :is(.why-pdk-card,.why-ai-card,.why-ax-card,.why-hw-card,
.why-hik-card,.why-bog-card,.why-cdvi-card,.proj-card,.project-card,.mfr-detail-card,
.brands-cat-card,.con-aud-card,.ab-card,.rv-card,.gr-card,.googrev-card,.dw-feature-card,
.cpro-card,.ct-office,.office-card-new,.ct-faq-card,.con-faq-card,.bc-body,
.industry-detail-card){
  --text:#12202E !important;--text-light:#3D4A5D !important;
}
/* the fix above only re-asserts the tokens on the CARD element itself — but
   custom properties are resolved per-element against every rule that matches
   THAT element, not by inheriting from the nearest ancestor that "meant" to
   set them: the TOKEN CONTRACT's section[data-band="ink"] * ALSO matches every
   descendant of the card directly (h4, p, etc. all match the universal
   selector), so those descendants were getting --text/--text-light set to the
   light ink-band value on themselves and never fell through to inherit the
   card's dark value at all. Re-assert on every descendant too. */
section[data-band="ink"] :is(.why-pdk-card,.why-ai-card,.why-ax-card,.why-hw-card,
.why-hik-card,.why-bog-card,.why-cdvi-card,.proj-card,.project-card,.mfr-detail-card,
.brands-cat-card,.con-aud-card,.ab-card,.rv-card,.gr-card,.googrev-card,.dw-feature-card,
.cpro-card,.ct-office,.office-card-new,.ct-faq-card,.con-faq-card,.bc-body,
.industry-detail-card) *,
section[data-band="ink2"] :is(.why-pdk-card,.why-ai-card,.why-ax-card,.why-hw-card,
.why-hik-card,.why-bog-card,.why-cdvi-card,.proj-card,.project-card,.mfr-detail-card,
.brands-cat-card,.con-aud-card,.ab-card,.rv-card,.gr-card,.googrev-card,.dw-feature-card,
.cpro-card,.ct-office,.office-card-new,.ct-faq-card,.con-faq-card,.bc-body,
.industry-detail-card) *{
  --text:#12202E !important;--text-light:#3D4A5D !important;
}
section[data-band="ink"] :is(.service-card,.industry-card,.feature-card,.proc-card,.camtype-card,
.eq-card,.blog-card,.a-card,.mss-brand-card,.backlink-card,.brand-chip-pill,.cd2,.stat-box)
  :is(div,span,p,li,small,strong,em,h3,h4,h5),
section[data-band="ink2"] :is(.service-card,.industry-card,.feature-card,.proc-card,.camtype-card,
.eq-card,.blog-card,.a-card,.mss-brand-card,.backlink-card,.brand-chip-pill,.cd2,.stat-box)
  :is(div,span,p,li,small,strong,em,h3,h4,h5){color:var(--text-ink-dim) !important;}
/* .brands-cat-body (/alarm-systems/ only) is a plain <div> with its own
   inline-style dark navy background wrapped around a grid of .brand-pill
   cards — it isn't a section[data-band="ink"], so the shared card system
   above never knew to flip these cards to their translucent dark-ground
   treatment, leaving them with their light-card off-white background (which
   never actually painted here — see below) and dark navy text sitting
   directly on the dark wrapper: invisible. Same translucent-card fix as the
   ink-band rule above, targeted at this one wrapper. */
.brands-cat-body .brand-pill{
  --text:#FBF8F3 !important;--text-light:rgba(251,248,243,.90) !important;
  background-color:rgba(255,255,255,.06) !important;border-color:rgba(255,255,255,.16) !important;
}
.brands-cat-body .brand-pill :is(div,span,p,li,small,strong,em,h3,h4,h5){color:var(--text-ink-dim) !important;}
.brands-cat-body .brand-pill .brand-pill-text .brand-pill-name{color:rgba(251,248,243,.96) !important;}
.brands-cat-body .brand-pill .brand-pill-text .brand-pill-sub{color:rgba(251,248,243,.7) !important;}

/* Several pages hardcode inline light-band text colors (color:var(--navy),
   color:var(--text), color:var(--text-light)) directly on table cells and other
   plain elements (e.g. the why-choose-us comparison table's <td style="...
   color:var(--navy)">) with no wrapping class for transform.py's per-page dark-
   band fixups to key off of. Where that element ends up inside a genuinely dark
   section[data-band="ink"/"ink2"], the hardcoded dark inline color stays dark-on-
   dark. A handful of per-page <style> blocks already neutralize this ad hoc for
   the classes they happened to cover; this is the same fix as a sitewide safety
   net so it doesn't have to be re-added page by page. */
section[data-band="ink"] [style*="color:var(--navy)"]:not([style*="background:"]),
section[data-band="ink2"] [style*="color:var(--navy)"]:not([style*="background:"]){color:var(--text-ink) !important;}
section[data-band="ink"] [style*="color:var(--text-light)"]:not([style*="background:"]),
section[data-band="ink2"] [style*="color:var(--text-light)"]:not([style*="background:"]){color:var(--text-ink-dim) !important;}
section[data-band="ink"] [style*="color:var(--text)"]:not([style*="background:"]),
section[data-band="ink2"] [style*="color:var(--text)"]:not([style*="background:"]){color:var(--text-ink) !important;}
/* same problem again, but for the "always dark, never gets a data-band" hero group
   (.hero, .pg-hero, .ab-hero, .rv-hero, .ct-hero, .con-hero, .cpro-hero, .legal-hero,
   .blog-hero, .page-hero — see the section-27 comment on this file's stars exception
   for why these never carry data-band). A page-local hero paragraph/link can still
   hardcode a light-band inline color (var(--navy), var(--text), var(--text-light),
   var(--blue)) the same way a table cell can, e.g. a city page's "Part of our
   <a>Livingston County</a> service area." line under the H1 — and since there's no
   data-band to key off of, the rules just above never catch it. */
:is(.hero,.pg-hero,.ab-hero,.rv-hero,.ct-hero,.con-hero,.cpro-hero,.legal-hero,.blog-hero,.page-hero)
  [style*="color:var(--navy)"]:not([style*="background:"]),
:is(.hero,.pg-hero,.ab-hero,.rv-hero,.ct-hero,.con-hero,.cpro-hero,.legal-hero,.blog-hero,.page-hero)
  [style*="color:var(--text)"]:not([style*="color:var(--text-light)"]):not([style*="background:"]){
  color:var(--text-ink) !important;
}
:is(.hero,.pg-hero,.ab-hero,.rv-hero,.ct-hero,.con-hero,.cpro-hero,.legal-hero,.blog-hero,.page-hero)
  [style*="color:var(--text-light)"]:not([style*="background:"]){
  color:var(--text-ink-dim) !important;
}
:is(.hero,.pg-hero,.ab-hero,.rv-hero,.ct-hero,.con-hero,.cpro-hero,.legal-hero,.blog-hero,.page-hero)
  [style*="color:var(--blue)"]:not([style*="background:"]){
  color:var(--accent2) !important;
}

/* --------------------------------------------------------------------------
   26. LINKS, STARS AND STRAY LITERALS
   -------------------------------------------------------------------------- */
section[data-band="paper"] a,section[data-band="white"] a{color:var(--blue);}
/* .vp-chip (vape-detection-systems "Where We Install Them" / related-links pills) is a
   genuinely dark navy chip (background:#12294a) with color:#fff baked into its own
   class rule, but the light-band default link color above has higher specificity
   (attribute+type beats a single class) and overrides it to --blue, a medium blue that
   fails against the chip's own dark background. Give it back its white text. */
section[data-band="paper"] a.vp-chip,section[data-band="white"] a.vp-chip{color:#fff !important;}
/* .mss-visit-btn/.mss-phone-link (the .mss-partner-section trust strip's "Visit
   Michigan Security Systems" button and phone link, 20 pages) are the same shape:
   their own class rules are light-on-navy by design, but the plain light-band
   anchor-color rule above outranks a single class and repaints them --blue,
   which fails against the strip's actual dark background (see .mss-partner-section
   fix above). */
section[data-band="paper"] a.mss-visit-btn,section[data-band="white"] a.mss-visit-btn{color:var(--accent) !important;}
section[data-band="paper"] a.mss-phone-link,section[data-band="white"] a.mss-phone-link{color:rgba(255,255,255,.72) !important;}
/* :not([style*="background:"]) — an anchor that paints its own inline
   background (a self-contained button like "Read the Case Study →", dark
   background + white text) isn't a plain in-body link and shouldn't be
   force-recolored blue just because its inline color happens to start with
   "#" — that was making several button labels the same blue as, or close
   to, their own dark background. */
section[data-band="paper"] a[style*="color:#"]:not([style*="background:"]),
section[data-band="white"] a[style*="color:#"]:not([style*="background:"]){color:var(--blue) !important;}
/* ...except inside a genuine dark island (e.g. contractors' .con-div-card list of inline
   color:#fff links): there's also a section[data-band] li a:not([style*="background:"]):not(
   [style*="color:rgba(255,255,255"]) rule (its :not() guard only recognizes the
   rgba(255,255,255,..) light-color format, not this hex color:#fff shape) that reaches
   (0,3,3) specificity -- higher than either the hex-fixup rule above or a plain
   ":is(...) a[style*=\"color:#\"]" fix at (0,3,2), so both lose to it regardless of source
   order. Repeat the attribute selector to clear (0,3,3) decisively rather than widen that
   shared rule's :not() guard (widening it once regressed the unrelated .contact-split-left
   dark panel, whose <a> elements have no inline hex color to guard against and so gained
   specificity they didn't need). */
section[data-band] :is(.section-dark,.section-dark2,.cta-banner,.hero-panel,.faq-dark-section,
  .related-brands-section,.emergency-box,.proc-cta,.cta-final,.final-cta,.industry-cta,.svc-cta,
  .blog-article-cta,.ab-cta,.pg-cta,.rv-cta,.con-div-card,
  [style*="background:var(--navy"],[style*="background: var(--navy"],
  [style*="background:#08"],[style*="background:#0A"],[style*="background:#0a"],
  [style*="background:#0B"],[style*="background:#0b"],[style*="background:#0D"],[style*="background:#0d"],
  [style*="background:#10"],[style*="background:#12"],
  [style*="background:linear-gradient(135deg,#0"],[style*="background:linear-gradient(135deg,#4a0"],[style*="background:linear-gradient(160deg,#0"]
) a[style*="color:#"][style*="color:#"]:not([style*="background:"]){color:var(--text-light) !important;}
:is(.stars,.rv-card-stars,.gr-card-stars,.googrev-stars,.rv-sum-stars,.googrev-card-stars,
.bcp-star,.a-dot,.pdot){color:var(--brass-ink) !important;}
section[data-band="ink"] :is(.stars,.rv-card-stars,.gr-card-stars,.googrev-stars,.rv-sum-stars,
.googrev-card-stars,.bcp-star),
section[data-band="ink2"] :is(.stars,.rv-card-stars,.gr-card-stars,.googrev-stars,.rv-sum-stars,
.googrev-card-stars,.bcp-star),footer :is(.stars,.rv-card-stars){color:var(--accent) !important;}
/* hero sections (.rv-hero, .ct-hero, .pg-hero, .ab-hero, .blog-hero, .con-hero,
   .legal-hero, .page-hero, .hero, .cpro-hero) never get a data-band attribute at
   all — they carry their own dark gradient/photo background via CSS class instead,
   by design, so the section[data-band="ink"] exception above never fires for stars
   inside one (e.g. reviews' .rv-summary "4.9 / rv-sum-stars" hero widget). They are
   always dark, same as an ink band, so give stars the same exception here. */
:is(.rv-hero,.ct-hero,.pg-hero,.ab-hero,.blog-hero,.con-hero,.legal-hero,.page-hero,.hero,.cpro-hero)
  :is(.stars,.rv-card-stars,.gr-card-stars,.googrev-stars,.rv-sum-stars,.googrev-card-stars,.bcp-star){
  color:var(--accent) !important;
}
/* same dark-hero gap for the breadcrumb trail: .breadcrumb a is styled var(--text-light)
   (a dark gray-blue) sitewide for its normal home on a paper/white section, but the
   blog/case-studies/industries hub pages plant the breadcrumb inside one of these
   always-dark hero divs instead, which never gets a data-band. Give it the same light
   exception, with the file's usual duplicated-class specificity bump so it reliably
   beats the plain ".breadcrumb a" rule regardless of source order. */
:is(.rv-hero,.ct-hero,.pg-hero,.ab-hero,.blog-hero,.con-hero,.legal-hero,.page-hero,.hero,.cpro-hero)
  .breadcrumb.breadcrumb,
:is(.rv-hero,.ct-hero,.pg-hero,.ab-hero,.blog-hero,.con-hero,.legal-hero,.page-hero,.hero,.cpro-hero)
  .breadcrumb-nav.breadcrumb-nav,
:is(.rv-hero,.ct-hero,.pg-hero,.ab-hero,.blog-hero,.con-hero,.legal-hero,.page-hero,.hero,.cpro-hero)
  .breadcrumb.breadcrumb a,
:is(.rv-hero,.ct-hero,.pg-hero,.ab-hero,.blog-hero,.con-hero,.legal-hero,.page-hero,.hero,.cpro-hero)
  .breadcrumb-nav.breadcrumb-nav a{
  color:rgba(251,248,243,.7) !important;
}
:is(.rv-hero,.ct-hero,.pg-hero,.ab-hero,.blog-hero,.con-hero,.legal-hero,.page-hero,.hero,.cpro-hero)
  .breadcrumb.breadcrumb a:hover,
:is(.rv-hero,.ct-hero,.pg-hero,.ab-hero,.blog-hero,.con-hero,.legal-hero,.page-hero,.hero,.cpro-hero)
  .breadcrumb-nav.breadcrumb-nav a:hover{
  color:var(--accent) !important;
}

/* --------------------------------------------------------------------------
   27. REMAINING COMPONENT CONTRACTS
   -------------------------------------------------------------------------- */
/* tags / chips sitting inside dark islands */
section[data-band] :is([style*="background:var(--navy"],[style*="background:#0"],
  [style*="background:#1"],.section-dark,.hero-panel) :is(.a-tag,.s-tag,.stag,.a-chip,.chip,
  .brand-chip,.city-tag,.tag,.proj-badge,.a-loc,.city-ticker-label,.btn-label){
  color:var(--accent) !important;border-color:rgba(255,255,255,.2) !important;
}
.brand-chip,.chip{color:var(--text-light) !important;}
section[data-band="ink"] :is(.brand-chip,.chip),
section[data-band="ink2"] :is(.brand-chip,.chip),
footer :is(.brand-chip,.chip){color:rgba(251,248,243,.7) !important;}
/* .city-ticker-label dropped from the lists above — it now has its own
   dedicated brass-ink eyebrow style (§10b), which these later same-
   specificity !important rules would otherwise win by source order. */

/* light surfaces dropped on an ink band take dark text back */
section[data-band="ink"] :is(table,thead,tbody,tr),
section[data-band="ink2"] :is(table,thead,tbody,tr){--text:#12202E !important;--text-light:#3D4A5D !important;}
section[data-band="ink"] :is(td,caption),section[data-band="ink2"] :is(td,caption){color:var(--text-light) !important;}
section[data-band="ink"] :is(td,caption) :is(strong,b,em,span,a),
section[data-band="ink2"] :is(td,caption) :is(strong,b,em,span,a){color:inherit !important;}
section[data-band="ink"] th,section[data-band="ink2"] th{color:var(--text-ink) !important;}
section[data-band="ink"] :is([style*="background:#fff"],[style*="background:#FFF"],
  [style*="background:var(--white"],[style*="background:var(--off-white"],[style*="background:#F"],
  [style*="background:#f"],.contact-form-box,.contact-form-card,.ct-form-panel,.lead-form-wrap),
section[data-band="ink2"] :is([style*="background:#fff"],[style*="background:#FFF"],
  [style*="background:var(--white"],[style*="background:var(--off-white"],[style*="background:#F"],
  [style*="background:#f"],.contact-form-box,.contact-form-card,.ct-form-panel,.lead-form-wrap){
  --text:#12202E !important;--text-light:#3D4A5D !important;color:var(--text) !important;
}
/* the descendant color rules just below rely on var(--text)/var(--text-light) resolving
   dark, but each of those custom properties is set again, directly, by the TOKEN CONTRACT's
   section[data-band="ink"] * rule further down this file -- and a direct match always beats
   inheriting the (correctly reset) value from this card's own element above. Reset the
   properties on every descendant too, not just the card itself. */
section[data-band="ink"] :is([style*="background:#fff"],[style*="background:var(--white"],
  [style*="background:var(--off-white"],.contact-form-box,.contact-form-card,.ct-form-panel,.lead-form-wrap) *,
section[data-band="ink2"] :is([style*="background:#fff"],[style*="background:var(--white"],
  [style*="background:var(--off-white"],.contact-form-box,.contact-form-card,.ct-form-panel,.lead-form-wrap) *{
  --text:#12202E !important;--text-light:#3D4A5D !important;
}
/* ...except a <thead> nested inside one of these cards (why-choose-us's comparison-table
   wrapper div): that thead row carries its own genuine navy background (inline
   background:var(--navy)) and is a real dark island, not part of the light card. Put its
   light tokens back so its own color:var(--text-ink)/var(--text-light) rules render light
   text on that navy row instead of the light-card's dark text. */
section[data-band="ink"] :is([style*="background:#fff"],[style*="background:var(--white"],
  [style*="background:var(--off-white"],.contact-form-box,.contact-form-card,.ct-form-panel,.lead-form-wrap) thead,
section[data-band="ink2"] :is([style*="background:#fff"],[style*="background:var(--white"],
  [style*="background:var(--off-white"],.contact-form-box,.contact-form-card,.ct-form-panel,.lead-form-wrap) thead,
section[data-band="ink"] :is([style*="background:#fff"],[style*="background:var(--white"],
  [style*="background:var(--off-white"],.contact-form-box,.contact-form-card,.ct-form-panel,.lead-form-wrap) thead *,
section[data-band="ink2"] :is([style*="background:#fff"],[style*="background:var(--white"],
  [style*="background:var(--off-white"],.contact-form-box,.contact-form-card,.ct-form-panel,.lead-form-wrap) thead *{
  --text:#FBF8F3 !important;--text-light:rgba(251,248,243,.90) !important;
}
section[data-band="ink"] :is([style*="background:#fff"],[style*="background:var(--white"],
  [style*="background:var(--off-white"],.contact-form-box,.contact-form-card,.ct-form-panel,.lead-form-wrap)
  :is(p,li,span,div,small,strong,em,h1,h2,h3,h4,a,label),
section[data-band="ink2"] :is([style*="background:#fff"],[style*="background:var(--white"],
  [style*="background:var(--off-white"],.contact-form-box,.contact-form-card,.ct-form-panel,.lead-form-wrap)
  :is(p,li,span,div,small,strong,em,h1,h2,h3,h4,a,label){
  color:var(--text-light) !important;
}
section[data-band="ink"] :is([style*="background:#fff"],[style*="background:var(--white"],
  .contact-form-box,.contact-form-card,.ct-form-panel,.lead-form-wrap) :is(h1,h2,h3,h4),
section[data-band="ink2"] :is([style*="background:#fff"],[style*="background:var(--white"],
  .contact-form-box,.contact-form-card,.ct-form-panel,.lead-form-wrap) :is(h1,h2,h3,h4){
  color:var(--text) !important;
}
/* solid-fill CTAs always carry their own contrast */
.product-cta,.btn-blue,.cta-btn,.rc-btn.filled{color:#FFFFFF !important;}
/* .product-cta is a solid blue button (background:var(--blue)) on every product/brand
   page's own local <style> block except digital-watchdog's, whose local CSS instead
   styles it as a plain color:var(--blue) text link with no background at all — an
   outlier in the page's own legacy markup. The rule just above still forces white
   text there (assuming the usual button), which on that one page renders white-on-
   transparent (effectively white-on-off-white). Reassert the same solid-button look
   used by every sibling product page so this one matches instead of going invisible. */
.product-cta{
  background:var(--blue) !important;padding:8px 16px !important;border-radius:var(--radius) !important;
}
.btn-primary,.btn-primary *,.form-submit,.form-submit *,.nav-cta,.nav-cta *{color:var(--navy) !important;}
.btn-primary svg,.form-submit svg{fill:var(--navy) !important;}
/* ink utility strips */
.hq-strip,.hq-strip *,.trust-bar *,.trust-strip,.trust-strip *,.accolade-bar *,.hero-accent-bar *,[data-mss-slim] *{color:rgba(251,248,243,.66) !important;}
.hq-strip .hq-value,.trust-bar .trust-item strong{color:var(--text-ink) !important;}
.hq-strip a[href^="tel"],.trust-bar a[href^="tel"],[data-mss-slim] a[href^="tel"],
[data-mss-slim] a[href^="mailto"],.gold-bar-cta,.gold-bar-cta *{color:var(--accent) !important;}
.trust-bar svg,.accolade-bar svg,[data-mss-slim] svg,.hq-strip svg{fill:var(--accent) !important;}
/* .trust-bar/.accolade-bar/.hq-strip/.mss-pg-strip/.ct-quickbar/.hero-accent-bar are
   ALWAYS solid dark (var(--ink-deep), set unconditionally near the top of the STATS
   section above) regardless of the section's data-band, because transform.py's band
   sniffer only reads inline section-level backgrounds, not these components' own
   CSS-class backgrounds. When one of these strips sits inside a
   section[data-band="paper"|"white"] (e.g. .hq-strip on the manufacturer pages'
   light "About" section), the "literal light colours on a paper/white ground" rule
   above (section 23) was STILL winning even though it's declared earlier and this
   block re-declares with what looks like equal specificity: that rule's :is() list
   includes ".clb-hdr p" as one of its arguments, a two-compound complex selector
   (class + type) with specificity (0,1,1) — and per the :is() spec, the WHOLE :is()
   contributes the specificity of its single MOST SPECIFIC argument, not the one
   that actually matches. That silently bumps that entire rule to (0,2,2), beating
   a same-shape (section[data-band] :is(single classes) *) fix at (0,2,1). The
   [data-band="paper"][data-band="paper"] duplication below is the established
   fix for this trap (see also the .brand-pill-name / .tb-in a.ph / .product-badge
   fixes elsewhere in this file): it adds one more attribute-selector specificity
   point, reaching (0,3,1), which reliably wins. */
section[data-band="paper"][data-band="paper"] :is(.trust-bar,.accolade-bar,.hq-strip,.mss-pg-strip,.ct-quickbar,.hero-accent-bar) *,
section[data-band="white"][data-band="white"] :is(.trust-bar,.accolade-bar,.hq-strip,.mss-pg-strip,.ct-quickbar,.hero-accent-bar) *{
  color:rgba(251,248,243,.66) !important;
}
/* .mss-pg-strip has a second, unrelated life as a plain photo-grid wrapper (e.g.
   /services/, /ai-security-cameras/'s 3-photo showcase row) — a dark ink-deep strip
   holding individual <figure> cards that carry their own solid white background
   inline. The blanket "* {color:rgba(251,248,243,.66)}" above doesn't know those
   figures opted back out of the dark backdrop, so their captions rendered light-on-
   white. Give the figure/figcaption its own light-box exception, one column higher
   again than the blanket rule (same duplication trick, plus the extra type
   selector). */
section[data-band="paper"][data-band="paper"] .mss-pg-strip figure,
section[data-band="white"][data-band="white"] .mss-pg-strip figure,
section[data-band="paper"][data-band="paper"] .mss-pg-strip figure *,
section[data-band="white"][data-band="white"] .mss-pg-strip figure *{
  color:var(--text-light) !important;
}
section[data-band="paper"][data-band="paper"] .hq-strip .hq-value,
section[data-band="white"][data-band="white"] .hq-strip .hq-value,
section[data-band="paper"][data-band="paper"] .trust-bar .trust-item strong,
section[data-band="white"][data-band="white"] .trust-bar .trust-item strong{
  color:var(--text-ink) !important;
}
section[data-band="paper"][data-band="paper"] .hq-strip a[href^="tel"],
section[data-band="white"][data-band="white"] .hq-strip a[href^="tel"],
section[data-band="paper"][data-band="paper"] .trust-bar a[href^="tel"],
section[data-band="white"][data-band="white"] .trust-bar a[href^="tel"],
section[data-band="paper"][data-band="paper"] .hq-strip a[href^="mailto"],
section[data-band="white"][data-band="white"] .hq-strip a[href^="mailto"]{
  color:var(--accent) !important;
}
section[data-band="paper"][data-band="paper"] :is(.trust-bar,.accolade-bar,.hq-strip) svg,
section[data-band="white"][data-band="white"] :is(.trust-bar,.accolade-bar,.hq-strip) svg{fill:var(--accent) !important;}
/* amber ground always takes ink text */
/* text on an amber ground takes ink — but two page-specific "utility strip"
   wrappers are restyled to ink (var(--navy2)) rather than amber and must not
   be caught by this: .tb-in (see .tb{} in the HEADER section, sitewide) and
   .trbar (/alarm-systems/ only — background:var(--navy2), NOT gold despite
   its similarity to the real .trust-bar/.hq-strip amber components). Both
   were mistakenly still in this list, forcing navy ink text onto their own
   navy2 background: .tb-in made the top-strip "Division of Michigan
   Security Systems" text invisible sitewide, and .trbar made the whole
   "Licensed Michigan Low-Voltage Contractor / All Work & Equipment
   Warranted / ..." trust-strip row invisible on /alarm-systems/. The
   :not([style*="background:"]) on the INNER :is() list is a second guard: a
   few of these gold contact bars nest their own dark pill buttons (e.g. a
   tel: link with background:var(--navy) and its own color:var(--accent)) —
   without this, those buttons' text was being forced to the same navy as
   their own background and disappeared entirely. */
:is(
[style*="background:var(--accent"]:not([data-mss-slim]),
[style*="background:#F5A623"]:not([data-mss-slim]),
[style*="background:#DFA13E"]:not([data-mss-slim])) :is(a,span,div,strong,p,.ph):not([style*="background:"]){
  color:var(--navy) !important;
}
.tb-in :is(a,span,div,strong,p,.ph):not([style*="background:"]),
.trbar :is(a,span,div,strong,p,.ph):not([style*="background:"]){color:rgba(251,248,243,.82) !important;}
.tb-in a[href^="tel"]:not(.ph),.tb-in a[href^="mailto"]:not(.ph),
.trbar a[href^="tel"]:not(.ph),.trbar a[href^="mailto"]:not(.ph){color:var(--accent2) !important;}
/* .ph (/alarm-systems/ top bar only) is a self-contained gold pill button —
   .ph{background:var(--accent);color:var(--navy)} — with its background
   coming from a CSS class rather than an inline style, so the
   :not([style*="background:"]) guards above (which only catch INLINE
   backgrounds) don't exclude it. Without this :not(.ph), the tel/mailto
   override just above forced it to accent2 (light gold), nearly the same
   as its own gold background. */
.tb-in a.ph.ph,.trbar a.ph.ph{color:var(--navy) !important;}
.trbar svg{fill:var(--accent) !important;}
[data-mss-slim] :is(a,span,div,strong,p){color:rgba(251,248,243,.66) !important;}
[data-mss-slim] a[href^="tel"],[data-mss-slim] a[href^="mailto"]{color:var(--accent) !important;}
.free-note,.fineprint,.disclaimer,.req-note,.form-note{color:inherit !important;opacity:.8;}

/* --------------------------------------------------------------------------
   28. EDITORIAL CONSISTENCY
   Section headers read left, like the heroes. Centred intros were the legacy
   template's default and are what made every page look interchangeable.
   -------------------------------------------------------------------------- */
section[data-band] > .container > div[style*="text-align:center"]:has(> h2),
section[data-band] > .container > div[style*="text-align: center"]:has(> h2),
section[data-band] > div[style*="text-align:center"]:has(> h2),
section[data-band] > div[style*="text-align: center"]:has(> h2),
section[data-band] .ab-inner:has(> h2),section[data-band] .rv-inner:has(> h2),
section[data-band] .sec-block:has(> h2),section[data-band] .con-sec-inner:has(> h2){
  text-align:left !important;
}
section[data-band] > .container > div:has(> h2) > p,
section[data-band] > div:has(> h2) > p,
section[data-band] .ab-inner > p,section[data-band] .rv-inner > p{
  margin-left:0 !important;margin-right:0 !important;
}
.ab-sub,.rv-eyebrow,.cr-sub,.csr-sub,.section-intro,.ab-why-lead,.ab-clients-lead,
.ct-offices-lead,.ct-faq-lead,.con-sec-lead,.bt-intro{text-align:left !important;}

/* long-form prose reads darker than secondary UI text. The :not([style*=
   "color:#"]) guard excludes a <p> that already declares its own inline hex
   color — a handful of blog posts wrap a callout/info box in a plain
   <div style="background:var(--navy);color:#fff;..."> with its own light
   paragraph color (e.g. color:#d7e0ea) meant for that dark box; without the
   guard this rule forced them to the same dark ink used for ordinary body
   copy, invisible on the box's navy background. Ordinary paragraphs never
   set their own color, so they're unaffected. */
.article p:not([style*="color:#"]),.article li,.blog-article p:not([style*="color:#"]),.blog-article li,
.art-body p:not([style*="color:#"]),.art-body li,
.legal-body p,.legal-body li,.ab-story p,.about-body p,.sec-intro p,
section[data-band="paper"]:not(.cta-banner):not(.ab-cta):not(.pg-cta):not(.rv-cta) .container > p,
section[data-band="white"]:not(.cta-banner):not(.ab-cta):not(.pg-cta):not(.rv-cta) .container > p{
  color:#2E3A4C !important;font-size:1.06rem;line-height:1.72;
}
/* .legal-body p above doesn't get the sibling rules' :not([style*="color:#"]) guard,
   and couldn't anyway: privacy-policy/terms-of-service's closing "Questions about this
   policy?" <p> inside .legal-contact-box (a genuine dark navy island) carries no inline
   color of its own -- only its nested <strong> does -- so the plain "Contact Michigan
   Security Systems at ..." text still went dark-on-navy. Scope the box's own light
   paragraph color back in with higher specificity. */
.legal-contact-box.legal-contact-box p{color:rgba(255,255,255,.85) !important;}
/* the four :not() exclusions above keep this long-form-prose darkening rule off the
   .cta-banner/.ab-cta/.pg-cta/.rv-cta "same-element dark island" shape (the class lives
   directly on the section[data-band] element, so .container > p is still a plain paragraph
   one level down) -- without them this rule and the same-element fix further up the file
   tie in specificity, and being declared later here, this one would win and re-darken the
   text on an actually-dark background. */

/* heroes with no photography: tighter, so the empty half is not the subject */
.ab-hero,.rv-hero,.legal-hero,.con-hero,.blog-hero,.page-hero,.ct-hero{
  padding:clamp(52px,5.4vw,86px) 0 clamp(48px,4.8vw,72px) !important;
}
.ab-hero h1,.rv-hero h1,.legal-hero h1,.ct-hero h1{max-width:22ch;}
.ab-hero p,.rv-hero p,.legal-hero p,.ct-hero p{max-width:58ch;}

/* keep the brass eyebrow rule clear of centred layouts */
.section-tag,.eyebrow,.ab-sub,.rv-eyebrow,.pg-eyebrow,.ct-eyebrow,.con-eyebrow{
  background:none !important;border:0 !important;
}

/* section headers, wherever the legacy markup centred them */
.mss-sechead{text-align:left !important;max-width:900px;margin-left:0 !important;margin-right:0 !important;}
.mss-sechead > p,.mss-sechead > .section-intro{
  margin-left:0 !important;margin-right:0 !important;max-width:66ch;text-align:left !important;
}
.mss-sechead h1,.mss-sechead h2,.mss-sechead h3{text-align:left !important;}

/* the legacy markup centres headings inline, element by element */
section[data-band] :is(h1,h2,h3,h4)[style*="text-align:center"],
section[data-band] :is(h1,h2,h3,h4)[style*="text-align: center"],
section[data-band] .section-head,section[data-band] .section-header{
  text-align:left !important;
}
section[data-band] :is(h1,h2,h3,h4) + p[style*="text-align:center"],
section[data-band] :is(h1,h2,h3,h4) + p[style*="text-align: center"],
section[data-band] :is(h1,h2,h3,h4) + div[style*="text-align:center"] > p{
  text-align:left !important;margin-left:0 !important;margin-right:0 !important;max-width:66ch;
}
section[data-band] :is(h1,h2,h3,h4) + p + p[style*="text-align:center"]{
  text-align:left !important;margin-left:0 !important;margin-right:0 !important;max-width:66ch;
}
/* centred eyebrow spans above a centred heading */
section[data-band] div[style*="text-align:center"] > :is(.section-tag,.eyebrow,.sec-label){margin-left:0;}

/* --------------------------------------------------------------------------
   29. TOP UTILITY STRIP ON SMALL SCREENS
   -------------------------------------------------------------------------- */
.gold-bar-text,[data-mss-slim] span{white-space:nowrap;}
.gold-bar-divider{height:11px !important;align-self:center;flex:0 0 auto;}
@media (max-width:1080px){
  .gold-bar-divider,[data-mss-slim] span[style*="width:1px"]{display:none !important;}
  .gold-bar-inner,[data-mss-slim] > div{
    gap:0 14px !important;justify-content:center !important;padding:7px var(--gutter) !important;
  }
  .gold-bar-text,[data-mss-slim] span{padding:2px 0 !important;font-size:.6rem !important;}
  .gold-bar-text:nth-of-type(n+3),[data-mss-slim] > div > span:nth-of-type(n+3){display:none !important;}
  .gold-bar-cta,[data-mss-slim] a[href^="tel"]{margin-left:0 !important;font-size:.66rem !important;}
}
@media (max-width:520px){
  .gold-bar-text:nth-of-type(n+2),[data-mss-slim] > div > span:nth-of-type(n+2){display:none !important;}
}

/* article-embedded CTA blocks are ink, so their copy is light */
.article :is(.final-cta,.cta-final,.blog-article-cta,.art-cta,.emergency-box[style*="background:#0"]),
.blog-article :is(.final-cta,.cta-final,.blog-article-cta){--text:#FBF8F3 !important;--text-light:rgba(251,248,243,.78) !important;}
.article :is(.final-cta,.cta-final,.blog-article-cta)
  :is(p,li,span,strong,b,em,h2,h3,h4),
.blog-article :is(.final-cta,.cta-final,.blog-article-cta)
  :is(p,li,span,strong,b,em,h2,h3,h4){
  color:var(--text-ink-dim) !important;
}
.article :is(.final-cta,.cta-final,.blog-article-cta) :is(h2,h3,h4,strong,b),
.article :is(.final-cta,.cta-final,.blog-article-cta) a[href^="tel"]{color:var(--text-ink) !important;}
.article .law-callout strong,.article .law-callout b{color:var(--text) !important;}

/* --------------------------------------------------------------------------
   30. AMBER GROUND, LAST WORD
   Any element painted amber by inline style carries ink text — including the
   hand-rolled, class-less buttons scattered through the article pages.
   -------------------------------------------------------------------------- */
[style*="background:var(--accent"]:not([data-mss-slim]),
[style*="background: var(--accent"]:not([data-mss-slim]),
[style*="background:#F5A623"]:not([data-mss-slim]),
[style*="background:#DFA13E"]:not([data-mss-slim]),
[style*="background:#E9A13B"]:not([data-mss-slim]){color:var(--navy) !important;}
/* a <th> that highlights one column with an inline amber background (e.g. the
   network-cabling/audio-video/security-cameras comparison tables' "recommended"
   column) never actually keeps that amber background — the sitewide th{background-
   color:var(--navy)!important} rule above always wins that property, since !important
   beats a plain inline style regardless of specificity. The AMBER GROUND rule just
   above doesn't know that and still forces navy TEXT to match the (overridden-away)
   amber background, leaving navy-on-navy. Give th the last word instead: two
   attribute-selector matches on the same [style] attribute (the trick used elsewhere
   in this file) reaches one specificity column higher than AMBER GROUND's own
   [style*=...]:not([data-mss-slim]) selector. */
th[style][style*="background:var(--accent"],th[style][style*="background: var(--accent"],
th[style][style*="background:#F5A623"],th[style][style*="background:#DFA13E"],
th[style][style*="background:#E9A13B"]{color:var(--text-ink) !important;}

/* --------------------------------------------------------------------------
   31. STAT ROWS — hairline-divided columns, never a stack
   -------------------------------------------------------------------------- */
.about-stat-grid,.ab-stats-grid,.stats-row,.stat-band-grid,.con-hero-stats,.cpro-statbar,
.pg-hero-stats,.hstats,.alarm-stat-grid,.repair-stat-grid,.hq-strip .container{
  display:grid !important;gap:0 !important;
  grid-template-columns:repeat(auto-fit,minmax(clamp(130px,15vw,190px),1fr)) !important;
  align-items:start;text-align:left !important;
}
.about-stat-grid > *,.ab-stats-grid > *,.stats-row > *,.stat-band-grid > *,
.con-hero-stats > *,.cpro-statbar > *,.pg-hero-stats > *,.hstats > *{
  text-align:left !important;padding:24px 20px 24px 22px !important;
  border-left:1px solid var(--border);background:none !important;border-radius:0 !important;
  box-shadow:none !important;display:flex;flex-direction:column;gap:6px;
}
.about-stat-grid > *:first-child,.ab-stats-grid > *:first-child,.stats-row > *:first-child,
.stat-band-grid > *:first-child,.con-hero-stats > *:first-child,.cpro-statbar > *:first-child,
.pg-hero-stats > *:first-child,.hstats > *:first-child{border-left:0;padding-left:0 !important;}

/* inside a dark hero the hairlines invert */
:is(.pg-hero,.ab-hero,.rv-hero,.ct-hero,.con-hero,.cpro-hero,.hero) :is(.pg-hero-stats,.ab-stats-grid,
.con-hero-stats,.cpro-statbar,.hstats,.stats-row){border-top-color:rgba(255,255,255,.14) !important;}
:is(.pg-hero,.ab-hero,.rv-hero,.ct-hero,.con-hero,.cpro-hero,.hero) :is(.pg-hero-stats,.ab-stats-grid,
.con-hero-stats,.cpro-statbar,.hstats,.stats-row) > *{border-left-color:rgba(255,255,255,.11) !important;}
:is(.pg-hero,.ab-hero,.rv-hero,.ct-hero,.con-hero,.cpro-hero) :is(.pg-hstat,.ab-stat,.con-stat,.cpro-stat) strong,
:is(.pg-hero,.ab-hero,.rv-hero,.ct-hero,.con-hero,.cpro-hero) .s-num{color:var(--accent) !important;}

@media (max-width:760px){
  .about-stat-grid,.ab-stats-grid,.stats-row,.stat-band-grid,.con-hero-stats,.cpro-statbar,
  .pg-hero-stats,.hstats{grid-template-columns:repeat(2,minmax(0,1fr)) !important;}
  .about-stat-grid > *:nth-child(odd),.ab-stats-grid > *:nth-child(odd),.stats-row > *:nth-child(odd),
  .pg-hero-stats > *:nth-child(odd),.con-hero-stats > *:nth-child(odd),.hstats > *:nth-child(odd){
    border-left:0;padding-left:0 !important;
  }
}

/* ==========================================================================
   32. COMPONENTS CARRIED OVER FROM THE PREVIOUS STYLESHEET
   These lived only in mss-redesign.css, which this build replaces. Without
   them the mobile CTA bar dumped two unsized icons at the foot of every page
   and photo slots lost their fill rules.
   ========================================================================== */

/* --- 32a. Unsized inline SVG can never blow up ---------------------------- */
/* An <svg viewBox="0 0 24 24"> with no width/height fills its container and
   scales its height to match. Give every icon a sane default; anything that
   needs to be bigger sets its own size and wins on specificity. */
svg:not([width]):not([height]){width:1em;height:1em;}
svg{max-width:100%;}
a svg,button svg,li svg,p svg,span svg,h1 svg,h2 svg,h3 svg,h4 svg,
.trust-item svg,.gold-bar-text svg,.gold-bar-cta svg,[data-mss-slim] svg,
.hq-strip svg,.ct-quick svg,.feature-check svg,.info-dot svg,.check-icon svg{
  width:1em;height:1em;flex:0 0 auto;
}
.mss-ico{display:inline-block;vertical-align:-.125em;width:1em;height:1em;}
/* icon tiles keep the larger mark they were designed with */
:is(.service-icon,.industry-icon,.pill-icon,.feat-icon,.svc-b-icon,.bsc-icon,
.ind-hub-icon,.brands-cat-icon,.con-aud-icon,.ab-card-icon,.backlink-icon,
.dw-feat-icon,.mss-brand-icon,.office-card-icon,.ct-info-ico,.brand-pill-icon,
.c-icon,.cd2-icon,.gr-card-icon,.svc-b-cta-icon,.hiw-num,.step-num,.proc-card-num) svg{
  width:20px;height:20px;
}
.carousel-arrow svg,.mobile-close svg,.hamburger svg,.modal-close svg,.social-btn svg{
  width:18px;height:18px;
}

/* --- 32b. Mobile sticky Call / Free Assessment bar ------------------------ */
/* Phones only. Hidden everywhere else — this is what was appearing full-size
   at the bottom of every desktop page. */
#mss-sticky-cta{display:none;}
@media (max-width:760px){
  #mss-sticky-cta{
    display:flex;position:fixed;left:0;right:0;bottom:0;z-index:2500;
    background-color:var(--ink-deep);border-top:1px solid rgba(223,161,62,.35);
    padding:8px 10px;gap:8px;box-shadow:0 -6px 24px rgba(0,0,0,.4);
  }
  #mss-sticky-cta a{
    flex:1;display:flex;align-items:center;justify-content:center;gap:7px;
    padding:13px 8px;border-radius:var(--radius);
    font-family:var(--f-body);font-weight:600;font-size:.92rem;
    text-decoration:none;letter-spacing:-.005em;
  }
  #mss-sticky-cta .msc-call{background:transparent;color:var(--accent);border:1px solid var(--accent);}
  #mss-sticky-cta .msc-quote{background-color:var(--accent);color:var(--navy);border:1px solid var(--accent);}
  #mss-sticky-cta svg{width:17px;height:17px;flex-shrink:0;}
  body{padding-bottom:66px !important;}
  /* the sticky bar replaces the floating phone pill on phones */
  .phone-fab,#mss-phone-pill{display:none !important;}
  #mss-chat-launcher{bottom:82px !important;right:14px !important;}
}

/* --- 32c. Photo slots fill their frame; logos are never cropped ----------- */
:is(.a-slide,.photo-slot,.service-card-img-wrap,.hero-carousel,.carousel-slide,
.gallery-item,.proj-img,.proj-photo,.gr-card-photo,.case-photo,.blog-thumb,
.project-card-photo,.pg-feature-photo,.blog-hero-img,.about-photo-wrap,
[class*="photo-wrap"],[class*="-photo-"]) img{
  object-fit:cover !important;object-position:center center !important;
  width:100% !important;height:100% !important;display:block;
}
.footer-brand img,.logo-img,.footer-logo-img,
[class*="logo"] img,[class*="mfr"] img,[class*="product"] img,[class*="brand-logo"] img,
[src*="/logos/"],[src*="mfr-"],[src*="-product-"]{
  object-fit:contain !important;
}
/* a photo slot with no explicit height still needs one, or the image collapses */
.photo-slot,.service-card-img-wrap,.blog-thumb,.project-card-photo,.gallery-item,
.proj-img,.proj-photo,.gr-card-photo,.case-photo{
  position:relative;overflow:hidden;background-color:var(--paper-2);
}
.photo-slot:not([style*="height"]),.service-card-img-wrap:not([style*="height"]){min-height:200px;}

/* --- 32d. Floating widgets ----------------------------------------------- */
#mss-chat-launcher{z-index:2400;}
.phone-fab,#mss-phone-pill{z-index:2400;}

/* --- 32e. Inline-styled grids must collapse on small screens, not clip ---- */
/* Hundreds of sections set their columns inline. Without these they stayed
   multi-column on phones and simply got cut off at the viewport edge. */
@media (max-width:1024px){
  [style*="grid-template-columns:repeat(3,1fr)"],
  [style*="grid-template-columns:repeat(3, 1fr)"],
  [style*="grid-template-columns:1fr 1fr 1fr"],
  [style*="grid-template-columns:repeat(4,1fr)"],
  [style*="grid-template-columns:repeat(4, 1fr)"]{
    grid-template-columns:repeat(2,minmax(0,1fr)) !important;
  }
}
@media (max-width:760px){
  [style*="grid-template-columns"]{grid-template-columns:minmax(0,1fr) !important;}
  [style*="min-width:5"],[style*="min-width:4"],[style*="min-width:3"],
  [style*="min-width:2"],[style*="min-width:1"]{min-width:0 !important;}
  .hero-panel,.hero-right-col{max-width:100% !important;}
  .logo-name,.logo-text-main{white-space:normal !important;}
  /* long unbroken strings (URLs, part numbers) must wrap */
  h1,h2,h3,h4,p,li,td,th,a,dd,dt{overflow-wrap:anywhere;}
}
@media (max-width:430px){
  .hero h1{font-size:clamp(1.75rem,7.8vw,2.3rem) !important;}
  .gold-bar-inner,[data-mss-slim] > div{gap:4px 10px !important;padding:6px 14px !important;}
}
/* tables never force the page wide */
table{display:block;overflow-x:auto;-webkit-overflow-scrolling:touch;white-space:normal;}
@media (min-width:761px){table{display:table;}}

/* ==========================================================================
   33. HEROES THAT CARRY THEIR PHOTO AS A CSS BACKGROUND
   A dozen pages set the hero photograph inline as background:linear-gradient(),
   url(...). Section 7 must tint those, never replace them.
   ========================================================================== */
.hero[style*="url("],.pg-hero[style*="url("],.ab-hero[style*="url("],
.rv-hero[style*="url("],.ct-hero[style*="url("],.con-hero[style*="url("],
.legal-hero[style*="url("],.blog-hero[style*="url("],.page-hero[style*="url("],
section[style*="url("]{
  background-color:transparent !important;
  background-size:cover !important;
  background-position:center 42% !important;
  background-repeat:no-repeat !important;
}
/* these heroes are a single centred block, not the split-bleed grid: give them
   back the vertical room the inline padding used to provide, and align them
   left so they read like every other hero on the site */
.hero[style*="url("],.pg-hero[style*="url("],.page-hero[style*="url("],
section.hero[style*="url("]{
  padding:clamp(64px,7vw,104px) 0 clamp(56px,6vw,88px) !important;
  display:block !important;overflow:hidden !important;
  max-height:none !important;height:auto !important;
}
.hero[style*="url("] > div{
  max-width:1240px !important;margin:0 auto !important;
  padding:0 var(--gutter) !important;text-align:left !important;
}
.hero[style*="url("] > div > *{margin-left:0 !important;margin-right:0 !important;}
.hero[style*="url("] h1{
  color:var(--text-ink) !important;max-width:19ch;
  font-size:clamp(2.3rem,4.4vw,3.9rem) !important;letter-spacing:-.035em !important;
  line-height:1.03 !important;text-align:left !important;
}
.hero[style*="url("] p{
  color:var(--text-ink-dim) !important;max-width:60ch !important;text-align:left !important;
}
.hero[style*="url("] > div > div:first-child{
  font-family:var(--f-mono) !important;font-size:.685rem !important;font-weight:600 !important;
  letter-spacing:.19em !important;text-transform:uppercase !important;
  color:var(--accent2) !important;padding-left:34px !important;position:relative;
  text-align:left !important;
}
.hero[style*="url("] > div > div:first-child::before{
  content:"";position:absolute;left:0;top:.62em;width:24px;height:2px;background:var(--accent);
}
.hero[style*="url("] .hero-actions,
.hero[style*="url("] > div > div:last-child{justify-content:flex-start !important;}

/* the gradient wash sits above the photo, not instead of it */
.hero[style*="url("] .hero-bg,.hero[style*="url("] .hero-grid,
.hero[style*="url("] .hero-grid-overlay{opacity:.35;}
.hero[style*="url("]::after{
  content:"";position:absolute;inset:0;pointer-events:none;z-index:0;
  background:linear-gradient(92deg,rgba(10,25,38,.90) 0%,rgba(10,25,38,.72) 46%,rgba(10,25,38,.52) 100%);
}
.hero[style*="url("] > *{position:relative;z-index:1;}

/* --- 33b. Blog cards: picture on top, text below, nothing clipped --------- */
.blog-card{display:flex !important;flex-direction:column !important;}
.blog-img,.blog-thumb{
  flex:0 0 auto !important;height:auto !important;aspect-ratio:16/10;
  overflow:hidden;position:relative;display:block !important;background:var(--paper-2);
}
.blog-img img,.blog-thumb img{width:100% !important;height:100% !important;object-fit:cover !important;display:block;}
/* Some .blog-thumb slots (alarm-systems' related-posts strip) carry a
   colored gradient placeholder with a gold category label directly on it
   (no photo yet) — the generic ".blog-card :is(div,...){color:var(--text-
   light)!important}" card-text rule (§ CARD TEXT) clobbers that inline gold
   with dark gray, illegible on the dark gradient. Restore the label's own
   inline gold since it was styled for exactly this dark-gradient ground. */
.blog-thumb div[style*="color:#F5A623"]{color:#F5A623 !important;}
/* SITEWIDE (81 pages — every city page's "Recent Michigan Installations"
   project-card grid, the homepage, and /alarm-systems/): each card's colored
   gradient header has an <h3 itemprop="headline" style="color:white;...">
   caption. section[data-band="paper"/"white"] :is(h1..h6){color:var(--text)
   !important} (§ TOKEN CONTRACT area) outranks that plain inline white and
   makes the caption dark-on-gradient. Only readcheck2's full sweep (not the
   top-3-per-page slice normally seen) surfaced this — every affected page
   had a higher-priority finding crowding it out of view until those were
   fixed. Matches only the literal inline value, so cards that don't set
   this exact color are unaffected. */
h3[itemprop="headline"][style*="color:white"]{color:#fff !important;}
/* .ctab (/alarm-systems/ only) is a standalone final-CTA <div> — not a
   <section>, so it never gets a data-band and the sitewide band-based text
   system doesn't apply to it. Its own navy gradient background is intact,
   but its "586-466-4490" outline button uses the shared .btn-outline family
   (color:inherit!important, see § BUTTONS), which inherits body's default
   dark var(--text) since nothing here sets an explicit light color for it
   to inherit — invisible dark text on the navy gradient. */
.ctab{color:var(--text-ink) !important;}
/* the "⇧ Back to Top" toggle (/alarm-systems/ only) is a single hand-authored
   snippet reused after 4 different sections; its inline
   color:rgba(255,255,255,.4) assumes a dark section, which is only true for
   2 of the 4 — on the light (paper/white) ones it renders as near-invisible
   pale text on off-white/white. Give it dark-ground-appropriate text only
   where the section is actually light. */
section[data-band="paper"] span[onclick="ss('home')"],
section[data-band="white"] span[onclick="ss('home')"]{color:var(--text-light) !important;}
/* .brands-cat-header (/alarm-systems/) is the colored gradient title strip
   atop each .brands-cat-card (siblings of .brands-cat-body, same card,
   different section — see that fix above); its <h3> is caught by the same
   generic ".blog-card,...,.brands-cat-card,... :is(...,h3,...)
   {color:var(--text-light)!important}" card-text rule, invisible on its own
   colored gradient background. */
.brands-cat-card .brands-cat-header h3{color:#fff !important;}
.bc-body,.blog-card-body{
  flex:1 1 auto !important;overflow:visible !important;min-height:0;
  display:flex !important;flex-direction:column;gap:8px;
  padding:20px 22px 22px !important;
}
.bc-title,.blog-title{
  font-family:var(--f-display) !important;font-weight:700 !important;
  font-size:1.12rem !important;line-height:1.22 !important;letter-spacing:-.022em !important;
  color:var(--text) !important;
}
.bc-excerpt,.blog-excerpt{
  font-size:.93rem !important;line-height:1.6 !important;color:var(--text-light) !important;
  flex:1 1 auto;margin:0 !important;
}
.bc-foot{
  display:flex !important;align-items:center;justify-content:space-between;gap:6px 12px;
  flex-wrap:wrap;row-gap:6px;
  padding-top:12px !important;margin-top:auto;border-top:1px solid var(--border);
}
.blog-date{
  font-family:var(--f-mono) !important;font-size:.66rem !important;letter-spacing:.13em !important;
  text-transform:uppercase !important;color:var(--text-light) !important;
  white-space:nowrap;
}

/* ==========================================================================
   34. CLEAR LEGACY GRADIENTS
   Section 33 switched solid fills from `background` to `background-color` so
   inline hero photographs survive. That leaves any legacy gradient underneath
   still painting — the amber striped accolade bar being the obvious one. Clear
   the image layer everywhere a flat surface is intended, and only there.
   ========================================================================== */
.gold-bar,.gold-bar::before,.gold-bar-cta,
.trust-bar,.trust-strip,.accolade-bar,.hero-accent-bar,.mss-pg-strip,.hq-strip,
.ct-quickbar,[data-mss-slim],
footer,.site-foot,
.btn-primary,.btn,.form-submit,.nav-cta,.nav-cta2,.btn-secondary,.btn-outline,
.service-card,.industry-card,.blog-card,.proj-card,.project-card,.a-card,.feature-card,
.mfr-detail-card,.brands-cat-card,.ind-hub-card,.svc-hub-card,.pt-card,.eq-card,
.camtype-card,.product-card,.con-why-card,.con-aud-card,.ab-card,.rv-card,.gr-card,
.googrev-card,.proc-card,.dw-feature-card,.backlink-card,.cpro-card,.hiw-card,
.ct-office,.office-card-new,.ct-faq-card,.con-faq-card,.stat-box,.cd2,.mss-brand-card,
.faq-item,.faq-u,.contact-form-box,.contact-form-card,.ct-form-panel,.lead-form-wrap,
.service-icon,.industry-icon,.pill-icon,.feat-icon,.svc-b-icon,.bsc-icon,.ind-hub-icon,
.brands-cat-icon,.con-aud-icon,.ab-card-icon,.backlink-icon,.dw-feat-icon,.mss-brand-icon,
.office-card-icon,.ct-info-ico,.brand-pill-icon,.c-icon,.cd2-icon,.gr-card-icon,
.clb,.brands-strip,.city-ticker-pill,.city-link-pill,.city-tag,.chip,.brand-chip,
.hero-panel,.hero-carousel,.mobile-nav,.nav-dropdown-menu,
input,select,textarea{
  background-image:none !important;
}
.gold-bar::before{display:none !important;}
/* Bands are flat by design. Heroes are NOT cleared — several carry their
   photograph from a stylesheet rather than inline, and that photo is the point
   of the design. */
section[data-band]:not([style*="url("]){background-image:none !important;}

/* ==========================================================================
   35. HERO SCRIM — works whether the photo comes from CSS or from markup
   ========================================================================== */
.hero,.pg-hero,.ab-hero,.rv-hero,.ct-hero,.con-hero,.cpro-hero,
.legal-hero,.blog-hero,.page-hero{
  background-size:cover !important;background-position:center 42% !important;
  background-repeat:no-repeat !important;position:relative;
}
.pg-hero::after,.ab-hero::after,.rv-hero::after,.ct-hero::after,.con-hero::after,
.cpro-hero::after,.legal-hero::after,.blog-hero::after,.page-hero::after{
  content:"";position:absolute;inset:0;pointer-events:none;z-index:0;
  background:linear-gradient(92deg,rgba(10,25,38,.92) 0%,rgba(10,25,38,.76) 48%,rgba(10,25,38,.55) 100%);
}
.pg-hero > *,.ab-hero > *,.rv-hero > *,.ct-hero > *,.con-hero > *,.cpro-hero > *,
.legal-hero > *,.blog-hero > *,.page-hero > *{position:relative;z-index:1;}

/* ==========================================================================
   36. PAGE HEADERS — every H1 block starts at the page gutter
   ========================================================================== */
.mss-pagehead{text-align:left !important;padding:clamp(56px,6vw,92px) 0 clamp(48px,5vw,76px) !important;}
.mss-pagehead > div,.mss-pagehead > .container{
  max-width:1240px !important;margin:0 auto !important;
  padding-left:var(--gutter) !important;padding-right:var(--gutter) !important;
  text-align:left !important;
}
.mss-pagehead h1{max-width:20ch;text-align:left !important;}
.mss-pagehead p{max-width:62ch;text-align:left !important;margin-left:0 !important;margin-right:0 !important;}
.mss-pagehead > div > div:first-child:not([class]){
  font-family:var(--f-mono) !important;font-size:.685rem !important;font-weight:600 !important;
  letter-spacing:.19em !important;text-transform:uppercase !important;
  padding-left:34px !important;position:relative;margin-bottom:16px !important;
}
.mss-pagehead > div > div:first-child:not([class])::before{
  content:"";position:absolute;left:0;top:.62em;width:24px;height:2px;background:var(--accent);
}
/* brand cards: one accent, not a rainbow of top borders */
.mfr-detail-card,.brands-cat-card,.mss-brand-card,.brand-chip-pill,.product-card{
  border-top-color:var(--border) !important;
}
section[data-band="ink"] :is(.mfr-detail-card,.brands-cat-card,.mss-brand-card,.product-card),
section[data-band="ink2"] :is(.mfr-detail-card,.brands-cat-card,.mss-brand-card,.product-card){
  border-top-color:rgba(255,255,255,.13) !important;
}
.mfr-detail-card:hover,.brands-cat-card:hover,.product-card:hover{border-top-color:var(--accent) !important;}

/* class-less inline-styled brand cards: one accent rule, one radius */
a[style*="border-top:3px solid"],div[style*="border-top:3px solid"],
a[style*="border-top: 3px solid"],div[style*="border-top: 3px solid"]{
  border-top-color:var(--border) !important;border-top-width:1px !important;
  border-color:var(--border) !important;border-radius:var(--radius) !important;
  box-shadow:none !important;transition:border-color .2s ease,transform .2s ease;
}
a[style*="border-top:3px solid"]:hover,a[style*="border-top: 3px solid"]:hover{
  border-color:var(--accent) !important;transform:translateY(-3px);
}
section[data-band="ink"] a[style*="border-top:3px solid"],
section[data-band="ink2"] a[style*="border-top:3px solid"]{
  border-color:rgba(255,255,255,.13) !important;
}
/* soften the other rounded chrome the legacy markup sets inline */
[style*="border-radius:14px"],[style*="border-radius:16px"],[style*="border-radius:12px"],
[style*="border-radius:10px"],[style*="border-radius: 14px"],[style*="border-radius: 12px"]{
  border-radius:var(--radius) !important;
}
[style*="border-radius:30px"],[style*="border-radius:999px"],[style*="border-radius:50%"]{
  border-radius:inherit;
}
.social-btn,.carousel-dots > *,[style*="border-radius:50%"]{border-radius:50% !important;}

/* the floating chat/phone stack must clear the sticky call bar on phones */
@media (max-width:760px){
  #mss-fab-stack{bottom:80px !important;right:14px !important;}
  #mss-chat-panel{bottom:80px !important;max-height:calc(100vh - 160px) !important;}
}

/* ==========================================================================
   37. READABILITY FLOOR — nothing on this site is set below a comfortable size,
       and no text sits under 4.5:1 against its own ground. Micro-type (mono,
       uppercase, letter-spaced) floors at 12.6px; running copy floors at 15.5px.
   ========================================================================== */

/* --- 37a. mono micro-type: eyebrows, kickers, category tags ---------------- */
.section-tag,.eyebrow,.ab-eyebrow,.pg-eyebrow,.ct-eyebrow,.rv-eyebrow,.con-eyebrow,
.sec-label,.hero-badge,.proc-head-tag,.blog-cat,.art-cat,.a-tag,.s-tag,.stag,.cpro-kick{
  font-size:.83rem !important;letter-spacing:.145em !important;
}
/* brass is not legible on ink — every eyebrow variant, not just two of them */
section[data-band="ink"] :is(.section-tag,.eyebrow,.ab-eyebrow,.pg-eyebrow,.ct-eyebrow,
.rv-eyebrow,.con-eyebrow,.sec-label,.hero-badge,.proc-head-tag,.blog-cat,.art-cat,
.a-tag,.s-tag,.stag,.cpro-kick,.service-cta-link,.service-cta-text,.rc-link,.link-arrow,
.svc-readmore,.blog-read,.art-cta,.blog-date,.stat-label,.office-card-label),
section[data-band="ink2"] :is(.section-tag,.eyebrow,.ab-eyebrow,.pg-eyebrow,.ct-eyebrow,
.rv-eyebrow,.con-eyebrow,.sec-label,.hero-badge,.proc-head-tag,.blog-cat,.art-cat,
.a-tag,.s-tag,.stag,.cpro-kick,.service-cta-link,.service-cta-text,.rc-link,.link-arrow,
.svc-readmore,.blog-read,.art-cta,.blog-date,.stat-label,.office-card-label),
.section-dark :is(.ct-eyebrow,.ab-eyebrow,.pg-eyebrow,.rv-eyebrow,.con-eyebrow,.blog-cat,
.art-cat,.blog-date,.stat-label),
.hero :is(.section-tag,.eyebrow,.ab-eyebrow,.ct-eyebrow,.pg-eyebrow,.hero-badge,.sec-label),
/* the photographic page-heroes (ab-hero, pg-hero, etc.) aren't caught by the
   ".hero" selector above — that's a literal class name, not a suffix match —
   so their eyebrow labels were still defaulting to brass-ink (dark, made for
   paper) sitting directly on the dark photo overlay. This used to be patched
   per-page by an auto-generated "mss-contrast-fix" nth-child style block;
   that mechanism was retired for being fragile (broke the moment a section
   was added/reordered) and never got a proper sitewide replacement here. */
:is(.ab-hero,.blog-hero,.con-hero,.cpro-hero,.ct-hero,.legal-hero,.page-hero,.pg-hero,.rv-hero)
  :is(.section-tag,.eyebrow,.ab-eyebrow,.pg-eyebrow,.ct-eyebrow,.rv-eyebrow,.con-eyebrow,
  .sec-label,.hero-badge,.proc-head-tag,.blog-cat,.art-cat,.a-tag,.s-tag,.stag,.cpro-kick){
  color:var(--accent2) !important;
}

/* --- 37b. labels, dates, chips, read-more links --------------------------- */
.service-cta-link,.service-cta-text,.rc-link,.link-arrow,.svc-readmore,.blog-read,.art-cta{
  font-size:.83rem !important;letter-spacing:.115em !important;
}
/* the 20 manufacturer pages' own legacy <style> block still colors this
   "Free Consultation →" link var(--accent) (gold, made for the ink header it
   used to sit under) even though .brands-strip's background was moved to
   var(--white) elsewhere in this file — gold-on-white is ~2.2:1. Same brass
   token the .service-cta-link family above uses on paper. */
.brands-strip-cta{color:var(--brass-ink) !important;}
.blog-date{font-size:.83rem !important;letter-spacing:.10em !important;}
.hero-stats .stat-label,.stat-label,.about-stat-label,.accolade-label,.s-lbl{
  font-size:.83rem !important;letter-spacing:.11em !important;
  color:rgba(251,248,243,.88) !important;
}
section[data-band="paper"] :is(.stat-label,.about-stat-label,.accolade-label,.s-lbl),
section[data-band="white"] :is(.stat-label,.about-stat-label,.accolade-label,.s-lbl),
.stat-card .stat-label{color:var(--text-light) !important;}
section[data-band="ink"] .stat-card .stat-label,
section[data-band="ink2"] .stat-card .stat-label,
.hero .stat-card .stat-label,.hero .stat-label{color:rgba(251,248,243,.88) !important;}

.city-link-pill,.city-tag,.msa-city-pill,.footer-city-link,.svc-ind-chip,
.brand-chip-pill,.chip,.ab-client-chip,.a-chip,.proc-chip,.compliance-badge,.eq-badge,
.ct-badge,.ab-loc-badge,.cql-pill,.service-pill,.brand-pill,.qls .quick-link-item{
  font-size:.83rem !important;letter-spacing:.075em !important;padding:8px 13px !important;
}
section[data-band="ink"] .city-link-pill,section[data-band="ink2"] .city-link-pill,
section[data-band="ink"] .city-ticker-pill,section[data-band="ink2"] .city-ticker-pill,
.section-dark .city-link-pill,footer .city-ticker-pill,.footer-city-link{
  color:rgba(251,248,243,.90) !important;border-color:rgba(255,255,255,.22) !important;
}
/* .city-ticker-track a / .city-ticker a used to be in the list above too,
   forcing near-white pill text unconditionally. Every actual usage of this
   "Serving 55+ Michigan Communities" ticker (114 pages) sits inside
   section[data-band="white"|"paper"] — a light map-section band, never a
   dark one — so that near-white text was landing on off-white/white and was
   nearly invisible. The scoped ink/ink2/section-dark rules above already
   handle the (currently nonexistent) dark case; .city-ticker-pill's own
   light-safe default (var(--text-light), earlier in this file) now wins. */
.gold-bar-text,.office-card-label,.office-card-sub,.pill-sub,.brand-pill-sub,.hq-label,
.trust-item,.tp-label,.badge-sub,.mini-label{
  font-size:.82rem !important;letter-spacing:.085em !important;
}
.hero .pill-sub,.pill-sub{color:rgba(251,248,243,.82) !important;}
.hero .pill-text,.pill-text,.brand-pill-name{font-size:.96rem !important;}
.nav-link,.nav-dropdown > .nav-link,.nav-item > a{font-size:.90rem !important;}

/* --- 37c. running copy floor ---------------------------------------------- */
ul.service-features li,.service-features li,.svc-features li,.feature-list li,
.card ul li,.svc-card ul li,.ind-card li,.industry-card li,.a-card li,
.mfr-detail-card li,.product-card li,.checklist li,.cl li{
  font-size:.98rem !important;line-height:1.62 !important;
}
.industry-card p,.ind-hub-card p,.ind-card p,.a-card p,.svc-card p,.service-card p,
.blog-card p,.bc-body p,.project-card p,.mfr-detail-card p,.product-card p,
.city-card p,.office-card p,.rc-card p,.faq-a,.faq-answer{
  font-size:1rem !important;line-height:1.66 !important;
}
.industry-card p,section[data-band="ink"] .industry-card p{color:var(--text-ink-dim) !important;}

/* inline-styled micro-type from the legacy markup: clamp each band up to the
   floor rather than flattening every size to one value */
[style*="font-size:.5"],[style*="font-size: .5"],[style*="font-size:0.5"],[style*="font-size: 0.5"],
[style*="font-size:.6"],[style*="font-size: .6"],[style*="font-size:0.6"],[style*="font-size: 0.6"],
[style*="font-size:.7"],[style*="font-size: .7"],[style*="font-size:0.7"],[style*="font-size: 0.7"]{
  font-size:.83rem !important;
}
[style*="font-size:.8"],[style*="font-size: .8"],[style*="font-size:0.8"],[style*="font-size: 0.8"]{
  font-size:.875rem !important;
}
[style*="font-size:.9"],[style*="font-size: .9"],[style*="font-size:0.9"],[style*="font-size: 0.9"]{
  font-size:.96rem !important;
}
[style*="font-size:10px"],[style*="font-size: 10px"],[style*="font-size:11px"],
[style*="font-size: 11px"],[style*="font-size:12px"],[style*="font-size: 12px"]{
  font-size:13.5px !important;
}
[style*="font-size:13px"],[style*="font-size: 13px"],[style*="font-size:14px"],
[style*="font-size: 14px"]{font-size:15px !important;}

/* --- 37d. dim text raised to a readable weight ---------------------------- */
.footer-link,.footer-col a{font-size:.98rem !important;color:rgba(251,248,243,.88) !important;}
.footer-brand p,.footer-note,.footer-legal,.footer-bottom,.footer-bottom a,
.footer-copy,.footer-disclaimer{
  font-size:.95rem !important;color:rgba(251,248,243,.82) !important;
}
.footer-col h4,.footer-col > strong,.footer-division{font-size:.82rem !important;letter-spacing:.15em !important;}
[style*="rgba(255,255,255,0.5)"],[style*="rgba(255,255,255,.5)"],
[style*="rgba(255,255,255,0.55)"],[style*="rgba(255,255,255,0.6)"],[style*="rgba(255,255,255,.6)"],
[style*="rgba(255,255,255,0.65)"],[style*="rgba(255,255,255,0.7)"],[style*="rgba(255,255,255,.7)"],
[style*="rgba(255,255,255,0.72)"],[style*="rgba(255,255,255,.72)"],
[style*="rgba(255,255,255,0.75)"],[style*="rgba(255,255,255,0.8)"],[style*="rgba(255,255,255,.8)"],
[style*="rgba(255,255,255,0.82)"],[style*="rgba(255,255,255,0.85)"]{
  color:rgba(251,248,243,.92) !important;
}

/* --- 37e. amber ground: text on brass is always ink ----------------------- */
/* .gold-bar/.gold-bar-inner/.gold-bar-text used to be excluded here too, back
   when the top bar sat on an amber ground — it was moved to the dark-ink
   background at §6 (HEADER) without this list being updated, so it was
   silently forcing dark-on-dark navy text over the bar's own correct light
   color ever since. Caught now that the per-page contrast-fix patches that
   used to paper over this (see §37/mss-contrast-fix note elsewhere) are gone. */
.product-badge,.badge-amber,
[style*="background:var(--accent)"] ,[style*="background-color:var(--accent)"],
[style*="background:#DFA13E"],[style*="background-color:#DFA13E"],
[style*="background:#dfa13e"],.tag-featured,.ribbon-featured{
  color:#0A1926 !important;
}
.product-badge a{color:#0A1926 !important;}
/* .product-badge.green (10 manufacturer pages) overrides the badge to a
   green background. Its own legacy <style> block sets color:white to go
   with the green, but white-on-this-green (rgb(22,163,74)) only measures
   3.30:1 — under the 4.5:1 AA floor. Navy (the same ink used on the amber
   badge) measures 5.40:1 on the same green, so use that instead of white. */
.product-badge.green{color:#0A1926 !important;}
/* The generic ".product-card :is(div,span,...){color:var(--text-light)
   !important}" card-text rule (§ CARD TEXT) outspecifies the plain
   ".product-badge{color:...!important}" rule above for reasons that don't
   reduce to a simple selector-list comparison in practice — bumping
   specificity here directly, the same fix already proven for .brand-pill-
   name, is the reliable way to make sure the badge keeps ITS OWN correct
   ink/white text instead of the generic gray body-copy color, on all ~20
   manufacturer/product pages that use this badge. */
.product-card .product-badge.product-badge{color:#0A1926 !important;}
.product-card .product-badge.green{color:#0A1926 !important;}

/* --- 37f. dim slate and gray inline colours raised to the readable token --- */
[style*="#64748b"],[style*="#64748B"],[style*="#7A8699"],[style*="#8A94A6"],
[style*="#94a3b8"],[style*="#94A3B8"],[style*="#9aa5b4"],[style*="#a0aec0"]{
  color:var(--text-light) !important;
}
section[data-band="ink"] :is([style*="#64748b"],[style*="#64748B"],[style*="#94a3b8"]),
section[data-band="ink2"] :is([style*="#64748b"],[style*="#64748B"],[style*="#94a3b8"]){
  color:var(--text-ink-dim) !important;
}

/* --- 37g. single-column heroes -------------------------------------------
   The split-bleed hero gives the page gutter to its first column. Three pages
   set the hero block to one centred column inline, so no column exists to carry
   that gutter and the headline runs to the very edge of the glass. Give those
   heroes the gutter directly and left-align them like every other hero. */
.hero-content[style*="display:block"],.hero-content[style*="display: block"],
.hero-inner[style*="display:block"],.hero-inner[style*="display: block"]{
  display:block !important;max-width:1400px !important;margin:0 auto !important;
  padding:clamp(52px,6vw,96px) var(--gutter) clamp(52px,6vw,88px) !important;
  text-align:left !important;
}
.hero-content[style*="display:block"] > *,.hero-content[style*="display: block"] > *,
.hero-inner[style*="display:block"] > *,.hero-inner[style*="display: block"] > *{
  margin-left:0 !important;margin-right:0 !important;text-align:left !important;
}
.hero-content[style*="display:block"] .hero-badge,
.hero-content[style*="display: block"] .hero-badge{
  display:inline-flex !important;width:auto !important;margin:0 0 18px !important;
}
.hero-content[style*="display:block"] .hero-desc,
.hero-content[style*="display: block"] .hero-desc{
  max-width:64ch !important;margin:0 0 30px !important;text-align:left !important;
}
.hero-content[style*="display:block"] .hero-actions,
.hero-content[style*="display: block"] .hero-actions{justify-content:flex-start !important;}
.hero-content[style*="display:block"] .hero-stats,
.hero-content[style*="display: block"] .hero-stats{justify-content:flex-start !important;}

/* --- 37h. hero status chip and photo caption ------------------------------
   These sit over photography, where the contrast pass cannot measure a ground.
   Set them bright enough to read against the darkest and lightest frames. */
.mss-live-sub,.hero .mss-live-sub,.mss-hero-live .mss-live-sub{
  color:rgba(251,248,243,.88) !important;font-size:.83rem !important;
}
.mss-live-top,.hero .mss-live-top{color:var(--text-ink) !important;font-size:.86rem !important;}
.hero-caption,.hero-photo-caption,.photo-caption,.carousel-caption,.hero-slide-caption{
  color:var(--text-ink) !important;font-size:.83rem !important;
  text-shadow:0 1px 3px rgba(10,25,38,.9),0 0 18px rgba(10,25,38,.75);
}

/* --- 37i. captions that sit on top of a photograph ------------------------
   These carry their own dark gradient, so the colour they inherit from the
   band is wrong: navy ink on a navy scrim is invisible. Cream, always, with a
   readable size and a shadow for the light frames. */
.photo-caption,.img-caption,.slide-caption,.gallery-label,.gallery-lightbox-caption,
.hero-caption,.hero-photo-caption,.carousel-caption,.proj-img-caption,.pg-gallery-cap,
.case-img-caption,.figure-caption-overlay{
  color:rgba(251,248,243,.94) !important;
  font-size:.84rem !important;line-height:1.45 !important;
  text-shadow:0 1px 3px rgba(6,15,24,.85) !important;
}
.photo-caption span,.img-caption span,.slide-caption span,.gallery-label span,
.hero-caption span,.carousel-caption span{
  color:var(--accent2) !important;font-size:.78rem !important;
}
.photo-caption,.img-caption{padding:34px 14px 12px !important;}
.slide-caption{padding:56px 24px 30px !important;}
.svc-photo-label,.svc-img-label,.card-photo-label,.tile-photo-label{
  color:var(--accent2) !important;font-size:.82rem !important;
  text-shadow:0 1px 3px rgba(6,15,24,.85) !important;
}

/* ==========================================================================
   38. TEXT ON THE DARK GROUND — no faint white on navy anywhere
   Every dim white the legacy pages use on a navy section (.5 to .82 alpha) is
   raised to near-solid cream. Body copy on ink now measures 15:1 or better.
   ========================================================================== */
:root{--text-ink-dim:rgba(251,248,243,.96);}

section[data-band="ink"] :is(p,li,td,th,dd,dt,span,div,label,small,figcaption,blockquote),
section[data-band="ink2"] :is(p,li,td,th,dd,dt,span,div,label,small,figcaption,blockquote),
.section-dark :is(p,li,td,th,dd,dt,small,figcaption,blockquote),
footer :is(p,li,td,dd,small),
.hero :is(p,li,dd,small),.hero-desc,.page-hero p,.pg-hero p,.ab-hero p,.ct-hero p,
.rv-hero p,.con-hero p,.blog-hero p,.legal-hero p{
  color:rgba(251,248,243,.96) !important;
}
section[data-band="ink"] :is(h1,h2,h3,h4,h5,h6,strong,b),
section[data-band="ink2"] :is(h1,h2,h3,h4,h5,h6,strong,b),
.section-dark :is(h1,h2,h3,h4,h5,h6,strong,b),
.hero :is(h1,h2,h3,h4,h5,h6),footer :is(h1,h2,h3,h4,h5,h6,strong){
  color:#FFFFFF !important;
}
/* this whole always-white CARDS-section family (see the CARD TEXT CONTRACT /
   TOKEN CONTRACT notes near line 1500) stays a solid white box even inside an
   ink-band section, so their own h3/h4 headings need to stay dark here too,
   not take the sitewide "headings on an ink band are white" treatment just
   above — otherwise their heading text (e.g. "No On-Site Server" on both the
   .why-cdvi-card AND .gr-card feature-card grids on the manufacturer pages)
   renders near-white on the card's own white background. */
section[data-band="ink"] :is(.why-pdk-card,.why-ai-card,.why-ax-card,.why-hw-card,
.why-hik-card,.why-bog-card,.why-cdvi-card,.proj-card,.project-card,.mfr-detail-card,
.brands-cat-card,.con-aud-card,.ab-card,.rv-card,.gr-card,.googrev-card,.dw-feature-card,
.cpro-card,.ct-office,.office-card-new,.ct-faq-card,.con-faq-card,.bc-body,
.industry-detail-card) :is(h1,h2,h3,h4,h5,h6,strong,b),
section[data-band="ink2"] :is(.why-pdk-card,.why-ai-card,.why-ax-card,.why-hw-card,
.why-hik-card,.why-bog-card,.why-cdvi-card,.proj-card,.project-card,.mfr-detail-card,
.brands-cat-card,.con-aud-card,.ab-card,.rv-card,.gr-card,.googrev-card,.dw-feature-card,
.cpro-card,.ct-office,.office-card-new,.ct-faq-card,.con-faq-card,.bc-body,
.industry-detail-card) :is(h1,h2,h3,h4,h5,h6,strong,b){
  color:var(--text) !important;
}
/* the legacy pages hard-code dim whites inline; lift every one of them */
[style*="rgba(255,255,255,0.4"],[style*="rgba(255,255,255,.4"],
[style*="rgba(255,255,255,0.5"],[style*="rgba(255,255,255,.5"],
[style*="rgba(255,255,255,0.6"],[style*="rgba(255,255,255,.6"],
[style*="rgba(255,255,255,0.7"],[style*="rgba(255,255,255,.7"],
[style*="rgba(255,255,255,0.8"],[style*="rgba(255,255,255,.8"],
[style*="rgba(255,255,255,0.9"],[style*="rgba(255,255,255,.9"],
[style*="#CDD8E8"],[style*="#cdd8e8"],[style*="#9db4c7"],[style*="#9DB4C7"],
[style*="#b9c7d8"],[style*="#B9C7D8"],[style*="#e8edf2"],[style*="#dfe6ef"]{
  color:rgba(251,248,243,.96) !important;
}
/* ...but .contact-form-card is a genuinely light/white card (85 city pages'
   "(optional)" form-field label uses the same dim-white hex by mistake) --
   reassert a dark muted color there; (0,2,0) beats the (0,1,0) blanket rule above. */
.contact-form-card [style*="#9db4c7"],.contact-form-card [style*="#9DB4C7"]{color:var(--text-light) !important;}
/* footer and hero support text was the faintest type on the site */
.footer-link,.footer-col a,.footer-brand p,.footer-note,.footer-legal,.footer-bottom,
.footer-bottom a,.footer-copy,.footer-disclaimer,.mss-live-sub,.pill-sub,.hero .pill-sub,
.stat-label,.hero-stats .stat-label,.footer-city-link,
section[data-band="ink"] .city-ticker-pill,section[data-band="ink2"] .city-ticker-pill,
footer .city-ticker-pill{
  color:rgba(251,248,243,.95) !important;
}
/* .city-ticker-track a dropped from the list above — see the note by the
   other .city-ticker-track a rule near §37b; it only ever sits on a light
   band, so unconditional near-white text there was a contrast bug. */
/* brass on ink must be the light brass, never the dark one */
section[data-band="ink"] :is(.section-tag,.eyebrow,.sec-label,.hero-badge,.blog-cat,
.art-cat,.service-cta-link,.blog-read,.art-cta,.svc-readmore,.link-arrow,.rc-link),
section[data-band="ink2"] :is(.section-tag,.eyebrow,.sec-label,.hero-badge,.blog-cat,
.art-cat,.service-cta-link,.blog-read,.art-cta,.svc-readmore,.link-arrow,.rc-link),
.section-dark :is(.section-tag,.eyebrow,.sec-label,.blog-cat,.art-cat),
.hero :is(.section-tag,.eyebrow,.sec-label,.hero-badge),
footer :is(.section-tag,.eyebrow,.sec-label){color:#F5C77E !important;}

/* --- 37j. client-logo trust bar: never a blank box ------------------------
   Belt-and-suspenders for the marquee logos above: even if one somehow loads
   late, reserve real space so the box never reads as empty, and keep the
   logo itself from ever rendering at 0 width while unloaded. */
.clb-ph{min-width:64px;min-height:36px;}
.clb-ph img,.client-logo img{min-width:32px;min-height:20px;}

/* --------------------------------------------------------------------------
   39. SERVICES GRID — always a clean 3-per-row, never 4-then-2
   Sections like "Complete Commercial Security Solutions" ship exactly 6
   service cards; the shared editorial auto-fit grid (§13) can fit 4 columns
   at common viewport widths, splitting 6 cards into an uneven 4-then-2. A
   fixed 3-column grid keeps every 6-card (and 3-card) services section on
   two even rows sitewide, while still collapsing sensibly on small screens.
   -------------------------------------------------------------------------- */
.services-grid{grid-template-columns:repeat(3,1fr) !important;}
@media(max-width:860px){.services-grid{grid-template-columns:repeat(2,1fr) !important;}}
@media(max-width:560px){.services-grid{grid-template-columns:1fr !important;}}

/* --------------------------------------------------------------------------
   40. BRANDS / EQUIPMENT STRIP — "Professional-Grade Brands We Design &
   Install". Centralised here (was duplicated, inconsistently, in 8 pages'
   own inline <style> blocks — only the home page had real card/chip styling
   at all, the other 7 pages had none). Also fixes the section rendering
   fully transparent: the old per-page rule set `background:linear-gradient
   (...)` on a two-class selector, which (a) out-specifies the plain
   `.section-dark{background-color:var(--navy)}` rule so its own transparent
   fallback background-color won, and (b) had its gradient image stripped by
   the sitewide "bands are flat" rule (§34) — leaving nothing at all painted.
   Fix: let the section's data-band (already forced to "ink" for any
   .section-dark/.section-dark2 class, see transform.py step 4) supply the
   solid navy background the normal way; this block only adds layout/cards.
   -------------------------------------------------------------------------- */
.brands-strip-section.section-dark{padding:64px 0;}
.brands-strip-section.section-dark p{color:var(--text-ink-dim);}
.brands-strip-section.section-dark .section-head p{color:var(--text-ink-dim);}
.bsg{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-bottom:20px;}
.bsc{background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.1);border-radius:12px;
  padding:20px 20px 18px;transition:background .2s ease,border-color .2s ease,transform .2s ease;}
.bsc:hover{background:rgba(255,255,255,.1);border-color:rgba(223,161,62,.35);transform:translateY(-2px);}
.bsc:nth-child(4){grid-column:1;}
.bsc:nth-child(5){grid-column:2;}
.bsc-hd{display:flex;align-items:center;gap:12px;margin-bottom:14px;padding-bottom:12px;
  border-bottom:1px solid rgba(255,255,255,.1);}
.bsc-icon{width:36px;height:36px;border-radius:9px;background:rgba(223,161,62,.16);
  display:flex;align-items:center;justify-content:center;flex-shrink:0;color:var(--accent);}
.bsc-icon svg{width:19px;height:19px;}
.bsc-name{font-family:var(--f-display);font-weight:800;font-size:1.05rem;color:var(--text-ink);
  letter-spacing:.01em;}
.bsc-chips{display:flex;flex-wrap:wrap;gap:7px;}
.bschip{font-family:var(--f-body);font-size:.86rem;font-weight:600;color:rgba(251,248,243,.86);
  background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.13);border-radius:6px;
  padding:5px 12px;letter-spacing:.01em;text-transform:none;text-decoration:none;
  display:inline-flex;align-items:center;transition:background .2s,color .2s,border-color .2s;}
.bschip:hover{background:rgba(223,161,62,.18);border-color:rgba(223,161,62,.45);color:var(--accent);}
.brands-sample-note{display:flex;align-items:flex-start;gap:12px;background:rgba(223,161,62,.08);
  border:1px solid rgba(223,161,62,.28);border-radius:10px;padding:14px 18px;margin-bottom:18px;
  font-size:.9rem;color:rgba(251,248,243,.82);line-height:1.6;}
.brands-sample-note strong{color:var(--text-ink);}
@media(max-width:820px){
  .bsg{grid-template-columns:1fr 1fr;}
  .bsc:nth-child(4),.bsc:nth-child(5){grid-column:auto;}
}
@media(max-width:560px){.bsg{grid-template-columns:1fr;}}

/* --------------------------------------------------------------------------
   41. REVIEWS TEASER — "What Our Clients Say" (home + access-control). Was
   entirely hand-rolled inline styles: a big dark stat block squeezed into
   the same flex row as up to 4 narrow (260px) review cards, forcing small
   (.9rem) italic quote text to wrap densely — hard to read. The stat now
   banners across the full width above a clean, wider card grid; quotes grow
   to a normal, non-italic size with roomier line-height.
   -------------------------------------------------------------------------- */
.reviews-teaser-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));
  gap:22px;align-items:stretch;}
.reviews-teaser-stat{grid-column:1/-1;display:flex;flex-wrap:wrap;align-items:center;
  justify-content:center;gap:14px 28px;background:linear-gradient(135deg,var(--navy),var(--navy2));
  border-radius:14px;padding:22px 28px;}
.reviews-teaser-stat-num{font-family:var(--f-display);font-size:2.5rem;font-weight:800;
  color:var(--accent);line-height:1;}
.reviews-teaser-stat-stars{color:var(--accent);font-size:1.15rem;letter-spacing:3px;}
.reviews-teaser-stat-label{font-size:.92rem;color:rgba(255,255,255,.85);}
.reviews-teaser-card{background:var(--white);border:1px solid var(--border);border-radius:14px;
  padding:26px;transition:box-shadow .25s ease,transform .25s ease;}
.reviews-teaser-card:hover{box-shadow:0 10px 26px rgba(10,25,38,.1);transform:translateY(-2px);}
.reviews-teaser-stars{display:block;color:var(--brass-ink);font-size:1rem;letter-spacing:2px;
  margin-bottom:12px;}
.reviews-teaser-quote{font-size:1.02rem;color:var(--text);line-height:1.72;margin:0 0 16px;
  font-style:normal;}
.reviews-teaser-author{font-size:.87rem;font-weight:700;color:var(--navy);}

/* general case of the .reviews-teaser-stars problem just above: --accent is a light amber
   built for dark backdrops, but plenty of pages hardcode inline color:var(--accent) on
   small eyebrow labels/stat text inside an ordinary inline background:var(--white) card
   (office-location cards, stat cards, etc.) -- 2.2-2.4:1 contrast on the actual white card,
   regardless of which section band the card happens to sit in. Swap to the darker
   brass-ink amber used everywhere else in this file for accent-on-light-backgrounds. */
[style*="background:var(--white)"] [style*="color:var(--accent)"],
[style*="background: var(--white)"] [style*="color:var(--accent)"],
[style*="background:var(--off-white)"] [style*="color:var(--accent)"],
[style*="background: var(--off-white)"] [style*="color:var(--accent)"],
[style*="background:#fff"] [style*="color:var(--accent)"],
[style*="background: #fff"] [style*="color:var(--accent)"],
[style*="background:#FFF"] [style*="color:var(--accent)"],
[style*="background: #FFF"] [style*="color:var(--accent)"]{
  color:var(--brass-ink) !important;
}
/* same problem again with no explicit light-card wrapper at all: contractors' "Bidding a
   Project?"/"Common Questions" eyebrows hardcode inline color:var(--accent) directly on a
   section[data-band="paper"] section's own (near-white) background, no card in between.
   Any inline color:var(--accent) sitting directly in a light-band section needs the same
   brass-ink swap; the dark-island descendant rules elsewhere in this file are all higher
   specificity (they key off a class/attribute list on the dark ancestor) and still win
   where an accent-colored element genuinely sits on a nested dark background instead. */
section[data-band="paper"] [style*="color:var(--accent)"]:not([style*="background:"]),
section[data-band="white"] [style*="color:var(--accent)"]:not([style*="background:"]){
  color:var(--brass-ink) !important;
}
/* .legal-contact-box (privacy-policy/terms-of-service/blog/case-studies/industries'
   closing "Questions?" card) is itself a genuine dark island -- background:var(--navy)
   set by its own CSS class -- but it's nested inside a generic page wrapper carrying a
   literal inline style="background:var(--white)", so the light-card rule just above
   still catches its inline color:var(--accent) contact links and darkens them to
   brass-ink, same near-invisible dark-on-dark as any other dark-island miss. Give it
   back the light accent color, with the file's usual duplicated-class specificity bump
   so it reliably beats the (0,2,0) rule above regardless of source order. */
.legal-contact-box.legal-contact-box [style*="color:var(--accent)"]{
  color:var(--accent) !important;
}
/* alarm-systems' NDAA/TAA/FCC "COMPLIANT" pill badges: an inline color:var(--accent) span
   two levels deep inside an unclassed inline-style dark navy gradient div
   (background:linear-gradient(160deg,#0D2240,#081829)) nested in a section[data-band="paper"].
   The amber-safety-net rule above (section[data-band="paper"] [style*="color:var(--accent)"]
   :not([style*="background:"]), specificity (0,3,1)) doesn't know about that nested dark
   island and wrongly swaps it to brass-ink (dark-on-dark, same failure mode as any other
   dark-island miss) -- it beats this file's existing text-ink-dim descendant rule for the
   same dark-island list ((0,2,2), loses on the middle specificity column) but not this,
   scoped to the identical dark-island selector list with a duplicated-attribute bump to
   (0,4,1), clearing it regardless of source order. */
section[data-band] :is(.section-dark,.section-dark2,.cta-banner,.hero-panel,.faq-dark-section,
  .related-brands-section,.proc-cta,.cta-final,.final-cta,.industry-cta,.svc-cta,.blog-article-cta,
  .ab-cta,.pg-cta,.rv-cta,.con-div-card,
  [style*="background:var(--navy"],[style*="background: var(--navy"],[style*="background:var(--blue"],
  [style*="background:#08"],[style*="background:#0A"],[style*="background:#0a"],[style*="background:#0B"],
  [style*="background:#0b"],[style*="background:#0D"],[style*="background:#0d"],[style*="background:#10"],
  [style*="background:#12"],[style*="background:#11"],[style*="background:linear-gradient(135deg,#0"],[style*="background:linear-gradient(135deg,#4a0"],
  [style*="background:linear-gradient(160deg,#0"]) [style*="color:var(--accent)"][style*="color:var(--accent)"]{
  color:var(--accent) !important;
}

/* --------------------------------------------------------------------------
   42. UNIFIED SERVICES FAQ (faq-uni)
   Also applied to the home page (Sept 2026) — its 6 FAQ blocks used a
   different two-div click-to-toggle pattern; converted to this same
   component in transform.py (convert_home_faq). Hover state (gold text,
   matching the family-strip's active-card treatment) added at the same
   time, sitewide, per Mike's request.
   Every page under the Services nav menu had its Q&A block built
   independently and had drifted into five different looks: a JS-driven
   2-column grid with a small arrow icon (Commercial Security Systems), a
   2-column grid of cards that inverted to solid navy on open (8 pages), a
   single-column dark panel style (4 pages), a page with every answer shown
   open at once and no accordion (Access Control), and one more one-off
   (Vape Detection). Mike picked the single-column dark panel treatment
   (chosen from 3 live options at /faq-options) to replace all of them.
   transform.py normalises every page's markup down to this one component;
   this is its only styling, defined once. -------------------------------- */
/* .showcase-toggle-btn (city pages' photo-showcase toggle buttons, e.g. "View PTZ
   Camera Installation") is a genuine dark island -- background:var(--navy) set by its
   own page-local CSS class -- nested inside a .service-card, one of section 9's white-
   card classes. Each city page's own local <style> already carries a per-page dark-
   island fix for this exact class (see the transform.py-generated ":is(...,.showcase-
   toggle-btn,...) :is(h1-h6/strong/b/p-etc/a){color:...}" block), but that generated
   list never covers <span>, and its .btn-label is a span -- so the label text still
   fell through to the service-card's white-card "span{color:var(--text-light)}"
   descendant rule and went dark-on-navy. Give it back its own accent color here,
   sitewide, at high enough specificity to beat that card rule regardless of order. */
.showcase-toggle-btn.showcase-toggle-btn .btn-label{color:var(--accent) !important;}
.showcase-toggle-btn.showcase-toggle-btn:hover .btn-label,
.showcase-toggle-btn.showcase-toggle-btn.active .btn-label{color:#fff !important;}
.faq-uni-list{display:grid;gap:10px;}
.faq-uni{
  background:linear-gradient(135deg,var(--navy2),var(--navy)) !important;
  border:0 !important;border-left:4px solid var(--accent) !important;
  border-radius:8px !important;overflow:hidden;box-shadow:none !important;margin:0 !important;
}
.faq-uni summary{
  list-style:none;cursor:pointer;padding:18px 46px 18px 20px !important;position:relative;
  font-family:var(--f-display) !important;font-weight:700 !important;font-size:1.02rem !important;
  color:var(--text-ink) !important;background:none !important;border:0 !important;
}
.faq-uni summary::-webkit-details-marker{display:none;}
.faq-uni summary::after{
  content:"+";position:absolute;right:18px;top:50%;transform:translateY(-50%);
  font-size:1.4rem;font-weight:400;color:var(--accent) !important;line-height:1;background:none !important;border:0 !important;
}
.faq-uni[open] summary::after{content:"\2212";}
.faq-uni[open] summary{color:var(--accent2) !important;}
.faq-uni summary:hover{color:var(--accent) !important;}
.faq-uni summary:hover::after{color:var(--accent2) !important;}
.faq-uni-ans{
  padding:0 20px 20px !important;font-size:.94rem;line-height:1.7;
  color:rgba(255,255,255,.74) !important;background:none !important;border:0 !important;
}
/* .faq-uni is a genuine dark island (its own navy gradient background, set two rules
   up) but it's a <details> element, not a <section>, so it never appears in any of
   this file's section[data-band] dark-island class lists. When one sits inside a
   section[data-band="paper"|"white"] (true on the home page, where this component now
   lives per the comment above), the light-band text-color rules still win over the
   plain .faq-uni-ans color set just above -- worst of all is the classless-link rule
   (section 26), whose three chained :not() clauses push it to (0,4,2); this needs the
   file's usual duplicated-class specificity bump taken further than usual to clear it. */
.faq-uni-ans.faq-uni-ans.faq-uni-ans.faq-uni-ans.faq-uni-ans :is(strong,b,em,span,small){color:rgba(255,255,255,.92) !important;}
.faq-uni-ans.faq-uni-ans.faq-uni-ans.faq-uni-ans.faq-uni-ans a{color:var(--accent2) !important;text-decoration:underline;}
/* Mike (Sept 2026) screenshotted several city pages' main #faq section (Shelby
   Township, Mount Clemens, Sterling Heights, and likely others) with the answer
   text nearly invisible against the dark card -- same root cause as the two rules
   above, just one tag the original fix missed: the answer's actual body text sits
   in a bare <p itemprop="text"> (every .faq-uni-ans body sitewide is just
   p/strong/span/a -- audited), and section[data-band="white"|"paper"]'s
   :is(p,...){color:var(--text-light) !important} rule (BAND TEXT CONTRACT, above)
   matches that <p> directly and wins over plain inheritance from .faq-uni-ans's own
   color -- inheritance always loses to any explicitly-matching rule, !important or
   not. This is not a per-city-page bug: every .faq-uni FAQ answer on every page
   sitting inside a "white"/"paper" band section had this same washed-out text
   whenever it reached this deep, it just wasn't noticed until now. Same
   duplicated-class specificity bump as the two rules above, same restored color. */
.faq-uni-ans.faq-uni-ans.faq-uni-ans.faq-uni-ans.faq-uni-ans p{color:rgba(255,255,255,.74) !important;}
@media(max-width:768px){.faq-uni summary{font-size:.98rem !important;padding:16px 42px 16px 18px !important;}}

/* --------------------------------------------------------------------------
   43. UNIFIED FAMILY STRIP (family-strip)
   The "Our Michigan Security Family" cross-brand strip existed on 20 pages,
   each with its own hand-copied inline styles. Two real bugs: (1) 5 product
   pages + all 10 industries pages had literally copy-pasted the
   security-cameras version verbatim, so they claimed "Security Cameras —
   You Are Here" even when nowhere near that page; (2) alarm-systems' "You
   Are Here" card highlighted using its own brand red (#E74C3C), which fails
   contrast against its own tinted background — contrastfix.js correctly
   flagged it and silently rewrote the text to near-white, so the "you are
   here" cue disappeared entirely on that one page. Mike asked for every
   instance to look and behave like the correct security-cameras example.
   Fix: one shared component, and the active/highlighted card ALWAYS uses
   the accent gold treatment (border+tint+title colour) regardless of which
   brand is active — guaranteed contrast, and matches the example exactly.
   Icon colours (blue/gold/red) stay fixed per brand slot as a visual
   identity cue independent of which card is "active". -------------------- */
.family-strip{background:var(--navy2);padding:32px 0;}
.family-strip-inner{max-width:1300px;margin:0 auto;padding:0 24px;}
.family-strip-label{font-family:var(--f-display);font-weight:800;font-size:.75rem;letter-spacing:.12em;text-transform:uppercase;color:var(--accent);text-align:center;margin-bottom:20px;}
.family-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;}
.family-card{background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.12);border-radius:10px;padding:18px 20px;display:flex;align-items:center;gap:14px;text-decoration:none;transition:all .2s;}
.family-card:hover{border-color:var(--accent);background:rgba(223,161,62,.07);}
.family-icon{width:40px;height:40px;border-radius:9px;display:flex;align-items:center;justify-content:center;flex-shrink:0;}
.family-icon svg{width:20px;height:20px;fill:currentColor;}
.family-icon--blue{background:var(--blue);color:#fff;}
.family-icon--gold{background:var(--accent);color:var(--navy);}
.family-icon--red{background:var(--red);color:#fff;}
.family-title{font-family:var(--f-display);font-weight:800;color:#fff;font-size:1rem;}
.family-sub{color:rgba(255,255,255,.72);font-size:.82rem;margin-top:2px;}
.family-arrow{color:var(--accent);margin-left:auto;font-size:1rem;}
.family-card.is-active{background:rgba(223,161,62,.1);border-color:rgba(223,161,62,.4);cursor:default;}
.family-card.is-active:hover{background:rgba(223,161,62,.1);border-color:rgba(223,161,62,.4);}
.family-card.is-active .family-title{color:var(--accent);}
@media(max-width:680px){.family-grid{grid-template-columns:1fr;}}

/* --------------------------------------------------------------------------
   44. UNIFIED SERVICES CONTACT SECTION (svc-contact-*)
   Only 4 of the 15 Services-menu pages had a bottom lead-capture section at
   all, and each of those 4 used a different one-off layout (a 2-column
   form+sidebar on alarm-systems, a different 2-column layout with its own
   class names on access-control, a single-column form with no sidebar on
   commercial-security-systems, and a centered dark card with no sidebar on
   security-camera-repair). Mike picked the alarm-systems layout ("Alarm")
   to be the one standard, applied everywhere with page-specific copy/fields.
   This component is built from alarm-systems' original CSS (verified via a
   sitewide grep that its class names — .fcard/.ctw/.cside/.ibox/etc. — were
   used on exactly that one page, so nothing else on the site depends on the
   old names), renamed to a svc-contact-* namespace and rebuilt on the 2026
   design tokens so it matches every other component's fonts/radii/shadows
   instead of the legacy Barlow/--radius:6px values it shipped with. -------- */
.svc-contact-wrap{display:grid;grid-template-columns:1.15fr .85fr;gap:50px;align-items:start;}
.svc-contact-form{background:var(--white);border:1px solid var(--border);border-radius:14px;padding:38px 36px;box-shadow:var(--shadow);}
.svc-contact-form h3{font-family:var(--f-display);color:var(--text);margin-bottom:6px;font-size:1.55rem;font-weight:700;}
.svcf-sub{font-size:.9rem;color:var(--text-light);margin-bottom:26px;font-family:var(--f-body);}
.svcf-row{display:grid;grid-template-columns:1fr 1fr;gap:16px;}
.svcf-g{margin-bottom:17px;}
.svcf-g label{display:block;font-size:.81rem;font-weight:700;color:var(--text);margin-bottom:6px;letter-spacing:.02em;font-family:var(--f-body);}
.svcf-g label span{color:var(--red);}
.svcf-g input,.svcf-g select,.svcf-g textarea{width:100%;border:1.5px solid var(--border);border-radius:var(--radius-lg);padding:11px 14px;font-family:var(--f-body);font-size:.9rem;color:var(--text);outline:none;transition:border-color .2s;background:var(--white);}
.svcf-g input:focus,.svcf-g select:focus,.svcf-g textarea:focus{border-color:var(--blue);box-shadow:0 0 0 3px rgba(31,91,146,.12);}
.svcf-g textarea{resize:vertical;min-height:110px;}
.svcf-submit{width:100%;margin-top:6px;display:inline-flex;align-items:center;justify-content:center;gap:8px;background:var(--accent);color:var(--navy);font-family:var(--f-display);font-size:1rem;font-weight:800;letter-spacing:.03em;padding:14px 28px;border-radius:var(--radius-lg);border:none;cursor:pointer;transition:all .2s;}
.svcf-submit:hover{background:var(--accent2);transform:translateY(-2px);box-shadow:0 8px 24px rgba(223,161,62,.35);}
.svcf-note{font-size:.75rem;color:var(--text-light);margin-top:12px;text-align:center;font-family:var(--f-body);}
.svcf-ok{display:none;background:#d4edda;border:1px solid #c3e6cb;border-radius:var(--radius-lg);padding:15px 18px;color:#155724;font-weight:600;font-size:.89rem;margin-top:13px;font-family:var(--f-body);}
.svc-contact-side{display:flex;flex-direction:column;gap:15px;}
.svc-contact-info{background:var(--navy);border-radius:12px;padding:26px;color:#fff;}
.svci-row{display:flex;gap:11px;align-items:flex-start;margin-bottom:13px;padding-bottom:13px;border-bottom:1px solid rgba(255,255,255,.09);}
.svci-row:last-child{border-bottom:none;margin-bottom:0;padding-bottom:0;}
.svci-dot{width:8px;height:8px;background:var(--accent);border-radius:50%;margin-top:6px;flex-shrink:0;}
/* §37a's "section[data-band=paper] :is(h1..h6){color:var(--text)!important}"
   (an attribute selector + an :is() list) out-specifies a plain ".svc-contact-info h4"
   even though this card is its own dark-navy island floating inside a paper
   section — so its heading/label text was landing dark-on-navy. Scoping
   through the .svc-contact-side wrapper adds the extra class needed to win. */
.svc-contact-side .svc-contact-info h4{color:var(--accent) !important;font-size:1.08rem;margin-bottom:15px;font-family:var(--f-display);font-weight:700;}
.svc-contact-side .svci-row h5{color:#fff !important;font-size:.9rem;font-weight:700;margin-bottom:2px;font-family:var(--f-body);}
.svc-contact-side .svci-row p{font-size:.81rem;color:rgba(255,255,255,.78) !important;margin:0;font-family:var(--f-body);}
.svc-contact-side.svc-contact-side .svc-contact-info .svci-row p a{color:rgba(255,255,255,.78) !important;text-decoration:none !important;}
/* .cside/.ibox/.irow (/alarm-systems/ only) are the ORIGINAL, pre-migration
   names for this exact component — see §"CONTACT PANEL" comment above: this
   page's own layout was picked as the sitewide standard and rebuilt as
   .svc-contact-*, but this one page's markup was never switched over to the
   new class names, so it kept the legacy names with none of the above
   contrast fixes applied — same dark-navy-card-in-a-paper-section clash. */
.cside .ibox h4{color:var(--accent) !important;font-size:1.08rem;margin-bottom:15px;font-family:var(--f-display);font-weight:700;}
.cside .irow h5{color:#fff !important;font-size:.9rem;font-weight:700;margin-bottom:2px;font-family:var(--f-body);}
.cside .irow p{font-size:.81rem;color:rgba(255,255,255,.78) !important;margin:0;font-family:var(--f-body);}
.cside.cside .ibox .irow p a{color:rgba(255,255,255,.78) !important;text-decoration:none !important;}
/* .contact-split-left (home + about/contact/contractors/reviews/manufacturers/
   projects/image-license "Request Your Free Assessment" panel, 8 pages) is a
   dark navy gradient box declared in each page's own inline <style> block —
   background:linear-gradient(160deg,#0d2240,#081829) — sitting inside a
   section[data-band="paper"|"white"]. Same class of bug as .hq-strip/
   .contact-left: transform.py's band sniffer only reads inline
   section-level backgrounds, so it never saw this panel's own dark
   background, and the sitewide "literal light colours on a paper/white
   ground" rule (§23, which already lists .csl-detail-label/.csl-detail-val
   among its ~29 classes) was winning over the page's own light inline
   colors for those two — while .csl-logo/.csl-phone-label/.csl-phone-sub/
   .csl-trust-badge span (not in that list) were instead losing to the
   plain sitewide body-text-color default. Re-assert light text here with
   section[data-band]-matching specificity, using the same
   [data-band="X"][data-band="X"] duplication trick as the .hq-strip fix to
   clear the §23 rule's (0,2,2) effective specificity (its :is() list
   contains ".clb-hdr p", a two-compound argument that quietly raises the
   whole rule beyond what it looks like). */
section[data-band="paper"][data-band="paper"] .contact-split-left
  :is(.csl-logo,.csl-phone-label,.csl-phone-sub,.csl-detail-label,.csl-detail-val),
section[data-band="white"][data-band="white"] .contact-split-left
  :is(.csl-logo,.csl-phone-label,.csl-phone-sub,.csl-detail-label,.csl-detail-val){
  color:rgba(255,255,255,.84) !important;
}
section[data-band="paper"][data-band="paper"] .contact-split-left .csl-detail-val a,
section[data-band="white"][data-band="white"] .contact-split-left .csl-detail-val a{
  color:rgba(255,255,255,.88) !important;text-decoration:none !important;
}
section[data-band="paper"][data-band="paper"] .contact-split-left .csl-trust-badge span,
section[data-band="white"][data-band="white"] .contact-split-left .csl-trust-badge span{
  color:rgba(255,255,255,.78) !important;
}
/* the "Toll Free 24-Hr Emergency" link carries its own inline
   style="color:var(--blue)" (meant for a light background elsewhere) which
   measures only 2.40:1 on this panel's dark gradient — an !important rule in
   the stylesheet beats a non-important inline style regardless of
   specificity, so this alone is enough to fix it without touching the
   page's markup. */
.contact-split-left a.csl-phone-sub{color:var(--accent2) !important;}
/* contractors' "4.9 [star] Google Rated" link inside .csl-trust-badge carries
   style="color:inherit" so it can pick up whatever this panel needs -- but the sitewide
   "plain light-band link" rule (section[data-band="paper"] a:not([class])..., a 3-way
   :not() chain that reaches (0,4,2) specificity) matches this classless anchor directly and
   always outranks inheriting from its .csl-trust-badge span parent (which the fix above
   already colors correctly), regardless of that parent rule's own specificity. Give the
   anchor itself the last word, with one extra class repeat to clear the :not() chain. */
section[data-band="paper"][data-band="paper"] .contact-split-left.contact-split-left a[style*="color:inherit"],
section[data-band="white"][data-band="white"] .contact-split-left.contact-split-left a[style*="color:inherit"]{
  color:rgba(255,255,255,.78) !important;
}
/* .vi-usecase (alarm-monitoring, gate-perimeter-access, video-intercom,
   wireless-networks, starlink-business-internet) and .vp-usecase
   (vape-detection-systems) are a recurring "problem/solution" 3-up card —
   always a dark navy gradient box (background:linear-gradient(135deg,#0D2240,
   #12294a), sometimes with its own !important) declared in each page's own
   inline <style> block, with h3/p/span/strong given matching light colors
   there. But these cards commonly sit inside a section[data-band="paper"|
   "white"] (they're meant to punctuate a light section with a dark callout),
   and the sitewide "headings/body text on a light band" rules
   (section[data-band="paper"|"white"] :is(h1..h6){color:var(--text)!important}
   and the :is(p,li,...) equivalent) have specificity (0,1,2) — enough to beat
   the page's own ".vi-usecase h3{color:#fff!important}" (0,1,1) regardless of
   load order. Re-declare with one more class-level qualifier (the same
   .foo.foo duplication used elsewhere in this file) to reach (0,2,1) and win
   reliably, restoring the light text these dark cards need on every band. */
.vi-usecase.vi-usecase :is(h1,h2,h3,h4,h5,h6){color:#fff !important;}
.vi-usecase.vi-usecase p{color:#b9c7d8 !important;}
.vi-usecase.vi-usecase :is(span,strong,div,li){color:#cdd9e8 !important;}
/* .vi-usecase a needs to beat section[data-band="paper"] a:not([class]):not([style*=
   "background:"]):not([style*="color:rgba(255,255,255"]){color:var(--blue)!important}
   (§ light-band default link color) — that selector's three :not() clauses each add
   their own specificity, reaching (0,4,2), so a plain .vi-usecase.vi-usecase a at
   (0,2,1) silently lost (the same :is()/:not() specificity trap noted elsewhere in
   this file, here via :not() instead of :is()). Duplicate the class enough times to
   clear it outright rather than race a tie. */
.vi-usecase.vi-usecase.vi-usecase.vi-usecase.vi-usecase a{color:#F5A623 !important;}
.vp-usecase.vp-usecase :is(h1,h2,h3,h4,h5,h6){color:#fff !important;}
.vp-usecase.vp-usecase p{color:#b9c7d8 !important;}
.vp-usecase.vp-usecase :is(span,strong,div,li){color:#cdd9e8 !important;}
.vp-usecase.vp-usecase.vp-usecase.vp-usecase.vp-usecase a{color:#F5A623 !important;}
.svc-quicklinks{display:flex;flex-direction:column;gap:9px;}
.svc-ql{display:flex;align-items:center;gap:11px;padding:11px 14px;background:var(--off-white);border:1px solid var(--border);border-radius:var(--radius-lg);transition:all .2s;text-decoration:none;color:var(--text);}
.svc-ql:hover{border-color:var(--blue);background:rgba(31,91,146,.05);}
.svc-ql svg{width:18px;height:18px;fill:var(--blue);flex-shrink:0;}
.svc-ql span{font-weight:600;font-size:.86rem;font-family:var(--f-body);}
@media(max-width:1080px){.svc-contact-wrap{grid-template-columns:1fr;}}
@media(max-width:768px){.svcf-row{grid-template-columns:1fr;}.svc-contact-form{padding:26px 22px;}}

/* ==========================================================================
   46. BLOG / CASE-STUDY ARTICLE LAYOUT (Sept 2026)
   The 38 blog posts + 6 case studies keep their own pre-2026 page-level
   <style> block and their #site-header/.hamburger markup depends on rules
   inside it that have no equivalent anywhere else on the site, so it is
   left in place rather than stripped. Because this stylesheet (mss-2026.css)
   loads AFTER that inline block, plain (non-!important) rules below already
   win the cascade on equal specificity — confirmed by computed-style checks
   on .article/.art-back/.art-cat/.art-meta/.art-body h2/li, all of which
   take effect with no !important needed. Two places do need it:
   1) .art-cta (the big bottom call-out box) collides with a sitewide
      "small brass link" rule that also targets a class named .art-cta
      (line ~668, !important) — without an equally-!important, higher-
      specificity override scoped to .article .art-cta, that generic rule
      strips the box down to a bare inline mono link and (combined with the
      dark-assumption cleanup elsewhere removing the old white-on-navy text
      colors) left the CTA heading rendering literally invisible: white
      text with no background. Every property that rule sets has to be
      re-asserted here with !important.
   2) .mss-related-cluster a.rc-link collides with the same sitewide rule
      (.rc-link is in its selector list too) — its background/border/
      padding need !important or the "related articles" cards render as
      bare text with no card styling.
   NOTE: 2 of the 22 .art-cta boxes (both case studies) already carry their
   own complete inline background/color styling and render correctly on
   their own — the :not([style*="background:"]) guard below leaves those
   two alone so this rule doesn't clobber a working custom CTA box with the
   forced navy treatment (which was making their own gold "or call
   586-466-4490" link invisible: navy-on-navy).
   ========================================================================== */
.article{max-width:780px;margin:0 auto;padding:clamp(96px,11vw,140px) 24px 64px;}
.article h1{font-size:clamp(1.9rem,4vw,2.7rem);line-height:1.16;margin:0 0 14px;color:var(--text);}
.art-back{margin-bottom:22px;}
.art-cat{margin-bottom:16px;}
.art-meta{display:block;font-family:var(--f-body);font-size:.9rem;color:var(--text-light);border-bottom:1px solid var(--border);padding-bottom:20px;margin-bottom:32px;}
.art-body h2{font-size:clamp(1.4rem,2.6vw,1.9rem);margin:1.7em 0 .55em;color:var(--text);}
.art-body h3{font-size:clamp(1.14rem,1.9vw,1.38rem);margin:1.5em 0 .5em;color:var(--text);}
.art-body ul{margin:0 0 18px 24px;}
.art-body li{margin-bottom:8px;line-height:1.7;color:var(--text);}
.art-body strong{color:var(--text);}
.article .art-cta{
  display:block !important;
  border:0 !important;border-radius:14px !important;padding:clamp(26px,4vw,36px) !important;
  margin:44px 0 0 !important;text-align:center !important;
  font-family:inherit !important;font-size:inherit !important;letter-spacing:normal !important;
  text-transform:none !important;color:inherit !important;
}
.article .art-cta:not([style*="background:"]){
  background:linear-gradient(135deg,var(--navy),var(--navy2)) !important;
}
.article .art-cta:not([style*="background:"]) h3{color:#fff !important;font-family:var(--f-display) !important;font-weight:800 !important;font-size:1.5rem !important;letter-spacing:normal !important;text-transform:none !important;margin-bottom:8px !important;}
.article .art-cta:not([style*="background:"]) p{color:rgba(255,255,255,.85) !important;font-family:var(--f-body) !important;font-size:1.05rem !important;letter-spacing:normal !important;text-transform:none !important;margin-bottom:18px !important;}
.article .art-cta:not([style*="background:"]) a{
  display:inline-block !important;background:var(--accent) !important;color:var(--navy) !important;
  font-family:var(--f-display) !important;font-weight:800 !important;font-size:1.05rem !important;
  letter-spacing:.01em !important;text-transform:none !important;padding:13px 30px !important;
  border-radius:var(--radius-lg) !important;text-decoration:none !important;
}
.article .art-cta:not([style*="background:"]) a:hover{background:var(--accent2) !important;}
/* The 2 self-styled .art-cta boxes (own inline background) still need their
   own text reasserted: the broad section[data-band="paper"] :is(h1..h6)
   {color:var(--text)!important} rule and similar body-text rules outrank
   their plain (non-!important) inline color, which otherwise makes the
   heading/paragraph go dark-on-dark. The "or call 586-466-4490" phone link
   has no background of its own, so it isn't caught by the anchor rule
   above and needs the same treatment, matched to its actual inline gold. */
.article .art-cta[style*="background:"] :is(h2,h3){color:#fff !important;}
.article .art-cta[style*="background:"] p{color:rgba(255,255,255,.92) !important;}
.article .art-cta[style*="background:"] a:not([style*="background:"]){color:#fff !important;background:none !important;text-decoration:underline !important;}
.article .art-cta[style*="background:"] div{color:#fff !important;}
/* Same collision as note (1) above hits the box's own background too: the
   sitewide "small brass link" rule (~line 672) sets background:none
   !important on every .art-cta, self-styled or not, and CSS has no way to
   say "put back whatever this element's own inline background was" — so
   the 2 known self-styled boxes (both using this exact blue gradient) are
   named explicitly here. A future .art-cta with a different custom
   gradient will need its own line added the same way. */
.article .art-cta[style*="background:linear-gradient(135deg,#1155CC,#0d3fa0)"]{
  background:linear-gradient(135deg,#1155CC,#0d3fa0) !important;
}
.mss-related-cluster{max-width:820px;margin:8px auto 0;padding:0 24px;}
.mss-related-cluster .rc-inner{background:var(--off-white);border:1px solid var(--border);border-radius:14px;padding:28px 28px 24px;}
.mss-related-cluster h3{font-size:1.35rem;margin:0 0 4px;color:var(--text);}
.mss-related-cluster .rc-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px 16px;margin-top:14px;}
.mss-related-cluster a.rc-link{
  display:flex !important;align-items:center;gap:9px;text-decoration:none !important;
  color:var(--text) !important;font-family:var(--f-body) !important;font-weight:600 !important;
  font-size:.95rem !important;text-transform:none !important;letter-spacing:normal !important;
  padding:10px 14px !important;border-radius:9px !important;background:var(--white) !important;border:1px solid var(--border) !important;
}
.mss-related-cluster a.rc-link:hover{border-color:var(--accent) !important;}
.mss-related-cluster .rc-svc{margin-top:16px;padding-top:15px;border-top:1px solid var(--border);display:flex;flex-wrap:wrap;gap:9px;align-items:center;}
@media(max-width:640px){.mss-related-cluster .rc-grid{grid-template-columns:1fr;}}
@media(max-width:640px){.article{padding-top:clamp(88px,20vw,110px);}}

/* ==========================================================================
   47. HUB-PAGE HAMBURGER LEAKING ONTO DESKTOP (Sept 2026)
   blog/index.html, case-studies/index.html and industries/index.html each
   carry a leftover, un-media-queried "nav{display:none;}.hamburger{display:
   flex;}" line in their legacy <style> block (found live on the site today,
   not introduced by this redesign) that permanently forces the mobile
   hamburger icon on next to the full desktop nav at every viewport width,
   including desktop. The real desktop nav lives in a different element than
   the bare <nav> the old rule targets, so it stays visible either way — the
   only visible symptom is the stray hamburger icon floating in the header
   next to "Free Assessment". Restoring the normal mobile-only behavior.
   ========================================================================== */
@media(min-width:769px){.hamburger{display:none !important;}}

/* ==========================================================================
   48. CITY GRID — replaces the auto-scrolling "Serving NN+ Michigan
   Communities" ticker (Sept 2026, v125)
   Mike: the marquee was cutting off mid-row on ~101 pages (see
   convert_city_ticker in transform.py for the full root-cause writeup —
   mss-2026.css §18's overflow guard capped .city-ticker-track's box width,
   which broke its translateX(-50%) marquee-loop math and clipped most of
   the list) and he didn't like the moving-ticker look regardless. Replaced
   with a static, wrapped grid — every city always fully visible, nothing to
   animate or overflow, so the whole bug class is gone for good. Every real
   occurrence of this component lives inside .map-section, which is already
   flattened to a plain off-white band sitewide, so one light-card treatment
   is correct everywhere (verified: no dark-band occurrence exists).
   ========================================================================== */
.city-grid-section{
  max-width:1100px;margin:0 auto;text-align:center;
  background:#fff;border:1px solid rgba(8,24,41,0.08);border-radius:16px;
  padding:clamp(28px,4vw,44px) clamp(20px,4vw,36px);
  box-shadow:0 2px 14px rgba(8,24,41,0.05);
}
.city-grid-label{
  font-family:var(--f-mono);font-size:.72rem;font-weight:600;
  letter-spacing:.16em;text-transform:uppercase;color:var(--brass-ink);
  margin:0 0 22px;padding-top:14px;position:relative;display:inline-block;
}
.city-grid-label::before{
  content:"";position:absolute;top:0;left:50%;transform:translateX(-50%);
  width:36px;height:2px;background-color:var(--accent);
}
.city-grid{display:flex;flex-wrap:wrap;justify-content:center;gap:9px;}
.city-chip{
  display:inline-flex;align-items:center;background:var(--off-white);
  border:1px solid rgba(8,24,41,0.09);border-radius:8px;padding:9px 16px;
  font-family:'Barlow Condensed',sans-serif;font-size:.94rem;font-weight:700;
  color:var(--navy);text-decoration:none;letter-spacing:.02em;
  white-space:nowrap;transition:all .2s;
}
.city-chip:hover{
  background:rgba(245,166,35,0.12);border-color:var(--accent);
  color:var(--navy);transform:translateY(-1px);
}
@media(max-width:640px){
  .city-grid-section{border-radius:12px;}
  .city-chip{font-size:.86rem;padding:8px 13px;}
}

/* CITY NOTE — the 79 city pages' short-statement replacement for the grid
   above (Mike, same day: the city pages already list every city in a
   separate "55 Cities · 13 Counties" section right above this one, so a
   second full list here was pure duplication — see the FOLLOW-UP comment
   by CITY_TICKER_PILL_RE in transform.py). Deliberately NOT a card/box like
   .city-grid-section — Mike asked for "a simple statement", so this is
   just a centered line of text with the same small gold accent dash used
   sitewide for section eyebrows, no border or background of its own. */
.city-note{
  text-align:center;max-width:640px;margin:0 auto;padding:14px 20px 0;
  font-family:'Barlow Condensed',sans-serif;font-size:1.05rem;font-weight:600;
  color:var(--brass-ink);position:relative;
}
.city-note::before{
  content:"";display:block;width:36px;height:2px;background-color:var(--accent);
  margin:0 auto 16px;
}
