/* ==========================================================================
   Cycle — Landing
   Refined dark minimalism. Monochrome surfaces from the product's own token
   set, one teal accent (#38CEB1 / oklch 0.7675 0.1298 176.47), status colors
   reserved for the deployment pipeline visual.
   ========================================================================== */

/* ---- Tokens ------------------------------------------------------------ */
:root {
  color-scheme: dark;

  /* Surfaces (Cycle dark tokens) */
  --bg: oklch(0.1448 0 0);
  --bg-raised: oklch(0.17 0 0);
  --card: oklch(0.2046 0 0);
  --card-2: oklch(0.2686 0 0);

  /* Content — neutrals tinted toward the brand (hue 196, the app's graphite
     family; chroma follows PALETTE-METHODOLOGY.md: fg 0.004 / muted 0.01).
     Same lightness as before, so contrast is unchanged — just cooler, on-brand. */
  --fg: oklch(0.9851 0.004 196);
  --fg-muted: oklch(0.7155 0.01 196);
  --fg-faint: oklch(0.6 0.012 196);

  /* Brand */
  --accent: oklch(0.7675 0.1298 176.47);          /* #38CEB1 */
  --accent-strong: oklch(0.84 0.14 176.47);
  --accent-dim: oklch(0.7675 0.1298 176.47 / 14%);
  --accent-ink: oklch(0.2046 0 0);
  --accent-comp: #ce3855;                          /* teal's complement — used for "the problem" */

  /* Status (pipeline) */
  --status-success: oklch(0.7675 0.1298 176.47);
  --status-error: oklch(0.7106 0.1661 22.22);
  --status-running: oklch(0.7137 0.1434 254.62);
  --status-queued: oklch(0.8369 0.1644 84.43);

  /* Strokes */
  --border: oklch(1 0 0 / 10%);
  --border-strong: oklch(1 0 0 / 16%);
  --ring: oklch(0.7675 0.1298 176.47 / 60%);

  /* Type */
  --font-sans: "Instrument Sans", ui-sans-serif, system-ui, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, "SF Mono", monospace;

  /* Rhythm */
  --container: 72rem;
  --section-pad: clamp(5rem, 10vw, 8.5rem);
  --radius-s: 8px;
  --radius-m: 12px;
  --radius-l: 16px;
  --radius-pill: 999px;

  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-soft: cubic-bezier(0.4, 0, 0.2, 1);
  --ease-inout: cubic-bezier(0.45, 0, 0.2, 1);

  /* Illustration system — shared frame, motion + visual tokens for the
     chapter-visual panels (one stage, one motion grammar, one teal focal). */
  --illo-h: clamp(232px, 26vw, 360px);
  --illo-h-strip: 116px;
  --illo-pad: clamp(1.5rem, 3vw, 2rem);
  --illo-grid: 30px;                       /* backdrop grid cell — matches "The fix" panel */
  --illo-graph-line: oklch(0.7 0.05 235 / 3.5%);   /* subtle blueprint line tone — faint enough that the crisp CSS grid reads as softly as "The fix" SVG grid */
  --illo-stroke: 1.5px;
  --illo-wire: oklch(1 0 0 / 9%);
  --illo-wire-active: oklch(0.7675 0.1298 176.47 / 22%);
  --illo-glow-alpha: 10%;
  --illo-reveal: 450ms;
  --illo-draw: 700ms;
  --illo-travel: 5s;
  --illo-pulse: 2.4s;
  --illo-stagger: 70ms;
}

/* ---- Reset ------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: 5rem;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-sans);
  font-size: 1rem;
  line-height: 1.6;
  font-feature-settings: "ss01" on, "cv05" on;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
}

img, svg { display: block; max-width: 100%; }
button { font: inherit; cursor: pointer; }
a { color: inherit; }

::selection { background: var(--accent); color: var(--accent-ink); }

:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
  border-radius: 4px;
}

/* ---- Typography -------------------------------------------------------- */
h1, h2, h3, h4 { margin: 0; font-weight: 600; letter-spacing: -0.022em; line-height: 1.12; text-wrap: balance; }

.display {
  font-size: clamp(2.6rem, 6.4vw, 4.35rem);
  letter-spacing: -0.034em;
  line-height: 1.05;
  font-weight: 600;
}

.h2 { font-size: clamp(1.9rem, 3.6vw, 2.65rem); letter-spacing: -0.028em; }
.h3 { font-size: 1.1875rem; font-weight: 600; letter-spacing: -0.014em; }

.lede {
  margin: 0; /* the section-head grid gap owns the spacing; UA default p margins were leaking in */
  font-size: 1.0625rem;
  line-height: 1.6;
  color: var(--fg-muted);
  text-wrap: pretty;
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
}
.eyebrow::before {
  content: "";
  width: 1.25rem;
  height: 1px;
  background: var(--accent);
  opacity: 0.6;
}

.mono { font-family: var(--font-mono); }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---- Layout ------------------------------------------------------------ */
.container {
  width: min(var(--container), 100% - 3rem);
  margin-inline: auto;
}

.section { padding-block: var(--section-pad); position: relative; }

.section-head {
  max-width: 38rem;
  display: grid;
  gap: 1.1rem;
  margin-bottom: clamp(2.75rem, 6vw, 4.25rem);
}
.section-sub {
  margin: -0.35rem 0 0;
  color: var(--fg-muted);
  font-size: 1.0625rem;
  line-height: 1.55;
  max-width: 34rem;
}

/* ---- Designed for AI (co-lead thesis) --------------------------------- */
.ai-foundation { padding-block: var(--section-pad); }
.ai-panel {
  max-width: 52rem;
  margin-inline: auto;
  display: grid;
  justify-items: center;
  gap: 1.1rem;
  text-align: center;
  border: 1px solid var(--border);
  border-radius: 22px;
  background:
    radial-gradient(120% 150% at 50% 0%, oklch(0.7675 0.1298 176.47 / 9%), transparent 62%),
    var(--card);
  padding: clamp(2.25rem, 5vw, 3.75rem) clamp(1.5rem, 4vw, 3rem);
}
.ai-panel .h2 { max-width: 19ch; }
.ai-panel p {
  margin: 0;
  max-width: 56ch;
  color: var(--fg-muted);
  font-size: 1.0625rem;
  line-height: 1.6;
}

/* ---- Buttons ----------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.66rem 1.25rem;
  border-radius: 10px;
  border: 1px solid transparent;
  font-size: 0.9375rem;
  font-weight: 550;
  letter-spacing: -0.008em;
  text-decoration: none;
  white-space: nowrap;
  transition: background 0.18s var(--ease-out), border-color 0.18s var(--ease-out),
              transform 0.18s var(--ease-out), box-shadow 0.18s var(--ease-out);
}
.btn:active { transform: translateY(1px); }

.btn-primary {
  background: var(--accent);
  color: var(--accent-ink);
  box-shadow: 0 0 0 1px oklch(1 0 0 / 8%) inset, 0 8px 24px -10px oklch(0.7675 0.1298 176.47 / 55%);
}
.btn-primary:hover {
  background: var(--accent-strong);
  box-shadow: 0 0 0 1px oklch(1 0 0 / 12%) inset, 0 10px 32px -10px oklch(0.7675 0.1298 176.47 / 70%);
}

.btn-ghost {
  background: oklch(1 0 0 / 4%);
  border-color: var(--border);
  color: var(--fg);
}
.btn-ghost:hover { background: oklch(1 0 0 / 8%); border-color: var(--border-strong); }

.btn-lg { padding: 0.82rem 1.6rem; font-size: 1rem; border-radius: 12px; }

.btn-arrow { transition: transform 0.18s var(--ease-out); }
.btn:hover .btn-arrow { transform: translateX(3px); }

/* ---- Nav --------------------------------------------------------------- */
.nav {
  position: fixed;
  inset-inline: 0;
  top: 0;
  z-index: 50;
  transition: background 0.25s ease, border-color 0.25s ease;
  border-bottom: 1px solid transparent;
}
.nav.is-scrolled {
  background: oklch(0.1448 0 0 / 78%);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  border-bottom-color: var(--border);
}
.nav-inner {
  display: flex;
  align-items: center;
  gap: 0;
  height: 4rem;
}
.nav-logo {
  position: relative;
  display: inline-flex;
  align-items: center;
  height: 1.5rem;
  width: 6.72rem;
  text-decoration: none;
  transition: width 0.3s var(--ease-out);
}
/* Bottom layer: the same wordmark clipped to just the icon (always present). */
.nav-logo .logo-clip { flex: none; width: 2.3rem; height: 1.5rem; overflow: hidden; }
.nav-logo .logo-clip img { height: 1.5rem; width: auto; max-width: none; display: block; transition: transform 0.28s var(--ease-out); }
/* Top layer: the full wordmark, fades out on scroll so only the letters vanish
   (the icon stays put — no clipping of the letters). */
.nav-logo .logo-full {
  position: absolute;
  left: 0; top: 50%;
  transform: translateY(-50%);
  height: 1.5rem; width: auto; max-width: none; display: block;
  transition: opacity 0.28s var(--ease-out);
}
.nav.is-scrolled .nav-logo { width: 2.3rem; }
.nav.is-scrolled .nav-logo .logo-full { opacity: 0; }
/* The wordmark reserves space below for the "y" descender, so the bare icon sits high.
   When only the icon remains (scrolled), nudge it down to optically center it. */
.nav.is-scrolled .nav-logo .logo-clip img { transform: translateY(0.16rem); }

.nav-links {
  display: flex;
  gap: 0.25rem;
  margin-left: auto;
}
.nav-links a {
  padding: 0.45rem 0.8rem;
  border-radius: 8px;
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--fg-muted);
  text-decoration: none;
  transition: color 0.15s ease, background 0.15s ease;
}
.nav-links a:hover { color: var(--fg); background: oklch(1 0 0 / 5%); }

.nav-actions {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-left: 1.1rem;
  padding-left: 1.1rem;
  border-left: 1px solid var(--border);
}
.nav-signin {
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--fg-muted);
  text-decoration: none;
  padding: 0.45rem 0.8rem;
  border-radius: 8px;
  transition: color 0.15s ease;
}
.nav-signin:hover { color: var(--fg); }
.nav .btn { padding: 0.5rem 1rem; font-size: 0.875rem; }

@media (max-width: 760px) {
  .nav-links, .nav-signin { display: none; }
}

/* ---- Hero -------------------------------------------------------------- */
.hero {
  position: relative;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-top: clamp(6rem, 9vh, 8rem);
  padding-bottom: clamp(3rem, 6vw, 5rem);
  text-align: left;
}

.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 0.88fr) minmax(0, 1.12fr);
  gap: clamp(2rem, 4vw, 4rem);
  align-items: center;
}
.hero-copy { min-width: 0; }
.hero-visual { min-width: 0; }
.hero-grid .hero-ctas { justify-content: flex-start; }
.hero-visual .app-window { margin: 0; max-width: 100%; }
.hero-visual .app-screens { max-width: 100%; }
.hero-visual .flow { margin: 0 0 1.2rem; max-width: 100%; }

/* Atmosphere: teal aurora + faint grid, contained to hero */
.hero::before {
  content: "";
  position: absolute;
  inset: -20% 0 0;
  z-index: -1;
  background:
    radial-gradient(42rem 22rem at 50% -4rem, oklch(0.7675 0.1298 176.47 / 13%), transparent 70%),
    radial-gradient(60rem 30rem at 80% -10rem, oklch(0.7137 0.1434 254.62 / 6%), transparent 70%);
  pointer-events: none;
}
/* (backdrop is the full-page scrolling .page-timeline git graph, built in main.js) */

.hero-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.32rem 0.85rem 0.32rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: oklch(1 0 0 / 4%);
  font-family: var(--font-mono);
  font-size: 0.74rem;
  letter-spacing: 0.05em;
  color: var(--fg-muted);
}
.hero-chip .dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 8px var(--accent);
}

.hero h1 {
  margin: 1.35rem 0 1.15rem;
  max-width: 15ch;
}
.hero h1 em {
  font-style: normal;
  color: var(--accent);
}

.hero .lede { max-width: 34rem; margin-inline: 0; }

.hero-ctas {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.8rem;
  margin-top: 2.2rem;
}

.hero-note {
  margin-top: 1.6rem;
  font-size: 0.84rem;
  color: var(--fg-faint);
}
.note-sep { margin: 0 0.6em; }

/* Staggered entrance */
.hero-chip, .hero h1, .hero .lede, .hero-ctas, .hero-note {
  animation: rise 0.9s var(--ease-out) both;
}
.hero h1 { animation-delay: 0.07s; }
.hero .lede { animation-delay: 0.14s; }
.hero-ctas { animation-delay: 0.21s; }
.hero-note { animation-delay: 0.26s; }

@keyframes rise {
  from { opacity: 0; transform: translateY(18px); }
  to { opacity: 1; transform: translateY(0); }
}

/* Hero stacks (copy over visual, recentered) on narrower screens */
@media (max-width: 1024px) {
  .hero { text-align: center; }
  .hero-grid {
    grid-template-columns: 1fr;
    gap: clamp(2.5rem, 6vw, 3.5rem);
  }
  .hero h1 { margin-inline: auto; }
  .hero .lede { margin-inline: auto; }
  .hero-grid .hero-ctas { justify-content: center; }
  .hero-visual .flow { margin-inline: auto; }
}

/* Wide screens: copy stays aligned to the container; the app window peeks
   out past the container's right edge — at most ~8rem (~20% of its width),
   and never closer than 5rem to the viewport edge (so it stays roomy when
   space is tight, escaping more only when there's room to spare). */
@media (min-width: 75rem) {
  .hero .container.hero-grid {
    width: 100%;
    max-width: none;
    margin-inline: 0;
    padding-left: max(1.5rem, calc((100% - var(--container)) / 2));
    /* right edge: app peeks out past the container, max ~8rem, min 5rem margin */
    padding-right: max(5rem, calc((100% - var(--container)) / 2 - 8rem));
    grid-template-columns: minmax(0, 34rem) minmax(0, 1fr);
    column-gap: clamp(2.5rem, 5vw, 5rem);
  }
}

/* ---- Window chrome dots (used by the app-window topbar) --------------- */
.window-dots { display: flex; gap: 6px; }
.window-dots span {
  width: 10px; height: 10px;
  border-radius: 50%;
  background: oklch(1 0 0 / 12%);
}

@keyframes spin { to { transform: rotate(360deg); } }

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}

/* Illustration motion primitives (separate from the hero's 18px @keyframes rise) */
@keyframes illo-rise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
/* one small token gliding along a lane: travel, then dwell hidden before repeating */
@keyframes lane-travel {
  0%   { left: 0%;   opacity: 0; }
  8%   { opacity: 1; }
  60%  { left: 100%; opacity: 1; }
  64%, 100% { left: 100%; opacity: 0; }
}
/* gentle focal pulse — opacity + barely-there scale, calmer than the hero */
@keyframes illo-breathe {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.62; transform: scale(1.05); }
}

/* ---- Trust strip ------------------------------------------------------- */
.trust {
  padding-block: 2.2rem;
  border-block: 1px solid var(--border);
  text-align: center;
}
.trust p {
  margin: 0;
  font-size: 1rem;   /* 16px — body tier */
  color: var(--fg-faint);
  letter-spacing: 0.01em;
}
/* Where the page-timeline spine crosses the thin trust band and the footer, dissolve it into
   the background: a cover that's solid --bg in the middle and fades to transparent at the
   edges (sits above the timeline at z -2, below the content). */
.trust, .footer { position: relative; }
.trust::before, .footer::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  z-index: -1;
  pointer-events: none;
}
/* the cover extends past the band so the spine is fully gone BEFORE it reaches the
   divider lines (it dissolves ~20px above the top border, reappears ~20px below the bottom) */
.trust::before {
  top: -72px;
  bottom: -72px;
  background: linear-gradient(to bottom, transparent 0, var(--bg) 52px, var(--bg) calc(100% - 52px), transparent 100%);
}
.footer::before {
  top: -72px;
  bottom: 0;
  background: linear-gradient(to bottom, transparent 0, var(--bg) 52px, var(--bg) 100%);
}

/* ---- Problem cards ------------------------------------------------------ */
.pain-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: var(--radius-l);
  overflow: hidden;
}
.pain-card {
  background: var(--bg);
  padding: 1.75rem;
  display: grid;
  gap: 0.6rem;
  align-content: start;
  transition: background 0.2s ease;
}
.pain-card:hover { background: var(--bg-raised); }
.pain-card .pain-k {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--accent-comp);
  letter-spacing: 0.08em;
}
.pain-card h3 { font-size: 1.02rem; letter-spacing: -0.012em; }
.pain-card p { margin: 0; font-size: 0.92rem; color: var(--fg-muted); line-height: 1.55; }

/* ---- Solution statement ------------------------------------------------- */
.solution {
  text-align: center;
  padding-block: var(--section-pad);
}
.solution .big-statement {
  font-size: clamp(1.8rem, 4.4vw, 3rem);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.15;
  max-width: 22ch;
  margin: 1.4rem auto 0;
}
.solution .big-statement .flow { color: var(--accent); }
.solution-sub {
  max-width: 54ch;
  margin: 1.15rem auto 0;
  color: var(--fg-muted);
  font-size: 1.0625rem;
  line-height: 1.6;
}

/* Solution "fix" pipeline — Developers/AI → Git → Cycle → NetSuite environments */
/* focal panel: hug the 900px pipeline with generous side room, and give it height.
   width = 900px pipeline + 64px side padding (+2px border). */
.solflow-visual { margin-top: clamp(2.5rem, 6vw, 5rem); text-align: left; }   /* fills the container; text→diagram gap up to 80px */
.solflow-visual .illo-stage {
  aspect-ratio: auto;
  max-height: none;
  min-height: 300px;           /* taller, less of a thin band */
  height: auto;
  /* ~48px top/bottom, 64px sides on desktop; sides go fluid on small screens so
     a fixed 4rem inset does not squeeze the pipeline out of the stage. */
  padding: clamp(2.4rem, 3.6vw, 3rem) clamp(1rem, 6vw, 4rem);
}
.sf2 {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  margin-inline: auto;
}
/* pipeline width — wider lets the transitions (lanes) breathe (beats .illo-content's 880px) */
.illo-content.sf2 { max-width: none; }   /* fill the padded stage, up to the container */
.sf2-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(0.35rem, 0.9vw, 0.65rem);
}
.sf2-node { padding: 0.6rem 0.7rem; gap: 0.3rem; min-width: 84px; text-align: center; }
.sf2-dev-icos { display: inline-flex; gap: 0.3rem; }   /* human + robot chips, side by side */
.sf2-name { font-size: 0.74rem; font-weight: 600; color: var(--fg); white-space: nowrap; line-height: 1.1; }
.sf2-node.is-active .sf2-name { color: var(--accent); }
.sf2-role { font-family: var(--font-mono); font-size: 0.56rem; color: var(--fg-faint); white-space: nowrap; }
.sf2-ico-cycle svg { width: auto; height: 13px; }
.sf2-lane { min-width: 1rem; }
.sf2-envs {
  display: grid;
  gap: 0.28rem;
  padding: 0.55rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-m);
  background: var(--card);
  justify-items: start;
}
.sf2-envs-head {
  display: inline-flex; align-items: center; gap: 0.4rem;
  font-size: 0.68rem; font-weight: 600; color: var(--fg); margin-bottom: 0.12rem;
}
.sf2-envs-head svg { width: 13px; height: 13px; color: var(--fg-muted); }
.sf2-env { display: inline-flex; align-items: center; gap: 0.42rem; font-size: 0.66rem; color: var(--fg-muted); }
.sf2-env-role { min-width: 6.3em; white-space: nowrap; }   /* reserves a column so the dimmed account tags line up */
.sf2-env-acct { font-family: var(--font-mono); font-size: 0.58rem; color: var(--fg-faint); white-space: nowrap; }
.sf2-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--fg-faint); flex: none; }
.sf2-dot.ok { background: var(--accent); box-shadow: 0 0 6px oklch(0.73 0.11 176.47 / 45%); }

/* Bidirectional Git ⇄ Cycle connector: forward "sync & deploy", reverse "restore + commit".
   Forward lanes carry a right-pointing arrow; the reverse lane points left so the two
   parallel flows read unambiguously. */
.solflow-visual {
  /* a calmer, more "opaque" green inside the illustration — less neon than the UI accent */
  --accent: oklch(0.73 0.11 176.47);
  --accent-strong: oklch(0.745 0.10 176.47);
  --accent-dim: oklch(0.73 0.11 176.47 / 12%);
  --illo-wire-active: oklch(0.73 0.11 176.47 / 17%);
  --sf2-arrow: oklch(0.73 0.11 176.47 / 78%);
  --sf2-back-line: oklch(1 0 0 / 20%);
  --sf2-back-arrow: oklch(0.7155 0 0 / 95%);
}
.solflow-visual .illo-token { box-shadow: 0 0 5px oklch(0.73 0.11 176.47 / 42%); }
.solflow-visual .illo-node.is-active { border-color: oklch(0.73 0.11 176.47 / 45%); }
.solflow-visual .illo-node.is-active .illo-node-ico { border-color: oklch(0.73 0.11 176.47 / 40%); }

/* Blueprint dot-grid, thinned out: keep the dots-on-intersections look but show only a
   subset of them, traced into a git history (a main line + two branches that step up/down),
   to cut the background noise. Grid + dots live in one SVG coord space so every dot lands
   exactly on a grid intersection — no new lines, no off-grid dots. */
.solflow-visual {
  --graph-grid: oklch(0.7 0.05 235 / 5.5%);
  --graph-dot:  oklch(0.73 0.075 235 / 19%);
}
.solflow-visual .illo-bg,
body.illo-blueprint .solflow-visual .illo-bg {
  background-image: none;
  /* gentle edge fade — wide enough that the commit dots stay visible from the first
     grid column to the last, top to bottom */
  -webkit-mask-image: radial-gradient(150% 132% at 50% 50%, #000 60%, transparent 95%);
  mask-image: radial-gradient(150% 132% at 50% 50%, #000 60%, transparent 95%);
}
.sf2-graph { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; }
.sf2-grid-line { fill: none; stroke: var(--graph-grid); stroke-width: 1; }
/* Grid-intersection dots hidden — testing the diagram without that background decoration.
   Remove `display: none` to bring the commit-history dots back. */
.sf2-graph-dots { fill: var(--graph-dot); display: none; }
.sf2-duo {
  flex: 1.6 1 auto;
  min-width: 84px;
  align-self: stretch;       /* fill row height so the forward lane can sit on the node centerline */
  position: relative;
}
.sf2-flow { position: relative; display: flex; align-items: center; }
/* Anchor both duo lanes off the row centerline: forward lane ON center (so all three
   forward arrows form one straight horizontal line), back lane a fixed step below it. */
.sf2-duo .sf2-flow { position: absolute; left: 0; right: 0; }
.sf2-duo .sf2-flow--fwd { top: 50%; transform: translateY(-50%); }
.sf2-duo .sf2-flow--back { top: 50%; transform: translateY(calc(-50% + 1.5rem)); }
.sf2-duo .illo-lane,
.sf2-duo .sf2-back-lane { flex: 0 0 auto; width: 100%; min-width: 0; }
/* Captions float outside the lanes (absolute) so the two lines stay perfectly aligned
   across both pairs regardless of which captions are present. */
.sf2-flow-cap {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--font-mono);
  font-size: 0.55rem;
  line-height: 1;
  letter-spacing: 0.02em;
  white-space: nowrap;
  color: var(--fg-faint);
}
.sf2-flow--fwd .sf2-flow-cap { bottom: calc(100% + 5px); color: oklch(0.73 0.11 176.47 / 88%); }
.sf2-flow--back .sf2-flow-cap { top: calc(100% + 5px); }
.sf2-cap-fwd { bottom: calc(100% + 5px); color: oklch(0.73 0.11 176.47 / 88%); }   /* "push" above the Dev→Git lane */

/* Arrowheads — forward & restore lanes point right (toward NetSuite);
   the back lanes (commit back, drift) point left toward Git/Cycle. */
.sf2-lane--fwd::after {
  content: "";
  position: absolute;
  right: -1px;
  top: 50%;
  transform: translateY(-50%);
  width: 0; height: 0;
  border-left: 5px solid var(--sf2-arrow);
  border-top: 3px solid transparent;
  border-bottom: 3px solid transparent;
}
.sf2-back-lane {       /* same dashed rendering as the bypass bus, so long & short lines match */
  position: relative;
  height: 0;
  border-top: 1.5px dashed var(--bp-line);
}
.sf2-back-lane::after {
  content: "";
  position: absolute;
  left: -1px;
  top: 50%;
  transform: translateY(-50%);
  width: 0; height: 0;
  border-right: 5px solid var(--sf2-back-arrow);
  border-top: 3px solid transparent;
  border-bottom: 3px solid transparent;
}
.sf2-back-token {
  position: absolute;
  top: 50%;
  left: 100%;
  width: 6px; height: 6px;
  margin: -3px 0 0 -3px;
  border-radius: 50%;
  background: var(--fg-muted);
  box-shadow: 0 0 5px oklch(1 0 0 / 22%);
  opacity: 0;
  pointer-events: none;
  will-change: left;
}
.chapter-visual:not(.is-inview) .sf2-back-token,
.chapter-visual:not(.is-inview) .sf2-rs-token,
.chapter-visual:not(.is-inview) .sf2-bp-token { animation-play-state: paused; }
@keyframes lane-travel-rev {
  0%   { left: 100%; opacity: 0; }
  10%  { opacity: 1; }
  85%  { opacity: 1; }
  100% { left: 0%;   opacity: 0; }
}

/* Legacy / bypass path — the ungoverned "developers push straight to NetSuite" flow.
   Dashed + dimmed so it clearly reads as the old way that skips Git & Cycle: a line
   that drops from the Developers/AI node, routes under the pipeline, and into NetSuite. */
.solflow-visual {
  --bp-line: oklch(1 0 0 / 15%);
  --bp-ink: oklch(0.7155 0 0 / 80%);
}
.sf2-bypass { position: relative; height: 54px; margin-top: 2px; pointer-events: none; }

.sf2-bp-bus {
  position: absolute;
  top: 38px;
  height: 0;
  border-top: 1.5px dashed var(--bp-line);
}
.sf2-bp-token {                 /* grey ball relaying along the legacy bus, Developers → NetSuite */
  position: absolute;
  top: 0;
  left: 0;
  margin: -3px 0 0 -3px;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--fg-muted);
  box-shadow: 0 0 5px oklch(1 0 0 / 22%);
  opacity: 0;
  pointer-events: none;
  will-change: left;
}
.sf2-bp-riser { position: absolute; width: 0; border-left: 1.5px dashed var(--bp-line); }
.sf2-bp-riser--down { top: 8px; height: 30px; transform: translateX(-0.75px); }   /* gap below the Developers node */
.sf2-bp-riser--up   { top: 14px; height: 24px; transform: translateX(-0.75px); }  /* arrow sits above this, gap below NetSuite */
.sf2-bp-arrow {
  position: absolute;
  top: 8px;                                  /* tip stops ~10px below the NetSuite box */
  width: 0; height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-bottom: 6px solid var(--bp-ink);   /* points up, toward NetSuite */
  transform: translateX(-50%);
}
.sf2-bp-cap {
  position: absolute;
  top: 43px;
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--font-mono);
  font-size: 0.55rem;
  letter-spacing: 0.02em;
  white-space: nowrap;
  color: var(--bp-ink);
}

/* Restore arch — Cycle pushes its known-good state back into NetSuite to reconcile drift.
   Same dashed ink as the bypass, but routed ABOVE the pipeline: it rises out of the top of
   Cycle, runs across, and drops into NetSuite (mirror image of the bypass bus below). */
.sf2-restore { position: relative; height: 50px; margin-bottom: 2px; pointer-events: none; }
.sf2-rs-cap {
  position: absolute;
  top: 1px;
  transform: translateX(-50%);
  font-family: var(--font-mono);
  font-size: 0.55rem;
  letter-spacing: 0.02em;
  white-space: nowrap;
  color: var(--bp-ink);
}
.sf2-rs-bus {
  position: absolute;
  top: 16px;
  height: 0;
  border-top: 1.5px dashed var(--bp-line);
}
.sf2-rs-token {                 /* grey ball relaying along the restore arch, Cycle → NetSuite */
  position: absolute;
  top: 0;
  left: 0;
  margin: -3px 0 0 -3px;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--fg-muted);
  box-shadow: 0 0 5px oklch(1 0 0 / 22%);
  opacity: 0;
  pointer-events: none;
  will-change: left;
}
.sf2-rs-riser { position: absolute; width: 0; border-left: 1.5px dashed var(--bp-line); transform: translateX(-0.75px); }
.sf2-rs-riser--cyc { top: 16px; height: 26px; }   /* down from the bus toward Cycle, gap above the box */
.sf2-rs-riser--ns  { top: 16px; height: 20px; }   /* arrow sits below this, gap above NetSuite */
.sf2-rs-arrow {
  position: absolute;
  top: 36px;                                  /* tip stops ~8px above the NetSuite box */
  width: 0; height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 6px solid var(--bp-ink);        /* points down, into NetSuite */
  transform: translateX(-50%);
}
@media (max-width: 720px) {
  .sf2-row { flex-wrap: wrap; gap: 0.7rem 1rem; }
  .sf2-lane { display: none; }
  .sf2-duo { display: none; }
  .sf2-bypass { display: none; }
  .sf2-restore { display: none; }
}

/* ---- Testimonials --------------------------------------------------------- */
.quotes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  gap: 1rem;
}
.quote {
  border: 1px solid var(--border);
  border-radius: var(--radius-l);
  background: var(--bg-raised);
  padding: 1.6rem;
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
}
.quote blockquote {
  margin: 0;
  font-size: 0.98rem;
  line-height: 1.6;
  color: var(--fg);
  text-wrap: pretty;
}
.quote blockquote::before { content: "“"; color: var(--accent); }
.quote blockquote::after { content: "”"; color: var(--accent); }
.quote cite {
  font-style: normal;
  font-size: 0.82rem;
  color: var(--fg-faint);
  margin-top: auto;
}

/* ---- Pricing --------------------------------------------------------------- */
/* The pricing section is much taller than the rest: land anchor jumps at the
   eyebrow (cancel the section's top padding), and tighten the seg's rhythm to
   an even 40px above/below — the section-head clamp reads too airy here. */
#pricing { scroll-margin-top: calc(25px - var(--section-pad)); } /* anchor lands with the eyebrow ~40px below the nav */
#pricing .section-head { margin-bottom: 3.75rem; } /* 60px head→seg (was 40 + 17px of leaked lede margin) */
.pricing-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 1rem;
  align-items: stretch;
}
.price-card {
  border: 1px solid var(--border);
  border-radius: var(--radius-l);
  background: var(--bg-raised);
  padding: 1.8rem;
  display: flex;
  flex-direction: column;
  gap: 1.3rem;
}
.price-card.is-featured {
  border-color: oklch(0.7675 0.1298 176.47 / 45%);
  background: linear-gradient(180deg, var(--accent-dim), transparent 40%), var(--bg-raised);
  box-shadow: 0 0 60px -25px oklch(0.7675 0.1298 176.47 / 35%);
}
.price-head { display: grid; gap: 0.3rem; }
.price-name {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-size: 1.2rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}
.price-badge {
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  border: 1px solid oklch(0.7675 0.1298 176.47 / 40%);
  background: var(--accent-dim);
  padding: 0.16rem 0.5rem;
  border-radius: 99px;
}
.price-desc { font-size: 0.9375rem; font-weight: 500; color: var(--fg-muted); }
.price-amount {
  display: flex; align-items: center; gap: 0.55rem;
  padding: 1rem 0;                 /* hairlines hug the price block */
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.price-amount .n { font-size: 2.4rem; font-weight: 600; letter-spacing: -0.03em; line-height: 1.05; }
/* Two small lines stacked beside the number: the period on top, the billing
   note underneath (its text swaps with the control — "Billed annually" ⟷
   "Billed monthly" — so it never leaves a gap). */
.price-meta { display: grid; gap: 0.2rem; }
.price-amount .per { font-size: 0.85rem; color: var(--fg-muted); line-height: 1.2; }
.price-qual { font-size: 0.74rem; color: var(--fg-faint); line-height: 1.2; }

.price-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.75rem;
  font-size: 0.95rem;
  color: var(--fg-muted);
}
.price-list li { display: flex; gap: 0.65rem; align-items: start; }
.price-list svg { flex-shrink: 0; margin-top: 0.3rem; color: var(--accent); }

.price-card .btn { margin-top: auto; }

.pricing-note {
  margin-top: 2.1rem;
  text-align: center;
  font-size: 0.86rem;
  color: var(--fg-faint);
}

/* Billing period — one segmented control for the whole section, centered above
   the grid. Annual is the default; the "2 months free" incentive lives inside
   its segment. Switching swaps every card's price number and billing note. */
.billing-seg {
  display: flex; align-items: center; gap: 0.25rem;
  width: fit-content;
  margin: 0 auto 2.5rem;
  padding: 0.3rem;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
}
.billing-seg-opt {
  display: inline-flex; align-items: center; gap: 0.4rem;
  padding: 0.5rem 1.05rem;
  border: 0; border-radius: var(--radius-pill);
  background: none; cursor: pointer;
  font-family: inherit; font-size: 0.9rem; font-weight: 500;
  color: var(--fg-faint);
  transition: color 0.18s var(--ease-soft), background 0.18s var(--ease-soft);
}
.billing-seg-opt:hover { color: var(--fg-muted); }
.billing-seg-opt:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
.billing-seg-opt.is-active {
  background: var(--accent);
  color: var(--accent-ink);
  font-weight: 600;
}
/* Plain parenthetical incentive — inherits the segment's color, slightly dimmed */
.seg-note { font-size: 0.76rem; font-weight: 500; opacity: 0.75; }

/* ---- FAQ --------------------------------------------------------------------- */
.faq-list {
  max-width: 44rem;
  display: grid;
  gap: 0;
  border-top: 1px solid var(--border);
}
.faq-item {
  border-bottom: 1px solid var(--border);
}
.faq-item summary {
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.2rem 0.2rem;
  font-weight: 550;
  font-size: 1rem;
  letter-spacing: -0.01em;
  cursor: pointer;
  transition: color 0.15s ease;
}
.faq-item summary:hover { color: var(--accent-strong); }
.faq-item summary::-webkit-details-marker { display: none; }
.faq-icon {
  flex-shrink: 0;
  width: 18px; height: 18px;
  color: var(--fg-faint);
  transition: transform 0.25s var(--ease-out);
}
.faq-item[open] .faq-icon { transform: rotate(45deg); color: var(--accent); }
.faq-body {
  padding: 0 0.2rem 1.3rem;
  max-width: 38rem;
  font-size: 0.94rem;
  color: var(--fg-muted);
  line-height: 1.62;
}
.faq-body p { margin: 0; }
.faq-body p + p { margin-top: 0.85em; }   /* answers run to two paragraphs */

/* ---- Final CTA ------------------------------------------------------------------ */
.final-cta {
  position: relative;
  text-align: center;
  padding-block: clamp(6rem, 12vw, 9.5rem);
  overflow: clip;
}
.final-cta::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: radial-gradient(40rem 20rem at 50% 110%, oklch(0.7675 0.1298 176.47 / 16%), transparent 70%);
}
.final-cta h2 { max-width: 18ch; margin-inline: auto; }
.final-cta .lede { max-width: 30rem; margin: 1.2rem auto 0; }
.final-cta .hero-ctas { margin-top: 2.4rem; }

/* ---- Footer ----------------------------------------------------------------------- */
.footer {
  border-top: 1px solid var(--border);
  padding: 4rem 0 2.5rem;
  font-size: 0.9rem;
}
.footer-grid {
  display: grid;
  grid-template-columns: 2fr repeat(3, 1fr);
  gap: 2.5rem;
}
@media (max-width: 760px) {
  .footer-grid { grid-template-columns: 1fr 1fr; }
}
.footer-brand { display: grid; gap: 0.9rem; align-content: start; }
.footer-brand img { height: 1.3rem; width: auto; }
.footer-brand p { margin: 0; color: var(--fg-faint); font-size: 0.85rem; max-width: 16rem; }

.footer h3 {
  font-size: 0.78rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--fg-faint);
  margin-bottom: 1rem;
}
.footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.55rem; }
.footer ul a {
  color: var(--fg-muted);
  text-decoration: none;
  transition: color 0.15s ease;
}
.footer ul a:hover { color: var(--fg); }

.footer-bottom {
  margin-top: 3.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border);
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  justify-content: space-between;
  color: var(--fg-faint);
  font-size: 0.82rem;
}
.footer-legal {
  margin: 1rem 0 0;
  max-width: 70ch;
  color: var(--fg-faint);
  font-size: 0.72rem;
  line-height: 1.5;
  opacity: 0.75;
}

/* ---- Scroll reveals ----------------------------------------------------------------- */
html.js .reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.8s var(--ease-out), transform 0.8s var(--ease-out);
}
html.js .reveal.is-visible { opacity: 1; transform: none; }
.reveal-stagger > * { transition-delay: calc(var(--i, 0) * 70ms); }

/* ==========================================================================
   v2 components — app-window hero, git graph, mapping diagram, chapters
   ========================================================================== */

/* Full-page scrolling git history — a tall vertical graph behind everything; a fixed
   top/bottom shadow reveals only the slice in the current viewport, so scrolling feels
   like advancing through the commit history. The SVG is built by JS, sized to the document. */
.page-timeline {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  z-index: -2;
  pointer-events: none;
  opacity: 0.9;
  overflow: hidden;
}
.page-timeline svg { display: block; }
.page-timeline path { fill: none; stroke-width: 2; }
.page-timeline .tl-green { stroke: oklch(0.7675 0.1298 176.47 / 28%); }  /* active line (main, and the branch) */
.page-timeline .tl-grey { stroke: oklch(1 0 0 / 10%); }                  /* dormant trunk while a branch is active */
.page-timeline .tl-commit { fill: oklch(0.66 0.12 176.47); }             /* commits always green, solid */
.page-timeline-fade {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  /* line is visible only in the middle ~33%; top & bottom dissolve into the bg quickly */
  background: linear-gradient(to bottom,
    oklch(0.1448 0 0) 0%, oklch(0.1448 0 0) 17%, oklch(0.1448 0 0 / 0) 33.5%,
    oklch(0.1448 0 0 / 0) 66.5%, oklch(0.1448 0 0) 83%, oklch(0.1448 0 0) 100%);
}
body:not([data-bg="timeline"]) .page-timeline,
body:not([data-bg="timeline"]) .page-timeline-fade { display: none; }

/* ---- App window (mirrors the real Cycle UI) ----------------------------- */
.app-window {
  margin: clamp(3rem, 6vw, 4.5rem) auto 0;
  max-width: 62rem;
  text-align: left;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-l);
  background: var(--bg-raised);
  box-shadow:
    0 0 0 1px oklch(0 0 0 / 40%),
    0 30px 80px -30px oklch(0 0 0 / 70%),
    0 0 120px -40px oklch(0.7675 0.1298 176.47 / 22%);
  overflow: hidden;
  font-size: 0.8rem;
}

.app-topbar {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.55rem 0.9rem;
  border-bottom: 1px solid var(--border);
  background: oklch(1 0 0 / 2%);
}
.app-topbar { position: relative; }
.app-titlebar {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  font-size: 0.74rem;
  font-weight: 500;
  color: var(--fg-muted);
  letter-spacing: 0.01em;
  white-space: nowrap;
}

.app-body {
  display: grid;
  grid-template-columns: 3.25rem minmax(0, 1fr);
  min-height: 24rem;
}

/* Sidebar — real nav groups from the product */
.app-sidebar {
  border-right: 1px solid var(--border);
  background: oklch(0.17 0 0 / 80%);
  padding: 0.7rem 0.35rem;
  display: grid;
  gap: 0.9rem;
  align-content: start;
  justify-items: center;
}
.ws-head {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.15rem 0;
}
.ws-name { display: none; }
.ws-avatar {
  width: 26px; height: 26px;
  border-radius: 7px;
  background: var(--accent-dim);
  border: 1px solid oklch(0.7675 0.1298 176.47 / 35%);
  display: grid;
  place-items: center;
  font-size: 0.62rem;
  font-weight: 650;
  color: var(--accent);
  letter-spacing: 0.02em;
}
.side-group { display: grid; gap: 4px; justify-items: center; width: 100%; }
.side-label { display: none; }
.side-item {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 8px;
  color: var(--fg-muted);
  font-size: 0;
}
.side-item svg { width: 15px; height: 15px; opacity: 0.8; }
.side-item.is-active {
  background: oklch(1 0 0 / 7%);
  color: var(--fg);
}
.side-item.is-active svg { opacity: 1; }

/* Main pane — Commit activity */
.app-main { padding: 1.1rem 1.3rem; display: grid; gap: 0.7rem; align-content: start; }
.app-main-head { display: grid; gap: 0.15rem; margin-bottom: 0.3rem; }
.app-main-title { margin: 0; font-size: 0.95rem; font-weight: 600; letter-spacing: -0.012em; }
.app-main-head p { margin: 0; font-size: 0.72rem; color: var(--fg-faint); }

.commit-date {
  font-size: 0.66rem;
  font-weight: 500;
  color: var(--fg-faint);
  padding-left: 1.4rem;
}

.commit-feed { display: grid; position: relative; }
.commit-row { display: grid; grid-template-columns: 1.4rem minmax(0, 1fr); align-items: stretch; margin-bottom: 0.5rem; }
.commit-feed > .commit-row:last-child { margin-bottom: 0; }
.commit-rail { position: relative; }
/* Timeline line: each segment reaches exactly halfway into the 0.5rem gap,
   so neighbours meet without overlapping. */
.commit-rail::before {
  content: "";
  position: absolute;
  left: 5px;
  top: -0.25rem; bottom: -0.25rem;
  width: 1px;
  background: var(--border);
  transition: top 0.7s cubic-bezier(0.45, 0, 0.2, 1);   /* bridge grows in sync with the row */
}
.commit-feed > .commit-row:last-child .commit-rail::before { bottom: 50%; }

/* New commit collapses (grid-rows 0fr→1fr) so the list pushes down as it
   enters, instead of sitting in a reserved gap. */
.commit-collapse {
  display: grid;
  grid-template-rows: 0fr;
  overflow: hidden;
  opacity: 0;
  margin-bottom: 0;
  transition: grid-template-rows 0.7s cubic-bezier(0.45, 0, 0.2, 1), opacity 0.55s ease, margin-bottom 0.7s cubic-bezier(0.45, 0, 0.2, 1);
}
.commit-collapse > .commit-row { min-height: 0; margin-bottom: 0; }
.commit-collapse.is-shown { grid-template-rows: 1fr; opacity: 1; margin-bottom: 0.5rem; }
html:not(.js) .commit-collapse { grid-template-rows: 1fr; opacity: 1; margin-bottom: 0.5rem; }

/* The newest commit draws no rail line of its own (it would be clipped by the
   collapse and read as a second line). Instead, the row BELOW grows a single
   continuous line up from its own dot to the new dot — one line, from below. */
.cr-new .commit-rail::before { display: none; }
.commit-collapse.is-shown + .commit-row .commit-rail::before { top: -2.5rem; }
.commit-collapse:not(.is-shown) + .commit-row .commit-rail::before { top: 50%; }
.commit-dot {
  position: absolute;
  left: 1px;
  top: calc(50% - 4.5px);
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--card-2);
  border: 1.5px solid var(--fg-faint);
}
.commit-row.is-new .commit-dot {
  background: var(--accent);
  border-color: var(--accent);
  box-shadow: 0 0 10px oklch(0.7675 0.1298 176.47 / 60%);
}

.commit-card {
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--card);
  padding: 0.65rem 0.85rem;
  display: grid;
  gap: 0.3rem;
  transition: border-color 0.3s ease;
}
.commit-row.is-new .commit-card { border-color: oklch(0.7675 0.1298 176.47 / 30%); }
.commit-title-row { display: flex; align-items: center; gap: 0.6rem; }
.commit-msg { font-size: 0.78rem; font-weight: 500; letter-spacing: -0.008em; color: var(--fg-muted); }
.commit-hash {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 0.64rem;
  color: var(--fg-faint);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.12rem 0.45rem;
  white-space: nowrap;
}
.commit-tag {
  font-family: var(--font-mono);
  font-size: 0.58rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  padding: 0.05rem 0.32rem;
  border-radius: 5px;
  background: oklch(0.7675 0.1298 176.47 / 12%);
  border: 1px solid oklch(0.7675 0.1298 176.47 / 50%);
  color: var(--accent);
  white-space: nowrap;
}
.commit-meta {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.68rem;
  color: var(--fg-faint);
  flex-wrap: wrap;
}
.commit-avatar {
  width: 14px; height: 14px;
  border-radius: 50%;
  background: linear-gradient(135deg, oklch(0.55 0.1 250), oklch(0.65 0.12 180));
  flex-shrink: 0;
}
.commit-sep { opacity: 0.5; }

/* Pipeline status chip — icon + tinted text, like the product */
.pstatus {
  display: inline-flex;
  align-items: center;
  gap: 0.32rem;
  font-size: 0.68rem;
  color: var(--fg-muted);
}
.pstatus .ps-icon { width: 12px; height: 12px; display: grid; place-items: center; }
.pstatus[data-state="queued"] .ps-icon { color: var(--status-queued); }
.pstatus[data-state="running"] .ps-icon { color: var(--accent); }
.pstatus[data-state="success"] .ps-icon { color: var(--status-success); }
.pstatus[data-state="error"] .ps-icon { color: var(--status-error); }
/* Cycle's live loader: green spinner draws the eye, text stays white. */
.pstatus[data-state="running"] { color: var(--fg); }
.pstatus .spin {
  width: 10px; height: 10px;
  border-radius: 50%;
  border: 1.5px solid oklch(0.7675 0.1298 176.47 / 22%);
  border-top-color: var(--accent);
  animation: spin 0.8s linear infinite;
}

/* ---- Workflow indicator (above the app window) --------------------------
   Three fixed apps (icon + label) joined by a thin line. Transient messages
   above each segment narrate the hand-off; the active app glows and drives
   the screen below. Kept visually secondary to the application screen. */
.flow {
  margin: clamp(2.6rem, 5vw, 3.6rem) auto 0;
  max-width: 62rem;
  padding: 1.85rem 0 1.55rem;       /* top band for messages, bottom band for labels */
}
.flow-track {
  display: flex;
  align-items: center;
  gap: 0;
  /* Inset the end stages so their icons sit centered over their labels
     (instead of flush to the edges) — the connectors shorten slightly. */
  padding-inline: 1.85rem;
}

/* App stage — icon + label, no box */
.flow-app {
  position: relative;
  flex: 0 0 auto;
  display: flex;
  justify-content: center;
  color: var(--fg-faint);
  transition: color 0.45s ease, filter 0.45s ease;
}
.flow-icon { display: flex; align-items: center; justify-content: center; height: 22px; }
.flow-icon svg { height: 22px; width: auto; display: block; }
.flow-icon-cycle svg { height: 15px; }   /* wide logomark — balance its visual weight */

.flow-cap {
  position: absolute;
  top: calc(100% + 0.6rem);
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  line-height: 1;
  color: var(--fg-faint);
  transition: color 0.45s ease;
}

/* Completed — visible but subdued */
.flow-app.is-done { color: oklch(0.7675 0.1298 176.47 / 62%); }
.flow-app.is-done .flow-cap { color: var(--fg-muted); }

/* Active — green accent + glow */
.flow-app.is-active {
  color: var(--accent);
  filter: drop-shadow(0 0 7px oklch(0.7675 0.1298 176.47 / 55%));
}
.flow-app.is-active .flow-cap { color: var(--accent); }

/* Connecting segment — thin line with a left-to-right fill, plus a message slot */
.flow-seg {
  position: relative;
  flex: 1 1 auto;
  min-width: 2.5rem;
  display: flex;
  align-items: center;
}
.flow-line {
  position: relative;
  flex: 1 1 auto;
  height: 1.5px;
  margin: 0 11px;
  background: var(--border);
  border-radius: 2px;
  overflow: hidden;
}
.flow-fill {
  position: absolute;
  inset: 0;
  display: block;
  background: linear-gradient(90deg, var(--accent), var(--accent-strong));
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.85s var(--ease-out);
}

/* Transient hand-off message — one at a time, above the line, no marker */
.flow-msg {
  position: absolute;
  bottom: calc(100% + 0.75rem);
  left: 50%;
  transform: translateX(-50%) translateY(3px);
  white-space: nowrap;
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.005em;
  color: var(--accent);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s var(--ease-out), transform 0.3s var(--ease-out);
}
.flow-msg.is-show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* Traveling token — the thing that physically moves between systems in T1/T2 */
.flow-token {
  position: absolute;
  top: 50%;
  left: 11px;
  margin-left: -9px;
  width: 18px; height: 18px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--bg-raised);
  border: 1.5px solid var(--accent);
  color: var(--accent);
  box-shadow: 0 0 10px oklch(0.7675 0.1298 176.47 / 55%);
  opacity: 0;
  transform: translateY(-50%) scale(0.4);
  transition: left 1.4s linear, opacity 0.3s ease, transform 0.3s var(--ease-out);
  pointer-events: none;
  z-index: 3;
}
.flow-token svg { width: 10px; height: 10px; }
.flow-token.is-traveling { opacity: 1; transform: translateY(-50%) scale(1); }

@media (max-width: 600px) {
  .flow { padding-top: 1.6rem; }
  .flow-cap { font-size: 0.6rem; }
  .flow-msg { font-size: 0.62rem; }
}

/* ---- App screens (one window per app node; only one shown at a time) ----- */
.app-screens { display: grid; }
.app-screen {
  grid-area: 1 / 1;               /* stack all screens in the same cell */
  display: flex;
  flex-direction: column;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.45s var(--ease-out), visibility 0.45s;
}
.app-screen.is-active { opacity: 1; visibility: visible; }
.app-blank { flex: 1 1 auto; min-height: 22rem; }

/* ---- AI Interface screen (E1) ------------------------------------------- */
.app-ai {
  flex: 1 1 auto;
  min-height: 22rem;
  display: flex;
  flex-direction: column;
  padding: 1.1rem 1.2rem 1rem;
  gap: 0.9rem;
}
.ai-thread {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 0.8rem;
}
.ai-row {
  display: flex;
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.45s var(--ease-out), transform 0.45s var(--ease-out);
}
.ai-row.is-shown { opacity: 1; transform: none; }
.ai-row-user { justify-content: flex-end; }
.ai-row-bot { gap: 0.6rem; align-items: flex-start; }

.ai-bubble {
  max-width: 82%;
  padding: 0.6rem 0.8rem;
  border-radius: 14px;
  font-size: 0.82rem;
  line-height: 1.45;
}
.ai-bubble-user {
  background: oklch(0.7675 0.1298 176.47 / 12%);
  border: 1px solid oklch(0.7675 0.1298 176.47 / 28%);
  color: var(--fg);
  border-bottom-right-radius: 5px;
  font-weight: 500;
}
.ai-bubble-bot {
  background: var(--card);
  border: 1px solid var(--border);
  color: var(--fg);
  border-bottom-left-radius: 5px;
  display: grid;
  gap: 0.6rem;
}
.ai-avatar {
  flex: none;
  width: 26px; height: 26px;
  border-radius: 8px;
  display: grid; place-items: center;
  background: var(--accent-dim);
  border: 1px solid oklch(0.7675 0.1298 176.47 / 35%);
  color: var(--accent);
}
.ai-avatar svg { width: 15px; height: 15px; }

.ai-typing { display: inline-flex; gap: 4px; align-items: center; padding: 0.2rem 0; }
.ai-typing:not(.is-shown) { display: none; }
.ai-typing i {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--fg-faint);
  animation: ai-blink 1.2s infinite ease-in-out both;
}
.ai-typing i:nth-child(2) { animation-delay: 0.18s; }
.ai-typing i:nth-child(3) { animation-delay: 0.36s; }

.ai-bot-text { display: none; }
.ai-bot-text.is-shown { display: block; }

.ai-actions { display: none; gap: 0.5rem; }
.ai-actions.is-shown { display: flex; }
.ai-action {
  font: inherit;
  font-size: 0.78rem;
  font-weight: 500;
  padding: 0.4rem 0.85rem;
  border-radius: 8px;
  border: 1px solid var(--border-strong);
  background: transparent;
  color: var(--fg-muted);
  transition: background 0.25s ease, color 0.25s ease, border-color 0.25s ease, box-shadow 0.25s ease;
}
.ai-action-primary { border-color: oklch(0.7675 0.1298 176.47 / 45%); color: var(--accent); }
.ai-action-primary.is-selected {
  background: oklch(0.7675 0.1298 176.47 / 16%);
  color: var(--accent);
  border-color: var(--accent);
}

/* AI workflow steps (E1: generating → committing → pushing) */
.ai-steps { display: none; flex-direction: column; gap: 0.5rem; }
.ai-steps.is-shown { display: flex; }
.ai-step {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  font-size: 0.78rem;
  color: var(--fg-faint);
  transition: color 0.3s ease;
}
.ai-step.is-active, .ai-step.is-done { color: var(--fg); }
.ai-step-ico {
  flex: none;
  width: 14px; height: 14px;
  border-radius: 50%;
  border: 1.5px solid var(--fg-faint);
  position: relative;
  transition: border-color 0.3s ease, background 0.3s ease;
}
.ai-step.is-active .ai-step-ico {
  border-color: oklch(1 0 0 / 15%);
  border-top-color: var(--accent);
  animation: spin 0.8s linear infinite;
}
.ai-step.is-done .ai-step-ico { background: oklch(0.7675 0.1298 176.47 / 16%); border-color: var(--accent); }
.ai-step.is-done .ai-step-ico::after {
  content: "";
  position: absolute;
  left: 4.5px; top: 2.3px;
  width: 3px; height: 6.5px;
  border: solid var(--accent);
  border-width: 0 1.6px 1.6px 0;
  transform: rotate(45deg);
}

.ai-composer {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.5rem 0.55rem 0.5rem 0.85rem;
  border: 1px solid var(--border-strong);
  border-radius: 12px;
  background: oklch(0 0 0 / 25%);
}
.ai-field {
  flex: 1 1 auto;
  min-width: 0;
  display: inline-flex;
  align-items: center;
  min-height: 1.2rem;
  font-size: 0.82rem;
  color: var(--fg);
}
.ai-field-text { white-space: pre-wrap; }
.ai-caret {
  flex: none;
  width: 1.5px; height: 0.95rem;
  background: var(--accent);
  margin-left: 1px;
  animation: ai-caret 1s steps(1) infinite;
}
.ai-send {
  flex: none;
  width: 28px; height: 28px;
  border-radius: 8px;
  display: grid; place-items: center;
  background: var(--accent-dim);
  color: var(--accent);
}
.ai-send svg { width: 15px; height: 15px; }

@keyframes ai-blink { 0%, 80%, 100% { opacity: 0.25; } 40% { opacity: 1; } }
@keyframes ai-caret { 0%, 50% { opacity: 1; } 50.01%, 100% { opacity: 0; } }

/* ---- NetSuite screen (E3) ----------------------------------------------- */
.app-ns {
  flex: 1 1 auto;
  min-height: 22rem;
  display: flex;
  flex-direction: column;
  padding: 1.15rem 1.3rem 1.3rem;
  gap: 0.7rem;
}
.ns-reveal {
  opacity: 0;
  transform: translateY(9px);
  transition: opacity 0.5s var(--ease-out), transform 0.5s var(--ease-out);
}
.ns-reveal.is-shown { opacity: 1; transform: none; }

.ns-titlerow { display: flex; align-items: center; }
.ns-title { margin: 0; font-size: 1rem; font-weight: 650; letter-spacing: -0.012em; color: var(--fg); }
.ns-sub { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.ns-metatext { font-size: 0.7rem; color: var(--fg-faint); display: flex; align-items: center; gap: 0.4rem; }
.ns-actions { display: flex; gap: 0.45rem; }
.ns-btn {
  font-size: 0.7rem; font-weight: 500;
  padding: 0.3rem 0.7rem; border-radius: 7px;
  border: 1px solid var(--border-strong); color: var(--fg-muted);
}
/* Export = filled secondary (gray), distinct from Refresh's outline. */
.ns-btn-primary { background: var(--card-2); color: var(--fg); border-color: transparent; }

.ns-filter { display: flex; align-items: center; gap: 0.5rem; margin-top: 0.1rem; }
.ns-filter-k { font-size: 0.7rem; color: var(--fg-faint); }
.ns-chip {
  display: inline-flex; align-items: center; gap: 0.3rem;
  font-size: 0.72rem; color: var(--fg);
  padding: 0.26rem 0.6rem; border-radius: 7px;
  border: 1px solid var(--border-strong); background: oklch(1 0 0 / 3%);
}
.ns-chip svg { width: 12px; height: 12px; opacity: 0.7; }

.ns-table { margin-top: 0.35rem; border: 1px solid var(--border); border-radius: 12px; overflow: hidden; }
.ns-tr {
  display: grid;
  grid-template-columns: 1fr auto auto;
  gap: 1.2rem;
  align-items: center;
  padding: 0.62rem 0.95rem;
  font-size: 0.8rem;
  border-top: 1px solid var(--border);
}
.ns-tr:first-child { border-top: none; }
.ns-th {
  background: oklch(1 0 0 / 3%);
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--fg-faint);
  font-weight: 600;
}
.ns-c2, .ns-c3 { text-align: right; font-variant-numeric: tabular-nums; min-width: 4.75rem; }
.ns-tr:not(.ns-th) .ns-c2 { color: var(--fg-muted); }
.ns-rev { font-weight: 650; color: var(--fg); }

.ns-status {
  align-self: center;        /* centered horizontally */
  margin-top: auto;          /* pushed to the bottom of the report, using the open space */
  margin-bottom: 0.4rem;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.74rem;
  font-weight: 600;
  padding: 0.34rem 0.8rem;
  border-radius: 999px;
  color: var(--accent);
  background: var(--accent-dim);
  border: 1px solid oklch(0.7675 0.1298 176.47 / 35%);
}
.ns-status svg { width: 13px; height: 13px; }

/* ---- Capability pillars -------------------------------------------------- */
.pillars {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  column-gap: 0;
  row-gap: 2.4rem;
}
.pillar {
  display: grid;
  gap: 0.5rem;
  align-content: start;
  justify-items: start;
  padding-inline: 1.6rem;                       /* ~26px of air on each side of the divider */
  border-left: 1px solid var(--border);         /* subtle vertical rule between columns */
}
.pillar:first-child { padding-left: 0; border-left: 0; }   /* flush with the section heading */
.pillar:last-child { padding-right: 0; }                   /* flush with the container edge */
@media (max-width: 900px) {
  .pillars { grid-template-columns: repeat(2, 1fr); row-gap: 2.4rem; }
  .pillar:nth-child(odd) { padding-left: 0; border-left: 0; }
  .pillar:nth-child(even) { padding-right: 0; }
}
@media (max-width: 560px) {
  .pillars { grid-template-columns: 1fr; row-gap: 2rem; }
  .pillar { padding-inline: 0; border-left: 0; }
}
.pillar-icon {
  width: 34px; height: 34px;
  border: 1px solid var(--border);
  border-radius: 9px;
  display: grid;
  place-items: center;
  color: var(--accent);
  background: oklch(1 0 0 / 3%);
  margin-bottom: 0.3rem;
}
.pillar-icon svg { width: 15px; height: 15px; }
.pillar h3 { font-size: 0.95rem; letter-spacing: -0.01em; }
.pillar p { margin: 0; font-size: 0.88rem; color: var(--fg-muted); line-height: 1.5; }

/* Outcomes — horizontal scroll-snap carousel; headline-forward, one line of copy,
   the next card peeks so it reads as "there is more", arrows drive it in main.js. */
.outcomes-head {
  max-width: none;                     /* override .section-head so arrows reach the far edge */
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 2rem;
  flex-wrap: wrap;
}
.outcomes-head-text { display: grid; gap: 1.05rem; max-width: 40rem; }
.outcomes-head-text .section-sub { margin: 0; }        /* drop the pull-up so it clears the big h2 */
.carousel-nav { display: flex; gap: 0.55rem; flex-shrink: 0; }
.carousel-arrow {
  width: 2.7rem; height: 2.7rem;
  display: grid; place-items: center;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: oklch(1 0 0 / 3%);
  color: var(--fg);
  cursor: pointer;
  transition: background 0.2s var(--ease-out), border-color 0.2s var(--ease-out),
              color 0.2s var(--ease-out), opacity 0.2s;
}
.carousel-arrow:hover { background: var(--bg-raised); border-color: var(--accent); color: var(--accent); }
.carousel-arrow:focus { outline: none; }
.carousel-arrow:focus-visible { border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in oklab, var(--accent) 35%, transparent); }
.carousel-arrow svg { width: 17px; height: 17px; }
.carousel-arrow:disabled { opacity: 0.3; cursor: default; pointer-events: none; }

.outcomes-track {
  display: flex;
  gap: 1.1rem;
  margin-top: 2.4rem;
  padding: 0.25rem 0.25rem 1rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;               /* Firefox */
  -webkit-overflow-scrolling: touch;
}
.outcomes-track::-webkit-scrollbar { display: none; }   /* Chrome/Safari */

/* Edge fades are gradient overlays that slide out past their own edge to hide,
   rather than dissolving in place: main.js drives --left-hide / --right-hide from
   the live scroll position, so each overlay tucks off-screen (clipped by the
   viewport) in sync with the card motion as you reach that side. */
.outcomes-viewport { position: relative; overflow: hidden; }
.outcomes-viewport::before,
.outcomes-viewport::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: clamp(2.5rem, 6vw, 4.5rem);
  pointer-events: none;
  z-index: 2;
  /* offset is scroll-driven from main.js; tiny transition just smooths jitter */
  transition: transform 0.1s linear;
}
.outcomes-viewport::before {
  left: 0;
  background: linear-gradient(90deg, var(--bg), transparent);
  transform: translateX(var(--left-hide, -100%));   /* -100% hidden off left, 0 shown */
}
.outcomes-viewport::after {
  right: 0;
  background: linear-gradient(270deg, var(--bg), transparent);
  transform: translateX(var(--right-hide, 100%));   /* 100% hidden off right, 0 shown */
}
.outcomes-track:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: 12px; }

.outcome-card {
  flex: 0 0 clamp(15.5rem, 24vw, 18.5rem);
  scroll-snap-align: start;
  scroll-margin-left: 0.25rem;         /* clear the track's side padding when snapping */
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
  padding: 1.5rem 1.4rem 1.6rem;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: oklch(1 0 0 / 2%);
  transition: border-color 0.25s var(--ease-out), background 0.25s var(--ease-out),
              transform 0.25s var(--ease-out);
}
/* the last card snaps by its end edge so the track can rest fully at max scroll
   (otherwise mandatory start-snap can pull back a card, leaving it half-shown) */
.outcome-card:last-child { scroll-snap-align: end; }
.outcome-card:hover { border-color: color-mix(in oklab, var(--accent) 45%, var(--border)); background: var(--bg-raised); transform: translateY(-3px); }
/* half-hidden under an edge fade: clicking scrolls it into view (main.js) */
.outcome-card.is-peek { cursor: pointer; }
.outcome-card .pillar-icon { margin-bottom: 0.35rem; }
.outcome-card h3 { font-size: 1rem; letter-spacing: -0.012em; line-height: 1.25; }
.outcome-card p { margin: 0; font-size: 0.9rem; color: var(--fg-muted); line-height: 1.5; }

@media (prefers-reduced-motion: reduce) { .outcomes-track { scroll-behavior: auto; } }
@media (max-width: 640px) {
  .carousel-nav { display: none; }     /* native swipe on touch */
  /* With no arrows, the only affordance is the next card peeking out — so size
     the peek off the track, not the viewport: 78vw ignored the container padding,
     leaving 0.8px of card at 320px and 16px at 390px, all of it buried under the
     40px edge fade. A fixed reserve keeps the same peek at every phone width,
     and the narrower fade lets it actually show. */
  .outcomes-track { gap: 0.85rem; }
  .outcome-card { flex-basis: calc(100% - 4.25rem); }
  .outcomes-viewport::before,
  .outcomes-viewport::after { width: 1.75rem; }
}

/* ---- Chapters (numbered product tour) ----------------------------------- */
.chapter { padding-block: clamp(3.5rem, 7vw, 5.5rem); }
.chapter + .chapter { border-top: 1px solid oklch(1 0 0 / 6%); }
.chapter-head {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  gap: 1.5rem 4rem;
  align-items: center;
  margin-bottom: clamp(2.5rem, 6vw, 5rem);   /* text→illustration gap: up to 80px on wide screens */
}
@media (max-width: 860px) {
  .chapter-head { grid-template-columns: 1fr; align-items: start; }
  /* stacked: put the tag back in normal flow above the title */
  .chapter-num { position: static; margin-bottom: 0.9rem; }
}
/* The numbered tag floats above the title so the h3 (not tag+h3) is what the
   description vertically centers against — keeps the heading visually balanced. */
.chapter-head > div { position: relative; }
.chapter-num {
  position: absolute;
  left: 0;
  bottom: calc(100% + 0.5rem);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
  white-space: nowrap;
}
.chapter-head h3 {
  font-size: clamp(1.6rem, 3vw, 2.2rem);
  letter-spacing: -0.026em;
  line-height: 1.1;
}
.chapter-head .chapter-desc {
  margin: 0;
  font-size: 1.0625rem;   /* 17px — matches .lede / .section-sub / .solution-sub */
  color: var(--fg-muted);
  line-height: 1.65;
  text-wrap: pretty;
}


.chapter-visual {
  position: relative;
  border: 1px solid var(--border);
  border-radius: var(--radius-l);
  background: var(--bg-raised);
  overflow: hidden;
}

/* ==========================================================================
   Illustration system — every chapter visual is a variation of ONE stage:
   .chapter-visual > .illo-stage > [.illo-bg, .illo-glow, .illo-content]
   built from CSS lanes/nodes (the hero's proven, fully-responsive pattern).
   Shared frame (one height band), three motion primitives, one teal focal.
   ========================================================================== */
.illo-stage {
  position: relative;
  aspect-ratio: 1150 / 360;
  max-height: var(--illo-h);
  width: 100%;
  padding: var(--illo-pad);
  display: grid;
  place-items: center;
  align-content: center;   /* keep tall content vertically centered (not top-aligned) */
  overflow: hidden;
}
.illo-stage.is-strip { aspect-ratio: 1150 / 116; max-height: var(--illo-h-strip); }

/* Layer A — masked blueprint grid (subliminal, fills emptiness) */
.illo-bg, .illo-glow { position: absolute; inset: 0; pointer-events: none; z-index: 0; }
/* Base illustration backdrop — the "The fix" (solflow) treatment promoted to the
   shared default: a single-weight, subtle 24px line grid (same --graph-grid tone)
   under a wide radial fade, so every chapter illo reads like that panel. */
.illo-bg {
  background-image:
    linear-gradient(var(--illo-graph-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--illo-graph-line) 1px, transparent 1px);
  background-size: var(--illo-grid) var(--illo-grid);
  background-position: center center;      /* centered → equal partial cells on every side */
  -webkit-mask-image: radial-gradient(150% 132% at 50% 50%, #000 60%, transparent 95%);
  mask-image: radial-gradient(150% 132% at 50% 50%, #000 60%, transparent 95%);
}
/* Layer B — one low-alpha teal radial behind the single focal node.
   Position via --glow-x / --glow-y per panel (default: left-of-centre). */
.illo-glow {
  background: radial-gradient(20rem 12rem at var(--glow-x, 30%) var(--glow-y, 50%),
    oklch(0.7675 0.1298 176.47 / var(--illo-glow-alpha)), transparent 70%);
}

/* Content sits above the backdrop layers */
.illo-content { position: relative; z-index: 2; width: 100%; max-width: 880px; }

/* Node card — real product-UI fragment (glassy hero-window vocabulary) */
.illo-node {
  display: inline-grid;
  place-items: center;
  gap: 0.45rem;
  padding: 0.75rem 0.95rem;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-m);
  color: var(--fg-muted);
}
.illo-node .illo-node-ico {
  display: grid; place-items: center;
  width: 30px; height: 30px;
  border-radius: 8px;
  background: oklch(1 0 0 / 4%);
  border: 1px solid var(--border);
  color: var(--fg-muted);
}
.illo-node .illo-node-ico svg { width: 16px; height: 16px; }
.illo-node .illo-node-cap { font-size: 0.7rem; font-weight: 500; letter-spacing: 0.01em; color: var(--fg-muted); white-space: nowrap; }
.illo-node.is-active { border-color: oklch(0.7675 0.1298 176.47 / 55%); color: var(--accent); }
.illo-node.is-active .illo-node-ico { background: var(--accent-dim); border-color: oklch(0.7675 0.1298 176.47 / 45%); color: var(--accent); }
.illo-node.is-active .illo-node-cap { color: var(--accent); }

/* Lane connector + traveling token (hero pattern, calmer) */
.illo-lane {
  position: relative;
  flex: 1 1 auto;
  min-width: 1.5rem;
  height: var(--illo-stroke);
  background: var(--illo-wire);
  border-radius: 2px;
}
.illo-lane.is-active { background: var(--illo-wire-active); }
.illo-line-fill {
  position: absolute;
  inset: 0;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--accent), var(--accent-strong));
  transform: scaleX(0);
  transform-origin: left center;
}
.chapter-visual.is-visible .illo-line-fill {
  transform: scaleX(1);
  transition: transform var(--illo-draw) var(--ease-out) 0.25s;
}
.illo-token {
  position: absolute;
  top: 50%;
  left: 0;
  width: 8px; height: 8px;
  margin: -4px 0 0 -4px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 6px oklch(0.7675 0.1298 176.47 / 60%);
  opacity: 0;
  pointer-events: none;
  will-change: left;
}
/* Other chapter illustrations keep their gentle perpetual token loop */
.chapter-visual.is-inview:not(.solflow-visual) .illo-token { animation: lane-travel var(--illo-travel) var(--ease-inout) infinite; }
/* Baseline relays each token ONCE, then rests — like "The fix" (no loop).
   --td staggers the segments: import first, then commit. */
.chapter-visual.is-visible .bl2 .bl2-lane .illo-token {
  animation: sf2-travel var(--seg) var(--ease-inout) var(--td, 0.5s) 1 both;
}

/* "The fix" diagram: two flows that relay segment-by-segment (one ball at a time), once,
   then rest — calmer and legible as a path rather than a perpetual loop.
   Green (governed):  Developers → Git → Cycle → NetSuite  (td 0 → 1.3 → 2.6)
   Grey (reconcile):  Developers ⇢ NetSuite → Cycle → Git  (td 0 → 2.0 → 3.3)
   Per-token --td sets when each segment fires; --seg its travel time. */
.solflow-visual { --seg: 1.3s; }
.solflow-visual.is-visible .illo-token {
  animation: sf2-travel var(--seg) var(--ease-inout) var(--td, 0s) 1 both;
}
.solflow-visual.is-visible .sf2-back-token {
  animation: sf2-travel-rev var(--seg) var(--ease-inout) var(--td, 0s) 1 both;
}
.solflow-visual.is-visible .sf2-rs-token {
  animation: sf2-travel var(--seg) var(--ease-inout) var(--td, 0s) 1 both;
}
.solflow-visual.is-visible .sf2-bp-token {
  animation: sf2-travel var(--seg) var(--ease-inout) var(--td, 0s) 1 both;
}
@keyframes sf2-travel     { 0% { left: 0%;   opacity: 0; } 14% { opacity: 1; } 86% { opacity: 1; } 100% { left: 100%; opacity: 0; } }
@keyframes sf2-travel-rev { 0% { left: 100%; opacity: 0; } 14% { opacity: 1; } 86% { opacity: 1; } 100% { left: 0%;   opacity: 0; } }

/* Entrance — staggered fade-up, runs once when the panel is well in view */
.illo-rise-item { opacity: 0; }
.chapter-visual.is-visible .illo-rise-item {
  animation: illo-rise var(--illo-reveal) var(--ease-out) both;
  animation-delay: calc(var(--ri, 0) * var(--illo-stagger));
}

/* Continuous focal loops (paused when the panel scrolls out of view) */
.illo-pulse { animation: pulse var(--illo-pulse) var(--ease-inout) infinite; }
.illo-breathe { animation: illo-breathe var(--illo-pulse) var(--ease-inout) infinite; }
.illo-caret { animation: ai-caret 1s infinite; }
.chapter-visual:not(.is-inview) .illo-token,
.chapter-visual:not(.is-inview) .illo-pulse,
.chapter-visual:not(.is-inview) .illo-breathe,
.chapter-visual:not(.is-inview) .illo-caret,
.chapter-visual:not(.is-inview) .cs-spin { animation-play-state: paused; }

@media (max-width: 720px) {
  /* content-driven height so stacked panels never clip; keep a calm minimum */
  .illo-stage { aspect-ratio: auto; max-height: none; min-height: 240px; height: auto; }
  .illo-stage.is-strip { min-height: 0; }
}

/* Ch02 Deployments — branch↔env mapping. Horizontal (commit→deploy) reads as the
   fix's dashed grey arrows; vertical (merge→promote) as solid green up-arrows. */
.dp {
  --accent: oklch(0.73 0.11 176.47);
  --accent-dim: oklch(0.73 0.11 176.47 / 12%);
  --bp-line: oklch(1 0 0 / 16%);       /* dashed lane, like the fix */
  --bp-ink: oklch(0.7155 0 0 / 78%);   /* grey arrowhead */
  --dp-gap: clamp(0.9rem, 2.2vw, 1.6rem);   /* gap between cells; also how far the token reaches into each box */
  display: grid; justify-items: center; gap: clamp(1.1rem, 2.6vw, 1.7rem);
  width: 100%; max-width: none;
}
.dp-map {
  display: grid;
  grid-template-columns: auto auto minmax(5rem, 10rem) auto;   /* promote · branch · arrow · env */
  align-items: center;
  justify-content: center;     /* keep the map compact & centered */
  column-gap: var(--dp-gap);
  row-gap: var(--dp-gap);      /* same as the horizontal gap → arrows sit off the boxes */
  width: 100%;
}
.dp-head {
  font-family: var(--font-mono); font-size: 0.7rem; letter-spacing: 0.11em;
  text-transform: uppercase; color: var(--fg-faint); padding-bottom: 0.7rem; align-self: end;
}
.dp-head-branch { grid-column: 2; grid-row: 1; }
.dp-head-env { grid-column: 4; grid-row: 1; }

/* rotated axis label on the far left */
.dp-promote {
  grid-column: 1; grid-row: 2 / 7;
  writing-mode: vertical-rl; transform: rotate(180deg);   /* reads bottom → top */
  font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.08em;
  color: var(--fg-faint); align-self: center; justify-self: center;
}
.dp-promote b { color: var(--fg-muted); font-weight: 500; }   /* "merge" lighter, like "commit" */

.dp-branch {
  grid-column: 2; grid-row: var(--r); justify-self: stretch;
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  font-family: var(--font-mono); font-size: 0.74rem; color: var(--fg);
  padding: 0.55rem 0.95rem; border: 1px solid var(--border); border-radius: 10px;
  background: var(--card); white-space: nowrap;
}
.dp-branch-ico { width: 14px; height: 14px; color: var(--fg-muted); flex: none; }

.dp-env {
  grid-column: 4; grid-row: var(--r); justify-self: stretch;
  display: inline-flex; align-items: center; gap: 0.55rem;
  padding: 0.55rem 0.95rem; border: 1px solid var(--border); border-radius: 10px;
  background: var(--card); font-family: var(--font-mono); font-size: 0.74rem;
  color: var(--fg); white-space: nowrap;
}
.dp-env-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--fg-faint); flex: none; transition: background 0.35s ease, box-shadow 0.35s ease; }
.dp-env-dot.ok { background: var(--accent); box-shadow: 0 0 8px oklch(0.73 0.11 176.47 / 50%); }

/* Deploy/promote token — one ball, injected by JS, relayed edge by edge in sequence.
   Like the fix: emerges from the source box and dissolves INTO the destination box
   (travels the full box-to-box path, not just the visible arrow), fading in/out. */
.dp-tok {
  position: absolute; width: 8px; height: 8px; border-radius: 50%;
  background: var(--accent); box-shadow: 0 0 5px oklch(0.73 0.11 176.47 / 42%);
  opacity: 0; pointer-events: none; z-index: 3;
}
.dp-harrow .dp-tok { top: 50%; left: 0; margin-top: -4px; }
.dp-harrow .dp-tok.is-run { animation: dp-tok-h 0.85s var(--ease-inout) forwards; }
.dp-vup .dp-tok { left: 50%; bottom: 0; margin-left: -4px; }
.dp-vup .dp-tok.is-run { animation: dp-tok-v 0.7s var(--ease-inout) forwards; }
@keyframes dp-tok-h {
  0%   { left: calc(-1 * var(--dp-gap)); opacity: 0; }   /* at the source box edge */
  16%  { opacity: 1; }
  84%  { opacity: 1; }
  100% { left: calc(100% + var(--dp-gap)); opacity: 0; } /* dissolves into the env box */
}
@keyframes dp-tok-v {
  0%   { bottom: calc(-1 * var(--dp-gap)); opacity: 0; }
  16%  { opacity: 1; }
  84%  { opacity: 1; }
  100% { bottom: calc(100% + var(--dp-gap)); opacity: 0; }
}

/* horizontal: dashed grey line + right arrowhead (commit → deploy) */
.dp-harrow { grid-column: 3; grid-row: var(--r); position: relative; align-self: center; width: 100%; height: 10px; }
.dp-harrow::before {
  content: ""; position: absolute; left: 0; right: 7px; top: 50%; transform: translateY(-50%);
  border-top: 1.5px dashed var(--bp-line);
}
.dp-harrow::after {
  content: ""; position: absolute; right: 0; top: 50%; transform: translateY(-50%);
  width: 0; height: 0; border-left: 6px solid var(--bp-ink);
  border-top: 4px solid transparent; border-bottom: 4px solid transparent;
}

/* vertical: solid green line + up arrowhead (merge → promote) */
.dp-vup { grid-column: 2; grid-row: var(--r); position: relative; justify-self: center; width: 12px; height: clamp(1.2rem, 2.6vw, 1.8rem); }
.dp-vup::before {
  content: ""; position: absolute; left: 50%; top: 6px; bottom: 0; transform: translateX(-50%);
  border-left: 1.5px solid var(--accent);
}
.dp-vup::after {
  content: ""; position: absolute; left: 50%; top: 0; transform: translateX(-50%);
  width: 0; height: 0; border-bottom: 6px solid var(--accent);
  border-left: 4px solid transparent; border-right: 4px solid transparent;
}

.dp-caption {
  grid-column: 2 / 5; grid-row: 7;   /* centered under the branch→env arrows, clear of the promote label */
  justify-self: center; margin: 0.2rem 0 0;
  font-family: var(--font-mono); font-size: 0.68rem; letter-spacing: 0.04em; color: var(--fg-faint);
}
.dp-caption b { color: var(--fg-muted); font-weight: 500; }
@media (max-width: 720px) {
  .dp-map { column-gap: clamp(0.5rem, 3vw, 1rem); }
  .dp-promote { font-size: 0.54rem; }
  .dp-env, .dp-branch { padding: 0.45rem 0.7rem; font-size: 0.7rem; }
}
/* Phones: the boxes are nowrap, so the map has a hard minimum width ("integration"
   + "Production" + the arrow lane). Below ~480px that minimum exceeded the stage
   and the env column was clipped away, so shrink every part with the viewport:
   the arrow lane may collapse to a stub, and type/padding/icons scale down. */
@media (max-width: 560px) {
  .dp-map {
    grid-template-columns: auto auto minmax(1rem, 10rem) auto;
    column-gap: clamp(0.4rem, 2vw, 0.8rem);
  }
  .dp-head { font-size: 0.58rem; letter-spacing: 0.07em; padding-bottom: 0.5rem; }
  .dp-promote { font-size: 0.5rem; }
  .dp-env, .dp-branch { padding: 0.4rem 0.5rem; font-size: clamp(0.58rem, 2.6vw, 0.7rem); gap: 0.35rem; }
  .dp-branch-ico { width: 11px; height: 11px; }
  .dp-caption { font-size: 0.6rem; }
}

/* Ch03 Drift — INTRUSION: asymmetric, broken red link, dominant Production,
   the calm teal "all match" row glowing amid the red (inverted hierarchy). */
.dr {
  --accent: oklch(0.73 0.11 176.47);         /* calmer illustration teal */
  --accent-dim: oklch(0.73 0.11 176.47 / 12%);
  display: grid; justify-items: center; gap: clamp(1.4rem, 3.2vw, 2.2rem);
  width: 100%; max-width: none;              /* fill the padded stage, up to the container */
}
.dr-track { display: flex; align-items: center; gap: clamp(0.6rem, 1.8vw, 1rem); width: 100%; }
.dr-ref { min-width: 84px; }
.dr-ref .illo-node-cap { color: var(--fg); font-weight: 600; font-size: 0.74rem; }   /* bright box title */
.dr-link { position: relative; flex: 1 1 auto; min-width: 2rem; height: 0;
  border-top: 1.5px dashed oklch(1 0 0 / 16%);   /* grey dashed line, like deploy / the fix */
}
.dr-break {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: 24px; height: 24px; display: grid; place-items: center; border-radius: 50%;
  background: var(--bg-raised);
  border: 1px solid oklch(0.7106 0.1661 22.22 / 45%);
  color: var(--status-error);
}
.dr-break svg { width: 13px; height: 13px; }
.dr-prod {                                                       /* drifted env — same size as Repository */
  display: inline-grid; place-items: center; gap: 0.45rem;
  padding: 0.75rem 0.95rem; min-width: 84px;
  border: 1px solid oklch(0.7106 0.1661 22.22 / 38%);
  border-radius: var(--radius-m);
  background: linear-gradient(180deg, oklch(0.7106 0.1661 22.22 / 7%), transparent), var(--card);
}
.dr-prod-ico { display: grid; place-items: center; width: 30px; height: 30px; border-radius: 8px; background: oklch(0.7106 0.1661 22.22 / 12%); border: 1px solid oklch(0.7106 0.1661 22.22 / 30%); color: var(--status-error); }
.dr-prod-ico svg { width: 15px; height: 15px; }
.dr-prod-name { font-size: 0.74rem; font-weight: 600; color: var(--fg); }
.dr-card { width: 100%; border: 1px solid var(--border); border-top-color: var(--border-strong); border-radius: var(--radius-m); background: var(--card); overflow: hidden; }
.dr-card-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0.5rem 0.85rem; border-bottom: 1px solid var(--border);
  background: oklch(1 0 0 / 4%);   /* distinct header bar, like code sync */
  font-family: var(--font-mono); font-size: 0.64rem; color: var(--fg-muted); letter-spacing: 0.02em;
}
.dr-head-flag { color: var(--status-error); }
.dr-card-head + .dr-row { border-top: none; }
.dr-row { display: flex; align-items: center; gap: 0.6rem; padding: 0.46rem 0.85rem; font-family: var(--font-mono); font-size: 0.72rem; color: var(--fg); border-top: 1px solid var(--border); }
.dr-row:first-child { border-top: none; }
.dr-dot { width: 7px; height: 7px; border-radius: 50%; flex: none; }
.dr-dot.bad { background: var(--status-error); }
.dr-path { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dr-diff { display: inline-flex; gap: 0.3rem; font-size: 0.62rem; flex: none; }
.dr-diff i { font-style: normal; }
.dr-diff .del { color: oklch(0.7106 0.1661 22.22 / 80%); }
.dr-diff .add { color: oklch(0.73 0.11 176.47 / 72%); }
.dr-tag {
  font-size: 0.58rem; padding: 0.12rem 0.45rem; border-radius: 999px;
  border: 1px solid oklch(0.7106 0.1661 22.22 / 35%);
  color: var(--status-error); background: oklch(0.7106 0.1661 22.22 / 10%);
  white-space: nowrap; flex: none;
}
.dr-actions { margin-left: auto; display: flex; gap: 0.35rem; flex: none; }
.dr-btn { font-size: 0.62rem; padding: 0.2rem 0.5rem; border: 1px solid var(--border); border-radius: 6px; color: var(--fg-muted); white-space: nowrap; }
.dr-btn.is-accent { border-color: oklch(0.73 0.11 176.47 / 42%); color: var(--accent); background: var(--accent-dim); }
/* the calm match row — the one glowing teal focal */
.dr-match { color: var(--fg-muted); }
.dr-match .dr-check {
  display: grid; place-items: center; width: 16px; height: 16px; border-radius: 50%; flex: none;
  background: var(--accent-dim); color: var(--accent);
  box-shadow: 0 0 10px oklch(0.73 0.11 176.47 / 45%);
}
.dr-match .dr-check svg { width: 10px; height: 10px; }
.dr-when { margin-left: auto; font-size: 0.62rem; color: var(--fg-faint); flex: none; }
@media (max-width: 720px) {
  .dr-track { flex-direction: column; gap: 0.7rem; }
  .dr-link { width: 60%; height: 0; }
  .dr-row { flex-wrap: wrap; }
}
/* Phones: the match row is a sentence, not a file path — let it wrap onto a
   second line instead of ellipsizing away the reassurance it exists to give.
   (File-path rows keep truncating: the tail is the identifying part there.) */
@media (max-width: 560px) {
  .dr-row { padding: 0.46rem 0.7rem; font-size: 0.68rem; }
  /* Keep the sentence on the check's line: flex-basis 0 stops its content width
     from bumping it to a line of its own, and sending the timestamp to a full
     row of its own gives the sentence the whole width instead of a narrow column. */
  .dr-match .dr-path { white-space: normal; overflow: visible; flex: 1 1 0; min-width: 0; }
  .dr-match .dr-when { flex-basis: 100%; text-align: right; }
  /* Drop the two redundant drift markers on phones: the red dot already flags
     each row (the chip only wrapped onto a line of its own), and the broken
     link between Repository and Production reads without the warning glyph. */
  .dr-tag { display: none; }
  .dr-break { display: none; }
}

/* Ch04 MCP — a live MCP session terminal: agent reads NetSuite context, audited */
.mc {
  --accent: oklch(0.73 0.11 176.47);         /* calmer illustration teal */
  --accent-dim: oklch(0.73 0.11 176.47 / 12%);
  --illo-wire-active: oklch(0.73 0.11 176.47 / 17%);
  display: grid; justify-items: center; width: 100%; max-width: none;
}
.mc-term {
  width: 100%;                                /* fill the padded stage, up to the container */
  border: 1px solid var(--border); border-top-color: var(--border-strong);
  border-radius: var(--radius-m);
  background: var(--card);
  overflow: hidden;
}
.mc-head {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 0.6rem 0.9rem;
  border-bottom: 1px solid var(--border);
  background: oklch(1 0 0 / 4%);              /* distinct header bar, like the other cards */
}
.mc-conn { display: inline-flex; align-items: center; gap: 0.5rem; min-width: 0; }
.mc-agent, .mc-ns { width: 24px; height: 24px; border-radius: 8px; display: grid; place-items: center; border: 1px solid var(--border); background: oklch(1 0 0 / 4%); color: var(--fg-muted); flex: none; }
.mc-agent { color: var(--accent); border-color: oklch(0.73 0.11 176.47 / 40%); background: var(--accent-dim); }
.mc-agent svg, .mc-ns svg { width: 13px; height: 13px; }
.mc-conn-line { width: 16px; height: 1.5px; background: var(--illo-wire-active); flex: none; }
.mc-conn-label { font-family: var(--font-mono); font-size: 0.66rem; color: var(--fg-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mc-status { display: inline-flex; align-items: center; gap: 0.4rem; font-family: var(--font-mono); font-size: 0.62rem; color: var(--fg-faint); white-space: nowrap; flex: none; }
.mc-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 8px oklch(0.73 0.11 176.47 / 50%); flex: none; }
.mc-rows { display: grid; min-width: 0; }
/* min-width: 0 — as grid items the rows default to min-width: auto, so they sat
   at their min-content width (533px) and punched out of the terminal instead of
   letting .mc-sql ellipsize: below 660px the text was cut off mid-word. */
.mc-row { display: flex; gap: 0.7rem; align-items: center; min-width: 0; padding: 0.42rem 0.9rem; font-family: var(--font-mono); font-size: 0.72rem; }
.mc-key { color: var(--fg-muted); white-space: nowrap; flex: none; }
.mc-row.is-active .mc-key { color: var(--accent); }
.mc-val { flex: 1 1 0; min-width: 0; color: var(--fg-faint); display: flex; align-items: center; gap: 0.45rem; }
.mc-sql { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mc-pill { flex: none; font-size: 0.56rem; color: var(--fg-faint); border: 1px solid var(--border); border-radius: 999px; padding: 0.06rem 0.42rem; }
.mc-caret { flex: none; width: 1.5px; height: 0.82rem; background: var(--accent); display: inline-block; }
.mc-audit {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.55rem 0.9rem;
  border-top: 1px solid var(--border);
  background: oklch(1 0 0 / 2%);
  font-family: var(--font-mono); font-size: 0.66rem; color: var(--fg-muted);
}
.mc-check { width: 16px; height: 16px; border-radius: 50%; display: grid; place-items: center; background: var(--accent-dim); color: var(--accent); flex: none; }
.mc-check svg { width: 10px; height: 10px; }
.mc-tag { margin-left: auto; flex: none; font-size: 0.58rem; color: var(--accent); border: 1px solid oklch(0.73 0.11 176.47 / 40%); background: var(--accent-dim); border-radius: 999px; padding: 0.06rem 0.45rem; }
@media (max-width: 720px) {
  .mc-conn-label { display: none; }
}
/* Phones: side by side, the tool name eats the row and the result ellipsizes to
   nothing. Stack them so each gets the full width — the result is the payload. */
@media (max-width: 560px) {
  .mc-row { flex-direction: column; align-items: stretch; gap: 0.1rem; padding: 0.5rem 0.75rem; font-size: 0.68rem; }
  .mc-audit { font-size: 0.62rem; padding: 0.5rem 0.75rem; }
  .mc-head { padding: 0.55rem 0.75rem; }
}

/* ---- v2: remaining pieces ------------------------------------------------ */

/* Hero entrance for the demo block */
#deploy-demo { animation: rise 0.9s var(--ease-out) both; animation-delay: 0.32s; }

/* Pain grid: five across on wide screens; explicit spans mid-range so the
   hairline-gap trick never exposes an empty glowing cell */
@media (min-width: 1100px) {
  .pain-grid-5 { grid-template-columns: repeat(5, 1fr); }
  .pain-grid-5 .pain-card { padding: 1.5rem 1.25rem; }
}
@media (min-width: 700px) and (max-width: 1099px) {
  .pain-grid-5 { grid-template-columns: repeat(6, 1fr); }
  .pain-grid-5 .pain-card { grid-column: span 2; }
  .pain-grid-5 .pain-card:nth-child(4) { grid-column: 1 / 4; }
  .pain-grid-5 .pain-card:nth-child(5) { grid-column: 4 / 7; }
}
@media (max-width: 699px) {
  .pain-grid-5 { grid-template-columns: 1fr; }
}

/* Ch00 Baseline — ingestion: File Cabinet → Repository, with a live count-up */
/* Baseline illustration — modelled on the sf2 "The fix" flow: an existing
   NetSuite codebase is imported into the repository (file count present but
   quiet), and a small git graph then grows commits, with context, on top of
   the baseline commit. */
.bl2 {
  /* calmer, desaturated teal — the shared illustration accent (as in "The fix"),
     less neon than the product-UI accent */
  --accent: oklch(0.73 0.11 176.47);
  --accent-strong: oklch(0.745 0.10 176.47);
  --accent-dim: oklch(0.73 0.11 176.47 / 12%);
  --illo-wire-active: oklch(0.73 0.11 176.47 / 17%);
  --bl2-arrow: oklch(0.73 0.11 176.47 / 78%);
  --seg: 1.6s;
  display: grid; justify-items: stretch; gap: clamp(1.3rem, 3vw, 2rem);
  width: 100%; max-width: none;   /* fill the padded stage (no .illo-content 880 cap) */
}

/* Shared "hug" stage: auto height (content never clips) with a generous 64px side
   inset — used by the panels modelled directly on the fix (baseline, code sync). */
.bl2-visual .illo-stage,
.cs-visual .illo-stage,
.dp-visual .illo-stage,
.dr-visual .illo-stage,
.mc-visual .illo-stage {
  aspect-ratio: auto; height: auto; max-height: none; min-height: 300px;
  /* 64px side inset on desktop, but fluid below ~1070px viewport: a fixed 4rem
     each side ate 128px of a 320px screen, leaving the illos no room to fit. */
  padding: clamp(2.5rem, 3.6vw, 3rem) clamp(1rem, 6vw, 4rem);
}

/* Import pipeline: File Cabinet → Cycle → Repository (fills the wide stage) */
.bl2-flow { display: flex; align-items: center; justify-content: center; gap: clamp(0.7rem, 2vw, 1.2rem); width: 100%; }
.bl2-node { min-width: 108px; gap: 0.4rem; text-align: center; }
/* Box title like the fix's sf2-name: bright + semibold (not muted) */
.bl2-node .illo-node-cap { color: var(--fg); font-weight: 600; font-size: 0.74rem; line-height: 1.15; }
/* Cycle icon: no override — inherit the shared 16px aspect-fit node-icon sizing,
   so its box renders identically to the Cycle node in "The fix". */
.bl2-node-sub {
  font-family: var(--font-mono); font-size: 0.56rem; line-height: 1;
  color: var(--fg-faint); white-space: nowrap;
}
.bl2-node-sub b { color: var(--fg-muted); font-weight: 600; }
/* lane grows to fill the row — a terse "import" arrow, like the fix's lanes */
.bl2-lane { flex: 1 1 auto; min-width: 3rem; position: relative; }
.bl2-lane::after {                          /* forward arrowhead into the Repository */
  content: ""; position: absolute; right: -1px; top: 50%; transform: translateY(-50%);
  width: 0; height: 0;
  border-left: 5px solid var(--bl2-arrow);
  border-top: 3px solid transparent; border-bottom: 3px solid transparent;
}
.bl2-lane-cap {
  position: absolute; bottom: calc(100% + 6px); left: 50%; transform: translateX(-50%);
  font-family: var(--font-mono); font-size: 0.55rem; letter-spacing: 0.02em;
  white-space: nowrap; color: oklch(0.73 0.11 176.47 / 88%);
}

/* Commit history — a compact git graph rooted at the baseline commit.
   Same width as the flow above (fills the padded stage). */
/* Commit history — a contained card mirroring .cs-card (header bar + body),
   so the baseline history reads as a panel instead of floating on the grid. */
.bl2-log {
  width: 100%;
  border: 1px solid var(--border);
  border-top-color: var(--border-strong);
  border-radius: var(--radius-m);
  background: var(--card);
  overflow: hidden;
}
.bl2-log-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0.5rem 0.85rem;
  border-bottom: 1px solid var(--border);
  background: oklch(1 0 0 / 4%);
  font-family: var(--font-mono); font-size: 0.64rem; color: var(--fg-muted);
  letter-spacing: 0.02em;
}
.bl2-log-body { padding: 0.35rem 0.85rem; display: grid; }
.bl2-c {
  display: grid;
  grid-template-columns: 16px minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.6rem;
  min-height: 2.25rem;
}
.bl2-c-rail { position: relative; align-self: stretch; }
.bl2-c-rail::before {                       /* continuous vertical connector */
  content: ""; position: absolute; left: 50%; top: 0; bottom: 0;
  width: 1.5px; transform: translateX(-50%); background: var(--border);
}
.bl2-c.is-first .bl2-c-rail::before { top: 50%; }
.bl2-c.is-last  .bl2-c-rail::before { bottom: 50%; }
.bl2-c-rail::after {                         /* commit dot */
  content: ""; position: absolute; left: 50%; top: 50%;
  width: 8px; height: 8px; margin: -4px 0 0 -4px; border-radius: 50%;
  background: var(--bg); border: 1.5px solid var(--fg-faint);
}
.bl2-c.is-base .bl2-c-rail::after {
  background: var(--accent); border-color: var(--accent);
  box-shadow: 0 0 7px oklch(0.73 0.11 176.47 / 45%);
}
.bl2-c-body { display: grid; gap: 0.12rem; min-width: 0; }
.bl2-c-msg {
  font-family: var(--font-mono); font-size: 0.72rem; color: var(--fg-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bl2-c.is-base .bl2-c-msg { color: var(--fg); }
.bl2-c-meta {
  font-family: var(--font-mono); font-size: 0.56rem; color: var(--fg-faint);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bl2-c-hash {
  font-family: var(--font-mono); font-size: 0.6rem; color: var(--fg-faint);
  border: 1px solid var(--border); border-radius: 5px; padding: 0.06rem 0.36rem;
}
.bl2-c.is-base .bl2-c-hash { color: var(--accent); border-color: oklch(0.73 0.11 176.47 / 40%); }
@media (max-width: 720px) {
  .bl2-flow { flex-direction: column; gap: 0.8rem; }
  .bl2-lane { display: none; }
}

/* Ch01 Code sync — AGREEMENT: two lit endpoints, one clean lane, file-sync card */
.cs {
  /* calmer, desaturated illustration teal (as in the fix / baseline) */
  --accent: oklch(0.73 0.11 176.47);
  --accent-strong: oklch(0.745 0.10 176.47);
  --accent-dim: oklch(0.73 0.11 176.47 / 12%);
  --illo-wire-active: oklch(0.73 0.11 176.47 / 17%);
  display: grid; justify-items: center; gap: clamp(1.4rem, 3.2vw, 2.2rem);
  width: 100%; max-width: none;   /* fill the padded stage, up to the container */
}
.cs-track { position: relative; display: flex; align-items: center; gap: clamp(0.7rem, 2vw, 1.1rem); width: 100%; }
.cs-node { min-width: 92px; padding: 0.55rem 0.85rem; }
/* box title like the fix's sf2-name: bright + semibold (not muted) */
.cs-node .illo-node-cap { color: var(--fg); font-weight: 600; font-size: 0.74rem; }
.cs-node .illo-node-ico { width: 30px; height: 30px; }
.cs-lane { overflow: visible; }
.cs-swap {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: 24px; height: 24px; display: grid; place-items: center;
  border-radius: 50%;
  background: var(--bg-raised);
  border: 1px solid oklch(0.73 0.11 176.47 / 38%);
  color: var(--accent);
  z-index: 2;
}
.cs-swap svg { width: 12px; height: 12px; }
.cs-card {
  width: 100%;
  border: 1px solid var(--border);
  border-top-color: var(--border-strong);
  border-radius: var(--radius-m);
  background: var(--card);
  overflow: hidden;
}
.cs-card-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0.5rem 0.85rem;
  border-bottom: 1px solid var(--border);
  background: oklch(1 0 0 / 4%);   /* distinct header bar (was same as the card) */
  font-family: var(--font-mono); font-size: 0.64rem; color: var(--fg-muted);
  letter-spacing: 0.02em;
}
.cs-row {
  display: flex; align-items: center; gap: 0.6rem;
  padding: 0.46rem 0.85rem;
  font-family: var(--font-mono); font-size: 0.72rem; color: var(--fg);
  border-top: 1px solid var(--border);
}
.cs-card-head + .cs-row { border-top: none; }
.cs-dot { width: 7px; height: 7px; border-radius: 50%; flex: none; }
.cs-dot.ok { background: var(--status-success); }
.cs-dot.run { background: var(--status-running); }
.cs-dot.mod { background: var(--fg-faint); }   /* neutral · changed, pending sync */
.cs-path { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cs-actions { display: flex; gap: 0.35rem; margin-left: auto; flex: none; }
.cs-btn {
  font-size: 0.62rem; padding: 0.2rem 0.5rem;
  border: 1px solid var(--border); border-radius: 6px;
  color: var(--fg-muted); white-space: nowrap;
}
.cs-btn.is-accent { border-color: oklch(0.73 0.11 176.47 / 42%); color: var(--accent); background: var(--accent-dim); }
/* Token relays ONCE: glides to the centre swap, dwells there, continues to
   NetSuite, then stops (JS flips the row to "Synced" on completion). */
.chapter-visual.is-visible .cs .cs-lane .illo-token {
  animation: cs-travel 3s var(--ease-inout) 0.6s 1 both;
}
@keyframes cs-travel {
  0%   { left: 0%;   opacity: 0; }
  8%   { opacity: 1; }
  38%  { left: 50%;  opacity: 1; }   /* arrive at the swap */
  55%  { left: 50%;  opacity: 1; }   /* dwell */
  92%  { left: 100%; opacity: 1; }   /* continue to NetSuite */
  100% { left: 100%; opacity: 0; }
}
.cs-synced { display: inline-flex; align-items: center; gap: 0.4rem; margin-left: auto; flex: none; color: var(--accent); font-size: 0.66rem; }
.cs-synced svg { width: 13px; height: 13px; }
/* both explicit-display spans need [hidden] restated (their display wins over the UA rule) */
.cs-synced[hidden], .cs-syncing[hidden] { display: none; }
.cs-syncing { display: inline-flex; align-items: center; gap: 0.4rem; margin-left: auto; flex: none; color: var(--fg); font-size: 0.66rem; }
.cs-spin {
  width: 10px; height: 10px; border-radius: 50%;
  border: 1.5px solid oklch(0.7137 0.1434 254.62 / 25%);
  border-top-color: var(--status-running);
  animation: spin 0.8s linear infinite;
}
@media (max-width: 720px) {
  .cs-track { flex-direction: column; gap: 0.7rem; }
  .cs-lane { display: none; }
}

/* ==========================================================================
   Illustration STYLE VARIANTS — toggle by setting a class on <body>:
     (none)          → A · "Studio"   — grid + product-UI teal (current)
     .illo-blueprint → B · "Blueprint"— cool technical-paper, muted accents
     .illo-slate     → C · "Slate"    — desaturated chalkboard, soft + recessive
   Scoped to the illustration panels only; the rest of the page is untouched.
   Desaturation is done with `filter: saturate()` on the stage, which mutes the
   coloured accents while leaving the grey type unchanged.
   ========================================================================== */

/* ---- B · Blueprint -------------------------------------------------------- */
body.illo-blueprint .illo-stage { filter: saturate(0.6) brightness(0.97); }
/* Blueprint now inherits the shared base backdrop (the promoted "The fix" line
   grid) so every panel matches that treatment — no dot-grid override here. */
body.illo-blueprint .illo-glow { opacity: 0.5; }
/* surfaces go translucent so the blueprint reads through them (drawing, not UI) */
body.illo-blueprint .illo-node,
body.illo-blueprint .cs-card,
body.illo-blueprint .bl2-log,
body.illo-blueprint .dr-card,
body.illo-blueprint .mc-term,
body.illo-blueprint .solflow-chip,
body.illo-blueprint .dp-branch,
body.illo-blueprint .dp-env { background: oklch(0.18 0.012 235 / 55%); }

/* ---- C · Slate (chalkboard) ----------------------------------------------- */
body.illo-slate .illo-stage { filter: saturate(0.4) brightness(0.93) contrast(0.97); }
body.illo-slate .illo-bg {
  background-image: radial-gradient(oklch(1 0 0 / 7%) 1px, transparent 1.5px);
  background-size: 19px 19px;
  -webkit-mask-image: radial-gradient(130% 100% at 50% 50%, #000 28%, transparent 82%);
  mask-image: radial-gradient(130% 100% at 50% 50%, #000 28%, transparent 82%);
}
body.illo-slate .illo-glow { opacity: 0.38; }
/* soft vignette → feels like a framed slate panel */
body.illo-slate .illo-stage::after {
  content: "";
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: radial-gradient(120% 92% at 50% 48%, transparent 52%, oklch(0 0 0 / 38%));
}
body.illo-slate .illo-node,
body.illo-slate .cs-card,
body.illo-slate .bl2-log,
body.illo-slate .dr-card,
body.illo-slate .mc-term,
body.illo-slate .solflow-chip,
body.illo-slate .dp-branch,
body.illo-slate .dp-env { background: oklch(0.2046 0 0 / 48%); }

/* ---- Reduced motion ------------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .reveal { opacity: 1; transform: none; }

  /* Illustration end-states: everything drawn, lit, and still. */
  .illo-stage *, .illo-rise-item { opacity: 1 !important; transform: none !important; }
  .illo-line-fill { transform: scaleX(1) !important; }
  .illo-token, .sf2-back-token, .sf2-rs-token, .sf2-bp-token { opacity: 0 !important; }
  .illo-pulse, .illo-breathe, .illo-caret { animation: none !important; opacity: 1 !important; }
}

/* ==========================================================================
   Contact page (contact.html) — request a demo / apply for early access.
   Split layout: title + proof points left, form panel right behind a hairline.
   The segmented control (billing-seg) switches the page intent.
   ========================================================================== */
.contact-main {
  min-height: 100vh;
  display: grid;
  align-items: center;
  padding-top: clamp(6.5rem, 13vh, 9rem);
  padding-bottom: clamp(3rem, 8vh, 5rem);
}
.contact-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: clamp(2.5rem, 5vw, 4.5rem);
}

.contact-intro { display: grid; gap: 1.5rem; align-content: start; padding-top: 0.75rem; }
.contact-intro > * { animation: rise 0.9s var(--ease-out) both; }
.contact-intro > :nth-child(2) { animation-delay: 0.06s; }
.contact-intro > :nth-child(3) { animation-delay: 0.12s; }
.contact-intro > :nth-child(4) { animation-delay: 0.18s; }
.contact-title {
  margin: 0;
  font-size: clamp(2.4rem, 5vw, 3.5rem);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.05;
}
.contact-points { list-style: none; margin: 0.25rem 0 0; padding: 0; display: grid; gap: 0.95rem; }
.contact-points li {
  display: flex; align-items: flex-start; gap: 0.75rem;
  color: var(--fg-muted); font-size: 1.0625rem; line-height: 1.5;
}
.contact-points svg { flex: none; margin-top: 0.42rem; color: var(--accent); }
.contact-note { margin: 0.5rem 0 0; font-size: 0.9rem; color: var(--fg-faint); }
.contact-note a { color: var(--fg-muted); text-decoration: underline; text-underline-offset: 3px; }
.contact-note a:hover { color: var(--accent); }

.contact-panel {
  border-left: 1px solid var(--border);
  padding-left: clamp(2rem, 4.5vw, 4rem);
  display: grid;
  gap: 1.6rem;
  align-content: start;
  animation: rise 0.9s var(--ease-out) 0.12s both;
}
.contact-seg { margin: 0; }              /* billing-seg centers itself; here it sits left */
/* Author display:flex would beat the UA [hidden] rule, same as .contact-form.
   The chooser is hidden once a request is sent: there is nothing to choose
   between on a confirmation, and the header CTA brings the form back. */
.contact-seg[hidden] { display: none; }

.contact-form { display: grid; gap: 1.05rem; }
.contact-form[hidden] { display: none; }      /* author display:grid would beat UA [hidden] */
.contact-form-title { margin: 0 0 0.15rem; font-size: 1.2rem; font-weight: 600; letter-spacing: -0.012em; }
.field { display: grid; gap: 0.45rem; }
.field > span { font-size: 0.85rem; font-weight: 500; color: var(--fg-muted); }
.field :is(input, select, textarea) {
  font: inherit;
  font-size: 0.95rem;
  width: 100%;
  color: var(--fg);
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-m);
  padding: 0.62rem 0.85rem;
  transition: border-color 0.18s var(--ease-soft), box-shadow 0.18s var(--ease-soft);
}
.field :is(input, select, textarea):hover { border-color: var(--border-strong); }
.field :is(input, select, textarea):focus {
  outline: none;
  border-color: oklch(0.7675 0.1298 176.47 / 55%);
  box-shadow: 0 0 0 3px var(--accent-dim);
}
.field ::placeholder { color: var(--fg-faint); }
.field textarea { min-height: 7.5rem; resize: vertical; }
.field select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 2.4rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%239CA5A5' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.8rem center;
}
.field select:invalid { color: var(--fg-faint); }   /* placeholder option showing */
/* Native dropdown popup: keep it on-palette (Chrome tints the highlight from
   accent-color; option backgrounds cover the dark list + checked row). */
.field select { accent-color: var(--accent); }
.field option { background: var(--card); color: var(--fg); }
.field option:checked { background: var(--accent-dim); color: var(--accent); }
.field optgroup { background: var(--card); color: var(--fg-muted); font-style: normal; }

/* Honeypot: off-screen rather than display:none, because some bots skip fields
   that are not rendered at all. Never focusable, never announced. */
.hp-field {
  position: absolute; left: -9999px; width: 1px; height: 1px;
  overflow: hidden; opacity: 0; pointer-events: none;
}

/* Turnstile renders its own iframe. No reserved height: with
   appearance="interaction-only" most visitors never see it, and holding 65px
   of empty space under the button for them would be worse than the widget. */
.cf-turnstile { max-width: 100%; overflow: hidden; }
.cf-turnstile:not(:empty) { margin-top: 0.35rem; }

.contact-error {
  margin: 0; padding: 0.7rem 0.85rem; border-radius: 10px;
  border: 1px solid oklch(0.7106 0.1661 22.22 / 35%);
  background: oklch(0.7106 0.1661 22.22 / 10%);
  color: oklch(0.8 0.12 22.22); font-size: 0.88rem; line-height: 1.5;
}
.contact-error[hidden] { display: none; }

.contact-actions { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; margin-top: 0.2rem; }
.contact-actions .alt { font-size: 0.85rem; color: var(--fg-faint); }
.contact-actions .alt a { color: var(--fg-muted); text-decoration: underline; text-underline-offset: 3px; }
.contact-actions .alt a:hover { color: var(--accent); }

/* Post-submit state — swaps in for the form. Receives focus programmatically
   on submit (keyboard position + SR announcement); no ring on that focus. */
/* ---- Thanks state --------------------------------------------------------
   Shown only once the Worker confirms the lead was stored. It has a job beyond
   saying thanks: the visitor has just declared intent and has nothing to do
   next, so it hands them somewhere to go. The mark draws itself once — the
   confirmation should feel resolved, not decorative. */
.contact-thanks { display: grid; gap: 1.4rem; align-content: start; outline: none; }
.contact-thanks[hidden] { display: none; }
.contact-thanks > * { animation: rise 0.75s var(--ease-out) both; }
.contact-thanks > :nth-child(2) { animation-delay: 0.09s; }
.contact-thanks > :nth-child(3) { animation-delay: 0.18s; }

.thanks-head { display: flex; align-items: center; gap: 1.15rem; }
.contact-thanks h2 {
  margin: 0; font-size: clamp(1.45rem, 3vw, 1.95rem);
  font-weight: 600; letter-spacing: -0.025em; line-height: 1.12;
}
.thanks-lede { margin: 0; color: var(--fg-muted); max-width: 34rem; line-height: 1.6; }

/* The mark: one ring, with the accent glow the illustrations use on their focal
   nodes, so the confirmation reads as part of the product's language. A second
   ring inside the disc read as a double outline and was dropped. */
.thanks-mark {
  flex: none; width: 62px; height: 62px; border-radius: 50%;
  display: grid; place-items: center; color: var(--accent);
  background: var(--accent-dim);
  box-shadow: inset 0 0 0 1.5px oklch(0.73 0.11 176.47 / 55%),
              0 0 30px oklch(0.73 0.11 176.47 / 28%);
}
.thanks-mark svg { width: 30px; height: 30px; overflow: visible; }
.thanks-mark-check {
  stroke-dasharray: 34; stroke-dashoffset: 34;
  animation: thanks-check 0.5s var(--ease-out) 0.15s forwards;
}
@keyframes thanks-check { to { stroke-dashoffset: 0; } }

.thanks-next { display: grid; gap: 0.8rem; }
.thanks-next-label {
  font-family: var(--font-mono); font-size: 0.68rem; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--fg-faint);
}
.thanks-links { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.85rem; }
.thanks-links a {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center;
  gap: 0.85rem; padding: 0.85rem 0.95rem;
  border: 1px solid var(--border); border-radius: 12px;
  background: oklch(1 0 0 / 2%); color: var(--fg); text-decoration: none;
  transition: border-color 0.22s var(--ease-out), background 0.22s var(--ease-out),
              transform 0.22s var(--ease-out);
}
.thanks-links a:hover {
  border-color: color-mix(in oklab, var(--accent) 45%, var(--border));
  background: var(--bg-raised);
  transform: translateY(-2px);
}
.thanks-link-ico {
  width: 34px; height: 34px; border-radius: 9px; display: grid; place-items: center;
  border: 1px solid var(--border); background: oklch(1 0 0 / 4%); color: var(--fg-muted);
  transition: color 0.22s var(--ease-out), border-color 0.22s var(--ease-out);
}
.thanks-link-ico svg { width: 16px; height: 16px; }
.thanks-links a:hover .thanks-link-ico { color: var(--accent); border-color: oklch(0.73 0.11 176.47 / 40%); }
.thanks-link-text { display: grid; gap: 0.15rem; min-width: 0; }
.thanks-link-text b { font-size: 0.94rem; font-weight: 550; letter-spacing: -0.01em; }
.thanks-link-text span { font-size: 0.85rem; color: var(--fg-muted); line-height: 1.45; }
.thanks-link-arrow {
  width: 15px; height: 15px; flex: none; color: var(--fg-faint);
  transition: transform 0.22s var(--ease-out), color 0.22s var(--ease-out);
}
.thanks-links a:hover .thanks-link-arrow { color: var(--accent); transform: translateX(3px); }

@media (prefers-reduced-motion: reduce) {
  .contact-thanks > *,
  .thanks-mark-check { animation: none; }
  .thanks-mark-check { stroke-dashoffset: 0; }
}
@media (max-width: 420px) {
  .thanks-head { gap: 0.85rem; }
  .thanks-mark { width: 50px; height: 50px; }
  .thanks-mark svg { width: 25px; height: 25px; }
  .thanks-links a { padding: 0.75rem 0.8rem; gap: 0.7rem; }
}

@media (max-width: 880px) {
  .contact-main { align-items: start; padding-top: 5.5rem; }
  .contact-grid { grid-template-columns: 1fr; gap: 2.4rem; }
  .contact-panel { border-left: 0; padding-left: 0; border-top: 1px solid var(--border); padding-top: 2.1rem; }
}
@media (max-width: 420px) {
  .contact-seg .billing-seg-opt { font-size: 0.82rem; padding-inline: 0.8rem; }
}
@media (max-width: 345px) {
  .contact-seg .billing-seg-opt { font-size: 0.75rem; padding-inline: 0.55rem; }
}
@media (prefers-reduced-motion: reduce) {
  .contact-intro > *, .contact-panel, .contact-thanks { animation: none !important; }
}

/* ==========================================================================
   Legal pages (terms.html, privacy.html, subprocessors.html)
   Sticky doc TOC on the left, measured prose on the right.
   ========================================================================== */
.legal-main { padding-top: clamp(7rem, 12vh, 8.5rem); padding-bottom: var(--section-pad); }
.legal-head { display: grid; gap: 1rem; margin-bottom: clamp(2.25rem, 5vw, 3.25rem); }
.legal-title { margin: 0; font-size: clamp(2.1rem, 4.5vw, 3rem); font-weight: 600; letter-spacing: -0.03em; line-height: 1.05; }
.legal-meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1.1rem;
  font-family: var(--font-mono); font-size: 0.72rem; color: var(--fg-faint);
}
.legal-badge {
  display: inline-flex; align-items: center; gap: 0.4rem;
  padding: 0.2rem 0.55rem; border-radius: var(--radius-pill);
  border: 1px solid oklch(0.8 0.12 80 / 30%);
  color: var(--status-queued); background: oklch(0.8 0.12 80 / 7%);
  font-size: 0.64rem; letter-spacing: 0.06em; text-transform: uppercase;
}

.legal-grid { display: grid; grid-template-columns: 15rem minmax(0, 1fr); gap: clamp(2rem, 5vw, 4.5rem); align-items: start; }
.legal-toc {
  position: sticky; top: 5.5rem;
  max-height: calc(100vh - 7rem); overflow-y: auto;
  display: grid; gap: 0.1rem; align-content: start;
  font-size: 0.82rem; scrollbar-width: thin;
}
.legal-toc-group {
  margin: 0 0 0.35rem; font-family: var(--font-mono); font-size: 0.62rem;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--fg-faint);
}
.legal-toc-group:not(:first-child) { margin-top: 1.4rem; }
.legal-toc a {
  padding: 0.3rem 0.7rem; border-left: 1px solid var(--border);
  color: var(--fg-faint); text-decoration: none;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: color 0.18s var(--ease-soft), border-color 0.18s var(--ease-soft);
}
.legal-toc .toc-n { font-family: var(--font-mono); font-size: 0.68rem; margin-right: 0.4rem; opacity: 0.75; }
.legal-toc a:hover { color: var(--fg); border-color: var(--border-strong); }
.legal-toc a.is-current { color: var(--accent); border-color: var(--accent); }

.legal-article { max-width: 46rem; min-width: 0; }
.legal-article .legal-lede { font-size: 1.0625rem; color: var(--fg-muted); line-height: 1.65; margin: 0 0 1rem; }
.legal-article section { border-top: 1px solid var(--border); padding-top: 2rem; margin-top: 2.4rem; }
.legal-article section:first-of-type { border-top: 0; padding-top: 0.8rem; margin-top: 1.6rem; }
.legal-article h2 { margin: 0 0 1rem; font-size: 1.2rem; font-weight: 600; letter-spacing: -0.015em; scroll-margin-top: 6rem; }
.legal-article .h2-n { font-family: var(--font-mono); font-size: 0.8em; font-weight: 500; color: var(--fg-faint); margin-right: 0.5rem; }
.legal-article p, .legal-article li { font-size: 0.95rem; line-height: 1.7; color: var(--fg-muted); }
.legal-article p { margin: 0 0 0.9rem; }
.legal-article b, .legal-article strong { color: var(--fg); font-weight: 600; }
.legal-article ul { margin: 0 0 0.9rem; padding-left: 1.25rem; display: grid; gap: 0.45rem; }
.legal-article li::marker { color: var(--fg-faint); }
.legal-article a { color: var(--accent); text-decoration: none; }
.legal-article a:hover { color: var(--accent-strong); text-decoration: underline; text-underline-offset: 3px; }
.legal-article code { font-family: var(--font-mono); font-size: 0.85em; color: var(--fg); background: oklch(1 0 0 / 6%); border-radius: 5px; padding: 0.08em 0.35em; }
.legal-tbd { color: var(--status-queued); }
.legal-fine { font-size: 0.8rem; color: var(--fg-faint); border-top: 1px solid var(--border); padding-top: 1.4rem; margin-top: 2rem; }

/* Data table (subprocessors) */
.legal-article table { width: 100%; border-collapse: collapse; margin: 0.4rem 0 1.2rem; font-size: 0.92rem; }
.legal-article th {
  text-align: left; font-family: var(--font-mono); font-size: 0.66rem;
  letter-spacing: 0.1em; text-transform: uppercase; font-weight: 500;
  color: var(--fg-faint); padding: 0.55rem 1rem 0.55rem 0;
  border-bottom: 1px solid var(--border-strong);
}
.legal-article td { padding: 0.7rem 1rem 0.7rem 0; border-bottom: 1px solid var(--border); color: var(--fg-muted); vertical-align: top; }
.legal-article td:first-child { color: var(--fg); font-weight: 500; white-space: nowrap; }
.legal-table-wrap { overflow-x: auto; }

@media (max-width: 880px) {
  .legal-grid { grid-template-columns: 1fr; gap: 2rem; }
  .legal-toc { position: static; max-height: none; border: 1px solid var(--border); border-radius: var(--radius-l); padding: 1rem; }
  .legal-article td:first-child { white-space: normal; }
}
