/* ==========================================================================
   Northline Heating & Air  —  "The Comfort Line" design system
   Fictional client site built by Obris Launch (portfolio example).
   Concept: thermal duality. Cool cyan (cooling) + warm amber (heating) on a
   deep midnight navy, joined by a signature cool-to-warm "thermal line".
   Type: Yantramanav (display/headings) + Archivo (body).
   Mobile-first. WCAG 2.2 AA. Reduced-motion honored.
   ========================================================================== */

:root {
  /* palette */
  --ink:        #0E1B2A;   /* deep midnight navy (night / cold base) */
  --ink-2:      #14283C;
  --ink-3:      #24405b;
  --surface:    #F4F8FB;   /* cool near-white */
  --surface-2:  #E7F0F6;   /* cool band */
  --card:       #FFFFFF;
  --line:       #D5E1EA;   /* hairline on light */

  --cool:       #1B93C9;   /* cooling cyan-blue (accent) */
  --cool-deep:  #0C6C9C;
  --cool-soft:  #7FCBEC;
  --cool-light: #4FB8E6;   /* cyan for text on dark */

  --warm:       #F0842B;   /* heating amber (accent) */
  --warm-deep:  #D26A1C;
  --warm-soft:  #F7B778;

  --link:       #0A5C86;   /* AA link on light (>=5:1) */

  --text:       #0E1B2A;   /* body on light */
  --muted:      #48596B;   /* AA muted on light (>=5:1) */
  --on-ink:     #EAF3FA;   /* body on dark */
  --on-ink-mut: #A9BED0;   /* muted on dark (AA on --ink) */

  /* type */
  --font-display: "Yantramanav", "Segoe UI", system-ui, sans-serif;
  --font-body: "Archivo", system-ui, -apple-system, "Segoe UI", sans-serif;

  /* fluid type scale */
  --fs-xs:   0.78rem;
  --fs-sm:   0.9rem;
  --fs-base: 1rem;
  --fs-md:   clamp(1.06rem, 1rem + 0.3vw, 1.2rem);
  --fs-lg:   clamp(1.28rem, 1.15rem + 0.7vw, 1.6rem);
  --fs-xl:   clamp(1.7rem, 1.4rem + 1.5vw, 2.4rem);
  --fs-2xl:  clamp(2.1rem, 1.6rem + 2.5vw, 3.3rem);
  --fs-3xl:  clamp(2.6rem, 1.9rem + 3.6vw, 4.5rem);

  /* spacing / layout */
  --maxw: 1240px;
  --gutter: clamp(18px, 4vw, 40px);
  --radius: 14px;
  --radius-sm: 9px;
  --radius-lg: 22px;
  --shadow-sm: 0 2px 10px rgba(14,27,42,.06);
  --shadow: 0 14px 40px -18px rgba(14,27,42,.28);
  --shadow-lg: 0 30px 70px -30px rgba(14,27,42,.45);

  /* motion */
  --ease: cubic-bezier(.22,.61,.36,1);
  --dur: .6s;
}
:root { --ink-3: #24405b; }

/* ---------- reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--fs-base);
  line-height: 1.72;
  color: var(--text);
  background: var(--surface);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
body.nav-locked { overflow: hidden; }
img { max-width: 100%; height: auto; display: block; }
a { color: var(--link); text-decoration-thickness: 1px; text-underline-offset: 2px; }
h1, h2, h3, h4 { font-family: var(--font-display); line-height: 1.1; letter-spacing: normal; color: var(--ink); margin: 0 0 .5em; font-weight: 700;
  /* Balance heading lines so a single word never widows on the last line.
     Responsive by design: rebalances at every width instead of a hard &nbsp;
     that can force mobile overflow. Falls back to normal wrapping pre-2023. */
  text-wrap: balance; }
p { margin: 0 0 1em;
  /* Prevent last-line orphans in body copy without hurting reflow. */
  text-wrap: pretty; }
li, figcaption, dd, blockquote { text-wrap: pretty; }
ul { margin: 0; padding: 0; }

/* ---------- helpers ---------- */
.container { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gutter); }
.narrow { max-width: 760px; }
.center { text-align: center; }
.kicker {
  display: inline-flex; align-items: center; gap: .55rem;
  font-family: var(--font-display); font-weight: 500;
  font-size: var(--fs-xs); letter-spacing: .16em; text-transform: uppercase;
  color: var(--cool-deep); margin: 0 0 .9rem;
}
.kicker::before { content: ""; width: 26px; height: 3px; border-radius: 3px;
  background: linear-gradient(90deg, var(--cool), var(--warm)); }
.on-ink .kicker { color: var(--cool-light); }
/* --cool-deep is tuned for light backgrounds and drops to ~3:1 on the ink
   sections, so the brand sub-line has to flip too wherever .on-ink applies. */
.on-ink .brand-sub { color: var(--cool-light); }

/* the signature thermal line */
.thermal-line { height: 4px; width: 100%; border-radius: 4px;
  background: linear-gradient(90deg, var(--cool-deep), var(--cool), #b9d7c9, var(--warm), var(--warm-deep));
  background-size: 220% 100%; }

/* small layout utilities — replace the inline styles that were scattered
   through the markup so every rule lives in one place */
.mt-sm { margin-top: .8rem; }
.mt-md { margin-top: 1.4rem; }
.mt-lg { margin-top: clamp(26px, 4vw, 40px); }
.mb-xs { margin-bottom: .3em; }
.rule-top { border-top: 1px solid rgba(255,255,255,.1); }
.justify-center { justify-content: center; }
.hidden { display: none; }
.note-sm { margin-top: 2rem; font-size: var(--fs-sm); color: var(--muted); }
.lede-muted { color: var(--muted); max-width: 46ch; margin: 0 auto 1.6rem; }
.muted-para { color: var(--muted); margin-bottom: 1.4rem; }

.skip-link {
  position: absolute; left: 12px; top: -60px; z-index: 200;
  background: var(--ink); color: #fff; padding: 10px 16px; border-radius: 8px;
  transition: top .2s var(--ease);
}
.skip-link:focus { top: 12px; }

:where(a, button, input, textarea, select, [tabindex]):focus-visible {
  outline: 3px solid var(--cool); outline-offset: 2px; border-radius: 4px;
}

/* ---------- buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .55rem;
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-sm);
  text-transform: uppercase; letter-spacing: .06em; line-height: 1;
  padding: 15px 26px; min-height: 48px; border-radius: 999px;
  border: 1.5px solid transparent; cursor: pointer; text-decoration: none;
  transition: transform .18s var(--ease), box-shadow .2s var(--ease), background-color .2s var(--ease), color .2s var(--ease);
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }
.btn-primary { background: var(--warm); color: #fff; box-shadow: 0 12px 26px -12px rgba(240,132,43,.7); }
.btn-primary:hover { background: var(--warm-deep); color: #fff; }
.btn-cool { background: var(--cool-deep); color: #fff; }
.btn-cool:hover { background: #094f74; }
.btn-outline { background: transparent; border-color: var(--cool-deep); color: var(--cool-deep); }
.btn-outline:hover { background: var(--cool-deep); color: #fff; }
.on-ink .btn-outline { border-color: rgba(255,255,255,.6); color: #fff; }
.on-ink .btn-outline:hover { background: #fff; color: var(--ink); }
.btn-lg { padding: 17px 32px; min-height: 54px; font-size: var(--fs-base); }
/* No full-width buttons in normal/desktop flow -- a stretched button reads
   heavy and generic (Julia 2026-07-28). Buttons size to their label. The
   mobile media block below still lets long-label hero pills go full-width on
   narrow phones, where that prevents the documented 360px overflow and is the
   expected touch pattern. */
.btn-block { width: auto; }
.btn svg { flex: none; }

/* ---------- top utility bar ---------- */
/* Visible at every size: tap-to-call above the fold is the single most useful
   thing on a home-services site. Below 880px it slims to phone (+ hours) only. */
.topbar { background: var(--ink); color: var(--on-ink-mut); font-size: .82rem; }
.topbar-in { display: flex; align-items: center; justify-content: space-between; gap: 1rem; min-height: 44px; }
.topbar-list { display: flex; align-items: center; list-style: none; margin: 0; padding: 0; }
.topbar-list li { display: flex; align-items: center; }
.topbar-list li + li { border-left: 1px solid rgba(255,255,255,.14); }
.topbar-list a, .topbar-list .tb-item { display: inline-flex; align-items: center; gap: .5rem;
  padding: .6rem clamp(.7rem, 1.4vw, 1.2rem); color: var(--on-ink-mut); text-decoration: none;
  transition: color .2s var(--ease); white-space: nowrap; }
.topbar-list li:first-child a, .topbar-list li:first-child .tb-item { padding-left: 0; }
.topbar-list a:hover { color: #fff; }
.topbar-list svg { width: 15px; height: 15px; flex: none; color: var(--warm); }
.topbar-social { display: flex; align-items: center; gap: .4rem; }
.topbar-social a { display: grid; place-items: center; width: 30px; height: 30px; border-radius: 9px;
  background: rgba(255,255,255,.08); color: var(--on-ink-mut);
  transition: background-color .2s var(--ease), color .2s var(--ease); }
.topbar-social a:hover { background: var(--warm); color: #fff; }
.topbar-social svg { width: 14px; height: 14px; }
@media (max-width: 879.98px) {
  .topbar-in { min-height: 38px; }
  .topbar-social { display: none; }
  .topbar-list { width: 100%; justify-content: space-between; }
  .topbar-list li:nth-child(2) { display: none; }          /* email: use the form */
  .topbar-list li + li { border-left: 0; }
  .topbar-list a, .topbar-list .tb-item { padding-inline: 0; }
  .topbar-list li:first-child a { font-weight: 600; color: #fff; }
}
@media (max-width: 429.98px) {
  .topbar-list li:nth-child(3) { display: none; }           /* hours: in the footer */
  .topbar-list { justify-content: flex-start; }
}

/* ---------- header / nav ---------- */
.site-header {
  position: sticky; top: 0; z-index: 100;
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  -webkit-backdrop-filter: saturate(1.4) blur(10px);
  backdrop-filter: saturate(1.4) blur(10px);
  border-bottom: 1px solid transparent;
  transition: box-shadow .25s var(--ease), border-color .25s var(--ease), background-color .25s var(--ease);
}
.site-header.is-scrolled { box-shadow: var(--shadow-sm); border-bottom-color: var(--line);
  background: color-mix(in srgb, var(--surface) 96%, transparent); }
.header-grid { display: flex; align-items: center; gap: clamp(.8rem, 2vw, 2rem); min-height: 78px; }

.brand { display: inline-flex; align-items: center; gap: .7rem; text-decoration: none; color: var(--ink); }
.brand-mark { width: 51px; height: 51px; flex: none; display: block; }
.brand-word { display: flex; flex-direction: column; line-height: 1; }
.brand-name { font-family: var(--font-display); font-weight: 700; font-size: 1.6rem; letter-spacing: -0.02em; color: var(--ink); }
.brand-sub { font-family: var(--font-body); font-weight: 600; font-size: 0.86rem; letter-spacing: .2em; text-transform: uppercase; color: var(--cool-deep); margin-top: 3px; }

/* centred primary nav (middle zone of the header row) */
.nav-center { display: none; flex: 1 1 auto; justify-content: center; min-width: 0; }
.nav-desktop { display: flex; align-items: center; gap: clamp(.85rem, 1.7vw, 1.9rem); }
.nav-desktop a {
  font-family: var(--font-display); font-weight: 600; font-size: .85rem;
  text-transform: uppercase; letter-spacing: .07em; white-space: nowrap;
  color: var(--ink); text-decoration: none; padding: 6px 2px; position: relative;
}
.nav-desktop a::after { content: ""; position: absolute; left: 0; right: 100%; bottom: -2px; height: 2px;
  background: linear-gradient(90deg, var(--cool), var(--warm)); border-radius: 2px; transition: right .28s var(--ease); }
.nav-desktop a:hover::after, .nav-desktop a[aria-current="page"]::after { right: 0; }

/* right-hand action cluster: circular call button + pill CTA */
.nav-cluster { display: none; align-items: center; gap: clamp(.6rem, 1.2vw, 1rem); margin-left: auto; }
.hdr-call {
  display: grid; place-items: center; width: 48px; height: 48px; border-radius: 50%; flex: none;
  background: var(--surface-2); color: var(--cool-deep); text-decoration: none;
  transition: background-color .22s var(--ease), color .22s var(--ease), transform .22s var(--ease);
}
.hdr-call:hover { background: var(--cool-deep); color: #fff; transform: translateY(-2px); }
.hdr-call svg { width: 19px; height: 19px; }
.btn-pill {
  display: inline-flex; align-items: center; gap: .8rem; white-space: nowrap;
  padding: 6px 6px 6px clamp(1rem, 1.6vw, 1.5rem); border-radius: 999px;
  background: var(--warm); color: #fff; text-decoration: none;
  font-family: var(--font-display); font-weight: 700; font-size: .82rem;
  text-transform: uppercase; letter-spacing: .06em;
  transition: background-color .22s var(--ease);
}
.btn-pill:hover { background: var(--warm-deep); }
/* size + layout variants so every Request Service button on the site is this
   same component, whatever context it sits in */
.btn-pill-lg { font-size: .9rem; padding: 8px 8px 8px clamp(1.2rem, 2vw, 1.8rem); }
.btn-pill-lg .pill-chip { width: 40px; height: 40px; }
.btn-pill-lg .pill-chip svg { width: 17px; height: 17px; }
/* Full-width pills: the circular chip is a nice detail when the button hugs
   its label (header, footer), but once the pill is stretched to 100% the chip
   orphans off to one edge with a wide empty gap and looks cheap. On any
   full-width pill, flatten the chip to a plain inline arrow and center the
   label+arrow as one tight unit -- "Request service" with the arrow tucked
   right after it. Caught by Julia 2026-07-24 on the mobile panic card. */
.btn-pill-block { width: auto; justify-content: center; gap: .5rem; }
.btn-pill-block .pill-chip,
.panic-card .btn-pill .pill-chip {
  background: transparent; width: auto; height: auto; }
.btn-pill-block .pill-chip svg,
.panic-card .btn-pill .pill-chip svg { width: 17px; height: 17px; }
.btn-pill-block:hover .pill-chip,
.panic-card .btn-pill:hover .pill-chip { transform: none; }
.btn-pill .pill-chip { display: grid; place-items: center; width: 36px; height: 36px; flex: none;
  border-radius: 50%; background: rgba(255,255,255,.24); transition: transform .28s var(--ease); }
.btn-pill:hover .pill-chip { transform: rotate(45deg); }
.btn-pill .pill-chip svg { width: 15px; height: 15px; }
@media (prefers-reduced-motion: reduce) {
  .hdr-call, .hdr-call:hover, .btn-pill .pill-chip, .btn-pill:hover .pill-chip { transform: none; transition: none; }
}

.nav-toggle {
  display: inline-flex; flex-direction: column; justify-content: center; gap: 5px;
  width: 48px; height: 48px; padding: 12px; background: transparent; border: 1px solid var(--line);
  border-radius: 12px; cursor: pointer;
}
.nav-toggle span { display: block; height: 2.5px; width: 100%; background: var(--ink); border-radius: 2px; transition: transform .28s var(--ease), opacity .2s var(--ease); }
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7.5px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7.5px) rotate(-45deg); }

/* Anchored to the bottom of the sticky header rather than a hard-coded 78px,
   so it stays correct whether or not the utility bar is above it or scrolled. */
.nav-mobile {
  position: absolute; top: 100%; left: 0; right: 0; z-index: 99;
  background: var(--ink);
  display: grid; gap: .25rem; padding: 1.2rem var(--gutter) 1.8rem;
  transform: translateY(-120%); transition: transform .35s var(--ease), visibility .35s;
  box-shadow: var(--shadow-lg); max-height: 78vh; overflow: auto;
  /* hidden, not merely offset: keeps the closed panel from peeking over the
     utility bar and keeps its links out of the keyboard tab order */
  visibility: hidden;
}
.nav-mobile.is-open { transform: translateY(0); visibility: visible; }
.nav-mobile a { color: var(--on-ink); font-family: var(--font-display); font-weight: 500; font-size: 1.15rem;
  text-decoration: none; padding: 14px 6px; border-bottom: 1px solid rgba(255,255,255,.09); }
.nav-mobile a[aria-current="page"] { color: var(--cool-light); }
.nav-phone-mobile { color: var(--warm-soft) !important; }
.nav-cta-mobile { margin-top: 1rem; }

@media (min-width: 880px) {
  .topbar { display: block; }
  /* equal-weight outer zones so the centred nav lands on true viewport centre */
  .brand { flex: 1 1 0; min-width: 0; }
  .nav-center { display: flex; flex: 0 0 auto; }
  .nav-cluster { display: flex; flex: 1 1 0; min-width: 0; justify-content: flex-end; }
  .nav-toggle { display: none; }
  .nav-mobile { display: none; }
  .header-grid { min-height: 92px; }
}
/* below 880 the topbar is hidden, so the mobile panel still hangs off a 78px header */
@media (max-width: 879.98px) { .nav-toggle { margin-left: auto; } }

/* ---------- sections ---------- */
.section { padding-block: clamp(40px, 5vh, 64px); }
.section-band { padding-block: clamp(48px, 6vh, 80px); }
.section-alt { background: var(--surface-2);
  background-image: radial-gradient(120% 100% at 85% 0%, color-mix(in srgb, var(--cool) 14%, transparent), transparent 60%); }
/* The heading is free to use the section's full width so it breaks naturally
   and never strands an empty right-hand void (the "narrow column marooned in a
   wide grid" AI tell). Only the supporting paragraph is held to a readable
   measure. Editorial hierarchy, the way a human designer sets a heading + dek. */
.section-head { max-width: none; margin-bottom: clamp(28px, 4vw, 46px); }
.section-head.center { margin-inline: auto; max-width: 820px; }
.section-head h2 { font-size: var(--fs-2xl); max-width: 34ch; }
.section-head.center h2 { max-width: none; }
.section-head p { color: var(--muted); font-size: var(--fs-md); margin-bottom: 0; max-width: 60ch; }
.eyebrow-rule { display: block; height: 4px; width: 64px; border-radius: 4px; margin-bottom: 1.2rem;
  background: linear-gradient(90deg, var(--cool), var(--warm)); }
/* RULE: a centred heading gets a centred eyebrow. The block .eyebrow-rule needs
   margin auto (text-align cannot centre a block); the inline-flex .kicker needs
   flex-centring (robust even when it is a flex-item in a column). Applies to
   every centred head site-wide. */
.center .eyebrow-rule, .section-head.center .eyebrow-rule { margin-inline: auto; }
.center .kicker, .section-head.center .kicker { display: flex; justify-content: center; }

/* Standardised sub-section rhythm on content-heavy pages. Direct-child H2s open
   a new sub-section; every one gets the SAME space above it whatever block
   precedes it, and that block's trailing margin is zeroed so the H2 margin is
   the single source of the gap. Fixes the uneven "some too much, some none"
   spacing between blocks inside a section. Nested H2s (.section-head, cards) are
   untouched. */
.section > .container > h2 { margin-top: clamp(34px, 5vw, 56px); }
.section > .container > h2:first-child { margin-top: 0; }
.section > .container > .prose > :last-child,
.section > .container > .answer > :last-child { margin-bottom: 0; }
/* Any block sitting directly before an H2 drops its own bottom margin, so the
   H2's top margin is the SOLE gap and every sub-section break is identical
   (otherwise a table/grid/box adds its margin on top of the H2's and the gap
   jumps around from one section to the next). */
.section > .container > *:has(+ h2) { margin-bottom: 0; }

.on-ink { background: var(--ink); color: var(--on-ink); }
/* A full section on ink gets the same dual-temperature depth as the heroes, so
   the dark band reads as designed rather than a flat fill (gradient register). */
.section.on-ink {
  background-image:
    radial-gradient(85% 90% at 12% 4%, color-mix(in srgb, var(--cool) 26%, transparent), transparent 60%),
    radial-gradient(72% 88% at 96% 102%, color-mix(in srgb, var(--warm) 16%, transparent), transparent 62%),
    linear-gradient(158deg, #0b1622, var(--ink) 60%, #0b1926);
}
.on-ink h1, .on-ink h2, .on-ink h3 { color: #fff; }
.on-ink p { color: var(--on-ink-mut); }
.on-ink a { color: var(--cool-light); }

/* The pill's label is white in EVERY context. `.on-ink a` and `.nav-mobile a`
   are two-class selectors that outrank the single-class `.btn-pill` above and
   were repainting it (blue text in the footer, off-white in the mobile menu).
   These must stay after both of those rules to win the tie on source order. */
.on-ink .btn-pill,
.nav-mobile .btn-pill,
.on-ink .btn-pill:hover,
.nav-mobile .btn-pill:hover { color: #fff; }

/* ---------- hero ---------- */
.hero {
  position: relative; overflow: hidden; color: var(--on-ink);
  background: var(--ink);
  background-image:
    radial-gradient(90% 70% at 12% 8%, color-mix(in srgb, var(--cool) 42%, transparent), transparent 60%),
    radial-gradient(80% 80% at 92% 96%, color-mix(in srgb, var(--warm) 30%, transparent), transparent 62%),
    linear-gradient(160deg, #0b1622, var(--ink) 55%, #0b1926);
  padding-block: clamp(44px, 6vh, 88px);
}
.hero h1 { color: #fff; font-size: var(--fs-3xl); font-weight: 600; margin-bottom: .5em; }
.hero h1 .warm, .hl-warm { color: var(--warm-soft); }
.hero h1 .cool, .hl-cool { color: var(--cool-light); }
.hero-sub { color: var(--on-ink); font-size: var(--fs-md); max-width: 46ch; margin-bottom: 0; }
.hero-ctas { display: flex; flex-wrap: wrap; gap: .8rem; }
.hero-chips { display: flex; flex-wrap: wrap; gap: .5rem .7rem; list-style: none; }
.hero-chips li { display: inline-flex; align-items: center; gap: .45rem; font-size: var(--fs-sm); font-weight: 500;
  color: var(--on-ink); background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.14);
  padding: 8px 14px; border-radius: 999px; }
.hero-chips svg { color: var(--cool-light); flex: none; }

@keyframes sweep { to { background-position: 220% 0; } }

/* ---------- intro statement ---------- */
.statement { max-width: 780px; }
.statement .lead { font-family: var(--font-display); font-size: var(--fs-xl); color: var(--ink); font-weight: 700; letter-spacing: normal; line-height: 1.12; margin-bottom: .8rem; }
.statement p { font-size: var(--fs-md); color: var(--muted); }

/* ---------- services grid ---------- */
/* auto-fit with a 360px min lands on 3 wide columns inside the 1240px container
   (4 can't fit: 4x360 + gaps > 1240), so the 6-card homepage grid is 3-across
   with roomier, less tall/narrow cards. Groups with 2 cards (services page)
   still show 2 wide cards side by side because auto-fit collapses empty tracks
   -- which is why this stays auto-fit rather than a hard repeat(3). */
.svc-grid { display: grid; gap: clamp(18px, 2.2vw, 28px); grid-template-columns: repeat(auto-fit, minmax(min(100%, 360px), 1fr)); }
.svc-card {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: clamp(22px, 3vw, 30px); box-shadow: var(--shadow-sm);
  transition: transform .22s var(--ease), box-shadow .22s var(--ease), border-color .22s var(--ease);
  position: relative; overflow: hidden;
}
.svc-card::before { content: ""; position: absolute; inset: 0 0 auto 0; height: 4px;
  background: linear-gradient(90deg, var(--cool), var(--warm)); transform: scaleX(0); transform-origin: left; transition: transform .3s var(--ease); }
.svc-card:hover { transform: translateY(-4px); box-shadow: var(--shadow); border-color: color-mix(in srgb, var(--cool) 40%, var(--line)); }
.svc-card:hover::before { transform: scaleX(1); }
.svc-ico { width: 52px; height: 52px; border-radius: 13px; display: grid; place-items: center; margin-bottom: 1.1rem;
  background: color-mix(in srgb, var(--cool) 14%, #fff); color: var(--cool-deep); }
.svc-card.warm .svc-ico { background: color-mix(in srgb, var(--warm) 16%, #fff); color: var(--warm-deep); }
.svc-card h3 { font-size: var(--fs-lg); margin-bottom: .35em; }
.svc-card p { color: var(--muted); font-size: var(--fs-sm); margin-bottom: 0; }
.svc-card .svc-list { margin-top: .9rem; list-style: none; display: grid; gap: .35rem; }
.svc-card .svc-list li { font-size: var(--fs-sm); color: var(--text); padding-left: 1.35rem; position: relative; }
.svc-card .svc-list li::before { content: ""; position: absolute; left: 0; top: .58em; width: 8px; height: 8px; border-radius: 50%;
  background: linear-gradient(150deg, var(--cool), var(--warm)); }
/* svc-card as a link: the homepage cards route to the real service pages, so the
   whole card is an anchor. Reset link colour/decoration and add an affordance. */
a.svc-card { display: block; text-decoration: none; color: inherit; }
a.svc-card:focus-visible { outline: 3px solid var(--cool); outline-offset: 3px; }
.svc-go { display: inline-flex; align-items: center; gap: .4rem; margin-top: 1.1rem;
  font-weight: 600; font-size: var(--fs-sm); color: var(--cool-deep); }
.svc-card.warm .svc-go { color: var(--warm-deep); }
.svc-go svg { width: 17px; height: 17px; transition: transform var(--ease); }
a.svc-card:hover .svc-go svg { transform: translateX(4px); }

/* ---------- decision hook band (homepage differentiator) ---------- */
.decision-hook .dh-copy { max-width: 60ch; }
.decision-hook h2 { margin-bottom: .5em; }
.decision-hook .kicker { color: var(--warm-soft); }
.decision-hook p { color: var(--on-ink-mut); margin-bottom: 1.6rem; font-size: var(--fs-md); }

/* ---------- promise grid (honest promise content; not testimonials) ---------- */
.promise-grid { display: grid; gap: clamp(16px, 2.4vw, 24px);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); }
.promise { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: clamp(22px, 3vw, 30px); box-shadow: var(--shadow-sm); position: relative; }
.promise h3 { font-size: var(--fs-lg); margin-bottom: .4em; }
.promise p { color: var(--muted); font-size: var(--fs-sm); margin-bottom: 0; }

/* ---------- seasonal duality band ---------- */
.duo { display: grid; gap: clamp(16px, 2.4vw, 22px); grid-template-columns: 1fr; }
@media (min-width: 720px) { .duo { grid-template-columns: 1fr 1fr; } }
.duo-panel { border-radius: var(--radius-lg); padding: clamp(26px, 4vw, 44px); color: #fff; position: relative; overflow: hidden; min-height: 260px; display: flex; flex-direction: column; justify-content: flex-start; }
.duo-cool { background:
  radial-gradient(90% 90% at 80% 10%, color-mix(in srgb, #7FCBEC 55%, transparent), transparent 60%),
  linear-gradient(155deg, #0C6C9C, #0a4f74); }
.duo-warm { background:
  radial-gradient(90% 90% at 80% 10%, color-mix(in srgb, #F7B778 60%, transparent), transparent 60%),
  linear-gradient(155deg, #D26A1C, #a8500f); }
.duo-panel .season-ico { position: absolute; top: 22px; right: 22px; opacity: .9; }
.duo-panel h3 { color: #fff; font-size: var(--fs-xl); margin-bottom: .3em;
  /* greedy fill (fill line 1 before wrapping) instead of the site-wide balanced
     headings, per Julia 2026-07-29; pretty still guards against a lone-word last line */
  text-wrap: pretty; }
.duo-panel p { color: rgba(255,255,255,.9); margin-bottom: 0; }
/* The panel's bright top-right highlight drops plain white text to ~1:1, so the
   tag carries its own dark chip and reads anywhere on the gradient. */
.duo-panel .tag { font-family: var(--font-display); font-size: var(--fs-xs); letter-spacing: .16em;
  text-transform: uppercase; margin-bottom: .7rem; color: #fff; align-self: flex-start;
  background: rgba(9,17,28,.55); padding: 5px 11px; border-radius: 999px; }

/* ---------- steps ---------- */
/* Tighter row-gap than column-gap: the numbered steps wrap to multiple rows, and
   a per-step top padding used to ADD to the row-gap on every wrapped row, so the
   vertical space between rows read as far too large. The heading-to-first-row
   space now lives once on the grid (margin-top), not on every step. */
.steps { display: grid; row-gap: clamp(16px, 2vw, 22px); column-gap: clamp(18px, 2.4vw, 32px);
  grid-template-columns: repeat(auto-fit, minmax(min(100%,230px), 1fr)); counter-reset: step; margin-top: .6rem; }
.step { position: relative; }
.step-num { font-family: var(--font-display); font-weight: 700; font-size: 2.4rem; letter-spacing: -0.03em;
  background: linear-gradient(150deg, var(--cool-deep), var(--warm)); -webkit-background-clip: text; background-clip: text; color: transparent; line-height: 1; margin-bottom: .5rem; }
.step h3 { font-size: var(--fs-lg); margin-bottom: .3em; }
.step p { color: var(--muted); font-size: var(--fs-sm); margin-bottom: 0; }

/* ---------- feature (image + text) ---------- */
.feature { display: grid; gap: clamp(24px, 4vw, 52px); align-items: center; }
@media (min-width: 880px) { .feature { grid-template-columns: 1fr 1fr; } .feature.reverse .feature-media { order: 2; } }
.feature-media img { border-radius: var(--radius-lg); box-shadow: var(--shadow); aspect-ratio: 4/3; object-fit: cover; width: 100%; }
.feature h2 { font-size: var(--fs-xl); }
.feature p { color: var(--muted); font-size: var(--fs-md); }
.check-list { list-style: none; display: grid; gap: .7rem; margin: 1.2rem 0 1.6rem; }
.check-list li { display: flex; gap: .7rem; align-items: flex-start; font-size: var(--fs-base); }
.check-list svg { flex: none; margin-top: .2em; color: var(--cool-deep); }

/* ---------- trust pillars ---------- */
.pillars { display: grid; gap: clamp(16px,2.4vw,24px); grid-template-columns: repeat(auto-fit, minmax(min(100%,220px),1fr)); }
.pillar { background: rgba(255,255,255,.04); border: 1px solid rgba(255,255,255,.12); border-radius: var(--radius); padding: clamp(22px,3vw,28px); }
.pillar .p-ico { width: 46px; height: 46px; border-radius: 12px; display: grid; place-items: center; margin-bottom: 1rem;
  background: rgba(255,255,255,.07); color: var(--cool-light); }
.pillar h3 { color: #fff; font-size: var(--fs-lg); margin-bottom: .3em; }
.pillar p { color: var(--on-ink-mut); font-size: var(--fs-sm); margin-bottom: 0; }

/* ---------- plan / comfort club ---------- */
.plan-card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow); }
.plan-head { padding: clamp(24px,3.4vw,34px); background:
  radial-gradient(100% 120% at 100% 0, color-mix(in srgb, var(--warm) 20%, transparent), transparent 55%),
  color-mix(in srgb, var(--cool) 8%, #fff); border-bottom: 1px solid var(--line); }
.plan-head h3 { font-size: var(--fs-xl); margin-bottom: .3em; }
.plan-head p { color: var(--muted); margin-bottom: 0; }
.plan-body { padding: clamp(24px,3.4vw,34px); display: grid; gap: 1.4rem; }
@media (min-width: 720px){ .plan-body { grid-template-columns: 1.2fr 1fr; } }
.plan-benefits { list-style: none; display: grid; gap: .7rem; }
.plan-benefits li { display: flex; gap: .7rem; font-size: var(--fs-sm); }
.plan-benefits svg { flex: none; color: var(--warm-deep); margin-top: .15em; }
.plan-aside { background: var(--surface); border-radius: var(--radius); padding: 1.4rem; align-self: start; }
.plan-aside p { font-size: var(--fs-sm); color: var(--muted); }
.plan-aside strong { color: var(--ink); }

/* ---------- testimonial ---------- */
.disclaimer { font-size: var(--fs-xs); color: var(--muted); margin-bottom: 1.2rem; font-style: italic; }

/* ---------- reviews ----------------------------------------------------
   One review at a time on a dark band, tinted to the season it is about.
   Replaces a three-card row that stacked into three full screens on mobile.
   The glow is CENTRED, which keeps this band distinct from the footer's
   top-right cool glow. The CTA band between them is warm LIGHT, so this is
   the only dark surface in the lower half of the page until the footer.
   No autoplay: nothing here moves on its own, so it needs no pause control.
   -------------------------------------------------------------------- */
.reviews {
  color: var(--on-ink); background: var(--ink); overflow: hidden;
  padding-block: clamp(48px, 6vh, 80px);
  --accent: var(--cool); --accent-2: var(--cool-light);
  background-image: radial-gradient(58% 78% at 50% 42%, color-mix(in srgb, var(--accent) 30%, transparent), transparent 70%);
  transition: background-image 700ms var(--ease);
}
.reviews[data-accent="cool"] { --accent: var(--cool);      --accent-2: var(--cool-light); }
.reviews[data-accent="warm"] { --accent: var(--warm-deep); --accent-2: var(--warm-soft); }
.reviews[data-accent="dual"] { --accent: var(--cool-deep); --accent-2: var(--warm-soft); }
.reviews h2 { color: #fff; }
.reviews .kicker { color: var(--accent-2); }
.reviews .kicker::before { background: linear-gradient(90deg, var(--accent), var(--accent-2)); }
.reviews .section-head { margin-bottom: clamp(20px, 3vw, 32px); }
.reviews .disclaimer { color: var(--on-ink-mut); margin: clamp(20px,3vw,30px) 0 0; }

.rev-stage { display: grid; max-width: 820px; margin-inline: auto; text-align: center; }
.rev { grid-area: 1 / 1; margin: 0; align-self: center;
  opacity: 0; visibility: hidden; transition: opacity 420ms var(--ease), visibility 420ms; }
.rev.is-active { opacity: 1; visibility: visible; }
.rev-mark { display: block; font-family: var(--font-display); font-weight: 700;
  font-size: clamp(3.4rem, 8vw, 5rem); line-height: .8; color: var(--accent-2);
  transition: color 700ms var(--ease); }
.rev blockquote { margin: 0; }
.rev blockquote p {
  font-family: var(--font-display); font-weight: 400;
  font-size: clamp(1.22rem, 1rem + 1.5vw, 1.85rem); line-height: 1.38;
  letter-spacing: -0.01em; color: #fff; margin: 0 0 clamp(18px, 3vw, 26px);
  text-wrap: balance;
}
.rev figcaption { display: inline-flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: .55rem .8rem; }
.rev-tag {
  font-family: var(--font-display); font-weight: 600; font-size: var(--fs-xs);
  letter-spacing: .12em; text-transform: uppercase; color: var(--ink);
  background: var(--accent-2); border-radius: 999px; padding: 5px 12px;
  transition: background-color 700ms var(--ease);
}
.rev-who { font-size: var(--fs-sm); color: var(--on-ink-mut); }

.rev-controls { display: flex; align-items: center; justify-content: center; gap: 1rem; margin-top: clamp(22px,3.4vw,32px); }
.rev-btn {
  display: grid; place-items: center; width: 44px; height: 44px; flex: none; cursor: pointer;
  border-radius: 50%; border: 1px solid rgba(255,255,255,.34); background: rgba(255,255,255,.1);
  color: #fff; transition: background-color .22s var(--ease), border-color .22s var(--ease);
}
.rev-btn:hover { background: rgba(255,255,255,.24); border-color: rgba(255,255,255,.55); }
.rev-btn svg { width: 19px; height: 19px; }
.rev-dots { display: flex; align-items: center; gap: .55rem; }
.rev-dot {
  width: 30px; height: 5px; padding: 0; border: 0; border-radius: 999px; cursor: pointer;
  background: rgba(255,255,255,.28); transition: background-color .25s var(--ease), width .25s var(--ease);
}
.rev-dot:hover { background: rgba(255,255,255,.5); }
.rev-dot.is-active { width: 46px; background: linear-gradient(90deg, var(--accent), var(--accent-2)); }
/* the dots are 5px tall but must still be a comfortable target */
.rev-dot::after { content: ""; position: absolute; inset: -14px -4px; }
.rev-dot { position: relative; }
@media (max-width: 520px) { .rev-btn { display: none; } }   /* swipe instead */
@media (prefers-reduced-motion: reduce) {
  .reviews, .rev, .rev-mark, .rev-tag, .rev-dot { transition: none; }
}

/* ---------- CTA band (WARM LIGHT — the break before the dark footer) ----------
   This band used to be navy, which stacked three dark surfaces in a row
   (reviews / CTA / footer) and read as one undifferentiated dark mass at the
   bottom of every page. It is now a warm cream register, so the page always
   alternates into the footer instead of sliding into it. It also lets the
   orange Request Service pill keep the exact header treatment. */
.cta-band { position: relative; color: var(--text); text-align: center;
  /* Cool slate: a quiet blue-gray so the warm CTA button is the only saturated
     element on the band (thermal-duality contrast). Kept light so it never
     matches the dark footer. Faint cool glow only, no orange. */
  background: #F1F5F9;
  background-image:
    radial-gradient(58% 116% at 50% 0%, color-mix(in srgb, var(--cool) 12%, transparent), transparent 64%),
    radial-gradient(46% 100% at 92% 104%, color-mix(in srgb, var(--cool-deep) 10%, transparent), transparent 66%),
    linear-gradient(168deg, #F8FAFC, #E7EEF4);
  padding-block: clamp(48px, 6vh, 80px);
}
/* The site's signature thermal line marks the change of register, so the jump
   out of the dark reviews band reads as designed rather than as a seam. */
.cta-band::before { content: ""; position: absolute; inset: 0 0 auto; height: 3px;
  background: linear-gradient(90deg, var(--cool), var(--cool-light) 38%, var(--warm-soft) 62%, var(--warm)); }
.cta-band h2 { color: var(--ink); font-size: var(--fs-2xl); }
.cta-band p { color: var(--muted); max-width: 52ch; margin-inline: auto; font-size: var(--fs-md); }
.cta-band .hero-ctas { justify-content: center; margin-top: 1.6rem; margin-bottom: 0; }
.cta-phone { display: inline-flex; align-items: center; gap: .5rem; margin-top: 1.2rem; font-family: var(--font-display); font-weight: 600; font-size: var(--fs-lg); color: var(--cool-deep); text-decoration: none; }
.cta-phone svg { color: var(--warm-deep); }
.cta-phone:hover { color: var(--ink); }

/* ---------- forms ---------- */
.form-wrap { display: grid; gap: clamp(24px,4vw,48px); }
@media (min-width: 900px){ .form-wrap { grid-template-columns: 1.1fr .9fr; align-items: start; } }
.form-card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: clamp(24px,3.5vw,38px); box-shadow: var(--shadow); }
.field { margin-bottom: 1.1rem; }
.field label { display: block; font-family: var(--font-display); font-weight: 500; font-size: var(--fs-sm); margin-bottom: .4rem; color: var(--ink); }
.field .req { color: #A8500F; }   /* warm-deep is only 3.6:1 on white */
.field input, .field select, .field textarea {
  width: 100%; font-family: var(--font-body); font-size: var(--fs-base); color: var(--text);
  padding: 13px 15px; border: 1.5px solid var(--line); border-radius: var(--radius-sm); background: #fff;
  min-height: 48px; transition: border-color .2s var(--ease), box-shadow .2s var(--ease);
}
.field textarea { min-height: 130px; resize: vertical; }
.field input:focus, .field select:focus, .field textarea:focus { outline: none; border-color: var(--cool); box-shadow: 0 0 0 3px color-mix(in srgb, var(--cool) 26%, transparent); }
.field-row { display: grid; gap: 0 1rem; grid-template-columns: 1fr; }
@media (min-width: 560px){ .field-row { grid-template-columns: 1fr 1fr; } }
.consent { display: flex; gap: .6rem; align-items: flex-start; font-size: var(--fs-sm); color: var(--muted); }
.consent input { width: 20px; height: 20px; min-height: 20px; margin-top: .2em; flex: none; accent-color: var(--cool-deep); }
.form-note { font-size: var(--fs-xs); color: var(--muted); margin-top: .8rem; }
.form-status { margin-top: 1rem; padding: 13px 16px; border-radius: var(--radius-sm); font-size: var(--fs-sm); display: none; }
.form-status.ok { display: block; background: color-mix(in srgb, var(--cool) 14%, #fff); color: var(--cool-deep); border: 1px solid var(--cool-soft); }
.form-status.err { display: block; background: #fdecec; color: #a12020; border: 1px solid #f3b6b6; }

.contact-aside { display: grid; gap: 1.2rem; }
.contact-box { background: var(--surface-2); border-radius: var(--radius); padding: clamp(20px,3vw,26px); }
.contact-box h3 { font-size: var(--fs-md); margin-bottom: .5em; }
.contact-box p, .contact-box a { font-size: var(--fs-base); color: var(--text); margin-bottom: .3rem; }
.contact-box .big { font-family: var(--font-display); font-weight: 600; font-size: var(--fs-lg); color: var(--cool-deep); text-decoration: none; }
.contact-box.emergency { background: color-mix(in srgb, var(--warm) 12%, #fff); border: 1px solid var(--warm-soft); }
.hours-table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.hours-table th { text-align: left; font-weight: 500; color: var(--muted); padding: 5px 0; }
.hours-table td { text-align: right; color: var(--text); padding: 5px 0; }
/* On the dark footer the light-theme text tokens are all but invisible, so the
   hours have to flip to the on-ink pair. */
.site-footer .hours-table th { color: var(--on-ink-mut); }
.site-footer .hours-table td { color: #fff; font-weight: 500; }

/* ---------- footer (cool glow — differs from CTA's warm) ---------- */
.site-footer { color: var(--on-ink); background: var(--ink);
  background-image:
    radial-gradient(70% 120% at 88% 0%, color-mix(in srgb, var(--cool) 26%, transparent), transparent 58%),
    linear-gradient(180deg, #0c1a28, var(--ink));
  padding-block: clamp(44px, 6vh, 72px) 0;
}
.footer-top { display: grid; gap: 1.4rem; align-items: center; padding-bottom: clamp(28px,4vw,40px); border-bottom: 1px solid rgba(255,255,255,.1); }
@media (min-width: 780px){ .footer-top { grid-template-columns: 1fr auto; } }
.footer-brand { display: inline-flex; align-items: center; gap: .7rem; text-decoration: none; }
.footer-brand .brand-name { color: #fff; }
.footer-lead { color: var(--on-ink-mut); max-width: 42ch; margin: .3rem 0 0; }
.footer-cols { display: grid; gap: clamp(24px,4vw,40px); padding-block: clamp(28px,4vw,40px); grid-template-columns: 1fr; }
@media (min-width: 620px){ .footer-cols { grid-template-columns: 1.4fr 1fr 1fr; } }
.footer-col h2 { color: #fff; font-size: var(--fs-sm); letter-spacing: .1em; text-transform: uppercase; margin-bottom: .9rem; }
.footer-col a, .footer-col p { color: var(--on-ink-mut); text-decoration: none; font-size: var(--fs-sm); display: block; margin-bottom: .5rem; }
.footer-col a:hover { color: #fff; }
.footer-nav-list { list-style: none; }
.footer-social { display: flex; gap: .6rem; margin-top: .3rem; }
.footer-social a { display: inline-grid; place-items: center; width: 42px; height: 42px; border-radius: 10px; background: rgba(255,255,255,.07); color: var(--on-ink); }
.footer-social a:hover { background: var(--cool-deep); color: #fff; }
.footer-bottom { border-top: 1px solid rgba(255,255,255,.1); padding-block: 1.4rem; display: grid; gap: .5rem; }
@media (min-width: 700px){ .footer-bottom { grid-template-columns: 1fr auto; align-items: center; } }
.footer-bottom p { color: var(--on-ink-mut); font-size: var(--fs-xs); margin: 0; }
.footer-disclosure { color: var(--on-ink-mut); font-size: var(--fs-xs); opacity: .85; padding-bottom: 1.6rem; margin: 0; max-width: 68ch; }
.footer-disclosure a { color: var(--cool-light); }

/* ---------- back to top ----------
   It was filled with var(--ink) — the same navy as the footer, so it vanished
   the moment you reached the bottom of the page, which is exactly where it is
   needed. Brand blue reads against both the light body sections and the navy
   footer. No single flat fill clears 3:1 against BOTH near-white and near-navy,
   so the visible edge is carried by a near-opaque white ring: on light sections
   the blue fill does the work (5:1 on white), on the footer the ring does
   (about 13:1 on navy). It cannot vanish on either. */
.to-top { position: fixed; right: 18px; bottom: 18px; z-index: 90; width: 48px; height: 48px; border-radius: 50%;
  border: none; cursor: pointer; background: var(--cool-deep); color: #fff;
  box-shadow: 0 8px 22px rgba(9,17,28,.38), 0 0 0 2px rgba(255,255,255,.85);
  display: grid; place-items: center; transition: transform .2s var(--ease), background-color .2s var(--ease); }
.to-top:hover { transform: translateY(-3px); background: var(--warm-deep); }
.to-top:focus-visible { outline: 3px solid #fff; outline-offset: 3px; }
.to-top[hidden] { display: none; }

/* ---------- page hero (interior pages) ---------- */
.page-hero { color: var(--on-ink); background: var(--ink);
  background-image:
    radial-gradient(80% 90% at 15% 0%, color-mix(in srgb, var(--cool) 34%, transparent), transparent 60%),
    radial-gradient(70% 90% at 95% 100%, color-mix(in srgb, var(--warm) 22%, transparent), transparent 60%),
    linear-gradient(155deg, #0b1622, var(--ink));
  padding-block: clamp(46px, 7vh, 88px); }
.page-hero h1 { color: #fff; font-size: var(--fs-3xl); max-width: 20ch; }
.page-hero p { color: var(--on-ink); font-size: var(--fs-md); max-width: 54ch; }
.breadcrumb { font-size: var(--fs-sm); color: var(--on-ink-mut); margin-bottom: 1rem; }
.breadcrumb a { color: var(--cool-light); text-decoration: none; }
.breadcrumb a:hover { text-decoration: underline; }

/* ---------- prose (privacy) ---------- */
.prose { max-width: 760px; }
/* Policy / legal / standalone text pages (privacy, terms) present their text at
   the FULL content-area width, never trapped in a narrow reading column with an
   empty void beside it. This pattern is prose applied directly to the container;
   a nested .prose inside a richer page keeps its readable 760px measure. */
.container.prose { max-width: var(--maxw); }
/* Long-form body prose fills the SAME content width as the tables, callouts and
   cards that sit beside it in the section. The old 760px cap left running text
   stranded at ~60% width while every neighbouring block ran full-width, which
   read as a ragged right-hand void. One shared width removes the mismatch; the
   generous line-height keeps the wider measure comfortable to read. */
.section > .container > .prose { max-width: none; margin-bottom: clamp(22px, 3vw, 32px); }
.section > .container > .prose p,
.section > .container > .prose li { line-height: 1.75; }
/* The prose block carries the same trailing rhythm as a table or card, so a
   prose-then-table or prose-then-cards sequence keeps an even gap. When an H2
   follows instead, the :has(+ h2) rule below zeroes this and the H2's top margin
   is the sole break -- so the spacing never collapses and never doubles. */
.prose h2 { font-size: var(--fs-lg); margin-top: 2rem; }
.prose p, .prose li { color: var(--muted); font-size: var(--fs-base); }
.prose ul { padding-left: 1.2rem; list-style: disc; margin-bottom: 1rem; }
.prose li { margin-bottom: .4rem; }

/* ---------- 404 ---------- */
.err-wrap { min-height: 60vh; display: grid; place-items: center; text-align: center; padding-block: clamp(48px,8vh,90px); }
.err-code { font-family: var(--font-display); font-weight: 700; font-size: clamp(4.5rem, 12vw, 8rem); line-height: 1;
  background: linear-gradient(140deg, var(--cool-deep), var(--warm)); -webkit-background-clip: text; background-clip: text; color: transparent; }

/* ---------- reveal motion ---------- */
.reveal { opacity: 0; transform: translateY(22px); transition: opacity .7s var(--ease), transform .7s var(--ease); }
.reveal.is-visible { opacity: 1; transform: none; }
.reveal[data-delay="1"] { transition-delay: .08s; }
.reveal[data-delay="2"] { transition-delay: .16s; }
.reveal[data-delay="3"] { transition-delay: .24s; }

@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1 !important; transform: none !important; transition: none !important; }
  .btn:hover, .svc-card:hover, .to-top:hover { transform: none !important; }
  * { scroll-behavior: auto !important; }
}

/* ============================================================================
   Northline design system v2 — full-bleed hero + matched motion (Lúmen method)
   Kills the split/floating-card hero; keeps the dual-temperature glow by
   layering it into the scrim over a full-bleed photo. Adds line-mask headline
   + hover-only CTA fill-wipe. Type scaled down from oversized 4.5rem.
   ========================================================================== */

/* Type down (hero + page-hero were 4.5rem max — oversized) */
:root { --fs-3xl: clamp(2.15rem, 1.55rem + 2.6vw, 3.5rem); }

/* ============================================================================
   THERMAL HERO SLIDER
   Three slides that tell the seasonal story (heating / cooling / year-round).
   The hero changes its own colour temperature as it rotates: every slide sets
   --accent + --accent-2, and the scrim, kicker rule and progress bar all
   inherit them. Motion carries meaning instead of decorating.
   Vanilla JS only. Slide 1 renders complete with JS disabled.
   ========================================================================== */

.hero--slider {
  padding: 0; min-height: clamp(560px, 86vh, 820px);
  display: flex; align-items: center; isolation: isolate;
  --accent: var(--warm); --accent-2: var(--warm-soft);
  transition: none;
}
.hero--slider[data-accent="warm"] { --accent: var(--warm);      --accent-2: var(--warm-soft); }
.hero--slider[data-accent="cool"] { --accent: var(--cool);      --accent-2: var(--cool-light); }
.hero--slider[data-accent="dual"] { --accent: var(--cool-deep); --accent-2: var(--warm-soft); }

/* --- background layer: crossfade + slow drift on the active image only ---- */
.hero-bgs { position: absolute; inset: 0; z-index: -2; overflow: hidden; }
.hero-bg { position: absolute; inset: 0; opacity: 0; transition: opacity 1100ms var(--ease); }
.hero-bg.is-active { opacity: 1; }
.hero-bg img { width: 100%; height: 100%; object-fit: cover; object-position: 72% center; display: block; }
.hero-bg.is-active img { animation: nl-drift 14s ease-out both; }
@keyframes nl-drift { from { transform: scale(1.005); } to { transform: scale(1.055); } }

/* --- scrim: coloured glow follows the slide's temperature ----------------- */
.hero--slider .hero-scrim {
  position: absolute; inset: 0; z-index: -1;
  transition: background-image 1100ms var(--ease);
  background-image:
    radial-gradient(74% 62% at 6% 8%, color-mix(in srgb, var(--accent) 52%, transparent), transparent 62%),
    radial-gradient(66% 70% at 98% 98%, color-mix(in srgb, var(--accent-2) 30%, transparent), transparent 60%),
    linear-gradient(100deg, rgba(9,17,28,.96) 0%, rgba(9,17,28,.90) 42%, rgba(9,17,28,.50) 76%, rgba(9,17,28,.14) 100%);
}

.hero--slider .hero-inner { width: 100%; display: grid; gap: clamp(1.5rem, 3vh, 2.4rem);
  padding-block: clamp(28px, 5vh, 56px); }
.hero--slider .kicker { color: var(--accent-2); }
.hero--slider .kicker::before { background: linear-gradient(90deg, var(--accent), var(--accent-2)); }

/* --- rotating copy: slides stacked so there is no layout shift ------------ */
.hero-stage { position: relative; max-width: 768px; }
.hero--slider .hero-sub { max-width: 56ch; }
/* Slides share one grid cell sized by the tallest, and sit on its bottom edge,
   so the gap down to the static CTA block is identical on every slide however
   many lines a headline wraps to. Nothing below the copy ever moves. */
.hero-slide { grid-area: 1 / 1; align-self: end; }
.hero-slide h1 { margin-bottom: .55em; }
.hero-slide .hl-thin   { font-weight: 300; }
.hero-slide .hl-strong { font-weight: 700; }
/* Before JS runs, slide 1 shows and the rest are simply not rendered.
   Once JS adds .is-ready the stack becomes absolute for crossfading. */
.hero-stage > .hero-slide:not(.is-active) { display: none; }
.hero--slider.is-ready .hero-stage { display: grid; }
.hero--slider.is-ready .hero-slide {
  display: block; opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity 520ms var(--ease), visibility 520ms;
}
.hero--slider.is-ready .hero-slide.is-active {
  opacity: 1; visibility: visible; pointer-events: auto;
}

/* --- static layer: trust never rotates or re-animates --------------------- */
.hero-static { display: grid; gap: clamp(1rem, 2vh, 1.5rem); }

/* --- control bar: labelled tabs + progress + arrow cluster ---------------- */
.hero-controls { display: none; align-items: flex-end; gap: 1.2rem; flex-wrap: wrap; }
.hero--slider.is-ready .hero-controls { display: flex; }
.hero-tabs { display: flex; gap: clamp(.4rem, 1.4vw, 1.1rem); flex: 1 1 auto; min-width: 0; }
.hero-tab {
  flex: 0 1 auto; min-width: 0; display: grid; gap: .5rem; padding: 0; cursor: pointer;
  background: none; border: 0; text-align: left; color: rgba(255,255,255,.72);
  font-family: var(--font-display); font-weight: 600; font-size: var(--fs-xs);
  letter-spacing: .12em; text-transform: uppercase;
  transition: color .25s var(--ease);
}
.hero-tab:hover { color: #fff; }
.hero-tab.is-active { color: #fff; }
.hero-tab .tab-name { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hero-tab .tab-track { display: block; height: 4px; border-radius: 4px; background: rgba(255,255,255,.22); overflow: hidden; }
.hero-tab .tab-fill {
  display: block; height: 100%; width: 100%; border-radius: 4px; transform: scaleX(0); transform-origin: left center;
  background: linear-gradient(90deg, var(--accent), var(--accent-2));
}
/* the signature thermal line, now doing double duty as the autoplay timer */
.hero-tab.is-active .tab-fill { animation: nl-tabfill var(--slide-ms, 7000ms) linear both; }
.hero--slider.is-paused .hero-tab.is-active .tab-fill { animation-play-state: paused; }
.hero--slider.no-timer .hero-tab.is-active .tab-fill { animation: none; transform: scaleX(1); }
@keyframes nl-tabfill { from { transform: scaleX(0); } to { transform: scaleX(1); } }

.hero-arrows { display: flex; align-items: center; gap: .5rem; flex: none; }
.hero-btn {
  display: grid; place-items: center; width: 46px; height: 46px; flex: none; cursor: pointer;
  border-radius: 50%; border: 1px solid rgba(255,255,255,.4); background: rgba(255,255,255,.2);
  color: #fff; -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  transition: background-color .22s var(--ease), border-color .22s var(--ease);
}
.hero-btn:hover { background: rgba(255,255,255,.28); border-color: rgba(255,255,255,.5); }
.hero-btn svg { width: 20px; height: 20px; }
.hero-btn-pause .ic-play { display: none; }
.hero-btn-pause[aria-pressed="true"] .ic-pause { display: none; }
.hero-btn-pause[aria-pressed="true"] .ic-play { display: block; }
@media (max-width: 700px) {
  .hero-btn[data-act="prev"], .hero-btn[data-act="next"] { display: none; }
}

/* --- mobile: the hero was 0.87x the whole screen; tighten it ------------- */
@media (max-width: 700px) {
  .hero--slider { min-height: min(74vh, 610px); }
  .hero--slider .hero-inner { gap: 1rem; padding-block: 18px; }
  .hero-static { gap: .85rem; }
  .hero-ctas { gap: .55rem; }
  /* The hero CTAs are left-aligned, so at narrow widths the long "Request
     service" pill (nowrap uppercase label + 40px chip + padding, ~355px min)
     overran a 360px viewport. Stack them full-width and give the pill the same
     flattened-chip treatment used on the mobile panic card, so the chip stops
     forcing the min-width and the button fits inside the container. */
  .hero-static .hero-ctas { flex-direction: column; align-items: stretch; }
  .hero-static .hero-ctas > .btn-pill,
  .hero-static .hero-ctas > .btn { width: 100%; justify-content: center; }
  .hero-static .hero-ctas > .btn-pill { gap: .5rem; padding-left: 1rem; padding-right: 1rem; }
  .hero-static .hero-ctas > .btn-pill .pill-chip { background: transparent; width: auto; height: auto; }
  .hero-static .hero-ctas > .btn-pill .pill-chip svg { width: 17px; height: 17px; }
  .hero-static .hero-ctas > .btn-pill:hover .pill-chip { transform: none; }
  /* The decision-hook band has a long-labelled pill ("Read the repair-or-replace
     guide"). Left-aligned and nowrap, it overran a 360px viewport. Full-width,
     flatten the chip, and allow the label to wrap so it always fits. */
  .decision-hook .btn-pill { width: 100%; justify-content: center; gap: .5rem;
    white-space: normal; text-align: center; padding-left: 1rem; padding-right: 1rem; }
  .decision-hook .btn-pill .pill-chip { background: transparent; width: auto; height: auto; flex: none; }
  .decision-hook .btn-pill .pill-chip svg { width: 17px; height: 17px; }
  .decision-hook .btn-pill:hover .pill-chip { transform: none; }
  /* let the chips sit two-up instead of one per line */
  .hero-chips { gap: .4rem; }
  .hero-chips li { font-size: var(--fs-xs); padding: 6px 10px; gap: .35rem; }
  .hero-chips svg { width: 13px; height: 13px; }
  .hero-slide .hero-sub { font-size: var(--fs-base); }
}

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* --- Line-mask headline reveal ------------------------------------------- */
.reveal-headline .line { display: block; overflow: hidden; padding-bottom: .08em; margin-bottom: -.08em; }
.reveal-headline .line > span { display: block; transform: translateY(100%); animation: nl-line-rise 1000ms cubic-bezier(.22,1,.36,1) both; }
.reveal-headline .line:nth-child(1) > span { animation-delay: .16s; }
.reveal-headline .line:nth-child(2) > span { animation-delay: .28s; }
@keyframes nl-line-rise { to { transform: translateY(0); } }

/* --- CTA fill-wipe (hover/focus only) — matched to real service sites ----- */
.btn { position: relative; overflow: hidden; isolation: isolate; }
.btn-primary::before, .btn-outline::before, .btn-cool::before {
  content: ""; position: absolute; inset: 0; z-index: -1; transform: translateY(100%);
  transition: transform .45s cubic-bezier(.22,1,.36,1); }
.btn-primary::before { background: var(--warm-deep); }
.btn-cool::before    { background: #094f74; }
.btn-outline::before { background: var(--cool-deep); }
.hero--slider .btn-outline::before, .on-ink .btn-outline::before { background: #fff; }
.btn-primary:hover::before, .btn-primary:focus-visible::before,
.btn-cool:hover::before, .btn-cool:focus-visible::before,
.btn-outline:hover::before, .btn-outline:focus-visible::before { transform: translateY(0); }
/* keep base colour during the wipe so the fill reads as motion, not a jump */
.btn-primary:hover { background: var(--warm); color: #fff; }
.btn-outline:hover { background: transparent; }
.hero--slider .btn-outline, .on-ink .btn-outline { border-color: rgba(255,255,255,.6); color: #fff; }
.hero--slider .btn-outline:hover, .on-ink .btn-outline:hover { color: var(--ink); }

/* --- Reduced-motion guard ------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  .reveal-headline .line > span { transform: none; animation: none; }
  .btn-primary::before, .btn-outline::before, .btn-cool::before { transition: none; }
  /* Slider: no autoplay (JS also opts out), no drift, no crossfade, no timer
     bar. The labelled tabs still switch slides, instantly. */
  .hero-bg { transition: none; }
  .hero-bg.is-active img { animation: none; transform: none; }
  .hero--slider .hero-scrim { transition: none; }
  .hero--slider.is-ready .hero-slide { transition: none; }
  .hero-tab.is-active .tab-fill { animation: none; transform: scaleX(1); }
}

/* ==========================================================================
   NORTHLINE_CONTENT_LAYER_v1
   Components added for the content buildout (2026-07-24). Everything here is
   NEW; the service pages otherwise reuse .section, .section-head, .kicker,
   .svc-grid/.svc-card, .steps/.step, .check-list, .prose and .pillars rather
   than duplicating them.
   ========================================================================== */

/* ---------- nav: services disclosure menu ----------
   Seven service pages is too many to bury behind a hub page, and both
   benchmark HVAC sites expose theirs in the nav. Click and keyboard driven,
   not hover, so it works on touch and dismisses with Escape. */
.nav-has-menu { position: relative; display: inline-flex; align-items: center; gap: 2px; }
.nav-caret { background: none; border: none; padding: 4px 2px; margin: 0; cursor: pointer;
  color: inherit; display: grid; place-items: center; border-radius: 4px; line-height: 0; }
.nav-caret svg { width: 15px; height: 15px; transition: transform .25s var(--ease); }
.nav-caret[aria-expanded="true"] svg { transform: rotate(180deg); }
.nav-caret:hover { color: var(--cool-deep); }
.nav-menu { position: absolute; top: calc(100% + 14px); left: -14px; z-index: 120;
  min-width: 286px; list-style: none; margin: 0; padding: 8px;
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  opacity: 0; visibility: hidden; transform: translateY(-6px);
  transition: opacity .2s var(--ease), transform .2s var(--ease), visibility .2s; }
.nav-menu::before { content: ""; position: absolute; inset: -14px 0 100% 0; }
.nav-has-menu.is-open .nav-menu { opacity: 1; visibility: visible; transform: translateY(0); }
/* Hover- and keyboard-open. The click-the-caret model alone hid the seven
   service pages: nobody hovers "Services" expecting to click a tiny chevron, so
   the menu read as empty and the pages looked missing. Deliberately NOT gated by
   a hover/pointer media query -- a Windows touchscreen laptop reports its PRIMARY
   pointer as coarse/no-hover even while a mouse is in use, so any such gate
   silently skips the rule on exactly the machines that have a mouse. Left
   unconditional: on a hovering device it opens; on a pure-touch phone :hover
   never fires so the rule is simply inert and the JS caret-click still opens it.
   CSS-only, so it never fights that click toggle. focus-within opens it for
   keyboard users. */
/* Invisible bridge across the 14px gap between the nav bar and the menu, so
   moving the pointer down onto the menu never drops :hover and snaps it shut. */
.nav-has-menu::after { content: ""; position: absolute; top: 100%; left: 0; right: 0; height: 16px; }
.nav-has-menu:hover .nav-menu,
.nav-has-menu:focus-within .nav-menu { opacity: 1; visibility: visible; transform: translateY(0); }
.nav-has-menu:hover .nav-caret svg { transform: rotate(180deg); }
.nav-menu li { margin: 0; }
.nav-menu a { display: block; padding: 9px 12px; border-radius: 7px;
  font-family: var(--font-body); font-size: var(--fs-sm); font-weight: 500;
  letter-spacing: 0; text-transform: none; color: var(--text); }
.nav-menu a::after { display: none; }
.nav-menu a:hover, .nav-menu a:focus-visible { background: var(--surface-2); color: var(--cool-deep); }
.nav-menu a[aria-current="page"] { color: var(--cool-deep); background: color-mix(in srgb, var(--cool) 10%, #fff); }
.nav-mobile .nav-sub { padding-left: 2.4rem; font-size: var(--fs-sm); opacity: .88; }

/* ---------- footer additions ---------- */
@media (min-width: 620px){ .footer-cols-4 { grid-template-columns: 1.25fr 1fr 1fr; } }
@media (min-width: 1000px){ .footer-cols-4 { grid-template-columns: 1.3fr 1.15fr 1fr .95fr; } }
.footer-proof { font-size: var(--fs-xs); color: var(--on-ink-mut); }
.footer-areas { border-top: 1px solid rgba(255,255,255,.1); padding-block: clamp(20px,3vw,28px); }
.footer-areas h2 { color: #fff; font-size: var(--fs-sm); letter-spacing: .1em; text-transform: uppercase; margin-bottom: .6rem; }
.footer-areas p { color: var(--on-ink-mut); font-size: var(--fs-xs); margin: 0; max-width: 86ch; line-height: 1.7; }
.footer-areas a { color: var(--cool-light); }
.mt-xs { margin-top: .5rem; }

/* ---------- breadcrumbs ---------- */
.crumbs { font-size: var(--fs-xs); color: var(--on-ink-mut); margin-bottom: .9rem; }
.crumbs ol { list-style: none; display: flex; flex-wrap: wrap; gap: .4rem; margin: 0; padding: 0; }
.crumbs a { color: var(--cool-light); text-decoration: none; }
.crumbs a:hover { text-decoration: underline; }
.crumbs li + li::before { content: "/"; margin-right: .4rem; opacity: .5; }

/* ---------- the panic rail ----------
   Top of every service page. A homeowner in a hot house needs coverage, a
   phone number and what-happens-next BEFORE any education, so the teaching
   content starts below this. */
.panic { background: var(--surface-2); border-bottom: 1px solid var(--line);
  padding-block: clamp(20px, 3vw, 30px); }
.panic-in { display: grid; gap: clamp(16px, 2.4vw, 30px); align-items: center; }
@media (min-width: 860px){ .panic-in { grid-template-columns: 1.35fr .95fr; } }
.panic-now { font-family: var(--font-display); font-weight: 600; font-size: var(--fs-lg);
  color: var(--ink); margin: 0 0 .35rem; }
.panic p { color: var(--muted); font-size: var(--fs-sm); margin: 0; max-width: 58ch; }
.panic-acts { display: flex; flex-wrap: wrap; gap: .7rem; align-items: center; }
.panic-tel { display: inline-flex; align-items: center; gap: .5rem; text-decoration: none;
  font-family: var(--font-display); font-weight: 700; font-size: clamp(1.15rem, 3vw, 1.5rem);
  color: var(--cool-deep); white-space: nowrap; }
.panic-tel svg { width: 22px; height: 22px; color: var(--warm-deep); flex: none; }
.panic-tel:hover { color: var(--ink); }
.panic-next { list-style: none; margin: .9rem 0 0; display: grid; gap: .3rem; }
.panic-next li { font-size: var(--fs-xs); color: var(--muted); padding-left: 1.4rem; position: relative; }
.panic-next li::before { content: ""; position: absolute; left: .35rem; top: .52em;
  width: 6px; height: 6px; border-radius: 50%; background: var(--cool); }

/* ---------- answer-first block ----------
   Recommendation 2 of the content plan: AI answer engines assemble passages,
   not pages, so each page opens with a self-contained answer that still makes
   sense lifted out of context. */
.answer { background: #fff; border: 1px solid var(--line); border-left: 4px solid var(--cool);
  border-radius: var(--radius); padding: clamp(18px, 2.6vw, 26px);
  box-shadow: var(--shadow); margin-bottom: clamp(26px, 4vw, 40px); }
.answer p { font-size: var(--fs-md); color: var(--text); margin: 0; max-width: none; line-height: 1.66; }
.answer p + p { margin-top: .8em; }
.answer strong { color: var(--ink); }

/* ---------- safety callout ---------- */
.safety { background: color-mix(in srgb, var(--warm) 9%, #fff);
  border: 1px solid color-mix(in srgb, var(--warm) 38%, var(--line));
  border-left: 4px solid var(--warm-deep);
  border-radius: var(--radius); padding: clamp(18px, 2.6vw, 26px); margin-bottom: clamp(22px,3vw,32px); }
.safety h3 { display: flex; align-items: center; gap: .55rem; font-size: var(--fs-md);
  color: #8F3F0C; margin-bottom: .5em; }
.safety h3 svg { width: 22px; height: 22px; flex: none; }
.safety ul { margin: 0; padding-left: 1.3rem; display: grid; gap: .45rem; }
.safety li { color: var(--text); font-size: var(--fs-sm); }
.safety li strong { color: #8F3F0C; }
.safety > p:last-child { margin-bottom: 0; }

/* ---------- data tables (symptom to action, comparisons) ----------
   Wide tables scroll inside their own container so the page body never scrolls
   sideways on a phone. */
.tbl-wrap { overflow-x: auto;
  border: 1px solid var(--line); border-radius: var(--radius); margin-bottom: clamp(22px,3vw,32px); }
.data-table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); min-width: 620px; background: #fff; }
.data-table th, .data-table td { text-align: left; padding: 12px 15px;
  border-bottom: 1px solid var(--line); vertical-align: top; color: var(--muted); }
.data-table thead th { background: var(--surface-2); color: var(--ink);
  font-family: var(--font-display); font-weight: 600; font-size: var(--fs-xs);
  letter-spacing: .05em; text-transform: uppercase; }
.data-table tbody th { color: var(--ink); font-weight: 600; font-family: var(--font-body); }
.data-table tbody tr:last-child th, .data-table tbody tr:last-child td { border-bottom: none; }
/* Body rows are white; only the header carries the shaded fill. Rows read off
   the border rules, not a zebra tint (Julia 2026-07-28). */
.data-table tbody td, .data-table tbody th { background: #fff; }
.tbl-note { font-size: var(--fs-xs); color: var(--muted); margin: -.6rem 0 clamp(22px,3vw,32px); font-style: italic; }
/* The -.6rem top margin tucks the note under a data table. When the note
   instead follows the wrapped city list (which has no bottom margin), that
   negative pull collides it with the last chip -- restore a positive gap. */
.area-list + .tbl-note { margin-top: clamp(12px, 1.6vw, 18px); }

/* ---------- FAQ ----------
   Real answers, always in the markup. The benchmark competitor lists questions
   with no answers behind them; native details and summary means the text is
   present for a reader, a crawler and an answer engine even when collapsed. */
.faq { display: grid; gap: .7rem; margin-bottom: clamp(22px,3vw,32px); }
.faq details { background: #fff; border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.faq summary { cursor: pointer; list-style: none; padding: 16px clamp(16px,2.2vw,22px);
  font-family: var(--font-display); font-weight: 600; font-size: var(--fs-base); color: var(--ink);
  display: flex; align-items: flex-start; gap: .8rem; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: ""; margin-left: auto; flex: none; width: 11px; height: 11px;
  margin-top: .35em; border-right: 2.4px solid var(--cool-deep); border-bottom: 2.4px solid var(--cool-deep);
  transform: rotate(45deg); transition: transform .25s var(--ease); }
.faq details[open] summary::after { transform: rotate(-135deg); }
.faq summary:hover { background: var(--surface-2); }
.faq summary:focus-visible { outline: 3px solid var(--cool); outline-offset: -3px; }
.faq .faq-body { padding: 0 clamp(16px,2.2vw,22px) 18px; }
.faq .faq-body p { color: var(--muted); font-size: var(--fs-sm); margin-bottom: .8em; max-width: none; }
.faq .faq-body :last-child { margin-bottom: 0; }
.faq .faq-body ul { margin: 0 0 .8em; padding-left: 1.3rem; }
.faq .faq-body li { color: var(--muted); font-size: var(--fs-sm); margin-bottom: .3em; }

/* ---------- will / will not ----------
   Replaces the invented-guarantee pattern. Stated boundaries, not warranties
   a real buyer has not agreed to. */
.will-wont { display: grid; gap: clamp(16px,2.4vw,26px); margin-bottom: clamp(22px,3vw,32px); }
@media (min-width: 760px){ .will-wont { grid-template-columns: 1fr 1fr; } }
.ww-col { background: #fff; border: 1px solid var(--line); border-radius: var(--radius);
  padding: clamp(20px,2.8vw,28px); }
.ww-col h3 { font-size: var(--fs-md); margin-bottom: .7em; display: flex; align-items: center; gap: .5rem; }
.ww-col.will { border-top: 3px solid var(--cool); }
.ww-col.wont { border-top: 3px solid var(--warm-deep); background: var(--surface-2); }
.ww-col ul { list-style: none; display: grid; gap: .6rem; margin: 0; }
.ww-col li { font-size: var(--fs-sm); color: var(--muted); padding-left: 1.6rem; position: relative; line-height: 1.6; }
.ww-col.will li::before { content: ""; position: absolute; left: 0; top: .42em; width: 11px; height: 6px;
  border-left: 2.2px solid var(--cool-deep); border-bottom: 2.2px solid var(--cool-deep); transform: rotate(-45deg); }
.ww-col.wont li::before { content: ""; position: absolute; left: .1rem; top: .62em; width: 10px; height: 2.2px;
  background: var(--warm-deep); border-radius: 2px; }

/* ---------- decision factors ---------- */
.factors { list-style: none; counter-reset: f; display: grid; gap: .8rem; margin: 0 0 clamp(22px,3vw,32px); }
.factors li { counter-increment: f; position: relative; padding-left: 3rem;
  font-size: var(--fs-sm); color: var(--muted); line-height: 1.65; }
.factors li::before { content: counter(f); position: absolute; left: 0; top: -.1em;
  width: 2rem; height: 2rem; border-radius: 50%; display: grid; place-items: center;
  background: color-mix(in srgb, var(--cool) 13%, #fff); color: var(--cool-deep);
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-xs); }
.factors li strong { color: var(--ink); display: block; margin-bottom: .1em; font-size: var(--fs-base); }

/* ---------- in-page jump nav (long pages) ---------- */
.jump { border-block: 1px solid var(--line); padding-block: 14px; margin-bottom: clamp(26px,4vw,40px); }
.jump h2 { font-size: var(--fs-xs); letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted); margin-bottom: .6rem; font-family: var(--font-body); font-weight: 600; }
/* Quick Links / in-page jump links are plain bold underlined text, never pills
   or chips (site-wide rule, Julia 2026-07-29). Inline row, dot-separated. */
.jump ul { list-style: none; display: flex; flex-wrap: wrap; align-items: baseline; gap: .35rem 0; margin: 0; }
.jump li:not(:last-child)::after { content: "\00B7"; margin: 0 .7rem; color: var(--muted); }
.jump a { font-size: var(--fs-sm); font-weight: 700; color: var(--text);
  text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1.5px; }
.jump a:hover { color: var(--cool-deep); }

/* ---------- sibling / related links ---------- */
.sib { display: grid; gap: .8rem; margin-bottom: clamp(22px,3vw,32px); }
@media (min-width: 700px){ .sib { grid-template-columns: 1fr 1fr; } }
.sib a { display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius);
  padding: 15px 18px; text-decoration: none; transition: border-color .2s var(--ease), transform .2s var(--ease); }
.sib a:hover { border-color: color-mix(in srgb, var(--cool) 45%, var(--line)); transform: translateX(3px); }
.sib .sib-t { font-family: var(--font-display); font-weight: 600; font-size: var(--fs-base); color: var(--ink); }
.sib .sib-d { display: block; font-family: var(--font-body); font-weight: 400;
  font-size: var(--fs-xs); color: var(--muted); margin-top: .15em; }
.sib svg { width: 18px; height: 18px; color: var(--cool-deep); flex: none; }

/* ---------- coverage lists ---------- */
.area-cols { display: grid; gap: clamp(18px,3vw,32px); margin-bottom: clamp(22px,3vw,32px); }
@media (min-width: 760px){ .area-cols { grid-template-columns: 1fr 1fr; } }
.area-card { display: block; background: #fff; border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: clamp(20px,3vw,30px); text-decoration: none; color: inherit;
  transition: transform var(--ease), box-shadow var(--ease), border-color var(--ease); }
a.area-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); border-color: color-mix(in srgb, var(--cool) 45%, var(--line)); }
a.area-card:focus-visible { outline: 3px solid var(--cool); outline-offset: 3px; }
.area-card h2 { font-size: var(--fs-xl); margin-bottom: .3em; color: var(--ink); }
.area-card h3 { font-size: var(--fs-lg); margin-bottom: .3em; }
.area-card > p { color: var(--muted); font-size: var(--fs-sm); }
.area-eyebrow { display: inline-block; font-family: var(--font-display); font-size: var(--fs-xs);
  letter-spacing: .08em; text-transform: uppercase; color: var(--cool-deep); margin-bottom: .5em; font-weight: 600; }
.area-go { display: inline-flex; align-items: center; gap: .4rem; margin-top: 1rem;
  font-weight: 600; font-size: var(--fs-sm); color: var(--cool-deep); }
.area-go svg { width: 17px; height: 17px; transition: transform var(--ease); }
a.area-card:hover .area-go svg { transform: translateX(4px); }
.area-list { list-style: none; display: flex; flex-wrap: wrap; gap: .4rem; margin: 1rem 0 0; }
.area-list li { font-size: var(--fs-xs); color: var(--text); background: var(--surface-2);
  border: 1px solid var(--line); border-radius: 99px; padding: 5px 12px; }

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  .nav-menu, .nav-caret svg, .faq summary::after, .sib a { transition: none; }
  .sib a:hover { transform: none; }
}
/* ---------- split page hero: copy left, panic card right ----------
   The interior hero was text-only and left a large dead zone on the right at
   desktop widths, and it pushed the phone number below the fold, which defeats
   the point of having a panic rail at all. The card lifts the urgent path into
   the hero so coverage, phone and what-happens-next are visible without
   scrolling, and it gives the dark band something to hold. */
.hero-split .container { display: grid; gap: clamp(24px, 3.5vw, 46px); align-items: center; }
@media (min-width: 920px){
  .hero-split .container { grid-template-columns: 1.1fr .9fr; }
  .hero-split .hero-copy { max-width: 640px; }
}
.hero-split .hero-sub { margin-bottom: 0; }

.panic-card { background: #fff; border-radius: var(--radius-lg); padding: clamp(20px, 2.8vw, 30px);
  box-shadow: var(--shadow-lg); border-top: 4px solid var(--warm);
  /* Column layout so every child STACKS. The phone link and the button are both
     inline-flex; without this they flow onto the same line and run together
     (the button's width:auto override removes the block break). Text still fills
     the card width (align-items defaults to stretch); the phone and button opt
     back to their natural width and sit left via align-self. */
  display: flex; flex-direction: column; }
.panic-card h2 { color: var(--ink); font-size: var(--fs-lg); margin-bottom: .35em; }
.panic-card > p { color: var(--muted); font-size: var(--fs-sm); margin-bottom: 1rem; }
.panic-card .panic-tel { margin-bottom: .9rem; align-self: flex-start; }
/* Auto width, not a full-width block: a full-width pill in this narrow card reads
   heavy and generic. Sits left at its natural size. Overrides .btn-pill-block. */
.panic-card .btn-pill { width: auto; gap: .5rem; align-self: flex-start; }
.panic-card .panic-next { margin: 1.1rem 0 0; padding-top: 1rem; border-top: 1px solid var(--line); }
/* When the button follows the promises list (process page card), give the copy
   real breathing room before the CTA. */
.panic-card .panic-next + .btn-pill { margin-top: 1.4rem; }
.panic-card .panic-next li { color: var(--muted); }

/* A light card nested inside an .on-ink band inherits the dark band's text and
   link colours, so anything that does not set its own colour gets silently
   repainted. Measured on the first build: the panic card's phone number came
   out as --cool-light at 2.25:1 on white, a genuine failure on the single most
   important link on the page. Same trap that turned the footer button's label
   blue -- `.on-ink a` is a two-class selector and outranks a single-class
   component rule. Reset at the card boundary so every light card on a dark
   band is safe by default instead of needing a patch per element. */
.on-ink .panic-card { color: var(--text); }
.on-ink .panic-card a:not(.btn-pill) { color: var(--cool-deep); }
.on-ink .panic-card a:not(.btn-pill):hover { color: var(--ink); }
.on-ink .panic-card .btn-pill { color: #fff; }

/* The standalone band is kept for pages that want the rail below a full-bleed
   hero (the homepage), but service pages use the card above. */
/* end NORTHLINE_CONTENT_LAYER_v1 */
