/* =====================================================================
   theme-cs.css — Computer Science, "RUNTIME" (design-spec §6.5 C1–C8,
   §14.3 personal / professionals / test prep, §14.5 AI & ML track).
   Loaded after styles.css on computer-science.html only. Adds
   theme-scoped rules; never redefines shared tokens or geometry.

   Rule 10: every html.motion-ok rule that hides, offsets, clips or
   un-draws something lives ONLY in the @media screen and
   (prefers-reduced-motion:no-preference) block at the end of this
   file. Outside it, everything is the final frame.

   01 C1 typed wordmark (rest)        08 §14.3 test prep
   02 C2 hero terminal + tabs          09 C6 paper & AI band
   03 C3 stat strip                    10 C7 stack-trace story
   04 C4 self-sorting bars             11 C8 closing CTA
   05 §14.3 personal plan              12 keyframes
   06 §14.3 professionals              13 RULE-10 BLOCK
   07 C5 git roadmap, §14.5 AI & ML
   ===================================================================== */

/* ---------------------------------------------------------------- 01 */
/* C1: rest = full text + a solid amber block caret (base geometry is shared). */
[data-theme="cs"] .wm-cs .wm-line { white-space: nowrap; }

/* ---------------------------------------------------------------- 02 */
/* C2 hero stage: three complete terminals behind language tabs. */
.term-fig { justify-items: stretch; }
.term-fig > .lang-tabs { justify-self: center; }
.hv-term { position: relative; isolation: isolate; }
.hv-term .seg-title { margin: 0; padding: 12px 18px 0; color: var(--text-3); }
/* the tallest transcript (Java, 10 lines + caret) sets one height for all
   three, so switching tabs never moves the contents list (tabs need JS: without
   it the three terminals are stacked and each keeps its natural height) */
html.js .term-fig .term-body { min-height: calc(10 * 1.75em + 1.4em + 36px); }
/* phones: comment-only lines wrap (hanging indent after the "# " / "// ") instead of
   running past the edge; real code keeps its scrollable lines. Two wrapped comments → 12 rows. */
@media (max-width: 479px) {
  html.js .term-fig .term-body { min-height: calc(12 * 1.75em + 1.4em + 36px); }
  .term-fig .tl:has(> :is(.tok-c, .tok-ok):only-child) { width: auto; white-space: pre-wrap; padding-left: 3ch; text-indent: -3ch; }
}
.tl-out { position: relative; }
.out-v { display: inline-block; font-weight: 700; color: var(--term-ink); }
.tok-ok { color: var(--tok-s); }
/* block caret on the next prompt line (blinks ≤ 5× after typing, then solid) */
.term-fig .term-body::after {
  content: ""; display: block; width: .6em; height: 1.2em; margin-top: 2px; background: var(--amber);
}
/* soft phosphor glow under the cursor (tilt writes --mx/--my; glow only, no rotation) */
@media (hover: hover) and (pointer: fine) {
  .motion-ok .term-fig .hv-term::before {
    content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
    background: radial-gradient(260px circle at calc(var(--mx) * 100%) calc(var(--my) * 100%), rgba(62,230,181,.13), transparent 70%);
  }
}

/* ---------------------------------------------------------------- 03 */
/* C3 binary stat strip: the bit cells sit on the paper surface. */
[data-theme="cs"] .stat-num .bin .bits { gap: .06em; }
[data-theme="cs"] .stat-num .bit::before, [data-theme="cs"] .stat-num .bit::after { border-radius: 3px; }

/* ---------------------------------------------------------------- 04 */
/* C4 self-sorting bars: one frame per bubble-sort pass, pure CSS. */
.sortbars { position: relative; height: 72px; max-width: 420px; margin-top: var(--s-5); }
.sb {
  --x: var(--x4); position: absolute; left: 0; bottom: 0; width: 12.5%; height: calc(var(--v) * 12.5%);
  padding-inline: 3px; background-clip: content-box; background-color: var(--accent); border-radius: 3px 3px 0 0;
  transform: translateX(calc(var(--x) * 100%)); transition: transform 360ms var(--ease-in-out);
}
[data-step-active="0"] .sb { --x: var(--x0); }
[data-step-active="1"] .sb { --x: var(--x1); }
[data-step-active="2"] .sb { --x: var(--x2); }
[data-step-active="3"] .sb { --x: var(--x3); }
/* "sorted" ink: opacity only; rest (--step 99) = every bar inked */
.sb::after {
  content: ""; position: absolute; inset: 0 3px; border-radius: inherit; background: var(--accent-ink);
  opacity: clamp(0, var(--step) - var(--fin) + 1, 1); transition: opacity 240ms var(--ease-out);
}

/* ---------------------------------------------------------------- 05 */
/* §14.3.1 Built around one student */
.plan-grid { display: grid; gap: var(--s-7); align-items: start; }
@media (min-width: 960px) { .plan-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); gap: var(--s-8); } }
.plan-points { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-6); }
.plan-point { position: relative; margin: 0; padding-left: 60px; }
.pp-key {
  position: absolute; left: 0; top: -4px; display: grid; place-items: center; width: 42px; height: 42px;
  border-radius: var(--r-sm); background: var(--tint); box-shadow: inset 0 0 0 1px var(--line);
  font: 700 14px/1 var(--font-mono); color: var(--accent-text);
}
.plan-point h3 { margin: 0 0 .3em; font-size: 1.1875rem; line-height: 1.3; }
.plan-point p { margin: 0; color: var(--text-2); }

.plan-demo { display: grid; justify-items: start; gap: var(--s-4); min-width: 0; }
.plan-demo-head { margin: 0; color: var(--text-2); }
.plan-card {
  width: 100%; margin: 0; overflow: hidden; border-radius: var(--r-tile); background: var(--card-bg);
  box-shadow: var(--shadow-2), inset 0 0 0 1px var(--line); color: var(--text-2);
}
.plan-bar { padding: 16px clamp(20px, 3vw, 28px) 0; }
.plan-file { display: inline-flex; align-items: center; gap: 8px; font: 500 12px/1.3 var(--font-mono); color: var(--text-3); }
.plan-file::before { content: ""; flex: none; width: 8px; height: 8px; border-radius: 2px; background: var(--accent); }
.plan-title { margin: 8px 0 0; }
.plan-facts { margin: var(--s-4) 0 0; padding: 0 clamp(20px, 3vw, 28px); }
.plan-facts > div { display: grid; grid-template-columns: 5.25rem minmax(0, 1fr); gap: 12px; padding: 10px 0; box-shadow: inset 0 1px 0 var(--line); }
.plan-facts dt { font: 600 13px/1.55 var(--font-mono); color: var(--accent-text); }
.plan-facts dd { margin: 0; font-size: 15px; line-height: 1.5; color: var(--text); }
.plan-sub { margin: var(--s-4) 0 0; padding: var(--s-4) clamp(20px, 3vw, 28px) 0; box-shadow: inset 0 1px 0 var(--line); font: 600 var(--fs-meta)/1.3 var(--font-sans); letter-spacing: .12em; text-transform: uppercase; color: var(--text-3); }
.plan-sessions { list-style: none; counter-reset: ses; display: grid; gap: 8px; margin: 12px 0 0; padding: 0 clamp(20px, 3vw, 28px) clamp(20px, 3vw, 28px); }
.plan-sessions li {
  counter-increment: ses; position: relative; margin: 0; padding: 10px 14px 10px 46px; border-radius: var(--r-md);
  background: var(--paper); box-shadow: inset 0 0 0 1px var(--line); font-size: 15px; line-height: 1.45; color: var(--text-2);
}
.plan-sessions li::before {
  content: counter(ses, decimal-leading-zero); content: counter(ses, decimal-leading-zero) / "";
  position: absolute; left: 14px; top: 10px; font: 700 13px/1.6 var(--font-mono); color: var(--accent-text);
}
.plan-note { margin: 0; font-size: var(--fs-small); color: var(--text-3); }

.hand-note {
  display: grid; gap: var(--s-6); margin-top: var(--s-8); padding: clamp(24px, 1.25rem + 2vw, 48px);
  border-radius: var(--r-tile); background: var(--tint); box-shadow: inset 0 0 0 1px var(--line);
}
@media (min-width: 960px) { .hand-note { grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); align-items: center; } }
.hand-note-lead { margin: 0; max-width: 34em; font: 400 var(--fs-lead)/1.32 var(--font-serif); letter-spacing: -.005em; color: var(--text); }
.hand-note-lead strong { color: var(--accent-text); }
/* 5 tools: 3 + 2 rows that fill the width (6-track grid), or 5 across when
   the column is wide enough — never a 4 + 1 orphan */
.hand-tools { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 10px; }
.hand-tools li { grid-column: span 2; }
.hand-tools li:nth-child(n + 4) { grid-column: span 3; }
@media (min-width: 560px) and (max-width: 959px), (min-width: 1240px) {
  .hand-tools { grid-template-columns: repeat(5, minmax(0, 1fr)); }
  .hand-tools li, .hand-tools li:nth-child(n + 4) { grid-column: auto; }
}
.hand-tools li {
  display: grid; justify-items: center; gap: 8px; margin: 0; padding: 14px 6px 12px; border-radius: var(--r-md);
  background: var(--card-bg); box-shadow: inset 0 0 0 1px var(--line); font: 600 13px/1.2 var(--font-sans); color: var(--text); text-align: center;
}
.hand-tools svg { width: 28px; height: 28px; overflow: visible; }
.hand-tools path { stroke: var(--graphite); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }

/* ---------------------------------------------------------------- 06 */
/* §14.3.2 Taught by professionals: real-world tiles with a tiny run */
.pro-grid { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--gap); }
/* 4 tiles: 1 → 2 columns (the mini terminals need the width of a half row) */
@media (min-width: 640px) { .pro-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.pro-tile { margin: 0; justify-content: flex-start; gap: var(--s-3); }
@media (hover: hover) { .pro-tile:hover { translate: none; box-shadow: inset 0 0 0 1px var(--line); } }
.pro-tile .tile-sub { flex: 1 1 auto; max-width: none; }
.pro-term { margin-top: var(--s-3); box-shadow: inset 0 0 0 1px var(--line); }
.pro-term .term-body { padding: 12px 16px; font-size: 13px; line-height: 1.7; }
/* phones: the longest typed line (≈34 mono chars) must fit the tile without a hidden scroll */
@media (max-width: 479px) { .pro-term .term-body { padding: 12px 14px; font-size: clamp(11px, 3.05vw, 13px); } }
.pro-err { color: var(--swp); }
.pro-pull { margin: var(--s-7) 0 0; max-width: 46rem; font: 400 var(--fs-lead)/1.35 var(--font-serif); letter-spacing: -.005em; color: var(--text); }
.pro-pull-mark { margin-right: .2em; font: 700 .9em/1 var(--font-mono); color: var(--accent-text); }
.pro-pull .link-arrow { margin-left: .2em; font-size: 1.0625rem; white-space: nowrap; vertical-align: .1em; }

/* ---------------------------------------------------------------- 07 */
/* C5 git-graph roadmap: branch rail, commit dots, bit-flip stage numbers */
.roadmap--git { isolation: isolate; }
.roadmap--git::before { left: 22.5px; width: 3px; background: var(--mark); }
.roadmap--git::after {
  content: ""; position: absolute; left: 23px; top: 24px; bottom: 24px; z-index: -1; width: 2px; border-radius: 2px; background: var(--line-strong);
}
.roadmap--git .stage-num { align-content: center; gap: 4px; }
.roadmap--git .stage-num::before {
  content: ""; position: absolute; inset: 0; z-index: -1; border-radius: 50%; background: var(--tint);
  box-shadow: inset 0 0 0 2px var(--accent-ink); opacity: clamp(0, (var(--p) * var(--n) - var(--i)) * 3, 1);
}
.roadmap--git .stage-num .bits { font-size: 11px; gap: 2px; }
.roadmap--git .bit { transition-delay: calc(260ms + var(--i) * 90ms); }
.roadmap--git .bit::before, .roadmap--git .bit::after { border-radius: 2px; font: 700 10px/1 var(--font-mono); }
.roadmap--git .stage-num small { font: 600 10px/1 var(--font-mono); letter-spacing: .04em; color: var(--text-3); }
.commit, .stage-body > .commit { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 0 0 var(--s-3); font: 500 12px/1.3 var(--font-mono); color: var(--text-3); }
.commit-hash { padding: 3px 8px; border-radius: var(--r-xs); background: var(--paper-2); box-shadow: inset 0 0 0 1px var(--line); color: var(--accent-text); }
.commit-head { font-weight: 700; color: var(--accent-text); opacity: 0; translate: -6px 0; transition: opacity var(--dur-ui) var(--ease-out), translate var(--dur-ui) var(--ease-out); }
.roadmap--git > li:is(:hover, :focus-within) .commit-head { opacity: 1; translate: 0 0; }
.git-branch { position: absolute; left: 0; top: 60px; width: 48px; height: calc(100% - 72px); overflow: visible; pointer-events: none; }
.git-branch path { stroke: var(--mark); stroke-width: 2.5; stroke-linecap: round; }
@media (max-width: 599px) { .roadmap--git::after, .git-branch { display: none; } .roadmap--git .stage-num .bits { font-size: 10px; } }
.releases { margin-top: var(--s-7); }
.release-tag {
  position: relative; align-self: flex-start; margin: 0 0 var(--s-3); padding: 4px 10px 4px 24px; border-radius: var(--r-pill);
  background: var(--tint); font: 600 12px/1.3 var(--font-mono); color: var(--accent-text);
}
.release-tag::before { content: ""; position: absolute; left: 10px; top: 50%; width: 7px; height: 7px; margin-top: -3.5px; border-radius: 50%; background: var(--accent-ink); }

/* §14.5 AI & Machine Learning track */
.track-meta { list-style: none; display: flex; flex-wrap: wrap; gap: 8px; margin: var(--s-5) 0 0; padding: 0; }
.track-meta li { margin: 0; padding: 6px 12px; border-radius: var(--r-pill); background: var(--tint); box-shadow: inset 0 0 0 1px var(--line); font-size: 14px; line-height: 1.35; color: var(--text); }
.track-meta strong { color: var(--accent-text); }
.ml-grid { display: grid; gap: var(--s-7); align-items: start; }
@media (min-width: 960px) { .ml-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--s-8); } }
.ml-fig { margin: 0; }
/* wide: the figure rides along beside the longer track list instead of leaving the column empty */
@media (min-width: 960px) { .ml-fig { position: sticky; top: calc(var(--stick-top-ui) + 24px); } }
.ml-body { display: grid; gap: var(--s-5); padding: clamp(18px, 2.5vw, 28px); }
.ml-split { display: grid; grid-template-columns: minmax(0, 1fr) minmax(28%, auto); margin: 0; max-width: none; overflow: hidden; border-radius: var(--r-sm); font: 600 12px/1.3 var(--font-mono); color: var(--term-ink); }
.ml-train { padding: 8px 10px; background: rgba(230,242,236,.10); }
.ml-test { padding: 8px 10px; background: rgba(62,230,181,.24); text-align: center; white-space: nowrap; }
.ml-bars { display: grid; gap: 16px; }
.ml-row { display: grid; grid-template-columns: minmax(0, 10rem) minmax(0, 1fr) 3.25rem; align-items: center; gap: 12px; margin: 0; max-width: none; font: 500 13px/1.35 var(--font-mono); color: var(--term-ink); }
.ml-track { position: relative; height: 14px; border-radius: var(--r-pill); background: rgba(230,242,236,.08); }
.ml-track i { position: absolute; inset: 0; border-radius: inherit; transform-origin: left; transform: scaleX(var(--v)); }
.ml-base .ml-track i { background: var(--tok-c); }
.ml-model .ml-track i { background: var(--sorted); }
.ml-track::after { content: ""; position: absolute; left: 50%; top: -5px; bottom: -5px; border-left: 2px dashed var(--amber); }
.ml-val { text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; }
.ml-model .ml-val { color: var(--sorted); }
.ml-note { margin: 0; max-width: none; font: 400 13px/1.5 var(--font-mono); }
@media (max-width: 479px) { .ml-row { grid-template-columns: minmax(0, 1fr) 3.25rem; row-gap: 6px; } .ml-label { grid-column: 1 / -1; } }
.ml-mods { list-style: none; margin: 0; padding: 0; display: grid; }
.ml-mod { position: relative; margin: 0; padding: var(--s-4) 0 var(--s-4) 60px; box-shadow: inset 0 -1px 0 var(--line); }
.ml-mod:first-child { padding-top: 0; }
.ml-mod:last-child { box-shadow: none; padding-bottom: 0; }
.ml-mod-num {
  position: absolute; left: 0; top: var(--s-4); display: grid; place-items: center; width: 42px; height: 30px; border-radius: var(--r-xs);
  background: var(--tint); font: 700 13px/1 var(--font-mono); color: var(--accent-text);
}
.ml-mod:first-child .ml-mod-num { top: 0; }
.ml-mod h3 { margin: 0 0 .25em; font-size: 1.1875rem; line-height: 1.3; }
.ml-mod p { margin: 0; color: var(--text-2); }
.ai-rule {
  margin-top: var(--s-8); padding: clamp(24px, 1.25rem + 2vw, 48px); border-radius: var(--r-tile);
  background: var(--spark-tint); box-shadow: inset 0 0 0 1px rgba(143,58,98,.2); color: var(--ink-2);
}
.ai-rule-kicker { margin: 0 0 var(--s-3); color: var(--spark-ink); }
.ai-rule-text { margin: 0; max-width: 40em; font: 400 var(--fs-lead)/1.32 var(--font-serif); letter-spacing: -.005em; color: var(--ink); }
.ai-rule-who { margin: var(--s-4) 0 0; max-width: 52em; font-size: 15px; color: var(--ink-2); }

/* ---------------------------------------------------------------- 08 */
/* §14.3.3 Test prep */
.exam-grid { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--gap); }
/* 4 exams: 1 → 2 → 4 columns (never a 3 + 1 orphan row) */
@media (min-width: 640px) { .exam-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1100px) { .exam-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.exam { margin: 0; box-shadow: var(--shadow-1), inset 0 3px 0 var(--mark), inset 0 0 0 1px var(--line); }
.exam h3 { margin: 0 0 .35em; font-size: 1.1875rem; line-height: 1.3; }
.exam p:last-child { margin: 0; font-size: 15px; color: var(--text-2); }
.exam-tag { margin: 0 0 var(--s-3); color: var(--accent-text); }
.prep-method { margin-top: var(--s-8); }
.prep-title { margin: 0 0 var(--s-6); }
.prep-steps { position: relative; list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-6); }
.prep-steps::before, .prep-steps::after {
  content: ""; position: absolute; left: 25px; top: 15px; bottom: 15px; width: 2px; border-radius: 2px; background: var(--line-strong);
}
.prep-steps::after { background: var(--mark); transform-origin: top; transform: scaleY(var(--p)); }
.prep-step { position: relative; margin: 0; padding-left: 72px; }
.prep-num {
  position: absolute; left: 0; top: 0; z-index: 1; display: inline-flex; align-items: center; min-height: 30px; padding: 0 9px;
  border-radius: var(--r-pill); background: var(--accent-ink); color: var(--white); font: 700 13px/1 var(--font-mono);
  transition: background-color var(--dur-ui) var(--ease-out), color var(--dur-ui), box-shadow var(--dur-ui);
}
.prep-step h4 { margin: 3px 0 .3em; font-size: 1.1875rem; }
.prep-step p { margin: 0; color: var(--text-2); }
@media (min-width: 860px) {
  .prep-steps { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .prep-steps::before, .prep-steps::after { left: 0; right: 0; top: 14px; bottom: auto; width: auto; height: 2px; }
  .prep-steps::after { transform-origin: left; transform: scaleX(var(--p)); }
  .prep-step { padding: 48px 0 0; }
  .prep-step h4 { margin-top: 0; }
}

/* ---------------------------------------------------------------- 09 */
/* C6 band: a scanline layer that slides with the band's entrance (--p of
   its own entry scrub), then rests. Transform-only. */
[data-theme="cs"] #pencil-ai::after {
  content: ""; position: absolute; inset: 0 0 -60px; z-index: -1; pointer-events: none;
  background: repeating-linear-gradient(to bottom, rgba(62,230,181,.04) 0 1px, transparent 1px 4px);
  transform: translateY(calc(var(--p) * -60px));
}
/* AI column: items are stack frames (pushed after the pencil ticks) */
[data-theme="cs"] .duo .is-ai .check-list { counter-reset: frm; }
[data-theme="cs"] .duo .is-ai .check-list li { counter-increment: frm; display: flex; flex-direction: column; }
[data-theme="cs"] .duo .is-ai .check-list li::before { top: calc(17px + .2em); }
[data-theme="cs"] .duo .is-ai .check-list li::after {
  content: "frame " counter(frm); content: "frame " counter(frm) / ""; order: -1; margin-bottom: 3px;
  font: 500 11px/1.3 var(--font-mono); letter-spacing: .04em; color: var(--text-3);
}
.ai-echo {
  position: relative; max-width: 52rem; margin: var(--s-6) 0 0; padding: var(--s-5) var(--s-5) var(--s-5) 56px; border-radius: var(--r-lg);
  background: rgba(227,154,181,.08); box-shadow: inset 0 0 0 1px rgba(227,154,181,.3);
  font: 400 var(--fs-read)/1.55 var(--font-serif); color: var(--text);
}
.ai-echo-mark { position: absolute; left: 22px; top: var(--s-5); font-size: 1.1em; line-height: 1.4; color: var(--spark-text); }

/* ---------------------------------------------------------------- 10 */
/* C7 stack-trace story: one terminal, editor / call stack / console */
.trace-fig { display: flex; flex-direction: column; }
.trace-grid {
  display: grid; gap: 12px 16px; padding: 14px 16px 16px; font: 400 12px/1.55 var(--font-mono); color: var(--term-ink);
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  grid-template-areas: "editor editor" "slip stack" "console console" "bubble bubble";
}
@media (min-width: 900px) {
  .trace-grid {
    gap: 14px 18px; padding: 18px 20px 20px; font-size: var(--fs-mono-sm); line-height: 1.6;
    grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
    grid-template-areas: "editor slip" "editor stack" "console console" "bubble bubble";
  }
}
@media (max-width: 479px) { .trace-grid { gap: 10px 12px; padding: 12px; font-size: 11px; } .trace-grid .trace-console, .trace-grid .trace-editor { padding-inline: 10px; } }
.trace-editor {
  grid-area: editor; margin: 0; padding: 10px 12px; overflow-x: auto; border-radius: var(--r-sm);
  background: rgba(230,242,236,.04); box-shadow: inset 0 0 0 1px var(--line); font: inherit; color: var(--term-ink);
}
.trace-editor code { font: inherit; }
.cl { display: block; margin: 0; max-width: none; white-space: pre; }
.cl-add { position: relative; border-radius: 3px; background: rgba(62,230,181,.12); }
.cl-add::before { content: "+"; content: "+" / ""; position: absolute; left: .5ch; font-weight: 700; color: var(--sorted); }
.cl-err { padding-left: 10px; box-shadow: inset 3px 0 0 var(--swp); color: var(--swp); }
.trace-grid .slip {
  grid-area: slip; align-self: start; justify-self: start; margin: 4px 0 0; padding: 10px 14px; rotate: -2deg;
  background-color: var(--hl-claim); font: 400 15px/1.35 var(--font-serif); color: var(--ink);
}
.trace-stack { grid-area: stack; min-width: 0; }
.trace-label { margin: 0 0 6px; font: 600 11px/1.3 var(--font-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--text-3); }
.trace-fig .callstack { gap: 5px; overflow: clip; } /* frames push in from (and pop out through) the top edge, never over the label */
.trace-fig .frame { padding: 5px 9px; font-size: 12px; background: rgba(230,242,236,.05); overflow-wrap: anywhere; }
.trace-fig .callstack .frame:last-child { box-shadow: inset 3px 0 0 var(--amber), inset 0 0 0 1px var(--line-strong); }
.trace-console {
  grid-area: console; min-width: 0; padding: 10px 12px; overflow-x: auto; border-radius: var(--r-sm);
  background: rgba(0,0,0,.28); box-shadow: inset 0 0 0 1px var(--line);
}
.spark-line { color: var(--spark-text); }
.bubble {
  grid-area: bubble; justify-self: end; max-width: 22rem; margin: 0; padding: 10px 14px; border-radius: 16px 16px 4px 16px;
  background: var(--cream); font: 500 14px/1.45 var(--font-sans); color: var(--ink);
}
/* the shared CS "0" prefix is a ::before grid item: lay it out inline ("01"), not stacked */
/* test-report chips on the step headings (silent: the headings carry the meaning) */
[data-theme="cs"] .story-steps > li > h3 { padding-right: 5.5em; }
[data-theme="cs"] .story-steps > li::after {
  content: "✓ PASS"; content: "✓ PASS" / ""; position: absolute; right: 0; top: 4px;
  font: 700 11px/1.3 var(--font-mono); letter-spacing: .08em; color: var(--accent-text);
}

/* ---------------------------------------------------------------- 11 */
/* C8 closing CTA: "$ book --intro-call" types above the button */
.cta-cmd {
  display: flex; align-items: center; gap: 4px; width: fit-content; max-width: 100%; margin: 0 auto var(--s-5);
  padding: 10px 18px; border-radius: var(--r-pill); font: 500 15px/1.4 var(--font-mono); box-shadow: var(--shadow-2);
}
.cta-cmd::after { content: ""; flex: none; width: .6em; height: 1.15em; background: var(--amber); }

/* ---------------------------------------------------------------- 12 */
@keyframes cs-caret-follow { from { translate: calc(-7 * (1ch - .04em)) 0; } to { translate: 0 0; } }
@keyframes cs-spin { 0% { opacity: 1; rotate: 0deg; } 99.9% { opacity: 1; rotate: 720deg; } 100% { opacity: 0; rotate: 720deg; } }

/* ---------------------------------------------------------------- 13 */
/* =====================================================================
   RULE-10 BLOCK — hidden starting states for this theme only.
   ===================================================================== */
@media screen and (prefers-reduced-motion: no-preference) {

  /* C1 typed wordmark: each line types in character steps, the amber
     caret rides line 2, then blinks 5× and stays solid (ends ≤ 5 s) */
  /* steps(n, jump-start): the last step lands at (n-1)/n, so float error at
     the end of a fractional duration can never leave the final glyph clipped */
  .motion-ok .wm-cs .wm-line { clip-path: inset(0 100% 0 0); animation: type-in 450ms steps(var(--chars), jump-start) 100ms forwards; }
  .motion-ok .wm-cs .wm-line:nth-child(2) { animation-duration: 400ms; animation-delay: 550ms; }
  .motion-ok .wm-cs .wm-caret {
    animation: cs-caret-follow 400ms steps(7) 550ms both, fade-in 1ms linear 550ms both, caret 800ms steps(1) 1000ms 5;
  }

  /* C2 terminal: the output line waits on a spinner, then pops; the ✓
     comment turns green and the caret blinks once typing is done */
  .motion-ok [data-motion~="type"] .tl-out[data-type-line] { clip-path: none; }
  .motion-ok [data-motion~="type"]:not(.is-in) .out-v { opacity: 0; }
  .motion-ok [data-motion~="type"].is-in .out-v { animation: pop-in 360ms var(--ease-pop) var(--type-delay) both; }
  .motion-ok [data-motion~="type"].is-in .tl-out::before {
    content: ""; position: absolute; left: .1em; top: 50%; width: .85em; height: .85em; margin-top: -.425em; opacity: 0;
    border: 2px solid var(--tok-c); border-right-color: transparent; border-radius: 50%;
    animation: cs-spin 600ms steps(8) calc(var(--type-delay) - 600ms) forwards;
  }
  .motion-ok .term-fig .term-body:not(.is-done) .tok-ok { color: var(--tok-c); }
  .motion-ok .term-fig .tok-ok { transition: color 400ms var(--ease-out); }
  .motion-ok .term-fig .term-body:not(.is-done)::after { opacity: 0; }
  .motion-ok .term-fig .term-body.is-done::after { animation: caret 800ms steps(1) 5; }

  /* C5 roadmap: cards slide from the branch, bits flip to the stage number */
  .motion-ok .roadmap--git > li.reveal:not(.is-visible) { transform: translateX(-16px); }
  .motion-ok .roadmap--git > li.reveal:not(.is-visible) .bit { transform: none; }

  /* §14.3.1 example plans: the first three sessions arrive in order */
  .motion-ok .plan-demo.is-visible .plan-card:not([hidden]) .plan-sessions li { animation: rise-in 420ms var(--ease-out) 200ms both; }
  .motion-ok .plan-demo.is-visible .plan-card:not([hidden]) .plan-sessions li:nth-child(2) { animation-delay: 290ms; }
  .motion-ok .plan-demo.is-visible .plan-card:not([hidden]) .plan-sessions li:nth-child(3) { animation-delay: 380ms; }

  /* §14.5 model vs baseline: bars grow with the reader (baseline first) */
  .motion-ok .ml-fig .ml-base .ml-track i { transform: scaleX(calc(var(--v) * var(--pe))); }
  .motion-ok .ml-fig .ml-model .ml-track i { transform: scaleX(calc(var(--v) * clamp(0, var(--pe) * 1.35 - .35, 1))); }

  /* §14.3.3 prep pipeline: steps light up as the line reaches them */
  .motion-ok .prep-steps[data-step-active="0"] .prep-step:nth-child(n+2) .prep-num,
  .motion-ok .prep-steps[data-step-active="1"] .prep-step:nth-child(n+3) .prep-num {
    background: var(--card-bg); color: var(--text-3); box-shadow: inset 0 0 0 1.5px var(--line-strong);
  }

  /* C6 AI column: frames push down from above, after the pencil ticks */
  .motion-ok [data-theme="cs"] .duo:not(.is-in) .is-ai .check-list li { opacity: 0; translate: 0 -100%; }
  .motion-ok [data-theme="cs"] .duo .is-ai .check-list li {
    transition: opacity 260ms var(--ease-out) calc(760ms + var(--li) * 120ms), translate 420ms var(--ease-out) calc(760ms + var(--li) * 120ms);
  }

  /* C7 story: chips read RUNNING on the current step, PASS once passed;
     on phones the student's answer replaces the prediction slip */
  .motion-ok [data-theme="cs"] .story:is(.is-pinned, .is-player) .story-steps > li:not(.is-past)::after { content: none; }
  .motion-ok [data-theme="cs"] .story:is(.is-pinned, .is-player) .story-steps > li.is-active::after { content: "RUNNING"; content: "RUNNING" / ""; color: var(--text-3); }
  /* p = 1 must read finished: the last step passes too */
  .motion-ok [data-theme="cs"] .story:is(.is-pinned, .is-player) .story-stage.is-complete .story-steps > li.is-active::after { content: "✓ PASS"; content: "✓ PASS" / ""; color: var(--accent-text); }
  @media (max-width: 899px) {
    .motion-ok .story:is(.is-pinned, .is-player) .trace-grid .bubble { grid-area: slip; align-self: start; }
    .motion-ok .story:is(.is-pinned, .is-player) .trace-grid { grid-template-areas: "editor editor" "slip stack" "console console"; }
    .motion-ok .story:is(.is-pinned, .is-player) .trace-grid .slip { opacity: calc(var(--on) * (1 - clamp(0, (var(--step) + var(--step-p) - 3.1) / .2, 1))); }
  }

  /* C8 CTA: the caret waits for the command, then blinks 5× */
  .motion-ok .cta-cmd:not(.is-done)::after { opacity: 0; }
  .motion-ok .cta-cmd.is-done::after { animation: caret 800ms steps(1) 5; }
}
