/* CS1 · layout only (docs/cs1-spec.md). Needs tokens.css, shell.css, thread.css, story.css, band.css.
   Desktop default; CS1's own switch at 1200 (side-by-side layouts); the shell's 900 and 600 for tablet and mobile. */

/* main is full width with no side padding: 100cqi is the page width */
.cs1 {
  --case: var(--color-case-cs1);
  --off: 80px;      /* content column offset from the page margin: 120 / 96 / 68 */
  container-type: inline-size;
}
.cs1 :where(p, h1, h2, h3, figure) { margin: 0; }
.cs1 .sec { color: var(--color-text-secondary); }
.cs1 .pri { color: var(--color-text-primary); }

/* ---------- Hero (§3) ---------- */
.cs1-hero {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  /* Update 6 Nov 2026 (Eden): 52 on every stacked layout, so the straight run across keeps 24 px from the note with
     the new thread corners. Geometry exception: not on the spacing scale (there is no --space-56) */
  gap: 52px;
  padding: var(--rh-section) var(--in-page-x) var(--rh-chapter);
}
.hero-main {
  display: flex;
  flex-direction: column;
  gap: var(--rh-element);
  width: 100%;
}
/* A plain block (not flex): the h1 is not a flex item, so the QA finds the headline's block and the lead below it (E1) */
.hero-text { max-width: var(--hero-col); }
.hero-text > .t-label { margin-bottom: var(--rh-element); }
.hero-lead {
  display: flex;
  flex-direction: column;
  gap: var(--rh-element);
  max-width: var(--hero-lead);
}

/* Written lines, never re-flowed: 3 on desktop, 2 below 901 */
.hero-title { white-space: nowrap; }
.br-d { display: inline; }

/* "why." carries the underline; the tracking given back as padding (shell spec §5, like "talk"),
   so the box and the underline match Figma (171 / 177.8 at 84) */
.why {
  position: relative;
  isolation: isolate;
  display: inline-block;
  padding-inline-end: 0.045em;
}
/* Mark · Underline, in em of the headline (Figma 177.8 × 10 at 84) */
.why__line {
  position: absolute;
  z-index: -1;
  left: -0.04em;
  top: 0.908em;
  width: calc(100% + 0.08em);
  height: 0.119em;
  overflow: visible;
}

/* The hero path: two drawings, one shown (§3.4) */
.hero-path { position: relative; flex: none; }
.hero-path--h { display: none; }
.hp-draw { position: relative; }
.hp-draw > * { position: absolute; }
.hp-label { white-space: nowrap; color: var(--color-text-secondary); }
.hp-line { overflow: visible; }
.hp-line path {
  fill: none;
  stroke: var(--color-line-exact);
  stroke-width: var(--stroke-exact);
  vector-effect: non-scaling-stroke;
}
.hp-turn { width: 0; height: 0; }
/* The Sign up knot is Reached at rest in Stage A (§3.4); Stage C ties it to the line */
.knot--on {
  --ol-line: var(--case);
  --ol-fill: var(--case);
  --ol-scale: 1.15;
}

/* Horizontal (desktop ≥ 1200): 640 × 290, never scaled */
.hero-path--h .hp-draw { width: 640px; height: 290px; }
.hero-path--h .hp-line { left: 0; top: 0; width: 640px; height: 290px; }
.hero-path--h .hp-knot { left: 28px; top: 138px; }
.hero-path--h .hp-l-signup { left: 31px; top: 96px; }
.hero-path--h .hp-l-steps { left: 220px; top: 96px; transform: translateX(-50%); }
.hero-path--h .hp-step1 { left: 150px; top: 130px; }
.hero-path--h .hp-step2 { left: 250px; top: 130px; }
.hero-path--h .hp-station { left: 372px; top: 122px; }
.hero-path--h .hp-l-lesson { left: 400px; top: 96px; transform: translateX(-50%); }
.hero-path--h .hp-in { left: calc(434px + var(--k) * 26px); top: 118px; }
.hero-path--h .hp-left { left: var(--x); top: var(--y); }
.hero-path--h .hp-turn { left: calc(100% - 18px); top: 150px; }

/* Vertical (below 1200): on the rail, x from the thread column, y from the figure top; 448 tall */
.hero-path--v {
  --c: 52px; /* content column offset from the thread column: 52 / 48 / 36 */
  --s: 24px; /* reached users step */
  align-self: stretch;
  margin-left: calc(var(--thread-x) - var(--in-page-x));
}
.hero-path--v .hp-draw { height: 448px; }
.hero-path--v .hp-line { left: -10px; top: 0; width: 20px; height: 448px; }
.hero-path--v .hp-knot { left: -12px; top: 44px; }
.hero-path--v .hp-step1 { left: -20px; top: 166px; }
.hero-path--v .hp-step2 { left: -20px; top: 266px; }
.hero-path--v .hp-station { left: -24px; top: 392px; }
.hero-path--v .hp-l-signup { left: var(--c); top: 48px; }
.hero-path--v .hp-l-steps { left: var(--c); top: 115px; }
.hero-path--v .hp-l-lesson { left: var(--c); top: 410px; }
.hero-path--v .hp-left { left: calc(var(--c) + var(--j) * 22px); top: var(--y); }
.hero-path--v .hp-in { left: calc(var(--c) + 108px + var(--k) * var(--s)); top: 401px; }

/* Result row (§3.6) */
.result {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: var(--rh-element);
}
.hero-path--v .result { margin-left: var(--c); }
.result__value { color: var(--color-text-primary); }
.result__what { color: var(--color-text-secondary); }

/* ---------- Chapter headers (§5.1, §7) ---------- */
.chapter {
  position: relative;
  padding: 0 var(--in-page-x) var(--rh-section) calc(var(--in-page-x) + var(--off));
}
.chapter__head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--rh-element);
}
/* Knot · chapter: centred on the thread column, its centre on the label line's centre (label line 17.6) */
.chapter__knot {
  position: absolute;
  left: calc(var(--thread-x) - 12px);
  top: calc(var(--head-top, 0px) + 8.8px - 12px);
}
.chapter__title { max-width: 900px; }
.chapter__title > span { display: block; }
.chapter__title > span + span { margin-top: var(--rh-element); } /* the two lines of the Chapter 1 heading (Figma 432) */
.chapter__sub { max-width: 700px; }
.legend {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* ---------- Stops (§6) ---------- */
.stops { padding: 0 var(--in-page-x); }
.stop {
  --st-top: 80px;
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--rh-block);
  padding: 0 0 var(--rh-section) var(--off);
}
.stop__station {
  position: absolute;
  left: calc(var(--knot-column) / 2 - var(--st) / 2);
  top: var(--st-top);
}
.stop__text {
  display: flex;
  flex-direction: column;
  gap: var(--rh-element);
  padding-top: var(--space-64);
}
.stop__head,
.stop__asked {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--rh-tight);
}
.fact {
  display: flex;
  align-items: center;
  gap: 20px;
}
.fact__text {
  display: flex;
  flex-direction: column;
  gap: var(--rh-tight);
  flex: 1;
  min-width: 0;
}
.screens {
  display: flex;
  align-items: flex-end;
  gap: 32px;
}
.screens .screen { width: 280px; }

/* ---------- Chapter 2 (§7) ---------- */
.ch2 {
  --head-top: var(--rh-chapter);
  padding-top: var(--rh-chapter);
  padding-bottom: var(--rh-chapter);
}
.lesson {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--rh-block);
  padding-top: var(--rh-section);
}
.lesson__text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--rh-element);
}
.lesson__body { max-width: 520px; }

/* Illustration · order of work: Numbers · rule · Users · rule · Screens, bottom-aligned */
.illus {
  display: flex;
  align-items: flex-end;
  flex: none;
}
.illus__col {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex: none;
}
.illus__col--numbers { gap: 12px; }
.illus__col--users { width: 124px; } /* Figma column 124 on desktop and tablet; the bubble hugs inside it */
.illus__col--screens { gap: 12px; width: 60px; }
.illus__pawn { margin: 8px 0 12px; }
.illus__rule {
  position: relative;
  align-self: stretch;
  flex: none;
  width: 56px;
}
.illus__rule svg {
  position: absolute;
  left: 0;
  bottom: 40px;
  width: 100%;
  height: 2px;
  overflow: visible;
}
.illus__rule path {
  fill: none;
  stroke: var(--color-line-exact);
  stroke-width: var(--stroke-exact);
  vector-effect: non-scaling-stroke;
}

.notes {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 48px;
  padding-top: var(--rh-block);
}
.note {
  display: flex;
  flex-direction: column;
  gap: var(--rh-element);
}

/* ---------- Stage B · motion (§12) ----------
   Every hidden start state sits under html.cs1-motion (set by cs1.js only when motion is allowed),
   so without JS, and in reduced motion, the page is the Stage A page. Only opacity, transform and clip-path move. */

/* Stop entrances (§12.3): each element rises once; --enter-d is its wait in its stop's group.
   The transitions sit on the entered side only, so the start state is set at once on load (no fade into hiding). */
.cs1-motion [data-enter].is-in {
  transition:
    opacity 0.7s cubic-bezier(0.2, 0.7, 0.2, 1) var(--enter-d, 0s),
    transform 0.7s cubic-bezier(0.2, 0.7, 0.2, 1) var(--enter-d, 0s);
}
.cs1-motion [data-enter]:not(.is-in) {
  opacity: 0;
  transform: translateY(18px);
}

/* Changed diagrams: the case line draws left to right (a clip in the line's own box), then the case shapes
   turn from white with an ink outline to the case color; the white checks appear with the fill */
.cs1-motion [data-enter].is-in .cs1-draw {
  clip-path: inset(-4px -4px -4px -4px);
  transition: clip-path 1s cubic-bezier(0.5, 0, 0.25, 1) calc(var(--enter-d, 0s) + 0.25s);
}
.cs1-motion [data-enter]:not(.is-in) .cs1-draw { clip-path: inset(-4px var(--cl-from) -4px -4px); }
.cs1-motion [data-enter].is-in .cs1-fill {
  transition:
    fill 0.4s ease calc(var(--enter-d, 0s) + 1.05s),
    stroke 0.4s ease calc(var(--enter-d, 0s) + 1.05s);
}
.cs1-motion [data-enter]:not(.is-in) .cs1-fill {
  fill: var(--color-bg-page);
  stroke: var(--color-line-exact);
}
.cs1-motion [data-enter].is-in .cs1-fill-check { transition: opacity 0.4s ease calc(var(--enter-d, 0s) + 1.05s); }
.cs1-motion [data-enter]:not(.is-in) .cs1-fill-check { opacity: 0; }

/* The underline under "After" / "Lesson to trade" reveals left to right with the screens row */
.cs1-motion [data-enter].is-in :is(.screen__mark, .cmp__word) svg {
  clip-path: inset(-4px -4px -4px -4px);
  transition: clip-path 0.6s cubic-bezier(0.5, 0, 0.25, 1) calc(var(--enter-d, 0s) + 0.5s);
}
.cs1-motion [data-enter]:not(.is-in) :is(.screen__mark, .cmp__word) svg { clip-path: inset(-4px calc(100% + 4px) -4px -4px); }

/* Chapter 1 opens when the line reaches its knot (§12.4), once; the knot itself always shows */
.cs1-motion .chapter-1.is-open .chapter__head > * {
  transition: opacity 0.55s ease, transform 0.55s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.cs1-motion .chapter-1.is-open .chapter__head > :nth-child(2) { transition-delay: 0.08s; }
.cs1-motion .chapter-1.is-open .chapter__head > :nth-child(3) { transition-delay: 0.18s; }
.cs1-motion .chapter-1.is-open .chapter__head > :nth-child(4) { transition-delay: 0.26s; }
.cs1-motion .chapter-1:not(.is-open) .chapter__head > * {
  opacity: 0;
  transform: translateY(12px);
}
.cs1-motion .chapter-1.is-open.is-instant .chapter__head > * { transition: none; }

/* The Rider (§12.5): a 34 ring (ink 34, white 30.8, two discs) with an Inside pawn 16 × 20, on the line's tip.
   Above the content (the root's children are z-index 1), below the sticky nav (10). */
[data-thread-root] > .cs1-rider {
  --case: var(--color-case-cs1);
  --ol-w: var(--stroke-exact);
  --ol-line: var(--color-line-exact);
  --ol-fill: var(--color-bg-page);
  position: absolute;
  left: 0;
  top: 0;
  z-index: 2;
  display: grid;
  place-items: center;
  isolation: isolate;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--color-line-exact);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease;
}
[data-thread-root] > .cs1-rider::before {
  content: "";
  position: absolute;
  inset: var(--stroke-exact);
  z-index: -1;
  border-radius: 50%;
  background: var(--color-bg-page);
}
[data-thread-root] > .cs1-rider.has-outline { background: none; }
[data-thread-root] > .cs1-rider.has-outline::before { content: none; }
[data-thread-root] > .cs1-rider .pawn { width: 16px; height: 20px; }
[data-thread-root] > .cs1-rider.is-on { opacity: 1; }
html:not(.cs1-motion) [data-thread-root] > .cs1-rider { display: none; }

/* The seventh reached user leaves the row while the Rider rides, so it never shows twice */
.cs1-motion .cs1-seventh { transition: opacity 0.25s ease; }
.cs1-motion .cs1-seventh.is-riding { opacity: 0; }

/* ---------- Stage C · the hero (§14) ----------
   All under html.cs1-motion. data-hero on .cs1-hero: wait → playing → done (update 12 Nov 2026: no "intro";
   the line runs to Sign up while the hero plays).
   cs1.js draws every piece from one clock; once done, its inline styles are gone and the hero is the Stage A hero. */

/* Load (§14.2), the Home rhythm: headline 0.2 s, underline under "why." 0.65 s, lead block 1.45 s; once */
@keyframes cs1-rise {
  from { transform: translateY(0.25em); opacity: 0; }
  to { transform: none; opacity: 1; }
}
@keyframes cs1-draw {
  from { clip-path: inset(0 100% 0 0); }
  to { clip-path: inset(0 0 0 0); }
}
@keyframes cs1-fade {
  from { opacity: 0; }
  to { opacity: 1; }
}
.cs1-motion .hero-title { animation: cs1-rise 0.6s ease 0.2s both; }
.cs1-motion .why__line { animation: cs1-draw 0.7s cubic-bezier(0.5, 0, 0.2, 1) 0.65s both; }
.cs1-motion .hero-lead { animation: cs1-fade 0.8s ease 1.45s both; }

/* Until the hero is done: the Stage A pieces start hidden (no flash of the final frame before first paint).
   The step stations and the lesson station are anchors: they keep their boxes, their moving drawings are .hp-a copies */
.cs1-motion .cs1-hero:not([data-hero="done"]) :is(.hp-label, .hp-in, .hp-left, .result, .hp-step1, .hp-step2, .hp-station) { opacity: 0; }
.cs1-motion .cs1-hero:not([data-hero="done"]) .hp-line path { visibility: hidden; }
.cs1-motion .cs1-hero[data-hero="playing"] .hp-line path { visibility: visible; }
/* Update 8 Nov 2026 (Eden): the desktop drawing is placed from the settled underline (after the load motion);
   until then its pieces are hidden, so the Sign up knot never visibly jumps */
.cs1-motion .hero-path--h:not(.is-placed) .hp-draw { visibility: hidden; }/* The Sign up knot: Ahead before the line arrives, then driven by the clock (--kc colour 0 → 1, --ks scale) */
.cs1-motion .cs1-hero:not([data-hero="done"]) .hp-knot {
  --ol-line: color-mix(in srgb, var(--case) calc(var(--kc, 0) * 100%), var(--color-line-exact));
  --ol-fill: color-mix(in srgb, var(--case) calc(var(--kc, 0) * 100%), var(--color-bg-page));
  --ol-scale: var(--ks, 1);
  --ol-t: 0s;
}
.cs1-motion .cs1-hero:not([data-hero="done"]) .hp-knot::before,
.cs1-motion .cs1-hero:not([data-hero="done"]) .hp-knot::after { transition: none; }
/* Pawns walking: fill and stroke crossfade between Waiting, Left and Inside */
.cs1-motion .cs1-hero:not([data-hero="done"]) .hp-p * {
  fill: var(--pf, var(--color-bg-page));
  stroke: var(--ps, var(--color-line-exact));
}
/* The count 9.25% → 34.75% never reflows: digits of one width (if the font has them), the box as wide as "34.75%" */
.cs1-motion .cs1-hero:not([data-hero="done"]) .result__value { font-variant-numeric: tabular-nums; }

/* The moving drawings (.hp-a): only while the hero plays */
.hp-draw > .hp-a { left: 0; top: 0; }
html:not(.cs1-motion) .hp-a,
.cs1-hero[data-hero="done"] .hp-a { display: none; }
.hp-a.qstation {
  --ol-line: var(--color-line-guide);
  color: var(--color-text-secondary);
  transform-origin: 20px 20px;
}
.hp-a.qstation[data-q="on"] {
  --ol-line: var(--color-line-exact);
  color: var(--color-text-primary);
}
.hp-a.hp-l-why { color: var(--color-text-primary); }
.hero-path--h .hp-l-why { left: 100px; top: 96px; }
.hero-path--v .hp-l-why { left: var(--c); top: 513px; }
/* Update 8 Nov 2026 (Eden): one line, never wrapped; below 390 "8 questions first" (the full label doesn't fit) */
.hp-why-short { display: none; }
@media (max-width: 389px) {
  .hp-l-why .hp-why-full { display: none; }
  .hp-l-why .hp-why-short { display: inline; }
}

/* Thread drawAll (QA screenshots): what opens, opens at once */
.cs1-motion [data-thread-static] [data-enter].is-in,
.cs1-motion [data-thread-static] [data-enter].is-in *,
.cs1-motion [data-thread-static] .chapter-1.is-open .chapter__head > * { transition: none; }

/* ---------- Desktop ≥ 1200: the side-by-side layouts ---------- */
@media (min-width: 1200px) {
  .cs1-hero {
    flex-direction: row;
    justify-content: space-between;
    gap: 24px;
  }
  .hero-main { flex: none; width: 680px; }
  .hero-path--h { display: block; margin-top: var(--hp-top, 137.3px); }
  .hero-path--v { display: none; }
  .hero-path--h .result {
    flex-direction: row;
    align-items: baseline;
    gap: 12px;
    padding-left: 28px;
  }

  .stop {
    flex-direction: row;
    gap: 24px;
    padding-bottom: 0;
  }
  .stop__text {
    flex: none;
    width: min(520px, 100cqi - 80px - 56px - 48px - 592px);
    padding-bottom: var(--rh-section);
  }
  .screens {
    margin-left: auto;
    padding: var(--space-64) 0 var(--rh-section);
  }

  .lesson {
    flex-direction: row;
    align-items: center;
    gap: 48px;
    padding-bottom: 32px;
  }
}

/* 1200–1423: the figure stays 640 at the right margin, the text column takes the rest,
   the headline shrinks in Figma's proportion so "I found out why." fits (84 at 1424, about 65 at 1200) */
@media (min-width: 1200px) and (max-width: 1423px) {
  .hero-main { width: calc(100cqi - 80px - 24px - 640px); }
  .hero-title { font-size: min(84px, (100cqi - 744px) / 6.99); }
}

/* Below 345 only (Eden, 5 Nov 2026): the headline lines open up a little, so the line's start keeps 24 px
   from "9 in 10 left at the door." when the fluid headline gets small (value checked at 320) */
@media (max-width: 344px) {
  .hero-title { line-height: 1.08; }
}

/* ---------- Tablet · 601–900 ---------- */
@media (max-width: 900px) {
  .cs1 { --off: 64px; }
  .br-d { display: none; }
  .hero-path--v { --c: 48px; }

  .only-desktop { display: none; }
  .chapter__title { max-width: none; }

  .stop { --st-top: 31px; }
  .stop .station { --st: 32px; --st-r: var(--radius-m); }
  .stop__text { padding-top: var(--space-32); }
  .stop .bubble { width: 380px; }
  .screens .screen { width: min(280px, (100% - 32px) / 2); }

  .illus__col--numbers { width: auto; }
  .notes { gap: 24px; }
}

/* ---------- Mobile · up to 600 ---------- */
@media (max-width: 600px) {
  .cs1 { --off: 48px; }
  /* 34 at 390, about 27.2 at 320; "9 in 10 left at the door." stays one line */
  .hero-title { font-size: min(34px, (100cqi - 40px) / 10.29); }
  .hero-path--v {
    --c: 36px;
    --s: min(24px, (100cqi - 220px) / 6); /* §4.4: the row tightens below 390 so it fits */
  }

  .stop { --st-top: 23px; }
  .stop__text { padding-top: var(--space-24); }
  .stop__asked .speaker { align-self: stretch; } /* the row is the column's width, so the bubble fills it (266 at 390) */
  .speaker .bubble { flex: 1; width: auto; }
  .illus__col--users { width: auto; }
  .fact .diagram { display: none; }
  .fact { display: block; }
  .metric { flex-wrap: wrap; }
  .screens { gap: 12px; }
  .screens .screen { width: calc((100% - 12px) / 2); }

  /* Below ~375 the illustration doesn't fit the content column: only the two rules shrink (to Eden for review) */
  .illus { max-width: 100%; }
  .illus__rule { width: 30px; flex: 0 1 30px; min-width: 2px; }
  .illus .station { --st: 48px; --st-r: var(--radius-l); }
  .notes { grid-template-columns: minmax(0, 1fr); gap: var(--rh-block); }
}
