/* ============================================================
   Pole Barn — site/style.css  ("rugged warm" skin)
   A block-palette skin of the shared vocabulary, derived from
   _easton-template. Same variable NAMES, new VALUES.
   Palette: warm charcoal + barn red, timber & oat neutrals,
   galvanized steel accents.
   Fonts: Zilla Slab (headings, slab) + Source Sans 3 (body), self-hosted.
   ============================================================ */

/* ---------- Design Tokens ---------- */
:root {
  /* --navy* = warm charcoal darks (header, dark sections, footer, form card) */
  --navy: #2B2A28;               /* dark sections, header, footer */
  --navy-2: #35332F;             /* slightly lighter charcoal panels */
  --navy-card: #3A362F;          /* quote-form card (warm dark) */
  /* --teal* = timber brown — the secondary accent (labels, h3, links, bands) */
  --teal: #6B4E3D;               /* timber — section labels, links on light */
  --teal-bright: #C9A57E;        /* warm tan — timber accent on dark bg */
  /* --orange* = barn red — the primary action color (CTA, phone) */
  --orange: #8C3A2B;             /* barn red — primary CTA, phone accents */
  --orange-bright: #D97A54;      /* warm brick — barn-red accent on dark bg */

  /* PRIMARY FILL vs PRIMARY INK — the opt-in that lets a palette choose its own
     colour structure instead of filling fixed slots.
     --orange must stay dark enough to read as TEXT on light backgrounds
     (.accent, .brand-text b, the faq "+", the button hover state), which caps how
     vivid it can be: the brightest white-safe orange is ~#D04910 at 4.5:1. A
     genuinely straight orange (#F26A1B and up) is only reachable with DARK ink, so
     fills get their own pair. Both DEFAULT to the existing behaviour, so every
     palette shipped before this change renders byte-identically unless it opts in. */
  /* KEYLINE — the offset frame peeking out behind --framed / --long figures and
     .split-media--framed. This is NOT the secondary accent doing accent work: in
     the default skin --teal is timber brown, so the frame reads as a quiet wooden
     keyline. A palette whose secondary is a saturated hue turns the same rule into
     a loud coloured rectangle, which reads as a stray element. Defaults to --teal
     so the default/harvest/walnut skins are unchanged; palettes with a saturated
     secondary point it at a neutral instead. */
  --keyline: var(--teal);
  /* CARD ACCENT — the 4px bar on .faq-item and .testi-quote. In the default skin
     --teal is timber brown, which harmonises with barn red; a palette with a
     SATURATED secondary turns the same two rules into isolated coloured bars on
     white cards that read as stray. Defaults to --teal (default/harvest/walnut
     unchanged); palettes with a saturated secondary point it at the accent. */
  --card-accent: var(--teal);
  /* ON-DARK BUTTON. A warm-led palette (navy + cream) cannot use one button
     colour on both surfaces: a cream button vanishes on a cream page, and forcing
     it dark enough to read there turns it to copper. So dark sections get their
     own pair. Defaults to the light-surface values, leaving every other palette
     byte-identical. */
  --btn-fill-dark: var(--orange-fill);
  --btn-ink-dark: var(--btn-ink);

  --orange-fill: var(--orange);   /* button / badge / node background */
  --btn-ink: #ffffff;             /* ink ON --orange-fill */

  --color-link: var(--teal);
  --color-text: #2E2B27;
  --color-text-muted: #6f6a62;
  --color-heading: #2B2A28;
  --color-bg: #ffffff;
  --color-bg-alt: #F3ECDD;       /* warm oat cream */
  --color-border: #e4ddd0;
  --color-error: #b00020;
  --color-focus: var(--orange);
  --color-fg-on-dark: #ffffff;

  /* barn-red accent used as a decorative RULE/BORDER on dark sections
     (project-card top rule on --navy-2, footer h4 underline on --navy,
     service-card-header inset on --teal). Role split from --orange so a
     palette whose primary is too dark to read on its own dark sections can
     lighten just these accents. DEFAULT aliases --orange, whose barn-red
     melts on the dark bands (1.0–1.9:1) — grandfathered as shipped; the two
     alternates re-derive it to ≥3:1 on navy/navy-2/teal. */
  --accent-frame: var(--orange);

  /* muted warm-neutral inks ON the dark charcoal chrome (top bar + footer) —
     tinted per palette so the chrome tracks the skin. */
  --on-dark-nav: #d9d3c7;        /* top-bar text + links (9.62:1 on --navy) */
  --on-dark-social: #cfc7b8;     /* top-bar social icons (8.55:1) */
  --on-dark-body: #b0a99c;       /* footer body text + legal links (6.15:1) */
  --on-dark-link: #cfc7b9;       /* footer nav + contact links (8.55:1) */
  --on-dark-faint: #8f8879;      /* legal fine print — 4.07:1 on --navy is grandfathered (pre-contract); alternates hit ≥4.5 */
  --on-teal-label: #e6dcc8;      /* pale label ON the timber/teal band (5.55:1 on --teal) */

  /* galvanized-steel corrugated ribbing (hero edge, .metal-edge, steps post
     line) — three-stop rib gradient. Retired the old unused --galvanized
     token in favour of these three consumed stops. Decorative texture (no
     text-contrast requirement); shifted per palette so the corrugation
     tracks the skin's temperature. */
  --metal-1: #767d84;            /* mid rib */
  --metal-2: #9aa2a8;            /* rib highlight */
  --metal-3: #656c73;            /* rib shadow */

  /* photo-overlay washes (tinted darkening over section bg images). The
     charcoal wash tint (30,28,26) is a hair deeper than --navy so photos
     read; re-derived per palette. Low-alpha scrims stay tinted too. */
  --overlay-dark: linear-gradient(rgba(30,28,26,0.82), rgba(30,28,26,0.88));   /* .bg-host default */
  --overlay-teal: linear-gradient(rgba(74,54,42,0.86), rgba(60,44,34,0.92));   /* .bg-host.bg-teal (timber-tinted) */
  --overlay-soft: linear-gradient(rgba(30,28,26,0.55), rgba(30,28,26,0.72));   /* .bg-host.bg-soft (banner) */
  --overlay-scrim: linear-gradient(rgba(30,28,26,0.30), rgba(30,28,26,0.30));  /* flex-media--overlay light scrim */
  --overlay-scrim-strong: linear-gradient(rgba(30,28,26,0.35), rgba(30,28,26,0.35)); /* flex-media--long-center scrim */
  --overlay-panel: rgba(30,28,26,0.78);   /* translucent .overlay-half / .overlay-center text panels */

  /* brand-tinted rings/washes (alpha too high / too saturated to read as
     neutral). NOTE: the default values carry easton's teal (46,112,119) —
     a stale clone leftover kept BYTE-IDENTICAL so the shipped default is
     unchanged; both alternates re-derive them from their own accents. */
  --focus-ring: rgba(46,112,119,0.18);    /* RESERVED — form-validation focus halo; no live rule uses it (see the utility-form note below) */
  --wash-accent: rgba(46,112,119,0.22);   /* .feature-aside-box panel wash */

  /* select placeholder ink + caret data-URI (dark quote-bar / contact form
     selects sit on the --oat field) — re-emitted per palette. */
  --select-ink: #6b7280;
  --select-caret: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%236b7280'><path d='M7 10l5 5 5-5z'/></svg>");

  /* check-bullet / tick data-URIs — a CSS var can't interpolate into a
     data-URI, so each palette re-emits the whole url() with its own fill.
     --bullet-hero rides the DARK hero panel; --bullet-badge/--bullet-snow
     ride LIGHT sections; --tick-timber is the light-bg feature tick (its
     tan 2.2:1 on white is grandfathered decorative — alternates use a
     darker secondary). The white on-dark tick stays a literal (exempt). */
  --bullet-hero: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%23B24A36'/><path d='M17 8.5L10.5 15.5 7 12' fill='none' stroke='white' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  --bullet-badge: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%238C3A2B'/><path d='M17 8.5L10.5 15.5 7 12' fill='none' stroke='white' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  --bullet-snow: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%236B4E3D'/><path d='M17 8.5L10.5 15.5 7 12' fill='none' stroke='white' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  --tick-timber: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M20 6L9 17l-5-5' fill='none' stroke='%23C9A57E' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/></svg>");

  /* extra rugged-skin tokens */
  --oat: #E7DCC7;                /* deeper oat for cards/strips */
  --radius: 0;

  --shadow-sm: 0 1px 3px rgba(43,42,40,0.14);
  --shadow-md: 0 10px 30px rgba(43,42,40,0.18);
  --shadow-lg: 0 18px 50px rgba(43,42,40,0.30);

  --max-w: 1200px;
  --header-h: 80px;

  --font-body: "Source Sans 3", system-ui, -apple-system, "Segoe UI", Arial, sans-serif;
  --font-head: "Cinzel", Georgia, "Times New Roman", serif;
}

/* ============================================================
   ASSEMBLY-TIME PALETTE VARIANTS — the standard every skin follows
   (full contract: templates/_template/CLAUDE.md "Color palettes")
   Default (no attribute) = the warm-charcoal + barn-red pole-barn skin in
   :root above. To build a site in another palette, set the attribute on
   <html>:
       <html lang="en" data-theme="denim">
   Rules of the system (hard requirements for every palette block):
   • FULL-SPECTRUM — override EVERY color role from :root (same role, new
     value), including the on-dark neutrals, metal ribbing, overlays,
     rings, select ink/caret and every check-bullet data-URI. Exemptions:
     white-on-dark inks stay white (--color-fg-on-dark; the literal #fff
     headings/copy/button-ink on .section-dark, .hero, bands and the dark
     form card; the rgba(255,255,255,…) washes; the white card/field/faq
     surfaces on light sections; the white on-dark feature-tick data-URI),
     and the low-alpha NEUTRAL shadows stay un-overridden (--shadow-sm/md/lg
     and the rgba(43,42,40,…)/rgba(0,0,0,…) box + inset shadows, alpha ≤0.30
     — at that opacity they read as neutral). Everything else — the four
     overlay washes, the two scrims + panel, the focus/error rings, the
     select caret and the bullet/tick URIs — 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. The
     pole-barn identity holds: ONE loud PRIMARY action family (--orange*:
     CTAs, phone, step nodes, project tags, decorative rules), a SEPARATE
     secondary (--teal* timber: labels, h3, links, bands, keyline frames),
     warm-neutral chrome darks (--navy*) and a soft section band
     (--color-bg-alt). Nothing reorganizes which role does what.
   • PALETTE SEPARATION — palettes differ at a glance INCLUDING neutrals.
     Primary accents sit apart in hue (barn-red 9° vs denim cobalt 216° vs
     harvest goldenrod 46° vs walnut caramel 29°); the section bands are
     different hue FAMILIES or lightnesses (default warm oat-cream ~41°/91% vs
     denim cool blue-gray ~219° vs harvest olive-wheat ~57° vs walnut warm tan
     ~36°/86%); the dark chrome carries an obvious temperature/depth shift
     (warm charcoal ~40°/4% vs cool slate ~226° vs harvest warm espresso
     ~25°/25%/L13% vs walnut near-black coffee-charcoal ~26°/16%/L9%); and the
     secondaries come from different families (timber-brown 22° vs deep teal
     177° vs olive-bronze 49° vs walnut bronze-brown 33°). Where hue crowds —
     the three WARM palettes' accents (barn-red 9° / goldenrod 46° / caramel
     29°) box each other in — separation is carried by LIGHTNESS/CHROMA per the
     family standard, not hue alone: walnut's caramel is brighter than the
     barn-red, and its coffee-charcoal darks are deeper AND lower-chroma than
     harvest's warm espresso so the two never read the same.
   • CONTRAST — white on --orange/--teal/--navy* fills ≥4.5; --teal &
     --orange as ink on --color-bg AND --color-bg-alt ≥4.5; --orange-bright
     & --teal-bright on --navy AND --navy-2 ≥4.5; --on-teal-label on the
     teal band ≥4.5; every --on-dark-* ink on --navy ≥4.5; --color-text on
     --color-bg ≥7; --color-text-muted on both light bgs ≥4.5; and every
     accent-on-dark DECORATIVE consumer (--accent-frame rules, hero bullet
     circle, feature ticks, --teal-bright frames) ≥3:1. All three alternates
     below pass ALL of these with zero failures. (The DEFAULT's grandfathered
     shortfalls — --on-dark-faint 4.07:1, barn-red --accent-frame melting on
     the dark bands, the 2.7:1 hero bullet and 2.2:1 tan feature tick, and
     --orange-bright's 4.12:1 on --navy-2 — predate this contract and are
     left as shipped; see the token comments.)
   Add a palette by cloning a block below and re-deriving every role. The three
   alternates span the separation standard: denim is a cool COUNTERPOINT to the
   warm default, while harvest and walnut are both WARM — kept apart from each
   other (and the default) by lightness/chroma, not hue (harvest = goldenrod +
   visible-brown espresso darks; walnut = brighter caramel + deeper, cooler
   coffee-charcoal darks + a distinct tan band). Cloning any of them inherits
   the standard: when a new accent hue is boxed in, separate on lightness/chroma.
   ============================================================ */

/* Denim — saturated cobalt-blue primary (216°, a true blue set apart from
   the repo's muted steel 205° / icy cyan 193–195° accents by its high
   chroma) + deep-teal secondary, on a COOL family: slate-indigo darks,
   cool blue-gray band + chrome, cool paper-white page. */
[data-theme="denim"] {
  --card-accent: var(--orange-fill);   /* saturated secondary -> card bars follow the accent */
  --keyline: #4C7271;   /* muted secondary — visible like the default timber frame, without the saturated hue */
  --navy: #232838;               /* slate-indigo dark sections/header/footer (white 14.66:1) */
  --navy-2: #2C3242;             /* lighter slate panels (service/project cards) */
  --navy-card: #2E3446;          /* quote-form card (white 12.38:1) */
  --teal: #316D6A;               /* deep teal secondary — 5.96:1 white-on-fill; 5.61/4.89:1 as ink on bg/bg-alt */
  --teal-bright: #86C0BC;        /* pale teal on dark — 7.18:1 on --navy, 6.26:1 on --navy-2 */
  --orange: #2B579A;             /* cobalt PRIMARY — 7.16:1 white-on-fill; 6.74/5.88:1 as ink on bg/bg-alt */
  --orange-bright: #7CA6DD;      /* light cobalt on dark — 5.83:1 on --navy, 5.09:1 on --navy-2 */

  --color-link: var(--teal);
  --color-text: #23272E;         /* cool near-black body (14.11:1 on bg) */
  --color-text-muted: #565E6A;   /* cool slate muted (6.17/5.38:1 on bg/bg-alt) */
  --color-heading: #1E222C;      /* near-black slate headings (14.98:1) */
  --color-bg: #F7F8FB;           /* cool paper-white page */
  --color-bg-alt: #E4E9F2;       /* cool blue-gray band (hue ~219° — vs default oat-cream and harvest olive) */
  --color-border: #D3D9E4;       /* cool gray-blue border */
  --oat: #DDE3ED;                /* cool blue-gray card/field surface (deeper than --color-bg-alt; text 11.6:1, teal 4.62:1) */
  --color-error: #B0243A;        /* cool crimson, off the blue axis (6.26:1 on bg) */
  --color-focus: var(--orange);
  --color-fg-on-dark: #ffffff;   /* stays white (exempt) */

  --accent-frame: #AEC9EA;       /* pale cobalt decorative rule — ≥3 on navy/navy-2/teal (7.5/8.6/3.5:1) */
  --on-dark-nav: #D2D8E2;        /* top-bar text (10.24:1 on --navy) */
  --on-dark-social: #C8CFDB;     /* top-bar social (9.36:1) */
  --on-dark-body: #A6AEBD;       /* footer body (6.57:1) */
  --on-dark-link: #C8CFDB;       /* footer links (9.36:1) */
  --on-dark-faint: #8892A0;      /* legal fine print (4.65:1) */
  --on-teal-label: #CFE9E6;      /* pale label on the teal band (4.67:1 on --teal) */

  --metal-1: #6E7A88;            /* cool blue-steel rib */
  --metal-2: #97A3B0;            /* rib highlight */
  --metal-3: #5C6673;            /* rib shadow */

  --overlay-dark: linear-gradient(rgba(24,27,38,0.82), rgba(24,27,38,0.88));
  --overlay-teal: linear-gradient(rgba(30,58,56,0.86), rgba(24,48,46,0.92));  /* deep-teal tinted */
  --overlay-soft: linear-gradient(rgba(24,27,38,0.55), rgba(24,27,38,0.72));
  --overlay-scrim: linear-gradient(rgba(24,27,38,0.30), rgba(24,27,38,0.30));
  --overlay-scrim-strong: linear-gradient(rgba(24,27,38,0.35), rgba(24,27,38,0.35));
  --overlay-panel: rgba(24,27,38,0.78);

  --focus-ring: rgba(43,87,154,0.18);     /* from --orange #2B579A */
  --wash-accent: rgba(49,109,106,0.22);   /* from --teal #316D6A */

  --select-ink: #565E6A;
  --select-caret: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23565E6A'><path d='M7 10l5 5 5-5z'/></svg>");

  /* light cobalt circle on the dark hero panel ⇒ dark (navy) check, not white */
  --bullet-hero: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%237CA6DD'/><path d='M17 8.5L10.5 15.5 7 12' fill='none' stroke='%23232838' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  --bullet-badge: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%232B579A'/><path d='M17 8.5L10.5 15.5 7 12' fill='none' stroke='white' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  --bullet-snow: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%23316D6A'/><path d='M17 8.5L10.5 15.5 7 12' fill='none' stroke='white' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  --tick-timber: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M20 6L9 17l-5-5' fill='none' stroke='%23316D6A' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/></svg>");
}

/* Harvest — goldenrod primary (46°, ≥27° off easton copper 19° / orange 15°)
   + olive-bronze secondary, on a WARM but distinctly deeper family than the
   default's pale oat: espresso-brown darks, olive-wheat band, wheat chrome,
   warm ivory page. */
[data-theme="harvest"] {
  --navy: #2A2019;               /* espresso brown-black dark sections (white 15.92:1) */
  --navy-2: #362B22;             /* lighter walnut panels */
  --navy-card: #3A2E24;          /* quote-form card (white 13.16:1) */
  --teal: #5E5320;               /* olive-bronze secondary — 7.68:1 white-on-fill; 7.24/5.98:1 as ink on bg/bg-alt */
  --teal-bright: #C9A94E;        /* gold on dark — 7.03:1 on --navy, 6.08:1 on --navy-2 */
  --orange: #725806;             /* goldenrod PRIMARY — 6.74:1 white-on-fill; 6.35/5.25:1 as ink on bg/bg-alt */
  --orange-bright: #E0A63A;      /* bright amber on dark — 7.34:1 on --navy, 6.35:1 on --navy-2 */

  --color-link: var(--teal);
  --color-text: #292219;         /* warm espresso body (14.80:1 on bg) */
  --color-text-muted: #6B6350;   /* warm taupe muted (5.61/4.64:1 on bg/bg-alt) */
  --color-heading: #241D14;      /* near-black brown headings (15.69:1) */
  --color-bg: #FBF8F0;           /* warm ivory page */
  --color-bg-alt: #E7E5BE;       /* olive-wheat band (hue ~57° — vs default oat-cream and denim blue-gray) */
  --color-border: #D9D3AE;       /* wheat-khaki border */
  --oat: #E4DDB6;                /* deeper wheat card/field surface (text 11.5:1, teal 5.60:1, select-ink 4.83:1) */
  --color-error: #B0242A;        /* warm brick-crimson, clear of the gold axis (6.32:1 on bg) */
  --color-focus: var(--orange);
  --color-fg-on-dark: #ffffff;   /* stays white (exempt) */

  --accent-frame: #E0A63A;       /* bright amber decorative rule — ≥3 on navy/navy-2/teal (7.3/6.4/3.5:1) */
  --on-dark-nav: #E0D6B8;        /* top-bar text (10.98:1 on --navy) */
  --on-dark-social: #D8CDAB;     /* top-bar social (10.04:1) */
  --on-dark-body: #B4AB8C;       /* footer body (6.93:1) */
  --on-dark-link: #D8CDAB;       /* footer links (10.04:1) */
  --on-dark-faint: #938A72;      /* legal fine print (4.64:1) */
  --on-teal-label: #EFE3B4;      /* pale label on the olive band (5.97:1 on --teal) */

  --metal-1: #7C7A72;            /* warm pewter/zinc rib */
  --metal-2: #A19E93;            /* rib highlight */
  --metal-3: #6B6960;            /* rib shadow */

  --overlay-dark: linear-gradient(rgba(30,23,17,0.82), rgba(30,23,17,0.88));
  --overlay-teal: linear-gradient(rgba(60,52,24,0.86), rgba(48,42,20,0.92));  /* olive-bronze tinted */
  --overlay-soft: linear-gradient(rgba(30,23,17,0.55), rgba(30,23,17,0.72));
  --overlay-scrim: linear-gradient(rgba(30,23,17,0.30), rgba(30,23,17,0.30));
  --overlay-scrim-strong: linear-gradient(rgba(30,23,17,0.35), rgba(30,23,17,0.35));
  --overlay-panel: rgba(30,23,17,0.78);

  --focus-ring: rgba(114,88,6,0.18);      /* from --orange #725806 */
  --wash-accent: rgba(94,83,32,0.22);     /* from --teal #5E5320 */

  --select-ink: #645C49;         /* darker so placeholder passes on the wheat --oat field (4.83:1) */
  --select-caret: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23645C49'><path d='M7 10l5 5 5-5z'/></svg>");

  /* bright amber circle on the dark hero panel ⇒ dark (espresso) check */
  --bullet-hero: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%23E0A63A'/><path d='M17 8.5L10.5 15.5 7 12' fill='none' stroke='%232A2019' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  --bullet-badge: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%23725806'/><path d='M17 8.5L10.5 15.5 7 12' fill='none' stroke='white' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  --bullet-snow: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%235E5320'/><path d='M17 8.5L10.5 15.5 7 12' fill='none' stroke='white' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  --tick-timber: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M20 6L9 17l-5-5' fill='none' stroke='%235E5320' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/></svg>");
}

/* Walnut — warm leather/caramel primary (29°, a burnt-caramel set apart from
   the default's barn-red 9° AND its timber secondary 22° by being a clearly
   lighter, more orange leather tone) + muted bronze-brown secondary, on warm
   tan bands + chrome and a tan oat page, over a NEAR-BLACK COFFEE-CHARCOAL dark
   family. Those darks are deliberately deeper AND lower-chroma than harvest's
   warm espresso (walnut --navy #1A1613 L9%/sat16% vs harvest #2A2019
   L13%/sat25%; R-B spread 7 vs 17) so the two warm palettes' dark chrome reads
   distinct at a glance — walnut = coffee-black charcoal, harvest = visible
   brown. Separation from the default here is lightness/chroma, not hue (the
   caramel accent is legitimately boxed between barn-red and goldenrod), per the
   family standard. The whole palette reads walnut/leather next to the default's
   red. */
[data-theme="walnut"] {
  --navy: #1A1613;               /* near-black coffee-charcoal dark sections (white 17.98:1) */
  --navy-2: #241F1B;             /* lighter coffee panels (service/project cards) */
  --navy-card: #292420;          /* quote-form card (white 15.36:1) */
  --teal: #5A4326;               /* bronze-brown secondary — 9.27:1 white-on-fill; 8.71/7.13:1 as ink on bg/bg-alt */
  --teal-bright: #D0A566;        /* warm tan on dark — 7.39:1 on --navy, 6.66:1 on --navy-2 */
  --orange: #8E5016;             /* caramel/leather PRIMARY — 6.35:1 white-on-fill; 5.96/4.88:1 as ink on bg/bg-alt */
  --orange-bright: #D08A44;      /* light caramel on dark — 5.91:1 on --navy, 5.33:1 on --navy-2 */

  --color-link: var(--teal);
  --color-text: #2B2119;         /* warm espresso body (14.78:1 on bg) */
  --color-text-muted: #6B5B49;   /* warm taupe muted (6.13/5.02:1 on bg/bg-alt) */
  --color-heading: #241B12;      /* near-black brown headings (15.90:1) */
  --color-bg: #FDF7EF;           /* warm tan-ivory page */
  --color-bg-alt: #EEE0CB;       /* warm tan band (hue ~36° — deeper & warmer than default oat-cream #F3ECDD 41°/91%; vs denim blue-gray & harvest olive-wheat) */
  --color-border: #DDCEB6;       /* warm tan border */
  --oat: #E0CDB0;                /* deeper tan card/field surface (text 12.6:1, teal 5.97:1, select-ink 4.96:1) */
  --color-error: #B0242A;        /* warm brick-crimson, clear of the caramel axis (6.30:1 on bg) */
  --color-focus: var(--orange);
  --color-fg-on-dark: #ffffff;   /* stays white (exempt) */

  --accent-frame: #D08A44;       /* light caramel decorative rule — ≥3 on navy/navy-2/teal (5.9/5.3/3.3:1) */
  --on-dark-nav: #DBCDB6;        /* top-bar text (10.72:1 on --navy) */
  --on-dark-social: #D2C3A9;     /* top-bar social (9.68:1) */
  --on-dark-body: #B2A488;       /* footer body (6.84:1) */
  --on-dark-link: #D2C3A9;       /* footer links (9.68:1) */
  --on-dark-faint: #948871;      /* legal fine print (4.81:1) */
  --on-teal-label: #E8D3AC;      /* pale label on the bronze band (6.33:1 on --teal) */

  --metal-1: #7E7264;            /* warm bronze/pewter rib */
  --metal-2: #A0937F;            /* rib highlight */
  --metal-3: #6B5F52;            /* rib shadow */

  --overlay-dark: linear-gradient(rgba(20,17,15,0.82), rgba(20,17,15,0.88));   /* a hair deeper than the coffee-charcoal --navy */
  --overlay-teal: linear-gradient(rgba(70,52,30,0.86), rgba(56,42,24,0.92));  /* bronze-brown tinted */
  --overlay-soft: linear-gradient(rgba(20,17,15,0.55), rgba(20,17,15,0.72));
  --overlay-scrim: linear-gradient(rgba(20,17,15,0.30), rgba(20,17,15,0.30));
  --overlay-scrim-strong: linear-gradient(rgba(20,17,15,0.35), rgba(20,17,15,0.35));
  --overlay-panel: rgba(20,17,15,0.78);

  --focus-ring: rgba(142,80,22,0.18);     /* from --orange #8E5016 */
  --wash-accent: rgba(90,67,38,0.22);     /* from --teal #5A4326 */

  --select-ink: #615040;         /* darker so placeholder passes on the tan --oat field (4.96:1) */
  --select-caret: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23615040'><path d='M7 10l5 5 5-5z'/></svg>");

  /* light caramel circle on the dark hero panel ⇒ dark (espresso) check */
  --bullet-hero: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%23D08A44'/><path d='M17 8.5L10.5 15.5 7 12' fill='none' stroke='%231A1613' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  --bullet-badge: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%238E5016'/><path d='M17 8.5L10.5 15.5 7 12' fill='none' stroke='white' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  --bullet-snow: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%235A4326'/><path d='M17 8.5L10.5 15.5 7 12' fill='none' stroke='white' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  --tick-timber: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M20 6L9 17l-5-5' fill='none' stroke='%235A4326' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/></svg>");
}

/* Evergreen — forest-green primary (156°, the empty 140–170° band; deliberately
   ≥19° off the teal 177° that denim's secondary, easton, findlay and immov2 all
   use, and pushed to high chroma so it reads GREEN not teal) + a slate-blue
   secondary, on a cool-green family: pine-black darks (146°/16%/L9%), pale sage
   band, cool green-white page. The most conventionally trade-credible of the new
   palettes — green reads as energy/efficiency without being literal. */
[data-theme="evergreen"] {
  --card-accent: var(--orange-fill);   /* saturated secondary -> card bars follow the accent */
  --keyline: #566F81;   /* muted secondary — visible like the default timber frame, without the saturated hue */
  --navy: #131A16;               /* pine near-black dark sections/header/footer (white 17.69:1) */
  --navy-2: #131915;             /* lighter pine panels (service/project cards) — white 15.56:1 */
  --navy-card: #212B24;          /* quote-form card (white 14.63:1) */
  --teal: #366485;               /* slate-blue secondary — 6.33:1 white-on-fill; 6.01/5.03:1 as ink on bg/bg-alt */
  --teal-bright: #7BA9C9;        /* pale slate-blue — 7.04:1 on --navy, 6.20:1 on --navy-2 */
  --orange: #18734F;             /* forest-green PRIMARY — 5.83:1 white-on-fill; 5.53/4.63:1 as ink on bg/bg-alt */
  --orange-bright: #1C9E6A;      /* saturated accent on dark — 5.18:1 on --navy, 4.56:1 on --navy-2 */

  --color-link: var(--teal);
  --color-text: #222925;         /* body ink (14.12:1 on bg) */
  --color-text-muted: #4F685B;   /* muted ink (5.76/4.82:1 on bg/bg-alt) */
  --color-heading: #1B211E;      /* headings (15.54:1 on bg) */
  --color-bg: #F6FAF7;           /* page */
  --color-bg-alt: #DDE8DF;       /* sage band (hue ~131°) */
  --color-border: #CBD9CD;       /* border */
  --oat: #D2E0D5;                /* card/field surface (text 10.9:1, teal 4.63:1, select-ink 4.95:1) */
  --color-error: #B8232D;        /* crimson, clear of the accent axis (6.01:1 on bg) */
  --color-focus: var(--orange);
  --color-fg-on-dark: #ffffff;   /* stays white (exempt) */

  --accent-frame: var(--orange-bright);   /* ON-DARK rules: the button colour is only 2.6-3.2:1 on the near-black sections */
  --on-dark-nav: #B1C4BA;        /* top-bar text (9.67:1 on --navy) */
  --on-dark-social: #A4BAAF;     /* top-bar social (8.61:1 on --navy) */
  --on-dark-body: #81A090;       /* footer body (6.20:1 on --navy) */
  --on-dark-link: #A4BAAF;       /* footer links (8.61:1 on --navy) */
  --on-dark-faint: #698C7A;      /* legal fine print (4.75:1 on --navy) */
  --on-teal-label: #D7E2EA;      /* pale label on the secondary band (4.81:1 on --teal) */

  --metal-1: #717F7A;            /* cool green-pewter rib */
  --metal-2: #97A5A0;            /* rib highlight */
  --metal-3: #606C68;            /* rib shadow */

  --overlay-dark: linear-gradient(rgba(17,24,20,0.82), rgba(17,24,20,0.88));
  --overlay-teal: linear-gradient(rgba(29,55,73,0.86), rgba(23,44,58,0.92));  /* secondary-tinted */
  --overlay-soft: linear-gradient(rgba(17,24,20,0.55), rgba(17,24,20,0.72));
  --overlay-scrim: linear-gradient(rgba(17,24,20,0.30), rgba(17,24,20,0.30));
  --overlay-scrim-strong: linear-gradient(rgba(17,24,20,0.35), rgba(17,24,20,0.35));
  --overlay-panel: rgba(17,24,20,0.78);

  --focus-ring: rgba(24,115,79,0.18);     /* from --orange #18734F */
  --wash-accent: rgba(54,100,133,0.22);   /* from --teal #366485 */

  --select-ink: #4B6056;         /* passes on the --oat field (4.95:1) */
  --select-caret: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%234B6056'><path d='M7 10l5 5 5-5z'/></svg>");

  /* bright green circle on the dark hero panel ⇒ dark check, not white */
  --bullet-hero: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%2318734F'/><path d='M17 8.5L10.5 15.5 7 12' fill='none' stroke='white' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  --bullet-badge: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%2318734F'/><path d='M17 8.5L10.5 15.5 7 12' fill='none' stroke='white' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  --bullet-snow: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%2318734F'/><path d='M17 8.5L10.5 15.5 7 12' fill='none' stroke='white' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  --tick-timber: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M20 6L9 17l-5-5' fill='none' stroke='%2318734F' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/></svg>");
}

/* Harbor — deliberately reduced to SEVEN values, the operator's specified palette:
     #0F232D navy · #FFF5D0 cream · #1C3846 mid navy · #E9E7D9 greige
     #FFFFFF white (page + card surfaces) · plus #B0242A, the only exception, because the
     contract requires error to stay recognizably red.
   Every other role is reassigned to one of those rather than given its own value.
   The proposed #1B3846 turned out unnecessary — #1C3846 covers every role it would
   have filled, and the two are 0.2% apart in lightness.
   TWO DISTINCTIONS ARE DELIBERATELY GIVEN UP, and they are tradeoffs, not bugs:
     - muted body text is #1C3846 against #0F232D body, only 12.0:1 vs 15.8:1 on the
       page, so paragraph hierarchy is nearly flat;
     - the on-dark chrome collapses from four weights to two (white / greige), so the
       top bar, footer links, footer body and legal fine print no longer differ.
   Both need a mid-tone that this palette does not contain. */
[data-theme="harbor"] {
  --navy: #0F232D;                    /* navy — chrome, dark sections, footer, in-hero form, light-surface buttons */
  --navy-2: #1C3846;                  /* = mid navy — service/project card panels */
  --navy-card: #1C3846;               /* = mid navy — the .quote-bar band under the split hero */
  --teal: #1C3846;                    /* = mid navy — h3, links, labels, card headers */
  --teal-bright: #FFF5D0;             /* = cream — labels on dark */
  --orange: #1C3846;                  /* = mid navy — small accent marks on light (.accent, wordmark, faq +) */
  --orange-bright: #FFF5D0;           /* = cream — the highlight on dark */
  --orange-fill: #0F232D;             /* = navy — button fill on LIGHT surfaces */
  --btn-ink: #FFF5D0;                 /* = cream ink on it (14.80:1) */
  --btn-fill-dark: #FFF5D0;           /* = cream — button fill on DARK surfaces */
  --btn-ink-dark: #0F232D;            /* = navy ink on it (14.80:1) */
  --accent-frame: #FFF5D0;            /* = cream — decorative rules on dark */
  --keyline: #1C3846;                 /* = mid navy — offset frame behind figures */
  --card-accent: #1C3846;             /* = mid navy — faq / testimonial card bars */

  --color-link: var(--teal);
  --color-text: #0F232D;
  --color-heading: #0F232D;
  --color-text-muted: #1C3846;
  --color-bg: #FFFFFF;
  --color-bg-alt: #FFFCF2;   /* alternating band: warm white, not the cream. #FFF5D0 is 100%
                                saturation at L91% — an accent on navy, too yellow as a full section. */
  --color-border: #E9E7D9;
  --oat: #E9E7D9;            /* cards + form fields: greige. Reads on the white page and on the
                                #FFFCF2 band; the earlier objection was greige on a warm-white PAGE. */
  --color-error: #B0242A;
  --color-focus: var(--orange-fill);
  --color-fg-on-dark: #ffffff;

  --on-dark-nav: #FFFFFF;
  --on-dark-social: #FFFFFF;
  --on-dark-body: #E9E7D9;
  --on-dark-link: #FFFFFF;
  --on-dark-faint: #E9E7D9;
  --on-teal-label: #FFF5D0;
  --metal-1: #1C3846;
  --metal-2: #E9E7D9;
  --metal-3: #0F232D;
  --select-ink: #1C3846;

  --overlay-dark: linear-gradient(rgba(15,35,45,0.82), rgba(15,35,45,0.88));
  --overlay-teal: linear-gradient(rgba(28,56,70,0.86), rgba(28,56,70,0.92));
  --overlay-soft: linear-gradient(rgba(15,35,45,0.55), rgba(15,35,45,0.72));
  --overlay-scrim: linear-gradient(rgba(15,35,45,0.30), rgba(15,35,45,0.30));
  --overlay-scrim-strong: linear-gradient(rgba(15,35,45,0.35), rgba(15,35,45,0.35));
  --overlay-panel: rgba(15,35,45,0.78);

  --focus-ring: rgba(15,35,45,0.18);
  --wash-accent: rgba(28,56,70,0.22);

  --select-caret: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%231C3846'><path d='M7 10l5 5 5-5z'/></svg>");

  --bullet-hero: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%23FFF5D0'/><path d='M17 8.5L10.5 15.5 7 12' fill='none' stroke='%230F232D' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  --bullet-badge: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%230F232D'/><path d='M17 8.5L10.5 15.5 7 12' fill='none' stroke='%23FFF5D0' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  --bullet-snow: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%230F232D'/><path d='M17 8.5L10.5 15.5 7 12' fill='none' stroke='%23FFF5D0' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  --tick-timber: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M20 6L9 17l-5-5' fill='none' stroke='%231C3846' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/></svg>");
}

/* Foreman — the operator's trio: #CD4B27 burnt orange as the loud PRIMARY and
   #225777 steel blue as the secondary, used VERBATIM for the blue, on a crisp
   white page with a cool blue-gray band and deep steel-navy darks drawn from the
   #225777 family. The orange sits at #BD4524 — the #CD4B27 family darkened just
   enough to clear 4.5:1 as ink on the band as well as on white (#CD4B27 itself is
   4.53:1 on white, fine on a button, short on the band). NOTE: the operator's
   #C24C3A is only 5° of hue and 1% of lightness from #CD4B27 — the two are the
   same colour in practice, so a single warm primary carries both. Orange + steel
   blue + white is the most standard trade scheme there is. */
[data-theme="foreman"] {
  --card-accent: var(--orange-fill);   /* saturated secondary -> card bars follow the accent */
  --keyline: #577383;   /* muted secondary — visible like the default timber frame, without the saturated hue */
  --navy: #13202B;               /* deep steel navy — white 16.55:1 */
  --navy-2: #17232D;             /* lighter panels (service/project cards) — white 14.32:1 */
  --navy-card: #20313E;          /* quote-form card (white 13.37:1) */
  --teal: #225777;               /* steel-blue secondary (operator #225777, verbatim) — 7.78:1 white-on-fill; 7.78/6.85:1 as ink on bg/bg-alt */
  --teal-bright: #7CAFCF;        /* pale steel-blue on dark — 7.00:1 on --navy, 6.06:1 on --navy-2 */
  --orange: #BD4524;             /* burnt-orange PRIMARY (from #CD4B27) — 5.20:1 white-on-fill; 5.20/4.58:1 as ink on bg/bg-alt */
  --orange-bright: #E17152;      /* saturated accent on dark — 5.27:1 on --navy, 4.56:1 on --navy-2 */

  --color-link: var(--teal);
  --color-text: #262C31;         /* body ink (14.12:1 on bg) */
  --color-text-muted: #576A78;   /* muted ink (5.62/4.95:1 on bg/bg-alt) */
  --color-heading: #1F2428;      /* headings (15.66:1 on bg) */
  --color-bg: #FFFFFF;           /* page */
  --color-bg-alt: #EDF1F4;       /* cool blue-gray band (hue ~206°) */
  --color-border: #D3DCE3;       /* border */
  --oat: #DFE6EB;                /* card/field surface (text 11.2:1, teal 6.17:1, select-ink 4.91:1) */
  --color-error: #BD2731;        /* crimson, clear of the rust axis (6.00:1 on bg) */
  --color-focus: var(--orange);
  --color-fg-on-dark: #ffffff;   /* stays white (exempt) */

  --accent-frame: var(--orange-bright);   /* ON-DARK rules: the button colour is only 2.6-3.2:1 on the near-black sections */
  --on-dark-nav: #BDC7CD;        /* top-bar text (9.62:1 on --navy) */
  --on-dark-social: #B2BDC5;     /* top-bar social (8.65:1 on --navy) */
  --on-dark-body: #91A1AC;       /* footer body (6.22:1 on --navy) */
  --on-dark-link: #B2BDC5;       /* footer links (8.65:1 on --navy) */
  --on-dark-faint: #798C9A;      /* legal fine print (4.75:1 on --navy) */
  --on-teal-label: #BBCEDA;      /* pale label on the secondary band (4.80:1 on --teal) */

  --metal-1: #697B86;            /* cool blue-steel rib */
  --metal-2: #92A1AB;            /* rib highlight */
  --metal-3: #5A6972;            /* rib shadow */

  --overlay-dark: linear-gradient(rgba(17,28,38,0.82), rgba(17,28,38,0.88));
  --overlay-teal: linear-gradient(rgba(18,47,65,0.86), rgba(14,38,52,0.92));  /* secondary-tinted */
  --overlay-soft: linear-gradient(rgba(17,28,38,0.55), rgba(17,28,38,0.72));
  --overlay-scrim: linear-gradient(rgba(17,28,38,0.30), rgba(17,28,38,0.30));
  --overlay-scrim-strong: linear-gradient(rgba(17,28,38,0.35), rgba(17,28,38,0.35));
  --overlay-panel: rgba(17,28,38,0.78);

  --focus-ring: rgba(189,69,36,0.18);     /* from --orange #BD4524 */
  --wash-accent: rgba(34,87,119,0.22);   /* from --teal #225777 */

  --select-ink: #55636D;         /* passes on the --oat field (4.91:1) */
  --select-caret: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2355636D'><path d='M7 10l5 5 5-5z'/></svg>");

  /* light orange circle on the dark hero panel ⇒ dark check, not white */
  --bullet-hero: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%23BD4524'/><path d='M17 8.5L10.5 15.5 7 12' fill='none' stroke='white' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  --bullet-badge: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%23BD4524'/><path d='M17 8.5L10.5 15.5 7 12' fill='none' stroke='white' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  --bullet-snow: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%23BD4524'/><path d='M17 8.5L10.5 15.5 7 12' fill='none' stroke='white' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  --tick-timber: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M20 6L9 17l-5-5' fill='none' stroke='%23BD4524' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/></svg>");
}

/* Ember — burnt orange as the loud PRIMARY on a crisp white page, with
   near-black cool-charcoal darks and a true navy-slate secondary. The primary
   sits at #BB4424, the #CD4B27 family darkened just enough to clear 4.5:1 on the
   warm-gray band as well as on white. Separated from the default barn-red (9°) by
   being brighter and more orange, and from Harbor by its neutrals: Ember is
   white + warm gray + near-black, Harbor is cream + greige + petrol navy. The
   primary-colour scheme — orange, navy, white — that most trade sites reach for. */
[data-theme="ember"] {
  --card-accent: var(--orange-fill);   /* saturated secondary -> card bars follow the accent */
  --keyline: #5C718A;   /* muted secondary — visible like the default timber frame, without the saturated hue */
  --navy: #1B2026;               /* cool near-black charcoal — white 16.39:1 */
  --navy-2: #1D2127;             /* lighter panels (service/project cards) — white 14.28:1 */
  --navy-card: #292F37;          /* quote-form card (white 13.50:1) */
  --teal: #3F6693;               /* navy-slate secondary — 5.94:1 white-on-fill; 5.94/5.14:1 as ink on bg/bg-alt */
  --teal-bright: #8BADD4;        /* pale navy-slate on dark — 7.04:1 on --navy, 6.14:1 on --navy-2 */
  --orange: #BB4424;             /* burnt-orange PRIMARY (from #CD4B27) — 5.30:1 white-on-fill; 5.30/4.58:1 as ink on bg/bg-alt */
  --orange-bright: #E17254;      /* saturated accent on dark — 5.26:1 on --navy, 4.58:1 on --navy-2 */

  --color-link: var(--teal);
  --color-text: #282C31;         /* body ink (14.05:1 on bg) */
  --color-text-muted: #5A6978;   /* muted ink (5.64/4.87:1 on bg/bg-alt) */
  --color-heading: #212428;      /* headings (15.58:1 on bg) */
  --color-bg: #FFFFFF;           /* page */
  --color-bg-alt: #F1EEE9;       /* warm light-gray band (hue ~38°) */
  --color-border: #DCD6CB;       /* border */
  --oat: #E6E1D9;                /* card/field surface (text 10.8:1, teal 4.57:1, select-ink 4.93:1) */
  --color-error: #BD2731;        /* crimson, clear of the rust axis (6.00:1 on bg) */
  --color-focus: var(--orange);
  --color-fg-on-dark: #ffffff;   /* stays white (exempt) */

  --accent-frame: var(--orange-bright);   /* ON-DARK rules: the button colour is only 2.6-3.2:1 on the near-black sections */
  --on-dark-nav: #C0C7CF;        /* top-bar text (9.61:1 on --navy) */
  --on-dark-social: #B4BDC6;     /* top-bar social (8.61:1 on --navy) */
  --on-dark-body: #93A1AE;       /* footer body (6.20:1 on --navy) */
  --on-dark-link: #B4BDC6;       /* footer links (8.61:1 on --navy) */
  --on-dark-faint: #7C8C9C;      /* legal fine print (4.75:1 on --navy) */
  --on-teal-label: #E1E8EF;      /* pale label on the secondary band (4.81:1 on --teal) */

  --metal-1: #6F7880;            /* cool steel rib */
  --metal-2: #969EA6;            /* rib highlight */
  --metal-3: #5F666D;            /* rib shadow */

  --overlay-dark: linear-gradient(rgba(24,28,33,0.82), rgba(24,28,33,0.88));
  --overlay-teal: linear-gradient(rgba(34,56,80,0.86), rgba(27,44,64,0.92));  /* secondary-tinted */
  --overlay-soft: linear-gradient(rgba(24,28,33,0.55), rgba(24,28,33,0.72));
  --overlay-scrim: linear-gradient(rgba(24,28,33,0.30), rgba(24,28,33,0.30));
  --overlay-scrim-strong: linear-gradient(rgba(24,28,33,0.35), rgba(24,28,33,0.35));
  --overlay-panel: rgba(24,28,33,0.78);

  --focus-ring: rgba(187,68,36,0.18);     /* from --orange #BB4424 */
  --wash-accent: rgba(63,102,147,0.22);   /* from --teal #3F6693 */

  --select-ink: #55606C;         /* passes on the --oat field (4.93:1) */
  --select-caret: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2355606C'><path d='M7 10l5 5 5-5z'/></svg>");

  /* light orange circle on the dark hero panel ⇒ dark check, not white */
  --bullet-hero: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%23BB4424'/><path d='M17 8.5L10.5 15.5 7 12' fill='none' stroke='white' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  --bullet-badge: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%23BB4424'/><path d='M17 8.5L10.5 15.5 7 12' fill='none' stroke='white' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  --bullet-snow: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%23BB4424'/><path d='M17 8.5L10.5 15.5 7 12' fill='none' stroke='white' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  --tick-timber: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M20 6L9 17l-5-5' fill='none' stroke='%23BB4424' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/></svg>");
}

/* Blaze — a CUSTOM palette, not a slot-fill. Every other palette in this skin
   fills the same four roles with distinct hues (loud primary + SEPARATE secondary
   hue + tinted darks + tinted band); that structure is what makes them read as
   "several colours" rather than one scheme. Blaze breaks it deliberately: ONE hue
   does all the colour work, and the secondary role — h3s, links, labels — is a
   NEUTRAL warm gray instead of a second hue. Black, white, gray, orange, nothing
   else.
   It is also the first palette to use the --orange-fill / --btn-ink split. White
   ink caps a usable orange at ~#D04910; the split lets the FILL people actually
   see on buttons, step nodes and tags be a genuinely straight #F26A1B carrying
   dark ink at 6.12:1, while --orange stays a legible #C4450F for the few small
   TEXT roles (the faq "+", .accent, .brand-text b, the button hover state). */
[data-theme="blaze"] {
  --navy: #121212;                /* true near-black */
  --navy-2: #1C1A18;              /* lighter panels */
  --navy-card: #201E1B;           /* quote-form card */
  --teal: #4A4441;                /* NEUTRAL warm gray secondary — deliberately not a second hue */
  --teal-bright: #C9C3BE;         /* pale warm gray on dark */
  --orange: #C4450F;              /* TEXT-role orange (must read on light) */
  --orange-bright: #F26A1B;   /* SAME single orange (6.11:1 on --navy) — a separate on-dark tint was the last stray */
  --orange-fill: #F26A1B;         /* THE straight orange — button/node/tag fills */
  --btn-ink: #1A1005;             /* dark ink ON --orange-fill (6.12:1) */

  --color-link: var(--teal);
  --color-text: #22201E;
  --color-text-muted: #635C57;
  --color-heading: #1A1817;
  --color-bg: #FFFFFF;
  --color-bg-alt: #F5F3F1;
  --color-border: #DFDAD5;
  --oat: #E8E4E0;
  --color-error: #B7232D;
  --color-focus: var(--orange-fill);
  --color-fg-on-dark: #ffffff;   /* stays white (exempt) */

  --accent-frame: #F26A1B;
  --on-dark-nav: #CFC9C4;
  --on-dark-social: #C4BDB8;
  --on-dark-body: #A29A94;
  --on-dark-link: #C4BDB8;
  --on-dark-faint: #867E78;
  --on-teal-label: #DDD7D2;
  --metal-1: #7A7570;
  --metal-2: #9E9993;
  --metal-3: #6A6560;

  --overlay-dark: linear-gradient(rgba(16,16,16,0.82), rgba(16,16,16,0.88));
  --overlay-teal: linear-gradient(rgba(41,38,36,0.86), rgba(33,30,29,0.92));  /* neutral-tinted */
  --overlay-soft: linear-gradient(rgba(16,16,16,0.55), rgba(16,16,16,0.72));
  --overlay-scrim: linear-gradient(rgba(16,16,16,0.30), rgba(16,16,16,0.30));
  --overlay-scrim-strong: linear-gradient(rgba(16,16,16,0.35), rgba(16,16,16,0.35));
  --overlay-panel: rgba(16,16,16,0.78);

  --focus-ring: rgba(242,106,27,0.18);
  --wash-accent: rgba(74,68,65,0.22);

  --select-ink: #5C5651;
  --select-caret: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%235C5651'><path d='M7 10l5 5 5-5z'/></svg>");

  /* the vivid fills take DARK checks; the neutral secondary keeps a white one */
  --bullet-hero: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%23F26A1B'/><path d='M17 8.5L10.5 15.5 7 12' fill='none' stroke='%231A1005' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  --bullet-badge: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%23F26A1B'/><path d='M17 8.5L10.5 15.5 7 12' fill='none' stroke='%231A1005' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  --bullet-snow: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%23F26A1B'/><path d='M17 8.5L10.5 15.5 7 12' fill='none' stroke='%231A1005' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  --tick-timber: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M20 6L9 17l-5-5' fill='none' stroke='%23F26A1B' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/></svg>");
}

/* Valley Oak — built for California stucco (Chico / north Sacramento Valley).
   Muted olive PRIMARY + terracotta-clay secondary on a LIMEWASH page: oak-bark
   olive-black darks, near-neutral stone band, pale sage card/field surfaces.
   The read is olive tree + terracotta pot + limewashed wall — the visual
   language of California stucco architecture.

   WHY THE BAND IS NEARLY ACHROMATIC (the whole point of this palette). Stucco
   photography is a large flat field of warm beige at moderate chroma. Every
   other warm palette here puts a SATURATED cream behind those photos — default
   oat 48%S, walnut tan 51%S, harvest wheat 46%S, harbor cream 100%S, all in the
   36-57 degree hue band, which is stucco's own hue. Wall and page land at the
   same hue AND the same value, and the photography stops reading as
   photography. This band sits at the same 47deg/91%L as the default oat but at
   20% saturation — under half — so the beige subject reads as coloured against
   a page that is nearly not. Separation-by-chroma is explicitly sanctioned by
   the contract (see royal's greige, 17%S beside ember's 54%S); it is what keeps
   this from being a fifth near-identical cream.

   SEPARATION FROM EVERGREEN, the other green-led palette: that one is emerald
   (156deg, 65%S) + slate-blue secondary + pine-black darks + mint band — cool
   throughout. This one is army olive (88deg, 30%S) + warm clay secondary +
   olive-black darks + warm stone band. Different chroma class, opposite
   temperature; they do not read as siblings.

   SATURATED SECONDARY, so per the opt-in contract --card-accent follows the
   primary and --keyline drops to a muted stone — an unmuted clay would leave
   stray terracotta bars and frames on white cards. */
[data-theme="valley-oak"] {
  --card-accent: var(--orange-fill);   /* saturated secondary -> card bars follow the primary */
  --keyline: #8E8C77;                  /* muted stone-olive frame — visible like the default timber, without the clay hue */
  --navy: #20241A;               /* oak-bark olive-black — sections/header/footer (white 15.81:1) */
  --navy-2: #282D20;             /* lighter panels — service/project cards (white 14.13:1) */
  --navy-card: #333A29;          /* quote-form card (white 11.81:1) */
  --teal: #9C4B30;               /* terracotta-clay SECONDARY — 6.06:1 white-on-fill; 5.81/5.08:1 as ink on bg/bg-alt */
  --teal-bright: #D98A66;        /* pale clay — 5.85:1 on --navy, 5.23:1 on --navy-2 */
  --orange: #4C6134;             /* muted olive PRIMARY — 6.85:1 white-on-fill; 6.56/5.74:1 as ink on bg/bg-alt */
  --orange-bright: #8FB068;      /* sage accent on dark — 6.46:1 on --navy, 5.77:1 on --navy-2 */

  --color-link: var(--teal);
  --color-text: #262620;         /* body ink (14.57:1 on bg) */
  --color-text-muted: #63645A;   /* muted ink (5.75/5.03:1 on bg/bg-alt) */
  --color-heading: #20241A;      /* headings (15.14:1 on bg) */
  --color-bg: #FBFAF7;           /* limewash page */
  --color-bg-alt: #EDEBE4;       /* stone band (47deg, 20%S — see the note above) */
  --color-border: #DCDACE;       /* border */
  --oat: #E2E0D4;                /* card/field surface (text 12.4:1, teal 4.58:1, select-ink 5.43:1) */
  --color-error: #B0242A;        /* crimson, clear of both accent axes (6.42:1 on bg) */
  --color-focus: var(--orange);
  --color-fg-on-dark: #ffffff;   /* stays white (exempt) */

  /* ON-DARK decorative rules. This one also sits INSET ON THE CLAY BAND
     (.service-card-header), which is the binding constraint: --orange-bright
     clears the dark sections easily but only reaches 2.48:1 on clay, so the
     frame lifts to a pale sage that clears all three surfaces. */
  --accent-frame: #C4D3AC;       /* navy 9.98:1 · navy-2 8.92:1 · clay band 3.83:1 (min 3) */
  --on-dark-nav: #CBCCC0;        /* top-bar text (9.74:1 on --navy) */
  --on-dark-social: #BFC0B3;     /* top-bar social (8.58:1 on --navy) */
  --on-dark-body: #9A9C8D;       /* footer body (5.66:1 on --navy) */
  --on-dark-link: #BFC0B3;       /* footer links (8.58:1 on --navy) */
  --on-dark-faint: #8F927A;      /* legal fine print (4.94:1 on --navy) */
  --on-teal-label: #F5E4DC;      /* pale label on the clay band (4.91:1 on --teal) */

  --metal-1: #7C7F72;            /* warm olive-pewter rib */
  --metal-2: #A0A296;            /* rib highlight */
  --metal-3: #6B6E62;            /* rib shadow */

  --overlay-dark: linear-gradient(rgba(26,29,21,0.82), rgba(26,29,21,0.88));
  --overlay-teal: linear-gradient(rgba(120,58,37,0.86), rgba(96,46,30,0.92));   /* clay-tinted */
  --overlay-soft: linear-gradient(rgba(26,29,21,0.55), rgba(26,29,21,0.72));
  --overlay-scrim: linear-gradient(rgba(26,29,21,0.30), rgba(26,29,21,0.30));
  --overlay-scrim-strong: linear-gradient(rgba(26,29,21,0.35), rgba(26,29,21,0.35));
  --overlay-panel: rgba(26,29,21,0.78);

  --focus-ring: rgba(76,97,52,0.18);      /* from --orange #4C6134 */
  --wash-accent: rgba(156,75,48,0.22);    /* from --teal #9C4B30 */

  --select-ink: #565948;         /* passes on the --oat field (5.43:1) */
  --select-caret: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23565948'><path d='M7 10l5 5 5-5z'/></svg>");

  /* The hero bullet rides the DARK panel, so its circle is squeezed from both
     sides: it must clear 3:1 on --navy while still carrying a white check.
     --orange is 2.31:1 on navy and --orange-bright leaves the check at 2.45:1;
     this mid olive is the value that satisfies both (4.04:1 / 3.92:1). */
  --bullet-hero: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%236B8A4B'/><path d='M17 8.5L10.5 15.5 7 12' fill='none' stroke='white' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  --bullet-badge: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%234C6134'/><path d='M17 8.5L10.5 15.5 7 12' fill='none' stroke='white' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  --bullet-snow: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%239C4B30'/><path d='M17 8.5L10.5 15.5 7 12' fill='none' stroke='white' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  --tick-timber: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M20 6L9 17l-5-5' fill='none' stroke='%239C4B30' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/></svg>");
}

/* ---------- Self-hosted fonts ---------- */
@font-face { font-family:"Source Sans 3"; font-style:normal; font-weight:400 700; font-display:swap; src:url("/fonts/source-sans-3.woff2") format("woff2"); }
@font-face { font-family:"Cinzel"; font-style:normal; font-weight:400 900; font-display:swap; src:url("/fonts/cinzel.woff2") format("woff2"); }

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
html, body { overflow-x: clip; }
:target, section[id] { scroll-margin-top: calc(var(--header-h) + 1rem); }
body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.7;
  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-head);
  font-weight: 700;
  line-height: 1.04;
  margin: 0 0 0.5em;
  color: var(--color-heading);
  text-transform: uppercase;
  letter-spacing: 0.01em;
}
h1 { font-size: clamp(2rem, 4vw, 2.8rem); }
h2 { font-size: clamp(1.6rem, 3vw, 2.05rem); }
h3 { font-size: clamp(1.2rem, 1.9vw, 1.35rem); color: var(--teal); }
h4 { font-size: 1.1rem; }
p { margin: 0 0 1em; }
a { color: var(--color-link); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { text-decoration-thickness: 2px; }
strong { color: inherit; font-weight: 700; }

/* ---------- A11y ---------- */
:focus-visible { outline: 3px solid var(--color-focus); outline-offset: 2px; }
.skip-link {
  position: absolute; left: -10000px; top: auto; width: 1px; height: 1px; overflow: hidden;
  background: var(--navy); color: #fff; padding: 0.75rem 1rem; z-index: 1000;
}
.skip-link:focus { left: 0; top: 0; width: auto; height: auto; }
.hp-field {
  position: absolute !important; width: 1px !important; height: 1px !important; min-width: 0 !important; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
.sr-h2, .visually-hidden {
  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.75rem, 6vw, 4.75rem) 0; }
.section-dark { background: var(--navy); color: var(--color-fg-on-dark); }
.section-dark h2, .section-dark h3, .section-dark h4 { color: #fff; }
.section-dark p { color: rgba(255,255,255,0.82); }
.section-dark a:not(.btn) { color: var(--orange-bright); }
.section-intro { max-width: 78ch; margin: 0 0 2rem; }
.section-cta { display: flex; justify-content: center; margin-top: 2rem; }
.section-label {
  font-family: var(--font-head); font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--teal); font-size: 1.05rem; margin: 0 0 0.4rem;
}
.section-dark .section-label, .lf-banner .section-label { color: var(--teal-bright); }
.lf-banner.b-teal .section-label { color: var(--on-teal-label); }
.accent { color: var(--orange); }
.section-dark .accent { color: var(--orange-bright); }

/* ---------- Gable roofline top edge (post-frame profile) ----------
   Carves a center roof-peak into the section's top edge; the section
   behind (usually white/oat) shows through the notches. Add extra
   top padding so content clears the peak. */
.gable-top {
  --gable: clamp(1.25rem, 3.2vw, 2.75rem);
  clip-path: polygon(0 var(--gable), 50% 0, 100% var(--gable), 100% 100%, 0 100%);
  padding-top: calc(clamp(2.75rem, 6vw, 4.75rem) + var(--gable));
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.55rem;
  font: inherit; font-family: var(--font-head); font-weight: 700; font-size: 0.95rem;
  text-transform: uppercase; letter-spacing: 0.04em;
  padding: 0.7rem 1.6rem; border: 2px solid transparent; border-radius: var(--radius);
  text-decoration: none; cursor: pointer; min-height: 50px; line-height: 1.1;
  transition: background-color .15s ease, color .15s ease, border-color .15s ease, transform .08s ease;
}
.btn:active { transform: translateY(1px); }
/* All .btn variants are SOLID by default and go OUTLINE on hover (inverse
   fill). The .btn 2px border is reserved transparent above, so the swap
   never changes the button's size. (.btn-tel, the header call button, is
   the sole exception — see its own rule below.) */
.btn-call, .btn-primary { background: var(--orange-fill); color: var(--btn-ink); border-color: var(--orange-fill); }
.btn-call:hover, .btn-primary:hover { background: transparent; color: var(--orange); border-color: var(--orange-fill); }
.btn-teal { background: var(--teal); color: #fff; border-color: var(--teal); }
.btn-teal:hover { background: transparent; color: var(--teal); border-color: var(--teal); }
/* white solid — sits on dark backgrounds */
.btn-services, .btn-outline-light { background: #fff; color: var(--navy); border-color: #fff; }
.btn-services:hover, .btn-outline-light:hover { background: transparent; color: #fff; border-color: #fff; }
/* Harbor's on-dark primary IS the cream, so a solid-white secondary next to it reads
   as two light buttons. Outline it there — same reasoning as .btn-outline-dark on the
   light surfaces, where harbor's primary is the navy. */
[data-theme="harbor"] .btn-outline-light { background: transparent; color: #fff; border-color: #fff; }
[data-theme="harbor"] .btn-outline-light:hover { background: #fff; color: var(--navy); border-color: #fff; }
/* In the HERO the secondary takes the mid navy as a solid fill instead of an outline:
   the cream primary is already the loud element, and a filled --navy-card sits quietly
   beside it while still reading against the hero photo (white ink at 12.33:1). */
[data-theme="harbor"] .hero .btn-outline-light {
  background: var(--navy-card); color: #fff; border-color: var(--navy-card);
}
[data-theme="harbor"] .hero .btn-outline-light:hover {
  background: transparent; color: #fff; border-color: #fff;
}
/* dark solid — sits on light backgrounds */
.btn-outline-dark, .btn-outline-navy { background: var(--color-heading); color: #fff; border-color: var(--color-heading); }
.btn-outline-dark:hover, .btn-outline-navy:hover { background: transparent; color: var(--color-heading); border-color: var(--color-heading); }
/* The .btn-*outline* classes are legacy aliases that render SOLID (see CLAUDE.md), which
   works while the PRIMARY is a saturated accent. Harbor's light-surface primary is the navy
   itself, so a solid near-black secondary next to it produced two buttons 3% apart in
   lightness and no hierarchy. Render the secondary as a true outline in that palette only —
   scoped rather than tokenized, because the skin already has more colour slots than it needs. */
[data-theme="harbor"] .btn-outline-dark,
[data-theme="harbor"] .btn-outline-navy { background: transparent; color: var(--color-heading); border-color: var(--color-heading); }
[data-theme="harbor"] .btn-outline-dark:hover,
[data-theme="harbor"] .btn-outline-navy:hover { background: var(--color-heading); color: #fff; border-color: var(--color-heading); }
/* on dark sections the barn-red outline needs the brighter brick to stay legible.
   `background: transparent` is load-bearing: `.section-dark .btn-call` below sets an
   on-dark FILL (--btn-fill-dark) at equal specificity but LATER in the file, so it beats
   the base `.btn-call:hover` transparent. Without restating it here the fill survives the
   hover and the button paints its hover ink on its own fill — invisible in harbor, where
   both resolve to the same cream. */
.hero .btn-call:hover, .section-dark .btn-call:hover, .section-dark .btn-primary:hover,
.section-dark .btn-teal:hover { background: transparent; color: var(--orange-bright); border-color: var(--orange-bright); }
.btn-block { display: flex; width: 100%; }

/* ============================================================
   img-as-background helper (real <img>, positioned to fill)
   ============================================================ */
.bg-host { position: relative; isolation: isolate; }
.bg-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 0; }
.bg-host::before {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: var(--overlay-dark);
}
.bg-host.bg-teal::before { background: var(--overlay-teal); }
.bg-host.bg-soft::before { background: var(--overlay-soft); }
/* Hero: a lighter scrim than the banner --overlay-soft so more of the home photo shows through. */
.hero.hero--form.bg-host::before { background: linear-gradient(rgba(30,28,26,0.35), rgba(30,28,26,0.48)); }
/* Service Areas: lighter scrim than the default --overlay-dark so the Chico landmark shows through. */
.spotlight.bg-host[aria-labelledby="areas-h2"]::before { background: linear-gradient(rgba(30,28,26,0.70), rgba(30,28,26,0.80)); }
.bg-host > .container { position: relative; z-index: 2; }
/* Fixed (parallax) backgrounds — disabled on small/touch screens where iOS renders them badly.
   The hero's parallax uses its CSS background (attachment: fixed, clips to the section);
   its .bg-img is hidden on desktop so the fixed background shows through. */
@media (max-width: 900px) {
  .bg-fixed { background-attachment: scroll !important; }
}

/* ============================================================
   Top bar (navy, scrolls away) + Header (white, sticky)
   ============================================================ */
.top-bar { background: var(--navy); color: var(--on-dark-nav); font-size: 0.9rem; }
.top-bar .container {
  padding-top: 0.5rem; padding-bottom: 0.5rem;
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 0.35rem 1.5rem;
}
.top-bar-list { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem 1.75rem; }
.top-bar-list li { display: inline-flex; align-items: center; gap: 0.5rem; color: var(--on-dark-nav); }
.top-bar-list a { color: var(--on-dark-nav); text-decoration: none; display: inline-flex; align-items: center; gap: 0.5rem; }
.top-bar-list a:hover { color: #fff; }
.top-bar-list svg { color: var(--orange-bright); flex-shrink: 0; }
.top-bar-social { display: inline-flex; align-items: center; gap: 0.9rem; }
.top-bar-social a { color: var(--on-dark-social); display: inline-flex; }
.top-bar-social a:hover { color: #fff; }

.site-header {
  position: sticky; top: 0; z-index: 50;
  background: #fff;
  box-shadow: 0 2px 14px rgba(43,42,40,0.12);
}
.site-header .container {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  min-height: var(--header-h);
}
.brand { display: inline-flex; align-items: center; gap: 0.6rem; text-decoration: none; padding: 0.4rem 0; min-width: 0; }
/* width-driven so height stays auto: the logo scales down proportionally when
   the header is tight (never distorts, never forces the hamburger to wrap) */
.brand-logo { width: 288px; height: auto; max-width: 100%; display: block; }
.brand-text { font-family: var(--font-head); font-weight: 700; text-transform: uppercase; letter-spacing: 0.01em; line-height: 1; font-size: 1.7rem; color: var(--navy); }
.brand-text b { color: var(--orange); font-weight: 700; }
@media (max-width: 600px) { .brand-logo { width: 220px; } .brand-text { font-size: 1.35rem; } }

.site-nav { display: flex; align-items: center; }
.nav-list { display: flex; align-items: center; gap: 0.25rem 1.4rem; flex-wrap: wrap; 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(--navy); text-decoration: none;
  font-family: var(--font-head); font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em;
  font-size: 0.9rem; padding: 1.4rem 0.1rem;
}
.nav-item > a:hover { color: var(--teal); }
.nav-caret { transition: transform .15s ease; flex-shrink: 0; }
.has-dropdown:hover > a .nav-caret, .has-dropdown:focus-within > a .nav-caret { transform: rotate(180deg); }
.dropdown {
  position: absolute; top: 100%; left: 0; min-width: 250px; background: #fff;
  box-shadow: 0 16px 36px rgba(43,42,40,0.22); list-style: none; margin: 0; padding: 0.5rem 0;
  z-index: 100; opacity: 0; visibility: hidden; transform: translateY(6px);
  transition: opacity .15s ease, visibility .15s ease, transform .15s ease;
  border-top: 3px solid var(--orange-fill);
}
.has-dropdown:hover > .dropdown, .has-dropdown:focus-within > .dropdown { opacity: 1; visibility: visible; transform: translateY(0); }
.dropdown li { margin: 0; }
.dropdown a { display: block; padding: 0.55rem 1.1rem; font-size: 0.95rem; font-weight: 500; color: var(--color-text); text-decoration: none; white-space: nowrap; }
.dropdown a:hover, .dropdown a:focus-visible { background: var(--color-bg-alt); color: var(--teal); }
.dropdown-2col, .dropdown-3col { display: grid; }
.dropdown-2col { grid-template-columns: 1fr 1fr; min-width: 440px; }
.dropdown-3col { grid-template-columns: 1fr 1fr 1fr; min-width: 560px; }
@media (max-width: 1100px) { .dropdown-3col { grid-template-columns: 1fr 1fr; min-width: 400px; } }

.nav-cta { margin-left: 0.5rem; }
.btn-tel {
  background: var(--navy); color: #fff; border-radius: var(--radius);
  /* 4px bottom border reserved transparent (bottom padding shortened to
     match) so the hover accent adds NO height — only its color changes */
  padding: 0.7rem 1.5rem calc(0.7rem - 4px); border-bottom: 4px solid transparent;
  font-family: var(--font-head); font-weight: 700; font-size: 1.3rem; letter-spacing: 0.02em;
  text-transform: none; display: inline-flex;
  align-items: center; gap: 0.5rem; min-height: 50px; text-decoration: none;
  white-space: nowrap; flex-shrink: 0;
  transition: border-color .15s ease;
}
/* Narrow-desktop squeeze (nav can wrap to two rows just above the hamburger
   breakpoint): tighten the rows */
@media (min-width: 1025px) and (max-width: 1140px) {
  .nav-item > a { padding-top: 0.45rem; padding-bottom: 0.45rem; }
  .nav-list { gap: 0.25rem 1.1rem; }
}
.btn-tel:hover { border-bottom-color: var(--orange-bright); }

.menu-toggle { display: none; background: transparent; border: 0; padding: 0; width: 44px; height: 44px; align-items: center; justify-content: center; cursor: pointer; }
.menu-toggle span, .menu-toggle span::before, .menu-toggle span::after { display: block; width: 26px; height: 3px; background: var(--navy); border-radius: var(--radius); transition: transform .25s ease, top .25s ease; }
.menu-toggle span { position: relative; }
.menu-toggle span::before, .menu-toggle span::after { content: ""; position: absolute; left: 0; }
.menu-toggle span::before { top: -8px; } .menu-toggle span::after { top: 8px; }
.menu-toggle.is-open span { background: transparent; }
.menu-toggle.is-open span::before { top: 0; transform: rotate(45deg); }
.menu-toggle.is-open span::after { top: 0; transform: rotate(-45deg); }

@media (max-width: 1024px) {
  .top-bar .container { justify-content: center; }
  .top-bar-list { justify-content: center; font-size: 0.82rem; gap: 0.25rem 1.25rem; }
  .site-header .container { flex-wrap: wrap; align-content: center; row-gap: 0; }
  .site-header .brand { min-height: var(--header-h); }
  .site-nav { display: none; }
  .menu-toggle { display: inline-flex; order: 3; }
  .nav-cta { order: 2; }
  .site-nav.is-open {
    display: block; order: 4; flex: 1 1 100%; margin: 0 -1.25rem 0;
    padding: 0.25rem 1.25rem 1rem; background: var(--navy);
  }
  .site-nav.is-open .nav-list { flex-direction: column; align-items: stretch; gap: 0; }
  .site-nav.is-open .nav-item { width: 100%; position: static; }
  .site-nav.is-open .nav-item + .nav-item { border-top: 1px solid rgba(255,255,255,0.15); }
  .site-nav.is-open .nav-item > a { justify-content: space-between; padding: 0.85rem 0; font-size: 1.15rem; color: #fff; }
  .site-nav.is-open .nav-item > a:hover { color: var(--orange-bright); }
  .site-nav.is-open .dropdown { display: none; position: static; opacity: 1; visibility: visible; transform: none; background: transparent; box-shadow: none; border-top: 0; min-width: 0; padding: 0 0 0.5rem 1rem; }
  .site-nav.is-open .has-dropdown.expanded > .dropdown { display: block; }
  .site-nav.is-open .has-dropdown.expanded > a .nav-caret { transform: rotate(180deg); }
  /* 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. */
  .site-nav.is-open .has-dropdown--unlinked > a .nav-caret { display: none; }
  .site-nav.is-open .dropdown a { color: rgba(255,255,255,0.85); padding: 0.4rem 0; white-space: normal; }
  .site-nav.is-open .dropdown a:hover { background: transparent; color: #fff; }
}

/* Narrow screens: keep logo + hamburger together on the top row and drop the
   phone button to its own centered row below (so the hamburger is never bumped
   down and the logo just scales to fit). */
@media (max-width: 720px) {
  .menu-toggle { order: 1; }
  .nav-cta { order: 2; flex: 0 0 100%; justify-content: center; margin: 0.5rem 0 0.75rem; }
}

/* ============================================================
   Hero (full-bleed photo + checklist left, quote card right)
   ============================================================ */
/* ---------- HERO: 50/50 split (Gable layout) ----------
   Solid charcoal type panel left | full-bleed photo right.
   No overlay, no floating form card — the lead form lives in the
   .quote-bar band directly beneath the hero. */
.hero { position: relative; color: #fff; background: var(--navy); padding: 0; }
/* Upward gable triangle rising from the hero's base — full width, apex at
   center. Same charcoal as the type panel, so its left half blends in and
   you only SEE it against the photo half. Sits behind the corrugated edge.
   Scoped OFF .hero--form: over a full-width photo the triangle has no panel
   to blend into, and that variant needs ::before for the .bg-host scrim. */
.hero:not(.hero--form)::before {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  height: clamp(2.5rem, 6vw, 5rem);
  background: var(--navy);
  clip-path: polygon(0 100%, 50% 0, 100% 100%);
  pointer-events: none;
}
/* Signature corrugated-metal edge — galvanized ribbing along the hero base + a barn-red line. */
.hero::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 12px; z-index: 3;
  background:
    linear-gradient(var(--accent-frame), var(--accent-frame)) bottom / 100% 3px no-repeat,
    repeating-linear-gradient(90deg, var(--metal-1) 0 7px, var(--metal-2) 7px 9px, var(--metal-3) 9px 14px);
  box-shadow: inset 0 2px 3px rgba(0,0,0,0.28);
}
/* reusable corrugated divider for other bands (e.g. banner) */
.metal-edge { position: relative; }
.metal-edge::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 11px; z-index: 3;
  background: repeating-linear-gradient(90deg, var(--metal-1) 0 7px, var(--metal-2) 7px 9px, var(--metal-3) 9px 14px);
  box-shadow: inset 0 2px 3px rgba(0,0,0,0.28);
}
.hero-split { display: grid; grid-template-columns: 1fr; }
@media (min-width: 900px) { .hero-split { grid-template-columns: 1.05fr 0.95fr; min-height: min(72vh, 680px); } }
.hero-panel {
  position: relative; z-index: 2;
  display: flex; flex-direction: column; justify-content: center;
  padding: clamp(2.5rem, 6vw, 4.25rem) clamp(1.25rem, 4vw, 3.5rem) clamp(3.25rem, 6vw, 4.5rem);
}
.hero-media { position: relative; min-height: 300px; }
.hero-media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.hero-kicker {
  font-family: var(--font-head); font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.14em; font-size: 1.05rem; color: var(--teal-bright); margin: 0 0 0.75rem;
}
.hero-title { color: #fff; margin: 0 0 clamp(1.25rem, 2.5vw, 1.75rem); font-size: clamp(1.75rem, 2.7vw, 2.4rem); line-height: 1.06; }
.hero-checklist { list-style: none; margin: 0 0 1.75rem; padding: 0; display: grid; gap: 0.55rem 1.5rem; grid-template-columns: 1fr; }
@media (min-width: 560px) { .hero-checklist { grid-template-columns: 1fr 1fr; } }
.hero-checklist li { position: relative; padding-left: 30px; font-weight: 500; line-height: 1.4; }
.hero-checklist li::before {
  content: ""; position: absolute; left: 0; top: 0.05em; width: 20px; height: 20px;
  background-repeat: no-repeat; background-size: contain;
  background-image: var(--bullet-hero);
}
.hero-intro { color: rgba(255,255,255,0.9); margin-bottom: 1.75rem; }
.hero-title + .hero-intro { margin-bottom: 1em; }  /* tighter gap after the first hero paragraph */
.hero-cta-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.85rem; }

/* ---------- HERO--FORM: full-width photo, intro LEFT, quote card RIGHT ----------
   The sibling skins' hero shape in polebarn dress, for sites that want the lead
   form above the fold instead of in the .quote-bar band. Standard .bg-host +
   <img class="bg-img"> scrim (which is why the gable ::before is scoped off this
   variant above); the corrugated ::after edge is kept as the skin marker.
   Overrides .hero's padding:0 — same specificity, later in the file wins. */
.hero--form { padding: clamp(1.5rem, 3.5vw, 2.75rem) 0 clamp(3.5rem, 7vw, 5.5rem); }
.hero-grid { display: grid; gap: clamp(1.75rem, 4vw, 3rem); grid-template-columns: 1fr; }
@media (min-width: 900px) { .hero-grid { grid-template-columns: 1.4fr 0.95fr; align-items: start; } }
/* the split hero's h1 is sized for a narrow panel; over the full container it can run larger */
.hero--form .hero-title { font-size: clamp(1.85rem, 3.2vw, 2.75rem); }
/* hero--form intro runs tighter than the split hero's single lede: reduced
   line-height and a smaller gap between the stacked paragraphs. */
.hero--form .hero-intro { line-height: 1.4; margin-bottom: 0.85rem; }
.hero--form .hero-intro:last-of-type { margin-bottom: 1.25rem; }
/* hero--form: kicker + h1 sit ABOVE both columns, full container width, so the
   headline is not boxed into the narrow intro column beside the form. */
.hero--form .hero-head { margin-bottom: 10px; }
.hero--form .hero-head .hero-title { margin-bottom: 0; }

/* ---------- Estimate / quote form card (kept for contact page + card-variant assemblies) ---------- */
.estimate-card { background: var(--navy-card); color: #fff; padding: clamp(1.5rem, 3vw, 2.25rem); border-radius: var(--radius); box-shadow: var(--shadow-lg); }
/* The hero--form treatment puts the quote form INSIDE the hero, where a separate
   card tone is a third dark for no gain — it reads as a panel on the hero rather
   than part of it. The standalone .quote-bar band under the split hero keeps
   --navy-card, since there it genuinely separates two stacked sections. */
.hero .estimate-card { background: var(--navy); }
.estimate-card .quote-mark { color: var(--orange-bright); margin-bottom: 0.25rem; }
.estimate-title { font-family: var(--font-head); font-weight: 700; text-transform: uppercase; font-size: clamp(1.35rem, 2.4vw, 1.7rem); line-height: 1.1; color: #fff; margin: 0 0 1.25rem; letter-spacing: 0.01em; }
.estimate-head { display: flex; align-items: center; gap: 0.65rem; margin: 0 0 1.25rem; }
.estimate-head .quote-mark { margin: 0; display: inline-flex; }
.estimate-head .estimate-title { margin: 0; }
.estimate-form { display: grid; gap: 0.7rem; grid-template-columns: 1fr 1fr; }
.estimate-form > .full, .estimate-form textarea, .estimate-form select, .estimate-form button, .estimate-form .cf-turnstile { grid-column: 1 / -1; }
/* Hard-locked Turnstile slot: the widget renders INTO this fixed box and can
   never resize the form / re-scale the hero background during its boot (the
   async iframe has no intrinsic height — the "hero hop"). display:block on
   the iframe kills the inline-gap that otherwise pads the box past 65px. */
.cf-turnstile { height: 65px; width: 300px; max-width: 100%; overflow: hidden; }
.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); } }

.estimate-form input, .estimate-form select, .estimate-form textarea {
  font: inherit; width: 100%; min-height: 48px; padding: 0.7rem 0.9rem;
  border: 0; border-radius: var(--radius); background: var(--oat); color: var(--color-text);
}
.estimate-form select { color: var(--select-ink); appearance: none; background-image: var(--select-caret); background-repeat: no-repeat; background-position: right 0.7rem center; padding-right: 2.2rem; }
.estimate-form textarea { min-height: 96px; resize: vertical; }
.estimate-form input:focus, .estimate-form select:focus, .estimate-form textarea:focus { outline: 3px solid var(--color-focus); outline-offset: 1px; }
.estimate-form button[type="submit"] {
  background: var(--btn-fill-dark); color: var(--btn-ink-dark); font: inherit; font-family: var(--font-head);
  font-weight: 700; font-size: 1.05rem; text-transform: uppercase; letter-spacing: 0.06em; padding: calc(0.85rem - 2px); border: 2px solid var(--btn-fill-dark);
  border-radius: var(--radius); cursor: pointer; min-height: 52px; display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  transition: background-color .15s ease, color .15s ease, border-color .15s ease;
}
.estimate-form button[type="submit"]:hover { background: transparent; color: var(--orange-bright); border-color: var(--orange-bright); }

/* Buttons on DARK surfaces (hero panel, .section-dark, the quote-bar / estimate
   card, feature-aside boxes). Same values as the light button unless a palette
   overrides the pair — see --btn-fill-dark. */
.section-dark .btn-call, .section-dark .btn-primary,
.hero .btn-call, .hero .btn-primary {
  background: var(--btn-fill-dark); color: var(--btn-ink-dark); border-color: var(--btn-fill-dark);
}

/* ---------- QUOTE-BAR: the lead form as a horizontal band under the hero ----------
   (Overrides live AFTER the base .estimate-form rules — same specificity, later wins.) */
.quote-bar { background: var(--navy-card); color: #fff; padding: clamp(1.75rem, 3.5vw, 2.75rem) 0; border-bottom: 4px solid var(--accent-frame); }
.quote-bar .estimate-head { margin-bottom: 1rem; }
.estimate-form--bar { grid-template-columns: repeat(4, 1fr); align-items: start; }
.estimate-form--bar > .full { grid-column: auto; }        /* name/address become normal row cells */
.estimate-form--bar textarea { grid-column: 1 / -1; min-height: 72px; }
.estimate-form--bar .cf-turnstile { grid-column: 1 / 3; }
.estimate-form--bar button[type="submit"] { grid-column: 3 / -1; align-self: stretch; }
@media (max-width: 880px) {
  .estimate-form--bar { grid-template-columns: 1fr 1fr; }
  .estimate-form--bar > .full, .estimate-form--bar .cf-turnstile, .estimate-form--bar button[type="submit"] { grid-column: 1 / -1; }
}

/* ============================================================
   Feature bands (navy + teal): icon + heading + text triplets
   ============================================================ */
.feature-band { background: var(--navy); color: #fff; padding: clamp(2.25rem, 4vw, 3rem) 0; }
.feature-band.band-teal { background: var(--teal); }
.feature-grid { display: grid; gap: clamp(1.5rem, 3vw, 2.5rem); grid-template-columns: 1fr; }
@media (min-width: 760px) { .feature-grid { grid-template-columns: repeat(3, 1fr); } }
.feature-item { display: grid; grid-template-columns: auto 1fr; gap: 0 1rem; align-items: start; }
.feature-item .feature-ico { grid-row: span 2; color: #fff; }
.feature-band.band-navy .feature-item .feature-ico { color: var(--teal-bright); }
.feature-item h3 { color: #fff; margin: 0 0 0.35rem; font-size: 1.4rem; }
.feature-item p { color: rgba(255,255,255,0.82); margin: 0; font-size: 0.95rem; line-height: 1.55; }

/* ============================================================
   Split content (About / Story): media + text + check badges
   ============================================================ */
.split { background: var(--color-bg); }
.split-alt { background: var(--color-bg-alt); }
.split-grid { display: grid; grid-template-columns: 1fr; gap: clamp(1.75rem, 4vw, 3.25rem); align-items: center; }
@media (min-width: 900px) { .split-grid { grid-template-columns: 1fr 1fr; } }
.split-grid.media-right .split-media { order: -1; }
@media (min-width: 900px) { .split-grid.media-right .split-media { order: 2; } }
.split-media img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: var(--radius); box-shadow: var(--shadow-md); }
.split h2 { color: var(--color-heading); }
.badge-grid { list-style: none; margin: 1.5rem 0 1.75rem; padding: 0; display: grid; gap: 0.55rem 1.5rem; grid-template-columns: 1fr; }
@media (min-width: 520px) { .badge-grid { grid-template-columns: 1fr 1fr; } }
.badge-grid li { position: relative; padding-left: 28px; font-weight: 600; color: var(--navy); line-height: 1.4; }
.badge-grid li::before {
  content: ""; position: absolute; left: 0; top: 0.1em; width: 18px; height: 18px;
  background-repeat: no-repeat; background-size: contain;
  background-image: var(--bullet-badge);
}
.split-cta-row { display: flex; flex-wrap: wrap; gap: 0.85rem; align-items: center; }
/* optional offset keyline box behind the split's image — the same treatment
   the --framed / --long flex-media family wears. Frame hangs off the corner
   AWAY from the copy (bottom-right when the image sits right, bottom-left
   when it sits left), and the grid reserves that 14px so it never clips. */
.split-media--framed { position: relative; }
.split-media--framed::after {
  content: ""; position: absolute; inset: 14px -14px -14px 14px;
  border: 3px solid var(--keyline); border-radius: var(--radius); z-index: 0; pointer-events: none;
}
.split-media--framed img { position: relative; z-index: 1; }
.split-grid.media-right:has(> .split-media--framed) { padding: 0 14px 14px 0; }
.split-grid:not(.media-right) > .split-media--framed::after { inset: 14px 14px -14px -14px; }
.split-grid:not(.media-right):has(> .split-media--framed) { padding: 0 0 14px 14px; }
@media (max-width: 899px) {
  .split-media--framed::after { inset: 10px -8px -8px 10px; }
  .split-grid:not(.media-right) > .split-media--framed::after { inset: 10px 10px -8px -8px; }
}

/* ============================================================
   How it works strip (teal)
   ============================================================ */
.howitworks { background: var(--teal); color: #fff; padding: clamp(1.75rem, 3.5vw, 2.5rem) 0; }
.hiw-grid { display: grid; grid-template-columns: 1fr; gap: 1.25rem 2rem; align-items: center; text-align: center; }
@media (min-width: 760px) { .hiw-grid { grid-template-columns: auto repeat(3, 1fr); text-align: left; } }
.hiw-title { font-family: var(--font-head); font-weight: 700; text-transform: uppercase; font-size: 1.7rem; color: #fff; margin: 0; }
.hiw-step { display: inline-flex; align-items: center; gap: 0.6rem; justify-content: center; font-family: var(--font-head); font-weight: 700; text-transform: uppercase; letter-spacing: 0.02em; font-size: 1.25rem; color: #fff; }
@media (min-width: 760px) { .hiw-step { justify-content: flex-start; } }
.hiw-step svg { color: #fff; flex-shrink: 0; }
.hiw-step a { color: #fff; text-decoration: none; }
.hiw-step a:hover { text-decoration: underline; }

/* ============================================================
   Services grid (shared vocab: header + image + description)
   Dark section.
   ============================================================ */
.services-head { text-align: center; max-width: 64ch; margin: 0 auto 2.25rem; }
.services-head .section-label, .services-head h2 { text-align: center; }
.services-head .section-label { color: var(--orange-bright); }
.section-dark .services-head h2 { color: #fff; margin-bottom: 0.5rem; }
/* Mosaic rows: the FIRST TWO cards form a row of 2 (wider, taller images);
   every card after flows into rows of 3. Works for any card count. */
.services-grid { display: grid; gap: 1.25rem; grid-template-columns: 1fr; margin-top: 0.5rem; }
@media (min-width: 600px) {
  .services-grid { grid-template-columns: 1fr 1fr; }
}
@media (min-width: 940px) {
  .services-grid { grid-template-columns: repeat(6, 1fr); }
  .service-card { grid-column: span 2; }
  /* first row AND last row show as a wide "row of 2" (each half-width); the
     middle cards run 3-per-row. Works out gap-free at 10 cards: 2 / 3 / 3 / 2. */
  .service-card:nth-child(-n+2),
  .service-card:nth-last-child(-n+2) { grid-column: span 3; }
}
.service-card {
  display: flex; flex-direction: column; background: var(--navy-2);
  border: 1px solid rgba(255,255,255,0.10); border-radius: var(--radius); overflow: hidden;
  transition: transform .12s ease, border-color .15s ease, box-shadow .15s ease;
}
.service-card:hover { transform: translateY(-3px); border-color: var(--teal-bright); box-shadow: 0 12px 28px rgba(0,0,0,0.35); }
.service-card-header {
  background: var(--teal); color: #fff; padding: 0.75rem 1.25rem; margin: 0; text-align: left;
  font-family: var(--font-head); font-size: 1.4rem; font-weight: 700; letter-spacing: 0.01em;
  text-transform: uppercase; line-height: 1.15;
  /* This header sits on --teal, the ONLY surface --accent-frame ever touched that
     is not the navy family. Requiring one accent to contrast against BOTH the
     near-black darks and a mid-dark secondary is what forced every palette's
     accent to a washed-out pastel. The rule belongs to this surface's own family. */
  box-shadow: inset 0 -3px 0 var(--on-teal-label);
}
.service-card-body { padding: 1.25rem; display: flex; flex-direction: column; flex: 1; gap: 0.9rem; }
.service-card-body img {
  width: calc(100% + 2.5rem); max-width: none; margin: -1.25rem -1.25rem 0;
  aspect-ratio: 16 / 9; object-fit: cover; border-radius: 0;
}
.service-card-body p { color: rgba(255,255,255,0.80); margin: 0; font-size: 1rem; }
/* first-row (of 2) cards keep their wider span, but h3 + body match the rest */
@media (min-width: 940px) {
  .service-card:nth-child(-n+2) .service-card-header { font-size: 1.4rem; }
  .service-card:nth-child(-n+2) .service-card-body p { font-size: 1rem; }
}

/* ============================================================
   Long-form banner sections (installation / repair / demolition / decorative)
   ============================================================ */
.lf-banner { color: #fff; padding: clamp(2.5rem, 5vw, 4rem) 0; }
.lf-banner.b-navy { background: var(--navy); }
.lf-banner.b-teal { background: var(--teal); }
.lf-banner-grid { display: grid; grid-template-columns: 1fr; gap: clamp(1.75rem, 4vw, 3rem); align-items: center; }
@media (min-width: 900px) { .lf-banner-grid { grid-template-columns: 1.05fr 0.95fr; } }
.lf-banner-grid.media-right .lf-media { order: -1; }
@media (min-width: 900px) { .lf-banner-grid.media-right .lf-media { order: 2; } }
.lf-media img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: var(--radius); box-shadow: var(--shadow-lg); }
.lf-banner h2 { color: #fff; }
.lf-banner p { color: rgba(255,255,255,0.85); }
.lf-sub-h { font-family: var(--font-head); font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: #fff; font-size: 1.2rem; margin: 1.5rem 0 0.75rem; }
.lf-body { background: var(--color-bg); }
.lf-body.body-alt { background: var(--color-bg-alt); }
.lf-body h2 { color: var(--color-heading); }
.lf-body h3 { color: var(--teal); margin-top: 1.75rem; }
.lf-prose { max-width: 82ch; }
.lf-prose.center { margin: 0 auto; }

/* ============================================================
   Check / feature lists
   ============================================================ */
.feature-list { list-style: none; margin: 0.75rem 0 0; padding: 0; font-size: 0.97rem; }
.feature-list li { position: relative; padding-left: 28px; margin-bottom: 0.65rem; line-height: 1.5; }
.feature-list li strong { color: var(--color-heading); }
.feature-list li::before {
  content: ""; position: absolute; left: 0; top: 0.2em; width: 16px; height: 16px;
  background-repeat: no-repeat; background-size: contain;
  background-image: var(--tick-timber);
}
.lf-banner .feature-list li, .section-dark .feature-list li { color: rgba(255,255,255,0.9); }
.lf-banner .feature-list li strong, .section-dark .feature-list li strong { color: #fff; }
.lf-banner .feature-list li::before, .section-dark .feature-list li::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M20 6L9 17l-5-5' fill='none' stroke='%23ffffff' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/></svg>"); }
.feature-list-2col, .feature-list-3col { display: grid; gap: 0 1.75rem; grid-template-columns: 1fr; }
@media (min-width: 600px) { .feature-list-2col, .feature-list-3col { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1000px) { .feature-list-3col { grid-template-columns: 1fr 1fr 1fr; } }
.inline-cta { margin-top: 1.5rem; display: inline-flex; }

/* ============================================================
   FAQ (navy panel with accordion)
   ============================================================ */
/* FAQ: LIGHT two-column — intro column (sticky on desktop) left,
   accordion of white cards right, on the oat section bg. */
.faq { background: var(--color-bg-alt); }
.faq-grid { display: grid; grid-template-columns: 1fr; gap: clamp(1.75rem, 4vw, 3.5rem); align-items: start; }
@media (min-width: 880px) {
  .faq-grid { grid-template-columns: 0.85fr 1.4fr; }
  .faq-intro { position: sticky; top: calc(var(--header-h) + 1.5rem); }
}
.faq-intro h2 { margin-bottom: 0.75rem; }
.faq-intro p { color: var(--color-text); max-width: 45ch; }
.faq-intro .btn { margin-top: 0.75rem; }
.faq-list { display: flex; flex-direction: column; gap: 0.75rem; }
.faq-item { background: #fff; border: 1px solid var(--color-border); border-left: 4px solid var(--card-accent); border-radius: var(--radius); box-shadow: var(--shadow-sm); }
.faq-item > summary { list-style: none; cursor: pointer; padding: 1rem 1.15rem; font-family: var(--font-head); font-weight: 700; text-transform: uppercase; letter-spacing: 0.01em; color: var(--color-heading); font-size: 1.2rem; 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.7rem; color: var(--orange); flex-shrink: 0; line-height: 1; }
.faq-item[open] > summary::after { content: "\2212"; }
.faq-item > .faq-body { padding: 0 1.15rem 1.1rem; color: var(--color-text); }
.faq-item > .faq-body ul { margin: 0.5rem 0; padding-left: 1.1rem; }
.faq-item > .faq-body a { color: var(--teal); }

/* ============================================================
   Final CTA (photo bg + centered quote card)
   ============================================================ */
.final-cta { color: #fff; padding: clamp(3rem, 6vw, 5rem) 0; }
.final-cta .estimate-card { max-width: 560px; margin: 0 auto; }

/* ============================================================
   Footer (navy + wood strip)
   ============================================================ */
.site-footer { background: var(--navy); color: var(--on-dark-body); padding: 3.25rem 0 1.5rem; border-top: 4px solid var(--accent-frame); }
.footer-grid { display: grid; gap: 2rem; grid-template-columns: 1fr; align-items: start; }
@media (min-width: 700px) { .footer-grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1000px) { .footer-grid { grid-template-columns: 1fr 1.9fr 1.35fr 0.95fr; } }
.footer-brand-logo { display: inline-block; text-decoration: none; }
.footer-brand-logo img { width: 100%; height: auto; display: block; }
/* knockout footer logo: width-driven so height stays auto (never distorts),
   capped so it doesn't fill the whole column */
.footer-brand-logo .footer-brand-img { width: 100%; height: auto; max-width: 260px; }
/* text wordmark fallback in the footer (dark bg): knockout white + brick accent */
.footer-brand-logo .brand-text { color: #fff; font-size: 1.9rem; }
.footer-brand-logo .brand-text b { color: var(--orange-bright); }
/* --boxed: for dark/color logos that need a white plate (no knockout version available) */
.footer-brand-logo--boxed { background: #fff; padding: 0.9rem 1rem; border-radius: var(--radius); display: inline-block; }
.footer-brand-logo--boxed img { height: 70px; width: auto; }
.footer-col h3 { color: #fff; margin: 0 0 1rem; padding-bottom: 0.5rem; position: relative; font-size: 1.3rem; }
.footer-col h3::after { content: ""; position: absolute; left: 0; bottom: 0; width: 38px; height: 3px; background: var(--accent-frame); }
.footer-col ul { list-style: none; padding: 0; margin: 0; }
.footer-col li { margin-bottom: 0.6rem; }
.footer-links a { color: var(--on-dark-link); text-decoration: none; display: inline-flex; align-items: center; gap: 0.6rem; }
.footer-links a:hover { color: #fff; }
.footer-links svg { color: var(--orange-bright); flex-shrink: 0; }
.footer-col ul.footer-col-links { margin-top: 2.25rem; }
.footer-list-plain { list-style: none; padding: 0; margin: 0; }
.footer-list-plain li { color: var(--on-dark-body); margin-bottom: 0.4rem; font-size: 0.88rem; line-height: 1.35; }
.footer-areas-list { columns: 2; column-gap: 1.5rem; }
.footer-areas-list li { break-inside: avoid; }
/* Our Services is a long list too — run it in two columns so the footer
   columns balance instead of one tall stack. */
.footer-services-list { columns: 2; column-gap: 1.5rem; }
.footer-services-list li { break-inside: avoid; }
.footer-contact-list li { display: flex; align-items: flex-start; gap: 0.6rem; line-height: 1.5; }
.footer-contact-list a, .footer-contact-list span { color: var(--on-dark-link); text-decoration: none; display: inline-flex; align-items: flex-start; gap: 0.6rem; }
.footer-contact-list a:hover { color: #fff; }
.footer-contact-list svg { color: var(--orange-bright); flex-shrink: 0; margin-top: 0.18em; }
.footer-phone { font-family: var(--font-head); font-weight: 700; font-size: 1.7rem; color: var(--orange-bright); text-decoration: none; }
.footer-phone:hover { color: #fff; }
.footer-phone-lead { margin: 0 0 1.5rem; }
/* company name under the footer logo, above the NAP block */
.footer-company { color: #fff; font-family: var(--font-head); font-weight: 700; font-size: 1rem; line-height: 1.15; text-transform: uppercase; letter-spacing: 0.02em; margin: 1rem 0 1rem; }
.legal { margin-top: 2.5rem; padding-top: 1.25rem; 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: 0.75rem 1.5rem; justify-content: space-between; }
.legal a { color: var(--on-dark-body); text-decoration: none; margin-right: 1rem; }
.legal a:hover { color: #fff; }

/* ============================================================
   Contact / utility forms (contact.html etc.)
   ============================================================ */
.page-narrow { max-width: 820px; margin: 0 auto; }
.page-hero { background: var(--navy); color: #fff; padding: clamp(2.5rem, 5vw, 3.75rem) 0; border-bottom: 4px solid var(--accent-frame); }
.page-hero h1 { color: #fff; }
.page-hero p { color: rgba(255,255,255,0.85); margin: 0; }
.breadcrumb { font-size: 0.9rem; color: rgba(255,255,255,0.7); margin-bottom: 0.5rem; }
.breadcrumb a { color: rgba(255,255,255,0.85); text-decoration: none; }
.breadcrumb a:hover { color: #fff; }
/* NOTE: the label/fieldset "utility-form" styles (.form-card / .form-grid /
   .field / .req / .help / .error / .form-footnote) were removed — this skin's
   contact page uses the .estimate-card + .estimate-form pattern, so they were
   dead in every page. They were inherited from a sibling skin. If a utility
   form is ever added here, style it as .estimate-form rather than reviving
   them. The --color-error / --focus-ring tokens are deliberately KEPT (see
   :root) — they are part of the 4-palette token contract and are the values a
   form-validation state would use. */
.contact-info { list-style: none; margin: 1.5rem 0 0; padding: 0; display: grid; gap: 0.85rem; }
.contact-info li { display: flex; align-items: flex-start; gap: 0.7rem; line-height: 1.4; }
.contact-info svg { color: var(--teal); flex-shrink: 0; margin-top: 0.12em; }
.contact-info a { color: var(--color-text); text-decoration: none; }
.contact-info a:hover { color: var(--teal); }
.nap address { font-style: normal; line-height: 1.7; }
.prose h2 { margin-top: 2rem; }
.prose h3 { margin-top: 1.5rem; color: var(--teal); }

/* ---------- Utility page simple nav ---------- */
.site-nav.simple { gap: 2rem; }
.site-nav.simple a { color: var(--navy); font-family: var(--font-head); font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; text-decoration: none; font-size: 1.15rem; }
.site-nav.simple a:hover { color: var(--teal); }
@media (max-width: 900px) { .site-nav.simple { display: none; } }

/* ============================================================
   SHARED BLOCK VOCABULARY (Gable / rugged-warm skin)
   The global blocks the assembler fills. Extras (feature-band,
   lf-banner) keep their own sections above.
   ============================================================ */

/* ---------- Flex-media (workhorse: overlapping offset card) ----------
   Desktop: the image bleeds wide on its side and the TEXT sits in an
   offset card that overlaps it by one grid column. Default = card left /
   image right; --reverse mirrors. Mobile stacks normally. */
/* The light-surface backgrounds of the flex-media family are declared AFTER
   .section-dark at the same specificity, so a plain `.flex-media.section-dark`
   would silently render on the light bg with dark headings. Every dark variant
   in the palette also carries .bg-host, whose ::before paints over it, which is
   why it never showed — but an image-less dark flex-media (e.g. --long-center
   with no photo) composites its translucent panel over white. :not(.section-dark)
   makes the dark modifier win without changing relative order inside the family. */
.flex-media:not(.section-dark) { background: var(--color-bg); }
.flex-media--reverse:not(.section-dark), .flex-media--long-reverse:not(.section-dark) { background: var(--color-bg-alt); }
.flex-media h2, .flex-media--long h2, .flex-media--long-reverse h2 { color: var(--color-heading); }
/* barn-red rule spans the FULL block width — above both the text card and
   the image; ONE box-shadow wraps the whole card+image unit (not per column) */
/* NOTE — decorative rules on LIGHT surfaces follow --orange-fill so they match
   the button colour in the same section. In blaze that is #F26A1B, which sits at
   3.06:1 on the white page and 2.77:1 on the band. That is deliberate and is NOT a
   contrast failure: WCAG 1.4.11 covers UI components and meaningful graphics, and
   these are purely decorative 4px keylines carrying no information. The luminance
   ratio also understates a saturated orange's visibility against an off-white —
   the alternative (the darker --orange #C4450F) is crisper but renders a visibly
   different orange directly beneath a --orange-fill button, which is the exact
   mismatch this whole pass set out to remove. */
.flex-media-grid { display: grid; gap: clamp(1.5rem, 3vw, 2rem); grid-template-columns: 1fr; align-items: center; border-top: 4px solid var(--orange-fill); box-shadow: var(--shadow-md); }
.flex-media-text {
  /* The offset card must read against its own section. The shadow lives on
     .flex-media-grid, not here, so when --oat matches the section background (a
     palette whose card surface is white on a white page) the card had no edge at
     all. A hairline restores it without needing a tinted fill. */
  border: 1px solid var(--color-border);
  background: var(--oat);
  border-radius: var(--radius);
  padding: clamp(1.5rem, 3vw, 2.5rem);
}
.flex-media--reverse .flex-media-text { background: #fff; }  /* card flips to white on the oat section bg */
.flex-media-text > :first-child { margin-top: 0; }
.flex-media-figure { margin: 0; }   /* no per-column shadow — the unit shadow lives on .flex-media-grid */
.flex-media-figure img { width: 100%; border-radius: var(--radius); aspect-ratio: 4 / 3; object-fit: cover; }
@media (min-width: 880px) {
  .flex-media-grid { grid-template-columns: repeat(12, 1fr); align-items: stretch; }
  .flex-media-text { grid-column: 1 / 7; grid-row: 1; position: relative; z-index: 2; }
  /* the TEXT card drives the row height; the image absolute-fills its
     figure and crops (object-fit) to always match the text's height */
  .flex-media-figure { grid-column: 6 / -1; grid-row: 1; position: relative; min-height: 300px; }
  .flex-media-figure img {
    position: absolute; inset: 0; width: 100%; height: 100%;
    object-fit: cover; aspect-ratio: auto;
  }
  /* --reverse mirrors the overlap */
  .flex-media--reverse .flex-media-text { grid-column: 7 / -1; }
  .flex-media--reverse .flex-media-figure { grid-column: 1 / 8; }
}
.flex-media-cta-row { display: flex; flex-wrap: wrap; gap: 0.85rem; margin-top: 2rem; align-items: center; }

/* --long / --long-reverse: two columns of long copy, image cornered.
   --long = image at TOP of the first column; --long-reverse = image at
   the BOTTOM of the first column (columns are equal height). Images get
   an offset timber keyline frame. */
.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; }
/* long-col is a flex column, so margins don't collapse: the 0.5rem here adds to
   the previous paragraph's 1rem bottom for a ~24px gap, matching the framed
   sections' collapsed .subhead gap. */
.flex-media-long-col h3 { margin-top: 0.5rem; }
.flex-media-long-figure { margin: 0; position: relative; }
/* offset keyline frame — peeks BOTTOM-RIGHT on --long */
.flex-media-long-figure::after {
  content: ""; position: absolute; inset: 14px -14px -14px 14px;
  border: 3px solid var(--keyline); border-radius: var(--radius); z-index: 0; pointer-events: none;
}
/* --long-reverse: same 14px offset, hangs off the BOTTOM-LEFT */
.flex-media--long-reverse .flex-media-long-figure::after { inset: 14px 14px -14px -14px; }
/* the bottom-cornered figure carries 1.25rem padding-top (its gap from the
   text above) — offset the frame from the IMAGE, not the padded figure box */
.flex-media--long-reverse .flex-media-long-figure:last-child::after { top: calc(1.25rem + 14px); }
.flex-media-long-figure img { position: relative; z-index: 1; width: 100%; border-radius: var(--radius); aspect-ratio: 4 / 3; object-fit: cover; box-shadow: var(--shadow-md); }
.flex-media-long-col > .flex-media-long-figure:first-child { margin-bottom: 1.75rem; }
/* ---- column balance: the IMAGE is the shock absorber ----
   Uneven columns are the #1 defect in this block, because a 4/3 image is a
   fixed ~360px slab and the copy split has to be guessed against it. Instead,
   let the figure GROW to swallow whatever height the other column dictates and
   crop via object-fit — the same mechanism the short .flex-media already uses
   ("the TEXT drives the row height, the image matches it"). Authoring rule
   collapses to: put LESS copy in the image column than in the other one.
   (Residual case: if the image column's own text already exceeds the other
   column, the other one still runs ragged — no CSS can fix that, move copy.) */
@media (min-width: 768px) {
  /* flex-basis 0 is the load-bearing part: the figure contributes only its
     min-height to the column's natural height, so the image column can never
     be the one that inflates the grid row. The row is then set by the copy,
     and the figure grows into whatever is left. (flex-basis auto would let a
     4/3 image push the row taller than the other column — which is exactly
     how this block used to end up ragged.) */
  /* 200px floor, not 240 — every extra px of floor is a px the figure cannot
     give back when the image column's own copy runs long. Below ~200 a
     full-width figure letterboxes badly, so this is the practical limit. */
  .flex-media-long-figure { flex: 1 1 0; min-height: 200px; }
  /* the image is taken out of flow entirely so it adds NO intrinsic height —
     same proven mechanism as the short .flex-media figure */
  .flex-media-long-figure img { position: absolute; inset: 0; width: 100%; height: 100%; aspect-ratio: auto; }
  /* the bottom-anchored figure fills the slack itself now, so drop the auto
     margin that used to push it down past a gap of whitespace */
  .flex-media-long-col > .flex-media-long-figure:last-child { margin-top: 0; }
}
.flex-media-long-col > .flex-media-long-figure:last-child { margin-top: auto; padding-top: 1.25rem; }
@media (max-width: 767px) {
  .flex-media-long-figure::after { inset: 10px -8px -8px 10px; }
  .flex-media--long-reverse .flex-media-long-figure::after { inset: 10px 10px -8px -8px; }
  .flex-media--long-reverse .flex-media-long-figure:last-child::after { top: calc(1.25rem + 10px); }
}

/* --overlay / --overlay-right: FULL-BLEED bg photo; the text lives on a
   TRANSLUCENT dark panel covering one half (photo fully visible on the
   other). Copy length is content-driven — works as a short OR long block.
   Section also carries .bg-host + .section-dark (white text).
   Default = panel LEFT; add --overlay-right for panel RIGHT. */
.flex-media--overlay { padding: 0; }
.flex-media--overlay.bg-host::before { background: var(--overlay-scrim); } /* light scrim only */
.flex-media--overlay .overlay-half {
  --panel-pad: clamp(1.25rem, 4vw, 3rem);
  position: relative; z-index: 2;
  background: var(--overlay-panel); border-top: 4px solid var(--accent-frame);  /* translucent — photo reads through */
  padding: clamp(2.75rem, 6vw, 4.5rem) var(--panel-pad);
}
.flex-media--overlay h2 { color: #fff; }
@media (min-width: 880px) {
  .flex-media--overlay .overlay-half {
    width: 50%; min-height: 480px; border-top: none; border-right: 4px solid var(--accent-frame);
    display: flex; flex-direction: column; justify-content: center;
  }
  /* align the panel's text with the global container's edge. The panel is
     exactly HALF the layout width, so 100% − max-w/2 is the gutter+padding
     distance — %-based, immune to the 100vw scrollbar error. */
  .flex-media--overlay .overlay-half-inner {
    max-width: 34rem;
    margin-left: max(0px, calc(100% + var(--panel-pad) + 4px - var(--max-w) / 2 + 1.25rem));
  }
  /* --overlay-right: mirror — panel covers the RIGHT half */
  .flex-media--overlay-right .overlay-half {
    margin-left: 50%; border-right: none; border-left: 4px solid var(--accent-frame);
  }
  .flex-media--overlay-right .overlay-half-inner {
    margin-left: auto; margin-right: max(0px, calc(100% + var(--panel-pad) + 4px - var(--max-w) / 2 + 1.25rem));
  }
}

/* --long-center: FULL-BLEED bg photo; the overlay is a CENTERED content
   panel holding the heading + the 2-col long grid.
   Section also carries .bg-host + .section-dark (white text). */
.flex-media--long-center { padding: 0; }  /* panel runs flush to the section's top + bottom */
.flex-media--long-center.bg-host::before { background: var(--overlay-scrim-strong); } /* light scrim only */
.flex-media--long-center h2 { color: #fff; }
.flex-media--long-center .overlay-center {
  /* SYMMETRIC rule: this panel is centered, so a lone border-right read as a
     mistake once the palettes gave --accent-frame real contrast. */
  background: var(--overlay-panel); border-inline: 4px solid var(--accent-frame);  /* translucent — photo reads through */
  padding: clamp(1.75rem, 4vw, 3rem);
}

/* ============================================================
   FLEX-MEDIA MATRIX — 4 families x short/long, mirrored.
   Each family is a distinct GEOMETRY; --long/short is how much
   copy it carries. Long copy may run as TWO columns (the default
   .flex-media-long-grid) or ONE taller column (add --single, or
   just put a single .flex-media-long-col in — :has() collapses it).

   | family                          | short              | long               |
   |---------------------------------|--------------------|--------------------|
   | matched-height image beside text| .flex-media        | --stack            |
   | image w/ offset keyline box     | --framed           | --long             |
   | side overlay on full-bleed photo| --overlay          | --overlay-long     |
   | center overlay on full-bleed    | --center           | --long-center      |
   ...each + its mirror (--reverse / --overlay-right; --center has no sides).
   ============================================================ */

/* long copy as ONE taller column instead of two */
.flex-media-long-grid--single { grid-template-columns: 1fr !important; }
.flex-media-long-grid:has(> .flex-media-long-col:only-child) { grid-template-columns: 1fr; }

/* ---------- --stack: matched-height family, LONG form ----------
   Same overlapping-card geometry as .flex-media, but the text card
   takes 7 of 12 columns (long copy needs the measure) and the figure
   holds TWO images stacked, split 50/50 down the column height with a
   barn-red rule between them. The TEXT still drives the row height;
   both images crop to fill their half. Mirror = --stack-reverse. */
.flex-media--stack:not(.section-dark) { background: var(--color-bg); }
.flex-media--stack-reverse:not(.section-dark) { background: var(--color-bg-alt); }
.flex-media--stack:not(.section-dark) h2, .flex-media--stack-reverse:not(.section-dark) h2 { color: var(--color-heading); }
.flex-media--stack-reverse .flex-media-text { background: #fff; }
/* grid rows (not flex) — 1fr/1fr splits the height deterministically;
   flex-basis sizing fights the images' intrinsic aspect ratios. */
.flex-media-figure--stack { display: grid; grid-template-rows: auto auto; gap: 0; min-height: 300px; }
.flex-media-figure--stack img {
  width: 100%; height: auto; min-height: 0;
  object-fit: cover; border-radius: var(--radius); aspect-ratio: 4 / 3;
}
.flex-media-figure--stack img + img { border-top: 4px solid var(--accent-frame); }
@media (min-width: 880px) {
  .flex-media--stack .flex-media-text, .flex-media--stack-reverse .flex-media-text { grid-column: 1 / 8; }
  .flex-media--stack .flex-media-figure, .flex-media--stack-reverse .flex-media-figure { grid-column: 7 / -1; }
  .flex-media--stack-reverse .flex-media-text { grid-column: 6 / -1; }
  .flex-media--stack-reverse .flex-media-figure { grid-column: 1 / 7; }
  /* The TEXT must drive the row height, so the images cannot contribute any
     intrinsic height — same absolute-fill trick the base single-image rule
     uses, just split into halves. (Leaving them in flow made the images'
     own height set the row and left the text card with dead space.) */
  .flex-media-figure--stack { min-height: 0; display: block; }
  .flex-media-figure--stack img {
    position: absolute; left: 0; right: 0; width: 100%; height: 50%;
    aspect-ratio: auto; object-fit: cover; box-sizing: border-box;
  }
  .flex-media-figure--stack img:first-child { top: 0; }
  .flex-media-figure--stack img:last-child  { top: 50%; }
  .flex-media--stack .flex-media-figure, .flex-media--stack-reverse .flex-media-figure { position: relative; }
}

/* the text card is 8 of 12 cols — only split the copy once that's genuinely wide */
@media (max-width: 1023px) {
  .flex-media--stack .flex-media-long-grid, .flex-media--stack-reverse .flex-media-long-grid { grid-template-columns: 1fr; }
}

/* ---------- --framed: keyline-box family, SHORT form ----------
   Plain two-column block (no overlapping card): text one side, a single
   image the other wearing the offset timber keyline frame that --long
   uses. The frame hangs 14px past the image, so the grid reserves that
   room. Mirror = --framed-reverse. */
.flex-media--framed:not(.section-dark) { background: var(--color-bg); }
.flex-media--framed-reverse:not(.section-dark) { background: var(--color-bg-alt); }
.flex-media--framed:not(.section-dark) h2, .flex-media--framed-reverse:not(.section-dark) h2 { color: var(--color-heading); }
/* plain copy column — no oat card, unlike .flex-media-text */
.flex-media-text-plain > :first-child { margin-top: 0; }
.flex-media-text-plain > :last-child { margin-bottom: 0; }
.flex-media-framed-grid { display: grid; grid-template-columns: 1fr; gap: clamp(1.75rem, 4vw, 3rem); align-items: center; }
@media (min-width: 880px) {
  .flex-media-framed-grid { grid-template-columns: 1fr 1fr; }
  .flex-media--framed-reverse .flex-media-framed-grid > .flex-media-long-figure { order: -1; }
}
/* room for the frame's 14px bottom-right (bottom-left when mirrored) overhang */
.flex-media--framed .flex-media-framed-grid { padding: 0 14px 14px 0; }
.flex-media--framed-reverse .flex-media-framed-grid { padding: 0 0 14px 14px; }
.flex-media--framed-reverse .flex-media-long-figure::after { inset: 14px 14px -14px -14px; }
@media (max-width: 879px) {
  .flex-media--framed-reverse .flex-media-long-figure::after { inset: 10px 10px -8px -8px; }
}

/* ---------- --framed-split: two text columns, image at bottom-left ----------
   Same framed block, but the section title spans the full width and the body
   runs in TWO copy columns instead of copy-beside-photo. The single photo drops
   to the BOTTOM of the left column and the CTA to the bottom of the right, so
   both columns bottom-align (image <-> buttons) and stretch to equal height.
   Content is split at subsection boundaries so a heading never straddles the
   image break. Below 880px it all stacks in source order. */
.flex-media-framed-grid--split { align-items: stretch; }
.flex-media-split-title { grid-column: 1 / -1; margin-bottom: 0; }
.flex-media-split-col { display: flex; flex-direction: column; }
.flex-media-split-col > :first-child { margin-top: 0; }
/* the photo sits directly under the left column's copy (not floated to the
   bottom); flex:none + static 4/3 image keeps it at a normal upright crop at
   EVERY width (the --long grow/absolute-fill rules would otherwise squash the
   stacked image to a 200px letterbox strip below 880px) */
.flex-media-split-figure { flex: none; min-height: 0; margin-top: 1.75rem; }
.flex-media-split-figure img {
  position: static; inset: auto; width: 100%; height: auto;
  aspect-ratio: 4 / 3; object-fit: cover; object-position: top;
}
/* pin the buttons to the bottom of the right column so it fills to the same
   height as the copy-plus-photo left column */
.flex-media-split-cta { margin-top: auto; padding-top: 1.75rem; }
@media (max-width: 879px) {
  .flex-media-split-cta { margin-top: 1.5rem; }
}

/* ---------- --overlay-long: side-overlay family, LONG form ----------
   Same full-bleed photo + translucent side panel as --overlay, but the
   panel widens (50% -> 62%) so long copy gets a workable measure, and it
   carries the 2-col long grid. Compose with --overlay-right to mirror. */
/* The panel stays EXACTLY half — it must never cross the midline, so the
   photo always keeps a clean, full half of the section. That caps the copy
   measure: the panel's right edge is the midpoint and the copy starts at the
   global container's left gutter, so the content column is always
   (--max-w / 2 − panel padding) ≈ 550px no matter how wide the viewport gets.
   Two columns of ~250px in that space are unreadable, so this family's long
   form is ALWAYS a single taller column — width inherits from --overlay and
   the long grid is forced to 1fr at every breakpoint. */
.flex-media--overlay-long .flex-media-long-grid { grid-template-columns: 1fr; }
.flex-media--overlay-long .flex-media-long-col h3 { color: #fff; }

/* ---------- --center: center-overlay family, SHORT form ----------
   The --long-center panel, sized for short copy: the section keeps its
   normal vertical padding (panel does NOT run flush to the edges) and the
   panel is a narrower centered column. No mirror — it has no sides. */
.flex-media--center.bg-host::before { background: var(--overlay-scrim-strong); }
.flex-media--center h2 { color: #fff; }
.flex-media--center .overlay-center {
  /* SYMMETRIC rule — see the --long-center note above. */
  background: var(--overlay-panel); border-inline: 4px solid var(--accent-frame);
  padding: clamp(1.75rem, 4vw, 3rem);
  max-width: 46rem; margin-inline: auto;
}

/* ---------- snow-list (check-bullet feature list) ---------- */
.snow-list { list-style: none; margin: 1.25rem 0 0; padding: 0; font-size: 0.97rem; }
.snow-list li { position: relative; padding-left: 30px; margin-bottom: 0.7rem; line-height: 1.5; color: var(--color-text); }
.snow-list li strong { color: var(--color-heading); }
.snow-list li::before {
  content: ""; position: absolute; left: 0; top: 0.15em; width: 20px; height: 20px;
  background-repeat: no-repeat; background-size: contain;
  background-image: var(--bullet-snow);
}
.flex-media .snow-list { display: grid; grid-template-columns: 1fr; gap: 0.4rem 1.5rem; }
@media (min-width: 560px) { .flex-media .snow-list { grid-template-columns: 1fr 1fr; } }
.snow-list--single { grid-template-columns: 1fr !important; }
.section-dark .snow-list li, .spotlight .snow-list li { color: rgba(255,255,255,0.9); }
.section-dark .snow-list li strong, .spotlight .snow-list li strong { color: #fff; }

/* ---------- subhead (h3 lead-in inside text blocks) ---------- */
.subhead { font-family: var(--font-head); font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em; color: var(--teal); font-size: 1.2rem; margin: 1.5rem 0 0.5rem; }
.section-dark .subhead, .feature-aside .subhead { color: var(--teal-bright); }

/* ---------- Feature-aside (dark text column + nav aside boxes) ---------- */
.feature-aside-grid { display: grid; gap: clamp(1.5rem, 3vw, 2.5rem); grid-template-columns: 1fr; align-items: center; }
@media (min-width: 960px) { .feature-aside-grid { grid-template-columns: 1.5fr 1fr; } }
.feature-aside-side { display: flex; flex-direction: column; gap: 1rem; justify-content: center; }
.feature-aside-box { background: var(--wash-accent); border: 1px solid var(--teal-bright); padding: 1.75rem; border-radius: var(--radius); text-align: center; }
.feature-aside-box-title { color: #fff; margin: 0 0 1rem; font-family: var(--font-head); font-size: clamp(1.3rem, 2vw, 1.6rem); font-weight: 700; text-transform: uppercase; line-height: 1.05; }
.feature-aside-box .btn { width: 100%; background: var(--btn-fill-dark); color: var(--btn-ink-dark); border-color: var(--btn-fill-dark); }
.feature-aside-box .btn:hover { background: transparent; color: var(--btn-fill-dark); border-color: var(--btn-fill-dark); }
/* No aside: single centered column (Licensed section). */
.feature-aside-centered { max-width: 50rem; margin-inline: auto; text-align: center; }
/* Long inline URLs break instead of overflowing the centered column. */
.url-wrap { overflow-wrap: anywhere; }

/* ---------- Spotlight (service areas + city narrative) ---------- */
.spotlight { color: #fff; }
.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: 1fr 1.3fr; }
  /* --reverse: narrative in the WIDE left column, areas chips narrow right */
  .spotlight--reverse .container { grid-template-columns: 1.3fr 1fr; }
}
.spotlight h2 { color: #fff; }
.spotlight p { color: rgba(255,255,255,0.85); }
.spotlight-side-title { font-family: var(--font-head); font-size: clamp(1.6rem, 3.5vw, 2.2rem); font-weight: 700; text-transform: uppercase; line-height: 1.05; color: #fff; margin: 0 0 1rem; }
/* areas render as stamped TAG CHIPS (not a bulleted list) */
.spotlight-areas { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-top: 0; font-size: 0.95rem; }
.spotlight-areas li {
  padding: 0.4rem 0.9rem; margin: 0; line-height: 1.4;
  background: rgba(0,0,0,0.35); border: 1px solid rgba(255,255,255,0.30);
  border-left: 3px solid var(--accent-frame); border-radius: var(--radius);
  color: #fff; font-weight: 600;
}
.spotlight-areas li::before { display: none; }
.spotlight--light .spotlight-areas li {
  background: var(--oat); border-color: var(--color-border);
  border-left-color: var(--orange-fill); color: var(--color-heading);
}
.spotlight--light { color: var(--color-text); background: var(--color-bg); }
.spotlight--light h2 { color: var(--color-heading); }
.spotlight--light .spotlight-side-title { color: var(--teal); }
.spotlight--light p, .spotlight--light .snow-list li { color: var(--color-text); }
.spotlight--light .snow-list li strong { color: var(--color-heading); }

/* ---------- Steps (vertical timeline on a galvanized post line) ----------
   Markup per step: <li><span class="step-num">N</span> <div class="process-step-body">
   h3 + p</div> <img|.process-step-icon></li>. Handles any step count. */
.steps h2 { color: #fff; }
.process-intro { max-width: 70ch; margin: 0 auto 2.5rem; text-align: center; color: rgba(255,255,255,0.85); }
.process-grid {
  position: relative; display: flex; flex-direction: column;
  gap: clamp(2rem, 4vw, 3rem); max-width: 820px; margin: 0 auto; padding: 0; list-style: none;
}
/* the "post": a ribbed galvanized line running down the number column */
.process-grid::before {
  content: ""; position: absolute; left: 26px; top: 10px; bottom: 10px; width: 4px;
  background: repeating-linear-gradient(180deg, var(--metal-1) 0 10px, var(--metal-2) 10px 14px);
  border-radius: var(--radius);
}
.process-step { display: grid; grid-template-columns: 56px 1fr auto; gap: 1.1rem 1.4rem; align-items: start; position: relative; }
.process-step .step-num {
  grid-column: 1; grid-row: 1 / span 2; position: relative; z-index: 1;
  width: 56px; height: 56px; display: flex; align-items: center; justify-content: center;
  background: var(--orange-fill); color: var(--btn-ink); font-family: var(--font-head); font-size: 1.7rem;
  font-weight: 700; line-height: 1; border-radius: var(--radius);
  box-shadow: 0 0 0 6px var(--navy);
}
.process-step-body { grid-column: 2; }
.process-step-body > :first-child { margin-top: 0; }
.process-step > img, .process-step > .process-step-icon {
  grid-column: 3; grid-row: 1 / span 2; width: 150px; height: 104px;
  border-radius: var(--radius); object-fit: cover; margin: 0;
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.process-step > .process-step-icon { background: var(--teal); color: #fff; }
.process-step h3 { color: #fff; margin-bottom: 0.4rem; }
.process-step p { color: rgba(255,255,255,0.80); font-size: 0.95rem; margin: 0; }
/* small screens: drop the side thumb below the text, keep the post line */
@media (max-width: 640px) {
  .process-step { grid-template-columns: 48px 1fr; }
  .process-grid::before { left: 22px; }
  .process-step .step-num { width: 48px; height: 48px; font-size: 1.4rem; grid-row: 1; }
  .process-step > img, .process-step > .process-step-icon { grid-column: 2; grid-row: 3; width: 100%; max-width: 320px; height: 140px; }
}
/* The closing box of the steps block. Was a 4%-white wash, which is barely visible;
   a real palette tone reads as a deliberate panel on the dark section. */
.mini-cta { margin-top: 3rem; text-align: center; padding: 1.75rem; background: var(--navy-card); border-radius: var(--radius); }
.mini-cta p { color: var(--orange-bright); font-family: var(--font-head); font-weight: 700; text-transform: uppercase; margin: 0 0 0.35rem; font-size: 1.15rem; }
.mini-cta p + p { color: rgba(255,255,255,0.80); font-weight: 400; text-transform: none; margin-bottom: 1rem; font-family: var(--font-body); }
.mini-cta .btn { margin-top: 0.5rem; }

/* ---------- Banner (centered emphasis over image) ---------- */
.banner { color: #fff; display: flex; align-items: center; min-height: 420px; padding: clamp(3.5rem, 7vw, 6rem) 0; text-align: center; }
.banner-inner { max-width: 760px; margin: 0 auto; }
.banner h2 { color: #fff; }
.banner p { color: rgba(255,255,255,0.9); }
.banner-kicker { font-family: var(--font-head); text-transform: uppercase; letter-spacing: 0.08em; font-weight: 700; font-size: 1.05rem; color: var(--teal-bright); margin: 0 0 0.5rem; }
.banner-cta-row { display: flex; flex-wrap: wrap; gap: 0.75rem 1rem; justify-content: center; margin-top: 1.75rem; }

/* ---------- Testimonials carousel (JS in /testimonials.js) ---------- */
.testimonials { background: var(--color-bg-alt); }
.testi-carousel { display: flex; align-items: center; gap: clamp(0.5rem, 2vw, 1rem); margin-top: 2rem; }
.testi-viewport { overflow: hidden; flex: 1 1 auto; min-width: 0; }
.testi-track { display: flex; margin: 0; padding: 0; list-style: none; will-change: transform; }
.testi-slide { flex: 0 0 100%; width: 100%; padding: 0.5rem clamp(0.25rem, 2vw, 1.5rem); }
.testi-quote { margin: 0 auto; max-width: 760px; background: #fff; border: 1px solid var(--color-border); border-top: 4px solid var(--card-accent); border-radius: var(--radius); padding: clamp(1.5rem, 4vw, 2.75rem); text-align: center; box-shadow: var(--shadow-md); }
.testi-quote > p { font-size: clamp(1.05rem, 2vw, 1.3rem); line-height: 1.6; font-style: italic; color: var(--color-text); margin: 0 0 1.5rem; }
.testi-quote > p::before { content: "\201C"; }
.testi-quote > p::after  { content: "\201D"; }
.testi-cite { display: flex; flex-direction: column; gap: 0.1rem; }
.testi-name { font-family: var(--font-head); font-weight: 700; text-transform: uppercase; letter-spacing: 0.02em; color: var(--color-heading); font-size: 1.2rem; }
.testi-meta { font-size: 0.9rem; color: var(--color-text-muted); }
.testi-arrow { flex: 0 0 auto; width: 48px; height: 48px; display: inline-flex; align-items: center; justify-content: center; background: var(--navy); color: #fff; border: 0; border-radius: 50%; cursor: pointer; transition: background-color .15s ease, transform .08s ease; }
.testi-arrow:hover { background: var(--orange-fill); color: var(--btn-ink); }
.testi-arrow:active { transform: scale(0.94); }
.testi-arrow svg { width: 24px; height: 24px; }
.testi-dots { display: flex; justify-content: center; gap: 0.5rem; margin-top: 1.5rem; }
.testi-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--color-border); transition: background-color .15s ease; }
.testi-dot.is-active { background: var(--teal); }
@media (prefers-reduced-motion: reduce) { .testi-track { transition: none !important; } }

/* ---------- Recent-projects carousel (scroll-snap gallery) ---------- */
.projects { background: var(--navy); color: var(--color-fg-on-dark); }
.projects h2 { color: #fff; }
.projects-head { margin-bottom: clamp(1.5rem, 3vw, 2.25rem); }
.projects-carousel { position: relative; }
.projects-track {
  display: flex; gap: 1.25rem; margin: 0; padding: 0 0 0.5rem; list-style: none;
  overflow-x: auto; scroll-snap-type: x mandatory; scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch; scrollbar-width: none;
}
.projects-track::-webkit-scrollbar { display: none; }
.projects-track:focus-visible { outline: 3px solid var(--color-focus); outline-offset: 4px; }
.project-card {
  flex: 0 0 auto; width: min(85%, 380px); scroll-snap-align: start;
  background: var(--navy-2); border-top: 4px solid var(--accent-frame);
  box-shadow: var(--shadow-md); overflow: hidden;
}
@media (min-width: 700px) { .project-card { width: calc((100% - 2.5rem) / 3); } }
@media (min-width: 1040px) { .project-card { width: calc((100% - 3.75rem) / 4); } }
.project-card img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block; }
.project-cap { padding: 0.9rem 1.1rem 1.1rem; }
.project-tag {
  display: inline-block; font-family: var(--font-head); font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.04em; font-size: 0.72rem;
  color: var(--btn-ink); background: var(--orange-fill); padding: 0.15rem 0.55rem; margin-bottom: 0.5rem;
}
.project-cap p { margin: 0; font-family: var(--font-head); font-weight: 700; text-transform: uppercase; color: #fff; font-size: 1.05rem; line-height: 1.15; }
.proj-arrows { display: flex; justify-content: center; gap: 0.6rem; margin-top: 1.5rem; }
.proj-btn {
  width: 48px; height: 48px; display: inline-flex; align-items: center; justify-content: center;
  background: var(--navy-2); color: #fff; border: 2px solid rgba(255,255,255,0.25); cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease, opacity .15s ease, transform .08s ease;
}
.proj-btn:hover { background: var(--orange-fill); border-color: var(--orange-fill); color: var(--btn-ink); }
.proj-btn:active { transform: scale(0.94); }
.proj-btn:disabled { opacity: 0.35; cursor: default; }
.proj-btn svg { width: 24px; height: 24px; }
@media (prefers-reduced-motion: reduce) { .projects-track { scroll-behavior: auto; } }

/* ---------- CTA (closing call to action) ---------- */
.cta-split { display: grid; gap: clamp(1.5rem, 3vw, 2.5rem); grid-template-columns: 1fr; align-items: start; }
@media (min-width: 880px) { .cta-split { grid-template-columns: 1fr 1fr; } }
.cta-split .btn-row { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 1.5rem; }
.cta > .container > .btn-row { display: flex; flex-wrap: wrap; gap: 0.75rem; justify-content: center; margin-top: clamp(1.5rem, 3vw, 2.5rem); }

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

/* ============================================================
   SITE-LOCAL (chico-elite-stucco) — the "Systems & Finishes" grid (block 05).
   Same card structure as the dark services-grid above it (header bar + image +
   body), but styled LIGHT with an OLIVE (--orange) header instead of the dark
   section's CLAY (--teal) header, so the two grids read as distinct. Cards flex
   to equal height so a short card (e.g. Acrylic) doesn't stub out.
   ============================================================ */
.systems { padding: clamp(3rem, 6vw, 5rem) 0; background: var(--color-bg); }
.systems .services-head { text-align: center; max-width: 62rem; margin: 0 auto clamp(1.5rem, 3vw, 2.25rem); }
.systems .services-head h2 { color: var(--color-heading); }
.systems-grid { display: grid; gap: 1.25rem; grid-template-columns: 1fr; }
@media (min-width: 640px) { .systems-grid { grid-template-columns: 1fr 1fr; } }
.systems-card {
  display: flex; flex-direction: column; background: var(--oat);
  border: 1px solid var(--color-border); border-radius: var(--radius); overflow: hidden;
  transition: transform .12s ease, border-color .15s ease, box-shadow .15s ease;
}
/* Matches the .service-card lift above; border picks up this card's orange
   accent (as the dark cards' hover uses their teal), lighter shadow for light bg. */
.systems-card:hover { transform: translateY(-3px); border-color: var(--orange-bright); box-shadow: 0 12px 28px rgba(0,0,0,0.15); }
.systems-card-header {
  background: var(--orange); color: #fff; padding: 0.75rem 1.25rem; margin: 0; text-align: left;
  font-family: var(--font-head); font-size: 1.4rem; font-weight: 700; letter-spacing: 0.01em;
  text-transform: uppercase; line-height: 1.15;
}
.systems-card-body { padding: 1.25rem; display: flex; flex-direction: column; flex: 1; gap: 0.9rem; }
.systems-card-body img {
  width: calc(100% + 2.5rem); max-width: none; margin: -1.25rem -1.25rem 0;
  aspect-ratio: 16 / 9; object-fit: cover; object-position: top;
}
.systems-card-body p { margin: 0; color: var(--color-text); font-size: 1rem; }

/* ============================================================
   SITE-LOCAL (chico-elite-stucco) — figure images.
   The matched (.flex-media-figure) and framed (.flex-media-long-figure)
   images default to absolute-filling their column, so a portrait photo gets
   cropped to whatever the text-height box is — a thin landscape slice. Anchor
   each figure to the TOP of its row and give the image a normal upright 3/4
   crop from the top instead. Excludes the two-image --stack figure.
   ============================================================ */
@media (min-width: 880px) {
  .flex-media-grid > .flex-media-figure:not(.flex-media-figure--stack) { align-self: start; min-height: 0; }
  .flex-media-figure:not(.flex-media-figure--stack) img {
    position: static; inset: auto; width: 100%; height: auto;
    aspect-ratio: 4 / 3; object-fit: cover; object-position: top;
  }
  .flex-media--framed .flex-media-framed-grid > .flex-media-long-figure,
  .flex-media--framed-reverse .flex-media-framed-grid > .flex-media-long-figure {
    align-self: start; flex: none; min-height: 0;
  }
  .flex-media--framed .flex-media-long-figure img,
  .flex-media--framed-reverse .flex-media-long-figure img {
    position: static; inset: auto; width: 100%; height: auto;
    aspect-ratio: 4 / 3; object-fit: cover; object-position: top;
  }
}

/* Block 03 (Which Scope) — tighten the space above the h3 subheads in the
   single-column overlay text so they don't float. */
.flex-media--overlay-long .flex-media-long-col h3 { margin-bottom: 0.35rem; }
/* Spotlight — gap between the "Neighborhoods" and "Surrounding Service Areas" lists. */
.spotlight-side-title--second { margin-top: 1.75rem; }

/* Why-Choose single-column list: tighter row spacing. */
.snow-list--single li { margin-bottom: 0.3rem; }

/* ============================================================
   SITE-LOCAL (chico-elite-stucco) — stacked-figure images + block-06 band.
   ============================================================ */
/* Stacked figures keep the palette's default behaviour: the two images fill the
   text-column height, each exactly half, so they are always equal and leave no
   gap below the text (no fixed aspect override here). */
/* Resurfacing (block 06): limewash band, white text card against it. */
.flex-media--stack[aria-labelledby="resurf-h2"] { background: var(--color-bg-alt); }
.flex-media--stack[aria-labelledby="resurf-h2"] .flex-media-text { background: #fff; }

/* Spotlight location-list titles: normal h3 size (not the big spotlight-side-title). */
.spotlight .areas-title {
  font-family: var(--font-head); font-weight: 700; text-transform: uppercase;
  font-size: 1.4rem; line-height: 1.15; letter-spacing: 0.01em;
  color: var(--teal-bright); margin: 0 0 1rem;
}
.spotlight--light .areas-title { color: var(--teal); }
.spotlight .areas-title--second { margin-top: 1.75rem; }

/* ============================================================
   SITE-LOCAL (chico-elite-stucco) — Which Scope (block 03) + Systems cards.
   ============================================================ */
@media (min-width: 901px) {
  /* Which Scope: text panel wider than half, and a fixed (parallax) background
     photo instead of the scrolling .bg-img. */
  .flex-media--overlay-long[aria-labelledby="scope-h2"] {
    background-image: url("/images/bg-scope-1600.webp");
    background-size: cover; background-position: center; background-attachment: fixed;
  }
  /* naked photo on the right — no full-bleed scrim; only the text panel is overlaid */
  .flex-media--overlay-long[aria-labelledby="scope-h2"]::before { display: none; }
  .flex-media--overlay-long[aria-labelledby="scope-h2"] > .bg-img { display: none; }
  .flex-media--overlay-long[aria-labelledby="scope-h2"] .overlay-half { width: 62%; }
  .flex-media--overlay-long[aria-labelledby="scope-h2"] .overlay-half-inner {
    max-width: 42rem;
    margin-left: max(1.25rem, calc((100vw - var(--max-w)) / 2 + 1.25rem));
  }
}

/* Hero: fixed (parallax) background photo instead of the scrolling .bg-img. */
@media (min-width: 901px) {
  .hero--form.bg-host {
    background-image: linear-gradient(rgba(30,28,26,0.40), rgba(30,28,26,0.54)), url("/images/home-hero-1600.webp");
    background-size: cover; background-position: center; background-attachment: fixed;
  }
  .hero--form.bg-host > .bg-img { display: none; }
}

/* Cost band: fixed (parallax) background photo instead of the scrolling .bg-img.
   Keeps the existing .bg-host::before scrim (overlay-scrim-strong) for contrast. */
@media (min-width: 901px) {
  .flex-media--center.bg-host[aria-labelledby="cost-h2"] {
    background-image: url("/images/bg-cost-1600.webp");
    background-size: cover; background-position: center; background-attachment: fixed;
  }
  .flex-media--center.bg-host[aria-labelledby="cost-h2"] > .bg-img { display: none; }
}

/* Service Areas band: fixed (parallax) background photo instead of the scrolling
   .bg-img. Keeps the existing .bg-host::before scrim (overlay-dark) for contrast. */
@media (min-width: 901px) {
  .spotlight.bg-host[aria-labelledby="areas-h2"] {
    background-image: url("/images/bg-areas-1600.webp");
    background-size: cover; background-position: center; background-attachment: fixed;
  }
  .spotlight.bg-host[aria-labelledby="areas-h2"] > .bg-img { display: none; }
}

/* Hero: replace the corrugated skin edge with a plain accent rule, matching the
   footer's top border. */
.hero--form::after { display: none; }
.hero--form { border-bottom: 4px solid var(--accent-frame); }
/* Closing CTA (18): heading, copy and buttons stacked and centered. */
.cta .cta-center { max-width: 52rem; margin: 0 auto; text-align: center; }
.cta .cta-center .btn-row { display: flex; flex-wrap: wrap; gap: 0.75rem; justify-content: center; margin-top: clamp(1.5rem, 3vw, 2.25rem); }
