/* ============================================================
   RELY Snow Removal — site/style.css
   Mobile-first, single stylesheet, semantic HTML.
   ============================================================ */

/* ---------- Design Tokens (the reskin surface) ----------
   Every palette-critical color lives here (or in a [data-theme] block below) —
   no block rule hardcodes a brand hex. The token set IS the skin. */
:root {
  --color-primary: #001D3D;            /* deep navy — header text, primary surfaces, quote card */
  --color-primary-dark: #00132a;       /* darker navy — mobile drawer */
  --color-primary-mid: #112748;        /* mid navy used in hero & services bg */
  --color-fg-on-dark: #ffffff;
  --color-secondary: #ABCCE7;          /* pale ice blue — accents/labels on dark */
  --color-lede: var(--color-secondary); /* hero lede + quote-form sub. Defaults to the secondary (the shipped look) and re-resolves per palette on its own, since [data-theme] sets --color-secondary on this same element. Override it in a palette block only when that skin wants its hero body copy to read differently from its on-dark label accent. */
  --color-submit: var(--color-accent);       /* quote-form submit fill — defaults to the accent; override to give a skin a second fill colour */
  --color-submit-hover: var(--color-accent-dark);
  --color-on-submit: var(--color-on-accent);
  --color-surface-services: var(--color-primary); /* .section-services surface — defaults to the shared dark-section colour; override for a skin that wants the services band on its own surface */
  --color-outline-on-dark: var(--color-fg-on-dark); /* .btn-outline-light border — defaults to white; override to bring a third colour into the button set */
  --btn-outline-bg: transparent;             /* .btn-outline-light's two states, as tokens, so a skin can run the */
  --btn-outline-ink: var(--color-outline-on-dark);        /* button filled-by-default and hollow-on-hover without a */
  --btn-outline-bg-hover: var(--color-outline-on-dark);   /* palette-scoped structural rule. Default = hollow, fills on hover. */
  --btn-outline-ink-hover: var(--color-primary);
  --btn-navy-bg: transparent;                /* same pair for .btn-outline-navy, the outline button on LIGHT */
  --btn-navy-ink: var(--color-primary);      /* sections (the "Free Quote" buttons). Default = hollow, fills on hover. */
  --btn-navy-bg-hover: var(--color-primary);
  --btn-navy-ink-hover: var(--color-fg-on-dark);
  --bar-1: var(--color-accent);              /* accent bar under each service-card image. Cards CYCLE through the */
  --bar-2: var(--color-secondary);           /* three via :nth-child(3n) — one solid colour per card, so the palette */
  --bar-3: var(--color-lede);                /* reads across the grid rather than inside a single bar. */
  --color-accent: #42A5F5;             /* light snowflake blue (button bg, accents on dark) */
  --color-accent-dark: #176ABC;        /* button hover bg / service-card header bg */
  --color-on-accent: #ffffff;          /* ink ON accent fills — white here is grandfathered (pre-contract, 2.65:1 on #42A5F5); new palettes must hit ≥4.5 on BOTH accent fills (light accent ⇒ dark ink) */
  --color-link: var(--color-accent-dark); /* body links + accent ink on light (a, .accent, .subhead, h3s) */
  --color-text: #2E2E32;
  --color-text-muted: #6c6f76;
  --color-charcoal: #2E2E32;          /* footer / dark surfaces */
  --color-bg: #ffffff;
  --color-bg-alt: #F3F3F3;
  --color-border: #e1e4ea;
  --color-error: #b00020;
  --color-focus: #176ABC;

  --color-dot-idle: #B6B8BB;           /* idle carousel dot (1.79:1 on the band) */

  /* muted foregrounds ON the dark footer — tinted per palette */
  --on-dark-body: #c9cfd8;             /* footer body text + links */
  --on-dark-faint: #8a909a;            /* legal fine print */

  /* photo-overlay gradients (tinted washes over section bg images) */
  --overlay-hero: linear-gradient(135deg, rgba(46, 46, 50, 0.65) 0%, rgba(46, 46, 50, 0.82) 100%);      /* hero + .hero-service (charcoal) */
  --overlay-spotlight: linear-gradient(135deg, rgba(46, 46, 50, 0.82) 0%, rgba(46, 46, 50, 0.92) 100%); /* .spotlight (charcoal, denser) */
  --overlay-deep: linear-gradient(135deg, rgba(0, 19, 42, 0.86) 0%, rgba(0, 19, 42, 0.93) 100%);        /* .feature-aside (primary-dark) */
  --overlay-banner: linear-gradient(135deg, rgba(0, 29, 61, 0.78) 0%, rgba(0, 29, 61, 0.88) 100%);      /* .banner (primary) */

  /* charcoal-tinted figure shadow (alpha too high to count as neutral) */
  --shadow-figure: 0 0 15px -3px rgba(46, 46, 50, 0.47);

  /* check list bullet — CSS vars can't interpolate into a data-URI, so each
     palette supplies its own full url() with the accent stroke */
  --check-list: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'><path d='M12 34L26 47L52 17' fill='none' stroke='%2342A5F5' stroke-width='6' stroke-linecap='round' stroke-linejoin='round'/></svg>");

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

  --shadow-sm: 0 1px 2px rgba(0, 29, 61, 0.06);
  --shadow-md: 0 8px 24px rgba(0, 29, 61, 0.12);
  --shadow-lg: 0 16px 48px rgba(0, 29, 61, 0.25);

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

  /* SITE-LOCAL type: Fraunces (display) + Source Sans 3 (body). The display
     fallbacks are SERIF on purpose — falling back to a sans would swap between
     wildly different shapes on a slow load. */
  --font-sans: "Source Sans 3", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-display: "Fraunces", Georgia, "Times New Roman", Times, serif;
  --font-watermark: "Fraunces", Georgia, "Times New Roman", Times, serif; /* hero watermark (uppercase + bold via .hero-watermark) */
}

/* ============================================================
   ASSEMBLY-TIME PALETTE VARIANTS — the standard every skin follows
   (full contract: templates/_template/CLAUDE.md "Color palettes")
   Default (no attribute) = the navy + snowflake-blue skin in :root above.
   To build a site in another palette, set the attribute on <html>:
       <html lang="en" data-theme="graphite">
   Rules of the system (hard requirements for every palette block):
   • FULL-SPECTRUM — override EVERY color role from :root (same role,
     new value). Exemptions: white-on-dark tokens (--color-fg-on-dark,
     white-alpha washes like the hero watermark) may stay white, and the
     low-alpha neutral shadows (--shadow-sm/md/lg, and the .dropdown's
     literal 0 12px 32px rgba(0,29,61,0.18)) stay un-overridden — at
     their opacity they read as neutral. The high-alpha
     --shadow-figure is NOT exempt and must be overridden.
   • FUNCTION PRESERVED — light backgrounds stay light, dark sections
     stay dark, inks stay dark-and-readable, error stays recognizably
     red. Nothing reorganizes which role does what.
   • PALETTE SEPARATION — palettes must differ at a glance INCLUDING
     neutrals and secondaries, not just the accent. Alt-band bgs sit in
     different hue families (neutral gray vs deeper concrete gray vs
     green mist — never two near-identical creams).
   • CONTRAST — --color-on-accent on --color-accent AND on
     --color-accent-dark ≥4.5:1; --color-link on white AND on
     --color-bg-alt ≥4.5:1; --color-accent / --color-secondary on
     --color-primary ≥4.5:1; --color-text on --color-bg targets ≥7:1
     (≥4.5 minimum). (The DEFAULT's white-on-#42A5F5 buttons predate
     this contract and are intentionally left as shipped.)
   Add a palette by cloning a block below and re-deriving every role.
   The blocks here are deliberately far apart (cool graphite/cyan vs
   deep spruce/green vs warm petrol/turquoise) so clones inherit the
   separation standard.
   ============================================================ */

/* Graphite — near-black graphite + steel: vivid ice-cyan accent with
   dark ink, frosty silver-blue secondary, concrete-gray alt band,
   cool white page, cool near-black dark sections. */
[data-theme="graphite"] {
  --color-primary: #23282F;            /* graphite — header text, primary surfaces, quote card */
  --color-primary-dark: #15181D;       /* deeper graphite — mobile drawer */
  --color-primary-mid: #333A44;        /* mid graphite panels */
  --color-fg-on-dark: #ffffff;         /* stays white (exempt) */
  --color-secondary: #B9C6D2;          /* frosty silver-blue on dark (≥4.5 on primary) */
  --color-accent: #3FC5EE;             /* vivid ice cyan — pops on graphite (≥4.5 on primary) */
  --color-accent-dark: #22A5CE;        /* deeper cyan hover / card-header bg */
  --color-on-accent: #0B2530;          /* deep ink on the cyan fills (≥4.5 on both) */
  --color-link: #2D6A85;               /* steel-blue link ink (≥4.5 on white + bg-alt) */
  --color-text: #26292E;               /* cool graphite body ink (~13:1 on bg) */
  --color-text-muted: #5C646E;         /* cool muted ink (≥4.5 on white + bg-alt) */
  --color-charcoal: #191C21;           /* cool near-black footer / hero overlay base */
  --color-bg: #F7F8FA;                 /* cool white page bg */
  --color-bg-alt: #E7E9EC;             /* concrete-gray alt band (clearly gray, not blue) */
  --color-border: #d3d7dc;             /* cool gray border */
  --color-error: #B0242F;              /* cool crimson */
  --color-focus: #2D6A85;              /* matches link ink */
  --color-dot-idle: #A8ADB3;           /* idle carousel dot (1.86:1) */

  --on-dark-body: #c3cad2;             /* cool footer body/links */
  --on-dark-faint: #868f99;            /* cool legal fine print */

  --overlay-hero: linear-gradient(135deg, rgba(25, 28, 33, 0.68) 0%, rgba(25, 28, 33, 0.84) 100%);
  --overlay-spotlight: linear-gradient(135deg, rgba(25, 28, 33, 0.84) 0%, rgba(25, 28, 33, 0.93) 100%);
  --overlay-deep: linear-gradient(135deg, rgba(13, 16, 20, 0.87) 0%, rgba(13, 16, 20, 0.94) 100%);
  --overlay-banner: linear-gradient(135deg, rgba(35, 40, 47, 0.80) 0%, rgba(35, 40, 47, 0.90) 100%);

  --shadow-figure: 0 0 15px -3px rgba(25, 28, 33, 0.45);

  --check-list: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'><path d='M12 34L26 47L52 17' fill='none' stroke='%233FC5EE' stroke-width='6' stroke-linecap='round' stroke-linejoin='round'/></svg>");
}

/* Evergreen — deep spruce + fresh green: spruce dark sections (warm vs
   graphite's cool near-black), fresh-green accent with spruce ink,
   ice-mint secondary, green-mist alt band, warm snow-white page. */
[data-theme="evergreen"] {
  --color-primary: #123B2E;            /* deep spruce — header text, primary surfaces, quote card */
  --color-primary-dark: #0B2A20;       /* darker spruce — mobile drawer */
  --color-primary-mid: #1E4F3E;        /* mid spruce panels */
  --color-fg-on-dark: #ffffff;         /* stays white (exempt) */
  --color-secondary: #B5DCC8;          /* ice-mint on dark (≥4.5 on primary) */
  --color-accent: #46C98A;             /* fresh green — reads on spruce (≥4.5 on primary) */
  --color-accent-dark: #2FAA71;        /* deeper green hover / card-header bg */
  --color-on-accent: #06281A;          /* spruce ink on the green fills (≥4.5 on both) */
  --color-link: #1F6B4A;               /* forest-green link ink (≥4.5 on white + bg-alt) */
  --color-text: #263229;               /* green-tinged body ink (~13:1 on bg) */
  --color-text-muted: #5B6A5F;         /* mossy muted ink (≥4.5 on white + bg-alt) */
  --color-charcoal: #14291F;           /* dark green-black footer / hero overlay base */
  --color-bg: #FAFAF6;                 /* warm snow-white page bg */
  --color-bg-alt: #E3EEE5;             /* green-mist alt band (hue ~130°) */
  --color-border: #cfdfd4;             /* mint-gray border */
  --color-error: #A82F23;              /* warm brick red */
  --color-focus: #1F6B4A;              /* matches link ink */
  --color-dot-idle: #A6B3A9;           /* idle carousel dot (1.83:1) */

  --on-dark-body: #c2d4c8;             /* minty footer body/links */
  --on-dark-faint: #83988a;            /* minty legal fine print */

  --overlay-hero: linear-gradient(135deg, rgba(20, 41, 31, 0.70) 0%, rgba(20, 41, 31, 0.85) 100%);
  --overlay-spotlight: linear-gradient(135deg, rgba(20, 41, 31, 0.85) 0%, rgba(20, 41, 31, 0.93) 100%);
  --overlay-deep: linear-gradient(135deg, rgba(8, 26, 18, 0.87) 0%, rgba(8, 26, 18, 0.94) 100%);
  --overlay-banner: linear-gradient(135deg, rgba(18, 59, 46, 0.80) 0%, rgba(18, 59, 46, 0.90) 100%);

  --shadow-figure: 0 0 15px -3px rgba(20, 41, 31, 0.45);

  --check-list: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'><path d='M12 34L26 47L52 17' fill='none' stroke='%2346C98A' stroke-width='6' stroke-linecap='round' stroke-linejoin='round'/></svg>");
}

/* Azure — bright winter cobalt: cobalt-navy dark sections (bluer & brighter
   than the default near-black navy), a vivid light-cobalt accent with deep
   navy ink, ice-blue secondary, a faint-blue alt band (clearly blue vs
   graphite's concrete-gray and evergreen's green mist), cool near-white page. */
[data-theme="azure"] {
  --color-primary: #073A6B;            /* cobalt navy — header text, primary surfaces, quote card */
  --color-primary-dark: #052C52;       /* deeper cobalt navy — mobile drawer */
  --color-primary-mid: #06457F;        /* mid cobalt (seed navy) — hero & services bg */
  --color-fg-on-dark: #ffffff;         /* stays white (exempt) */
  --color-secondary: #A8C4EC;          /* ice-blue on dark (6.4:1 on primary) */
  --color-accent: #5CADF7;             /* vivid light cobalt — reads on cobalt navy (4.8:1 on primary) */
  --color-accent-dark: #2685E1;        /* deeper cobalt hover / card-header bg */
  --color-on-accent: #05182C;          /* deep navy ink on the cobalt fills (7.5:1 accent / 4.7:1 accent-dark) */
  --color-link: #0A62B0;               /* cobalt link ink (5.9:1 on white + 5.2:1 on bg-alt) */
  --color-text: #232833;               /* cool blue-black body ink (~14:1 on bg) */
  --color-text-muted: #5A6472;         /* cool slate muted ink (≥4.5 on white + bg-alt) */
  --color-charcoal: #262B40;           /* near-black navy footer / hero overlay base (seed) */
  --color-bg: #F7FAFD;                 /* cool near-white page bg */
  --color-bg-alt: #E4EDF7;             /* faint-azure alt band (HSL 212°/54% — clearly blue) */
  --color-border: #CDD9E6;             /* cool cobalt-gray border */
  --color-error: #B0202F;              /* cool crimson (6.5:1 on bg) */
  --color-focus: #0A62B0;              /* matches link ink */
  --color-dot-idle: #A6AFBB;           /* idle carousel dot (1.87:1) */

  --on-dark-body: #C4CEDE;             /* cool cobalt footer body/links (8.8:1 on charcoal) */
  --on-dark-faint: #9099AB;            /* cool legal fine print (4.88:1 on charcoal; #8790A2 was 4.36, Codex PR#5) */

  --overlay-hero: linear-gradient(135deg, rgba(38, 43, 64, 0.66) 0%, rgba(38, 43, 64, 0.83) 100%);
  --overlay-spotlight: linear-gradient(135deg, rgba(38, 43, 64, 0.83) 0%, rgba(38, 43, 64, 0.92) 100%);
  --overlay-deep: linear-gradient(135deg, rgba(5, 44, 82, 0.86) 0%, rgba(5, 44, 82, 0.93) 100%);
  --overlay-banner: linear-gradient(135deg, rgba(7, 58, 107, 0.78) 0%, rgba(7, 58, 107, 0.88) 100%);

  --shadow-figure: 0 0 15px -3px rgba(38, 43, 64, 0.46);

  --check-list: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'><path d='M12 34L26 47L52 17' fill='none' stroke='%235CADF7' stroke-width='6' stroke-linecap='round' stroke-linejoin='round'/></svg>");
}

/* Sandstone — high-desert turquoise + sandstone: deep petrol dark sections,
   a medium turquoise accent with near-black teal ink, warm sand secondary
   carried ON the dark (too saturated to be a background field), pale cream
   alt band, warm off-white page. The only warm-neutral sibling. */
[data-theme="sandstone"] {
  --color-primary: #0F2E3D;            /* deep petrol — header text, primary surfaces, quote card */
  --color-primary-dark: #09212C;       /* deeper petrol — mobile drawer */
  --color-primary-mid: #113240;        /* mid petrol — hero & services bg (kept close to primary so the mid-tone accent still clears 4.5) */
  --color-fg-on-dark: #ffffff;         /* stays white (exempt) */
  --color-secondary: #E5CB90;          /* warm sand on dark (8.98 on primary) */
  --color-lede: #FFF3C8;               /* pale cream hero lede — the sand is kept for LABELS (eyebrows, subheads, on-dark links) but read too tinted as running body copy */
  --color-submit: #E5CB90;             /* sand submit button — a second fill colour so the turquoise isn't the only saturated thing on the page (8.98 on the quote card) */
  --color-submit-hover: #D6B872;       /* deeper sand hover */
  --color-on-submit: #2A2416;          /* warm near-black ink (9.75 on the fill, 8.04 on hover) */
  --color-surface-services: #325F6C;   /* steel services band — the seed #458393 is a mid-tone and fails as a surface (white 4.27, body copy 3.27); this is the same hue dropped far enough to carry white at 7.03 and body at 5.03, and it reads 2.02 off the petrol bands either side */
  --color-outline-on-dark: #FFF3C8;    /* cream outline buttons — third colour in the button set alongside turquoise fills and the sand submit */
  --btn-outline-bg: var(--color-outline-on-dark);    /* FLIPPED vs the default: this skin runs the button */
  --btn-outline-ink: var(--color-primary);           /* filled cream by default (petrol ink, 12.79 on the fill) */
  --btn-outline-bg-hover: transparent;               /* and hollows out on hover, so the cream reads as a solid */
  --btn-outline-ink-hover: var(--color-outline-on-dark); /* block next to the turquoise Call button rather than a hairline */
  --btn-navy-bg: var(--color-primary);               /* FLIPPED too: the light-section "Free Quote" buttons run */
  --btn-navy-ink: var(--color-fg-on-dark);           /* filled petrol with white ink (14.20), hollowing on hover. */
  --btn-navy-bg-hover: transparent;                  /* Puts the petrol surface colour into the light sections, */
  --btn-navy-ink-hover: var(--color-primary);        /* which otherwise only ever show turquoise. */
  --bar-1: #E5CB90;                    /* sand  — 4.44 on the services band */
  --bar-2: #FFF3C8;                    /* cream — 6.33 on the services band */
  --bar-3: #458393;                    /* steel — 1.65 on the services band. Chosen deliberately as the palette's own mid-steel, but it is near-invisible against --color-surface-services (#325F6C), which is the same hue: every third card reads as having no bar. #7FC0CE (3.46) or #8FCBD8 (3.91) are the same family and actually show. */
  --color-accent: #34A99D;             /* turquoise — reads on petrol (4.94 on primary) */
  --color-accent-dark: #2C9A8F;        /* deeper turquoise hover / card-header bg (a medium accent leaves little headroom — this is as dark as it goes with dark ink) */
  --color-on-accent: #04211E;          /* near-black teal ink on the turquoise fills (5.89 accent / 4.93 accent-dark) */
  --color-link: #326A7A;               /* deep steel-teal link ink (5.83 on bg + 5.44 on bg-alt) */
  --color-text: #262A2C;               /* warm-neutral body ink (~14:1 on bg) */
  --color-text-muted: #5B6560;         /* slate-sage muted ink (≥4.5 on bg + bg-alt) */
  --color-charcoal: #1E2A2E;           /* dark teal-slate footer / hero overlay base */
  --color-bg: #FDFBF4;                 /* warm off-white page bg */
  --color-bg-alt: #FBF3DA;             /* pale cream band (hue ~46° — vs neutral gray, concrete gray, green mist, faint azure). Desaturated from the seed #FFF3C8: at full-section scale that read as a wall of yellow. Same luminance step off the page (1.07:1), less chroma. */
  --color-border: #E0D9C4;             /* warm sand-tinted border */
  --color-error: #B3231F;              /* warm brick red (6.38 on bg) */
  --color-focus: #326A7A;              /* matches link ink */
  --color-dot-idle: #B3B3A3;           /* idle carousel dot (1.91:1) */

  --on-dark-body: #BFD3D0;             /* cool-teal footer body/links (9.43 on charcoal) */
  --on-dark-faint: #8FA3A4;            /* teal-gray legal fine print (5.57 on charcoal) */

  --overlay-hero: linear-gradient(135deg, rgba(30, 42, 46, 0.66) 0%, rgba(30, 42, 46, 0.83) 100%);
  --overlay-spotlight: linear-gradient(135deg, rgba(30, 42, 46, 0.83) 0%, rgba(30, 42, 46, 0.92) 100%);
  --overlay-deep: linear-gradient(135deg, rgba(9, 33, 44, 0.87) 0%, rgba(9, 33, 44, 0.94) 100%);
  --overlay-banner: linear-gradient(135deg, rgba(15, 46, 61, 0.78) 0%, rgba(15, 46, 61, 0.88) 100%);

  --shadow-figure: 0 0 15px -3px rgba(30, 42, 46, 0.46);

  --check-list: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'><path d='M12 34L26 47L52 17' fill='none' stroke='%2334A99D' stroke-width='6' stroke-linecap='round' stroke-linejoin='round'/></svg>");
}

/* ---------- Self-hosted fonts (latin subsets) ----------
   SITE-LOCAL: this skin runs Fraunces + Source Sans 3, not rely's Raleway.
   Fraunces is variable on opsz 9–144 AND wght 400–900, so headings pick up the
   display cut automatically at large sizes (font-optical-sizing below). Its
   SOFT/WONK axes are left at their 0 defaults — the straight-laced instance.
   Source Sans 3 is the same file the polebarn skin ships (400–700). */
@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 400 900;   /* variable wght — covers 700 headings + 800 watermark */
  font-display: swap;
  src: url("/fonts/fraunces.woff2") format("woff2");
}
@font-face {
  font-family: "Source Sans 3";
  font-style: normal;
  font-weight: 400 700;   /* variable wght — covers 400/500/600/700 body + nav */
  font-display: swap;
  src: url("/fonts/source-sans-3.woff2") format("woff2");
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
/* scrollbar-gutter: the hero's min-height and --hero-notch are both vw-based,
   so a scrollbar appearing after load narrows the viewport, recomputes them and
   visibly re-scales the cover background. Reserving the gutter from first paint
   keeps those vw values constant. */
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scrollbar-gutter: stable; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
:target,
section[id] { scroll-margin-top: calc(80px + 1rem); }
html, body { overflow-x: clip; } /* safety net against rogue horizontal overflow */
body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.6;
  color: var(--color-text);
  background: var(--color-bg);
  -webkit-font-smoothing: antialiased;
}
img, picture, svg { display: block; max-width: 100%; height: auto; }
h1, h2, h3, h4 {
  font-family: var(--font-display);
  line-height: 1.05;
  margin: 0 0 0.5em;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  font-weight: 400;
  color: var(--color-primary);
}
h1 { font-size: clamp(2.25rem, 5.5vw, 3.75rem); }
h2 { font-size: clamp(1.5rem, 1.25rem + 0.9vw, 1.9rem); text-transform: none; margin-bottom: 0.7em; } /* fluid ~24px→~30px, smooth across phone→desktop; uniform space below */
h3 { font-size: clamp(1.05rem, 2.2vw, 1.25rem); }                      /* 20px desktop, scales down on mobile */
h4 {
  font-family: var(--font-sans);
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  color: var(--color-fg-on-dark);
  text-transform: uppercase;
}
p { margin: 0 0 1em; }
a { color: var(--color-link); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { text-decoration-thickness: 2px; }

/* ---------- A11y ---------- */
:focus-visible {
  outline: 3px solid var(--color-focus);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}
.skip-link {
  position: absolute;
  left: -10000px;
  top: auto;
  width: 1px; height: 1px;
  overflow: hidden;
  background: var(--color-primary);
  color: #fff;
  padding: 0.75rem 1rem;
  z-index: 1000;
}
.skip-link:focus { left: 0; top: 0; width: auto; height: auto; }
.visually-hidden,
.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;
}

/* ---------- Layout ---------- */
.container {
  width: 100%;
  max-width: var(--max-w);
  margin: 0 auto;
  padding: 0 1.25rem;
}
main { display: block; }
section { padding: clamp(3rem, 7vw, 5rem) 0; }
.section-dark { background: var(--color-primary); color: var(--color-fg-on-dark); }
.section-dark h2, .section-dark h3 { color: var(--color-fg-on-dark); }
.section-dark p { color: rgba(255,255,255,0.82); }
.section-dark a { color: var(--color-secondary); }
/* keep button text on intent inside dark sections (the rule above would otherwise tint links) */
.section-dark .btn-primary,
.section-dark .btn-primary:hover { color: var(--color-on-accent); }
/* The services band on its own surface. Same specificity as .section-dark (0,1,0),
   so this MUST stay after it to win the cascade. Defaults to the same colour, i.e.
   a no-op for any palette that doesn't override --color-surface-services. */
.section-services { background: var(--color-surface-services); }
.section-dark .btn-outline-light { color: #fff; }
.section-dark .btn-outline-light:hover { color: var(--color-primary); }

/* Accent inline-text helper: RELY SNOW REMOVAL inside headings */
.accent { color: var(--color-link); }
.accent-light { color: var(--color-secondary); }

/* Subhead pattern — blue uppercase under H2 (used on h3 elements with this class) */
.subhead {
  font-family: var(--font-display);
  text-transform: uppercase;
  color: var(--color-link);
  font-size: clamp(1.05rem, 2.2vw, 1.25rem); /* match h3 — sits under the h2 as a kicker */
  margin: 1.25em 0 0.4em;
  letter-spacing: 0.01em;
  font-weight: 400;
  line-height: 1.15;
}
.section-dark .subhead { color: var(--color-secondary); }

/* ---------- Header / nav ----------
   The header runs on --color-primary at EVERY width (it used to be --color-bg
   above 880px and only went dark on mobile). A light header is only ever held
   apart from the page by a 1px --color-border hairline, and in skins whose page
   bg is close to their alt band that reads as no bar at all — sandstone's
   --color-bg (#FDFBF4) IS the page colour and its alt band is 1.07:1 off it.
   Dark gives the sticky bar a real edge in every palette (white on primary runs
   11.5–16.9 across the five skins) and puts the primary surface at the top of
   every page rather than only in the dark bands.
   Consequence for assembly: the logo is on a DARK plate at all widths, so a skin
   needs ONE light-ink logo — not the light/dark <picture> pair the old
   breakpoint-switched header required. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--color-primary);
  border-bottom: 0;
}
/* Focus ring: --color-focus is tuned for LIGHT surfaces and lands ~2.4:1 on the
   primary bar in several skins, under the 3:1 floor for a non-text indicator.
   --color-secondary is the on-dark accent by contract (6.44–10.07 across skins). */
.site-header :focus-visible { outline-color: var(--color-secondary); }
.site-header .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
  min-height: 80px;
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  color: var(--color-fg-on-dark);   /* the .brand-mark svg is fill="currentColor" */
  text-decoration: none;
}
.brand-mark { width: 44px; height: 44px; flex-shrink: 0; }
.brand-logo { height: 56px; width: auto; display: block; }
@media (max-width: 600px) { .brand-logo { height: 44px; } }
.brand-text {
  display: flex;
  flex-direction: column;
  line-height: 0.95;
}
.brand-text .name {
  font-family: var(--font-display);
  font-size: 1.6rem;
  letter-spacing: 0.04em;
  color: var(--color-fg-on-dark);
}
.brand-text .tag {
  font-family: var(--font-sans);
  font-size: 0.85rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--on-dark-body);   /* was --color-text-muted, a light-surface ink */
}
.site-nav { display: flex; align-items: center; }
.nav-list {
  display: flex;
  align-items: center;
  gap: 0.25rem 2rem;
  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(--color-fg-on-dark);
  text-decoration: none;
  font-weight: 600;
  font-size: 0.95rem;
  padding: 1.5rem 0.25rem; /* tall hit area so dropdown stays open while moving cursor */
}
/* Nav hover ink sits on the DARK header (see .site-header above) — use
   --color-secondary, the on-dark accent by contract. NOT --color-link, which is
   tuned for light surfaces and lands ~2.4:1 on the bar in several skins, and NOT
   --color-accent-dark (a fill token that goes light-cyan/green in alternates). */
.nav-item > a:hover { color: var(--color-secondary); }
.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: 260px;
  background: var(--color-bg);
  box-shadow: 0 12px 32px rgba(0, 29, 61, 0.18);
  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(--color-accent);
}
.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 1rem;
  font-size: 0.9rem;
  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(--color-link); }
.dropdown-2col {
  display: grid;
  grid-template-columns: 1fr 1fr;
  min-width: 380px;
  gap: 0;
}
.nav-cta { margin-left: 0.5rem; }
.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 { display: block; position: relative; width: 22px; height: 2px; background: #fff; transition: background-color .2s ease; }
.menu-toggle span::before,
.menu-toggle span::after {
  content: "";
  position: absolute;
  left: 0;
  width: 22px;
  height: 2px;
  background: #fff;
  transition: transform .25s ease, top .25s ease;
}
.menu-toggle span::before { top: -6px; }
.menu-toggle span::after  { top:  6px; }
.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: 880px) {
  .site-header {
    position: static; /* scroll fully off-screen on mobile */
    /* background/border-bottom used to be set here — they are the base rule now. */
  }
  .site-header .container {
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: center;
    gap: 0.5rem 0.75rem;
    padding: 0.75rem 1.25rem;
  }
  .site-nav { display: none; }
  .brand { order: 1; }
  .menu-toggle { order: 2; display: inline-flex; }
  .nav-cta {
    order: 3;
    margin: 0;
    flex: 0 1 auto;
  }
  /* If both can't fit side-by-side, push the phone to its own full-width row below the logo */
  @media (max-width: 460px) {
    .nav-cta { flex: 1 1 100%; text-align: center; }
  }

  /* Mobile drawer: revealed when .is-open is set by nav.js */
  .site-nav.is-open {
    display: block;
    order: 4;
    flex: 1 1 100%;
    margin: 0.75rem -1.25rem -0.75rem; /* extend full bleed to container edges */
    padding: 0.25rem 1.25rem 1rem;
    background: var(--color-primary-dark);
    border-top: 1px solid rgba(255,255,255,0.08);
  }
  .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.08);
  }
  .site-nav.is-open .nav-item > a {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.85rem 0;
    color: #fff;
    font-size: 1rem;
  }
  /* Caret stays visible in drawer; rotates 180° on expand */
  .site-nav.is-open .nav-caret {
    transition: transform .2s ease;
  }
  .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; }
  /* Dropdowns start collapsed in the mobile drawer; show only when .expanded */
  .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;
    margin: 0;
  }
  .site-nav.is-open .has-dropdown.expanded > .dropdown {
    display: block;
  }
  .site-nav.is-open .dropdown a {
    white-space: normal; /* allow long items to wrap on mobile drawer */
  }
  .site-nav.is-open .dropdown-2col {
    grid-template-columns: 1fr;
  }
  .site-nav.is-open .dropdown a {
    color: rgba(255,255,255,0.8);
    padding: 0.4rem 0;
    font-size: 0.9rem;
    white-space: normal;
  }
  .site-nav.is-open .dropdown a:hover,
  .site-nav.is-open .dropdown a:focus-visible {
    background: transparent;
    color: var(--color-secondary);
  }
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  font: inherit;
  font-weight: 700;
  padding: 0.85rem 1.6rem;
  border-radius: var(--radius-md);
  border: 2px solid transparent;
  text-decoration: none;
  cursor: pointer;
  transition: transform .08s ease, background-color .15s ease, color .15s ease, border-color .15s ease;
  min-height: 48px;
  line-height: 1.2;
  letter-spacing: 0.02em;
}
.btn-primary {
  background: var(--color-accent);
  color: var(--color-on-accent);
}
.btn-primary:hover { background: var(--color-accent-dark); }
.btn-primary:active { transform: translateY(1px); }
.btn-outline-navy {
  background: var(--btn-navy-bg);
  color: var(--btn-navy-ink);
  border-color: var(--color-primary);
}
.btn-outline-navy:hover { background: var(--btn-navy-bg-hover); color: var(--btn-navy-ink-hover); }
.btn-outline-light {
  background: var(--btn-outline-bg);
  color: var(--btn-outline-ink);
  border-color: var(--color-outline-on-dark);
}
.btn-outline-light:hover { background: var(--btn-outline-bg-hover); color: var(--btn-outline-ink-hover); }
.btn-tel {
  background: var(--color-accent);
  color: var(--color-on-accent);
}
.btn-tel:hover { background: var(--color-accent-dark); }
.btn-block { display: flex; width: 100%; }

/* ---------- Hero ---------- */
.hero {
  --hero-notch: clamp(4rem, 9vw, 7rem); /* depth of the downward triangle */
  position: relative;
  /* Uniform height across pages: the box is governed by min-height and the
     content is vertically centered, so headline/lede/breadcrumb length no
     longer changes how tall the hero is. Padding is just minimum insets. */
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: clamp(44rem, 38rem + 14vw, 52rem);
  padding: clamp(5rem, 11vw, 9rem) 0 calc(clamp(8rem, 14vw, 11rem) + var(--hero-notch));
  background:
    var(--overlay-hero),
    url("/images/snow-removal-service-bg.webp") center / cover no-repeat,
    var(--color-charcoal);
  color: #fff;
  text-align: center;
  overflow: hidden;
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - var(--hero-notch)), 50% 100%, 0 calc(100% - var(--hero-notch)));
}
.hero-inner {
  position: relative;
  z-index: 2;
  max-width: 900px;
  margin: 0 auto;
  padding: 0 1.25rem;
}
.hero h1 {
  color: #fff;
  font-size: clamp(2rem, 5.5vw, 3.5rem);
  margin: 0 0 2rem;
  text-transform: none;
  font-family: var(--font-sans);
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.15;
}
.hero-lede {
  color: var(--color-lede);
  font-size: 1rem; /* match body copy */
  margin: 0 auto 2rem;
}
.hero-cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1rem;
  justify-content: center;
}
.hero-watermark {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  z-index: 1;
  text-align: center;
  font-family: var(--font-watermark);
  font-weight: 800; /* Fraunces extra-bold (its wght axis reaches 900) */
  font-size: clamp(6rem, 17vw, 14rem);
  line-height: 0.85;
  letter-spacing: -7px;
  color: rgba(255,255,255,0.12);
  text-transform: uppercase;
  white-space: nowrap;
  user-select: none;
}
.hero-watermark span { display: block; }
.hero-watermark span:nth-child(1) { font-size: clamp(8rem, 22vw, 18rem); }
.hero-watermark span:nth-child(2) { font-size: clamp(4rem, 11vw, 9rem); }

/* ---------- ALT HERO: split (intro + form) variant ---------- */
/* Drops the centered/notched treatment: left-aligned two-column layout,
   no watermark, no clip-path (so the form card can't be clipped). */
.hero--split {
  min-height: auto;
  text-align: left;
  clip-path: none;
  padding: clamp(1.5rem, 4vw, 2.75rem) 0 clamp(3rem, 8vw, 6rem);
}
.hero--split .hero-watermark { display: none; }
.hero--split .hero-inner {
  max-width: var(--max-w);
  width: 100%;
  padding: 0 1.25rem;
}
.hero-split-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(2rem, 4vw, 3rem);
  align-items: start;
}
/* full-width headline for the split hero — spans above both columns */
.hero-split-title { margin-bottom: clamp(1.5rem, 3vw, 2.25rem); }
@media (min-width: 900px) {
  .hero-split-grid { grid-template-columns: 1.05fr 0.95fr; }
}
.hero--split .hero-lede { margin-left: 0; margin-right: 0; }
.hero--split .hero-cta-row { justify-content: flex-start; }
/* form card sits in the narrow right column — stack pitch above form */
.hero--split .quote-form-card {
  grid-template-columns: 1fr;
  gap: 1.25rem;
  padding: clamp(1.5rem, 3vw, 2rem);
}
.hero--split .quote-form-pitch { align-items: flex-start; text-align: left; }

/* Inner-page hero: same centered/notched treatment, but the home page's
   min-height is sized for four lede paragraphs and leaves a breadcrumb +
   one-line lede floating in dead space. */
.hero--page { min-height: clamp(26rem, 22rem + 10vw, 32rem); }
.hero--page h1 { margin-bottom: 1.25rem; }

/* ---------- Quote form (sits at the V-peak of the hero) ---------- */
.quote-form-section {
  position: relative;
  margin-top: clamp(-3rem, -5vw, -4rem);
  padding: 0 0 clamp(3rem, 6vw, 5rem);
  z-index: 3;
}
.quote-form-card {
  background: var(--color-primary);
  color: #fff;
  border-radius: var(--radius-lg);
  padding: clamp(1.75rem, 4vw, 2.5rem);
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.5rem;
  box-shadow: var(--shadow-lg);
}
@media (min-width: 820px) {
  .quote-form-card { grid-template-columns: 1fr 1.4fr; gap: 2.5rem; padding: 2.5rem 3rem; }
}
.quote-form-pitch {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  justify-content: center;
  gap: 0.5rem;
}
@media (min-width: 820px) { .quote-form-pitch { align-items: flex-start; text-align: left; } }
.quote-form-pitch .quote-form-title {
  color: #fff;
  font-family: var(--font-sans);
  font-weight: 800;
  margin: 0;
  font-size: clamp(1.5rem, 3vw, 2rem);
  line-height: 1.15;
}
.quote-form-pitch .quote-form-sub {
  color: var(--color-lede);
  font-weight: 600;
  margin: 0;
}
.quote-form-icon {
  width: 60px;
  height: 60px;
  border-radius: 50%;
  background: var(--color-secondary);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-top: 0.5rem;
  color: var(--color-primary);
}
.quote-form-icon svg {
  display: block;
  transform: rotate(90deg); /* default: point right toward form */
  transition: transform .2s ease;
}
@media (max-width: 819px) {
  .quote-form-icon svg { transform: rotate(180deg); /* stacked: point down toward form */ }
}
.quote-form form { display: grid; gap: 0.75rem; }
.quote-form .row-2 { display: grid; gap: 0.75rem; grid-template-columns: 1fr; }
@media (min-width: 520px) { .quote-form .row-2 { grid-template-columns: 1fr 1fr; } }
.quote-form input,
.quote-form textarea {
  font: inherit;
  padding: 0.85rem 1rem;
  border: 0;
  border-radius: var(--radius-sm);
  background: #fff;
  color: var(--color-text);
  width: 100%;
  min-height: 48px;
}
.quote-form textarea { min-height: 140px; resize: vertical; }
.quote-form input:focus,
.quote-form textarea:focus {
  outline: 3px solid var(--color-accent);
  outline-offset: 1px;
}
.quote-form button[type="submit"] {
  background: var(--color-submit);
  color: var(--color-on-submit);
  font: inherit;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 1rem;
  border: 0;
  border-radius: var(--radius-sm);
  cursor: pointer;
  min-height: 52px;
}
.quote-form button[type="submit"]:hover { background: var(--color-submit-hover); }

/* --- Turnstile responsiveness ---
   The widget renders at a fixed 300px width (Cloudflare's minimum), which would
   otherwise force the form column to 300px and overflow narrow phones. min-width:0
   lets the form/column shrink; the wrapper (a scroll container) drops the widget's
   300px min-content contribution and clips any spillover; the scale steps keep the
   whole widget visible as the column gets narrower. */
.quote-form,
.quote-form form { min-width: 0; }
.turnstile-wrap {
  width: 100%;
  min-width: 0;
  overflow: hidden;
  /* Reserve the widget's height BEFORE its iframe renders. Turnstile injects
     async with no intrinsic height, so without this the quote card grows on
     load, the hero grows with it, and the cover background visibly re-scales
     (the platform-wide "hero hop" — same fix as immov2's .cf-turnstile
     min-height). Light-theme widget measures 73px in this skin. */
  min-height: 73px;
}
.turnstile-wrap .cf-turnstile { transform-origin: left top; }
@media (max-width: 400px) {
  .turnstile-wrap .cf-turnstile { transform: scale(0.9); }
  .turnstile-wrap { height: 59px; min-height: 59px; }
}
@media (max-width: 345px) {
  .turnstile-wrap .cf-turnstile { transform: scale(0.74); }
  .turnstile-wrap { height: 48px; min-height: 48px; }
}

/* ---------- Flex-media (workhorse content block) ----------
   Text column + media column. The home page's Trust and Why sections are both
   instances of this one block. Variants:
     .flex-media--reverse  → media column on the LEFT (desktop)
   The text column may contain a heading, subheads, paragraphs, an optional
   .snow-list feature list, and a .flex-media-cta-row. */
.flex-media-grid {
  display: grid;
  gap: clamp(1.5rem, 3vw, 2.5rem);
  grid-template-columns: 1fr;
  align-items: start; /* image (and the buttons under it) top-align with the heading */
}
@media (min-width: 880px) { .flex-media-grid { grid-template-columns: 1.1fr 1fr; } }
.flex-media-text > :first-child { margin-top: 0; }
.flex-media-figure img {
  width: 100%;
  border-radius: var(--radius-md);
  aspect-ratio: 4 / 3;
  object-fit: cover;
  box-shadow: var(--shadow-figure);
}
.flex-media .snow-list {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.5rem 1.5rem;
  margin-top: 1.5rem;
}
@media (min-width: 560px) { .flex-media .snow-list { grid-template-columns: 1fr 1fr; } }
.flex-media-cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 2rem;
}
/* --reverse: put the media column first on desktop, natural order when stacked */
@media (min-width: 880px) {
  .flex-media--reverse .flex-media-figure { order: -1; }
}

/* --long: two-column layout for LONG copy, with the image cornered in one column.
   Default = image at the TOP of the right column; --long-reverse = image at the
   BOTTOM of the left column. Columns are equal height (stretch) so a bottom-pinned
   image sits flush with where the other column ends. Replaces the old --wrap and
   feature-columns blocks; holds ~2x the text of the side-by-side flex-media. */
.flex-media-long-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(1.5rem, 3vw, 2.5rem);
  align-items: stretch;
}
@media (min-width: 768px) {
  .flex-media-long-grid { grid-template-columns: 1fr 1fr; }
}
.flex-media-long-col { display: flex; flex-direction: column; }
.flex-media-long-col > :first-child { margin-top: 0; }
.flex-media-long-col h3 { color: var(--color-link); margin-top: 1.25em; }
.flex-media-long-figure { margin: 0; }
.flex-media-long-figure img {
  width: 100%;
  border-radius: var(--radius-md);
  aspect-ratio: 4 / 3;
  object-fit: cover;
  box-shadow: var(--shadow-figure);
}
/* image at the top of a column → gap below it; at the bottom → pushed down, gap above */
.flex-media-long-col > .flex-media-long-figure:first-child { margin-bottom: 1.25rem; }
.flex-media-long-col > .flex-media-long-figure:last-child { margin-top: auto; padding-top: 1.25rem; }

/* Snowflake bulleted list */
.snow-list {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 0.95rem;
}
.snow-list li {
  position: relative;
  padding-left: 32px;
  margin-bottom: 0.9rem;
  line-height: 1.5;
  color: var(--color-text);
}
.snow-list li strong { color: var(--color-primary); }
.snow-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.2em;
  width: 18px;
  height: 18px;
  background-repeat: no-repeat;
  background-size: contain;
  background-image: var(--check-list);
}
.section-dark .snow-list li { color: rgba(255,255,255,0.85); }
.section-dark .snow-list li strong { color: #fff; }

/* ---------- Services grid (dark) ---------- */
.services-grid {
  display: grid;
  gap: 1.5rem;
  grid-template-columns: 1fr;
  margin-top: 2rem;
}
@media (min-width: 600px) { .services-grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 960px) { .services-grid { grid-template-columns: repeat(3, 1fr); } }
.service-card {
  display: flex;
  flex-direction: column;
  background: transparent;
  border: 1px solid var(--color-accent-dark);
  border-radius: var(--radius-md);
  overflow: hidden;
  transition: transform .12s ease, border-color .15s ease, box-shadow .15s ease;
}
.service-card:hover {
  transform: translateY(-3px);
  border-color: var(--color-accent);
  box-shadow: 0 12px 28px rgba(0,0,0,0.35);
}
/* The card used to carry its name TWICE: an .service-card-header bar above the
   image and a differently-worded button below it. The bar is gone; the h3 moved
   down onto the button, so the service name is still a heading (8 per page on a
   services grid — they carry the section's keyword weight) but renders as the
   card's one call to action. */
.service-card-body { padding: 1.25rem; display: flex; flex-direction: column; flex: 1; gap: 0.75rem; }
.service-card-body img {
  width: calc(100% + 2.5rem);
  max-width: none; /* override global img max-width:100% so the bleed actually applies */
  margin: -1.25rem -1.25rem 0; /* bleed flush to left, top, right of card body */
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: 0;
  /* Accent bar welded to the foot of every card image — one solid colour per
     card, cycling through --bar-1/2/3 down the grid (see :nth-child below).
     The palette reads across the row rather than inside one bar. */
  border-bottom: 5px solid var(--bar-1);
}
.services-grid .service-card:nth-child(3n+2) .service-card-body img { border-bottom-color: var(--bar-2); }
.services-grid .service-card:nth-child(3n+3) .service-card-body img { border-bottom-color: var(--bar-3); }
/* Full white, not the 0.78 wash the other dark sections use — the services band
   sits on its own lighter steel surface, where a knocked-back white goes muddy. */
.service-card-body p { color: var(--color-fg-on-dark); margin: 0; font-size: 0.95rem; }
/* .service-card-cta is now an <h3>, sitting directly under the image and above
   the body copy — so it reads as the card's title and behaves as its button.
   The fill/padding sit on the inner <a> (or on the h3 itself for the static
   variant) so the whole button area is the click target. The 0,3,0 selector
   also has to out-specify `.section-dark a` (0,1,1), which would otherwise
   tint the label with --color-secondary. */
.service-card .service-card-cta {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 0.9rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  line-height: 1.2;
}
.service-card .service-card-cta > a,
.service-card .service-card-cta.service-card-cta--static {
  display: block;
  background: var(--color-accent);
  color: var(--color-on-accent);
  text-align: center;
  text-decoration: none;
  padding: 0.7rem 1rem;
  border-radius: var(--radius-sm);
  transition: background-color .15s ease;
}
.service-card .service-card-cta > a:hover { background: var(--color-accent-dark); }
/* Static (non-link) variant — looks like the button but isn't interactive.
   Used on the service cards we deliberately don't link out from the home page. */
.service-card .service-card-cta--static { cursor: default; }

/* ---------- Why-choose-us — now uses the shared .flex-media block (see above) ---------- */

/* ---------- Feature-aside (text column + aside links, over image bg) ---------- */
/* Background image behind the (already dark) section. Placed after .section-dark
   in source so it wins the equal-specificity background cascade. Swap the image
   once real content/photography lands. */
.feature-aside {
  position: relative;
  background:
    var(--overlay-deep),
    url("/images/snow-removal-service-bg.webp") center / cover no-repeat,
    var(--color-primary);
}
.feature-aside-grid {
  display: grid;
  gap: clamp(1.5rem, 3vw, 2.5rem);
  grid-template-columns: 1fr;
}
@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(--color-primary-mid);
  padding: 1.75rem;
  border-radius: var(--radius-md);
  text-align: center;
}
.feature-aside-box .feature-aside-box-title {
  color: #fff;
  margin: 0 0 1rem;
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 2vw, 1.5rem);
  font-weight: 400;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  line-height: 1.05;
}
.feature-aside-box .btn { width: 100%; background: var(--color-secondary); color: var(--color-primary); }
.feature-aside-box .btn:hover { background: #fff; }

/* ---------- Spotlight ---------- */
/* ---------- Banner (flex block: centered content over image bg) ---------- */
.banner {
  position: relative;
  min-height: 480px;
  display: flex;
  align-items: center;
  background:
    var(--overlay-banner),
    url("/images/parking-lot-snow-removal-piles-bg.webp") center / cover no-repeat,
    var(--color-primary);
  color: #fff;
  padding: clamp(3rem, 6vw, 5rem) 0;
}
.banner-inner {
  max-width: 760px;
  margin: 0 auto;
  text-align: center;
}
.banner h2 { color: #fff; }
.banner p { color: rgba(255, 255, 255, 0.85); }
/* Heading and CTA row stay centred (.banner-inner text-align + the row's own
   justify-content); only the body copy goes ragged-right, which reads far
   better now the block runs to two paragraphs. */
.banner-inner p { text-align: left; }
.banner-inner .banner-kicker { text-align: center; }

/* Stucco Systems and Finishes: the 70ch intro keeps the base rule's auto
   margins so it sits centred under the centred h2, but its text reads
   left-justified. #systems is the only .process-intro left on the site. */
#systems .process-intro { text-align: left; }

/* Our Stucco Project Process: .process-step centres the whole step, which is
   right for the icon, the step number and the h3 — only the step's body copy
   goes ragged-right. The icon keeps its own margin:0 auto, so it is unaffected.
   NOTE: the FAQ intro and the process intro were both .process-intro and both
   have been removed, so #systems is the only remaining use and the base rule's
   `text-align: center` no longer renders anywhere. */
.process-step p { text-align: left; }
.banner-kicker {
  font-family: var(--font-display);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 700;
  font-size: 0.9rem;
  color: var(--color-secondary) !important;
  margin: 0 0 0.5rem;
}
.banner-cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1rem;
  justify-content: center;
  margin-top: 1.75rem;
}

.spotlight {
  position: relative;
  background:
    var(--overlay-spotlight),
    url("/images/downtown-grand-rapids-mi-skyline-bg.webp") center / cover no-repeat,
    var(--color-charcoal);
  color: #fff;
}
.spotlight .container { display: grid; grid-template-columns: 1fr; gap: clamp(1.5rem, 4vw, 3rem); }
@media (min-width: 880px) { .spotlight .container { grid-template-columns: 1.3fr 1fr; } }
.spotlight h2 { color: var(--color-secondary); }
/* .spotlight is a dark panel but carries no .section-dark class, so headings
   would take the base light-surface ink (--color-primary) and vanish. */
.spotlight h3 { color: var(--color-fg-on-dark); }
.spotlight-side-title {
  font-family: var(--font-display);
  font-size: clamp(1.85rem, 4vw, 2.75rem);
  font-weight: 400;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  line-height: 1.05;
  color: #ffffff;
  margin: 0 0 1rem;
}
.spotlight-areas {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0 1.5rem;
}
@media (min-width: 480px) { .spotlight-areas { grid-template-columns: 1fr 1fr; } }
.spotlight-areas li { color: rgba(255,255,255,0.9); }
.spotlight-areas a { color: rgba(255,255,255,0.9); text-decoration: none; }
.spotlight-areas a:hover { color: #fff; text-decoration: underline; }

/* ---------- (feature-columns retired — long content now uses .flex-media--long) ---------- */

/* ---------- How it works ---------- */
.process-intro { max-width: 70ch; margin: 0 auto 2.5rem; text-align: center; }
.process-grid {
  display: grid;
  gap: 2rem;
  grid-template-columns: 1fr;
  list-style: none;
  padding: 0;
  margin: 0;
}
@media (min-width: 600px) { .process-grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 960px) { .process-grid { grid-template-columns: repeat(4, 1fr); } }
.process-step { text-align: center; }
.process-step img,
.process-step .process-step-icon {
  width: 160px;
  height: 160px;
  border-radius: 50%;
  object-fit: cover;
  margin: 0 auto 0.75rem;
  display: flex;
  align-items: center;
  justify-content: center;
}
.process-step .process-step-icon {
  background: var(--color-primary-mid);
  color: var(--color-secondary);
}
.process-step .step-num {
  display: block;
  font-family: var(--font-display);
  font-size: 2rem;
  color: var(--color-accent);
  line-height: 1;
  margin-bottom: 0.25rem;
}
.process-step h3 { color: #fff; margin-bottom: 0.5rem; }
.process-step p { color: rgba(255,255,255,0.78); font-size: 0.95rem; }

/* Mini CTA inside dark sections */
.mini-cta {
  margin-top: 3rem;
  text-align: center;
  padding: 1.5rem;
  background: rgba(255,255,255,0.03);
  border-radius: var(--radius-md);
}
.mini-cta p {
  color: var(--color-accent);
  font-weight: 700;
  margin: 0 0 0.5rem;
  font-size: 1.05rem;
}
.mini-cta p + p { color: rgba(255,255,255,0.78); font-weight: 400; margin-bottom: 1rem; }
.mini-cta .btn-primary { font-size: 0.95rem; color: var(--color-on-accent); }
.mini-cta .btn-primary:hover { color: var(--color-on-accent); }

/* ---------- Areas served chips (used elsewhere) ---------- */
.areas-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 0.75rem;
  padding: 0;
  margin: 1rem 0 0;
  list-style: none;
}
.areas-list li {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: 0;
  padding: 0.35rem 0.9rem;
  font-size: 0.95rem;
  color: var(--color-primary);
}

/* ---------- Testimonials carousel ---------- */
.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; /* allow the flex item to shrink instead of forcing overflow */
}
.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: var(--color-bg);
  border: 1px solid var(--color-border);
  border-top: 4px solid var(--color-accent);
  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-display);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--color-primary);
}
.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(--color-primary);
  color: #fff;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  transition: background-color .15s ease, color .15s ease, transform .08s ease;
}
.testi-arrow:hover { background: var(--color-accent); color: var(--color-on-accent); }
.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;
}
/* The idle dot was --color-border, a hairline token doing duty as a UI fill: it
   measured 1.15–1.27:1 against its own band in ALL FIVE palettes, so the row read
   as one floating dot rather than a position indicator (same bug fixed on
   rochester-radon-mitigation-co, 2026-08-04). --color-dot-idle is --color-text-muted
   mixed 45% into that palette's band, precomputed per palette and shipped as a token
   rather than left as a live color-mix() — the token set IS the skin here, and a
   palette-critical color computed inline in a block rule is the one thing this
   stylesheet's contract rules out. (color-mix renders this correctly; it was tried.)
   It lands ~1.85:1 — visible, and deliberately NOT higher: the
   accent-colored ACTIVE dot is itself only 1.65–2.59:1 on a light band, so a
   full-strength muted idle dot (4.5–5.4:1) would out-shout the active one in
   graphite and evergreen and invert the emphasis. State is carried by hue —
   neutral gray vs saturated accent — not by lightness. Like rochester, these
   dots are aria-hidden decoration and the arrows are the real control. */
.testi-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--color-dot-idle);
  transition: background-color .15s ease;
}
.testi-dot.is-active { background: var(--color-accent); }
@media (prefers-reduced-motion: reduce) {
  .testi-track { transition: none !important; }
}

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

/* ---------- Get In Touch ---------- */
.cta-split {
  /* Single stacked column at every width: heading, copy, then buttons each get
     their own row. The block is centred in the container but its text stays
     left-justified, so the left edge lines up down the whole stack. */
  display: grid;
  gap: clamp(1rem, 2vw, 1.5rem);
  grid-template-columns: 1fr;
  align-items: start;
  max-width: 68ch;
  margin-inline: auto;
  /* Paragraphs read left-justified; the heading and the button row centre. */
  text-align: left;
}
.cta-split h2 { text-align: center; margin: 0; }
.cta-split .btn-row { justify-content: center; }
/* The two inner <div>s are leftovers of the old two-column split. display:
   contents lifts their children into the grid, so heading, paragraphs and
   button row each land in their own row with ONE uniform gap between rows —
   without it the seam between the divs got grid gap + paragraph margin. */
.cta-split > div { display: contents; }
.cta-split p { margin: 0; }
.cta-split .btn-row { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 1.5rem; }

/* ---------- Footer ---------- */
.site-footer {
  background: var(--color-charcoal);
  color: var(--on-dark-body);
  padding: 3rem 0 1.5rem;
}
.site-footer a { color: var(--on-dark-body); text-decoration: none; }
.site-footer a:hover { color: #fff; text-decoration: underline; }
.footer-grid {
  display: grid;
  gap: 2rem;
  grid-template-columns: 1fr;
}
@media (min-width: 720px) { .footer-grid { grid-template-columns: 1fr 1fr; } }
/* Three columns: brand/NAP/quick-links, Services, Service Areas. */
@media (min-width: 1000px) { .footer-grid { grid-template-columns: 1fr 1.1fr 1.5fr; } }
/* 19 service areas run a full column taller than every neighbour, so the areas
   list splits into two flowed columns and its grid track is widened to suit. */
@media (min-width: 720px) {
  .footer-areas-list { columns: 2; column-gap: 1.5rem; }
  .footer-areas-list li { break-inside: avoid; }
}
.footer-grid h3 {
  color: #fff;
  font-family: var(--font-display);
  font-size: 1.3rem;
  letter-spacing: 0.04em;
  margin: 0 0 0.4rem;
  padding-bottom: 0.4rem;
  border-bottom: 2px solid var(--color-accent);
  display: inline-block;
}
.footer-grid ul { list-style: none; padding: 0; margin: 0.75rem 0 0; }
.footer-grid li { margin-bottom: 0.5rem; }
.footer-logo {
  height: 80px;
  width: auto;
  display: block;
  max-width: 100%;
}
@media (max-width: 720px) {
  .footer-logo { height: 64px; }
}
.footer-contact .phone {
  display: block;
  font-family: var(--font-display);
  font-size: 1.5rem;
  color: #fff;
  letter-spacing: 0.04em;
  margin-bottom: 0.5rem;
}
.footer-contact address { font-style: normal; line-height: 1.7; margin-top: 0.75rem; }

/* NAP block under the footer logo: icon in a fixed gutter, text beside it. */
.footer-nap { margin: 1.25rem 0 1.75rem !important; }
.footer-nap li {
  display: grid;
  grid-template-columns: 16px 1fr;
  align-items: start;
  gap: 0.6rem;
  line-height: 1.5;
}
.footer-nap svg { margin-top: 0.2em; color: var(--color-accent); flex: none; }
.footer-nap address { font-style: normal; margin: 0; }
/* The phone is one NAP row among four, so it takes the same type as its
   siblings — no display face, no size bump. */
.footer-nap .phone { font-size: inherit; }
.footer-quick-links a { display: inline-flex; align-items: center; gap: 0.5rem; }
.footer-quick-links svg { color: var(--color-accent); flex: none; }
.legal {
  margin-top: 2rem;
  padding-top: 1.25rem;
  border-top: 1px solid rgba(255,255,255,0.08);
  font-size: 0.85rem;
  color: var(--on-dark-faint);
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  justify-content: space-between;
}
.legal a { margin-right: 1rem; }

/* ============================================================
   Service page — content column + sticky right rail
   (template basis for /services/<slug>/)
   ============================================================ */

/* .hero-service inherits the home-page .hero dimensions as-is (same height);
   it only carries the breadcrumb above the H1 and its own hero photo. */
.hero-service {
  background:
    var(--overlay-hero),
    url("/images/snow-hauling-relocation-bg.webp") center / cover no-repeat,
    var(--color-charcoal);
}

/* Breadcrumb (sits above the H1 inside the hero) */
.breadcrumb { margin: 0 0 1rem; }
.breadcrumb ol {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.35rem 0.6rem;
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 0.85rem;
}
.breadcrumb li {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  color: rgba(255, 255, 255, 0.75);
}
.breadcrumb li:not(:last-child)::after {
  content: "/";
  color: rgba(255, 255, 255, 0.4);
}
.breadcrumb a { color: var(--color-secondary); text-decoration: none; }
.breadcrumb a:hover { text-decoration: underline; }
.breadcrumb [aria-current="page"] { color: #fff; }

/* Two-column layout: content + rail */
.service-layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(2rem, 4vw, 3.5rem);
  align-items: start;
}
@media (min-width: 960px) {
  .service-layout { grid-template-columns: minmax(0, 1fr) 330px; }
}

/* Content column */
.service-content > :first-child { margin-top: 0; }
.service-content h2 {
  margin-top: 1.8em;
  color: var(--color-primary);
}
/* in-page anchor targets clear the sticky header on jump */
.service-content h2[id] { scroll-margin-top: calc(80px + 1rem); }
.service-content h3 {
  margin-top: 1.4em;
  color: var(--color-link);
  /* size inherits the global h3 (20px desktop) so it matches every other page */
}
.service-intro { color: var(--color-text); }
.service-areas-line {
  font-size: 0.95rem;
  margin-bottom: 1.75rem;
}
.service-areas-line strong { color: var(--color-primary); }

/* Numbered process steps */
.process-steps {
  list-style: none;
  counter-reset: step;
  margin: 1rem 0 0;
  padding: 0;
  display: grid;
  gap: 1.5rem;
}
.process-steps li {
  position: relative;
  padding-left: 3.75rem;
  counter-increment: step;
  min-height: 2.75rem;
}
.process-steps li::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: 0;
  width: 2.75rem;
  height: 2.75rem;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-accent);
  color: var(--color-on-accent);
  font-family: var(--font-display);
  font-size: 1.5rem;
  line-height: 1;
}
.process-steps h3 { margin: 0 0 0.35rem; color: var(--color-primary); }
.process-steps p { margin: 0; }

/* Sticky right rail */
.service-rail {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}
@media (min-width: 960px) {
  .service-rail {
    position: sticky;
    top: calc(80px + 1.5rem); /* header height + breathing room */
  }
}
.rail-card {
  background: var(--color-primary);
  color: var(--color-secondary);
  padding: 1.5rem 1.5rem 1.75rem;
}
.rail-title {
  margin: 0 0 1rem;
  text-align: center;
  color: #fff;
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 2.4vw, 2rem);
  font-weight: 400;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.rail-nav { list-style: none; margin: 0; padding: 0; }
.rail-nav li { margin: 0; }
.rail-nav a {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.4rem 0;
  color: var(--color-secondary);
  text-decoration: none;
  font-weight: 600;
  font-size: 0.98rem;
  line-height: 1.3;
}
/* leading navigation arrow from the icon sprite; color follows currentColor */
.rail-nav a svg { flex-shrink: 0; }
.rail-nav a:hover { color: #fff; text-decoration: underline; }
.rail-nav a[aria-current="page"] { color: #fff; font-weight: 700; }
.rail-cta {
  background: var(--color-primary-mid);
  color: #fff;
  padding: 1.5rem 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  text-align: center;
}
.rail-cta-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.4rem;
  font-weight: 400;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  line-height: 1.1;
}
.rail-cta-sub { margin: 0 0 0.25rem; color: rgba(255, 255, 255, 0.8); font-size: 0.9rem; }

/* Final dark CTA (call / quote split) */
.final-cta .cta-split { margin-top: 2.5rem; align-items: start; }
.final-cta .cta-split h3 { margin-top: 0; color: #fff; }
.final-cta .cta-split .btn { margin-top: 0.5rem; }

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

/* ---------- Heading weight (Fraunces on this site) ----------
   Give headings real weight so they don't read thin.
   Placed last so it wins on cascade order. */
h1, h2, h3,
.subhead, .spotlight-side-title, .feature-aside-box .feature-aside-box-title,
.service-card-header, .rail-title { font-weight: 700; }
.process-step .step-num { font-weight: 800; }

/* ============================================================
   SITE-LOCAL — st-george-elite-stucco
   TEMPORARY: gray placeholder art.
   The template's section-background photos are rely's snow images, deleted from
   this site (wrong trade). Each of the five background slots now carries its own
   St. George stucco photograph, so this block is PERMANENT — it is the point at
   which this file deliberately diverges from the template. Swap a filename here
   to change a section background; do not delete the block.
   ============================================================ */
/* Each rule keeps its OWN overlay gradient and its OWN solid fallback layer —
   these are three-layer `background` shorthands, so overriding background-image
   alone would drop `center / cover no-repeat` and the fallback colour. */
.hero {
  background:
    var(--overlay-hero),
    url("/images/hero-st-george-red-rock-v3-1600.webp") center / cover no-repeat,
    var(--color-charcoal);
}
.hero-service {
  background:
    var(--overlay-hero),
    url("/images/hero-service-scratch-coat-1600.webp") center / cover no-repeat,
    var(--color-charcoal);
}
.feature-aside {
  /* --overlay-deep runs 0.87->0.94 and is shared with another rule, so it is
     overridden here rather than retuned globally. Softened so the sand-float
     texture actually reads; white body copy still measures well above 7:1 over it. */
  background:
    linear-gradient(135deg, rgba(9, 33, 44, 0.78) 0%, rgba(9, 33, 44, 0.87) 100%),
    url("/images/why-choose-bg-1600.webp") center / cover no-repeat,
    var(--color-primary);
}
.banner {
  background:
    var(--overlay-banner),
    url("/images/benefits-bg-1600.webp") center / cover no-repeat,
    var(--color-primary);
}
.spotlight {
  background:
    var(--overlay-spotlight),
    url("/images/about-st-george-red-rock-1600.webp") center / cover no-repeat,
    var(--color-charcoal);
}

/* --- Top-of-right-column figure: absorb column slack ---------------------
   rely's .flex-media-long-figure is fixed-height, so a --long block only
   balances if the copy happens to divide evenly. On "Which Stucco Service Do
   You Need?" every legal split point left 82px+ of ragged bottom. Letting the
   figure grow into the slack (the trick the polebarn skin gets from
   `flex: 1 1 0`) squares the columns without touching a word of copy. */
/* Figures stay at their NATURAL aspect ratio — deliberately not stretched.
   An earlier revision let them grow to square up the two columns, which
   balanced every block but produced 561x831 portrait crops of a 4:3 source.
   Image fidelity wins. */
.flex-media-long-col > .flex-media-long-figure { flex: 0 0 auto; }
.flex-media-long-col > .flex-media-long-figure img { height: auto; object-fit: initial; }

/* Bottom-anchoring the figure column's tail copy was tried here to make the two
   columns end level. It does — but it just relocates the slack into a void in
   the MIDDLE of the column (370px between the image and a one-line CTA on the
   pricing block), which reads worse than an uneven bottom. Reverted: the slack
   is dealt with per block, by choosing the split point so the copy divides more
   evenly. See the block comments in index.html. */

/* --- Corner accent triangle on every block figure ------------------------
   Sits ON the image at its top outer corner, offset outward past both edges.
   The corner FOLLOWS THE IMAGE'S COLUMN: figures that render on the right get
   the top-right corner, figures that render on the left get the top-left.
   Note --reverse flips the image side in CSS only (source order is unchanged),
   so the side is read off the section's modifier, never off source position. */
.flex-media-figure,
.flex-media-long-figure {
  position: relative;
  overflow: visible;        /* let the accent break the figure's bounds */
}
.flex-media-figure::after,
.flex-media-long-figure::after {
  content: "";
  position: absolute;
  top: -8px;
  width: 76px;
  height: 76px;
  background: var(--color-accent);
  z-index: 2;
  pointer-events: none;
}

/* --- --long-reverse: stop bottom-anchoring the figure --------------------
   The template pins that figure to the foot of its column with margin-top:auto.
   That only looks right when the column's copy nearly fills the row; on the
   Desert Climate block the left column is one intro paragraph against three
   subsections opposite, so the auto margin opened a ~134px gap between the
   paragraph and the image. Sit the image directly under the copy and let the
   column end early instead — an uneven bottom beats a hole.
   This block is the only --long-reverse left on the page (Systems and Finishes
   became a grid), so the override is effectively block-scoped. */
.flex-media--long-reverse .flex-media-long-col > .flex-media-long-figure:last-child {
  margin-top: 1.25rem;   /* was auto */
  padding-top: 0;        /* the padding only existed to open space above the pinned figure */
}
/* padding-top is gone, so the accent no longer needs offsetting by it */
.flex-media--long-reverse .flex-media-long-col > .flex-media-long-figure:last-child::after {
  top: -8px;
}

/* ALIGNMENT FIX — the bottom-anchored figure in a --long-reverse column carries
   `padding-top: 1.25rem` (it is how the template opens space above a figure that
   margin-top:auto has pushed to the bottom). The accent is positioned against the
   FIGURE BOX, whose top therefore sits 20px above the image's top edge — so on
   that one block the triangle floated ~20px high. Offset it back by the padding.
   Only the :last-child (bottom-anchored) case is affected; :first-child uses
   margin-bottom, which does not move the box's top edge. */
.flex-media-long-col > .flex-media-long-figure:last-child::after {
  top: calc(1.25rem - 8px);
}

/* Image renders RIGHT -> top-right corner; right angle at top-right. */
.flex-media:not(.flex-media--reverse):not(.flex-media--long-reverse) .flex-media-figure::after,
.flex-media--long .flex-media-long-figure::after {
  right: -8px;
  clip-path: polygon(100% 0, 100% 100%, 0 0);
}

/* Image renders LEFT -> top-left corner; mirrored, right angle at top-left. */
.flex-media--reverse .flex-media-figure::after,
.flex-media--long-reverse .flex-media-long-figure::after {
  left: -8px;
  clip-path: polygon(0 0, 100% 0, 0 100%);
}

/* The figure's own drop shadow would otherwise sit over the accent. */
.flex-media-figure img,
.flex-media-long-figure img { position: relative; z-index: 1; }

/* --- Inline links in the hero -------------------------------------------
   The template gives .section-dark its own on-dark link ink, but .hero is not
   .section-dark and was never covered — its alt-hero lede shipped with no links
   in it, so nothing surfaced the gap. This pour puts a tel: link in the lede,
   and it inherited --color-link (#326A7A), the LIGHT-surface ink: 2.44:1 on the
   hero's charcoal base. The sand secondary is this palette's on-dark accent and
   reads 9.31:1 there. Buttons are excluded — they carry their own fills.
   Worth promoting to _rely-template; left site-local for now. */
.hero a:not(.btn) { color: var(--color-secondary); }
.hero a:not(.btn):hover { color: var(--color-fg-on-dark); }

/* --- Hero split: wider copy column, tighter lede ------------------------
   Template ships 1.05fr / 0.95fr (a near-even split). Give the copy the room
   and let the form card shrink. FLOOR ON THE FORM COLUMN: the Turnstile widget
   is a fixed 300px iframe, so the card's inner width must stay above it or the
   challenge overflows the card — hence minmax(), not a bare fr. */
@media (min-width: 900px) {
  .hero-split-grid { grid-template-columns: 1.5fr minmax(380px, 1fr); }
}
.hero--split .hero-lede {
  margin-bottom: 0.75rem;  /* template 2rem -> 1rem -> 0.75rem */
  line-height: 1.45;       /* was body's 1.6 */
}
/* h1 sits tighter to the copy + form beneath it */
.hero--split .hero-split-title {
  margin-bottom: clamp(1rem, 2vw, 1.5rem);  /* was clamp(1.5rem, 3vw, 2.25rem) */
}

/* --- Headings that were pinned to --font-sans ---------------------------
   rely sets `.hero h1` and the service-card h3 in var(--font-sans). That was
   invisible in the parent skin because --font-sans and --font-display were BOTH
   Raleway, so the two tokens were interchangeable. The moment display != sans
   it surfaces: the h1 — the largest type on the page — renders in the body face
   while every other heading is the display face. Repointed to --font-display.
   Deliberately NOT changed: h4, .brand-text .tag and .quote-form-title, which
   are UI labels rather than document headings and read better in the sans. */
.hero h1,
.service-card .service-card-cta { font-family: var(--font-display); }

/* --- Optical sizing for Fraunces ----------------------------------------
   Its opsz axis runs 9–144: small text gets the sturdier text cut, the hero h1
   and watermark get the finer display cut. `auto` is the browser default, but
   it is stated here because the whole point of choosing this face is that the
   axis is doing work. */
h1, h2, h3, .hero-watermark, .subhead, .spotlight-side-title,
.service-card-header, .quote-form-title { font-optical-sizing: auto; }

/* --- process-grid: fit any step count ------------------------------------
   The template hard-codes `repeat(4, 1fr)` at desktop, so the 5th step orphaned
   onto a row of its own. auto-fit makes the track count follow the step count,
   which is what the block vocabulary already claims this grid does. */
@media (min-width: 960px) {
  .process-grid { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
}

/* --- CTA row at the foot of a long column --------------------------------
   The --long variants ship no CTA furniture, so the button row added to the
   pricing block is pinned to the bottom of its column. Side effect worth
   having: it consumes that column's leftover slack, so the two columns finish
   level instead of leaving a ragged bottom. padding-top guarantees breathing
   room when there is no slack to absorb. */
.flex-media--long .flex-media-long-col > .flex-media-cta-row:last-child {
  margin-top: auto;
  padding-top: 2rem;
}

/* --- .section-alt: the palette's alt band --------------------------------
   Reusable light-band utility (rely has no equivalent). Uses the token rather
   than the literal #FBF3DA so it re-resolves if the skin ever changes; in
   sandstone --color-bg-alt IS #FBF3DA. Currently on Common Stucco Problems.
   The palette already tunes --color-link and --color-text-muted to clear 4.5
   on bg-alt as well as bg, so body copy and links need no adjustment. */
.section-alt { background: var(--color-bg-alt); }

/* --- Service-areas heading matches the h2 -------------------------------
   .spotlight-side-title shipped LARGER than h2 (up to 2.75rem vs 1.9rem).
   Pinned to the exact h2 ramp so the two column headings read as one level. */
.spotlight-side-title { font-size: clamp(1.5rem, 1.25rem + 0.9vw, 1.9rem); }

/* --- Header phone ------------------------------------------------------- */
.nav-cta { font-size: 1.15rem; }

/* --- .snow-list--single -------------------------------------------------
   The shared block vocabulary documents this modifier ("force a 1-column
   list"), but rely never implemented it — so the class was inert here while
   `.flex-media .snow-list` and `.spotlight-areas` both went 2-up at their
   breakpoints. Implemented so the documented modifier actually does its job;
   used only where the items are full sentences or long comma runs. */
.flex-media .snow-list.snow-list--single,
.snow-list.snow-list--single,
.spotlight-areas.snow-list--single { grid-template-columns: 1fr; }

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