/* GSM8K live — paper page, two terminals.
 *
 * The palette, the type and the geometry come from the Claude Design imports:
 * warm paper, a Newsreader masthead, IBM Plex Mono for machine text, Libre
 * Franklin for labels, and two dark terminals side by side as the whole point
 * of the screen. Everything the demo needs that the mock did not have — the
 * container-boot banner, the queued state, the honesty notes — is built from
 * the same tokens rather than bolted on in a different accent.
 */

:root {
  --paper: #faf9f6;
  --card: #fdfdfb;
  --ink: #1b1a17;
  --rule: rgba(27, 26, 23, 0.16);
  --rule-soft: rgba(27, 26, 23, 0.10);
  --muted: rgba(27, 26, 23, 0.55);
  --faint: rgba(27, 26, 23, 0.45);
  --ghost: rgba(27, 26, 23, 0.30);

  --green: oklch(0.52 0.11 150);
  --green-deep: oklch(0.42 0.09 150);
  --amber: oklch(0.55 0.13 72);
  --red: oklch(0.52 0.16 28);

  /* the terminals */
  --term-bg: #15161a;
  --term-bar: #1d1f24;
  --term-line: #2a2d33;
  --term-dot: #3b3f46;
  --term-title: #8b9099;
  --term-clock: #6d727a;
  --t-txt: #d7dae0;
  --t-dim: #7b8189;
  --t-echo: #aab0b9;
  --t-key: #a8b6ff;
  --t-num: #f0c987;
  --t-out: #7fe0a8;
  --t-err: #f08a72;
  --t-warn: #e8c07a;
  --t-caret: oklch(0.75 0.13 150);

  --serif: Newsreader, Georgia, "Times New Roman", serif;
  --sans: "Libre Franklin", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, "SF Mono", "DejaVu Sans Mono", Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }

/* The UA [hidden] rule loses to any class that sets `display` (.terminals is a
   grid, .caret-row is a flex box). Every beat on this page is toggled by the
   hidden attribute, so state it once and loudly. */
[hidden] { display: none !important; }

/* The page's base face is --sans, the face STYLE.md §2 assigns to labels and
   chrome. Mono is not a default anyone inherits: it is switched on exactly
   where a machine emitted the text — the terminals, code blocks, the shell
   sigil — because a page that sets it globally ends up with mono buttons and
   mono status chips, which is the thing the type system exists to prevent. */
html, body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

body { padding: 0 clamp(16px, 3vw, 40px) 96px; }

.wrap {
  width: 100%;
  max-width: 1240px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
}

b { font-weight: 700; }
.faint { color: var(--faint); }

/* ---------------- top bar + masthead ---------------- */

.topbar {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 20px;
  padding: 26px 0 22px;
  border-bottom: 1px solid rgba(27, 26, 23, 0.14);
}
/* The lab's wordmark, carried over from www.lateralintelligence.org so the two
   pages read as one site: a 10px square, an 11px gap, the name. The square is
   maroon there and --ink here — the marketing site's accent is #7c1f2b and this
   page's only accent is --green (STYLE.md §2: one accent, and a second hue is a
   redesign). Ink keeps the mark identical in every dimension that is not the
   one colour this page has already spent. */
.brand {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  font-family: var(--serif);
  font-size: 19px;
  letter-spacing: -0.01em;
  color: inherit;
  text-decoration: none;
  white-space: nowrap;
}
.brand .tick {
  width: 10px;
  height: 10px;
  flex: none;
  background: var(--ink);
}
.brand:hover .tick { background: var(--green); }
.nav {
  display: flex;
  gap: 22px;
  font-size: 11.5px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--muted);
}
.nav a { color: inherit; text-decoration: none; }
.nav a:hover { color: var(--green); }

.masthead { padding: 62px 0 44px; }
.masthead h1 {
  margin: 0;
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(28px, 4vw, 46px);
  line-height: 1.04;
  letter-spacing: -0.022em;
  text-wrap: balance;
}

/* ---------------- prose ----------------
   The written half of the page: one block above the demo, one below, both
   filled from Markdown by prose.js. The rules here are the ones long-form text
   needs and the rest of this page does not — a measure narrow enough to read
   (66 characters, not the 1240 px the terminals want), the serif that the
   masthead already established, and a size that survives a projector.

   Everything else stays in the demo's language: mono for code, tables and
   figure captions; the same green for links; the same hairline rules. A post
   and a demo on one page should look like one document. */

.prose {
  --measure: 66ch;
  font-family: var(--serif);
  font-size: 17.5px;
  line-height: 1.68;
  color: var(--ink);
  max-width: var(--measure);
  margin: 0 0 52px;
}
.prose-notes { margin: 74px 0 0; }

.prose > * { max-width: var(--measure); }
.prose p { margin: 0 0 1.05em; }
.prose > :first-child { margin-top: 0; }
.prose > :last-child { margin-bottom: 0; }

/* The lede: the first paragraph of the intro carries the weight of a standfirst
   under the masthead, so it is set larger and lighter than body text. prose.js
   tags it — :first-of-type would catch a raw-HTML dateline above it instead. */
.prose p.lede {
  font-size: 21px;
  line-height: 1.55;
  font-weight: 300;
  letter-spacing: -0.008em;
  color: var(--ink);
  margin-bottom: 1.1em;
}

.prose h2, .prose h3, .prose h4 {
  font-family: var(--serif);
  font-weight: 400;
  letter-spacing: -0.015em;
  line-height: 1.2;
  margin: 1.9em 0 0.5em;
  text-wrap: balance;
}
.prose h2 { font-size: 27px; }
.prose h3 { font-size: 21px; }
.prose h4 { font-size: 17.5px; font-weight: 500; }

.prose a { color: var(--green); text-decoration: none; border-bottom: 1px solid color-mix(in oklab, var(--green) 35%, transparent); }
.prose a:hover { border-bottom-color: var(--green); }
.prose b { font-weight: 600; }
.prose em { font-style: italic; }
.prose hr { border: 0; border-top: 1px solid var(--rule); margin: 2.4em 0; }

.prose ul, .prose ol { margin: 0 0 1.05em; padding-left: 1.3em; }
.prose li { margin: 0.25em 0; }
.prose li::marker { color: var(--faint); }

.prose blockquote {
  margin: 1.4em 0;
  padding-left: 18px;
  border-left: 2px solid color-mix(in oklab, var(--green) 45%, transparent);
  color: var(--muted);
}
.prose blockquote p:last-child { margin-bottom: 0; }

/* Code keeps the demo's voice: mono, the terminal's key colour for inline
   spans, a bordered card for blocks. */
.prose code {
  font-family: var(--mono);
  font-size: 0.82em;
  color: var(--green-deep);
  background: color-mix(in oklab, var(--green) 7%, transparent);
  padding: 0.1em 0.34em;
  border-radius: 3px;
}
.prose pre {
  font-family: var(--mono);
  font-size: 12.5px;
  line-height: 1.6;
  background: var(--term-bg);
  color: var(--t-txt);
  border-radius: 6px;
  padding: 16px 18px;
  overflow-x: auto;
  margin: 1.4em 0;
}
.prose pre code { background: none; color: inherit; padding: 0; font-size: inherit; }

/* Tables and figures are allowed to break the measure — a table squeezed to
   66ch is a table nobody reads. They stop at the width of the terminals. */
.prose figure, .prose .table-scroll { max-width: min(920px, 100%); }

.prose figure {
  margin: 2em 0;
}
.prose figure img, .prose img { max-width: 100%; height: auto; display: block; }
/* Serif, like the prose it belongs to. A caption is a sentence, not data —
   setting it in the terminal's mono made it read as a readout. */
.prose figcaption {
  font-family: var(--serif);
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--muted);
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px solid var(--rule-soft);
}
.prose figcaption b { color: var(--ink); font-weight: 500; }

/* Tables read as prose too — same serif, one size down from body text. The
   mono version lined its columns up beautifully and looked like a log file in
   the middle of an essay; tabular-nums buys back the alignment that actually
   mattered, which was the digits. */
.prose .table-scroll { overflow-x: auto; margin: 1.7em 0; }
.prose table {
  border-collapse: collapse;
  width: 100%;
  font-family: var(--serif);
  font-size: 16px;
  font-variant-numeric: tabular-nums;
}
.prose th, .prose td {
  text-align: left;
  padding: 10px 26px 10px 0;
  border-bottom: 1px solid var(--rule-soft);
  vertical-align: baseline;
}
/* Only the last column runs to the edge. `:last-child` binds to one selector,
   so this must name both — as `.prose th, .prose td:last-child` it zeroed the
   padding on every header, and a right-aligned header then sat 26px right of
   the numerals it labels. */
.prose th:last-child, .prose td:last-child { padding-right: 0; }

/* A header is a label rather than a sentence, so it is sans — the face STYLE.md
   §2 assigns to every label on the page. It was mono until --sans existed, back
   when the only alternative to serif was the terminal's face; the uppercase
   tracking, not the face, is what separates it from the rows without asking for
   a heavier rule. */
.prose th {
  font-family: var(--sans);
  font-weight: 500;
  color: var(--faint);
  font-size: 10.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding-bottom: 7px;
  border-bottom-color: var(--rule);
  white-space: nowrap;
}
/* Row labels recede so the values carry the row; anything the writer marked
   with ** comes back to full ink wherever it sits. */
.prose td:first-child { color: var(--muted); }
.prose td b { color: var(--ink); font-weight: 600; }
.prose tbody tr:last-child td { border-bottom: 0; }

/* Two figures side by side: a raw HTML block in the Markdown,
   <div class="fig-row"> … </div>, with no blank line inside it. */
.prose .fig-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
  max-width: min(920px, 100%);
  margin: 2em 0;
}
.prose .fig-row figure { margin: 0; }

/* A dateline / byline: <p class="dateline">…</p> as a raw block. */
.prose .dateline {
  font-family: var(--sans);
  font-size: 11.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--faint);
  margin-bottom: 1.4em;
}

/* ---------------- an interactive figure: the decoding schematic ----------
   Imported from Claude Design ("Latent Refinement Figure.dc.html") and rebuilt
   on this page's tokens: the mock's greys are --muted/--faint/--rule, its
   accent is the one --green, and the faces are --sans for labels, --mono for
   cells, --serif for the two big letters. The markup is built by
   figure_refine.js into the raw-HTML <figure> in notes.md — if that script
   never runs, the figure is simply absent and the page reads on without it.

   Two rules of the figure section apply here as much as to a chart: colour by
   entity (green is the model under study, ink is the baseline) and no legend —
   each column is labelled at its own head. */

.prose .refine {
  /* The mock's #6c6a63 stated as what it is: ink, stepped back off paper. */
  --fig-base: color-mix(in oklab, var(--ink) 62%, var(--paper));
  font-family: var(--sans);
  margin: 26px 0 0;
}

/* the strip above the panels: state on the left, replay on the right. Every
   selector here is scoped to .prose — inside a prose block, `.prose p` and
   `.prose b` would otherwise outrank a bare class and put a paragraph margin
   or a 600 weight back. */
.prose .refine-head { display: flex; align-items: center; gap: 14px; margin-bottom: 26px; }
.prose .refine-state {
  font-size: 11.5px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--faint);
}
.prose .refine-head hr { flex: 1; border: 0; border-top: 1px solid var(--rule); margin: 0; }
.prose .refine-replay {
  font-family: var(--sans);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 9px 16px;
  background: transparent;
  color: var(--muted);
  border: 1px solid var(--ghost);
  cursor: pointer;
}
.prose .refine-replay:hover { border-color: var(--ink); color: var(--ink); }

/* one hairline between the panes, one above and below the pair */
.prose .refine-panes {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1px;
  background: var(--rule);
  border-top: 1px solid var(--muted);
  border-bottom: 1px solid var(--muted);
}
.prose .refine-pane { background: var(--paper); padding: 30px 34px 34px 4px; }
.prose .refine-pane + .refine-pane { padding: 30px 4px 34px 34px; }

.prose .refine-title { display: flex; align-items: baseline; gap: 12px; margin-bottom: 6px; }
.prose .refine-swatch { width: 11px; height: 11px; background: var(--fig-base); }
.prose .refine-lat .refine-swatch { background: var(--green); }
.prose .refine-name { font-size: 14px; font-weight: 600; letter-spacing: -0.01em; }
.prose .refine-kind { font-size: 12px; color: var(--muted); }
.prose .refine-how { font-size: 12px; color: var(--muted); margin: 0 0 28px 23px; }

.prose .refine-rows { display: flex; flex-direction: column; gap: 7px; }

/* A row is dim until the pass that produces it has run. Opacity only: the
   cells must not move, or the eye reads the animation as layout. */
.prose .refine-row { display: flex; align-items: center; gap: 12px; opacity: 0.12; transition: opacity 180ms linear; }
.prose .refine-row[data-on] { opacity: 1; }
.prose .refine-tag {
  width: 62px;
  flex: none;
  /* a label a person wrote, not a token the model emitted — sans, like every
     other figure label (the cells below are the mono half of this figure) */
  font-family: var(--sans);
  font-size: 10.5px;
  color: var(--faint);
  text-align: right;
}
.prose .refine-lat .refine-tag { text-align: left; width: 74px; }
.prose .refine-cells { flex: 1; display: flex; gap: 5px; min-width: 0; }
.prose .refine-cell {
  flex: 1;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: -0.01em;
  border: 1px solid var(--rule);
  background: transparent;
  color: transparent;
}
/* the transformer's three states: not yet reached, being emitted now, fixed */
.prose .refine-cell[data-cell="emit"] { background: var(--fig-base); border-color: var(--fig-base); color: var(--paper); }
.prose .refine-cell[data-cell="done"] { background: color-mix(in oklab, var(--fig-base) 13%, var(--paper)); color: var(--ink); }
.prose .refine-cell[data-cell="out"] {
  background: color-mix(in oklab, var(--green) 14%, var(--paper));
  border-color: var(--green);
  color: var(--ink);
}

/* the latent column: a bracket down the side, labelled once */
.prose .refine-loop { display: flex; gap: 12px; }
.prose .refine-rail { width: 62px; flex: none; position: relative; }
.prose .refine-rail span {
  position: absolute;
  top: 50%;
  right: 20px;
  transform: translateY(-50%) rotate(-90deg);
  transform-origin: right center;
  font-family: var(--sans);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
}
.prose .refine-rail::before {
  content: "";
  position: absolute;
  top: 8px;
  bottom: 56px;
  right: 0;
  width: 14px;
  border: 1px solid var(--ghost);
  border-right: 0;
}
.prose .refine-stack { flex: 1; display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.prose .refine-arrows { padding: 10px 0 4px; }
.prose .refine-arrows .refine-cells > div { flex: 1; text-align: center; font-size: 11px; color: var(--faint); }
.prose .refine-arrows .refine-tag { color: var(--green-deep); }

/* The count each column pays, in the serif that carries every other result on
   the page. .refine-gutter is the rail's width without the bracket — the
   bracket is an absolutely-positioned pseudo-element and must not be inherited
   by a second box that only exists to hold the rule off the left edge. */
.prose .refine-cost { display: flex; gap: 12px; margin-top: 20px; }
.prose .refine-gutter { width: 62px; flex: none; }
.prose .refine-cost p {
  flex: 1;
  border-top: 1px solid var(--ghost);
  padding-top: 12px;
  margin: 0;
  display: flex;
  align-items: baseline;
  gap: 10px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--muted);
}
.prose .refine-cost b {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 28px;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--ink);
}

@media (max-width: 700px) {
  .prose { font-size: 16.5px; }
  .prose p.lede { font-size: 19px; }
  .prose .fig-row { grid-template-columns: 1fr; }
  /* Stacked, each pane gets the full measure and the gap between them becomes
     the rule under one and over the next. */
  .prose .refine-panes { grid-template-columns: 1fr; }
  .prose .refine-pane, .prose .refine-pane + .refine-pane { padding: 26px 0 30px; }
  .prose .refine-tag, .prose .refine-lat .refine-tag,
  .prose .refine-rail, .prose .refine-gutter { width: 46px; }
  .prose .refine-rail span { right: 14px; }
}

/* ---------------- the question ---------------- */

.prompt {
  border: 1px solid var(--rule);
  background: var(--card);
  padding: 26px 28px 20px;
}

.prompt-row { display: flex; gap: 14px; align-items: flex-start; }
.prompt-sigil {
  /* a shell prompt, so mono — the one machine character above the fold */
  font-family: var(--mono);
  font-size: 20px;
  line-height: 1.5;
  color: var(--green);
  padding-top: 2px;
}

#prompt {
  flex: 1;
  min-width: 0;
  border: 0;
  outline: none;
  resize: none;
  min-height: 150px;
  overflow: hidden;
  background: transparent;
  color: var(--ink);
  font-family: var(--serif);
  font-size: 21px;
  line-height: 1.5;
  letter-spacing: -0.005em;
}
#prompt::placeholder { color: var(--ghost); }

.prompt-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--rule-soft);
}
.prompt-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  font-size: 11px;
  color: var(--faint);
}
.q-id { letter-spacing: 0.005em; }
.q-id b { color: var(--muted); font-weight: 500; }

.chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 11px;
  letter-spacing: 0.005em;
  border: 1px solid var(--rule);
  padding: 3px 9px;
  color: var(--muted);
  white-space: nowrap;
}
.chip .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--ghost); }
.chip[data-warm="true"] { color: var(--green); border-color: color-mix(in oklab, var(--green) 45%, transparent); }
.chip[data-warm="true"] .dot { background: var(--green); }
.chip[data-warm="false"] { color: var(--amber); border-color: color-mix(in oklab, var(--amber) 45%, transparent); }
.chip[data-warm="false"] .dot { background: var(--amber); }
.chip-fixture { color: var(--ink); border-color: var(--rule); }

.prompt-actions { display: flex; gap: 10px; margin-left: auto; }
/* Buttons say what the markup says. No text-transform: a label is written in
   index.html or set in app.js, and reading the source should tell you what the
   room sees. Sentence case also needs far less tracking than caps did. */
.btn {
  /* A <button> does not inherit the page face — the UA gives it its own stack,
     so an unstated font here is Arial, not --sans. State it. */
  font-family: inherit;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.005em;
  padding: 11px 18px;
  background: transparent;
  color: rgba(27, 26, 23, 0.7);
  border: 1px solid rgba(27, 26, 23, 0.22);
  cursor: pointer;
  white-space: nowrap;
}
.btn:hover:not(:disabled) { border-color: var(--ink); color: var(--ink); }
.btn:disabled { opacity: 0.45; cursor: default; }
.btn-go {
  padding: 11px 22px;
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
}
.btn-go:hover:not(:disabled) { background: var(--green-deep); border-color: var(--green-deep); color: var(--paper); }
.btn-go:disabled { opacity: 0.5; }

/* fixture rehearsal chips — only the questions recorded offline can play */
.highlights {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--rule-soft);
}
.hl-label {
  font-size: 11px;
  letter-spacing: 0.005em;
  color: var(--faint);
}
#highlight-buttons { display: flex; gap: 6px; flex-wrap: wrap; }
.btn-hl {
  padding: 5px 10px;
  font-size: 11px;
  letter-spacing: 0.005em;
}
.btn-hl[data-cell="both"]:hover { border-color: var(--green); color: var(--green); }
.btn-hl[data-cell="neither"]:hover { border-color: var(--red); color: var(--red); }
.btn-hl[data-cell]:not([data-cell="both"]):not([data-cell="neither"]):hover {
  border-color: var(--amber); color: var(--amber);
}

/* ---------------- container boot, and nothing else ----------------
   Same paper card as everything else, but the only amber rule on the page, so
   it cannot be read as a terminal and cannot be read as "the model is slow". */

.boot {
  margin-top: 24px;
  padding: 20px 24px;
  background: var(--card);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--amber);
}
.boot-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.boot-title {
  font-size: 12.5px;
  letter-spacing: 0.005em;
  font-weight: 600;
  color: var(--amber);
}
.boot-elapsed {
  margin-left: auto;
  font-size: 17px;
  color: var(--amber);
  font-variant-numeric: tabular-nums;
}
.boot-sub {
  margin: 10px 0 0;
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--muted);
  max-width: 100ch;
}
.boot-sub b { color: var(--ink); }
.boot-sub code { font-family: var(--mono); color: var(--green); }
#boot-sub2 { margin-top: 4px; }

.spinner {
  width: 12px; height: 12px;
  flex: none;
  border: 2px solid color-mix(in oklab, var(--amber) 30%, transparent);
  border-top-color: var(--amber);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------------- the terminals ----------------
   data-arms comes from model.arms.length. Two today; the count is a data
   change, not a layout change. */

.terminals {
  display: grid;
  grid-template-columns: 1fr;
  gap: 26px;
  margin-top: 30px;
  /* stretch, so two terminals are always the same height: a shorter program
     leaves blank screen, exactly like a real terminal, rather than shrinking
     its box and breaking the side-by-side read */
  align-items: stretch;
}
.terminals[data-arms="2"] { grid-template-columns: 1fr 1fr; }
.terminals[data-arms="3"] { grid-template-columns: repeat(3, 1fr); }
/* Two 380px terminals side by side is two unreadable terminals. */
@media (max-width: 900px) {
  .terminals[data-arms="2"], .terminals[data-arms="3"] { grid-template-columns: 1fr; }
}

.term-col { display: flex; flex-direction: column; min-width: 0; }

.term {
  /* Everything inside a terminal is machine text: the title bar, the clock, the
     echoed question, the program, stdout, the verdict. One declaration here,
     inherited by all of it, and nothing outside this box gets mono for free. */
  font-family: var(--mono);
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: var(--term-bg);
  border: 1px solid var(--term-bg);
  box-shadow: 0 18px 44px rgba(27, 26, 23, 0.16);
}

.term-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 14px;
  background: var(--term-bar);
  border-bottom: 1px solid var(--term-line);
}
.dots { display: flex; gap: 6px; flex: none; }
.dots i { width: 9px; height: 9px; border-radius: 50%; background: var(--term-dot); }
.term-title {
  flex: 1;
  text-align: center;
  font-size: 11px;
  color: var(--term-title);
  letter-spacing: 0.04em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.term-clock {
  flex: none;
  font-size: 11px;
  color: var(--term-clock);
  font-variant-numeric: tabular-nums;
}
/* the live stopwatch stays quiet; the server's own meta.seconds is the number
   that matters, and it replaces this the moment the response lands */
.term-clock[data-live] { opacity: 0.75; }
.term-clock[data-final] { color: var(--t-out); }
.term[data-state="queued"] .term-clock { color: var(--t-warn); }
.term[data-state="failed"] .term-clock { color: var(--t-err); }

.term-body {
  flex: 1;
  padding: 18px 18px 22px;
  min-height: 560px;
  max-height: 72vh;
  overflow: auto;
  font-size: 12.5px;
  line-height: 1.62;
  color: var(--t-txt);
  font-variant-ligatures: none;
}

/* one printed line */
.tl { white-space: pre; font-variant-ligatures: none; }
.tl.dim { color: var(--t-dim); }
.tl.soft { color: var(--t-dim); opacity: 0.7; }
.tl.echo { color: var(--t-echo); }
.tl.out { color: var(--t-out); }
.tl.key { color: var(--t-key); }
.tl.err { color: var(--t-err); }
.tl.warn { color: var(--t-warn); }
/* The returned value is the answer, and it used to be set at 19px to make it
   the loudest thing on screen. It read as a slide, not as a terminal: no shell
   prints one line of stdout at 1.5x the rest. Colour and weight carry the
   emphasis instead — both are things a real terminal can actually do — and
   every line in the body is now the same size. */
.tl.num {
  color: var(--t-num);
  font-weight: 700;
}
.tl.grade { font-weight: 700; letter-spacing: 0.04em; white-space: pre-wrap; }
.tl.err { white-space: pre-wrap; }
.tl.grade.ok { color: var(--t-out); }
.tl.grade.bad { color: var(--t-err); }
.tl.grade.none { color: var(--t-warn); }
.tl.wrapped { white-space: pre-wrap; }

/* The generated program, typed in.
   pre-wrap, not pre: these are real model outputs and a docstring line runs
   well past 80 columns. On a projector, a line nobody can scroll to is a line
   nobody reads, so long lines fold instead of disappearing off the right edge. */
.t-code {
  display: block;
  white-space: pre-wrap;
  overflow-wrap: break-word;
  font-family: inherit;
  font-size: inherit;
  color: var(--t-txt);
}
.t-code .k { color: var(--t-key); }
.t-code .c { color: var(--t-dim); }
.t-code.typing::after {
  content: "\2588";
  color: var(--t-caret);
}

.caret-row { display: flex; gap: 8px; color: #9aa1ab; padding-top: 2px; }
.c-sig { color: var(--t-caret); }
.c-blk {
  width: 8px; height: 15px;
  background: var(--t-txt);
  display: inline-block;
  animation: blink 1.06s steps(1) infinite;
}
@keyframes blink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  .spinner, .c-blk { animation: none; }
}

.term-meta {
  padding: 12px 2px 0;
  font-size: 11px;
  color: var(--faint);
}

.skip-hint {
  text-align: center;
  color: var(--faint);
  font-size: 11px;
  margin: 16px 0 0;
}

.footer {
  display: flex;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
  margin-top: 74px;
  padding-top: 20px;
  border-top: 1px solid rgba(27, 26, 23, 0.14);
  font-size: 11px;
  color: var(--faint);
}

.boot-error {
  margin: 24px 0 0;
  padding: 14px 18px;
  background: var(--card);
  border: 1px solid var(--red);
  border-left: 3px solid var(--red);
  color: var(--red);
  font-size: 12.5px;
}

/* terminal scrollbars, dark to match the box they live in */
.term-body::-webkit-scrollbar { width: 9px; height: 9px; }
.term-body::-webkit-scrollbar-track { background: var(--term-bg); }
.term-body::-webkit-scrollbar-thumb { background: #2f333a; }
.term-body::-webkit-scrollbar-thumb:hover { background: #3d424a; }
