/* CarBluff - WARM variant (Option B). Self-contained, light-first, trust-first.
   Standalone token system. Does not touch style.css (the live "A" design).
   Reuses the exact class + id contract the markup and js/*.js expect, restyled
   as a calm, human, low-clutter results summary rather than a hacker console.
   Palette: deep teal (trust) + warm coral (warmth). Neon lime is gone; green is
   a status-only "safe" color. Type: Figtree + Hanken Grotesk (humanist sans). */

/* Self-hosted fonts (CSP/self-host policy: no Google Fonts CDN). Variable woff2,
   full weight axis in one file per family + latin-ext for accented characters. */
@font-face {
  font-family: "Figtree"; font-style: normal; font-weight: 400 800; font-display: swap;
  src: url(../fonts/figtree-latin.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Figtree"; font-style: normal; font-weight: 400 800; font-display: swap;
  src: url(../fonts/figtree-latin-ext.woff2) format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Hanken Grotesk"; font-style: normal; font-weight: 400 700; font-display: swap;
  src: url(../fonts/hanken-latin.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Hanken Grotesk"; font-style: normal; font-weight: 400 700; font-display: swap;
  src: url(../fonts/hanken-latin-ext.woff2) format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* Warm palette is a single ivory aesthetic; pin it under the dark/light toggle attrs too so
   style.css's :root[data-theme="light"] (higher specificity) can't override the warm ground.
   warm.css loads AFTER style.css, so at equal specificity these win by source order.

   2026-08-21, DARK-B: the warm palette is no longer a single ivory aesthetic. It used to be pinned
   identically across :root, [data-theme="dark"] and [data-theme="light"], which meant the twenty
   pages still rendering a theme toggle had a control that provably could not change one byte of
   colour. Warm now has a genuine night variant (see the [data-theme="dark"] block below), so the
   toggle is real again and the two surfaces (web + iOS app) are back at parity.
   Resolution order matches js/theme.js exactly:
     explicit choice  -> [data-theme="dark"] / [data-theme="light"]
     no choice at all -> prefers-color-scheme (dark only when the OS asks for dark; light otherwise)
   The light values below are UNCHANGED from the shipped warm theme, byte for byte. */
:root, :root[data-theme="light"] {
  color-scheme: light;

  /* grounds & surfaces (soft warm light) */
  --bg: #faf7f2;            /* warm ivory page */
  --surface: #ffffff;       /* cards */
  --surface-soft: #f4efe7;  /* warm panel */
  --surface-tint: #eaf5f5;  /* calm teal-tinted panel */
  --peach: #fcece1;         /* soft warm fill */
  --peach-line: #f6d9c8;

  /* lines.
     2026-08-21, A11Y: --border-strong is the token the dark block already documents as the one that
     "carries real UI boundaries (input edges, chip outlines)", tuned there to clear 3:1. Light never
     got the same treatment: the shipped #d9cfbe measured 1.44:1 against --bg, so every transparent
     control (form inputs, the scan-mode tabs, the ghost result buttons, the theme toggle) had a
     boundary that was, for contrast purposes, not there at all - WCAG 2.1 SC 1.4.11 wants 3:1.
     Retuned to a warm taupe on the same hue family, measured on every warm light ground:
     --bg 3.40:1, --surface 3.63:1, --surface-soft 3.17:1, --surface-tint 3.26:1, --peach 3.15:1.
     Dark is deliberately untouched (#7a6a58 already measures 3.55:1 on --bg).
     --rail-muted keeps the OLD value for the two places that are decorative rather than a control
     boundary - the "minor" severity rail and the dimmed hero-card bullet - so nothing in the risk
     ramp gets visually heavier as a side effect of a boundary fix. */
  --border: #e9e1d4;
  --border-strong: #8f8576;
  --rail-muted: #d9cfbe;

  /* ink (warm-cool slate) */
  --ink: #253039;           /* headings / strong body - ~12:1 on bg */
  --ink-2: #515c66;         /* body - ~6.5:1 on bg */
  --ink-3: #5d6771;         /* muted, >=14px - ~5:1 on surfaces */

  /* brand */
  --primary: #0f6e78;       /* deep teal - white text passes AA */
  --primary-strong: #0b5a63;
  --primary-soft: #dcedef;
  --primary-ink: #ffffff;

  --accent: #dd6038;        /* warm coral - for marks/large text, not body */
  /* 2026-08-21, A11Y: was #c14f2b, which measured 4.45:1 on --bg and 4.12:1 on --peach - i.e. the
     link colour missed AA body text on the two grounds it is most often used on. Darkened one step,
     same hue family (16deg vs 14deg): --bg 5.15:1, --surface 5.51:1, --surface-soft 4.81:1,
     --surface-tint 4.95:1, --peach 4.78:1. Dark's --accent-deep is unchanged (9.16:1 on --bg). */
  --accent-deep: #b34620;   /* coral for small text / links (AA on every warm light ground) */
  --accent-soft: #fbe6da;

  /* status (risk ladder + success). green is status-only now.
     Every rung now has a "-deep" TEXT shade beside its ramp colour, the way --safe and --critical
     already did. The ramp colours themselves are UNCHANGED - they still paint the rails, meters,
     pins and chip tints, where 3:1 is the bar. The -deep shades exist because the same colour used
     as 10-14px LABEL text needs 4.5:1, and --caution measured 2.92:1 / --high 3.15:1 as chip text.
     Hue is held on each rung (caution 39->41, high 23->23), so the ramp stays separable by hue and
     is not flattened toward the middle: safe 153, caution 41, high 23, critical 2. */
  --safe: #1f9d63;   --safe-deep: #157a4c;  --safe-soft: #e4f5ec;
  --caution: #b9821a; --caution-deep: #856011; --caution-soft: #f9efd6;
  --high: #cf6a2c;   --high-deep: #a3521f;  --high-soft: #f8e6d9;
  --critical: #cf4741; --critical-deep: #b53a35; --critical-soft: #f9e3e1;

  /* css/chartkit.css names the same ramp --good/--warn/--serious/--critical (index-warm.html's
     inline bridge aliases them onto the warm tokens). These give its text shades the same names it
     can reach. Declared once: var() resolves against whichever theme block last set the target, so
     these follow light and dark automatically without being restated in either. */
  --warn-deep: var(--caution-deep);
  --serious-deep: var(--high-deep);

  /* shape (locked): cards 18, panels 20, inputs 12, buttons pill, chips pill */
  --r-card: 18px;
  --r-panel: 22px;
  --r-input: 12px;
  --r-pill: 999px;

  --shadow-sm: 0 1px 2px rgba(37,48,57,.05), 0 2px 8px rgba(37,48,57,.04);
  --shadow-md: 0 10px 30px rgba(37,48,57,.08), 0 2px 8px rgba(37,48,57,.05);
  --shadow-teal: 0 18px 44px rgba(15,110,120,.14);

  /* Values that used to be written as literal rgba()/#fff inside component rules and therefore
     could not follow a theme. Tokenised here with their EXACT shipped light values, so light is
     unchanged and dark finally has somewhere to say something different. */
  --header-bg: rgba(250,247,242,.85);   /* sticky header wash */
  --scrim: rgba(37,48,57,.55);          /* modal backdrop */
  --modal-shadow: 0 30px 70px rgba(37,48,57,.28);
  --btn-shadow: 0 8px 18px rgba(15,110,120,.18);
  --btn-shadow-hover: 0 10px 22px rgba(15,110,120,.24);
  --illo-shadow: 0 8px 18px rgba(37,48,57,.10);
  --blob-a: rgba(221,96,56,.16);        /* hero glow, coral */
  --blob-b: rgba(15,110,120,.16);       /* hero glow, teal */
  --toast-bg: var(--ink);               /* inverted chip: dark ground, light label */
  --toast-ink: #ffffff;
  --seg-off: .3;                        /* unlit meter / gauge segment opacity */

  --font-head: "Figtree", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-body: "Hanken Grotesk", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-num: "Figtree", system-ui, sans-serif;
  /* 2026-08-26, CASCADE GAP. This block redeclared --font-head and --font-body but NOT
     --font-mono, and warm.css only beats style.css for properties it RE-DECLARES. So on the
     22 pages that load both files, --font-mono kept resolving to style.css's "Geist Mono"
     unless that page's own [data-design="warm"] bridge happened to remap it. Every page did
     carry such a bridge, which is why nothing visibly rendered in mono - but the system was
     one forgotten bridge away from a console face appearing on a live page, and the six warm-
     only pages (pricing, how-it-works, deal-score, checklist, seller-checklist, buying-help)
     resolved --font-mono to nothing at all. Declaring it here closes both holes at the source
     and makes the per-page bridges redundant rather than load-bearing.
     Aliased to --font-num, not to a mono stack: see the long note in style.css: there is no
     monospace in this system, and call sites showing digits must add tabular-nums themselves
     because Figtree's default figures are proportional. */
  --font-mono: var(--font-num);

  --wrap: 1080px;
}

/* ==========================================================================
   WARM DARK (2026-08-21)
   The warm system at NIGHT, not the retired arm-A dark resurrected. Arm A was a cold
   #0b0e13 near-black with an acid lime; warm deliberately moved away from that toward a
   calmer, more trustworthy read for wary, non-car-literate buyers. So the ground here is a
   warm umber-black on the SAME hue family as the ivory it replaces (bg hue ~33deg both ways),
   never blue-black, and the accent stays coral rather than turning neon.

   Two structural inversions the light palette does not need:
   - --primary flips from a deep teal (dark text on it) to a LIGHT teal, so --primary-ink
     becomes a dark teal-black. Every filled control keeps its dark-on-light relationship.
   - the "-deep" status shades are the TEXT shades. On ivory that means darker; on umber it
     means lighter. Same job, opposite direction.
   The ramp keeps its semantic direction (green safe -> amber -> orange -> red) and its hue
   separation; it is lightened for legibility, not flattened toward one another.
   ---- KEEP THIS BLOCK AND THE prefers-color-scheme COPY BELOW IN SYNC. ---- */
:root[data-theme="dark"] {
  color-scheme: dark;

  /* grounds & surfaces (warm umber night) */
  --bg: #17130f;            /* warm umber-black page */
  --surface: #221d18;       /* cards, raised off the ground */
  --surface-soft: #2b241d;  /* warm panel */
  --surface-tint: #14292d;  /* calm teal-tinted panel */
  --peach: #33241b;         /* soft warm fill */
  --peach-line: #4a3227;

  /* lines. --border is the decorative hairline; --border-strong carries real UI boundaries
     (input edges, chip outlines) and is set to clear 3:1 against --surface (3.21:1). */
  --border: #3b322a;
  --border-strong: #7a6a58;
  /* Dark's decorative rail happens to want the same value as its boundary token; named separately
     so the light override of --border-strong cannot drag the "minor" rail along with it. */
  --rail-muted: #7a6a58;

  /* ink (warm off-white) */
  --ink: #f5efe6;           /* headings / strong body - 16.2:1 on bg */
  --ink-2: #d5cabb;         /* body - 11.4:1 on bg, 9.5:1 on --surface-soft */
  --ink-3: #b3a698;         /* muted - 7.8:1 on bg, 6.4:1 on --surface-soft */

  /* brand */
  --primary: #4cc7cf;       /* light teal - dark --primary-ink on it passes AA */
  --primary-strong: #7fdde3;/* hover/text teal: LIGHTER in dark, the mirror of light mode */
  --primary-soft: #13343a;
  --primary-ink: #0a1f22;

  --accent: #ef8552;        /* warm coral, held warm - no neon substitution */
  --accent-deep: #f4a382;   /* coral for small text / links - 9.2:1 on bg */
  --accent-soft: #3b2117;

  /* status (risk ladder + success). The "-deep" text shades run the other way here, exactly as
     --safe-deep and --critical-deep already do on this side: lighter, not darker. Measured as chip
     text on --surface: caution-deep 10.61:1, high-deep 8.82:1. Hues held (caution 40, high 25). */
  --safe: #35bd7a;   --safe-deep: #5fd79b;  --safe-soft: #112c1f;
  --caution: #e8b552; --caution-deep: #f0c979; --caution-soft: #33260d;
  --high: #f0904f;   --high-deep: #f6ac78;  --high-soft: #3a2010;
  --critical: #f26a60; --critical-deep: #ff8f86; --critical-soft: #3a1917;

  /* depth: on a dark ground a tinted shadow reads as haze, so these go to true black */
  --shadow-sm: 0 1px 2px rgba(0,0,0,.5), 0 2px 8px rgba(0,0,0,.35);
  --shadow-md: 0 10px 30px rgba(0,0,0,.55), 0 2px 8px rgba(0,0,0,.4);
  --shadow-teal: 0 18px 44px rgba(0,0,0,.55);

  --header-bg: rgba(23,19,15,.86);
  --scrim: rgba(8,6,4,.68);
  --modal-shadow: 0 30px 70px rgba(0,0,0,.6);
  --btn-shadow: 0 8px 18px rgba(0,0,0,.45);
  --btn-shadow-hover: 0 10px 22px rgba(0,0,0,.55);
  --illo-shadow: 0 8px 18px rgba(0,0,0,.5);
  --blob-a: rgba(239,133,82,.14);
  --blob-b: rgba(76,199,207,.13);
  /* Inverted toast: on a dark page the light chip is the one that reads as "on top". */
  --toast-bg: #f2eae0;
  --toast-ink: #1d1815;
  /* An unlit segment at .3 over umber is dimmer than the same .3 over ivory, so the unlit
     half of the meter lifts slightly to keep the instrument reading as one scale. */
  --seg-off: .42;
}

/* Same palette, for a visitor who has NEVER touched the toggle and whose OS asks for dark.
   Scoped so an explicit choice in either direction always wins, and so it can never fight
   the pre-paint snippet. Mirrors js/theme.js systemTheme(): dark only on an explicit
   prefers-color-scheme: dark, light in every other case (including "no preference"). */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]):not([data-theme="dark"]) {
    color-scheme: dark;
    --bg: #17130f;
    --surface: #221d18;
    --surface-soft: #2b241d;
    --surface-tint: #14292d;
    --peach: #33241b;
    --peach-line: #4a3227;
    --border: #3b322a;
    --border-strong: #7a6a58;
    --rail-muted: #7a6a58;
    --ink: #f5efe6;
    --ink-2: #d5cabb;
    --ink-3: #b3a698;
    --primary: #4cc7cf;
    --primary-strong: #7fdde3;
    --primary-soft: #13343a;
    --primary-ink: #0a1f22;
    --accent: #ef8552;
    --accent-deep: #f4a382;
    --accent-soft: #3b2117;
    --safe: #35bd7a;   --safe-deep: #5fd79b;  --safe-soft: #112c1f;
    --caution: #e8b552; --caution-deep: #f0c979; --caution-soft: #33260d;
    --high: #f0904f;   --high-deep: #f6ac78;  --high-soft: #3a2010;
    --critical: #f26a60; --critical-deep: #ff8f86; --critical-soft: #3a1917;
    --shadow-sm: 0 1px 2px rgba(0,0,0,.5), 0 2px 8px rgba(0,0,0,.35);
    --shadow-md: 0 10px 30px rgba(0,0,0,.55), 0 2px 8px rgba(0,0,0,.4);
    --shadow-teal: 0 18px 44px rgba(0,0,0,.55);
    --header-bg: rgba(23,19,15,.86);
    --scrim: rgba(8,6,4,.68);
    --modal-shadow: 0 30px 70px rgba(0,0,0,.6);
    --btn-shadow: 0 8px 18px rgba(0,0,0,.45);
    --btn-shadow-hover: 0 10px 22px rgba(0,0,0,.55);
    --illo-shadow: 0 8px 18px rgba(0,0,0,.5);
    --blob-a: rgba(239,133,82,.14);
    --blob-b: rgba(76,199,207,.13);
    --toast-bg: #f2eae0;
    --toast-ink: #1d1815;
    --seg-off: .42;
  }
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
}
body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
h1, h2, h3, h4 { font-family: var(--font-head); color: var(--ink); line-height: 1.12; letter-spacing: -0.01em; }
::selection { background: var(--primary-soft); color: var(--primary-strong); }
:focus-visible { outline: 3px solid var(--primary); outline-offset: 3px; border-radius: 4px; }
a { color: var(--accent-deep); }

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 200; background: var(--primary);
  color: var(--primary-ink); padding: 12px 18px; font-weight: 700; text-decoration: none; border-radius: 0 0 12px 0;
}
.skip-link:focus { left: 0; }
.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 20px; }

/* ---------- header ---------- */
header {
  position: sticky; top: 0; z-index: 40;
  background: var(--header-bg);
  backdrop-filter: saturate(140%) blur(10px);
  -webkit-backdrop-filter: saturate(140%) blur(10px);
  border-bottom: 1px solid var(--border);
}
.nav { display: flex; align-items: center; justify-content: space-between; height: 68px; }
.logo { display: flex; align-items: center; gap: 10px; text-decoration: none; color: var(--ink); padding: 8px 0; }
.logo svg { display: block; }
.logo b { font-family: var(--font-head); font-size: 21px; font-weight: 800; letter-spacing: -0.02em; }
/* "Bluff" is teal text, not a pill. css/style.css:161 still carries the retired dark arm's treatment
   (lime background, padding: 1px 7px, border-radius, margin-left: .26em), and the 22 pages that load
   style.css inherit all of it. Twenty of them neutralise it with an identical one-line <style> in
   their own head, which is exactly the per-page duplication the text-transform reset below was moved
   here to end, and it drifted: verified.php and methodology.html both omit `margin-left: 0`, so both
   render the wordmark as "Car Bluff" with a 5.5px gap (measured 84px wide against index.html's 79px)
   instead of the locked-up "CarBluff". Owning the whole reset here means no page can drift again. */
.logo b span {
  color: var(--primary); background: none; padding: 0; margin-left: 0; border-radius: 0;
}
.nav nav { display: flex; align-items: center; flex-wrap: wrap; }
.nav a.link {
  color: var(--ink-2); text-decoration: none; font-family: var(--font-body);
  font-size: 15px; font-weight: 500; letter-spacing: 0; margin-left: 22px;
  display: inline-flex; align-items: center; min-height: 44px; border-radius: 8px;
}
.nav a.link:hover, .nav a.link:focus-visible { color: var(--primary); }
/* The CTA states font-size and border explicitly. css/style.css:1432 still carries a .nav a.link.nav-cta
   block written for the retired Log-in button; that block is now deleted, but stating both properties
   here keeps this control identical on any page that ever loads an older stylesheet again. */
.nav a.link.nav-cta {
  background: var(--primary); color: var(--primary-ink); padding: 0 16px; min-height: 40px; border-radius: var(--r-pill);
  border: 0; font-size: 15px; font-weight: 700;
}
.nav a.link.nav-cta:hover, .nav a.link.nav-cta:focus-visible { background: var(--primary-strong); color: var(--primary-ink); }
/* The old 700px mobile-nav block lived here (static header, column .nav, 14px links, the 253px
   two-row header). Every one of its declarations was overwritten by the 860px global-nav block at
   the bottom of this file, which sets the exact opposite for the same elements at overlapping
   widths and wins on source order. Deleted 2026-08-26 so there is one mobile nav to edit, not two
   contradictory blocks 1000 lines apart. The theme-switch 700px rule near line 1210 is separate
   and still live. */

/* style.css sets text-transform: uppercase on .logo b, h1 and .btn. warm.css wins on font, size and
   tracking but never touched that property, so the shouting treatment survived on every bridged page
   that lacked an inline reset (14 of the 21). The reset belongs here, next to the .logo b rule it
   corrects, rather than in per-page <style> blocks that sync-nav.js does not enforce. */
:root[data-design="warm"] h1,
:root[data-design="warm"] .logo b,
:root[data-design="warm"] .btn,
:root[data-design="warm"] .panel h2,
:root[data-design="warm"] section h2,
:root[data-design="warm"] .article-wrap h2,
:root[data-design="warm"] .step h3,
:root[data-design="warm"] .trend-title,
:root[data-design="warm"] .checklist-row h3,
:root[data-design="warm"] .modal h3 { text-transform: none; }

/* ---------- hero ---------- */
.hero { padding: 40px 0 8px; position: relative; overflow: hidden; }
.hero-grid { display: grid; gap: 44px; grid-template-columns: 1fr; align-items: center; padding-bottom: 40px; }
/* Two columns of very different heights (a 241px text block beside a 586px scanner panel), so
   centring the short one left ~172px of empty ivory above the H1 and the same below it, with
   nothing in that column to fill it. Top-align them and let the headline start where the panel
   starts; the hero's own top padding came down 64 -> 40 to take up the slack. */
@media (min-width: 1000px) { .hero-grid { grid-template-columns: 1.05fr .95fr; gap: 56px; align-items: start; } }

.kicker {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--font-body); font-size: 14px; font-weight: 600; letter-spacing: 0;
  color: var(--primary-strong); background: var(--primary-soft);
  padding: 7px 14px; border-radius: var(--r-pill); margin-bottom: 20px;
}
.kicker svg { width: 16px; height: 16px; }

h1 {
  font-size: clamp(34px, 5vw, 50px); font-weight: 800; line-height: 1.06; letter-spacing: -0.025em;
  max-width: 15ch; color: var(--ink);
}
/* One accent for the highlighted word, everywhere. #deal-score h2 em used to paint it coral and
   .dealsoon h2 em painted the same Deal Score content teal, so the brand's signature move changed
   colour between pages. Both of those rules are deleted; this is the only one. */
h1 em, h2 em { font-style: normal; color: var(--primary); }
/* The brand rule is that there is no monospace anywhere in the system, and index.html's --font-mono
   token was pointed at Figtree for exactly that reason. One bare <code> survived: the cookie name on
   privacy.html:319, which carried no rule at all and so fell to the UA default. It still needs to
   read as a literal string rather than prose, so it keeps a tinted chip and a step down in size and
   gets that in the body face instead of Consolas. Site-wide, so the next <code> cannot reintroduce
   the console look either. */
code {
  font-family: var(--font-body); font-size: 0.94em; font-weight: 600; letter-spacing: 0;
  background: var(--surface-soft); border: 1px solid var(--border);
  border-radius: 6px; padding: 1px 6px; word-break: break-word;
}
.sub { color: var(--ink-2); max-width: 52ch; margin-top: 18px; font-size: 19px; line-height: 1.6; }

.actions { display: flex; gap: 14px; flex-wrap: wrap; align-items: center; margin-top: 28px; }
.hero .actions { margin-top: 30px; }
.reassure {
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
  margin-top: 22px; color: var(--ink-3); font-size: 14.5px;
}
.reassure span { display: inline-flex; align-items: center; gap: 7px; }
.reassure svg { width: 18px; height: 18px; color: var(--safe); flex: none; }

/* hero visual: soft scene + a real sample-result card */
.hero-visual { position: relative; display: none; }
@media (min-width: 1000px) { .hero-visual { display: block; } }
.hero-blob {
  position: absolute; inset: -8% -6% -14% -6%; z-index: 0;
  background:
    radial-gradient(60% 55% at 78% 22%, var(--blob-a), transparent 70%),
    radial-gradient(70% 60% at 20% 78%, var(--blob-b), transparent 72%);
  filter: blur(6px);
}
.hero-illustration { position: absolute; z-index: 3; filter: drop-shadow(var(--illo-shadow)); }
.hero-illo-a { top: -22px; left: 6px; width: 82px; height: 82px; }
.hero-illo-b { bottom: -20px; right: 34px; width: 68px; height: 68px; }

.hero-card {
  position: relative; z-index: 2;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-card); box-shadow: var(--shadow-teal);
  padding: 24px 24px 22px; max-width: 380px; margin: 0 auto;
}
.hc-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 16px; }
.hc-listing { font-size: 14px; font-weight: 600; color: var(--ink); }
.hc-listing small { display: block; color: var(--ink-3); font-weight: 500; font-size: 12.5px; margin-top: 1px; }
.hc-badge {
  font-size: 11.5px; font-weight: 700; color: var(--primary-strong);
  background: var(--primary-soft); padding: 5px 10px; border-radius: var(--r-pill);
}
.hc-scorewrap { display: flex; align-items: baseline; gap: 14px; }
.hero-card-score {
  font-family: var(--font-num); font-weight: 800; font-size: 68px; line-height: .9;
  letter-spacing: -0.04em; color: var(--critical); font-variant-numeric: tabular-nums;
}
.hero-card-score span { font-size: 20px; color: var(--ink-3); font-weight: 600; letter-spacing: 0; }
.hero-card-verdict {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 13px; font-weight: 700; color: var(--critical-deep);
  background: var(--critical-soft); padding: 7px 13px; border-radius: var(--r-pill);
}
.hero-card-verdict svg { width: 15px; height: 15px; }
.hero-card-meter { position: relative; display: flex; gap: 3px; height: 10px; margin: 20px 0 18px; }
.hc-seg { height: 100%; border-radius: var(--r-pill); }
.hc-1 { flex: 4; background: var(--critical); }
.hc-2 { flex: 2; background: var(--high); opacity: .28; }
.hc-3 { flex: 2; background: var(--caution); opacity: .28; }
.hc-4 { flex: 2; background: var(--safe); opacity: .28; }
.hc-pin { position: absolute; left: 23%; top: -6px; width: 3px; height: 22px; background: var(--ink); border-radius: var(--r-pill); }
.hero-card-flag {
  display: flex; align-items: flex-start; gap: 9px;
  font-size: 13.5px; color: var(--ink-2); border-top: 1px solid var(--border); padding: 11px 0;
}
.hero-card-flag::before {
  content: ""; flex: none; width: 8px; height: 8px; margin-top: 6px; border-radius: 50%;
  background: var(--critical);
}
.hero-card-flag.dim { color: var(--ink-3); }
.hero-card-flag.dim::before { background: var(--rail-muted); }

/* ---------- section shells ---------- */
section.block { padding: 72px 0; }
.section-tint { background: var(--surface-tint); }
.section-soft { background: var(--surface-soft); }
section h2 { font-size: clamp(26px, 3.4vw, 34px); font-weight: 800; letter-spacing: -0.02em; margin-bottom: 8px; }
section.block .lead { color: var(--ink-2); max-width: 60ch; margin: 8px 0 34px; font-size: 18px; }
section.block .lead a, .panel .hint a, footer a { color: var(--accent-deep); text-decoration: underline; text-underline-offset: 3px; }
section.block .lead a:hover, footer a:hover { color: var(--primary); }

/* ---------- analyzer / scan form ---------- */
.analyzer { padding: 8px 0 72px; }
.analyzer .wrap { max-width: 760px; }
.panel {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-panel); padding: 30px; box-shadow: var(--shadow-md);
}
.panel h2 { font-size: 24px; margin-bottom: 6px; }
.panel .hint { color: var(--ink-3); font-size: 15px; margin-bottom: 22px; line-height: 1.55; }
.grid { display: grid; gap: 18px; grid-template-columns: 1fr; }
@media (min-width: 640px) { .grid.cols-2 { grid-template-columns: 1fr 1fr; } .grid.cols-3 { grid-template-columns: 1fr 1fr 1fr; } }
.field label {
  display: block; font-family: var(--font-body); font-size: 14.5px; font-weight: 600;
  letter-spacing: 0; color: var(--ink); margin-bottom: 8px;
}
.field label .req { color: var(--accent-deep); }
.field-label-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.field-label-row label { margin-bottom: 0; }
.field input, .field textarea {
  width: 100%; background: var(--surface); border: 1.5px solid var(--border-strong);
  border-radius: var(--r-input); color: var(--ink); font-family: var(--font-body);
  font-size: 16px; padding: 14px 15px; min-height: 52px;
  transition: border-color 150ms ease, box-shadow 150ms ease;
}
.field textarea { min-height: 140px; resize: vertical; line-height: 1.55; }
.field input:focus, .field textarea:focus {
  outline: none; border-color: var(--primary); box-shadow: 0 0 0 4px var(--primary-soft);
}
.field input::placeholder, .field textarea::placeholder, .restore-row input::placeholder {
  color: var(--ink-3); opacity: .85;
}
.field .help { color: var(--ink-3); font-size: 13.5px; margin-top: 6px; }

fieldset.obs { border: 1px solid var(--border); border-radius: var(--r-card); padding: 20px; background: var(--surface-soft); }
fieldset.obs legend { font-family: var(--font-head); font-size: 15px; font-weight: 700; color: var(--ink); padding: 0 8px; }
fieldset.obs .obs-note { color: var(--ink-3); font-size: 14px; margin: 0 0 14px; }

.shots { margin-top: 14px; }
.shots-btn { display: inline-flex; }
.shots-hint { color: var(--ink-3); font-size: 13.5px; margin: 10px 0 0; line-height: 1.5; }
.shots-status { display: block; color: var(--ink-2); font-size: 13.5px; margin-top: 8px; min-height: 1em; }

.check {
  display: flex; gap: 12px; align-items: flex-start; padding: 11px 4px; cursor: pointer; min-height: 48px;
}
.check input { width: 22px; height: 22px; min-height: 0; accent-color: var(--primary); cursor: pointer; flex: none; margin-top: 2px; }
.check span { font-size: 15px; color: var(--ink); line-height: 1.4; }

/* buttons - pill, warm, tactile */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  min-height: 54px; padding: 0 30px; border: 1.5px solid var(--primary);
  background: var(--primary); color: var(--primary-ink); font-family: var(--font-head);
  font-weight: 700; font-size: 16.5px; letter-spacing: 0;
  border-radius: var(--r-pill); cursor: pointer; text-decoration: none;
  box-shadow: var(--btn-shadow);
  transition: background 140ms ease, transform 120ms ease, box-shadow 140ms ease;
}
.btn:hover, .btn:focus-visible { background: var(--primary-strong); border-color: var(--primary-strong); box-shadow: var(--btn-shadow-hover); }
.btn:active { transform: translateY(1px) scale(.995); }
.btn.ghost {
  background: var(--surface); color: var(--primary-strong); border-color: var(--border-strong);
  box-shadow: var(--shadow-sm);
}
.btn.ghost:hover, .btn.ghost:focus-visible { border-color: var(--primary); color: var(--primary-strong); background: var(--surface); }
.btn.btn-sm { min-height: 40px; padding: 0 16px; font-size: 14px; box-shadow: none; }
.btn[disabled] { opacity: .55; cursor: progress; }
.quota {
  font-family: var(--font-body); font-size: 13.5px; font-weight: 600; color: var(--ink-3);
  background: var(--surface-soft); padding: 6px 12px; border-radius: var(--r-pill);
}
.error-msg { color: var(--critical-deep); font-weight: 600; font-size: 14.5px; margin-top: 12px; display: none; }
.linklike {
  background: none; border: none; color: var(--ink-3); font-family: var(--font-body);
  font-size: 14px; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; padding: 8px; min-height: 44px;
}
.linklike:hover, .linklike:focus-visible { color: var(--primary); }

.adv { margin-top: 20px; border: 1px solid var(--border); border-radius: var(--r-card); background: var(--surface-soft); overflow: hidden; }
.adv > summary {
  cursor: pointer; list-style: none; padding: 16px 18px; font-family: var(--font-head);
  font-weight: 700; font-size: 15.5px; color: var(--ink); display: flex; align-items: center; gap: 10px;
}
.adv > summary::-webkit-details-marker { display: none; }
.adv > summary::before {
  content: "+"; color: var(--primary); font-weight: 700; font-size: 20px; line-height: 1;
}
.adv[open] > summary::before { content: "\2013"; }
.adv .inner { padding: 4px 18px 20px; display: grid; gap: 18px; }
.fallback-note {
  color: var(--ink); font-size: 14.5px; margin-bottom: 14px; line-height: 1.55;
  background: var(--caution-soft); border-left: 4px solid var(--caution); padding: 12px 14px; border-radius: 10px;
}

/* ---------- dedicated result screen: view takeover ----------
   js/main.js enterResultView() only toggles body.cb-result-open; every rule that acts on
   that class used to live in css/style.css, which this arm never loads, so a finished scan
   rendered far below an untouched marketing page and the visitor was scrolled back to the
   hero. Ported from arm A and retuned for the warm palette: the marketing chrome recedes
   and the verdict becomes the page. */
body:not(.cb-result-open) #report { display: none !important; }
body.cb-result-open #report { display: block !important; margin-top: 0; }
body.cb-result-open header,
body.cb-result-open .hero,
body.cb-result-open #scan-form,
body.cb-result-open .analyzer .ad-slot,
body.cb-result-open main > section.block,
body.cb-result-open .cb-ph,
body.cb-result-open .cb-ph-badge { display: none !important; }
/* The footer used to be hidden here too. With the header hidden as well, that left the highest-intent
   screen in the funnel with no wordmark, no home link, and no route to Pricing, Terms or Privacy,
   which got materially worse once this rebuild consolidated all global navigation into one header.
   The footer sits below the whole report, so it competes with nothing, and the result bar's wordmark
   (index.html .result-brand) carries the home link at the top. */
/* The analyzer's marketing padding goes with them, so the result bar is the first thing
   under the top of the page instead of floating in leftover whitespace. */
body.cb-result-open .analyzer { padding: 0 0 72px; border-bottom: none; }
/* Warm counterpart to arm A's sticky verdict bar: "Check another listing" and the wordmark stay
   reachable through a long report, on a translucent ivory ground. The share cluster left this bar
   on 2026-08-26 and now sits under the verdict instead. */
body.cb-result-open .result-bar {
  position: sticky; top: 0; z-index: 30;
  padding: 14px 0; margin-bottom: 10px;
  background: color-mix(in srgb, var(--bg) 90%, transparent);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
}

/* ---------- report ---------- */
#report { display: none; margin-top: 28px; }
.report-head {
  display: grid; gap: 26px; grid-template-columns: 1fr;
  border: 1px solid var(--border); background: var(--surface); box-shadow: var(--shadow-md);
  border-radius: var(--r-panel); padding: 30px;
}
@media (min-width: 720px) { .report-head { grid-template-columns: auto 1fr; align-items: center; } }
.score-block { text-align: left; }
.score-num {
  font-family: var(--font-num); font-variant-numeric: tabular-nums; font-weight: 800;
  font-size: clamp(72px, 12vw, 116px); line-height: .92; letter-spacing: -0.04em; color: var(--ink);
}
.score-den { font-size: 0.34em; color: var(--ink-3); font-weight: 600; }
.verdict {
  display: inline-flex; align-items: center; gap: 9px; margin-top: 10px;
  font-family: var(--font-head); font-size: 15px; font-weight: 700; letter-spacing: 0;
  padding: 9px 16px; border-radius: var(--r-pill); border: 1.5px solid currentColor;
}
.verdict svg { flex: none; }
.b-low { color: var(--safe-deep); background: var(--safe-soft); border-color: transparent; }
.b-caution { color: var(--caution); background: var(--caution-soft); border-color: transparent; }
.b-high { color: var(--high); background: var(--high-soft); border-color: transparent; }
.b-scam { color: var(--critical-deep); background: var(--critical-soft); border-color: transparent; }
.meter { margin-top: 6px; }
.meter-track {
  position: relative; height: 14px; display: flex; gap: 3px; overflow: visible; background: transparent;
}
.meter-seg { height: 100%; opacity: var(--seg-off); border-radius: var(--r-pill); }
.meter-seg.on { opacity: 1; }
.seg-scam { width: 40%; background: var(--critical); }
.seg-high { width: 20%; background: var(--high); }
.seg-caution { width: 20%; background: var(--caution); }
.seg-low { width: 20%; background: var(--safe); }
.meter-pin {
  position: absolute; top: -11px; width: 3px; height: 34px; background: var(--ink);
  border-radius: var(--r-pill); transform: translateX(-1px); transition: left 400ms ease-out;
}
.meter-labels { display: flex; justify-content: space-between; font-size: 12px; font-weight: 600; color: var(--ink-3); margin-top: 12px; }
.report-meta { font-size: 14px; color: var(--ink-3); margin-top: 16px; }
.flags { margin-top: 22px; display: grid; gap: 14px; }
.flag {
  border: 1px solid var(--border); background: var(--surface); box-shadow: var(--shadow-sm);
  padding: 18px 20px 18px 22px; border-radius: var(--r-card); position: relative; overflow: hidden;
}
.flag::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 5px; background: var(--border-strong); }
.flag h4 { font-size: 17px; font-weight: 700; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.flag .sev {
  font-family: var(--font-body); font-size: 12px; font-weight: 700; letter-spacing: .02em;
  padding: 3px 10px; border-radius: var(--r-pill);
}
.flag p { color: var(--ink-2); font-size: 15px; margin-top: 8px; line-height: 1.55; }
.f-critical::before { background: var(--critical); }
.f-critical .sev { color: var(--critical-deep); background: var(--critical-soft); }
.f-major::before { background: var(--high); }
.f-major .sev { color: var(--high-deep); background: var(--high-soft); }
.f-moderate::before { background: var(--caution); }
.f-moderate .sev { color: var(--caution-deep); background: var(--caution-soft); }
.f-minor::before { background: var(--rail-muted); }
.f-minor .sev { color: var(--ink-2); background: var(--surface-soft); }
.f-info::before { background: var(--primary); }
.f-info .sev { color: var(--primary-strong); background: var(--primary-soft); }
.flag-quote {
  margin: 10px 0 0; padding: 10px 13px; font-size: 14px;
  color: var(--ink-2); background: var(--surface-soft); border-radius: 10px; word-break: break-word;
}
.clean {
  border: 1px solid var(--safe); background: var(--safe-soft); color: var(--safe-deep);
  padding: 18px 20px; font-size: 15px; font-weight: 600; border-radius: var(--r-card);
}

/* ---------- deal score ---------- */
.deal-card { border: 1px solid var(--border); border-radius: var(--r-card); background: var(--surface-soft); padding: 22px; margin-top: 24px; }
.deal-hold { border-color: var(--critical); }
.deal-head { display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap; }
.deal-title { font-family: var(--font-head); font-size: 14px; font-weight: 700; letter-spacing: .02em; color: var(--ink); }
.deal-tag {
  font-family: var(--font-body); font-size: 12px; font-weight: 600; letter-spacing: 0;
  color: var(--primary-strong); background: var(--primary-soft); padding: 4px 11px; border-radius: var(--r-pill);
}
.deal-score-row { display: flex; align-items: baseline; gap: 12px; margin-top: 14px; flex-wrap: wrap; }
.deal-score-num { font-family: var(--font-num); font-size: 30px; font-weight: 800; color: var(--ink); }
.deal-band {
  font-family: var(--font-head); font-size: 13px; font-weight: 700; letter-spacing: 0;
  padding: 5px 12px; border-radius: var(--r-pill); border: 1.5px solid currentColor;
}
.db-great, .db-reasonable { color: var(--safe-deep); }
.db-good { color: var(--primary-strong); }
.db-typical, .db-wear { color: var(--caution); }
.db-above, .db-highmiles { color: var(--high); }
.db-over, .db-concern { color: var(--critical-deep); }

/* Deal temperature gauge (js/main.js dealGauge). Missing entirely from this arm until now, so
   the track, the five zone segments and the needle all measured zero height and the gauge was
   invisible. Built as the twin of the scam meter above so the two scores read as one instrument,
   drawn in the warm palette: soft pill segments, the score's own zone lit, and a needle at the
   exact score tinted by its band (.db-* sets currentColor). */
.deal-gauge { margin-top: 18px; }
.deal-meter-track { position: relative; height: 14px; background: transparent; overflow: visible; }
.deal-meter-fill { position: absolute; inset: 0; display: flex; gap: 3px; overflow: visible; }
.deal-meter-seg { height: 100%; opacity: var(--seg-off); border-radius: var(--r-pill); }
.deal-meter-seg.on { opacity: 1; }
.dg-over { background: var(--critical); }
.dg-above { background: var(--high); }
.dg-typical { background: var(--caution); }
.dg-good { background: color-mix(in srgb, var(--safe) 62%, var(--caution)); }  /* yellow-green: keeps the ramp monotonic red to green */
.dg-great { background: var(--safe); }
.deal-meter-pin {
  position: absolute; top: -11px; width: 3px; height: 34px; background: currentColor;
  border-radius: var(--r-pill); transform: translateX(-1px); transition: left 400ms ease-out;
}
@media (prefers-reduced-motion: reduce) { .deal-meter-pin { transition: none; } }
/* Direction legend, shared by the scam meter and the deal gauge. With no layout rule its two
   spans collapsed into one run-together string ("Deal scaleHigher = better deal"). */
.scale-dir {
  display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
  font-size: 12px; font-weight: 600; color: var(--ink-3); margin-bottom: 9px;
}
.scale-dir .sd-arrow { color: var(--ink-2); }
.deal-basis { color: var(--ink-2); font-size: 14.5px; margin-top: 10px; }
.deal-list { margin-top: 16px; }
.deal-list h4 { font-family: var(--font-head); font-size: 13px; font-weight: 700; color: var(--ink); margin-bottom: 8px; }
.deal-list ul { list-style: none; display: grid; gap: 6px; }
.deal-list li { color: var(--ink-2); font-size: 14.5px; padding-left: 16px; position: relative; }
.deal-list li::before { content: ""; position: absolute; left: 0; top: 9px; width: 7px; height: 7px; border-radius: 50%; background: var(--primary); opacity: .5; }
.deal-note { font-size: 14px; color: var(--high-deep); margin-top: 14px; border-left: 3px solid var(--high); padding-left: 12px; }
.deal-note-info { color: var(--ink-2); border-left-color: var(--rail-muted); }
.deal-empty { color: var(--ink-2); font-size: 14.5px; margin-top: 10px; line-height: 1.55; }
.deal-soon-cta { color: var(--ink-3); font-size: 13.5px; margin-top: 10px; }
.deal-teaser { display: flex; justify-content: space-between; align-items: center; gap: 14px; flex-wrap: wrap; margin-top: 12px; }
.deal-teaser p { color: var(--ink-2); font-size: 14.5px; margin: 0; flex: 1; min-width: 200px; }
.deal-teaser .btn { flex: none; }

/* ---------- report footer bits ---------- */
.kit { margin-top: 28px; }
.kit h3 { font-size: 19px; font-weight: 800; margin-bottom: 14px; }
.kit ul { list-style: none; display: grid; gap: 10px; }
.kit li {
  border: 1px solid var(--border); background: var(--surface); box-shadow: var(--shadow-sm);
  padding: 15px 17px; border-radius: var(--r-card); font-size: 15px; color: var(--ink-2); line-height: 1.55;
}
.kit li b { color: var(--ink); }
.kit a { color: var(--accent-deep); text-decoration: underline; text-underline-offset: 3px; }
.disclaimer { color: var(--ink-3); font-size: 13.5px; margin-top: 22px; line-height: 1.55; }

/* ---------- how it works ---------- */
.how-steps { display: grid; gap: 18px; grid-template-columns: 1fr; }
@media (min-width: 760px) { .how-steps { grid-template-columns: repeat(3, 1fr); } }
.how-step { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-card); padding: 26px 24px; box-shadow: var(--shadow-sm); }
.how-ico {
  width: 52px; height: 52px; border-radius: 14px; display: flex; align-items: center; justify-content: center;
  background: var(--primary-soft); color: var(--primary-strong); margin-bottom: 16px;
}
.how-ico.peach { background: var(--accent-soft); color: var(--accent-deep); }
.how-ico svg { width: 26px; height: 26px; }
.how-step h3 { font-size: 18.5px; font-weight: 700; margin-bottom: 7px; }
.how-step p { color: var(--ink-2); font-size: 15px; line-height: 1.55; }

/* checks explainer list (kept from product substance, warm skin) */
.checklist { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-panel); box-shadow: var(--shadow-sm); padding: 6px 8px; margin-top: 26px; }
.checklist-row { display: grid; grid-template-columns: 62px 1fr; gap: 18px; align-items: start; padding: 22px; border-bottom: 1px solid var(--border); }
.checklist-row:last-child { border-bottom: none; }
/* These are counts of checks, not step numbers. Rendered as bare zero-padded 04 / 11 / 07 they read
   as section numbering, which is the standard shape for that, and the only clue otherwise was that
   they were out of sequence. The numeral still anchors the row; the unit says what it counts. */
.checklist-count { font-family: var(--font-num); font-weight: 800; font-size: 26px; color: var(--primary); line-height: 1.1; }
.checklist-unit {
  display: block; font-family: var(--font-body); font-size: 12px; font-weight: 600;
  letter-spacing: 0; color: var(--ink-3); margin-top: 2px;
}
/* The one H2 on how-it-works.html that carried an inline font-size, which made it smaller than its
   sibling H2s. Same ramp as its peers now; only the top gap is bespoke. */
.h2-spaced { margin-top: 56px; }
.checklist-row h3 { font-size: 18px; font-weight: 700; margin-bottom: 6px; }
.checklist-row p { color: var(--ink-2); font-size: 15px; line-height: 1.55; }

/* ---------- toolkit ---------- */
.locked { background: var(--surface); }
.locked h3 { font-size: 20px; font-weight: 800; margin-bottom: 14px; display: flex; align-items: center; gap: 8px; }
.locked h3 svg { color: var(--primary); }
.locked-list { list-style: none; display: grid; gap: 10px; margin-bottom: 18px; }
.locked-list li { color: var(--ink-2); font-size: 15px; padding-left: 26px; position: relative; line-height: 1.5; }
.locked-list li b { color: var(--ink); }
.locked-list li::before {
  content: ""; position: absolute; left: 0; top: 3px; width: 18px; height: 18px; border-radius: 50%;
  background: var(--safe-soft) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none'%3E%3Cpath d='m5 13 4 4L19 7' stroke='%231f9d63' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/12px no-repeat;
}
.tk-section { margin-top: 40px; }
.tk-section:first-child { margin-top: 0; }
.tk-title { font-size: 20px; font-weight: 800; margin-bottom: 4px; }

.journey-stage { border: 1px solid var(--border); border-radius: var(--r-card); background: var(--surface); margin-bottom: 12px; overflow: hidden; box-shadow: var(--shadow-sm); }
.journey-stage[open] { border-color: var(--primary); }
.journey-stage summary { display: flex; align-items: center; gap: 14px; padding: 16px 18px; cursor: pointer; list-style: none; font-family: var(--font-head); font-weight: 700; font-size: 17px; }
.journey-stage summary::-webkit-details-marker { display: none; }
.journey-stage summary::after { content: "+"; margin-left: auto; color: var(--primary); font-weight: 700; font-size: 20px; }
.journey-stage[open] summary::after { content: "\2013"; }
.js-num { flex: none; width: 32px; height: 32px; border-radius: 50%; background: var(--primary); color: var(--primary-ink); display: flex; align-items: center; justify-content: center; font-family: var(--font-num); font-weight: 700; font-size: 15px; }
.journey-inner { padding: 4px 18px 22px 64px; }
.journey-blurb { color: var(--ink-2); font-size: 15px; line-height: 1.6; margin-bottom: 18px; }
.journey-steps { list-style: none; display: grid; gap: 16px; }
.journey-steps li { position: relative; padding-left: 22px; }
.journey-steps li::before { content: ""; position: absolute; left: 0; top: 6px; width: 10px; height: 10px; border-radius: 50%; border: 2px solid var(--primary); }
.journey-steps b { display: block; font-size: 15px; margin-bottom: 3px; color: var(--ink); }
.journey-steps p { color: var(--ink-2); font-size: 14.5px; line-height: 1.55; }
.journey-steps a { color: var(--accent-deep); font-size: 14px; text-decoration: none; display: inline-block; margin-top: 4px; }
.journey-steps a:hover { text-decoration: underline; }
.journey-msg-head { font-family: var(--font-head); font-size: 13.5px; font-weight: 700; color: var(--ink); margin: 24px 0 12px; }
.msg-card { border: 1px solid var(--border); background: var(--surface-soft); border-radius: var(--r-card); padding: 16px; margin-bottom: 12px; }
.msg-card b { display: block; font-size: 15px; margin-bottom: 6px; color: var(--ink); }
.msg-why { color: var(--ink-3); font-size: 13.5px; font-style: italic; line-height: 1.5; margin-bottom: 10px; }
.msg-body { color: var(--ink); font-size: 14.5px; line-height: 1.6; background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 12px; margin-bottom: 10px; white-space: pre-line; }
.msg-copy { min-height: 44px; padding: 0 16px; font-size: 14px; }

/* Three labelled clusters instead of one eleven-row wall (js/main.js renderGlossary). The hairline
   between rows stays: on an accordion whose summary has no other boundary it is what separates one
   tap target from the next, and it is --border, the decorative weight, which is correct here. */
.gloss-group + .gloss-group { margin-top: 26px; }
.gloss-group-h {
  font-family: var(--font-head); font-size: 12px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-3); margin: 0 0 2px; padding: 0 4px 8px;
}
.gloss-item { border-bottom: 1px solid var(--border); padding: 2px 0; }
.gloss-group .gloss-item:last-child { border-bottom: none; }
.gloss-item:last-child { border-bottom: none; }
.gloss-item summary { cursor: pointer; list-style: none; padding: 14px 4px; font-family: var(--font-head); font-weight: 700; font-size: 15.5px; display: flex; align-items: center; justify-content: space-between; gap: 14px; }
.gloss-item summary::-webkit-details-marker { display: none; }
.gloss-item summary::after { content: "+"; color: var(--primary); flex: none; }
/* U+2212 MINUS SIGN, the correct partner for the "+" above. It was an en dash, which is a
   punctuation mark, not an operator, and en dashes are out across this codebase. */
.gloss-item[open] summary::after { content: "\2212"; }
.gloss-item p { color: var(--ink-2); font-size: 14.5px; line-height: 1.6; padding: 0 4px 14px; }

.hist-item { display: flex; align-items: center; gap: 14px; border: 1px solid var(--border); border-radius: var(--r-card); background: var(--surface); padding: 13px 15px; margin-bottom: 10px; flex-wrap: wrap; box-shadow: var(--shadow-sm); }
.hist-score { font-family: var(--font-num); font-weight: 800; font-size: 22px; min-width: 3ch; }
.hist-score.b-low { color: var(--safe-deep); background: none; } .hist-score.b-caution { color: var(--caution); background: none; }
.hist-score.b-high { color: var(--high); background: none; } .hist-score.b-scam { color: var(--critical-deep); background: none; }
.hist-meta { flex: 1; min-width: 160px; }
.hist-meta .hist-band { font-family: var(--font-body); font-weight: 700; font-size: 12px; display: block; border: none; background: none; padding: 0; }
.hist-band.b-low { color: var(--safe-deep); } .hist-band.b-caution { color: var(--caution); }
.hist-band.b-high { color: var(--high); } .hist-band.b-scam { color: var(--critical-deep); }
.hist-meta .hist-when { color: var(--ink-3); font-size: 12.5px; display: block; margin-top: 2px; overflow-wrap: anywhere; }
.hist-item .btn { min-height: 44px; padding: 0 16px; font-size: 13.5px; box-shadow: none; }
.hist-empty { color: var(--ink-3); font-size: 14px; padding: 8px 0 16px; }

/* ---------- deal-soon coming-soon section ---------- */
.dealsoon .kicker { color: var(--primary-strong); background: var(--primary-soft); }
.dealsoon-list { list-style: none; margin: 22px 0 20px; max-width: 62ch; display: grid; gap: 2px; }
.dealsoon-list li { border-top: 1px solid var(--border); padding: 16px 0 16px 30px; color: var(--ink-2); font-size: 15px; line-height: 1.5; position: relative; }
.dealsoon-list li:first-child { border-top: none; }
.dealsoon-list li::before {
  content: ""; position: absolute; left: 0; top: 18px; width: 18px; height: 18px; border-radius: 50%;
  background: var(--primary-soft) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none'%3E%3Cpath d='m5 13 4 4L19 7' stroke='%230b5a63' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/12px no-repeat;
}
.ds-k { display: block; color: var(--ink); font-family: var(--font-head); font-weight: 700; font-size: 16px; margin-bottom: 2px; }
.dealsoon-foot { color: var(--ink-3); font-size: 14.5px; }
.dealsoon-foot a { color: var(--accent-deep); text-decoration: underline; text-underline-offset: 3px; }

/* ---------- pricing ---------- */
.plans { display: grid; gap: 18px; grid-template-columns: 1fr; align-items: stretch; }
@media (min-width: 760px) { .plans { grid-template-columns: repeat(3, 1fr); } }
.plan { border: 1px solid var(--border); background: var(--surface); padding: 28px; border-radius: var(--r-card); display: flex; flex-direction: column; box-shadow: var(--shadow-sm); transition: transform 150ms ease, box-shadow 150ms ease; }
.plan:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); }
.plan.featured { border: 2px solid var(--primary); box-shadow: var(--shadow-teal); position: relative; }
.plan.active { border-color: var(--safe); }
#pricing-plans[hidden], #current-plan-panel[hidden] { display: none; }
.plan .tag { display: inline-flex; align-items: center; align-self: flex-start; margin: 0 0 10px; font-family: var(--font-body); font-size: 12px; font-weight: 700; letter-spacing: 0; padding: 5px 12px; border-radius: var(--r-pill); }
.plan .tag.rec { color: var(--primary-ink); background: var(--primary); }
.plan .tag.active { color: var(--safe-deep); background: var(--safe-soft); }
.plan h3 { font-family: var(--font-head); font-size: 15px; font-weight: 700; letter-spacing: 0; color: var(--ink-2); text-transform: none; }
.price { font-family: var(--font-num); font-size: 44px; font-weight: 800; margin: 12px 0 4px; font-variant-numeric: tabular-nums; color: var(--ink); }
.price small { font-size: 16px; color: var(--ink-3); font-weight: 500; }
.plan ul { list-style: none; margin: 18px 0 24px; flex: 1; }
.plan li { color: var(--ink-2); font-size: 15px; padding: 8px 0 8px 26px; border-bottom: 1px solid var(--border); position: relative; }
.plan li:last-child { border-bottom: none; }
.plan li::before {
  content: ""; position: absolute; left: 0; top: 12px; width: 16px; height: 16px; border-radius: 50%;
  background: var(--safe-soft) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none'%3E%3Cpath d='m5 13 4 4L19 7' stroke='%231f9d63' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/11px no-repeat;
}
.plan .btn { width: 100%; }
.plan .hint { color: var(--ink-3); font-size: 13.5px; }

/* ---------- FAQ ---------- */
#faq details { border: 1px solid var(--border); border-radius: var(--r-card); margin-bottom: 12px; background: var(--surface); box-shadow: var(--shadow-sm); overflow: hidden; }
#faq summary { cursor: pointer; padding: 18px 20px; font-family: var(--font-head); font-weight: 700; font-size: 16.5px; list-style: none; display: flex; align-items: center; justify-content: space-between; gap: 14px; }
#faq summary::-webkit-details-marker { display: none; }
#faq summary::after { content: "+"; color: var(--primary); font-weight: 700; flex: none; }
#faq details[open] summary::after { content: "\2013"; }
#faq details div { padding: 0 20px 18px; color: var(--ink-2); font-size: 15px; line-height: 1.6; }

/* ---------- footer ---------- */
footer { padding: 48px 0 64px; color: var(--ink-3); font-size: 14px; background: var(--surface-soft); border-top: 1px solid var(--border); }
footer a { color: var(--ink-2); display: inline-block; padding: 8px 0; text-decoration: none; }
footer a:hover { color: var(--primary); text-decoration: underline; }
/* 2026-08-21, A11Y: the footer's standalone link row measured 40px tall on a phone - the same
   under-44px touch target the header nav was just fixed for, and the same fix: two more pixels of
   padding per side, 24px of text + 20px = exactly 44. Scoped to the touch breakpoint so the desktop
   footer stays pixel-for-pixel what it is today, and the footer sits below the fold either way so
   nothing above it moves. Inline links inside footer prose are untouched: they are exempt under
   WCAG 2.2 SC 2.5.8's inline exception and padding them would break the paragraph's line rhythm. */
@media (max-width: 700px) {
  /* border-box is global (line 1), so min-height includes the padding: this pins the touch
     target at exactly 44px regardless of the link's line-box height, which the earlier
     padding-only math got wrong (landed 42.7px). inline-flex centres the label in the taller box. */
  footer a { min-height: 44px; display: inline-flex; align-items: center; padding: 8px 0; }
}

/* ---------- closing page CTA (2026-08-26) ----------
   how-it-works, buying-help and deal-score absorbed content moved off the homepage and shipped with
   no route back to the scanner: searching each page body for a link to the checker returned 0, 0 and
   one buried inline text link. The intended path is home -> tutorial -> scan your own, and the
   tutorial terminated. Same shape as pricing.html's existing closing CTA. */
.page-cta {
  text-align: center; padding: 34px 26px; margin-top: 8px;
  background: var(--peach); border: 1px solid var(--peach-line); border-radius: var(--r-panel);
}
.page-cta h2 { font-size: clamp(21px, 3.4vw, 27px); line-height: 1.2; margin: 0; }
.page-cta .lead { max-width: 52ch; margin: 12px auto 20px; color: var(--ink-2); font-size: 16px; line-height: 1.55; }
.page-cta .btn { margin: 0 auto; }
/* An inline CTA that sits mid-page, at the moment the reader first understands the product, rather
   than only at the very bottom. Quieter than the closing block so it does not read as the end. */
.inline-cta { display: flex; justify-content: center; margin: 30px 0 6px; }

/* ---------- footer navigation (2026-08-26) ----------
   The footer used to be a single <p> in which the legal disclaimer ran straight into fifteen links
   separated by middle dots, so the sentence appeared to continue into the navigation and every
   destination carried identical weight: "Privacy" read exactly as loud as "How it works". At 375px
   that block was 527px of a 1573px page, a third of the homepage, and once six sections moved off
   the homepage it became the only navigation visible without opening a menu. Grouped into four
   titled columns, no separators, and one step down in size so it stops competing with the hero. */
.foot-nav { display: grid; gap: 22px 28px; grid-template-columns: repeat(4, minmax(0, 1fr)); margin: 22px 0 24px; }
@media (max-width: 720px) { .foot-nav { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px 20px; } }
.foot-col h2 {
  font-family: var(--font-head); font-size: 12px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-3); margin: 0 0 4px;
}
.foot-col ul { list-style: none; margin: 0; padding: 0; }
.foot-col li { margin: 0; }
.foot-col a, .foot-col .linklike {
  display: inline-flex; align-items: center; min-height: 34px; padding: 3px 0;
  font-size: 14px; color: var(--ink-2); text-decoration: none;
}
.foot-col a:hover, .foot-col a:focus-visible, .foot-col .linklike:hover { color: var(--primary); text-decoration: underline; }
.foot-legal { font-size: 13.5px; line-height: 1.6; color: var(--ink-3); }
.foot-legal + .foot-legal { margin-top: 10px; }
/* Privacy and Terms sit inside this sentence, so they must render as prose links, not as the
   standalone 44px block targets `footer a` makes every other footer link. The generic rule above
   sets display:inline-block + 8px of vertical padding (and inline-flex + min-height:44px under the
   touch breakpoint), which on a wrapped sentence pushes the line box apart and breaks the paragraph
   rhythm. These two are exempt from WCAG 2.2 SC 2.5.8 under the inline exception, the same exemption
   the touch-target block below already claims for links in footer prose. Underlined because an
   inline link with no box needs the underline to be identifiable as a link at all. */
.foot-legal a {
  display: inline; min-height: 0; padding: 0;
  color: var(--ink-2); text-decoration: underline; text-underline-offset: 3px;
}
.foot-legal a:hover, .foot-legal a:focus-visible { color: var(--primary); }

/* Grouping the footer fixed its flatness but cost height: on a 375px phone the four columns took the
   homepage from 1573px to 1884px and the footer itself from 33.5% of the page to 43.2%, which is the
   opposite of "do not make it a super long scroll page". The structure stays; the rhythm tightens.
   Links go 44px to 40px, which is still far above the 24px WCAG 2.5.8 minimum and spans the full
   column width horizontally, and the trademark paragraph drops a step because it is fine print, not
   reading matter. Recovers about 110px without collapsing anything behind a tap. */
@media (max-width: 700px) {
  footer { padding: 32px 0 40px; }
  .foot-nav { margin: 16px 0 18px; }
  .foot-col a, .foot-col .linklike { min-height: 40px; padding: 4px 0; }
  .foot-legal + .foot-legal { font-size: 12.5px; line-height: 1.55; }
}

/* ---------- ads (hidden until a client is configured; never for subscribers) ---------- */
.ad-slot { display: none; }
.ad-slot.on { display: block; margin-top: 32px; border: 1px solid var(--border); border-radius: var(--r-card); padding: 16px; min-height: 110px; background: var(--surface); }
.ad-tag { font-family: var(--font-body); font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); }
.ad-slot .ad-tag { display: block; margin-bottom: 8px; }

/* ---------- paywall modal ---------- */
/* Safe-centered and scrollable. At 375x812 the buy-credits modal is taller than the viewport,
   and a centered flex item that overflows gets clipped at BOTH ends: the close button sat at
   top -199 (arm A) / -151 (arm B), offscreen and unreachable, with nothing to scroll because
   the backdrop was overflow-y: visible. A phone has no Escape key, so the modal was a dead end
   on the exact checkout path. flex-start plus margin:auto on the card keeps it centered when it
   fits and pinned to the top when it does not; overflow-y:auto lets the rest be reached. */
.modal-backdrop { position: fixed; inset: 0; background: var(--scrim); z-index: 100; display: none; align-items: flex-start; justify-content: center; padding: 20px; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; backdrop-filter: blur(3px); }
.modal-backdrop.open { display: flex; }
.modal { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-panel); max-width: 520px; width: 100%; margin: auto; padding: 34px; position: relative; box-shadow: var(--modal-shadow); }
.modal h3 { font-size: 24px; font-weight: 800; margin-bottom: 8px; padding-right: 46px; }  /* clears the close button, which the title used to wrap under at 375 */
.modal p { color: var(--ink-2); margin-bottom: 20px; }
.modal .close { position: absolute; top: 12px; right: 12px; background: var(--surface-soft); border: none; color: var(--ink-2); font-size: 22px; cursor: pointer; width: 44px; height: 44px; border-radius: 50%; }
.modal .close:hover { color: var(--ink); background: var(--border); }
.modal .actions { margin-top: 0; }
.restore { margin-top: 22px; border-top: 1px solid var(--border); padding-top: 18px; }
.restore-label { display: block; color: var(--ink-2); font-size: 14.5px; margin-bottom: 12px; }
.restore-row { display: flex; gap: 10px; flex-wrap: wrap; }
.restore-row input { flex: 1; min-width: 200px; background: var(--surface); border: 1.5px solid var(--border-strong); border-radius: var(--r-input); color: var(--ink); font-family: var(--font-body); font-size: 16px; padding: 13px 14px; min-height: 50px; }
.restore-row input:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 4px var(--primary-soft); }
.restore-msg { font-size: 13.5px; color: var(--ink-2); margin-top: 10px; min-height: 1.2em; }


/* ==========================================================================
   ARM-A RETIREMENT PORT (2026-08-21)
   Everything below moved here from css/style.css and index.html's inline <style>
   when the warm-vs-dark A/B was killed and warm became the only homepage.
   RETUNED, not pasted: every rule is written against warm's own tokens
   (--primary / --accent / --safe / --caution / --high / --critical / --ink-*),
   never the dark era's --accent-text / --accent-ink / --deal-* / --shadow-soft.
   ========================================================================== */

/* ---------- M17: the missing deal band -----------------------------------
   deal-engine.js emits band.key "toocheap" (ratio <= 0.62) and main.js builds
   "deal-meter-pin db-toocheap". Every other db-* band had a warm rule; this one
   did not, so the needle drew UNCOLOURED on the single most scam-relevant band.
   A price far under market is a warning, not a bargain, so it reads as the
   caution hue rather than the "great deal" green. */
.db-toocheap { color: var(--caution); }

/* ---------- M16: share/copy confirmation toast ---------------------------
   main.js showToast() appends a bare div.cb-toast to document.body. Unstyled it
   landed as loose text under the footer for 2.8s. */
.cb-toast {
  position: fixed; left: 50%; bottom: 28px; transform: translate(-50%, 16px);
  z-index: 300; max-width: min(92vw, 420px);
  background: var(--toast-bg); border: 1px solid var(--toast-bg); border-radius: var(--r-card);
  color: var(--toast-ink); font-family: var(--font-body); font-size: 14.5px; line-height: 1.45;
  padding: 13px 18px; box-shadow: var(--shadow-md);
  opacity: 0; pointer-events: none; transition: opacity 180ms ease, transform 180ms ease;
}
.cb-toast.show { opacity: 1; transform: translate(-50%, 0); }
@media (prefers-reduced-motion: reduce) { .cb-toast { transition: opacity 180ms ease; } }

/* ---------- M15: post-result extension nudge ----------------------------
   THE LIVE BUG THIS FIXES: main.js maybeShowExtPromo() fires 1.2s after a result
   renders for any desktop Chromium visitor and appends a role="dialog". Its CSS
   only ever existed in the retired arm's inline style block, so on warm the
   dialog was appended UNPOSITIONED at the bottom of body, invisible, with no
   backdrop, and it moved keyboard focus into itself and trapped Tab there.
   [DEV] The durable fix is to move this into main.js injectOnce() next to
   cb-upsell-css so the promo can never again outrun its own styling on a new
   surface; this file is the correct home only while main.js is owned elsewhere. */
.cb-extpromo {
  position: fixed; z-index: 320; left: 50%; bottom: 20px; transform: translate(-50%, 20px);
  width: min(94vw, 400px); background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--r-card);
  box-shadow: var(--shadow-md); padding: 18px 16px 16px;
  opacity: 0; pointer-events: none; transition: opacity 200ms ease, transform 200ms ease;
}
.cb-extpromo.show { opacity: 1; transform: translate(-50%, 0); pointer-events: auto; }
@media (min-width: 760px) {
  .cb-extpromo { left: auto; right: 24px; transform: translate(0, 20px); }
  .cb-extpromo.show { transform: translate(0, 0); }
}
@media (prefers-reduced-motion: reduce) { .cb-extpromo { transition: opacity 200ms ease; } }
.cb-extpromo-top { display: flex; align-items: flex-start; gap: 12px; }
.cb-extpromo-ic {
  flex: none; width: 34px; height: 34px; display: grid; place-items: center;
  border: 1px solid var(--border); border-radius: 10px;
  background: var(--primary-soft); color: var(--primary);
}
.cb-extpromo-h {
  margin: 0; font-family: var(--font-head); font-weight: 700; font-size: 15.5px;
  line-height: 1.3; letter-spacing: -0.01em; color: var(--ink); text-transform: none;
}
.cb-extpromo-p { margin: 6px 0 0; font-family: var(--font-body); font-size: 13.5px; line-height: 1.5; color: var(--ink-2); }
.cb-extpromo-x {
  position: absolute; top: 4px; right: 4px; width: 44px; height: 44px;
  display: grid; place-items: center; background: none; border: 0; color: var(--ink-3); cursor: pointer;
}
.cb-extpromo-x:hover, .cb-extpromo-x:focus-visible { color: var(--ink); }
.cb-extpromo-actions { display: flex; align-items: center; gap: 8px; margin-top: 14px; }
.cb-extpromo .btn { min-height: 44px; padding: 0 18px; font-size: 14px; }
.cb-extpromo-no {
  background: none; border: 0; cursor: pointer; font-family: var(--font-body);
  font-size: 13px; font-weight: 600; color: var(--ink-3); min-height: 44px; padding: 0 12px;
}
.cb-extpromo-no:hover, .cb-extpromo-no:focus-visible { color: var(--ink); }

/* ---------- M13: NHTSA recall check (main.js renderRecalls) --------------
   Painted into #r-recalls, which already lived inside warm's "Safety recalls"
   accordion, so every warm result was rendering raw unstyled text and a bare
   VIN input. Recalls are a genuine safety axis, so severity here DOES use the
   risk ladder (safe / high / critical), unlike the buy-quality card below. */
.recalls-card { padding: 4px 0 2px; }
.recalls-body { margin-top: 2px; }
.recalls-head { display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap; }
.recalls-title { font-family: var(--font-head); font-size: 13px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3); }
.recalls-tag {
  font-family: var(--font-body); font-size: 11.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--primary); background: var(--primary-soft); border: 1px solid transparent;
  padding: 4px 10px; border-radius: var(--r-pill);
}
.recalls-intro { color: var(--ink-2); font-size: 14.5px; line-height: 1.6; margin-top: 12px; }
.recalls-loading { color: var(--ink-3); font-size: 14.5px; margin-top: 12px; }
.recall-clean {
  border: 1px solid var(--safe); background: var(--safe-soft); color: var(--safe-deep);
  padding: 15px 18px; margin-top: 14px; font-size: 14.5px; font-weight: 600; border-radius: var(--r-card);
}
.recall-item {
  border: 1px solid var(--high); background: var(--high-soft);
  padding: 16px 18px; border-radius: var(--r-card); margin-top: 14px;
}
.recall-comp { font-family: var(--font-head); font-size: 16px; font-weight: 700; color: var(--ink); }
.recall-danger {
  display: inline-block; font-family: var(--font-body); font-size: 12px; font-weight: 700;
  letter-spacing: .05em; text-transform: uppercase; color: var(--critical-deep);
  background: var(--critical-soft); border: 1px solid var(--critical);
  border-radius: var(--r-pill); padding: 5px 11px; margin-top: 10px;
}
.recall-line { color: var(--ink-2); font-size: 14.5px; line-height: 1.6; margin-top: 8px; }
.recall-line b { color: var(--ink); }
.recall-meta { font-size: 12.5px; color: var(--ink-3); margin-top: 10px; }
.recall-ask { border-top: 1px solid var(--border); margin-top: 14px; padding-top: 12px; }
.recall-ask-q { color: var(--ink); font-size: 14.5px; font-weight: 700; margin-bottom: 10px; }
.recall-copy { min-height: 44px; padding: 0 16px; }
.recall-verify { color: var(--ink-3); font-size: 13px; line-height: 1.55; margin-top: 16px; }
.recall-verify a, .recall-link { color: var(--accent-deep); text-decoration: underline; text-underline-offset: 3px; }
.recall-verify a:hover, .recall-link:hover { color: var(--primary); }
.recall-link { display: inline-block; margin-top: 10px; font-size: 14.5px; font-weight: 600; }
.recall-vin-form { margin-top: 14px; }
.recall-vin-row { display: flex; gap: 10px; flex-wrap: wrap; }
.recall-vin-input {
  flex: 1 1 220px; min-height: 50px; padding: 0 14px; background: var(--surface);
  border: 1.5px solid var(--border-strong); border-radius: var(--r-input);
  color: var(--ink); font-family: var(--font-body); font-size: 16px; letter-spacing: .04em; text-transform: uppercase;
}
.recall-vin-input:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 4px var(--primary-soft); }
.recall-vin-row .btn { flex: none; min-height: 50px; }
.recall-vin-msg { color: var(--high); font-size: 13.5px; font-weight: 600; margin-top: 10px; }
.recall-again { margin-top: 12px; }

/* ---------- M14: buy-quality card (buy-quality.js, main.js paintBqBody) ---
   A SEPARATE axis from scam risk, so it deliberately does NOT borrow the risk
   colour language (the Risk-Colour Lock in DESIGN.md): severity is carried by
   the MAJOR/MODERATE/MINOR tag and border weight, with teal as the one
   indicator hue, never a rival green/amber/red. */
.bq-card { padding: 4px 0 2px; }
.bq-head { display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap; }
.bq-title { font-family: var(--font-head); font-size: 13px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3); }
.bq-tag {
  font-family: var(--font-body); font-size: 11.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--primary); background: var(--primary-soft); padding: 4px 10px; border-radius: var(--r-pill);
}
.bq-body { margin-top: 14px; }
.bq-chip {
  display: inline-flex; align-items: center; gap: 9px;
  font-family: var(--font-head); font-size: 14px; font-weight: 700;
  color: var(--ink); background: var(--surface-soft);
  border: 1px solid var(--border-strong); border-radius: var(--r-pill); padding: 9px 16px;
}
.bq-chip.bq-high { border-color: var(--ink-3); }
.bq-chip.bq-high::before { content: ""; flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--primary); }
.bq-chip.bq-moderate { border-color: var(--border-strong); }
.bq-chip.bq-low, .bq-chip.bq-none { color: var(--ink-2); font-weight: 600; }
.bq-intro { color: var(--ink-3); font-size: 13.5px; line-height: 1.6; margin-top: 12px; max-width: 62ch; }
.bq-clean { color: var(--ink-2); font-size: 14.5px; line-height: 1.6; margin-top: 12px; }
.bq-flags { margin-top: 16px; display: grid; gap: 12px; }
.bq-flag { border: 1px solid var(--border); background: var(--surface-soft); padding: 14px 16px; border-radius: var(--r-card); }
.bq-flag.bq-f-major { border-color: var(--ink-3); }
.bq-flag-h { font-family: var(--font-head); font-size: 15px; font-weight: 700; color: var(--ink); line-height: 1.35; }
.bq-sev {
  display: inline-block; font-family: var(--font-body); font-size: 11.5px; font-weight: 700; letter-spacing: .05em;
  border: 1px solid var(--border-strong); border-radius: var(--r-pill); padding: 3px 9px; color: var(--ink-3);
}
.bq-f-major .bq-sev { color: var(--ink); border-color: var(--ink-3); }
.bq-f-moderate .bq-sev { color: var(--ink-2); }
.bq-flag-p { color: var(--ink-2); font-size: 14.5px; line-height: 1.6; margin-top: 8px; }
.bq-cta { color: var(--ink-2); font-size: 14.5px; line-height: 1.6; margin-top: 16px; }
.bq-complaints { border-top: 1px solid var(--border); margin-top: 16px; padding-top: 14px; }
.bq-complaints-h { font-family: var(--font-head); font-size: 12.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3); }
.bq-comp-list { margin: 10px 0 0; padding: 0; list-style: none; display: flex; flex-wrap: wrap; gap: 8px; }
.bq-comp-list li {
  font-size: 13.5px; color: var(--ink); border: 1px solid var(--border);
  background: var(--surface); border-radius: var(--r-pill); padding: 5px 12px;
}
.bq-comp-sev { color: var(--ink); font-size: 14.5px; margin-top: 12px; }
.bq-comp-note { color: var(--ink-3); font-size: 12.5px; line-height: 1.5; margin-top: 10px; }

/* ---------- S5: the lead "see a sample" CTA -----------------------------
   The markup already carried .sample-cta-lead with no rule, so the demo button
   rendered as a plain ghost. It carries hesitant visitors who will not paste
   their own link, so it gets weight without outranking the filled primary. */
/* .btn.ghost is two classes; a bare .sample-cta-lead is one, so the rule below never applied and the
   demo button painted as a plain ghost regardless of source order. Matched at .btn.sample-cta-lead so
   it actually outranks .btn.ghost. It is still quieter than the filled "Check this listing" primary:
   soft teal fill, teal border, teal ink, against the primary's solid teal with white ink. */
.btn.sample-cta-lead { color: var(--primary); border-color: var(--primary); background: var(--primary-soft); }
.btn.sample-cta-lead:hover, .btn.sample-cta-lead:focus-visible { color: var(--primary-ink); background: var(--primary); border-color: var(--primary); }
.sample-cta-lead svg { flex: none; }
/* S10: zero-friction reassurance directly under the check button. */
.scan-reassure { margin: 12px 0 0; font-size: 13.5px; color: var(--ink-2); }

/* ---------- S4: marketplace coverage row --------------------------------- */
.trust-strip .wrap { padding-top: 4px; padding-bottom: 0; }
.mkt-row {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px 14px;
  padding: 2px 0 18px; border-bottom: 1px solid var(--border);
}
.mkt-kicker, .mkt-any { font-size: 13px; color: var(--ink-3); flex: none; }
.mkt-logos { display: flex; flex-wrap: wrap; gap: 8px 10px; list-style: none; margin: 0; padding: 0; }
.mkt-logos li {
  font-size: 13px; font-weight: 600; color: var(--ink-2); white-space: nowrap;
  padding: 7px 13px; border: 1px solid var(--border); border-radius: var(--r-pill); background: var(--surface);
}

/* ---------- M7: scam-trend feed (scam-trends.js) ------------------------- */
.trends-stamp { font-size: 13.5px; color: var(--ink-3); margin: -20px 0 26px; }
.trend-grid { display: grid; gap: 18px; grid-template-columns: 1fr; }
@media (min-width: 768px) { #scam-trends-home .trend-grid { grid-template-columns: repeat(3, 1fr); } }
/* scam-trends.js builds each card as <article class="trend"> (NOT .trend-card). */
.trend {
  border: 1px solid var(--border); background: var(--surface); border-radius: var(--r-card);
  padding: 24px; box-shadow: var(--shadow-sm);
}
.trend-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
.trend-cat { font-size: 11.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--primary); background: var(--primary-soft); padding: 4px 10px; border-radius: var(--r-pill); }
.trend-sev { font-size: 11.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; }
.trend-sev.sev-high { color: var(--critical-deep); }
.trend-sev.sev-medium { color: var(--caution); }
.trend-sev.sev-low { color: var(--ink-3); }
.trend-title { font-family: var(--font-head); font-size: 19px; font-weight: 800; letter-spacing: -0.01em; line-height: 1.3; margin-bottom: 12px; color: var(--ink); }
.trend-tactic, .trend-avoid { color: var(--ink-2); font-size: 15px; line-height: 1.6; margin-top: 10px; }
.trend-tactic b, .trend-avoid b { color: var(--ink); }
.trend-avoid b { color: var(--primary); }
.trend-plat { font-size: 12.5px; color: var(--ink-3); margin-top: 14px; }
.trend-empty { color: var(--ink-3); font-size: 15px; }
.trends-more { margin-top: 26px; }
#scam-trends-all .trend-grid { max-width: 760px; }

/* ---------- M4: Deal Score explainer ------------------------------------- */
.soon-badge {
  display: inline-block; margin-bottom: 14px;
  font-family: var(--font-body); font-size: 11.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--primary-ink); background: var(--primary); padding: 6px 13px; border-radius: var(--r-pill);
}
.deal-tiles { margin-bottom: 26px; }
.deal-tile { border: 1px solid var(--border); background: var(--surface); border-radius: var(--r-card); padding: 24px; box-shadow: var(--shadow-sm); }
.deal-tile h3 { font-family: var(--font-head); font-size: 17px; font-weight: 700; letter-spacing: -0.01em; color: var(--ink); margin-bottom: 8px; }
.deal-tile p { color: var(--ink-2); font-size: 15px; line-height: 1.6; }
.dealsoon-foot { color: var(--ink-2); font-size: 15.5px; line-height: 1.6; max-width: 62ch; }
.dealsoon-foot a { color: var(--accent-deep); text-decoration: underline; text-underline-offset: 3px; }
.dealsoon-foot a:hover { color: var(--primary); }

/* ---------- M5 / M6: email capture (newsletter.js) ----------------------- */
.leadmag {
  display: grid; gap: 26px; align-items: center;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-panel); padding: 34px; box-shadow: var(--shadow-sm);
}
@media (min-width: 820px) { .leadmag { grid-template-columns: 1.2fr 1fr; } }
.leadmag h2 { margin: 0 0 10px; font-size: clamp(22px, 2.6vw, 27px); }
.leadmag-copy p { color: var(--ink-2); font-size: 15.5px; line-height: 1.65; margin: 0; }
.newsletter-form { display: flex; flex-wrap: wrap; gap: 10px; }
.leadmag-form { align-content: start; }
.newsletter-form input[type=email] {
  flex: 1 1 220px; min-height: 52px; padding: 0 15px; background: var(--surface);
  border: 1.5px solid var(--border-strong); border-radius: var(--r-input);
  color: var(--ink); font-family: var(--font-body); font-size: 16px;
}
.newsletter-form input[type=email]:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 4px var(--primary-soft); }
.newsletter-form .btn { min-height: 52px; }
.newsletter-form .nl-msg { flex-basis: 100%; margin: 4px 0 0; color: var(--ink-2); font-size: 14px; line-height: 1.5; min-height: 1.2em; }
.newsletter-form .nl-msg a { color: var(--accent-deep); text-decoration: underline; text-underline-offset: 3px; }
.lm-sr, .getapp .ga-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0, 0, 0, 0); }

/* ---------- M2: extension + iPhone cards --------------------------------- */
.getapp .ga-grid { margin-top: 22px; }
.getapp .ga-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-card);
  padding: 26px; display: flex; flex-direction: column; gap: 10px; box-shadow: var(--shadow-sm);
}
.getapp .ga-badge {
  align-self: flex-start; font-family: var(--font-body); font-size: 11.5px; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; color: var(--primary);
  background: var(--primary-soft); padding: 5px 11px; border-radius: var(--r-pill);
}
.getapp .ga-badge.alt { color: var(--accent-deep); background: var(--accent-soft); }
.getapp .ga-card h3 { font-family: var(--font-head); font-size: 19px; font-weight: 700; letter-spacing: -0.01em; color: var(--ink); margin: 0; }
.getapp .ga-card p { margin: 0; color: var(--ink-2); font-size: 15px; line-height: 1.6; }
.getapp .ga-card .btn { align-self: flex-start; margin-top: 6px; min-height: 50px; }
.getapp .ga-card .ga-note { font-size: 12.5px; color: var(--ink-3); }
.getapp .ga-notify-lead { margin: 30px 0 12px; color: var(--ink-2); font-size: 15.5px; }
.getapp .ga-notify { max-width: 520px; }

/* print walkthrough (kept functional) */
.print-only { display: none; }
@media print {
  @page { margin: 16mm 14mm; }
  body.print-kit header, body.print-kit footer, body.print-kit .hero, body.print-kit #scan,
  body.print-kit #how, body.print-kit #deal-score, body.print-kit #pricing, body.print-kit #faq,
  body.print-kit .ad-slot, body.print-kit .modal, body.print-kit .toast,
  body.print-kit #toolkit > .wrap > h2, body.print-kit #toolkit > .wrap > .lead,
  body.print-kit #tk-locked, body.print-kit .tk-section:not(.printable),
  body.print-kit #journey-print, body.print-kit .actions, body.print-kit .msg-copy { display: none !important; }
  body.print-kit, body.print-kit * { color: #000 !important; background: #fff !important; box-shadow: none !important; }
  body.print-kit .print-head { display: block; padding: 0 0 10px; margin: 0 0 16px; border-bottom: 1.5pt solid #000; }
  body.print-kit .print-mark { display: flex; align-items: center; gap: 8px; }
  body.print-kit .print-mark svg { width: 24px; height: 24px; }
  body.print-kit .print-mark b { font-family: var(--font-head); font-size: 19pt; font-weight: 800; }
  body.print-kit .print-mark b span { color: #0f6e78 !important; }
  body.print-kit .print-sub { display: block; font-size: 11pt; color: #333 !important; margin-top: 6px; }
  body.print-kit .tk-section { margin: 0 0 6px; }
  body.print-kit .tk-title { font-size: 15pt; margin: 18px 0 2px; page-break-after: avoid; }
  body.print-kit .hint { font-size: 9.5pt; color: #555 !important; margin-bottom: 8px; }
  body.print-kit details { display: block !important; border: none !important; border-radius: 0 !important; margin: 0; }
  body.print-kit summary { padding: 0 !important; }
  body.print-kit summary::after, body.print-kit summary::marker, body.print-kit summary::-webkit-details-marker { content: "" !important; display: none !important; }
  body.print-kit .journey-stage { page-break-inside: avoid; margin-bottom: 12px; border-bottom: 0.75pt solid #ccc !important; padding-bottom: 8px; }
  body.print-kit .journey-stage summary { font-size: 13pt; font-weight: 700; gap: 8px; padding: 2px 0 !important; }
  body.print-kit .js-num { border: 1pt solid #000 !important; width: 20px; height: 20px; font-size: 10pt; }
  body.print-kit .journey-inner { padding: 4px 0 6px 28px; }
  body.print-kit .journey-steps li::before { border-color: #000 !important; }
  body.print-kit .journey-steps a[href]::after { content: " (" attr(href) ")"; font-size: 9pt; color: #555 !important; }
  body.print-kit .msg-card { border: 0.75pt solid #bbb !important; page-break-inside: avoid; padding: 8px 10px; }
  body.print-kit .gloss-item { page-break-inside: avoid; border-bottom: 0.75pt solid #ccc !important; padding: 3px 0; }
  body.print-kit .gloss-item summary { font-size: 12pt; font-weight: 700; padding: 3px 0 !important; }
  body.print-kit .gloss-item p { padding: 0 0 6px !important; font-size: 10.5pt; }
}

/* ==========================================================================
   DARK-B (2026-08-21): the handful of rules that need a per-theme value rather
   than a per-theme token. Nothing here fires in light mode.
   ========================================================================== */

/* ---------- theme-swap transition suppression ----------------------------
   BL-3 REGRESSION GUARD. The canonical rule lives in css/style.css, and index-warm.html is the one
   warm page that does not load style.css. js/theme.js stamps .theme-swapping on <html> for one
   frame around every toggle precisely so nothing crossfades between two themes; with the rule
   absent, the homepage crossfaded instead, and measured mid-swap on this build the ghost button's
   label hit 1.02:1 and the theme toggle 1.51:1 - the same invisible-text bug, in a new place.
   Duplicated here (byte-identical declaration) so the fix travels with the theme rather than with
   the other stylesheet. Harmless where both sheets load: same rule, same value. */
:root.theme-swapping,
:root.theme-swapping *,
:root.theme-swapping *::before,
:root.theme-swapping *::after {
  transition: none !important;
}

/* ---------- theme toggle (homepage only) ---------------------------------
   The toggle's own styling only ever lived in css/style.css. index-warm.html does not load
   style.css, and as of DARK-B it does load js/theme.js, so without this the homepage would
   render the control as a raw <button> with BOTH icons stacked (style.css owns the
   .ic-moon{display:none} half of the swap too) and a hover colour of var(--accent-text), a
   token warm never defines.
   DELIBERATELY SCOPED to :root:not([data-design]). Every other warm page carries a static
   data-design="warm" attribute AND loads style.css, so it already has a working, already-shipped
   toggle; excluding those pages here is what keeps warm LIGHT pixel-for-pixel unchanged on all
   twenty of them. Only the homepage, which had no toggle at all until now, is styled here. */
:root:not([data-design]) .theme-switch { position: relative; display: inline-flex; margin-left: 22px; }
:root:not([data-design]) .theme-toggle {
  display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 14px;
  background: transparent; border: 1px solid var(--border-strong); border-radius: var(--r-pill);
  color: var(--ink-2); font-family: var(--font-body); font-size: 14px; font-weight: 500;
  letter-spacing: 0; cursor: pointer;
  transition: border-color 150ms ease, color 150ms ease;
}
:root:not([data-design]) .theme-toggle:hover,
:root:not([data-design]) .theme-toggle:focus-visible { border-color: var(--primary); color: var(--primary); }
:root:not([data-design]) .theme-toggle svg { flex: none; }
/* Dark shows the sun (tap for light); light shows the moon (tap for dark). */
:root:not([data-design]) .theme-toggle .ic-sun { display: block; }
:root:not([data-design]) .theme-toggle .ic-moon { display: none; }
:root:not([data-design])[data-theme="light"] .theme-toggle .ic-sun { display: none; }
:root:not([data-design])[data-theme="light"] .theme-toggle .ic-moon { display: block; }
/* margin-top 6 -> 2 pays back the 4px the toggle just gained going 40px -> 44px, so raising it to
   a real touch target costs the mobile header nothing. */
@media (max-width: 700px) { :root:not([data-design]) .theme-switch { margin-left: 0; margin-top: 2px; } }

/* ---------- dark-only corrections ---------------------------------------- */

/* The hero card's unlit risk segments sit at .28 for the ivory ground; over umber the same
   alpha nearly disappears, so they lift to match the meter's own unlit opacity. */
:root[data-theme="dark"] .hc-2,
:root[data-theme="dark"] .hc-3,
:root[data-theme="dark"] .hc-4 { opacity: .42; }

/* Three inline data-URI checkmarks bake their stroke colour, so they cannot follow a token.
   Re-declared with the dark palette's lighter safe-green / teal so the tick stays visible
   inside its dark tinted disc instead of reading as an empty circle. */
:root[data-theme="dark"] .locked-list li::before,
:root[data-theme="dark"] .plan li::before {
  background: var(--safe-soft) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none'%3E%3Cpath d='m5 13 4 4L19 7' stroke='%2335bd7a' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/12px no-repeat;
}
:root[data-theme="dark"] .plan li::before { background-size: 11px; }
:root[data-theme="dark"] .dealsoon-list li::before {
  background: var(--primary-soft) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none'%3E%3Cpath d='m5 13 4 4L19 7' stroke='%234cc7cf' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/12px no-repeat;
}

/* The paywall modal is the one card that sits on a DIMMED page rather than on the page. In dark its
   hairline --border edge measured 1.18:1 against the scrimmed ground, i.e. the card had no visible
   edge at all; in light the same card measured 3.51:1 because a white panel separates itself. It
   takes the strong border in dark only, which restores a real 3:1+ boundary without touching light. */
:root[data-theme="dark"] .modal { border-color: var(--border-strong); }

/* Same three fixes for a visitor who never touched the toggle and whose OS asks for dark. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]):not([data-theme="dark"]) .hc-2,
  :root:not([data-theme="light"]):not([data-theme="dark"]) .hc-3,
  :root:not([data-theme="light"]):not([data-theme="dark"]) .hc-4 { opacity: .42; }
  :root:not([data-theme="light"]):not([data-theme="dark"]) .locked-list li::before,
  :root:not([data-theme="light"]):not([data-theme="dark"]) .plan li::before {
    background: var(--safe-soft) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none'%3E%3Cpath d='m5 13 4 4L19 7' stroke='%2335bd7a' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/12px no-repeat;
  }
  :root:not([data-theme="light"]):not([data-theme="dark"]) .plan li::before { background-size: 11px; }
  :root:not([data-theme="light"]):not([data-theme="dark"]) .dealsoon-list li::before {
    background: var(--primary-soft) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none'%3E%3Cpath d='m5 13 4 4L19 7' stroke='%234cc7cf' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/12px no-repeat;
  }
  :root:not([data-theme="light"]):not([data-theme="dark"]) .modal { border-color: var(--border-strong); }
}

/* ==========================================================================
   GLOBAL HEADER NAV (2026-08-26)
   One header for every page: a compact bar, grouped dropdowns on desktop, and a real
   hamburger panel on phones. This block lives in warm.css deliberately - warm.css is the
   only stylesheet loaded by all 24 pages, and on the pages that also load css/style.css it
   comes second, so these rules win over style.css's older hover-first .menu-* set without
   needing that file edited.

   Why the rebuild: on 375x812 the flat nine-link nav wrapped to two rows and consumed 253px,
   31% of the viewport, and none of the thirteen controls above the fold was the scan input.
   Grouping into menus behind one Menu button gets the header to a single 68px row.

   Breakpoint: the desktop row only fits on one line from 992px up, so that is where the
   hamburger hands over. It is hardcoded in exactly two places, here and js/nav.js's DESKTOP
   constant, and they must move together or CSS and JS disagree about which layout is live.

   Visibility has ONE source of truth: .nav .menu.open .menu-pop, written by js/nav.js, which
   also writes aria-expanded. A CSS :hover / :focus-within rule used to open the card too, so
   the pop could stand open with aria-expanded="false" and a click on the trigger could not
   close it while the pointer stayed over the group. Hover-open now runs through js/nav.js's
   own open()/close(), so the visual state and the ARIA state cannot diverge.
   ========================================================================== */

.nav { position: relative; gap: 12px; justify-content: flex-start; }
/* Logo left, everything else one right-aligned run. With space-between the nav group floated in
   the middle of the bar and the theme switcher sat alone 104px further right, attached to nothing,
   and the group's left edge moved between pages as its width changed. */
/* align-self: stretch on the nav AND on .menu (below) makes the group the full height of the bar, so
   .menu-pop's top:100% resolves to the bar's bottom edge. .menu is a child of #site-nav, not of .nav,
   so stretching .menu alone only reached the 44px row and left the card's top corners painted over
   the header's hairline. margin-top:1px clears the 1px bottom border. */
@media (min-width: 992px) {
  #site-nav { margin-left: auto; align-self: stretch; }
  /* .nav .menu-pop, not .menu-pop: the base rule below sets margin-top: 0 at equal specificity and
     later source order, so a bare selector here loses and the card lands 1px high, on the hairline. */
  .nav .menu-pop { margin-top: 1px; }
}

/* --- the Menu button (phones only) --- */
.nav-toggle {
  display: none; align-items: center; gap: 9px;
  min-height: 44px; padding: 0 14px 0 12px; margin-left: auto;
  border: 1px solid var(--border-strong); border-radius: var(--r-pill);
  background: var(--surface); color: var(--ink);
  font-family: var(--font-body); font-size: 14.5px; font-weight: 600; letter-spacing: 0;
  cursor: pointer;
}
.nav-toggle:hover, .nav-toggle:focus-visible { border-color: var(--primary); color: var(--primary); }
.nav-toggle-bars { display: block; width: 17px; }
.nav-toggle-bars i {
  display: block; height: 2px; border-radius: 2px; background: currentColor;
  transition: transform .18s ease, opacity .18s ease;
}
.nav-toggle-bars i + i { margin-top: 4px; }
[aria-expanded="true"] > .nav-toggle-bars i:nth-child(1) { transform: translateY(6px) rotate(45deg); }
[aria-expanded="true"] > .nav-toggle-bars i:nth-child(2) { opacity: 0; }
[aria-expanded="true"] > .nav-toggle-bars i:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }
@media (prefers-reduced-motion: reduce) { .nav-toggle-bars i { transition: none; } }

/* --- a dropdown group ---
   The 22px inter-item gap lives on .menu, NOT on .menu-trigger. Two reasons. (1) .menu-pop is
   positioned left:0 against .menu, so a margin on the trigger pushed the label 22px right of the
   card that is supposed to be anchored to it. (2) css/style.css:1446 also sets .menu{margin-left:22px};
   with the gap on the trigger as well the two stacked into a 44px gap, which is what made the 21
   style.css pages need ~1010px to fit a row that index.html fits at 960px.
   align-self: stretch makes .menu the full height of the bar so the pop's top:100% resolves to the
   bar's bottom edge instead of 7px above it, where it painted over the header's hairline. */
.nav .menu { position: relative; display: inline-flex; align-items: center; align-self: stretch; margin-left: 22px; }
.nav .menu-trigger {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 44px; margin-left: 0; padding: 0; border: 0; background: none; cursor: pointer;
  color: var(--ink-2); font-family: var(--font-body); font-size: 15px; font-weight: 500; letter-spacing: 0;
}
.nav .menu-trigger:hover, .nav .menu-trigger:focus-visible, .nav .menu.open .menu-trigger { color: var(--primary); }
.menu-caret { transition: transform .18s ease; }
.nav .menu.open .menu-caret { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) { .menu-caret { transition: none; } }

.menu-pop {
  display: none; position: absolute; top: 100%; left: 0; z-index: 60;
  min-width: 268px; padding: 8px; margin-top: 0;
  border: 1px solid var(--border-strong); border-radius: var(--r-card, 14px);
  background: var(--surface); box-shadow: var(--modal-shadow);
}
.nav .menu.open .menu-pop { display: block; }
.menu-item {
  display: block; padding: 10px 12px; border-radius: 10px; text-decoration: none;
}
.menu-item:hover, .menu-item:focus-visible { background: var(--surface-soft); }
.menu-item-t {
  display: block; font-family: var(--font-body); font-size: 14.5px; font-weight: 600;
  letter-spacing: 0; text-transform: none; color: var(--ink);
}
.menu-item-d {
  display: block; margin-top: 2px; font-family: var(--font-body); font-size: 12.5px;
  font-weight: 400; letter-spacing: 0; color: var(--ink-3);
}
.menu-item:hover .menu-item-t, .menu-item:focus-visible .menu-item-t { color: var(--primary); }

/* The CSS hover-open rule that used to sit here is deleted. It opened .menu-pop without touching
   .open or aria-expanded, so hover showed four visible links while the trigger told a screen reader
   the group was collapsed, and a click meant to close the group left the card on screen because
   :hover still matched. js/nav.js now drives hover through the same open()/close() that writes the
   class and the ARIA state. */

/* --- you are here --- */
/* scripts/sync-nav.js stamps aria-current on the item matching the page it writes, so the one
   header shared by 25 pages can still say which of them you are on. */
.nav a.link[aria-current], .nav .menu-trigger[aria-current] { color: var(--primary); font-weight: 700; }
.nav .menu-item[aria-current] { background: var(--primary-soft); }
.nav .menu-item[aria-current] .menu-item-t { color: var(--primary); }
@media (min-width: 992px) {
  .nav a.link[aria-current]:not(.nav-cta), .nav .menu-trigger[aria-current] {
    box-shadow: inset 0 -2px 0 var(--primary);
  }
}
/* On the homepage the scan form is already on screen, so the filled pill would be inviting you to
   go where you are. It drops to a plain link there and the group keeps its "you are here" weight. */
.nav a.link.nav-cta[aria-current] {
  background: none; color: var(--primary); padding: 0; min-height: 44px;
}
.nav a.link.nav-cta[aria-current]:hover, .nav a.link.nav-cta[aria-current]:focus-visible {
  background: none; color: var(--primary-strong);
}

/* --- phones: one bar, everything behind the Menu button --- */
@media (max-width: 991px) {
  header { position: sticky; }
  .nav { flex-direction: row; align-items: center; height: 60px; padding: 0 20px; gap: 10px; }
  .nav-toggle { display: inline-flex; }
  .nav a.link.nav-cta[aria-current] { background: var(--primary); color: var(--primary-ink); }

  #site-nav {
    display: none; position: absolute; top: 100%; left: 0; right: 0; z-index: 55;
    /* flex-wrap MUST be reset. .nav nav sets wrap for the desktop row, and a column flex container
       that both wraps and has a capped height wraps into a SECOND COLUMN instead of scrolling:
       measured at 375x812 with two groups open the panel was 718px wide inside a 375px viewport,
       with the primary CTA rendering at x=359, off the right edge, and nothing to signal that
       horizontal scroll existed. */
    flex-direction: column; flex-wrap: nowrap; align-items: stretch; gap: 0;
    max-height: calc(100vh - 60px); max-height: calc(100dvh - 60px); overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding: 8px 16px 20px;
    /* --surface, not --bg: --bg is the exact colour of the page ground, so in dark mode the panel
       and the live page behind it were both #17130f and only a hairline separated them. */
    background: var(--surface); border-bottom: 1px solid var(--border);
    box-shadow: var(--modal-shadow);
  }
  #site-nav.is-open { display: flex; }
  /* Lock the page behind the panel, never the panel itself. */
  body.nav-open { overflow: hidden; }
  /* The panel is a card under a 60px bar, so roughly 40% of a phone viewport stayed live page. A tap
     meant to dismiss the menu also fired whatever sat underneath (verified: it closed the menu AND
     launched the sample tour). The scrim gives that tap something inert to land on, and says the
     page behind is not currently in play.

     Z-INDEX, and the reason it is 39 and not 54. The scrim is a child of <body>, so it stacks in the
     ROOT stacking context. #site-nav's z-index:55 does not stack there: header is `position: sticky;
     z-index: 40` (line 296), which makes header its own stacking context, so 55 only orders the panel
     against header's other children and the whole header subtree participates in the root context at
     40. A scrim at 54 therefore painted OVER the open menu: hit-testing the first dropdown trigger at
     375x812 returned BODY.nav-open, not the button, so on every one of the 25 pages the panel opened,
     dimmed itself, and swallowed every tap in it. Sitting the scrim at 39 puts it under header (40)
     and over all page content, including the sticky result bar at 30, which is what it was for. */
  body.nav-open::after {
    content: ""; position: fixed; inset: 60px 0 0; z-index: 39; background: var(--scrim);
  }

  .nav a.link, .nav .menu-trigger {
    margin-left: 0; width: 100%; min-height: 52px; font-size: 16.5px; font-weight: 600;
    border-bottom: 1px solid var(--border); border-radius: 0; padding: 0 2px;
  }
  .nav .menu { display: block; width: 100%; margin-left: 0; align-self: auto; }
  .nav .menu-trigger { justify-content: space-between; }
  .nav a.link.nav-cta {
    margin-top: 14px; min-height: 52px; justify-content: center;
    border-bottom: 0; border-radius: var(--r-pill); font-size: 16px;
  }
  /* Accordion, not a floating card. The left rail is pure decoration indicating nesting, so per
     DESIGN.md's Control-Boundary Invariant it takes --rail-muted, not --border-strong, which is
     reserved for the edge of something you can operate. */
  .menu-pop {
    position: static; min-width: 0; margin: 0 0 6px; padding: 4px 0 8px 12px;
    border: 0; border-left: 2px solid var(--rail-muted); border-radius: 0;
    background: none; box-shadow: none;
  }
  .menu-item { padding: 11px 10px; }
  .menu-item-t { font-size: 15.5px; }

  /* The theme control was a 97px bordered pill sitting beside a 90px Menu button, so a cosmetic
     preference read as the peer of the site's only navigation affordance and was in fact the wider
     of the two. Icon-only square below the breakpoint, matched to the Menu button's box. The header
     stays exactly two controls wide. */
  :root:not([data-design]) .theme-switch, .theme-switch { margin-left: 0; margin-top: 0; }
  :root:not([data-design]) .theme-toggle, .theme-toggle {
    width: 44px; min-width: 44px; height: 44px; min-height: 44px; padding: 0;
    justify-content: center; gap: 0;
  }
  /* The button keeps aria-label="Switch color theme" (js/theme.js:98), so dropping the visible
     word costs it no accessible name. */
  .theme-toggle .tt-label { display: none; }
}
