/* ============================================================
   ObserveCo Consulting — draft site stylesheet
   Consulting design system (design/consulting-tokens.css):
   light-first paper canvas, insight teal accent, serif display
   authority, mono demoted to labels + data, editorial spacing,
   tinted status chips. Same class contract — visual only.

   Brand: "ObserveCo" is the WORKING title. D1 (brand decision)
   is pending. Tokens live here so the brand can be swapped
   globally without structural change.

   Type: serif display (system stack) · Inter (body) · JetBrains Mono (data/labels)
   Dials: VARIANCE 5 / MOTION 2 / DENSITY 3
   ============================================================ */
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }

:root {
  /* Surfaces — light-first paper canvas (consulting-tokens.css) */
  --bg: #f7f6f3;              /* page canvas — bond paper */
  --surface: #ffffff;         /* cards, panels */
  --surface-2: #f1f0ec;       /* nested elevation */
  --border: #e4e2dc;          /* hairline */
  --border-subtle: #efeee9;   /* lighter hairline */

  /* Single accent — insight teal (differentiation brand) */
  --green: #0e6e5c;           /* insight teal, AA on paper */
  --green-hover: #0a5447;
  --green-dim: rgba(14, 110, 92, 0.08);

  /* Complementary warm — coral (before/negative states, data-viz contrast) */
  --coral: #b84a2f;           /* warm complement to teal, AA on paper */
  --coral-hover: #9c3d25;
  --coral-dim: rgba(184, 74, 47, 0.10);
  --amber: #c99a3f;           /* secondary warm accent (trends, markers) */

  /* Neutrals — ink on paper */
  --fg: #1b1f24;
  --fg-2: #4a525c;
  --fg-3: #6b737e;
  --fg-muted: #8a929c;

  /* Type */
  --font-display: 'Iowan Old Style', 'Palatino Linotype', 'Book Antiqua', Palatino, Georgia, 'Times New Roman', serif;
  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, monospace;

  --radius: 10px;
  --radius-lg: 14px;
  --maxw: 1120px;

  --space-1: 8px;
  --space-2: 16px;
  --space-3: 24px;
  --space-4: 40px;
  --space-5: 64px;
  --space-6: 88px;
}

html { scroll-behavior: smooth; }

body {
  font-family: var(--font-sans);
  background: var(--bg);
  color: var(--fg);
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  font-size: 17px;
}

.container { max-width: var(--maxw); margin: 0 auto; padding: 0 24px; }

/* Focus state — visible everywhere (a11y, WCAG) */
:focus-visible {
  outline: 2px solid var(--green);
  outline-offset: 3px;
  border-radius: 3px;
}

a { color: var(--green); }
a:hover { color: var(--green-hover); }

/* Typography — editorial scale */
h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.12;
  letter-spacing: -0.015em;
  color: var(--fg);
  text-wrap: balance;
}
h1 { font-size: clamp(36px, 6.2vw, 56px); letter-spacing: -0.02em; }
h2 { font-size: clamp(26px, 4vw, 36px); }
h3 { font-size: 20px; }

.kicker {
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--green);
  margin-bottom: var(--space-3);
}
.lead { color: var(--fg-2); font-size: 18px; line-height: 1.65; max-width: 65ch; }

/* ─── BUTTONS ─── */
.btn {
  display: inline-block;
  font-family: var(--font-sans);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.01em;
  text-decoration: none;
  padding: 14px 22px;
  border-radius: var(--radius);
  border: 1px solid transparent;
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease, transform 0.1s ease;
  white-space: nowrap;
}
.btn:active { transform: translateY(1px); }

.btn-primary {
  background: var(--green);
  color: #ffffff;
}
.btn-primary:hover { background: var(--green-hover); color: #ffffff; }

.btn-ghost {
  background: transparent;
  color: var(--fg);
  border-color: var(--border);
}
.btn-ghost:hover { border-color: var(--green); color: var(--green); }

.btn-wa {
  background: transparent;
  color: var(--green);
  border-color: var(--green);
}
.btn-wa:hover { background: var(--green-dim); color: var(--green); }

.link-arrow {
  font-family: var(--font-sans);
  font-size: 15px;
  font-weight: 600;
  color: var(--green);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.link-arrow:hover { color: var(--green-hover); }
.link-arrow::after { content: "→"; transition: transform 0.2s ease; }
.link-arrow:hover::after { transform: translateX(3px); }

/* ─── NAV (single line, <=80px) ─── */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(255, 255, 255, 0.88);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--border);
}
.nav-bar { display: flex; align-items: center; justify-content: space-between; height: 68px; }
.nav-brand {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 19px;
  letter-spacing: -0.02em;
  color: var(--fg);
  text-decoration: none;
}
.nav-brand .dot { color: var(--green); }

.nav-links { display: flex; gap: 26px; align-items: center; }
.nav-links a {
  color: var(--fg-2);
  text-decoration: none;
  font-size: 14.5px;
  font-weight: 500;
}
.nav-links a:hover { color: var(--fg); }
.nav-links a[aria-current="page"] { color: var(--fg); }

.nav-links a.nav-cta {
  background: var(--green);
  color: #ffffff;
  padding: 10px 18px;
  border-radius: var(--radius);
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  margin-left: 8px;
}
.nav-links a.nav-cta:hover { background: var(--green-hover); color: #ffffff; }

/* ─── NAV DROPDOWN — References ─── */
.nav-dropdown { position: relative; line-height: 0; }
.nav-dropdown-toggle {
  background: none; border: none; cursor: pointer;
  color: var(--fg-2); font-family: var(--font-sans);
  font-size: 14.5px; font-weight: 500; padding: 0;
  display: inline-flex; align-items: center; gap: 5px;
}
.nav-dropdown-toggle:hover { color: var(--fg); }
.nav-dropdown-toggle .caret { font-size: 10px; transition: transform 0.15s ease; }
.nav-dropdown.active .nav-dropdown-toggle,
.nav-dropdown.open .nav-dropdown-toggle { color: var(--fg); }
.nav-dropdown.open .nav-dropdown-toggle .caret { transform: rotate(180deg); }
.nav-dropdown-menu {
  position: absolute; top: 100%; left: 50%;
  transform: translateX(-50%);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: 0 12px 32px rgba(27, 31, 36, 0.10);
  min-width: 200px; padding: 12px 6px 6px;
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity 0.15s ease, visibility 0.15s ease;
}
.nav-dropdown.open .nav-dropdown-menu {
  opacity: 1; visibility: visible; pointer-events: auto;
}
.nav-dropdown-menu a {
  display: block; padding: 10px 14px; border-radius: 6px;
  color: var(--fg-2); font-size: 14px; font-weight: 500;
  text-decoration: none; white-space: nowrap;
}
.nav-dropdown-menu a:hover { background: var(--surface-2); color: var(--fg); }
.nav-dropdown-menu a[aria-current="page"] { color: var(--green); }

.nav-toggle {
  display: none;
  background: none;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--fg);
  padding: 9px 12px;
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
}

/* ─── MOVING GRADIENT WASH BACKGROUND ───
   Fixed full-viewport canvas behind the page content. Negative
   z-index puts it above body's paper background but below all
   content (static elements paint above negative z-index children).
   pointer-events none so it never blocks clicks. The wash is a
   soft teal tint that drifts downward and loops — no mask needed,
   it's already subtle and full-viewport. */
.bg-wash {
  position: fixed;
  top: 0; left: 0;
  width: 100%; height: 100%;
  z-index: -1;
  pointer-events: none;
}
/* Keep the page body above the canvas stacking-wise (harmless —
   the site header is already sticky with z-index:100). */
body { position: relative; }

/* ─── INTERACTIVE NODE GRID BACKGROUND ───
   Second fixed full-viewport canvas (see draft.js). Same negative
   z-index as .bg-wash; being later in the DOM it paints above the
   wash and below all content. pointer-events none so the cursor
   reaches the page normally. Nothing here styles the nodes
   themselves — they are drawn on the canvas. */
.bg-nodes {
  position: fixed;
  top: 0; left: 0;
  width: 100%; height: 100%;
  z-index: -1;
  pointer-events: none;
}

/* ─── MOBILE BOTTOM BAR CTA (thumb zone) ─── */
.mobile-cta-bar {
  display: none;
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 200;
  background: rgba(255, 255, 255, 0.96);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-top: 1px solid var(--border);
  padding: 12px 20px calc(12px + env(safe-area-inset-bottom));
}
.mobile-cta-bar .btn { width: 100%; text-align: center; }

/* ─── HERO — service-first, nothing competes with the H1 ─── */
.hero { padding: var(--space-6) 0 var(--space-5); }
.hero .container { max-width: 920px; }
.hero h1 {
  max-width: none;
  font-family: var(--font-display);
  font-size: clamp(36px, 6.2vw, 56px);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--fg);
  margin: 0 0 var(--space-3);
}
/* Homepage only: the h1 is the small mono kicker when a big serif
   tagline follows it. Tab pages put the headline in the h1, so they
   get the big serif above. */
.hero h1:has(+ .hero-tagline) {
  max-width: none;
  margin-bottom: var(--space-2);
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--green);
}
.hero-tagline {
  font-family: var(--font-display);
  font-size: clamp(36px, 6.2vw, 56px);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--fg);
  margin: 0 0 var(--space-3);
}
.hero-tagline .teal { color: var(--green); }
.hero .sub {
  font-size: 19px;
  color: var(--fg-2);
  max-width: 60ch;
  margin-bottom: var(--space-4);
}

/* ─── PROCESS FLOW — 4-step infographic above the hero CTA ─── */
.process-flow {
  margin-bottom: var(--space-4);
  padding: var(--space-4) 0;
  border-top: 1px solid var(--border-soft);
}
.process-flow-headline {
  font-family: var(--font-display);
  font-size: clamp(18px, 2.5vw, 24px);
  font-weight: 600;
  color: var(--fg);
  text-align: center;
  margin: 0 0 var(--space-4);
  letter-spacing: 0.02em;
}
.process-flow-headline .arrow {
  color: var(--green);
  margin: 0 0.3em;
  font-weight: 400;
}
.process-steps {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-3);
  text-align: center;
}
.process-step {
  display: flex;
  flex-direction: column;
  align-items: center;
}
.step-icon {
  width: 84px;
  height: 84px;
  border-radius: 50%;
  background: var(--surface-2);
  border: 1px solid var(--border-soft);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: var(--space-2);
  color: var(--green);
  box-shadow: 0 2px 8px rgba(20, 60, 50, 0.06);
}
.step-icon svg {
  width: 42px;
  height: 42px;
  overflow: visible;
}
/* Feather icons — clean continuous stroke (no hand-drawn fill) */
.step-icon .pi {
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* Stroke draw-in on the icon outlines */
.process-flow.in-view .step-icon .pi-a,
.process-flow.in-view .step-icon .pi-b,
.process-flow.in-view .step-icon .pi-c {
  stroke-dasharray: 60;
  stroke-dashoffset: 60;
  animation: pi-draw-loop 5s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}
.process-flow.in-view .step-icon .pi-a { animation-delay: 0.1s; }
.process-flow.in-view .step-icon .pi-b { animation-delay: 0.35s; }
.process-flow.in-view .step-icon .pi-c { animation-delay: 0.6s; }
@keyframes pi-draw-loop {
  0%   { stroke-dashoffset: 60; opacity: 1; }
  25%  { stroke-dashoffset: 0; }
  100% { stroke-dashoffset: 0; }
}
/* Icon circle pulses softly — the process is alive */
.process-flow.in-view .step-icon {
  animation: icon-ring-loop 5s ease-in-out infinite;
}
.process-flow.in-view .step-icon:nth-of-type(1) { animation-delay: 0.1s; }
.process-flow.in-view .step-icon:nth-of-type(2) { animation-delay: 0.35s; }
.process-flow.in-view .step-icon:nth-of-type(3) { animation-delay: 0.6s; }
.process-flow.in-view .step-icon:nth-of-type(4) { animation-delay: 0.85s; }
@keyframes icon-ring-loop {
  0%, 100% { box-shadow: 0 2px 8px rgba(20, 60, 50, 0.06); }
  50%      { box-shadow: 0 4px 18px rgba(14, 110, 92, 0.22); }
}
.step-num {
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 600;
  color: var(--green);
  letter-spacing: 0.05em;
  margin-bottom: 6px;
}
.step-title {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 600;
  color: var(--fg);
  margin: 0 0 6px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.step-desc {
  font-size: 14px;
  color: var(--fg-3);
  line-height: 1.5;
  max-width: 20ch;
  margin: 0;
}
@media (max-width: 768px) {
  .process-steps { grid-template-columns: repeat(2, 1fr); gap: var(--space-4) var(--space-3); }
}
@media (max-width: 480px) {
  .process-steps { grid-template-columns: 1fr; }
  .step-desc { max-width: none; }
}

.hero-ctas { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; }
.hero .cta-caption {
  width: 100%;
  margin-top: 10px;
  font-size: 14px;
  color: var(--fg-3);
}
.hero .trust-line {
  margin-top: var(--space-4);
  padding-top: var(--space-3);
  border-top: 1px solid var(--border-subtle);
  font-size: 14px;
  color: var(--fg-3);
  max-width: 52ch;
  line-height: 1.6;
}
.hero .trust-line strong { color: var(--fg-2); font-weight: 600; }

/* ─── HERO MAP — the white-space map as a living archipelago ───
   The hero on The Watch page gets a map metaphor: a survey grid,
   teal 'countries' (the crowded market), small countries that flash
   white (the open white spaces), and a beachhead that lands white
   and expands like Normandy → Europe. Decorative (aria-hidden). */
.hero-map-wrap { position: relative; overflow: hidden; }

/* Two-column hero: text left, map right — map gets the majority of width */
.hero-split {
  display: grid;
  grid-template-columns: 0.9fr 1.2fr;
  gap: var(--space-5);
  align-items: center;
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 24px;
}
.hero-copy { position: relative; z-index: 1; }
.hero-copy .container { max-width: none; padding: 0; }

/* Map column — a visible card, not a background */
.hero-map-col {
  position: relative;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background:
    radial-gradient(120% 100% at 70% 0%, rgba(14, 110, 92, 0.10) 0%, transparent 60%),
    linear-gradient(180deg, #eaf4f1 0%, #f4faf8 55%, #e8f1ee 100%);
  border: 1px solid var(--border);
  box-shadow: 0 12px 40px rgba(14, 110, 92, 0.10);
  aspect-ratio: 3 / 2;
}

/* Glossy sheen — a diagonal light band that sweeps across the map
   like light moving over glass. Loops forever, gated by .in-view. */
.hero-map-col::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  background: linear-gradient(
    115deg,
    transparent 20%,
    rgba(255, 255, 255, 0.12) 40%,
    rgba(255, 255, 255, 0.35) 50%,
    rgba(255, 255, 255, 0.12) 60%,
    transparent 80%
  );
  transform: translateX(-110%);
}
.hero-map-col.in-view::after {
  animation: sheen-sweep 7s ease-in-out infinite;
}
@keyframes sheen-sweep {
  0%, 55% { transform: translateX(-110%); }
  85%     { transform: translateX(110%); }
  100%    { transform: translateX(110%); }
}
.hero-map {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
}
.hero-map-col .map-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* The whole map drifts — slow cinematic pan/zoom (Ken Burns).
   Scale stays ≥1.02 so edges never show. Loops forever. */
.hero-map.in-view {
  animation: map-drift 36s ease-in-out infinite;
}
@keyframes map-drift {
  0%, 100% { transform: scale(1.02) translate(0, 0); }
  25%      { transform: scale(1.07) translate(-1.5%, -1%); }
  50%      { transform: scale(1.04) translate(1%, 1.5%); }
  75%      { transform: scale(1.08) translate(-0.5%, 1%); }
}

/* Big zones breathe — the crowded market is alive, shifting.
   Each breathes on its own phase (staggered), scale 1 → 1.02. */
.zone.big {
  transform-box: fill-box;
  transform-origin: center;
}
.hero-map.in-view .zone.big {
  animation: zone-breathe 18s ease-in-out infinite;
}
.zone.big:nth-of-type(6n+1) { animation-delay: 0s; }
.zone.big:nth-of-type(6n+2) { animation-delay: 3s; }
.zone.big:nth-of-type(6n+3) { animation-delay: 6s; }
.zone.big:nth-of-type(6n+4) { animation-delay: 9s; }
.zone.big:nth-of-type(6n+5) { animation-delay: 12s; }
.zone.big:nth-of-type(6n+6) { animation-delay: 15s; }
@keyframes zone-breathe {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.02); }
}

/* Survey grid — faint map lines */
.map-grid {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(14, 110, 92, 0.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(14, 110, 92, 0.05) 1px, transparent 1px);
  background-size: 44px 44px;
  mask-image: radial-gradient(120% 120% at 50% 30%, #000 30%, transparent 75%);
  -webkit-mask-image: radial-gradient(120% 120% at 50% 30%, #000 30%, transparent 75%);
}

/* The map itself — fills the hero, sits under the text */
.map-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* Planning zones — Singapore's landmasses (the crowded market).
   3D treatment: each zone gets a drop-shadow so the map reads as
   raised land tiles on the water card. */
.zone {
  fill: rgba(14, 110, 92, 0.26);
  stroke: rgba(14, 110, 92, 0.55);
  stroke-width: 0.8;
  stroke-linejoin: round;
  filter: drop-shadow(0 2px 2px rgba(20, 60, 50, 0.25)) drop-shadow(0 6px 8px rgba(20, 60, 50, 0.12));
}

/* Small zones — flash white alternately: the open white spaces.
   Each flashes on its own loop (--sd stagger, set per-path in the SVG),
   suggesting a zone that can be occupied if you're smart. */
.zone.small {
  transform-box: fill-box;
  transform-origin: center;
  transform: scale(1.6);
}
.hero-map.in-view .zone.small {
  animation: small-flash 12s ease-in-out infinite;
  animation-delay: var(--sd, 0s);
}
@keyframes small-flash {
  0%, 100% { fill: rgba(14, 110, 92, 0.26); filter: none; }
  8%       { fill: rgba(255, 255, 255, 0.95); filter: drop-shadow(0 0 8px rgba(255, 255, 255, 0.95)); }
  16%      { fill: rgba(14, 110, 92, 0.26); filter: none; }
}

/* White sparkles — small stars twinkling across the landmass.
   Each twinkles on its own --sp stagger (set per-circle in the SVG),
   like openings glinting in the crowded market. */
.sparkle {
  fill: #ffffff;
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
}
.hero-map.in-view .sparkle {
  animation: sparkle-twinkle 7.2s ease-in-out infinite;
  animation-delay: var(--sp, 0s);
}
@keyframes sparkle-twinkle {
  0%, 100% { opacity: 0; transform: scale(0.4); }
  6%       { opacity: 1; transform: scale(1.1); }
  16%      { opacity: 0.25; transform: scale(0.75); }
  26%      { opacity: 0.95; transform: scale(1); }
  36%      { opacity: 0.1; transform: scale(0.6); }
  44%      { opacity: 0.85; transform: scale(0.95); }
  54%      { opacity: 0; transform: scale(0.4); }
}

/* Reduced motion — freeze the map, keep it static */
@media (prefers-reduced-motion: reduce) {
  .hero-map.in-view .zone.small,
  .hero-map.in-view .sparkle { animation: none; }
  .hero-map.in-view .zone.small { fill: rgba(14, 110, 92, 0.26); }
  .hero-map.in-view .sparkle { opacity: 0.5; }
  .hero-map-col.in-view::after { animation: none; transform: translateX(-110%); }
}

/* Mobile — smaller map, no layout break */
@media (max-width: 860px) {
  .hero-split { grid-template-columns: 1fr; gap: var(--space-4); }
  .hero-map-col { max-width: 420px; margin: 0 auto; }
}
@media (max-width: 640px) {
  .map-svg { opacity: 0.9; }
}

/* How it works strip (answers "what do you actually do?" immediately) */
.how-it-works {
  margin-top: var(--space-5);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
}
.how-it-works h2 { font-size: 20px; margin-bottom: var(--space-3); }
.steps { display: flex; align-items: stretch; gap: 0; counter-reset: how; }
.steps .step { flex: 1 1 0; }
.step-arrow { display: flex; align-items: center; justify-content: center; color: var(--green); font-size: 20px; padding: 0 12px; flex: 0 0 auto; }
.step {
  counter-increment: how;
  border-top: 1px solid var(--border);
  padding-top: var(--space-2);
}
.step::before {
  content: "0" counter(how);
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--green);
  display: block;
  margin-bottom: var(--space-1);
}
.step strong { display: block; margin-bottom: 6px; font-size: 17px; }
.step span { color: var(--fg-2); font-size: 15px; }

/* ─── SECTIONS ─── */
.section { padding: var(--space-5) 0; }
.section-alt { background: var(--surface); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.section h2 { max-width: 22ch; margin-bottom: var(--space-3); }
.section .lead { margin-bottom: var(--space-3); }

/* Proof strip */
.proof { display: flex; flex-direction: column; gap: var(--space-2); }
.stat-chips { display: flex; flex-wrap: wrap; gap: 12px; margin-top: var(--space-2); }
.chip {
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--fg);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 9999px;
  padding: 9px 16px;
}
.chip strong { color: var(--green); font-weight: 600; }

/* Fork cards */
.fork-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
.fork-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  transition: border-color 0.2s ease, transform 0.2s ease;
}
.fork-card:hover { border-color: var(--green); }
.fork-card .tag {
  font-family: var(--font-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--fg-3);
}
.fork-card h3 { font-size: 20px; }
.fork-card p { color: var(--fg-2); font-size: 15px; flex: 1; }
.fork-card a { align-self: flex-start; margin-top: var(--space-1); }

/* Pain stats */
.stats-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-3); margin-bottom: var(--space-3); }
.stat-block { border-top: 1px solid var(--border); padding-top: var(--space-3); }
.stat-block .num {
  font-family: var(--font-display);
  font-size: 38px;
  font-weight: 700;
  color: var(--fg);
  display: block;
  margin-bottom: var(--space-1);
}
.stat-block .num em { font-style: normal; color: var(--green); }
.stat-block p { color: var(--fg-2); font-size: 15px; }

/* Stat cards — consistent-but-distinct treatment.
   Mirrors the case-card anatomy (surface, border, radius, padding)
   so the stakes read as the same family as the education cards,
   but keeps a distinct top bar + number treatment so the two
   sections stay legibly different. */
.stat-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  transition: border-color 0.2s ease;
}
.stat-card:hover { border-color: var(--green); }
.stat-card .sc-label {
  font-family: var(--font-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--fg-3);
}
.stat-card .num {
  font-family: var(--font-display);
  font-size: 38px;
  font-weight: 700;
  color: var(--fg);
  display: block;
  line-height: 1;
}
.stat-card .num em { font-style: normal; color: var(--green); }
.stat-card p { color: var(--fg-2); font-size: 15px; line-height: 1.5; }
.stat-card .sc-source { color: var(--muted); font-size: 12px; margin-top: 2px; }
/* Distinct accent: a subtle top hairline in teal so the card family
   reads as its own section, not identical to the education cards. */
.stat-card { border-top: 2px solid var(--green); }
/* Competition journey: 39% (2024) -> 50% (2025) */
.stat-card .sc-journey { font-family: var(--font-display); font-size: 26px; font-weight: 700; color: var(--fg); margin: 0; }
.stat-card .sc-journey strong { color: var(--green); }
.stat-card .sc-arrow { color: var(--fg-3); margin: 0 6px; font-size: 20px; }
/* Comparison bars with year + value on the left */
.stat-card .cmp-bars { margin-top: 6px; }
.stat-card .cmp-bars .cmp-row { grid-template-columns: 72px 1fr; align-items: center; }
.stat-card .cmp-bars .cmp-label { display: flex; flex-direction: column; gap: 1px; font-family: var(--font-mono); }
.stat-card .cmp-bars .cmp-year { font-size: 10px; color: var(--fg-3); text-transform: uppercase; letter-spacing: 0.05em; }
.stat-card .cmp-bars .cmp-val { font-size: 14px; font-weight: 700; color: var(--fg); }
.stat-card .sc-note { font-size: 13px; color: var(--fg-2); margin-top: 2px; }

/* Cost vs value comparison chart (25K) — two rows (Free, Analysis).
   Each row: cost bar (coral) stacked above value bar (teal). The
   contrast shows S$0 costs nothing and returns nothing, while S$500
   costs little yet returns far more. */
.value-chart { margin-top: 8px; display: flex; flex-direction: column; gap: 14px; }
.vc-legend { display: flex; gap: 16px; font-size: 11px; color: var(--fg-3); font-family: var(--font-mono); text-transform: uppercase; letter-spacing: 0.05em; }
.vc-legend-item { display: inline-flex; align-items: center; gap: 6px; }
.vc-swatch { width: 10px; height: 10px; border-radius: 2px; display: inline-block; }
.vc-swatch.vc-cost { background: var(--coral); }
.vc-swatch.vc-value { background: var(--green); }
.vc-row { display: grid; grid-template-columns: 64px 1fr; column-gap: 8px; row-gap: 3px; align-items: center; }
.vc-label { grid-row: span 2; font-size: 12px; color: var(--fg); font-weight: 600; display: flex; flex-direction: column; line-height: 1.1; }
.vc-sub { font-size: 10px; color: var(--fg-3); font-weight: 400; font-family: var(--font-mono); }
.vc-cost-track { height: 8px; background: var(--surface-2); border-radius: 3px; overflow: hidden; }
.vc-value-track { height: 14px; background: var(--surface-2); border-radius: 3px; overflow: hidden; }
.vc-cost-fill { height: 100%; background: var(--coral); border-radius: 3px; transform-origin: left; transform: scaleX(0); }
.vc-value-fill { height: 100%; background: var(--green); border-radius: 3px; transform-origin: left; transform: scaleX(0); }

/* Survival cohort — 10 shopfronts, half go dark */
.cohort { display: grid; gap: 6px; margin-top: 10px; }
.cohort-row { display: flex; gap: 6px; }
.cohort-shop { width: 30px; height: 22px; border-radius: 3px; flex: 1; max-width: 34px; }
.cohort-shop.lit { background: var(--green); box-shadow: inset 0 0 0 2px rgba(255,255,255,0.15); }
.cohort-shop.dark { background: var(--surface-2); border: 1px solid var(--border); position: relative; }
.cohort-shop.dark::after { content: "×"; position: absolute; inset: 0; display: grid; place-items: center; color: var(--coral); font-weight: 700; font-size: 13px; }
.cohort-caption { font-size: 11px; color: var(--fg-3); font-family: var(--font-mono); text-transform: uppercase; letter-spacing: 0.05em; }

/* New-registration ticker — one every ~7 min */
.ticker { display: inline-flex; align-items: center; gap: 8px; font-size: 12px; color: var(--fg-2); font-family: var(--font-mono); margin-top: 6px; }
.ticker-pulse { width: 9px; height: 9px; border-radius: 50%; background: var(--green); }

/* 55% customer concern split bar */
.split { margin-top: 10px; }
.split-bar { display: flex; height: 18px; border-radius: 4px; overflow: hidden; background: var(--surface-2); }
.split-keep { background: var(--coral); border-radius: 4px 0 0 4px; transform-origin: left; transform: scaleX(0); }
.split-rest { background: var(--surface-2); }
.split-legend { display: flex; gap: 14px; margin-top: 6px; font-size: 11px; color: var(--fg-3); font-family: var(--font-mono); }
.split-item { display: inline-flex; align-items: center; gap: 5px; }
.split-swatch { width: 9px; height: 9px; border-radius: 2px; }
.split-swatch.keep { background: var(--coral); }
.split-swatch.rest { background: var(--surface-2); border: 1px solid var(--border); }

/* 36% #1 concern rank row */
.rank { margin-top: 10px; }
.rank-row { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 4px; }
.rank-row.top { background: var(--surface-2); border: 1px solid var(--border); }
.rank-badge { font-family: var(--font-mono); font-size: 11px; font-weight: 700; color: var(--green); background: rgba(14,110,92,0.15); padding: 2px 6px; border-radius: 3px; }
.rank-name { font-size: 13px; color: var(--fg); flex: 1; }
.rank-val { font-family: var(--font-mono); font-size: 13px; font-weight: 700; color: var(--coral); }

/* Method teaser / cards */
.card-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-3); }
.card-item {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  transition: border-color 0.2s ease;
}
.card-item:hover { border-color: var(--green); }
.card-item h3 { font-size: 20px; }
.card-item p { color: var(--fg-2); font-size: 15px; flex: 1; }
.card-item a { align-self: flex-start; }

/* Industry depth split */
.split { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4); align-items: start; }

/* Price + CTA band */
.price-band {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  text-align: center;
}
.price-band .line { font-size: 19px; margin: 10px 0; }
.price-band .line strong { color: var(--fg); font-family: var(--font-sans); font-weight: 600; }
.price-band .line .price-num { color: var(--green); font-family: var(--font-mono); font-weight: 600; }
.price-band .caption { font-family: var(--font-sans); font-size: 14px; color: var(--fg-3); margin: var(--space-3) 0 var(--space-4); }
.price-band .price-ctas { display: flex; gap: var(--space-2); justify-content: center; flex-wrap: wrap; }

/* Storefront Pricing section (productized-service practice) */
.manifesto {
  max-width: 62ch;
  margin-bottom: var(--space-4);
  display: grid;
  gap: var(--space-2);
}
.manifesto p { color: var(--fg-2); font-size: 17px; line-height: 1.6; }
.manifesto p.strong { color: var(--fg); font-weight: 600; font-size: 19px; }
.pricing-head { margin-bottom: var(--space-4); }
.store-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-3); align-items: stretch; }
.offer-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  transition: border-color 0.2s ease;
}
.offer-card:hover { border-color: var(--green); }
.offer-card-featured {
  border-color: var(--green);
  background: linear-gradient(180deg, var(--green-dim), var(--surface));
}
.offer-card .offer-name { font-family: var(--font-display); font-size: 20px; font-weight: 600; color: var(--fg); }
.offer-card .offer-price { font-size: 15px; color: var(--fg-2); }
.offer-card .offer-price strong { font-family: var(--font-display); font-size: 26px; font-weight: 700; color: var(--green); display: block; }
.offer-card .offer-meta { color: var(--fg-3); font-size: 14px; }
.offer-card .offer-cta { margin-top: var(--space-1); }
.offer-card .offer-cta .btn { width: 100%; text-align: center; }
.offer-card .offer-list { list-style: none; display: grid; gap: 10px; margin-top: var(--space-2); }
.offer-card .offer-list li { position: relative; padding-left: 20px; color: var(--fg-2); font-size: 15px; }
.offer-card .offer-list li::before {
  content: "✓";
  position: absolute; left: 0; top: 0;
  color: var(--green); font-weight: 700;
}
.guarantee-line {
  border-left: 3px solid var(--green);
  padding-left: 16px;
  color: var(--fg-2);
  margin: var(--space-4) 0 var(--space-2);
  max-width: 60ch;
}
.pricing-caption { font-family: var(--font-mono); font-size: 13px; color: var(--fg-3); margin-bottom: var(--space-3); }
.pricing-ctas { display: flex; gap: var(--space-2); flex-wrap: wrap; }

/* Ordered "what you get" lists */
.what-list { counter-reset: wl; display: grid; gap: var(--space-2); }
.what-list li {
  list-style: none;
  counter-increment: wl;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 20px 22px 20px 64px;
  position: relative;
}
.what-list li::before {
  content: counter(wl);
  position: absolute;
  left: 24px; top: 22px;
  font-family: var(--font-mono);
  font-weight: 700;
  color: var(--green);
}
.what-list strong { display: block; margin-bottom: 4px; }
.what-list span { color: var(--fg-2); }

/* Process steps */
.process { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-3); counter-reset: step; }
.process .step { border-top: 1px solid var(--border); padding-top: var(--space-3); }
.process .step::before { content: "0" counter(step); }
.process .step strong { display: block; margin-bottom: 6px; font-size: 17px; }
.process .step span { color: var(--fg-2); font-size: 15px; }

/* Guarantee + price blocks */
.price-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
}
.price-card .price { font-family: var(--font-display); font-size: 34px; font-weight: 700; color: var(--green); display: block; margin-bottom: 8px; }
.price-card .price-note { color: var(--fg-2); margin-bottom: var(--space-2); }
.price-card .guarantee {
  border-left: 3px solid var(--green);
  padding-left: 16px;
  color: var(--fg-2);
  margin: var(--space-3) 0;
}
.price-card .note { font-size: 14px; color: var(--fg-3); }
.price-card .anchor { font-size: 15px; color: var(--fg-2); margin: var(--space-2) 0; }

/* Compare table */
.table-wrap { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius-lg); }
table.compare { width: 100%; border-collapse: collapse; min-width: 680px; font-size: 14.5px; }
table.compare th, table.compare td { text-align: left; padding: 15px 18px; border-bottom: 1px solid var(--border-subtle); }
table.compare tr:last-child th, table.compare tr:last-child td { border-bottom: none; }
table.compare thead th { font-family: var(--font-mono); font-size: 12px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--fg-3); }
table.compare th.highlight, table.compare td.highlight { background: var(--green-dim); }
table.compare tbody th { font-weight: 600; color: var(--fg); }
table.compare .yes { color: var(--green); }
table.compare .no { color: var(--fg-muted); }
table.compare .generic { color: var(--yellow); }

/* Honesty banner */
.honesty {
  border: 1px solid var(--border);
  border-left: 4px solid var(--green);
  border-radius: var(--radius);
  background: var(--surface);
  padding: var(--space-3);
}
.honesty strong { display: block; margin-bottom: 8px; color: var(--fg); }
.honesty p { color: var(--fg-2); }

/* Engagement summary + findings */
.summary { display: grid; gap: var(--space-2); }
.summary-item { border-top: 1px solid var(--border); padding-top: var(--space-3); }
.summary-item strong { display: block; margin-bottom: 4px; }
.summary-item span { color: var(--fg-2); }

.findings { display: grid; gap: var(--space-2); }
.findings-item {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-3);
}
.findings-item strong { display: block; margin-bottom: 8px; }
.findings-item p { color: var(--fg-2); font-size: 15.5px; }

/* Deliverable / deck link */
.deck-link {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  margin-top: var(--space-3);
}
.deck-link p { color: var(--fg-2); flex: 1; min-width: 220px; }

/* FAQ (FAQPage schema) */
.faq { display: grid; gap: 12px; }
.faq details {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.faq summary {
  cursor: pointer;
  padding: 18px 22px;
  font-weight: 600;
  font-size: 17px;
  list-style: none;
  color: var(--fg);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+";
  float: right;
  font-family: var(--font-mono);
  color: var(--green);
  font-size: 20px;
  line-height: 1;
}
.faq details[open] summary::after { content: "−"; }
.faq details .faq-body { padding: 0 22px 20px; color: var(--fg-2); }

/* CTA band on sub pages */
.cta-band { text-align: center; }
.cta-band h2 { margin-bottom: var(--space-2); }
.cta-band p { color: var(--fg-2); margin-bottom: var(--space-3); }
.cta-band .cta-links { display: flex; gap: var(--space-2); justify-content: center; flex-wrap: wrap; }

/* The human */
.human {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-3);
  align-items: start;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
}
.human .avatar {
  /* 220px: portrait card sized to the photo's 2:3 ratio (533x800).
     ponytail: hard-coded width tracks the photo's aspect ratio; if the
     founder photo is swapped to landscape, bump this back to 320px. */
  width: 220px;
  height: auto;
  border-radius: var(--radius-lg);
  border: 1px solid var(--green);
}
.human h3 { margin-bottom: 4px; }
.human .role { font-family: var(--font-mono); font-size: 13px; color: var(--fg-3); margin-bottom: 12px; }
.human .bio { font-weight: 600; color: var(--fg); margin-bottom: 10px; }
.human .career { list-style: none; margin: 0 0 14px; padding: 0; display: grid; gap: 10px; }
.human .career li { display: grid; gap: 2px; }
.human .career strong { color: var(--fg); font-weight: 600; font-size: 14.5px; }
.human .career span { color: var(--fg-2); font-size: 14px; }
.human p { color: var(--fg-2); margin-bottom: 12px; }
.human .line {
  font-size: 15px;
  color: var(--fg-2);
  background: var(--green-dim);
  border-left: 3px solid var(--green);
  padding: 10px 12px;
  border-radius: 0 var(--radius) var(--radius) 0;
  margin: 4px 0 12px;
}

/* ─── FOOTER ─── */
.site-footer {
  border-top: 1px solid var(--border);
  margin-top: var(--space-5);
  padding: var(--space-5) 0 120px;
}
.site-footer .footer-inner { display: flex; flex-direction: column; gap: var(--space-3); }
.footer-links { display: flex; flex-wrap: wrap; gap: 8px 22px; align-items: center; }
.footer-links a { color: var(--fg-2); text-decoration: none; font-size: 14px; }
.footer-links a:hover { color: var(--green); }
.footer-links .sep { color: var(--fg-muted); }
.site-footer .legal { font-size: 13px; color: var(--fg-3); line-height: 1.6; }

/* ─── EDUCATION-FIRST (positioning directive, 17 Aug 2026) ─── */
/* Before/after case cards — the education core */
.case-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-3); }
.case-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  transition: border-color 0.2s ease;
}
.case-card:hover { border-color: var(--green); }
.case-card .case-brand { font-family: var(--font-display); font-size: 20px; font-weight: 700; color: var(--fg); }
.case-card .case-year { font-family: var(--font-mono); font-size: 12px; color: var(--fg-3); text-transform: uppercase; letter-spacing: 0.1em; }
.case-card .case-before, .case-card .case-after { font-size: 15px; }
.case-card .case-before { color: var(--fg-3); }
.case-card .case-before strong { color: var(--fg-2); font-weight: 600; }
.case-card .case-after { color: var(--fg); }
.case-card .case-after strong { color: var(--green); font-weight: 700; }
.case-card .case-result {
  border-top: 1px solid var(--border-subtle);
  padding-top: var(--space-2);
  font-size: 15px;
  color: var(--fg-2);
}
.case-card .case-result strong { color: var(--green); font-weight: 700; }

/* Consolidated before/after positioning blocks */
.case-card .case-phase {
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius);
  padding: var(--space-2) var(--space-3);
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.case-card .case-phase .phase-label {
  font-family: var(--font-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--fg-3);
}
.case-card .case-phase .phase-statement {
  font-size: 15px;
  line-height: 1.5;
  margin: 0;
  color: var(--fg);
}
.case-card .case-phase .phase-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
}
.case-card .case-phase .phase-bar .bar-label { color: var(--fg-3); white-space: nowrap; }
.case-card .case-phase .phase-bar .bar-track { flex: 1; height: 14px; background: var(--surface-2); border-radius: 3px; position: relative; overflow: hidden; }
.case-card .case-phase .phase-bar .bar-fill { height: 100%; border-radius: 3px; transform-origin: left; }
.case-card .case-phase .phase-bar .bar-fill.before { background: var(--coral); }
.case-card .case-phase .phase-bar .bar-fill.after { background: var(--green); }
.case-card .case-phase .phase-bar .bar-val { color: var(--fg); font-weight: 600; white-space: nowrap; font-family: var(--font-mono); font-size: 12px; }

/* The one-word pattern strip */
.word-strip { display: flex; flex-wrap: wrap; gap: 12px; margin-top: var(--space-3); }
.word-chip {
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--fg);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 9999px;
  padding: 9px 16px;
}
.word-chip strong { color: var(--green); font-weight: 600; }

/* Cost-of-wrong-positioning scenario table */
.cost-table { width: 100%; border-collapse: collapse; font-size: 14.5px; }
.cost-table th, .cost-table td { text-align: left; padding: 14px 16px; border-bottom: 1px solid var(--border-subtle); vertical-align: top; }
.cost-table thead th { font-family: var(--font-mono); font-size: 12px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--fg-3); }
.cost-table tbody th { font-weight: 600; color: var(--fg); }
.cost-table td { color: var(--fg-2); }
.cost-table .cost-total { color: var(--fg); font-weight: 600; white-space: nowrap; }
.cost-table .cost-ratio { color: var(--green); font-weight: 700; white-space: nowrap; }
.cost-table .cost-anchor { color: var(--fg-3); font-size: 13px; }

/* The anchor ratio callout */
.anchor-ratio {
  border-left: 4px solid var(--green);
  background: var(--surface);
  border-radius: var(--radius);
  padding: var(--space-3);
  margin-top: var(--space-3);
}
.anchor-ratio strong { color: var(--green); }
.anchor-ratio p { color: var(--fg-2); font-size: 15px; }

/* Education lead-in band (sub pages) */
.educate-band {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  margin-bottom: var(--space-4);
}
.educate-band h2 { font-size: 20px; margin-bottom: var(--space-2); }
.educate-band p { color: var(--fg-2); font-size: 15.5px; }
.educate-band .educate-link { margin-top: var(--space-2); }

/* ─── INFOGRAPHIC COMPONENTS (graphics layer, 18 Aug 2026) ─── */
/* All use existing tokens only. One message per graphic. Labels on elements. */

/* Hero promise flow — customers → reach → win */
.hero-flow {
  margin-top: var(--space-4);
  display: flex;
  align-items: stretch;
  gap: 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-3);
}
.hero-flow .flow-node {
  flex: 1 1 0;
  text-align: center;
  padding: var(--space-2) var(--space-2);
}
.hero-flow .flow-node .flow-num {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--green);
  display: block;
  margin-bottom: 6px;
}
.hero-flow .flow-node .flow-label {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 600;
  color: var(--fg);
  line-height: 1.25;
}
.hero-flow .flow-node .flow-sub {
  font-size: 13px;
  color: var(--fg-3);
  margin-top: 4px;
}
.hero-flow .flow-arrow {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--green);
  font-size: 22px;
  flex: 0 0 auto;
  padding: 0 10px;
}

/* Case before/after revenue bars */
.case-bars {
  margin-top: var(--space-2);
  display: grid;
  gap: 8px;
}
.case-bar-row { display: grid; grid-template-columns: 84px 1fr; gap: 10px; align-items: center; }
.case-bar-row .bar-label { font-family: var(--font-mono); font-size: 11px; color: var(--fg-3); text-align: right; }
.case-bar-row .bar-track { height: 14px; background: var(--surface-2); border-radius: 3px; position: relative; }
.case-bar-row .bar-fill { height: 100%; border-radius: 3px; }
.case-bar-row .bar-fill.before { background: var(--coral); }
.case-bar-row .bar-fill.after { background: var(--green); }
.case-bar-row .bar-val { font-family: var(--font-mono); font-size: 11px; color: var(--fg-2); margin-left: 8px; white-space: nowrap; }
.case-bars .bar-caption { font-size: 12px; color: var(--fg-3); margin-top: 2px; }

/* Trend chip (only where a real trend exists) */
.trend-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
  color: var(--amber);
  background: rgba(201, 154, 63, 0.12);
  border-radius: 9999px;
  padding: 4px 10px;
  margin-top: 8px;
}
.trend-chip .trend-arrow { font-size: 13px; line-height: 1; }

/* Cost scale — analysis vs cost of being wrong */
.cost-scale {
  margin-top: var(--space-3);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
}
.cost-scale .scale-title { font-family: var(--font-mono); font-size: 12px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--fg-3); margin-bottom: var(--space-3); }
.cost-scale .scale-row { display: grid; grid-template-columns: 120px 1fr; gap: var(--space-2); align-items: center; margin-bottom: var(--space-2); }
.cost-scale .scale-row .scale-label { font-size: 14px; color: var(--fg-2); }
.cost-scale .scale-row .scale-label strong { color: var(--fg); font-weight: 600; }
.cost-scale .scale-row .scale-track { height: 22px; background: var(--surface-2); border-radius: 4px; position: relative; }
.cost-scale .scale-row .scale-fill { height: 100%; border-radius: 4px; }
.cost-scale .scale-row .scale-fill.analysis { background: var(--green); }
.cost-scale .scale-row .scale-fill.wrong { background: var(--coral); }
.cost-scale .scale-row .scale-val { font-family: var(--font-mono); font-size: 12px; color: var(--fg-2); margin-left: 10px; white-space: nowrap; }
.cost-scale .scale-note { font-size: 13px; color: var(--fg-3); margin-top: var(--space-2); }

/* Flywheel circular SVG */
.flywheel-wrap { display: flex; justify-content: center; margin-top: var(--space-3); }
.flywheel-wrap svg { max-width: 640px; width: 100%; height: auto; }

/* Registry counts strip — decorative visual of SG registry data */
.registry-strip {
  margin-top: var(--space-3);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-2);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-3);
}
.registry-item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--space-2);
  border-radius: var(--radius);
  background: var(--surface-2);
}
.registry-num { font-family: var(--font-display); font-size: 30px; font-weight: 700; color: var(--green); line-height: 1.1; }
.registry-name { font-size: 13px; color: var(--fg); font-weight: 600; }
.registry-src { font-family: var(--font-mono); font-size: 10px; color: var(--fg-3); text-transform: uppercase; letter-spacing: 0.05em; }
.registry-asof { grid-column: 1 / -1; font-family: var(--font-mono); font-size: 11px; color: var(--fg-3); margin: 0; padding-top: var(--space-1); border-top: 1px solid var(--border-subtle); }

/* SingStat catalog block */
.singstat-block {
  margin-top: var(--space-3);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-3);
}
.singstat-title { font-family: var(--font-display); font-size: 18px; font-weight: 700; color: var(--fg); margin-bottom: 6px; }
.singstat-lead { font-size: 14px; color: var(--fg-2); line-height: 1.5; margin-bottom: var(--space-2); }
.singstat-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-2); }
.singstat-cat {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: var(--space-2);
  border-radius: var(--radius);
  background: var(--surface-2);
}
.ssc-name { font-family: var(--font-mono); font-size: 12px; font-weight: 700; color: var(--green); text-transform: uppercase; letter-spacing: 0.05em; }
.ssc-desc { font-size: 12px; color: var(--fg-2); line-height: 1.4; }
.singstat-note { font-family: var(--font-mono); font-size: 11px; color: var(--fg-3); margin: var(--space-2) 0 0; padding-top: var(--space-1); border-top: 1px solid var(--border-subtle); }

/* Watch report sections — competitor analysis + disruption signals */
.watch-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-3); }
.watch-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-3);
  display: flex;
  flex-direction: column;
  gap: 6px;
  transition: border-color 0.2s ease;
}
.watch-card:hover { border-color: var(--green); }
.watch-card-num {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--green);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}
.watch-card h3 { font-size: 17px; color: var(--fg); }
.watch-card p { font-size: 14px; color: var(--fg-2); }

.watch-example {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--green);
  border-radius: var(--radius);
  padding: var(--space-3);
  margin-bottom: var(--space-3);
}
.watch-example-kicker { font-family: var(--font-mono); font-size: 11px; color: var(--fg-3); text-transform: uppercase; letter-spacing: 0.1em; }
.watch-example-body { font-size: 15px; color: var(--fg); line-height: 1.6; margin-top: 6px; }
.watch-example-body strong { color: var(--green); }

.watch-signal-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-2); }
.watch-signal {
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius);
  background: var(--surface-2);
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.watch-signal-name { font-family: var(--font-mono); font-size: 12px; font-weight: 700; color: var(--green); text-transform: uppercase; letter-spacing: 0.05em; }
.watch-signal p { font-size: 13px; color: var(--fg-2); line-height: 1.45; }

.watch-callout {
  margin-top: var(--space-3);
  padding: var(--space-3);
  border-radius: var(--radius);
  background: var(--green-dim);
  border: 1px solid var(--border);
  font-size: 14px;
  color: var(--fg-2);
}
.watch-callout strong { color: var(--fg); }

/* Watch decorative visuals — white-space band + signal radar */
.watch-radar {
  display: flex;
  justify-content: center;
  margin: var(--space-3) 0;
}
.watch-radar svg { max-width: 200px; width: 100%; height: auto; }

/* Watch white-space band — mirrors The Method's white-space visual */
.watch-ws-band {
  position: relative;
  overflow: hidden;
  height: 300px;
  border-radius: var(--radius-lg);
  background:
    radial-gradient(120% 140% at 15% 20%, #0a5447 0%, #0e6e5c 45%, #0a5447 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  margin: var(--space-3) 0;
}
.watch-ws-band .ws-gaps { position: absolute; inset: 0; pointer-events: none; }
.watch-ws-band .ws-gap {
  position: absolute;
  display: block;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, rgba(255,255,255,0.95) 0%, rgba(255,255,255,0.55) 45%, rgba(255,255,255,0) 72%);
  opacity: 0;
  will-change: transform, opacity;
}
.watch-ws-band .ws-gap-1 { width: 150px; height: 150px; top: 12%;  left: 6%;  }
.watch-ws-band .ws-gap-2 { width: 90px;  height: 90px;  top: 60%;  left: 18%; }
.watch-ws-band .ws-gap-3 { width: 210px; height: 210px; top: 30%;  left: 34%; }
.watch-ws-band .ws-gap-4 { width: 70px;  height: 70px;  top: 70%;  left: 48%; }
.watch-ws-band .ws-gap-5 { width: 120px; height: 120px; top: 15%;  left: 60%; }
.watch-ws-band .ws-gap-6 { width: 180px; height: 180px; top: 55%;  left: 72%; }
.watch-ws-band .ws-gap-7 { width: 60px;  height: 60px;  top: 25%;  left: 84%; }
.watch-ws-band .ws-gap-8 { width: 100px; height: 100px; top: 65%;  left: 90%; }
.watch-ws-band .ws-gap-9 { width: 140px; height: 140px; top: 40%;  left: 12%; }
.watch-ws-band .ws-gap { animation: none; }
.watch-ws-band.in-view .ws-gap-1 { animation: ws-drift-1 14s ease-in-out infinite; }
.watch-ws-band.in-view .ws-gap-2 { animation: ws-drift-2 11s ease-in-out infinite; }
.watch-ws-band.in-view .ws-gap-3 { animation: ws-drift-3 17s ease-in-out infinite; }
.watch-ws-band.in-view .ws-gap-4 { animation: ws-drift-4 9s  ease-in-out infinite; }
.watch-ws-band.in-view .ws-gap-5 { animation: ws-drift-5 13s ease-in-out infinite; }
.watch-ws-band.in-view .ws-gap-6 { animation: ws-drift-6 16s ease-in-out infinite; }
.watch-ws-band.in-view .ws-gap-7 { animation: ws-drift-7 10s ease-in-out infinite; }
.watch-ws-band.in-view .ws-gap-8 { animation: ws-drift-8 12s ease-in-out infinite; }
.watch-ws-band.in-view .ws-gap-9 { animation: ws-drift-9 15s ease-in-out infinite; }
.watch-ws-band .ws-caption { position: relative; z-index: 2; text-align: center; color: #ffffff; padding: 0 var(--space-3); max-width: 640px; }
.watch-ws-band .ws-caption h2 { font-family: var(--font-display); font-size: clamp(1.6rem, 3.4vw, 2.4rem); font-weight: 600; line-height: 1.15; margin-bottom: var(--space-2); color: #ffffff; }
.watch-ws-band .ws-caption p { font-family: var(--font-sans); font-size: clamp(1rem, 1.6vw, 1.15rem); color: rgba(255,255,255,0.9); line-height: 1.5; }

/* Signal radar: sweep rotates, blips ping */
.wr-ring { fill: none; stroke: var(--border); stroke-width: 1; }
.wr-cross { stroke: var(--border); stroke-width: 1; }
.wr-sweep-arc { fill: var(--green); opacity: 0.12; transform-origin: 100px 100px; animation: wr-sweep 4s linear infinite; }
@keyframes wr-sweep { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
.wr-blip { fill: var(--coral); transform-origin: center; transform-box: fill-box; animation: wr-blip 2.4s ease-out infinite; }
.wr-blip:nth-child(2) { animation-delay: 0.8s; }
.wr-blip:nth-child(3) { animation-delay: 1.6s; }
@keyframes wr-blip { 0% { transform: scale(0.4); opacity: 0.9; } 70% { transform: scale(1.4); opacity: 0.4; } 100% { transform: scale(1.4); opacity: 0; } }

/* Industry ranking bars */
.rank-bar { display: flex; align-items: center; gap: 10px; }
.rank-bar .rank-track { flex: 1; height: 12px; background: var(--surface-2); border-radius: 3px; min-width: 60px; }
.rank-bar .rank-fill { height: 100%; border-radius: 3px; background: var(--green); }
.rank-bar .rank-val { font-family: var(--font-mono); font-size: 11px; color: var(--fg-2); white-space: nowrap; }

/* Industry icons — clean line icons depicting each industry */
.industry-cell {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 600;
}
.industry-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 8px;
  background: var(--green-dim);
  color: var(--green);
  flex: 0 0 auto;
}
.industry-icon svg {
  width: 22px;
  height: 22px;
}

/* Method pipeline */
.method-pipeline { display: flex; align-items: stretch; gap: 0; margin-top: var(--space-3); }
.method-pipeline .pipe-node { flex: 1 1 0; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: var(--space-3); }
.method-pipeline .pipe-node .pipe-num { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--green); display: block; margin-bottom: 6px; }
.method-pipeline .pipe-node strong { display: block; font-size: 16px; margin-bottom: 4px; }
.method-pipeline .pipe-node span { color: var(--fg-2); font-size: 14px; }
.method-pipeline .pipe-arrow { display: flex; align-items: center; justify-content: center; color: var(--green); font-size: 22px; flex: 0 0 auto; padding: 0 10px; }
.method-pipeline .pipe-link { display: inline-block; margin-top: 10px; }

/* GreenPackers data bars */
.data-bar { display: grid; grid-template-columns: 1fr auto; gap: var(--space-2); align-items: center; margin-bottom: var(--space-2); }
.data-bar .data-track { height: 18px; background: var(--surface-2); border-radius: 4px; position: relative; }
.data-bar .data-fill { height: 100%; border-radius: 4px; background: var(--green); }
.data-bar .data-fill.partial { background: var(--border); }
.data-bar .data-val { font-family: var(--font-mono); font-size: 12px; color: var(--fg-2); white-space: nowrap; }
.data-bar .data-label { font-size: 14px; color: var(--fg-2); margin-bottom: 4px; }
.data-bar .data-label strong { color: var(--fg); font-weight: 600; }

/* ─── DYNAMIC VISUALS (18 Aug 2026) — CSS keyframes only, no JS ─── */
/* All animations GPU-accelerated (transform/opacity), wrapped in
   prefers-reduced-motion: no-preference. One animation per element.
   Existing tokens only — no new colors. */

/* Brand logos on case cards + word strip */
.brand-logo {
  max-height: 28px;
  width: auto;
  filter: grayscale(1);
  transition: filter 0.3s ease;
  vertical-align: middle;
}
.case-card:hover .brand-logo,
.word-chip:hover .brand-logo { filter: grayscale(0); }

/* Wanglaoji — no clean logo exists; styled text chip instead */
.brand-logo-text {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 15px;
  color: var(--green);
  border: 1px solid var(--green);
  border-radius: 6px;
  padding: 2px 8px;
  line-height: 1.4;
  background: var(--green-dim);
}

/* Case brand row: logo + name on one line */
.case-brand { display: flex; align-items: center; gap: 10px; }
.case-brand .brand-logo { flex: 0 0 auto; }

/* Word chips: logo + text on one line */
.word-chip { display: inline-flex; align-items: center; gap: 8px; }
.word-chip .brand-logo { flex: 0 0 auto; }

/* Bar growth keyframes */
@keyframes grow-bar {
  from { transform: scaleX(var(--grow-from, 0)); }
  to   { transform: scaleX(1); }
}
@keyframes grow-fill {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}
/* Looping versions — entrance + hold, repeat every 5s */
@keyframes grow-bar-loop {
  0%   { transform: scaleX(0); }
  15%  { transform: scaleX(1); }
  100% { transform: scaleX(1); }
}
@keyframes grow-fill-loop {
  0%   { transform: scaleX(0); }
  15%  { transform: scaleX(1); }
  100% { transform: scaleX(1); }
}

@media (prefers-reduced-motion: no-preference) {
  /* All animations are gated behind .in-view, added by assets/draft.js
     (IntersectionObserver) to the container itself when it scrolls into
     view. Selectors use <container>.in-view <child> because the class
     lands on the container, not an ancestor of it.
     If JS is disabled, .in-view is never added and elements show their
     natural final state — no animation, no broken layout. */

  /* Case before/after bars: the AFTER bar grows from the BEFORE value
     to the AFTER value when the card scrolls into view
     (transform-origin: left, GPU-accelerated). */
  .case-bars.in-view .bar-fill.after {
    transform-origin: left;
    animation: grow-bar-loop 5s cubic-bezier(0.22, 1, 0.36, 1) infinite;
  }
  /* Consolidated phase bars: BEFORE (orange) grows from 0, AFTER (teal)
     grows from the before value — both when the phase-bar scrolls in. */
  .phase-bar.in-view .bar-fill.before {
    transform-origin: left;
    animation: grow-fill-loop 5s cubic-bezier(0.22, 1, 0.36, 1) infinite;
  }
  .phase-bar.in-view .bar-fill.after {
    transform-origin: left;
    animation: grow-bar-loop 5s cubic-bezier(0.22, 1, 0.36, 1) infinite;
  }
  /* Cost scale bars grow from 0 */
  .cost-scale.in-view .scale-fill {
    transform-origin: left;
    animation: grow-fill-loop 5s cubic-bezier(0.22, 1, 0.36, 1) infinite;
  }
  /* Industry ranking bars */
  .rank-bar.in-view .rank-fill {
    transform-origin: left;
    animation: grow-fill-loop 5s cubic-bezier(0.22, 1, 0.36, 1) infinite;
  }
  /* GreenPackers data bars */
  .data-bar.in-view .data-fill {
    transform-origin: left;
    animation: grow-fill-loop 5s cubic-bezier(0.22, 1, 0.36, 1) infinite;
  }

  /* Stagger case cards so they cascade, not all at once.
     .in-view is added to .case-bars (a descendant of .case-card), so
     use :has() to target the card that contains an in-view bars block. */
  .case-card:nth-child(1):has(.in-view) .bar-fill.after { animation-delay: 0.1s; }
  .case-card:nth-child(2):has(.in-view) .bar-fill.after { animation-delay: 0.2s; }
  .case-card:nth-child(3):has(.in-view) .bar-fill.after { animation-delay: 0.3s; }
  .case-card:nth-child(4):has(.in-view) .bar-fill.after { animation-delay: 0.4s; }
  .case-card:nth-child(5):has(.in-view) .bar-fill.after { animation-delay: 0.5s; }
  .case-card:nth-child(6):has(.in-view) .bar-fill.after { animation-delay: 0.6s; }

  /* ── FLYWHEEL — premium circular choreography ──
     Sequence (all gated behind .in-view on .flywheel-wrap):
     1. Ring draws itself (stroke-dashoffset, expo-out)
     2. 4 nodes pop in sequentially with overshoot (staggered 0.15s)
     3. Energy dots flow clockwise around the ring (dashed stroke, infinite)
     4. Hub pulses with glow (box-shadow + scale 1→1.05→1)
     Ring is static (draw-in only) so labels stay fixed; only energy flows. */
  .flywheel-wrap.in-view .fw-ring {
    stroke-dasharray: 1131;
    stroke-dashoffset: 1131;
    animation: fw-draw 1.2s cubic-bezier(0.16, 1, 0.3, 1) both;
  }
  @keyframes fw-draw { to { stroke-dashoffset: 0; } }

  .flywheel-wrap.in-view .fw-node-scale {
    transform-box: fill-box;
    transform-origin: center;
    animation: fw-node-pop 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) both;
  }
  .flywheel-wrap.in-view .fw-node-1 .fw-node-scale { animation-delay: 1.2s; }
  .flywheel-wrap.in-view .fw-node-2 .fw-node-scale { animation-delay: 1.35s; }
  .flywheel-wrap.in-view .fw-node-3 .fw-node-scale { animation-delay: 1.5s; }
  .flywheel-wrap.in-view .fw-node-4 .fw-node-scale { animation-delay: 1.65s; }
  @keyframes fw-node-pop {
    0%   { transform: scale(0); opacity: 0; }
    60%  { transform: scale(1.25); opacity: 1; }
    100% { transform: scale(1); opacity: 1; }
  }

  /* Energy dots flow clockwise — starts after the ring draws + nodes pop */
  .flywheel-wrap.in-view .fw-energy {
    stroke-dashoffset: 0;
    animation: fw-flow 3s linear infinite 1.8s;
  }
  @keyframes fw-flow { to { stroke-dashoffset: -48; } }

  /* Hub pulses with glow — starts after the energy flow is running */
  .flywheel-wrap.in-view .fw-core {
    transform-box: fill-box;
    transform-origin: center;
    animation: fw-glow 2.4s ease-in-out infinite 2.2s;
  }
  @keyframes fw-glow {
    0%, 100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(14, 110, 92, 0); }
    50%      { transform: scale(1.05); box-shadow: 0 0 0 10px rgba(14, 110, 92, 0.12); }
  }

  /* Moving arrowhead — orbits clockwise 1 → 2 → 3 → 4 on an 8s loop.
     Starts after the entrance choreography (~2.2s) so the ring draws,
     nodes pop, THEN the arrow begins its circuit. */
  .flywheel-wrap.in-view .fw-arrow {
    transform-box: view-box;
    transform-origin: 410px 410px;
    animation: fw-arrow-orbit 8s linear infinite 2.2s;
  }
  @keyframes fw-arrow-orbit {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
  }

  /* Stage reaction — each node pulses + flashes amber when the arrow
     passes it. Same 8s cycle, phase-shifted by the arrow's travel time:
     node 1 at 0s, node 2 at 2s, node 3 at 4s, node 4 at 6s (after the
     2.2s entrance delay). */
  .flywheel-wrap.in-view .fw-node-pulse {
    transform-box: fill-box;
    transform-origin: center;
    animation: fw-node-react 8s ease-in-out infinite 2.2s;
  }
  .flywheel-wrap.in-view .fw-node-flash {
    transform-box: fill-box;
    transform-origin: center;
    animation: fw-node-flash 8s ease-in-out infinite 2.2s;
  }
  .flywheel-wrap.in-view .fw-node-2 .fw-node-pulse,
  .flywheel-wrap.in-view .fw-node-2 .fw-node-flash { animation-delay: 4.2s; }
  .flywheel-wrap.in-view .fw-node-3 .fw-node-pulse,
  .flywheel-wrap.in-view .fw-node-3 .fw-node-flash { animation-delay: 6.2s; }
  .flywheel-wrap.in-view .fw-node-4 .fw-node-pulse,
  .flywheel-wrap.in-view .fw-node-4 .fw-node-flash { animation-delay: 8.2s; }
  @keyframes fw-node-react {
    0%, 100% { transform: scale(1); }
    4%       { transform: scale(1.2); }
    8%       { transform: scale(1); }
  }
  @keyframes fw-node-flash {
    0%, 100% { opacity: 0; }
    4%       { opacity: 0.9; }
    8%       { opacity: 0; }
  }

  /* Method pipeline: flowing arrows */
  .method-pipeline.in-view .pipe-arrow {
    animation: pipe-flow 1.6s ease-in-out infinite;
  }
  @keyframes pipe-flow {
    0%, 100% { transform: translateX(0); opacity: 0.6; }
    50%      { transform: translateX(4px); opacity: 1; }
  }

  /* Hero flow: nodes light up in sequence (node, arrow, node, arrow, node) */
  .hero-flow.in-view .flow-node {
    animation: node-light 2.4s ease-in-out infinite;
  }
  .hero-flow.in-view .flow-node:nth-child(1) { animation-delay: 0s; }
  .hero-flow.in-view .flow-node:nth-child(3) { animation-delay: 0.4s; }
  .hero-flow.in-view .flow-node:nth-child(5) { animation-delay: 0.8s; }
  @keyframes node-light {
    0%, 100% { background: transparent; }
    50%      { background: var(--green-dim); }
  }

  /* ── SIGNATURE CASE ANIMATIONS (one distinct type per case) ── */

  /* 1. Airbnb — odometer digit-roll count-up (0.9 → 4.8) + bar.
     Digits roll with overshoot (each strip settles with a tiny bounce);
     the final 'B' digit lands with a scale pop as the climax. */
  .case-card:nth-child(1) .odometer.in-view .odo-strip {
    animation: odo-roll-loop 5s cubic-bezier(0.34, 1.56, 0.64, 1) infinite;
  }
  /* Airbnb stock chart — the line draws upward from $0.9B to $4.8B */
  .case-card:nth-child(1) .stock-chart.in-view .chart-line {
    animation: chart-draw-loop 5s cubic-bezier(0.22, 1, 0.36, 1) infinite;
  }
  .case-card:nth-child(1) .stock-chart.in-view .chart-dot.end {
    animation: chart-dot-in 1.2s cubic-bezier(0.22, 1, 0.36, 1) 0.8s forwards;
  }
  /* Wang Lao Ji stock chart — same draw-up visual as Airbnb */
  .case-card:nth-child(5) .stock-chart.in-view .chart-line {
    animation: chart-draw-loop 5s cubic-bezier(0.22, 1, 0.36, 1) infinite;
  }
  .case-card:nth-child(5) .stock-chart.in-view .chart-dot.end {
    animation: chart-dot-in 1.2s cubic-bezier(0.22, 1, 0.36, 1) 0.8s forwards;
  }
  @keyframes chart-dot-in {
    0%   { opacity: 0; }
    100% { opacity: 1; }
  }
  @keyframes chart-draw-loop {
    0%   { stroke-dashoffset: 400; }
    60%  { stroke-dashoffset: 0; }
    100% { stroke-dashoffset: 0; }
  }
  .case-card:nth-child(1) .odometer.in-view .odo-digit:nth-child(1) .odo-strip { animation-delay: 0.1s; }
  .case-card:nth-child(1) .odometer.in-view .odo-digit:nth-child(2) .odo-strip { animation-delay: 0.2s; }
  .case-card:nth-child(1) .odometer.in-view .odo-digit:nth-child(3) .odo-strip { animation-delay: 0.3s; }
  .case-card:nth-child(1) .odometer.in-view .odo-digit:nth-child(4) .odo-strip { animation-delay: 0.4s; }
  @keyframes odo-roll {
    from { transform: translateY(0); }
    to   { transform: translateY(-1em); }
  }
  /* Climax: the 'B' lands with a scale pop after the digits settle */
  .case-card:nth-child(1) .odometer.in-view .odo-final {
    display: inline-block;
    animation: odo-final-pop-loop 5s cubic-bezier(0.34, 1.56, 0.64, 1) 0.6s  infinite;
  }
  @keyframes odo-final-pop {
    0%   { transform: scale(0); opacity: 0; }
    60%  { transform: scale(1.3); opacity: 1; }
    100% { transform: scale(1); opacity: 1; }
  }

  /* 2. Avis — gauge needle sweeps 10% → 29%.
     Anticipation: needle pulls back slightly before sweeping, then
     overshoots past 29% and wobbles back to settle. */
  .gauge.in-view .gauge-needle {
    transform-origin: 100px 100px;
    animation: gauge-sweep-loop 5s cubic-bezier(0.22, 1, 0.36, 1) infinite;
  }
  @keyframes gauge-sweep {
    0%   { transform: rotate(-72deg); }  /* 10% — start, in lock step with bars */
    15%  { transform: rotate(-38deg); }  /* 29% — settle, same window as bars */
    100% { transform: rotate(-38deg); }
  }

  /* 3. Domino's — USA map: the coral origin domino is always visible
     first. The 99 teal dominoes then ripple in one after another in a
     continuous loop (dynamic), each appearing, holding, then resetting
     so the cascade keeps running. */
  .usa-map use[href="#domino-tile-origin"] {
    opacity: 1;
  }
  .usa-map use[href="#domino-tile"] {
    opacity: 0;
  }
  .usa-map.in-view use[href="#domino-tile"] {
    animation: domino-in-loop 6s cubic-bezier(0.34, 1.56, 0.64, 1) infinite;
    animation-delay: calc(0.1s + (var(--i, 1) * 0.05s));
  }
  @keyframes domino-in-loop {
    0%   { opacity: 0; }
    6%   { opacity: 1; }
    88%  { opacity: 1; }
    100% { opacity: 1; }  /* was 0: that frame only existed to reset the old
                             infinite loop. One-shot now — tiles must stay. */
  }
  @keyframes map-dot-pop {
    0%   { transform: scale(0); opacity: 0; }
    60%  { transform: scale(1.2); opacity: 1; }
    100% { transform: scale(1); opacity: 1; }
  }

  /* 4. Volvo — was a drawn-in shield containing a cartoon car. The mark is
     now a designed glyph (Tabler shield-check) that reads at rest; its
     draw-in loop and the car-drive keyframes are deleted with the shapes
     they animated. No motion, so nothing to gate. */

  /* 5. Wanglaoji — ladder steps fill with overshoot (compounding climb).
     Each bar overshoots (scaleX 0 → 1.05 → 1); each step's label pops in
     after its bar. */
  .ladder.in-view .ladder-bar::after {
    animation: ladder-fill-loop 5s cubic-bezier(0.34, 1.56, 0.64, 1) infinite;
  }
  .ladder.in-view .ladder-step:nth-child(1) .ladder-bar::after { animation-delay: 0.1s; }
  .ladder.in-view .ladder-step:nth-child(2) .ladder-bar::after { animation-delay: 0.3s; }
  .ladder.in-view .ladder-step:nth-child(3) .ladder-bar::after { animation-delay: 0.5s; }
  .ladder.in-view .ladder-step:nth-child(4) .ladder-bar::after { animation-delay: 0.7s; }
  @keyframes ladder-fill {
    0%   { transform: scaleX(0); }
    70%  { transform: scaleX(1.05); }
    100% { transform: scaleX(1); }
  }
  /* Each step's label pops in after its bar fills */
  .ladder.in-view .ladder-label {
    animation: ladder-label-pop-loop 5s cubic-bezier(0.34, 1.56, 0.64, 1) infinite;
  }
  .ladder.in-view .ladder-step:nth-child(1) .ladder-label { animation-delay: 0.3s; }
  .ladder.in-view .ladder-step:nth-child(2) .ladder-label { animation-delay: 0.5s; }
  .ladder.in-view .ladder-step:nth-child(3) .ladder-label { animation-delay: 0.7s; }
  .ladder.in-view .ladder-step:nth-child(4) .ladder-label { animation-delay: 0.9s; }
  @keyframes ladder-label-pop {
    0%   { transform: scale(0.6); opacity: 0; }
    60%  { transform: scale(1.15); opacity: 1; }
    100% { transform: scale(1); opacity: 1; }
  }

  /* 6. Great Wall SUV — was a cartoon car that drove in on a scrolling
     road with spinning wheels, looping forever. The mark is now a
     designed glyph composition (pickup → SUV) that reads at rest; the
     drive-in / wheel-spin / ground-scroll keyframes are deleted with the
     shapes they animated. No motion, so nothing to gate. */

  /* ── SINGAPORE STAKES INFOGRAPHICS (one distinct treatment each) ── */

  /* 1. 50% don't survive — a cohort of 10 shopfronts: 5 stay open,
     the other 5 go dark (a 'lights out' flicker) one after another. */
  .stat-card:nth-child(1) .cohort.in-view .cohort-shop.dark {
    animation: dark-flicker-loop 6s cubic-bezier(0.34, 1.56, 0.64, 1) infinite;
  }
  .stat-card:nth-child(1) .cohort.in-view .cohort-shop.dark:nth-child(1) { animation-delay: 0.6s; }
  .stat-card:nth-child(1) .cohort.in-view .cohort-shop.dark:nth-child(2) { animation-delay: 0.8s; }
  .stat-card:nth-child(1) .cohort.in-view .cohort-shop.dark:nth-child(3) { animation-delay: 1.0s; }
  .stat-card:nth-child(1) .cohort.in-view .cohort-shop.dark:nth-child(4) { animation-delay: 1.2s; }
  .stat-card:nth-child(1) .cohort.in-view .cohort-shop.dark:nth-child(5) { animation-delay: 1.4s; }
  @keyframes dark-flicker {
    0%   { background: var(--green); box-shadow: inset 0 0 0 2px rgba(255,255,255,0.15); }
    30%  { background: var(--coral); opacity: 0.9; }
    50%  { background: var(--surface-2); opacity: 1; }
    100% { background: var(--surface-2); border: 1px solid var(--border); opacity: 1; }
  }
  .stat-card:nth-child(1) .cohort.in-view .cohort-shop.dark::after { animation: dark-x-in 6s ease 1.4s infinite; }
  @keyframes dark-x-in {
    0%, 60% { opacity: 0; }
    100%    { opacity: 1; }
  }

  /* 2. 213/day — manual clicker counter: each box rolls its strip up
     incrementally to its digit — ones 0→1→2→3, tens 0→1, hundreds
     0→2 — reading like clicking a mechanical tally counter. Each line
     is 52px tall; -104px reveals the 3rd line, etc. Plus the pulsing
     '~7 min' dot. */
  .stat-card:nth-child(2) .clicker.in-view .clicker-cell:nth-child(1) .clicker-strip { animation: click-2 6s cubic-bezier(0.22, 1, 0.36, 1) infinite; }
  .stat-card:nth-child(2) .clicker.in-view .clicker-cell:nth-child(2) .clicker-strip { animation: click-1 6s cubic-bezier(0.22, 1, 0.36, 1) infinite; }
  .stat-card:nth-child(2) .clicker.in-view .clicker-cell:nth-child(3) .clicker-strip { animation: click-3 6s cubic-bezier(0.22, 1, 0.36, 1) infinite; }
  @keyframes click-2 {
    0%   { transform: translateY(0); }
    40%  { transform: translateY(-52px); }
    55%  { transform: translateY(-104px); }
    100% { transform: translateY(-104px); }
  }
  @keyframes click-1 {
    0%   { transform: translateY(0); }
    60%  { transform: translateY(-52px); }
    100% { transform: translateY(-52px); }
  }
  @keyframes click-3 {
    0%   { transform: translateY(0); }
    33%  { transform: translateY(-52px); }
    50%  { transform: translateY(-104px); }
    100% { transform: translateY(-156px); }
  }
  /* Pulse dot — a steady heartbeat suggesting continuous registration */
  .stat-card:nth-child(2) .ticker.in-view .ticker-pulse {
    animation: ticker-pulse 1.6s ease-out infinite;
  }
  @keyframes ticker-pulse {
    0%   { box-shadow: 0 0 0 0 rgba(14,110,92,0.5); }
    100% { box-shadow: 0 0 0 8px rgba(14,110,92,0); }
  }

  /* 3. 50% up from 39% — comparison bars grow with overshoot; the 50%
     bar overshoots to 105% then settles to 100%; trend chip pops with
     anticipation. */
  .stat-card:nth-child(3) .cmp-bars.in-view .cmp-fill.before {
    animation: grow-fill-loop 5s cubic-bezier(0.34, 1.56, 0.64, 1) infinite;
  }
  .stat-card:nth-child(3) .cmp-bars.in-view .cmp-fill.after {
    animation: grow-fill-overshoot-loop 5s cubic-bezier(0.16, 1, 0.3, 1) 0.4s  infinite;
  }
  @keyframes grow-fill-overshoot {
    0%   { transform: scaleX(0); }
    70%  { transform: scaleX(1.05); }
    100% { transform: scaleX(1); }
  }
  .stat-card:nth-child(3) .trend-chip.in-view {
    animation: chip-pop-loop 5s cubic-bezier(0.34, 1.56, 0.64, 1) 0.9s  infinite;
  }
  @keyframes chip-pop {
    0%   { transform: scale(0.6); opacity: 0; }
    60%  { transform: scale(1.15); opacity: 1; }
    100% { transform: scale(1); opacity: 1; }
  }

  /* 4. 55% — customer concern split: the 55% majority bar grows with
     overshoot, highlighting that more than half worry about customers. */
  .stat-card:nth-child(4) .split.in-view .split-keep {
    transform-origin: left;
    animation: grow-fill-overshoot-loop 5s cubic-bezier(0.16, 1, 0.3, 1) infinite;
  }

  /* 5. 36% #1 concern — the rank row slides in with a pop. */
  .stat-card:nth-child(5) .rank.in-view .rank-row.top {
    animation: rank-in-loop 5s cubic-bezier(0.34, 1.56, 0.64, 1) infinite;
  }
  @keyframes rank-in {
    0%   { opacity: 0; transform: translateY(6px); }
    60%  { opacity: 1; transform: translateY(-2px); }
    100% { opacity: 1; transform: translateY(0); }
  }

  /* 6. 25K — cost vs value: cost bars grow first, then value bars
     overgrow them (the contrast shows a little cost buys a lot of
     value). */
  .stat-card:nth-child(6) .value-chart.in-view .vc-cost-fill {
    animation: grow-fill-loop 5s cubic-bezier(0.22, 1, 0.36, 1) infinite;
  }
  .stat-card:nth-child(6) .value-chart.in-view .vc-value-fill {
    animation: grow-fill-overshoot-loop 5s cubic-bezier(0.16, 1, 0.3, 1) 0.5s infinite;
  }
  @keyframes crowd-rain {
    0%   { transform: translateY(-12px) scale(0.4); opacity: 0; }
    60%  { transform: translateY(2px) scale(1.2); opacity: 1; }
    100% { transform: translateY(0) scale(1); opacity: 1; }
  }
}

/* ─── SIGNATURE CASE ANIMATIONS + STAT INFOGRAPHICS (18 Aug 2026) ─── */
/* Distinct animation per case + dynamic stat blocks. Base layout styles
   apply ALWAYS (elements visible even without animation); the keyframes
   live inside the prefers-reduced-motion: no-preference block below.
   All visuals are aria-hidden — the real numbers stay in .case-bars and
   .num text (the animation is a visual layer, not the data). */

/* Odometer — digit-roll count-up (CSS-only; true counter count-up needs JS) */
.odometer {
  display: inline-flex;
  align-items: baseline;
  font-family: var(--font-mono);
  font-weight: 700;
  color: var(--green);
  line-height: 1;
  margin-top: 10px;
  font-size: 1.6em;
}
.odo-digit { display: inline-block; height: 1em; overflow: hidden; }
.odo-strip { display: block; line-height: 1; }
.odo-sep { color: var(--fg-2); }
/* Final digit of the odometer — the climax lands with a scale pop */
.odo-final { display: inline-block; color: var(--green); font-weight: 700; }

/* Manual clicker counter device — 3 rectangle boxes in a frame,
   counting up incrementally (tally-counter style). */
.clicker {
  display: inline-flex;
  flex-direction: column;
  margin-top: 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  overflow: hidden;
  max-width: 240px;
  box-shadow: 0 2px 12px rgba(0,0,0,0.18);
}
.clicker-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 12px;
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
}
.clicker-brand { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.12em; color: var(--fg-3); text-transform: uppercase; }
.clicker-handle { width: 32px; height: 10px; border-radius: 3px; background: var(--green); transform: rotate(-6deg); box-shadow: 0 2px 4px rgba(0,0,0,0.25); }
.clicker-box {
  display: flex;
  gap: 4px;
  padding: 10px 12px;
  background: var(--surface);
  justify-content: center;
}
.clicker-cell {
  display: inline-grid;
  place-items: center;
  width: 40px;
  height: 52px;
  border: 2px solid var(--border);
  border-radius: 4px;
  background: var(--surface-2);
  font-family: var(--font-mono);
  font-size: 30px;
  font-weight: 700;
  color: var(--fg);
  box-shadow: inset 0 2px 3px rgba(0,0,0,0.12);
  overflow: hidden;
  line-height: 1;
  position: relative;
}
.clicker-strip { display: block; line-height: 52px; }
.clicker-base { height: 5px; background: repeating-linear-gradient(90deg, var(--surface-2) 0 6px, var(--border) 6px 8px); }

/* Airbnb stock-price line chart — draws upward from $0.9B (2015) to $4.8B (2019) */
.stock-chart { margin-top: var(--space-2); }
.stock-chart svg { width: 100%; height: auto; display: block; }
.stock-chart .chart-grid { stroke: var(--border-subtle); stroke-width: 1; stroke-dasharray: 3 3; }
.stock-chart .chart-line {
  fill: none;
  stroke: var(--green);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 400;
  stroke-dashoffset: 400;
}
.stock-chart .chart-dot { fill: var(--green); }
.stock-chart .chart-dot.start { fill: var(--coral); }
.stock-chart .chart-label { font-family: var(--font-mono); font-size: 10px; fill: var(--fg-3); }
.stock-chart .chart-label.end { fill: var(--green); font-weight: 600; }

/* Avis gauge — semicircle needle sweep */
.gauge { margin: var(--space-2) auto 0; display: flex; justify-content: center; }
.gauge svg { width: 100%; max-width: 280px; height: auto; display: block; }
.gauge .gauge-arc { fill: none; stroke: var(--surface-2); stroke-width: 12; }
.gauge .gauge-tick { stroke: var(--fg-3); stroke-width: 2; }
.gauge .gauge-needle { stroke: var(--green); stroke-width: 4; stroke-linecap: round; }
.gauge .gauge-pivot { fill: var(--green); }
.gauge .gauge-label { font-family: var(--font-mono); font-size: 12px; fill: var(--fg-3); }

/* Domino's USA map — 1 store, then dots spread across the country */
.usa-map { margin-top: var(--space-2); }
.usa-map svg { width: 100%; max-width: 280px; height: auto; display: block; }
.usa-outline {
  fill: rgba(14, 110, 92, 0.10);
  stroke: rgba(14, 110, 92, 0.55);
  stroke-width: 1.5;
  stroke-linejoin: round;
}
.usa-dot { fill: var(--green); opacity: 0; }
.usa-dot.first { fill: var(--coral); }

/* ── DESIGNED OBJECT SPEC — Tabler 24-grid, 2px stroke, brand green ──
   Both marks are glyphs from a professionally drawn family (Tabler,
   MIT), fetched from the Iconify API and pasted inline: no runtime
   dependency, no new files, no build step. They replace two
   hand-drawn pictograms whose uniform stroke + flat single-hue fill
   read as clip-art (the "kiddish" complaint).

   What changed beyond taste: the OLD marks drew a thing and encoded
   nothing. The new GWM mark draws the card's actual thesis —
   "pickup-truck maker" → "SUV specialist" — so past/present are
   distinguishable at a glance, which the single-weight cartoon
   could not express.

   ponytail: stock glyphs are recognisable AS stock — Tabler ships in
   a thousand SaaS dashboards, and this is a positioning consultancy
   whose whole pitch is differentiation. Fine at this mnemonic size;
   the upgrade path is the same 24-grid / 2px contract, redrawn
   bespoke, once the family's shape is settled. */

/* Volvo — safety. A designed shield-check, not a shield containing a car.
   Explicit box: an inline SVG with no width/height fills its container,
   which at this card width means a 442px shield. Same 120px footprint the
   old mark occupied, so the card's rhythm is unchanged. */
.volvo-mark {
  width: 120px;
  height: 120px;
  margin: var(--space-2) auto 0;
  display: block;
  color: var(--green);
}
.volvo-mark .volvo-shield-check {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Great Wall Motors — pickup → SUV, the repositioning the card measures.
   Past state recedes (muted grey); the present state carries the weight
   (full-strength brand green). Colour IS the second weight here, which
   is the hierarchy the old uniform-stroke cartoon lacked. */
.suv { color: var(--fg-3); }
.suv .reposition-from { color: var(--fg-3); }
.suv .reposition-arrow { color: var(--fg-3); opacity: 0.55; }
.suv .reposition-to { color: var(--green); }
.suv g > path {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Stat infographics */
/* Wanglaoji ladder — ascending steps */
.ladder { display: grid; gap: 8px; margin-top: var(--space-2); }
.ladder-step { display: grid; grid-template-columns: 64px 1fr; gap: 10px; align-items: center; }
.ladder-label { font-family: var(--font-mono); font-size: 12px; color: var(--fg-3); text-align: right; }
.ladder-bar { height: 18px; background: var(--surface-2); border-radius: 4px; width: var(--h, 100%); position: relative; overflow: hidden; }
.ladder-bar::after { content: ""; position: absolute; inset: 0; background: var(--green); transform-origin: left; transform: scaleX(0); }

/* Great Wall SUV — now the pickup→SUV glyph composition (see DESIGNED
   OBJECT SPEC above). Only the box is styled here; per-glyph colour and
   stroke live in the spec block. */
.suv { width: 100%; max-width: 280px; height: auto; margin-top: var(--space-2); display: block; }

/* Stat infographics */
.dot-row { display: flex; gap: 8px; margin-top: 10px; }
.dot-row .dot { width: 14px; height: 14px; border-radius: 50%; background: var(--green); }
/* The five that don't survive are coral (negative) */
.dot-row .dot:nth-child(n+6) { background: var(--coral); }

/* Flowing dot stream — continuous registration (213/day) */
.dot-stream { display: flex; gap: 6px; margin-top: 10px; overflow: hidden; }
.dot-stream .stream-dot { flex: 0 0 auto; width: 9px; height: 9px; border-radius: 50%; background: var(--green); opacity: 0.35; }

.cmp-bars { display: grid; gap: 8px; margin-top: 10px; }
.cmp-row { display: grid; grid-template-columns: 44px 1fr; gap: 10px; align-items: center; }
.cmp-label { font-family: var(--font-mono); font-size: 12px; color: var(--fg-3); }
.cmp-track { height: 18px; background: var(--surface-2); border-radius: 4px; }
.cmp-fill { height: 100%; border-radius: 4px; transform-origin: left; transform: scaleX(0); }
.cmp-fill.before { background: var(--coral); }
.cmp-fill.after { background: var(--green); }

.donut { width: 120px; height: 120px; margin-top: 10px; }
.donut-bg { fill: none; stroke: var(--surface-2); stroke-width: 12; }
.donut-fill { fill: none; stroke: var(--green); stroke-width: 12; stroke-linecap: round; stroke-dasharray: 201; stroke-dashoffset: 201; transform: rotate(-90deg); transform-origin: center; }
.donut-num { font-family: var(--font-mono); font-size: 22px; font-weight: 700; fill: var(--green); }

.marker-bar { margin-top: 10px; }
.marker-track { position: relative; height: 20px; background: var(--surface-2); border-radius: 4px; }
.marker-fill { height: 100%; width: 36%; background: var(--green); border-radius: 4px; transform-origin: left; transform: scaleX(0); }
.marker-pin { position: absolute; left: 36%; top: -8px; transform: translateX(-50%); font-family: var(--font-mono); font-size: 11px; color: #fff; background: var(--amber); border-radius: 3px; padding: 2px 6px; }

.crowd { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; max-width: 240px; }
.crowd .crowd-dot { width: 11px; height: 11px; border-radius: 50%; background: var(--green); }

/* ─── RESPONSIVE ─── */
@media (max-width: 860px) {
  body { font-size: 16px; }

  /* On mobile the text column is full-width — there are no margins to
     hide in. Dim the whole wash instead so it stays subtle behind text. */
  .bg-wash {
    opacity: 0.45;
  }

  .nav-links {
    position: fixed;
    top: 68px; left: 0; right: 0;
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    background: var(--bg);
    border-bottom: 1px solid var(--border);
    padding: 0 24px;
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.25s ease;
  }
  .nav-links.open { max-height: 460px; }
  .nav-links a { padding: 14px 0; width: 100%; border-bottom: 1px solid var(--border-subtle); }
  .nav-cta { margin-left: 0; margin: 16px 0; width: 100%; text-align: center; }
  .nav-toggle { display: inline-block; }

  /* Mobile dropdown — full-width, stacked */
  .nav-dropdown { width: 100%; }
  .nav-dropdown-toggle {
    width: 100%; justify-content: space-between;
    padding: 14px 0; border-bottom: 1px solid var(--border-subtle);
  }
  .nav-dropdown-menu {
    position: static; transform: none; width: 100%;
    min-width: 0; box-shadow: none; border: none; border-radius: 0;
    padding: 0 0 0 16px; background: transparent;
    opacity: 1; visibility: visible; pointer-events: auto;
    max-height: 0; overflow: hidden;
    transition: max-height 0.25s ease;
  }
  .nav-dropdown.open .nav-dropdown-menu { max-height: 200px; }
  .nav-dropdown-menu a { padding: 12px 0; border-bottom: 1px solid var(--border-subtle); }

  .mobile-cta-bar { display: block; }
  .site-footer { padding-bottom: 110px; }

  .hero { padding: var(--space-5) 0 var(--space-4); }
  .section { padding: var(--space-4) 0; }

  .fork-grid, .card-grid, .stats-grid, .process, .split, .store-grid, .case-grid { grid-template-columns: 1fr; }
  .steps { flex-direction: column; }
  .step-arrow { transform: rotate(90deg); padding: 4px 0; }
  .hero-flow { flex-direction: column; }
  .hero-flow .flow-arrow { transform: rotate(90deg); padding: 4px 0; }
  .method-pipeline { flex-direction: column; }
  .method-pipeline .pipe-arrow { transform: rotate(90deg); padding: 4px 0; }
  .cost-scale .scale-row { grid-template-columns: 1fr; gap: 6px; }
  .case-bar-row { grid-template-columns: 64px 1fr; }
  .cost-table { font-size: 13.5px; }
  .cost-table th, .cost-table td { padding: 12px 10px; }
  .human { grid-template-columns: 1fr; }
  .price-band { text-align: left; padding: var(--space-3); }
  .price-band .price-ctas { justify-content: flex-start; }
  .hero .sub { font-size: 17px; }
}

/* ─── REDUCED MOTION ─── */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { transition: none !important; }
}

@keyframes grow-fill-overshoot-loop {
  0%   { transform: scaleX(0); }
  10%  { transform: scaleX(1.05); }
  15%  { transform: scaleX(1); }
  100% { transform: scaleX(1); }
}

@keyframes fw-draw-loop {
  0%   { stroke-dashoffset: 1131; }
  15%  { stroke-dashoffset: 0; }
  100% { stroke-dashoffset: 0; }
}

@keyframes fw-node-pop-loop {
  0%   { transform: scale(0); opacity: 0; }
  9%   { transform: scale(1.25); opacity: 1; }
  15%  { transform: scale(1); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}

@keyframes odo-roll-loop {
  0%   { transform: translateY(0); }
  15%  { transform: translateY(var(--odo-to, -1em)); }
  100% { transform: translateY(var(--odo-to, -1em)); }
}

@keyframes odo-final-pop-loop {
  0%   { transform: scale(0); opacity: 0; }
  9%   { transform: scale(1.3); opacity: 1; }
  15%  { transform: scale(1); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}

@keyframes gauge-sweep-loop {
  0%   { transform: rotate(-72deg); }  /* 10% — start, in lock step with bars */
  15%  { transform: rotate(-38deg); }  /* 29% — settle, same window as bars */
  100% { transform: rotate(-38deg); }
}

@keyframes map-dot-pop-loop {
  0%   { transform: scale(0); opacity: 0; }
  9%   { transform: scale(1.2); opacity: 1; }
  15%  { transform: scale(1); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}

@keyframes ladder-fill-loop {
  0%   { transform: scaleX(0); }
  10%  { transform: scaleX(1.05); }
  15%  { transform: scaleX(1); }
  100% { transform: scaleX(1); }
}

@keyframes ladder-label-pop-loop {
  0%   { transform: scale(0.6); opacity: 0; }
  9%   { transform: scale(1.15); opacity: 1; }
  15%  { transform: scale(1); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}


@keyframes dot-fall-loop {
  0%   { transform: translateY(0) scale(1); opacity: 1; }
  15%  { transform: translateY(14px) scale(0.4); opacity: 0; }
  100% { transform: translateY(14px) scale(0.4); opacity: 0; }
}

@keyframes chip-pop-loop {
  0%   { transform: scale(0.6); opacity: 0; }
  9%   { transform: scale(1.15); opacity: 1; }
  15%  { transform: scale(1); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}

@keyframes donut-fill-loop {
  0%   { stroke-dashoffset: 201; }
  15%  { stroke-dashoffset: 90; }
  100% { stroke-dashoffset: 90; }
}

@keyframes donut-num-pop-loop {
  0%   { transform: scale(0); opacity: 0; }
  9%   { transform: scale(1.25); opacity: 1; }
  15%  { transform: scale(1); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}

@keyframes pin-drop-loop {
  0%   { transform: translateX(-50%) translateY(-14px); opacity: 0; }
  9%   { transform: translateX(-50%) translateY(4px); opacity: 1; }
  15%  { transform: translateX(-50%) translateY(0); opacity: 1; }
  100% { transform: translateX(-50%) translateY(0); opacity: 1; }
}

@keyframes crowd-rain-loop {
  0%   { transform: translateY(-12px) scale(0.4); opacity: 0; }
  9%   { transform: translateY(2px) scale(1.2); opacity: 1; }
  15%  { transform: translateY(0) scale(1); opacity: 1; }
  100% { transform: translateY(0) scale(1); opacity: 1; }
}

/* ============================================================
   White-space band — the crowded market, and the gaps that move.
   Teal field = the crowded market. White radial holes = the
   open positions nobody owns. Gaps drift, pulse and slide on
   infinite loops. Animation is gated behind .in-view (added by
   assets/draft.js when the band scrolls into view).
   ============================================================ */
.white-space-section {
  padding: 0;                       /* band is full-bleed, no side padding */
}

.white-space-band {
  position: relative;
  overflow: hidden;
  height: 300px;
  background:
    radial-gradient(120% 140% at 15% 20%, #0a5447 0%, #0e6e5c 45%, #0a5447 100%);
  display: flex;
  align-items: center;
  justify-content: center;
}

/* The drifting white gaps — decorative, aria-hidden in markup */
.ws-gaps {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.ws-gap {
  position: absolute;
  display: block;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, rgba(255,255,255,0.95) 0%, rgba(255,255,255,0.55) 45%, rgba(255,255,255,0) 72%);
  opacity: 0;
  will-change: transform, opacity;
}

/* Sizes + base positions — organic variety */
.ws-gap-1 { width: 150px; height: 150px; top: 12%;  left: 6%;  }
.ws-gap-2 { width: 90px;  height: 90px;  top: 60%;  left: 18%; }
.ws-gap-3 { width: 210px; height: 210px; top: 30%;  left: 34%; }
.ws-gap-4 { width: 70px;  height: 70px;  top: 70%;  left: 48%; }
.ws-gap-5 { width: 120px; height: 120px; top: 15%;  left: 60%; }
.ws-gap-6 { width: 180px; height: 180px; top: 55%;  left: 72%; }
.ws-gap-7 { width: 60px;  height: 60px;  top: 25%;  left: 84%; }
.ws-gap-8 { width: 100px; height: 100px; top: 65%;  left: 90%; }
.ws-gap-9 { width: 140px; height: 140px; top: 40%;  left: 12%; }

/* Drift + breathe loops — each gap moves at its own pace */
@keyframes ws-drift-1 { 0%{transform:translate(0,0) scale(1);opacity:0} 8%{opacity:.9} 50%{transform:translate(60px,-30px) scale(1.15);opacity:.85} 100%{transform:translate(0,0) scale(1);opacity:0} }
@keyframes ws-drift-2 { 0%{transform:translate(0,0) scale(1);opacity:0} 10%{opacity:.8} 50%{transform:translate(-50px,40px) scale(.8);opacity:.7} 100%{transform:translate(0,0) scale(1);opacity:0} }
@keyframes ws-drift-3 { 0%{transform:translate(0,0) scale(1);opacity:0} 6%{opacity:.9} 50%{transform:translate(-80px,-20px) scale(1.3);opacity:.8} 100%{transform:translate(0,0) scale(1);opacity:0} }
@keyframes ws-drift-4 { 0%{transform:translate(0,0) scale(1);opacity:0} 12%{opacity:.7} 50%{transform:translate(40px,50px) scale(.7);opacity:.6} 100%{transform:translate(0,0) scale(1);opacity:0} }
@keyframes ws-drift-5 { 0%{transform:translate(0,0) scale(1);opacity:0} 7%{opacity:.9} 50%{transform:translate(70px,30px) scale(1.2);opacity:.8} 100%{transform:translate(0,0) scale(1);opacity:0} }
@keyframes ws-drift-6 { 0%{transform:translate(0,0) scale(1);opacity:0} 9%{opacity:.85} 50%{transform:translate(-60px,-40px) scale(1.1);opacity:.75} 100%{transform:translate(0,0) scale(1);opacity:0} }
@keyframes ws-drift-7 { 0%{transform:translate(0,0) scale(1);opacity:0} 11%{opacity:.7} 50%{transform:translate(30px,60px) scale(.9);opacity:.6} 100%{transform:translate(0,0) scale(1);opacity:0} }
@keyframes ws-drift-8 { 0%{transform:translate(0,0) scale(1);opacity:0} 8%{opacity:.8} 50%{transform:translate(-40px,-50px) scale(1.25);opacity:.7} 100%{transform:translate(0,0) scale(1);opacity:0} }
@keyframes ws-drift-9 { 0%{transform:translate(0,0) scale(1);opacity:0} 10%{opacity:.85} 50%{transform:translate(50px,20px) scale(1.05);opacity:.75} 100%{transform:translate(0,0) scale(1);opacity:0} }

/* Gate the animation behind .in-view (scroll-triggered) */
.white-space-band .ws-gap {
  animation: none;
}
.white-space-band.in-view .ws-gap-1 { animation: ws-drift-1 14s ease-in-out infinite; }
.white-space-band.in-view .ws-gap-2 { animation: ws-drift-2 11s ease-in-out infinite; }
.white-space-band.in-view .ws-gap-3 { animation: ws-drift-3 17s ease-in-out infinite; }
.white-space-band.in-view .ws-gap-4 { animation: ws-drift-4 9s  ease-in-out infinite; }
.white-space-band.in-view .ws-gap-5 { animation: ws-drift-5 13s ease-in-out infinite; }
.white-space-band.in-view .ws-gap-6 { animation: ws-drift-6 16s ease-in-out infinite; }
.white-space-band.in-view .ws-gap-7 { animation: ws-drift-7 10s ease-in-out infinite; }
.white-space-band.in-view .ws-gap-8 { animation: ws-drift-8 12s ease-in-out infinite; }
.white-space-band.in-view .ws-gap-9 { animation: ws-drift-9 15s ease-in-out infinite; }

/* Caption — real text, white on teal */
.ws-caption {
  position: relative;
  z-index: 2;
  text-align: center;
  color: #ffffff;
  padding: 0 var(--space-3);
  max-width: 640px;
}
.ws-caption h2 {
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 3.4vw, 2.4rem);
  font-weight: 600;
  line-height: 1.15;
  margin-bottom: var(--space-2);
  color: #ffffff;
}
.ws-caption p {
  font-family: var(--font-sans);
  font-size: clamp(1rem, 1.6vw, 1.15rem);
  color: rgba(255,255,255,0.9);
  line-height: 1.5;
}

/* Mobile — shorter band, no layout break */
@media (max-width: 640px) {
  .white-space-band { height: 220px; }
  .ws-gap-1 { width: 110px; height: 110px; }
  .ws-gap-3 { width: 150px; height: 150px; }
  .ws-gap-6 { width: 130px; height: 130px; }
}

/* Respect reduced-motion — freeze the gaps, keep the caption */
@media (prefers-reduced-motion: reduce) {
  .white-space-band.in-view .ws-gap {
    animation: none;
    opacity: 0.5;
  }
}


/* ════════════════════════════════════════════════════════════════
   FLANK AND BEACHHEAD - native explainer (ported from the React bundle)
   Stepper + scroll cue. Same design tokens. No framework.
   ════════════════════════════════════════════════════════════════ */

/* Act spine - three labelled acts, not seven dots */
.act-spine { display: flex; gap: 2px; margin-bottom: var(--space-3); background: var(--border); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.act-spine .act-seg { flex: 1; text-align: center; padding: 12px 10px; background: var(--surface); font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--fg-3); cursor: pointer; transition: background 0.25s ease, color 0.25s ease; border: 0; }
.act-spine .act-seg:hover { color: var(--green); }
.act-spine .act-seg.active { background: var(--green); color: #fff; }

/* Step dots — one per step, grouped by act */
.flank-dots { display: flex; align-items: center; gap: 6px; }
.flank-dots .fdot { width: 34px; height: 34px; display: grid; place-items: center; border: 0; background: none; cursor: pointer; padding: 0; border-radius: var(--radius); }
.flank-dots .fdot span { display: block; width: 100%; height: 4px; border-radius: 3px; transition: background 0.25s ease; }
.flank-dots .fdot:hover span { background: var(--green); }
.flank-dots .fdot.active span { background: var(--green); }
.flank-dots .fdot.done span { background: var(--green-dim); }

/* Map card + overlays */
.flank-map-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); overflow: hidden; box-shadow: 0 1px 2px rgba(27,31,36,.04); }
.flank-map-card .flank-map-head { display: flex; flex-wrap: wrap; gap: 12px; align-items: baseline; justify-content: space-between; padding: 16px 20px; border-bottom: 1px solid var(--border); }
.flank-map-card .flank-map-head .map-label { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--fg-3); }
.flank-map-card .flank-map-head .map-step { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--green); }
.flank-map-card svg { display: block; width: 100%; height: auto; background: var(--bg); }
.flank-map-card .flank-map-foot { padding: 20px 24px 24px; border-top: 1px solid var(--border); min-height: 240px; }

/* Legend chips */
.flank-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; min-height: 26px; }
.flank-chips .chip { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; border-radius: 6px; padding: 5px 10px; }
.flank-chips .chip-a { color: var(--green); background: var(--green-dim); border: 1px solid #c6dcd4; }
.flank-chips .chip-b { color: var(--fg-2); background: var(--surface); border: 1px solid var(--border); }

/* Stepper body + worked example */
.flank-step-title { font-family: var(--font-display); font-size: 22px; line-height: 1.22; margin: 0 0 8px; }
.flank-step-body { font-size: 15px; line-height: 1.65; color: var(--fg-2); max-width: 74ch; }
.flank-example { margin-top: 14px; border-left: 2px solid #c6dcd4; padding: 1px 0 1px 14px; }
.flank-example .ex-label { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--green); margin-bottom: 5px; }
.flank-example p { margin: 0; font-size: 14px; line-height: 1.6; color: var(--fg-2); max-width: 72ch; }

/* Stepper controls */
.flank-topbar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 14px; }
.flank-topbar .btn-step { width: 42px; height: 42px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--surface); color: var(--fg); cursor: pointer; font-size: 17px; display: grid; place-items: center; transition: border-color 0.2s ease, color 0.2s ease; }
.flank-topbar .btn-step:hover { border-color: var(--green); color: var(--green); }
.flank-topbar .flank-counter { margin-left: auto; font-family: var(--font-mono); font-size: 12px; color: var(--fg-3); letter-spacing: 0.1em; }
.flank-topbar .act-spine { margin-bottom: 0; }
.flank-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 20px; }
.flank-controls .btn-step { width: 42px; height: 42px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--surface); color: var(--fg); cursor: pointer; font-size: 17px; display: grid; place-items: center; transition: border-color 0.2s ease, color 0.2s ease; }
.flank-controls .btn-step:hover { border-color: var(--green); color: var(--green); }
.flank-counter { margin-left: auto; font-family: var(--font-mono); font-size: 12px; color: var(--fg-3); letter-spacing: 0.1em; }
.flank-dots { margin-top: 16px; }

/* The three-act reference rail */
.flank-rail { display: flex; flex-direction: column; gap: 4px; }
.flank-rail article { padding: 18px 0 20px; border-top: 1px solid var(--border); transition: opacity 0.35s ease; }
.flank-rail article .rail-kicker { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase; margin-bottom: 8px; display: block; }
.flank-rail article h3 { font-family: var(--font-display); font-size: 20px; line-height: 1.15; margin: 0 0 10px; font-weight: 600; }
.flank-rail article p { margin: 0 0 12px; font-size: 15px; line-height: 1.62; color: var(--fg-2); }
.flank-rail article ul { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 8px; }
.flank-rail article li { display: grid; grid-template-columns: 14px 1fr; gap: 10px; font-size: 14px; line-height: 1.55; color: var(--fg-2); }
.flank-rail article li .dash { color: var(--green); }

/* Layout — full-bleed flank section */
.section-flank { padding: var(--space-5) 0; }
.flank-wrap { max-width: 1600px; margin: 0 auto; padding: 0 24px; }
.flank-grid { display: grid; grid-template-columns: minmax(0,1fr); gap: 0; margin-top: var(--space-4); }
.flank-grid > .flank-map-col { min-width: 0; }

/* Map + step content side by side, same eye level, full width */
.flank-map-card { display: flex; flex-direction: column; }
.flank-map-body { display: grid; grid-template-columns: minmax(0,1fr) minmax(340px, 420px); gap: 0; align-items: start; }
.flank-map-body > #mapSvg { min-width: 0; }
.flank-map-body > .flank-map-foot { border-top: 0; border-left: 1px solid var(--border); min-height: 0; }
@media (max-width: 980px) {
  .flank-map-body { grid-template-columns: 1fr; }
  .flank-map-body > .flank-map-foot { border-left: 0; border-top: 1px solid var(--border); }
}

/* Three bounded outcomes */
.outcome-grid { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 20px; }
@media (max-width: 980px) { .outcome-grid { grid-template-columns: 1fr; } }
.outcome-card { position: relative; display: flex; flex-direction: column; padding: 24px; border-radius: var(--radius-lg); border: 1px solid var(--border); background: var(--surface); box-shadow: 0 1px 2px rgba(27,31,36,.04); overflow: hidden; transition: opacity 0.35s ease, background 0.35s ease, border-color 0.35s ease, box-shadow 0.35s ease; }
.outcome-card::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 3px; background: var(--border); transition: background 0.35s ease; }
.outcome-card.on { background: var(--green-dim); border-color: #c6dcd4; box-shadow: 0 12px 32px rgba(14,110,92,.10); }
.outcome-card.on::before { background: var(--green); }
.outcome-card .oc-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 8px; }
.outcome-card .oc-kicker { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase; display: block; color: var(--fg-3); }
.outcome-card .oc-illus { font-family: var(--font-mono); font-size: 9px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--coral); background: var(--coral-dim); padding: 3px 8px; border-radius: 9999px; white-space: nowrap; }
.outcome-card h3 { font-family: var(--font-display); font-size: 23px; margin: 0 0 6px; font-weight: 600; }
.outcome-card .oc-thesis { margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: var(--fg-2); }
.outcome-card p { margin: 0; }

/* Tier legend */
.tier-legend { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-bottom: 26px; padding: 16px 18px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); }
.tier-legend .tier-legend-label { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--fg-3); margin-right: 4px; }
.tier-pill { display: inline-flex; align-items: center; font-size: 12.5px; font-weight: 500; padding: 5px 11px; border-radius: 9999px; background: var(--surface-muted, #f1f0ec); color: var(--fg-2); }
.tier-pill.t1 { background: var(--coral-dim); color: var(--coral); }
.tier-pill.t2 { background: rgba(201,154,63,.14); color: #9a6500; }
.tier-pill.t3 { background: var(--green-dim); color: var(--green); }

/* Who you steal from */
.outcome-card .oc-steal { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--fg-2); padding: 8px 12px; border-radius: 10px; margin-bottom: 16px; }
.outcome-card .oc-steal.t1 { background: var(--coral-dim); }
.outcome-card .oc-steal.t2 { background: rgba(201,154,63,.12); }
.outcome-card .oc-steal.t3 { background: var(--green-dim); }
.outcome-card .oc-steal .ss-note { color: var(--fg-3); font-size: 12px; }

/* KPI row */
.oc-kpis { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; margin-bottom: 18px; }
.oc-kpi { background: var(--surface-muted, #f1f0ec); border-radius: 10px; padding: 10px 12px; }
.oc-kpi .k-label { font-family: var(--font-mono); font-size: 9px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--fg-3); display: block; margin-bottom: 4px; }
.oc-kpi .k-value { font-family: var(--font-mono); font-size: 19px; font-weight: 600; color: var(--fg); line-height: 1.1; }
.oc-kpi .k-value small { font-size: 12px; font-weight: 500; color: var(--fg-3); }
.oc-kpi .k-delta { font-family: var(--font-mono); font-size: 10px; display: block; margin-top: 2px; }
.k-delta.upk { color: var(--green); }
.k-delta.flat { color: var(--fg-3); }

/* Chart */
.oc-chart { position: relative; height: 150px; margin-bottom: 16px; border: 1px solid var(--border-soft, #efeee9); border-radius: 10px; background: var(--surface); overflow: hidden; }
.oc-chart .chart-label { position: absolute; top: 8px; left: 12px; font-family: var(--font-mono); font-size: 9px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--fg-3); z-index: 2; }
.oc-chart svg { position: absolute; inset: 0; width: 100%; height: 100%; }

/* How you steal it */
.outcome-card .oc-how { margin-top: auto; padding: 14px; border-radius: 10px; background: var(--green-dim); }
.outcome-card .oc-how .oc-how-label { font-family: var(--font-mono); font-size: 9px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--green-hover); display: block; margin-bottom: 5px; }
.outcome-card .oc-how p { font-size: 13px; line-height: 1.55; color: var(--fg-2); }
.outcome-card .oc-how p strong { color: var(--fg); font-weight: 600; }

/* Chart animations (gated by .in-view) */
.donut-ring { fill: none; stroke: var(--border); stroke-width: 14; }
.donut-fill { fill: none; stroke: var(--green); stroke-width: 14; stroke-linecap: round; stroke-dasharray: 0 100; transition: stroke-dasharray 1.1s cubic-bezier(.16,1,.3,1); }
.in-view .donut-fill { stroke-dasharray: 100 0; }
.donut-center { font-family: var(--font-mono); font-size: 15px; font-weight: 600; fill: var(--fg); }
.donut-sub { font-family: var(--font-mono); font-size: 8px; fill: var(--fg-3); letter-spacing: 0.1em; }

/* Pie chart — total market share (outcome cards) */
.pie-ring { fill: var(--surface-2); }
.pie-slice { fill: var(--green); transform-origin: center; transform-box: fill-box; opacity: 0; }
.in-view .pie-slice { animation: pie-sweep 1.2s cubic-bezier(.16,1,.3,1) forwards; }
@keyframes pie-sweep {
  0%   { opacity: 0; transform: scale(0.4); }
  100% { opacity: 1; transform: scale(1); }
}
.pie-center { font-family: var(--font-mono); font-size: 20px; font-weight: 700; fill: var(--fg); }
.pie-sub { font-family: var(--font-mono); font-size: 8px; fill: var(--fg-3); letter-spacing: 0.1em; }

/* Pie callout — % label OUTSIDE the pie, with a leader line + dot
   pointing at the slice. Dark ink on paper, readable. */
.pie-callout { opacity: 0; }
.in-view .pie-callout { animation: pie-callout-in 0.6s ease 0.9s forwards; }
@keyframes pie-callout-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.pie-leader { stroke: var(--fg-3); stroke-width: 1.5; stroke-dasharray: 3 3; }
.pie-leader-dot { fill: var(--green); }
.pie-label { font-family: var(--font-mono); font-size: 15px; font-weight: 700; fill: var(--fg); }
.flat-line { fill: none; stroke: var(--green); stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 400; stroke-dashoffset: 400; transition: stroke-dashoffset 1.2s cubic-bezier(.16,1,.3,1); }
.in-view .flat-line { stroke-dashoffset: 0; }
.flat-dot { fill: var(--green); opacity: 0; transition: opacity 0.3s ease 1.1s; }
.in-view .flat-dot { opacity: 1; }
.bar { fill: var(--green); opacity: 0; transform-origin: bottom; transform: scaleY(0); transition: transform 0.7s cubic-bezier(.16,1,.3,1) var(--d,0s), opacity 0.3s ease; }
.in-view .bar { transform: scaleY(1); opacity: 1; }
.bar-grid { stroke: var(--border-soft); stroke-width: 1; }
.scurve { fill: none; stroke: var(--green); stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 500; stroke-dashoffset: 500; transition: stroke-dashoffset 1.4s cubic-bezier(.16,1,.3,1); }
.in-view .scurve { stroke-dashoffset: 0; }
.scurve-area { fill: url(#scurveGrad); opacity: 0; transition: opacity 0.6s ease 0.9s; }
.in-view .scurve-area { opacity: 1; }
.rival-marker { opacity: 0; transition: opacity 0.3s ease 1.3s; }
.in-view .rival-marker { opacity: 1; }
.rival-line { stroke: var(--coral); stroke-width: 1.5; stroke-dasharray: 4 3; }
.rival-dot { fill: var(--coral); }

@media (prefers-reduced-motion: reduce) {
  .donut-fill, .flat-line, .bar, .scurve, .scurve-area, .rival-marker, .flat-dot { transition: none; opacity: 1; transform: none; stroke-dashoffset: 0; stroke-dasharray: 100 0; }
  .bar { transform: scaleY(1); }
}

/* Four words grid */
.words-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px,1fr)); gap: 1px; background: var(--border); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; margin-top: var(--space-4); }
.words-grid .word-cell { background: var(--surface); padding: 16px 18px; }
.words-grid .word-cell .wc-kicker { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--green); margin-bottom: 6px; display: block; }
.words-grid .word-cell p { margin: 0; font-size: 14px; line-height: 1.55; color: var(--fg-2); }

/* Flank hero acts */
.flank-hero-acts { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 20px; }
.flank-hero-acts dt { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--fg-3); margin-bottom: 8px; }
.flank-hero-acts dd { margin: 0; font-family: var(--font-display); font-size: 18px; line-height: 1.25; }
@media (max-width: 720px) { .flank-hero-acts { grid-template-columns: 1fr; gap: 12px; } }

/* Scroll cue */
.flank-scroll-cue { display: flex; align-items: center; gap: 8px; margin-top: 10px; font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); }
.flank-scroll-cue .cue-bar { width: 28px; height: 3px; border-radius: 2px; background: var(--border); overflow: hidden; position: relative; }
.flank-scroll-cue .cue-bar::after { content: ""; position: absolute; inset: 0; background: var(--green); transform: translateX(-100%); animation: cue-slide 2.4s ease-in-out infinite; }
@keyframes cue-slide { 0% { transform: translateX(-100%); } 60%,100% { transform: translateX(100%); } }

/* ─── TOUCH TARGET SIZES (48px min for coarse pointers — audit 2026-09-15) ─── */
@media (pointer: coarse) {
  .nav-bar { height: auto; min-height: 64px; }
  .nav-brand, .nav-links a, .nav-dropdown-toggle { display: inline-flex; align-items: center; min-height: 48px; }
  .nav-links a { padding: 0 2px; }
  #sg-intro .skip { padding: 16px 24px; font-size: 13px; }
  .link-arrow { display: inline-flex; align-items: center; min-height: 48px; }
  .btn-wa { min-height: 48px; padding: 14px 24px; display: inline-flex; align-items: center; justify-content: center; }
}
/* ponytail: 48px min-height on coarse pointers only — desktop nav stays compact (68px bar).
   If a future design needs 48px on hover devices too, drop the media query scope. */

/* ============================================================
   ONE-SHOT EXHIBITS — 28 Sep 2026
   Why: the case-grid and stats-grid reveals replayed on infinite
   loops — bars re-grew, the odometer re-rolled, Domino's tiles
   re-rippled, and the Great Wall SUV re-drove in every 5s with its
   wheels spinning and the road scrolling forever. In a section that
   has to read as EVIDENCE, a perpetual loop reads as a toy. The
   site's own chart primitives (.bar / .scurve / .flat-line /
   .pie-slice) were always one-shot — these exhibits were the
   outlier, not the rule.

   Fix: each exhibit plays its reveal once and SETTLES on its true
   value. The *-loop keyframes already end on their settle frame, so
   only the iteration count changes — no keyframe was rewritten.

   Longhands only: the `animation` shorthand would wipe the per-element
   animation-delay stagger set further up.
   (Override block, kept append-only per site convention. If the
   exhibit CSS is ever refactored, fold these two longhands into the
   original declarations and delete this block.)
   ============================================================ */
@media (prefers-reduced-motion: no-preference) {
  /* A. Bars / fills that grow — settle at their true value */
  .case-bars.in-view .bar-fill.after,
  .phase-bar.in-view .bar-fill.before,
  .phase-bar.in-view .bar-fill.after,
  .cost-scale.in-view .scale-fill,
  .rank-bar.in-view .rank-fill,
  .data-bar.in-view .data-fill,
  .case-card:nth-child(1) .stock-chart.in-view .chart-line,
  .case-card:nth-child(5) .stock-chart.in-view .chart-line,
  .ladder.in-view .ladder-bar::after,
  .stat-card:nth-child(3) .cmp-bars.in-view .cmp-fill.before,
  .stat-card:nth-child(3) .cmp-bars.in-view .cmp-fill.after,
  .stat-card:nth-child(4) .split.in-view .split-keep,
  .stat-card:nth-child(6) .value-chart.in-view .vc-cost-fill,
  .stat-card:nth-child(6) .value-chart.in-view .vc-value-fill {
    animation-iteration-count: 1;
    animation-fill-mode: forwards;
  }

  /* B. Pop / slide / draw reveals — land once and hold */
  .case-card:nth-child(1) .odometer.in-view .odo-strip,
  .case-card:nth-child(1) .odometer.in-view .odo-final,
  .gauge.in-view .gauge-needle,
  .usa-map.in-view use[href="#domino-tile"],
  .ladder.in-view .ladder-label,
  .stat-card:nth-child(1) .cohort.in-view .cohort-shop.dark,
  .stat-card:nth-child(1) .cohort.in-view .cohort-shop.dark::after,
  .stat-card:nth-child(2) .clicker.in-view .clicker-cell:nth-child(1) .clicker-strip,
  .stat-card:nth-child(2) .clicker.in-view .clicker-cell:nth-child(2) .clicker-strip,
  .stat-card:nth-child(2) .clicker.in-view .clicker-cell:nth-child(3) .clicker-strip,
  .stat-card:nth-child(3) .trend-chip.in-view,
  .stat-card:nth-child(5) .rank.in-view .rank-row.top {
    animation-iteration-count: 1;
    animation-fill-mode: forwards;
  }

  /* C. Great Wall SUV — its drive-in / wheel-spin / road-scroll rules and
     keyframes were deleted with the cartoon they animated. The replacement
     mark is static, so it needs no settle gate (and no motion at all). */

  /* D. Process strip — the four step icons draw themselves once
     instead of redrawing their strokes every 5s. */
  .process-flow.in-view .step-icon .pi-a,
  .process-flow.in-view .step-icon .pi-b,
  .process-flow.in-view .step-icon .pi-c {
    animation-iteration-count: 1;
    animation-fill-mode: forwards;
  }

  /* Deliberately still looping (not reveals — they signal ONGOING
     activity, which is true): .ticker-pulse ("~1 registration every
     7 min") and .step-icon (soft "process is alive" halo). */
}

/* ============================================================
   INTERACTION LIFT — 28 Sep 2026
   Why: 23 hover rules existed and 13 of them changed ONLY
   border-color. Every interactive surface was static under the
   pointer — the CTAs changed colour and nothing else, and
   .fork-card even declared `transform 0.2s ease` in its
   transition with no transform anywhere to animate (a dead
   transition). That reads as inert, not restrained.

   Fix: one shared lift. Cards rise 2px and take a teal-tinted
   shadow; CTAs rise 2px; the nav CTA joins them. The site's own
   easing curve (cubic-bezier(.22,1,.36,1)) throughout — no new
   curve invented.

   Two traps dodged here:
   1. `.btn:active { transform: translateY(1px) }` (line 121) is
      equal specificity to a plain `.btn-primary:hover` and
      EARLIER in the file, so a plain :hover transform would have
      silently killed the press feedback. Hence `:hover:not(:active)`.
   2. Hover is gated behind `(hover: hover)` — on touch, hover
      styles latch on tap and never release.
   ============================================================ */
@media (prefers-reduced-motion: no-preference) {
  .fork-card,
  .stat-card,
  .card-item,
  .offer-card,
  .case-card {
    transition: border-color 0.2s ease,
                transform 0.24s cubic-bezier(0.22, 1, 0.36, 1),
                box-shadow 0.3s cubic-bezier(0.22, 1, 0.36, 1);
  }

  /* .btn already transitions transform at 0.1s — too abrupt to read
     as a lift. Give it the house curve, but let the press stay fast. */
  .btn {
    transition: background 0.2s ease, color 0.2s ease,
                border-color 0.2s ease,
                transform 0.18s cubic-bezier(0.22, 1, 0.36, 1);
  }
  .btn:active { transition-duration: 0.06s; }

  /* .nav-cta had no transition at all — this supplies its first. */
  .nav-links a.nav-cta {
    transition: background 0.2s ease, color 0.2s ease,
                transform 0.18s cubic-bezier(0.22, 1, 0.36, 1);
  }
}

@media (prefers-reduced-motion: no-preference) and (hover: hover) {
  .fork-card:hover,
  .stat-card:hover,
  .card-item:hover,
  .offer-card:hover,
  .case-card:hover {
    transform: translateY(-2px);
    border-color: var(--green);
    box-shadow: 0 12px 32px rgba(14, 110, 92, 0.10);
  }

  /* :not(:active) so the press state below still wins. */
  .btn-primary:hover:not(:active),
  .btn-ghost:hover:not(:active) {
    transform: translateY(-2px);
  }

  .nav-links a.nav-cta:hover { transform: translateY(-2px); }
}
/* ponytail: a flat -2px lift, not size-proportional — it reads as motion at
   the card sizes on the site today (all ~300-500px). If a future card is
   dramatically larger, drive it from a --lift token instead.
   Ceiling 2: reduced-motion users get the border-color change only. That is
   deliberate (WCAG) — the colour shift still confirms the target is live.
   Ceiling 3: no hover on touch by design; the coarse-pointer block above
   already gives those users 48px targets instead. */

/* ============================================================
   MARK REVEALS — 28 Sep 2026
   Why: replacing the two clip-art pictograms with designed glyphs
   removed their motion outright (the old ones re-drove / re-drew on
   infinite loops). That killed the "too kiddish" axis but left these
   two marks as the ONLY static objects in an otherwise animated
   card grid — an inconsistency introduced by the mark swap.

   Fix: give each mark the reveal every sibling object already has —
   plays ONCE, settles on its final state. Same idiom as `fw-draw`
   (the flywheel ring): finite duration, `both` fill, no iteration.

   Durations are finite on purpose. Re-using the deleted `*-loop`
   keyframes was not an option: their 100% frame existed only to
   restart the cycle, so a one-shot version would have snapped the
   mark back off.

   Dasharray values are MEASURED path lengths (getTotalLength), not
   guesses — volvo 53 / pickup 94 / arrow 26 / SUV 97 — rounded up so
   no stroke is left partly undrawn.

   ponytail: all of it lives inside `no-preference`, so a
   reduced-motion user gets no dasharray at all and the marks render
   fully drawn and static. Putting the dasharray outside this block
   would leave them permanently invisible for those users.
   Ceiling: one reveal per mark, no hover/replay — if a future pass
   wants a mark to re-draw on hover, that is a new treatment, not a
   tweak to this one.
   ============================================================ */
@media (prefers-reduced-motion: no-preference) {
  /* Volvo — the shield-check draws itself, then holds. */
  .volvo-mark.in-view .volvo-shield-check {
    stroke-dasharray: 56;
    stroke-dashoffset: 56;
    animation: volvo-mark-draw 1.4s cubic-bezier(0.16, 1, 0.3, 1) 0.15s both;
  }

  /* Great Wall Motors — the repositioning plays in sequence: the past
     state lands, the arrow carries the eye across, the SUV arrives.
     Targets are the inner <path>s, never the <g>s: each <g> carries a
     `transform` ATTRIBUTE for positioning, and a CSS transform on the
     <g> would override that attribute and collapse the composition. */
  .suv.in-view .reposition-from path {
    stroke-dasharray: 100;
    stroke-dashoffset: 100;
    animation: gwm-from-in 1.2s cubic-bezier(0.16, 1, 0.3, 1) 0.15s both;
  }
  .suv.in-view .reposition-arrow path {
    stroke-dasharray: 32;
    stroke-dashoffset: 32;
    animation: gwm-arrow-in 1s cubic-bezier(0.16, 1, 0.3, 1) 0.45s both;
  }
  .suv.in-view .reposition-to path {
    stroke-dasharray: 104;
    stroke-dashoffset: 104;
    animation: gwm-to-in 1.4s cubic-bezier(0.16, 1, 0.3, 1) 0.75s both;
  }
}

@keyframes volvo-mark-draw {
  0%   { stroke-dashoffset: 56; }
  100% { stroke-dashoffset: 0; }
}

@keyframes gwm-from-in {
  0%   { stroke-dashoffset: 100; opacity: 0; }
  100% { stroke-dashoffset: 0;   opacity: 1; }
}

/* Settles at opacity 1 on the path — which MULTIPLIES with the <g>'s own
   resting opacity of 0.55, giving the intended effective 0.55. Ending the
   keyframe at 0.55 as well would have compounded to 0.30 and made the arrow
   dimmer than the base stylesheet ever drew it. */
@keyframes gwm-arrow-in {
  0%   { stroke-dashoffset: 32; opacity: 0; }
  100% { stroke-dashoffset: 0;  opacity: 1; }
}

@keyframes gwm-to-in {
  0%   { stroke-dashoffset: 104; opacity: 0; }
  100% { stroke-dashoffset: 0;   opacity: 1; }
}
