/* Katy Brothers Pressure Washing - premium design system, trades/industrial
   end of the dial (premium-design-system.md section 3). Cool ground, cold
   ink, heavy grotesque headings, 8-12px radius, snappy motion, visible
   structure. Navy carries every button; gold is a highlight only. */
:root{
  --hue:251;
  /* neutral ramp, all derived off the navy hue so a client color change is
     a one-variable edit, never pure white or pure black anywhere */
  --ground:oklch(96.2% 0.007 var(--hue));       /* page background: cool concrete/slate, never #fff */
  --ground-alt:oklch(92.3% 0.011 var(--hue));   /* alternating section band, structure over whitespace */
  --surface:oklch(98.8% 0.004 var(--hue));      /* card/panel surface, still a hair off pure white */
  --line:oklch(83% 0.014 var(--hue));           /* visible rules and dividers */
  --line-on-dark:oklch(100% 0 0 / .14);
  --ink:oklch(21% 0.020 var(--hue));            /* headings: near-black, cold cast, never #000 */
  --body-c:oklch(34% 0.018 var(--hue));
  --muted:oklch(49% 0.016 var(--hue));

  --navy:#0B5FA5; --navy-dark:#08447a; --navy-deep:#062f54;
  --gold:#FAC800; --gold-ink:#7a5f00; --tint:#E6F0FA;

  /* Radii opened up and shadows softened on 2026-09-08, after Charlie sent
     a reference site and asked for that sleek/pro feel with Katy Brothers'
     own colours: rounder surfaces, softer edges, more atmosphere. The
     trades-industrial bones stay (navy carries every button, gold is a
     highlight only, structure over whitespace) -- this is a finish pass on
     that system, not a different one. */
  --radius-sm:10px; --radius:14px; --radius-lg:20px; --radius-pill:999px;
  --wrap:1180px; --wrap-narrow:820px; --wrap-header:1340px;
  --shadow:0 18px 44px -20px oklch(21% 0.03 var(--hue) / .42);
  --shadow-lift:0 26px 60px -24px oklch(21% 0.03 var(--hue) / .5);
  --glass:oklch(100% 0 0 / .08);
  --glass-line:oklch(100% 0 0 / .16);
  --ease:cubic-bezier(.22,.72,.24,1); --dur:280ms;
  --callbar-h:64px;
  --header-h:118px;
}
*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;font-family:'Inter',system-ui,sans-serif;font-size:1.0625rem;color:var(--body-c);
  background:var(--ground);-webkit-font-smoothing:antialiased;overflow-x:hidden}
h1,h2,h3,h4{font-family:'Space Grotesk',system-ui,sans-serif;color:var(--ink);margin:0 0 .5em;line-height:1.12;
  text-wrap:balance}
h1{font-size:clamp(2.1rem,4.6vw,3.15rem);font-weight:700;letter-spacing:-.01em}
h2{font-size:clamp(1.5rem,2.9vw,2.05rem);font-weight:700;letter-spacing:-.005em}
h3{font-size:1.1rem;font-weight:650}
p{line-height:1.65;margin:0 0 1em;text-wrap:pretty}
a{color:var(--navy);text-decoration:none}
img,picture{max-width:100%;display:block}
picture{display:contents}
img{overflow:clip}
/* present to assistive tech, absent on screen */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip-path:inset(50%);white-space:nowrap;border:0}
.skip{position:absolute;left:-999px;top:0;background:var(--navy);color:#fff;padding:10px 16px;z-index:200}
.skip:focus{left:8px;top:8px}
.wrap{max-width:var(--wrap);margin:0 auto;padding:0 24px}
.wrap.narrow{max-width:var(--wrap-narrow)}
section{padding:64px 0}
.prose h2{margin-top:1.4em}
.prose p{color:var(--body-c)}
.eyebrow{display:inline-flex;align-items:center;gap:10px;font-family:'Space Grotesk',sans-serif;font-weight:700;
  font-size:.78rem;letter-spacing:.08em;text-transform:uppercase;color:var(--navy);margin-bottom:.6em}
.eyebrow::before{content:'';width:22px;height:3px;background:var(--gold);border-radius:2px;flex:none}
.eyebrow.on-dark{color:#fff}

/* reveal on scroll: two element types only (sections, cards), snappy and
   never blurred, and only inside @supports so a browser without the API
   simply shows everything instead of leaving content invisible */
@supports (animation-timeline: view()){
  @media (prefers-reduced-motion:no-preference){
    .rv{animation:rv-in .5s var(--ease) both;animation-timeline:view();animation-range:entry 0% cover 22%}
    @keyframes rv-in{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:none}}
  }
}
@media (prefers-reduced-motion:reduce){.rv{animation:none}}

/* buttons: navy carries every fill. squared-off, modest radius, never a
   pill. gold never fills a button. */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;padding:13px 26px;
  border-radius:var(--radius);font-family:'Space Grotesk',sans-serif;font-weight:700;font-size:.94rem;
  border:2px solid var(--navy);background:var(--navy);color:#fff;cursor:pointer;
  transition:transform var(--dur) var(--ease),box-shadow var(--dur) var(--ease),background var(--dur) var(--ease)}
.btn:hover{transform:translateY(-2px);box-shadow:var(--shadow);background:var(--navy-dark)}
.btn.on-dark{background:var(--surface);border-color:var(--surface);color:var(--navy-deep)}
.btn.on-dark:hover{background:var(--ground-alt);border-color:var(--ground-alt)}
.btn.ghost{background:transparent;color:var(--navy)}
.btn.ghost.light{color:#fff;border-color:oklch(100% 0 0 / .55)}
.btn.ghost.light:hover{border-color:#fff;background:oklch(100% 0 0 / .08)}
.btn.sm{padding:9px 18px;font-size:.85rem}
.btn.full{width:100%}

/* ---------------------------------------------------------------
   Interaction layer (Charlie, 2026-09-08: "make sure there is
   animation to make the site feel snappy and responsive to clicks,
   hovers and mouse movements").

   All of it is CSS transitions and transforms plus one tiny
   pointer-position hook in main.js. No Lottie: a Lottie player is a
   ~250KB third-party dependency whose value is illustrative
   character animation, and nothing here needs an illustration. It
   would slow the page down to do worse what compositor-driven
   transforms already do well. Everything is transform/opacity only
   (no layout thrash), micro-interactions run at --dur-fast so they
   feel immediate, and the whole layer is disabled under
   prefers-reduced-motion at the bottom of this file.
   --------------------------------------------------------------- */
:root{--dur-fast:150ms}

/* press feedback: the click should register in the surface itself */
.btn:active{transform:translateY(0) scale(.97);box-shadow:none;transition-duration:var(--dur-fast)}
.btn{will-change:transform}
.short-dot:active,.shorts-nav:active{transform:scale(.9)}
.burger:active span{background:var(--navy)}

/* focus: visible, branded, and never only-on-mouse */
:where(a,button,summary,[tabindex]):focus-visible{outline:3px solid var(--gold);outline-offset:3px;border-radius:4px}

/* cards: lift, plus a highlight that follows the cursor. --mx/--my are
   set by main.js on pointermove; with no JS the gradient just sits
   centred and invisible at 0 opacity. */
.svc-card,.t-card,.ba-card{transition:transform var(--dur) var(--ease),box-shadow var(--dur) var(--ease),
  border-color var(--dur) var(--ease)}
.svc-card::before{content:'';position:absolute;inset:0;z-index:1;pointer-events:none;opacity:0;
  transition:opacity var(--dur) var(--ease);
  background:radial-gradient(340px circle at var(--mx,50%) var(--my,50%),oklch(59% 0.14 var(--hue) / .13),transparent 60%)}
.svc-card:hover::before{opacity:1}
.svc-card:active{transform:translateY(-1px) scale(.995);transition-duration:var(--dur-fast)}
.svc-card img{transition:transform 420ms var(--ease)}
.svc-card:hover img{transform:scale(1.045)}
.svc-card .svc-link{transition:gap var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease)}
.svc-card:hover .svc-link{gap:12px}

.t-card:hover{transform:translateY(-3px);border-color:oklch(100% 0 0 / .28)}
.ba-card figure{overflow:clip;border-radius:var(--radius)}
.ba-card img{transition:transform 420ms var(--ease)}
.ba-card:hover img{transform:scale(1.03)}

/* trust bar + how-it-works: small, quiet responses to the pointer */
.trust-item{transition:transform var(--dur) var(--ease)}
.trust-item:hover{transform:translateY(-2px)}
.hiw-step .hiw-num{transition:transform var(--dur) var(--ease),background var(--dur) var(--ease)}
.hiw-step:hover .hiw-num{transform:translateY(-3px) rotate(-4deg);background:var(--navy-dark)}

/* links: underline grows from the left rather than blinking on */
.prose a:not(.btn),.f-cols a,.area-list a{background-image:linear-gradient(currentColor,currentColor);
  background-size:0% 1.5px;background-position:0 100%;background-repeat:no-repeat;
  transition:background-size var(--dur) var(--ease),color var(--dur-fast) var(--ease)}
.prose a:not(.btn):hover,.f-cols a:hover,.area-list a:hover{background-size:100% 1.5px}

/* nav: dropdown items slide in under the cursor */
.drop-menu li a{transition:background var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease),
  padding-left var(--dur-fast) var(--ease)}
.drop-menu li a:hover{padding-left:16px}
nav.desk>ul>li>a,nav.desk .drop-btn{transition:background var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease)}

/* FAQ: the row itself responds, not just the caret */
.faq-item{transition:background var(--dur-fast) var(--ease)}
.faq-item:hover{background:var(--ground-alt)}

/* sticky call bar: the two highest-value taps on the site */
.sticky-callbar a:active,.sticky-callbar button:active{transform:scale(.96);transition-duration:var(--dur-fast)}

/* header: floats over the hero as a translucent pill, then settles into a
   solid blurred bar once the page scrolls past it (main.js toggles
   .scrolled). Pages whose hero is not a dark photo get .solid-nav from the
   generator and skip the transparent state, so nav text is never white on
   a light background. */
header.site{position:sticky;top:0;z-index:100;transition:background var(--dur) var(--ease),
  border-color var(--dur) var(--ease),box-shadow var(--dur) var(--ease),padding var(--dur) var(--ease);
  background:transparent;border-bottom:1px solid transparent;padding:10px 14px}
header.site .bar{max-width:var(--wrap-header);margin:0 auto;padding:10px 24px;display:flex;align-items:center;gap:16px;
  border-radius:var(--radius-lg);transition:background var(--dur) var(--ease),
  border-color var(--dur) var(--ease),box-shadow var(--dur) var(--ease);
  border:1px solid transparent}
/* At the very top the header is bare: no pill, no panel, no border, just
   the logo and nav sitting straight on the hero photo (Charlie,
   2026-09-08). The pill materialises only once the page scrolls. A text
   shadow keeps the light type readable against whatever part of the photo
   happens to be behind it now that there is no panel to sit on. */
header.site:not(.scrolled):not(.solid-nav) .bar{background:transparent;border-color:transparent;
  box-shadow:none;backdrop-filter:none;-webkit-backdrop-filter:none}
header.site:not(.scrolled):not(.solid-nav) nav.desk>ul>li>a,
header.site:not(.scrolled):not(.solid-nav) .brand,
header.site:not(.scrolled):not(.solid-nav) .bar-cta .tel{text-shadow:0 1px 12px oklch(0% 0 0 / .55)}
header.site:not(.scrolled):not(.solid-nav) nav.desk>ul>li>a,
header.site:not(.scrolled):not(.solid-nav) nav.desk .drop-btn,
header.site:not(.scrolled):not(.solid-nav) .bar-cta .tel{color:oklch(100% 0 0 / .94)}
header.site:not(.scrolled):not(.solid-nav) nav.desk>ul>li>a:hover,
header.site:not(.scrolled):not(.solid-nav) nav.desk .drop-btn:hover{background:oklch(100% 0 0 / .12);color:#fff}
header.site:not(.scrolled):not(.solid-nav) .burger span{background:oklch(100% 0 0 / .95)}
/* Scrolled (and any light-hero page): the pill appears. It floats as an
   inset rounded panel rather than a full-width bar, so the header reads as
   one object that arrives on scroll instead of a band that changes colour.
   The header element itself stays transparent; only .bar is painted. */
header.site.scrolled .bar,header.site.solid-nav .bar{background:oklch(98.8% 0.004 var(--hue) / .86);
  backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);
  border-color:var(--line);box-shadow:0 10px 34px -20px oklch(21% 0.03 var(--hue) / .55)}
header.site.scrolled,header.site.solid-nav{background:transparent;border-bottom-color:transparent}
/* Pull the following section up under the floating header so the hero
   starts at the very top of the viewport and the nav sits over it. Pages
   with a light solid hero (.solid-nav) keep the header in normal flow, so
   their heading is never hidden behind it. */
header.site:not(.solid-nav){margin-bottom:calc(-1 * var(--header-h))}
header.site:not(.solid-nav) + main > .page-hero:first-child{padding-top:var(--header-h)}
/* Full mascot+wordmark lockup, so it needs more height than a wordmark
   banner did to stay legible. It is never cropped: height is set, width
   follows the real aspect ratio. */
header.site .brand img{height:78px;width:auto;flex:none;transition:height var(--dur) var(--ease)}
header.site.scrolled .brand img{height:50px}
nav.desk{flex:1;min-width:0}
nav.desk>ul{list-style:none;display:flex;gap:2px;margin:0;padding:0;align-items:center;flex-wrap:nowrap}
nav.desk>ul>li>a,nav.desk .drop-btn{padding:9px 10px;font-weight:600;color:var(--ink);border-radius:var(--radius-sm);
  font-size:.88rem;background:none;border:none;font-family:inherit;cursor:pointer;display:inline-block;white-space:nowrap}
nav.desk>ul>li>a:hover,nav.desk .drop-btn:hover,nav.desk>ul>li>a.on{color:var(--navy);background:var(--ground-alt)}
.has-drop{position:relative}
.drop-menu{list-style:none;margin:0;padding:8px;position:absolute;top:100%;left:0;background:var(--surface);
  border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow);min-width:230px;
  opacity:0;visibility:hidden;transform:translateY(6px);transition:var(--dur) var(--ease)}
.has-drop:hover .drop-menu,.has-drop:focus-within .drop-menu{opacity:1;visibility:visible;transform:none}
.drop-menu li a{display:block;padding:9px 12px;border-radius:var(--radius-sm);font-size:.92rem;color:var(--body-c)}
.drop-menu li a:hover{background:var(--ground-alt);color:var(--navy)}
.bar-cta{display:flex;align-items:center;gap:14px}
.bar-cta .tel{font-weight:700;color:var(--ink)}
.burger{display:none;background:none;border:none;width:40px;height:36px;position:relative;cursor:pointer}
.burger span{position:absolute;left:6px;right:6px;height:3px;background:var(--ink);border-radius:2px;
  transition:transform var(--dur) var(--ease),opacity var(--dur-fast) var(--ease),background var(--dur) var(--ease)}
.burger span:nth-child(1){top:9px}.burger span:nth-child(2){top:17px}.burger span:nth-child(3){top:25px}
/* the burger IS the close button: it folds into an X while the menu is open */
.burger[aria-expanded="true"] span:nth-child(1){transform:translateY(8px) rotate(45deg)}
.burger[aria-expanded="true"] span:nth-child(2){opacity:0;transform:scaleX(.4)}
.burger[aria-expanded="true"] span:nth-child(3){transform:translateY(-8px) rotate(-45deg)}
nav.mob{display:none}

/* With the menu open: lift the header (and so the burger/X) above the
   panel, and take the two fixed elements that were covering the menu's own
   buttons out of the way entirely. */
body.nav-open{overflow:hidden}
body.nav-open header.site{z-index:160}
/* nav.mob is a SIBLING of .bar inside <header>, so raising the header
   alone still lets the panel paint over the burger. The bar itself has to
   come up, or there is no visible way to close the menu. */
body.nav-open header.site .bar{position:relative;z-index:170}
body.nav-open header.site:not(.solid-nav) .burger span{background:var(--ink)}
body.nav-open .sticky-callbar{display:none}
body.nav-open chat-widget,body.nav-open .kb-chat-host,body.nav-open [id^="lc_text-widget"]{display:none !important}

@media (max-width:960px){
  nav.desk,.bar-cta .tel{display:none}
  .burger{display:block}
  nav.mob{position:fixed;inset:0 0 0 auto;width:min(86vw,360px);height:100vh;background:var(--surface);
    transform:translateX(100%);transition:transform var(--dur) var(--ease);z-index:150;overflow-y:auto;
    padding:96px 22px 56px;box-shadow:-10px 0 30px oklch(21% 0.03 var(--hue) / .18);
    overscroll-behavior:contain}
  nav.mob.open{transform:none;display:block}
  nav.mob .mob-h{font-family:'Space Grotesk',sans-serif;font-weight:700;color:var(--navy);text-transform:uppercase;
    font-size:.78rem;letter-spacing:.07em;margin:18px 0 8px}
  nav.mob ul{list-style:none;margin:0 0 6px;padding:0}
  nav.mob li a{display:block;padding:10px 4px;font-weight:600;color:var(--ink);border-bottom:1px solid var(--line)}
  /* the rule above is specific enough to override .btn's own display, which
     left the Call button's label stuck on the left edge (Charlie,
     2026-09-08). Give the buttons their flex centring back. */
  nav.mob li a.btn{display:inline-flex;justify-content:center;text-align:center;
    padding:13px 26px;border:2px solid var(--navy);color:var(--navy)}
  nav.mob li{margin-bottom:6px}
  /* keep the pill clear of the screen edges, and its contents clear of the
     pill's own edge (Charlie, 2026-09-08) */
  header.site{padding:10px 12px}
  header.site .bar{padding:10px 14px;gap:10px}
  header.site .brand img{height:56px}
  header.site.scrolled .brand img{height:42px}
  /* Push the quote button and the burger to the right edge, so the burger
     is right-justified rather than packed in beside the logo (Charlie,
     2026-09-08). */
  .bar-cta{margin-left:auto}
  .burger{margin-left:2px;flex:none}
  body{padding-bottom:var(--callbar-h)}
}

/* page hero (service/area/interior pages) */
.page-hero{position:relative;min-height:56vh;display:flex;align-items:flex-end;padding:0;overflow:clip;color:#fff}
.page-hero.home-hero{min-height:0;max-height:640px;height:82vh}
.page-hero .hero-bg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0}
/* Atmospheric scrim: a vignette plus a directional gradient rather than a
   flat wash, so the hero reads as depth instead of a dimmed photo. Three
   stacked layers: a soft radial glow behind the copy, a corner vignette,
   and the vertical gradient that carries text contrast. */
.page-hero .hero-scrim{position:absolute;inset:0;z-index:1;
  background:
    radial-gradient(120% 90% at 22% 42%, oklch(45% 0.10 var(--hue) / .30) 0%, transparent 58%),
    radial-gradient(130% 110% at 50% 50%, transparent 42%, oklch(14% 0.05 var(--hue) / .62) 100%),
    linear-gradient(180deg, oklch(18% 0.05 var(--hue) / .52) 0%, oklch(16% 0.05 var(--hue) / .58) 45%, oklch(14% 0.05 var(--hue) / .88) 100%)}
.page-hero .hero-copy{position:relative;z-index:2;padding:56px 24px 52px;max-width:var(--wrap)}
.page-hero h1{color:#fff;margin-bottom:.3em}
.page-hero p{color:oklch(100% 0 0 / .92);font-size:1.15rem;max-width:640px}
.hero-cta{display:flex;gap:14px;flex-wrap:wrap;margin-top:22px}

/* Hero-featured video (currently just the homepage). The source clip is
   vertical (9:16), so it is treated differently per breakpoint rather than
   forced to act like a normal 16:9 background: on mobile, where the
   viewport is itself portrait, it fills the hero as the background in
   place of the static photo (sitting under the scrim, same layer the photo
   would occupy); on desktop it floats as a framed portrait card above the
   photo and scrim instead, since a vertical video stretched across a wide
   background would look distorted and thin. */
.hero-video-wrap{position:absolute;inset:0;z-index:0;overflow:hidden;background:var(--navy-deep)}
.hero-video-wrap iframe{position:absolute;inset:0;width:100%;height:100%;border:0;object-fit:cover}
.page-hero.has-hero-video .hero-bg{display:none}
.hero-newsbadge{position:absolute;top:18px;left:18px;z-index:3;background:oklch(100% 0 0 / .94);color:var(--navy-deep);
  font-family:'Space Grotesk',sans-serif;font-weight:700;font-size:.72rem;letter-spacing:.04em;text-transform:uppercase;
  padding:8px 14px;border-radius:999px;box-shadow:0 6px 18px oklch(21% 0.06 var(--hue) / .25)}

@media (min-width:761px){
  .page-hero.has-hero-video .hero-bg{display:block}
  .page-hero.has-hero-video .hero-video-wrap{inset:auto;top:50%;right:5%;transform:translateY(-50%);
    width:240px;height:427px;border-radius:18px;box-shadow:0 24px 60px oklch(0% 0 0 / .4);z-index:3}
  .page-hero.has-hero-video .hero-newsbadge{top:auto;left:auto;bottom:calc(50% - 213px - 40px);right:5%}
}
@media (min-width:1080px){
  .page-hero.has-hero-video .hero-video-wrap{width:280px;height:498px}
  .page-hero.has-hero-video .hero-newsbadge{bottom:calc(50% - 249px - 40px)}
}

/* ---- swipeable Shorts reel in the homepage hero ---- */
.shorts-hero{align-items:center}
.page-hero.home-hero.shorts-hero{height:auto;max-height:none;min-height:0}
.shorts-hero .hero-newsbadge{position:static;display:inline-block;margin-bottom:16px}
.shorts-hero-grid{position:relative;z-index:2;display:grid;grid-template-columns:minmax(0,1fr);gap:30px;
  padding:44px 24px 40px;align-items:center}
.shorts-hero .hero-copy{padding:0;max-width:none;min-width:0}

/* min-width:0 matters: the rail is a flex row of fixed-width slides, so
   its intrinsic width is the whole reel. Without this the grid column
   sizes to that intrinsic width, squeezing the copy column on desktop and
   pushing the whole hero past the viewport on mobile. */
.shorts-stage{position:relative;min-width:0}
.shorts-rail{list-style:none;margin:0;padding:0 0 4px;display:flex;gap:16px;overflow-x:auto;max-width:100%;
  scroll-snap-type:x mandatory;scrollbar-width:none;-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain}
.shorts-rail::-webkit-scrollbar{display:none}
.short-slide{flex:0 0 auto;scroll-snap-align:center;width:min(64vw,260px)}
.short-poster,.short-live{position:relative;display:block;width:100%;aspect-ratio:9/16;overflow:hidden;
  border-radius:var(--radius-lg);background:var(--navy-deep);box-shadow:0 18px 44px oklch(0% 0 0 / .38)}
.short-poster img{width:100%;height:100%;object-fit:cover}
.short-live iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
.short-play{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:56px;height:56px;border-radius:50%;
  background:oklch(100% 0 0 / .92);box-shadow:0 8px 24px oklch(0% 0 0 / .35);transition:transform var(--dur) var(--ease)}
.short-play::after{content:'';position:absolute;left:52%;top:50%;transform:translate(-50%,-50%);
  border-left:16px solid var(--navy-deep);border-top:10px solid transparent;border-bottom:10px solid transparent}
.short-poster:hover .short-play{transform:translate(-50%,-50%) scale(1.08)}
.short-cap{display:block;margin-top:10px;color:oklch(100% 0 0 / .9);font-size:.85rem;font-weight:600;line-height:1.35}

.shorts-nav{display:none;position:absolute;top:calc(50% - 22px);transform:translateY(-50%);z-index:4;
  width:44px;height:44px;border-radius:50%;border:none;cursor:pointer;background:oklch(100% 0 0 / .92);
  box-shadow:0 8px 22px oklch(0% 0 0 / .3);transition:transform var(--dur) var(--ease)}
.shorts-nav:hover{transform:translateY(-50%) scale(1.08)}
.shorts-nav::after{content:'';position:absolute;left:50%;top:50%;width:11px;height:11px;
  border-right:3px solid var(--navy-deep);border-bottom:3px solid var(--navy-deep);border-radius:1px}
.shorts-nav.prev::after{transform:translate(-35%,-50%) rotate(135deg)}
.shorts-nav.next::after{transform:translate(-65%,-50%) rotate(-45deg)}
.shorts-nav.prev{left:-14px}
.shorts-nav.next{right:-14px}
.shorts-nav[disabled]{opacity:.35;pointer-events:none}

.shorts-dots{display:flex;gap:8px;justify-content:center;margin-top:16px}
.short-dot{width:8px;height:8px;padding:0;border:none;border-radius:50%;cursor:pointer;
  background:oklch(100% 0 0 / .42);transition:background var(--dur) var(--ease),width var(--dur) var(--ease)}
.short-dot.on{background:var(--surface);width:22px;border-radius:999px}

@media (min-width:861px){
  .shorts-hero-grid{grid-template-columns:1.05fr .95fr;gap:52px;padding:64px 24px 60px}
  .short-slide{width:264px}
  .shorts-nav{display:block}
  .shorts-rail{padding-left:2px;padding-right:2px}
}
@media (min-width:1180px){
  .short-slide{width:290px}
}

/* solid-color hero for pages with no photo (contact, and the bare/hidden
   pages) -- without this, white heading text sits directly on the page's
   own light background and is illegible/washed out */
.page-hero.solid{background:var(--navy-deep);min-height:0;align-items:center}
.page-hero.solid .wrap{padding-top:44px;padding-bottom:44px}

/* trust bar: license/insurance/tenure/guarantee, placed directly under the
   home hero so it is seen, not buried. Structure over whitespace: a real
   bordered strip with dividers, not four floating icons in whitespace. */
.trust-bar{background:var(--surface);border-bottom:1px solid var(--line)}
.trust-grid{display:grid;grid-template-columns:repeat(4,1fr);padding:22px 0}
.trust-item{display:flex;align-items:center;gap:12px;padding:0 20px;border-left:1px solid var(--line)}
.trust-item:first-child{border-left:none;padding-left:0}
.trust-item svg{flex:none;width:26px;height:26px;color:var(--navy)}
.trust-item strong{display:block;font-family:'Space Grotesk',sans-serif;font-weight:700;font-size:.92rem;color:var(--ink)}
.trust-item span{display:block;font-size:.8rem;color:var(--muted)}
@media (max-width:860px){
  .trust-grid{grid-template-columns:repeat(2,1fr);row-gap:18px}
  .trust-item{border-left:none;padding-left:0}
  .trust-item:nth-child(2n){border-left:1px solid var(--line);padding-left:20px}
}

/* featured video */
.featured-video{background:var(--navy-deep);color:#fff}
.featured-video h2{color:#fff}
.featured-video .lede{font-size:1.1rem;color:#fff}
.video-wrap{display:grid;grid-template-columns:1fr 1fr;gap:48px;align-items:center}
.video-copy p{color:oklch(100% 0 0 / .82)}
.video-frame{display:flex;justify-content:center}
.feature-video{width:100%;max-width:360px;aspect-ratio:9/16;border-radius:var(--radius-lg);
  box-shadow:0 20px 50px oklch(0% 0 0 / .4);background:var(--navy-deep)}
/* The KPRC segment as uploaded is a vertical clip, despite the 959x606
   embed code YouTube hands out. In a 16:9 frame it played as a narrow strip
   between two wide black bars, so the frame is portrait and capped in
   height, centred in its column. */
.yt-16x9{position:relative;width:100%;max-width:340px;margin:0 auto;aspect-ratio:9/16;max-height:600px;
  border-radius:var(--radius-lg);overflow:hidden;
  box-shadow:0 20px 50px oklch(0% 0 0 / .4);background:var(--navy-deep)}
.yt-16x9 iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
@media (max-width:860px){.video-wrap{grid-template-columns:1fr}.video-frame{order:-1}}

/* services grid: fixed 3-column so all six read as one scannable grid, not
   an alternating scroll and not a wrap that varies by width */
.svc-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:22px}
@media (max-width:960px){.svc-grid{grid-template-columns:repeat(2,1fr)}}
@media (max-width:620px){.svc-grid{grid-template-columns:1fr}}
.svc-card{position:relative;display:block;background:var(--surface);border:1px solid var(--line);
  border-radius:var(--radius-lg);overflow:clip;transition:transform var(--dur) var(--ease),box-shadow var(--dur) var(--ease);
  color:inherit}
.svc-card:hover{transform:translateY(-3px);box-shadow:var(--shadow);border-color:oklch(83% 0.014 var(--hue) / 0)}
/* a taller crop box so people and equipment in the photo are not sliced
   through by a short letterbox (Charlie, 2026-09-08: subjects should
   never be cut off) */
.svc-card img{height:210px;object-fit:cover;object-position:center;width:100%}
.svc-card-body{padding:18px 20px 20px}
.svc-card-body h3{margin-bottom:.35em}
.svc-card-body p{font-size:.92rem;margin-bottom:.7em}
.svc-fact{display:flex;align-items:center;gap:7px;font-size:.82rem;font-weight:700;color:var(--navy);margin-bottom:.6em}
.svc-fact::before{content:'';width:6px;height:6px;border-radius:50%;background:var(--gold);flex:none}
.svc-link{color:var(--navy);font-weight:700;font-size:.88rem}
.svc-card .svc-link::after{content:'';position:absolute;inset:0}

/* specialty services chip row under the six core cards. Pill links, not
   cards, so the grid above stays the thing the eye lands on while every
   service page still earns an internal link from the homepage. */
.svc-more{margin-top:26px;display:flex;flex-wrap:wrap;align-items:center;gap:10px 14px}
.svc-more-lead{font-size:.88rem;font-weight:700;color:var(--muted);margin:0}
.svc-chips{list-style:none;display:flex;flex-wrap:wrap;gap:10px;margin:0;padding:0}
.svc-chips a{display:inline-block;padding:9px 16px;border-radius:999px;background:var(--surface);
  border:1px solid var(--line);font-size:.86rem;font-weight:600;color:var(--navy);
  transition:transform var(--dur-fast) var(--ease),border-color var(--dur-fast) var(--ease),
    box-shadow var(--dur-fast) var(--ease)}
.svc-chips a:hover{transform:translateY(-2px);border-color:var(--gold);box-shadow:var(--shadow)}
.svc-chips a:active{transform:translateY(0)}
@media (max-width:620px){.svc-more{flex-direction:column;align-items:flex-start;gap:12px}}

/* service areas hub: one card per city, linking to that city's page. Same
   lift-on-hover language as the service cards, without a photo, so the hub
   reads as a directory rather than competing with the service grid. */
.hub{background:var(--ground-alt)}
.hub-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:20px}
@media (max-width:960px){.hub-grid{grid-template-columns:repeat(2,1fr)}}
@media (max-width:560px){.hub-grid{grid-template-columns:1fr}}
.hub-card{display:flex;flex-direction:column;gap:6px;padding:22px 22px 20px;background:var(--surface);
  border:1px solid var(--line);border-radius:var(--radius-lg);color:inherit;
  transition:transform var(--dur) var(--ease),box-shadow var(--dur) var(--ease),border-color var(--dur) var(--ease)}
.hub-card:hover{transform:translateY(-3px);box-shadow:var(--shadow);border-color:var(--gold)}
.hub-card:active{transform:translateY(-1px) scale(.995);transition-duration:var(--dur-fast)}
.hub-hook{font-size:.74rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--gold-ink)}
.hub-card h3{margin:0;font-size:1.18rem}
.hub-card p{font-size:.9rem;color:var(--body-c);margin:0 0 6px}
.hub-go{margin-top:auto;font-weight:700;font-size:.86rem;color:var(--navy);
  transition:letter-spacing var(--dur-fast) var(--ease)}
.hub-card:hover .hub-go{letter-spacing:.01em}

/* pre-purchase reading, linked from every service page */
.res-strip{background:var(--ground-alt);border-top:1px solid var(--line);border-bottom:1px solid var(--line);padding:0}
.res-strip-inner{display:flex;flex-wrap:wrap;align-items:center;gap:10px 22px;padding:18px 24px}
.res-strip-label{font-size:.76rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  color:var(--muted);margin:0}
.res-strip-links{list-style:none;display:flex;flex-wrap:wrap;gap:8px 26px;margin:0;padding:0}
.res-strip-links a{font-size:.92rem;font-weight:600;color:var(--navy);
  border-bottom:1px solid transparent;transition:border-color var(--dur-fast) var(--ease)}
.res-strip-links a:hover{border-bottom-color:var(--gold)}
.areas-bar-all{font-weight:700}
@media (max-width:620px){.res-strip-inner{flex-direction:column;align-items:flex-start;gap:10px}}

/* social icons. Facebook and Instagram only, and Instagram only renders once
   data.INSTAGRAM is set, so no dead icon ever ships. */
.f-social{list-style:none;display:flex;gap:10px;margin:14px 0 0;padding:0}
.f-social a{display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;
  border-radius:50%;border:1px solid var(--line-on-dark);color:oklch(100% 0 0 / .86);
  transition:transform var(--dur-fast) var(--ease),background var(--dur-fast) var(--ease),
    border-color var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease)}
.f-social svg{width:19px;height:19px}
.f-social a:hover{transform:translateY(-2px);background:oklch(100% 0 0 / .12);
  border-color:var(--gold);color:#fff}
.f-social a:active{transform:translateY(0)}
/* on the light contact card the dark-on-light treatment applies instead */
.formcard .f-social a{border-color:var(--line);color:var(--navy)}
.formcard .f-social a:hover{background:var(--tint);border-color:var(--gold);color:var(--navy-dark)}

/* how it works */
.how{background:var(--ground-alt)}
.hiw-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:32px;margin-top:12px}
.hiw-num{display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;border-radius:var(--radius);
  background:var(--navy);color:#fff;font-weight:700;font-family:'Space Grotesk',sans-serif;font-size:1.1rem;margin-bottom:14px}

/* before/after: fixed 2-column grid (Charlie, 2026-09-08: with 4 cards,
   auto-fit at this minmax was rendering 3+1 and leaving a gap; 2 columns
   fills the section as a clean 2x2). */
.ba-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:26px;margin-top:12px}
@media (max-width:620px){.ba-grid{grid-template-columns:1fr}}
.ba-card h3{text-align:center;margin-top:.6em}
.ba-imgs{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.ba-imgs figure{margin:0;position:relative}
.ba-imgs img{border-radius:var(--radius-sm);width:100%;height:220px;object-fit:cover}
.ba-imgs figcaption{position:absolute;left:10px;bottom:10px;background:oklch(21% 0.06 var(--hue) / .85);color:#fff;
  font-size:.72rem;font-family:'Space Grotesk',sans-serif;font-weight:700;text-transform:uppercase;letter-spacing:.05em;
  padding:4px 10px;border-radius:var(--radius-sm)}

/* testimonials */
.testimonials{background:var(--navy-deep);color:#fff}
.testimonials h2{color:#fff;text-align:center}
.t-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:20px;margin-top:28px}
.t-card{background:oklch(100% 0 0 / .06);border:1px solid var(--line-on-dark);border-radius:var(--radius-lg);
  padding:22px;margin:0;color:oklch(100% 0 0 / .92);border-top:3px solid var(--gold)}
.t-card p{margin-bottom:14px;font-size:.98rem}
.t-card footer{font-size:.85rem;color:oklch(100% 0 0 / .68)}
.t-src{opacity:.75}

/* faq */
.faq-list{margin-top:20px}
.faq-item{border-bottom:1px solid var(--line);padding:16px 0}
.faq-item summary{cursor:pointer;font-weight:700;font-family:'Space Grotesk',sans-serif;color:var(--ink);
  display:flex;justify-content:space-between;align-items:center;list-style:none;gap:16px}
.faq-item summary::-webkit-details-marker{display:none}
.faq-ic{width:20px;height:20px;position:relative;flex:none}
.faq-ic::before,.faq-ic::after{content:'';position:absolute;background:var(--navy);top:50%;left:50%;transform:translate(-50%,-50%)}
.faq-ic::before{width:14px;height:2px}
.faq-ic::after{width:2px;height:14px;transition:transform var(--dur) var(--ease)}
.faq-item[open] .faq-ic::after{transform:translate(-50%,-50%) scaleY(0)}
.faq-item p{margin-top:10px}

/* area / map */
.two-col{display:grid;grid-template-columns:1fr 1fr;gap:40px;align-items:center}
@media (max-width:860px){.two-col{grid-template-columns:1fr}}
.area-list{list-style:none;padding:0;margin:16px 0 0;display:grid;grid-template-columns:1fr 1fr;gap:8px}
.area-list a{font-weight:600}
.map-frame iframe{width:100%;height:380px;border:0;border-radius:var(--radius-lg)}
/* Contact page: the map column matches the form's height instead of
   floating short and centred beside it (Charlie, 2026-09-08). The form's
   height comes from its own fixed-height GHL iframe, so stretching the row
   and letting the map fill its cell is what lines the two up. */
.contact-body .two-col{align-items:stretch}
.contact-body .map-frame{display:flex}
.contact-body .map-frame iframe{height:100%;min-height:420px;border-radius:var(--radius-lg)}
@media (max-width:860px){.contact-body .map-frame iframe{min-height:340px}}

/* reviews embed -- per BUILD-SOP Review Widget Spec: full width, min-height
   600/500, negative top margin to pull the widget's own internal header
   whitespace up, no overflow:hidden, never cropped */
.reviews-embed{background:var(--ground-alt);padding-bottom:40px}
.reviews-embed h2{text-align:center}
/* The widget Charlie restyled on 2026-09-08 renders a compact review row
   about 340px tall. The old 600px floor (and the negative top margin that
   pulled a taller widget up) left roughly 270px of dead space under it on
   every page. Floor lowered to fit the widget it actually holds; overflow
   stays visible so the widget is never cropped. */
.reviews-embed-frame{width:100%;min-height:380px;overflow:visible}
.reviews-embed-frame iframe{width:100%;min-height:380px;display:block}
@media (max-width:760px){
  .reviews-embed-frame{min-height:340px}
  .reviews-embed-frame iframe{min-height:340px}
}

/* CTA band */
.cta-band{background:linear-gradient(135deg,var(--navy),var(--navy-dark));color:#fff;text-align:center}
.cta-band h2{color:#fff}
.cta-band p{color:oklch(100% 0 0 / .85)}

/* gallery */
.thumb-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:12px;margin-top:20px}
.thumb-grid img{border-radius:var(--radius-sm);height:180px;width:100%;object-fit:cover;
  transition:transform var(--dur) var(--ease)}
.thumb-grid a:hover img{transform:scale(1.03)}
.shorts-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:16px;margin-top:20px}
.short-embed{position:relative;aspect-ratio:9/16;border-radius:var(--radius);overflow:clip;background:var(--navy-deep)}
.short-embed iframe{width:100%;height:100%;border:0}
/* poster facade: a button, not an iframe, until it is clicked */
.short-embed .short-poster{position:absolute;inset:0;width:100%;height:100%;padding:0;border:0;
  background:var(--navy-deep);cursor:pointer;display:block;box-shadow:none}
.short-embed .short-poster img{width:100%;height:100%;object-fit:cover}

/* contact / forms */
.contact-body{padding-top:0}
.formcard{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-lg);padding:28px;
  box-shadow:0 4px 16px oklch(21% 0.03 var(--hue) / .06)}
/* live GHL form embeds: the iframe is given an explicit pixel height (from
   its own data-height) by the generator, so it never collapses to zero or
   scrolls inside itself. The wrapper just owns the width and radius. */
.form-frame{width:100%;margin:16px 0;border-radius:var(--radius);overflow:hidden}
.form-frame iframe{display:block;width:100%;height:100%;border:none}
/* homepage contact: quote form and map side by side in one section */
.home-contact{background:var(--ground-alt)}
.contact-head{max-width:var(--wrap-narrow);margin-bottom:26px}
.contact-split{display:grid;grid-template-columns:1fr 1fr;gap:28px;align-items:start}
.contact-split .form-frame{margin:0;background:var(--surface);box-shadow:var(--shadow)}
.contact-split .map-frame{height:100%;min-height:420px;border-radius:var(--radius);overflow:hidden;
  box-shadow:var(--shadow)}
.contact-split .map-frame iframe{width:100%;height:100%;min-height:420px;border:0;display:block}
@media (max-width:860px){
  .contact-split{grid-template-columns:1fr}
  .contact-split .map-frame,.contact-split .map-frame iframe{min-height:320px}
}

/* service locations: a thin bar, not a full block */
.areas-bar{background:var(--navy-deep);color:oklch(100% 0 0 / .9);padding:18px 0}
.areas-bar-inner{display:flex;align-items:center;gap:18px;flex-wrap:wrap}
.areas-bar-label{font-family:'Space Grotesk',sans-serif;font-weight:700;font-size:.72rem;letter-spacing:.09em;
  text-transform:uppercase;color:var(--gold);flex:none}
.areas-bar-links{display:flex;gap:6px;flex-wrap:wrap}
.areas-bar-links a{color:oklch(100% 0 0 / .86);font-size:.92rem;font-weight:600;padding:6px 12px;
  border-radius:var(--radius-pill);border:1px solid var(--line-on-dark);
  transition:background var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease),
  border-color var(--dur-fast) var(--ease)}
.areas-bar-links a:hover{background:oklch(100% 0 0 / .12);color:#fff;border-color:oklch(100% 0 0 / .34)}
.form-placeholder{border:2px dashed var(--gold);background:oklch(98% 0.03 90);border-radius:var(--radius);padding:20px;margin:16px 0}
.form-placeholder p{margin:0 0 8px}
.form-placeholder p:last-child{margin-bottom:0}
.ph-alt{color:var(--muted);font-size:.92rem}
.f-contact{margin:14px 0 6px}
.hours{margin:10px 0 0}
.hr{display:flex;justify-content:space-between;gap:12px;padding:4px 0;border-bottom:1px dashed var(--line);font-size:.92rem}
.hr:last-child{border-bottom:none}

/* svc body / area body */
.svc-body{padding-top:56px}
/* Body photos are mostly phone shots in portrait. Contain (not cover) so
   nothing in frame is ever sliced off, centred with a sensible max width so
   a tall photo reads as a framed picture rather than a letterboxed strip. */
.inline-img{border-radius:var(--radius-lg);margin:22px auto;display:block;height:auto;
  max-height:560px;width:auto;max-width:100%;object-fit:contain}
.check-list{list-style:none;padding:0;margin:0 0 1.4em;display:grid;gap:10px}
.check-list li{padding-left:30px;position:relative}
.check-list li::before{content:'';position:absolute;left:0;top:.45em;width:8px;height:8px;border-radius:50%;
  background:var(--navy)}
.check-list.gold li::before{background:var(--gold)}

/* footer */
footer.site{background:var(--navy-deep);color:oklch(100% 0 0 / .85);padding:60px 0 24px}
footer.site .holder{max-width:var(--wrap);margin:0 auto;padding:0 24px}
footer.site h4{color:#fff;font-family:'Space Grotesk',sans-serif;font-size:.9rem;text-transform:uppercase;letter-spacing:.05em}
footer.site a.btn{color:#fff}
footer.site a:not(.btn){color:oklch(100% 0 0 / .8)}
footer.site a:not(.btn):hover{color:#fff}
.f-top{display:grid;grid-template-columns:1.3fr 1fr;gap:40px;padding-bottom:36px;border-bottom:1px solid var(--line-on-dark)}
.f-brand img{height:96px;width:auto;margin-bottom:14px}
.f-brand p{max-width:360px;color:oklch(100% 0 0 / .72)}
.f-why{margin-top:26px}
.f-badges{list-style:none;margin:10px 0 0;padding:0;display:flex;flex-wrap:wrap;gap:8px}
.f-badges li{font-size:.82rem;font-weight:600;color:oklch(100% 0 0 / .82);padding:6px 12px;
  border:1px solid var(--line-on-dark);border-radius:var(--radius-pill)}
.f-cols{display:grid;grid-template-columns:repeat(4,1fr);gap:30px;padding:32px 0}
@media (max-width:1020px){.f-cols{grid-template-columns:repeat(2,1fr)}}
.f-cols ul{list-style:none;margin:10px 0 0;padding:0}
.f-cols li{margin-bottom:8px;font-size:.92rem}
.f-legal{font-size:.82rem;color:oklch(100% 0 0 / .55);border-top:1px solid var(--line-on-dark);padding-top:20px}
@media (max-width:760px){.f-top{grid-template-columns:1fr}.f-cols{grid-template-columns:1fr 1fr}}

/* mobile sticky call bar: highest-leverage element on a local service site.
   Two actions, tel: link always real. Hidden on desktop; body gets the
   matching padding-block-end above so nothing sits behind it. */
.sticky-callbar{display:none}
@media (max-width:760px){
  .sticky-callbar{display:grid;grid-template-columns:1fr 1fr;position:fixed;left:0;right:0;bottom:0;z-index:140;
    height:var(--callbar-h);background:var(--navy-deep);border-top:1px solid oklch(100% 0 0 / .12);
    box-shadow:0 -6px 20px oklch(0% 0 0 / .18)}
  .sticky-callbar a,.sticky-callbar button{display:flex;align-items:center;justify-content:center;gap:8px;
    font-family:'Space Grotesk',sans-serif;font-weight:700;font-size:.92rem;border:none;background:none;color:#fff;
    cursor:pointer}
  .sticky-callbar .cb-quote{background:var(--navy)}
  .sticky-callbar .cb-call{background:var(--gold);color:var(--navy-deep)}
  .sticky-callbar svg{width:18px;height:18px}
}

/* modal */
.modal-overlay{position:fixed;inset:0;background:oklch(21% 0.06 var(--hue) / .72);z-index:300;display:flex;
  align-items:center;justify-content:center;padding:20px}
.modal-overlay[hidden]{display:none}
.modal-box{background:var(--surface);border-radius:var(--radius-lg);max-width:520px;width:100%;max-height:90vh;
  overflow-y:auto;padding:32px;position:relative;box-shadow:0 30px 80px oklch(0% 0 0 / .4);margin:auto}
.modal-close{position:absolute;top:14px;right:14px;width:44px;height:44px;border:none;background:var(--ground-alt);
  border-radius:50%;font-size:1.5rem;line-height:1;color:var(--navy);cursor:pointer}
.modal-box h3{margin-bottom:16px;font-size:1.3rem}

.fine{font-size:.8rem}
.dk{color:var(--muted)}

/* bare pages (hidden: thank-you, review, get-your-discount, marketing-form) */
main.bare{min-height:100vh;display:flex;flex-direction:column;align-items:center;padding:40px 24px 64px;background:var(--ground-alt)}
.bare-logo{display:block;margin:0 auto 36px}
.bare-logo img{height:88px;width:auto}
main.bare .page-hero{width:100%;border-radius:var(--radius-lg);min-height:0;align-items:center;text-align:center}
main.bare .page-hero .hero-copy{max-width:var(--wrap-narrow);margin:0 auto;padding:52px 24px}
main.bare .page-hero .hero-cta{justify-content:center}
main.bare section.rv{width:100%;max-width:var(--wrap-narrow)}

/* Chat widget vs sticky call bar: on mobile the call bar owns the bottom
   64px, so the chat launcher must sit above it, never on top of the "Call
   Now" button. This covers widget builds that keep the launcher in the
   light DOM; main.js injects the same offset into the shadow root for the
   builds that don't. */
@media (max-width:960px){
  chat-widget,.kb-chat-host,#lc_text-widget,[id^="lc_text-widget"]{
    position:relative;z-index:120;bottom:calc(var(--callbar-h) + 6px)}
  chat-widget .lc_text-widget--btn,.kb-chat-host [class*="widget--btn"],
  [id^="lc_text-widget"] [class*="btn"]{bottom:calc(var(--callbar-h) + 14px) !important}
}

/* Reduced motion: keep every hover/press state legible (colour, shadow,
   outline all still change) but stop anything that moves or scales, and
   stop the cursor-following highlight. Placed last so it wins. */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{transition-duration:.01ms !important;animation-duration:.01ms !important;
    animation-iteration-count:1 !important;scroll-behavior:auto !important}
  .btn:hover,.btn:active,.svc-card:hover,.svc-card:active,.t-card:hover,.trust-item:hover,
  .hiw-step:hover .hiw-num,.short-dot:active,.shorts-nav:active,.shorts-nav:hover,
  .short-poster:hover .short-play,.sticky-callbar a:active,.sticky-callbar button:active{transform:none}
  .svc-card:hover img,.ba-card:hover img{transform:none}
  .svc-card::before{display:none}
  .shorts-rail{scroll-snap-type:none}
}

/* Video hero on interior pages (2026-10-09, Charlie). The framed video card (427 to 498 px tall)
   was taller than a 56vh hero, so on interior pages it touched the top and bottom edges with no
   padding, and the title ran under it on narrower screens. Give the hero room for the card plus
   breathing space, center the card in the space below the header (same look as the homepage),
   and keep the text clear of the card. */
@media (min-width:761px){
  .page-hero.has-hero-video{min-height:calc(427px + var(--header-h) + 96px)}
  .page-hero.has-hero-video .hero-video-wrap{top:calc(50% + var(--header-h) / 2)}
  .page-hero.has-hero-video .hero-newsbadge{bottom:calc(50% - var(--header-h) / 2 - 213px - 40px)}
  .page-hero.has-hero-video .hero-copy{padding-right:calc(240px + 5% + 40px)}
}
@media (min-width:1080px){
  .page-hero.has-hero-video{min-height:calc(498px + var(--header-h) + 96px)}
  .page-hero.has-hero-video .hero-newsbadge{bottom:calc(50% - var(--header-h) / 2 - 249px - 40px)}
  .page-hero.has-hero-video .hero-copy{padding-right:calc(280px + 5% + 40px)}
}

/* Video hero on phones (2026-10-09, Charlie): follow the homepage layout. The video was a full-bleed
   background behind the text. Now the photo is the backdrop, the news badge, headline, text and
   buttons come first, and the video sits below as a framed card with padding around it. */
@media (max-width:760px){
  .page-hero.has-hero-video{flex-direction:column;align-items:stretch;justify-content:flex-start;min-height:0;padding-bottom:44px}
  .page-hero.has-hero-video .hero-bg{display:block}
  .page-hero.has-hero-video .hero-newsbadge{position:static;order:0;align-self:flex-start;margin:36px 24px 16px}
  .page-hero.has-hero-video .hero-copy{order:1;padding:0 24px 30px;max-width:none}
  .page-hero.has-hero-video .hero-video-wrap{position:relative;inset:auto;order:2;z-index:2;width:min(280px,calc(100% - 48px));
    height:auto;aspect-ratio:9/16;margin:0 auto;border-radius:18px;box-shadow:0 24px 60px oklch(0% 0 0 / .4)}
}

/* Video hero on phones, photo (2026-10-09, Charlie): the photo behind the text hid the subjects behind the
   headline, buttons and video card on a tall phone screen. Show it as a full width band at the top instead
   (photo first, then badge, headline, text, buttons, then the video card), so everyone is in frame. */
@media (max-width:760px){
  .page-hero.has-hero-video{background:var(--navy-deep)}
  .page-hero.has-hero-video picture{order:-1;display:block;width:100%}
  .page-hero.has-hero-video .hero-bg{position:relative;inset:auto;display:block;width:100%;height:auto;aspect-ratio:4/3;object-position:center 40%}
  .page-hero.has-hero-video .hero-scrim{display:none}
  .page-hero.has-hero-video .hero-newsbadge{margin-top:26px}
}
