/* ==========================================================================
   LAYOUT CONTRACT — read before adding a rule to this file

   Media queries add no specificity, so at equal specificity the LATER
   declaration in source order wins regardless of whether it's inside a
   media query. That means a base (non-media) rule placed below a media
   query silently beats it. This file enforces one invariant to make that
   impossible: every base rule lives above the "RESPONSIVE OVERRIDES"
   banner near the end of the file; every @media block lives below it.
   tests/test_css_order.py fails the build if this is violated.

   Breakpoint ladder (desktop-first, max-width, descending):
     920   layout grids collapse (services, hero, footer, pricing, ...)
     860   nav -> hamburger — ALSO hardcoded in static/js/main.js (the
           mobileQuery matchMedia call). Keep both in sync if this changes.
     768   rescue strip stacks
     640   phone tier — the bulk of the mobile overrides
   Plus one min-width:641px block (.sector-groups-grid) — kept as
   min-width deliberately; see its own comment for why not to "simplify"
   it to the max-width inverse.

   A repeated idiom you'll see below and should not "deduplicate": a
   shared rule across a group of selectors (e.g. ".contact-primary,
   .cta-panel") followed by a second, later rule for just one of those
   selectors, adding a property the group rule can't carry alone. That's
   two rules by design, not an accidental duplicate.
   ========================================================================== */

/* ---------- Self-hosted fonts ---------- */
/*
   Generated from the Google Fonts CSS the site used to link to, then vendored
   into static/fonts/. Removes two cross-origin connections from the critical
   path (googleapis + gstatic), removes a third-party data transfer, and lets
   the CSP drop both fonts.g*.com entries.

   Inter and Syne are variable fonts — one file covers the whole weight range,
   which is why several weights share a filename. unicode-range keeps the
   latin-ext files from ever downloading unless the page actually renders a
   character from that range.

   Regenerate: see README, "Fonts".
*/

@font-face{
  font-family:'IBM Plex Mono';
  font-style:normal;
  font-weight:500;
  font-display:swap;
  src:url('../fonts/ibm-plex-mono-latin-ext-93cfae.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face{
  font-family:'IBM Plex Mono';
  font-style:normal;
  font-weight:500;
  font-display:swap;
  src:url('../fonts/ibm-plex-mono-latin-0bc96c.woff2') format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face{
  font-family:'IBM Plex Mono';
  font-style:normal;
  font-weight:600;
  font-display:swap;
  src:url('../fonts/ibm-plex-mono-latin-ext-a73533.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face{
  font-family:'IBM Plex Mono';
  font-style:normal;
  font-weight:600;
  font-display:swap;
  src:url('../fonts/ibm-plex-mono-latin-1b581b.woff2') format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face{
  font-family:'Inter';
  font-style:normal;
  font-weight:400 600;
  font-display:swap;
  src:url('../fonts/inter-latin-ext-b6db4a.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face{
  font-family:'Inter';
  font-style:normal;
  font-weight:400 600;
  font-display:swap;
  src:url('../fonts/inter-latin-6ab57b.woff2') format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face{
  font-family:'Syne';
  font-style:normal;
  font-weight:600 700;
  font-display:swap;
  src:url('../fonts/syne-latin-ext-4f40e3.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face{
  font-family:'Syne';
  font-style:normal;
  font-weight:600 700;
  font-display:swap;
  src:url('../fonts/syne-latin-c0b667.woff2') format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root{
  --ink:#15171C;
  --ink-soft:#1E212A;
  --paper:#F5F4F0;
  --paper-dim:#EAE8E1;
  --muted:#666A72;
  --border:#DDDBD3;
  --border-dark:#2B2E38;
  --focus:#2FA36A;
  --focus-dim:rgba(47,163,106,.14);
  /* --focus at 12–14px on --paper measures 2.9:1, below the 4.5:1 WCAG AA
     threshold. This darker green measures ~4.8:1 and is near-indistinguishable
     at small sizes. Use it for green TEXT on light backgrounds; keep --focus
     for borders, fills, the focus ring, and text on --ink (5.6:1, passes).
     In dark mode the two tokens swap roles — see the dark-mode block below. */
  --focus-text:#1B7A4E;
  --radius:3px;
  --max:1180px;
  --serif: "Syne", sans-serif;
  --body: "Inter", sans-serif;
  --mono: "IBM Plex Mono", monospace;

  --surface:#fff;
  --error:#B3492F;
  /* Constant — never redefined in dark mode. A handful of panels (skip-link,
     pricing, footer, estimate-panel) are intentionally always-dark accent
     surfaces, independent of the page theme; they use this instead of --ink
     so they don't invert to a light background when --ink flips in dark mode. */
  --ink-fixed:#15171C;
  --nav-bg:rgba(245,244,240,.82);
  --nav-bg-scrolled:rgba(245,244,240,.94);
  --hero-tint:rgba(245,244,240,.45);
  --grid-line:rgba(21,23,28,.08);
}

/* ---------- Dark mode ---------- */
:root[data-theme="dark"]{
  --ink:#F2F1ED;
  --paper:#14161B;
  --paper-dim:#1B1E24;
  --muted:#A0A3AC;
  --border:rgba(255,255,255,.12);
  --surface:#1E212A;
  --error:#E2694F;
  --nav-bg:rgba(20,22,27,.72);
  --nav-bg-scrolled:rgba(20,22,27,.88);
  --hero-tint:rgba(20,22,27,.45);
  --grid-line:rgba(255,255,255,.06);
  /* The light-mode --focus-text (#1B7A4E) measures 3.0–3.4:1 on dark --paper/
     --surface — below the 4.5:1 text threshold. --focus (#2FA36A) measures
     5.66:1 on dark --paper, so the two tokens swap roles here. */
  --focus-text:#2FA36A;
}

*{box-sizing:border-box;margin:0;padding:0;}
/* Placed early so any later, more specific selector's own `transition`
   declaration (buttons, nav blur, etc.) simply overrides this default —
   this only fills in smooth theme-swap animation for elements that don't
   already declare their own transition timing. */
*{transition:background-color .3s ease, border-color .3s ease, color .3s ease, fill .3s ease, stroke .3s ease;}
html{scroll-behavior:smooth;overflow-x:clip;}
html.reduced-motion{scroll-behavior:auto;}
body{
  background:var(--paper);
  color:var(--ink);
  font-family:var(--body);
  font-size:16px;
  line-height:1.55;
  -webkit-font-smoothing:antialiased;
  overflow-x:clip;
}
img,svg{display:block;max-width:100%;}
a{color:inherit;text-decoration:none;}
ul{list-style:none;}
button{font:inherit;cursor:pointer;background:none;border:none;color:inherit;}

/* --focus-text rather than --focus: focus indicators are UI components, which
   WCAG 1.4.11 holds to 3:1. --focus is 2.9:1 on --paper (fails); --focus-text
   is 4.8:1 on paper and 3.4:1 on --ink, so one token passes on both. */
:focus-visible{
  outline:2px solid var(--focus-text);
  outline-offset:3px;
}

/* Lets keyboard and screen-reader users jump the nav. Off-screen until focused. */
.skip-link{
  position:absolute;left:-9999px;top:0;z-index:100;
  background:var(--ink-fixed);color:#F5F4F0;
  padding:12px 20px;font-size:14px;font-weight:600;
  border-radius:0 0 var(--radius) 0;
}
.skip-link:focus{left:0;}

/* Visually hidden but still reachable by screen readers — for headings that
   exist purely to give a section a name in the a11y tree. */
.sr-only{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;
}

/* Honeypot: must be invisible to people but still fillable by bots, so it
   can't use display:none or visibility:hidden — those get skipped by many. */
.hp-field{
  position:absolute;left:-9999px;width:1px;height:1px;
  overflow:hidden;
}

/* The gutter every page depends on. A class applied ALONGSIDE .wrap (such as
   .page-header) must set vertical spacing with padding-top / padding-bottom
   longhand — the `padding` shorthand would reset these left and right values
   to 0 and slam content against the viewport edge. */
.wrap{
  max-width:var(--max);
  margin:0 auto;
  padding-left:32px;
  padding-right:32px;
}

h1,h2,h3{
  font-family:var(--serif);
  font-weight:600;
  letter-spacing:-0.01em;
  line-height:1.1;
}

.eyebrow{
  font-family:var(--mono);
  font-size:12px;
  font-weight:600;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--focus-text);
}

.see-all{
  font-family:var(--mono);
  font-size:13px;
  font-weight:600;
  color:var(--ink);
  border-bottom:1px solid var(--focus);
  padding-bottom:2px;
  display:inline-block;
}
.see-all:hover{color:var(--focus-text);}
.pricing .see-all, .pricing-cta .see-all{color:#F5F4F0;}

/* ---------- Buttons ---------- */
.btn{
  display:inline-flex;
  align-items:center;
  gap:8px;
  padding:13px 24px;
  font-family:var(--body);
  font-weight:600;
  font-size:14.5px;
  border-radius:var(--radius);
  border:1px solid var(--ink);
  transition:background .2s ease, color .2s ease, border-color .2s ease, opacity .2s ease;
}
.btn-primary{background:var(--ink);color:var(--paper);}
.btn-primary:hover{background:var(--focus);border-color:var(--focus);color:var(--ink);}
.btn-primary:disabled{opacity:.35;cursor:not-allowed;}
.btn-primary:disabled:hover{background:var(--ink);border-color:var(--ink);color:var(--paper);}
.btn-ghost{background:transparent;color:var(--ink);}
.btn-ghost:hover{background:var(--ink);color:var(--paper);}
.btn-ghost.light{border-color:var(--paper-dim);color:var(--paper);}
.btn-ghost.light:hover{background:var(--paper);color:var(--ink);}
.btn-nav{padding:10px 18px;font-size:13.5px;}
.btn-large{padding:16px 30px;font-size:15.5px;}

/* ---------- Focus-frame signature element ---------- */
.frame{position:relative;}
.corner{position:absolute;width:16px;height:16px;opacity:0;transition:opacity .35s ease, transform .35s ease;}
.c-tl{top:-1px;left:-1px;border-top:2px solid var(--focus);border-left:2px solid var(--focus);transform:translate(7px,7px);}
.c-tr{top:-1px;right:-1px;border-top:2px solid var(--focus);border-right:2px solid var(--focus);transform:translate(-7px,7px);}
.c-bl{bottom:-1px;left:-1px;border-bottom:2px solid var(--focus);border-left:2px solid var(--focus);transform:translate(7px,-7px);}
.c-br{bottom:-1px;right:-1px;border-bottom:2px solid var(--focus);border-right:2px solid var(--focus);transform:translate(-7px,-7px);}
.frame.in-view .corner,
.frame.always-on .corner{opacity:1;transform:translate(0,0);}
/* Hover-reveal only where there's a real pointer. Touch browsers emulate
   :hover as a sticky state on tap, which made the corners appear on the
   tapped panel and jump to the next one on the following tap — the reveal
   on touch should come from .in-view alone. */
/* ---------- Nav ---------- */
.nav{
  position:sticky;top:0;z-index:50;
}
/* Blur/tint (and the scroll border) live on a pseudo-element rather than .nav
   itself — backdrop-filter on .nav would make it a containing block for its
   position:fixed children (the mobile dropdown), trapping that panel inside
   the header's own height instead of the full viewport. */
.nav::before{
  content:"";
  position:absolute;inset:0;
  z-index:-1;
  background:var(--nav-bg);
  backdrop-filter:blur(26px) saturate(200%);
  border-bottom:1px solid var(--grid-line);
  transition:border-color .25s ease, background-color .25s ease;
}
.nav.scrolled::before{border-bottom-color:var(--border);background:var(--nav-bg-scrolled);}
.nav-inner{
  display:flex;align-items:center;justify-content:space-between;
  min-height:64px;
}
.logo{display:flex;align-items:center;gap:10px;}
.logo-text{font-family:var(--serif);font-weight:700;font-size:26px;letter-spacing:-0.01em;line-height:1.15;}
.logo-text::after{content:".";color:var(--focus-text);}
.logo-text span{display:none;}

.nav-links{display:flex;align-items:center;gap:32px;}
.nav-links a:not(.btn){
  font-size:14.5px;font-weight:500;color:var(--ink);
  position:relative;padding:4px 0;
}
.nav-links a:not(.btn)::after{
  content:"";position:absolute;left:0;bottom:0;width:0;height:1px;background:var(--focus);
  transition:width .2s ease;
}
.nav-links a:not(.btn):hover::after{width:100%;}
.nav-links a.is-active:not(.btn){color:var(--focus-text);}
.nav-cta{display:flex;align-items:center;gap:22px;}
/* Visual icon stays 26x16, but padding + an equal negative margin push the
   actual clickable box out to 44x44 (WCAG 2.2 target size) without shifting
   the icon itself or widening the row it sits in. */
.nav-toggle{
  display:none;flex-direction:column;justify-content:center;gap:5px;
  width:44px;height:44px;padding:14px 9px;margin:-14px -9px;
}
.nav-toggle span{height:2px;background:var(--ink);width:100%;transition:transform .2s ease, opacity .2s ease;}

.theme-toggle{
  width:38px;height:38px;flex:none;border-radius:50%;
  border:1.5px solid var(--border);
  display:flex;align-items:center;justify-content:center;
  transition:border-color .2s ease, background-color .2s ease;
}
.theme-toggle:hover{border-color:var(--focus);}
.theme-toggle-icon{width:18px;height:18px;stroke:var(--ink);overflow:visible;}
.theme-toggle-icon .icon-sun,.theme-toggle-icon .icon-moon{
  transition:opacity .4s ease, transform .4s ease;
  transform-origin:12px 12px;
}
.theme-toggle-icon .icon-moon{opacity:0;transform:rotate(-90deg) scale(.5);}
:root[data-theme="dark"] .theme-toggle-icon .icon-sun{opacity:0;transform:rotate(90deg) scale(.5);}
:root[data-theme="dark"] .theme-toggle-icon .icon-moon{opacity:1;transform:rotate(0) scale(1);}
.theme-toggle--mobile{display:none;}

/* ---------- Hero ---------- */
.hero{
  position:relative;
  padding:88px 0 100px;
  overflow:hidden;
}
.hero::before{
  content:"";position:absolute;inset:0;z-index:-1;
  background-image:
    repeating-linear-gradient(0deg, var(--grid-line) 0 1px, transparent 1px 64px),
    repeating-linear-gradient(90deg, var(--grid-line) 0 1px, transparent 1px 64px);
  background-color:var(--hero-tint);
  mask-image:radial-gradient(ellipse 80% 60% at 60% 20%, black, transparent 75%);
}
.hero-grid{
  display:grid;
  grid-template-columns:1.15fr .85fr;
  gap:64px;
  align-items:center;
}
.hero h1{
  font-size:clamp(34px,4.4vw,54px);
  margin:18px 0 22px;
}
.hero p.lead{
  font-size:18px;
  color:var(--muted);
  max-width:46ch;
  margin-bottom:34px;
}
.hero-ctas{display:flex;gap:14px;flex-wrap:wrap;margin-bottom:30px;}
.trust-line{
  font-family:var(--mono);font-size:12.5px;color:var(--muted);
  display:flex;align-items:center;gap:10px;
}
.trust-line .dot{width:6px;height:6px;border-radius:50%;background:var(--focus);flex:none;}

.focus-panel--plain{
  display:flex;
}
.focus-image{
  width:100%;
  height:100%;
  min-height:320px;
  object-fit:cover;
  display:block;
}
.focus-image--square{
  aspect-ratio:1;
}

.hero-slideshow{
  position:relative;
  width:100%;
  aspect-ratio:1;
  overflow:hidden;
}
.hero-slide{
  position:absolute;
  inset:0;
  opacity:0;
  filter:blur(20px);
  animation:heroSlideCycle 18s ease-in-out infinite;
}
.hero-slide:first-child{animation-delay:0s;}
.hero-slide:nth-child(2){animation-delay:-12s;}
.hero-slide:nth-child(3){animation-delay:-6s;}
@keyframes heroSlideCycle{
  0%, 27.778%{opacity:1;filter:blur(0px);}
  33.333%, 94.444%{opacity:0;filter:blur(20px);}
  100%{opacity:1;filter:blur(0px);}
}
.hero-progress{
  position:absolute;
  left:0;
  bottom:0;
  z-index:1;
  width:0%;
  height:2px;
  background:var(--focus);
  opacity:0;
  animation:heroProgressCycle 18s linear infinite;
}
.hero-progress:nth-of-type(1){animation-delay:0s;}
.hero-progress:nth-of-type(2){animation-delay:-12s;}
.hero-progress:nth-of-type(3){animation-delay:-6s;}
@keyframes heroProgressCycle{
  0%{width:0%;opacity:1;}
  27.778%{width:100%;opacity:1;}
  33.333%{width:100%;opacity:0;}
  33.334%{width:0%;opacity:0;}
  99.9%{opacity:0;}
  100%{opacity:1;}
}
@media(prefers-reduced-motion:reduce){
  .hero-slide{animation:none;opacity:0;}
  .hero-slide:first-child{opacity:1;}
  .hero-progress{display:none;}
}

/* ---------- Page header (non-homepage) ---------- */
/* Top padding intentionally mirrors .hero's top padding (88px desktop /
   56px at the same <=640px breakpoint) so non-home pages open with the same
   gap under the nav as the homepage. */
.page-header{padding-top:88px;padding-bottom:8px;}
.page-header .eyebrow{margin-bottom:14px;display:block;}
.page-header h1{font-size:clamp(30px,4vw,44px);margin-bottom:16px;}
.page-header p{color:var(--muted);font-size:17px;max-width:56ch;}
.page-header .price-line{font-family:var(--serif);font-size:clamp(22px,2.6vw,28px);color:var(--focus-text);margin-top:20px;}

/* ---------- 404 page ---------- */
.notfound-hero{position:relative;overflow:hidden;}
.notfound-mark{
  position:absolute;z-index:-1;top:-.1em;left:-.02em;
  font-family:var(--mono);font-weight:600;
  font-size:clamp(140px,24vw,280px);line-height:1;letter-spacing:-.02em;
  color:var(--ink);opacity:.05;
  pointer-events:none;user-select:none;
}
.notfound-hero .work-note{max-width:56ch;word-break:break-all;}

/* ---------- Legal content ---------- */
.legal-content{max-width:72ch;}
.legal-content h2{font-size:clamp(19px,2.4vw,23px);margin:40px 0 12px;}
.legal-content h2:first-of-type{margin-top:0;}
.legal-content p{color:var(--muted);font-size:15.5px;line-height:1.7;margin-bottom:14px;}
.legal-content ul{margin:0 0 14px;padding-left:22px;}
.legal-content li{color:var(--muted);font-size:15.5px;line-height:1.7;margin-bottom:8px;}
.legal-content a{color:inherit;text-decoration:underline;text-underline-offset:2px;}

/* ---------- Section basics ---------- */
section{padding:64px 0;}
.section-head{max-width:640px;margin-bottom:52px;}
.section-head h2{font-size:clamp(26px,3vw,34px);margin-top:14px;}
.section-head p{color:var(--muted);font-size:16.5px;margin-top:14px;}
.section-head-row{
  display:flex;justify-content:space-between;align-items:flex-end;
  gap:24px;flex-wrap:wrap;margin-bottom:52px;
}
.section-head-row .section-head{margin-bottom:0;}

.reveal{opacity:0;transform:translateY(16px);transition:opacity .55s ease, transform .55s ease;}
.reveal.reveal-in{opacity:1;transform:translateY(0);}

/* ---------- Services ---------- */
.services-grid{
  display:grid;grid-template-columns:repeat(4,1fr);gap:24px;
}
.service-card{
  background:var(--paper);
  border:1px solid var(--border);
  padding:34px 26px;
  position:relative;
}
.service-card .icon{
  width:34px;height:34px;margin-bottom:22px;
  border:1.5px solid var(--ink);border-radius:50%;
  display:flex;align-items:center;justify-content:center;
}
.service-card .icon svg{width:16px;height:16px;stroke:var(--ink);}
.service-card h3{font-size:18px;margin-bottom:10px;}
.service-card p{font-size:14.5px;color:var(--muted);}
.service-card .see-all{font-size:12.5px;margin-top:16px;}

/* ---------- Rescue Strip ---------- */
.rescue-strip{
  background:var(--paper-dim);
  border-top:1px solid var(--border);
  border-bottom:1px solid var(--border);
  padding:16px 0;
}
.rescue-strip-inner{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:20px;
  text-decoration:none;
  color:var(--ink);
  font-size:14.5px;
  padding:4px 0;
  border-radius:var(--radius);
  transition:color .2s ease;
}
.rescue-strip-inner:focus-visible{
  outline:2px solid var(--focus);
  outline-offset:4px;
}
.rescue-strip-lead{
  display:flex;
  align-items:center;
  gap:10px;
  color:var(--muted);
  font-family:var(--body);
}
.rescue-strip-lead .dot{
  width:7px;
  height:7px;
  border-radius:50%;
  background:var(--focus);
  flex:none;
}
.rescue-strip-action{
  display:inline-flex;
  align-items:center;
  flex-wrap:wrap;
  max-width:100%;
  gap:8px;
  font-family:var(--body);
}
.rescue-strip-action strong{
  color:var(--ink);
  font-weight:600;
}
.rescue-strip-action .arrow{
  font-family:var(--mono);
  color:var(--focus-text);
  transition:transform .2s ease;
}
.rescue-strip-inner:hover .rescue-strip-lead{
  color:var(--ink);
}
.rescue-strip-inner:hover .rescue-strip-action strong{
  color:var(--focus-text);
}
.rescue-strip-inner:hover .arrow{
  transform:translateX(4px);
}

/* ---------- Work ---------- */
.work-grid{
  display:grid;grid-template-columns:repeat(2,1fr);gap:24px;
}
.work-card{
  background:var(--paper);
  border:1px solid var(--border);
  padding:30px 26px;
  display:flex;flex-direction:column;gap:14px;
}
.work-card .tag{font-family:var(--mono);font-size:11px;letter-spacing:.1em;color:var(--focus-text);text-transform:uppercase;}
.work-card h3{font-size:19px;}
.work-image{
  width:100%;
  border-radius:2px;
  overflow:hidden;
  border:1px solid var(--border);
}
.work-image img{
  width:100%;
  height:auto;
  display:block;
}
.work-card p{font-size:14.5px;color:var(--muted);flex-grow:1;}
.work-result{
  font-family:var(--mono);font-size:13px;color:var(--focus-text);font-weight:600;
  border-top:1px solid var(--border);padding-top:14px;margin-top:4px;
}
.work-quote{
  font-family:var(--serif);font-size:14.5px;font-style:italic;color:var(--ink);
  border-left:2px solid var(--focus);padding-left:14px;
}
.work-quote cite{
  display:block;font-family:var(--mono);font-style:normal;font-size:11.5px;
  color:var(--muted);margin-top:8px;
}
.work-card .btn{align-self:flex-start;margin-top:4px;}
.work-note{
  font-family:var(--mono);font-size:12.5px;color:var(--error);
  border:1px dashed var(--error);padding:12px 16px;margin-top:28px;
  border-radius:var(--radius);
}

/* ---------- Process ---------- */
.process-list{
  display:grid;grid-template-columns:repeat(3,1fr);gap:40px;
}
.process-step .num{
  font-family:var(--mono);font-size:13px;color:var(--focus-text);font-weight:600;
  margin-bottom:16px;display:block;
}
.process-step h3{font-size:19px;margin-bottom:10px;}
.process-step p{font-size:15px;color:var(--muted);}

/* ---------- Sectors ---------- */
.sectors{background:var(--paper-dim);}
.sectors-grid{
  display:grid;grid-template-columns:repeat(3,1fr);gap:24px;
}
.sector-card{
  background:var(--paper);
  border:1px solid var(--border);
  padding:30px 26px;
  display:flex;flex-direction:column;gap:14px;
}
.sector-card .tag{font-family:var(--mono);font-size:11px;letter-spacing:.1em;color:var(--focus-text);text-transform:uppercase;}
.sector-card h3{font-size:18px;}
.sector-card p{font-size:14.5px;color:var(--muted);flex-grow:1;}
.sector-card .see-all{font-size:12.5px;}

/* ---------- Sector marquee (homepage) ---------- */
/* Three rows of trade names, each a real <a>, looping via CSS transform —
   not canvas or decorative text, so it stays usable for keyboard, screen
   reader and crawler traffic. Each row renders its track twice; the
   aria-hidden copy exists purely so the loop has something to scroll into
   once the first copy scrolls out, and is pulled out of tab order below so
   keyboard users don't land on invisible duplicate links. */
.sector-marquee{
  --gap:26px;
  display:flex;flex-direction:column;gap:6px;
  overflow:hidden;
  mask-image:linear-gradient(to right, transparent, black 8%, black 92%, transparent);
  -webkit-mask-image:linear-gradient(to right, transparent, black 8%, black 92%, transparent);
}
.marquee-row{display:flex;width:max-content;}
.marquee-track{
  display:flex;
  align-items:baseline;
  gap:var(--gap);
  padding-right:var(--gap);
  animation-name:marquee-scroll;
  animation-duration:var(--duration, 45s);
  animation-timing-function:linear;
  animation-iteration-count:infinite;
  will-change:transform;
}
@keyframes marquee-scroll{
  from{transform:translateX(0);}
  to{transform:translateX(-100%);}
}
/* A dedicated mirrored keyframe, not animation-direction:reverse — swapping
   the direction keyword left every row still visibly scrolling the same
   way, so the middle row gets its own animation that runs the transform
   backwards from the start instead. */
@keyframes marquee-scroll-reverse{
  from{transform:translateX(-100%);}
  to{transform:translateX(0);}
}
.marquee-row.reverse .marquee-track{animation-name:marquee-scroll-reverse;}
/* Per-row speeds live here, not in a style="--duration:…" attribute on the
   row. The site's CSP sends `style-src 'self'` with no 'unsafe-inline', and
   with no style-src-attr to override it that blocks inline style attributes
   outright — so an inline --duration silently never applied and every row
   fell back to the 45s default above. Slightly different values per row keep
   the four lines from scrolling in lockstep. */
.sector-marquee .marquee-row:nth-child(1){--duration:72s;}
.sector-marquee .marquee-row:nth-child(2){--duration:108s;}
.sector-marquee .marquee-row:nth-child(3){--duration:100s;}
.sector-marquee .marquee-row:nth-child(4){--duration:80s;}
.marquee-track a{
  flex:none;
  color:var(--ink);
  font-family:var(--serif);
  font-weight:700;
  font-size:clamp(32px,4.6vw,52px);
  text-transform:uppercase;
  letter-spacing:.01em;
  white-space:nowrap;
}
.marquee-track a:hover,
.marquee-track a:focus-visible{
  color:var(--focus-text);
}
.marquee-sep{
  flex:none;
  font-family:var(--serif);
  font-size:clamp(24px,3.2vw,36px);
  color:var(--border);
}
.sector-marquee-cta{
  display:flex;
  justify-content:center;
  margin-top:28px;
}
/* ---------- Pricing ---------- */
.pricing{background:var(--ink-fixed);color:#F5F4F0;}
.pricing .eyebrow{color:var(--focus);}
.pricing .section-head p{color:#A6A9B2;}
.pricing-grid{
  display:grid;grid-template-columns:repeat(2,1fr);gap:24px;
}
.price-card{
  border:1px solid var(--border-dark);
  padding:30px 26px 26px;
}
.price-card h3{font-size:17px;margin-bottom:4px;color:#F5F4F0;}
.price-card .sub{font-size:13px;color:#9EA1AA;margin-bottom:22px;}
.price-card--wide{grid-column:1/-1;}
.price-row{
  display:flex;justify-content:space-between;align-items:baseline;
  padding:13px 0;border-top:1px solid var(--border-dark);
}
.price-row:first-of-type{border-top:none;}
.price-row>div{min-width:0;}
.price-row .label{font-size:14.5px;color:#D6D7DC;}
.tier-badge{
  display:inline-block;
  font-family:var(--mono);font-size:10px;letter-spacing:.05em;text-transform:uppercase;
  color:var(--focus);border:1px solid var(--focus);border-radius:20px;
  padding:3px 9px;margin-left:8px;
}
.tier-desc{font-size:12.5px;color:#9EA1AA;margin-top:4px;}
.tier-list{list-style:none;margin:0;padding:0;}
.tier-list li{position:relative;padding-left:15px;}
.tier-list li:not(:first-child){margin-top:3px;}
.tier-list li::before{content:"•";position:absolute;left:0;color:var(--focus);}
.price-row .amount{font-family:var(--mono);font-size:14px;color:var(--focus);white-space:nowrap;margin-left:12px;}
.price-note{font-size:12.5px;color:#8C8F98;margin-top:20px;line-height:1.5;}
.pricing-cta{margin-top:44px;text-align:center;}
.pricing-cta p{color:#A6A9B2;font-size:14.5px;margin-bottom:18px;}

/* ---------- About ---------- */
.about-grid{
  display:grid;grid-template-columns:.9fr 1.1fr;gap:64px;align-items:center;
}
.about-grid h2{font-size:clamp(24px,3vw,32px);margin-bottom:22px;}
.about-grid p{color:var(--muted);font-size:16px;margin-bottom:16px;max-width:52ch;}
.about-author{display:flex;align-items:center;gap:14px;margin-bottom:22px;}
.about-author-photo{
  width:112px;height:112px;border-radius:50%;flex:none;overflow:hidden;
  display:flex;align-items:center;justify-content:center;
  background:#f5f2ed;
  border:none;outline:none;
  box-shadow:none;
  aspect-ratio:1 / 1;
}
.about-author-photo img{width:100%;height:100%;object-fit:cover;display:block;padding:0;margin:0;object-position:center;}
.about-author-info{display:flex;flex-direction:column;gap:2px;}
.about-author-name{font-family:var(--serif);font-weight:700;font-size:16px;color:var(--ink);}
.about-author-role{font-family:var(--mono);font-size:12px;color:var(--muted);}
.about-stats{display:flex;flex-direction:column;gap:0;border-top:1px solid var(--border);}
.about-stats div{
  padding:20px 0;border-bottom:1px solid var(--border);
  display:flex;justify-content:space-between;align-items:baseline;gap:16px;
}
.about-stats .k{font-family:var(--mono);font-size:13px;color:var(--muted);white-space:nowrap;}
.about-stats .v{font-family:var(--serif);font-size:15px;font-weight:600;text-align:right;}

/* ---------- FAQ preview ---------- */
.faq-list{border-top:1px solid var(--border);max-width:820px;}
.faq-item{padding:26px 0;border-bottom:1px solid var(--border);}
.faq-item h3{font-size:16.5px;font-weight:600;margin-bottom:8px;font-family:var(--body);}
.faq-item p{font-size:14.5px;color:var(--muted);max-width:64ch;}

/* ---------- Contact ---------- */
/* .cta-panel is the same component used to close every inner page. It shares
   these rules rather than copying them so the homepage and inner pages can't
   drift apart visually. */
.contact-primary,.cta-panel{
  border:1px solid var(--border);
  background:var(--surface);
  padding:44px;
  text-align:center;
}
.contact-primary{margin-bottom:56px;}
.contact-primary .eyebrow,.cta-panel .eyebrow{display:block;margin-bottom:12px;}
.contact-primary h2,.cta-panel h2{font-size:clamp(24px,3vw,30px);margin-bottom:14px;}
.contact-primary p,.cta-panel p{color:var(--muted);font-size:16px;max-width:52ch;margin:0 auto 28px;}
.contact-primary p a,.cta-panel p a{color:var(--ink);text-decoration:underline;text-underline-offset:2px;}
.contact-primary .reassure,.cta-panel .reassure{font-family:var(--mono);font-size:12.5px;color:var(--muted);margin-top:16px;}

.contact-secondary{max-width:560px;margin:0 auto;}
.contact-secondary .section-head{margin-bottom:28px;text-align:center;max-width:none;}
.contact-secondary .eyebrow{display:block;margin-bottom:10px;}
.contact-secondary h3{font-family:var(--serif);font-size:20px;font-weight:600;}
.contact-secondary > p{text-align:center;color:var(--muted);font-size:14.5px;margin-bottom:26px;}

.form-row{margin-bottom:18px;}
.form-row label{display:block;font-family:var(--mono);font-size:11.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);margin-bottom:8px;}
.form-row input,.form-row textarea,.form-row select{
  width:100%;border:1px solid var(--border);background:var(--surface);
  padding:12px 14px;font-family:var(--body);font-size:15px;color:var(--ink);
  border-radius:var(--radius);
  transition:border-color .2s ease;
}
.form-row input:focus,.form-row textarea:focus,.form-row select:focus{border-color:var(--focus-text);outline:none;}
.form-row textarea{min-height:100px;resize:none;}
.form-note{font-size:12.5px;color:var(--muted);margin-top:14px;text-align:center;}
.text-center{text-align:center;}
.audit-success{display:none;text-align:center;padding:20px 0;}
.audit-success.is-active{display:block;}
.audit-success p{color:var(--ink);font-size:15px;font-weight:600;}

.contact-direct{
  max-width:560px;margin:40px auto 0;padding-top:32px;
  border-top:1px solid var(--border);text-align:center;
}
.contact-direct .eyebrow{display:block;margin-bottom:10px;}
.contact-direct-links{
  display:flex;justify-content:center;align-items:center;gap:32px;
  flex-wrap:wrap;font-family:var(--mono);font-size:14px;
}
.contact-direct-links a{
  display:inline-flex;align-items:center;gap:12px;
  color:var(--ink);transition:color .2s ease;
}
.contact-direct-links a:hover{color:var(--focus-text);}
.contact-direct-icon{
  width:32px;height:32px;flex:none;border-radius:50%;
  border:1.5px solid var(--border);
  display:flex;align-items:center;justify-content:center;
  transition:border-color .2s ease,background .2s ease;
}
.contact-direct-icon svg{width:14px;height:14px;stroke:var(--ink);transition:stroke .2s ease;}
.contact-direct-links a:hover .contact-direct-icon{border-color:var(--focus);background:rgba(47,163,106,.08);}
.contact-direct-links a:hover .contact-direct-icon svg{stroke:var(--focus-text);}

.about-contact-links{margin-top:4rem;}

/* ---------- Footer ---------- */
footer{background:var(--ink-fixed);color:#A6A9B2;padding:56px 0 34px;}
.footer-grid{
  display:grid;grid-template-columns:1.4fr 1fr 1fr 1fr;gap:32px;
  padding-bottom:40px;margin-bottom:28px;border-bottom:1px solid var(--border-dark);
}
.footer-grid .logo-text{color:#F5F4F0;margin-bottom:14px;display:inline-block;}
.footer-grid .logo-text span{color:#8C8F98;}
.footer-grid p{font-size:13.5px;color:#8C8F98;max-width:32ch;line-height:1.6;}
.footer-address{
  font-style:normal;font-size:13.5px;color:#8C8F98;line-height:1.7;margin-top:18px;
}
.footer-contact{display:flex;flex-direction:column;gap:14px;margin-top:24px;}
.footer-contact a{
  display:inline-flex;align-items:center;gap:12px;
  font-family:var(--mono);font-size:14px;color:#F5F4F0;
  transition:color .2s ease;
}
.footer-contact a:hover{color:var(--focus);}
.footer-contact-icon{
  width:32px;height:32px;flex:none;border-radius:50%;
  border:1.5px solid #3A3D44;
  display:flex;align-items:center;justify-content:center;
  transition:border-color .2s ease,background .2s ease;
}
.footer-contact-icon svg{width:14px;height:14px;stroke:#D6D3C9;transition:stroke .2s ease;}
.footer-contact a:hover .footer-contact-icon{border-color:var(--focus);background:rgba(47,163,106,.12);}
.footer-contact a:hover .footer-contact-icon svg{stroke:var(--focus);}
.footer-col h3{font-family:var(--mono);font-size:11.5px;letter-spacing:.1em;text-transform:uppercase;color:#8C8F98;margin-bottom:16px;}
.footer-col ul{display:flex;flex-direction:column;gap:11px;}
.footer-col a{font-size:14px;}
.footer-col a:hover{color:#F5F4F0;}
.footer-bottom{display:flex;justify-content:space-between;font-size:12.5px;flex-wrap:wrap;gap:12px;}
.socials{display:flex;gap:16px;}

/* ---------- Mobile call button ---------- */
.mobile-call-btn{display:none;}

/* ============ GUIDED FORM (/start) ============ */
.wizard-section{padding:56px 0 110px;}
.wizard-shell{
  max-width:760px;margin:0 auto;
  border:1px solid var(--border);
  background:var(--surface);
}
.wizard-resume{
  border-bottom:1px solid var(--border);background:var(--focus-dim);
  padding:24px 44px;
  display:flex;align-items:center;justify-content:space-between;gap:20px;flex-wrap:wrap;
}
.wizard-resume[hidden]{display:none;} /* explicit override — same precedent as .exit-modal[hidden] */
.wizard-resume p{font-size:14.5px;color:var(--ink);max-width:52ch;}
.wizard-resume-actions{display:flex;gap:12px;flex-shrink:0;}

.wizard-head{padding:40px 44px 0;}
.wizard-head .eyebrow{margin-bottom:12px;display:block;}
.wizard-head h1{font-size:clamp(24px,3vw,30px);margin-bottom:10px;}
.wizard-head p{color:var(--muted);font-size:15px;}

.wizard-progress{padding:28px 44px 0;}
.wizard-progress-track{
  height:3px;background:var(--paper-dim);position:relative;overflow:hidden;
  border-radius:2px;
}
.wizard-progress-fill{
  height:100%;background:var(--focus);width:20%;
  transition:width .3s ease;
}
.wizard-progress-label{
  font-family:var(--mono);font-size:11.5px;color:var(--muted);
  letter-spacing:.06em;margin-top:10px;text-transform:uppercase;
}

.wizard-body{padding:34px 44px 40px;}
.wizard-step{display:none;}
.wizard-step.is-active{display:block;animation:stepIn .3s ease;}
@keyframes stepIn{from{opacity:0;transform:translateY(6px);}to{opacity:1;transform:translateY(0);}}
.wizard-step h2{font-size:21px;margin-bottom:8px;}
.wizard-step > p.step-sub{color:var(--muted);font-size:14.5px;margin-bottom:26px;}

.wizard-field{margin-bottom:28px;}
.wizard-field:last-child{margin-bottom:0;}
.wizard-field-label{
  font-family:var(--mono);font-size:11.5px;letter-spacing:.08em;text-transform:uppercase;
  color:var(--muted);margin-bottom:12px;display:block;
}
.wizard-field input,.wizard-field textarea,.wizard-field select{
  width:100%;border:1px solid var(--border);background:var(--surface);
  padding:12px 14px;font-family:var(--body);font-size:15px;color:var(--ink);
  border-radius:var(--radius);
  transition:border-color .2s ease;
}
.wizard-field input:focus,.wizard-field textarea:focus,.wizard-field select:focus{border-color:var(--focus-text);outline:none;}
.wizard-field textarea{min-height:100px;resize:none;}

/* Big selectable service cards (step 1) */
.service-select-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px;}
.service-select{position:relative;}
.service-select input{position:absolute;opacity:0;width:0;height:0;}
.service-select .card{
  border:1px solid var(--border);padding:20px 18px;cursor:pointer;
  display:flex;flex-direction:column;gap:8px;height:100%;
  transition:border-color .18s ease, background .18s ease;
}
.service-select .card .icon{
  width:28px;height:28px;border:1.5px solid var(--ink);border-radius:50%;
  display:flex;align-items:center;justify-content:center;
}
.service-select .card .icon svg{width:14px;height:14px;stroke:var(--ink);}
.service-select .card h3{font-family:var(--body);font-weight:600;font-size:15px;}
.service-select .card p{font-size:13px;color:var(--muted);}
.service-select input:checked + .card{border-color:var(--focus);background:var(--focus-dim);}
.service-select input:checked + .card .corner{opacity:1;transform:translate(0,0);}
.service-select input:focus-visible + .card{outline:2px solid var(--focus-text);outline-offset:2px;}

/* The rescue card is a fifth, exclusive option — set apart from the four
   project types rather than just another grid item. */
.service-select--rescue{grid-column:1 / -1;}
.service-select--rescue .card .icon{border-color:var(--error);}
.service-select--rescue .card .icon svg{stroke:var(--error);}
.service-select--rescue input:checked + .card{border-color:var(--error);background:color-mix(in srgb, var(--error) 10%, transparent);}

/* Chip choice buttons (radio / checkbox groups) */
.chip-grid{display:flex;flex-wrap:wrap;gap:10px;}
.chip{position:relative;}
.chip input{position:absolute;opacity:0;width:0;height:0;}
.chip .chip-label{
  display:inline-flex;align-items:center;gap:8px;
  padding:11px 18px;border:1px solid var(--border);border-radius:var(--radius);
  font-size:14px;font-weight:500;cursor:pointer;background:var(--surface);
  transition:border-color .15s ease, background .15s ease, color .15s ease;
}
.chip input:checked + .chip-label{
  border-color:var(--focus);background:var(--focus-dim);color:var(--ink);font-weight:600;
}
.chip input:focus-visible + .chip-label{outline:2px solid var(--focus-text);outline-offset:2px;}
.chip-badge{
  font-family:var(--mono);font-size:9.5px;letter-spacing:.05em;text-transform:uppercase;
  color:var(--focus);border:1px solid var(--focus);border-radius:20px;
  padding:2px 8px;white-space:nowrap;
}

.field-hint{font-size:12.5px;color:var(--muted);margin:-6px 0 12px;}
.field-hint a{text-decoration:underline;text-underline-offset:2px;color:var(--focus-text);}

.service-detail{
  border-top:1px solid var(--border);padding-top:26px;margin-top:26px;
  display:none;
}
.service-detail.is-visible{display:block;}
.service-detail:first-of-type{border-top:none;padding-top:0;margin-top:0;}
.service-detail-title{
  font-family:var(--mono);font-size:11.5px;letter-spacing:.08em;text-transform:uppercase;
  color:var(--focus-text);margin-bottom:18px;
}

/* Estimate panel */
.estimate-panel{
  border:1px solid var(--border-dark);background:var(--ink-fixed);color:#F5F4F0;
  padding:26px 28px;margin-top:8px;
}
.estimate-panel .estimate-label{font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:#9EA1AA;margin-bottom:14px;}
.estimate-rows{display:flex;gap:32px;flex-wrap:wrap;align-items:baseline;margin-bottom:14px;}
/* A range ("£5,500 – £8,500") runs roughly twice as wide as the old "from
   £4,500" figure did, so it sits a touch smaller than the single-figure size
   this was originally tuned for. */
.estimate-row .amt{font-family:var(--serif);font-size:22px;font-weight:700;color:var(--focus);}
.estimate-row .lbl{font-size:12.5px;color:#A6A9B2;margin-top:4px;}
/* The plan recommendation is a sentence, not a figure — it shouldn't inherit
   the serif/26px treatment tuned for a standalone amount. */
.estimate-plan{font-size:15px;line-height:1.5;color:#F5F4F0;margin-bottom:14px;}
.estimate-plan strong{color:var(--focus);}
.estimate-flag{
  font-size:13px;color:#D9A441;line-height:1.5;margin:0 0 14px;
  padding:10px 14px;border:1px solid rgba(217,164,65,.4);background:rgba(217,164,65,.08);
}
.estimate-maintain{
  border:1px solid var(--border-dark);padding:18px 20px;margin-bottom:14px;
}
.estimate-maintain p{font-size:13.5px;color:#D6D7DC;line-height:1.55;margin-bottom:12px;}
.estimate-maintain p:last-of-type{margin-bottom:16px;}
.estimate-maintain strong{color:var(--focus);}
.estimate-panel .note{font-size:12.5px;color:#8C8F98;line-height:1.5;}
.estimate-panel .note:empty{display:none;}

.wizard-nav{
  display:flex;justify-content:space-between;align-items:center;
  padding:26px 44px 34px;border-top:1px solid var(--border);
}
.wizard-nav .btn-back{opacity:.6;}
.wizard-nav .btn-back:hover{opacity:1;}
.wizard-nav .btn-back[hidden]{visibility:hidden;}

.wizard-success{display:none;text-align:center;padding:70px 44px;}
.wizard-success.is-active{display:block;}
.wizard-success .icon-check{
  width:52px;height:52px;border:2px solid var(--focus-text);border-radius:50%;
  display:flex;align-items:center;justify-content:center;margin:0 auto 24px;
}
.wizard-success h2{font-size:24px;margin-bottom:12px;}
.wizard-success p{color:var(--muted);font-size:15px;max-width:44ch;margin:0 auto;}

.field-error{
  font-size:12.5px;color:var(--error);margin-top:8px;display:none;
}
.field-error.is-visible{display:block;}

/* Submit-level rejection (failed verification, rate limit) rather than a
   single bad field — sits above the nav buttons, so it needs more presence
   than the 12.5px hint that sits under an input. */
.wizard-submit-error{
  font-size:14px;margin-top:0;margin-bottom:20px;
  padding:14px 16px;border:1px solid var(--error);
  background:var(--surface);
}

.wizard-consent{
  font-size:12.5px;color:var(--muted);line-height:1.6;margin-top:24px;
}
.wizard-consent a{text-decoration:underline;text-underline-offset:2px;}

/* ---------- Breadcrumbs ---------- */
.breadcrumb{
  font-family:var(--mono);font-size:11.5px;letter-spacing:.06em;
  color:var(--muted);margin-bottom:18px;
}
.breadcrumb a{border-bottom:1px solid var(--border);padding-bottom:1px;}
.breadcrumb a:hover{color:var(--focus-text);border-bottom-color:var(--focus);}
.breadcrumb span[aria-hidden]{margin:0 4px;opacity:.6;}

/* ---------- Body content panel (service / sectors page) ---------- */
/* Long-form copy on inner pages sits in a card, matching the homepage's
   framed-card motif rather than the bare prose used for legal pages. */
/* Sector-group cards on /sectors: two columns on tablet and up, since with
   seven groups of uneven length a single column runs very long. A grid
   would still lock panels into rows — a short panel in column 1 leaves a
   gap even though its column-2 neighbour is taller — so this is a true
   masonry-style flow via CSS multicol instead: each column fills
   independently in source order, so a short panel just lets the next one
   start right underneath it. break-inside:avoid stops a panel being cut
   across the column boundary.

   The 2-column rule (in RESPONSIVE OVERRIDES, near the bottom) is
   deliberately min-width:641px rather than the max-width:640px inverse.
   `columns:1` isn't actually the inverse of `columns:2` — a
   column-count of 1 still establishes a multicol formatting context
   (activates break-inside:avoid, creates a BFC), where the true base
   state below has none. min-width also avoids a gap at fractional
   widths: max-width:640px and min-width:641px both fail to match at
   640.5px (zoom, non-integer DPR); falling through to this base rule
   correctly gives one column there, matching the phone tier either
   side of it. */
.sector-groups-grid{
  column-gap:24px;
}
.content-panel{
  background:var(--paper);
  border:1px solid var(--border);
  padding:40px 38px;
  max-width:860px;
  margin-bottom:24px;
}
.sector-groups-grid .content-panel{max-width:none;break-inside:avoid;}
/* Corner accents sit flush inside the box here, not the usual 1px outside it.
   A column box is a fragmentainer, and Chromium clips whatever overflows its
   top edge — so on the one panel that opens column 2, the 1px the accents
   normally stick out above the border swallowed their whole 2px horizontal
   stroke, leaving bare vertical ticks. Panels mid-column are unaffected,
   which is why this looked like one panel misbehaving. The 1px inset is
   imperceptible; overflowing a column edge is not. */
.sector-groups-grid .c-tl{top:0;left:0;}
.sector-groups-grid .c-tr{top:0;right:0;}
.sector-groups-grid .c-bl{bottom:0;left:0;}
.sector-groups-grid .c-br{bottom:0;right:0;}
.content-panel:last-of-type{margin-bottom:0;}
.content-panel h2{font-family:var(--serif);font-size:clamp(19px,2.4vw,23px);margin:36px 0 12px;}
.content-panel h2:first-of-type{margin-top:0;}
.content-panel h3{font-size:17px;margin:22px 0 8px;}
.content-panel p{color:var(--muted);font-size:15.5px;line-height:1.7;margin-bottom:14px;}
.content-panel p:last-child{margin-bottom:0;}
.content-panel p a{color:var(--ink);text-decoration:underline;text-underline-offset:2px;}
.content-panel .tier-list{margin-bottom:14px;}
.content-panel .tier-list li{color:var(--muted);font-size:15.5px;line-height:1.7;padding-left:18px;}
.content-panel .tier-list li:not(:first-child){margin-top:6px;}

/* Anchor targets on /sectors — from the homepage marquee, the footer's
   group links, and the retired sector pages' 301 redirects. Two things
   needed so landing on one isn't broken: room below the sticky nav
   (64px tall) so it doesn't cover the heading, and a highlight so it's
   obvious which section you were sent to. */
.content-panel h2[id],
.content-panel h3[id]{
  scroll-margin-top:100px;
  transition:background-color .6s ease;
}
.content-panel p{transition:background-color .6s ease;}
.content-panel h2:target,
.content-panel h3:target,
.content-panel h2:target + p,
.content-panel h3:target + p{
  background:var(--focus-dim);
}
.content-panel h2:target,
.content-panel h3:target{
  margin-left:-16px;margin-right:-16px;margin-bottom:0;
  padding:10px 16px 0;
  border-radius:var(--radius) var(--radius) 0 0;
}
.content-panel h2:target + p,
.content-panel h3:target + p{
  margin-left:-16px;margin-right:-16px;margin-top:0;
  padding:4px 16px 12px;
  border-radius:0 0 var(--radius) var(--radius);
}

/* ---------- FAQ accordion ---------- */
.faq-accordion{max-width:820px;border-top:1px solid var(--border);}
.faq-accordion .faq-item{
  border-bottom:1px solid var(--border);padding:22px 0;
}
.faq-accordion .faq-q-heading{margin:0;font-size:inherit;font-weight:inherit;line-height:inherit;}
.faq-accordion .faq-q{
  display:block;width:100%;background:none;border:0;margin:0;text-align:left;
  font-family:var(--body);font-weight:600;font-size:16px;color:var(--ink);
  cursor:pointer;position:relative;padding-right:28px;
}
.faq-accordion .faq-q::after{
  content:"+";position:absolute;right:0;top:0;
  font-family:var(--mono);font-size:18px;color:var(--focus-text);
  transition:transform .2s ease;
}
.faq-accordion .faq-item.open .faq-q::after{transform:rotate(135deg);}
.faq-accordion .faq-q:hover{color:var(--focus-text);}
/* visibility (not display) keeps the 0fr→1fr row animation intact while also
   removing collapsed answers from the accessibility tree — without it, screen
   readers announce every answer as though all panels were open. Transitioning
   visibility defers the flip to hidden until the collapse has finished. */
.faq-accordion .faq-a-wrap{
  display:grid;grid-template-rows:0fr;
  visibility:hidden;
  transition:grid-template-rows .25s ease, visibility .25s ease;
}
.faq-accordion .faq-a-wrap > p.a{
  overflow:hidden;min-height:0;padding-top:14px;
  color:var(--muted);font-size:15px;max-width:66ch;line-height:1.6;
}
.faq-accordion .faq-item.open .faq-a-wrap{grid-template-rows:1fr;visibility:visible;}
/* ---------- Page-header CTA row (inner pages that convert directly) ---------- */
.page-header-ctas{
  display:flex;align-items:center;gap:20px;flex-wrap:wrap;margin-top:28px;
}
.page-header-note{font-family:var(--mono);font-size:12.5px;color:var(--muted);}

/* ---------- Free review: the checklist ---------- */
.review-checks{
  display:grid;grid-template-columns:repeat(3,1fr);gap:0 40px;
  border-top:1px solid var(--border);
}
.review-checks li{padding:26px 0;border-bottom:1px solid var(--border);}
.review-checks h3{font-family:var(--body);font-size:16px;font-weight:600;margin-bottom:8px;}
.review-checks p{color:var(--muted);font-size:14.5px;line-height:1.6;}

/* ---------- Free review: the form panel ---------- */
/* The page's one conversion point, so it gets the framed-card treatment rather
   than sitting as bare fields the way the homepage's secondary offer does. */
.review-form-panel{
  background:var(--surface);border:1px solid var(--border);
  padding:48px 44px;max-width:620px;margin:0 auto;
}
.review-form-panel .section-head{max-width:none;margin-bottom:32px;text-align:center;}
.review-form-panel .section-head .eyebrow{display:block;margin-bottom:12px;}
.review-form-panel .section-head h2{font-size:clamp(22px,2.6vw,28px);}
.review-form-panel .section-head p{font-size:15px;}
.review-form-panel .btn{margin-top:6px;}
.review-form-panel .field-error{text-align:center;}

/* ---------- Thanks page ---------- */
.thanks-section{padding-top:88px;}
.thanks-panel{
  background:var(--surface);border:1px solid var(--border);
  padding:52px 44px;text-align:center;max-width:720px;margin:0 auto;
}
.thanks-panel .eyebrow{display:block;margin-bottom:12px;}
.thanks-panel h1{font-size:clamp(26px,3.4vw,36px);margin-bottom:16px;}
.thanks-panel p{color:var(--muted);font-size:16px;max-width:52ch;margin:0 auto 16px;}
.thanks-panel p:last-of-type{margin-bottom:0;}
.thanks-rescue-actions{
  display:flex;justify-content:center;gap:14px;flex-wrap:wrap;margin-top:28px;
}
.icon-check{
  width:52px;height:52px;border:2px solid var(--focus-text);border-radius:50%;
  display:flex;align-items:center;justify-content:center;margin:0 auto 24px;
}

.thanks-next{max-width:940px;margin:72px auto 0;}
.thanks-next h2,.thanks-meanwhile h2{
  font-size:clamp(20px,2.4vw,26px);margin-bottom:32px;text-align:center;
}

.thanks-booking{
  background:var(--surface);border:1px solid var(--border);
  padding:48px 44px;max-width:720px;margin:72px auto 0;text-align:center;
}
.thanks-booking .eyebrow{display:block;margin-bottom:12px;}
.thanks-booking h2{font-size:clamp(22px,2.6vw,28px);margin-bottom:14px;}
.thanks-booking > p{color:var(--muted);font-size:15.5px;max-width:52ch;margin:0 auto 32px;}
/* Google's scheduling widget is a cross-origin embed we can't theme — force
   it to stay light regardless of site theme rather than let dark mode's
   page/card background bleed around its edges or invert its own UI. */
.calendar-slot{
  margin-bottom:8px;
  background:#fff;
  border-radius:var(--radius);
  overflow:hidden;
  color-scheme:light;
}
/* border:0 lives here rather than as an inline style="" on the iframe: CSP
   sets style-src 'self' with no 'unsafe-inline', which blocks style attributes
   as well as <style> blocks, so the inline version was silently dropped. */
.calendar-slot iframe{display:block;border:0;color-scheme:light;}

.thanks-direct{margin-top:36px;padding-top:32px;border-top:1px solid var(--border);}
.thanks-direct .eyebrow{display:block;margin-bottom:16px;}
.thanks-direct-note{font-family:var(--mono);font-size:12.5px;color:var(--muted);margin-top:20px;}

.thanks-meanwhile{max-width:720px;margin:72px auto 0;}
.thanks-meanwhile ul{border-top:1px solid var(--border);}
.thanks-meanwhile li{
  padding:18px 0;border-bottom:1px solid var(--border);
  color:var(--muted);font-size:15px;line-height:1.6;
}
.thanks-meanwhile li a{
  color:var(--ink);font-weight:600;
  text-decoration:underline;text-underline-offset:2px;
}
.thanks-meanwhile li a:hover{color:var(--focus-text);}

/* ---------- Exit-intent offer ---------- */
/* `hidden` is the pre-JS guarantee; .is-open is what actually shows it. The
   explicit [hidden] rule is needed because display:flex on .is-open would
   otherwise win over the attribute's UA default. */
.exit-modal{
  position:fixed;inset:0;z-index:200;
  display:none;align-items:center;justify-content:center;padding:24px;
}
.exit-modal[hidden]{display:none;}
.exit-modal.is-open{display:flex;}
.exit-modal-backdrop{position:absolute;inset:0;background:rgba(21,23,28,.62);}
.exit-modal-panel{
  position:relative;background:var(--surface);
  width:100%;max-width:520px;padding:36px 38px 28px;
  max-height:calc(100vh - 48px);overflow:hidden;
  animation:exit-modal-in .28s ease;
}
html.reduced-motion .exit-modal-panel{animation:none;}
@keyframes exit-modal-in{
  from{opacity:0;transform:translateY(12px);}
  to{opacity:1;transform:translateY(0);}
}
.exit-modal-panel .eyebrow{display:block;margin-bottom:10px;}
.exit-modal-panel h2{font-size:clamp(20px,2.4vw,24px);margin-bottom:10px;}
.exit-modal-panel > p{color:var(--muted);font-size:14.5px;line-height:1.55;margin-bottom:20px;}
.exit-modal-panel .btn{width:100%;justify-content:center;margin-top:6px;}
.exit-modal-panel .field-error{text-align:center;}
.exit-modal-panel .form-row{margin-bottom:14px;}
.exit-modal-close{
  position:absolute;top:14px;right:14px;
  width:32px;height:32px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  color:var(--muted);transition:color .2s ease,background .2s ease;
}
.exit-modal-close:hover{color:var(--ink);background:var(--paper-dim);}
.exit-modal-dismiss{
  display:block;width:100%;margin-top:16px;padding-top:14px;
  border-top:1px solid var(--border);
  font-family:var(--mono);font-size:12px;color:var(--muted);
  transition:color .2s ease;
}
.exit-modal-dismiss:hover{color:var(--ink);}

/* ===== RESPONSIVE OVERRIDES =====
   Everything below this line is a media query. Everything above it is a
   base rule. See the LAYOUT CONTRACT at the top of this file — this
   ordering is load-bearing, not cosmetic. */

@media(max-width:920px){
  /* Hero, work, process and pricing keep their desktop column counts through
     the tablet/foldable tier (641–920px) rather than collapsing to one
     column here — that collapse is phone-only now, restated explicitly in
     the 640px block below. Gap trimmed a little so the narrower end of this
     range (foldables unfolded around 640–720px) doesn't feel cramped. */
  .hero-grid{gap:40px;}
  /* aspect-ratio:1 + width:100% already derives height from the column
     width, which is well under 320px through most of this tier — the
     320px floor (sized for the wide desktop column) would otherwise force
     a tall, cropped rectangle instead of a square. */
  .focus-image{min-height:auto;}
  .services-grid{grid-template-columns:repeat(2,1fr);}
  .process-list{gap:32px;}
  .sectors-grid{grid-template-columns:1fr;}
  .about-grid{grid-template-columns:1fr;gap:36px;}
  .footer-grid{grid-template-columns:1fr 1fr;}
  /* Tier label, badge and amount stop competing for one line once the card
     narrows to half the row — same fix the phone tier already needed, just
     needed one tier earlier now that pricing-grid stays 2-up through here. */
  .price-row{flex-wrap:wrap;gap:2px 12px;}
  .price-row .amount{margin-left:0;}
  .review-checks{grid-template-columns:repeat(2,1fr);gap:0 32px;}
}
/* Nav switches to the hamburger/dropdown well before the phone tier below,
   so tablet-width viewports never get a squeezed, wrapping nav bar. Also
   hardcoded in static/js/main.js (the mobileQuery matchMedia call) — keep
   both in sync if this value ever changes. */
@media(max-width:860px){
  .nav-links{
    position:fixed;top:64px;left:0;right:0;z-index:40;
    max-height:calc(100vh - 64px);
    background:var(--nav-bg);
    backdrop-filter:blur(20px) saturate(180%);
    border-radius:0;
    border-bottom:1px solid var(--grid-line);
    box-shadow:0 16px 40px rgba(21,23,28,.16);
    flex-direction:column;justify-content:flex-start;align-items:flex-start;
    padding:28px 24px;gap:26px;
    overflow-y:auto;
    transform:translateY(-8px);opacity:0;pointer-events:none;
    transition:opacity .2s ease, transform .2s ease, background-color .25s ease;
  }
  body.nav-open .nav-links{opacity:1;transform:translateY(0);pointer-events:auto;}
  .nav.scrolled .nav-links{background:var(--nav-bg-scrolled);}
  .nav-links a:not(.btn){font-size:18px;}
  .nav-cta .btn-primary{display:none;}
  body.nav-open .nav-cta .btn-primary{display:inline-flex;}
  .nav-toggle{display:flex;}
  body.nav-open .nav-toggle span:nth-child(1){transform:translateY(7px) rotate(45deg);}
  body.nav-open .nav-toggle span:nth-child(2){opacity:0;}
  body.nav-open .nav-toggle span:nth-child(3){transform:translateY(-7px) rotate(-45deg);}
  .theme-toggle--desktop{display:none;}
  .theme-toggle--mobile{display:flex;position:absolute;top:20px;right:20px;}
}
@media(max-width:768px){
  .rescue-strip{padding:14px 0;}
  .rescue-strip-inner{
    flex-direction:column;
    align-items:flex-start;
    gap:6px;
  }
}
@media(max-width:640px){
  .service-select-grid{grid-template-columns:1fr;}
  .wizard-head,.wizard-progress,.wizard-body,.wizard-nav,.wizard-resume{padding-left:24px;padding-right:24px;}
  .estimate-rows{gap:20px;}
  .wrap{padding-left:20px;padding-right:20px;}
  .services-grid{grid-template-columns:1fr;}
  section{padding:68px 0;}
  .hero{padding:56px 0 64px;}
  .page-header{padding-top:56px;padding-bottom:8px;}
  .contact-primary,.cta-panel{padding:32px 22px;}
  .content-panel{padding:28px 22px;}
  .footer-grid{grid-template-columns:1fr;gap:28px;}
  .section-head-row{flex-direction:column;align-items:flex-start;}
  /* Below this width the hero photo, work/pricing cards and process steps
     go back to one column — the tablet/foldable tier above (920px block)
     keeps them at their desktop column counts, this is the phone-only
     collapse. */
  .hero-grid{grid-template-columns:1fr;}
  .work-grid{grid-template-columns:1fr;}
  .process-list{grid-template-columns:1fr;}
  .pricing-grid{grid-template-columns:1fr;}
  /* Key/value pairs stack instead of being squeezed either side of a gap. */
  .about-stats div{flex-direction:column;align-items:flex-start;gap:6px;}
  .about-stats .v{text-align:left;}
  .contact-direct-links{gap:18px;}
  .mobile-call-btn{
    display:flex;align-items:center;justify-content:center;
    position:fixed;right:calc(18px + env(safe-area-inset-right, 0px));bottom:calc(18px + env(safe-area-inset-bottom, 0px));z-index:50;
    width:52px;height:52px;border-radius:50%;
    /* --focus-text, not --focus: the icon is the button's only content, and
       --paper-on-focus measures 2.9:1 in light mode — below the 3:1 non-text
       contrast floor (WCAG 1.4.11). --focus-text is darker in light mode
       (~5.6:1) and equals --focus in dark mode, where it already passed. */
    background:var(--focus-text);color:var(--paper);
    box-shadow:0 8px 20px rgba(21,23,28,.28);
  }
  .mobile-call-btn svg{width:24px;height:24px;stroke:var(--paper);}
  .thanks-rescue-actions{flex-direction:column;align-items:stretch;}
  .thanks-rescue-actions .btn{justify-content:center;}
  .review-checks{grid-template-columns:1fr;}
  .review-form-panel,.thanks-panel,.thanks-booking{padding:32px 22px;}
  .thanks-section{padding-top:56px;}
  .thanks-next,.thanks-booking,.thanks-meanwhile{margin-top:52px;}
  .exit-modal{padding:14px;}
  .exit-modal-panel{padding:32px 22px 24px;}
}
@media(min-width:641px){
  .sector-groups-grid{columns:2;}
}

/* Feature queries — kept last since they're not part of the width ladder
   above and don't interact with it. */
@media(hover:hover){
  .frame:hover .corner{opacity:1;transform:translate(0,0);}
}
@media(prefers-reduced-motion:reduce){
  .sector-marquee{mask-image:none;-webkit-mask-image:none;overflow:visible;}
  .marquee-row{flex-wrap:wrap;width:auto;}
  /* .marquee-row.reverse .marquee-track is (0,3,0) — a plain .marquee-track
     reset here is (0,1,0) and loses to it on specificity alone, regardless
     of source order. Repeating the reverse-row compound keeps the reset
     from being an accident of the shorthand also zeroing the duration. */
  .marquee-track,
  .marquee-row.reverse .marquee-track{animation:none;flex-wrap:wrap;}
  .marquee-track[aria-hidden="true"]{display:none;}
  *{animation-duration:0.001ms !important;transition-duration:0.001ms !important;}
}
