/* ============================================================================
   tokens.css — NathanaelTyre.ai design system tokens
   ----------------------------------------------------------------------------
   Single source of truth for color, type, spacing, motion, shadow, radius.
   Loaded via <link rel="stylesheet" href="/tokens.css"> on every in-scope
   page. Per-page <style> blocks consume these tokens — no hard-coded hex,
   no hard-coded font stacks, no hard-coded spacing/motion values.

   Scope: 10 public pages (homepage, /quiz, /audit, /audit/company,
   /individual, /individual/respondent, /build-sprint, /methodology,
   /about, /data).

   Architecture follows handoff D9: single tokens.css + per-page <style>,
   no build step, no framework. Tokens named generically so a future client
   portal (tabs, modals, tooltips, toasts, etc.) extends without rewriting.

   Last updated: 2026-05-06
   ============================================================================ */

/* ---------------------------------------------------------------------------
   Web fonts (rebrand) — Space Grotesk (display/headlines) + Inter (body/sans).
   No serif: editorial italic emphasis renders as true Inter italic (--font-serif
   now aliases --font-sans). Both families are loaded via <link rel=stylesheet>
   in each page <head> (kept out of @import for render-perf — no CSS-in-CSS
   waterfall). See https://web.dev/defer-non-critical-css/
   --------------------------------------------------------------------------- */

:root {
  /* ==========================================================================
     COLOR — refined from the existing palette, not reset (D3).
     Three clusters of drift were consolidated; canonical hex chosen by
     majority + WCAG audit. See decision log D22.
     ========================================================================== */

  /* Surfaces — espresso canvas + lifted warm panels (rebrand: light→dark inversion).
     Token NAMES preserved (per-page styles + components resolve them); VALUES + intent flipped. */
  --bg-paper:          #211913;  /* main canvas; espresso. body bg on all pages */
  --bg-paper-warm:     #2A211C;  /* lifted alt-section panel (was tinted paper) */
  --bg-paper-deep:     #322820;  /* deepest lifted panel; emphasis blocks */
  --bg-white:          #322820;  /* elevated dark panel (raised surface). TRUE WHITE only inside printable reports (set locally there) */
  --bg-cream-hi:       #F2E9D6;  /* CREAM highlight gradient — top stop (client-portal unlock banner stays a warm cream moment; dark text on it) */
  --bg-cream-lo:       #E4D6BB;  /* cream highlight gradient — bottom stop; pairs with --bg-cream-hi */
  --bg-slate:          #322820;  /* "dark band" = a LIFTED warm panel (was near-black #1A130D, read as too black). footer + dark-band sections. Cream text ~9:1 */
  --bg-slate-2:        #3E3228;  /* cards/steps on the band — a touch lighter so they lift off it */

  /* Generic surface aliases — for portal-ready extension (D6).
     Tabs/modals/tooltips/toasts can target --surface-* without re-deciding hex. */
  --surface-1:         var(--bg-paper);
  --surface-2:         var(--bg-paper-warm);
  --surface-3:         var(--bg-slate);
  --surface-3-2:       var(--bg-slate-2);

  /* --bg-primary / --bg-secondary — elevated panel aliases. Consumed by the
     cost-calculator card, sticky mobile CTA bar, and range-slider thumb ring.
     Previously referenced but never defined in :root (resolved to invalid →
     transparent). Defined now so those surfaces render the elevated dark panel. */
  --bg-primary:        var(--bg-white);
  --bg-secondary:      var(--bg-paper-warm);

  /* Ink — cream/stone text on espresso. Two levels for prose; UI gray for chrome (see grays). */
  --ink-primary:       #ECE3D0;  /* headings, strong text, nav brand. cream. ~13:1 on --bg-paper (AAA) */
  --ink-body:          #E0D7C4;  /* default body prose. stone-cream. ~11:1 on --bg-paper (AAA) */
  --ink-secondary:     #CBBFA9;  /* secondary prose, captions, muted body. brightened stone. ~8.4:1 on --bg-paper, ~6.6:1 on lifted panels */

  /* Ink on dark — text + muted text on the deeper --bg-slate band */
  --ink-on-dark:       #ECE3D0;  /* primary text on the deeper band. cream. ~14:1 on --bg-slate (AAA) */
  --ink-on-dark-muted: #CBBFA9;  /* muted text on the deeper band. brightened stone. ~9:1 on --bg-slate */
  --border-on-dark:    #4A3D31;  /* warm hairlines/dividers on dark bands. NOT a text token. */

  /* Accent — brass (links, accent borders, structural emphasis). NAME kept; blue→brass per rebrand. */
  --accent-blue:       #D8A45C;  /* link/structural brass on espresso. ~5.6:1 on --bg-paper (AA) */
  --accent-blue-hover: #E0B574;  /* brass-bright link hover */

  /* Accent — brass-bright (emphasis in display headings, dark-band accents) */
  --accent-gold:        #E0B574;  /* brass-bright on espresso. ~6.6:1 — AA on display + body */
  --accent-gold-soft:   #E4BE7D;  /* brass on the deeper band. ~7:1 on --bg-slate */
  --accent-gold-strong: #E0B574;  /* brass for small text on the dark canvas (was: small gold on light).
                                     ~5.9:1 on --bg-paper (AA normal), ~4.6:1 on --bg-paper-deep (AA Large).
                                     Added Wave 3.5b (D178.A close): retire misuse of --accent-gold on
                                     small numeric labels (path-price, principle .num, dim-num, stage-num)
                                     and cream-bg .end-cta h2 em. See D180.B in 00_Decisions/06_decision_log.md. */

  /* CTA — brass. Primary buttons. Brass fill + espresso label (--cta-on). */
  --cta-orange:        #D8A45C;  /* button bg (brass). With espresso label → ~5.6:1 (AA). */
  --cta-orange-hover:  #E0B574;  /* hover bg (brass-bright). With espresso label → ~7:1. */
  --cta-on:            #211913;  /* button label color = espresso (on brass). NOTE: surface/bright-text misuses redirected to --bg-white / --ink-on-dark below. */

  /* Grays — warm dark equivalents (NAMES kept). */
  --gray-50:           #2A211C;  /* subtle warm panel bg (callouts, hover tints on dark). */
  --gray-300:          #4A3D31;  /* borders, dividers, hairlines on dark. Folded --rule + --rule-warm. */
  --gray-700:          #C4B8A2;  /* muted UI text (captions, helper, placeholder). brightened stone. ~7.6:1 on --bg-paper. */

  /* Status — tuned for legibility on the espresso canvas. */
  --status-error:      #E0795F;  /* form errors, danger text. warm coral-red. ~4.8:1 on --bg-paper (AA) */
  --status-success:    #6FB58A;  /* availability dot, success cues. ~6:1 on --bg-paper */
  --status-warn:       #E6C07A;  /* warning cues. brass-amber. */

  /* Focus — visible focus ring. Honored by :focus-visible. */
  --focus-ring:        var(--cta-orange);

  /* ==========================================================================
     TYPOGRAPHY — D33 (supersedes D2). Space Grotesk for display/headlines +
     Inter for body/sans (readability + cross-platform restraint, no curvy
     display font); --font-serif aliases the sans stack (see below). Case rules
     (sentence / Title Case / UPPERCASE letterspaced) are content-driven and
     enforced in component classes.
     ========================================================================== */

  /* Font stacks (rebrand). Display = Space Grotesk (headlines), body = Inter.
     Load Space Grotesk + Inter via <link> in each page <head> (see build/per-page heads).
     --font-serif now aliases the SANS stack: the brand is Space Grotesk + Inter only,
     and editorial italic emphasis (pull-quote, testimonial, em) renders as TRUE Inter
     italic — Space Grotesk has only synthetic italics. Decision: italic = Inter italic. */
  --font-display:      "Space Grotesk", "Inter", -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  --font-serif:        var(--font-sans);  /* prose/blockquote/italic-emphasis contexts → Inter */
  --font-sans:         "Inter", -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  --font-mono:         ui-monospace, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;

  /* Type scale — modular ~1.25 ratio, anchored at body 18px (1.125rem).
     Existing pages render body at 18px; preserving avoids reflow across copy. */
  --fs-xs:             0.75rem;   /* 12px — labels, captions, footer fine print */
  --fs-sm:             0.875rem;  /* 14px — small UI text, badge labels */
  --fs-base:           1rem;      /* 16px — small UI default */
  --fs-md:             1.125rem;  /* 18px — body prose default */
  --fs-lg:             1.25rem;   /* 20px — h3, lede small */
  --fs-xl:             1.5rem;    /* 24px — h2 small, section subtitle */
  --fs-2xl:            2rem;      /* 32px — h2 default */
  --fs-3xl:            2.5rem;    /* 40px — h1 secondary, large display */
  --fs-4xl:            3.5rem;    /* 56px — h1 hero, max display */

  /* Line height */
  --lh-tight:          1.05;      /* hero h1 */
  --lh-snug:           1.15;      /* h2/h3 */
  --lh-normal:         1.5;       /* prose */
  --lh-loose:          1.65;      /* long-form body */

  /* Letter spacing */
  --tracking-tight:    -0.025em;  /* hero h1 */
  --tracking-snug:     -0.015em;  /* h2/h3 */
  --tracking-normal:   0;
  --tracking-wide:     0.08em;    /* eyebrows, section labels (UPPERCASE) */
  --tracking-wider:    0.14em;    /* small caps labels, footer column heads */

  /* Font weight */
  --fw-regular:        400;
  --fw-medium:         500;
  --fw-semibold:       600;
  --fw-bold:           700;

  /* ==========================================================================
     SPACING — 4/8/12/16/24/32/48/64/96 (D9). Use these instead of arbitrary
     rem values. Keys map to px so callers can reason about visual rhythm.
     ========================================================================== */
  --space-1:           0.25rem;   /* 4px */
  --space-2:           0.5rem;    /* 8px */
  --space-3:           0.75rem;   /* 12px */
  --space-4:           1rem;      /* 16px */
  --space-6:           1.5rem;    /* 24px */
  --space-8:           2rem;      /* 32px */
  --space-12:          3rem;      /* 48px */
  --space-16:          4rem;      /* 64px */
  --space-24:          6rem;      /* 96px */

  /* ==========================================================================
     LAYOUT — content widths and gutters. Names match existing page usage.
     ========================================================================== */
  --max-prose:         680px;     /* max-width for long-form prose (--max in old) */
  --max-text:          740px;     /* slightly wider text column (build-sprint, methodology) */
  --max-wide:          820px;     /* wider article column */
  --max-hero:          1100px;    /* hero + dark-band wrappers */
  --max-full:          1240px;    /* outer container */
  --gutter:            1.5rem;    /* horizontal padding inside wrappers */

  /* ==========================================================================
     MOTION — D7 budget. Honor `prefers-reduced-motion: reduce` in components.
     ========================================================================== */
  --motion-fast:       220ms;     /* hover, focus, micro-interactions (snappy) */
  --motion-medium:     520ms;     /* scroll-reveals, accordion expand */
  --motion-slow:       900ms;     /* cinematic page-enter / headline mask reveals */

  /* Rebrand motion = cinematic reveals with precise, snappy easing (M3+M4). */
  --ease-standard:     cubic-bezier(0.65, 0, 0.2, 1);  /* default — precise/snappy (the rebrand curve) */
  --ease-precise:      cubic-bezier(0.65, 0, 0.2, 1);  /* explicit alias for new motion layer */
  --ease-out:          cubic-bezier(0.16, 1, 0.3, 1);  /* reveals — snappy soft landing */
  --ease-in:           cubic-bezier(0.4, 0, 1, 1);     /* exits */

  /* Backwards-compatible alias so per-page <style> blocks still resolve --ease
     until step 2 migrates them to --ease-out. Removed at end of overhaul. */
  --ease:              var(--ease-out);
  --ease-soft:         var(--ease-standard);

  /* ==========================================================================
     LEGACY ALIASES — Step 5 transition.
     Per-page <style> blocks have ~30+ selectors using the pre-overhaul token
     names (--paper, --ink, --rule, --accent, --cta, --gold, --slate). Deleting
     the per-page :root before renaming every var() reference would break those
     selectors. These aliases let Step 5 delete per-page :root blocks safely;
     Step 10 final cleanup removes them after a global find/replace.
     Each alias maps the old name to its canonical token. Where the legacy hex
     drifted from the canonical (per D22 cluster consolidation), the canonical
     wins — the slight shade shift is the design-system fix.
     ========================================================================== */

  /* Surfaces */
  --paper:             var(--bg-paper);
  --paper-warm:        var(--bg-paper-warm);
  --paper-deep:        var(--bg-paper-deep);
  --slate:             var(--bg-slate);
  --slate-warm:        var(--bg-slate-2);

  /* Ink */
  --ink:               var(--ink-primary);
  --ink-soft:          var(--ink-secondary);
  --ink-muted:         var(--gray-700);
  --slate-on:          var(--ink-on-dark);
  --slate-soft:        var(--ink-on-dark-muted);

  /* Borders */
  --rule:              var(--gray-300);
  --rule-soft:         var(--gray-50);

  /* Accents — D163 (2026-05-12): --accent flipped from blue → orange site-wide
     for brand unification. --accent-soft kept blue (no live consumers; reserved).
     /quiz keeps blue interaction accents via local :root override (D163 follow-up). */
  --accent:            var(--cta);
  --accent-hover:      var(--cta-hover);
  --accent-soft:       var(--accent-blue);
  --accent-on:         var(--cta-on);
  --gold:              var(--accent-gold);
  --gold-soft:         var(--accent-gold-soft);
  --gold-strong:       var(--accent-gold-strong);

  /* CTA */
  --cta:               var(--cta-orange);
  --cta-hover:         var(--cta-orange-hover);

  /* Status */
  --error:             var(--status-error);

  /* Layout */
  --max:               var(--max-prose);

  /* ==========================================================================
     SHADOW — three-step ramp. Tinted with ink primary RGB for warmth.
     ========================================================================== */
  /* On dark: deeper ambient shadows (black-based, not ink-tinted). */
  --shadow-1:          0 1px 2px rgba(0, 0, 0, 0.35);                                  /* resting cards, buttons */
  --shadow-2:          0 4px 14px rgba(0, 0, 0, 0.42), 0 1px 2px rgba(0, 0, 0, 0.30); /* card hover, sticky nav */
  --shadow-3:          0 16px 38px rgba(0, 0, 0, 0.52), 0 2px 8px rgba(0, 0, 0, 0.36); /* elevated (path-card hover) */
  --shadow-cta:        0 8px 22px rgba(216, 164, 92, 0.30);                            /* btn:hover brass glow, matches --cta-orange RGB */

  /* ==========================================================================
     BORDER RADIUS — three steps + pill.
     ========================================================================== */
  --radius-sm:         10px;      /* buttons, cards, inputs (soft-rounded rebrand) */
  --radius-md:         12px;      /* photos, hero illustration frame */
  --radius-lg:         16px;      /* respondent surface cards, large panels */
  --radius-pill:       100px;     /* badges, availability pill */

  /* ==========================================================================
     Z-INDEX — keep low and named to avoid future stacking-context drift.
     ========================================================================== */
  --z-base:            1;
  --z-sticky-cta:      30;
  --z-nav:             50;
  --z-drawer:          90;
  --z-modal:           100;
  --z-skip-link:       200;
}

/* ============================================================================
   COMPONENTS — core kit (10 components, per D6 in handoff).
   Each component consumes canonical tokens from :root above. No hard-coded
   hex, font stacks, or spacing values appear below this line.

   Per-page <style> blocks may still define duplicate component CSS during
   the overhaul transition. Step 5 strips those per-page duplicates so these
   canonical definitions are the only source.
   ============================================================================ */

/* ---------------------------------------------------------------------------
   .btn — primary CTA button (orange) + .btn-ghost secondary (accent-blue).
   Case rule: button labels are Title Case (e.g., "Run Your Audit"). Enforced
   in copy, not on the class. Variants: [disabled] / .is-disabled, .is-loading,
   .no-arrow (suppresses the trailing arrow glyph).
   --------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  background: var(--cta-orange);
  color: var(--cta-on);
  text-decoration: none;
  padding: var(--space-3) var(--space-6);
  border: none;
  border-radius: var(--radius-sm);
  font-family: var(--font-sans);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-base);
  letter-spacing: 0.005em;
  cursor: pointer;
  position: relative;
  box-shadow: var(--shadow-1), 0 0 0 1px rgba(168, 82, 28, 0.4);
  transition:
    background var(--motion-fast) var(--ease-standard),
    transform var(--motion-fast) var(--ease-standard),
    box-shadow var(--motion-fast) var(--ease-standard);
}
.btn::after {
  content: "→";
  display: inline-block;
  font-weight: var(--fw-medium);
  transition: transform var(--motion-fast) var(--ease-standard);
}
.btn:hover {
  background: var(--cta-orange-hover);
  transform: translateY(-1px);
  box-shadow: var(--shadow-cta), 0 0 0 1px rgba(142, 69, 23, 0.5);
}
.btn:hover::after { transform: translateX(3px); }
.btn:active { transform: translateY(0); box-shadow: var(--shadow-1); }
.btn:focus-visible {
  outline: 2px solid var(--cta-on);
  outline-offset: 2px;
  box-shadow: 0 0 0 4px var(--focus-ring);
}
.btn.no-arrow::after { display: none; }

/* Keep the button LABEL color immune to generic per-page `a:hover { color }`
   rules. A bare .btn (an <a>) loses its espresso label to a:hover (0,1,1) >
   .btn (0,1,0), recoloring the text to match the brass fill = invisible. The nav
   button escapes via nav.css's higher specificity; the doubled-class selector
   (0,3,0) > a:hover brings every other .btn / .btn-secondary in line. */
.btn.btn:hover,
.btn.btn:focus,
.btn.btn:active { color: var(--cta-on); }
.btn-secondary.btn-secondary:hover,
.btn-secondary.btn-secondary:focus { color: var(--paper); }

/* Disabled — non-interactive. */
.btn[disabled],
.btn.is-disabled {
  background: var(--gray-300);
  color: var(--gray-700);
  cursor: not-allowed;
  box-shadow: none;
  pointer-events: none;
}
.btn[disabled]::after,
.btn.is-disabled::after { opacity: 0.5; }

/* Loading — spinner replaces arrow. Honors prefers-reduced-motion. */
.btn.is-loading { pointer-events: none; opacity: 0.85; }
.btn.is-loading::after {
  content: "";
  width: 0.85em;
  height: 0.85em;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: btn-spin var(--motion-slow) linear infinite;
}
@keyframes btn-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .btn.is-loading::after { animation: none; }
  .btn:hover { transform: none; }
  .btn:hover::after { transform: none; }
}

/* Ghost — secondary action, underline-bottom on accent-blue. */
.btn-ghost {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  background: transparent;
  color: var(--accent-blue);
  text-decoration: none;
  padding: var(--space-3) 0;
  font-family: var(--font-sans);
  font-weight: var(--fw-medium);
  font-size: var(--fs-base);
  border-bottom: 1px solid var(--accent-blue);
  transition:
    color var(--motion-fast) var(--ease-standard),
    border-color var(--motion-fast) var(--ease-standard);
}
.btn-ghost::after {
  content: "→";
  display: inline-block;
  transition: transform var(--motion-fast) var(--ease-standard);
}
.btn-ghost:hover {
  color: var(--accent-blue-hover);
  border-color: var(--accent-blue-hover);
}
.btn-ghost:hover::after { transform: translateX(3px); }
.btn-ghost:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 3px;
}
.btn-ghost.no-arrow::after { display: none; }
@media (prefers-reduced-motion: reduce) {
  .btn-ghost:hover::after { transform: none; }
}

/* ---------------------------------------------------------------------------
   .btn-secondary — outlined button-shaped secondary CTA. Use as the secondary
   action paired with a primary .btn in a .cta-row, or as a standalone
   secondary marketing CTA. Distinct from .btn-ghost: ghost is the text-link
   variant (Back / Cancel / dismiss in forms + admin), secondary is button-shaped.
   D193 (2026-05-12) — added to resolve canonical .btn-ghost looking scrunched
   next to a primary .btn in marketing CTA rows post-D189.
   --------------------------------------------------------------------------- */
.btn-secondary {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  background: transparent;
  color: var(--accent-blue);
  text-decoration: none;
  padding: calc(var(--space-3) - 1px) calc(var(--space-6) - 1px);
  border: 1px solid var(--accent-blue);
  border-radius: var(--radius-sm);
  font-family: var(--font-sans);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-base);
  letter-spacing: 0.005em;
  cursor: pointer;
  position: relative;
  box-shadow: var(--shadow-1);
  transition:
    background var(--motion-fast) var(--ease-standard),
    color var(--motion-fast) var(--ease-standard),
    border-color var(--motion-fast) var(--ease-standard),
    transform var(--motion-fast) var(--ease-standard),
    box-shadow var(--motion-fast) var(--ease-standard);
}
.btn-secondary::after {
  content: "→";
  display: inline-block;
  font-weight: var(--fw-medium);
  transition: transform var(--motion-fast) var(--ease-standard);
}
.btn-secondary:hover {
  background: var(--accent-blue);
  color: var(--paper);
  border-color: var(--accent-blue);
  transform: translateY(-1px);
  box-shadow: var(--shadow-2);
}
.btn-secondary:hover::after { transform: translateX(3px); }
.btn-secondary:active { transform: translateY(0); box-shadow: var(--shadow-1); }
.btn-secondary:focus-visible {
  outline: 2px solid var(--accent-blue);
  outline-offset: 2px;
  box-shadow: 0 0 0 4px var(--focus-ring);
}
.btn-secondary.no-arrow::after { display: none; }
@media (prefers-reduced-motion: reduce) {
  .btn-secondary:hover { transform: none; }
  .btn-secondary:hover::after { transform: none; }
}

/* ---------------------------------------------------------------------------
   .cta-row — flex container that pairs a primary .btn with a secondary
   (.btn-secondary or .btn-ghost). Wraps below 640px so buttons stack full-width.
   --------------------------------------------------------------------------- */
.cta-row {
  margin-top: var(--space-6);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-6);
}
@media (max-width: 640px) {
  .cta-row { flex-direction: column; align-items: stretch; gap: var(--space-3); }
  .cta-row .btn,
  .cta-row .btn-secondary,
  .cta-row .btn-ghost { justify-content: center; width: 100%; }
}

/* ---------------------------------------------------------------------------
   .wrap-full — full-bleed page container used by header.site-nav, footer,
   and wide content sections. Centralized in Wave 5 (D183) to kill cross-page
   padding-x drift (notably /build-sprint's 1.75rem outlier that caused
   visible logo-position shift). header.site-nav + .scrolled themselves live
   in /assets/nav.css (the actual canonical, loaded after tokens.css). D185
   RESERVED tracks consolidating tokens.css + nav.css into a single nav
   source of truth and fixing the 2px headerH desktop residual.
   --------------------------------------------------------------------------- */
.wrap-full {
  max-width: var(--max-full);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

/* ---------------------------------------------------------------------------
   Nav + drawer — top bar with brand mark + links + mobile drawer.
   JS-light pattern: toggle `body.is-nav-open` to open the drawer. The
   button reflects state via `aria-expanded`. No framework, no JSX.
   --------------------------------------------------------------------------- */
.nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--space-3) 0;
  font-family: var(--font-sans);
  position: relative;
  z-index: var(--z-nav);
}

.nav-brand {
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-2);
  text-decoration: none;
  color: var(--ink-primary);
}
.nav-brand:hover .nav-name { color: var(--accent-blue); }
.nav-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px; height: 30px;
  border: 1px solid var(--ink-primary);
  color: var(--ink-primary);
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--fs-base);
  font-weight: var(--fw-medium);
  letter-spacing: -0.02em;
  line-height: 1;
}
/* Rebrand: when a .nav-mark hosts the arrow-N SVG (header + footer brand mark),
   it IS the mark — drop the legacy letter-box border and size the svg. The svg
   uses currentColor, so it inherits brass (header) / cream (footer) from context. */
.nav-mark:has(svg) { border: none; }
.nav-mark svg { display: block; width: 30px; height: 30px; }
.nav-name {
  font-family: var(--font-sans);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-base);
  letter-spacing: -0.005em;
  color: var(--ink-primary);
}

.nav-links {
  display: flex;
  align-items: center;
  gap: var(--space-6);
}
.nav-links a {
  color: var(--ink-secondary);
  text-decoration: none;
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  transition: color var(--motion-fast) var(--ease-standard);
}
.nav-links a:hover { color: var(--ink-primary); }
.nav-links a.btn,
.nav-links a.btn-nav {
  color: var(--cta-on);
  padding: var(--space-2) var(--space-4);
  font-size: var(--fs-sm);
}
.nav-links a.btn::after,
.nav-links a.btn-nav::after { display: none; }

/* Hamburger toggle — animated 3-bar → X via aria-expanded */
.nav-toggle {
  display: none;
  background: none;
  border: none;
  cursor: pointer;
  padding: var(--space-1);
  flex-direction: column;
  gap: 5px;
  align-items: center;
  justify-content: center;
}
.nav-toggle .bar {
  display: block;
  width: 22px;
  height: 2px;
  background: var(--ink-primary);
  border-radius: 2px;
  transition:
    transform var(--motion-fast) var(--ease-standard),
    opacity var(--motion-fast) var(--ease-standard);
}
.nav-toggle[aria-expanded="true"] .bar:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .bar:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .bar:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* Drawer — slide-in panel from the right. Hidden by default; revealed when
   <body> carries .is-nav-open. Backdrop sits behind via ::before. */
.nav-drawer {
  position: fixed;
  top: 0;
  right: 0;
  width: min(86vw, 360px);
  height: 100vh;
  background: var(--bg-paper);
  border-left: 1px solid var(--gray-300);
  box-shadow: var(--shadow-3);
  padding: var(--space-12) var(--space-6) var(--space-6);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  transform: translateX(100%);
  transition: transform var(--motion-medium) var(--ease-out);
  z-index: var(--z-drawer);
  visibility: hidden;
}
.nav-drawer a {
  display: block;
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--gray-300);
  font-family: var(--font-sans);
  font-size: var(--fs-md);
  font-weight: var(--fw-medium);
  color: var(--ink-secondary);
  text-decoration: none;
}
.nav-drawer a:hover { color: var(--ink-primary); }
.nav-drawer a.btn {
  margin-top: var(--space-6);
  border-bottom: none;
  text-align: center;
  color: var(--cta-on);
}
.nav-drawer a.btn::after { display: none; }

/* Backdrop scrim — sits between page and drawer */
.nav-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
  opacity: 0;
  visibility: hidden;
  transition:
    opacity var(--motion-medium) var(--ease-standard),
    visibility var(--motion-medium) var(--ease-standard);
  z-index: calc(var(--z-drawer) - 1);
}

/* Open state — driven by body class (no JS framework needed) */
body.is-nav-open { overflow: hidden; }
body.is-nav-open .nav-drawer { transform: translateX(0); visibility: visible; }
body.is-nav-open .nav-backdrop { opacity: 1; visibility: visible; }

@media (max-width: 768px) {
  .nav-links { display: none !important; }
  .nav-toggle { display: flex; }
}
@media (prefers-reduced-motion: reduce) {
  .nav-drawer,
  .nav-toggle .bar,
  .nav-backdrop { transition: none; }
}

/* ---------------------------------------------------------------------------
   .site-footer — slate-band footer with brand + 2 link columns + bottom bar.
   --------------------------------------------------------------------------- */
.site-footer {
  background: var(--bg-slate);
  color: var(--ink-on-dark-muted);
  padding: var(--space-16) 0 var(--space-12);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  line-height: var(--lh-normal);
}
.site-footer a {
  color: var(--ink-on-dark);
  text-decoration: none;
  transition: color var(--motion-fast) var(--ease-standard);
}
.site-footer a:hover { color: var(--ink-on-dark); text-decoration: underline; }

.footer-grid {
  display: grid;
  gap: var(--space-12);
  grid-template-columns: 1.2fr 1fr 1fr;
  margin-bottom: var(--space-12);
}

.footer-brand .nav-mark {
  border-color: var(--ink-on-dark);
  color: var(--ink-on-dark);
  margin-bottom: var(--space-3);
}
.footer-brand .footer-tagline {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: var(--fs-md);
  color: var(--ink-on-dark);
  margin: 0 0 var(--space-2) 0;
}
.footer-brand p.small {
  color: var(--ink-on-dark-muted);
  font-size: var(--fs-xs);
  margin: 0;
}

/* D171 (2026-05-14) — footer headings semantic upgrade h4 → h2
   to satisfy axe-core heading-order. h2 chosen (not h3) because
   /quiz intro screen renders only h1 (q* screens are display:none
   on initial paint), so any heading skip past h2 fails the rule.
   Footer landmark headings as h2 is standard practice. Visual
   styling unchanged; h3/h4 selectors retained for backwards-compat
   during patch ship — remove once all 10 pages migrated. */
.footer-col h2,
.footer-col h3,
.footer-col h4 {
  color: var(--ink-on-dark);
  font-family: var(--font-sans);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  margin: 0 0 var(--space-4) 0;
}
.footer-col ul { list-style: none; padding: 0; margin: 0; }
.footer-col li { margin: 0 0 var(--space-2) 0; }

.footer-bottom {
  padding-top: var(--space-6);
  border-top: 1px solid var(--bg-slate-2);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  justify-content: space-between;
  align-items: center;
  color: var(--ink-on-dark-muted);
  font-size: var(--fs-xs);
}

@media (max-width: 720px) {
  .footer-grid { grid-template-columns: 1fr; gap: var(--space-8); }
}

/* ---------------------------------------------------------------------------
   .eyebrow — UPPERCASE letterspaced section label. Mono for an editorial
   "operator" feel; can host an optional `.num` chip for numbered sections.
   Sits above an h1/h2 with margin-bottom.
   --------------------------------------------------------------------------- */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--ink-secondary);
  margin: 0 0 var(--space-3) 0;
}
.eyebrow::before {
  content: "";
  display: inline-block;
  width: var(--space-4);
  height: 1px;
  background: var(--accent-gold);
  flex-shrink: 0;
}
.eyebrow .num {
  display: inline-block;
  padding: 0 var(--space-2);
  border: 1px solid var(--gray-300);
  border-radius: var(--radius-sm);
  font-size: var(--fs-xs);
  color: var(--ink-secondary);
  background: var(--bg-paper);
}
/* On dark surfaces — invert ink + soften the gold rule */
.dark-band .eyebrow,
.section-dark .eyebrow,
.site-footer .eyebrow { color: var(--ink-on-dark-muted); }
.dark-band .eyebrow::before,
.section-dark .eyebrow::before,
.site-footer .eyebrow::before { background: var(--accent-gold-soft); }

/* ---------------------------------------------------------------------------
   .card — container for grouped content. Modifiers:
     .card--accent      blue top rule (reframe / methodology callouts)
     .card--tinted      left rule + warm bg (deliverable lists)
     .card--elevated    larger shadow + hover lift (path-card pattern)
     .card--dark        for use inside dark-band sections
   --------------------------------------------------------------------------- */
.card {
  background: var(--bg-white);
  border: 1px solid var(--gray-300);
  border-radius: var(--radius-sm);
  padding: var(--space-8);
  box-shadow: var(--shadow-1);
}

.card--accent {
  border-top: 3px solid var(--accent-blue);
}

.card--tinted {
  background: var(--bg-white);
  border-left: 3px solid var(--accent-blue);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}

.card--elevated {
  transition:
    transform var(--motion-medium) var(--ease-standard),
    box-shadow var(--motion-medium) var(--ease-standard),
    border-color var(--motion-medium) var(--ease-standard);
}
.card--elevated:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-3);
  border-color: var(--accent-blue);
}

.card--dark {
  background: var(--bg-slate-2);
  border-color: rgba(241, 236, 225, 0.08);
  color: var(--ink-on-dark);
}
.card--dark h3 { color: var(--ink-on-dark); }
.card--dark p { color: var(--ink-on-dark-muted); }

@media (max-width: 600px) {
  .card { padding: var(--space-6); }
}
@media (prefers-reduced-motion: reduce) {
  .card--elevated:hover { transform: none; }
}

/* ---------------------------------------------------------------------------
   Form inputs — .field wrapper + base styles for input/textarea/select.
   .field--error adds the error tint; helper/error message slots below.
   --------------------------------------------------------------------------- */
.field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}
.field label,
.field .field-label {
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--ink-primary);
}
.field .field-help {
  font-size: var(--fs-xs);
  color: var(--ink-secondary);
  line-height: var(--lh-normal);
}
.field .field-error {
  font-size: var(--fs-xs);
  color: var(--status-error);
  font-weight: var(--fw-medium);
}

/* Base input/textarea/select — token-driven, no hard-coded colors */
.field input[type="text"],
.field input[type="email"],
.field input[type="tel"],
.field input[type="url"],
.field input[type="number"],
.field input[type="search"],
.field input[type="password"],
.field textarea,
.field select,
input.field-input,
textarea.field-input,
select.field-input {
  width: 100%;
  padding: var(--space-3) var(--space-4);
  background: var(--bg-white);
  border: 1px solid var(--gray-300);
  border-radius: var(--radius-sm);
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  color: var(--ink-primary);
  line-height: var(--lh-normal);
  transition:
    border-color var(--motion-fast) var(--ease-standard),
    box-shadow var(--motion-fast) var(--ease-standard);
}
.field textarea,
textarea.field-input { min-height: 7rem; resize: vertical; }
.field input::placeholder,
.field textarea::placeholder { color: var(--gray-700); }

.field input:hover,
.field textarea:hover,
.field select:hover { border-color: var(--accent-blue); }

.field input:focus-visible,
.field textarea:focus-visible,
.field select:focus-visible {
  outline: none;
  border-color: var(--accent-blue);
  box-shadow: 0 0 0 3px rgba(216, 164, 92, 0.30);
}

.field input:disabled,
.field textarea:disabled,
.field select:disabled {
  background: var(--gray-50);
  color: var(--gray-700);
  cursor: not-allowed;
}

/* Error state — red border + ring */
.field--error input,
.field--error textarea,
.field--error select,
.field input[aria-invalid="true"],
.field textarea[aria-invalid="true"] {
  border-color: var(--status-error);
}
.field--error input:focus-visible,
.field--error textarea:focus-visible,
.field--error select:focus-visible {
  border-color: var(--status-error);
  box-shadow: 0 0 0 3px rgba(185, 28, 28, 0.18);
}

/* Checkbox + radio — keep system look but tint accent */
.field input[type="checkbox"],
.field input[type="radio"] {
  accent-color: var(--accent-blue);
  width: auto;
  margin-right: var(--space-2);
}

/* ---------------------------------------------------------------------------
   .faq-accordion — uses native HTML <details>/<summary>. No JS.
   Markup:
     <div class="faq-accordion">
       <details><summary>Q…</summary><p>A…</p></details>
       …
     </div>
   --------------------------------------------------------------------------- */
.faq-accordion {
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--gray-300);
}
.faq-accordion details {
  border-bottom: 1px solid var(--gray-300);
  padding: var(--space-4) 0;
}
.faq-accordion summary {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-2) 0;
  cursor: pointer;
  list-style: none;
  font-family: var(--font-sans);
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  color: var(--ink-primary);
  transition: color var(--motion-fast) var(--ease-standard);
}
.faq-accordion summary::-webkit-details-marker { display: none; }
.faq-accordion summary::after {
  content: "+";
  flex-shrink: 0;
  font-family: var(--font-sans);
  font-size: var(--fs-xl);
  font-weight: var(--fw-regular);
  color: var(--accent-blue);
  line-height: 1;
  transition: transform var(--motion-medium) var(--ease-standard);
}
.faq-accordion summary:hover { color: var(--accent-blue); }
.faq-accordion summary:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 4px;
  border-radius: var(--radius-sm);
}
.faq-accordion details[open] summary::after { transform: rotate(45deg); }

.faq-accordion details > *:not(summary) {
  margin: var(--space-3) 0 var(--space-2) 0;
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  color: var(--ink-body);
  line-height: var(--lh-loose);
}
.faq-accordion details > *:not(summary):last-child { margin-bottom: 0; }

@media (prefers-reduced-motion: reduce) {
  .faq-accordion summary::after { transition: none; }
}

/* ---------------------------------------------------------------------------
   .pull-quote — editorial blockquote pulled out of body prose.
   Italic serif, gold rule on the left, optional .pull-quote-cite below.
   --------------------------------------------------------------------------- */
.pull-quote {
  margin: var(--space-12) 0;
  padding: var(--space-2) 0 var(--space-2) var(--space-6);
  border-left: 3px solid var(--accent-gold);
  font-family: var(--font-serif);
  font-style: italic;
  font-size: var(--fs-xl);
  line-height: var(--lh-snug);
  color: var(--ink-primary);
  letter-spacing: var(--tracking-snug);
  max-width: var(--max-prose);
}
.pull-quote p { margin: 0; }
.pull-quote p + p { margin-top: var(--space-3); }

.pull-quote-cite {
  display: block;
  margin-top: var(--space-3);
  font-family: var(--font-sans);
  font-style: normal;
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--ink-secondary);
  letter-spacing: var(--tracking-normal);
}
.pull-quote-cite::before {
  content: "— ";
}

/* On dark surfaces */
.dark-band .pull-quote,
.section-dark .pull-quote {
  color: var(--ink-on-dark);
  border-left-color: var(--accent-gold-soft);
}
.dark-band .pull-quote-cite,
.section-dark .pull-quote-cite { color: var(--ink-on-dark-muted); }

/* ---------------------------------------------------------------------------
   .table — comparison / data table. Sans body, mono numerics, hairlines.
   Wrap in a .table-wrap div for horizontal scroll on small viewports.
   --------------------------------------------------------------------------- */
.table-wrap {
  width: 100%;
  overflow-x: auto;
  margin: var(--space-6) 0;
  border: 1px solid var(--gray-300);
  border-radius: var(--radius-sm);
}
.table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  color: var(--ink-body);
}
.table caption {
  caption-side: top;
  text-align: left;
  padding: var(--space-3) var(--space-4);
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--ink-secondary);
  background: var(--bg-paper-warm);
  border-bottom: 1px solid var(--gray-300);
}
.table thead th {
  text-align: left;
  padding: var(--space-3) var(--space-4);
  background: var(--bg-paper-warm);
  border-bottom: 1px solid var(--gray-300);
  font-family: var(--font-sans);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--ink-primary);
  white-space: nowrap;
}
.table tbody th,
.table tbody td {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--gray-300);
  vertical-align: top;
  line-height: var(--lh-normal);
}
.table tbody th {
  text-align: left;
  font-weight: var(--fw-semibold);
  color: var(--ink-primary);
}
.table tbody tr:last-child th,
.table tbody tr:last-child td { border-bottom: none; }
.table tbody tr:hover { background: var(--gray-50); }

/* Numeric columns — right-aligned, mono, tabular */
.table .num,
.table td.num,
.table th.num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}

/* Compact variant — denser rows */
.table--compact tbody th,
.table--compact tbody td,
.table--compact thead th { padding: var(--space-2) var(--space-3); }

/* ----------------------------------------------------------------------------
   .callout — canonical notice box (D351).
   One token-based component that retires the per-page border-left:3px
   "side-tab" variants (quiz .intro-callout / .result-preview, dark-band gray
   boxes, client-portal drift). Surface + padding are tokenized; the accent
   defaults to --gold and is overridable per variant via --callout-accent.
---------------------------------------------------------------------------- */
.callout {
  background: var(--bg-white);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--callout-accent, var(--gold));
  padding: 1.25rem 1.5rem;
  margin: 0 0 1.75rem 0;
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  color: var(--ink-soft);
  line-height: 1.55;
}
.callout strong { color: var(--ink); }

/* ============================================================================
   SECTION ARCHETYPES — 8 section primitives (D4) that compose pages.
   Each archetype owns: padding, max-width wrapper, internal grid. Archetypes
   consume the components above (.btn, .card, .eyebrow, .pull-quote, etc.) —
   they do NOT redefine button/card/etc. styles.

   All archetypes share the .section base for vertical rhythm + bottom hairline.
   Archetype-specific tuning overrides where needed.
   ============================================================================ */

/* Shared section base — vertical padding + bottom hairline for default rhythm. */
.section {
  padding: var(--space-16) 0;
  border-bottom: 1px solid var(--gray-300);
}
.section:last-of-type,
.section.no-divider { border-bottom: none; }
.section + .section.no-top-divider { border-top: none; }

/* Inner wrapper — applied to a child div, NOT to the section element itself.
   Lets archetypes vary max-width without wrestling padding. */
.section-inner {
  max-width: var(--max-full);
  margin: 0 auto;
  padding: 0 var(--gutter);
}
.section-inner--prose { max-width: var(--max-prose); }
.section-inner--text  { max-width: var(--max-text); }
.section-inner--wide  { max-width: var(--max-wide); }
.section-inner--hero  { max-width: var(--max-hero); }

/* ---------------------------------------------------------------------------
   .section-hero — top-of-page archetype. Larger vertical padding, room for
   eyebrow + h1 + lede + .cta-row + optional .hero-photo-wrap split.
   --------------------------------------------------------------------------- */
.section-hero {
  padding: var(--space-24) 0 var(--space-16);
  border-bottom: 1px solid var(--gray-300);
  background: var(--bg-paper);
}
.section-hero h1 {
  font-family: var(--font-display);
  font-size: var(--fs-4xl);
  line-height: var(--lh-tight);
  letter-spacing: var(--tracking-tight);
  color: var(--ink-primary);
  margin: 0 0 var(--space-4) 0;
}
/* D179 (2026-05-14): Removed `.section-hero h1 em` rule. Orphan selector
   (no markup uses .section-hero anywhere in /vercel_deploy). Gold on paper
   ~3.4:1 fails AAA 7:1 for normal text. Same rationale as Wave 2 + Wave 3.5
   per-page strips. Rule deletion prevents revival in future copy edits. */
.section-hero .lede {
  font-family: var(--font-sans);
  font-size: var(--fs-lg);
  line-height: var(--lh-loose);
  color: var(--ink-secondary);
  max-width: var(--max-prose);
  margin: 0 0 var(--space-6) 0;
}

/* Split layout — hero copy left, photo right, stacks on small viewports. */
.section-hero--split .section-inner {
  display: grid;
  grid-template-columns: 1fr 320px;
  gap: var(--space-12);
  align-items: center;
}
.section-hero .hero-photo-wrap img {
  width: 100%;
  border-radius: var(--radius-md);
  display: block;
  object-fit: cover;
  object-position: top center;
  aspect-ratio: 4/5;
  border: 1px solid var(--gray-300);
  box-shadow: var(--shadow-2);
}

@media (max-width: 760px) {
  .section-hero { padding: var(--space-16) 0 var(--space-12); }
  .section-hero h1 { font-size: var(--fs-3xl); }
  .section-hero--split .section-inner { grid-template-columns: 1fr; gap: var(--space-8); }
  .section-hero .hero-photo-wrap { display: none; }
}

/* ---------------------------------------------------------------------------
   .section-prose — long-form body text. Narrow column, generous line height,
   serif h2/h3, sans body. For methodology, about, build-sprint copy.
   --------------------------------------------------------------------------- */
.section-prose {
  padding: var(--space-16) 0;
  border-bottom: 1px solid var(--gray-300);
}
.section-prose .section-inner { max-width: var(--max-text); }
.section-prose h2 {
  font-family: var(--font-display);
  font-size: var(--fs-2xl);
  line-height: var(--lh-snug);
  letter-spacing: var(--tracking-snug);
  color: var(--ink-primary);
  margin: 0 0 var(--space-4) 0;
}
.section-prose h3 {
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  line-height: var(--lh-snug);
  color: var(--ink-primary);
  margin: var(--space-8) 0 var(--space-3) 0;
}
.section-prose p {
  font-family: var(--font-sans);
  font-size: var(--fs-md);
  line-height: var(--lh-loose);
  color: var(--ink-body);
  margin: 0 0 var(--space-4) 0;
}
.section-prose a {
  color: var(--accent-blue);
  text-decoration: underline;
  text-underline-offset: 2px;
  transition: color var(--motion-fast) var(--ease-standard);
}
.section-prose a:hover { color: var(--accent-blue-hover); }
.section-prose ul,
.section-prose ol {
  font-family: var(--font-sans);
  font-size: var(--fs-md);
  line-height: var(--lh-loose);
  color: var(--ink-body);
  margin: 0 0 var(--space-4) 0;
  padding-left: var(--space-6);
}
.section-prose li { margin-bottom: var(--space-2); }
.section-prose strong { font-weight: var(--fw-semibold); color: var(--ink-primary); }
.section-prose em { font-family: var(--font-display); font-style: italic; }

/* ---------------------------------------------------------------------------
   .section-two-up — two equal columns. Used for pain-vs-reframe, fit/not-a-fit,
   problem/solution. Stacks below 760px. Optional intro h2 above the grid.
   --------------------------------------------------------------------------- */
.section-two-up {
  padding: var(--space-16) 0;
  border-bottom: 1px solid var(--gray-300);
}
.section-two-up .section-inner { max-width: var(--max-hero); }
.section-two-up h2 {
  font-family: var(--font-display);
  font-size: var(--fs-2xl);
  line-height: var(--lh-snug);
  letter-spacing: var(--tracking-snug);
  color: var(--ink-primary);
  margin: 0 0 var(--space-3) 0;
}
.section-two-up .lede {
  font-family: var(--font-sans);
  font-size: var(--fs-md);
  line-height: var(--lh-loose);
  color: var(--ink-secondary);
  max-width: var(--max-prose);
  margin: 0 0 var(--space-8) 0;
}
.section-two-up .two-up {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-12);
  align-items: start;
}
.section-two-up .two-up h3 {
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  font-weight: var(--fw-semibold);
  color: var(--ink-secondary);
  margin: 0 0 var(--space-4) 0;
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--gray-300);
}
.section-two-up .two-up p {
  font-family: var(--font-sans);
  font-size: var(--fs-md);
  line-height: var(--lh-loose);
  color: var(--ink-body);
  margin: 0 0 var(--space-3) 0;
}
@media (max-width: 760px) {
  .section-two-up .two-up { grid-template-columns: 1fr; gap: var(--space-8); }
}

/* ---------------------------------------------------------------------------
   .section-pull-quote — standalone pull-quote section. Tinted bg, generous
   vertical padding, the .pull-quote component does the actual styling.
   Use --variant-large for hero-sized pull quotes.
   --------------------------------------------------------------------------- */
.section-pull-quote {
  padding: var(--space-16) 0;
  background: var(--bg-paper-warm);
  border-bottom: 1px solid var(--gray-300);
}
.section-pull-quote .section-inner { max-width: var(--max-wide); }
.section-pull-quote .pull-quote {
  margin: 0 auto;
  max-width: var(--max-prose);
}
.section-pull-quote--large .pull-quote {
  font-size: var(--fs-2xl);
  line-height: var(--lh-snug);
  max-width: var(--max-wide);
}
@media (max-width: 760px) {
  .section-pull-quote { padding: var(--space-12) 0; }
  .section-pull-quote--large .pull-quote { font-size: var(--fs-xl); }
}

/* ---------------------------------------------------------------------------
   .section-card-grid — 2- or 3-column grid of .card components. Stacks on
   mobile. Optional intro h2 + lede above the grid.
     .section-card-grid--3up   3 columns
     .section-card-grid--2up   2 columns (default)
   --------------------------------------------------------------------------- */
.section-card-grid {
  padding: var(--space-16) 0;
  border-bottom: 1px solid var(--gray-300);
}
.section-card-grid .section-inner { max-width: var(--max-hero); }
.section-card-grid h2 {
  font-family: var(--font-display);
  font-size: var(--fs-2xl);
  line-height: var(--lh-snug);
  letter-spacing: var(--tracking-snug);
  color: var(--ink-primary);
  margin: 0 0 var(--space-3) 0;
}
.section-card-grid .lede {
  font-family: var(--font-sans);
  font-size: var(--fs-md);
  line-height: var(--lh-loose);
  color: var(--ink-secondary);
  max-width: var(--max-prose);
  margin: 0 0 var(--space-8) 0;
}
.section-card-grid .card-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-6);
}
.section-card-grid--3up .card-grid {
  grid-template-columns: repeat(3, 1fr);
}
@media (max-width: 900px) {
  .section-card-grid--3up .card-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 640px) {
  .section-card-grid .card-grid,
  .section-card-grid--3up .card-grid { grid-template-columns: 1fr; gap: var(--space-4); }
}

/* ---------------------------------------------------------------------------
   .section-dark-band — slate background, light ink, gold accents. Used for
   "How It Works" steps, methodology framing, contrast breaks. Cards inside
   should use .card.card--dark.
   --------------------------------------------------------------------------- */
.section-dark-band {
  padding: var(--space-24) 0;
  background: var(--bg-slate);
  color: var(--ink-on-dark);
  border-bottom: none;
}
.section-dark-band .section-inner { max-width: var(--max-hero); }
.section-dark-band h2,
.section-dark-band h3 {
  font-family: var(--font-display);
  color: var(--ink-on-dark);
  letter-spacing: var(--tracking-snug);
  margin: 0 0 var(--space-3) 0;
}
.section-dark-band h2 { font-size: var(--fs-2xl); line-height: var(--lh-snug); }
.section-dark-band h3 { font-size: var(--fs-lg); line-height: var(--lh-snug); }
.section-dark-band p {
  font-family: var(--font-sans);
  font-size: var(--fs-md);
  line-height: var(--lh-loose);
  color: var(--ink-on-dark-muted);
  margin: 0 0 var(--space-4) 0;
}
.section-dark-band a:not(.btn):not(.btn-ghost) {
  color: var(--accent-gold-soft);
  text-decoration: underline;
  text-underline-offset: 2px;
  transition: color var(--motion-fast) var(--ease-standard);
}
.section-dark-band a:not(.btn):not(.btn-ghost):hover { color: var(--ink-on-dark); }
.section-dark-band .btn-ghost {
  color: var(--ink-on-dark);
  border-bottom-color: rgba(241, 236, 225, 0.4);
}
.section-dark-band .btn-ghost:hover {
  color: var(--ink-on-dark);
  border-bottom-color: var(--ink-on-dark);
}

/* Steps grid (3-up numbered cards on dark band) */
.section-dark-band .steps-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-6);
  margin-top: var(--space-12);
}
@media (max-width: 760px) {
  .section-dark-band { padding: var(--space-16) 0; }
  .section-dark-band .steps-grid { grid-template-columns: 1fr; gap: var(--space-4); }
}

/* Section adjacency — kill double borders when dark-band sits next to others. */
.section-dark-band + .section,
.section + .section-dark-band { border-top: none; }

/* ---------------------------------------------------------------------------
   .section-stat-block — 4-up numeric credential strip (replaces simple stats
   bar). Display-serif num + sans label per cell; hairline rules between.
   Stacks 2x2 on mid viewports, 1up on small.
   --------------------------------------------------------------------------- */
.section-stat-block {
  padding: var(--space-8) 0;
  background: var(--bg-paper);
  border-bottom: 1px solid var(--gray-300);
}
.section-stat-block .section-inner { max-width: var(--max-hero); }
.section-stat-block .stat-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0;
  font-family: var(--font-sans);
}
.section-stat-block .stat-cell {
  padding: var(--space-2) var(--space-6);
  border-left: 1px solid var(--gray-300);
}
.section-stat-block .stat-cell:first-child { border-left: none; padding-left: 0; }
.section-stat-block .stat-cell .num {
  display: block;
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  font-weight: var(--fw-bold);
  color: var(--ink-primary);
  letter-spacing: var(--tracking-tight);
  line-height: 1;
  margin-bottom: var(--space-2);
}
.section-stat-block .stat-cell .label {
  font-size: var(--fs-xs);
  color: var(--ink-secondary);
  line-height: var(--lh-snug);
  font-weight: var(--fw-medium);
}

@media (max-width: 800px) {
  .section-stat-block .stat-grid { grid-template-columns: repeat(2, 1fr); gap: var(--space-6) 0; }
  .section-stat-block .stat-cell { padding: var(--space-2) var(--space-4); }
  .section-stat-block .stat-cell:nth-child(odd) { border-left: none; padding-left: 0; }
  .section-stat-block .stat-cell:nth-child(even) { border-left: 1px solid var(--gray-300); }
}
@media (max-width: 480px) {
  .section-stat-block .stat-grid { grid-template-columns: 1fr; }
  .section-stat-block .stat-cell { border-left: none !important; padding-left: 0 !important; }
}

/* ---------------------------------------------------------------------------
   .section-cta-closer — final CTA section. Centered eyebrow + h2 + lede +
   .cta-row. Variants: --tinted (warm bg), --dark (slate bg), default (paper).
   --------------------------------------------------------------------------- */
.section-cta-closer {
  padding: var(--space-16) 0;
  text-align: center;
  border-bottom: none;
}
.section-cta-closer .section-inner {
  max-width: var(--max-wide);
  display: flex;
  flex-direction: column;
  align-items: center;
}
.section-cta-closer .eyebrow {
  margin-bottom: var(--space-3);
}
.section-cta-closer h2 {
  font-family: var(--font-display);
  font-size: var(--fs-3xl);
  line-height: var(--lh-tight);
  letter-spacing: var(--tracking-tight);
  color: var(--ink-primary);
  margin: 0 0 var(--space-4) 0;
  max-width: var(--max-wide);
}
.section-cta-closer h2 em {
  color: var(--accent-gold);
  font-style: italic;
}
.section-cta-closer .lede {
  font-family: var(--font-sans);
  font-size: var(--fs-md);
  line-height: var(--lh-loose);
  color: var(--ink-secondary);
  margin: 0 0 var(--space-6) 0;
  max-width: var(--max-prose);
}
.section-cta-closer .cta-row {
  justify-content: center;
  margin-top: 0;
}

/* Tinted variant */
.section-cta-closer--tinted {
  background: var(--bg-paper-warm);
}

/* Dark variant — slate bg, light ink, gold accents */
.section-cta-closer--dark {
  background: var(--bg-slate);
  color: var(--ink-on-dark);
}
.section-cta-closer--dark h2 { color: var(--ink-on-dark); }
.section-cta-closer--dark h2 em { color: var(--accent-gold-soft); }
.section-cta-closer--dark .lede { color: var(--ink-on-dark-muted); }
.section-cta-closer--dark .btn-ghost {
  color: var(--ink-on-dark);
  border-bottom-color: rgba(241, 236, 225, 0.4);
}
.section-cta-closer--dark .btn-ghost:hover {
  color: var(--ink-on-dark);
  border-bottom-color: var(--ink-on-dark);
}

@media (max-width: 760px) {
  .section-cta-closer { padding: var(--space-12) 0; }
  .section-cta-closer h2 { font-size: var(--fs-2xl); }
}


/* ============================================================================
   ACCENT COMPONENTS — Step 6.
   Single-purpose components that compose inside any section. Each is
   independent (no implicit grid), each follows BEM-light modifiers per D28,
   each lands on the strict spacing scale per D29.
   ============================================================================ */

/* ---------------------------------------------------------------------------
   .stat-block — single number + label (single metric callout).
   Composable inside any section. For multi-stat strips use .section-stat-block.
   Variants: --lg (hero-sized number), --accent (gold rule top), --dark (on slate).
   --------------------------------------------------------------------------- */
.stat-block {
  display: block;
  padding: var(--space-4) var(--space-6);
  background: var(--bg-paper);
  border-left: 3px solid var(--gray-300);
  font-family: var(--font-sans);
}
.stat-block .stat-block-num {
  display: block;
  font-family: var(--font-display);
  font-size: var(--fs-2xl);
  font-weight: var(--fw-bold);
  color: var(--ink-primary);
  letter-spacing: var(--tracking-tight);
  line-height: 1;
  margin-bottom: var(--space-2);
}
.stat-block .stat-block-label {
  font-size: var(--fs-xs);
  color: var(--ink-secondary);
  line-height: var(--lh-snug);
  font-weight: var(--fw-medium);
  text-transform: uppercase;
  letter-spacing: 0.1em;
}
.stat-block .stat-block-caption {
  display: block;
  margin-top: var(--space-3);
  font-size: var(--fs-sm);
  color: var(--ink-secondary);
  font-family: var(--font-serif);
  line-height: var(--lh-normal);
}

.stat-block--lg .stat-block-num { font-size: var(--fs-4xl); }
.stat-block--accent {
  border-left: none;
  border-top: 3px solid var(--accent-gold);
  padding-top: var(--space-6);
}
.stat-block--dark {
  background: var(--bg-slate);
  border-left-color: var(--accent-gold);
}
.stat-block--dark .stat-block-num { color: var(--ink-on-dark); }
.stat-block--dark .stat-block-label { color: var(--ink-on-dark-muted); }
.stat-block--dark .stat-block-caption { color: var(--ink-on-dark-muted); }


/* ---------------------------------------------------------------------------
   .timeline — vertical sequence of phases (Week 1 / Week 2 / Day 30, etc.).
   Each item has a marker + label + title + description. Default markers are
   dots on a gold rule. Variants:
   --numbered : marker shows item number instead of a dot
   --dark     : slate bg, light text
   --------------------------------------------------------------------------- */
.timeline {
  list-style: none;
  margin: var(--space-8) 0;
  padding: 0;
  position: relative;
  font-family: var(--font-serif);
  counter-reset: timeline-counter;
}
.timeline::before {
  content: "";
  position: absolute;
  left: 9px;
  top: var(--space-2);
  bottom: var(--space-2);
  width: 1px;
  background: var(--accent-gold);
  opacity: 0.5;
}
.timeline-item {
  position: relative;
  padding: 0 0 var(--space-8) var(--space-8);
  counter-increment: timeline-counter;
}
.timeline-item:last-child { padding-bottom: 0; }
.timeline-marker {
  position: absolute;
  left: 3px;
  top: 6px;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: var(--bg-paper);
  border: 2px solid var(--accent-gold);
  box-shadow: 0 0 0 4px var(--bg-paper);
}
.timeline-label {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--ink-secondary);
  margin-bottom: var(--space-2);
}
.timeline-title {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  color: var(--ink-primary);
  margin: 0 0 var(--space-2) 0;
  letter-spacing: var(--tracking-snug);
  line-height: var(--lh-snug);
}
.timeline-item p {
  margin: 0;
  color: var(--ink-body);
  line-height: var(--lh-normal);
}

.timeline--numbered .timeline-marker {
  width: 24px;
  height: 24px;
  left: -2px;
  top: 0;
  background: var(--accent-gold);
  border: none;
  color: var(--cta-on);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-sans);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  box-shadow: 0 0 0 4px var(--bg-paper);
}
.timeline--numbered .timeline-marker::before { content: counter(timeline-counter); }
.timeline--numbered .timeline-item { padding-left: var(--space-12); }
.timeline--numbered::before { left: 11px; }

.timeline--dark { background: transparent; }
.timeline--dark .timeline-marker {
  background: var(--bg-slate);
  box-shadow: 0 0 0 4px var(--bg-slate);
}
.timeline--dark .timeline-label { color: var(--ink-on-dark-muted); }
.timeline--dark .timeline-title { color: var(--ink-on-dark); }
.timeline--dark .timeline-item p { color: var(--ink-on-dark-muted); }
.timeline--dark.timeline--numbered .timeline-marker {
  background: var(--accent-gold);
  box-shadow: 0 0 0 4px var(--bg-slate);
}


/* ---------------------------------------------------------------------------
   .table--comparison — feature comparison modifier on the .table base.
   Use for "Tool A vs Tool B vs Recommended" decision tables. First column
   left-aligned (feature name); option columns centered. Mark a recommended
   column with .col-recommended on its <th> + matching <td>s.
   Glyphs: .glyph-yes (gold check), .glyph-no (muted dash), .glyph-partial
   (gold open circle). Use as inline content inside <td>.
   --------------------------------------------------------------------------- */
.table--comparison thead th {
  text-align: center;
  vertical-align: bottom;
  padding-top: var(--space-4);
  padding-bottom: var(--space-4);
}
.table--comparison thead th:first-child { text-align: left; }
.table--comparison tbody td {
  text-align: center;
  font-family: var(--font-serif);
  font-size: var(--fs-base);
  color: var(--ink-body);
  text-transform: none;
  letter-spacing: 0;
}
.table--comparison tbody th {
  font-family: var(--font-sans);
  font-weight: var(--fw-semibold);
  color: var(--ink-primary);
  width: 32%;
}
.table--comparison .col-recommended {
  background: var(--bg-paper-warm);
  border-left: 1px solid var(--accent-gold);
  border-right: 1px solid var(--accent-gold);
}
.table--comparison thead th.col-recommended {
  border-top: 3px solid var(--accent-gold);
  color: var(--ink-primary);
}
.table--comparison thead th.col-recommended::after {
  content: "Recommended";
  display: block;
  margin-top: var(--space-1);
  font-family: var(--font-mono);
  font-size: 0.65rem;
  font-weight: var(--fw-medium);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--accent-gold);
}
.table--comparison tbody tr:last-child .col-recommended {
  border-bottom: 1px solid var(--accent-gold);
}
.table--comparison tbody tr:hover { background: transparent; }
.table--comparison tbody tr:hover td:not(.col-recommended) { background: var(--gray-50); }

.glyph-yes,
.glyph-no,
.glyph-partial {
  display: inline-block;
  width: 1em;
  font-family: var(--font-sans);
  font-weight: var(--fw-bold);
  font-size: 1.1em;
  line-height: 1;
}
.glyph-yes { color: var(--accent-gold); }
.glyph-yes::before { content: "✓"; }
.glyph-no { color: var(--gray-700); opacity: 0.55; }
.glyph-no::before { content: "—"; }
.glyph-partial { color: var(--accent-gold); }
.glyph-partial::before { content: "○"; }


/* ---------------------------------------------------------------------------
   .pricing-card — single tier card with price + features list + CTA.
   For multi-tier rows, place 2-3 .pricing-card inside a .section-card-grid
   or any flex/grid container.
   Variants:
   --featured  : gold top rule + 'Recommended' pill, mild elevation
   --dark      : slate bg, light text
   --------------------------------------------------------------------------- */
.pricing-card {
  display: flex;
  flex-direction: column;
  background: var(--bg-paper);
  border: 1px solid var(--gray-300);
  border-radius: var(--radius-sm);
  padding: var(--space-8);
  font-family: var(--font-serif);
  position: relative;
}
.pricing-card-tier {
  font-family: var(--font-sans);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--ink-secondary);
  margin: 0 0 var(--space-2) 0;
}
.pricing-card-name {
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  font-weight: var(--fw-semibold);
  color: var(--ink-primary);
  margin: 0 0 var(--space-3) 0;
  letter-spacing: var(--tracking-snug);
  line-height: var(--lh-snug);
}
.pricing-card-price {
  display: flex;
  align-items: baseline;
  gap: var(--space-1);
  font-family: var(--font-display);
  margin-bottom: var(--space-4);
  color: var(--ink-primary);
}
.pricing-card-price .currency {
  font-size: var(--fs-lg);
  font-weight: var(--fw-medium);
}
.pricing-card-price .amount {
  font-size: var(--fs-3xl);
  font-weight: var(--fw-bold);
  letter-spacing: var(--tracking-tight);
  line-height: 1;
}
.pricing-card-price .interval {
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  color: var(--ink-secondary);
  margin-left: var(--space-1);
}
.pricing-card-prefix {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--ink-secondary);
  margin-bottom: var(--space-2);
}
.pricing-card-summary {
  font-size: var(--fs-base);
  color: var(--ink-secondary);
  line-height: var(--lh-normal);
  margin: 0 0 var(--space-6) 0;
  padding-bottom: var(--space-6);
  border-bottom: 1px solid var(--gray-300);
}
.pricing-card-features {
  list-style: none;
  padding: 0;
  margin: 0 0 var(--space-8) 0;
  flex: 1;
}
.pricing-card-features li {
  position: relative;
  padding: 0 0 var(--space-3) var(--space-6);
  line-height: var(--lh-normal);
  color: var(--ink-body);
}
.pricing-card-features li::before {
  content: "✓";
  position: absolute;
  left: 0;
  top: 0;
  color: var(--accent-gold);
  font-family: var(--font-sans);
  font-weight: var(--fw-bold);
}
.pricing-card .btn { align-self: stretch; justify-content: center; }

.pricing-card--featured {
  border-top: 3px solid var(--accent-gold);
  box-shadow: 0 8px 32px -12px rgba(10, 13, 18, 0.12);
}
.pricing-card--featured::before {
  content: "Recommended";
  position: absolute;
  top: -1px;
  right: var(--space-6);
  transform: translateY(-50%);
  background: var(--accent-gold);
  color: var(--cta-on);
  font-family: var(--font-mono);
  font-size: 0.65rem;
  font-weight: var(--fw-bold);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
}

.pricing-card--dark {
  background: var(--bg-slate-2);
  border-color: rgba(241, 236, 225, 0.12);
}
.pricing-card--dark .pricing-card-tier { color: var(--ink-on-dark-muted); }
.pricing-card--dark .pricing-card-name { color: var(--ink-on-dark); }
.pricing-card--dark .pricing-card-price { color: var(--ink-on-dark); }
.pricing-card--dark .pricing-card-price .interval { color: var(--ink-on-dark-muted); }
.pricing-card--dark .pricing-card-prefix { color: var(--ink-on-dark-muted); }
.pricing-card--dark .pricing-card-summary {
  color: var(--ink-on-dark-muted);
  border-bottom-color: rgba(241, 236, 225, 0.12);
}
.pricing-card--dark .pricing-card-features li { color: var(--ink-on-dark); }


/* ---------------------------------------------------------------------------
   .testimonial — quote + attribution (name / role / firm). Distinct from
   .pull-quote (editorial body-prose blockquote without attribution).
   Variants:
   --card  : white card with mild elevation (use in .section-card-grid)
   --dark  : slate bg variant
   --------------------------------------------------------------------------- */
.testimonial {
  margin: var(--space-8) 0;
  padding: 0 0 0 var(--space-6);
  border-left: 3px solid var(--accent-gold);
  font-family: var(--font-serif);
  max-width: var(--max-prose);
}
.testimonial-quote {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: var(--fs-xl);
  line-height: var(--lh-snug);
  letter-spacing: var(--tracking-snug);
  color: var(--ink-primary);
  margin: 0 0 var(--space-6) 0;
}
.testimonial-quote p { margin: 0 0 var(--space-3) 0; }
.testimonial-quote p:last-child { margin-bottom: 0; }
.testimonial-attribution {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  font-style: normal;
}
.testimonial-photo {
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--gray-50);
}
.testimonial-byline { display: flex; flex-direction: column; line-height: 1.35; }
.testimonial-name {
  font-weight: var(--fw-semibold);
  color: var(--ink-primary);
}
.testimonial-name a {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--rule);
  text-underline-offset: 2px;
}
.testimonial-name a:hover {
  text-decoration-color: var(--accent-gold);
}
.testimonial-role {
  color: var(--ink-secondary);
  font-size: var(--fs-xs);
}

.testimonial--card {
  background: var(--bg-white);
  border: 1px solid var(--gray-300);
  border-left: 3px solid var(--accent-gold);
  border-radius: var(--radius-sm);
  padding: var(--space-8);
  box-shadow: 0 4px 16px -8px rgba(10, 13, 18, 0.08);
}

.testimonial--dark {
  background: var(--bg-slate-2);
  border: 1px solid rgba(241, 236, 225, 0.12);
  border-left: 3px solid var(--accent-gold);
  border-radius: var(--radius-sm);
  padding: var(--space-8);
}
.testimonial--dark .testimonial-quote { color: var(--ink-on-dark); }
.testimonial--dark .testimonial-name { color: var(--ink-on-dark); }
.testimonial--dark .testimonial-role { color: var(--ink-on-dark-muted); }


/* ---------------------------------------------------------------------------
   .alert — inline notice block (info / success / warn / error). Default is
   info. Use for non-blocking messages: form-section context, availability
   note, post-purchase status, etc. For toast/portal extension see D6 —
   --surface-* tokens are portal-ready.
   --------------------------------------------------------------------------- */
.alert {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-6);
  background: var(--gray-50);
  border-left: 3px solid var(--accent-blue);
  border-radius: var(--radius-sm);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  line-height: var(--lh-normal);
  color: var(--ink-body);
  margin: var(--space-4) 0;
}
.alert::before {
  content: "i";
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  margin-top: 1px;
  border-radius: 50%;
  background: var(--accent-blue);
  color: var(--cta-on);
  font-family: var(--font-display);
  font-style: italic;
  font-size: 0.78rem;
  font-weight: var(--fw-bold);
  line-height: 1;
}
.alert-title {
  display: block;
  font-weight: var(--fw-semibold);
  color: var(--ink-primary);
  margin-bottom: var(--space-1);
}
.alert p { margin: 0; }
.alert p + p { margin-top: var(--space-2); }
.alert a { color: inherit; font-weight: var(--fw-semibold); }

.alert--success {
  background: rgba(61, 156, 110, 0.08);
  border-left-color: var(--status-success);
}
.alert--success::before {
  background: var(--status-success);
  content: "✓";
  font-style: normal;
  font-family: var(--font-sans);
}

.alert--warn {
  background: rgba(245, 176, 107, 0.12);
  border-left-color: var(--status-warn);
}
.alert--warn::before {
  background: var(--status-warn);
  color: var(--ink-primary);
  content: "!";
  font-style: normal;
  font-family: var(--font-sans);
}

.alert--error {
  background: rgba(185, 28, 28, 0.06);
  border-left-color: var(--status-error);
}
.alert--error::before {
  background: var(--status-error);
  content: "!";
  font-style: normal;
  font-family: var(--font-sans);
}


/* ---------------------------------------------------------------------------
   .badge — small pill / chip. Use for status indicators, tags, version
   labels, count chips. Default is neutral (paper bg, ink-soft, gray border).
   Variants per D28 BEM-light:
   --accent / --gold / --success / --warn / --error : color variants
   --dot : prepend a status dot before the label (use with any color variant)
   --solid : filled background instead of outlined
   --------------------------------------------------------------------------- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0.18rem var(--space-3);
  background: var(--bg-paper);
  border: 1px solid var(--gray-300);
  border-radius: var(--radius-pill);
  font-family: var(--font-sans);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  color: var(--ink-secondary);
  letter-spacing: 0.04em;
  line-height: 1.4;
  white-space: nowrap;
}
.badge--accent  { color: var(--accent-blue);   border-color: var(--accent-blue); }
.badge--gold    { color: var(--accent-gold);   border-color: var(--accent-gold); }
.badge--success { color: var(--status-success); border-color: var(--status-success); }
.badge--warn    { color: var(--status-warn);   border-color: var(--status-warn); }
.badge--error   { color: var(--status-error); border-color: var(--status-error); }

.badge--solid                 { background: var(--ink-secondary); color: var(--cta-on); border-color: transparent; }
.badge--solid.badge--accent   { background: var(--accent-blue);   color: var(--cta-on); }
.badge--solid.badge--gold     { background: var(--accent-gold);   color: var(--cta-on); }
.badge--solid.badge--success  { background: var(--status-success); color: var(--cta-on); }
.badge--solid.badge--warn     { background: var(--status-warn);   color: var(--ink-primary); }
.badge--solid.badge--error    { background: var(--status-error);  color: var(--cta-on); }

.badge--dot::before {
  content: "";
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}
.badge--dot.badge--success::before { box-shadow: 0 0 0 3px rgba(61, 156, 110, 0.18); }
.badge--dot.badge--warn::before    { box-shadow: 0 0 0 3px rgba(245, 176, 107, 0.22); }
.badge--dot.badge--error::before   { box-shadow: 0 0 0 3px rgba(185, 28, 28, 0.16); }

/* ============================================================
   MOTION — scroll-reveal hook (driven by /motion.js)

   Add `.reveal` to any element you want to fade-and-rise into
   view as the user scrolls. Optional direction modifiers shift
   the start position. Optional `--delay-N` modifiers stagger
   adjacent reveals (80ms steps).

   Honors `prefers-reduced-motion: reduce` — under reduce, the
   .reveal start state is identity (no opacity, no transform)
   so reduced-motion users never see flicker even before
   motion.js attaches.
   ============================================================ */

.reveal {
  opacity: 0;
  transform: translate3d(0, 24px, 0);
  transition:
    opacity 1100ms var(--ease-out),
    transform 1100ms var(--ease-out);
  will-change: opacity, transform;
}
.reveal.is-revealed {
  opacity: 1;
  transform: translate3d(0, 0, 0);
}

.reveal--up   { transform: translate3d(0, 24px, 0); }
.reveal--down { transform: translate3d(0, -24px, 0); }
.reveal--left { transform: translate3d(24px, 0, 0); }
.reveal--right{ transform: translate3d(-24px, 0, 0); }
.reveal--fade { transform: none; }

.reveal--delay-1 { transition-delay: 140ms; }
.reveal--delay-2 { transition-delay: 280ms; }
.reveal--delay-3 { transition-delay: 420ms; }
.reveal--delay-4 { transition-delay: 560ms; }
.reveal--delay-5 { transition-delay: 700ms; }

@media (prefers-reduced-motion: reduce) {
  .reveal,
  .reveal--up,
  .reveal--down,
  .reveal--left,
  .reveal--right,
  .reveal--fade {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .reveal--delay-1,
  .reveal--delay-2,
  .reveal--delay-3,
  .reveal--delay-4,
  .reveal--delay-5 { transition-delay: 0s; }
}

/* No-JS safety — motion.js applies the hidden state and then reveals it by
   adding `.is-revealed`. With scripting disabled, motion.js never runs and the
   reduced-motion query does not match, so without this every author-applied
   `.reveal` (and the hero data-polygon) would stay permanently invisible.
   `@media (scripting: none)` matches exactly when JS is off (and in print
   snapshots) — show everything immediately so non-JS users see all content.
   `!important` makes it order-independent vs the later `.data-poly` base rule;
   it only ever applies when scripting is off, so JS-on rendering is untouched. */
@media (scripting: none) {
  .reveal,
  .reveal--up,
  .reveal--down,
  .reveal--left,
  .reveal--right,
  .reveal--fade { opacity: 1 !important; transform: none !important; transition: none !important; }
  .brand-graphic .data-poly { opacity: 1 !important; }
}

/* ============================================================
   STICKY MOBILE CTA — fixed bottom bar shown <= 760px wide.
   JS toggles `.is-visible` (or legacy `.visible`) once the
   in-page hero CTA leaves the viewport. The bar slides up from
   below.

   Safe-area-inset on three sides keeps the inner button
   centered between the iOS home indicator (bottom) and the
   landscape camera notch (left/right). On non-notched devices
   max() falls back to the floor padding values so behavior is
   unchanged.
   ============================================================ */

.sticky-cta-mobile {
  display: none;
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: var(--z-sticky-cta);
  background: var(--bg-primary);
  border-top: 1px solid var(--rule);
  padding-top: var(--space-3);
  padding-bottom: max(var(--space-3), env(safe-area-inset-bottom));
  padding-left: max(var(--space-4), env(safe-area-inset-left));
  padding-right: max(var(--space-4), env(safe-area-inset-right));
  text-align: center;
  box-shadow: 0 -2px 16px rgba(10, 13, 18, 0.06);
  transform: translateY(100%);
  transition: transform var(--motion-medium) var(--ease-out);
}
.sticky-cta-mobile.is-visible,
.sticky-cta-mobile.visible { transform: translateY(0); }
.sticky-cta-mobile .btn {
  width: 100%;
  padding: var(--space-3) var(--space-4);
  font-size: var(--fs-base);
  justify-content: center;
}

@media (max-width: 760px) {
  .sticky-cta-mobile { display: block; }
  /* D89 (2026-05-09): On pages that mount the Tyred Bot, the bot itself
     does the conversion-grab work that the sticky CTA used to do. We
     can't have both — they collide visually at the bottom of the viewport
     and the bot wins because it's higher z-index + more capable. The
     `body.has-tyred-bot` class is added by tyred-bot.js on mount. */
  body.has-tyred-bot .sticky-cta-mobile { display: none !important; }
}

@media (prefers-reduced-motion: reduce) {
  .sticky-cta-mobile { transition: none; }
}


/* ============================================================
   COST CALCULATOR — interactive "cost of doing nothing"
   ============================================================
   This block is the SINGLE SOURCE OF TRUTH for the cost calculator
   appearance. The component is rendered on:
     - /index.html              (homepage cost section)
     - /audit/index.html        (audit page cost section)
   Both pages share this CSS + /cost-calculator.js. The HTML markup
   is currently duplicated across both pages — when updating markup,
   edit BOTH index.html and audit/index.html so they stay in sync,
   and update the markup contract block below to match.

   Markup contract (two sliders: team size + workload intensity):

   <div class="cost-calculator" data-cost-calc
        data-weeks="50" data-hourly-cost="50">
     <div class="cost-counters">
       <div class="cost-counter">
         <div class="cost-counter-label">Lost annually</div>
         <div class="cost-counter-value" data-cost-money>$0</div>
       </div>
       <div class="cost-counter">
         <div class="cost-counter-label">Months back per person</div>
         <div class="cost-counter-value" data-cost-months>0.0</div>
       </div>
     </div>
     <div class="cost-slider-wrap">
       <label class="cost-slider-label" for="cost-employees-N">
         Employees
         <span class="cost-slider-value" data-cost-employees>25</span>
       </label>
       <input class="cost-slider" type="range" id="cost-employees-N"
              min="1" max="500" value="25" step="1" data-cost-input-employees>
       <div class="cost-slider-scale">
         <span>1</span><span>100</span><span>500</span>
       </div>
     </div>
     <div class="cost-slider-wrap">
       <label class="cost-slider-label" for="cost-workload-N">
         How much can AI handle?
         <span class="cost-slider-value" data-cost-workload-label>Some</span>
       </label>
       <p class="cost-slider-help">
         Admin, drafting, reporting, research &mdash; anything an LLM can already do.
       </p>
       <input class="cost-slider" type="range" id="cost-workload-N"
              min="1" max="5" value="3" step="1" data-cost-input-workload
              data-workload-hours="1,3,5,8,12"
              data-workload-labels="Almost none,A little,Some,A lot,Tons">
       <div class="cost-slider-scale">
         <span>Almost none</span><span>Some</span><span>Tons</span>
       </div>
     </div>
     <p class="cost-calculator-note" data-cost-note>
       Math: 5 hrs/wk &times; 50 wks &times; $50/hr per employee.
     </p>
   </div>

   Driver: /cost-calculator.js reads data-weeks + data-hourly-cost
   on the root, and data-workload-hours / data-workload-labels on
   the workload input. data-cost-money scales with employees AND
   workload; data-cost-months is the per-employee figure (constant
   at hoursPerWeek * weeks / 160 — "each of your people could get
   this many months back" framing). 1 month = 160 hrs (4 wks * 40).
   CSS exposes --cost-pct on each slider for the gold fill; JS sets
   it via inline style on input.
   ============================================================ */

.cost-calculator {
  --cost-pct: 5%;
  background: var(--bg-primary);
  border: 1px solid var(--rule);
  border-radius: var(--radius-md);
  padding: var(--space-8) var(--space-8) var(--space-6);
  box-shadow: 0 4px 24px rgba(10, 13, 18, 0.05);
  max-width: 44rem;
  margin: 0 auto;
  /* D-OVERFLOW-FIX (2026-06-05): .cost-calculator is a direct grid item of
     .cost-grid, so its default min-width:auto resolved to min-content. The
     11ch value reserve below pushed that min-content to ~792px, overriding
     max-width:44rem and bleeding 31px off the page edge at 1512px. min-width:0
     lets it shrink to its column (capped by max-width). */
  min-width: 0;
}
.cost-counters {
  display: grid;
  /* minmax(0,1fr) → true equal halves that content can't expand. With Space
     Grotesk's wider tabular digits, plain 1fr let the long "$15,000,000" value
     push its track and grow the whole calculator (shifting the slider). */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-8);
  margin-bottom: var(--space-8);
  text-align: center;
  min-width: 0;
}
/* D196 (2026-05-12): lock counter dimensions so the box doesn't reflow as the
   slider sweeps. .cost-counter min-height stabilizes vertical bounds; label
   min-height + flex-end alignment keeps value baselines aligned whether label
   is 1 or 2 lines ("Lost annually" vs "Months back per person"); nowrap on
   value prevents wrap-to-2-lines at $1M.
   D200 (2026-05-12): D196 left a horizontal-shift bug — grid track 1fr was
   re-auto-mining off content width as value grew from $0 to $1M+, pushing
   the slider track left/right. Fix is to pre-reserve max-content horizontal
   space on the value element itself. Max possible value at this calc
   (500 empl × 12 hr/wk × 50 wks × $50/hr) = $15,000,000 = 11 chars. We
   reserve 11ch on the value so the grid cell auto-min is constant from $0
   through $15M, and dropped min-width:0 on .cost-counter so grid tracks
   stably size to that pre-reserved max. */
/* D-OVERFLOW-FIX (2026-06-05) supersedes the D200 approach: restoring
   min-width:0 on .cost-counter makes the two 1fr tracks pure equal halves
   (content-independent), so the slider track no longer shifts as the value
   grows — the same goal D200 chased with the 11ch reserve, but without forcing
   the calculator's min-content past its 44rem cap. The 11ch reserve is removed
   on .cost-counter-value below; a clamp() keeps even the $15M extreme inside
   its half-cell. */
.cost-counter {
  min-height: 5.5rem;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-width: 0;
}
.cost-counter-label {
  font-family: var(--font-sans);
  font-size: 0.78rem;
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  margin-bottom: var(--space-2);
  min-height: 2.2em;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
.cost-counter-value {
  font-family: var(--font-display);
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--gold);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  white-space: nowrap;
  /* clamp lets the big-dollar value scale down on tighter widths so it never
     spills its half-cell; stays 3rem on full-width desktop. */
  font-size: clamp(1.6rem, 2.6vw, 2.25rem); /* capped so the longest "$15,000,000" fits a locked half-cell in Space Grotesk */
  min-width: 0;
  max-width: 100%;
  display: inline-block;
  text-align: center;
  align-self: center;
}
.cost-slider-wrap { margin-top: var(--space-6); }
.cost-slider-label {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  color: var(--ink);
  margin-bottom: var(--space-3);
  gap: var(--space-4);
}
.cost-slider-value {
  font-family: var(--font-display);
  font-size: 1.6rem;
  color: var(--gold);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  line-height: 1;
}

/* Custom-styled range input.
   Track fill uses linear-gradient driven by --cost-pct (set by JS).
   Vendor pseudos can't share rules — duplicated for -webkit / -moz. */
.cost-slider {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 6px;
  border-radius: 3px;
  background: linear-gradient(
    to right,
    var(--gold) 0%,
    var(--gold) var(--cost-pct),
    var(--rule) var(--cost-pct),
    var(--rule) 100%
  );
  outline: none;
  cursor: pointer;
  margin: var(--space-2) 0;
}
.cost-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--gold);
  border: 3px solid var(--bg-primary);
  box-shadow: 0 2px 6px rgba(10, 13, 18, 0.18);
  cursor: grab;
  transition: transform var(--motion-fast) var(--ease-out);
}
.cost-slider::-moz-range-thumb {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--gold);
  border: 3px solid var(--bg-primary);
  box-shadow: 0 2px 6px rgba(10, 13, 18, 0.18);
  cursor: grab;
  transition: transform var(--motion-fast) var(--ease-out);
}
.cost-slider:active::-webkit-slider-thumb { transform: scale(1.15); cursor: grabbing; }
.cost-slider:active::-moz-range-thumb { transform: scale(1.15); cursor: grabbing; }
.cost-slider:focus-visible::-webkit-slider-thumb {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
}
.cost-slider:focus-visible::-moz-range-thumb {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
}

.cost-slider-scale {
  display: flex;
  justify-content: space-between;
  font-family: var(--font-sans);
  font-size: 0.78rem;
  color: var(--ink-soft);
  margin-top: var(--space-2);
  font-variant-numeric: tabular-nums;
  /* Inset tick labels from card edge so they don't kiss the card padding line */
  padding-inline: 0.25rem;
}
.cost-slider-help {
  font-family: var(--font-sans);
  font-size: 0.85rem;
  color: var(--ink-soft);
  line-height: 1.4;
  margin: 0 0 var(--space-2) 0;
}
.cost-calculator-note {
  margin: var(--space-6) 0 0 0;
  font-family: var(--font-sans);
  font-size: 0.85rem;
  color: var(--ink-soft);
  text-align: center;
  /* Better line breaks at narrow widths — avoids "per\nemployee." orphan */
  text-wrap: pretty;
}

@media (max-width: 640px) {
  /* Premium-feel mobile: card gets breathing room inside AND outside.
     UNIVERSAL SELECTOR — :has() targets any wrap (.wrap-hero on the
     homepage, .wrap-wide on the audit page, etc.) that hosts the
     cost-calculator. Add new pages without touching this rule. */
  .wrap-hero:has(.cost-calculator),
  .wrap-wide:has(.cost-calculator) {
    padding-inline: var(--space-4);
  }
  .cost-calculator {
    padding: var(--space-6);
    border-radius: 10px;
  }
  /* Stack the two counters vertically with generous separation between
     pairs. Each label-value group reads as ONE unit (tight 12px internal
     gap), and pairs are separated by 32px + a hairline rule for clarity.
     Premium-feel principle: the eye should immediately know which label
     belongs to which value. */
  .cost-counters {
    grid-template-columns: 1fr;
    gap: var(--space-8);
    margin-bottom: var(--space-6);
  }
  /* D196 (2026-05-12): release desktop dimension-lock on mobile — stacked
     cards don't need horizontal-symmetry alignment between counters, and
     the desktop 5.5rem min-height would add empty space at the smaller
     mobile font sizes. nowrap on the value still applies (inherited). */
  .cost-counter { min-height: auto; }
  .cost-counter + .cost-counter {
    border-top: 1px solid var(--rule);
    padding-top: var(--space-6);
  }
  .cost-counter-label {
    font-size: 0.72rem;
    margin-bottom: var(--space-3);
    min-height: auto;
  }
  .cost-counter-value { font-size: 2.2rem; }
  /* Slider label: allow wrap so the value doesn't shove the label off-screen.
     Value is sized close to the label (1.05rem vs 0.95rem) so when it does
     wrap, it sits as a quiet inline-end note instead of a big gold heading.
     Baseline alignment matches the desktop default — keeps the label/value
     pair feeling typographically connected. */
  .cost-slider-label {
    font-size: 0.95rem;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-3);
    align-items: baseline;
    margin-bottom: var(--space-2);
  }
  .cost-slider-value { font-size: 1.05rem; }
  .cost-slider-wrap {
    margin-top: var(--space-6);
    /* Inset the slider so the thumb at min/max doesn't kiss the card edge */
    padding-inline: 0.25rem;
  }
  .cost-slider-help { font-size: 0.82rem; margin-bottom: var(--space-3); }
  /* Bigger touch target on mobile */
  .cost-slider { height: 8px; margin: var(--space-3) 0; }
  .cost-slider::-webkit-slider-thumb { width: 28px; height: 28px; }
  .cost-slider::-moz-range-thumb { width: 28px; height: 28px; }
  /* Scale endpoints — keep readable, don't let middle label crowd the edges */
  .cost-slider-scale {
    font-size: 0.72rem;
    margin-top: var(--space-3);
    line-height: 1.3;
    padding-inline: 0.5rem;
  }
  .cost-slider-scale span:first-child { text-align: left; }
  .cost-slider-scale span:last-child { text-align: right; }
}

@media (max-width: 380px) {
  /* iPhone SE width: keep card visually inset, never let content
     touch the screen edge. Same universal :has() pattern as above. */
  .wrap-hero:has(.cost-calculator),
  .wrap-wide:has(.cost-calculator) {
    padding-inline: var(--space-3);
  }
  .cost-calculator {
    padding: var(--space-4);
    border-radius: 10px;
  }
  .cost-counter-value { font-size: 2rem; }
  .cost-slider-value { font-size: 1rem; }
  .cost-slider-scale { font-size: 0.68rem; padding-inline: 0.375rem; }
}

@media (prefers-reduced-motion: reduce) {
  .cost-slider::-webkit-slider-thumb { transition: none; }
  .cost-slider::-moz-range-thumb { transition: none; }
}

/* ----------------------------------------------------------------------------
   ILLUSTRATIONS — Tier-A editorial line-art (D40)
   M1 (/methodology/), AU1 (/audit/), BS1 (/build-sprint/).
   Each SVG lives at /assets/illustrations/. Embedded via <img> in a
   .illustration-figure wrapper inside a light-background section.
   Ink strokes are #0a0d12 — these illustrations are designed for paper/light
   backgrounds only; do NOT place them inside .dark sections.
   ---------------------------------------------------------------------------- */
.illustration-figure {
  margin: 0 auto;
  max-width: 720px;
  padding: 0;
}
.illustration-figure img {
  display: block;
  width: 100%;
  height: auto;
}
.illustration-section {
  padding: var(--space-8) 0 var(--space-6) 0;
}
@media (max-width: 640px) {
  .illustration-section { padding: var(--space-6) 0 var(--space-4) 0; }
}


/* ============================================================================
   REBRAND MOTION + GRAPHICS LAYER (cinematic reveals, precise easing).
   Reusable primitives productionized from brand-hero-preview.html. Behaviors
   are driven by /motion.js. Everything here is transform/opacity only and is
   fully neutralized under prefers-reduced-motion: reduce. Drop the classes on
   any page's hero — they are NOT one-offs.
   ============================================================================ */

/* Thin scroll-progress bar — motion.js auto-injects <div class="scroll-progress">
   on pages that contain a hero (.hero / .hero-home / .section-hero). */
.scroll-progress {
  position: fixed;
  top: 0;
  left: 0;
  height: 3px;
  width: 0;
  background: var(--accent-blue); /* brass */
  z-index: 60;
  pointer-events: none;
  transition: width 80ms linear;
}

/* Atmospheric brass/espresso gradient field behind heroes (graphic I2).
   Host element must be position:relative + overflow:hidden; place hero content
   above it with position:relative; z-index:2. */
.hero-aurora {
  position: absolute;
  inset: -15%;
  z-index: 0;
  pointer-events: none;
}
.hero-aurora .blob {
  position: absolute;
  border-radius: 50%;
  filter: blur(72px);
  opacity: 0.5;
  will-change: transform;
}
/* Continuous, slow "lava-lamp" drift — the hero field is always gently moving.
   Distinct durations so the blobs never sync (organic). Transform-only / GPU. */
.hero-aurora .blob-1 { width: 44vw; height: 44vw; background: var(--accent-blue); opacity: 0.6; top: -8%; left: -6%; animation: drift-a 26s ease-in-out infinite alternate; }
.hero-aurora .blob-2 { width: 40vw; height: 40vw; background: var(--rust, #A85230); top: 22%; right: -8%; opacity: 0.5; animation: drift-b 33s ease-in-out infinite alternate; }
.hero-aurora .blob-3 { width: 34vw; height: 34vw; background: #2F4738; bottom: -14%; left: 28%; opacity: 0.5; animation: drift-c 39s ease-in-out infinite alternate; } /* pine */
.hero-aurora .mesh {
  position: absolute;
  inset: 0;
  opacity: 0.5;
  background-image:
    radial-gradient(circle at 50% 42%, rgba(216, 164, 92, 0.12) 0, transparent 60%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='44' height='44'%3E%3Cpath d='M44 0H0v44' fill='none' stroke='%234A3D31' stroke-width='.5' opacity='.5'/%3E%3C/svg%3E");
}

/* Site-wide ambient field — a fixed, slow-drifting gradient behind ALL content
   (motion.js auto-injects <div class="ambient-field"> on every page). Plain
   (transparent) sections reveal it; tinted/dark bands cover it, giving rhythm.
   This is what keeps the whole site gently alive — "lava-lamp" slow. */
.ambient-field {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  overflow: hidden;
}
.ambient-field .ab {
  position: absolute;
  border-radius: 50%;
  filter: blur(74px);  /* tighter than a flat field so the orbs read as orbs */
  will-change: transform;
}
.ambient-field .ab-1 { width: 46vw; height: 46vw; background: var(--accent-blue); opacity: 0.30; top: -10%; left: -8%;   animation: drift-a 34s ease-in-out infinite alternate; }
.ambient-field .ab-2 { width: 42vw; height: 42vw; background: var(--rust, #A85230); opacity: 0.24; bottom: -12%; right: -8%; animation: drift-b 41s ease-in-out infinite alternate; }
.ambient-field .ab-3 { width: 40vw; height: 40vw; background: #2F4738;          opacity: 0.22; top: 34%; left: 42%;     animation: drift-c 47s ease-in-out infinite alternate; }

/* Shared drift keyframes (organic, return-friendly via ease-in-out + alternate). */
@keyframes drift-a { from { transform: translate3d(0,0,0) scale(1); } to { transform: translate3d(13vw, 10vh, 0) scale(1.25); } }
@keyframes drift-b { from { transform: translate3d(0,0,0) scale(1); } to { transform: translate3d(-11vw, -8vh, 0) scale(1.18); } }
@keyframes drift-c { from { transform: translate3d(0,0,0) scale(1); } to { transform: translate3d(9vw, -11vh, 0) scale(0.82); } }

/* Headline line-mask reveal (cinematic). Markup:
     <h1 class="headline-reveal">
       <span class="line"><span class="in">First line.</span></span>
       <span class="line"><span class="in"><em>Brass</em> second.</span></span>
     </h1>
   The .in element rises out of the clipped .line on load. */
.headline-reveal .line { display: block; overflow: hidden; }
.headline-reveal .line .in {
  display: block;
  transform: translateY(115%);
  animation: headline-rise var(--motion-slow) var(--ease-out) both;
}
.headline-reveal .line:nth-child(1) .in { animation-delay: 0.10s; }
.headline-reveal .line:nth-child(2) .in { animation-delay: 0.22s; }
.headline-reveal .line:nth-child(3) .in { animation-delay: 0.34s; }
.headline-reveal em { font-style: normal; color: var(--accent-blue); } /* brass emphasis */
@keyframes headline-rise { to { transform: translateY(0); } }

/* Card hover — lift + brass GLOW. On dark, a light glow reads where the old
   dark drop-shadows vanished. Applies to the canonical .card kit. */
.card,
.card--elevated,
.pricing-card,
.testimonial--card {
  transition:
    transform var(--motion-medium) var(--ease-out),
    box-shadow var(--motion-medium) var(--ease-out),
    border-color var(--motion-medium) var(--ease-out);
}
.card:hover,
.card--elevated:hover,
.pricing-card:hover,
.testimonial--card:hover {
  transform: translateY(-4px);
  border-color: var(--accent-blue);
  box-shadow: 0 0 0 1px rgba(216, 164, 92, 0.45), 0 20px 52px -18px rgba(216, 164, 92, 0.24);
}

/* Brand graphic — 5-dimension radar (hero visual). The outer ring rotates slowly
   like a gear; the inner data polygon continuously MORPHS between score profiles
   (SMIL animate on the points — "as if different people's results"). It fades in
   when revealed (motion.js adds .is-revealed; it also pauses the SMIL under
   reduced motion). No pulsing dots. */
.brand-graphic { position: relative; width: 100%; max-width: 460px; margin: 0 auto; aspect-ratio: 1 / 1; }
.brand-graphic > svg { width: 100%; height: 100%; overflow: visible; display: block; }
.brand-graphic .web { transform-box: view-box; transform-origin: 50% 50%; animation: graphic-spin 60s linear infinite; }
.brand-graphic .data-poly {
  opacity: 0;
  transition: opacity 1.1s var(--ease-out) .25s;
}
.brand-graphic.is-revealed .data-poly { opacity: 1; }
@keyframes graphic-spin { to { transform: rotate(360deg); } }

/* --- Build Sprint variant: a workflow PIPELINE assembling. The brass line draws
   itself along the circuit (the workflow being built), step nodes flash as the
   signal passes, and a signal dot travels the path. Tells the "ship one workflow
   end-to-end" story (not a measurement radar). */
.brand-graphic--flow .flow-track { stroke: var(--gray-300); stroke-width: 2; fill: none; }
.brand-graphic--flow .flow-build {
  stroke: var(--accent-blue); stroke-width: 2.5; fill: none; stroke-linecap: round;
  /* one glowing segment travels the path continuously — no redraw reset, so the
     motion stays smooth. pathLength=100 on the <path> normalizes these to %, and
     the path starts off-canvas so the signal rolls in from off-page. */
  stroke-dasharray: 16 84;
  stroke-dashoffset: 100;
  animation: flow-move 5.4s linear infinite;
}
.brand-graphic--flow .flow-endzone {
  fill: none; stroke: var(--accent-blue); stroke-width: 1.5;
  transform-box: view-box; transform-origin: 128px 166px;
  animation: flow-endzone 5.4s ease-in-out infinite;
}
@keyframes flow-endzone { 0%, 55% { opacity: 0.18; transform: scale(0.8); } 82% { opacity: 0.7; transform: scale(1.12); } 100% { opacity: 0.18; transform: scale(0.8); } }
/* The idea forms at the top — core pulses, rays burst — then the signal flows
   down the natural path into the build pipeline. */
.brand-graphic--flow .flow-idea-core { fill: var(--accent-gold); animation: idea-core 5.4s ease-in-out infinite; }
.brand-graphic--flow .flow-idea-ray {
  stroke: var(--accent-gold); stroke-width: 2; stroke-linecap: round;
  transform-box: view-box; transform-origin: 100px 38px;
  animation: idea-ray 5.4s ease-in-out infinite;
}
@keyframes idea-core { 0% { opacity: .3; } 12% { opacity: 1; } 32%, 100% { opacity: .55; } }
@keyframes idea-ray { 0%, 3% { opacity: 0; transform: scale(.3); } 12% { opacity: .9; transform: scale(1); } 26%, 100% { opacity: 0; transform: scale(1.25); } }

/* --- Individual variant: a radial SCORE GAUGE that gently breathes around a
   high score (your personal read). --- */
.brand-graphic--gauge .gauge-track { stroke: var(--gray-300); stroke-width: 9; opacity: 0.55; }
.brand-graphic--gauge .gauge-arc {
  stroke: var(--accent-blue); stroke-width: 9; stroke-linecap: round;
  stroke-dasharray: 100; stroke-dashoffset: 100;
  animation: gauge-fill 6s ease-in-out infinite alternate;
}
.brand-graphic--gauge .gauge-tick { stroke: var(--accent-gold); stroke-width: 2.2; opacity: 0.6; }
.brand-graphic--gauge .gauge-core { stroke: var(--accent-blue); fill: none; animation: gauge-core 6s ease-in-out infinite; }
@keyframes gauge-fill { 0% { stroke-dashoffset: 42; } 100% { stroke-dashoffset: 25; } }
@keyframes gauge-core { 0%, 100% { opacity: 0.14; } 50% { opacity: 0.4; } }

/* --- Company variant: a DUAL radar — leaders' read (brass, outer) vs operators'
   read (rust, inner). The GAP between them is the page's pitch; both morph slowly
   (SMIL on points) so the gap shifts. Grid + ring reused from the radar. --- */
.brand-graphic--gap { /* polygons are visible by default; the gap is the story */ }

/* --- Quiz variant: a SCORECARD of 5 bars filling fast — light + inviting. --- */
.brand-graphic--bars .bar-track { fill: var(--gray-300); opacity: 0.5; }
.brand-graphic--bars .bar-fill {
  fill: var(--accent-blue); transform-box: fill-box; transform-origin: left center;
  transform: scaleX(0); animation: bar-fill 4.6s cubic-bezier(.16,1,.3,1) infinite;
}
.brand-graphic--bars .bar-fill.b1 { --lvl: 0.86; animation-delay: 0.0s; }
.brand-graphic--bars .bar-fill.b2 { --lvl: 0.54; animation-delay: 0.18s; }
.brand-graphic--bars .bar-fill.b3 { --lvl: 0.72; animation-delay: 0.36s; }
.brand-graphic--bars .bar-fill.b4 { --lvl: 0.40; animation-delay: 0.54s; }
.brand-graphic--bars .bar-fill.b5 { --lvl: 0.64; animation-delay: 0.72s; }
.brand-graphic--bars .bar-dot { fill: var(--accent-gold); }
@keyframes bar-fill { 0% { transform: scaleX(0); } 28%, 82% { transform: scaleX(var(--lvl, 0.6)); } 100% { transform: scaleX(0); } }
.brand-graphic--flow .flow-node {
  fill: var(--bg-white); stroke: var(--accent-blue); stroke-width: 2;
  animation: flow-node 5.4s ease-in-out infinite;
}
.brand-graphic--flow .flow-node:nth-of-type(1) { animation-delay: 1.8s; }
.brand-graphic--flow .flow-node:nth-of-type(2) { animation-delay: 3.0s; }
.brand-graphic--flow .flow-node:nth-of-type(3) { animation-delay: 4.1s; }
.brand-graphic--flow .flow-node:nth-of-type(4) { animation-delay: 4.9s; }
/* hold at the start while the idea forms, then the signal flows down the path */
@keyframes flow-move { 0%, 16% { stroke-dashoffset: 100; } 100% { stroke-dashoffset: 0; } }
@keyframes flow-node { 0%, 32%, 100% { fill: var(--bg-white); } 50% { fill: var(--accent-blue); } }

/* Reusable brand hero — atmospheric field + a brand graphic beside the copy.
   Markup: <section class="hero hero-brand"> <div class="hero-aurora">…</div>
   <div class="wrap-*"> <div class="hero-split-2"> <div class="hero-copy">…</div>
   <div class="hero-graphic-wrap brand-graphic">…svg…</div> </div></div></section> */
.hero-brand { position: relative; overflow: hidden; }
.hero-brand > .wrap-wide,
.hero-brand > .wrap-full,
.hero-brand > .wrap-hero,
.hero-brand > .wrap { position: relative; z-index: 1; }
.hero-split-2 { display: grid; grid-template-columns: minmax(0, 1fr) 330px; gap: 2.6rem; align-items: center; }
.hero-split-2 .hero-graphic-wrap { width: 100%; max-width: 320px; margin: 0 auto; }
@media (max-width: 880px) {
  .hero-split-2 { grid-template-columns: 1fr; gap: 1.4rem; }
  .hero-split-2 .hero-graphic-wrap { max-width: 230px; }
}

/* Warm-duotone treatment (graphic I1) for photos of Nathanael. Add .photo-duotone
   to the position:relative frame that wraps the <img>. */
.photo-duotone { position: relative; }
.photo-duotone::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(150deg, rgba(216, 164, 92, 0.20), rgba(33, 25, 19, 0.28) 58%, rgba(111, 106, 58, 0.18));
  mix-blend-mode: soft-light;
  pointer-events: none;
}

/* On-brand text selection (was the default browser highlight). */
::selection { background: var(--accent-blue); color: var(--cta-on); }

@media (prefers-reduced-motion: reduce) {
  .scroll-progress { display: none; }
  .ambient-field { display: none; }
  .hero-aurora .blob,
  .ambient-field .ab,
  .brand-graphic .web { animation: none; }
  .brand-graphic--flow .flow-node,
  .brand-graphic--flow .flow-endzone,
  .brand-graphic--flow .flow-idea-core,
  .brand-graphic--flow .flow-idea-ray { animation: none; }
  .brand-graphic--flow .flow-build { animation: none; stroke-dasharray: none; }
  .brand-graphic--gauge .gauge-arc { animation: none; stroke-dashoffset: 28; }
  .brand-graphic--gauge .gauge-core { animation: none; }
  .brand-graphic--bars .bar-fill { animation: none; transform: scaleX(var(--lvl, 0.6)); }
  .headline-reveal .line .in { transform: none; animation: none; }
  .brand-graphic .data-poly { opacity: 1; }
  .card:hover,
  .card--elevated:hover,
  .pricing-card:hover,
  .testimonial--card:hover { transform: none; }
}
