@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;600;700&family=Inter:wght@400;450;500;600&display=swap');

/* ============================================================
   Runles - web design system (landing + dashboard)
   Desktop-first. Space Grotesk display, Inter body, light canvas,
   acid lime split into fill and text variants.
   ============================================================ */

:root {
  --bg:        oklch(97.4% 0.002 265);
  --surface:   oklch(100% 0 0);
  --raised:    oklch(95.2% 0.003 265);
  --ink:       oklch(18% 0.014 265);
  --fg:        oklch(21% 0.012 265);
  --muted:     oklch(52% 0.014 265);
  --faint:     oklch(66% 0.010 265);
  --border:    oklch(90.5% 0.004 265);
  --border-2:  oklch(85% 0.006 265);

  --accent:      oklch(88% 0.21 128);
  --accent-ink:  oklch(23% 0.07 128);
  --accent-text: oklch(46% 0.13 133);

  --pos:     oklch(52% 0.15 152);
  --caution: oklch(58% 0.13 72);
  --neg:     oklch(52% 0.19 25);
  --info:    oklch(52% 0.14 250);

  --tint-pos:     color-mix(in oklab, var(--pos) 9%, var(--surface));
  --tint-caution: color-mix(in oklab, var(--caution) 12%, var(--surface));
  --tint-neg:     color-mix(in oklab, var(--neg) 8%, var(--surface));
  --tint-info:    color-mix(in oklab, var(--info) 9%, var(--surface));
  --tint-accent:  color-mix(in oklab, var(--accent) 24%, var(--surface));

  --font-display: 'Space Grotesk', 'Helvetica Neue', -apple-system, sans-serif;
  --font-body:    'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;

  /* surfaces that sit on ink - five arbitrary lightnesses collapsed to two */
  --on-ink:         oklch(96% 0.003 265);
  --on-ink-strong:  oklch(98% 0.002 265);
  --on-ink-dim:     oklch(74% 0.008 265);
  --on-ink-faint:   oklch(62% 0.008 265);
  --on-dark:        oklch(97% 0.003 265);
  --av-fg:          oklch(97% 0 0);

  /* interaction + structural fills that were inline literals */
  --btn-hover:          oklch(92% 0.004 265);
  --btn-primary-hover:  oklch(84% 0.21 128);
  --ink-hover:          oklch(26% 0.014 265);
  --overlay-05:  oklch(100% 0 0 / 0.05);
  --overlay-08:  oklch(100% 0 0 / 0.08);
  --overlay-10:  oklch(100% 0 0 / 0.10);
  --track:         oklch(21% 0.012 265 / 0.06);
  --track-strong:  oklch(21% 0.012 265 / 0.09);

  --r: 12px;
  --r-soft: 16px;
  --shadow-soft: 0 1px 2px oklch(21% 0.012 265 / 0.04), 0 8px 22px -14px oklch(21% 0.012 265 / 0.20);
  --shadow-lift: 0 2px 4px oklch(21% 0.012 265 / 0.05), 0 16px 34px -16px oklch(21% 0.012 265 / 0.26);
  --r-sm: 8px;
  --shadow: 0 1px 2px oklch(21% 0.012 265 / 0.05), 0 8px 24px -14px oklch(21% 0.012 265 / 0.25);
  --container: 1180px;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

/* the UA's [hidden] { display: none } loses to any class that sets display,
   so tab panes and filtered grids stayed visible - this wins it back */
[hidden] { display: none !important; }

html { scroll-behavior: smooth; }
body {
  font-family: var(--font-body);
  color: var(--fg);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  line-height: 1.5;
}
img { max-width: 100%; display: block; }
a { color: inherit; }

.container { max-width: var(--container); margin: 0 auto; padding: 0 32px; }
.narrow { max-width: 820px; }

/* ---------- type ---------- */
h1, h2, h3, h4 { font-family: var(--font-display); font-weight: 700; letter-spacing: -0.03em; line-height: 1.05; }
h1 { font-size: clamp(44px, 5.4vw, 74px); }
h2 { font-size: clamp(30px, 3.4vw, 44px); }
h3 { font-size: 21px; letter-spacing: -0.025em; font-weight: 600; }
h4 { font-size: 16px; letter-spacing: -0.02em; font-weight: 600; }
p { font-size: 16px; line-height: 1.6; }
.lede { font-size: 19px; line-height: 1.55; color: var(--muted); }
.eyebrow {
  display: inline-block;
  font-size: 13px; font-weight: 600; letter-spacing: 0.02em;
  color: var(--accent-text);
}
.fig { font-family: var(--font-display); font-variant-numeric: tabular-nums; letter-spacing: -0.035em; font-weight: 700; }
.num { font-variant-numeric: tabular-nums; }
.muted { color: var(--muted); }

/* ---------- buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 46px; padding: 0 20px;
  border: 1px solid transparent; border-radius: 10px;
  font-family: var(--font-body); font-size: 15px; font-weight: 600; letter-spacing: -0.01em;
  cursor: pointer; text-decoration: none; white-space: nowrap;
  background: var(--raised); color: var(--fg);
  transition: transform .08s, background .15s, border-color .15s;
}
.btn:hover { background: var(--btn-hover); }
.btn:active { transform: translateY(1px); }
.btn.primary { background: var(--accent); color: var(--accent-ink); }
.btn.primary:hover { background: var(--btn-primary-hover); }
.btn.dark { background: var(--ink); color: var(--on-dark); }
.btn.dark:hover { background: var(--ink-hover); }
.btn.ghost { background: none; border-color: var(--border-2); }
.btn.ghost:hover { background: var(--raised); }
.btn.lg { min-height: 54px; padding: 0 26px; font-size: 16px; }
.btn.sm { min-height: 36px; padding: 0 13px; font-size: 14px; border-radius: 8px; }
.btn:disabled, .btn[disabled] {
  opacity: .42; cursor: not-allowed; filter: saturate(.6);
}
.btn:disabled:hover, .btn[disabled]:hover { background: var(--accent); }
.btn.ghost:disabled:hover { background: none; }

/* ---------- shell components (injected by assets/shell.js) ---------- */
.sprite { position: absolute; }
.wordmark.sm { font-size: 17px; }
.wordmark.xs { font-size: 16px; }
.wordmark.xs .dot { width: 19px; height: 19px; }
.who { text-decoration: none; }
.who .n, .who .e { display: block; }

/* ---------- utilities ----------
   Deliberately small. Anything reached for 3+ times becomes a component
   class instead; these exist for genuine one-offs. Spacing is a 4px scale
   so ad-hoc 6/13/15px margins can't creep back in. */
.grow    { flex: 1 1 auto; }
.w-full  { width: 100%; }
.center  { text-align: center; }
.nowrap  { white-space: nowrap; }
.mt-1 { margin-top: 4px; }
.mt-2 { margin-top: 8px; }
.mt-3 { margin-top: 12px; }
.mt-4 { margin-top: 16px; }
.mt-5 { margin-top: 22px; }
.mt-6 { margin-top: 28px; }
.t-sm { font-size: 13px; line-height: 1.5; }
.t-md { font-size: 14.5px; }
.t-lg { font-size: 17px; }
.c-pos     { color: var(--pos); }
.c-neg     { color: var(--neg); }
.c-caution { color: var(--caution); }
.c-accent  { color: var(--accent-text); }
.d-block { display: block; }
.no-underline { text-decoration: none; }

/* small component variants that were repeated inline */
.fig-lg    { font-size: 30px; }          /* dark-band efficiency figures */
.score-lg  { font-size: 23px; }          /* idea-card score */
.cell-note { max-width: 26ch; }
.col       { display: flex; flex-direction: column; }
.fw-600    { font-weight: 600; }
.fig-xl    { font-size: 38px; }
.stack.gap-lg { gap: 22px; }
.field.narrow { max-width: 520px; }
.empty.sm  { padding: 44px 24px; }
.dot-ic.pos       { background: var(--tint-pos); color: var(--pos); }
.dot-ic.neg       { background: var(--tint-neg); color: var(--neg); }
.dot-ic.on-accent { background: var(--surface); color: var(--accent-text); }
.set-row .ctl input[type="time"] { min-width: 120px; }          /* wrapping note column in a data table */

/* ---------- icons ----------
   One inline <symbol> sprite per page, referenced with <use href="#i-name">.
   Stroke geometry only, 1.7px monoline, always currentColor. */
.ic {
  display: block; flex: none;
  width: 18px; height: 18px;
  fill: none; stroke: currentColor;
  stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
}
.ic-14 { width: 14px; height: 14px; stroke-width: 1.9; }
.ic-16 { width: 16px; height: 16px; stroke-width: 1.8; }
.ic-20 { width: 20px; height: 20px; }
.ic-22 { width: 22px; height: 22px; stroke-width: 1.6; }
.ic-26 { width: 26px; height: 26px; stroke-width: 1.5; }

.tile-ic {
  width: 44px; height: 44px; border-radius: 12px; flex: none;
  display: grid; place-items: center;
  background: var(--tint-accent); color: var(--accent-ink);
}
.tile-ic.sm { width: 30px; height: 30px; border-radius: 9px; }
.tile-ic.lg { width: 54px; height: 54px; border-radius: 15px; }
.tile-ic.neutral { background: var(--raised); color: var(--muted); }
.tile-ic.pos     { background: var(--tint-pos); color: var(--pos); }
.tile-ic.caution { background: var(--tint-caution); color: var(--caution); }
.tile-ic.neg     { background: var(--tint-neg); color: var(--neg); }
.tile-ic.info    { background: var(--tint-info); color: var(--info); }
/* on the dark band the tint tokens go muddy - but white cards sitting
   inside that band still need the light-theme treatment */
.band-dark .tile-ic { background: var(--overlay-08); color: var(--accent); }
.band-dark .card .tile-ic { background: var(--tint-accent); color: var(--accent-ink); }

/* ---------- diagrams ----------
   Schematics drawn from the product's own data. Classes rather than
   presentation attributes, because var() doesn't resolve in those. */
.dia { display: block; width: 100%; height: auto; }
.dia .sf   { fill: var(--surface); stroke: var(--border-2); stroke-width: 1.4; }
.dia .sf-2 { fill: var(--raised); stroke: none; }
.dia .ln   { fill: none; stroke: var(--border-2); stroke-width: 1.4; stroke-linecap: round; }
.dia .dash { fill: none; stroke: var(--border-2); stroke-width: 1.4; stroke-dasharray: 3 5; stroke-linecap: round; }
.dia .acc  { fill: var(--accent); }
.dia .acc-s{ fill: none; stroke: var(--accent-text); stroke-width: 2; stroke-linecap: round; }
.dia .pos  { fill: var(--pos); }
.dia .pos-s{ fill: none; stroke: var(--pos); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.dia .info { fill: var(--info); }
.dia .neg  { fill: var(--neg); }
.dia .mut  { fill: var(--faint); }
.dia .ink  { fill: var(--fg); }
.dia text  { font-family: var(--font-body); font-size: 12px; fill: var(--muted); }
.dia .fignum {
  font-family: var(--font-display); font-size: 21px; font-weight: 700;
  letter-spacing: -0.035em; fill: var(--fg);
}
.dia .fignum.big { font-size: 36px; }
/* uppercase labels inside diagrams need the same tracking as anywhere else */
.dia .cap { font-size: 11px; font-weight: 600; letter-spacing: 0.08em; fill: var(--faint); }
.dia .t-pos { fill: var(--pos); }
.dia .t-mut { fill: var(--muted); }
/* funnel stages, neutral → positive as ideas survive */
.dia .f-1 { fill: var(--raised); }
.dia .f-2 { fill: color-mix(in oklab, var(--info) 13%, var(--surface)); }
.dia .f-3 { fill: var(--tint-accent); }
.dia .f-4 { fill: color-mix(in oklab, var(--pos) 20%, var(--surface)); }

/* score sparkline */
.spark { display: block; width: 100%; height: auto; }
.spark-x { display: flex; justify-content: space-between; margin-top: 9px; font-size: 12px; color: var(--faint); }
.spark .fill { fill: color-mix(in oklab, var(--pos) 12%, transparent); stroke: none; }

/* ---------- surfaces ---------- */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r);
}
.card.pad { padding: 24px; }
.card.lift { box-shadow: var(--shadow); }

.pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 11px; border-radius: 999px;
  font-size: 13px; font-weight: 600; letter-spacing: -0.005em;
  background: var(--raised); color: var(--muted);
}
.pill.good { background: var(--tint-pos); color: var(--pos); }
.pill.watch { background: var(--tint-caution); color: var(--caution); }
.pill.risk { background: var(--tint-neg); color: var(--neg); }
.pill.accent { background: var(--tint-accent); color: var(--accent-text); }

/* display:block matters - an inline span ignores height */
.meter { display: block; height: 6px; border-radius: 3px; background: var(--track-strong); overflow: hidden; }
.meter > span { display: block; height: 100%; border-radius: 3px; background: var(--info); }
.meter > span.good { background: var(--pos); }
.meter > span.watch { background: var(--caution); }
.meter > span.risk { background: var(--neg); }
.meter > span.accent { background: var(--accent-text); }

/* ============================================================
   LANDING
   ============================================================ */
.site-nav {
  position: sticky; top: 0; z-index: 40;
  background: color-mix(in oklab, var(--bg) 86%, transparent);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid transparent;
  transition: border-color .2s;
}
.site-nav.stuck { border-bottom-color: var(--border); }
.site-nav .inner { display: flex; align-items: center; gap: 32px; height: 68px; }
.wordmark {
  display: flex; align-items: center; gap: 9px;
  font-family: var(--font-display); font-size: 19px; font-weight: 700; letter-spacing: -0.035em;
  text-decoration: none;
}
.wordmark .dot { width: 22px; height: 22px; border-radius: 6px; background: var(--accent); display: grid; place-items: center; color: var(--accent-ink); }
.wordmark { display: block; width: 132px; height: 38px; line-height: 0; }
.wordmark img { display: block; width: 132px; height: 38px; object-fit: contain; }
.wordmark.xs { width: 102px; height: 30px; }
.wordmark.xs img { width: 102px; height: 30px; }
.site-nav .links { display: flex; gap: 26px; margin-left: 12px; }
.site-nav .links a { font-size: 15px; color: var(--muted); text-decoration: none; }
.site-nav .links a:hover { color: var(--fg); }
.site-nav .links { align-items: center; }
.site-nav .links > a { position: relative; display: flex; align-items: center; height: 44px; }
.site-nav .links > a[aria-current="page"] { color: var(--fg); font-weight: 600; }
.site-nav .links > a[aria-current="page"]::after { content: ""; position: absolute; right: 0; bottom: 0; left: 0; height: 2px; border-radius: 2px; background: var(--accent-text); }
.site-nav .more-menu { position: relative; display: flex; align-items: center; height: 44px; color: var(--muted); }
.site-nav .more-menu summary { display: flex; align-items: center; gap: 8px; height: 44px; color: inherit; font-size: 15px; line-height: 1; cursor: pointer; list-style: none; }
.site-nav .more-menu summary::before { content: ""; position: absolute; right: 0; bottom: 0; left: 0; height: 2px; border-radius: 2px; background: transparent; }
.site-nav .more-menu:has(.more-popover a[aria-current="page"]) { color: var(--fg); font-weight: 600; }
.site-nav .more-menu:has(.more-popover a[aria-current="page"]) summary::before { background: var(--accent-text); }
.site-nav .more-menu summary::-webkit-details-marker { display: none; }
.site-nav .more-menu summary::after { content: ""; width: 7px; height: 7px; margin-top: -4px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(45deg); transition: transform .15s; }
.site-nav .more-menu[open] summary, .site-nav .more-menu summary:hover { color: var(--fg); }
.site-nav .more-menu[open] summary::after { margin-top: 4px; transform: rotate(225deg); }
.site-nav .more-menu summary:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; border-radius: 5px; }
.site-nav .more-popover { position: absolute; z-index: 20; top: calc(100% + 8px); right: -10px; width: 184px; padding: 7px; border: 1px solid color-mix(in oklab, var(--border) 72%, transparent); border-radius: 12px; background: var(--surface); box-shadow: 0 18px 44px color-mix(in oklab, var(--fg) 14%, transparent); }
.site-nav .links .more-popover a { display: flex; align-items: center; min-height: 44px; padding: 0 12px; border-radius: 8px; color: var(--fg); font-size: 14px; font-weight: 550; letter-spacing: .01em; }
.site-nav .links .more-popover a:hover { background: var(--tint-accent); color: var(--fg); }
.site-nav .links .more-popover a:focus-visible { outline: 3px solid var(--accent); outline-offset: -1px; }
.site-nav .links .more-popover a[aria-current="page"] { background: var(--tint-accent); color: var(--accent-ink); }
.site-nav .right { margin-left: auto; display: flex; align-items: center; gap: 12px; }

.hero { padding: 84px 0 32px; }
.hero h1 { max-width: 15ch; }
.hero .lede { max-width: 54ch; margin-top: 22px; }
.hero .actions { display: flex; gap: 12px; margin-top: 32px; flex-wrap: wrap; }
.hero .under { margin-top: 16px; font-size: 14px; color: var(--faint); }

/* inline demo - the hero's proof, not a stock illustration */
.demo {
  margin-top: 54px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 16px;
  box-shadow: var(--shadow);
  overflow: hidden;
}
.demo-bar {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 16px; border-bottom: 1px solid var(--border);
  background: var(--raised);
}
.demo-bar .dots { display: flex; gap: 6px; }
.demo-bar .dots i { width: 10px; height: 10px; border-radius: 50%; background: var(--border-2); display: block; }
.demo-bar .path { font-size: 13px; color: var(--faint); margin-left: 6px; }
.demo-body { display: grid; grid-template-columns: 1.05fr 1fr; }
.demo-in { padding: 26px; border-right: 1px solid var(--border); }
.demo-in label { font-size: 13px; font-weight: 600; color: var(--muted); }
.demo-in textarea {
  width: 100%; margin-top: 10px; min-height: 132px; resize: none;
  border: 1px solid var(--border); border-radius: 10px; padding: 13px 14px;
  font: inherit; font-size: 15px; line-height: 1.55; color: var(--fg);
  background: var(--bg); outline: 0;
}
.demo-in textarea:focus { border-color: color-mix(in oklab, var(--accent-text) 45%, var(--border)); }
.demo-out { padding: 26px; display: grid; align-content: start; gap: 16px; }
.demo-score { display: flex; align-items: center; gap: 16px; }
.demo-score .n { font-family: var(--font-display); font-size: 54px; font-weight: 700; letter-spacing: -0.045em; line-height: .9; color: var(--pos); }
.demo-axis { display: grid; gap: 9px; }
.demo-axis .r { display: flex; align-items: center; gap: 10px; font-size: 14px; }
.demo-axis .r .lbl { flex: 1 1 auto; color: var(--muted); }
.demo-axis .r .v { font-family: var(--font-display); font-weight: 600; font-variant-numeric: tabular-nums; }
.demo-axis .meter { width: 84px; flex: none; }

.section { padding: 88px 0; }
.section.tight { padding: 64px 0; }
.section-head { max-width: 62ch; margin-bottom: 44px; }
.section-head h2 { margin-top: 10px; }
.section-head p { margin-top: 16px; font-size: 17px; color: var(--muted); }

.hero .trust { display: flex; gap: 24px; flex-wrap: wrap; margin-top: 18px; }
.hero .trust span { display: flex; align-items: center; gap: 8px; font-size: 14px; color: var(--muted); }
.hero .trust .ic { color: var(--accent-text); }

.flow { margin-bottom: 40px; }

.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
.step { padding-top: 22px; border-top: 2px solid var(--ink); }
.step-top { display: flex; align-items: center; gap: 13px; margin-bottom: 16px; }
.step .n { font-family: var(--font-display); font-size: 13px; font-weight: 700; color: var(--accent-text); }
.step h3 { margin: 0 0 9px; }
.step p { font-size: 15px; color: var(--muted); }

/* a figure with an icon above the number - used on the dark band and in panels */
.fig-ic { display: flex; align-items: center; gap: 10px; }
.fig-ic .k { font-size: 13px; color: var(--muted); }

.band-dark { background: var(--ink); color: var(--on-ink); }
.band-dark h2 { color: var(--on-ink-strong); }
.band-dark .lede, .band-dark p { color: var(--on-ink-dim); }
.band-dark .eyebrow { color: var(--accent); }
/* white cards sitting inside the dark band keep light-theme text -
   otherwise they inherit the band's pale copy colour onto white */
.band-dark .card { color: var(--fg); }
.band-dark .card h2,
.band-dark .card h3,
.band-dark .card h4,
.band-dark .card .fig { color: var(--fg); }
.band-dark .card p,
.band-dark .card .muted { color: var(--muted); }

.compare { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.compare-col {
  border: 1px solid var(--border); border-radius: var(--r);
  background: var(--surface); padding: 26px;
}
.compare-col.is-us { border-color: var(--accent-text); box-shadow: 0 0 0 3px var(--tint-accent); }
.compare-col h3 { display: flex; align-items: center; gap: 10px; }
.compare-col .price { font-family: var(--font-display); font-size: 38px; font-weight: 700; letter-spacing: -0.04em; margin: 16px 0 4px; }
.compare-col .price small { font-size: 15px; font-weight: 500; color: var(--muted); letter-spacing: 0; }
.compare-list { list-style: none; margin-top: 20px; display: grid; gap: 11px; }
.compare-list li { display: flex; gap: 10px; font-size: 15px; line-height: 1.45; }
.compare-list svg { flex: none; margin-top: 3px; }
.compare-list .y { color: var(--pos); }
.compare-list .n { color: var(--faint); }

.faq { display: grid; gap: 0; border-top: 1px solid var(--border); }
.faq details { border-bottom: 1px solid var(--border); }
.faq summary {
  cursor: pointer; list-style: none; padding: 22px 0;
  font-family: var(--font-display); font-size: 18px; font-weight: 600; letter-spacing: -0.02em;
  display: flex; align-items: center; gap: 16px;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+"; margin-left: auto; font-size: 22px; font-weight: 400; color: var(--faint);
}
.faq details[open] summary::after { content: "–"; }
.faq details p { padding: 0 40px 22px 0; color: var(--muted); max-width: 70ch; }

.site-foot { border-top: 1px solid var(--border); padding: 44px 0; }
.site-foot .inner { display: flex; gap: 24px; align-items: center; flex-wrap: wrap; }
.site-foot p { font-size: 14px; color: var(--faint); }
.site-foot .links { margin-left: auto; display: flex; gap: 22px; }
.site-foot .links a { font-size: 14px; color: var(--muted); text-decoration: none; }

/* ============================================================
   DASHBOARD - sidebar + workspace, desktop density
   ============================================================ */
.app { display: grid; grid-template-columns: 236px 1fr; min-height: 100vh; }

.sidebar {
  border-right: 1px solid var(--border);
  background: var(--surface);
  display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh;
}
.sidebar .brand { display: flex; align-items: center; height: 60px; padding: 0 18px; border-bottom: 1px solid var(--border); }
.side-nav { padding: 14px 10px; display: grid; gap: 2px; }
.side-label {
  font-size: 11.5px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--faint); padding: 16px 8px 6px;
}
.side-link {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px; border-radius: var(--r-sm);
  font-size: 14.5px; color: var(--muted); text-decoration: none;
}
.side-link:hover { background: var(--raised); color: var(--fg); }
.side-link[aria-current="page"] { background: var(--tint-accent); color: var(--accent-ink); font-weight: 600; }
.side-link .c { margin-left: auto; font-size: 12.5px; color: var(--faint); font-variant-numeric: tabular-nums; }
.sidebar .foot { margin-top: auto; padding: 14px; border-top: 1px solid var(--border); }
.who { display: flex; align-items: center; gap: 10px; }
.who .av {
  width: 30px; height: 30px; border-radius: 50%; flex: none;
  background: var(--ink); color: var(--av-fg);
  display: grid; place-items: center; font-size: 12px; font-weight: 600;
}
.who .n { font-size: 13.5px; font-weight: 500; }
.who .e { font-size: 12px; color: var(--faint); }

.work { min-width: 0; display: flex; flex-direction: column; }
.topbar {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: 16px;
  height: 60px; padding: 0 24px;
  background: color-mix(in oklab, var(--bg) 88%, transparent);
  backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid var(--border);
}
.topbar h1 { font-size: 19px; letter-spacing: -0.025em; font-weight: 600; }
.topbar .spacer { flex: 1 1 auto; }
.search {
  display: flex; align-items: center; gap: 8px;
  min-width: 260px; padding: 0 12px; height: 36px;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-sm);
  color: var(--faint);
}
.search input { flex: 1 1 auto; border: 0; outline: 0; background: none; font: inherit; font-size: 14px; color: var(--fg); }
.search kbd {
  font-family: var(--font-body); font-size: 11px; color: var(--faint);
  border: 1px solid var(--border); border-radius: 4px; padding: 1px 5px;
}

.work-body { padding: 26px 24px 48px; display: grid; gap: 22px; }

.kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
.kpi { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r); padding: 18px 20px; }
.kpi-head { display: flex; align-items: flex-start; gap: 10px; }
.kpi-head .k { flex: 1 1 auto; }
.kpi .k { font-size: 13px; color: var(--muted); font-weight: 500; }
.kpi .v { font-family: var(--font-display); font-size: 32px; font-weight: 700; letter-spacing: -0.035em; margin-top: 8px; font-variant-numeric: tabular-nums; }
.kpi .d { font-size: 12.5px; color: var(--faint); margin-top: 5px; }
.kpi .d.up { color: var(--pos); }

.grid-2 { display: grid; grid-template-columns: 1.5fr 1fr; gap: 22px; align-items: start; }

.panel { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r); }
.panel-head {
  display: flex; align-items: center; gap: 12px;
  padding: 15px 20px; border-bottom: 1px solid var(--border);
}
.panel-head h3 { font-size: 15.5px; letter-spacing: -0.02em; }
.panel-head .spacer { flex: 1 1 auto; }
.panel-body { padding: 20px; }
.panel-foot { padding: 13px 20px; border-top: 1px solid var(--border); font-size: 13px; color: var(--faint); }

/* data table - a genuine desktop idiom */
table.data { width: 100%; border-collapse: collapse; }
table.data th {
  text-align: left; font-size: 12px; font-weight: 600; letter-spacing: 0.02em;
  text-transform: uppercase; color: var(--faint);
  padding: 10px 20px; border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
table.data th.right, table.data td.right { text-align: right; }
table.data td { padding: 13px 20px; border-bottom: 1px solid var(--border); font-size: 14.5px; vertical-align: middle; }
table.data tbody tr:last-child td { border-bottom: 0; }
table.data tbody tr:hover { background: var(--bg); }
table.data .title { font-weight: 500; letter-spacing: -0.01em; }
table.data .sub { font-size: 12.5px; color: var(--faint); margin-top: 2px; }
table.data .score { font-family: var(--font-display); font-size: 17px; font-weight: 700; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; }
table.data .score.good { color: var(--pos); }
table.data .score.watch { color: var(--caution); }
table.data .score.risk { color: var(--neg); }
table.data th.sortable { cursor: pointer; user-select: none; }
table.data th.sortable:hover { color: var(--fg); }
table.data th .arrow { opacity: 0; margin-left: 4px; }
table.data th[aria-sort] .arrow { opacity: 1; }

/* distribution chart - bars computed from --v / --max */
.chart { display: grid; gap: 12px; --max: 100; }
.bar-row { display: grid; grid-template-columns: 116px 1fr 46px; align-items: center; gap: 12px; }
.bar-label { font-size: 13.5px; color: var(--muted); }
.bar-track { height: 22px; border-radius: 5px; background: var(--track); overflow: hidden; }
/* display:block matters - an inline span ignores width and height */
.bar { display: block; height: 100%; border-radius: 5px; width: calc(var(--v) / var(--max) * 100%); background: var(--info); }
.bar.good { background: var(--pos); }
.bar.watch { background: var(--caution); }
.bar.risk { background: var(--neg); }
.bar-value { font-family: var(--font-display); font-size: 14px; font-weight: 600; text-align: right; font-variant-numeric: tabular-nums; }

.stack { display: grid; gap: 14px; }
.mini { display: flex; align-items: flex-start; gap: 12px; }
.dot-ic {
  width: 28px; height: 28px; border-radius: 7px; flex: none;
  display: grid; place-items: center; background: var(--raised); color: var(--muted);
}
.mini h4 { font-size: 14.5px; }
.mini p { font-size: 13px; color: var(--muted); margin-top: 2px; line-height: 1.4; }

.running-card { background: var(--tint-accent); border-color: color-mix(in oklab, var(--accent) 40%, var(--border)); }

/* ---------- page heads, tabs, toolbars ---------- */
.page-head { display: flex; align-items: flex-end; gap: 20px; flex-wrap: wrap; }
.page-head .lede { font-size: 15.5px; max-width: 66ch; margin-top: 7px; }
.page-head h2 { font-size: 28px; }
.page-head .actions { margin-left: auto; display: flex; gap: 10px; }

.tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); }
.tab {
  padding: 10px 13px; margin-bottom: -1px;
  font-size: 14.5px; color: var(--muted); text-decoration: none;
  border-bottom: 2px solid transparent;
}
.tab:hover { color: var(--fg); }
.tab[aria-current="page"] { color: var(--fg); font-weight: 600; border-bottom-color: var(--accent-text); }
.tab .c { color: var(--faint); font-variant-numeric: tabular-nums; margin-left: 5px; }

.toolbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.toolbar .spacer { flex: 1 1 auto; }
.chipset { display: flex; gap: 6px; flex-wrap: wrap; }
.chip {
  appearance: none; cursor: pointer;
  border: 1px solid var(--border); border-radius: 999px;
  background: var(--surface); padding: 6px 13px;
  font: inherit; font-size: 13.5px; color: var(--muted);
  transition: background .14s, color .14s, border-color .14s;
}
.chip:hover { background: var(--raised); color: var(--fg); }
.chip[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--av-fg); font-weight: 500; }
.chip .c { opacity: .6; margin-left: 5px; font-variant-numeric: tabular-nums; }

select.sel {
  height: 36px; padding: 0 10px;
  border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--surface); color: var(--fg);
  font: inherit; font-size: 14px; cursor: pointer;
}

/* ---------- forms ---------- */
.field { display: grid; gap: 7px; }
.field > label { font-size: 13.5px; font-weight: 600; letter-spacing: -0.005em; }
.field .hint { font-size: 12.5px; color: var(--faint); }
.field input, .field select, .field textarea, .input,
.set-row .ctl > input, .set-row .ctl > select {
  width: 100%; min-height: 44px;
  border: 1px solid var(--border); border-radius: 10px;
  background: var(--surface); padding: 0 13px;
  font: inherit; font-size: 15px; color: var(--fg); outline: 0;
  transition: border-color .14s, box-shadow .14s;
}
.field textarea { padding: 12px 13px; min-height: 104px; resize: vertical; line-height: 1.55; }
.field input::placeholder, .field textarea::placeholder { color: var(--faint); }
.field input:focus, .field select:focus, .field textarea:focus, .input:focus,
.set-row .ctl > input:focus, .set-row .ctl > select:focus {
  border-color: color-mix(in oklab, var(--accent-text) 55%, var(--border));
  box-shadow: 0 0 0 3px var(--tint-accent);
}
.field.bad input { border-color: var(--neg); }
.field .err { font-size: 12.5px; color: var(--neg); }
.form-grid { display: grid; gap: 16px; }
.form-grid.two { grid-template-columns: 1fr 1fr; }

.sw { position: relative; display: inline-block; width: 44px; height: 26px; flex: none; }
.sw input { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; margin: 0; cursor: pointer; z-index: 1; }
.sw i { position: absolute; inset: 0; border-radius: 999px; background: var(--border-2); transition: background .18s; }
.sw i::after {
  content: ""; position: absolute; top: 3px; left: 3px;
  width: 20px; height: 20px; border-radius: 50%;
  background: var(--surface); box-shadow: 0 1px 3px oklch(21% 0.012 265 / 0.35);
  transition: transform .18s;
}
.sw input:checked + i { background: var(--pos); }
.sw input:checked + i::after { transform: translateX(18px); }

.set-row { display: flex; align-items: flex-start; gap: 24px; padding: 17px 20px; border-bottom: 1px solid var(--border); }
.set-row:last-child { border-bottom: 0; }
.set-row .lbl { flex: 1 1 auto; max-width: 62ch; }
.set-row .lbl h4 { font-size: 14.5px; }
.set-row .lbl p { font-size: 13px; color: var(--muted); margin-top: 3px; line-height: 1.45; }
.set-row .ctl { flex: none; display: flex; align-items: center; gap: 10px; }
.set-row .ctl .field, .set-row .ctl input, .set-row .ctl select { min-width: 200px; }
.panel.danger { border-color: color-mix(in oklab, var(--neg) 34%, var(--border)); }
.panel.danger .panel-head h3 { color: var(--neg); }

/* ---------- report detail ---------- */
.report-hero { display: grid; grid-template-columns: auto 1fr; gap: 34px; align-items: center; }
.gauge {
  position: relative; width: 152px; height: 152px; border-radius: 50%; flex: none;
  display: grid; place-items: center;
  background: conic-gradient(var(--gc, var(--pos)) calc(var(--v) * 3.6deg), oklch(21% 0.012 265 / 0.08) 0);
}
.gauge .in {
  width: 122px; height: 122px; border-radius: 50%; background: var(--surface);
  display: grid; place-content: center; justify-items: center;
}
.gauge .n { font-family: var(--font-display); font-size: 44px; font-weight: 700; letter-spacing: -0.045em; line-height: 1; }
.gauge .of { font-size: 10.5px; font-weight: 600; letter-spacing: 0.09em; text-transform: uppercase; color: var(--faint); margin-top: 6px; }

.axes { display: grid; gap: 11px; max-width: 560px; }
.axis { display: grid; grid-template-columns: 158px 1fr 30px; align-items: center; gap: 13px; font-size: 14px; }
.axis .lbl { color: var(--muted); }
.axis .v { font-family: var(--font-display); font-weight: 600; font-variant-numeric: tabular-nums; text-align: right; }

.figs { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0; }
.figs > div { padding: 0 22px; border-left: 1px solid var(--border); }
.figs > div:first-child { padding-left: 0; border-left: 0; }
.figs .v { font-family: var(--font-display); font-size: 30px; font-weight: 700; letter-spacing: -0.038em; font-variant-numeric: tabular-nums; }
.figs .k { font-size: 12.5px; color: var(--muted); margin-top: 6px; }

.callout { display: flex; gap: 14px; padding: 20px; border-radius: var(--r); background: var(--tint-neg); border: 1px solid color-mix(in oklab, var(--neg) 24%, var(--border)); }
.callout.pos { background: var(--tint-pos); border-color: color-mix(in oklab, var(--pos) 24%, var(--border)); }
.callout.warn { background: var(--tint-caution); border-color: color-mix(in oklab, var(--caution) 26%, var(--border)); }
.callout.warn .ic { color: var(--caution); }
.callout .ic { flex: none; color: var(--neg); margin-top: 2px; }
.callout.pos .ic { color: var(--pos); }
.callout p { font-size: 14.5px; color: var(--fg); margin-top: 5px; line-height: 1.5; }

.phase { display: grid; grid-template-columns: 106px 1fr; gap: 22px; padding: 22px 20px; border-top: 1px solid var(--border); }
.phase:first-child { border-top: 0; }
.phase .when { font-family: var(--font-display); font-size: 13.5px; font-weight: 600; color: var(--accent-text); }
.phase .when .wk { display: block; font-family: var(--font-body); font-size: 12px; font-weight: 400; color: var(--faint); margin-top: 4px; }
.phase h4 { font-size: 15.5px; }
.phase > div > p { font-size: 13.5px; color: var(--muted); margin-top: 4px; }
.check { display: flex; gap: 10px; align-items: flex-start; font-size: 14.5px; padding: 5px 0; cursor: pointer; }
.check input { width: 17px; height: 17px; margin: 2px 0 0; flex: none; accent-color: var(--accent-text); cursor: pointer; }
/* strike-through belongs to roadmap checklists only - .check is also used
   for plain form checkboxes like "keep me signed in", which must not strike */
.checks .check input:checked ~ span { color: var(--faint); text-decoration: line-through; }
.checks { margin-top: 10px; }

/* competitors - one self-contained block per review */
.sc {
  font-family: var(--font-display); font-size: 21px; font-weight: 700;
  letter-spacing: -0.03em; font-variant-numeric: tabular-nums;
}
.ic.flip { transform: rotate(180deg); }
.grid-chart { display: grid; grid-template-columns: 1.45fr 1fr; gap: 28px; align-items: start; }
/* company names need more room than the dashboard's short category labels */
.chart.named .bar-row { grid-template-columns: 152px 1fr 44px; }

.comp-grid, .card-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; }
.card-grid > .panel { display: flex; flex-direction: column; }
.card-grid > .panel > .panel-body { flex: 1 1 auto; }
.card-grid .panel-foot { display: flex; align-items: center; gap: 10px; }
.card-grid .panel-foot .spacer { flex: 1 1 auto; }
.comp { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r); padding: 20px; }
.comp .top { display: flex; align-items: flex-start; gap: 12px; }
.comp .mark {
  width: 34px; height: 34px; border-radius: 9px; flex: none;
  display: grid; place-items: center; background: var(--raised);
  font-family: var(--font-display); font-size: 14px; font-weight: 700; color: var(--muted);
}
.comp h4 { font-size: 15.5px; }
.comp .who { font-size: 12.5px; color: var(--faint); margin-top: 2px; }
.comp p { font-size: 13.5px; color: var(--muted); margin-top: 12px; line-height: 1.5; }
.comp .ov { display: flex; align-items: center; gap: 10px; margin-top: 14px; font-size: 12.5px; color: var(--muted); }
.comp .ov .meter { flex: 1 1 auto; }

.kv { display: grid; gap: 0; }
.kv > div { display: flex; gap: 20px; padding: 11px 0; border-bottom: 1px solid var(--border); font-size: 14px; }
.kv > div:last-child { border-bottom: 0; }
.kv .k { color: var(--muted); min-width: 168px; }
.kv .v { margin-left: auto; text-align: right; font-weight: 500; }

/* ---------- empty state ---------- */
.empty { text-align: center; padding: 62px 24px; }
.empty .ic {
  width: 46px; height: 46px; border-radius: 12px; margin: 0 auto 15px;
  background: var(--raised); color: var(--faint); display: grid; place-items: center;
}
.empty h3 { font-size: 17px; }
.empty p { font-size: 14px; color: var(--muted); margin: 7px auto 0; max-width: 44ch; }
.empty .btn { margin-top: 18px; }

/* ---------- help ---------- */
.help-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.help-card {
  display: block; text-decoration: none;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r); padding: 20px;
  transition: border-color .15s, box-shadow .15s;
}
.help-card:hover { border-color: var(--border-2); box-shadow: var(--shadow); }
.help-card h4 { font-size: 15px; margin-top: 14px; }
.help-card p { font-size: 13.5px; color: var(--muted); margin-top: 5px; line-height: 1.45; }
.help-card .go { font-size: 13px; color: var(--accent-text); font-weight: 600; margin-top: 12px; display: block; }

/* the FAQ accordion is reused inside panels on the help page */
.panel .faq { border-top: 0; }
.panel .faq summary { padding: 18px 20px; font-size: 15.5px; }
.panel .faq details p { padding: 0 20px 18px; font-size: 14px; }
.panel .faq details:last-child { border-bottom: 0; }

/* ============================================================
   AUTH - no sidebar, split canvas
   ============================================================ */
.auth { min-height: 100vh; display: grid; grid-template-columns: 1.05fr 1fr; }
.auth-form { background: var(--surface); padding: 34px clamp(32px, 6vw, 92px); display: flex; flex-direction: column; }
.auth-form .inner { margin: auto 0; width: 100%; max-width: 404px; padding: 44px 0; }
.auth-form h2 { font-size: 34px; }
.auth-form .sub { font-size: 15px; color: var(--muted); margin-top: 10px; }
.auth-form form { display: grid; gap: 16px; margin-top: 30px; }
.auth-form .btn { width: 100%; }
.auth-alt { display: flex; align-items: center; gap: 14px; margin: 22px 0; color: var(--faint); font-size: 12.5px; }
.auth-alt::before, .auth-alt::after { content: ""; height: 1px; background: var(--border); flex: 1 1 auto; }
.auth-swap { font-size: 14px; color: var(--muted); margin-top: 24px; }
.auth-swap a { color: var(--accent-text); font-weight: 600; text-decoration: none; }
.auth-fine { font-size: 12.5px; color: var(--faint); line-height: 1.5; }
.auth-fine a { color: var(--muted); }

.auth-aside {
  background: var(--ink); color: var(--on-ink);
  padding: 34px clamp(32px, 5vw, 68px); display: flex; flex-direction: column;
}
.auth-aside .eyebrow { color: var(--accent); }
.auth-aside .top { display: flex; justify-content: flex-end; }
.auth-aside .top a { font-size: 14px; color: var(--on-ink-dim); text-decoration: none; }
.auth-aside .mid { margin: auto 0; max-width: 440px; }
.auth-aside blockquote { font-family: var(--font-display); font-size: 26px; font-weight: 500; letter-spacing: -0.028em; line-height: 1.28; }
.auth-aside .by { font-size: 13.5px; color: var(--on-ink-dim); margin-top: 18px; }
.auth-aside .proof { margin-top: 34px; background: var(--overlay-05); border: 1px solid var(--overlay-10); border-radius: var(--r); padding: 20px; }
.auth-aside .proof .row { display: flex; align-items: center; gap: 12px; font-size: 13.5px; color: var(--on-ink-dim); }
.auth-aside .proof .row + .row { margin-top: 12px; }
.auth-aside .proof .sc { font-family: var(--font-display); font-size: 19px; font-weight: 700; letter-spacing: -0.03em; color: var(--accent); min-width: 30px; font-variant-numeric: tabular-nums; }
.auth-aside .fine { font-size: 12.5px; color: var(--on-ink-faint); }

@media (max-width: 1080px) {
  .comp-grid, .card-grid, .help-grid, .form-grid.two, .grid-chart { grid-template-columns: 1fr; }
  .figs { grid-template-columns: repeat(2, 1fr); gap: 22px 0; }
  .auth { grid-template-columns: 1fr; }
  .auth-aside { display: none; }
  .report-hero { grid-template-columns: 1fr; }
  .demo-body { grid-template-columns: 1fr; }
  .demo-in { border-right: 0; border-bottom: 1px solid var(--border); }
  .kpis { grid-template-columns: repeat(2, 1fr); }
  .grid-2 { grid-template-columns: 1fr; }
  .app { grid-template-columns: 1fr; }
  .sidebar { display: none; }
}
@media (max-width: 820px) {
  .container { padding: 0 20px; }
  .steps, .compare { grid-template-columns: 1fr; }
  .site-nav .links { display: none; }
  .hero { padding-top: 56px; }
  /* the pipeline schematic carries 11px labels - below this width they'd
     scale under legibility, so drop it rather than ship unreadable type */
  .flow { display: none; }
  .hero .trust { gap: 14px 20px; }
  .phase { grid-template-columns: 1fr; gap: 10px; }
  .set-row { flex-direction: column; gap: 12px; }
  .set-row .ctl { width: 100%; }
  .set-row .ctl .field, .set-row .ctl input, .set-row .ctl select { min-width: 0; width: 100%; }
  .axis { grid-template-columns: 1fr 30px; }
  .axis .meter { grid-column: 1 / -1; }
  .figs { grid-template-columns: 1fr; }
  .figs > div { padding: 0; border-left: 0; }
}
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .001ms !important; transition-duration: .001ms !important; }
  html { scroll-behavior: auto; }
}


/* ============================================================
   NEW REVIEW - composer + run sequence
   ============================================================ */
.readiness { display: grid; gap: 10px; margin-top: 16px; list-style: none; }
.readiness li { display: flex; align-items: center; gap: 10px; font-size: 13.5px; color: var(--faint); }
.readiness li .tick {
  width: 18px; height: 18px; border-radius: 50%; flex: none;
  border: 1.5px solid var(--border-2); display: grid; place-items: center;
  color: transparent; transition: background .15s, border-color .15s, color .15s;
}
.readiness li.on { color: var(--fg); }
.readiness li.on .tick { background: var(--pos); border-color: var(--pos); color: var(--surface); }

.run-step {
  display: flex; align-items: center; gap: 13px;
  padding: 14px 0; border-top: 1px solid var(--border);
  font-size: 14.5px; color: var(--faint);
}
.run-step:first-child { border-top: 0; }
.run-step .mk {
  width: 22px; height: 22px; border-radius: 50%; flex: none;
  border: 1.5px solid var(--border-2); display: grid; place-items: center; color: transparent;
}
.run-step.on   { color: var(--fg); font-weight: 500; }
.run-step.on .mk { border-color: var(--accent-text); color: var(--accent-text); }
.run-step.done { color: var(--muted); }
.run-step.done .mk { background: var(--pos); border-color: var(--pos); color: var(--surface); }
.run-step .when { margin-left: auto; font-size: 12.5px; color: var(--faint); font-variant-numeric: tabular-nums; }

/* ============================================================
   STATE LAYER - ?state=loading | empty | error
   Applied to <html> by assets/shell.js. No demo controls ship
   inside the product; app/states.html is the gallery.
   ============================================================ */
@keyframes sk-sweep { from { background-position: 100% 0; } to { background-position: -100% 0; } }

/* Loading needs no per-page markup: panels keep their real height while
   their children go invisible, so the skeleton matches the true layout. */
[data-state="loading"] .work-body,
[data-state="loading"] main .container { pointer-events: none; }
[data-state="loading"] .panel,
[data-state="loading"] .kpi,
[data-state="loading"] .comp,
[data-state="loading"] .card,
[data-state="loading"] .help-card {
  background-image: linear-gradient(90deg, var(--raised) 0%, var(--surface) 45%, var(--raised) 90%);
  background-size: 220% 100%;
  animation: sk-sweep 1.3s linear infinite;
}
[data-state="loading"] .panel > *,
[data-state="loading"] .kpi > *,
[data-state="loading"] .comp > *,
[data-state="loading"] .card > *,
[data-state="loading"] .help-card > * { visibility: hidden; }
[data-state="loading"] .page-head { opacity: .45; }

.state-block .empty .ic-wrap { margin: 0 auto 15px; }
/* --tint-neg is 8% and reads as grey on a lone tile - an error mark needs to land */
.state-block.error .tile-ic { background: color-mix(in oklab, var(--neg) 15%, var(--surface)); color: var(--neg); }
.state-block .acts { display: flex; gap: 10px; justify-content: center; margin-top: 20px; }
.state-note {
  margin-top: 14px; font-size: 12.5px; color: var(--faint);
  font-family: var(--font-body);
}


/* ============================================================
   IDEA CARD - a split card, not a plain rectangle.
   Two splits do the work: a tinted score pane down the left,
   and a footer strip divided off the body. Soft 18px corners,
   no border, low wide shadow, cards spaced apart.
   ============================================================ */
.ledger-group + .ledger-group { margin-top: 36px; }
.ledger-group { display: grid; gap: 14px; }
.ledger-head { display: flex; align-items: baseline; gap: 10px; padding: 0 4px 2px; }
.ledger-head h3 {
  font-family: var(--font-body); font-size: 12px; font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted);
}
.ledger-head .n { font-size: 12px; color: var(--faint); font-variant-numeric: tabular-nums; }
.ledger-head .note { margin-left: auto; font-size: 12.5px; color: var(--faint); }

.idea-card {
  display: grid;
  grid-template-columns: 132px 1fr;
  grid-template-areas: "pane body" "pane foot";
  background: var(--surface);
  border-radius: 18px;
  box-shadow: var(--shadow-soft);
  overflow: hidden;
  text-decoration: none; color: inherit;
  transition: box-shadow .2s ease, transform .2s ease;
}
a.idea-card:hover { box-shadow: var(--shadow-lift); transform: translateY(-2px); }

/* left split - the score, on its verdict's own tint */
.idea-card .pane {
  grid-area: pane; display: grid; align-content: center; justify-items: center;
  padding: 24px 14px; text-align: center;
}
.idea-card .pane .sc {
  font-family: var(--font-display); font-size: 36px; font-weight: 700;
  letter-spacing: -0.045em; font-variant-numeric: tabular-nums; line-height: 1;
}
.idea-card .pane .sub {
  margin-top: 8px; font-size: 10.5px; font-weight: 600;
  letter-spacing: 0.09em; text-transform: uppercase; opacity: .72;
}
.idea-card .pane.pos     { background: color-mix(in oklab, var(--pos) 12%, var(--surface));     color: var(--pos); }
.idea-card .pane.caution { background: color-mix(in oklab, var(--caution) 14%, var(--surface)); color: var(--caution); }
.idea-card .pane.neg     { background: color-mix(in oklab, var(--neg) 12%, var(--surface));     color: var(--neg); }
.idea-card .pane.accent  { background: var(--tint-accent);                                      color: var(--accent-ink); }
.idea-card .pane.plain   { background: var(--raised);                                           color: var(--faint); }

/* right split - body above, divided footer strip below */
.idea-card .body { grid-area: body; padding: 20px 26px 16px; }
.idea-card .body h4 { font-size: 17px; letter-spacing: -0.02em; }
.idea-card .body .desc { font-size: 13.5px; color: var(--muted); line-height: 1.45; margin-top: 5px; max-width: 78ch; }
.idea-card .body .ask {
  display: flex; gap: 8px; margin-top: 7px; max-width: 76ch;
  font-size: 13.5px; line-height: 1.45; color: var(--muted);
}
.idea-card .body .ask svg { flex: none; margin-top: 2px; color: var(--faint); }

.idea-card .foot {
  grid-area: foot; display: flex; align-items: center; gap: 20px;
  padding: 12px 26px; border-top: 1px solid var(--border);
  background: color-mix(in oklab, var(--bg) 60%, var(--surface));
  font-size: 12.5px; color: var(--faint); font-variant-numeric: tabular-nums;
}
.idea-card .foot .act { color: var(--accent-text); font-weight: 600; }
.idea-card .foot .go { margin-left: auto; color: var(--border-2); transition: transform .2s, color .2s; }
a.idea-card:hover .foot .go { color: var(--accent-text); transform: translateX(3px); }

@media (max-width: 1080px) {
  .idea-card { grid-template-columns: 1fr; grid-template-areas: "pane" "body" "foot"; }
  .idea-card .pane {
    flex-direction: row; display: flex; align-items: baseline; gap: 10px;
    justify-content: flex-start; padding: 14px 20px;
  }
  .idea-card .pane .sc { font-size: 26px; }
  .idea-card .pane .sub { margin-top: 0; }
  .idea-card .foot { flex-wrap: wrap; gap: 8px 16px; }
}

/* ---------- stat line - the KPI row without the boxes ----------
   Same figures the Reports page carried in four cards, set on a pair of
   rules instead so the merged Ideas page doesn't reintroduce containers. */
.statline {
  display: flex; flex-wrap: wrap;
  background: var(--surface);
  border-radius: var(--r-soft);
  box-shadow: var(--shadow-soft);
  overflow: hidden;
}
.statline > div { flex: 1 1 0; padding: 19px 24px; border-left: 1px solid var(--border); min-width: 150px; }
.statline > div:first-child { border-left: 0; }
.statline .v {
  font-family: var(--font-display); font-size: 26px; font-weight: 700;
  letter-spacing: -0.035em; font-variant-numeric: tabular-nums; line-height: 1;
}
.statline .k { font-size: 12.5px; color: var(--muted); margin-top: 8px; }



/* the Ideas page runs on the soft surface, so its empty state matches */
[data-od-id="page-ideas"] .panel {
  border: 0; border-radius: var(--r-soft); box-shadow: var(--shadow-soft);
}


/* ============================================================
   SOFT SURFACE PASS - the Ideas card language, applied app-wide.
   Every container drops its 1px border for an 16px radius and a
   low wide shadow; head/foot strips become the internal splits.
   ============================================================ */
.panel, .kpi, .comp, .card, .help-card {
  border: 0;
  border-radius: var(--r-soft);
  box-shadow: var(--shadow-soft);
}
.card.lift { box-shadow: var(--shadow-soft); }
.panel-foot {
  background: color-mix(in oklab, var(--bg) 60%, var(--surface));
  border-radius: 0 0 var(--r-soft) var(--r-soft);
}
.help-card:hover, .comp:hover { box-shadow: var(--shadow-lift); }
/* borderless means danger/selected states need a ring instead */
.panel.danger { box-shadow: var(--shadow-soft), inset 0 0 0 1.5px color-mix(in oklab, var(--neg) 34%, var(--border)); }
.compare-col { border: 0; border-radius: var(--r-soft); box-shadow: var(--shadow-soft); }
.compare-col.is-us { box-shadow: var(--shadow-lift), inset 0 0 0 1.5px var(--accent-text); }
/* shadows don't read on the ink band - those cards keep a flat edge */
.band-dark .card { box-shadow: none; }
.demo { border: 0; border-radius: var(--r-soft); box-shadow: var(--shadow-soft); }

/* ============================================================
   BLUEPRINT - the roadmap as a node graph.
   Nodes are the same split card (tinted header, body, footer
   strip) laid on a dotted canvas and joined by bezier wires,
   with pins where the wires meet the node.
   ============================================================ */
.blueprint {
  position: relative; overflow-x: auto; padding: 10px;
  border-radius: var(--r-soft);
  box-shadow: var(--shadow-soft);
  background:
    radial-gradient(circle, var(--border) 1.1px, transparent 1.1px) 0 0 / 24px 24px,
    var(--surface);
}
.bp-canvas { position: relative; width: 2060px; height: 560px; }
.bp-wires { position: absolute; inset: 0; overflow: visible; }
.bp-wires path { fill: none; stroke: var(--border-2); stroke-width: 2.2; stroke-linecap: round; }
.bp-wires path.yes { stroke: var(--pos); }
.bp-wires path.no  { stroke: var(--border-2); stroke-dasharray: 5 7; }
.bp-wires text { font-family: var(--font-body); font-size: 11px; font-weight: 600; letter-spacing: .06em; }
.bp-wires text.yes { fill: var(--pos); }
.bp-wires text.no  { fill: var(--faint); }

.node {
  position: absolute; background: var(--surface);
  border-radius: 14px; box-shadow: var(--shadow-soft); overflow: hidden;
}
.node .nh {
  display: flex; align-items: center; gap: 8px; padding: 10px 14px;
  font-size: 10.5px; font-weight: 600; letter-spacing: .085em; text-transform: uppercase;
}
.node .nh .wk { margin-left: auto; opacity: .7; letter-spacing: .04em; }
.node .nh.pos     { background: color-mix(in oklab, var(--pos) 14%, var(--surface));     color: var(--pos); }
.node .nh.accent  { background: var(--tint-accent);                                      color: var(--accent-ink); }
.node .nh.info    { background: color-mix(in oklab, var(--info) 13%, var(--surface));    color: var(--info); }
.node .nh.caution { background: color-mix(in oklab, var(--caution) 15%, var(--surface)); color: var(--caution); }
.node .nh.plain   { background: var(--raised);                                           color: var(--muted); }
.node .nb { padding: 14px 15px 15px; }
.node .nb h4 { font-size: 15px; letter-spacing: -0.015em; }
.node .nb ul { list-style: none; display: grid; gap: 8px; margin-top: 11px; }
.node .nb li { display: flex; gap: 9px; font-size: 12.5px; color: var(--muted); line-height: 1.4; }
.node .nb li i { width: 6px; height: 6px; border-radius: 50%; background: var(--border-2); margin-top: 6px; flex: none; }
.node .nb li.done i { background: var(--pos); }
.node .nb li.done   { color: var(--faint); text-decoration: line-through; }
.node .nf {
  display: flex; gap: 14px; padding: 9px 15px;
  border-top: 1px solid var(--border);
  background: color-mix(in oklab, var(--bg) 60%, var(--surface));
  font-size: 11.5px; color: var(--faint); font-variant-numeric: tabular-nums;
}
.node .pin {
  position: absolute; top: 50%; margin-top: -5px;
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--surface); box-shadow: 0 0 0 2.2px var(--border-2);
}
.node .pin.in  { left: -5px; }
.node .pin.out { right: -5px; }
.node .pin.on  { box-shadow: 0 0 0 2.2px var(--pos); background: var(--pos); }

.bp-chip {
  position: absolute; display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 16px; border-radius: 999px;
  background: var(--ink); color: var(--on-dark);
  font-size: 11.5px; font-weight: 600; letter-spacing: .09em; text-transform: uppercase;
  box-shadow: var(--shadow-soft);
}
.bp-chip.ship { background: var(--pos); color: var(--surface); }
.bp-chip.dead { background: var(--raised); color: var(--faint); box-shadow: none; }

/* the gate - a decision node, squarer and centred */
.node.gate .nb { text-align: center; padding: 16px 15px; }
.node.gate .nb p { font-size: 13px; color: var(--fg); line-height: 1.4; }

/* ============================================================
   Marketing pages beyond the landing
   ------------------------------------------------------------
   /pricing, /how-it-works, /sample-report and /faq are their own
   URLs because each answers a different search intent, and a
   section behind an #anchor can't rank on its own. The landing
   page keeps a teaser for each one that links through - never a
   second full copy, or the two URLs compete for the same query.
   ============================================================ */
.page-hero { padding: 54px 0 42px; border-bottom: 1px solid var(--border); }
.page-hero h1 { font-size: clamp(38px, 4.4vw, 56px); margin-top: 14px; }
.page-hero .lede { margin-top: 18px; font-size: 19px; color: var(--muted); max-width: 60ch; }
.page-hero .actions { display: flex; gap: 12px; margin-top: 30px; flex-wrap: wrap; }

.crumb { display: flex; align-items: center; gap: 9px; font-size: 13px; color: var(--faint); }
.crumb a { color: var(--muted); text-decoration: none; }
.crumb a:hover { color: var(--fg); }

.prose { max-width: 68ch; }
.prose h2 { font-size: 30px; margin: 54px 0 16px; }
.prose h3 { margin: 30px 0 10px; }
.prose p { font-size: 16.5px; color: var(--muted); margin-bottom: 14px; line-height: 1.65; }
.prose p strong { color: var(--fg); font-weight: 600; }
.prose p.t-sm { font-size: 13.5px; }
.prose ul { list-style: none; margin-bottom: 18px; }
.prose li { position: relative; padding-left: 20px; font-size: 16.5px; color: var(--muted);
  margin-bottom: 9px; line-height: 1.6; }
.prose li::before { content: ''; position: absolute; left: 0; top: 12px; width: 8px; height: 2px;
  border-radius: 1px; background: var(--accent-text); }

/* the five scoring axes, explained - reads as a table, built as rows */
.axis-list { display: grid; gap: 1px; background: var(--border); border-radius: var(--r-soft);
  overflow: hidden; box-shadow: var(--shadow-soft); }
/* these rows keep a light surface even inside .band-dark, so they have to
   reassert the text colour or they inherit the band's and vanish */
.axis-row { display: grid; grid-template-columns: 190px 1fr 58px; gap: 22px; align-items: baseline;
  background: var(--surface); color: var(--fg); padding: 20px 24px; }
.axis-row h4 { color: var(--fg); }
.axis-row .fig { color: var(--fg); }
.axis-row h4 { font-size: 16px; }
.axis-row p { font-size: 14.5px; color: var(--muted); line-height: 1.55; }
.axis-row .fig { text-align: right; font-size: 20px; }

.plans { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.plan { background: var(--surface); border-radius: var(--r-soft); box-shadow: var(--shadow-soft);
  padding: 28px; display: flex; flex-direction: column; }
.plan.is-pro { box-shadow: var(--shadow-lift), inset 0 0 0 1.5px var(--accent-text); }
.plan-price { font-family: var(--font-display); font-weight: 700; font-size: 40px;
  letter-spacing: -0.035em; margin: 14px 0 6px; }
.plan-price small { font-size: 15px; font-weight: 500; color: var(--muted); letter-spacing: 0; }

/* a landing section that now lives on its own page keeps a teaser here */
.teaser { display: grid; grid-template-columns: 1fr 400px; gap: 56px; align-items: center; }
.teaser-copy h2 { font-size: clamp(27px, 3vw, 38px); }
.teaser-copy > p { margin-top: 16px; font-size: 17px; color: var(--muted); max-width: 52ch; }
.teaser-more { display: inline-flex; align-items: center; gap: 8px; margin-top: 24px;
  font-weight: 600; color: var(--accent-text); text-decoration: none; font-size: 16px;
  transition: gap .2s ease; }
.teaser-more:hover { gap: 13px; }
.teaser.flip { grid-template-columns: 400px 1fr; }
.teaser.flip .teaser-copy { order: 2; }
.teaser.flip .teaser-proof { order: 1; }
.teaser-proof { background: var(--surface); border-radius: var(--r-soft);
  box-shadow: var(--shadow-soft); padding: 26px; }
.band-dark .teaser-copy > p { color: var(--on-ink-dim); }
.band-dark .teaser-more { color: var(--accent); }
.band-dark .teaser-proof { background: var(--overlay-05); box-shadow: none; }

@media (max-width: 900px) {
  .teaser, .teaser.flip { grid-template-columns: 1fr; gap: 30px; }
  .teaser.flip .teaser-copy, .teaser.flip .teaser-proof { order: 0; }
  .plans { grid-template-columns: 1fr; }
  .axis-row { grid-template-columns: 1fr auto; }
  .axis-row p { grid-column: 1 / -1; }
}

/* ============================================================
   Pricing tiers
   ------------------------------------------------------------
   Built from the dashboard's own parts: a .panel shell with a
   tinted head strip, .kv rows for the spec table, and a foot
   strip. Every row states a real number - there is no
   "unlimited" tier, so the table never claims one.
   ============================================================ */
.seg-group { display: flex; gap: 10px; flex-wrap: wrap; }
.seg { display: inline-flex; gap: 4px; padding: 4px; border-radius: 999px;
  background: var(--raised); }
.seg button {
  min-height: 36px; padding: 0 18px; border: 0; border-radius: 999px;
  background: none; color: var(--muted); cursor: pointer;
  font: 500 14px/1 var(--font-body); letter-spacing: 0.01em;
  display: inline-flex; align-items: center; gap: 6px;
  transition: background .15s ease, color .15s ease;
}
.seg button:hover { background: var(--btn-hover); color: var(--fg); }
.seg button[aria-pressed="true"] { background: var(--ink); color: var(--on-dark); }
.seg button[aria-pressed="true"]:hover { background: var(--ink-hover); color: var(--on-dark); }
.seg button:focus-visible { outline: 2px solid var(--accent-text); outline-offset: 2px; }
.seg .off { font-size: 12px; color: var(--pos); font-weight: 600; }
.seg button[aria-pressed="true"] .off { color: var(--accent); }

.plan-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; align-items: start; }

.plan-card { display: flex; flex-direction: column; border-radius: var(--r-soft);
  background: var(--surface); box-shadow: var(--shadow-soft); overflow: hidden; }
.plan-card.is-rec:not(.is-dark) { box-shadow: var(--shadow-lift), inset 0 0 0 1.5px var(--accent-text); }
.plan-card.is-dark.is-rec { box-shadow: var(--shadow-lift), inset 0 0 0 1.5px var(--accent); }
.plan-card.is-dark { background: var(--ink); color: var(--on-ink); }

.plan-head { display: flex; align-items: center; gap: 11px; padding: 16px 24px;
  background: var(--raised); }
.plan-head h3 { font-size: 18px; }
.plan-card.is-rec:not(.is-dark) .plan-head { background: var(--tint-accent); color: var(--accent-ink); }
.plan-card.is-dark .plan-head { background: var(--overlay-05); color: var(--on-ink-strong); }
.plan-card.is-rec:not(.is-dark) .plan-head .pill { background: var(--accent-ink); color: var(--accent); }
.plan-card.is-dark .plan-head .pill { background: var(--accent); color: var(--accent-ink); }

/* signal-bar tier glyph: one lit bar per tier */
.plan-mark { display: flex; align-items: flex-end; gap: 3px; height: 16px; flex: none; }
.plan-mark i { width: 5px; border-radius: 1.5px; background: var(--border-2); display: block; }
.plan-mark i:nth-child(1) { height: 7px; }
.plan-mark i:nth-child(2) { height: 11px; }
.plan-mark i:nth-child(3) { height: 16px; }
.plan-mark i.lit { background: var(--fg); }
.plan-card.is-rec:not(.is-dark) .plan-mark i.lit { background: var(--accent-ink); }
.plan-card.is-dark .plan-mark i     { background: var(--overlay-10); }
.plan-card.is-dark .plan-mark i.lit { background: var(--accent); }

.plan-body { padding: 26px 24px 24px; display: flex; flex-direction: column; flex: 1; }
.pricebox { font-family: var(--font-display); font-weight: 700; font-size: 46px;
  letter-spacing: -0.045em; line-height: 1; display: flex; align-items: baseline;
  gap: 8px; flex-wrap: wrap; }
.pricebox .per { font-family: var(--font-body); font-size: 15px; font-weight: 500;
  letter-spacing: 0; color: var(--muted); }
.plan-card.is-dark .pricebox .per { color: var(--on-ink-dim); }
.tagline { font-size: 14.5px; color: var(--muted); margin-top: 12px; }
.plan-card.is-dark .tagline { color: var(--on-ink-dim); }

.plan-card .kv { margin-top: 22px; }
.plan-card .kv .k { min-width: 0; }
.plan-card .kv > div { gap: 12px; align-items: baseline; }
.plan-card.is-dark .kv > div { border-bottom-color: var(--overlay-08); }
.plan-card.is-dark .kv .k { color: var(--on-ink-dim); }
.plan-card.is-dark .kv .v { color: var(--on-ink-strong); }
.kv .v.off { color: var(--faint); font-weight: 400; }
.plan-card.is-dark .kv .v.off { color: var(--on-ink-faint); }

.plan-card .btn { margin-top: 24px; }
.plan-card.is-dark .btn { background: var(--on-ink-strong); color: var(--ink); }
.plan-card.is-dark .btn:hover { background: var(--on-dark); }

.plan-foot { padding: 14px 24px; font-size: 13px; color: var(--muted);
  border-top: 1px solid var(--border); background: color-mix(in oklab, var(--bg) 60%, var(--surface)); }
.plan-card.is-dark .plan-foot { border-top-color: var(--overlay-08);
  background: var(--overlay-05); color: var(--on-ink-faint); }

/* the pricing explainers - three panels instead of one narrow prose column
   stranded against the left edge of a 1180px container */
.note-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.note-grid .panel { display: flex; flex-direction: column; }
.note-grid .panel-body { flex: 1; }
.note-grid .panel-body p { font-size: 14.5px; color: var(--muted); line-height: 1.6; }
.note-grid .panel-body p + p { margin-top: 12px; }

@media (max-width: 1000px) {
  .plan-grid, .note-grid { grid-template-columns: 1fr; }
}

/* ============================================================
   Pricing visuals - volume picker, comparison figures, time strip
   ------------------------------------------------------------
   Bars reuse the shared .chart contract (--v / --max), so every
   length is computed from the real number and the label states it.
   Motion is a reveal on scroll plus a count-up on the billing
   toggle; both collapse to their end state under reduced motion.
   ============================================================ */
.mb-4 { margin-bottom: 16px; }
.mb-5 { margin-bottom: 22px; }

.picker { background: var(--surface); border-radius: var(--r-soft);
  box-shadow: var(--shadow-soft); padding: 24px 26px; }
.picker-head { display: flex; align-items: baseline; gap: 16px; flex-wrap: wrap; }
.picker-head label { font-family: var(--font-display); font-weight: 600; font-size: 18px;
  letter-spacing: -0.02em; }
.picker-out { margin-left: auto; font-family: var(--font-display); font-weight: 700;
  font-size: 26px; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; }
.picker-out small { font-size: 14px; font-weight: 500; color: var(--muted); letter-spacing: 0; }

input[type="range"].vol {
  -webkit-appearance: none; appearance: none; width: 100%; margin: 20px 0 6px;
  height: 8px; border-radius: 4px; background: var(--track-strong); cursor: pointer;
}
input[type="range"].vol::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none; width: 26px; height: 26px; border-radius: 50%;
  background: var(--accent); border: 3px solid var(--surface);
  box-shadow: var(--shadow-lift); cursor: grab;
}
input[type="range"].vol::-moz-range-thumb {
  width: 26px; height: 26px; border-radius: 50%; background: var(--accent);
  border: 3px solid var(--surface); box-shadow: var(--shadow-lift); cursor: grab;
}
input[type="range"].vol:active::-webkit-slider-thumb { cursor: grabbing; }
input[type="range"].vol:focus-visible { outline: 2px solid var(--accent-text); outline-offset: 4px; }
.picker-ticks { display: flex; justify-content: space-between; font-size: 12px;
  color: var(--faint); font-variant-numeric: tabular-nums; }
.picker-say { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--border);
  font-size: 15px; color: var(--muted); }
.picker-say strong { color: var(--fg); font-weight: 600; }
.picker-say .c-accent { color: var(--accent-text); font-weight: 600; }

/* two computed charts side by side - volume against unit cost */
.figure-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.figure { background: var(--surface); border-radius: var(--r-soft);
  box-shadow: var(--shadow-soft); padding: 24px 26px; }
.figure h3 { font-size: 15px; font-weight: 600; letter-spacing: 0.02em;
  font-family: var(--font-body); margin-bottom: 4px; }
.figure .cap { font-size: 13px; color: var(--faint); margin-bottom: 20px; display: block; }
.figure .chart { --max: 100; }
.figure .bar-row { grid-template-columns: 78px 1fr 62px; }
.figure .bar { transition: width .9s cubic-bezier(.32,.72,0,1); }
.figure .bar.q { background: var(--border-2); }
/* the volume chart spans 1 to 400, so Free's single review is a quarter of a
   percent - a floor keeps it visible; the label still carries the real value */
#fig-volume .bar { min-width: 4px; }

/* time cost: 21 day-blocks against one tick */
.timestrip { display: grid; gap: 14px; }
.ts-row { display: grid; grid-template-columns: 132px 1fr auto; align-items: center; gap: 16px; }
.ts-label { font-size: 14px; color: var(--muted); }
.ts-track { display: flex; gap: 3px; align-items: center; height: 34px; }
.ts-track i { display: block; width: 12px; height: 26px; border-radius: 3px;
  background: var(--border-2); flex: none;
  transform: scaleY(.25); transform-origin: bottom; transition: transform .5s cubic-bezier(.32,.72,0,1); }
.ts-row.is-us .ts-track i { width: 20px; height: 34px; background: var(--accent); }
.ts-track i { transform: scaleY(1); }
.js-motion .ts-track i { transform: scaleY(.25); }
.js-motion .reveal.in .ts-track i { transform: scaleY(1); }
.ts-value { font-family: var(--font-display); font-weight: 700; font-size: 17px;
  letter-spacing: -0.02em; white-space: nowrap; }
.ts-row.is-us .ts-value { color: var(--accent-text); }

/* Reveal is opt-IN, not opt-out. These blocks were previously opacity:0 in the
   base stylesheet and only became visible once IntersectionObserver fired - so
   a capture taken before it fired, a target taller than the scroll viewport, or
   any earlier throw in the script left the page's three visual blocks invisible
   for good. The hidden start state now applies only after JS has confirmed it
   is running AND a watchdog is armed to force them visible regardless. */
.reveal { opacity: 1; }
.js-motion .reveal { opacity: 0; transform: translateY(10px);
  transition: opacity .5s ease, transform .5s cubic-bezier(.32,.72,0,1); }
.js-motion .reveal.in { opacity: 1; transform: none; }

@media (max-width: 1000px) {
  .figure-2 { grid-template-columns: 1fr; }
  .ts-row { grid-template-columns: 1fr; gap: 6px; }
}
@media (prefers-reduced-motion: reduce) {
  .reveal, .reveal.in { opacity: 1; transform: none; transition: none; }
  .figure .bar, .ts-track i { transition: none; }
  .ts-track i { transform: scaleY(1); }
}


/* ============================================================
   Fact rows and the comparison matrix
   ------------------------------------------------------------
   Both exist to carry information that was previously prose.
   A fact row states a cost or a count as a mark plus a label;
   the matrix answers one question per row across two columns.
   ============================================================ */
.facts { display: grid; gap: 1px; background: var(--border); border-radius: var(--r);
  overflow: hidden; }
.fact { display: flex; align-items: center; gap: 14px; background: var(--surface);
  padding: 12px 16px; font-size: 14px; color: var(--muted); }
.fv { flex: none; min-width: 34px; height: 28px; border-radius: 8px; display: grid;
  place-items: center; font-family: var(--font-display); font-weight: 700; font-size: 14px;
  background: var(--raised); color: var(--fg); }
.fv.pos { background: var(--tint-pos); color: var(--pos); }
.fv.neg { background: var(--tint-neg); color: var(--neg); }
.fv.acc { background: var(--tint-accent); color: var(--accent-ink); }

.matrix { display: grid; gap: 1px; background: var(--border); border-radius: var(--r-soft);
  overflow: hidden; box-shadow: var(--shadow-soft); }
.mx-head, .mx-row { display: grid; grid-template-columns: 1fr 150px 150px;
  background: var(--surface); align-items: center; }
.mx-head { background: var(--raised); }
.mx-head span { padding: 13px 18px; font-size: 12px; font-weight: 600; letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--muted); text-align: center; }
.mx-head span:first-child { text-align: left; }
.mx-head .us { color: var(--accent-ink); background: var(--tint-accent); }
.mx-row > * { padding: 15px 18px; }
.mx-k { font-size: 14.5px; }
.mx-cell { display: grid; place-items: center; }
.mx-row .us { background: color-mix(in oklab, var(--accent) 7%, var(--surface)); }
.mx-mark { width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center;
  background: var(--tint-pos); color: var(--pos); }
.mx-mark.off { background: var(--raised); color: var(--faint); }
.mx-val { font-family: var(--font-display); font-weight: 700; font-size: 15px;
  letter-spacing: -0.02em; text-align: center; }
.mx-val.us { color: var(--accent-ink); }

@media (max-width: 760px) {
  .mx-head, .mx-row { grid-template-columns: 1fr 84px 84px; }
  .mx-head span, .mx-row > * { padding: 11px 10px; }
}

/* ============================================================
   Volume made visual - hero triptych and per-card allowance
   ------------------------------------------------------------
   Both encode the same fact the spec rows state in words: Free is
   one review, Founder a hundred, Studio four hundred. Widths are
   inline and real, and the entry motion is a CSS animation with
   `both` - so it always finishes in the visible state whether or
   not any script runs.
   ============================================================ */
@keyframes grow-x { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes rise   { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* the allowance a tier buys you, drawn where the eye already is */
.allow { display: block; height: 7px; border-radius: 4px; background: var(--track);
  margin: 16px 0 2px; overflow: hidden; }
.allow i { display: block; height: 100%; border-radius: 4px; min-width: 3px; width: var(--p);
  background: var(--border-2); transform-origin: left;
  animation: grow-x .9s cubic-bezier(.32,.72,0,1) .25s both; }
.plan-card.is-rec .allow i { background: var(--accent-text); }
.plan-card.is-dark .allow { background: var(--overlay-10); }
.plan-card.is-dark .allow i { background: var(--accent); }
.allow-cap { display: block; font-size: 12px; color: var(--faint); }
.plan-card.is-dark .allow-cap { color: var(--on-ink-faint); }

@media (prefers-reduced-motion: reduce) {
  .allow i { animation: none; }
}

/* ============================================================
   Three-way comparison - asking around, a chat assistant, Runles
   ------------------------------------------------------------
   "Why not just ask ChatGPT" is the real objection, so the matrix
   carries a third column rather than sitting beside a second one.
   The amber mark is a genuine third state: a chat assistant will
   often do this, but only if you know to ask.
   ============================================================ */
.matrix.three .mx-head,
.matrix.three .mx-row { grid-template-columns: 1fr 138px 138px 138px; }
.mx-head .mx-sub { display: block; font-size: 10.5px; font-weight: 500; letter-spacing: 0.03em;
  text-transform: none; color: var(--faint); margin-top: 3px; }
.mx-head .us .mx-sub { color: var(--accent-ink); opacity: .7; }
.mx-mark.part { background: var(--tint-caution); color: var(--caution); }

@media (max-width: 900px) {
  .matrix.three .mx-head,
  .matrix.three .mx-row { grid-template-columns: 1fr 62px 62px 62px; }
  .matrix.three .mx-head span, .matrix.three .mx-row > * { padding: 10px 8px; }
  .mx-head .mx-sub { display: none; }
}

/* ============================================================
   Same idea, two answers - the side-by-side output comparison
   ------------------------------------------------------------
   The matrix explains the difference; this shows it. The left
   panel is a chat window whose reply is explicitly labelled
   illustrative - we do not put words in another product's mouth,
   so it demonstrates the SHAPE of a prose answer, not a quote.
   The right panel is built from the real report components.
   ============================================================ */
.vs-two { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; align-items: start; }
.vs-pane { background: var(--surface); border-radius: var(--r-soft);
  box-shadow: var(--shadow-soft); overflow: hidden; display: flex; flex-direction: column; }
.vs-pane.is-us { box-shadow: var(--shadow-lift), inset 0 0 0 1.5px var(--accent-text); }
.vs-head { display: flex; align-items: center; gap: 10px; padding: 14px 20px;
  background: var(--raised); font-size: 14px; font-weight: 600; }
.vs-pane.is-us .vs-head { background: var(--tint-accent); color: var(--accent-ink); }
.vs-head .tag { margin-left: auto; font-size: 11px; font-weight: 600; letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--faint); }
.vs-pane.is-us .vs-head .tag { color: var(--accent-ink); opacity: .75; }
.vs-body { padding: 20px; flex: 1; }

/* the chat window */
.cm-msg { max-width: 92%; padding: 12px 15px; border-radius: 14px; font-size: 14px;
  line-height: 1.55; }
.cm-msg.you { background: var(--ink); color: var(--on-dark); border-bottom-right-radius: 5px;
  margin-left: auto; }
.cm-msg.ai { background: var(--raised); color: var(--fg); border-bottom-left-radius: 5px;
  margin-top: 12px; }
.cm-msg.ai ul { list-style: none; margin: 10px 0; }
.cm-msg.ai li { position: relative; padding-left: 15px; margin-bottom: 5px; }
.cm-msg.ai li::before { content: ''; position: absolute; left: 0; top: 9px; width: 5px;
  height: 5px; border-radius: 50%; background: var(--faint); }
.cm-msg.ai .ask { color: var(--muted); font-style: italic; margin-top: 10px; }
.cm-input { display: flex; align-items: center; gap: 10px; margin-top: 16px; padding: 11px 14px;
  border-radius: 999px; background: var(--bg); box-shadow: inset 0 0 0 1px var(--border);
  font-size: 13.5px; color: var(--faint); }
.cm-input .caret { width: 1.5px; height: 15px; background: var(--faint); flex: none;
  animation: blink 1.1s step-end infinite; }
@keyframes blink { 50% { opacity: 0; } }
.cm-note { margin-top: 14px; font-size: 12px; line-height: 1.5; color: var(--faint);
  padding-top: 12px; border-top: 1px solid var(--border); }

.vs-foot { border-top: 1px solid var(--border); }
.vs-pane.is-us .vs-foot { border-top-color: var(--border); }
.vs-foot .facts { border-radius: 0; }

@media (prefers-reduced-motion: reduce) { .cm-input .caret { animation: none; } }
@media (max-width: 900px) { .vs-two { grid-template-columns: 1fr; } }

/* ============================================================
   Closing call to action
   ------------------------------------------------------------
   The page's one full-strength colour moment, and it earns it by
   being the point of decision. Content sits left; the tier ladder
   repeats on the right so the number you're choosing between is
   in view when you click. Ink on lime is the only pairing here
   with enough contrast for body text at this size.
   ============================================================ */
.cta-card {
  display: grid; grid-template-columns: 1fr auto; gap: 56px; align-items: center;
  background: var(--accent); color: var(--accent-ink);
  border-radius: 24px; padding: 48px 52px; box-shadow: var(--shadow-lift);
}
.cta-card .eyebrow { color: var(--accent-ink); opacity: .62; }
.cta-card h2 { margin-top: 10px; font-size: clamp(30px, 3.4vw, 42px); color: var(--accent-ink); }
.cta-card > .cta-copy > p { margin-top: 14px; font-size: 17px; line-height: 1.55;
  color: var(--accent-ink); opacity: .78; max-width: 46ch; }
.cta-actions { display: flex; gap: 12px; margin-top: 30px; flex-wrap: wrap; }
.cta-card .btn.dark { background: var(--ink); color: var(--on-dark); }
.cta-card .btn.dark:hover { background: var(--ink-hover); color: var(--on-dark); }
.cta-card .btn.ghost {
  background: none; color: var(--accent-ink);
  border-color: color-mix(in oklab, var(--accent-ink) 34%, var(--accent));
}
.cta-card .btn.ghost:hover { background: color-mix(in oklab, var(--accent-ink) 12%, var(--accent));
  color: var(--accent-ink); }
.cta-card .btn:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 3px; }

/* the tier ladder, restated where the decision happens */
.cta-side { display: grid; gap: 2px; padding-left: 40px;
  border-left: 1px solid color-mix(in oklab, var(--accent-ink) 22%, var(--accent)); }
.cta-side-head { font-size: 11px; font-weight: 600; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--accent-ink); opacity: .55; margin-bottom: 4px; }
.cta-tier { display: grid; grid-template-columns: auto 1fr; align-items: baseline;
  column-gap: 16px; padding: 11px 0; }
.cta-tier + .cta-tier { border-top: 1px solid color-mix(in oklab, var(--accent-ink) 15%, var(--accent)); }
.cta-tier b { font-family: var(--font-display); font-weight: 700; font-size: 28px;
  letter-spacing: -0.04em; font-variant-numeric: tabular-nums; color: var(--accent-ink); }
.cta-tier .cost { justify-self: end; font-size: 14px; font-weight: 600;
  color: var(--accent-ink); opacity: .7; white-space: nowrap; }
.cta-tier .note { grid-column: 1 / -1; font-size: 13px; color: var(--accent-ink);
  opacity: .64; margin-top: 2px; }

@media (max-width: 900px) {
  .cta-card { grid-template-columns: 1fr; gap: 34px; padding: 36px 28px; }
  .cta-side { padding-left: 0; padding-top: 26px; border-left: 0;
    border-top: 1px solid color-mix(in oklab, var(--accent-ink) 22%, var(--accent)); }
}

/* the billing toggle sits centred between the hero rule and the cards */
.seg-center { display: flex; justify-content: center; margin-bottom: 30px; }

/* two stacked sections put 88px + 64px of padding between them, which reads as
   a hole rather than a break - this closes the seam where the content already
   ends with a quiet line */
.section.flush-b { padding-bottom: 0; }
/* a section carrying straight on from the hero it belongs to */
.section.after-hero { padding-top: 40px; }


/* ============================================================
   Dark-band corrections and the thread diagram
   ------------------------------------------------------------
   .prose is declared after .band-dark, so `.prose p` (0,1,1) and
   `.band-dark p` (0,1,1) tie on specificity and .prose wins on
   source order - which painted body copy --muted and, worse, put
   near-black --fg <strong> on the near-black band. These two rules
   put the band back in charge of its own text.
   ============================================================ */
.band-dark .prose p { color: var(--on-ink-dim); }
.band-dark .prose p strong { color: var(--on-ink-strong); }
.band-dark .prose li { color: var(--on-ink-dim); }
.band-dark .prose h2, .band-dark .prose h3 { color: var(--on-ink-strong); }

/* Three threads that share nothing, against one continuous record.
   No numbers - the argument is the topology, and inventing scores to
   dramatise it would be inventing data. */
.threads { display: grid; gap: 14px; margin-top: 30px; }
.th-row { display: grid; grid-template-columns: 150px 1fr; align-items: center; gap: 18px; }
.th-label { font-size: 13.5px; color: var(--on-ink-faint); }
.th-row.is-us .th-label { color: var(--accent); font-weight: 600; }
.th-track { display: flex; gap: 10px; }
.th-box {
  flex: 1; padding: 14px 16px; border-radius: 10px; font-style: normal;
  font-size: 13.5px; color: var(--on-ink-faint);
  border: 1px dashed var(--on-ink-faint); background: var(--overlay-05);
}
.th-box small { display: block; font-size: 11.5px; opacity: .7; margin-top: 3px; }
.th-bar {
  flex: 1; padding: 14px 18px; border-radius: 10px; font-style: normal;
  font-size: 13.5px; font-weight: 600; color: var(--accent-ink);
  background: var(--accent);
}
@media (max-width: 700px) {
  .th-row { grid-template-columns: 1fr; gap: 8px; }
  .th-track { flex-direction: column; }
}

/* ============================================================
   Landing page rhythm
   ------------------------------------------------------------
   Seven stacked sections at 88px top and bottom put 176px of
   undifferentiated space between each one, with nothing marking
   where a section ends - so the page reads as content floating in
   a void rather than as blocks. Scoped to the landing's <main>,
   because the other pages were tuned individually with flush-b
   and after-hero and should not shift underneath.
   ============================================================ */
.rhythm .section { padding: 64px 0; }
.rhythm .hero + .section,
.rhythm .section + .section { border-top: 1px solid var(--border); }
/* the dark band is its own boundary - a hairline above or below it
   would be a line drawn against a colour change that already reads */
.rhythm .band-dark,
.rhythm .band-dark + .section { border-top: 0; }
.rhythm .section.tight { padding: 72px 0 80px; }

/* ============================================================
   The Runles lane
   ------------------------------------------------------------
   The header was --tint-accent (24%) sitting on a 7% body wash,
   which read as a detached rectangle rather than one column. It
   is now a continuous lane: solid accent head, a wash with enough
   weight to hold, corners that follow the card's radius, and
   marks at full strength so the eye lands there first. Every
   other column stays quiet by comparison.
   ============================================================ */
/* align-items:center on the row means a cell only paints its own content
   height, so the lane's fill stopped short of the row's top and bottom edges.
   Stretching it fills the cell; the inner grid keeps the label centred.
   No border-radius here on purpose - .matrix already clips with overflow
   hidden, and a radius on the cell as well double-rounds the corner and
   leaves a pale crescent against the clip. */
.matrix.three .mx-head .us,
.matrix.three .mx-row .us { align-self: stretch; }
.matrix.three .mx-head .us {
  background: var(--accent); color: var(--accent-ink);
  display: grid; place-items: center;
}
.matrix.three .mx-head .us .mx-sub { color: var(--accent-ink); opacity: .72; }
.matrix.three .mx-row .us { background: color-mix(in oklab, var(--accent) 17%, var(--surface)); }
.matrix.three .mx-row .us .mx-mark { background: var(--accent); color: var(--accent-ink); }
/* the one honest "no" in the lane stays quiet - a filled accent cross would
   read as a positive at a glance */
.matrix.three .mx-row .us .mx-mark.off { background: var(--surface); color: var(--faint); }
.matrix.three .mx-head span,
.matrix.three .mx-row > * { padding: 17px 20px; }

/* the closing card can run without its side column */
.cta-card.solo { grid-template-columns: 1fr; }

/* ============================================================
   Stepper
   ------------------------------------------------------------
   Replaces three stacked rows that shared only a top border. A
   rail connects the nodes so the sequence is structural rather
   than implied, and each node states what actually happens at
   that step. Motion is CSS with `both` fill, so it always ends
   in the visible state whether or not any script runs.
   ============================================================ */
@keyframes grow-y { from { transform: scaleY(0); } to { transform: scaleY(1); } }
@keyframes pop    { from { opacity: 0; transform: scale(.7); } to { opacity: 1; transform: none; } }

.stepper { position: relative; display: grid; gap: 24px; list-style: none; margin: 0; }
.stepper::before {
  content: ''; position: absolute; left: 19px; top: 22px; bottom: 22px; width: 2px;
  background: var(--border-2); transform-origin: top;
  animation: grow-y .8s cubic-bezier(.32,.72,0,1) .1s both;
}
.sn { display: grid; grid-template-columns: 40px 1fr; gap: 16px; align-items: start; }
.sn-dot {
  width: 40px; height: 40px; border-radius: 50%; flex: none;
  background: var(--ink); color: var(--on-dark);
  display: grid; place-items: center; position: relative; z-index: 1;
  box-shadow: 0 0 0 4px var(--surface);
  animation: pop .5s cubic-bezier(.32,.72,0,1) both;
}
.sn:nth-child(1) .sn-dot { animation-delay: .30s; }
.sn:nth-child(2) .sn-dot { animation-delay: .48s; }
.sn:nth-child(3) .sn-dot { animation-delay: .66s; }
.sn-body { animation: rise .5s cubic-bezier(.32,.72,0,1) both; }
.sn:nth-child(1) .sn-body { animation-delay: .36s; }
.sn:nth-child(2) .sn-body { animation-delay: .54s; }
.sn:nth-child(3) .sn-body { animation-delay: .72s; }
.sn-n { display: block; font-family: var(--font-body); font-size: 11px; font-weight: 600;
  letter-spacing: 0.09em; text-transform: uppercase; color: var(--accent-text); }
.sn-body h3 { font-size: 17px; margin-top: 4px; }
.sn-body p { font-size: 14px; color: var(--muted); margin-top: 5px; line-height: 1.5; }

@media (prefers-reduced-motion: reduce) {
  .stepper::before, .sn-dot, .sn-body { animation: none; }
}

/* The lane's roomier padding is declared after the narrow-screen rule that
   compacts these cells, so it was winning at every width. Restated here to
   put the mobile compaction back in charge below 900px. */
@media (max-width: 900px) {
  .matrix.three .mx-head span,
  .matrix.three .mx-row > * { padding: 11px 9px; }
}

/* ---- step illustrations -------------------------------------------------
   Ink line drawings, one per step. They carry their own colour because an
   <img>-referenced SVG renders outside this stylesheet's cascade - see the
   comment in each file. Deliberately monochrome: the matrix directly below
   this section is a full-strength accent lane, and a second colour moment
   here would fight it. Lime stays the only colour on the page. */
.sn { grid-template-columns: 40px 1fr auto; }
.sn-ill {
  width: 120px; height: 120px; flex: none;
  align-self: center; justify-self: end;
  /* the drawings are pure line work - nothing to select or drag */
  user-select: none; -webkit-user-drag: none;
  animation: rise .5s cubic-bezier(.32,.72,0,1) both;
}
.sn:nth-child(1) .sn-ill { animation-delay: .40s; }
.sn:nth-child(2) .sn-ill { animation-delay: .58s; }
.sn:nth-child(3) .sn-ill { animation-delay: .76s; }

@media (prefers-reduced-motion: reduce) {
  .sn-ill { animation: none; }
}

/* Below 900px the row is too tight to hold text and a 120px drawing side by
   side; below 620px it stops fitting at all, so the step reverts to the
   two-column layout it had before. Declared after the sizing rule above so
   it actually wins - an override placed before it would not. */
@media (max-width: 900px) {
  .sn-ill { width: 88px; height: 88px; }
}
@media (max-width: 620px) {
  .sn { grid-template-columns: 40px 1fr; }
  .sn-ill { display: none; }
}


/* 01 - the input, set at display size because it is the subject of everything
   below it, not a caption on the hero. */
.idea-text {
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(19px, 2.2vw, 25px); letter-spacing: -0.02em; line-height: 1.32;
  color: var(--fg); max-width: 44ch;
}


/* 05 - the plan, as connected shapes. Boxes are --raised so they read as
   nested inside the white card rather than as a second flat surface. */
/* the gate is the point of the step: --neg, and pushed to the card foot so
   all four sit on one line however long the titles run */




/* the destination is the one solid dot, same logic as the flag in ill-plan.svg */

/* The connector is drawn per row rather than as one absolute line down the
   list, so it stops at the last dot instead of running past it. */


.tl-foot { margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--border);
  font-size: 13.5px; line-height: 1.5; color: var(--muted); }
.tl-foot b { font-family: var(--font-display); font-weight: 700; font-size: 16px;
  letter-spacing: -0.02em; color: var(--fg); margin-right: 6px; }


/* ---- report step rail ---------------------------------------------------
   The report's five sections are one sequence, so they hang off a single rail
   instead of sitting as five separately-numbered cards. The number lives on
   the rail node, not inside the card head: a number inside a card reads as
   part of that card's title, a number on a rail reads as position in a list.

   This sits on .band-dark, so the node is a light disc and the connector uses
   the on-ink scale rather than --border. */
.rsteps { list-style: none; margin: 0; padding: 0; }

@media (max-width: 620px) {
  .rstep { grid-template-columns: 26px 1fr; gap: 0 12px; }
}

/* Scroll-spy state. The default node above is fully legible on its own - this
   only ever adds emphasis, so a page with no JS loses nothing but the
   indicator. --accent is safe here despite the two-per-screen cap: only one
   node is lit at a time, and the hero button and closing card are both off
   screen by the time the reader is inside the report. */

/* Step heads carry the report's structure, so they are sized as headings, not
   as card labels. Scoped through .fig-ic so the h4s inside the plan timeline
   keep their smaller size. */
.rstep .fig-ic h4 { font-size: 20px; letter-spacing: -0.022em; line-height: 1.3; }

/* The report's sign-off, inside the last step so the invitation is the end of
   the report rather than a banner bolted underneath it. */
.step-cta {
  margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--border);
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
}
.step-cta p { margin: 0; font-size: 15px; font-weight: 500; color: var(--fg); }
.step-cta .btn { margin-left: auto; }

@media (max-width: 620px) {
  .rstep .fig-ic h4 { font-size: 17.5px; }
  .step-cta .btn { margin-left: 0; }
}

/* ---- sample-report hero -------------------------------------------------
   Two columns: the pitch on the left, a preview of the verdict on the right.
   The preview is not a second source of truth - every number in it is the one
   the report below carries, and its footer link goes there for the reasoning. */
.page-hero.two-col { padding: 46px 0 54px; }
.hero-grid { display: grid; grid-template-columns: minmax(0, 1.04fr) minmax(0, .96fr);
  gap: 54px; align-items: start; }
/* the base h1 clamp is sized for a full-width column and overruns a half one */
.page-hero.two-col h1 { font-size: clamp(33px, 3.6vw, 46px); }

.idea-chip {
  margin-top: 26px; padding: 17px 20px 19px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r); box-shadow: var(--shadow-soft);
}
.idea-chip .fig-ic { margin-bottom: 11px; }
.idea-chip p {
  margin: 0; font-family: var(--font-display); font-weight: 600;
  font-size: 19px; letter-spacing: -0.02em; line-height: 1.35; color: var(--fg);
}
.hero-note { margin-top: 16px; font-size: 13px; color: var(--muted); }

.verdict-peek {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-soft); padding: 24px 26px 20px; box-shadow: var(--shadow-soft);
}
.vp-h { display: block; font-family: var(--font-display); font-weight: 600;
  font-size: 16px; letter-spacing: -0.02em; color: var(--fg); }

.vp-top { display: flex; align-items: center; gap: 22px; margin-top: 18px; }
.vp-top h3 { font-size: 16px; letter-spacing: -0.02em; }
.vp-top p { margin-top: 7px; font-size: 14px; line-height: 1.5; color: var(--muted); }
/* .gauge ships at 152px for the full-width app report; scoped down here so the
   ring and the copy beside it both fit the narrower card */
.verdict-peek .gauge { width: 116px; height: 116px; }
.verdict-peek .gauge .in { width: 92px; height: 92px; }
.verdict-peek .gauge .n { font-size: 34px; }

.vp-legend { display: grid; grid-template-columns: 1fr 1fr; gap: 0 18px;
  margin-top: 20px; padding-top: 18px; border-top: 1px solid var(--border); }
.vp-legend > div + div { padding-left: 18px; border-left: 1px solid var(--border); }
.vp-k { display: block; font-size: 12px; color: var(--muted); }
.vp-v { display: flex; align-items: center; gap: 8px; margin-top: 6px;
  font-size: 14px; font-weight: 600; color: var(--fg); }
.vp-dot { width: 9px; height: 9px; border-radius: 50%; flex: none; background: var(--muted); }
.vp-dot.neg { background: var(--neg); }
.vp-dot.caution { background: var(--caution); }

.vp-scores { margin-top: 20px; padding-top: 18px; border-top: 1px solid var(--border); }
.verdict-peek .demo-axis .lbl { font-size: 13px; }
.verdict-peek .demo-axis .meter { width: 124px; }

/* --muted, not --accent-text: the hero already spends its two accent uses on
   the lime button and the lit rail node further down */
.vp-more { display: flex; align-items: center; gap: 8px; margin-top: 18px; padding-top: 16px;
  border-top: 1px solid var(--border); font-size: 13.5px; font-weight: 600;
  color: var(--muted); text-decoration: none; }
.vp-more .ic { transform: rotate(90deg); }
.vp-more:hover { color: var(--fg); }
.vp-more:focus-visible { outline: 2px solid var(--fg); outline-offset: 3px; border-radius: 4px; }

@media (max-width: 980px) {
  .hero-grid { grid-template-columns: 1fr; gap: 34px; }
  .page-hero.two-col h1 { font-size: clamp(30px, 6vw, 40px); }
}
@media (max-width: 560px) {
  .vp-legend { grid-template-columns: 1fr; }
  .vp-legend > div + div { padding-left: 0; border-left: 0;
    margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--border); }
  .verdict-peek .demo-axis .meter { width: 84px; }
}

/* ---- report index -------------------------------------------------------
   The report's sequence moved out of an inline rail and into a sticky index
   beside the cards: the rail could only show position, the index also shows
   what each step answers, and it stays on screen while you read. */
.report-grid { display: grid; grid-template-columns: 232px minmax(0, 1fr);
  gap: 44px; align-items: start; }

.report-index { position: sticky; top: 84px; }
.report-index .eyebrow { color: var(--on-ink-faint); }
.report-index ol { list-style: none; margin: 18px 0 0; padding: 0; }
.ri-item { position: relative; display: grid; grid-template-columns: 26px 1fr;
  gap: 12px; padding-bottom: 22px; align-items: start; }
.ri-item:last-child { padding-bottom: 0; }
.ri-item:not(:last-child)::after {
  content: ''; position: absolute; left: 13px; top: 32px; bottom: 4px; width: 2px;
  transform: translateX(-50%);
  background: repeating-linear-gradient(to bottom,
    var(--on-ink-faint) 0 3px, transparent 3px 8px);
}
.ri-n { width: 26px; height: 26px; border-radius: 50%; z-index: 1;
  display: grid; place-items: center; background: transparent;
  font-family: var(--font-display); font-weight: 700; font-size: 11.5px;
  color: var(--on-ink-dim); box-shadow: inset 0 0 0 1.5px var(--on-ink-faint);
  transition: background .25s ease, color .25s ease, box-shadow .25s ease;
}
.ri-t { display: block; font-family: var(--font-display); font-weight: 600;
  font-size: 15px; letter-spacing: -0.015em; color: var(--on-ink); }
.ri-q { display: block; margin-top: 3px; font-size: 12.5px; color: var(--on-ink-faint); }

/* the one accent moment on the dark band - the card chips stay neutral so
   this is the only thing competing for the eye */
.ri-item.is-current .ri-n { background: var(--accent); color: var(--accent-ink); box-shadow: none; }
.ri-item.is-current .ri-t { color: var(--accent); }
.ri-item.is-current .ri-q { color: var(--on-ink-dim); }

.report-cards { display: grid; gap: 18px; }
/* The chip sits in a gutter to the left of its card, not inside the head -
   outside the card it reads as an index marker, inside it reads as part of
   the title. margin-top aligns it with the head's line box (24px card padding
   + half of the 20px/1.3 heading), not with the card's top edge. */
.report-cards .rstep { display: grid; grid-template-columns: 30px minmax(0, 1fr);
  gap: 14px; align-items: start; }
.rc-chip { margin-top: 22px; }
.rc-chip { width: 30px; height: 30px; border-radius: 50%; flex: none;
  display: grid; place-items: center; background: var(--raised); color: var(--fg);
  font-family: var(--font-display); font-weight: 700; font-size: 12.5px; }

/* The blueprint ships with its own white ground and lift for the app page.
   Inside a report card that reads as white-on-white, so it becomes an inset
   panel instead: canvas tone, hairline, no shadow. */
.card .blueprint {
  box-shadow: none; border: 1px solid var(--border);
  background: radial-gradient(circle, var(--border) 1.1px, transparent 1.1px) 0 0 / 24px 24px,
              var(--bg);
}
.bp-mini { width: 1760px; height: 400px; }

@media (prefers-reduced-motion: reduce) { .ri-n { transition: none; } }

@media (max-width: 980px) {
  .report-grid { grid-template-columns: 1fr; gap: 26px; }
  .report-cards .rstep { grid-template-columns: 26px minmax(0, 1fr); gap: 10px; }
  .report-index { position: static; }
  .report-index ol { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0 20px; }
  .ri-item:not(:last-child)::after { display: none; }
}

/* ---- source graph -------------------------------------------------------
   A node editor: compact node bars on a dark canvas, coloured ports, and
   bezier wires tinted by the signal each source moved. The whole interaction
   is CSS :has() - no script anywhere in this component. Every finding sits in
   the markup; one shows at a time and the fourth is the default, because that
   is the reading that reframes the idea and it should be seen unprompted. */
.ngraph {
  padding: 14px; border-radius: var(--r-soft); overflow-x: auto;
  background:
    radial-gradient(circle, oklch(97% 0.003 265 / 0.09) 1px, transparent 1px) 0 0 / 22px 22px,
    var(--ink);
}
.ng-canvas { position: relative; width: 800px; height: 400px; }
/* Fluid: the box carries the viewBox's own aspect ratio, so the SVG and the
   percentage-positioned nodes scale as one and nothing can overflow the card.
   A fixed canvas could not work - at a 1024px viewport this column is only
   564px wide, and at 1180px it is 720px. */
.ng-canvas.radial { width: 100%; max-width: 620px; aspect-ratio: 620 / 324; height: auto; }
.ng-canvas.radial .ng-wires { width: 100%; height: 100%; }
.ng-canvas.radial .ng-src { width: 27.097%; height: 10.494%; }
.ng-canvas.radial .ng-hub { width: 30.645%; height: 13.580%; }
.ng-wires { position: absolute; inset: 0; overflow: visible; }
.ng-wires path {
  fill: none; stroke-width: 1.6; stroke-linecap: round; opacity: .62;
  transition: opacity .18s ease, stroke-width .18s ease;
}
/* the semantic tokens are tuned for a light canvas, so each is lifted toward
   the on-ink scale to survive on the dark one */
.ng-wires path.pos     { stroke: color-mix(in oklab, var(--pos) 55%, var(--on-ink)); }
.ng-wires path.info    { stroke: color-mix(in oklab, var(--info) 55%, var(--on-ink)); }
.ng-wires path.caution { stroke: color-mix(in oklab, var(--caution) 60%, var(--on-ink)); }
.ng-wires path.neg     { stroke: color-mix(in oklab, var(--neg) 55%, var(--on-ink)); }

.ng-node, .ng-src {
  position: absolute; height: 34px; width: 190px;
  display: flex; align-items: center; padding: 0; text-align: left;
  background: var(--ink-hover); border: 1px solid oklch(97% 0.003 265 / 0.14);
  border-radius: 7px; box-shadow: 0 2px 10px oklch(0% 0 0 / 0.32);
  transition: background .18s ease, border-color .18s ease, opacity .18s ease;
}
.ng-idea { width: 200px; }
/* the hub is the focal object in a ring, so it sits taller and brighter */
.ng-hub { width: 200px; height: 44px; border-color: oklch(97% 0.003 265 / 0.30); }
.ng-src { cursor: pointer; font: inherit; }

.ng-ic { width: 31px; align-self: stretch; flex: none; display: grid; place-items: center;
  border-right: 1px solid oklch(97% 0.003 265 / 0.12); color: var(--on-ink-dim); }
.ng-lbl { padding: 0 11px; font-size: 12px; font-weight: 500; color: var(--on-ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ng-hub .ng-lbl { font-weight: 600; }
.ng-hub .ng-score { margin-left: auto; padding-right: 12px; font-family: var(--font-display);
  font-weight: 700; font-size: 16px; letter-spacing: -0.03em;
  color: color-mix(in oklab, var(--pos) 55%, var(--on-ink)); }
.ng-hub .ng-score i { font-style: normal; font-size: 10.5px; color: var(--on-ink-faint); }

/* Every port is centred on its own coordinate, so a percentage position lands
   exactly where the wire expects it however the canvas is scaled. */
.ng-port { position: absolute; transform: translate(-50%, -50%);
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--on-ink-faint); box-shadow: 0 0 0 2px var(--ink); }
.ng-port.in, .ng-port.t   { left: 50%; top: 0; }
.ng-port.out              { left: 50%; top: 100%; }
.ng-port.r                { left: 100%; top: 50%; }
.ng-port.l                { left: 0; top: 50%; }
.ng-port.pos     { background: color-mix(in oklab, var(--pos) 55%, var(--on-ink)); }
.ng-port.info    { background: color-mix(in oklab, var(--info) 55%, var(--on-ink)); }
.ng-port.caution { background: color-mix(in oklab, var(--caution) 60%, var(--on-ink)); }
.ng-port.neg     { background: color-mix(in oklab, var(--neg) 55%, var(--on-ink)); }

.ng-src:hover, .ng-src:focus-visible {
  background: oklch(32% 0.014 265); border-color: oklch(97% 0.003 265 / 0.42);
}
.ng-src:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* nothing hovered yet: node four and its wires carry the default emphasis */
.ng-canvas:not(:has(.ng-src:hover)):not(:has(.ng-src:focus-visible)) .ng-src[data-s="4"] {
  background: oklch(32% 0.014 265); border-color: oklch(97% 0.003 265 / 0.42);
}
.ng-canvas:not(:has(.ng-src:hover)):not(:has(.ng-src:focus-visible)) .ng-wires path.w4 {
  opacity: 1; stroke-width: 2.4;
}

/* dim everything, then relight the chosen path */
.ng-canvas:has(.ng-src:hover) .ng-wires path,
.ng-canvas:has(.ng-src:focus-visible) .ng-wires path { opacity: .12; }
.ng-canvas:has(.ng-src:hover) .ng-src:not(:hover),
.ng-canvas:has(.ng-src:focus-visible) .ng-src:not(:focus-visible) { opacity: .45; }
.ng-canvas:has(.ng-src[data-s="1"]:hover) .ng-wires path.w1,
.ng-canvas:has(.ng-src[data-s="1"]:focus-visible) .ng-wires path.w1 { opacity: 1; stroke-width: 2.4; }
.ng-canvas:has(.ng-src[data-s="2"]:hover) .ng-wires path.w2,
.ng-canvas:has(.ng-src[data-s="2"]:focus-visible) .ng-wires path.w2 { opacity: 1; stroke-width: 2.4; }
.ng-canvas:has(.ng-src[data-s="3"]:hover) .ng-wires path.w3,
.ng-canvas:has(.ng-src[data-s="3"]:focus-visible) .ng-wires path.w3 { opacity: 1; stroke-width: 2.4; }
.ng-canvas:has(.ng-src[data-s="4"]:hover) .ng-wires path.w4,
.ng-canvas:has(.ng-src[data-s="4"]:focus-visible) .ng-wires path.w4 { opacity: 1; stroke-width: 2.4; }

.ng-detail {
  margin-top: 14px; padding: 15px 17px; border-radius: var(--r); min-height: 96px;
  background: var(--ink-hover); border: 1px solid oklch(97% 0.003 265 / 0.12);
}
.det { display: none; }
.det[data-d="4"] { display: block; }
.ngraph:has(.ng-src:hover) .det[data-d="4"],
.ngraph:has(.ng-src:focus-visible) .det[data-d="4"] { display: none; }
.ngraph:has(.ng-src[data-s="1"]:hover) .det[data-d="1"],
.ngraph:has(.ng-src[data-s="1"]:focus-visible) .det[data-d="1"] { display: block; }
.ngraph:has(.ng-src[data-s="2"]:hover) .det[data-d="2"],
.ngraph:has(.ng-src[data-s="2"]:focus-visible) .det[data-d="2"] { display: block; }
.ngraph:has(.ng-src[data-s="3"]:hover) .det[data-d="3"],
.ngraph:has(.ng-src[data-s="3"]:focus-visible) .det[data-d="3"] { display: block; }
.ngraph:has(.ng-src[data-s="4"]:hover) .det[data-d="4"],
.ngraph:has(.ng-src[data-s="4"]:focus-visible) .det[data-d="4"] { display: block; }

.det-h { display: flex; align-items: center; gap: 9px; font-size: 13px; font-weight: 600;
  color: var(--on-ink-strong); }
.det p { margin-top: 8px; font-size: 13.5px; line-height: 1.5; color: var(--on-ink-dim);
  max-width: 70ch; }
.det-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.ng-tag { font-style: normal; font-size: 10.5px; font-weight: 600; letter-spacing: 0.02em;
  padding: 2px 8px; border-radius: 999px;
  background: oklch(97% 0.003 265 / 0.10); color: var(--on-ink-dim); }
.ng-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.ng-dot.pos     { background: color-mix(in oklab, var(--pos) 55%, var(--on-ink)); }
.ng-dot.info    { background: color-mix(in oklab, var(--info) 55%, var(--on-ink)); }
.ng-dot.caution { background: color-mix(in oklab, var(--caution) 60%, var(--on-ink)); }
.ng-dot.neg     { background: color-mix(in oklab, var(--neg) 55%, var(--on-ink)); }

.ng-cap { margin-top: 12px; font-size: 12.5px; line-height: 1.5; color: var(--muted); }

@media (prefers-reduced-motion: reduce) {
  .ng-wires path, .ng-node, .ng-src { transition: none; }
}

/* ---- blueprint, dark variant --------------------------------------------
   Scoped to .card so app/roadmap.html keeps the light original. Same ground,
   node bars, port dots and lifted wire colours as the source graph, so the
   two diagrams in this report read as one family. */
.card .blueprint {
  border: 0; box-shadow: none; padding: 14px;
  background:
    radial-gradient(circle, oklch(97% 0.003 265 / 0.09) 1px, transparent 1px) 0 0 / 22px 22px,
    var(--ink);
}
.card .blueprint .bp-wires path     { stroke: oklch(97% 0.003 265 / 0.22); }
.card .blueprint .bp-wires path.yes { stroke: color-mix(in oklab, var(--pos) 55%, var(--on-ink)); }
.card .blueprint .bp-wires path.no  { stroke: oklch(97% 0.003 265 / 0.22); }
.card .blueprint .bp-wires text.yes { fill: color-mix(in oklab, var(--pos) 55%, var(--on-ink)); }
.card .blueprint .bp-wires text.no  { fill: var(--on-ink-faint); }

.card .blueprint .node {
  background: var(--ink-hover); border: 1px solid oklch(97% 0.003 265 / 0.14);
  box-shadow: 0 2px 10px oklch(0% 0 0 / 0.32);
}
.card .blueprint .node .nh.plain   { background: oklch(97% 0.003 265 / 0.07); color: var(--on-ink-dim); }
.card .blueprint .node .nh.pos     { background: color-mix(in oklab, var(--pos) 20%, var(--ink));
                                     color: color-mix(in oklab, var(--pos) 55%, var(--on-ink)); }
.card .blueprint .node .nh.info    { background: color-mix(in oklab, var(--info) 20%, var(--ink));
                                     color: color-mix(in oklab, var(--info) 58%, var(--on-ink)); }
.card .blueprint .node .nh.caution { background: color-mix(in oklab, var(--caution) 22%, var(--ink));
                                     color: color-mix(in oklab, var(--caution) 62%, var(--on-ink)); }
.card .blueprint .node .nb h4 { color: var(--on-ink-strong); }
.card .blueprint .node .nb p  { color: var(--on-ink); }
.card .blueprint .node .nb li { color: var(--on-ink-dim); }
.card .blueprint .node .nb li i { background: oklch(97% 0.003 265 / 0.28); }
.card .blueprint .node .nf {
  background: oklch(97% 0.003 265 / 0.05); border-top-color: oklch(97% 0.003 265 / 0.12);
  color: var(--on-ink-faint);
}
.card .blueprint .node .pin { background: var(--ink-hover);
  box-shadow: 0 0 0 2.2px oklch(97% 0.003 265 / 0.32); }
.card .blueprint .node .pin.on { background: color-mix(in oklab, var(--pos) 55%, var(--on-ink));
  box-shadow: 0 0 0 2.2px color-mix(in oklab, var(--pos) 55%, var(--on-ink)); }

.card .blueprint .bp-chip {
  background: var(--ink-hover); color: var(--on-ink);
  border: 1px solid oklch(97% 0.003 265 / 0.18); box-shadow: none;
}
.card .blueprint .bp-chip.ship {
  background: color-mix(in oklab, var(--pos) 24%, var(--ink));
  color: color-mix(in oklab, var(--pos) 60%, var(--on-ink));
  border-color: color-mix(in oklab, var(--pos) 38%, var(--ink));
}
.card .blueprint .bp-chip.dead {
  background: oklch(97% 0.003 265 / 0.05); color: var(--on-ink-faint);
  border-color: oklch(97% 0.003 265 / 0.12);
}

/* ---- data flowing into the verdict --------------------------------------
   A short dash travelling each wire from its source to the hub. pathLength
   normalises every curve to 100 units, so one keyframe drives all four however
   long each actually is, and the dashes stay the same size on every wire. */
.ng-wires path.pulse {
  stroke-width: 3.4; stroke-linecap: round; opacity: 1;
  stroke-dasharray: 3 97;
  animation: ng-flow 2.6s linear infinite;
}
@keyframes ng-flow { from { stroke-dashoffset: 0; } to { stroke-dashoffset: -100; } }
/* staggered so the four arrive separately - in sync they read as one pulse */
.ng-wires path.pulse.w1 { animation-delay: 0s; }
.ng-wires path.pulse.w2 { animation-delay: .65s; }
.ng-wires path.pulse.w3 { animation-delay: 1.3s; }
.ng-wires path.pulse.w4 { animation-delay: 1.95s; }

@media (prefers-reduced-motion: reduce) {
  .ng-wires path.pulse { animation: none; opacity: 0; }
}
