:root{--accent:#d9822b;--accent-ink:#a85312;--on-accent:#14110D;--accent-lite:#D9822B;--accent-hover:#B26B23;--ink:#14110d;--coal:#221c15;--paper:#fff;--mist:#f6f3ef;--line:#16181c21;--line-dark:#ffffff1a;--text-soft:#16181cb8;--text-mute:#16181c85;--font-poster:"Archivo Black", "Arial Black", sans-serif;--font-display:"Instrument Sans", system-ui, -apple-system, sans-serif;--pad:clamp(1.15rem, 4vw, 3.5rem);--maxw:1240px;--header-h:78px;--radius:4px;--ease:cubic-bezier(.22, 1, .36, 1)}*,:before,:after{box-sizing:border-box}html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;overflow-x:clip}body{background:var(--paper);color:var(--ink);font:400 1rem/1.6 var(--font-display);-webkit-font-smoothing:antialiased;margin:0;overflow-x:hidden}img,video,svg{max-width:100%;display:block}a{color:inherit;text-decoration:none}button{font:inherit;color:inherit;cursor:pointer;background:0 0;border:0}ul{margin:0;padding:0;list-style:none}h1,h2,h3,p{margin:0}:focus-visible{outline:3px solid var(--accent);outline-offset:3px;border-radius:2px}.wrap{width:100%;max-width:var(--maxw);padding-inline:var(--pad);margin-inline:auto}.section{padding-block:clamp(3.5rem,8vw,6.5rem);position:relative}.section--paper{background:var(--paper)}.section--mist{background:var(--mist)}.section--dark{background:var(--ink);color:#fff}.section--dark .body{color:#ffffffbd}.section--dark .body strong{color:#fff}.section--dark .kicker{color:var(--accent-lite)}.grid-tex:before{content:"";pointer-events:none;z-index:0;background-image:linear-gradient(#ffffff0b 1px,#0000 1px),linear-gradient(90deg,#ffffff0b 1px,#0000 1px);background-size:64px 64px;position:absolute;inset:0;mask-image:radial-gradient(85% 70% at 50% 40%,#000 30%,#0000 100%)}.section>.wrap{z-index:1;position:relative}.h-hero,.h-section,.h-card{font-family:var(--font-poster);text-transform:uppercase;letter-spacing:-.005em;font-weight:400}.h-hero,.h-section,.h-card{text-wrap:balance}
.h-hero{font-size:clamp(2.25rem,4.9vw,3.9rem);line-height:.98}.h-section{font-size:clamp(1.85rem,3.6vw,2.95rem);line-height:1.03;text-wrap:balance}.h-card{font-size:clamp(1.25rem,2vw,1.55rem);line-height:1.1}.kicker{font:700 .73rem/1 var(--font-display);letter-spacing:.17em;text-transform:uppercase;color:var(--accent-ink);align-items:center;gap:.55rem;margin-bottom:.9rem;display:inline-flex}.kicker:before{content:"";background:currentColor;flex:none;width:22px;height:2px}.body{color:var(--text-soft);font-size:1.04rem;line-height:1.75}.body+.body{margin-top:1.1rem}.body strong{color:var(--ink);font-weight:600}.measure{max-width:62ch}.micro{font:700 .7rem/1 var(--font-display);letter-spacing:.14em;text-transform:uppercase}.nb{display:block}@media (width<=640px){.nb{display:inline}.nb:before{content:" "}}.btn{font:700 .82rem/1 var(--font-display);letter-spacing:.1em;text-transform:uppercase;border-radius:var(--radius);transition:background .28s var(--ease), color .28s var(--ease), transform .28s var(--ease), border-color .28s var(--ease);border:2px solid #0000;justify-content:center;align-items:center;gap:.55rem;padding:1.05rem 1.75rem;display:inline-flex}.btn--primary{background:var(--accent);color:var(--on-accent,var(--ink))}.btn--primary:hover{background:var(--accent-hover,var(--accent));color:var(--on-accent,var(--ink));transform:translateY(-2px);box-shadow:0 10px 26px -10px #00000073}.btn--ink{background:var(--ink);color:#fff}.btn--ink:hover{background:var(--accent);color:var(--on-accent,var(--ink));transform:translateY(-2px)}.btn--ghost{color:#fff;border-color:#ffffff73}.btn--ghost:hover{color:var(--ink);background:#fff;border-color:#fff}.btn--outline{border-color:var(--ink);color:var(--ink)}.btn--outline:hover{background:var(--ink);color:#fff}.header{z-index:100;height:var(--header-h);transition:background .3s var(--ease), border-color .3s var(--ease);border-bottom:1px solid #0000;align-items:center;display:flex;position:fixed;inset:0 0 auto}.header.stuck{background:var(--ink);border-bottom-color:var(--line-dark)}.header__inner{justify-content:space-between;align-items:center;gap:1.5rem;width:100%;display:flex}.header__logo{color:#fff;align-items:baseline;gap:.5rem;display:flex}.header__logo b{font-family:var(--font-poster);text-transform:uppercase;letter-spacing:-.01em;font-size:1.18rem;font-weight:400}.header__logo span{font:700 .6rem/1 var(--font-display);letter-spacing:.18em;text-transform:uppercase;color:var(--accent-lite)}.header__nav{align-items:center;gap:1.6rem;display:flex}.header__nav a{font:600 .84rem/1 var(--font-display);color:#ffffffdb;transition:color .2s var(--ease)}.header__nav a:hover{color:var(--accent-lite)}.header__cta{align-items:center;gap:.7rem;display:flex}.header__phone{white-space:nowrap;font:700 .88rem/1 var(--font-display);color:#fff;border-radius:var(--radius);transition:all .25s var(--ease);border:1px solid #ffffff47;flex:none;align-items:center;gap:.5rem;padding:.8rem 1.1rem;display:inline-flex}.header__phone svg{flex:none}.header__phone:hover{background:var(--accent);color:var(--on-accent);border-color:var(--accent)}.header__burger{color:#fff;justify-content:center;align-items:center;width:44px;height:44px;display:none}@media (width<=1040px){.header__nav,.header__cta .btn{display:none}.header__burger{flex:none;display:inline-flex}.header__inner{gap:.75rem}}@media (width<=560px){.header__inner{gap:.5rem}.header__phone{gap:.4rem;padding:.7rem .8rem;font-size:.82rem}.brandmark{flex:none}}@media (width<=380px){.header__phone{padding:.65rem .7rem;font-size:.78rem}}.mobile-menu{z-index:1200;background:var(--ink);padding:calc(var(--header-h) + 1rem) var(--pad) 2rem;-webkit-overflow-scrolling:touch;opacity:0;visibility:hidden;transition:opacity .3s var(--ease), visibility .3s;flex-direction:column;justify-content:center;display:flex;position:fixed;inset:0;overflow-y:auto}.mobile-menu.open{opacity:1;visibility:visible}.mobile-menu nav{flex-direction:column;display:flex}.mobile-menu nav a{font-family:var(--font-poster);text-transform:uppercase;color:#fff;border-bottom:1px solid var(--line-dark);padding:.5rem 0;font-size:clamp(1.5rem,6.5vw,2.2rem);line-height:1.1;display:block}.mobile-menu nav a:hover{color:var(--accent-lite)}.mobile-menu__foot{flex-direction:column;gap:.7rem;margin-top:1.8rem;display:flex}.mobile-menu__foot .btn{width:100%}.hero{text-align:center;background:var(--ink);color:#fff;min-height:var(--hero-h,76svh);padding:calc(var(--header-h) + 3rem) 0 clamp(3rem,7vw,5rem);justify-content:center;align-items:flex-start;display:flex;position:relative;overflow:hidden}.hero__media{z-index:0;will-change:transform;position:absolute;inset:0}.hero__media video,.hero__media img{object-fit:cover;object-position:center;width:100%;height:100%;position:absolute;inset:0}.hero--still .hero__media img{transform-origin:52% 46%;animation:26s ease-in-out infinite alternate heroDrift}@keyframes heroDrift{0%{transform:scale(1.02)}to{transform:scale(1.14)}}.hero__scrim{z-index:1;pointer-events:none;background:radial-gradient(80% 68% at 50% 42%,#16181c1f 0%,#16181c5c 100%),linear-gradient(#16181c73 0%,#16181c14 26%,#16181c30 60%,#16181cbf 100%);position:absolute;inset:0}.hero__grain{z-index:1;pointer-events:none;opacity:.5;background-image:linear-gradient(#ffffff08 1px,#0000 1px),linear-gradient(90deg,#ffffff08 1px,#0000 1px);background-size:72px 72px;position:absolute;inset:0;mask-image:radial-gradient(70% 60%,#0000 30%,#000 100%)}.hero__content{z-index:2;width:100%;max-width:900px;padding-inline:var(--pad);flex-direction:column;align-items:center;margin-inline:auto;margin-block:auto;display:flex;position:relative}.hero__eyebrow{font:700 .72rem/1 var(--font-display);letter-spacing:.2em;text-transform:uppercase;color:var(--accent-lite);text-shadow:0 2px 12px #0009;align-items:center;gap:.6rem;margin-bottom:1.35rem;display:inline-flex}.hero__eyebrow:before,.hero__eyebrow:after{content:"";background:currentColor;width:24px;height:2px}.lockup{flex-direction:column;align-items:center;gap:.35rem;margin-bottom:1.5rem;display:flex}.lockup__name{font-family:var(--font-poster);text-transform:uppercase;letter-spacing:-.022em;text-shadow:0 18px 48px #0000009e;font-size:clamp(2.6rem,9.2vw,6.4rem);font-weight:400;line-height:.86}.lockup__rule{align-items:center;gap:.85rem;width:100%;max-width:min(560px,84vw);display:flex}.lockup__rule:before,.lockup__rule:after{content:"";background:#ffffff6b;flex:1;height:2px}.lockup__sub{font:700 clamp(.72rem,1.7vw,1rem)/1 var(--font-display);letter-spacing:.42em;text-transform:uppercase;color:#fff;text-shadow:0 2px 12px #0009;padding-left:.42em}.hero__title{text-shadow:0 14px 40px #0000008c;text-wrap:balance;margin-bottom:1.2rem}.hero__sub{color:#fffffff0;text-shadow:0 2px 16px #0000009e;max-width:44ch;margin:0 auto 2.1rem;font-size:clamp(1rem,1.75vw,1.28rem);font-weight:500;line-height:1.62}.hero__ctas{flex-wrap:wrap;justify-content:center;gap:.85rem;margin-bottom:2.3rem;display:flex}.hero__trust{font:700 .78rem/1.4 var(--font-display);letter-spacing:.11em;text-transform:uppercase;color:#fffffff0;text-shadow:0 2px 12px #0009;flex-wrap:wrap;justify-content:center;gap:.7rem 1.9rem;display:flex}.hero__trust li{align-items:center;gap:.55rem;display:flex}.hero__trust li:before{content:"";background:var(--accent);border-radius:50%;flex:none;width:8px;height:8px}.hero__cue{z-index:2;font:700 .64rem/1 var(--font-display);letter-spacing:.2em;text-transform:uppercase;color:#ffffffb8;flex-direction:column;align-items:center;gap:.55rem;display:flex;position:absolute;bottom:1.6rem;left:50%;transform:translate(-50%)}.hero__cue i{background:linear-gradient(#ffffffb3,#0000);width:1px;height:34px;position:relative;overflow:hidden}.hero__cue i:after{content:"";background:var(--accent);animation:cueRun 2.1s var(--ease) infinite;position:absolute;inset:0}@keyframes cueRun{0%{transform:translateY(-100%)}60%,to{transform:translateY(100%)}}.hero--page{min-height:min(76svh,760px)}.hero--page .hero__title{max-width:18ch}@media (width<=540px){.hero__ctas{flex-direction:column;align-items:stretch;width:100%}.hero__ctas .btn{width:100%}.hero__cue{display:none}}/* LCP: the hero children used to sit at opacity 0 until motion.js (deferred) added .in, which Lighthouse measured as a 2.3s element render delay on the hero lockup, the LCP element. The rise now runs from first paint with no JS gate. */.js .hero .hero__content>*{animation:heroRise .95s var(--ease) backwards;animation-delay:calc(var(--i,0) * .13s + 60ms)}@keyframes heroRise{0%{opacity:0;transform:translateY(24px)}to{opacity:1;transform:none}}.ticker{background:var(--accent);border-block:3px solid var(--ink);padding:.85rem 0;overflow:hidden}.ticker__track{width:max-content;animation:30s linear infinite tickerscroll;display:flex}.ticker__group{font-family:var(--font-poster);text-transform:uppercase;color:var(--on-accent);align-items:center;gap:1.4rem;padding-right:1.4rem;font-size:clamp(1rem,2.1vw,1.5rem);display:flex}.ticker__dot{opacity:.45}@keyframes tickerscroll{0%{transform:none}to{transform:translate(-33.333%)}}.strip__head{flex-wrap:wrap;justify-content:space-between;align-items:flex-end;gap:2rem;margin-bottom:2.4rem;display:flex}.strip__scroll{scroll-snap-type:x proximity;scroll-padding-left:var(--pad);padding:0 var(--pad) 1.2rem;-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain;gap:1rem;display:flex;overflow-x:auto}.strip__scroll::-webkit-scrollbar{height:8px}.strip__scroll::-webkit-scrollbar-track{background:#00000012}.strip__scroll::-webkit-scrollbar-thumb{background:var(--accent);border-radius:4px}.strip__item{aspect-ratio:4/5;scroll-snap-align:start;border-radius:6px;flex:0 0 clamp(255px,29vw,360px);position:relative;overflow:hidden}.strip__item img{object-fit:cover;width:100%;height:100%;transition:transform .65s var(--ease)}.strip__item:hover img{transform:scale(1.07)}.strip__overlay{color:#fff;background:linear-gradient(#0000 0%,#16181c0d 42%,#16181ce0 100%);flex-direction:column;justify-content:flex-end;padding:1.2rem;display:flex;position:absolute;inset:0}.strip__cat{font:700 .66rem/1 var(--font-display);letter-spacing:.16em;text-transform:uppercase;color:var(--accent-lite);margin-bottom:.35rem}.strip__title{font:600 1rem/1.3 var(--font-display)}.svc__head{border-bottom:1px solid var(--line-dark);grid-template-columns:1.3fr 1fr;align-items:end;gap:3rem;margin-bottom:2.8rem;padding-bottom:1.8rem;display:grid}.svc__grid{gap:1.3rem;display:flex;flex-wrap:wrap;justify-content:center}.svc__grid>*{flex:0 1 calc((100% - 2.6rem)/3);min-width:220px}@media (width<=1040px){.svc__grid>*{flex-basis:calc((100% - 1.3rem)/2)}.svc__head{grid-template-columns:1fr;gap:1.4rem}}@media (width<=620px){.svc__grid>*{flex-basis:100%}}.svc-card{color:#fff;background-color:var(--coal);border:1px solid var(--line-dark);transition:transform .35s var(--ease), border-color .35s var(--ease), box-shadow .35s var(--ease);background-image:repeating-linear-gradient(135deg,#ffffff07 0 1px,#0000 1px 8px);border-radius:10px;flex-direction:column;display:flex;position:relative;overflow:hidden}.svc-card:after{content:"";background:var(--accent);transform-origin:0;height:4px;transition:transform .4s var(--ease);position:absolute;bottom:0;left:0;right:0;transform:scaleX(0)}.svc-card:hover{border-color:var(--accent);transform:translateY(-8px);box-shadow:0 30px 60px -28px #000000bf}.svc-card:hover:after{transform:scaleX(1)}.svc-card__media{aspect-ratio:5/4;position:relative;overflow:hidden}.svc-card__media img{object-fit:cover;width:100%;height:100%;transition:transform .7s var(--ease)}.svc-card__media:before{content:"";z-index:1;background:linear-gradient(#16181c26 0%,#0000 40%,#16181cdb 100%);position:absolute;inset:0}.svc-card__media:after{content:"";z-index:1;background:var(--accent);mix-blend-mode:multiply;opacity:0;transition:opacity .4s var(--ease);position:absolute;inset:0}.svc-card:hover .svc-card__media img{transform:scale(1.09)}.svc-card:hover .svc-card__media:after{opacity:.1}.svc-card__body{flex-direction:column;flex:1;padding:1.4rem 1.4rem 1.7rem;display:flex}.svc-card__name{font-family:var(--font-poster);text-transform:uppercase;margin-bottom:.55rem;font-size:1.28rem;line-height:1.1}.svc-card__desc{color:#ffffffad;flex:1;margin-bottom:1.1rem;font-size:.93rem;line-height:1.6}.svc-card__cta{font:700 .76rem/1 var(--font-display);letter-spacing:.1em;text-transform:uppercase;color:var(--accent-lite,var(--accent));align-items:center;gap:.45rem;display:inline-flex}.svc-card:hover .svc-card__cta svg{transform:translate(5px)}.svc-card__cta svg{transition:transform .3s var(--ease)}.intro__grid{grid-template-columns:1fr 1fr;align-items:center;gap:clamp(2rem,5vw,4rem);display:grid}@media (width<=900px){.intro__grid{grid-template-columns:1fr}}.intro__media{aspect-ratio:4/3;border-radius:6px;position:relative;overflow:hidden;box-shadow:0 30px 60px -30px #00000080}.intro__media img{object-fit:cover;width:100%;height:100%}.stats{border-top:1px solid var(--line);grid-template-columns:repeat(2,1fr);gap:1.5rem 1rem;margin-top:2rem;padding-top:2rem;display:grid}.stat__val{font-family:var(--font-poster);color:var(--accent-ink);font-size:clamp(1.6rem,2.8vw,2.2rem);line-height:1}.stat__label{font:700 .7rem/1.3 var(--font-display);letter-spacing:.1em;text-transform:uppercase;color:var(--text-mute);margin-top:.35rem}.section--dark .stat__val{color:var(--accent-lite)}.section--dark .stat__label{color:#ffffff8c}.section--dark .stats{border-top-color:var(--line-dark)}.certs{grid-template-columns:repeat(3,1fr);gap:1.2rem;display:grid}@media (width<=860px){.certs{grid-template-columns:1fr}}.cert{background:var(--coal);border:1px solid var(--line-dark);border-radius:8px;padding:2.1rem 1.7rem 1.9rem;position:relative;overflow:hidden}.cert:before{content:"";background:var(--accent);height:4px;position:absolute;inset:0 0 auto}.cert__name{font-family:var(--font-poster);text-transform:uppercase;color:#fff;margin-bottom:.5rem;font-size:1.22rem;line-height:1.15}.cert__note{color:#ffffffa8;font-size:.9rem;line-height:1.6}.proc__grid{grid-template-columns:1fr 1fr;align-items:center;gap:clamp(2rem,5vw,4rem);display:grid}@media (width<=900px){.proc__grid{grid-template-columns:1fr}}.proc__steps{flex-direction:column;gap:1.15rem;margin-top:1.8rem;display:flex}.proc__step{grid-template-columns:auto 1fr;align-items:start;gap:1rem;display:grid}.proc__n{background:var(--accent);width:38px;height:38px;color:var(--on-accent);font:700 .8rem/1 var(--font-display);border-radius:6px;flex:none;justify-content:center;align-items:center;display:inline-flex}.proc__name{font:700 1.02rem/1.3 var(--font-display);margin-bottom:.2rem}.proc__desc{color:var(--text-soft);font-size:.94rem;line-height:1.6}.section--dark .proc__desc{color:#ffffffb3}.proc__media{aspect-ratio:4/3;border-radius:6px;overflow:hidden;box-shadow:0 30px 60px -30px #0000008c}.proc__media img{object-fit:cover;width:100%;height:100%}.why__grid{grid-template-columns:repeat(3,1fr);gap:1.2rem;display:grid}@media (width<=880px){.why__grid{grid-template-columns:1fr 1fr}}@media (width<=560px){.why__grid{grid-template-columns:1fr}}.why__item{background:var(--paper);border-top:4px solid var(--accent);border-radius:0 0 6px 6px;padding:1.9rem 1.5rem}.section--paper .why__item{background:var(--mist)}.why__title{font-family:var(--font-poster);text-transform:uppercase;margin:0 0 .55rem;font-size:1.08rem;line-height:1.15}.why__desc{color:var(--text-soft);font-size:.93rem;line-height:1.65}.area__grid{grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:.9rem;margin-top:2.2rem;display:grid}.area__card{background:var(--paper);border:1px solid var(--line);border-radius:var(--radius);transition:all .28s var(--ease);flex-direction:column;gap:.3rem;padding:1.15rem 1.25rem;display:flex}.area__card:hover{border-color:var(--accent);transform:translateY(-3px);box-shadow:0 16px 32px -20px #00000059}.area__name{font-family:var(--font-poster);text-transform:uppercase;font-size:1.02rem}.area__county{font:600 .74rem/1 var(--font-display);letter-spacing:.08em;text-transform:uppercase;color:var(--text-mute)}.band{background:var(--accent);color:var(--on-accent);padding-block:clamp(2.6rem,6vw,4rem)}.band__inner{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:2rem;display:flex}.band h2{font-family:var(--font-poster);text-transform:uppercase;max-width:20ch;text-wrap:balance;font-size:clamp(1.5rem,3vw,2.3rem);line-height:1.08}.faq__layout{grid-template-columns:1fr 1.45fr;align-items:start;gap:clamp(2rem,5vw,4rem);display:grid}@media (width<=900px){.faq__layout{grid-template-columns:1fr}}.faq__call{background:var(--ink);color:#fff;border-radius:var(--radius);font:700 .84rem/1 var(--font-display);transition:background .25s var(--ease), color .25s var(--ease);align-items:center;gap:.6rem;margin-top:1.4rem;padding:.95rem 1.35rem;display:inline-flex}.faq__call:hover{background:var(--accent);color:var(--on-accent)}.faq__item{border-top:1px solid var(--line)}.faq__item:last-child{border-bottom:1px solid var(--line)}.faq__trigger{text-align:left;grid-template-columns:1fr auto;align-items:center;gap:1.4rem;width:100%;padding:1.35rem .2rem;display:grid}.faq__q{font:600 1.04rem/1.35 var(--font-display)}.faq__icon{border:2px solid var(--ink);width:38px;height:38px;transition:all .3s var(--ease);border-radius:50%;flex:none;justify-content:center;align-items:center;display:flex}.faq__trigger:hover .faq__icon,.faq__trigger[aria-expanded=true] .faq__icon{background:var(--accent);border-color:var(--accent)}.faq__trigger[aria-expanded=true] .faq__icon{transform:rotate(45deg)}.faq__answer{max-height:0;transition:max-height .4s var(--ease);overflow:hidden}.faq__answer.open{max-height:520px}.faq__answer p{color:var(--text-soft);max-width:68ch;padding:0 .2rem 1.35rem;font-size:.97rem;line-height:1.75}.contact{scroll-margin-top:calc(var(--header-h) + 12px);position:relative;overflow:hidden}.contact:before{content:"";pointer-events:none;opacity:.16;background:radial-gradient(circle,var(--accent) 0%,#0000 70%);width:540px;height:540px;position:absolute;bottom:-220px;left:-160px}.contact__grid{z-index:1;grid-template-columns:1fr 1fr;align-items:start;gap:clamp(2rem,5vw,4rem);display:grid;position:relative}@media (width<=900px){.contact__grid{grid-template-columns:1fr}.contact__form{order:-1}}.channels{flex-direction:column;gap:.85rem;margin-top:1.9rem;display:flex}.channel{color:#fff;border:1px solid var(--line-dark);transition:all .3s var(--ease);background:#ffffff0b;border-radius:6px;align-items:center;gap:1rem;padding:1rem;display:flex}a.channel:hover{background:var(--coal);border-color:var(--accent);transform:translate(6px)}.channel__icon{background:var(--accent);width:44px;height:44px;color:var(--on-accent);border-radius:8px;flex:none;justify-content:center;align-items:center;display:inline-flex}.channel>span:last-child{flex-direction:column;min-width:0;display:flex}.channel__label{font:700 .68rem/1 var(--font-display);letter-spacing:.14em;text-transform:uppercase;color:#ffffff94;display:block}.channel__val{font:600 1.02rem/1.3 var(--font-display);overflow-wrap:anywhere;margin-top:.3rem;display:block}.form{background:var(--paper);color:var(--ink);border-radius:8px;padding:1.9rem;box-shadow:0 40px 90px -30px #0000008c}@media (width<=480px){.form{padding:1.4rem}}.form--hero{box-shadow:none}.field{margin-bottom:1rem}.field label{font:700 .7rem/1 var(--font-display);letter-spacing:.12em;text-transform:uppercase;color:var(--text-mute);margin-bottom:.45rem;display:block}.field input,.field select,.field textarea{width:100%;font:400 1rem/1.4 var(--font-display);color:var(--ink);background:var(--mist);border:1px solid var(--line);border-radius:var(--radius);transition:border-color .2s var(--ease), background .2s var(--ease);padding:.85rem .9rem}.field input:focus,.field select:focus,.field textarea:focus{border-color:var(--accent);background:#fff;outline:none}.field textarea{resize:vertical;min-height:108px}.form__row{grid-template-columns:1fr 1fr;gap:.8rem;display:grid}@media (width<=520px){.form__row{grid-template-columns:1fr;gap:0}}.form__submit{width:100%;margin-top:.4rem}.form__note{color:var(--text-mute);text-align:center;margin-top:.9rem;font-size:.82rem;line-height:1.5}.form__note a{color:var(--accent-ink);font-weight:600}.form__status{border-radius:var(--radius);margin-top:.9rem;padding:.85rem 1rem;font-size:.9rem;line-height:1.5;display:none}.form__status.ok{color:#1c6b38;background:#1e783c1a;border:1px solid #1e783c47;display:block}.form__status.err{color:#9d2626;background:#b4282814;border:1px solid #b4282840;display:block}.hp{width:1px;height:1px;position:absolute;left:-9999px;overflow:hidden}.phero{background:var(--ink);color:#fff;padding-top:var(--header-h);position:relative;overflow:hidden}.phero__media{position:absolute;inset:0}.phero__media img{object-fit:cover;width:100%;height:100%}.phero__media:after{content:"";background:linear-gradient(90deg,#16181cf0 0%,#16181cb8 45%,#16181c73 100%);position:absolute;inset:0}.phero__inner{z-index:1;max-width:780px;padding-block:clamp(3rem,8vw,5.5rem);position:relative}.crumbs{font:600 .74rem/1 var(--font-display);letter-spacing:.1em;text-transform:uppercase;color:#ffffff8c;flex-wrap:wrap;align-items:center;gap:.5rem;margin-bottom:1.2rem;display:flex}.crumbs a:hover{color:var(--accent-lite)}.prose{max-width:68ch}.prose h2{font-family:var(--font-poster);text-transform:uppercase;margin:2.4rem 0 1rem;font-size:clamp(1.5rem,2.6vw,2rem);line-height:1.08}.prose h3{font:700 1.1rem/1.3 var(--font-display);margin:1.8rem 0 .6rem}.prose p{color:var(--text-soft);margin-bottom:1.1rem;font-size:1.04rem;line-height:1.78}.checks{gap:.7rem;margin:1.2rem 0 1.8rem;display:grid}.checks li{color:var(--text-soft);grid-template-columns:auto 1fr;align-items:start;gap:.7rem;font-size:1rem;line-height:1.55;display:grid}.checks li:before{content:"";background:var(--accent);border-radius:3px;flex:none;width:18px;height:18px;margin-top:.2rem;-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20 6 9 17l-5-5' fill='none' stroke='%23000' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") 50%/contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20 6 9 17l-5-5' fill='none' stroke='%23000' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") 50%/contain no-repeat}.split{grid-template-columns:1.5fr 1fr;align-items:start;gap:clamp(2rem,5vw,3.5rem);display:grid}@media (width<=900px){.split{grid-template-columns:1fr}}.aside{top:calc(var(--header-h) + 20px);background:var(--mist);border-top:4px solid var(--accent);border-radius:8px;padding:1.6rem;position:sticky}@media (width<=900px){.aside{position:static}}.aside h3{font-family:var(--font-poster);text-transform:uppercase;margin-bottom:.7rem;font-size:1.2rem;line-height:1.1}.aside ul{flex-direction:column;gap:.5rem;margin-top:1rem;display:flex}.aside ul a{font:600 .93rem/1.4 var(--font-display);color:var(--text-soft);gap:.5rem;display:flex}.aside ul a:hover{color:var(--accent-ink)}.footer{background:var(--ink);color:#fff;padding-block:clamp(3rem,6vw,4.5rem) 1.5rem}.footer__grid{grid-template-columns:1.5fr 1fr 1fr 1.2fr;gap:2.5rem;display:grid}@media (width<=900px){.footer__grid{grid-template-columns:1fr 1fr;gap:2rem}}@media (width<=560px){.footer__grid{grid-template-columns:1fr}}.footer h2{font:700 .74rem/1 var(--font-display);letter-spacing:.16em;text-transform:uppercase;color:var(--accent-lite);margin-bottom:1.1rem}.footer ul{flex-direction:column;gap:.6rem;display:flex}.footer a{color:#ffffffbd;font-size:.93rem}.footer a:hover{color:var(--accent-lite)}.footer__blurb{color:#fff9;max-width:34ch;margin-top:.9rem;font-size:.93rem;line-height:1.7}.footer__legal{border-top:1px solid var(--line-dark);color:#ffffff73;flex-wrap:wrap;justify-content:space-between;gap:1rem;margin-top:3rem;padding-top:1.4rem;font-size:.82rem;align-items:center;display:flex}.js .reveal{opacity:0;transition:opacity .8s var(--ease), transform .8s var(--ease)}.js .reveal:not(.in){transform:translateY(22px)}.js .reveal.in{opacity:1}@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}*,:before,:after{transition-duration:.01ms!important;animation:none!important}.js .reveal{opacity:1;transform:none}}.visually-hidden{clip:rect(0 0 0 0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.skip-link{z-index:999;background:var(--accent);color:var(--on-accent);border-radius:var(--radius);padding:.8rem 1.2rem;transition:top .2s;position:absolute;top:-60px;left:8px}.skip-link:focus{top:8px}.js .stagger>*{opacity:0;transition:opacity .75s var(--ease), transform .75s var(--ease)}.js .stagger:not(.in)>*{transform:translateY(26px)}.js .stagger.in>*{opacity:1}.js .stagger.in>:first-child{transition-delay:20ms}.js .stagger.in>:nth-child(2){transition-delay:.1s}.js .stagger.in>:nth-child(3){transition-delay:.18s}.js .stagger.in>:nth-child(4){transition-delay:.26s}.js .stagger.in>:nth-child(5){transition-delay:.34s}.js .stagger.in>:nth-child(6){transition-delay:.42s}.js .stagger.in>:nth-child(n+7){transition-delay:.5s}.js .wipe{clip-path:inset(0 100% 0 0);transition:clip-path 1.05s var(--ease)}.js .wipe.in{clip-path:inset(0)}.px{will-change:transform}.stat__val{font-variant-numeric:tabular-nums}.js .unmask{clip-path:inset(0 0 100%);transition:clip-path 1.1s var(--ease)}.js .unmask.in{clip-path:inset(0)}.callbar{z-index:90;background:var(--line-dark);transition:transform .35s var(--ease);gap:1px;display:none;position:fixed;bottom:0;left:0;right:0;transform:translateY(110%)}.callbar.show{transform:none}.callbar a{font:700 .8rem/1 var(--font-display);letter-spacing:.06em;text-transform:uppercase;flex:1;justify-content:center;align-items:center;gap:.5rem;padding:.95rem .5rem;display:flex}.callbar__call{background:var(--accent);color:var(--on-accent)}.callbar__quote{background:var(--ink);color:#fff}@media (width<=820px){.callbar{display:flex}.footer{padding-bottom:calc(1.5rem + 56px)}}@media (prefers-reduced-motion:reduce){.js .stagger>*{opacity:1;transform:none}.js .wipe,.js .unmask{clip-path:none}.js .hero__content>*,.js .hero:not(.in) .hero__content>*{opacity:1!important;animation:none!important;transform:none!important}.hero--still .hero__media img,.hero__cue i:after{animation:none}.px{transform:none!important}}.crumbs--bar{background:var(--coal);color:#fff9;border-bottom:1px solid var(--line-dark);margin:0;padding:.85rem 0}.crumbs--bar .wrap{flex-wrap:wrap;align-items:center;gap:.5rem;display:flex}.crumbs--bar a{color:#ffffffbf}.crumbs--bar a:hover{color:var(--accent-lite)}.brandmark{align-items:center;gap:.6rem;display:flex}.brandmark img{width:auto;height:42px;display:block}.footer .brandmark img{height:64px}.hero__logo{filter:drop-shadow(0 2px 3px #00000073) drop-shadow(0 0 14px #00000059);width:clamp(270px,34vw,470px);max-width:88vw;height:auto;margin-bottom:1.4rem}@media (width<=640px){.brandmark img{height:34px}.footer .brandmark img{height:54px}}ul.social{flex-flow:wrap;gap:.5rem;margin:0;padding:0;list-style:none;display:flex}.footer ul.social{flex-direction:row;gap:.5rem;margin-top:1.1rem}.mobile-menu ul.social{margin-top:.4rem}.social a{border-radius:var(--radius);color:#ffffffd1;border:1px solid var(--line-dark);width:40px;height:40px;transition:background .25s var(--ease), color .25s var(--ease), transform .25s var(--ease), border-color .25s var(--ease);background:#ffffff0f;justify-content:center;align-items:center;display:inline-flex}.social a:hover{background:var(--accent);color:var(--on-accent);border-color:var(--accent);transform:translateY(-3px)}.social--light a{color:var(--text-soft);border-color:var(--line);background:0 0}.social--light a:hover{background:var(--accent);color:var(--on-accent);border-color:var(--accent)}.header__prog{background:var(--accent);transform-origin:0;opacity:0;width:100%;height:2px;transition:opacity .35s var(--ease);pointer-events:none;position:absolute;bottom:-1px;left:0;transform:scaleX(0)}.header.stuck .header__prog{opacity:1}.ticker--js .ticker__track{will-change:transform;animation:none}.proc__steps{position:relative}.proc__rail{background:var(--line);z-index:0;width:2px;position:absolute;top:19px;bottom:19px;left:18px;overflow:hidden}.section--dark .proc__rail,.section--mist .proc__rail{background:#16181c29}.proc__rail i{background:var(--accent);transform-origin:50% 0;will-change:transform;position:absolute;inset:0;transform:scaleY(1)}.proc__step{z-index:1;position:relative}.proc-scrub .proc__rail i{transform:scaleY(0)}.proc-scrub .proc__n{color:var(--text-soft);transition:background .45s var(--ease), color .45s var(--ease);background:#16181c1a}.section--dark .proc-scrub .proc__n{color:#ffffffbf;background:#ffffff24}.proc-scrub .proc__step.lit .proc__n{background:var(--accent);color:var(--on-accent)}.grid-tex:before{transform:translate3d(0, var(--gridY,0px), 0);inset:-90px 0}@media (prefers-reduced-motion:reduce){.header__prog{display:none}.ticker__track{animation:none!important}.ticker--js .ticker__track{transform:none!important}.proc-scrub .proc__rail i{transform:scaleY(1)!important}.proc-scrub .proc__n{background:var(--accent);color:var(--on-accent)}.grid-tex:before{transform:none!important}}

/* ==========================================================================
   MOTION + INTERACTION LAYER v2
   Every entrance state below is gated on .js so that with JavaScript blocked
   the content paints fully visible. Nothing here hardcodes a brand color.
   ========================================================================== */

/* --- token safety: text on an accent fill, accent text on a dark surface --- */
.btn--primary{color:var(--on-accent,var(--ink))}
.proc__n,.channel__icon,.callbar__call,.skip-link,.ticker__group,.band{color:var(--on-accent,var(--ink))}
.proc-scrub .proc__step.lit .proc__n{color:var(--on-accent,var(--ink))}
.header__phone:hover,.header__logo span{color:var(--on-accent,var(--ink))}
.header__logo span{color:var(--accent-lite,var(--accent))}
.hero__eyebrow,.section--dark .kicker,.svc-card__cta,.footer h2,.section--dark .stat__val{color:var(--accent-lite,var(--accent))}
.header__nav a:hover,.footer a:hover,.crumbs a:hover,.mobile-menu nav a:hover{color:var(--accent-lite,var(--accent))}
.svc-card:hover{border-color:var(--accent)}

/* --- scroll progress bar: readable on a dark header even with a dark accent --- */
.header__prog{background:var(--accent-lite,var(--accent));height:3px;box-shadow:0 0 10px var(--accent-lite,var(--accent))}

/* ==========================================================================
   1. DIRECTIONAL REVEALS
   .reveal--left | --right | --up | --down | --scale | --blur | --rotate
   --d  per element entry delay      --rv  duration override
   ========================================================================== */
/* Nothing here asserts `transform` once the element has landed. A reveal that keeps
   declaring transform:none outranks .svc-card:hover and silently kills every card lift. */
.js .reveal--left:not(.stagger),.js .reveal--right:not(.stagger),.js .reveal--up:not(.stagger),.js .reveal--down:not(.stagger),.js .reveal--scale:not(.stagger),.js .reveal--blur:not(.stagger),.js .reveal--rotate:not(.stagger){opacity:0;transition:opacity var(--rv,.85s) var(--ease) var(--d,0ms),transform var(--rv,.85s) var(--ease) var(--d,0ms),filter var(--rv,.85s) var(--ease) var(--d,0ms)}
.js .reveal--left:not(.stagger):not(.in){transform:translate3d(calc(var(--rvd,56px) * -1),0,0);will-change:transform,opacity}
.js .reveal--right:not(.stagger):not(.in){transform:translate3d(var(--rvd,56px),0,0);will-change:transform,opacity}
.js .reveal--up:not(.stagger):not(.in){transform:translate3d(0,var(--rvd,48px),0);will-change:transform,opacity}
.js .reveal--down:not(.stagger):not(.in){transform:translate3d(0,calc(var(--rvd,44px) * -1),0);will-change:transform,opacity}
.js .reveal--scale:not(.stagger):not(.in){transform:scale(.94);will-change:transform,opacity}
.js .reveal--blur:not(.stagger):not(.in){transform:translate3d(0,18px,0);filter:blur(10px);will-change:transform,opacity,filter}
.js .reveal--rotate:not(.stagger):not(.in){transform:translate3d(0,40px,0) rotate(1.8deg);will-change:transform,opacity}
.js .reveal--left.in,.js .reveal--right.in,.js .reveal--up.in,.js .reveal--down.in,.js .reveal--scale.in,.js .reveal--blur.in,.js .reveal--rotate.in{opacity:1}
.reveal--fast{--rv:.7s}
.reveal--slow{--rv:.95s}
.reveal--far{--rvd:64px}

/* --- stagger, now direction aware. The container stays neutral, the children move. --- */
.js .stagger>*{transition:opacity .78s var(--ease),transform .78s var(--ease),filter .78s var(--ease)}
.js .stagger.reveal--left:not(.in)>*{transform:translate3d(-48px,0,0)}
.js .stagger.reveal--right:not(.in)>*{transform:translate3d(48px,0,0)}
.js .stagger.reveal--up:not(.in)>*{transform:translate3d(0,40px,0)}
.js .stagger.reveal--down:not(.in)>*{transform:translate3d(0,-36px,0)}
.js .stagger.reveal--scale:not(.in)>*{transform:scale(.94)}
.js .stagger.reveal--blur:not(.in)>*{transform:translate3d(0,16px,0);filter:blur(9px)}
.js .stagger.reveal--rotate:not(.in)>*{transform:translate3d(0,34px,0) rotate(1.6deg)}
.js .stagger.in>:nth-child(1){transition-delay:var(--d,0ms)}
.js .stagger.in>:nth-child(2){transition-delay:calc(var(--d,0ms) + var(--sg,88ms))}
.js .stagger.in>:nth-child(3){transition-delay:calc(var(--d,0ms) + var(--sg,88ms)*2)}
.js .stagger.in>:nth-child(4){transition-delay:calc(var(--d,0ms) + var(--sg,88ms)*3)}
.js .stagger.in>:nth-child(5){transition-delay:calc(var(--d,0ms) + var(--sg,88ms)*4)}
.js .stagger.in>:nth-child(6){transition-delay:calc(var(--d,0ms) + var(--sg,88ms)*5)}
.js .stagger.in>:nth-child(7){transition-delay:calc(var(--d,0ms) + var(--sg,88ms)*6)}
.js .stagger.in>:nth-child(8){transition-delay:calc(var(--d,0ms) + var(--sg,88ms)*7)}
.js .stagger.in>:nth-child(9){transition-delay:calc(var(--d,0ms) + var(--sg,88ms)*8)}
.js .stagger.in>:nth-child(n+10){transition-delay:calc(var(--d,0ms) + var(--sg,88ms)*9)}
.stagger--fast{--sg:52ms}
.stagger--slow{--sg:145ms}

/* ==========================================================================
   2. HOVER + MICRO INTERACTION LAYER
   Everything behind @media (hover:hover) so a touch device never sticks.
   ========================================================================== */
.why__item,.area__card,.strip__item,.cert{position:relative}
.why__item,.area__card{overflow:hidden}
.why__item:after,.area__card:after,.strip__item:after{content:"";background:var(--accent);transform-origin:0 50%;height:3px;transition:transform .45s var(--ease);position:absolute;bottom:0;left:0;right:0;z-index:2;transform:scaleX(0)}
.strip__item:after{height:4px}
.why__item{transition:transform .38s var(--ease),box-shadow .38s var(--ease)}
.area__card{transition:transform .32s var(--ease),box-shadow .32s var(--ease),border-color .32s var(--ease)}
.strip__item{transition:transform .42s var(--ease),box-shadow .42s var(--ease)}
.cert{transition:transform .38s var(--ease),box-shadow .38s var(--ease),border-color .38s var(--ease)}
.cert:before{transition:height .38s var(--ease)}
.cert__name,.area__name,.strip__title{transition:color .28s var(--ease),transform .38s var(--ease)}
.svc-card__name{transition:color .28s var(--ease)}
.intro__media img,.proc__media img{transition:transform .8s var(--ease)}

@media (hover:hover){
  .why__item:hover{transform:translateY(-6px);box-shadow:0 26px 52px -26px #16181c73}
  .area__card:hover{transform:translateY(-6px);box-shadow:0 24px 46px -24px #16181c8c;border-color:var(--accent)}
  .strip__item:hover{transform:translateY(-8px);box-shadow:0 34px 62px -30px #16181cb3}
  .cert:hover{transform:translateY(-6px);box-shadow:0 30px 58px -28px #000000bf;border-color:var(--accent)}
  .why__item:hover:after,.area__card:hover:after,.strip__item:hover:after{transform:scaleX(1)}
  .cert:hover:before{height:7px}
  .cert:hover .cert__name{color:var(--accent-lite,var(--accent))}
  .area__card:hover .area__name{color:var(--accent-ink)}
  .strip__item:hover .strip__title{transform:translateY(-3px)}
  .svc-card:hover .svc-card__name{color:var(--accent-lite,var(--accent))}
  .intro__media:hover img,.proc__media:hover img{transform:scale(1.05)}
}

/* --- buttons: sheen sweep + a real pressed state --- */
.btn{isolation:isolate;position:relative;overflow:hidden}
.btn:before{content:"";pointer-events:none;background:linear-gradient(105deg,#0000 34%,#ffffff5c 47%,#ffffff5c 53%,#0000 66%);transition:transform .75s var(--ease);position:absolute;inset:0;transform:translate3d(-130%,0,0)}
@media (hover:hover){.btn:hover:before{transform:translate3d(130%,0,0)}}
.btn:active{transform:translateY(1px) scale(.975)}
.faq__call:active,.channel:active,.header__phone:active{transform:scale(.985)}

/* --- links in body copy and lists: underline grows from the left --- */
@media (hover:hover){
  .body a,.prose a,.checks a,.footer ul a,.aside ul a,.form__note a,.footer__legal a{background-image:linear-gradient(currentColor,currentColor);background-repeat:no-repeat;background-position:0 100%;background-size:0 1px;transition:background-size .42s var(--ease),color .25s var(--ease)}
  .body a:hover,.prose a:hover,.checks a:hover,.footer ul a:hover,.aside ul a:hover,.form__note a:hover,.footer__legal a:hover{background-size:100% 1px}
}

/* --- nav: accent underline grows from center --- */
.header__nav a,.crumbs a{position:relative}
.header__nav a:after,.crumbs a:after{content:"";background:var(--accent-lite,var(--accent));transition:left .3s var(--ease),right .3s var(--ease);height:2px;position:absolute;bottom:-7px;left:50%;right:50%}
.crumbs a:after{bottom:-3px}
@media (hover:hover){.header__nav a:hover:after,.crumbs a:hover:after{left:0;right:0}}

/* --- .tilt : opt in pointer follow 3D, driven by motion.js, max 6deg --- */
.tilt{transform:perspective(900px) rotateX(var(--ry,0deg)) rotateY(var(--rx,0deg));transition:transform .45s var(--ease)}
.tilt.tilt--live{transition:transform .12s linear}
@media (hover:hover){.tilt:hover{transform:perspective(900px) rotateX(var(--ry,0deg)) rotateY(var(--rx,0deg)) translateY(-8px)}}

/* --- .magnetic : opt in CTA pull, driven by motion.js, max 8px --- */
.magnetic{transform:translate3d(var(--mx,0px),var(--my,0px),0);transition:transform .35s var(--ease)}
.magnetic.magnetic--live{transition:transform .1s linear}
@media (hover:hover){.magnetic:hover{transform:translate3d(var(--mx,0px),calc(var(--my,0px) - 2px),0)}}
.magnetic:active{transform:translate3d(var(--mx,0px),1px,0) scale(.975)}

/* ==========================================================================
   3. CUSTOM SELECT (progressive enhancement, native select stays the value)
   ========================================================================== */
.sel{position:relative}
.sel .sel__native{clip:rect(0 0 0 0);white-space:nowrap;background:0 0;border:0;width:1px;height:1px;min-height:0;margin:-1px;padding:0;position:absolute;overflow:hidden;pointer-events:none}
.sel__trigger{width:100%;font:400 1rem/1.4 var(--font-display);color:var(--ink);text-align:left;background:var(--mist);border:1px solid var(--line);border-radius:var(--radius);transition:border-color .22s var(--ease),background .22s var(--ease),box-shadow .22s var(--ease);justify-content:space-between;align-items:center;gap:.75rem;padding:.85rem .9rem;display:flex}
.sel__trigger:focus-visible{outline:3px solid var(--accent);outline-offset:2px}
.sel.open .sel__trigger{border-color:var(--accent);background:var(--paper);box-shadow:0 0 0 3px #16181c14}
@media (hover:hover){.sel__trigger:hover{border-color:var(--accent);background:var(--paper)}}
.sel__value{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}
.sel--empty .sel__value{color:var(--text-mute)}
.sel__chev{color:var(--text-mute);transition:transform .3s var(--ease),color .3s var(--ease);flex:none}
.sel.open .sel__chev{color:var(--accent-ink);transform:rotate(180deg)}
.sel__panel{z-index:1000;max-height:min(288px,52vh);background:var(--paper);border:1px solid var(--line);border-radius:var(--radius);opacity:0;visibility:hidden;transform-origin:50% 0;transition:opacity .22s var(--ease),transform .26s var(--ease),visibility .26s;margin:0;padding:.34rem;list-style:none;position:fixed;overflow:auto;box-shadow:0 30px 60px -26px #16181c8c,0 2px 6px #16181c1a;transform:translateY(-8px) scale(.985)}
.sel.open .sel__panel{opacity:1;visibility:visible;transform:none}
.sel__panel:focus-visible{outline:3px solid var(--accent);outline-offset:-1px}
.sel__opt{font:400 .97rem/1.35 var(--font-display);color:var(--ink);border-radius:calc(var(--radius) + 1px);cursor:pointer;transition:background .18s var(--ease),color .18s var(--ease);align-items:center;gap:.6rem;padding:.62rem .7rem;display:flex}
.sel__opt:before{content:"";background:#0000;border-radius:2px;transition:background .18s var(--ease);flex:none;align-self:stretch;width:3px}
.sel__opt.act{background:#16181c0f}
.sel__opt[aria-selected=true]{color:var(--accent-ink);font-weight:600}
.sel__opt[aria-selected=true]:before{background:var(--accent)}
.sel__opt[aria-disabled=true]{color:var(--text-mute);cursor:default}
@media (hover:hover){.sel__opt:hover{background:#16181c0f}}
.form--dark .sel__trigger,.section--dark .sel__trigger{color:#fff;background:#ffffff0f;border-color:var(--line-dark)}

/* ==========================================================================
   4. REDUCED MOTION: every new effect is dead, every hidden state is visible
   ========================================================================== */
@media (prefers-reduced-motion:reduce){
  .js .reveal--left,.js .reveal--right,.js .reveal--up,.js .reveal--down,.js .reveal--scale,.js .reveal--blur,.js .reveal--rotate{opacity:1!important;filter:none!important;transform:none!important}
  .js .stagger>*,.js .stagger.reveal--left>*,.js .stagger.reveal--right>*,.js .stagger.reveal--up>*,.js .stagger.reveal--down>*,.js .stagger.reveal--scale>*,.js .stagger.reveal--blur>*,.js .stagger.reveal--rotate>*{opacity:1!important;filter:none!important;transform:none!important;transition-delay:0s!important}
  .why__item:hover,.area__card:hover,.strip__item:hover,.cert:hover,.svc-card:hover,.btn:hover,.btn:active,.magnetic,.magnetic:hover,.magnetic:active,.tilt,.tilt:hover,.strip__item:hover .strip__title,.intro__media:hover img,.proc__media:hover img{transform:none!important}
  .btn:before{display:none}
  .header__nav a:after,.crumbs a:after{transition:none!important}
  .sel__panel{transition:none!important}
  .sel.open .sel__chev{transform:none!important}
}

/* ==========================================================================
   5. CRO LAYER
   Added for the CRO Master Checklist rebuild. Additive only: nothing above is
   edited. Every block names the rule it closes and the measured result behind
   it. No literal brand color appears here, so palette-patch.py stays correct.
   ========================================================================== */

/* --- rule 12 (ROBUST, HubSpot +16% to +28%): conversion page with no nav ---
   The bare header keeps the logo and the phone and nothing else, so the only
   forward action on the page is the form. */
.header--bare .header__cta--bare{display:flex}
@media (width<=1040px){.header--bare .header__cta--bare{display:flex}}
.footer--bare{padding-block:2.2rem 1.4rem}
.footer__blurb--bare{color:#ffffffbd;max-width:none;margin-top:0;font-size:.9rem}
.footer--bare .footer__legal{margin-top:1.2rem}
.callbar--bare .callbar__call{flex:1}

/* --- rules 49, 53, 55, 56, 57: the form ---------------------------------- */
/* 55 (ROBUST, Baymard: only 14% of checkouts mark BOTH states) */
.form__legend{color:var(--text-soft);margin-bottom:1.1rem;font-size:.82rem;line-height:1.4}
.field label .req,.form__legend .req{color:var(--accent-ink);margin-left:.25rem;font-weight:700}
.field label .opt,.form__more-toggle .opt{color:var(--text-soft);text-transform:none;letter-spacing:0;margin-left:.4rem;font-weight:400}
/* 49 (ROBUST, HubSpot: 4 fields to 3 measured nearly +50% across 40,000 pages).
   Email and property address live behind this disclosure, closed by default, so
   the form reads as three fields and neither field is lost. */
.form__more{border-top:1px solid var(--line);margin:.2rem 0 1.1rem;padding-top:.9rem}
.form__more-toggle{font:700 .74rem/1 var(--font-display);letter-spacing:.1em;text-transform:uppercase;color:var(--text-soft);cursor:pointer;align-items:center;gap:.4rem;min-height:44px;display:flex}
.form__more-toggle::marker,.form__more-toggle::-webkit-details-marker{color:var(--accent-ink)}
.form__more[open] .form__more-toggle{margin-bottom:.7rem}
.form__more-toggle:hover{color:var(--ink)}
/* 56 (ROBUST, Baymard: 31% of tested sites had no inline validation) */
.field.is-err input,.field.is-err select{border-color:#b3261e;background:#fff6f5}
.field.is-ok input,.field.is-ok select{border-color:#1c6b38}
.field__err{color:#b3261e;margin-top:.35rem;font-size:.82rem;line-height:1.4}
/* 57 (ROBUST, VWO 100+ tests: a trust cue at the CTA lifted conversion +42%
   for first-time visitors to a brand they do not already know) */
.form__privacy{color:var(--text-soft);justify-content:center;align-items:flex-start;gap:.45rem;margin-top:.9rem;font-size:.84rem;line-height:1.45;display:flex}
.form__privacy svg{flex:none;margin-top:.22rem}

/* --- rules 19, 21, 24, 26: social proof ---------------------------------- */
/* Star glyphs paint the real fraction. 4.9 renders as 4.9, never rounded to a
   flat 5, because rule 20 (ROBUST, Spiegel) records that 46% of shoppers
   distrust a perfect score. The amber is the review convention rather than the
   brand accent, which keeps rule 14's accent isolation intact. */
.stars{line-height:0;display:inline-block;position:relative}
.stars__track,.stars__fill{flex-wrap:nowrap;gap:2px;display:flex}
.stars__track{color:#16181c30}
.stars__fill{color:#e8a33d;width:100%;position:absolute;inset:0;overflow:hidden}
.rev__aggregate--dark .stars__track,.section--dark .stars__track{color:#ffffff40}
.rev__head{flex-wrap:wrap;justify-content:space-between;align-items:flex-end;gap:1.6rem;margin-bottom:2.4rem;display:flex}
/* 24 (ROBUST, NNG): the claim itself is the link out to the platform. */
.rev__aggregate{border:1px solid var(--line);border-radius:var(--radius);transition:border-color .28s var(--ease),transform .28s var(--ease);flex-wrap:wrap;align-items:center;gap:.5rem 1rem;min-height:48px;padding:1rem 1.2rem;display:flex}
a.rev__aggregate:hover{border-color:var(--accent);transform:translateY(-2px)}
.rev__aggregate--dark{border-color:var(--line-dark);background:#ffffff0f;color:#fff}
.rev__agg-num{font-family:var(--font-poster);font-size:2.1rem;line-height:1}
.rev__agg-body{flex-direction:column;gap:.35rem;display:flex}
.rev__agg-count{font:600 .82rem/1.3 var(--font-display);color:var(--text-soft)}
.rev__aggregate--dark .rev__agg-count{color:#ffffffbd}
.rev__agg-go{font:700 .74rem/1 var(--font-display);letter-spacing:.09em;text-transform:uppercase;color:var(--accent-ink);align-items:center;gap:.4rem;margin-left:auto;display:inline-flex}
.rev__aggregate--dark .rev__agg-go{color:var(--accent-lite,var(--accent))}
.rev__proof{flex-wrap:wrap;align-items:center;gap:1.2rem;display:flex}
.rev__proof .rev__aggregate{flex:0 0 auto}
/* Hard cap of 6 badges is enforced in the generator, not here: the checklist's
   myth list records 7 or more measuring 8% worse. */
.rev__badges{flex-wrap:wrap;gap:.55rem;display:flex}
.rev__badge{font:600 .82rem/1 var(--font-display);color:var(--text-soft);background:var(--mist);border:1px solid var(--line);border-radius:var(--radius);align-items:center;gap:.4rem;padding:.75rem .9rem;display:inline-flex}
.rev__badge svg{color:#1c6b38;flex:none}
.rev__grid{grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:1.3rem;display:grid}
.rev{background:var(--mist);border:1px solid var(--line);border-radius:8px;flex-direction:column;gap:1rem;margin:0;padding:1.6rem;display:flex}
.rev__text{color:var(--ink);margin:0;font-size:1.02rem;line-height:1.6}
.rev__who{align-items:center;gap:.8rem;margin-top:auto;display:flex}
.rev__who-body{flex-direction:column;min-width:0;display:flex}
.rev__face{object-fit:cover;border-radius:50%;flex:none;width:48px;height:48px}
.rev__face--initial{background:var(--ink);color:#fff;font-family:var(--font-poster);place-items:center;font-size:1.15rem;display:grid}
.rev__name{font-size:.98rem;font-weight:700}
.rev__meta{color:var(--text-soft);margin-top:.15rem;font-size:.82rem}
/* 26 (ROBUST, Spiegel +15%): the local-services equivalent of a verified buyer. */
.rev__verified{font:600 .74rem/1 var(--font-display);color:#1c6b38;align-items:center;gap:.35rem;margin-top:.4rem;display:inline-flex}
.rev-inline{margin-bottom:1rem}
.rev-inline .rev__aggregate{width:100%}

/* --- rule 15 (ROBUST, GoodUI 7% to 12.8%, +84%): the repeated CTA --------- */
.cta-row{background:var(--mist);border-block:1px solid var(--line);padding-block:2.2rem}
.cta-row__inner{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:1.4rem;display:flex}
.cta-row__line{font-family:var(--font-poster);text-transform:uppercase;font-size:clamp(1.15rem,2vw,1.5rem);line-height:1.1}
.cta-row__sub{color:var(--text-soft);margin-top:.4rem;font-size:.95rem}
.cta-row__acts{flex-wrap:wrap;gap:.7rem;display:flex}
@media (width<=680px){.cta-row__acts{width:100%}.cta-row__acts .btn{flex:1 1 100%}}

/* --- rule 38 (DIRECTIONAL, CXL eye tracking): a cue that points AT the CTA - */
.cue-down{padding-bottom:3.4rem;position:relative}
.cue-down:after{content:"";background:linear-gradient(var(--accent-ink),#0000);width:2px;height:1.6rem;position:absolute;bottom:1.1rem;left:50%;transform:translateX(-50%)}
.cue-down:before{content:"";border-right:2px solid var(--accent-ink);border-bottom:2px solid var(--accent-ink);width:10px;height:10px;position:absolute;bottom:.8rem;left:50%;transform:translateX(-50%)rotate(45deg)}

/* --- opening hours, read off the contractor's own site ------------------- */
.channel--hours{align-items:flex-start}
.hours{flex-direction:column;gap:.3rem;margin-top:.3rem;display:flex}
.hours li{justify-content:space-between;gap:1.2rem;font:600 .93rem/1.35 var(--font-display);display:flex}
.hours__days{color:#ffffffbd}
.hours__time{white-space:nowrap}
.contact__finance{color:var(--accent-lite,var(--accent));margin-top:.7rem;font-weight:600}

/* --- rule 37 (ROBUST, CXL +24.5%): /quote/ left column carries proof ------ */
.quote__proof{flex-direction:column;align-items:flex-start;gap:1.1rem;display:flex}
.quote__proof .rev__badges{gap:.5rem}
.quote__proof .rev__badge{color:#ffffffd1;background:#ffffff0f;border-color:var(--line-dark)}
.hero__trust--left{text-align:left;justify-content:flex-start;gap:.6rem 1.4rem}

/* --- rules 18 and 70 (ROBUST, Apple HIG 44pt / Google 48px) --------------- */
/* Only the elements on the conversion path are raised here. */
.callbar a{min-height:52px;padding:1.15rem .5rem}
.header__phone{min-height:48px}
.social a{place-items:center;width:48px;height:48px;display:grid}

@media (prefers-reduced-motion:reduce){
  a.rev__aggregate:hover{transform:none}
}

/* --- the optional-fields disclosure needs a visible affordance -------------
   `display:flex` on a <summary> removes the browser's default triangle, so the
   control rendered as plain text with nothing saying it opens. Caught by looking
   at the screenshot, not by any gate. An explicit chevron replaces the marker. */
.form__more-toggle{list-style:none;justify-content:flex-start}
.form__more-toggle::-webkit-details-marker{display:none}
.form__more-toggle:after{content:"";border-right:2px solid currentColor;border-bottom:2px solid currentColor;width:7px;height:7px;margin-top:-3px;margin-left:.2rem;transition:transform .25s var(--ease);transform:rotate(45deg)}
.form__more[open] .form__more-toggle:after{margin-top:2px;transform:rotate(-135deg)}

/* ==========================================================================
   CRO fix 6: contrast (rules 60, 61) and tap targets (rules 18, 70)
   Additive block. Measured values, not estimates. Method and numbers:
   contrast computed with scripts/contrast-gate.py's WCAG 2.1 formula,
   box sizes read from live getBoundingClientRect() at 390x844 in Chrome.
   ========================================================================== */

/* --- rules 60 and 61: text under the 4.5:1 AA floor ----------------------
   --text-mute was #16181c85 (alpha .522), measured 3.61:1 on --paper and
   3.52:1 on --mist. Both fail. It styles the label on every field of the only
   conversion mechanism on the site, which is the worst possible placement for
   text a 20/40 eye cannot resolve.

   Every selector that reads this token sits on a light surface (.field label,
   .form__note, .stat__label, .area__county, .sel__value, .sel__chev,
   .sel__opt[aria-disabled]), so darkening the token itself fixes all of them
   at once. Checked each one rather than assuming.

   #16181ca5 (alpha .647) measures 5.43:1 on --paper and 5.26:1 on --mist.
   It stays visibly lighter than --text-soft (alpha .722), so the three step
   type hierarchy of ink, soft, mute survives. */
:root{--text-mute:#16181ca5}

/* An outline button sitting ON the accent band inherited --ink, measured
   2.71:1 against the accent fill. The band already flips its own text to
   --on-accent for exactly this reason; the button was missed. --on-accent is
   white on this brand and measures 6.68:1 on the fill. Never hardcode the
   value: dark and light brand accents resolve it differently. */
.band .btn--outline{color:var(--on-accent,var(--ink));border-color:var(--on-accent,var(--ink))}
.band .btn--outline:hover{background:var(--on-accent,var(--ink));color:var(--accent)}

/* --- rules 18 and 70: every tap target reaches 48px ---------------------
   Measured before: sticky call bar 45.4px, header phone 39.4px, social icons
   40x40px, burger 44x44px, brandmark 34px, FAQ call link 44.7px, and 17
   footer and menu links at 18px with no row spacing. Google Material and the
   W3C both put the floor at 48px; Apple's HIG says 44pt. Hold 48. */
.callbar a{min-height:52px;padding:1.15rem .5rem}
.header__phone{min-height:48px}
.social a{width:48px;height:48px}
.header__burger{width:48px;height:48px}
.brandmark{min-height:48px;align-items:center;display:inline-flex}
.faq__call{min-height:48px;align-items:center;display:inline-flex}

/* Floors, so these can never regress below the standard as their padding or
   font size is retuned. All three already measured over 48px; a floor costs
   nothing and removes the need to re-measure after every type change. */
.btn{min-height:48px}
.faq__trigger{min-height:48px}
.sel__trigger{min-height:48px}

/* Footer and mobile menu link lists were 18px rows touching each other, which
   fails the spacing half of rule 70 as well as the size half. Padding rather
   than a fixed height keeps the text baseline where the design put it. */
.footer ul a,.aside ul a,.mobile-menu a{min-height:48px;align-items:center;display:inline-flex}
.footer__legal a{min-height:48px;align-items:center;display:inline-flex}

/* Deliberately NOT enlarged, each for a stated reason:
   .hp            the honeypot. It has to stay invisible or it stops trapping.
   .sel__native   the visually hidden native <select> behind the custom one.
                  It is 1x1 by design and the 48px trigger is its real target.
   .field label   a label forwards focus to its input but is not the primary
                  control, and inflating every label to 48px would pull the
                  form apart vertically. The inputs themselves clear 48px. */

/* --- rule 34 (ROBUST, NNG: 57% of viewing time is above the fold) ----------
   Measured at 1440x900 on /quote/: the submit button sat at 909px, nine pixels
   under the fold. These four declarations are scoped to the in-hero form only,
   so the contact-block form keeps its roomier spacing. Input font size is left
   at 16px on purpose (rule 59, iOS auto-zoom on focus). */
.hero .form--hero{padding:1.5rem}
.hero .form--hero h3{margin-bottom:.5rem;font-size:1.15rem}
.hero .form--hero .form__legend{margin-bottom:.8rem}
.hero .form--hero .field{margin-bottom:.72rem}
.hero .form--hero .form__more{margin:.1rem 0 .85rem;padding-top:.7rem}

/* --- rule 70, second pass. Found by re-measuring, not by assuming the first
   pass was complete. All values below are the measured layout box at 390px. */

/* Was 29px wide by 48px tall: the mark alone is narrow on mobile. */
.brandmark{min-width:48px;justify-content:center}

/* The optional-fields disclosure measured 44px. */
.form__more-toggle{min-height:48px;align-items:center}

/* Breadcrumb links measured 12px tall. */
.crumbs a{min-height:48px;align-items:center;display:inline-flex}

/* Phone links sitting inside a sentence measured 16px, 19px and 43px tall.
   inline-flex would break the line they live in, so the hit area grows with
   padding and is pulled back with an equal negative margin: the touch target
   passes 48px and the text sits exactly where it did. Each of these is the
   only link in its paragraph, so no two hit areas can overlap. */
.form__note a,.footer__blurb a,.aside .body a{padding-block:1.05rem;margin-block:-1.05rem}.form__more:not([open]) .field{display:none}

/* --- rule 60, the failure a computed-style sweep cannot see -----------------
   .strip__cat sat in the accent color ON TOP of a photograph. Any checker that
   resolves a background by walking up to the nearest opaque ancestor reports
   this as accent-on-white and gets the wrong answer in both directions. Read
   off the actual painted pixels of a 390px screenshot, the kicker measured
   2.27:1 against its real backdrop and 3.10:1 in the flattest part of the
   scrim. Both fail 4.5:1.

   Strengthening the scrim does not rescue it: --accent-lite has a relative
   luminance of 0.2387, so it needs a backdrop under 0.0141 to reach 4.5:1, and
   even a 96% opaque scrim over a bright photo only reaches 4.38:1. A mid
   luminance color cannot sit on unpredictable imagery and stay legible.

   So the kicker inherits .strip__overlay's own white, which measured 11.03:1
   on the same backdrop. No literal color is introduced. It also serves rule
   14, which wants the accent isolated to the CTA rather than repeated over
   every portfolio card. Weight, size, letter-spacing and uppercase still
   separate the kicker from the title below it. */
.strip__cat{color:inherit;opacity:.86}

/* ==========================================================================
   TRUST SEALS, WHY-US ICONS, AND PHOTO SERVICE-AREA CARDS
   Additive block. Nothing above this line is edited.

   The client read the site and named four dead spots: credentials printed as
   words instead of marks, why-us cards with no icons, a service area grid of
   plain text, and the same word-only credentials again on the dark row. Every
   rule below exists to fix one of those and every color is a token.
   ========================================================================== */

/* --- 1. the Google mark inside the rating ---------------------------------
   The G sits at the head of the aggregate, so the 4.9 and the 528 read as
   Google's numbers rather than ours. The svg is inline markup with its own
   four brand fills; nothing here recolors it. */
.rev__agg-mark{flex:none;align-items:center;display:inline-flex;margin-right:.15rem}
.rev__agg-mark svg{width:22px;height:22px;display:block}
.rev__aggregate--dark .rev__agg-mark svg,.rev__aggregate .rev__agg-mark svg{opacity:1}

/* --- 2. the seals ---------------------------------------------------------
   Every mark is boxed to one height, so a row of badges with wildly different
   aspect ratios still lines up on its baseline. 42px is the measured height in
   both the light proof block and the dark quote hero.

   The two supplied badges are RGBA but almost entirely opaque, so they need no
   plate on either surface. --seal-plate is defined anyway and left transparent:
   a contractor whose badge is a white knockout sets it once and every seal on
   both surfaces gets a plate, with no markup change. */
.seals{--seal-h:42px;--seal-plate:#0000;grid-template-columns:repeat(3,minmax(0,1fr));gap:1.5rem 1.6rem;width:100%;display:grid;list-style:none;margin:0;padding:0}
.seal{flex-direction:column;align-items:flex-start;gap:.6rem;display:flex}
.seal__mark{background:var(--seal-plate);border-radius:3px;align-items:center;height:var(--seal-h);display:inline-flex}
.seal__mark img{width:auto;height:var(--seal-h);max-width:100%;object-fit:contain;display:block}
.seal__mark--drawn{color:var(--accent-ink);gap:.5rem;padding-right:.2rem}
.seal__mark--drawn svg{flex:none;width:26px;height:26px}
.seal__word{font-family:var(--font-poster);text-transform:uppercase;letter-spacing:-.005em;color:var(--ink);font-size:1.06rem;line-height:1.1}
.seal__note{color:var(--text-soft);max-width:34ch;font-size:.855rem;line-height:1.55}

/* Dark surfaces: the quote hero and anywhere .section--dark wraps a seal row.
   The badges are opaque so they carry themselves; only the drawn shield and
   the note text need lifting off the ink. */
.seals--dark .seal__mark--drawn,.section--dark .seal__mark--drawn{color:var(--accent-lite,var(--accent))}
.seals--dark .seal__word,.section--dark .seal__word{color:#fff}
.seals--dark .seal__note,.section--dark .seal__note{color:#ffffffad}

/* The /quote/ hero runs the marks with no notes, in one tight row, because
   rule 34 is measured in pixels on that page. */
.seals--compact{grid-template-columns:none;flex-wrap:wrap;align-items:center;gap:1.1rem 1.4rem;display:flex}
.seals--compact .seal{--seal-h:34px;flex-direction:row;align-items:center}

/* The proof block stacks: rating first, then the seal row across the width. */
.rev__proof{flex-direction:column;align-items:flex-start;gap:1.7rem;display:flex}
.rev__proof .rev__aggregate{flex:0 0 auto}

/* --- 3. the certifications row, dark -------------------------------------
   Same mark, same plain sentence, on the ink section. The card already carried
   a name and a note; it was the mark that was missing. */
.cert__seal{align-items:center;height:46px;margin-bottom:1.1rem;display:flex}
.cert__seal .seal__mark{--seal-h:46px}
.cert__seal .seal__mark--drawn{color:var(--accent-lite,var(--accent))}
.cert__seal .seal__word{color:#fff}

/* --- 4. why-us icons ------------------------------------------------------
   44px, stroked, inheriting the accent through currentColor on the wrapper so
   no literal color is introduced. */
.why__icon{color:var(--accent-ink);align-items:center;height:44px;margin-bottom:1rem;display:flex}
.why__icon svg{width:44px;height:44px;display:block}
.section--dark .why__icon{color:var(--accent-lite,var(--accent))}
.why__item{transition:transform .38s var(--ease),box-shadow .38s var(--ease),color .28s var(--ease)}

/* --- 5. the service area grid, with photographs --------------------------
   Built out of the .svc-card language: media box, scrim, name over it, county
   under it, and the lift plus zoom plus accent edge every other card on the
   site already does. The .area__card:after accent rail from the hover layer
   still applies, so the edge treatment is literally the same rule. */
.area__grid--media{display:flex;flex-wrap:wrap;justify-content:center;gap:1.15rem;margin-top:2.4rem}
.area__grid--media>*{flex:0 1 calc((100% - 3.45rem)/4);min-width:250px}
.area__card--media{background:var(--paper);border:1px solid var(--line);border-radius:8px;gap:0;padding:0;overflow:hidden}
.area__media{aspect-ratio:16/10;display:block;position:relative;overflow:hidden}
.area__media img{object-fit:cover;width:100%;height:100%;transition:transform .7s var(--ease)}
.area__media:before{content:"";z-index:1;background:linear-gradient(#16181c1f 0%,#0000 38%,#16181ceb 100%);position:absolute;inset:0}
.area__media:after{content:"";z-index:1;background:var(--accent);mix-blend-mode:multiply;opacity:0;transition:opacity .4s var(--ease);position:absolute;inset:0}
.area__card--media .area__name{color:#fff;z-index:2;text-shadow:0 1px 12px #16181c8c;font-size:1.12rem;position:absolute;bottom:.85rem;left:1.05rem;right:1.05rem}
.area__body{justify-content:space-between;align-items:center;gap:.8rem;padding:.95rem 1.05rem 1rem;display:flex}
.area__go{color:var(--accent-ink);align-items:center;display:inline-flex;transition:transform .3s var(--ease)}
@media (hover:hover){
  .area__card--media:hover .area__media img{transform:scale(1.07)}
  .area__card--media:hover .area__media:after{opacity:.12}
  .area__card--media:hover .area__go{transform:translate(4px)}
}

/* --- 6. narrow screens ---------------------------------------------------- */
@media (max-width:900px){
  .seals{grid-template-columns:repeat(2,minmax(0,1fr));gap:1.3rem}
}
@media (max-width:560px){
  .seals{--seal-h:36px;grid-template-columns:1fr}
  .cert__seal{height:38px}
  .cert__seal .seal__mark{--seal-h:38px}
  .why__icon,.why__icon svg{height:40px}
  .why__icon svg{width:40px}
}

/* The drawn shield is alone in a .cert card now that the word moved to the h3
   under it, so it grows to fill the same 46px box the badge images occupy. */
.cert__seal .seal__mark--drawn svg{width:38px;height:38px}.seal__mark--drawn{border:1px solid var(--line);border-radius:3px;min-width:118px;justify-content:center;padding:0 .85rem;gap:.55rem}.seal__mark--drawn svg{width:calc(var(--seal-h) * .58);height:calc(var(--seal-h) * .58)}.section--dark .seal__mark--drawn,.seals--dark .seal__mark--drawn{border-color:var(--line-dark);background:#ffffff0a}.cert .seal__mark--drawn{min-width:132px}.section--dark .seal__mark:not(.seal__mark--drawn),.seals--dark .seal__mark:not(.seal__mark--drawn),.cert .seal__mark:not(.seal__mark--drawn){background:#fff;border-radius:4px;padding:6px 10px;height:auto}.section--dark .seal__mark:not(.seal__mark--drawn) img,.seals--dark .seal__mark:not(.seal__mark--drawn) img,.cert .seal__mark:not(.seal__mark--drawn) img{height:calc(var(--seal-h) - 4px)}.cert__seal{margin-bottom:1.1rem}.form .sel__trigger{background:var(--mist);border:1px solid var(--line);color:var(--ink)}.form .sel__trigger:hover{border-color:var(--text-mute)}.form .sel--open .sel__trigger,.form .sel__trigger:focus-visible{border-color:var(--accent);background:var(--paper);box-shadow:0 0 0 3px #16181c14}.form .sel__value{color:var(--ink)}.form .sel--empty .sel__value{color:var(--text-mute)}.form .sel__chev{color:var(--text-mute)}.form .sel__panel{background:var(--paper);border:1px solid var(--line);box-shadow:0 24px 60px -20px #00000038}.form .sel__opt{color:var(--ink)}

/* REPERTOIRE MODULES (references/design-repertoire.md): call band, catch-all card, estimate wizard */
.callband{background:var(--accent);color:var(--on-accent,var(--ink))}
.callband__inner{display:flex;flex-direction:column;align-items:flex-start;gap:.5rem;padding-block:clamp(2.5rem,6vw,4rem)}
.callband__line{font-family:var(--font-poster);text-transform:uppercase;text-wrap:balance;font-size:clamp(1.5rem,3vw,2.4rem);line-height:1.05;margin:0}
.callband__line .hx-accent{color:inherit}
.callband__sub{color:inherit;max-width:46ch;margin:0}
.callband__tel{font-family:var(--font-poster);font-size:clamp(2.1rem,6.5vw,4.4rem);letter-spacing:-.01em;line-height:1;border-bottom:4px solid currentColor;white-space:nowrap}
.callband__tel:hover{opacity:.85}
@media(min-width:760px){.callband__inner{flex-direction:row;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:1.2rem}}
.svc-card--catchall{display:flex;align-items:center;border:2px dashed var(--accent);background:transparent;min-height:220px}
.svc-card--catchall .svc-card__body{padding:2rem 1.6rem}
.section--dark .svc-card--catchall{background:#ffffff08}
.wiz{max-width:680px;margin-inline:auto}
.wiz__progress{height:6px;background:var(--line);border-radius:99px;overflow:hidden;margin:1.6rem 0 2.2rem}
.wiz__progress i{display:block;height:100%;width:0;background:var(--accent);transition:width .35s var(--ease)}
.wiz__step{display:none}
.wiz__step.is-on{display:block}
.wiz__q{font-family:var(--font-poster);text-transform:uppercase;font-size:clamp(1.3rem,2.6vw,1.9rem);line-height:1.1;margin-bottom:1.4rem}
.wiz__opts{display:grid;gap:.7rem}
.wiz__opt{display:flex;justify-content:space-between;align-items:baseline;gap:1rem;text-align:left;width:100%;padding:1.05rem 1.2rem;border:1.5px solid var(--line);border-radius:var(--radius);background:var(--paper);transition:border-color .15s,transform .15s}
.wiz__opt:hover{border-color:var(--accent);transform:translateY(-1px)}
.wiz__opt-note{color:var(--text-soft);font-size:.92rem;white-space:nowrap}
.wiz__back{margin-top:1.4rem;display:inline-block;color:var(--text-soft);text-decoration:underline}
.wiz__summary{margin:0 0 1.4rem;padding:1rem 1.2rem;border-left:3px solid var(--accent);background:var(--mist)}
.wiz__summary li{display:flex;justify-content:space-between;gap:1rem;padding:.2rem 0}
.wiz__summary li span:first-child{color:var(--text-mute);text-transform:capitalize}
.wiz__note{color:var(--text-mute);font-size:.9rem;margin-top:1.2rem}
/* HERO LAYOUT VARIANT (design-repertoire): heroLayout "left" in config */
.hero--left .hero__content{align-items:flex-start;text-align:left;margin-inline:0;max-width:1240px}
.hero--left .hero__title{max-width:14ch}
.hero--left .hero__sub{max-width:52ch;text-align:left;margin-inline:0}
.hero--left .hero__trust{justify-content:flex-start}
.hero--left .hero__ctas{justify-content:flex-start}
/* QA ROUND 2 (design-repertoire): defects caught in the 6-skin visual sweep */
/* Two-voice headline accent phrase was raw --accent on dark sections = dark-on-dark. */
.section--dark .hx-accent{color:var(--accent-lite,var(--accent))}
/* Honest-aggregate reviews (no cards) hugged the left, leaving an empty right half. Center it. */
.rev--solo .rev__head{flex-direction:column;align-items:center;text-align:center}
.rev--solo .rev__head .measure{margin-inline:auto}
.rev--solo .rev__proof{justify-content:center}
.rev--solo .rev__proof .rev__aggregate{margin-inline:auto}
/* The fixed mobile call bar covered the last strip of content (footer, privacy link). Reserve space. */
@media (width<=820px){body{padding-bottom:60px}}
/* Sticky header covered anchor-jump targets. Offset every heading and id target. */
:where(h1,h2,h3,section,[id]){scroll-margin-top:calc(var(--header-h) + 16px)}
/* REPERTOIRE LAYOUT VARIANTS (references/design-repertoire.md): hero layouts, services styles, new home sections */
/* hero--form: headline left, lead form card right, on the first screen */
.hero--form .hero__content{max-width:1240px;margin-inline:auto;align-items:stretch;text-align:left}
.hero__split{display:grid;grid-template-columns:1.1fr .9fr;gap:clamp(1.5rem,4vw,3.5rem);align-items:center;width:100%}
.hero__copy{display:flex;flex-direction:column;align-items:flex-start}
.hero--form .hero__title{max-width:14ch}
.hero--form .hero__sub{text-align:left;margin-inline:0;max-width:48ch}
.hero--form .hero__ctas,.hero--form .hero__trust{justify-content:flex-start}
.hero__formcol .form--hero{margin:0}
@media (width<=900px){.hero__split{grid-template-columns:1fr}.hero--form .hero__content{align-items:center;text-align:center}.hero__copy{align-items:center}.hero--form .hero__sub{text-align:center;margin-inline:auto}.hero--form .hero__ctas,.hero--form .hero__trust{justify-content:center}}
/* hero--minimal: short, content-first, no cue */
.hero--minimal{min-height:auto}
.hero--minimal .hero__content{padding-block:clamp(5.5rem,12vw,8rem) clamp(3rem,7vw,5rem)}
.hero--minimal .hero__title{font-size:clamp(2rem,4vw,3.2rem)}
/* hero--poster: giant type, no sub */
.hero--poster .hero__title{font-size:clamp(3rem,8.5vw,7.2rem);line-height:.92;max-width:12ch;letter-spacing:-.02em}
.hero--poster .hero__ctas{margin-top:2rem}
/* services list */
.svclist{border-top:1px solid var(--line-dark);display:flex;flex-direction:column}
.svclist__row{display:grid;grid-template-columns:3.2rem 1fr auto;align-items:center;gap:1.2rem;padding:1.35rem 0;border-bottom:1px solid var(--line-dark);color:inherit;transition:padding-left .25s var(--ease),color .25s var(--ease)}
.svclist__row:hover{padding-left:.6rem;color:var(--accent-lite,var(--accent))}
.svclist__n{font-family:var(--font-poster);font-size:1.1rem;color:var(--accent-lite,var(--accent));opacity:.8}
.svclist__name{margin:0}
.svclist__desc{color:#ffffffb0;font-size:.95rem;grid-column:2;max-width:64ch}
.svclist__row svg{grid-column:3;grid-row:1/3;width:20px;height:20px}
@media (width<=620px){.svclist__row{grid-template-columns:2.4rem 1fr auto;gap:.8rem}}
/* services tiles */
.svctiles{display:grid;grid-template-columns:repeat(3,1fr);gap:1.1rem}
.svctile{display:flex;flex-direction:column;gap:.55rem;padding:1.6rem 1.4rem;background:#ffffff0a;border:1px solid var(--line-dark);border-radius:10px;color:inherit;transition:transform .3s var(--ease),border-color .3s var(--ease)}
.svctile:hover{transform:translateY(-5px);border-color:var(--accent)}
.svctile svg{width:34px;height:34px;color:var(--accent-lite,var(--accent))}
.svctile__name{margin:.3rem 0 0}
.svctile__desc{color:#ffffffb0;font-size:.95rem;flex:1}
@media (width<=1040px){.svctiles{grid-template-columns:repeat(2,1fr)}}
@media (width<=620px){.svctiles{grid-template-columns:1fr}}
/* stats band (standalone) */
.statband{padding-block:clamp(2.5rem,6vw,4rem)}
.stats--band{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:1.2rem;text-align:center;margin:0}
.stats--band .stat__val{font-size:clamp(2.2rem,5vw,3.6rem)}
/* tagged gallery */
.gal{display:grid;grid-template-columns:repeat(4,1fr);gap:.9rem;margin-top:2rem}
.gal__item{margin:0;position:relative;border-radius:8px;overflow:hidden;aspect-ratio:4/3}
.gal__item img{width:100%;height:100%;object-fit:cover;transition:transform .7s var(--ease)}
.gal__item:hover img{transform:scale(1.05)}
.gal__tag{position:absolute;left:.7rem;bottom:.7rem;background:var(--accent);color:var(--on-accent,var(--ink));font:700 .66rem/1 var(--font-display);letter-spacing:.12em;text-transform:uppercase;padding:.45rem .6rem;border-radius:3px}
@media (width<=1040px){.gal{grid-template-columns:repeat(3,1fr)}}
@media (width<=620px){.gal{grid-template-columns:repeat(2,1fr)}}
/* guarantee */
.guarantee{display:grid;grid-template-columns:120px 1fr;gap:2rem;align-items:start}
.guarantee__mark{color:var(--accent);width:120px;height:120px}
.guarantee__mark svg{width:100%;height:100%}
@media (width<=620px){.guarantee{grid-template-columns:1fr}.guarantee__mark{width:72px;height:72px}}
/* wizard teaser */
.wizteaser{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:2rem}
.wizteaser__chips{display:flex;flex-wrap:wrap;gap:.6rem;margin-top:1.4rem}
.wizteaser__chip{display:inline-flex;flex-direction:column;gap:.15rem;padding:.7rem 1rem;border:1px solid var(--line-dark);border-radius:6px;background:#ffffff0a;font-size:.9rem;color:#ffffffc0}
.wizteaser__chip b{color:#fff;font-weight:600}
/* wide GPT lockups shrank inside the fixed header box; size by height with a wider cap */
.brandmark img{height:44px;width:auto;max-width:280px;object-fit:contain}
@media (width<=560px){.brandmark img{height:36px;max-width:160px}}

/* ==========================================================================
   COMPONENT VARIANTS (Sep 2, 2026)
   Victor on the twelve template demos: "still very cookie cutter, same layout,
   no different functions". Reordering identical components is not variety, so
   these five axes change what the components ARE. Every selector below is
   keyed off a class the generator only emits when the config asks for it, so a
   config that sets none of them renders exactly what it rendered before.
     body.mode-light   colorMode
     body.hdr-*        headerStyle    .header--centered|--utility|--transparent
     body.chrome-*     sectionChrome
     body.cards-*      cardStyle
     body.foot-*       footerStyle    .footer--compact|--centered
   ========================================================================== */

/* --- 1. colorMode: light -------------------------------------------------
   Paper first. The ink sections become mist, so the page alternates
   paper / mist instead of paper / near-black, and the only surfaces left dark
   are the ones that are meant to interrupt: the hero photograph, the accent
   band, the offer band, the image band and the footer. */
body.mode-light .section--dark{background:var(--mist);color:var(--ink);border-block:1px solid var(--line)}
body.mode-light .section--dark .body{color:var(--text-soft)}
body.mode-light .section--dark .body strong{color:var(--ink)}
body.mode-light .section--dark .kicker,body.mode-light .section--dark .stat__val,
body.mode-light .section--dark .why__icon,body.mode-light .section--dark .hx-accent,
body.mode-light .section--dark .svc-card__cta,body.mode-light .section--dark .contact__finance,
body.mode-light .section--dark .rev__agg-go{color:var(--accent-ink)}
body.mode-light .section--dark .stat__label{color:var(--text-mute)}
body.mode-light .section--dark .stats{border-top-color:var(--line)}
body.mode-light .section--dark .proc__desc{color:var(--text-soft)}
body.mode-light .section--dark .stars__track{color:#16181c33}
body.mode-light .grid-tex:before{background-image:linear-gradient(#16181c0f 1px,#0000 1px),linear-gradient(90deg,#16181c0f 1px,#0000 1px)}
body.mode-light .section--dark .svc-card{background-color:var(--paper);color:var(--ink);border-color:var(--line)}
body.mode-light .section--dark .svc-card__desc{color:var(--text-soft)}
body.mode-light .section--dark .svc-card:hover{box-shadow:0 30px 60px -30px #16181c4d}
body.mode-light .section--dark .svc-card:hover .svc-card__name{color:var(--accent-ink)}
body.mode-light .section--dark .svc-card--catchall{background:#16181c05}
body.mode-light .section--dark .cert{background:var(--paper);border-color:var(--line)}
body.mode-light .section--dark .cert__name{color:var(--ink)}
body.mode-light .section--dark .cert__note{color:var(--text-soft)}
body.mode-light .section--dark .cert:hover .cert__name{color:var(--accent-ink)}
body.mode-light .section--dark .cert__seal .seal__word{color:var(--ink)}
body.mode-light .section--dark .seal__mark--drawn{background:#16181c08;border-color:var(--line);color:var(--accent-ink)}
body.mode-light .section--dark .seal__mark:not(.seal__mark--drawn){background:0 0}
body.mode-light .section--dark .seal__word{color:var(--ink)}
body.mode-light .section--dark .seal__note{color:var(--text-soft)}
body.mode-light .section--dark .svctile{background:#16181c05;border-color:var(--line)}
body.mode-light .section--dark .svctile__desc{color:var(--text-soft)}
body.mode-light .section--dark .svctile svg{color:var(--accent-ink)}
body.mode-light .section--dark .svclist{border-top-color:var(--line)}
body.mode-light .section--dark .svclist__row{border-bottom-color:var(--line)}
body.mode-light .section--dark .svclist__desc{color:var(--text-soft)}
body.mode-light .section--dark .svclist__n,body.mode-light .section--dark .svclist__row:hover{color:var(--accent-ink)}
body.mode-light .section--dark .channel{color:var(--ink);background:var(--paper);border-color:var(--line)}
body.mode-light .section--dark a.channel:hover{background:var(--paper);border-color:var(--accent)}
body.mode-light .section--dark .channel__label{color:var(--text-mute)}
body.mode-light .section--dark .form{border:1px solid var(--line);box-shadow:0 30px 70px -40px #16181c66}
body.mode-light .section--dark .rev__aggregate--dark{background:var(--paper);border-color:var(--line);color:var(--ink)}
body.mode-light .section--dark .rev__aggregate--dark .rev__agg-count{color:var(--text-soft)}
body.mode-light .section--dark .sel__trigger{color:var(--ink);background:var(--mist);border-color:var(--line)}
body.mode-light .section--dark .wizteaser__chip{background:#16181c05;border-color:var(--line);color:var(--text-soft)}
body.mode-light .section--dark .wizteaser__chip b{color:var(--ink)}
body.mode-light .section--dark .proc-scrub .proc__n{color:var(--text-soft);background:#16181c1a}
body.mode-light .crumbs--bar{background:var(--mist);color:var(--text-mute);border-bottom-color:var(--line)}
body.mode-light .crumbs--bar a{color:var(--text-soft)}
/* The header rides over a photographic hero, so it keeps white text there and
   flips to ink only once it is sitting on paper. A "light header" that turned
   ink the moment the page loaded would be ink text on a dark photograph. */
body.mode-light .header.stuck{background:var(--paper);border-bottom-color:var(--line)}
body.mode-light .header.stuck .header__nav a{color:var(--text-soft)}
body.mode-light .header.stuck .header__phone{color:var(--ink);border-color:var(--line)}
body.mode-light .header.stuck .header__burger{color:var(--ink)}
body.mode-light .header.stuck .header__phone:hover{color:var(--on-accent,var(--ink))}

/* --- 2. headerStyle ------------------------------------------------------ */
/* centered: logo on its own centered row, nav under it, actions under that. */
body.hdr-centered{--header-h:152px}
.header--centered{height:auto;padding-block:.75rem}
.header--centered .header__inner{grid-template-columns:1fr;justify-items:center;gap:.5rem;display:grid}
.header--centered .header__nav{justify-content:center}
.header--centered .header__cta{justify-content:center}
.header--centered .header__burger{position:absolute;top:1.1rem;right:var(--pad)}
/* utility: a thin always-solid strip of facts above the nav row. */
body.hdr-utility{--header-h:132px}
.header--utility{height:auto;flex-direction:column;align-items:stretch;padding:0}
.header__util{background:var(--ink);border-bottom:1px solid var(--line-dark)}
body.mode-light .header__util{background:var(--paper);border-bottom-color:var(--line)}
.hutil{flex-wrap:wrap;align-items:center;gap:1.5rem;padding-block:.6rem;font:600 .78rem/1 var(--font-display);color:#ffffffc4;display:flex}
body.mode-light .hutil{color:var(--text-soft)}
.hutil__item{align-items:center;gap:.45rem;display:inline-flex;min-height:32px}
.hutil__tel{font-weight:700;color:#fff}
body.mode-light .hutil__tel{color:var(--ink)}
.hutil__note{margin-left:auto;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--accent-lite,var(--accent))}
body.mode-light .hutil__note{color:var(--accent-ink)}
.header--utility .header__inner{height:78px}
/* transparent: never a full-width bar. On scroll it contracts into a floating
   pill so the page underneath keeps showing through at the edges. */
.header--transparent:before{content:"";pointer-events:none;background:linear-gradient(#16181cb0,#0000);height:190%;position:absolute;inset:0 0 auto;z-index:-1}
.header--transparent.stuck{background:0 0;border-bottom-color:#0000}
.header--transparent.stuck .header__inner{background:var(--ink);border:1px solid var(--line-dark);border-radius:100px;width:auto;max-width:calc(var(--maxw) - 2rem);padding:.5rem .6rem .5rem 1.4rem;box-shadow:0 20px 44px -22px #000000a6}
body.mode-light .header--transparent.stuck .header__inner{background:var(--paper);border-color:var(--line);box-shadow:0 20px 44px -26px #16181c73}
body.mode-light .header--transparent.stuck .header__nav a{color:var(--text-soft)}
body.mode-light .header--transparent.stuck .header__phone{color:var(--ink);border-color:var(--line)}
body.mode-light .header--transparent.stuck .header__burger{color:var(--ink)}
.header--transparent .header__prog{bottom:0}

/* --- 3. sectionChrome ---------------------------------------------------- */
.shead--plain{font-size:clamp(2.05rem,4.4vw,3.5rem);letter-spacing:-.018em;max-width:20ch}
body.chrome-rule .shead__rule{background:currentColor;opacity:.2;width:100%;height:1px;margin-bottom:1.6rem;display:block}
body.chrome-numbered main{counter-reset:shead}
body.chrome-numbered .shead__n{font-family:var(--font-poster);color:var(--accent-ink);opacity:.32;margin-bottom:.35rem;font-size:clamp(2.4rem,5.5vw,4rem);line-height:.8;letter-spacing:-.02em;display:block}
body.chrome-numbered .shead__n:before{counter-increment:shead;content:counter(shead,decimal-leading-zero)}
body.chrome-numbered .section--dark .shead__n{color:var(--accent-lite,var(--accent));opacity:.44}
body.chrome-numbered.mode-light .section--dark .shead__n{color:var(--accent-ink);opacity:.32}

/* --- 4. cardStyle -------------------------------------------------------- */
/* flat: hairline borders, square corners, photograph on top, nothing zooms. */
body.cards-flat{--radius:0}
body.cards-flat .svc-card,body.cards-flat .area__card--media,body.cards-flat .strip__item,
body.cards-flat .gal__item,body.cards-flat .cert,body.cards-flat .why__item,
body.cards-flat .plan,body.cards-flat .socialcard{border-radius:0}
body.cards-flat .svc-card{background-color:#0000;border:1px solid var(--line-dark)}
body.mode-light body.cards-flat .svc-card,body.cards-flat.mode-light .svc-card{border-color:var(--line)}
body.cards-flat .svc-card__media{aspect-ratio:16/10}
body.cards-flat .svc-card__media:before,body.cards-flat .area__media:before{background:linear-gradient(#0000 60%,#16181c99 100%)}
body.cards-flat .svc-card:hover .svc-card__media img,body.cards-flat .area__card--media:hover .area__media img,
body.cards-flat .strip__item:hover img,body.cards-flat .gal__item:hover img{transform:none}
body.cards-flat .svc-card:hover,body.cards-flat .area__card:hover,body.cards-flat .strip__item:hover,
body.cards-flat .cert:hover,body.cards-flat .why__item:hover{transform:none;box-shadow:none;border-color:var(--accent)}
body.cards-flat .svc-card:after{display:none}
body.cards-flat .area__card--media{border:1px solid var(--line)}
body.cards-flat .strip__item{border:1px solid var(--line)}
body.cards-flat .gal__tag{border-radius:0}
/* rounded: soft corners and a lifted shadow on everything, buttons included. */
body.cards-rounded{--radius:12px}
body.cards-rounded .svc-card,body.cards-rounded .area__card--media,body.cards-rounded .strip__item,
body.cards-rounded .gal__item,body.cards-rounded .splitck__media,body.cards-rounded .ba{border-radius:18px;overflow:hidden}
body.cards-rounded .cert,body.cards-rounded .why__item,body.cards-rounded .plan,
body.cards-rounded .socialcard,body.cards-rounded .form,body.cards-rounded .aside{border-radius:16px}
bodybody.cards-rounded .gal__tag,body.cards-rounded .plan__tag{border-radius:100px}
body.cards-rounded .svc-card{box-shadow:0 18px 40px -28px #00000073}
body.cards-rounded .svc-card:hover{box-shadow:0 36px 70px -30px #00000094}
body.cards-rounded .why__item{border-top-left-radius:16px;border-top-right-radius:16px}

/* --- 5. footerStyle ------------------------------------------------------ */
.footer__row{grid-template-columns:minmax(230px,1fr) 1.9fr;gap:clamp(1.8rem,4vw,3.5rem);align-items:start;display:grid}
.footer__flow{flex-wrap:wrap;gap:.2rem 1.5rem;display:flex}
.footer__flow a{font-size:.9rem}
.footer__contactline{color:#ffffff96;margin-top:1rem;font-size:.9rem;line-height:1.7}
.footer--compact .footer__blurb{max-width:30ch}
.footer--centered{text-align:center}
.footer__stack{flex-direction:column;align-items:center;gap:.9rem;display:flex}
.footer--centered .footer__blurb{max-width:54ch;margin-inline:auto}
.footer--centered .footer__flow{justify-content:center;max-width:70ch}
.footer--centered .footer__legal{justify-content:center}
.footer--centered ul.social{justify-content:center}
@media (max-width:900px){.footer__row{grid-template-columns:1fr}}

/* --- 6. heroChips (Oak City): the trust facts floated at the hero corners - */
.hero__chip{border-radius:var(--radius);color:#fff;-webkit-backdrop-filter:blur(9px);backdrop-filter:blur(9px);background:#16181cbf;border:1px solid #ffffff2e;align-items:center;gap:.55rem;max-width:min(290px,36vw);padding:.72rem 1.05rem;font:700 .78rem/1.25 var(--font-display);display:inline-flex}
.hero__chip svg{color:var(--accent-lite,var(--accent));flex:none;width:17px;height:17px}
@media (min-width:1000px){
  .hero__chips{z-index:3;pointer-events:none;margin:0;display:block;position:absolute;inset:0}
  .hero__chip{pointer-events:auto;position:absolute}
  .hero__chip:nth-child(1){top:clamp(7rem,15vh,10.5rem);left:clamp(1.5rem,5vw,5rem)}
  .hero__chip:nth-child(2){top:clamp(7rem,15vh,10.5rem);right:clamp(1.5rem,5vw,5rem)}
  .hero__chip:nth-child(3){bottom:clamp(6rem,13vh,8.5rem);left:clamp(1.5rem,5vw,5rem)}
}
@media (max-width:999px){
  .hero--chips{flex-wrap:wrap}
  .hero__chips{z-index:3;flex-wrap:wrap;justify-content:center;gap:.5rem;width:100%;margin-top:1.6rem;padding-inline:var(--pad);display:flex;position:relative}
  .hero__chip{max-width:none;font-size:.74rem}
}

/* ==========================================================================
   INTERACTIVE MODULES (repertoire axis 4, one per build)
   beforeAfter | pricingCards | testimonialCarousel | radiusMap | stickyRail |
   lightboxGallery. Behavior for all six lives at the end of assets/motion.js.
   ========================================================================== */

/* --- beforeAfter: two photographs, one draggable handle ------------------
   The handle is a full-bleed <input type=range> at opacity 0. Pointer drag and
   the arrow keys are then the same code path, so keyboard operation is not a
   second implementation that can rot. */
.ba{--x:50%;aspect-ratio:16/9;border-radius:var(--radius);margin-top:2.2rem;position:relative;overflow:hidden}
.ba__pane{position:absolute;inset:0}
.ba__pane img{object-fit:cover;width:100%;height:100%}
.ba__pane--b{clip-path:inset(0 0 0 var(--x))}
.ba__label{color:#fff;background:var(--ink);letter-spacing:.14em;text-transform:uppercase;padding:.55rem .85rem;font:700 .68rem/1 var(--font-display);position:absolute;bottom:1.1rem}
.ba__label--a{left:1.1rem}
.ba__label--b{background:var(--accent);color:var(--on-accent,var(--ink));right:1.1rem}
.ba__bar{background:#fff;width:3px;position:absolute;top:0;bottom:0;left:var(--x);pointer-events:none;box-shadow:0 0 18px #00000073;transform:translate(-50%)}
.ba__bar i{background:#fff;border-radius:50%;width:52px;height:52px;position:absolute;top:50%;left:50%;box-shadow:0 8px 24px #00000059;transform:translate(-50%,-50%)}
.ba__bar i:before,.ba__bar i:after{content:"";border-block:6px solid #0000;width:0;height:0;position:absolute;top:50%;transform:translateY(-50%)}
.ba__bar i:before{border-right:9px solid var(--ink);left:12px}
.ba__bar i:after{border-left:9px solid var(--ink);right:12px}
.ba__range{cursor:ew-resize;opacity:0;width:100%;height:100%;margin:0;position:absolute;inset:0}
.ba:focus-within .ba__bar{outline:3px solid var(--accent);outline-offset:2px}
.ba__note{color:var(--text-soft);margin-top:.85rem;font-size:.9rem}
.section--dark .ba__note{color:#ffffffa8}
@media (max-width:700px){.ba{aspect-ratio:4/3}.ba__bar i{width:44px;height:44px}}

/* --- pricingCards: plan cards, MOST POPULAR tag, price optional ---------- */
.plans{grid-template-columns:repeat(3,1fr);gap:1.2rem;margin-top:2.4rem;display:grid}
.plan{background:var(--paper);border:1px solid var(--line);border-radius:var(--radius);flex-direction:column;padding:1.9rem 1.6rem 1.7rem;display:flex;position:relative;transition:transform .34s var(--ease),box-shadow .34s var(--ease),border-color .34s var(--ease)}
.plan:hover{transform:translateY(-6px);box-shadow:0 30px 60px -30px #16181c66;border-color:var(--accent)}
.plan--pop{border:2px solid var(--accent);box-shadow:0 30px 60px -34px #16181c73}
.plan__tag{background:var(--accent);color:var(--on-accent,var(--ink));letter-spacing:.14em;text-transform:uppercase;border-radius:3px;padding:.5rem .8rem;font:700 .64rem/1 var(--font-display);position:absolute;top:-.85rem;left:1.6rem}
.plan__name{font-family:var(--font-poster);text-transform:uppercase;margin-bottom:.5rem;font-size:1.35rem;line-height:1.1}
.plan__price{font-family:var(--font-poster);font-size:2.4rem;line-height:1}
.plan__unit{color:var(--text-mute);margin-left:.4rem;font:600 .8rem/1 var(--font-display)}
.plan__blurb{color:var(--text-soft);margin-top:.45rem;font-size:.95rem;line-height:1.6}
.plan__list{margin:1.3rem 0 1.2rem}
.plan__list li{font-size:.95rem}
.plan__note{color:var(--text-mute);margin-bottom:1.1rem;font-size:.84rem;line-height:1.6}
.plan__cta{margin-top:auto;width:100%}
@media (max-width:900px){.plans{grid-template-columns:1fr}}

/* --- testimonialCarousel: reviews.items only, never a written review ----- */
.tcar{margin-top:2rem;position:relative;overflow:hidden}
.tcar__head{flex-wrap:wrap;justify-content:space-between;align-items:flex-end;gap:1.6rem;display:flex}
.tcar__track{gap:1.2rem;transition:transform .55s var(--ease);will-change:transform;display:flex}
.tcar__slide{flex:0 0 100%}
.tcar__slide .rev{height:100%}
.tcar__nav{align-items:center;gap:1rem;margin-top:1.6rem;display:flex}
.tcar__arrow{color:inherit;border:1px solid var(--line-dark);border-radius:50%;place-items:center;width:48px;height:48px;display:grid}
.tcar__arrow:hover{border-color:var(--accent);color:var(--accent-lite,var(--accent))}
.tcar__arrow:first-of-type svg{transform:rotate(180deg)}
.tcar__dots{flex-wrap:wrap;gap:.5rem;margin-inline:auto;display:flex}
.tcar__dot{background:currentColor;opacity:.28;border-radius:50%;width:10px;height:10px;min-width:10px;transition:opacity .25s var(--ease),transform .25s var(--ease)}
.tcar__dot.on{opacity:1;background:var(--accent);transform:scale(1.35)}
@media (min-width:900px){.tcar__slide{flex-basis:calc(33.3333% - .8rem)}}
body.mode-light .tcar__arrow{border-color:var(--line)}

/* --- radiusMap: an inline SVG radar, no map vendor and no map tiles ------ */
.radius{grid-template-columns:1fr 1fr;align-items:center;gap:clamp(2rem,5vw,4rem);display:grid}
.radius__list{grid-template-columns:1fr 1fr;gap:.55rem;margin-top:1.5rem;display:grid}
.radius__list a{align-items:center;gap:.5rem;font:600 .93rem/1.4 var(--font-display);display:flex;min-height:44px}
.radius__list svg{color:var(--accent-lite,var(--accent));flex:none;width:16px;height:16px}
.radius__note{opacity:.62;margin-top:1.2rem;font-size:.84rem}
.radar{width:100%;height:auto;overflow:visible}
.radar__ring{fill:none;stroke:currentColor;stroke-opacity:.17}
.radar__spoke{stroke:currentColor;stroke-opacity:.09}
.radar__home{fill:var(--accent)}
.radar__homelabel{fill:currentColor;letter-spacing:.14em;text-transform:uppercase;font:700 15px var(--font-display)}
.radar__pin circle{fill:var(--accent-lite,var(--accent));stroke:currentColor;stroke-opacity:.35;stroke-width:1.5}
.radar__pin text{fill:currentColor;font:600 15px var(--font-display)}
.radar__sweep{fill:var(--accent);opacity:.13;transform-origin:300px 300px;animation:radarSweep 7s linear infinite}
@keyframes radarSweep{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.radar__sweep{animation:none}}
@media (max-width:900px){.radius{grid-template-columns:1fr}.radius__viz{order:-1;max-width:460px;margin-inline:auto}}

/* --- stickyRail: desktop right-edge CTA rail, hides at the footer -------- */
.railcta{z-index:80;flex-direction:column;gap:2px;display:none;position:fixed;top:50%;right:0;transform:translateY(-50%);transition:transform .4s var(--ease),opacity .4s var(--ease)}
.railcta--hide{opacity:0;pointer-events:none;transform:translate(115%)translateY(-50%)}
.railcta__item{writing-mode:vertical-rl;letter-spacing:.16em;text-transform:uppercase;align-items:center;gap:.7rem;padding:1.4rem .8rem;font:700 .76rem/1 var(--font-display);display:flex}
.railcta__item svg{transform:rotate(90deg)}
.railcta__call{background:var(--ink);color:#fff;border-radius:8px 0 0}
.railcta__quote{background:var(--accent);color:var(--on-accent,var(--ink));border-radius:0 0 0 8px}
.railcta__item:hover{filter:brightness(1.12)}
@media (min-width:1100px){.railcta{display:flex}}

/* --- lightboxGallery: click to enlarge, Escape closes -------------------- */
.gal__btn{cursor:zoom-in;width:100%;height:100%;padding:0;display:block;position:relative}
.gal__item--zoom .gal__btn img{width:100%;height:100%;object-fit:cover}
.gal__zoomcue{color:#fff;opacity:0;background:#16181cbf;border-radius:50%;place-items:center;width:34px;height:34px;transition:opacity .3s var(--ease);display:grid;position:absolute;top:.6rem;right:.6rem}
.gal__item--zoom:hover .gal__zoomcue,.gal__btn:focus-visible .gal__zoomcue{opacity:1}
[data-lightbox] .strip__item img,[data-lightbox].strip__scroll img{cursor:zoom-in}
.lbx{z-index:200;opacity:0;visibility:hidden;background:#0d0f12f5;justify-content:center;align-items:center;padding:clamp(1rem,4vw,3rem);transition:opacity .3s var(--ease),visibility 0s .3s;display:flex;position:fixed;inset:0}
/* visibility is NOT part of the opacity transition: with it in there the
   overlay is still computed hidden on the frame the script tries to focus
   the close button, so focus silently stayed on <body>. Measured. */
.lbx.open{opacity:1;visibility:visible;transition:opacity .3s var(--ease),visibility 0s}
.lbx img{object-fit:contain;width:auto;max-width:100%;height:auto;max-height:84vh;box-shadow:0 40px 90px -30px #000}
.lbx__close{color:#fff;border:1px solid #ffffff40;border-radius:50%;place-items:center;width:48px;height:48px;display:grid;position:absolute;top:1.2rem;right:1.2rem}
.lbx__close:hover{border-color:#fff;background:#ffffff1a}
.lbx__cap{color:#ffffffc4;text-align:center;padding-inline:1.5rem;font-size:.9rem;position:absolute;bottom:1.2rem;left:0;right:0}

/* ==========================================================================
   STRUCTURAL SECTIONS from the Sep 2 side-by-side against the rip
   offerBand | imageBand | splitChecklist | socialBlock | reviewCards
   ========================================================================== */
.offer{background:var(--accent);color:var(--on-accent,var(--ink));padding-block:clamp(2.4rem,6vw,3.9rem)}
.offer__inner{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:1.8rem;display:flex}
.offer__kicker{letter-spacing:.18em;text-transform:uppercase;opacity:.78;margin-bottom:.75rem;font:700 .72rem/1 var(--font-display);display:block}
.offer__title{max-width:22ch}
.offer__title .hx-accent{color:inherit;opacity:.72}
.offer__desc{opacity:.9;max-width:52ch;margin-top:.7rem}
.offer__fine{opacity:.72;max-width:62ch;margin-top:.9rem;font-size:.8rem;line-height:1.6}
.offer__acts{flex-wrap:wrap;gap:.7rem;display:flex}
.offer .btn--outline{color:var(--on-accent,var(--ink));border-color:var(--on-accent,var(--ink))}
.offer .btn--outline:hover{background:var(--on-accent,var(--ink));color:var(--accent)}

.imgband{color:#fff;align-items:center;min-height:clamp(300px,42vw,470px);display:flex;position:relative;overflow:hidden}
.imgband__media{position:absolute;inset:0}
.imgband__media img{object-fit:cover;width:100%;height:100%}
.imgband__scrim{background:linear-gradient(90deg,#16181cf0,#16181cb8 46%,#16181c40);position:absolute;inset:0}
.imgband__inner{z-index:1;padding-block:clamp(2.5rem,6vw,4rem);position:relative}
.imgband__title{max-width:17ch}
.imgband__sub{color:#ffffffd6;max-width:48ch;margin-top:.95rem;font-size:1.02rem;line-height:1.7}
.imgband .kicker{color:var(--accent-lite,var(--accent))}
@media (max-width:700px){.imgband__scrim{background:linear-gradient(#16181cd6,#16181ce6)}}

.splitck{grid-template-columns:1fr 1fr;align-items:center;gap:clamp(2rem,5vw,4rem);display:grid}
.splitck__media{aspect-ratio:4/3;border-radius:var(--radius);overflow:hidden}
.splitck__media img{object-fit:cover;width:100%;height:100%}
.splitck__list{gap:1.05rem;margin:1.7rem 0 1.9rem;display:grid}
.splitck__list li{grid-template-columns:auto 1fr;align-items:start;gap:.85rem;display:grid}
.splitck__list li:before{content:"";background:var(--accent);border-radius:4px;flex:none;width:22px;height:22px;margin-top:.15rem;-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20 6 9 17l-5-5' fill='none' stroke='%23000' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") 50%/contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20 6 9 17l-5-5' fill='none' stroke='%23000' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") 50%/contain no-repeat}
.splitck__list strong,.splitck__list span{grid-column:2}
.splitck__list strong{font:600 1.02rem/1.35 var(--font-display)}
.splitck__list span{color:var(--text-soft);margin-top:.2rem;font-size:.94rem;line-height:1.62;display:block}
@media (max-width:900px){.splitck{grid-template-columns:1fr}}

.socialcards{grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:1rem;margin-top:2.2rem;display:grid}
.socialcard{background:var(--paper);border:1px solid var(--line);border-radius:var(--radius);align-items:center;gap:1.1rem;padding:1.4rem;transition:transform .3s var(--ease),border-color .3s var(--ease),box-shadow .3s var(--ease);display:flex}
.socialcard:hover{border-color:var(--accent);transform:translateY(-5px);box-shadow:0 24px 46px -26px #16181c66}
.socialcard__icon{background:var(--ink);color:#fff;border-radius:50%;flex:none;place-items:center;width:54px;height:54px;display:grid}
.socialcard__name{font-family:var(--font-poster);text-transform:uppercase;font-size:1.1rem;line-height:1.1;display:block}
.socialcard__go{color:var(--accent-ink);letter-spacing:.1em;text-transform:uppercase;align-items:center;gap:.4rem;margin-top:.45rem;font:700 .72rem/1 var(--font-display);display:inline-flex}
/* A two-line job tag ran past the right edge of its own gallery card: .gal__tag
   was anchored left and bottom with nothing capping its width. */
.gal__tag{max-width:calc(100% - 1.4rem)}
/* headerStyle "transparent", two fixes found by looking at the stuck state:
   the top scrim exists to make white nav readable over the HERO PHOTOGRAPH, so
   it has no business hazing a white section once the header has contracted into
   its pill; and the full-width scroll progress bar drew a stray rule across the
   page outside the pill it belongs to. */
.header--transparent:before{transition:opacity .3s var(--ease)}
.header--transparent.stuck:before{opacity:0}
.header--transparent .header__prog{display:none}
/* Mobile headers. Measured at 390px: the utility strip wrapped its three facts
   onto three lines and the header stood 243px tall against a --header-h of
   124px, so the hero padding and every scroll-margin under it were wrong and the
   strip ate a third of the first screen. The hours line is the one that can go:
   it is repeated in the contact block and in the schema. */
@media (max-width:760px){
  .hutil{gap:.9rem;padding-block:.45rem;font-size:.74rem}
  .hutil .hutil__item--hours{display:none}
  body.hdr-utility{--header-h:130px}
  body.hdr-centered{--header-h:132px}
}
@media (max-width:430px){
  .hutil__note{display:none}
  .hutil{justify-content:center}
  body.hdr-utility{--header-h:126px}
}
body.cards-rounded .btn,body.cards-rounded .form__submit,body.cards-rounded .hero__chip{border-radius:4px}

/* =====================================================================
   ROUND 5 QA FIXES (2026-09-02). Every rule below closes a defect that was
   measured on all 12 live demo skins. Each block names the defect number from
   /tmp/qa-r5/report.md and the measurement that proves it.
   ===================================================================== */

/* R5-1 Invisible text, both halves of it.
   .hours__days was a hardcoded #ffffffbd. On a light skin the contact block's
   .channel card is repainted to var(--paper) with ink text, so the day names
   were white on white: 2,520 sampled pixels of pure rgb(255,255,255) where
   "Mon to Fri" should be. inherit + the SAME 0.741 alpha keeps the dark skins
   byte-identical in appearance and makes the light skins readable.
   .why__item is a var(--paper) or var(--mist) card, which is light in BOTH
   modes, so its title has to be ink in both. On the five dark skins it was
   inheriting #fff from .section--dark and printing white on white. */
.hours__days{color:var(--ink);opacity:.74}
.why__item{color:var(--ink)}
.why__title{color:var(--ink)}

/* R5-7 The footer link flow collapsed to one link per row.
   .footer ul{flex-direction:column} (0,1,1) beats .footer__flow{flex-wrap:wrap}
   (0,1,0), so 21 links stacked 1,226 to 1,453px tall. The flow is a row, and
   each item takes a third of the track so it wraps three per row. */
.footer ul.footer__flow{flex-direction:row;flex-wrap:wrap}
.footer__flow>li{flex:0 0 calc((100% - 3rem)/3);min-width:9rem}
.footer--centered .footer__flow{max-width:52rem}
@media (max-width:760px){.footer__flow>li{flex-basis:calc((100% - 1.5rem)/2)}}
@media (max-width:430px){.footer__flow>li{flex-basis:100%}}

/* R5-10 Pill chips beside 4px buttons. --radius is the token every other
   control follows; the chip was hardcoded to 100px. */
.hero__chip{border-radius:var(--radius)}
/* the same clash, shipped dead: this selector was typed "bodybody" so it never
   matched. Repaired, and pointed at the token instead of a 100px pill. */
body.cards-rounded .gal__tag{border-radius:var(--radius)}

/* R5-11 Orphan card in a 3-up grid. Four cards in repeat(3,1fr) leaves one
   alone beside ~765x225px of empty white. Same fix the services grid already
   uses: flex with a centred wrap, so 4 cards render 3 + 1 centred and 6 still
   render two clean rows of three. */
.why__grid{display:flex;flex-wrap:wrap;justify-content:center;gap:1.2rem}
.why__grid>*{flex:0 1 calc((100% - 2.4rem)/3);min-width:230px}
@media (max-width:900px){.why__grid>*{flex-basis:calc((100% - 1.2rem)/2)}}
@media (max-width:620px){.why__grid>*{flex-basis:100%}}

/* R5-13 The page hero sat on its own left edge. .phero__inner carries .wrap,
   whose margin-inline:auto centred it once .phero__inner capped the width at
   780px, so the h1 started at x=387 and the breadcrumb under it at x=156.
   The wrap keeps the page grid; the 780px measure moves onto the children. */
.phero__inner{max-width:var(--maxw)}
.phero__inner>*{max-width:780px}

/* R5-8 Mobile source order in the contact block. The form was hoisted with
   order:-1, which put it 739px ABOVE the heading that introduces it. The
   heading is now its own grid child, so the phone order is head, form,
   channels, and the desktop two-column layout is unchanged. */
.contact .contact__grid{grid-template-areas:"head form" "copy form";row-gap:0}
.contact .contact__head{grid-area:head}
.contact .contact__copy{grid-area:copy}
.contact .contact__form{grid-area:form}
@media (width<=900px){
  .contact .contact__grid{grid-template-areas:"head" "form" "copy";row-gap:2rem}
  .contact .contact__form{order:0}
}

/* R5-6 Trust seals on /quote/. 981x400 masters were forced into a 74x30 box, a
   13x downscale that rendered as an illegible smear on the highest intent page.
   The compact row now runs at 56px tall, which puts the Owens Corning mark at
   137px wide and the BBB at 154px, both over the 120px floor. */
.seals--compact{--seal-h:64px;gap:1.2rem 1.6rem}
.seals--compact .seal{--seal-h:64px}
.seals--compact .seal__mark img{min-width:120px;object-fit:contain}
@media (max-width:520px){.seals--compact{--seal-h:46px}.seals--compact .seal{--seal-h:46px}}

/* R5-9 The portfolio strip was a carousel with no controls: 8 items,
   scrollWidth 3,744 against clientWidth 1,440, no arrows, no dots, no
   scrollbar, and body{overflow-x:hidden}, so 5 of 8 projects were unreachable.
   It also started at x=56 while every heading started at x=156. The strip is
   now inside the page grid and carries the same arrow/dot control set the
   testimonial carousel already ships. */
.strip{position:relative}
/* the scroller bleeds off the right edge on purpose, but its FIRST item has to
   start on the page grid: (100% - maxw)/2 + pad resolves to x=156 at 1440 and
   collapses to a plain pad below 1240, which is where .wrap loses its gutters
   too. */
.strip__scroll{scroll-behavior:smooth;scroll-padding-left:max(var(--pad),calc((100% - var(--maxw))/2 + var(--pad)));padding-inline:max(var(--pad),calc((100% - var(--maxw))/2 + var(--pad))) var(--pad)}
.strip__nav{display:flex;align-items:center;gap:1rem;margin-top:1.4rem}
.strip__arrow{color:inherit;border:1px solid var(--line);border-radius:50%;place-items:center;width:48px;height:48px;display:grid;flex:none}
.strip__arrow:hover{border-color:var(--accent);color:var(--accent-ink)}
.strip__arrow[disabled]{opacity:.32;cursor:default}
.strip__arrow:first-of-type svg{transform:rotate(180deg)}
.section--dark .strip__arrow{border-color:var(--line-dark)}
.section--dark .strip__arrow:hover{color:var(--accent-lite,var(--accent))}
.strip__dots{display:flex;flex:1 1 auto;flex-wrap:nowrap;justify-content:center;gap:.2rem;margin-inline:auto;max-width:100%}
.strip__dot{background:none;border:0;padding:0;width:auto;height:44px;min-width:0;flex:1 1 0;max-width:44px;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;-webkit-tap-highlight-color:transparent}.strip__dot::before{content:"";width:9px;height:9px;min-width:9px;border-radius:50%;background:currentColor;opacity:.3;transition:opacity .25s var(--ease),transform .25s var(--ease)}
.strip__dot.on::before{opacity:1;background:var(--accent);transform:scale(1.4)}
@media (max-width:700px){.strip__nav{margin-top:1rem}}

/* R5-16 The lightbox opened empty: it fetched a 148KB to 750KB full size webp
   only on click, with no spinner and no placeholder, so the panel showed a
   caption and a close button over a dark scrim and no picture. The caption also
   sat 408px below the image because it was absolutely positioned to the
   viewport rather than under the photo. */
.lbx{flex-direction:column;gap:.9rem}
.lbx__cap{position:static;max-width:min(100%,72ch);padding-inline:0;text-align:center;bottom:auto;left:auto;right:auto}
.lbx img{max-height:78vh}
.lbx__spin{width:44px;height:44px;border-radius:50%;border:3px solid #ffffff2e;border-top-color:#fff;animation:lbxspin .8s linear infinite;display:none}
.lbx.loading .lbx__spin{display:block}
.lbx.loading img,.lbx.loading .lbx__cap{display:none}
@keyframes lbxspin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.lbx__spin{animation-duration:2.4s}}

/* R5-18 Headline wrap. --h1-cap is written onto the h1 by the generator from
   the character count of that page's own copy, so a long headline steps its
   own size down instead of wrapping to four lines. min() means the cap can only
   ever make the type smaller than the clamp, never larger, and at phone widths
   the clamp minimum is already below every cap, so mobile is untouched. */
.hero__title,.phero__inner .h-hero{font-size:min(clamp(2.25rem,4.9vw,3.9rem),var(--h1-cap,99rem))}
.hero--minimal .hero__title{font-size:min(clamp(2rem,4vw,3.2rem),var(--h1-cap,99rem))}
.hero--poster .hero__title{font-size:min(clamp(3rem,8.5vw,7.2rem),var(--h1-cap,99rem))}

/* R5-2 /work/ used to ship <div class="prose"></div>, measured 643x0 beside a
   1,074px aside. The main column now carries the full portfolio grid. */
.workgrid{display:grid;grid-template-columns:repeat(2,1fr);gap:1rem}
@media (max-width:620px){.workgrid{grid-template-columns:1fr}}
.workgrid .gal__item{aspect-ratio:4/3}

/* R5-17 Oversized assets. The brand lockups had no srcset at all: a 734px
   master rendered into a 245px header box and a 1,025px master into 235px of
   footer. Both now emit a ladder; these caps keep the rendered box honest. */
.brandmark img{max-width:min(100%,300px)}
.footer .brandmark img{max-width:min(100%,260px)}
.strip--nonav .strip__nav{display:none}
/* R5-18 continued: the measure. A ch max-width scales with the font, so on the
   layouts that carry one (14ch left/form, 12ch poster, 18ch page) shrinking the
   type alone can never change the line count. --h1-ch is written per page from
   that page's own words; the fallback in each rule is the value that shipped
   before, so an h1 the generator did not measure renders exactly as it did. */
.hero__title{max-width:min(100%,var(--h1-ch,100ch))}
.hero--left .hero__title{max-width:min(100%,var(--h1-ch,14ch))}
.hero--form .hero__title{max-width:min(100%,var(--h1-ch,14ch))}
.hero--page .hero__title{max-width:min(100%,var(--h1-ch,18ch))}
.hero--poster .hero__title{max-width:min(100%,var(--h1-ch,12ch))}
.phero__inner .h-hero{max-width:min(100%,var(--h1-ch,780px))}

/* QA r5 fixes at source */
.why__title{color:var(--ink)}
.section--dark .why__title{color:#fff}
.hours__days,.hours__time{color:var(--ink)}
.section--dark .hours__days,.section--dark .hours__time{color:#fff}
/* Scoped to the single long list (.footer__flow). The mega footer's per-column lists
   (.footer__grid) must stay one link per row: the unscoped rule split "12075 Starcrest Dr."
   into three cramped sub-columns inside a 1.2fr column (utilitarian, Sep 2 2026). */
.footer ul.footer__flow{flex-direction:row;flex-wrap:wrap;gap:.6rem 1.4rem}
.footer ul.footer__flow{justify-content:flex-start}
.footer ul.footer__flow li{flex:0 0 calc(33.333% - 1rem)}
@media (width<=760px){.footer ul.footer__flow li{flex-basis:calc(50% - .7rem)}}
@media (width<=380px){.footer ul.footer__flow li{flex-basis:100%}}
.why__grid{display:flex;flex-wrap:wrap;justify-content:center;gap:1.2rem}
.why__grid>*{flex:0 1 calc((100% - 2.4rem)/3);min-width:240px}
@media (width<=1040px){.why__grid>*{flex-basis:calc((100% - 1.2rem)/2)}}
@media (width<=620px){.why__grid>*{flex-basis:100%}}
.hero__chip{border-radius:var(--radius)}
.strip__ctl{display:flex;gap:.5rem;justify-content:flex-end;margin-top:1rem}
.strip__btn{width:44px;height:44px;border:1.5px solid var(--line);border-radius:var(--radius);display:inline-flex;align-items:center;justify-content:center;background:var(--paper);color:var(--ink)}
.strip__btn:hover{border-color:var(--accent)}
.section--dark .strip__btn{background:#ffffff10;border-color:var(--line-dark);color:#fff}
.strip__scroll{scroll-snap-type:x mandatory;scroll-behavior:smooth;padding-inline:var(--pad);scrollbar-width:thin}
.strip__scroll>*{scroll-snap-align:start}
/* r5 #1 for real: a white card is a white card in any section or mode. Key text on the CARD surface, not the section class. */
.why__item .why__title,.why__item .why__desc{color:var(--ink)}
.why__item .why__desc{color:var(--text-soft)}
.contact__card .hours__days,.contact__card .hours__time,.contact__card,.contact__card *{color:var(--ink)}
.contact__card .hours__days{opacity:.74}
body.mode-light .section--dark .why__title,body.mode-light .section--dark .hours__days,body.mode-light .section--dark .hours__time{color:var(--ink)}
body.mode-light .section--dark .contact__card,body.mode-light .section--dark .contact__card *{color:var(--ink)}
/* r5 #1 final: text follows the CARD it sits in. .channel and .why__item are white cards in light mode. */
body.mode-light .channel,body.mode-light .channel *{color:var(--ink)}
body.mode-light .channel .hours__days{opacity:.74}
body.mode-light .why__item .why__title{color:var(--ink)}
body.mode-light .why__item .why__desc{color:var(--text-soft)}

/* ==========================================================================
   ROUND 6 (Sep 2, 2026): commercial + maintenance templates
   hero--portfolio, the case study grid, the plan comparison table.
   Everything keys on tokens (--radius, --accent, --paper, --mist, --coal,
   --line) and on the CARD surface, never the section class (bug 52).
   ========================================================================== */
.sr-only{clip:rect(0 0 0 0);clip-path:inset(50%);width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;white-space:nowrap;position:absolute}

/* --- hero--portfolio: headline left, one featured project card right --- */
.hero--portfolio .hero__content{max-width:1240px;margin-inline:auto;align-items:stretch;text-align:left;padding-top:calc(var(--header-h) + clamp(2rem,5vw,4rem));padding-bottom:clamp(2.5rem,6vw,4.5rem)}
.hero--portfolio .hero__title{max-width:min(100%,var(--h1-ch,14ch))}
.hero--portfolio .hero__sub{text-align:left;margin-inline:0;max-width:48ch}
.hero--portfolio .hero__ctas,.hero--portfolio .hero__trust{justify-content:flex-start}
.hero--portfolio .hero__split{grid-template-columns:1fr .95fr;align-items:center}
.hero--portfolio .hero__split--solo{grid-template-columns:1fr}
.hero__feat{display:flex;flex-direction:column;background:#ffffff12;border:1px solid var(--line-dark);border-radius:var(--radius);overflow:hidden;color:#fff;text-decoration:none;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);transition:transform .42s var(--ease),border-color .42s var(--ease),box-shadow .42s var(--ease)}
.hero__feat:hover{transform:translateY(-4px);border-color:var(--accent);box-shadow:0 30px 60px -30px #000c}
.hero__feat-media{display:block;aspect-ratio:4/3;overflow:hidden;background:#0006}
.hero__feat-media img{width:100%;height:100%;object-fit:cover;display:block}
.hero__feat-body{display:flex;flex-direction:column;gap:.35rem;padding:1.1rem 1.2rem 1.25rem}
.hero__feat-tag{color:var(--accent-lite,var(--accent));font:700 .66rem/1 var(--font-display);letter-spacing:.14em;text-transform:uppercase}
.hero__feat-title{font-family:var(--font-poster);font-size:1.25rem;line-height:1.15}
.hero__feat-facts{display:grid;grid-template-columns:1fr 1fr;gap:.55rem 1rem;margin:.55rem 0 0;padding-top:.75rem;border-top:1px solid var(--line-dark)}
.hero__feat-facts dt{font:600 .64rem/1 var(--font-display);letter-spacing:.12em;text-transform:uppercase;opacity:.66}
.hero__feat-facts dd{margin:.2rem 0 0;font-size:.92rem;line-height:1.35}
@media (width<=900px){.hero--portfolio .hero__split{grid-template-columns:1fr}.hero--portfolio .hero__content{align-items:center;text-align:center}.hero--portfolio .hero__sub{text-align:center;margin-inline:auto}.hero--portfolio .hero__ctas,.hero--portfolio .hero__trust{justify-content:center}.hero__feat{max-width:520px;width:100%;margin-inline:auto;text-align:left}.hero__feat-media{aspect-ratio:16/10}}

/* --- case studies: the procurement grid --- */
.cases{display:flex;flex-wrap:wrap;justify-content:center;gap:1.3rem;margin-top:2.2rem}
.cases>*{flex:0 1 calc((100% - 1.3rem)/2);min-width:280px}
.case{display:flex;flex-direction:column;background:var(--coal);color:#fff;border:1px solid var(--line-dark);border-radius:var(--radius);overflow:hidden;transition:transform .38s var(--ease),border-color .38s var(--ease),box-shadow .38s var(--ease)}
.case:hover{transform:translateY(-5px);border-color:var(--accent);box-shadow:0 30px 60px -34px #000c}
.case__media{position:relative;aspect-ratio:16/9;overflow:hidden}
.case__media img{width:100%;height:100%;object-fit:cover;display:block;transition:transform .8s var(--ease)}
.case:hover .case__media img{transform:scale(1.04)}
.case__tag{position:absolute;left:.8rem;top:.8rem;background:var(--accent);color:var(--on-accent,var(--ink));font:700 .64rem/1 var(--font-display);letter-spacing:.12em;text-transform:uppercase;padding:.45rem .6rem;border-radius:3px}
.case__body{display:flex;flex-direction:column;gap:.7rem;padding:1.3rem 1.4rem 1.5rem}
.case__title{font-family:var(--font-poster);font-size:1.35rem;line-height:1.12;color:inherit}
.case__facts{display:grid;grid-template-columns:repeat(4,1fr);gap:.6rem .9rem;margin:0;padding:.85rem 0;border-block:1px solid var(--line-dark)}
.case__facts dt{font:600 .62rem/1 var(--font-display);letter-spacing:.12em;text-transform:uppercase;opacity:.62}
.case__facts dd{margin:.25rem 0 0;font-size:.9rem;line-height:1.35}
.case__sum{color:inherit;opacity:.82;font-size:.95rem;line-height:1.6}
body.mode-light .case{background:var(--paper);color:var(--ink);border-color:var(--line)}
body.mode-light .case__facts{border-color:var(--line)}
body.mode-light .case:hover{box-shadow:0 30px 60px -30px #16181c40}
.section--paper .case,.section--mist .case{background:var(--paper);color:var(--ink);border-color:var(--line)}
.section--paper .case__facts,.section--mist .case__facts{border-color:var(--line)}
body.cards-flat .case,body.cards-flat .case__tag,body.cards-flat .hero__feat{border-radius:0}
body.cards-flat .case:hover .case__media img{transform:none}
body.cards-rounded .case{border-radius:16px}
body.cards-rounded .case__tag{border-radius:var(--radius)}
@media (width<=1040px){.case__facts{grid-template-columns:repeat(2,1fr)}}
@media (width<=900px){.cases>*{flex-basis:100%}}

/* --- plan comparison table --- */
.pcmp__scroll{position:relative;margin-top:2rem;overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:thin;border:1px solid var(--line);border-radius:var(--radius);background:var(--paper)}
.pcmp{width:100%;min-width:500px;border-collapse:collapse;color:var(--ink);font-size:.95rem}
.pcmp th,.pcmp td{padding:.95rem 1.1rem;border-bottom:1px solid var(--line);text-align:center;vertical-align:middle}
.pcmp thead th{font-family:var(--font-poster);text-transform:uppercase;font-size:.95rem;letter-spacing:.04em;line-height:1.1;background:var(--mist);border-bottom:2px solid var(--line)}
.pcmp tbody th{text-align:left;font-weight:600;color:var(--ink);width:38%}
.pcmp tbody tr:last-child th,.pcmp tbody tr:last-child td{border-bottom:0}
.pcmp tbody tr:hover td,.pcmp tbody tr:hover th{background:#16181c05}
.pcmp thead th.pcmp__pop{color:var(--accent-ink);box-shadow:inset 0 3px 0 var(--accent)}
.pcmp td.pcmp__pop{background:#16181c06}
.pcmp__yes{display:inline-flex;width:28px;height:28px;align-items:center;justify-content:center;border-radius:50%;background:var(--accent);color:var(--on-accent,var(--ink))}
.pcmp__yes svg{width:15px;height:15px}
.pcmp__no{display:inline-block;width:14px;height:2px;background:var(--line);vertical-align:middle}
.pcmp__note{color:var(--text-mute);margin-top:1rem;font-size:.84rem;line-height:1.6}
body.cards-flat .pcmp__scroll{border-radius:0}
body.cards-rounded .pcmp__scroll{border-radius:16px}
@media (width<=620px){.pcmp{font-size:.86rem}.pcmp th,.pcmp td{padding:.75rem .7rem}.pcmp tbody th{width:auto}}

/* ==========================================================================
   ROUND 7: the section vocabulary from the SiteRabbits gap table
   (/tmp/qa-r7/siterabbits-baseline.md, graded 2026-09-03). Every block here
   is inert until the matching config key exists, so nothing below can change
   a build that did not opt in.
   ========================================================================== */

/* --- a section with the padding turned down, for a bare strip --- */
.section--tight{padding-block:clamp(1.6rem,3.4vw,2.6rem)}

/* --- 1. client logo strip --- */
.logostrip__row{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:clamp(1.4rem,4vw,3.2rem)}
.logostrip__cell{display:inline-flex;flex-direction:column;align-items:center;justify-content:center;min-height:56px;opacity:.72;filter:grayscale(1);transition:opacity .3s var(--ease),filter .3s var(--ease),transform .3s var(--ease)}
.logostrip__cell:hover,.logostrip__cell:focus-visible{opacity:1;filter:grayscale(0);transform:translateY(-2px)}
a.logostrip__cell:focus-visible{outline:2px solid var(--accent);outline-offset:6px}
.logostrip__img{display:block;width:auto;max-width:190px;max-height:52px;height:auto}
.logostrip__word{font-family:var(--font-poster);text-transform:uppercase;letter-spacing:.02em;font-size:clamp(1.05rem,2.1vw,1.5rem);line-height:1;color:var(--ink);white-space:nowrap}
.section--dark .logostrip__word,.logostrip--dark .logostrip__word{color:#fff}
.logostrip__note{margin-top:1.4rem;text-align:center;font:600 .76rem/1.5 var(--font-display);letter-spacing:.06em;color:var(--text-mute)}
.logostrip__marquee{overflow:hidden;mask-image:linear-gradient(90deg,#0000,#000 8%,#000 92%,#0000)}
.logostrip__track{display:flex;width:max-content;animation:36s linear infinite tickerscroll}
.logostrip__group{display:flex;align-items:center;gap:clamp(1.6rem,4vw,3.4rem);padding-right:clamp(1.6rem,4vw,3.4rem)}
.logostrip__group .logostrip__cell{flex:none}
@media (prefers-reduced-motion:reduce){.logostrip__track{animation:none}}
@media (width<=560px){.logostrip__img{max-width:130px;max-height:42px}}

/* --- 2a. in-page video proof band --- */
.vband{display:grid;grid-template-columns:1.15fr 1fr;align-items:center;gap:clamp(2rem,5vw,4rem)}
.vband--flip .vband__media{order:2}
.vband__media{position:relative;aspect-ratio:16/9;border-radius:8px;overflow:hidden;box-shadow:0 40px 80px -34px #000000b8}
.vband__media video,.vband__media img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.vband__copy .body{color:#ffffffc4}
.vband__acts{display:flex;flex-wrap:wrap;gap:.8rem;margin-top:1.7rem}
@media (width<=900px){.vband{grid-template-columns:1fr}.vband--flip .vband__media{order:0}}

/* --- 2b. portrait 9:16 reel row --- */
.reels{display:flex;flex-wrap:wrap;gap:1rem}
.reel{flex:1 1 210px;max-width:300px;margin:0;display:flex;flex-direction:column}
.reel__btn{position:relative;display:block;width:100%;padding:0;aspect-ratio:9/16;border-radius:8px;overflow:hidden;background:var(--coal);cursor:pointer}
.reel__btn img{width:100%;height:100%;object-fit:cover;display:block;transition:transform .6s var(--ease)}
.reel__btn:hover img{transform:scale(1.05)}
.reel__btn:focus-visible{outline:3px solid var(--accent);outline-offset:3px}
.reel__blank{position:absolute;inset:0;background:linear-gradient(160deg,#ffffff14,#0000)}
.reel__cue{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:52px;height:52px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;background:var(--accent);color:var(--on-accent,var(--ink));box-shadow:0 12px 28px -10px #000c;transition:transform .3s var(--ease)}
.reel__btn:hover .reel__cue{transform:translate(-50%,-50%) scale(1.08)}
.reel__cap{margin-top:.7rem;font:600 .88rem/1.4 var(--font-display);color:var(--ink)}
.section--dark .reel__cap{color:#fff}
.reel__city{display:block;margin-top:.2rem;font:700 .66rem/1 var(--font-display);letter-spacing:.14em;text-transform:uppercase;color:var(--accent-ink)}
.section--dark .reel__city{color:var(--accent)}
@media (width<=700px){.reel{flex-basis:44%}}
.lbx__vid{max-width:min(92vw,520px);max-height:86vh;border-radius:8px;background:#000;display:block}
.lbx__vid[hidden]{display:none}

/* --- 3. one-row quote bar under the hero --- */
.qbar{background:var(--accent);color:var(--on-accent,var(--ink));padding-block:clamp(1.5rem,3.2vw,2.2rem)}
.qbar__inner{display:grid;grid-template-columns:minmax(180px,.7fr) 2.3fr;align-items:center;gap:clamp(1.2rem,3vw,2.4rem)}
.qbar__copy .kicker{color:var(--on-accent,var(--ink));opacity:.72;margin-bottom:.5rem}
.qbar__line{font-family:var(--font-poster);text-transform:uppercase;font-size:clamp(1.15rem,2.2vw,1.75rem);line-height:1.05;max-width:16ch}
.form--bar{background:0 0;box-shadow:none;padding:0;border-radius:0;color:var(--ink)}
.form__bar{display:grid;grid-template-columns:1.1fr 1fr 1.2fr auto;gap:.7rem;align-items:end}
.form--bar .field{margin-bottom:0}
.form--bar .field label{color:var(--ink);opacity:.72}
.form--bar .field input,.form--bar .field select{background:#fff;border-color:#0000001f}
.form--bar .form__submit{width:auto;margin-top:0;background:var(--ink);color:#fff;white-space:nowrap;padding-block:1.02rem}
.form--bar .form__submit:hover{background:#fff;color:var(--ink)}
.form__foot{display:flex;flex-wrap:wrap;align-items:flex-start;gap:.4rem 1.4rem;margin-top:.85rem}
.form--bar .form__privacy{color:var(--ink);opacity:.8}
.form--bar .form__status{background:#fff;margin-top:.7rem}
@media (width<=1040px){.qbar__inner{grid-template-columns:1fr}.qbar__line{max-width:none}}
@media (width<=900px){.form__bar{grid-template-columns:1fr;gap:.75rem}.form--bar .form__submit{width:100%}}

/* --- 4/5. role select, trade qualifier, SMS consent --- */
.form__consent{display:grid;grid-template-columns:auto 1fr;gap:.6rem;align-items:start;margin:.2rem 0 1rem;font-size:.8rem;line-height:1.5;color:var(--text-mute);cursor:pointer}
.form__consent input{width:20px;height:20px;margin-top:.1rem;accent-color:var(--accent-ink);flex:none}
.form__consent:hover{color:var(--text-soft)}
.form--bar .form__consent{margin:0;max-width:56ch;color:var(--ink);opacity:.8}

/* --- 6. edge-justified two-label keyline above a section head --- */
.shead__key{display:flex;align-items:baseline;justify-content:space-between;gap:1.2rem;border-bottom:1px solid var(--line);padding-bottom:.7rem;margin-bottom:1.1rem}
.shead__key .kicker{margin-bottom:0}
.shead__key-r{font:700 .73rem/1 var(--font-display);letter-spacing:.17em;text-transform:uppercase;color:var(--text-mute);text-align:right}
.section--dark .shead__key{border-bottom-color:var(--line-dark)}
.section--dark .shead__key-r{color:#ffffff8c}

/* --- 7. corner badge pinned to a section photograph --- */
.photobadge{position:absolute;left:0;bottom:0;z-index:2;display:flex;flex-direction:column;gap:.2rem;background:var(--accent);color:var(--on-accent,var(--ink));padding:.85rem 1.1rem;max-width:72%;border-radius:0 8px 0 0}
.photobadge__line{font-family:var(--font-poster);text-transform:uppercase;font-size:clamp(1rem,1.9vw,1.35rem);line-height:1}
.photobadge__sub{font:700 .64rem/1.3 var(--font-display);letter-spacing:.13em;text-transform:uppercase;opacity:.78}
@media (width<=560px){.photobadge{padding:.65rem .8rem;max-width:86%}}

/* --- 8. city keyline header and neighborhoods --- */
.citykey{display:flex;align-items:baseline;justify-content:space-between;gap:1.2rem;border-bottom:1px solid var(--line);padding:1.4rem 0 .7rem;margin-bottom:-.6rem}
.citykey__l,.citykey__r{font:700 .78rem/1 var(--font-display);letter-spacing:.18em;text-transform:uppercase}
.citykey__l{color:var(--ink)}
.citykey__r{color:var(--text-mute)}
.hoods{display:flex;flex-wrap:wrap;gap:.55rem;margin-top:1.6rem;padding:0;list-style:none}
.hoods li{font:600 .84rem/1 var(--font-display);color:var(--text-soft);background:var(--paper);border:1px solid var(--line);border-radius:999px;padding:.62rem .95rem}

/* --- 9. multi-platform review cards --- */
.revplats{display:flex;flex-wrap:wrap;gap:.7rem}
.revplat{display:flex;align-items:center;gap:.7rem;background:var(--paper);border:1px solid var(--line);border-radius:8px;padding:.75rem .95rem;color:var(--ink);transition:border-color .25s var(--ease),transform .25s var(--ease)}
a.revplat:hover{border-color:var(--accent);transform:translateY(-2px)}
.revplat__mark{display:inline-flex;flex:none}
.revplat__body{display:grid;grid-template-columns:auto auto;align-items:center;gap:.1rem .5rem}
.revplat__name{grid-column:1/-1;font:700 .64rem/1 var(--font-display);letter-spacing:.14em;text-transform:uppercase;color:var(--text-mute)}
.revplat__num{font-family:var(--font-poster);font-size:1.2rem;line-height:1}
.revplat__count{grid-column:1/-1;font:600 .74rem/1.3 var(--font-display);color:var(--text-mute)}
.revplats--dark .revplat{background:#ffffff0f;border-color:var(--line-dark);color:#fff}
.revplats--dark .revplat__name,.revplats--dark .revplat__count{color:#ffffff94}
.section--dark .revplat{background:#ffffff0f;border-color:var(--line-dark);color:#fff}
.section--dark .revplat__name,.section--dark .revplat__count{color:#ffffff94}
@media (width<=560px){.revplats{width:100%}.revplat{flex:1 1 100%}}

/* The strip's heading is centered over its own centered row. Left-aligning the head while the
   row centers reads as two unrelated blocks (corporate, Sep 3 2026). The heading class differs
   by template (shead, shead--plain, shead--rule), so this targets the h2 itself, and it gets the
   full column width because a four-word line broken over three lines is not a section head. */
.logostrip .shead,.logostrip .shead--plain{text-align:center;justify-items:center}
.logostrip .shead__rule{margin-inline:auto}
.logostrip>.wrap>.h-section,.logostrip .shead .h-section{max-width:none;text-align:center;margin-inline:auto;font-size:clamp(1.5rem,2.6vw,2.1rem);margin-bottom:1.6rem}
.logostrip .kicker{text-align:center;display:block}
.logostrip .body.measure,.logostrip__note{margin-inline:auto;text-align:center}

/* --- lockup hero: photo, brand mark centred large, one line, one button --- */
/* The dominant reference pattern (Hugo Builders, Rooferz, 5 Star, LeonGTO). The mark carries the
   fold, not a headline, so it is set at 620px on desktop and 82vw on a phone. */
/* The .hero box already carries min-height:var(--hero-h,76svh) and its own header-clearing
   padding. Repeating the min-height here stacked a second full hero height inside the first,
   so a 76svh hero measured 890px of a 900px fold: 684 content + 126 top pad + 80 bottom pad.
   The reference median is 605px, 76% of the fold, which is what --hero-h alone produces. */
.hero--lockup .hero__content{display:grid;place-items:center;text-align:center}
.lockhero{display:grid;justify-items:center;gap:clamp(1.1rem,2.6vw,1.9rem);max-width:min(92vw,760px)}
.lockhero__mark{width:min(64vw,346px);height:auto;filter:drop-shadow(0 6px 26px #0000005c)}
.lockhero__line{font-family:var(--font-display);text-transform:uppercase;letter-spacing:.16em;font-size:clamp(.72rem,1.35vw,.92rem);line-height:1.7;font-weight:600;color:#ffffffe8;margin:0;max-width:52ch}
.lockhero__line .hx-accent{color:var(--accent-lite,var(--accent))}
.lockhero__act{display:flex;gap:.7rem;flex-wrap:wrap;justify-content:center}
/* Measured against the reference crops Sep 3: their lockup heroes keep the photograph
   bright and carry only enough scrim to float the mark, bottoming out around 45%.
   Ours bottomed out at #16181cd6, 84% black, which crushed the aerial into a grey
   plate and was the largest single colour difference in the side-by-side. */
.hero--lockup .hero__scrim{background:linear-gradient(#16181c3d 0%,#16181c5c 48%,#16181c8a 100%)}
@media (width<=700px){.lockhero{gap:1rem}.lockhero__line{letter-spacing:.12em}}

/* --- trust strip: the four cell band directly under the hero --- */
.tstrip{background:var(--paper);border-bottom:1px solid var(--line);padding-block:clamp(.9rem,1.8vw,1.15rem)}
.tstrip__row{display:grid;grid-template-columns:repeat(4,1fr);align-items:center;gap:1rem}
.tstrip__cell{display:flex;align-items:center;justify-content:center;gap:.6rem;text-align:center;padding-inline:.5rem;border-right:1px solid var(--line)}
.tstrip__cell:last-child{border-right:0}
.tstrip__ico{display:inline-flex;flex:none;width:22px;height:22px;color:var(--accent-ink,var(--accent))}
.tstrip__ico svg{width:100%;height:100%}
.tstrip__lbl{font-family:var(--font-display);text-transform:uppercase;letter-spacing:.09em;font-size:.76rem;font-weight:700;line-height:1.35;color:var(--ink)}
.section--dark+.tstrip,.hero+.tstrip{border-top:0}
@media (width<=900px){.tstrip__row{grid-template-columns:1fr 1fr;gap:.9rem 1rem}.tstrip__cell:nth-child(2n){border-right:0}.tstrip__cell:nth-child(-n+2){padding-bottom:.85rem;border-bottom:1px solid var(--line)}}
@media (width<=430px){.tstrip__lbl{font-size:.7rem;letter-spacing:.07em}}

/* --- sheadAlign: center -----------------------------------------------------
   Measured Sep 3 across all 22 reference rips: every one of them centres the
   services section head, and ours sat hard left with the sub floated to the
   right of it. shead() emits a fragment (kicker + h2) that 19 call sites wrap
   themselves, so the align axis rides on one body class instead of touching
   every caller, and it has to collapse the two-column head rows as well as set
   text-align, because a centred heading with a sub still floated right reads
   worse than the left version it replaced.
   Scoped to section heads only: hero, cards, forms, footer and the ticker keep
   their own alignment. */
.shead-center .svc__head,
.shead-center .strip__head{display:block;text-align:center}
.shead-center .svc__head > div,
.shead-center .strip__head > div{margin-inline:auto}
.shead-center .svc__head .body,
.shead-center .strip__head .body{max-width:56ch;margin-inline:auto}
.shead-center .strip__head > .btn{margin-top:1.6rem}
.shead-center .section > .wrap > div > .kicker,
.shead-center .svc__head .kicker,
.shead-center .strip__head .kicker{display:inline-flex}
.shead-center .h-section,
.shead-center .shead--plain{margin-inline:auto;max-width:22ch;text-align:center}
.shead-center .shead__rule{margin-inline:auto}
.shead-center .shead__n{text-align:center}
/* The keyline chrome is a deliberate left/right pair on one rule. Centring it
   would destroy the pattern, so it opts out. */
.shead-center .shead__key{justify-content:center;gap:1.6rem}
/* The kicker carries a 22px leading rule, which reads as a hanging indent when
   the kicker is left aligned and as a stray dash when it is centred. Every
   centred reference kicker (Hugo's WHAT WE DO, 5 Star's WHY CHOOSE US) is bare
   letterspaced caps with nothing before it. */
.shead-center .svc__head .kicker:before,
.shead-center .strip__head .kicker:before,
.shead-center .section > .wrap > div > .kicker:before{display:none}
.shead-center .kicker{gap:0}

/* === Family 1c: the LEFT lockup (Clear and Bright, Dump It Done, LeonGTO) ====
   Same parts as the centred lockup, set on a left rail: mark, one line, a sub,
   two ghost buttons. The content column is left-justified and the mark sits a
   touch smaller than the centred variant so the headline block reads first. */
.hero--lockleft .hero__content{display:flex;place-items:start;text-align:left}
.hero--lockleft .lockhero,
.lockhero--left{justify-items:start;text-align:left;max-width:min(94vw,620px);gap:clamp(1rem,2.2vw,1.6rem)}
.lockhero--left .lockhero__mark{width:min(58vw,300px)}
.lockhero--left .lockhero__line{max-width:40ch}
.lockhero__sub{color:#ffffffe6;text-shadow:0 2px 16px #0000009e;max-width:46ch;margin:0;font-size:clamp(1rem,1.7vw,1.24rem);line-height:1.6}
.lockhero--left .lockhero__act{justify-content:flex-start}
@media (width<=700px){.lockhero--left{max-width:100%}}

/* === Family 2: the TYPE hero (Pixler Construction) ==========================
   No mark. The company NAME is the hero art in giant two-voice display type,
   a letterspaced service keyline above it, a city line below, an in-hero stat
   row on a hairline, then the buttons. This is the one architecture whose art
   is the name itself, which is why it never shares the stage with a lockup. */
.hero--type .hero__content{display:grid;place-items:center;text-align:center}
.typehero{display:grid;justify-items:center;gap:clamp(.9rem,2vw,1.5rem);max-width:min(94vw,1100px)}
.typehero__kicker{font-family:var(--font-display);text-transform:uppercase;letter-spacing:.28em;font-size:clamp(.68rem,1.1vw,.82rem);font-weight:700;color:var(--accent-lite,var(--accent))}
.typehero__name{font-family:var(--font-poster);text-transform:uppercase;font-weight:800;line-height:.9;letter-spacing:-.015em;font-size:clamp(3.2rem,9vw,7.6rem);margin:0;color:#fff;text-shadow:0 4px 40px #00000066}
.typehero__name .hx-accent{color:var(--accent-lite,var(--accent))}
.typehero__city{font-family:var(--font-display);text-transform:uppercase;letter-spacing:.2em;font-size:clamp(.78rem,1.3vw,.98rem);font-weight:600;color:#fffffff0;margin:0}
.typehero__stats{display:grid;grid-template-columns:repeat(4,auto);gap:clamp(1.4rem,4vw,3.4rem);justify-content:center;padding-top:clamp(1rem,2vw,1.6rem);margin-top:.4rem;border-top:1px solid #ffffff33}
.typehero__stat{display:grid;justify-items:center;gap:.2rem}
.typehero__num{font-family:var(--font-poster);font-size:clamp(1.8rem,3.4vw,2.7rem);font-weight:800;line-height:1;color:#fff}
.typehero__lbl{font-family:var(--font-display);text-transform:uppercase;letter-spacing:.1em;font-size:clamp(.6rem,.9vw,.72rem);font-weight:600;color:#ffffffb8}
@media (width<=700px){.typehero__stats{grid-template-columns:1fr 1fr;gap:1.1rem 1.6rem}}

/* The hero primary CTA sits on a photograph, so it needs to lift off it the way the reference
   gold buttons do. A drop shadow plus a hairline ring gives that separation without changing the
   brand colour. Scoped to hero CTAs; section buttons on solid backgrounds are untouched. */
.hero__ctas .btn--primary,.lockhero__act .btn--primary,.typehero .btn--primary{box-shadow:0 10px 30px -8px #00000073,0 0 0 1px #ffffff26}

/* --- type hero, LEFT variant (Pixler) --- */
.hero--typeleft .hero__content{place-items:start;text-align:left}
.hero--typeleft .typehero{justify-items:start;text-align:left;max-width:min(94vw,1100px)}
.hero--typeleft .typehero__stats{justify-content:start}
.hero--typeleft .typehero__stat{justify-items:start}
.hero--typeleft .hero__ctas{justify-content:flex-start}

/* === Grading loop round 1 (Sep 3 2026), systemic fixes off 196 graded defects === */

/* Hero eyebrow: accent-coloured .72rem caps over a bright sky read as nothing on landmark (x5),
   northstar and bexar. Every reference sets its kicker in white or a near-white tint over the
   photograph. White plus a real shadow, and the accent survives on the little rule marks. */
.hero .hero__eyebrow,.phero .hero__eyebrow,.hero__eyebrow{color:#fff;text-shadow:0 1px 3px #000c,0 2px 14px #0009}
.hero .hero__eyebrow:before,.hero .hero__eyebrow:after{background:var(--accent-lite,var(--accent))}

/* Accent-tinted headline words over a photograph (the "tint" voice) had no shadow, so a green
   or teal word vanished into the roofline. Same shadow the white words already carry. */
.hero .hero__title .hx-accent,.hero .lockhero__line .hx-accent,.hero .typehero__name .hx-accent{text-shadow:0 2px 18px #000a,0 1px 2px #0008}

/* Ghost button is white-on-transparent, which is invisible the moment a light-mode template
   puts it on a cream band (halcyon video band). On any light surface it borrows the ink. */
.mode-light .section--paper .btn--ghost,.mode-light .section--mist .btn--ghost,.mode-light .vband--light .btn--ghost,.section--paper .btn--ghost,.section--mist .btn--ghost{color:var(--ink);border-color:var(--ink)}
.mode-light .section--paper .btn--ghost:hover,.section--paper .btn--ghost:hover,.section--mist .btn--ghost:hover{background:var(--ink);color:#fff}

/* Mobile header overflow: logo + phone pill + burger do not fit in 390px, so the burger was
   clipped (corporate) or pushed clean off the viewport (redline, every page, a blocker). The
   phone pill drops to its icon under 560px and the burger is pinned to the right edge. */
@media (width<=560px){
  .header__inner{flex-wrap:nowrap;min-width:0;overflow:visible}
  .header__logo{min-width:0;flex:1 1 auto}
  .header__logo img{max-width:min(46vw,190px);height:auto}
  .header__phone{font-size:0;gap:0;padding:.6rem .7rem;min-width:44px}
  .header__phone svg{width:20px;height:20px}
  .header__burger{flex:none;margin-left:.25rem;display:inline-flex;position:static}
  .header--centered .header__burger{position:static}
}

/* Quote bar inputs and consent copy sat on the accent with --ink text: near-black on navy (athletic grader). */
.qbar label,.qbar .field label,.qbar .form__fine,.qbar .form__consent,.qbar small,.qbar p{color:var(--on-accent,var(--ink))}

/* City/service page hero on a phone: the eyebrow sat on the H1's first line (northstar city-m-p1).
   The H1 fit box is desktop-sized; on a phone give the pair real breathing room. */
@media (width<=640px){.phero .hero__eyebrow,.hero--page .hero__eyebrow{margin-bottom:1.15rem}.phero .hero__title,.hero--page .hero__title{line-height:1.02;margin-top:0}}
/* Thank-you referral ask left ~150px of dead paper before the reviews heading (halcyon, poster, craftsman). */
.thanks__referral,.referral{padding-bottom:clamp(1.2rem,3vw,2rem)}
.thanks__referral+.section,.referral+.section{padding-top:clamp(2rem,5vw,3.5rem)}
/* Services intro was a lone measure in a full-width band, half the section empty (editorial,
   craftsman). It now pairs with the crew photo the build already installs. */
.split--intro{grid-template-columns:1.1fr 1fr;align-items:center}
.split__media img{width:100%;height:auto;border-radius:var(--radius);display:block;box-shadow:0 24px 50px -30px #0008}
@media (width<=900px){.split--intro{grid-template-columns:1fr}}
/* Split pages (about, contact, privacy): the prose column ran out ~250px before the aside did
   (halcyon, bexar about-d-p1). The page's own drone photo now closes the column. */
.prose__fig{margin:clamp(1.6rem,3vw,2.4rem) 0 0}
.prose__fig img{width:100%;height:auto;border-radius:var(--radius);display:block}
/* 1b hero mark (hero__logo) had a shadow only for the lockup variant; a dark logo like AGR's
   mountains sank into the roofline on the live mockup. Same lift as .lockhero__mark. */
.hero__logo{filter:drop-shadow(0 2px 3px #00000073) drop-shadow(0 0 14px #00000059)}
/* Plan-compare table scrolls sideways on a phone but nothing said so; the last tier read as
   missing (maintenance home-m-p6). A right-edge fade plus a visible hint under 700px. */
@media (width<=700px){.pcmp__scroll{-webkit-mask-image:linear-gradient(90deg,#000 88%,#0000);mask-image:linear-gradient(90deg,#000 88%,#0000)}.pcmp__scroll:after{content:"Swipe to see every plan";display:block;font:600 .72rem/1 var(--font-display);letter-spacing:.08em;text-transform:uppercase;color:var(--text-mute);padding:.6rem .8rem;position:sticky;left:0}}
/* Quote/hero rating card sat flush on the certification badges (redline quote-d-p1) and its
   outbound link was accent-on-photo. Space below the card; the link goes white with a shadow. */
.hero .rev__agg,.hero .rev__agg-body{margin-bottom:1.1rem}
.hero .rev__agg-go{color:#fff;text-shadow:0 1px 3px #000c;text-decoration:underline;text-underline-offset:3px}
.hero .rev__agg-count{color:#fffffff0;text-shadow:0 1px 3px #000c}
/* The type hero's kicker is .typehero__kicker, not .hero__eyebrow, so it missed the white fix
   (corporate home/services/commercial/about). Same treatment. */
.typehero__kicker{color:#fff;text-shadow:0 1px 3px #000c,0 2px 14px #0009}
/* Transparent header over a bright sky: the phone pill's white text washed out (corporate about). */
.header:not(.stuck) .header__phone{text-shadow:0 1px 2px #000b}
.header:not(.stuck) .header__phone svg{filter:drop-shadow(0 1px 1px #000b)}
/* Town cards: auto-fill at 210px made 5 columns on desktop, so 6 towns left one card alone on
   row two (corporate, redline home-d-p4 / area-d-p1). Three across from 900px up. */
@media (width>=900px){.area__grid{grid-template-columns:repeat(3,1fr)}}
/* Quote-bar fine print (the lock-icon privacy line, consent copy, footer note) was still ink on
   the accent band after the label fix (athletic home-d-p1, home-m-p2). */
.qbar .form__privacy,.qbar .form__foot,.qbar .form__consent,.qbar .form__privacy span,.qbar .form__status{color:var(--on-accent,var(--ink))}
.qbar .form__privacy svg{color:var(--on-accent,var(--ink))}
/* Thank-you: the reviews block and the next paper section both carried full padding, leaving
   ~140px of nothing between the Google card and "Try one of these" (athletic thanks-d-p2). */
.section:has(.rev__agg)+.section{padding-top:clamp(1.6rem,4vw,2.6rem)}
/* The lockup's one-line caption is .9rem letterspaced caps over a photograph; an accent-tinted
   word in it (bexar "ROOFER, LITERALLY") stays low-contrast even with a shadow. White it is. */
.lockhero__line .hx-accent{color:#fff}
/* Proof-gallery tag chips wrapped to 3-4 lines and covered half the photo on a phone (poster
   home-m-p2/p3). One line, clipped, smaller, and the grid goes single column under 480px. */
@media (width<=480px){.gal__tag{font-size:.6rem;max-width:calc(100% - 1.4rem);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;letter-spacing:.08em;padding:.4rem .55rem}.gal__grid,.gal{grid-template-columns:1fr}}
/* mode-light restyles every .section--dark to mist, so a ghost button inside one (halcyon video
   band, home-d-p3 / home-m-p8) was white on cream. Ink on any light-mode dark section. */
.mode-light .section--dark .btn--ghost{color:var(--ink);border-color:var(--ink)}
.mode-light .section--dark .btn--ghost:hover{background:var(--ink);color:#fff;border-color:var(--ink)}
/* Page heroes (.phero) label with the generic .kicker, which is accent-ink on paper and vanished
   over a bright roof (northstar commercial-m-p1, halcyon service-detail/city). White over photos. */
.phero .kicker{color:#fff;text-shadow:0 1px 3px #000c,0 2px 14px #0009}
.phero .kicker:before{background:var(--accent-lite,var(--accent))}

/* Page-hero kicker must beat any later .kicker rule on light-mode templates (utilitarian about/area/work were gold). */
body .phero .kicker,body.mode-light .phero .kicker{color:#fff}
/* Header wordmark over a light-toned aerial (halcyon service-detail/city/commercial) sank into the
   sky. Same drop-shadow the hero mark carries, only while the header is transparent over the photo. */
.header:not(.stuck) .header__logo img{filter:drop-shadow(0 2px 6px #0009) drop-shadow(0 1px 1px #0008)}
/* Split pages on a phone: the breadcrumb bar was followed by a full section padding, ~180px of
   paper before the first heading (craftsman about-m-p1, three rounds). Half of it under 640px. */
@media (width<=640px){.crumbs+.section,.crumbs+section{padding-top:clamp(1.4rem,5vw,2.2rem)}}
/* Breadcrumb links inherited the nav's hover-underline pseudo-element, which rendered as a stray
   dot under the trail at rest (athletic city-d-p1, three rounds). Breadcrumbs get no underline. */
.crumbs a:after{display:none!important}
/* One-line chips cut words in half (corporate work-m-p2/p4). Two clamped lines instead. */
@media (width<=480px){.gal__tag{white-space:normal;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:clip;line-height:1.25}}
/* Some headers set the wordmark as text (halcyon), which the img drop-shadow above never touched. */
.header:not(.stuck) .header__logo,.header:not(.stuck) .header__logo span{text-shadow:0 1px 3px #000c,0 2px 10px #0009}
/* Two-column intro and split-checklist bands left ~100-130px of paper under the shorter column
   (landmark home-d-p3, services-d-p1, three rounds). From 900px up the photo column stretches to
   the text column and the image covers it. */
@media (width>=900px){
  .intro__grid{align-items:stretch}
  .intro__media{aspect-ratio:auto;min-height:100%;height:auto}
  .splitck{align-items:stretch}
  .splitck__media{display:flex}
  .splitck__media img{width:100%;height:100%;object-fit:cover;border-radius:var(--radius)}
}
/* R5-01 Interior page heroes had nothing to press, so a search visitor landing on /services/ or
   /service-area/ scrolled a full screen before the first action (editorial services-d-p1,
   area-d-p1). Same two buttons the home hero carries, on the same rail as the copy. */
.phero__acts{display:flex;flex-wrap:wrap;gap:.8rem;margin-top:1.6rem}
@media (width<=560px){.phero__acts{gap:.6rem}.phero__acts .btn{flex:1 1 100%;padding-block:.95rem}}
/* R5-03 The portfolio page ran a 2-across grid while home and services ran 3-across, so the same
   photographs read as two different galleries (landmark work-d-p1). Three from 1000px up. */
@media (width>=1000px){.workgrid{grid-template-columns:repeat(3,1fr)}}
/* R5-06 Ticker skins. Nine reference sites run a marquee under the hero: 5 accent, 4 dark, 1
   white, and two set the words as alternating solid and hollow type. Ours was one accent band
   with a slash on every site that used it. Default (.ticker alone) is unchanged. */
/* .ticker__group already forces color:var(--on-accent,var(--ink)), which is #FFFFFF on every
   dark-accent brand. Setting the colour on the section alone left the paper skin white on white
   (probed: wordColor rgb(255,255,255) on a rgb(255,255,255) band). Every skin sets the GROUP. */
.ticker--dark{background:var(--ink);border-block:3px solid var(--accent)}
.ticker--dark .ticker__group{color:#fff}
.ticker--dark .ticker__dot{color:var(--accent-lite,var(--accent))}
.ticker--paper{background:#fff;border-block:1px solid #0000001f}
.ticker--paper .ticker__group{color:var(--ink)}
.ticker--paper .ticker__dot{color:var(--accent-ink,var(--accent))}
.ticker--outline{background:var(--ink);border-block:3px solid var(--accent)}
.ticker--outline .ticker__group{color:#fff}
.ticker--outline .ticker__dot{color:var(--accent-lite,var(--accent))}
.ticker--outline .ticker__w--hollow{color:#0000;-webkit-text-stroke:1px var(--accent-lite,var(--accent))}
@supports not (-webkit-text-stroke:1px #000){.ticker--outline .ticker__w--hollow{color:var(--accent-lite,var(--accent));-webkit-text-stroke:0}}
/* R5-09 Mosaic portfolio (rooferzcorp): one large frame, two stacked beside it, then one wide,
   repeating in fours. Falls back to the plain grid under 900px where every reference stacks. */
@media (width>=900px){
  .workgrid--mosaic{grid-template-columns:repeat(3,1fr);grid-auto-flow:dense}
  .workgrid--mosaic .gal__item{aspect-ratio:4/3}
  .workgrid--mosaic .gal__item:nth-child(4n+1){grid-column:span 2;grid-row:span 2;aspect-ratio:auto}
  .workgrid--mosaic .gal__item:nth-child(4n+4){grid-column:span 3;aspect-ratio:21/9}
  .workgrid--mosaic .gal__item:nth-child(4n+1) img,.workgrid--mosaic .gal__item:nth-child(4n+4) img{width:100%;height:100%;object-fit:cover}
}
/* R5-10 CONTRAST. Victor, Sep 4: "some of them have like black fucking writing on like dark blue
   background. you can't even see it." Measured by qa/contrast-audit.mjs on the live pages:
   athletic's required-field asterisk rendered --accent-ink #0e2745 on the --accent #14365d quote
   bar at 1.23:1. --accent-ink is the accent DARKENED for text on paper; inside an accent-filled
   block it is the accent on itself. Redefining the variable on the block fixes every consumer at
   once (.req, .kicker, .stat__val, .area__go, .rev__agg-go, .form__note a, .why__icon) instead of
   one selector at a time. .ticker--paper is excluded: its band is white, so paper rules apply. */
.qbar,.band,.callband,.offer,.gal__tag,.photobadge,.plan__tag,.case__tag,.ba__label--b,
.skip-link,.ticker:not(.ticker--paper):not(.ticker--dark):not(.ticker--outline){
  --accent-ink:var(--on-accent,var(--ink))
}
/* R5-11 CONTRAST OVER PHOTOGRAPHS. Measured with the pixel pass in qa/contrast-pixels.py, which
   reads the glyphs against the pixels actually behind them rather than against a CSS ancestor:
   athletic /thank-you/ h1 2.51:1 over a white roof, hero ghost button label 2.75:1, hero sub
   2.64:1, header phone 2.50:1. A 36% scrim is not enough over a bright sky. The scrim comes up,
   the hero type carries a shadow, and the ghost button on a photo gets a dark plate so its
   label is read against something known instead of against whatever the drone flew over. */
.hero__scrim{background:linear-gradient(#16181c70 0%,#16181c85 46%,#16181cb0 100%)}
.hero .hero__title,.hero .hero__sub,.hero .hero__eyebrow,.hero .lockhero__line,
.hero .lockhero__sub,.hero .typehero__name,.hero .typehero__city{
  text-shadow:0 1px 3px #16181cbf,0 2px 18px #16181c99
}
.hero .btn--ghost,.phero .btn--ghost{background:#16181c66;border-color:#ffffff8f}
.hero .btn--ghost:hover,.phero .btn--ghost:hover{background:#fff;border-color:#fff}
.header:not(.stuck) .header__phone{background:#16181c59;border-radius:var(--radius)}
/* R5-12 CONTRAST, second pass. Same measurement, the elements the first pass did not cover:
   header nav links 2.74:1 over a bright hero, a section kicker 3.24:1 over a photo band, and the
   review count in the quote hero 4.24:1. Anything painted over a photograph gets the same
   treatment the hero type already has. */
.header:not(.stuck) .nav a,.header:not(.stuck) .nav__link,.header:not(.stuck) .header__logo span{
  text-shadow:0 1px 3px #16181ccc,0 2px 12px #16181ca6
}
.hero .kicker,.imgband .kicker,.videoband .kicker,.offer .kicker,.reel .kicker,
.hero .rev__agg-count,.hero .rev__agg-body,.phero .rev__agg-count{
  color:#fff;text-shadow:0 1px 3px #16181ccc,0 2px 12px #16181ca6
}
.hero .kicker:before,.imgband .kicker:before,.videoband .kicker:before,.offer .kicker:before,
.reel .kicker:before{background:var(--accent-lite,var(--accent))}
/* R5-13 The nav is .header__nav, not .nav, so the R5-12 shadow rule matched nothing and the nav
   links stayed at 2.74:1 over a bright sky (athletic 404-d, city-d, thanks-d). Verified against
   the rendered markup this time instead of a guessed selector. */
.header:not(.stuck) .header__nav a,.header:not(.stuck) .brandmark span{
  text-shadow:0 1px 3px #16181cd9,0 2px 12px #16181cb3
}
/* R5-14 The last seven sat at 3.96 to 4.47 against a 4.5 target, all of them white on a bright
   roof or sky. The plates and the shadows go one step darker so the whole set clears AA rather
   than sitting just under it, which is the state that ships and then gets reported by eye. */
.hero .btn--ghost,.phero .btn--ghost{background:#16181c8c}
.header:not(.stuck) .header__phone{background:#16181c8c}
.hero .hero__title,.hero .hero__sub,.hero .hero__eyebrow,.hero .lockhero__line,
.hero .lockhero__sub,.hero .typehero__name,.hero .typehero__city,
.phero .hero__sub,.phero .h-hero{text-shadow:0 1px 3px #16181ce6,0 2px 20px #16181cc4}
/* R5-15 The plates were still translucent enough that a bright sky pushed the composite to a
   mid grey and white on it measured 4.06 to 4.46 against a 4.5 target. Both go opaque enough
   that the label is read against a known colour whatever the drone flew over. */
.hero .btn--ghost,.phero .btn--ghost{background:#16181cc4}
.header:not(.stuck) .header__phone{background:#16181cdb}
/* R5-16 CONTRAST CLASSES, from the full 14-site sweep (qa/contrast, findings.json per site). Four
   classes accounted for every solid-background failure that was not the accent-ink one. */

/* 1. .btn--outline is ink on ink inside a dark band: an invisible button. commercial home-d
      "All projects" measured 1.00:1. mode-light repaints .section--dark as cream, so it keeps
      the ink version. */
.section--dark .btn--outline,.contact .btn--outline,.hero .btn--outline,.imgband .btn--outline,
.videoband .btn--outline{border-color:#fff;color:#fff}
.section--dark .btn--outline:hover,.contact .btn--outline:hover,.hero .btn--outline:hover,
.imgband .btn--outline:hover,.videoband .btn--outline:hover{background:#fff;color:var(--ink)}
.mode-light .section--dark .btn--outline{border-color:var(--ink);color:var(--ink)}
.mode-light .section--dark .btn--outline:hover{background:var(--ink);color:#fff}

/* 2. The two-voice accent word used --accent-lite everywhere. --accent-lite is the accent
      LIGHTENED to clear AA on a dark card, so on a white or cream section it is the least
      readable colour available: maintenance measured 1.84:1 on mist and 2.04:1 on white, and
      bexar rendered the accent word ON an accent band at 1.00:1. One rule per context. */
.hx-accent{color:var(--accent-ink)}
.section--dark .hx-accent,.contact .hx-accent,.imgband .hx-accent,.videoband .hx-accent,
.hero .hx-accent{color:var(--accent-lite,var(--accent))}
.band .hx-accent,.qbar .hx-accent,.offer .hx-accent,.callband .hx-accent{color:var(--on-accent,var(--ink))}
.lockhero__line .hx-accent{color:#fff}

/* 3. The footer copyright ran 45% white on ink, 4.41 to 4.49 against a 4.5 target, on ten of
      the fourteen. It is the legal line; it has to be readable. */
.footer__legal{color:#ffffffb0}

/* 4. The Google review link sat at 4.32 to 4.50 on the review card. It is a link, so it gets the
      link treatment rather than another shade of accent. */
.rev__agg-go{color:#fff;text-decoration:underline;text-underline-offset:3px}
.section--paper .rev__agg-go,.section--mist .rev__agg-go,.mode-light .rev__agg-go{color:var(--accent-ink)}
/* R5-18 The featured-project tag in the portfolio hero is accent-colored text sitting on a
   translucent card over the hero photograph, measured 2.22:1 on commercial home-d. The card
   gets a real fill behind the label rather than a blur over whatever the drone flew over. */
.hero__feat{background:#16181cb8}
.hero__feat-tag{color:var(--accent-lite,var(--accent));text-shadow:0 1px 3px #16181ce6}
/* NO PLATE BEHIND THE HERO LOGO (Victor's Law 2026-09-09). R5-19 painted a radial dark
   ellipse straight onto the logo img to make a dark wordmark legible on a photograph. On
   Innova Pro Painting it rendered as a grey smudge floating behind the mark, and Victor:
   "i don't like that black spot you put behind the logo, look at siterabbit they never add
   that." None of the 22 reference sites plate their hero logo. The hero photograph already
   carries its own overlay, and a mark that still cannot be read on it is a hero-image
   problem or a wrong logo variant, never a reason to paint a blob on the page.
   Legibility now comes from a tight shadow that hugs the letterforms instead. */
.hero__logo,.lockhero__mark{background:none;padding:0;box-sizing:border-box}
.hero--markdark .hero__logo,.hero--markdark .lockhero__mark{
  background:none;
  filter:drop-shadow(0 1px 2px #ffffffb3) drop-shadow(0 0 10px #ffffff80)
}
/* R5-20 OVERLAP. The R5 fix that stretched the split-checklist photo to the text column set
   display:flex on the media cell. A flex item defaults to min-width:auto, so the 1,600px master
   refused to shrink below its own content size: measured on the live AGR page the grid track was
   532px and .splitck__media rendered 1,125px, spilling across both columns with the checklist
   text painted on top of the truck. A fix that closed a whitespace gap opened a legibility
   blocker on every site that runs the module. min-width:0 is the flex overflow fix. */
.splitck__media,.intro__media{min-width:0;max-width:100%}
/* min-width:0 alone stops the spill and then collapses the cell to nothing, because the image
   was carrying the width with height:100% and no height to resolve against: the first attempt
   left a 630px empty column where the photo had been. The cell owns the box, the image fills it
   absolutely, so the track size never depends on the image's intrinsic size in either direction. */
@media (width>=900px){
  .splitck__media,.intro__media{position:relative;display:block;align-self:stretch}
  .splitck__media img,.intro__media img{
    position:absolute;inset:0;width:100%;height:100%;object-fit:cover;border-radius:var(--radius)
  }
}

/* Victor's Law 2026-09-07 ("I don't want these transparent buttons"): every CTA renders FILLED.
   .btn--outline and .btn--ghost keep their names for the templates but never show a transparent
   face again. Appended last on purpose so it wins every earlier context rule at equal specificity. */
.btn--outline,.section--paper .btn--outline,.section--mist .btn--outline,.mode-light .btn--outline{background:var(--ink);color:#fff;border-color:var(--ink)}
.btn--outline:hover,.section--paper .btn--outline:hover,.section--mist .btn--outline:hover{background:var(--accent);color:var(--on-accent,var(--ink));border-color:var(--accent);transform:translateY(-2px)}
.band .btn--outline,.callband .btn--outline,.videoband .btn--outline,.qbar .btn--outline,.offer .btn--outline{background:var(--on-accent,#fff);color:var(--accent);border-color:var(--on-accent,#fff)}
.band .btn--outline:hover,.callband .btn--outline:hover,.videoband .btn--outline:hover,.qbar .btn--outline:hover,.offer .btn--outline:hover{background:var(--ink);color:#fff;border-color:var(--ink)}
.btn--ghost,.phero .btn--ghost,.hero .btn--ghost,.header .btn--ghost{background:#fff;color:var(--ink);border-color:#fff}
.btn--ghost:hover,.phero .btn--ghost:hover,.hero .btn--ghost:hover,.header .btn--ghost:hover{background:var(--accent);color:var(--on-accent,var(--ink));border-color:var(--accent);transform:translateY(-2px)}
.mode-light .btn--ghost,.mode-light .section--mist .btn--ghost,.mode-light .vband--light .btn--ghost,.section--paper .btn--ghost,.section--mist .btn--ghost,.header.is-scrolled .btn--ghost,.header.is-light .btn--ghost{background:var(--ink);color:#fff;border-color:var(--ink)}
.mode-light .btn--ghost:hover,.section--paper .btn--ghost:hover,.section--mist .btn--ghost:hover,.header.is-scrolled .btn--ghost:hover,.header.is-light .btn--ghost:hover{background:var(--accent);color:var(--on-accent,var(--ink));border-color:var(--accent)}

/* Victor's Law 2026-09-07 ("I don't like this gray scroll wheel"): the page scrollbar is thin, the
   thumb is the brand accent, the track is transparent, so a dark hero never shows a gray bar. */
html{scrollbar-width:thin;scrollbar-color:var(--accent) transparent}
html::-webkit-scrollbar,body::-webkit-scrollbar{width:9px;height:9px}
html::-webkit-scrollbar-track,body::-webkit-scrollbar-track{background:transparent}
html::-webkit-scrollbar-thumb,body::-webkit-scrollbar-thumb{background:var(--accent);border-radius:999px;border:2px solid transparent;background-clip:padding-box}
html::-webkit-scrollbar-thumb:hover,body::-webkit-scrollbar-thumb:hover{background:var(--accent-hover,var(--accent));background-clip:padding-box}
body.mode-light .header.stuck .btn--ghost{background:var(--ink);color:#fff;border-color:var(--ink)}
body.mode-light .header.stuck .btn--ghost:hover{background:var(--accent);color:var(--on-accent,var(--ink));border-color:var(--accent)}

/* Victor's Law 2026-09-08 ("fix this transparent bullshit"): a button on an ACCENT surface never
   hovers to the accent, or it disappears into the band. On .band, .callband, .qbar, .offer the
   hover goes ink to white and outline to ink, never accent. */
.band .btn--ink:hover,.callband .btn--ink:hover,.qbar .btn--ink:hover,.offer .btn--ink:hover,.band .btn--primary:hover,.callband .btn--primary:hover,.qbar .btn--primary:hover,.offer .btn--primary:hover{background:#fff;color:var(--ink);border-color:#fff}
.band .btn--outline:hover,.callband .btn--outline:hover,.qbar .btn--outline:hover,.offer .btn--outline:hover{background:#fff;color:var(--ink);border-color:#fff}

/* heroProof: the rating row under the hero CTAs (Victor's Law 2026-09-09). Centres under the
   buttons on the centred hero, sits left on the left and lockup heroes, and the aggregate
   inside it keeps its own dark-surface colours. */
.hero__proof{justify-content:center;margin-top:1.15rem;display:flex}
.hero--left .hero__proof,.hero--lockupLeft .hero__proof,.hero--form .hero__proof{justify-content:flex-start}
.hero__proof .rev__aggregate{background:none;border:0;padding:0;box-shadow:none}
@media (width<=640px){.hero__proof{margin-top:.9rem}}

/* scroll-scrub section (scrub:<key> in homeSections). Ported Sep 9 2026 from scripts/inject-scrub-hero.py. overflow-x:clip on html/body, never hidden, or position:sticky dies. */
html,body{overflow-x:clip}
.scrub-sec{position:relative;height:300vh;height:300svh;background:var(--ink)}
.scrub-sec .scrub-sticky{position:sticky;top:0;height:100vh;height:100svh;height:100dvh;overflow:hidden;display:flex;align-items:center}
.scrub-sec .scrub-media{position:absolute;inset:0;z-index:0}
.scrub-sec .scrub-canvas{position:absolute;inset:0;width:100%;height:100%;display:block}
.scrub-sec .scrub-pill{position:absolute;right:28px;bottom:28px;z-index:6;font:700 12px/1 var(--font-display);letter-spacing:.14em;text-transform:uppercase;padding:10px 14px;border:1px solid #ffffff47;border-radius:999px;background:#16181c80;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);color:#fff}
.scrub-sec .scrub-pill b{color:var(--accent-lite,var(--accent))}
.scrub-sec .scrub-scrim{position:absolute;inset:0;z-index:1;pointer-events:none;background:linear-gradient(90deg,#0e0d0be6 0%,#0e0d0bb3 44%,#0e0d0b26 74%,#0e0d0b73 100%)}
.scrub-sec .scrub-copy{position:relative;z-index:3;width:100%;max-width:1240px;margin:0 auto;padding:0 clamp(20px,4vw,48px)}
.scrub-sec .scrub-copy .kick{font:700 12px/1 var(--font-display);letter-spacing:.22em;text-transform:uppercase;color:var(--accent-lite,var(--accent));display:block;margin-bottom:16px}
.scrub-sec .scrub-copy h2{font-size:clamp(34px,5.4vw,68px);line-height:.99;color:#fff;max-width:15ch;text-wrap:balance;margin:0 0 18px}
.scrub-sec .scrub-copy h2 .hx-accent,.scrub-sec .scrub-copy h2 em{font-style:normal;color:var(--accent-lite,var(--accent))}
.scrub-sec .scrub-copy p{font-size:18px;line-height:1.55;color:#ffffffd9;max-width:44ch;margin:0 0 26px}
@media (max-width:700px){
  .scrub-sec{height:280svh}
  .scrub-sec .scrub-sticky{justify-content:center;padding:calc(var(--header-h) + 8px) 0 calc(env(safe-area-inset-bottom) + 78px)}
  /* the copy block gets its own ellipse of scrim; a flat wash dark enough for AA over a pale floor erases the picture (Innova, kicker 1.41:1 -> 4.66:1) */
  .scrub-sec .scrub-scrim{background:radial-gradient(130% 52% at 50% 48%,#0b0b0ba6 0%,#0b0b0b99 42%,#0b0b0b4d 68%,#0b0b0b00 86%),linear-gradient(180deg,#0b0b0bb3 0%,#0b0b0b40 26%,#0b0b0b33 58%,#0b0b0bd9 100%)}
  .scrub-sec .scrub-copy{text-align:center;padding:0 20px}
  .scrub-sec .scrub-copy .kick{margin-bottom:10px}
  .scrub-sec .scrub-copy h2{font-size:clamp(30px,9vw,44px);max-width:18ch;margin:0 auto 12px;text-shadow:0 4px 30px #000000a6}
  .scrub-sec .scrub-copy p{font-size:15px;line-height:1.45;max-width:32ch;margin:0 auto 18px;text-shadow:0 2px 18px #000000a6}
  .scrub-sec .scrub-copy .btn{padding:16px 26px}
  .scrub-sec .scrub-pill{right:12px;bottom:calc(env(safe-area-inset-bottom) + 86px);font-size:10px;padding:6px 10px}
}

/* the icon inside a tap target must not be the thing a tap lands on (qa-mobile TAP_REACHES_CLOSE, J&M Sep 10 2026) */
#menuClose svg,#burger svg,.header__burger svg,.callbar a svg,.btn svg{pointer-events:none}

/* --- config-driven form fields --- */
.form fieldset.field{border:0;margin:0 0 1rem;padding:0;min-width:0}.form .field__legend{font:700 .7rem/1 var(--font-display);letter-spacing:.12em;text-transform:uppercase;color:var(--text-mute);margin:0 0 .55rem;padding:0;display:block;float:none}.form .field__legend .req{color:var(--accent-ink);margin-left:.25rem;font-weight:700}.form .field__legend .opt{color:var(--text-soft);text-transform:none;letter-spacing:0;margin-left:.4rem;font-weight:400}.form .field__hint{color:var(--text-soft);margin:0 0 .55rem;font-size:.84rem;line-height:1.5}.form .pills{display:grid;grid-template-columns:1fr;gap:.5rem;margin:0}@media (width>=560px){.form .pills{grid-template-columns:1fr 1fr}}.form .pill{display:flex;position:relative;margin:0;font:inherit;letter-spacing:0;text-transform:none;color:inherit;cursor:pointer}.form .pill input{position:absolute;width:1px;height:1px;padding:0;margin:0;opacity:0;border:0;background:none;pointer-events:none}.form .pill>span{display:flex;align-items:center;gap:.7rem;width:100%;min-height:48px;padding:.7rem .9rem;border:1.5px solid var(--line);border-radius:var(--radius);background:var(--mist);color:var(--ink);font:500 .97rem/1.3 var(--font-display);transition:border-color .2s var(--ease),background .2s var(--ease),color .2s var(--ease)}.form .pill>span:before{content:"";flex:none;width:20px;height:20px;border-radius:4px;border:1.5px solid var(--line);background:#fff;transition:background .18s var(--ease),border-color .18s var(--ease)}.form .field--pills:not(.field--checks) .pill>span:before{border-radius:50%}.form .pill:hover>span{border-color:var(--accent);background:#fff}.form .pill input:checked+span{border-color:var(--accent-ink);background:var(--accent);color:var(--on-accent,var(--ink));font-weight:600}.form .pill input:checked+span:before{border-color:var(--accent-ink);background:var(--accent-ink) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20 6 9 17l-5-5' fill='none' stroke='%23fff' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/13px 13px no-repeat}.form .pill input:focus-visible+span{outline:2px solid var(--accent-ink);outline-offset:2px}.form .field--pills.is-err .pill>span{border-color:#b3261e}.form .field--photos .photos__input{position:absolute;width:1px;height:1px;padding:0;margin:0;opacity:0;border:0;background:none}.form .photos__pick{display:inline-flex;align-items:center;justify-content:center;min-height:44px;padding:.7rem 1.2rem;border:1.5px dashed var(--line);border-radius:var(--radius);background:var(--mist);color:var(--ink);font:700 .74rem/1 var(--font-display);letter-spacing:.1em;text-transform:uppercase;margin:0;cursor:pointer;transition:border-color .2s var(--ease),background .2s var(--ease)}.form .photos__pick:hover{border-color:var(--accent);background:#fff}.form .field--photos:focus-within .photos__pick{outline:2px solid var(--accent-ink);outline-offset:2px}.form .photos__list{display:flex;flex-wrap:wrap;gap:.6rem;margin:.7rem 0 0;padding:0;list-style:none}.form .photos__item{width:88px}.form .photos__item img{width:88px;height:88px;object-fit:cover;display:block;border-radius:var(--radius);background:var(--mist)}.form .photos__rm{display:block;width:100%;min-height:32px;margin-top:.2rem;padding:0;border:0;background:none;color:var(--accent-ink);font:600 .74rem/1 var(--font-display);text-decoration:underline;cursor:pointer}.form .photos__note{color:var(--text-soft);margin:.55rem 0 0;font-size:.84rem;line-height:1.5;min-height:1px}.form .window__row{display:grid;gap:.8rem}.form .field--window .field{margin-bottom:0}.form .field--select select,.form .field--window select{min-height:44px}@media (width>=520px){.form .window__row{grid-template-columns:1fr 1fr}}@media (width<=380px){.form .pill>span{padding:.6rem .85rem;font-size:.9rem}}
/* --- stepped lead form --- */
.form .form__steps{scroll-margin-top:120px;min-width:0}.form .form__step{min-width:0}.form .form__step[hidden],.form .form__nav .btn[hidden],.form .form__foot--steps[hidden]{display:none}.form .form__progress{display:flex;flex-direction:column;gap:.5rem;margin:0 0 1.2rem}.form .form__progress-track{display:block;height:4px;border-radius:999px;background:var(--line);overflow:hidden}.form .form__progress-fill{display:block;height:100%;width:33%;border-radius:999px;background:var(--accent-ink);transition:width .3s var(--ease)}.form .form__progress-text{font:700 .7rem/1.3 var(--font-display);letter-spacing:.12em;text-transform:uppercase;color:var(--text-mute)}.form .form__nav{display:flex;flex-wrap:wrap;align-items:center;gap:.6rem;margin-top:1.1rem}.form .form__nav .form__next{flex:1 1 auto;min-height:52px;padding-inline:1.2rem}.form .form__nav .form__back{order:-1;flex:0 0 auto;min-height:44px;padding:.6rem .2rem;background:none;border:0;color:var(--text-mute);text-decoration:underline;text-underline-offset:3px;font:700 .72rem/1 var(--font-display);letter-spacing:.1em}.form .form__nav .form__back:hover{color:var(--accent-ink);background:none;transform:none;box-shadow:none}.form .form__foot--steps{margin-top:1.1rem}.form .form__foot--always{margin-top:.9rem}.form .form__foot--always[hidden]{display:none}@media (width<=420px){.form .form__nav .form__next{width:100%;flex:none}}.form .form__meta{display:flex;flex-wrap:wrap;gap:.35rem 1.1rem;margin:0 0 .7rem;font:600 .82rem/1.4 var(--font-display);color:var(--text-soft)}.form .form__meta[hidden]{display:none}.form .form__meta-item{display:inline-flex;align-items:center;gap:.4rem}.form .form__meta-item svg{flex:none;color:var(--accent-ink)}.form .form__done{padding:.4rem 0 .2rem}.form .form__done-h{display:flex;align-items:center;gap:.6rem;margin:0 0 .6rem;font-family:var(--font-poster);text-transform:uppercase;font-size:1.3rem;line-height:1.1;color:var(--ink)}.form .form__done-h svg{flex:none;color:#1e783c}.form .form__done-slot{margin:0 0 .7rem;padding:.75rem .9rem;border-radius:var(--radius);background:#1e783c14;border:1px solid #1e783c47;color:#1c6b38;font:700 1rem/1.35 var(--font-display)}.form .form__done-p{margin:0 0 .7rem;color:var(--text-soft);font-size:.97rem;line-height:1.6}.form .form__done-call{margin:0;color:var(--text-mute);font-size:.86rem;line-height:1.5}.form .form__done-call a{color:var(--accent-ink);font-weight:600}.form .field select{appearance:none;-webkit-appearance:none;min-height:48px;padding-right:2.4rem;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m6 9 6 6 6-6' fill='none' stroke='%236b7280' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right .85rem center;background-size:16px}.form .sel .field select,.form .sel select.sel__native{background-image:none}.hero .form,.hero .form .field,.hero .form label,.hero .form .field__legend,.hero .form .form__legend,.hero .form .form__meta{text-align:left}.hero .form h3{text-align:left}
