/* R&S Roofing — preview. Navy/gold pulled from the R&S logo. */
:root{
  --navy:#14355B; --navy-deep:#0E2A47; --navy-ink:#0A1F36;
  --gold:#F8DC62; --gold-deep:#E3BC35;
  --paper:#FFFFFF; --mist:#F4F6F9; --line:#E3E8EF;
  --ink:#182433; --mut:#5B6B7E;
  --head:"Barlow Condensed",sans-serif; --body:"Inter",sans-serif;
}
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
body{font-family:var(--body);color:var(--ink);background:var(--paper);line-height:1.6}
img{max-width:100%;display:block}
h2{font-family:var(--head);font-weight:700;font-size:clamp(30px,4.2vw,44px);line-height:1.08;letter-spacing:.01em;text-transform:uppercase;color:var(--navy-ink)}
.kicker{font-family:var(--head);font-weight:600;letter-spacing:.28em;text-transform:uppercase;font-size:13px;color:var(--gold-deep);margin-bottom:8px}
.wrap{max-width:1140px;margin:0 auto;padding:0 22px}

/* ---------- nav ---------- */
#nav{position:fixed;inset:0 0 auto 0;z-index:50;transition:background .3s,box-shadow .3s;padding:10px 0}
#nav.solid{background:rgba(10,31,54,.96);box-shadow:0 2px 18px rgba(0,0,0,.25)}
.nav-inner{max-width:1240px;margin:0 auto;padding:0 22px;display:grid;grid-template-columns:1fr auto 1fr;align-items:center}
.nav-links{display:flex;gap:26px;align-items:center}
.nav-left{justify-content:flex-end;padding-right:34px}
.nav-right{justify-content:flex-start;padding-left:34px}
.nav-links a{color:#fff;text-decoration:none;font-family:var(--head);font-weight:600;letter-spacing:.14em;text-transform:uppercase;font-size:14.5px;opacity:.92}
.nav-links a:hover{opacity:1;color:var(--gold)}
.nav-logo img{height:42px;width:auto}
a.nav-cta{background:var(--gold);color:var(--navy-ink)!important;padding:9px 16px;border-radius:4px;font-weight:700;opacity:1}
a.nav-cta:hover{background:#fff}
.nav-burger{display:none;background:none;border:0;cursor:pointer;padding:8px;justify-self:end}
.nav-burger span{display:block;width:24px;height:2.5px;background:#fff;margin:5px 0;border-radius:2px}
.nav-mobile{display:none;flex-direction:column;gap:4px;padding:12px 22px 18px;background:rgba(10,31,54,.98)}
.nav-mobile a{color:#fff;text-decoration:none;font-family:var(--head);font-weight:600;text-transform:uppercase;letter-spacing:.12em;padding:10px 0;border-bottom:1px solid rgba(255,255,255,.08)}
.nav-mobile a.nav-cta{border:0;text-align:center;margin-top:8px;border-radius:4px}
#navMobile.open{display:flex}

/* ---------- hero ---------- */
.hero{position:relative;height:100svh;min-height:620px;overflow:hidden;display:flex;align-items:center;justify-content:center}
.hero-video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
/* photo hero: 3 stills, slow zoom + crossfade. Cannot shake. */
.hero-stills{position:absolute;inset:0;overflow:hidden}
.hero-stills i{position:absolute;inset:0;background-position:center;background-size:cover;
  opacity:0;animation:fadeSeq 27s linear infinite,kb 27s ease-in-out infinite}
.hero-stills i:nth-child(1){background-image:url('media/hero-a.webp');animation-delay:0s,0s}
.hero-stills i:nth-child(2){background-image:url('media/hero-b.webp');animation-delay:9s,9s}
.hero-stills i:nth-child(3){background-image:url('media/hero-c.webp');animation-delay:18s,18s}
@keyframes fadeSeq{0%{opacity:0}4%{opacity:1}30%{opacity:1}37%{opacity:0}100%{opacity:0}}
@keyframes kb{0%{transform:scale(1.02)}37%{transform:scale(1.12)}100%{transform:scale(1.12)}}
.hero-overlay{position:absolute;inset:0;background:linear-gradient(180deg,rgba(10,31,54,.55) 0%,rgba(10,31,54,.38) 45%,rgba(10,31,54,.62) 100%)}
.hero-content{position:relative;z-index:2;text-align:center;padding:0 20px;display:flex;flex-direction:column;align-items:center}
/* hero logo: official reversed white+gold vector straight on the video.
   Legibility comes from the video scrim (.hero-overlay) — no shadow/glow per brand rules. */
.hero-plate{display:flex;justify-content:center;padding:0}
.hero-plate img{width:min(400px,72vw);height:auto}
.hero-tag{margin-top:22px;color:#fff;font-weight:500;font-size:clamp(14px,1.6vw,17px);letter-spacing:.04em;text-shadow:0 1px 8px rgba(0,0,0,.4)}
.hero-loc{margin-top:8px;color:var(--gold);font-family:var(--head);font-weight:600;letter-spacing:.34em;font-size:13px}
.hero-cta{margin-top:30px;display:inline-block;color:#fff;text-decoration:none;font-family:var(--head);font-weight:600;letter-spacing:.2em;text-transform:uppercase;font-size:15px;border:1.5px solid rgba(255,255,255,.85);padding:15px 34px;border-radius:3px;transition:all .25s}
.hero-cta:hover{background:var(--gold);border-color:var(--gold);color:var(--navy-ink)}
.hero-scroll{position:absolute;bottom:26px;left:50%;transform:translateX(-50%);z-index:2;color:#fff;text-decoration:none;font-family:var(--head);letter-spacing:.3em;text-transform:uppercase;font-size:11px;opacity:.85;text-align:center}
.hero-scroll i{display:block;width:1.5px;height:34px;background:linear-gradient(#fff,transparent);margin:8px auto 0;animation:drop 1.8s infinite}
@keyframes drop{0%{transform:scaleY(0);transform-origin:top}45%{transform:scaleY(1);transform-origin:top}55%{transform:scaleY(1);transform-origin:bottom}100%{transform:scaleY(0);transform-origin:bottom}}

/* ---------- trust bar ---------- */
.trust{background:var(--navy-deep);color:#fff;padding:22px 0}
.trust-inner{max-width:1140px;margin:0 auto;padding:0 22px;display:flex;justify-content:space-between;gap:18px;flex-wrap:wrap}
.trust-item{text-align:center;flex:1;min-width:130px}
.trust-item b{display:block;font-family:var(--head);font-size:26px;font-weight:700;color:var(--gold);letter-spacing:.02em}
.trust-item span{font-size:12.5px;opacity:.85}

/* ---------- services ---------- */
.services{padding:88px 0 78px;background:var(--paper)}
.svc-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:26px;margin-top:38px}
.svc-card{background:#fff;border:1px solid var(--line);border-radius:12px;overflow:hidden;transition:box-shadow .25s,transform .25s}
.svc-card:hover{box-shadow:0 16px 44px rgba(14,42,71,.14);transform:translateY(-3px)}
.svc-img{aspect-ratio:16/10;overflow:hidden}
.svc-img img{width:100%;height:100%;object-fit:cover}
.svc-card h3{font-family:var(--head);font-size:24px;font-weight:700;text-transform:uppercase;letter-spacing:.03em;color:var(--navy);padding:18px 20px 0}
.svc-card p{padding:8px 20px 0;color:var(--mut);font-size:14.5px}
.svc-link{display:inline-block;margin:14px 20px 20px;color:var(--navy);font-weight:600;font-size:14px;text-decoration:none;border-bottom:2px solid var(--gold)}
.svc-link:hover{color:var(--gold-deep)}

/* ---------- about ---------- */
.about{background:var(--mist);padding:0}
.about-grid{display:grid;grid-template-columns:1fr 1fr;min-height:560px}
.about-img{overflow:hidden}
.about-img img{width:100%;height:100%;object-fit:cover}
.about-copy{padding:70px 64px;display:flex;flex-direction:column;justify-content:center;align-items:flex-start}
.about-copy p{color:var(--mut);margin-top:14px;max-width:52ch}
.checks{list-style:none;margin:22px 0 28px}
.checks li{padding:7px 0 7px 34px;position:relative;font-weight:500;color:var(--ink)}
.checks li:before{content:"";position:absolute;left:0;top:9px;width:20px;height:20px;border-radius:50%;background:var(--gold);
 -webkit-mask:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="black" d="M9 16.2 4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4z"/></svg>') center/14px no-repeat;
 mask:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="black" d="M9 16.2 4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4z"/></svg>') center/14px no-repeat;
 background-color:var(--gold-deep)}
.btn-solid{display:inline-block;background:var(--navy);color:#fff;text-decoration:none;font-family:var(--head);font-weight:600;letter-spacing:.16em;text-transform:uppercase;font-size:14.5px;padding:15px 28px;border-radius:4px;transition:background .25s}
.btn-solid:hover{background:var(--navy-deep)}

/* ---------- process / insurance ---------- */
.process{background:var(--mist);padding:84px 0}
.process-lead{max-width:66ch;color:var(--mut);margin-top:12px;font-size:15px}
.steps{list-style:none;counter-reset:st;display:grid;grid-template-columns:repeat(5,1fr);gap:20px;margin-top:40px}
.steps li{counter-increment:st;position:relative;padding-top:52px}
.steps li:before{content:counter(st);position:absolute;top:0;left:0;width:38px;height:38px;border-radius:50%;
  background:var(--navy);color:var(--gold);font-family:var(--head);font-weight:700;font-size:18px;
  display:flex;align-items:center;justify-content:center}
.steps li:after{content:"";position:absolute;top:19px;left:46px;right:-20px;height:2px;background:#dfe5ec}
.steps li:last-child:after{display:none}
.steps b{display:block;font-family:var(--head);font-size:17px;font-weight:700;text-transform:uppercase;
  letter-spacing:.02em;color:var(--navy-ink);margin-bottom:5px}
.steps span{font-size:13.5px;line-height:1.6;color:var(--mut)}

/* ---------- work ---------- */
.work{padding:88px 0 0;background:var(--paper)}
.work-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-top:38px}
.work-grid img{width:100%;height:260px;object-fit:cover}

/* ---------- reviews ---------- */
.reviews{background:var(--navy-deep);color:#fff;padding:84px 0}
.reviews h2{color:#fff}
.rev-head{display:flex;align-items:center;gap:30px;flex-wrap:wrap}
.rev-head .kicker{margin-bottom:4px}
.rev-score{text-align:center;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.14);border-radius:12px;padding:18px 26px}
.rev-score b{font-family:var(--head);font-size:44px;font-weight:700;color:var(--gold);display:block;line-height:1}
.rev-score span{color:var(--gold);letter-spacing:.2em;font-size:15px;display:block;margin-top:4px}
.rev-score em{font-style:normal;font-size:12px;opacity:.8;display:block;margin-top:6px}
/* ---- scrolling review wall ---- */
.rv-wall{margin-top:38px;position:relative;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent)}
.rv-row{overflow:hidden;padding:9px 0}
/* margin-right (not gap) so every card occupies an identical 366+18 slot —
   that makes translateX(-50%) land exactly on the duplicate = seamless.
   NO will-change here: it pins a ~6000px composited layer per row, which
   browsers drop under memory pressure (row intermittently renders blank). */
.rv-track{display:flex;width:max-content;backface-visibility:hidden}
/* BOTH rows scroll left and start at translate 0, so cards always fill from the
   first frame. A right-scrolling row must start shifted off-screen and pull
   cards in from the left edge each cycle, which flashes blank in Safari — that
   was the "row 2 not showing right away" bug. Different speed + a negative delay
   (phase offset) keeps the two rows visually distinct. */
.rv-row--1 .rv-track{animation:marquee-l 62s linear infinite}
.rv-row--2 .rv-track{animation:marquee-l 88s linear infinite;animation-delay:-31s}
.rv-wall:hover .rv-track{animation-play-state:paused}
/* THREE copies; travelling 33.3333% = exactly one set → seamless loop with a
   spare set off-screen to cover ultrawide viewports. */
@keyframes marquee-l{from{transform:translate3d(0,0,0)}to{transform:translate3d(-33.3333%,0,0)}}
.rv-card{flex:0 0 366px;margin:0 18px 0 0;background:rgba(255,255,255,.055);border:1px solid rgba(255,255,255,.13);
  border-radius:13px;padding:22px 24px;display:flex;flex-direction:column;transition:border-color .25s,background .25s}
.rv-card:hover{background:rgba(255,255,255,.09);border-color:rgba(248,220,98,.45)}
.rv-stars{color:var(--gold);letter-spacing:.14em;font-size:13px;margin-bottom:10px}
.rv-card blockquote{font-size:14.5px;line-height:1.62;color:#eef2f7;flex:1}
.rv-card figcaption{margin-top:14px;font-size:12.5px;font-weight:600;color:#fff}
.rv-card figcaption span{display:block;font-weight:400;opacity:.6;font-size:11.5px;margin-top:2px}
.rv-foot{text-align:center;margin-top:26px}
.rv-link{color:var(--gold);text-decoration:none;font-family:var(--head);font-weight:600;
  letter-spacing:.12em;text-transform:uppercase;font-size:14px;border-bottom:1px solid rgba(248,220,98,.4);padding-bottom:3px}
.rv-link:hover{color:#fff;border-color:#fff}
@media(prefers-reduced-motion:reduce){.rv-track{animation:none}.rv-row{overflow-x:auto}}

/* ---------- areas ---------- */
.areas{padding:84px 0;background:var(--paper)}
.areas-grid{display:grid;grid-template-columns:1fr 1fr;gap:34px;margin-top:34px}
.areas-grid>div{background:var(--mist);border-radius:12px;padding:30px 34px}
.areas-grid h3{font-family:var(--head);font-size:22px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--navy)}
.areas-grid p{margin-top:10px;color:var(--mut);font-size:14.5px;line-height:1.9}

/* ---------- cta ---------- */
.cta{background:linear-gradient(140deg,var(--navy) 0%,var(--navy-deep) 100%);color:#fff;padding:84px 0}
.cta-inner{max-width:1140px;margin:0 auto;padding:0 22px;display:grid;grid-template-columns:1fr 1fr;gap:54px;align-items:center}
.cta-copy h2{color:#fff}
.cta-copy p{opacity:.85;margin-top:10px}
.cta-phone{display:inline-block;margin-top:22px;color:var(--gold);text-decoration:none;font-family:var(--head);font-weight:700;font-size:clamp(34px,4vw,46px);letter-spacing:.02em}
.cta-phone:hover{color:#fff}
.cta-sub{font-size:13.5px;opacity:.75;margin-top:8px}
.cta-form{background:#fff;border-radius:14px;padding:30px;color:var(--ink);box-shadow:0 24px 70px rgba(0,0,0,.3)}
.cta-form label{display:block;font-size:13px;font-weight:600;margin-bottom:14px;color:var(--navy-ink)}
.cta-form input,.cta-form textarea{width:100%;margin-top:6px;border:1.5px solid var(--line);border-radius:8px;padding:11px 13px;font:inherit;font-size:14.5px}
.cta-form input:focus,.cta-form textarea:focus{outline:none;border-color:var(--navy)}
.cta-form button{width:100%;background:var(--gold);border:0;border-radius:8px;padding:15px;font-family:var(--head);font-weight:700;letter-spacing:.12em;text-transform:uppercase;font-size:15px;color:var(--navy-ink);cursor:pointer;transition:background .2s}
.cta-form button:hover{background:var(--gold-deep)}
.form-thanks{text-align:center;padding:24px 10px}
.form-thanks b{font-family:var(--head);font-size:22px;color:var(--navy-ink);display:block;margin-bottom:8px}
.form-thanks p{font-size:14px;color:var(--mut);line-height:1.6}

/* ---------- footer ---------- */
footer{background:var(--navy-ink);color:rgba(255,255,255,.8);padding:46px 0 40px;text-align:center;font-size:14px}
.foot-inner{max-width:800px;margin:0 auto;padding:0 22px}
.foot-logo{height:70px;width:auto;margin:0 auto 18px}
footer a{color:var(--gold);text-decoration:none}
footer p{margin-top:6px}
.foot-fine{margin-top:16px;font-size:12px;opacity:.55}

/* ---------- sticky mobile action bar ---------- */
.mobile-bar{position:fixed;left:0;right:0;bottom:0;z-index:60;display:none;
  background:rgba(10,31,54,.97);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  border-top:1px solid rgba(255,255,255,.12);padding:9px 10px calc(9px + env(safe-area-inset-bottom));
  gap:9px;transform:translateY(115%);transition:transform .3s ease}
.mobile-bar.show{transform:translateY(0)}
.mobile-bar a{flex:1;display:flex;align-items:center;justify-content:center;gap:7px;
  padding:14px 8px;border-radius:8px;text-decoration:none;
  font-family:var(--head);font-weight:700;letter-spacing:.09em;text-transform:uppercase;font-size:14px}
.mb-call{background:var(--gold);color:var(--navy-ink)}
.mb-call svg{width:17px;height:17px;fill:currentColor}
.mb-quote{background:rgba(255,255,255,.1);color:#fff;border:1px solid rgba(255,255,255,.28)}

/* ---------- scroll reveal ----------
   Progressive enhancement: content is VISIBLE by default. Only once JS runs
   (html.js) does it start hidden. If JS fails, never runs, or the page is
   printed, everything still shows. Content must never be trapped invisible. */
.js .reveal{opacity:0;transform:translateY(22px);transition:opacity .7s ease,transform .7s cubic-bezier(.2,.7,.3,1)}
.js .reveal.in{opacity:1;transform:none}
.js .reveal-d1{transition-delay:.09s}
.js .reveal-d2{transition-delay:.18s}
@media print{.reveal{opacity:1!important;transform:none!important}.mobile-bar{display:none!important}}
@media(prefers-reduced-motion:reduce){.js .reveal{opacity:1;transform:none;transition:none}}

/* ---------- responsive ---------- */
@media(max-width:960px){
  .mobile-bar{display:flex}
  body{padding-bottom:0}
  .svc-grid{grid-template-columns:1fr}
  .about-grid{grid-template-columns:1fr}
  .about-img{max-height:340px}
  .about-copy{padding:48px 26px}
  .work-grid{grid-template-columns:repeat(2,1fr)}
  .rev-grid{grid-template-columns:1fr}
  .areas-grid{grid-template-columns:1fr}
  .cta-inner{grid-template-columns:1fr;gap:38px}
  .nav-links{display:none}
  .nav-burger{display:block;grid-column:3}
  .nav-inner{grid-template-columns:auto 1fr auto}
  .nav-logo{grid-column:1}
}
@media(max-width:600px){
  .work-grid{grid-template-columns:1fr}
  .work-grid img{height:220px}
  .rv-card{flex:0 0 300px;padding:19px 20px}
  .steps{grid-template-columns:1fr;gap:8px}
  .steps li{padding:6px 0 6px 54px;min-height:44px}
  .steps li:before{top:4px;width:34px;height:34px;font-size:16px}
  .steps li:after{top:38px;left:16px;right:auto;width:2px;height:calc(100% - 34px)}
  .cta{padding-bottom:100px}
  footer{padding-bottom:96px}
  .trust-inner{gap:10px}
  .trust-item{min-width:100px}
  .trust-item b{font-size:20px}
}

/* ==========================================================================
   ==========================================================================
   SHARED FOUNDATION — appended 2026-09-06 for the 56-page rs-roofs.com build.
   EVERYTHING ABOVE THIS BANNER IS THE APPROVED PREVIEW DESIGN. DO NOT EDIT IT.
   Everything below is additive: new tokens, accessibility fixes required by
   spec §5, two documented bug fixes, and the archetype classes the page
   agents build with. Append-only — later rules win, so nothing above breaks.

   Three intentional visual changes to the approved preview (all fixes, all
   flagged in _partials/README.md §9):
     1. .kicker on light grounds -> --gold-ink (contrast was 1.82:1, now 5.06:1)
     2. .foot-fine lightened (compound opacity put it at 4.24:1, now 7.7:1)
     3. sticky mobile bar no longer covers the footer between 601-960px
   ========================================================================== */

/* ---------- new tokens ---------- */
:root{
  /* Real fallback stacks so async webfonts never blank or block first paint.
     Primary faces are unchanged, so nothing shifts once the fonts land. */
  --head:"Barlow Condensed","Oswald","Arial Narrow",Arial,sans-serif;
  --body:"Inter","Helvetica Neue",Helvetica,Arial,system-ui,sans-serif;
  /* Gold that passes AA as TEXT on white/mist. --gold and --gold-deep stay
     for dark grounds and for fills; never use them for small text on light. */
  --gold-ink:#8A6A0B;
  --nav-h:62px;
}

/* ---------- accessibility base ---------- */
.skip{position:absolute;left:-9999px;top:0;z-index:100}
.skip:focus{left:12px;top:12px;background:var(--gold);color:var(--navy-ink);
  padding:12px 18px;border-radius:4px;text-decoration:none;
  font-family:var(--head);font-weight:700;letter-spacing:.1em;text-transform:uppercase}
.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}
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}

/* Visible focus everywhere. The preview had none, and one rule that REMOVED
   the indicator (.cta-form input:focus{outline:none}) — overridden below. */
/* navy, not gold: the ring itself must clear 3:1 against the surface it sits
   on (WCAG 1.4.11). --gold-deep on white/mist is 1.7:1 — invisible. */
:focus-visible{outline:3px solid var(--navy);outline-offset:2px}
/* .side-card--dark and .cta-band are navy grounds too: without them the ring
   was var(--navy) on var(--navy) = 1.00:1 on the primary click-to-call and the
   inspection CTA of every city + service page (WCAG 2.4.7 / 1.4.11). */
#nav :focus-visible,.hero :focus-visible,.pagehead :focus-visible,
.reviews :focus-visible,.cta :focus-visible,.cta-band :focus-visible,
.side-card--dark :focus-visible,footer :focus-visible,
.mobile-bar :focus-visible,.section--dark :focus-visible{outline-color:#fff}
/* ...but the ring sits on the CONTROL's own surface, not the section's. The
   gold buttons live inside those dark sections while being light themselves,
   so the white ring above lands on #F8DC62 at 1.36:1. Put them back to navy
   (12.21:1). Measured in-browser, not assumed. #nav needs the id in its
   selector to outrank `#nav :focus-visible`, which is (1,1,0). */
#nav a.nav-cta:focus-visible,.btn-gold:focus-visible,
.mobile-bar .mb-call:focus-visible{outline-color:var(--navy-ink)}
.cta-form input:focus-visible,.cta-form textarea:focus-visible{outline:3px solid var(--navy);outline-offset:1px}
.cta-form button:focus-visible{outline:3px solid var(--navy-ink);outline-offset:3px}

/* Anchor targets must clear the fixed nav (#contact, #areas, in-page jumps). */
[id]{scroll-margin-top:96px}
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}}

/* Contrast fix: .kicker carries real words ("What we do", "Where we work") on
   light sections at 13px — --gold-deep on white was 1.82:1. Dark grounds keep
   the bright gold. */
.kicker{color:var(--gold-ink)}
.reviews .kicker,.cta .kicker,.pagehead .kicker,.section--dark .kicker,
.hero .kicker,footer .kicker{color:var(--gold)}
.svc-link:hover{color:var(--gold-ink)}

/* ---------- nav additions ---------- */
/* Interior pages open on .pagehead, so the nav must be opaque from pixel one.
   app.js reads data-nav-mode and keeps .solid pinned on. */
#nav[data-nav-mode="solid"]{background:rgba(10,31,54,.96);box-shadow:0 2px 18px rgba(0,0,0,.25)}
/* Active state. aria-current="true" is NO LONGER emitted anywhere in the nav
   (it lied to AT: "true" asserts the item IS the current one in its set, so an
   ancestor parent claimed to be the current page). An ancestor now carries the
   visual-only class .is-ancestor and NO ARIA attribute. The selector is kept
   as [aria-current] rather than [aria-current="page"] purely so any stray
   legacy value still paints instead of silently losing its highlight.
   See the ACTIVE STATE section of _partials/header.html. */
.nav-links a[aria-current],.nav-mobile a[aria-current]{color:var(--gold);opacity:1}
.nav-logo img{height:42px;width:auto}

/* BUG FIX: #nav is position:fixed and .nav-mobile had no height cap, so the
   open menu ran past the viewport with no way to scroll to it. At 667x375 the
   panel ended at y=552 — "Service Areas", the phone link and "Free Inspection"
   were unreachable. Same failure at 200% zoom in portrait. */
.nav-mobile{max-height:calc(100svh - var(--nav-h));overflow-y:auto;
  -webkit-overflow-scrolling:touch;overscroll-behavior:contain}

/* ---------- homepage hero H1 ----------
   The preview hero had NO h1 (the logo is an <img>). Every page needs exactly
   one. The homepage keeps the logo AND gains a real visible headline. */
.hero h1,.hero-h1{margin-top:20px;color:#fff;font-family:var(--head);font-weight:700;
  text-transform:uppercase;letter-spacing:.01em;line-height:1.06;
  font-size:clamp(26px,3.6vw,42px);max-width:20ch;text-shadow:0 2px 14px rgba(0,0,0,.35)}

/* ==========================================================================
   INTERIOR PAGE HEAD (.pagehead) — every non-homepage page starts with this
   ========================================================================== */
.pagehead{position:relative;background:linear-gradient(140deg,var(--navy) 0%,var(--navy-ink) 100%);
  color:#fff;padding:calc(var(--nav-h) + 62px) 0 54px;overflow:hidden}
.pagehead .wrap{position:relative;z-index:2}
.pagehead h1{font-family:var(--head);font-weight:700;text-transform:uppercase;
  font-size:clamp(31px,4.8vw,52px);line-height:1.05;letter-spacing:.01em;color:#fff;max-width:22ch}
.pagehead .lead{margin-top:15px;max-width:64ch;font-size:clamp(15px,1.6vw,17px);color:rgba(255,255,255,.88)}
.pagehead-actions{display:flex;flex-wrap:wrap;gap:14px;margin-top:28px;align-items:center}
/* photo variant: put the image on .pagehead-bg so alt-less decoration stays
   out of the accessibility tree */
.pagehead-bg{position:absolute;inset:0;z-index:0}
.pagehead-bg img{width:100%;height:100%;object-fit:cover}
.pagehead-bg:after{content:"";position:absolute;inset:0;
  background:linear-gradient(120deg,rgba(10,31,54,.92) 0%,rgba(10,31,54,.72) 60%,rgba(14,42,71,.6) 100%)}
.pagehead--photo{background:var(--navy-ink)}

/* breadcrumbs (live inside .pagehead, above the h1) */
.crumbs{margin-bottom:16px;font-family:var(--head);font-weight:600;font-size:12.5px;
  letter-spacing:.12em;text-transform:uppercase}
.crumbs ol{list-style:none;display:flex;flex-wrap:wrap;align-items:center;gap:9px;margin:0;padding:0}
.crumbs li{display:flex;align-items:center;gap:9px}
.crumbs li+li:before{content:"\203A";color:rgba(255,255,255,.5)}
.crumbs a{color:var(--gold);text-decoration:none;border-bottom:1px solid rgba(248,220,98,.4)}
.crumbs a:hover{color:#fff;border-color:#fff}
.crumbs [aria-current="page"]{color:rgba(255,255,255,.82)}

/* ==========================================================================
   GENERIC SECTIONS — page agents use these instead of inventing classes
   ========================================================================== */
.section{padding:74px 0}
.section--tight{padding:52px 0}
.section--paper{background:var(--paper)}
.section--mist{background:var(--mist)}
.section--dark{background:var(--navy-deep);color:#fff}
.section--dark h2,.section--dark h3{color:#fff}
.section--dark p{color:rgba(255,255,255,.86)}
.section-head{max-width:70ch}
.section-head p{color:var(--mut);margin-top:12px}
.section--dark .section-head p{color:rgba(255,255,255,.86)}

/* two-column body + sticky sidebar (city pages, service pages, guides) */
.layout{display:grid;grid-template-columns:minmax(0,1fr) 328px;gap:56px;align-items:start}
.sidebar{position:sticky;top:calc(var(--nav-h) + 26px);display:grid;gap:18px}
.side-card{background:var(--mist);border:1px solid var(--line);border-radius:12px;padding:24px}
.side-card h2,.side-card h3{font-family:var(--head);font-weight:700;font-size:20px;
  text-transform:uppercase;letter-spacing:.03em;color:var(--navy)}
.side-card p{margin-top:10px;color:var(--mut);font-size:14.5px}
.side-card ul{list-style:none;margin-top:12px}
.side-card li{padding:6px 0;border-bottom:1px solid var(--line);font-size:14.5px}
.side-card li:last-child{border-bottom:0}
.side-card a{color:var(--navy);font-weight:600;text-decoration:none}
.side-card a:hover{color:var(--gold-ink);text-decoration:underline}
.side-card--dark{background:var(--navy);border-color:var(--navy-deep);color:#fff}
.side-card--dark h2,.side-card--dark h3{color:#fff}
.side-card--dark p{color:rgba(255,255,255,.85)}
/* .side-card .side-phone, not .side-phone: `.side-card a` above is (0,1,1) and
   would otherwise win, painting the phone navy-on-navy inside .side-card--dark. */
.side-card .side-phone{display:block;margin-top:12px;color:var(--gold);text-decoration:none;
  font-family:var(--head);font-weight:700;font-size:30px;letter-spacing:.02em}
.side-card .side-phone:hover{color:#fff}

/* ==========================================================================
   PROSE — migrated long-form body copy (city pages, guides, blog posts)
   Wrap every run of migrated <p>/<h2>/<h3>/<ul>/<ol> in <div class="prose">.
   ========================================================================== */
.prose{max-width:74ch}
.prose>*+*{margin-top:18px}
.prose p{color:var(--mut);font-size:16px;line-height:1.72}
.prose h2{font-size:clamp(26px,3.2vw,36px);margin-top:46px}
.prose h3{font-family:var(--head);font-weight:700;font-size:clamp(21px,2.4vw,26px);
  text-transform:uppercase;letter-spacing:.02em;color:var(--navy);line-height:1.15;margin-top:34px}
.prose h4{font-family:var(--head);font-weight:700;font-size:18px;text-transform:uppercase;
  letter-spacing:.05em;color:var(--navy-ink);margin-top:28px}
.prose h2+p,.prose h3+p,.prose h4+p{margin-top:12px}
/* :not([class]) matters: component links (.loc-card, .btn-gold, .tag, .svc-link)
   are frequently nested inside .prose, and a blanket `.prose a` rule painted a
   gold underline across the bottom of every card. Only bare inline links get
   the underline treatment. */
.prose a:not([class]){color:var(--navy);font-weight:600;text-decoration:none;border-bottom:2px solid var(--gold)}
.prose a:not([class]):hover{color:var(--gold-ink);border-color:var(--gold-deep)}
.prose strong{color:var(--ink)}
.prose ul,.prose ol{list-style:none;padding:0;margin-top:14px}
.prose ul li{position:relative;padding:6px 0 6px 30px;color:var(--mut);font-size:16px}
.prose ul li:before{content:"";position:absolute;left:3px;top:15px;width:9px;height:9px;
  border-radius:2px;background:var(--gold-deep);transform:rotate(45deg)}
/* .col-list — the city long-tail neighbourhood lists. The live pages carry
   40-65 names each (Plano has 61, Denton more); a single column is a mile of
   scroll. Same idiom as .rev-list{columns:3}. Names stay verbatim and every
   one stays in the DOM — this only changes how they wrap. */
.prose ul.col-list{columns:3;column-gap:26px;margin-top:14px}
.prose ul.col-list li{break-inside:avoid;font-size:15px;padding:4px 0 4px 26px}
.prose ul.col-list li:before{top:13px;width:7px;height:7px}
.prose ol{counter-reset:pn}
.prose ol li{counter-increment:pn;position:relative;padding:7px 0 7px 44px;color:var(--mut);font-size:16px;min-height:34px}
.prose ol li:before{content:counter(pn);position:absolute;left:0;top:5px;width:28px;height:28px;
  border-radius:50%;background:var(--navy);color:var(--gold);font-family:var(--head);font-weight:700;
  font-size:15px;display:flex;align-items:center;justify-content:center}
.prose blockquote{margin-top:22px;padding:18px 24px;background:var(--mist);
  border-left:4px solid var(--gold);border-radius:0 10px 10px 0;color:var(--ink);font-size:16px}
.prose blockquote cite{display:block;margin-top:8px;font-style:normal;font-weight:600;
  font-size:13.5px;color:var(--navy)}
.prose figure{margin-top:26px}
.prose img{border-radius:12px}
.prose figcaption{margin-top:8px;font-size:13px;color:var(--mut)}
.prose hr{border:0;border-top:1px solid var(--line);margin:34px 0}
.prose table{width:100%;border-collapse:collapse;margin-top:22px;font-size:15px}
.prose th,.prose td{border:1px solid var(--line);padding:10px 13px;text-align:left}
.prose th{background:var(--mist);font-family:var(--head);text-transform:uppercase;
  letter-spacing:.04em;color:var(--navy-ink)}
.prose-wide{max-width:none}

/* ==========================================================================
   CARD GRIDS — reuse .svc-grid/.svc-card from the approved design
   ========================================================================== */
.svc-grid--2{grid-template-columns:repeat(2,1fr)}
.svc-grid--4{grid-template-columns:repeat(4,1fr)}
.svc-card--flat h3{padding-top:22px}
.svc-card p+.svc-card-list{padding:0 20px}
.svc-card-list{list-style:none;padding:8px 20px 0}
.svc-card-list li{position:relative;padding:5px 0 5px 22px;color:var(--mut);font-size:14px}
.svc-card-list li:before{content:"";position:absolute;left:2px;top:13px;width:7px;height:7px;
  border-radius:2px;background:var(--gold-deep);transform:rotate(45deg)}

/* ==========================================================================
   LOCATION CARDS — city link grids on /katy-roofing/, service + city pages
   ========================================================================== */
.loc-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(196px,1fr));gap:14px;margin-top:28px}
.loc-card{display:block;background:var(--mist);border:1px solid var(--line);border-radius:12px;
  padding:16px 18px;text-decoration:none;transition:border-color .2s,box-shadow .2s,transform .2s}
.loc-card:hover{border-color:var(--gold-deep);box-shadow:0 10px 26px rgba(14,42,71,.1);transform:translateY(-2px)}
.loc-card b{display:block;font-family:var(--head);font-weight:700;font-size:19px;
  text-transform:uppercase;letter-spacing:.03em;color:var(--navy)}
.loc-card span{display:block;margin-top:2px;font-size:13px;color:var(--mut)}
.loc-card[aria-current="page"]{border-color:var(--navy);background:#fff}
/* photo variant — alt text must describe the PHOTO, not claim a city.
   Only 14 distinct city photos exist across 27 cities (they are reused). */
.loc-card--photo{padding:0;overflow:hidden}
.loc-card--photo img{width:100%;aspect-ratio:3/2;object-fit:cover}
.loc-card--photo b{padding:14px 16px 0}
.loc-card--photo span{padding:0 16px 15px}

/* ==========================================================================
   HUB / TEAM / FAQ / NAP / INLINE CTA
   ========================================================================== */
.team-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:22px;margin-top:34px}
.team-card{background:#fff;border:1px solid var(--line);border-radius:12px;padding:24px 22px}
.team-card .t-name{font-family:var(--head);font-weight:700;font-size:21px;text-transform:uppercase;
  letter-spacing:.03em;color:var(--navy-ink)}
.team-card .t-role{margin-top:2px;font-family:var(--head);font-weight:600;font-size:12.5px;
  letter-spacing:.16em;text-transform:uppercase;color:var(--gold-ink)}
.team-card ul{list-style:none;margin-top:14px}
.team-card li{padding:4px 0;font-size:14.5px}
.team-card a{color:var(--navy);font-weight:600;text-decoration:none;word-break:break-word}
.team-card a:hover{color:var(--gold-ink);text-decoration:underline}

.faq{margin-top:32px;max-width:860px;border-top:1px solid var(--line)}
.faq details{border-bottom:1px solid var(--line)}
.faq summary{cursor:pointer;list-style:none;position:relative;padding:18px 44px 18px 0;
  font-family:var(--head);font-weight:700;font-size:19px;text-transform:uppercase;
  letter-spacing:.02em;color:var(--navy-ink)}
.faq summary::-webkit-details-marker{display:none}
.faq summary:after{content:"+";position:absolute;right:8px;top:11px;font-size:26px;
  line-height:1;color:var(--gold-ink)}
.faq details[open] summary:after{content:"\2013"}
.faq details>*:not(summary){padding-bottom:18px;color:var(--mut);max-width:74ch}

.nap{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:20px;margin-top:28px}
.nap-card{background:var(--mist);border:1px solid var(--line);border-radius:12px;padding:24px}
.nap-card h3{font-family:var(--head);font-weight:700;font-size:19px;text-transform:uppercase;
  letter-spacing:.04em;color:var(--navy)}
.nap-card address{font-style:normal;margin-top:10px;color:var(--mut);font-size:15px;line-height:1.7}
.nap-card a{color:var(--navy);font-weight:600;text-decoration:none}
.nap-card a:hover{color:var(--gold-ink);text-decoration:underline}

.cta-band{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:22px;
  margin:40px 0;padding:28px 32px;border-radius:14px;color:#fff;
  background:linear-gradient(140deg,var(--navy) 0%,var(--navy-deep) 100%)}
.cta-band b{display:block;font-family:var(--head);font-weight:700;font-size:clamp(21px,2.6vw,27px);
  text-transform:uppercase;letter-spacing:.01em}
.cta-band p{margin-top:6px;color:rgba(255,255,255,.85);font-size:14.5px;max-width:52ch}
.cta-band-actions{display:flex;gap:12px;flex-wrap:wrap}

/* button vocabulary additions (the preview has .btn-solid, .nav-cta,
   .hero-cta and the form button; these two cover dark grounds) */
.btn-gold{display:inline-block;background:var(--gold);color:var(--navy-ink);text-decoration:none;
  font-family:var(--head);font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  font-size:14.5px;padding:15px 28px;border-radius:4px;transition:background .2s}
.btn-gold:hover{background:#fff}
.btn-ghost{display:inline-block;color:#fff;text-decoration:none;font-family:var(--head);
  font-weight:600;letter-spacing:.16em;text-transform:uppercase;font-size:14.5px;
  padding:14px 26px;border:1.5px solid rgba(255,255,255,.7);border-radius:4px;transition:all .2s}
.btn-ghost:hover{background:#fff;color:var(--navy-ink);border-color:#fff}

/* ==========================================================================
   REVIEWS — light-ground list for /reviews/ (the navy marquee stays on the
   homepage and /reviews/ ONLY: it is ~46KB of duplicated markup per page)
   ========================================================================== */
.rev-list{columns:3;column-gap:22px;margin-top:34px}
.rev-list .rv-card{display:block;break-inside:avoid;margin:0 0 22px;background:#fff;
  border:1px solid var(--line);color:var(--ink)}
.rev-list .rv-card:hover{background:#fff;border-color:var(--gold-deep)}
.rev-list .rv-stars{color:var(--gold-ink)}
.rev-list .rv-card blockquote{color:var(--ink)}
.rev-list .rv-card figcaption{color:var(--navy-ink)}
.rev-list .rv-card figcaption span{color:var(--mut);opacity:1}

/* ==========================================================================
   BLOG
   ========================================================================== */
.post-meta{margin-top:14px;font-size:13.5px;color:rgba(255,255,255,.8);
  font-family:var(--head);letter-spacing:.1em;text-transform:uppercase}
.post-list{display:grid;gap:18px;margin-top:32px}
.post-card{background:#fff;border:1px solid var(--line);border-radius:12px;padding:24px 26px;
  transition:box-shadow .25s,transform .25s}
.post-card:hover{box-shadow:0 14px 36px rgba(14,42,71,.12);transform:translateY(-2px)}
.post-card h2,.post-card h3{font-family:var(--head);font-weight:700;font-size:clamp(20px,2.4vw,25px);
  text-transform:uppercase;letter-spacing:.02em;color:var(--navy-ink);line-height:1.14}
.post-card h2 a,.post-card h3 a{color:inherit;text-decoration:none}
.post-card h2 a:hover,.post-card h3 a:hover{color:var(--navy)}
.post-card p{margin-top:10px;color:var(--mut);font-size:15px}
.tag{display:inline-block;margin-top:14px;padding:6px 14px;border-radius:999px;background:var(--mist);
  border:1px solid var(--line);color:var(--navy);text-decoration:none;font-size:12.5px;font-weight:600}
.tag:hover{border-color:var(--gold-deep);color:var(--gold-ink)}
.post-nav{display:flex;flex-wrap:wrap;justify-content:space-between;gap:18px;margin-top:46px;
  padding-top:22px;border-top:1px solid var(--line)}
.post-nav a{color:var(--navy);font-weight:600;text-decoration:none;font-size:14.5px}
.post-nav a:hover{color:var(--gold-ink);text-decoration:underline}

/* ==========================================================================
   FOOTER — multi-column + the 27-city block (spec §4.1)
   The old centered .foot-inner rules are untouched and simply unused.
   ========================================================================== */
.foot-grid{max-width:1140px;margin:0 auto;padding:0 22px;text-align:left;
  display:grid;grid-template-columns:1.5fr 1fr 1fr 1fr;gap:38px}
.foot-grid .foot-logo{margin:0 0 16px}
.foot-brand p{color:rgba(255,255,255,.78);font-size:14px;max-width:34ch}
.foot-phone a{font-family:var(--head);font-weight:700;font-size:26px;letter-spacing:.02em}
.foot-nap{font-style:normal;margin-top:14px;color:rgba(255,255,255,.72);font-size:13.5px;line-height:1.6}
.foot-nap b{display:block;font-family:var(--head);font-weight:700;font-size:13px;
  letter-spacing:.16em;text-transform:uppercase;color:var(--gold)}
.foot-col h2{font-family:var(--head);font-weight:700;font-size:15px;letter-spacing:.16em;
  text-transform:uppercase;color:#fff;margin-bottom:13px}
.foot-col ul{list-style:none}
.foot-col li{margin-bottom:8px}
.foot-col a{color:rgba(255,255,255,.78);text-decoration:none;font-size:14px}
.foot-col a:hover{color:var(--gold);text-decoration:underline}

.foot-cities{max-width:1140px;margin:40px auto 0;padding:30px 22px 0;text-align:left;
  border-top:1px solid rgba(255,255,255,.13)}
.foot-cities-h{font-family:var(--head);font-weight:700;font-size:15px;letter-spacing:.16em;
  text-transform:uppercase;color:#fff;text-align:left}
.foot-city-groups{display:grid;grid-template-columns:1fr 1fr;gap:32px;margin-top:20px}
.foot-city-group h3{font-family:var(--head);font-weight:700;font-size:13.5px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--gold);margin-bottom:12px}
.foot-city-group ul{list-style:none;display:grid;grid-template-columns:repeat(auto-fill,minmax(136px,1fr));gap:7px 18px}
.foot-city-group a{color:rgba(255,255,255,.76);text-decoration:none;font-size:13.5px}
.foot-city-group a:hover{color:var(--gold);text-decoration:underline}
.foot-city-group a[aria-current="page"]{color:var(--gold);font-weight:600}

.foot-bottom{max-width:1140px;margin:32px auto 0;padding:18px 22px 0;text-align:left;
  border-top:1px solid rgba(255,255,255,.1);display:flex;flex-wrap:wrap;gap:10px 26px;
  justify-content:space-between;align-items:baseline}
.foot-bottom p{margin-top:0;font-size:13px;color:rgba(255,255,255,.72)}
/* was opacity:.55 INSIDE footer's own rgba(255,255,255,.8) -> 4.24:1. */
.foot-bottom .foot-fine{margin-top:0;opacity:1;color:rgba(255,255,255,.66);font-size:12.5px}

/* ==========================================================================
   RESPONSIVE — foundation
   ========================================================================== */
@media(max-width:1040px){
  .layout{grid-template-columns:1fr;gap:38px}
  .sidebar{position:static;grid-template-columns:repeat(2,1fr);display:grid}
  .team-grid{grid-template-columns:repeat(2,1fr)}
  .rev-list{columns:2}
}
@media(max-width:960px){
  /* BUG FIX: .mobile-bar becomes display:flex at 960px, but the compensating
     bottom padding only existed at 600px — so the bar covered the footer
     between 601 and 960px. */
  .cta{padding-bottom:100px}
  footer{padding-bottom:96px}
  .foot-grid{grid-template-columns:1fr 1fr;gap:30px}
  .svc-grid--2,.svc-grid--4{grid-template-columns:1fr}
  .pagehead{padding:calc(var(--nav-h) + 46px) 0 44px}
  .nap{grid-template-columns:1fr}
  .cta-band{padding:24px 24px}
  .prose ul.col-list{columns:2}
}
@media(max-width:600px){
  .foot-grid{grid-template-columns:1fr;gap:26px}
  .foot-city-groups{grid-template-columns:1fr;gap:24px}
  .sidebar{grid-template-columns:1fr}
  .team-grid{grid-template-columns:1fr}
  .rev-list{columns:1}
  .prose ul.col-list{columns:1}
  .loc-grid{grid-template-columns:repeat(auto-fill,minmax(150px,1fr))}
  .section{padding:56px 0}
  .prose p,.prose ul li,.prose ol li{font-size:15.5px}
  .foot-bottom{margin-top:24px}
}
@media print{
  #nav,.mobile-bar,.skip,.hero-scroll,.cta-form{display:none!important}
  .pagehead{background:none;color:#000;padding:0 0 18px}
  .pagehead h1,.pagehead .lead{color:#000}
  .prose a{border:0;text-decoration:underline}
}

/* ============================================================================
   NAV DROPDOWNS — appended block. Nothing above this line was modified.
   ----------------------------------------------------------------------------
   The nav gained 5 parents with panels (Services 5, Storm & Insurance 3,
   About 1, Reviews & Tips 2, Service Areas 27 in two groups). Markup contract:
   _partials/header.html. Behaviour: app.js.

   The panels open from THREE independent triggers, deliberately:
     .nav-item.open        set by app.js (click / touch / pointer)
     :focus-within         pure CSS, so a keyboard reaches every child link
                           even with JS off — the 27 city pages must never be
                           orphaned again
     :hover                pure CSS, fine pointers only, and gated on
                           :not(.nav-hover-off) so Escape can dismiss a
                           hover-opened panel without moving the pointer
                           (WCAG 1.4.13 Content on Hover or Focus).
   .esc                   set by app.js on the item Escape just dismissed, and
                          cleared on focusout. Without it Escape cannot dismiss
                          anything: it returns focus to the toggle, the toggle
                          is INSIDE .nav-item, so :focus-within would re-open
                          the panel the same tick it was closed.
   visibility (not display) is what hides a closed panel: it keeps the links in
   the DOM for crawlers while correctly removing them from the tab order and
   the accessibility tree.

   Focus rings are already handled above by `#nav :focus-visible{outline-color:#fff}`
   — 3px white on rgba(10,31,54,.985) — and it inherits to every new control
   here. Do not add outline:none to anything in this block.
   ========================================================================= */

/* ---------- desktop: parents ---------- */
.nav-item{position:relative;display:flex;align-items:center;gap:1px}

/* "Service Areas" has no page of its own, so its parent is a <button>. These
   rules give it the exact look of the sibling <a> parents. */
#nav .nav-parent{background:none;border:0;margin:0;padding:0;cursor:pointer;
  color:#fff;opacity:.92;font-family:var(--head);font-weight:600;font-size:14.5px;
  letter-spacing:.14em;text-transform:uppercase;line-height:1.2;
  display:inline-flex;align-items:center;gap:8px;min-height:24px}
#nav .nav-parent:hover{opacity:1;color:var(--gold)}
#nav .nav-parent[aria-current]{color:var(--gold);opacity:1}

/* Disclosure control next to the linked parents. 24x24 is the WCAG 2.5.8
   (Target Size, Minimum) floor — do not shrink it to fit the caret. */
#nav .nav-tog{background:none;border:0;margin:0;padding:0;cursor:pointer;
  color:#fff;opacity:.92;width:24px;height:24px;flex:0 0 24px;
  display:inline-flex;align-items:center;justify-content:center}
#nav .nav-tog:hover{opacity:1;color:var(--gold)}
.nav-item > a[aria-current] ~ .nav-tog{color:var(--gold);opacity:1}

.nav-caret{display:block;width:6px;height:6px;border:solid currentColor;
  border-width:0 2px 2px 0;transform:translateY(-2px) rotate(45deg);
  transition:transform .18s ease}
.nav-item.open > .nav-tog .nav-caret,
.nav-item.open > .nav-parent .nav-caret,
.navm-item.open .navm-row .nav-caret{transform:translateY(1px) rotate(-135deg)}

/* ---------- desktop: panels ---------- */
.nav-drop{position:absolute;top:100%;left:-16px;z-index:60;
  padding-top:14px;               /* hover bridge: no dead gap under the bar */
  min-width:236px;max-width:calc(100vw - 32px);
  opacity:0;visibility:hidden;transform:translateY(-6px);
  transition:opacity .18s ease,transform .18s ease,visibility 0s linear .18s}
.nav-right .nav-drop{left:auto;right:-16px}   /* clamp the right-edge panels */
.nav-item.open > .nav-drop,
.nav-item:focus-within:not(.esc) > .nav-drop{opacity:1;visibility:visible;transform:none;
  transition-delay:0s}
@media(hover:hover) and (pointer:fine){
  #nav:not(.nav-hover-off) .nav-item:hover > .nav-drop{opacity:1;visibility:visible;
    transform:none;transition-delay:0s}
}
@media(prefers-reduced-motion:reduce){
  .nav-drop{transition:none}
  .nav-caret{transition:none}
}
.nav-drop-card{background:rgba(10,31,54,.985);border:1px solid rgba(255,255,255,.11);
  border-radius:6px;box-shadow:0 18px 46px rgba(0,0,0,.45);padding:10px 8px;
  max-height:calc(100svh - var(--nav-h) - 28px);overflow-y:auto;
  overscroll-behavior:contain;-webkit-overflow-scrolling:touch}
.nav-drop-list{list-style:none;margin:0;padding:0}
#nav .nav-drop-list a{display:block;box-sizing:border-box;min-height:24px;
  padding:8px 14px;border-radius:4px;opacity:.9;
  font-size:12.5px;letter-spacing:.1em;line-height:1.35;white-space:nowrap}
#nav .nav-drop-list a:hover{background:rgba(255,255,255,.08);color:var(--gold);opacity:1}
#nav .nav-drop-list a[aria-current]{color:var(--gold);opacity:1}

/* Service Areas: 27 links, two columns. */
.nav-drop--wide{min-width:452px}
.nav-drop-cols{display:grid;grid-template-columns:1fr 1fr;gap:0 14px}
.nav-drop-h{margin:8px 14px 4px;font-family:var(--head);font-weight:700;
  font-size:10.5px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--gold);opacity:.95}

/* 320px safety. The desktop nav is display:none under 960px so this is belt and
   braces, but a panel must never be able to push the page sideways: below
   520px it stops hanging off its item and pins to the viewport instead. */
@media(max-width:520px){
  .nav-drop,.nav-right .nav-drop{position:fixed;top:calc(var(--nav-h) - 4px);
    left:12px;right:12px;width:auto;min-width:0;max-width:none;padding-top:6px}
  .nav-drop-cols{grid-template-columns:1fr}
  .nav-drop-card{max-height:min(62vh,380px)}
  #nav .nav-drop-list a{white-space:normal}
}

/* ---------- mobile menu accordions ---------- */
.navm-item{border-bottom:1px solid rgba(255,255,255,.08)}
.navm-row{display:flex;align-items:center;gap:6px}
#nav .navm-row > a{flex:1 1 auto;border-bottom:0}
#nav .navm-parent{flex:1 1 auto;background:none;border:0;margin:0;padding:10px 0;
  cursor:pointer;text-align:left;color:#fff;font-family:var(--head);font-weight:600;
  font-size:inherit;letter-spacing:.12em;text-transform:uppercase;min-height:44px;
  display:flex;align-items:center;justify-content:space-between;gap:8px}
#nav .navm-parent[aria-current]{color:var(--gold)}
#nav .navm-tog{background:none;border:0;margin:0;padding:0;cursor:pointer;color:#fff;
  width:44px;height:44px;flex:0 0 44px;
  display:inline-flex;align-items:center;justify-content:center}
.navm-sub{display:none;padding:0 0 10px 12px}
.navm-item.open > .navm-sub{display:block}
#nav .navm-sub a{display:block;min-height:24px;padding:9px 0;border-bottom:0;
  font-size:13px;letter-spacing:.06em;text-transform:none;opacity:.88}
#nav .navm-sub a:hover{color:var(--gold);opacity:1}
#nav .navm-sub a[aria-current]{color:var(--gold);opacity:1}
.navm-sub-h{margin:10px 0 2px;font-family:var(--head);font-weight:700;font-size:10.5px;
  letter-spacing:.18em;text-transform:uppercase;color:var(--gold);opacity:.95}
.navm-sub-group{display:grid;grid-template-columns:1fr 1fr;gap:0 10px}
@media(max-width:360px){.navm-sub-group{grid-template-columns:1fr}}

/* ==========================================================================
   ANCESTOR HIGHLIGHT — the aria-current="true" replacement
   ==========================================================================
   A nav parent whose SECTION contains the current page is not itself the
   current page, so it carries no ARIA at all: just this class. It used to
   carry aria-current="true", which asserts "this is the current item in its
   set" — a straight lie on /houston-tx/, where the <button> saying it has no
   href and no page of its own. That build announced "current page" on the nav
   link, the breadcrumb AND the footer city link at once.
   aria-current="page" is now emitted at most ONCE per menu tree, on the
   deepest exact-URL match; everything else above it gets .is-ancestor.
   These selectors mirror the [aria-current] ones above so the gold highlight
   is byte-identical either way. */
#nav .is-ancestor{color:var(--gold);opacity:1}
.nav-links a.is-ancestor,.nav-mobile a.is-ancestor{color:var(--gold);opacity:1}
#nav .nav-parent.is-ancestor,#nav .navm-parent.is-ancestor{color:var(--gold);opacity:1}
#nav .nav-drop-list a.is-ancestor,#nav .navm-sub a.is-ancestor{color:var(--gold);opacity:1}
/* the caret next to a linked parent tracks its parent's state */
.nav-item > a.is-ancestor ~ .nav-tog,
.navm-row > a.is-ancestor ~ .navm-tog{color:var(--gold);opacity:1}
/* "You are here" inside the Service Areas panel. Visual ONLY, no aria-current:
   the breadcrumb and the footer city block already announce the current page,
   and a third announcement in the nav is what this build set out to remove. */
#nav .nav-drop-list a.is-here,#nav .navm-sub a.is-here{color:var(--gold);opacity:1;font-weight:600}

/* Exact height cap for the open mobile menu.
   .nav-mobile above uses calc(100svh - var(--nav-h)), and --nav-h is 62px while
   the bar actually measures 63.5px, so the panel overhung the viewport by 1.5px.
   --nav-h is NOT the place to fix it: it also drives .pagehead padding and the
   .sidebar sticky offset on all 56 pages, and this is a nav-only change.
   Making #nav a flex column below the burger breakpoint lets the panel take
   exactly the leftover space instead of a hard-coded number, so it stays right
   if the bar's height ever changes. Desktop is untouched. */
@media(max-width:960px){
  #nav{display:flex;flex-direction:column;max-height:100svh}
  /* .nav-inner keeps `margin:0 auto`, and an auto cross-axis margin CANCELS
     flex stretch — without this the bar collapsed to its content width (189px
     of a 320px viewport) and the logo/burger drifted to the middle. */
  .nav-inner{width:100%}
  .nav-mobile{max-height:none;min-height:0;flex:1 1 auto}
}

/* The sticky call bar still covers the bottom of the open burger menu.
   Measured 2026-09-07 on /houston-tx/ with every mobile group expanded:
     .mobile-bar  z-index 60, shown at top 595.6, height 71.4
     #nav         z-index 50  -> the bar paints OVER the menu
     menu         clientH 604, scrollH 1501 (320px) / 996 (375px), bottom 657
   Scrolled fully to the end, the last item ("Free Inspection" — the menu's
   primary conversion action) ended at 639.2 / 638.8, i.e. 43.6px / 43.2px
   INSIDE the bar, and could not be reached at either width.

   Padding, not a smaller max-height: the bar is only present once the page is
   scrolled (.mobile-bar.show), so capping the panel would waste 76px of menu
   every time the bar is hidden. Extra scroll length costs nothing when it is.
   After this rule the last item lands at ~563, clearing the bar by ~32px. */
@media(max-width:960px){
  .nav-mobile{padding-bottom:calc(18px + 76px + env(safe-area-inset-bottom))}
}

/* ============================================================
   Whole-card click targets
   ------------------------------------------------------------
   The visible "Residential roof repair →" style links stay exactly
   as they are; a stretched ::after overlay on that same link makes
   the ENTIRE card clickable. No HTML change, no nested links, and
   only one entry per card in the accessibility tree.
   .loc-card is already an <a> and needs nothing.
   Vendor cards on /roofing-material-vendors/ have no destination,
   so they deliberately stay non-clickable.
   ============================================================ */
.svc-card,.post-card{position:relative}
.svc-card > .svc-link::after,
.post-card > h3 > a::after{content:"";position:absolute;inset:0;z-index:1}

/* affordance: the whole card reacts, not just the link */
@media(hover:hover) and (pointer:fine){
  .svc-card,.post-card,.loc-card{transition:transform .18s ease,box-shadow .18s ease,border-color .18s ease}
  .svc-card:hover,.post-card:hover,.loc-card:hover{transform:translateY(-3px);
    box-shadow:0 14px 34px rgba(10,31,54,.14);border-color:rgba(10,31,54,.28)}
  .svc-card:hover .svc-link,.post-card:hover h3 a{color:var(--navy)}
  .svc-card:hover .svc-img img{transform:scale(1.03)}
}
.svc-card .svc-img{overflow:hidden}
.svc-card .svc-img img{transition:transform .35s ease}
/* keyboard parity: focusing the inner link rings the whole card */
.svc-card:focus-within,.post-card:focus-within,.loc-card:focus-visible{
  outline:3px solid var(--navy);outline-offset:3px}
.svc-card:focus-within > .svc-link:focus-visible,
.post-card:focus-within > h3 > a:focus-visible{outline:none}
@media(prefers-reduced-motion:reduce){
  .svc-card,.post-card,.loc-card,.svc-card .svc-img img{transition:none}
  .svc-card:hover,.post-card:hover,.loc-card:hover{transform:none}
}

/* ---------- chamber affiliations (added 2026-09-07) ---------- */
.affil{padding:clamp(56px,6vw,78px) 0;background:var(--mist);border-top:1px solid var(--line)}
.affil .kicker,.affil h2{text-align:center}
.affil-lead{text-align:center;max-width:620px;margin:15px auto 0;color:var(--mut);font-size:15.5px}
.affil-grid{list-style:none;display:flex;flex-wrap:wrap;justify-content:center;gap:16px;margin-top:36px}
.affil-card{flex:1 1 168px;max-width:216px;min-width:148px;display:flex}
.affil-card a{width:100%;display:flex;flex-direction:column;justify-content:center}
.affil-card a{display:block;text-align:center;background:var(--paper);border:1px solid var(--line);
  border-radius:5px;padding:26px 14px 22px;text-decoration:none;
  transition:border-color .25s ease,transform .25s ease,box-shadow .25s ease}
.affil-card a::before{content:"";display:block;width:26px;height:2px;background:var(--gold-deep);
  margin:0 auto 15px;transition:width .25s ease}
.affil-card b{display:block;font-family:var(--head);font-weight:700;text-transform:uppercase;
  letter-spacing:.05em;font-size:19px;line-height:1.15;color:var(--navy-ink)}
.affil-card span{display:block;margin-top:7px;font-size:10.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--mut)}
.affil-note{text-align:center;margin-top:24px;font-size:12.5px;color:var(--mut)}
.affil-card a:focus-visible{outline:2px solid var(--gold-deep);outline-offset:3px}
@media(hover:hover) and (pointer:fine){
  .affil-card a:hover{border-color:var(--gold-deep);transform:translateY(-3px);
    box-shadow:0 10px 26px rgba(20,53,91,.10)}
  .affil-card a:hover::before{width:46px}
}
@media(prefers-reduced-motion:reduce){
  .affil-card a,.affil-card a::before{transition:none}
  .affil-card a:hover{transform:none}
}
@media(min-width:561px) and (max-width:1000px){
  /* 3 across beats auto-wrapping to 4+1; the trailing 2 centre themselves */
  .affil-card{flex:0 1 calc(33.333% - 11px);max-width:none}
  .affil-card a{min-height:124px}
}
@media(max-width:560px){
  .affil-grid{gap:12px}
  /* exact half-width cards so the odd 5th matches the other four */
  .affil-card{flex:0 1 calc(50% - 6px);min-width:0;max-width:none}
  .affil-card a{padding:22px 8px 18px}
  .affil-card b{font-size:17px}
  /* tighter so "Chamber of Commerce" stays on one line -> uniform card heights */
  .affil-card span{font-size:9.5px;letter-spacing:.1em}
  /* floor so a 2-line label can never make one card taller than its neighbours */
  .affil-card a{min-height:116px}
}

/* trust strip -> 5 items; grid wraps cleanly instead of orphaning the last item */
.trust-inner{display:grid;grid-template-columns:repeat(5,1fr);gap:18px}
@media(max-width:640px){
  .trust-inner{grid-template-columns:repeat(2,1fr);gap:18px 12px}
  .trust-item:nth-child(5){grid-column:1/-1}
}
