/* ============================================================
   _findlay-template/style.css
   Findlay Concrete skin — a block-palette template.
   Palette + type extracted from findlayconcretecompany.com:
   navy #1d2c49 headings/washes · teal #4f898f accent + frames ·
   green #488a75 steps band · taupe #bab9b4 form card · Kanit type.
   Mobile-first, conversion-tuned, accessibility-first.
   ============================================================ */

/* ---------- Self-hosted font (Kanit, latin subset) ---------- */
@font-face {
  font-family: "Kanit";
  font-style: normal;
  font-weight: 400;
  font-display: optional;
  src: url("/fonts/kanit-400.woff2") format("woff2");
}
@font-face {
  font-family: "Kanit";
  font-style: normal;
  font-weight: 600;
  font-display: optional;
  src: url("/fonts/kanit-600.woff2") format("woff2");
}

/* ---------- Tokens (the reskin surface) ----------
   Every palette-critical color lives here (or in a [data-theme] block below) —
   no block rule hardcodes a brand hex. The token set IS the skin. */
:root {
  /* Source palette (findlayconcretecompany.com theme variables) */
  --teal: #4f898f;               /* --main-color: accent, CTA fills, menu, h3, phone — its 3.96:1 (white ink on the fill AND as ink on white) is grandfathered (pre-contract); new palettes must hit ≥4.5 BOTH ways, on bg AND bg-alt */
  --teal-dark: #3d6f74;          /* teal hover (5.64:1 with white) */
  --dark: #404040;               /* --main-color-dark: body text + footer bg */
  --taupe: #bab9b4;              /* --main-color-light: form card, footer headings, step underline accents (its 2.07:1 underline on --green-band is decorative; new palettes aim ≥3:1 there) */
  --navy: #1d2c49;               /* h1/h2 headings (Elementor per-heading) + all photo washes */
  --green-band: #488a75;         /* steps band (green sampled off the source's Featured-Services band) — its 4.06:1 with white step headings/copy is grandfathered (pre-contract); new palettes ≥4.5 */

  --color-primary: var(--teal);
  --color-primary-dark: var(--teal-dark);
  --color-primary-fg: #ffffff;   /* ink ON the accent fills (.btn-primary/.btn-call/submit/.svc-desc) — white's 3.96:1 on --teal is grandfathered (pre-contract); a new palette's accent must carry this ink ≥4.5 (light accent ⇒ dark ink) */
  --color-heading: var(--navy);
  --color-text: var(--dark);     /* body copy #404040 */
  --color-text-muted: #6b6f77;   /* 5.04:1 on bg; its 4.46:1 on bg-alt is grandfathered (pre-contract); new palettes ≥4.5 on both */
  --color-link: var(--teal);     /* links teal → darker teal on hover */
  --color-bg: #ffffff;
  --color-bg-alt: #f1f1f0;       /* alternating section bg — 20% taupe / 80% white mix (near-neutral) */
  --color-border: #e2e2df;
  --color-footer: var(--dark);   /* footer #404040 */
  --color-error: #b00020;
  --color-success: #1e7e34;
  --color-focus: var(--teal);

  /* accent AS A BORDER on dark sections (.feature-aside-box on --navy,
     .svc-card frames on the --wash-navy services band) — role split from
     --teal so palettes whose accent melts into their dark sections can
     lighten just these frames. Default 3.52:1 on --navy (decorative ≥3). */
  --accent-on-dark: var(--teal);

  /* muted foreground ON the dark footer — tinted per palette. NOTE:
     its only consumer (.legal) is currently shadowed by .site-footer
     .legal's own rgba(255,255,255,0.6) ink on every page, so this
     token does not paint today; retained for future use. Palettes
     still supply ≥4.5:1-on-footer values so it's safe to consume. */
  --on-dark-faint: #8a909a;

  --card-input-border: #d8d7d2;  /* field borders inside the taupe estimate card */

  /* navy wash over the section photos (hero / services-band / banner / spotlight) */
  --wash-navy: rgba(29, 44, 73, 0.62);
  --svc-label-bg: rgba(61,111,116,0.92);  /* teal-dark service-label bar flush on the card image */
  --focus-ring: rgba(79,137,143,0.25);    /* teal focus halo on form fields */
  --error-ring: rgba(176,0,32,0.15);      /* invalid-field halo (derived from --color-error) */
  --turnstile-border: rgba(64,64,64,0.12);/* quiet skeleton border around the Turnstile slot */
  --hero-fallback: linear-gradient(180deg, #f8fafc 0%, #ffffff 100%);  /* pre-photo hero surface (mobile paints .bg-img over it) */

  --radius-sm: 0;
  --radius-md: 0;
  --radius-lg: 0;

  --shadow-sm: 0 1px 2px rgba(29,44,73,0.08);
  --shadow-md: 0 4px 14px rgba(29,44,73,0.12);
  --shadow-lg: 0 14px 40px rgba(29,44,73,0.22);

  --max-w: 1200px;
  --gap: clamp(1rem, 3vw, 2.5rem);

  --font-sans: "Kanit", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-display: "Kanit", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

/* ============================================================
   ASSEMBLY-TIME PALETTE VARIANTS — the standard every skin follows
   (full contract: templates/_template/CLAUDE.md "Color palettes")
   Default (no attribute) = the navy + teal Findlay skin in :root above.
   To build a site in another palette, set the attribute on <html>:
       <html lang="en" data-theme="rosewood">
   Rules of the system (hard requirements for every palette block):
   • FULL-SPECTRUM — override EVERY color role from :root (same role,
     new value). Exemptions: white-on-dark inks/washes may stay white
     (the literal #fff headings/copy on the washes, steps band, navy
     trust-break and footer; the rgba(255,255,255,…) washes — step
     ghost numbers, banner copy, quote-badge plate, Turnstile skeleton,
     header glass; the white card/field/logo-plate surfaces on light
     sections; .btn-outline-light and the white .cta-banner .btn-tel),
     and the low-alpha neutral shadows stay un-overridden
     (--shadow-sm/md/lg, alpha ≤0.22 — at that opacity they read as
     neutral). Everything else — including the washes, focus/error
     rings, svc-label bar and the hero fallback surface — is a role
     above and MUST be re-derived.
   • FUNCTION PRESERVED — light backgrounds stay light, dark sections
     stay dark, inks stay dark-and-readable, error stays recognizably
     red. Findlay's identity holds: ONE accent family (--teal roles:
     fills, links, h3, offset frames), a SEPARATE steps-band secondary
     (--green-band), a pale form-card neutral (--taupe), and a deep
     heading/wash dark (--navy). Nothing reorganizes which role does
     what.
   • PALETTE SEPARATION — palettes must differ at a glance INCLUDING
     neutrals and secondaries. Alt-band bgs sit in different hue
     families (default near-neutral #f1f1f0 vs rosewood blush ~0° vs
     indigo periwinkle ~240°), page bgs are clearly apart while staying
     near-white (pure white vs warm ivory vs cool violet-white), dark
     sections carry an obvious temperature shift (blue navy #1d2c49 vs
     wine-brown #402B30 vs violet-navy #2C2650), and the steps-band
     secondaries come from different families (green 161° vs
     olive-gold 48° vs plum 316°).
   • CONTRAST — --color-primary-fg on --teal AND --teal-dark ≥4.5:1;
     --teal as ink on bg AND bg-alt ≥4.5:1; white on --green-band
     ≥4.5:1; --on-dark-faint on --color-footer ≥4.5:1 (currently
     shadowed — see its token note — but keep it passing);
     --color-text-muted on bg AND bg-alt ≥4.5:1; --color-text on
     --color-bg targets ≥7:1 (≥4.5 minimum); decorative accents
     (--accent-on-dark box frames, --taupe step underlines) ≥3:1.
     (The DEFAULT's 3.96:1 teal, 4.06:1 steps band and 4.46:1
     muted-on-alt predate this contract and are intentionally left as
     shipped — see the token comments above.)
   Add a palette by cloning a block below and re-deriving every role.
   The two blocks here are deliberately far apart (warm wine/burgundy
   vs cool indigo/plum) so clones inherit the separation standard.
   ============================================================ */

/* Rosewood — deep wine/burgundy + olive-gold: burgundy accent (a hue
   family no other template palette uses — repo warm accents are rust
   ~14° / copper ~19° / amber ~39°; this sits at ~347°), wine-brown
   heading/wash dark, warm plum-charcoal footer, olive-gold steps band,
   rose-greige form card, blush alt band, warm ivory page. */
[data-theme="rosewood"] {
  --teal: #8E2F44;               /* wine accent — 7.95:1 white-on-fill; 7.47/6.72:1 as ink on bg/bg-alt */
  --teal-dark: #722639;          /* wine hover (10.23:1 with white) */
  --dark: #3E3335;               /* warm plum-charcoal — body ink (11.40:1 on bg) + footer */
  --taupe: #CBB3B4;              /* rose-greige form card + footer headings (6.15:1 on footer); 3.10:1 step underline on the olive band (decorative) */
  --navy: #402B30;               /* wine-brown headings (12.27:1 on bg) + washes; white on it 13.07:1 */
  --green-band: #71611F;         /* olive-gold steps band (6.12:1 with white) */

  --color-primary: var(--teal);
  --color-primary-dark: var(--teal-dark);
  --color-primary-fg: #ffffff;   /* white ink passes on both wine fills (7.95 / 10.23:1) */
  --color-heading: var(--navy);
  --color-text: var(--dark);
  --color-text-muted: #71615E;   /* warm muted ink (5.52/4.97:1 on bg/bg-alt) */
  --color-link: var(--teal);
  --color-bg: #FBF7F4;           /* warm ivory page */
  --color-bg-alt: #F6E9E9;       /* blush alt band (hue ~0° — vs default's near-neutral and indigo's periwinkle) */
  --color-border: #E7D8D6;       /* rose-tinted border */
  --color-footer: var(--dark);
  --color-error: #C41230;        /* scarlet crimson — brighter than the wine accent so errors still pop (5.67:1 on bg) */
  --color-success: #256B40;      /* warm-leaning green (6.05:1 on bg) */
  --color-focus: var(--teal);

  --accent-on-dark: #C4899A;     /* lightened wine frame on the wine-brown trust-break (4.60:1 — the full-strength accent would melt at 1.64:1) */
  --on-dark-faint: #AF9C9F;      /* legal fine print (4.67:1 on the footer) */
  --card-input-border: #D8C6C4;  /* field borders on the rose-greige card */

  --wash-navy: rgba(64, 43, 48, 0.62);     /* wine-brown photo wash (from --navy #402B30) */
  --svc-label-bg: rgba(114,38,57,0.92);    /* wine label bar (from --teal-dark #722639) */
  --focus-ring: rgba(142,47,68,0.25);      /* wine focus halo (from --teal #8E2F44) */
  --error-ring: rgba(196,18,48,0.15);      /* from --color-error #C41230 */
  --turnstile-border: rgba(62,51,53,0.12); /* from --dark #3E3335 */
  --hero-fallback: linear-gradient(180deg, #F7EFEC 0%, #FBF7F4 100%);  /* warm ivory pre-photo surface */
}

/* Indigo — indigo/plum: violet family untouched anywhere else in the
   repo (cool accents elsewhere are steel/cyan blues ~193–210°; this
   sits at ~245° with a plum 316° steps band), violet-navy heading/wash
   dark, cool charcoal-violet footer, lavender-gray form card,
   periwinkle alt band, cool violet-white page. */
[data-theme="indigo"] {
  --teal: #5B54A4;               /* indigo accent — 6.46:1 white-on-fill; 6.15/5.36:1 as ink on bg/bg-alt */
  --teal-dark: #4A4389;          /* indigo hover (8.55:1 with white) */
  --dark: #34324A;               /* charcoal-violet — body ink (11.75:1 on bg) + footer */
  --taupe: #B9B6CE;              /* lavender-gray form card + footer headings (6.26:1 on footer); 3.39:1 step underline on the plum band (decorative) */
  --navy: #2C2650;               /* violet-navy headings (13.32:1 on bg) + washes; white on it 14.00:1 */
  --green-band: #7A4E6E;         /* plum steps band (6.68:1 with white) */

  --color-primary: var(--teal);
  --color-primary-dark: var(--teal-dark);
  --color-primary-fg: #ffffff;   /* white ink passes on both indigo fills (6.46 / 8.55:1) */
  --color-heading: var(--navy);
  --color-text: var(--dark);
  --color-text-muted: #666478;   /* cool muted ink (5.46/4.76:1 on bg/bg-alt) */
  --color-link: var(--teal);
  --color-bg: #F9F9FC;           /* cool violet-white page */
  --color-bg-alt: #E9E9F4;       /* periwinkle alt band (hue ~240° — vs default's near-neutral and rosewood's blush) */
  --color-border: #DBDAE8;       /* lavender-tinted border */
  --color-footer: var(--dark);
  --color-error: #B00034;        /* cool crimson-rose — clearly off the indigo/plum axis (6.90:1 on bg) */
  --color-success: #1E6E4C;      /* cool green (5.90:1 on bg) */
  --color-focus: var(--teal);

  --accent-on-dark: #9C96D6;     /* lightened indigo frame on the violet-navy trust-break (5.16:1 — the full-strength accent would melt at 2.17:1) */
  --on-dark-faint: #A09FBA;      /* legal fine print (4.80:1 on the footer) */
  --card-input-border: #CBC8DC;  /* field borders on the lavender card */

  --wash-navy: rgba(44, 38, 80, 0.62);     /* violet-navy photo wash (from --navy #2C2650) */
  --svc-label-bg: rgba(74,67,137,0.92);    /* indigo label bar (from --teal-dark #4A4389) */
  --focus-ring: rgba(91,84,164,0.25);      /* indigo focus halo (from --teal #5B54A4) */
  --error-ring: rgba(176,0,52,0.15);       /* from --color-error #B00034 */
  --turnstile-border: rgba(52,50,74,0.12); /* from --dark #34324A */
  --hero-fallback: linear-gradient(180deg, #F1F1F8 0%, #F9F9FC 100%);  /* cool violet-white pre-photo surface */
}

/* Sage — on-trend kitchen sage green + deep forest: mid-green sage accent
   (~124° — a hue the other palettes don't sit in: default's teal is 186°,
   its band 161°; this is a warmer spring-green), deep-forest heading/wash
   dark, forest footer, mid-sage steps band, pale-sage form card, pale-sage
   alt band, sage-white page. */
[data-theme="sage"] {
  --teal: #4C6B4E;               /* sage accent — 5.97:1 white-on-fill; 5.62/4.68:1 as ink on bg/bg-alt */
  --teal-dark: #3C5740;          /* deep-sage hover (7.99:1 with white) */
  --dark: #3D4A37;               /* deep forest — body ink (8.86:1 on bg) + footer */
  --taupe: #C2CFB8;              /* pale-sage form card + footer headings (5.78:1 on footer); 3.23:1 step underline on the sage band (decorative) */
  --navy: #2C3826;               /* deep-forest headings (11.63:1 on bg) + washes; white on it 12.35:1 */
  --green-band: #55744F;         /* mid-sage steps band (5.25:1 with white) */

  --color-primary: var(--teal);
  --color-primary-dark: var(--teal-dark);
  --color-primary-fg: #ffffff;   /* white ink passes on both sage fills (5.97 / 7.99:1) */
  --color-heading: var(--navy);
  --color-text: var(--dark);
  --color-text-muted: #5B6752;   /* sage-gray muted ink (5.64/4.70:1 on bg/bg-alt) */
  --color-link: var(--teal);
  --color-bg: #F6F9F4;           /* sage-white page */
  --color-bg-alt: #DDE7D6;       /* pale-sage alt band (hue ~95° — vs default near-neutral, rosewood blush, indigo periwinkle, blush mauve) */
  --color-border: #D5DFCC;       /* sage-tinted border */
  --color-footer: var(--dark);
  --color-error: #B00020;        /* true red — clearly off the green axis (6.90:1 on bg) */
  --color-success: #2F7D46;      /* forest-leaning green (4.77:1 on bg) */
  --color-focus: var(--teal);

  --accent-on-dark: #9DB88F;     /* lightened sage frame on the deep-forest band (5.70:1 — the full-strength accent would melt at 2.07:1) */
  --on-dark-faint: #B4BCAD;      /* legal fine print (4.81:1 on the footer) */
  --card-input-border: #B7C4AC;  /* field borders on the pale-sage card */

  --wash-navy: rgba(44, 56, 38, 0.62);     /* deep-forest photo wash (from --navy #2C3826) */
  --svc-label-bg: rgba(60,87,64,0.92);     /* deep-sage label bar (from --teal-dark #3C5740) */
  --focus-ring: rgba(76,107,78,0.25);      /* sage focus halo (from --teal #4C6B4E) */
  --error-ring: rgba(176,0,32,0.15);       /* from --color-error #B00020 */
  --turnstile-border: rgba(61,74,55,0.12); /* from --dark #3D4A37 */
  --hero-fallback: linear-gradient(180deg, #EEF3EA 0%, #F6F9F4 100%);  /* sage-white pre-photo surface */
}

/* Blush — soft spa/bath: dusty-blue + blush + muted olive. The softest seed
   set, so the contract drives it hard — none of the seed colors is dark
   enough for a section, so the dark is DERIVED (slate-blue). Dusty-blue
   accent (~218°, deepened off the #8a9db1 seed so it clears AA on white AND
   the pale alt band), slate-blue heading/wash dark, plum-slate footer, muted
   olive steps band, mauve-taupe form card, blush-pink on-dark frames, mauve
   alt band, blush-white page. */
[data-theme="blush"] {
  --teal: #52678A;               /* dusty-blue accent — 5.73:1 white-on-fill; 5.27/4.87:1 as ink on bg/bg-alt (seed #8a9db1 was too light — deepened) */
  --teal-dark: #41556F;          /* deep dusty-blue hover (7.63:1 with white) */
  --dark: #3E3A42;               /* plum-slate — body ink (10.24:1 on bg) + footer (derived; no seed was dark enough) */
  --taupe: #CFC3C2;              /* mauve-taupe form card + footer headings (6.48:1 on footer); 3.40:1 step underline on the olive band (decorative) */
  --navy: #313D49;               /* slate-blue headings (10.21:1 on bg) + washes; white on it 11.09:1 (derived section dark) */
  --green-band: #6B6550;         /* muted-olive steps band (5.83:1 with white) */

  --color-primary: var(--teal);
  --color-primary-dark: var(--teal-dark);
  --color-primary-fg: #ffffff;   /* white ink passes on both dusty-blue fills (5.73 / 7.63:1) */
  --color-heading: var(--navy);
  --color-text: var(--dark);
  --color-text-muted: #6A6672;   /* slate-mauve muted ink (5.15/4.75:1 on bg/bg-alt) */
  --color-link: var(--teal);
  --color-bg: #FBF4F3;           /* blush-white page (pink ~8° — vs rosewood's yellow ivory) */
  --color-bg-alt: #F4EAEE;       /* mauve alt band (hue ~336° — cool-mauve, distinct from rosewood's warm blush 0°) */
  --color-border: #E4D8DC;       /* mauve-tinted border */
  --color-footer: var(--dark);
  --color-error: #C41230;        /* scarlet crimson — off the blue/olive axis (5.56:1 on bg) */
  --color-success: #256B40;      /* balanced green (5.94:1 on bg) */
  --color-focus: var(--teal);

  --accent-on-dark: #ECC5C6;     /* blush-pink frame on the slate-blue band (7.06:1 — the full-strength dusty-blue accent would melt at 1.94:1) */
  --on-dark-faint: #B6AEB0;      /* legal fine print (5.12:1 on the footer) */
  --card-input-border: #DBCFD2;  /* field borders on the mauve-taupe card */

  --wash-navy: rgba(49, 61, 73, 0.62);     /* slate-blue photo wash (from --navy #313D49) */
  --svc-label-bg: rgba(65,85,111,0.92);    /* deep dusty-blue label bar (from --teal-dark #41556F) */
  --focus-ring: rgba(82,103,138,0.25);     /* dusty-blue focus halo (from --teal #52678A) */
  --error-ring: rgba(196,18,48,0.15);      /* from --color-error #C41230 */
  --turnstile-border: rgba(62,58,66,0.12); /* from --dark #3E3A42 */
  --hero-fallback: linear-gradient(180deg, #F4E9E7 0%, #FBF4F3 100%);  /* blush-white pre-photo surface */
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; scroll-behavior: smooth; scrollbar-gutter: stable; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
/* anchor targets clear the sticky header (taller two-row header on mobile) */
:target, section[id] { scroll-margin-top: calc(100px + 1rem); }
@media (max-width: 880px) { :target, section[id] { scroll-margin-top: calc(132px + 1rem); } }
body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 18px;
  line-height: 1.6;
  color: var(--color-text);
  background: var(--color-bg);
  -webkit-font-smoothing: antialiased;
}
img, picture, svg { display: block; max-width: 100%; height: auto; }
h1, h2, h3, h4 {
  font-family: var(--font-display);
  line-height: 1.15;
  margin: 0 0 0.5em;
  color: var(--color-heading);
  font-weight: 600;               /* Kanit 600 is the site's heading weight */
}
h1 { font-size: clamp(2.1rem, 5vw, 3.4rem); letter-spacing: -0.01em; }
h2 { font-size: clamp(1.5rem, 3.4vw, 1.95rem); }
h3 { font-size: clamp(1.2rem, 2.1vw, 1.5rem); color: var(--teal); }
p { margin: 0 0 1em; }
a { color: var(--color-link); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 2px; }
.btn:hover, .nav-tel:hover { text-decoration: none; }   /* buttons + header phone: no hover underline */

/* ---------- A11y: focus + skip link ---------- */
:focus-visible {
  outline: 3px solid var(--color-focus);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}
.skip-link {
  position: absolute;
  left: -10000px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
  background: var(--color-text);
  color: #fff;
  padding: 0.75rem 1rem;
  z-index: 1000;
  border-radius: 0 0 var(--radius-md) 0;
}
.skip-link:focus {
  left: 0;
  top: 0;
  width: auto;
  height: auto;
}
.visually-hidden,
.hp-field {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0);
  white-space: nowrap; border: 0;
}

/* ---------- Layout ---------- */
.container {
  width: 100%;
  max-width: var(--max-w);
  margin: 0 auto;
  padding: 0 1.25rem;
}
main { display: block; }
section { padding: clamp(2.5rem, 6vw, 4.5rem) 0; }
section.alt { background: var(--color-bg-alt); }

/* ---------- Header / nav ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(255,255,255,0.96);
  backdrop-filter: saturate(180%) blur(8px);
  border-bottom: 1px solid var(--color-border);
}
.site-header .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-top: 0.75rem;
  padding-bottom: 0.75rem;
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 600;
  font-size: 1.3rem;
  letter-spacing: -0.01em;
  color: var(--navy);
  text-decoration: none;
}
.brand svg { width: 28px; height: 28px; }
.site-nav { display: flex; align-items: center; gap: 0.25rem 1rem; flex-wrap: wrap; }
.site-nav a {
  color: var(--teal);           /* --menu-item-color */
  text-decoration: none;
  font-weight: 400;
  padding: 0.5rem 0.25rem;
}
.site-nav a:hover { color: var(--teal-dark); }
.site-nav a.nav-cta { color: var(--teal); font-weight: 600; font-size: 1.35rem; }
.nav-cta { margin-left: 0.5rem; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  font: inherit;
  font-weight: 700;
  padding: 0.85rem 1.4rem;
  border-radius: var(--radius-md);
  border: 2px solid transparent;
  text-decoration: none;
  cursor: pointer;
  transition: transform .08s ease, box-shadow .15s ease, background-color .15s ease, color .15s ease, border-color .15s ease;
  min-height: 48px;
  line-height: 1.2;
}
.btn-primary {
  background: var(--color-primary);
  color: var(--color-primary-fg);
  box-shadow: var(--shadow-md);
}
.btn-primary:hover { background: var(--color-primary-dark); }
.btn-primary:active { transform: translateY(1px); }
.btn-secondary {
  background: transparent;
  color: var(--color-text);
  border-color: var(--color-text);
}
.btn-secondary:hover { background: var(--color-text); color: #fff; }
.btn-block { display: flex; width: 100%; }
.btn-tel {
  background: var(--navy);
  color: #fff;
}

/* ---------- Hero ---------- */
.hero {
  position: relative;
  padding: clamp(2.5rem, 7vw, 5rem) 0;
  background: var(--hero-fallback);
}
.hero-grid {
  display: grid;
  gap: var(--gap);
  align-items: center;
  grid-template-columns: 1fr;
}
@media (min-width: 820px) {
  .hero-grid { grid-template-columns: 1.1fr 1fr; }
}
.hero-lede {
  font-size: clamp(1.1rem, 2vw, 1.25rem);
  color: var(--color-text-muted);
  max-width: 56ch;
}
.hero-cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1.5rem;
}
@media (min-width: 600px) { }
@media (min-width: 960px) { }
@media (min-width: 720px) { }
@media (min-width: 1000px) { }
.why-card .num {
  display: inline-block;
  font-weight: 800;
  font-size: 1.4rem;
  color: var(--color-primary-dark);
  margin-bottom: 0.25rem;
}

/* ---------- FAQ (CSS-only accordion via <details>) ---------- */
.faq-list { display: flex; flex-direction: column; gap: 0.75rem; }
.faq-item {
  background: #fff;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: 0;
  overflow: hidden;
}
.faq-item > summary {
  list-style: none;
  cursor: pointer;
  padding: 1rem 1.25rem;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}
.faq-item > summary::-webkit-details-marker { display: none; }
.faq-item > summary::after {
  content: "+";
  font-size: 1.5rem;
  font-weight: 400;
  color: var(--color-primary-dark);
  flex-shrink: 0;
}
.faq-item[open] > summary::after { content: "−"; }
.faq-item > .faq-body {
  padding: 0 1.25rem 1.25rem;
  color: var(--color-text-muted);
}
.cta-banner .btn-primary { background: var(--color-primary); }
.cta-banner .btn-tel { background: #fff; color: var(--color-text); }

/* ---------- Forms ---------- */
.form-card {
  background: #fff;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding: clamp(1.25rem, 3vw, 2rem);
}
.form-grid {
  display: grid;
  gap: 1rem;
}
.field { display: flex; flex-direction: column; gap: 0.4rem; }
.field label {
  font-weight: 600;
  font-size: 0.95rem;
}
.field .req { color: var(--color-error); margin-left: 0.15rem; }
.field input,
.field textarea {
  font: inherit;
  padding: 0.75rem 0.9rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: #fff;
  color: var(--color-text);
  min-height: 48px;
  width: 100%;
  transition: border-color .12s ease, box-shadow .12s ease;
}
.field textarea { min-height: 140px; resize: vertical; }
.field input:focus,
.field textarea:focus,
.field select:focus {
  border-color: var(--color-focus);
  box-shadow: 0 0 0 3px var(--focus-ring);
  outline: none;
}
.field input[aria-invalid="true"],
.field textarea[aria-invalid="true"] {
  border-color: var(--color-error);
  box-shadow: 0 0 0 3px var(--error-ring);
}
.field .help {
  font-size: 0.85rem;
  color: var(--color-text-muted);
}
.field .error {
  font-size: 0.9rem;
  color: var(--color-error);
  display: none;
}
.field input[aria-invalid="true"] ~ .error,
.field textarea[aria-invalid="true"] ~ .error { display: block; }

.form-footnote {
  font-size: 0.85rem;
  color: var(--color-text-muted);
  margin-top: 0.5rem;
}

/* ---------- Footer ---------- */
.site-footer {
  background: var(--color-footer);   /* #404040 */
  color: rgba(255,255,255,0.82);     /* --footer-text-color: #fff */
  padding: 3rem 0 2rem;
  margin-top: 0;
}
.site-footer a { color: #fff; }
.footer-grid {
  display: grid;
  gap: 2rem;
  grid-template-columns: 1fr;
}
@media (min-width: 720px) { .footer-grid { grid-template-columns: 1.4fr 1fr 1fr; } }
.footer-grid h4 { color: #fff; font-size: 1rem; margin-bottom: 0.75rem; }
.footer-grid ul { list-style: none; padding: 0; margin: 0; }
.footer-grid li { margin-bottom: 0.4rem; }
.nap address {
  font-style: normal;
  line-height: 1.7;
}
.legal {
  margin-top: 2rem;
  padding-top: 1.5rem;
  border-top: 1px solid rgba(255,255,255,0.1);
  font-size: 0.85rem;
  color: var(--on-dark-faint);
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  justify-content: space-between;
}

/* ---------- 404 / utility pages ---------- */
.page-narrow {
  max-width: 720px;
  margin: 0 auto;
}
.page-narrow h2 { margin-top: 2em; }
.page-narrow ul { padding-left: 1.25em; }

/* ============================================================
   FINDLAY BLOCKS — the skin's block vocabulary
   ============================================================ */

/* ---------- Header logo + nav (dropdown + mobile drawer) ---------- */
.brand-logo { width: auto; height: 52px; }
.site-header .container { gap: 1.5rem; }
.nav-list {
  display: flex; align-items: center; gap: 1.75rem;
  list-style: none; margin: 0; padding: 0;
}
.nav-item { position: relative; }
.nav-item > a {
  display: inline-flex; align-items: center; gap: 0.3rem;
  color: var(--dark); text-decoration: none; font-weight: 400; font-size: 1.05rem;
  padding: 1.5rem 0;
}
.nav-item > a:hover { color: var(--teal); }
.nav-caret { transition: transform .15s ease; }
.dropdown {
  position: absolute; top: 100%; left: 50%; transform: translateX(-50%) translateY(6px);
  min-width: 230px; background: #fff; border: 1px solid var(--color-border);
  border-radius: var(--radius-md); box-shadow: var(--shadow-md);
  list-style: none; margin: 0; padding: 0.5rem;
  opacity: 0; visibility: hidden; transition: opacity .15s ease, transform .15s ease; z-index: 60;
}
.nav-item.has-dropdown:hover .dropdown,
.nav-item.has-dropdown:focus-within .dropdown { opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0); }
.dropdown a { display: block; padding: 0.5rem 0.75rem; color: var(--navy); text-decoration: none; border-radius: var(--radius-sm); font-size: 0.98rem; }
.dropdown a:hover { background: var(--color-bg-alt); color: var(--teal); }
.nav-tel {
  display: inline-flex; align-items: center; gap: 0.4rem;
  color: var(--navy); font-weight: 600; font-size: 1.95rem; text-decoration: none; white-space: nowrap;
}
.nav-tel svg { fill: currentColor; color: var(--teal); width: 26px; height: 26px; }   /* icon stays teal */
.menu-toggle {
  display: none; width: 44px; height: 44px; border: 0; background: transparent; cursor: pointer;
  position: relative;
}
.menu-toggle span, .menu-toggle span::before, .menu-toggle span::after {
  content: ""; position: absolute; left: 10px; width: 24px; height: 2px; background: var(--navy); transition: transform .2s ease, opacity .2s ease;
}
.menu-toggle span { top: 21px; }
.menu-toggle span::before { top: -7px; }
.menu-toggle span::after { top: 7px; }
.menu-toggle.is-open span { background: transparent; }
.menu-toggle.is-open span::before { transform: translateY(7px) rotate(45deg); }
.menu-toggle.is-open span::after { transform: translateY(-7px) rotate(-45deg); }

/* ---------- Background host (real <img> + overlay) ---------- */
.bg-host { position: relative; isolation: isolate; overflow: hidden; }
.bg-host > .bg-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: -2; }
.bg-host > .container { position: relative; z-index: 1; }

/* ---------- Hero + quote-form fusion ---------- */
.hero { padding: clamp(1.25rem, 2.5vw, 2rem) 0 clamp(2.5rem, 6vw, 4.5rem); }
/* Fixed (parallax) hero background on desktop: the section's CSS
   background does the fixed effect and clips to the section; the inline
   .bg-img is hidden. <=900px the CSS bg is dropped and the .bg-img
   returns (avoids iOS fixed-bg bugs + mobile double-download).
   NOTE: swapping the hero photo means changing it here AND in the <img>. */
@media (min-width: 901px) {
  .hero { background: url("/images/band-exterior-elevation-1600.webp") center / cover no-repeat fixed; }
  .hero > .bg-img { display: none; }
}
.hero::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background-color: var(--wash-navy);   /* navy wash over the hero photo */
}
.hero-grid { display: grid; gap: var(--gap); align-items: start; grid-template-columns: 1fr; }
/* Wider copy column, narrower form. minmax floors the form at 300px so it
   never gets squeezed below a usable field width on mid-size screens. */
/* The form column can never be narrower than the Turnstile widget, whose
   iframe is a fixed 300px and floors the form grid's only column. The card
   adds 26.55px padding each side, so anything under ~355px pushes the fields
   out through the card's right edge. 380px leaves a little headroom. */
@media (min-width: 880px) { .hero-grid { grid-template-columns: minmax(0, 1.5fr) minmax(380px, 0.75fr); align-items: flex-start; } }
.hero .hero-title {
  color: #ffffff;                /* locked variant C: white text on navy wash */
  font-size: clamp(2.1rem, 4vw, 2.8125rem);   /* cap = 45px at the 16px root */
  max-width: none;
  margin-bottom: 0.9375rem;      /* = 15px at the 16px root; rem so it tracks
                                    a user's browser font-size setting */
}
.hero-lede {
  color: #ffffff;
  max-width: none;
  margin-bottom: .6em;
  font-size: 18px;               /* match body copy (1rem = 16px root, so px here) */
  line-height: 1.4;              /* tighter than body: the hero carries all four intro paragraphs */
}
.hero-lede + .hero-cta-row { margin-top: 1.4rem; }

/* Estimate / quote-form card (taupe) */
.estimate-card { background: var(--taupe); border-radius: var(--radius-md); padding: clamp(1.25rem, 3vw, 1.9rem); box-shadow: var(--shadow-md); }
.estimate-title { color: var(--navy); font-family: var(--font-display); font-weight: 600; font-size: 1.6rem; text-align: center; margin: 0 0 1rem; }
.estimate-form { display: grid; gap: 0.7rem; }
.estimate-form input, .estimate-form select, .estimate-form textarea {
  font: inherit; width: 100%; padding: 0.75rem 0.9rem; border: 1px solid var(--card-input-border); border-radius: 0;
  background: #fff; color: var(--color-text); min-height: 48px;
}
.estimate-form textarea { resize: vertical; min-height: 120px; }
.estimate-form select { color: var(--color-text-muted); }
.estimate-form input:focus, .estimate-form select:focus, .estimate-form textarea:focus {
  outline: none; border-color: var(--teal); box-shadow: 0 0 0 3px var(--focus-ring);
}
.estimate-form button[type="submit"] {
  justify-self: center; margin-top: 0.4rem; min-height: 48px; padding: 0.8rem 2.2rem;
  background: var(--teal); color: var(--color-primary-fg); border: 0; border-radius: 0; font: inherit; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.03em; cursor: pointer; transition: background .15s ease;
}
.estimate-form button[type="submit"]:hover { background: var(--teal-dark); }

/* reserve the widget's exact box and pre-fill it with a quiet skeleton so
   the widget paints into an already-occupied slot instead of popping in */
.cf-turnstile {
  height: 65px; width: 300px; max-width: 100%;   /* HARD-locked box: the widget can never resize the form */
  overflow: hidden;
  background: rgba(255,255,255,0.45);
  border: 1px solid var(--turnstile-border);
}
.cf-turnstile iframe { display: block; transform-origin: left top; }
/* Narrow phones: the 300px iframe won't fit the card's content box, so scale
   it down rather than clip it (overflow:hidden would crop the right edge on
   360/375px phones). Height tracks the scale so no dead space opens below. */
@media (max-width: 400px) { .cf-turnstile { width: 270px; height: 59px; } .cf-turnstile iframe { transform: scale(0.9); } }
@media (max-width: 345px) { .cf-turnstile { width: 222px; height: 48px; } .cf-turnstile iframe { transform: scale(0.74); } }


.flex-quote-btn { margin-top: 0.75rem; align-self: flex-start; }   /* size to content inside flex cols */

/* Hero CTA button ("Call Us Today!") */
.btn-call { background: var(--teal); color: var(--color-primary-fg); border-color: var(--teal); }
.hero .btn-call,
.banner .btn-call { border: 2px solid #ffffff; }
.btn-call:hover { background: var(--teal-dark); border-color: var(--teal-dark); color: var(--color-primary-fg); }
.hero .btn-call:hover,
.banner .btn-call:hover { border-color: #ffffff; }
.btn-call svg { fill: currentColor; }

/* ---------- Featured Services (green band, image cards) ---------- */
/* Fixed photo background (same desktop/mobile split as the hero). */
.services-band { position: relative; }
@media (min-width: 901px) {
  .services-band { background: url("/images/band-dark-siding-1600.webp") center / cover no-repeat fixed; }
  .services-band > .bg-img { display: none; }
}
.services-band::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background-color: var(--wash-navy);   /* navy wash, matching the hero */
}
.services-band h2 { color: #fff; text-align: center; margin-bottom: 2rem; }
.svc-grid { list-style: none; margin: 0; padding: 0; display: grid; gap: 1.5rem; grid-template-columns: 1fr; }
@media (min-width: 560px) { .svc-grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 920px) { .svc-grid { grid-template-columns: repeat(3, 1fr); } }
.svc-grid > li { display: flex; }
/* card = image (flush teal label at its bottom) + description extension */
.svc-card {
  display: flex; flex-direction: column; width: 100%;
  border: 3px solid var(--accent-on-dark);   /* frame sits on the dark wash band — see the token's role-split note */
  overflow: hidden; box-shadow: var(--shadow-md);
  background: #fff;
}
.svc-media { position: relative; display: block; aspect-ratio: 4 / 3; overflow: hidden; }
.svc-media img { width: 100%; height: 100%; object-fit: cover; transition: transform .3s ease; }

h3.svc-label {
  position: absolute; left: 0; right: 0; bottom: 0; margin: 0;   /* flush with image bottom */
  background: var(--svc-label-bg); color: #fff; text-align: center;
  font-family: var(--font-display); font-weight: 600; font-size: 1.35rem; padding: 0.55rem 0.5rem;
}

.svc-desc {
  display: block; flex: 1; margin: 0; padding: 0.9rem 1.1rem 1.1rem; text-align: center;
  background: var(--teal); color: var(--color-primary-fg); font-size: 16px; line-height: 1.55;
}

/* ---------- Flex-media (image + text; --reverse; --long) ---------- */
.flex-media--reverse { background: var(--color-bg-alt); }
.flex-media-grid { display: grid; gap: var(--gap); align-items: center; grid-template-columns: 1fr; }
@media (min-width: 880px) { .flex-media-grid { grid-template-columns: 1fr 1fr; } }
.flex-media--reverse .flex-media-figure { order: -1; }  /* image to the LEFT */
.flex-media-text h2, .flex-media-text h3:first-child { margin-top: 0; }
.flex-media-figure { margin: 0; }
.flex-media-figure img { width: 100%; border-radius: 0; object-fit: cover; }

/* badge-figure: teal offset frame + "Get Concrete Quote" overlay */
.badge-figure { position: relative; display: inline-block; width: 100%; }
/* teal offset frame — equal overhang on its two exposed sides, always
   facing the OUTSIDE margin: image-right blocks drop bottom-right
   (default); image-left blocks (--long-reverse) mirror to bottom-left */
.badge-figure::after {
  content: ""; position: absolute; z-index: 0;
  left: 16px; right: -16px; top: 16px; bottom: -16px;
  background: var(--teal);
}
.flex-media--long-reverse .badge-figure::after,
.flex-media--reverse .badge-figure::after {
  left: -16px; right: 16px;
}
.badge-figure img { position: relative; z-index: 1; }
/* badge hugs the same outside edge as the frame, flush with the image
   edge (image-right blocks: right edge; image-left blocks: left edge) */
.quote-badge {
  position: absolute; z-index: 2; top: 16px; right: 0; left: auto;
  background: rgba(255,255,255,0.9); padding: 0.55rem 1rem; text-align: center; border-radius: 0;
  display: flex; flex-direction: column; line-height: 1.2;
}
.quote-badge span { color: var(--navy); font-family: var(--font-display); font-weight: 600; }
.flex-media--long-reverse .quote-badge,
.flex-media--reverse .quote-badge { left: 0; right: auto; }
.quote-badge a { color: var(--teal); font-family: var(--font-display); font-weight: 600; font-size: 1.35rem; text-decoration: none; }

/* long-form: full-width h2, then two equal columns; the figure rides
   INSIDE a column — top of the right col (--long) or bottom of the
   left col (--long-reverse). Background alternation comes from .alt. */
.flex-media-long-grid { display: grid; grid-template-columns: 1fr; gap: clamp(1.5rem, 3vw, 2.5rem); align-items: stretch; margin-top: 1.5rem; }
@media (min-width: 768px) { .flex-media-long-grid { grid-template-columns: 1fr 1fr; } }
.flex-media-long-col { display: flex; flex-direction: column; }
.flex-media-long-col > :first-child { margin-top: 0; }
.flex-media-long-col h3 { margin-top: 0; }
.flex-media-long-figure { margin: 0; }
.flex-media-long-figure img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: 0; }
/* figure at top of a column (image top-right pattern) */
.flex-media-long-col > .flex-media-long-figure:first-child { margin-bottom: 1.5rem; }
/* figure at bottom of a column (image bottom-left pattern) — the
   badge-figure teal frame needs breathing room below */
.flex-media-long-col > .flex-media-long-figure:last-child { margin-top: auto; }  /* no padding here — it would shift the img inside the figure and break the badge/frame 16px corner */
.flex-media-long-col > .badge-figure:last-child { margin-bottom: 16px; }
.feature-list { margin: 0 0 1em; padding-left: 1.2em; }
.feature-list li { margin-bottom: 0.35em; }

/* ---------- Quote-band (full-width taupe + form) ---------- */
.quote-band { background: var(--body-quote-form-bkg, var(--taupe)); }
.quote-band .estimate-form { max-width: 640px; margin: 0 auto; }
.quote-band .estimate-title { font-size: 1.9rem; }

/* ---------- FAQ (teal question text) ---------- */
.faq-item > summary { color: var(--teal); font-size: 1.15rem; }
.faq-item > .faq-body p:last-child { margin-bottom: 0; }

/* ---------- Banner (emphasis break over fixed photo) ---------- */
.banner { position: relative; color: #fff; text-align: center; }
@media (min-width: 901px) {
  .banner { background: url("/images/band-dark-siding-1600.webp") center / cover no-repeat fixed; }
  .banner > .bg-img { display: none; }
}
.banner::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background-color: var(--wash-navy);   /* navy wash, matching hero/services/spotlight */
}
.banner-kicker {
  font-family: var(--font-display); font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.08em; font-size: 1.05rem; color: var(--taupe); margin: 0 0 0.5rem;
}
.banner h2 { color: #fff; max-width: 26ch; margin: 0 auto 0.6rem; }
.banner-copy { color: rgba(255,255,255,0.88); max-width: 62ch; margin: 0 auto; }
.banner-cta-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.9rem; margin-top: 1.5rem; }
.btn-outline-light { background: transparent; color: #fff; border: 2px solid #fff; font-weight: 600; }
.btn-outline-light:hover { background: #fff; color: var(--navy); }
.btn-outline-light svg { fill: currentColor; }

/* ---------- Steps (green band, typographic ghost numbers) ---------- */
.steps { background: var(--green-band); color: #fff; }
.steps h2 { color: #fff; text-align: center; margin: 0 0 2.5rem; }
.steps-grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: 1fr; gap: 2rem; }
@media (min-width: 640px) { .steps-grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1020px) { .steps-grid { grid-template-columns: repeat(4, 1fr); } }
.step { position: relative; padding-top: 2.6rem; }
.step-num {
  position: absolute; top: 0; left: 0; z-index: 0;
  font-family: var(--font-display); font-weight: 600; font-size: 4.6rem; line-height: 1;
  color: rgba(255,255,255,0.26);
}
.step h3 { position: relative; z-index: 1; color: #fff; margin: 0 0 0.6rem; }
.step h3::after { content: ""; display: block; width: 44px; height: 3px; background: var(--taupe); margin-top: 0.5rem; }
.step p { color: rgba(255,255,255,0.9); margin: 0; }

/* ---------- Testimonials (staggered cards, taupe offset frames) ---------- */
.testimonials h2 { text-align: center; margin: 0 0 2.5rem; }
.testi-grid {
  list-style: none; margin: 0; padding: 0 16px 16px 0;   /* room for the offset frames */
  display: grid; grid-template-columns: 1fr; gap: 2.5rem;
}
@media (min-width: 900px) {
  .testi-grid { grid-template-columns: repeat(3, 1fr); }
  .testi-grid > li:nth-child(2) { margin-top: 2rem; }   /* staggered middle card */
}
.testi-card {
  position: relative; background: #fff; border: 1px solid var(--color-border);
  padding: 1.6rem 1.5rem 1.4rem; box-shadow: var(--shadow-sm);
}
.testi-card::after {                       /* teal offset frame (matches badge-figure motif) */
  content: ""; position: absolute; z-index: -1;
  left: 16px; right: -16px; top: 16px; bottom: -16px;
  background: var(--teal);
}
.testi-card::before {                      /* ghost quote mark */
  content: "\201C"; position: absolute; top: -0.4rem; right: 1rem;
  font-family: var(--font-display); font-weight: 600; font-size: 5.5rem; line-height: 1;
  color: var(--teal); opacity: 0.3; pointer-events: none;
}
.testi-stars { display: flex; gap: 0.2rem; color: var(--teal); margin: 0 0 0.8rem; }
.testi-stars svg { fill: currentColor; }
.testi-card blockquote { margin: 0 0 1rem; font-size: 16px; }
.testi-name { font-family: var(--font-display); font-weight: 600; color: var(--navy); margin: 0; }
.testi-meta { color: var(--color-text-muted); font-size: 0.9rem; margin: 0; }

.contact-info-list { list-style: none; margin: 1.25rem 0 0; padding: 0; display: grid; gap: 0.7rem; }
.contact-info-list li { display: flex; align-items: center; gap: 0.6rem; }
.contact-info-list svg { stroke: var(--teal); flex-shrink: 0; }
.contact-info-list a { font-weight: 600; }

/* ---------- Page hero (inner pages: compact, h1 only) ---------- */
.page-hero { padding: clamp(2rem, 5vw, 3.25rem) 0; }
.page-hero .hero-title { margin-bottom: 0; }
.flex-media-grid--start { align-items: start; }

/* ---------- Feature-aside (navy trust break + nav boxes) ---------- */
.feature-aside { background: var(--navy); color: #fff; }
.feature-aside h2 { color: #fff; margin-top: 0; }
.feature-aside .subhead { color: var(--taupe); }
.feature-aside p { color: rgba(255,255,255,0.88); }
.feature-aside p:last-child { margin-bottom: 0; }
.feature-aside-grid { display: grid; grid-template-columns: 1fr; gap: clamp(1.5rem, 4vw, 3rem); align-items: center; }
@media (min-width: 880px) { .feature-aside-grid { grid-template-columns: 1.5fr 1fr; } }
.feature-aside-side { display: grid; gap: 1.5rem; align-content: center; }
.feature-aside-box {
  border: 3px solid var(--accent-on-dark); padding: 1.5rem; text-align: center;
}
.feature-aside-box-title { font-family: var(--font-display); font-weight: 600; font-size: 1.35rem; color: #fff; margin: 0 0 0.9rem; }

/* ---------- Spotlight (service areas + city narrative) ---------- */
.spotlight { position: relative; color: #fff; }
@media (min-width: 901px) {
  .spotlight:not(.spotlight--light) { background: url("/images/hero-exterior-install-1600.webp") center / cover no-repeat fixed; }
  .spotlight:not(.spotlight--light) > .bg-img { display: none; }
}
.spotlight:not(.spotlight--light)::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background-color: var(--wash-navy);   /* navy wash, matching hero/services */
}
.spotlight .container { display: grid; grid-template-columns: 1fr; gap: clamp(1.5rem, 4vw, 3rem); align-items: start; }
@media (min-width: 880px) { .spotlight .container { grid-template-columns: 1.3fr 1fr; } }   /* narrative left (wider), areas right */
.spotlight h2 { color: #fff; margin-top: 0; }
.spotlight p { color: rgba(255,255,255,0.88); }
.spotlight-side-title {
  font-family: var(--font-display); font-weight: 600; text-transform: uppercase;
  font-size: clamp(1.5rem, 3vw, 2rem); line-height: 1.1; color: #fff; margin: 0 0 1rem;
}
.spotlight-areas { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: 1fr; gap: 0.4rem 1.5rem; }
@media (min-width: 480px) { .spotlight-areas { grid-template-columns: 1fr 1fr; } }
.spotlight-areas li { position: relative; padding-left: 1.5em; }
.spotlight-areas li::before { content: "\2713"; position: absolute; left: 0; color: var(--taupe); font-weight: 600; }

/* light variant: white bg, no photo/wash, teal side-title */
.spotlight--light { color: var(--color-text); background: var(--color-bg); }
.spotlight--light h2 { color: var(--color-heading); }
.spotlight--light p { color: var(--color-text); }
.spotlight--light .spotlight-side-title { color: var(--teal); }
.spotlight--light .spotlight-areas li::before { color: var(--teal); }

/* ---------- Closing CTA (centered, narrow) ---------- */
.cta-close { text-align: center; }
.cta-close .container { max-width: 780px; }
.cta-close h2 { color: var(--navy); }
.cta-close p { margin-inline: auto; }
.cta-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.9rem; margin-top: 1.6rem; }
.btn-outline {
  background: transparent; color: var(--teal); border-color: var(--teal); font-weight: 600;
}
.btn-outline:hover { background: var(--teal); color: var(--color-primary-fg); }
.btn-outline svg { fill: currentColor; }

/* ---------- Footer (charcoal, 4-col) ---------- */
.site-footer .footer-grid { grid-template-columns: 1fr; gap: 2.5rem; align-items: start; }
@media (min-width: 760px) { .site-footer .footer-grid { grid-template-columns: repeat(4, 1fr); } }
.footer-logo-link { display: inline-block; margin-bottom: 1rem; }
.footer-logo-sq { background: #fff; padding: 10px; width: 150px; height: auto; display: block; }
.site-footer address { font-style: normal; line-height: 1.7; color: rgba(255,255,255,0.82); }
.footer-heading { color: var(--taupe); font-family: var(--font-display); font-weight: 600; font-size: 1.3rem; margin: 0 0 0.75rem; }
.footer-links { list-style: none; margin: 0 0 1.25rem; padding: 0; }
.footer-links li { margin-bottom: 0.4rem; font-size: 0.95rem; color: rgba(255,255,255,0.82); }
.footer-links a { color: #fff; }
.footer-contact .footer-heading { margin-top: 1.5rem; }
.footer-phone { display: inline-flex; align-items: center; gap: 0.5rem; color: #fff; font-family: var(--font-display); font-weight: 600; font-size: 1.6rem; text-decoration: none; }
.footer-phone:hover { text-decoration: none; color: var(--taupe); }
.footer-phone svg { fill: currentColor; }
.site-footer .legal {
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0.5rem 1.5rem;
  margin-top: 2.5rem; padding-top: 1.25rem; border-top: 1px solid rgba(255,255,255,0.15);
  color: rgba(255,255,255,0.6); font-size: 0.95rem;
}
.legal-links a { color: rgba(255,255,255,0.75); }

/* ---------- Mobile nav drawer (≤880px) ---------- */
@media (max-width: 880px) {
  /* Row 1: logo centered on its own line. Row 2: phone left, hamburger right. */
  .site-header .container { flex-wrap: wrap; row-gap: 0.25rem; }
  .brand { flex: 0 0 100%; justify-content: center; }
  .brand-logo { flex-shrink: 0; }
  .nav-tel { order: 2; margin-right: auto; font-size: 1.35rem; }
  .menu-toggle { display: block; order: 3; }
  .site-nav {
    position: absolute; top: 100%; left: 0; right: 0;
    background: #fff; border-bottom: 1px solid var(--color-border); box-shadow: var(--shadow-md);
    max-height: 0; overflow: hidden; transition: max-height .25s ease;
  }
  .site-nav.is-open { max-height: 80vh; overflow-y: auto; }
  .nav-list { flex-direction: column; align-items: stretch; gap: 0; padding: 0.5rem 1.25rem 1rem; }
  .nav-item > a { padding: 0.85rem 0; }
  .dropdown {
    position: static; transform: none; opacity: 1; visibility: visible; box-shadow: none; border: 0;
    min-width: 0; padding: 0 0 0 1rem; max-height: 0; overflow: hidden; transition: max-height .2s ease;
  }
  .nav-item.expanded .dropdown { max-height: 500px; }
  /* nav.js flags dropdowns whose children are plain text: in the drawer those
     parents navigate instead of expanding, so the caret would promise a
     disclosure that never happens. It still earns its place on desktop, where
     hover reveals the list. */
  .has-dropdown--unlinked > a .nav-caret { display: none; }
  .nav-item.has-dropdown:hover .dropdown { max-height: 0; }
  .nav-item.expanded.has-dropdown:hover .dropdown { max-height: 500px; }
}

/* ---------- Print ---------- */
@media print {
  .site-header, .site-footer, .quote-band, .nav-cta { display: none; }
  body { font-size: 12pt; color: #000; background: #fff; }
}


/* ============================================================ END TEMP */
/* --- Server-side form errors (rendered inline by form.js) -------------------
   Paints its own background rather than inheriting one, because the same rule
   has to read on the dark hero form and the light contact-page form. Shown
   only when form.js has a message; the element is created hidden. */
.form-error {
  margin: 0 0 0.85rem;
  padding: 0.7rem 0.9rem;
  border: 1px solid #f0a9a2;
  border-left: 4px solid #b02a1c;
  border-radius: 6px;
  background: #fdecea;
  color: #7d1a10;
  font-size: 0.95rem;
  line-height: 1.45;
}
.form-error[hidden] { display: none; }
.form-error:focus { outline: 2px solid #b02a1c; outline-offset: 2px; }


/* ===================================================================
   CUSTOM RADON BLOCKS — zoneband (EPA zone map) + compare (active vs
   passive). Ported from the Rochester/Eau Claire radon builds at the
   operator's request; these are NOT template blocks. Rochester's azure
   tokens are remapped onto sage: --orange -> --color-primary,
   --teal-bright -> --accent-on-dark. --section-pad keeps its inline
   fallback, so it needs no definition here.
   =================================================================== */
.zoneband { background: var(--color-bg); padding: var(--section-pad, clamp(3rem, 7vw, 5.5rem)) 0; }
.zoneband h2 { color: var(--color-heading); }
.zoneband-grid { display: grid; gap: clamp(1.5rem, 3vw, 2.75rem); grid-template-columns: 1fr; align-items: start; }
.zoneband-text > :first-child { margin-top: 0; }
.zoneband-figure { margin: 0; }
.zoneband-figure .zonemap { display: block; width: 100%; height: auto; max-width: 420px; margin-inline: auto; }
.zonemap-z1 { fill: var(--navy); }
.zonemap-z2 { fill: var(--color-bg-alt); }
.zonemap-z1, .zonemap-z2, .zonemap-here { stroke: var(--color-bg); stroke-width: 1.6; stroke-linejoin: round; }
/* Steele County keeps the Zone-1 FILL (it genuinely is Zone 1) and is marked by
   outline + dot. Rochester used a bright blue on navy; the sage remap put a dark
   green on a dark green, so the highlight stopped reading. --accent-on-dark is
   the palette tone built to sit on the deep-forest band. */
.zonemap-here { fill: var(--navy); stroke: var(--accent-on-dark); stroke-width: 9; paint-order: stroke; }
.zonemap-dot { fill: #fff; }
.zoneband-legend { list-style: none; margin: 1.25rem 0 0; padding: 0; display: grid; gap: 0.6rem; }
.zoneband-legend li { display: grid; grid-template-columns: 1.1rem 1fr; gap: 0.7rem; align-items: start; font-size: 0.95rem; line-height: 1.45; }
.zoneband-legend .sw { width: 1.1rem; height: 1.1rem; border-radius: 3px; border: 1px solid var(--navy); margin-top: 0.15rem; }
.zoneband-legend .sw--z1 { background: var(--navy); }
.zoneband-legend .sw--z2 { background: var(--color-bg-alt); }
.zoneband-legend .sw--here { background: var(--navy); box-shadow: inset 0 0 0 2px var(--accent-on-dark); position: relative; }
.zoneband-legend .sw--here::after { content: ""; position: absolute; inset: 0; margin: auto; width: 5px; height: 5px; border-radius: 50%; background: #fff; }
.zoneband-legend b { color: var(--color-heading); }
.zoneband-source { margin: 1.1rem 0 0; font-size: 0.85rem; line-height: 1.5; color: var(--color-text-muted); }
.compare { background: var(--navy); color: #fff; padding: var(--section-pad, clamp(3rem, 7vw, 5.5rem)) 0; }
.compare h2 { color: #fff; margin-top: 0; text-align: center; }
.compare-intro { max-width: 68ch; color: rgba(255,255,255,0.92); margin-inline: auto; text-align: left; }
.compare-grid { display: grid; gap: clamp(1.25rem, 2.5vw, 2rem); grid-template-columns: 1fr; margin-top: clamp(1.5rem, 3vw, 2.5rem); }
.compare-item { background: rgba(255,255,255,0.07); border: 1px solid rgba(255,255,255,0.20); border-radius: 8px; padding: clamp(1.1rem, 2.2vw, 1.75rem); }
.compare-item h3 { color: #fff; margin: 1rem 0 0.5rem; font-size: clamp(1.15rem, 2.2vw, 1.4rem); }
.compare-item > p { color: rgba(255,255,255,0.92); margin: 0 0 0.9rem; }
.compare-figure { margin: 0; background: rgba(0,0,0,0.16); border-radius: 6px; padding: 0.75rem; }
.compare-figure .sysdiagram { display: block; width: 100%; max-width: 250px; height: auto; margin-inline: auto; }
.compare-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.5rem; }
.compare-list li { position: relative; padding-left: 1.4rem; font-size: 0.95rem; line-height: 1.5; color: rgba(255,255,255,0.92); }
.compare-list li::before { content: ""; position: absolute; left: 0; top: 0.5em; width: 0.5rem; height: 0.5rem; border-radius: 50%; background: var(--accent-on-dark); }
.compare-note { margin: clamp(1.25rem, 2.5vw, 2rem) auto 0; max-width: 68ch; color: rgba(255,255,255,0.92); text-align: left; }
.sysdiagram-soil { fill: rgba(255,255,255,0.13); }
.sysdiagram-house { fill: rgba(255,255,255,0.06); }
.sysdiagram-struct { fill: none; stroke: rgba(255,255,255,0.55); stroke-width: 2.5; stroke-linejoin: round; }
.sysdiagram-pipe { fill: #fff; }
.sysdiagram-pipe-line { fill: none; stroke: #fff; stroke-width: 20; stroke-linejoin: round; }
.sysdiagram-gas { fill: var(--accent-on-dark); }
.sysdiagram-gas-in { fill: var(--color-primary); }
.sysdiagram-flow { fill: none; stroke: var(--navy); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.sysdiagram-flow--strong { stroke-width: 4.5; }
.sysdiagram-pull { fill: none; stroke: var(--accent-on-dark); stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; }
.sysdiagram-fan { fill: var(--color-primary); stroke: #fff; stroke-width: 2.5; }
.sysdiagram-fan-collar { fill: #fff; }
.sysdiagram-fan-seam { fill: none; stroke: #fff; stroke-width: 2.5; stroke-linecap: round; }
@media (min-width: 880px) { .zoneband-grid { grid-template-columns: 1.25fr 1fr; } }
@media (min-width: 760px) { .compare-grid { grid-template-columns: 1fr 1fr; } }


/* --- Accessibility corrections found by axe on the built page -------------
   The sage palette ships --accent-on-dark exactly for ink on the deep-forest
   bands, but the findlay skin never scoped LINK colour there, so an inline
   tel: link inside .feature-aside / .steps rendered at 1.13-2.06:1 — the worst
   contrast on the page. Prose links also relied on colour alone
   (link-in-text-block), and the step numerals sat at 1.68:1. */
.feature-aside a:not(.btn),
.services-band a:not(.btn),
.spotlight a:not(.btn),
.compare a:not(.btn) { color: var(--accent-on-dark); }

/* .cta-close is a LIGHT band, so it keeps the normal link colour — putting
   --accent-on-dark there was worse than the bug it replaced. The .steps band
   is mid-sage (#55744F), lighter than the deep-forest sections, and
   --accent-on-dark only reaches 2.41:1 on it; white clears AA at 5.24:1. */
.steps a:not(.btn) { color: #fff; }

/* Links inside body prose need a non-colour cue. */
.zoneband-text p a:not(.btn),
.flex-media-text p a:not(.btn),
.feature-aside p a:not(.btn),
.steps p a:not(.btn),
.compare p a:not(.btn),
.spotlight p a:not(.btn),
.faq-body a:not(.btn),
.process-outro a:not(.btn),
.compare-note a:not(.btn),
.cta-close p a:not(.btn) { text-decoration: underline; text-underline-offset: 2px; }

/* Step numerals: --taupe on the mid-sage band is 3.19:1, clearing the 3:1
   large-text threshold (they were 1.68:1). */
.steps .step-num { color: var(--taupe); }

/* Hero "Our Services": normal and hover swapped — solid white by default,
   outline-only on hover. Scoped to the hero so .btn-outline-light keeps its
   usual behaviour anywhere else it is used. */
.hero .hero-cta-row .btn-outline-light {
  background: #fff;
  color: var(--navy);
  border: 2px solid #fff;
}
.hero .hero-cta-row .btn-outline-light:hover {
  background: transparent;
  color: #fff;
  border-color: #fff;
}

/* Hero wash a touch more opaque than the shared --wash-navy (0.62). Scoped to
   the hero: the same token also washes the services band, spotlight and cta
   photo, and those were not part of the request. Same deep-forest --navy
   (#2C3826), only the alpha changes — and a darker wash can only improve the
   white hero copy's contrast, never worsen it. */
.hero::before { background-color: rgba(44, 56, 38, 0.74); }

/* The services band's intro paragraph. The palette's services block had no
   intro, so .process-intro arrived with the pour and inherited body ink
   (#3D4A37) onto the dark photo band — 1.31:1. Every other band either sets
   white at section level (.steps, .feature-aside) or is light (.faq,
   .testimonials), so this was the only one that fell through.

   axe could not catch it: the band's background is an IMAGE, and axe reports
   contrast over background-images as "incomplete" rather than a violation, so
   the clean 0-violation run never covered this element. */
.services-band .process-intro { color: #fff; }

/* Process steps: the ghost numeral is 4.6rem (73.6px) tall at line-height 1,
   but .step only reserved 2.6rem of padding-top, so each title sat 32px inside
   the numeral. Reserve the numeral's full height plus a small gap. */
.steps .step { padding-top: 5rem; }

/* flex-media figures sit top-aligned in their column. The grid is
   align-items: center, which floated each image ~258px down from the top of
   the copy column. Only the figure is re-aligned, so the text column keeps
   its existing behaviour. Covers the --reverse variants too, same class. */
.flex-media .flex-media-figure { align-self: start; }

/* --- Long-form blocks: the figure absorbs the column slack ----------------
   A --long block only reads right when its two columns end near the same
   height. Rather than hand-tuning a crop per section, the figure-bearing
   column becomes a flex column and the figure takes flex: 1 1 0 — it
   contributes ~nothing to intrinsic height, so the ROW height is set by the
   copy, and each figure then grows into whatever space its own column has
   left. Taller column: the image shrinks. Shorter column: it grows. No
   margin-top:auto, so no artificial gap opens between the text and the image.
   min-height keeps it from collapsing when the copy is long. */
.flex-media--long .flex-media-long-col,
.flex-media--long-reverse .flex-media-long-col { display: flex; flex-direction: column; }
.flex-media-long-figure { flex: 0 0 auto; }
/* Long-block figures match the short sections' 4:3 so every photo on the page
   is the same shape. This gives up the flex-absorb balancing, so each --long
   block's copy split has to carry the balance on its own. */
.flex-media-long-figure img { width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover; }
/* the CTA button should not stretch to the column width */
.flex-media-long-col .flex-quote-btn { align-self: flex-start; }

/* Bare URLs printed in text (we don't link out from the home page). Long
   paths must be allowed to break mid-string or they force a horizontal
   scrollbar on narrow screens. */
.bare-url { overflow-wrap: anywhere; word-break: break-word; }

/* Uniform figure dimensions across the short flex-media sections. The source
   photos have mixed aspect ratios — one is portrait (576x768), which rendered
   748px tall next to a 320px neighbour. Lock them all to the 4:3 the Bid
   section already used and let the crop absorb the difference. */
.flex-media .flex-media-figure img {
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

/* --- Icon list markers ---------------------------------------------------
   Check marks instead of disc bullets on the prose lists. CSS cannot pull a
   symbol out of icons.svg, so this is the same Lucide "check" path inlined as
   a data URI and used as a MASK — masking means the glyph takes currentColor,
   so it stays legible on the light zoneband and the dark feature-aside/compare
   bands alike, with no per-band colour to maintain. (CSP allows data: under
   img-src, which is what governs mask-image.) */
.feature-list,
.compare-list,
.zoneband-notes { list-style: none; padding-left: 0; }

.feature-list li,
.compare-list li,
.zoneband-notes li {
  position: relative;
  padding-left: 1.8em;
  margin-bottom: 0.45em;
}

.feature-list li::before,
.compare-list li::before,
.zoneband-notes li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.30em;
  width: 1.05em;
  height: 1.05em;
  background: currentColor;
  opacity: 0.85;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* The base skin bottom-anchors a trailing figure in a --long column
   (.flex-media-long-figure:last-child { margin-top: auto }), which opens a gap
   between the copy and the image. Not wanted here: the image should sit
   directly under the text it belongs to. Note this also means the column's
   real content height is now visible, so the balance check reports the true
   gap rather than one masked by the auto margin. */
.flex-media-long-col > .flex-media-long-figure:last-child { margin-top: 0; }

/* FAQ sits between testimonials and the closing CTA, all three of which fell
   through to the page background, so it read as one long undifferentiated
   stretch. --color-bg-alt is the same pale-sage band the diagnostics/winter/
   ventilation sections already use, so this separates the FAQ without
   introducing a new colour. */
.faq { background: var(--color-bg-alt); }

/* Steps-band CTA row. The band is mid-sage (#55744F), which the standard
   .btn-call fill (#4C6B4E) sits almost on top of — so these two get their own
   treatment: a solid white button with deep-forest ink, and a white outline. */
.steps-cta {
  display: flex; flex-wrap: wrap; gap: 0.9rem;
  justify-content: center; margin-top: 2.5rem;
}
.btn-steps-solid {
  background: #fff; color: var(--navy); border: 2px solid #fff; font-weight: 600;
}
.btn-steps-solid:hover { background: transparent; color: #fff; }
.btn-steps-solid svg { fill: currentColor; }
.btn-steps-outline {
  background: transparent; color: #fff; border: 2px solid #fff; font-weight: 600;
}
.btn-steps-outline:hover { background: #fff; color: var(--navy); }

/* A Free Quote button that lives beside the figure (rather than inside the
   text column) is a THIRD grid child. Auto-placement drops it into row 2
   column 1 in BOTH variants — --reverse only reorders the figure (order: -1),
   it does not move the implicit column — so the button landed bottom-LEFT even
   in blocks where the figure is on the right. Pin it to the figure's column. */
/* Superseded: the button now rides inside .flex-media-figure-col with the
   figure, so it no longer needs column pinning. Left as a note because the
   grid-child approach LOOKED right at a glance — the button did land in the
   correct column, but as a row-2 item it sat below the full height of row 1,
   which the tall copy column sets. That reads as a button stranded far beneath
   its image. */
.flex-media-figure-col { display: flex; flex-direction: column; align-items: flex-start; }
.flex-media--reverse .flex-media-figure-col { order: -1; }   /* image column to the LEFT */
.flex-media-figure-col .flex-quote-btn { margin-top: 2rem; } /* clears the figure's 16px offset frame */

/* "Areas We Serve" reads as a normal subheading rather than a display-scale
   all-caps title: drop the uppercase transform and bring it down to h3 size. */
.spotlight-side-title {
  text-transform: none;
  font-size: 1.5rem;   /* = 24px, matching the site's other h3s */
}

/* A little more opacity on the spotlight photo wash (shared token is 0.62),
   scoped so the hero/services bands keep theirs. */
.spotlight:not(.spotlight--light)::before { background-color: rgba(44, 56, 38, 0.78); }

/* Second heading in the spotlight column (the Owatonna neighbourhood list)
   needs breathing room from the list above it; the first one is fine because
   it opens the column. */
.spotlight-areas + .spotlight-side-title { margin-top: 2rem; }

/* The map SVG and its caption sat flush (0px) — the ported rules zero the
   caption's first child. Give the heading room to read as a title for the
   figure rather than part of it. */
.zoneband-caption { margin-top: 1.25rem; }

/* Brand lockups. The logo is a 3.65:1 horizontal lockup with a transparent
   background, so it composites over the translucent sticky header and the
   deep-forest footer without a colour box. Height is the controlled dimension;
   width follows the aspect so the wordmark never distorts. */
.brand-logo { height: 60px; width: auto; display: block; }
.footer-logo { height: 66px; width: auto; display: block; margin-bottom: 0.9rem; }
@media (max-width: 880px) { .brand-logo { height: 46px; } }

/* Footer brand contact block (under the logo). White ink at graded emphasis on
   the deep-forest footer; the email is long, so let it break mid-string
   rather than widen the column. */
.footer-biz-name { color: #fff; font-family: var(--font-display); font-weight: 600; margin: 0.9rem 0 0.15rem; }
.site-footer address { font-style: normal; color: var(--on-dark-faint); margin: 0 0 0.6rem; }
.footer-contact-line { display: block; color: var(--accent-on-dark); text-decoration: none; margin-bottom: 0.35rem; }
.footer-contact-line:hover { color: #fff; }
.footer-email { overflow-wrap: anywhere; }
.footer-hours { color: var(--on-dark-faint); margin: 0.35rem 0 0; }

/* Optional-field tag on the labeled contact form. */
.label-optional { color: var(--color-text-muted); font-weight: 400; font-size: 0.9em; }

/* Prose links on the legal pages carry a non-colour cue, same as the body
   prose convention on the home page (link-in-text-block). */
.page-narrow p a { text-decoration: underline; text-underline-offset: 2px; }
