/* ───────────────────────────────────────────────────────────────
 * cold-solve cinema — "archival research dossier" skin.
 *
 * Warm near-black paper, a single oxidized-amber accent, serif body
 * + mono labels. Palette and primitives are lifted from the
 * cold-solve design system (web/dossier.css / web/timeline.css) so
 * the operator viewer reads as part of the same publication.
 *
 * Legacy token names (--bg-elev, --text-dim, --insight, …) are kept
 * as aliases pointing at the new palette so the player's existing
 * colour rules resolve without a rename sweep.
 * ─────────────────────────────────────────────────────────────── */

:root {
  /* ── Type stacks ── */
  --ff-serif: "Source Serif 4", "Source Serif Pro", Charter, "Iowan Old Style", Georgia, ui-serif, serif;
  --ff-mono:  "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --serif: var(--ff-serif);
  --mono:  var(--ff-mono);

  /* ── Surfaces: warm near-black, paper aged into the dark ── */
  --bg:        oklch(0.155 0.005 60);
  --bg-1:      oklch(0.180 0.006 60);
  --bg-2:      oklch(0.215 0.007 60);
  --bg-3:      oklch(0.260 0.008 60);
  --bg-frame:  oklch(0.110 0.004 60);
  --bg-elev:   var(--bg-1);            /* legacy alias */

  /* ── Text ladder (light → faint) ── */
  --text:      oklch(0.935 0.008 80);
  --text-2:    oklch(0.840 0.010 78);
  --muted:     oklch(0.700 0.012 75);
  --dim:       oklch(0.640 0.011 72);
  --faint:     oklch(0.460 0.009 65);
  --text-dim:  var(--muted);           /* legacy alias */
  --rule:      oklch(0.300 0.008 65);
  --rule-soft: oklch(0.235 0.008 65);

  /* ── Accent: amber / phosphor (the only chroma in the UI) ── */
  --accent:        oklch(0.78 0.14 65);
  --accent-soft:   oklch(0.78 0.14 65 / 0.15);
  --accent-quiet:  oklch(0.78 0.14 65 / 0.45);

  /* ── Semantic (sparingly; pulled into the warm register) ── */
  --diff-add:  oklch(0.78 0.13 145);   /* green / confirm / win / live */
  --diff-del:  oklch(0.70 0.16 28);    /* oxidised red / die / error */
  --info:      oklch(0.74 0.10 220);   /* blue / tool / open */

  /* ── Legacy semantic aliases (keep existing rules resolving) ── */
  --insight:    var(--diff-add);
  --surprise:   var(--diff-del);
  --prediction: var(--info);
  --hypothesis: oklch(0.80 0.13 80);   /* warm amber — game-over / chapters */
  --recap:      oklch(0.72 0.13 300);  /* model purple */
  --journal:    oklch(0.77 0.14 60);   /* warm orange */
  --thought-bg: oklch(0.110 0.004 60 / 0.92);

  /* ── Tool badge hues (small, decorative) ── */
  --tool-bash:  oklch(0.80 0.12 150);
  --tool-read:  oklch(0.74 0.10 220);
  --tool-edit:  oklch(0.82 0.13 85);
  --tool-write: oklch(0.70 0.16 28);
  --tool-grep:  oklch(0.72 0.13 300);
  --tool-glob:  oklch(0.78 0.10 220);
  --tool-task:  oklch(0.75 0.15 350);
  --tool-other: var(--muted);
}

* { box-sizing: border-box; }

/* The HTML `hidden` attribute always wins over our display rules. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--bg);
  color: var(--text);
  font-family: var(--ff-serif);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow: hidden;
}
::selection { background: var(--accent-soft); color: var(--text); }

/* ───────────────────────────────────────────────────────────────
 * Topbar — sticky, blurred navigation spine shared by every view.
 * Discovery renders it inside the scroll container (sticky); the
 * player pins its own copy (fixed). Same look, same brand.
 * ─────────────────────────────────────────────────────────────── */

.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  background: color-mix(in oklab, var(--bg) 90%, transparent);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--rule-soft);
}
.topbar-inner,
.player-topbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1.5rem;
  padding: 0.85rem clamp(1.25rem, 4vw, 3rem);
  font-family: var(--ff-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}
.player-topbar {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 44px;
  z-index: 11;
  background: color-mix(in oklab, var(--bg) 88%, transparent);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--rule-soft);
}
.player-topbar[hidden] { display: none !important; }

.topbar-title {
  color: var(--muted);
  text-decoration: none;
  white-space: nowrap;
}
.topbar-title b { color: var(--text); font-weight: 500; }
.topbar-title:hover b { color: var(--accent); }
.topbar-dot { color: var(--accent); }

.topbar-nav {
  display: flex;
  align-items: center;
  gap: 0.6em;
  flex-wrap: wrap;
  justify-content: flex-end;
  min-width: 0;
  margin-left: auto;
}
.topbar-nav a {
  color: var(--muted);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: color 120ms ease, border-color 120ms ease;
}
.topbar-nav a:hover { color: var(--accent); border-bottom-color: var(--accent-quiet); }
.crumb-sep { color: var(--faint); }
.crumb-current { color: var(--text); }

/* ARC replay → arcprize.org scorecard, pinned to the right of the topbar.
 * Hidden for offline runs (no scorecard url). */
.arc-replay {
  flex: none;
  color: var(--accent);
  text-decoration: none;
  border: 1px solid var(--accent-quiet);
  border-radius: 2px;
  padding: 0.35em 0.7em;
  white-space: nowrap;
  transition: color 120ms ease, background 120ms ease, border-color 120ms ease;
}
.arc-replay:hover { background: var(--accent); color: var(--bg); border-color: var(--accent); }
.arc-replay[hidden] { display: none !important; }

/* ───────────────────────────────────────────────────────────────
 * Discovery (lobby + instance) — a scrolling dossier page.
 * ─────────────────────────────────────────────────────────────── */

.discovery {
  position: fixed;
  inset: 0;
  overflow: auto;
  background: var(--bg);
  z-index: 50;
}

.page {
  max-width: 76rem;
  margin: 0 auto;
  padding: 0 clamp(1.25rem, 4vw, 3rem);
}

section.sec {
  padding-top: clamp(3rem, 6vw, 5rem);
  padding-bottom: 0;
}

/* Canonical section header: mono amber number | serif title + sub. */
.sec-header {
  display: grid;
  grid-template-columns: 7rem 1fr;
  gap: 2rem;
  align-items: baseline;
  border-top: 1px solid var(--rule);
  padding-top: 1.2rem;
  margin-bottom: 2.4rem;
}
.sec-num {
  font: 12px/1.4 var(--ff-mono);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  padding-top: 0.55em;
}
.sec-title {
  font-family: var(--ff-serif);
  font-weight: 400;
  font-size: clamp(1.7rem, 3.4vw, 2.6rem);
  line-height: 1.1;
  letter-spacing: -0.015em;
  margin: 0 0 0.4rem;
  color: var(--text);
}
.sec-title em { color: var(--accent); font-style: italic; }
.sec-sub {
  font: 12px var(--ff-mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

.empty-note {
  font-family: var(--ff-serif);
  font-size: 1.05rem;
  color: var(--muted);
  max-width: 48ch;
}
.empty-note code {
  font-family: var(--ff-mono);
  font-size: 0.85em;
  background: var(--bg-2);
  padding: 0.08em 0.36em;
  border-radius: 2px;
  color: var(--text-2);
}

/* Card grid — hairline-bordered records, borders not shadows. */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 14px;
}

.card {
  background: var(--bg-1);
  border: 1px solid var(--rule-soft);
  border-radius: 2px;
  padding: 18px 20px;
  cursor: pointer;
  transition: border-color 120ms ease, background 120ms ease;
  display: block;
  text-decoration: none;
  color: inherit;
}
.card:hover {
  border-color: var(--accent-quiet);
  background: var(--bg-2);
}

.card-title {
  font-family: var(--ff-mono);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--text);
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Multi-attempt badge: "2/3" next to the game name. */
.attempt-badge {
  margin-left: auto;
  padding: 1px 6px;
  background: var(--bg-2);
  border: 1px solid var(--rule);
  color: var(--muted);
  font-family: var(--ff-mono);
  font-size: 10px;
  border-radius: 2px;
  letter-spacing: 0.04em;
}

/* First card of a same-game cluster gets an amber left edge so a
 * multi-attempt group reads as a unit. */
.card.first-in-game {
  border-left: 2px solid var(--accent-quiet);
  padding-left: 19px;
}

.card-cell {
  display: flex;
  flex-direction: column;
}
.card-cell.first-in-game {
  border-left: 2px solid var(--accent-quiet);
  border-radius: 2px;
}
.card-cell.first-in-game .card { border-left: none; padding-left: 20px; }

.resume-hint {
  margin-left: 8px;
  color: var(--muted);
}

/* Resume-chain expander — kept quiet so it never competes. */
.card-segments {
  margin: 2px 0 0 2px;
  font-family: var(--ff-mono);
  font-size: 10px;
  letter-spacing: 0.03em;
  color: var(--muted);
}
.card-segments > summary {
  cursor: pointer;
  list-style: none;
  padding: 3px 6px;
  color: var(--dim);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  user-select: none;
}
.card-segments > summary::-webkit-details-marker { display: none; }
.card-segments > summary::before { content: "▸ "; }
.card-segments[open] > summary::before { content: "▾ "; }
.card-segments > summary:hover { color: var(--text-2); }
.seg-list {
  list-style: none;
  margin: 2px 0 6px;
  padding: 0 6px;
}
.seg-row {
  display: flex;
  gap: 8px;
  align-items: baseline;
  padding: 2px 0;
}
.seg-idx { color: var(--faint); min-width: 1.2em; }
.seg-steps { color: var(--text-2); min-width: 5.5em; font-variant-numeric: tabular-nums; }
.seg-note { color: var(--muted); }
.seg-terminal .seg-note { color: var(--accent); }

.card-sub {
  font-family: var(--ff-mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--muted);
  margin-top: 7px;
  min-height: 1em;
}
.card-meta {
  display: flex;
  gap: 14px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--rule-soft);
  font-family: var(--ff-mono);
  font-size: 11px;
  letter-spacing: 0.03em;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.card-meta b { color: var(--text); font-weight: 500; }

/* Status dot for live / finished. */
.dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--faint);
  flex-shrink: 0;
}
.dot.live {
  background: var(--diff-add);
  box-shadow: 0 0 8px color-mix(in oklab, var(--diff-add) 70%, transparent);
  animation: pulse-dot 1.6s ease-in-out infinite;
}
.dot.win { background: var(--diff-add); }
.lvl-won {
  color: var(--diff-add);
  margin-left: 0.25em;
  font-weight: 700;
}
.dot.game-over { background: var(--hypothesis); }
.dot.gave-up { background: var(--diff-del); }
.dot.legacy { background: var(--faint); opacity: 0.5; }

@keyframes pulse-dot {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.6; transform: scale(0.85); }
}

/* Page footer — institutional voice, generous breathing room. */
.page-footer {
  max-width: 76rem;
  margin: clamp(4rem, 8vw, 7rem) auto 0;
  padding: 2rem clamp(1.25rem, 4vw, 3rem) 3rem;
  border-top: 1px solid var(--rule-soft);
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  font-family: var(--ff-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dim);
}
.page-footer a { color: var(--dim); text-decoration: none; border-bottom: 1px solid transparent; }
.page-footer a:hover { color: var(--accent); border-bottom-color: var(--accent-quiet); }

/* Collapse the 2-col section header + topbar on narrow screens. */
@media (max-width: 700px) {
  .sec-header { grid-template-columns: 1fr; gap: 0.5rem; }
  .sec-num { padding-top: 0; }
  .topbar-inner, .player-topbar { gap: 0.75rem; }
}

/* ───────────────────────────────────────────────────────────────
 * Player — full-bleed cinema. Restyled to the warm palette: amber
 * accents, hairline borders, mono labels. Sits below the player
 * topbar (44px) and above the transport (64px).
 * ─────────────────────────────────────────────────────────────── */

.player-grid {
  position: fixed;
  inset: 44px 0 64px 0;
  display: grid;
  grid-template-columns: 1fr 320px 460px;
  gap: 24px;
  padding: 16px;
  overflow: hidden;
  background: var(--bg);
}

.stage-region {
  position: relative;
  display: grid;
  place-items: center;
  overflow: hidden;
  min-width: 0;
}

.side-column {
  display: flex;
  flex-direction: column;
  gap: 20px;
  align-items: center;
  justify-content: flex-start;
  padding-top: 48px;
  overflow: hidden;
}

.scratchpads {
  display: flex;
  flex-direction: column;
  background: var(--bg-1);
  border: 1px solid var(--rule-soft);
  border-radius: 2px;
  overflow: hidden;
  min-height: 0;
}

.scratchpad-tabs {
  display: flex;
  gap: 4px;
  padding: 8px 12px;
  background: var(--bg);
  border-bottom: 1px solid var(--rule-soft);
  align-items: center;
}
.scratchpad-tab {
  background: transparent;
  border: 1px solid transparent;
  color: var(--muted);
  font-family: var(--ff-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 4px 10px;
  border-radius: 2px;
  cursor: pointer;
  transition: color 120ms ease, border-color 120ms ease, background 120ms ease;
}
.scratchpad-tab:hover { color: var(--text); }
.scratchpad-tab.active {
  background: var(--accent-soft);
  border-color: var(--accent-quiet);
  color: var(--accent);
}
.scratchpad-tab.has-new::after {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-left: 6px;
  border-radius: 50%;
  background: var(--accent);
  vertical-align: middle;
  animation: pulse-dot 1.6s ease-in-out infinite;
}
.scratchpad-meta {
  margin-left: auto;
  font-family: var(--ff-mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.scratchpad-body {
  flex: 1;
  overflow: auto;
  margin: 0;
  padding: 18px 22px;
  font-family: var(--ff-serif);
  font-size: 15px;
  line-height: 1.6;
  color: var(--text-2);
  white-space: pre-wrap;
  word-wrap: break-word;
}
.scratchpad-body:empty::before {
  content: "(empty — no content written yet)";
  color: var(--muted);
  font-style: italic;
}

/* ── Markdown rendering for scratchpad bodies ── */

.scratchpad-body .md-h1,
.scratchpad-body .md-h2,
.scratchpad-body .md-h3,
.scratchpad-body .md-h4,
.scratchpad-body .md-h5,
.scratchpad-body .md-h6 {
  margin: 16px 0 5px 0;
  font-family: var(--ff-mono);
  font-weight: 500;
  color: var(--text);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  line-height: 1.3;
}
.scratchpad-body .md-h1 { font-size: 13px; letter-spacing: 0.1em; color: var(--accent); }
.scratchpad-body .md-h2 { font-size: 12px; letter-spacing: 0.1em; color: var(--text);
                          border-bottom: 1px solid var(--rule-soft);
                          padding-bottom: 5px; }
.scratchpad-body .md-h3 { font-size: 12px; letter-spacing: 0.08em; color: var(--muted); }
.scratchpad-body .md-h4,
.scratchpad-body .md-h5,
.scratchpad-body .md-h6 { font-size: 11px; color: var(--muted); }

.scratchpad-body .md-p {
  margin: 8px 0;
  font-family: var(--ff-serif);
  font-size: 15px;
  line-height: 1.6;
  color: var(--text-2);
}

.scratchpad-body .md-ul {
  margin: 8px 0;
  padding-left: 24px;
  font-family: var(--ff-serif);
  font-size: 15px;
  line-height: 1.55;
  color: var(--text-2);
}
.scratchpad-body .md-ul li { margin: 3px 0; }
.scratchpad-body .md-ul li::marker { color: var(--accent-quiet); }

.scratchpad-body .md-inline-code {
  font-family: var(--ff-mono);
  font-size: 12px;
  background: var(--bg-2);
  color: var(--accent);
  padding: 1px 6px;
  border-radius: 2px;
}

.scratchpad-body .md-code {
  background: var(--bg-frame);
  border: 1px solid var(--rule-soft);
  border-radius: 2px;
  padding: 10px 14px;
  margin: 10px 0;
  overflow-x: auto;
  font-family: var(--ff-mono);
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-2);
}

.scratchpad-body .md-bq {
  margin: 10px 0;
  padding: 4px 14px;
  border-left: 2px solid var(--accent-quiet);
  background: var(--accent-soft);
  color: var(--muted);
  font-family: var(--ff-serif);
  font-size: 14px;
  font-style: italic;
}

.scratchpad-body .md-link {
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px solid var(--accent-quiet);
}
.scratchpad-body .md-link:hover { border-bottom-color: var(--accent); }

.scratchpad-body .md-hr {
  border: 0;
  border-top: 1px solid var(--rule-soft);
  margin: 16px 0;
}

.scratchpad-body strong { color: var(--text); font-weight: 600; }
.scratchpad-body em { color: var(--muted); font-style: italic; }

/* Banner above theory body — snapshot context. */
.scratchpad-body .md-banner {
  background: var(--accent-soft);
  border: 1px solid var(--accent-quiet);
  border-radius: 2px;
  padding: 10px 14px;
  margin: 0 0 14px 0;
  font-family: var(--ff-mono);
  font-size: 11px;
  letter-spacing: 0.03em;
  color: var(--accent);
  line-height: 1.5;
}
.scratchpad-body .md-banner small { color: var(--muted); font-size: 10px; }

/* Harness-injected protocol preamble — demoted, collapsed by default. */
.scratchpad-body .md-boilerplate {
  margin: 0 0 14px 0;
  border: 1px dashed var(--rule);
  border-radius: 2px;
  padding: 4px 12px;
  background: var(--bg);
}
.scratchpad-body .md-boilerplate > summary {
  font-family: var(--ff-mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  cursor: pointer;
  padding: 4px 0;
  user-select: none;
  list-style: none;
}
.scratchpad-body .md-boilerplate > summary::before {
  content: "▸ ";
  display: inline-block;
  transition: transform 120ms ease;
}
.scratchpad-body .md-boilerplate[open] > summary::before { transform: rotate(90deg); }
.scratchpad-body .md-boilerplate[open] { padding-bottom: 10px; }
.scratchpad-body .md-boilerplate .md-h1,
.scratchpad-body .md-boilerplate .md-h2,
.scratchpad-body .md-boilerplate .md-h3 { color: var(--muted); border: 0; }
.scratchpad-body .md-boilerplate .md-p,
.scratchpad-body .md-boilerplate .md-ul,
.scratchpad-body .md-boilerplate em { color: var(--muted); }

.scratchpad-body .md-empty {
  color: var(--muted);
  font-style: italic;
}

/* Single-column fallback for narrow screens. */
@media (max-width: 1200px) {
  .player-grid {
    grid-template-columns: 1fr 280px;
    grid-template-rows: 1fr 280px;
  }
  .scratchpads { grid-column: 1 / -1; }
}

.stage-bg {
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at center,
              oklch(0.185 0.006 60) 0%, var(--bg) 70%);
  pointer-events: none;
}

/* Title strip — below the run HUD so the two top overlays don't collide. */
.title-strip {
  position: absolute;
  top: 100px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 16px;
  align-items: center;
  font-family: var(--ff-mono);
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  z-index: 5;
}

.step-label { color: var(--text); font-weight: 500; }

.action-label {
  padding: 3px 10px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-quiet);
  color: var(--accent);
  border-radius: 2px;
}
.action-label:empty { display: none; }

.game-state {
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dim);
}
.game-state:empty { display: none; }
.game-state.win { color: var(--diff-add); }

/* Frame */
.frame-wrap {
  position: relative;
  display: grid;
  place-items: center;
  z-index: 1;
}

/* The frame, its ASCII fallback, and the grid overlay are stacked in one
   shrink-to-fit box. The box sizes itself to whichever frame is visible,
   so the absolutely-positioned overlay fills exactly the board area and
   its cell lines register against the pixels. */
.frame-stack {
  position: relative;
  display: inline-block;
  line-height: 0;
  max-width: 100%;
}

.frame,
#frame-ascii {
  display: block;
  max-width: 100%;
  height: auto;
  image-rendering: pixelated;
  image-rendering: crisp-edges;
}
.frame { transition: opacity 200ms ease; }
.frame.fading { opacity: 0.0; }

/* Coordinate grid overlay — viewBox is the board's [cols, rows] so cell
   lines land on integer coordinates. Lines stay 1px crisp at any display
   size via non-scaling-stroke. */
.grid-overlay {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 3;
}
.grid-overlay[hidden] { display: none; }
.grid-overlay .grid-line {
  stroke: oklch(0.935 0.008 80 / 0.12);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}
.grid-overlay .grid-line.major {
  stroke: oklch(0.935 0.008 80 / 0.30);
}
.grid-overlay .grid-label {
  fill: var(--accent);
  font-family: var(--ff-mono);
  paint-order: stroke;
  stroke: rgba(0, 0, 0, 0.9);
  stroke-linejoin: round;
}
.grid-overlay .grid-guide {
  stroke: var(--accent-quiet);
  stroke-width: 1;
  stroke-dasharray: 4 3;
  vector-effect: non-scaling-stroke;
}
.grid-overlay .grid-cell-hl {
  fill: var(--accent-soft);
  stroke: var(--accent);
  stroke-width: 2;
  vector-effect: non-scaling-stroke;
}

/* No-op pulse */
.noop-pulse {
  position: absolute;
  inset: 0;
  border: 2px solid var(--muted);
  pointer-events: none;
  opacity: 0;
  border-radius: 2px;
}
.noop-pulse.active { animation: noopPulse 600ms ease-out; }
@keyframes noopPulse {
  0%   { opacity: 0; transform: scale(1); }
  40%  { opacity: 0.4; transform: scale(1.015); }
  100% { opacity: 0; transform: scale(1); }
}

/* Subtitle — the human voice: serif italic. */
.subtitle {
  position: absolute;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  max-width: 80vw;
  text-align: center;
  font-family: var(--ff-serif);
  font-size: 18px;
  font-style: italic;
  line-height: 1.5;
  color: var(--text);
  text-wrap: pretty;
  z-index: 5;
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.85);
  transition: opacity 220ms ease;
}
.subtitle.hidden { opacity: 0; }
.subtitle:empty { display: none; }

/* Thought card (full-bleed cut) */
.thought-card {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background: var(--thought-bg);
  z-index: 20;
  padding: 0 8vw;
  text-align: center;
  opacity: 0;
  transition: opacity 350ms ease;
  pointer-events: none;
}
.thought-card[hidden] { display: none; }
.thought-card.shown { opacity: 1; }

.thought-kind {
  font-family: var(--ff-mono);
  font-size: 11px;
  letter-spacing: 0.25em;
  text-transform: uppercase;
  margin-bottom: 32px;
  color: var(--muted);
}

.thought-quote {
  font-family: var(--ff-serif);
  font-size: clamp(22px, 3.6vw, 44px);
  line-height: 1.4;
  font-weight: 400;
  max-width: 900px;
  text-wrap: balance;
}

.thought-card.kind-hypothesis .thought-kind { color: var(--hypothesis); }
.thought-card.kind-surprise .thought-kind { color: var(--surprise); }
.thought-card.kind-prediction .thought-kind { color: var(--prediction); }
.thought-card.kind-insight .thought-kind { color: var(--insight); }
.thought-card.kind-recap .thought-kind { color: var(--recap); }

/* Tool badges (floating around frame) */
.badges {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.badge {
  position: absolute;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  background: color-mix(in oklab, var(--bg-frame) 90%, transparent);
  border: 1px solid var(--rule);
  border-left-width: 3px;
  border-radius: 2px;
  font-family: var(--ff-mono);
  font-size: 11px;
  letter-spacing: 0.03em;
  color: var(--text);
  white-space: nowrap;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 250ms ease, transform 250ms ease;
}
.badge.in { opacity: 1; transform: translateY(0); }
.badge.out { opacity: 0; transform: translateY(-4px); }

.badge .glyph { font-weight: 700; font-size: 13px; }
.badge .duration { color: var(--muted); font-size: 10px; }

.badge.tool-Bash    { border-left-color: var(--tool-bash);  color: var(--tool-bash); }
.badge.tool-Read    { border-left-color: var(--tool-read);  color: var(--tool-read); }
.badge.tool-Edit    { border-left-color: var(--tool-edit);  color: var(--tool-edit); }
.badge.tool-Write   { border-left-color: var(--tool-write); color: var(--tool-write); }
.badge.tool-Grep    { border-left-color: var(--tool-grep);  color: var(--tool-grep); }
.badge.tool-Glob    { border-left-color: var(--tool-glob);  color: var(--tool-glob); }
.badge.tool-Task    { border-left-color: var(--tool-task);  color: var(--tool-task); }
.badge.tool-Agent   { border-left-color: var(--tool-task);  color: var(--tool-task); }
.badge.tool-other   { border-left-color: var(--tool-other); color: var(--tool-other); }

/* Journal flash (corner card) */
.journal-flash {
  position: absolute;
  bottom: 80px;
  right: 32px;
  max-width: 320px;
  padding: 14px 16px;
  background: color-mix(in oklab, var(--bg-frame) 92%, transparent);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--journal);
  border-radius: 2px;
  z-index: 10;
  opacity: 0;
  transform: translateX(20px);
  transition: opacity 280ms ease, transform 280ms ease;
}
.journal-flash[hidden] { display: none; }
.journal-flash.shown { opacity: 1; transform: translateX(0); }

.journal-eyebrow {
  font-family: var(--ff-mono);
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--journal);
  margin-bottom: 6px;
}
.journal-title { font-size: 14px; font-weight: 600; margin-bottom: 6px; }
.journal-trigger { font-size: 12px; color: var(--muted); line-height: 1.4; }

/* ── Loading / error ── */
.loading {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  background: var(--bg);
  z-index: 200;
  color: var(--muted);
  font-family: var(--ff-mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.loading.hidden { display: none; }

.error {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  background: var(--bg);
  z-index: 200;
  color: var(--diff-del);
  font-family: var(--ff-mono);
  font-size: 13px;
  letter-spacing: 0.04em;
  padding: 0 24px;
  text-align: center;
}
.error[hidden] { display: none; }

/* Live banner on a player */
.live-banner {
  position: absolute;
  top: 24px;
  right: 24px;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  background: color-mix(in oklab, var(--diff-add) 14%, var(--bg-frame));
  border: 1px solid color-mix(in oklab, var(--diff-add) 45%, transparent);
  color: var(--diff-add);
  font-family: var(--ff-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  border-radius: 2px;
  z-index: 6;
}
.live-banner[hidden] { display: none; }
.live-banner.stale {
  background: color-mix(in oklab, var(--hypothesis) 14%, var(--bg-frame));
  border-color: color-mix(in oklab, var(--hypothesis) 45%, transparent);
  color: var(--hypothesis);
}
.live-banner.cold {
  background: color-mix(in oklab, var(--diff-del) 14%, var(--bg-frame));
  border-color: color-mix(in oklab, var(--diff-del) 45%, transparent);
  color: var(--diff-del);
}

/* Kind / validity banner above the player. */
.kvb {
  position: absolute;
  top: 64px;
  left: 24px;
  right: 24px;
  z-index: 4;
  display: flex;
  flex-direction: column;
  gap: 4px;
  pointer-events: none;
}
.kvb[hidden] { display: none; }
.kvb-row {
  padding: 6px 10px;
  border-radius: 2px;
  font-family: var(--ff-mono);
  font-size: 11px;
  letter-spacing: 0.03em;
  line-height: 1.5;
  border: 1px solid;
  pointer-events: auto;
}
.kvb-invalid {
  background: color-mix(in oklab, var(--diff-del) 18%, var(--bg-frame));
  border-color: color-mix(in oklab, var(--diff-del) 55%, transparent);
  color: var(--diff-del);
}
.kvb-invalid .kvb-label { font-weight: 600; margin-right: 4px; }
.kvb-invalid .kvb-ref { color: var(--muted); font-size: 10px; }
.kvb-kind {
  background: color-mix(in oklab, var(--hypothesis) 12%, var(--bg-frame));
  border-color: color-mix(in oklab, var(--hypothesis) 45%, transparent);
  color: var(--hypothesis);
}
.kvb-kind-resume_continuation {
  background: color-mix(in oklab, var(--info) 12%, var(--bg-frame));
  border-color: color-mix(in oklab, var(--info) 45%, transparent);
  color: var(--info);
}
.kvb-kind-warm_resume {
  background: color-mix(in oklab, var(--journal) 14%, var(--bg-frame));
  border-color: color-mix(in oklab, var(--journal) 50%, transparent);
  color: var(--journal);
}
.kvb-kind-loop_reset {
  background: color-mix(in oklab, var(--recap) 14%, var(--bg-frame));
  border-color: color-mix(in oklab, var(--recap) 50%, transparent);
  color: var(--recap);
}

/* Lobby/instance card kind chip + invalid warning. */
.kind-chip {
  display: inline-block;
  font-family: var(--ff-mono);
  font-size: 10px;
  font-weight: 500;
  padding: 1px 5px;
  border-radius: 2px;
  margin-left: 6px;
  vertical-align: middle;
  border: 1px solid;
}
.kind-chip-resume_continuation {
  background: color-mix(in oklab, var(--info) 16%, transparent);
  border-color: color-mix(in oklab, var(--info) 50%, transparent);
  color: var(--info);
}
.kind-chip-warm_resume {
  background: color-mix(in oklab, var(--journal) 18%, transparent);
  border-color: color-mix(in oklab, var(--journal) 55%, transparent);
  color: var(--journal);
}
.kind-chip-loop_reset {
  background: color-mix(in oklab, var(--recap) 16%, transparent);
  border-color: color-mix(in oklab, var(--recap) 50%, transparent);
  color: var(--recap);
}
.invalid-chip {
  display: inline-block;
  margin-left: 4px;
  color: var(--diff-del);
  font-size: 13px;
  vertical-align: middle;
}

/* Card legend — keys the dot/chip/mark vocabulary used on the cards. */
.card-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 28px;
  margin: -1.6rem 0 2rem;
  padding-bottom: 1.3rem;
  border-bottom: 1px solid var(--rule-soft);
  font: 11px var(--ff-mono);
  letter-spacing: 0.03em;
  color: var(--muted);
}
.legend-group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 16px;
}
.legend-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.legend-item .dot,
.legend-item .kind-chip,
.legend-item .invalid-chip { margin: 0; }
.legend-item b { color: var(--text-2); font-weight: 500; }
.legend-plain {
  display: inline-block;
  min-width: 1.1em;
  text-align: center;
  color: var(--text-2);
}
.legend-metrics { color: var(--faint); }

/* Run HUD — session metrics stacked top-left of the stage. */
.run-hud {
  position: absolute;
  top: 24px;
  left: 24px;
  z-index: 6;
  display: flex;
  gap: 22px;
  padding: 10px 16px;
  background: color-mix(in oklab, var(--bg-frame) 60%, transparent);
  border: 1px solid var(--rule-soft);
  border-radius: 2px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.run-hud[hidden] { display: none; }
.hud-stat { display: flex; flex-direction: column; gap: 3px; }
.hud-label {
  font-family: var(--ff-mono);
  font-size: 9px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
}
.hud-value {
  font-family: var(--ff-mono);
  font-size: 17px;
  font-weight: 500;
  line-height: 1;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.hud-level { min-width: 64px; }
.hud-level-track {
  margin-top: 4px;
  height: 3px;
  width: 100%;
  border-radius: 2px;
  background: var(--rule);
  overflow: hidden;
}
.hud-level-bar {
  display: block;
  height: 100%;
  width: 0;
  border-radius: 2px;
  background: var(--accent);
  transition: width 280ms ease;
}

/* Avatar — square face, ported geometry. The warm cream frame is
 * intentionally kept: it reads as a paper-mounted portrait, which
 * sits naturally in the dossier register. */
.avatar-wrap {
  width: 280px;
  height: 280px;
  perspective: 750px;
  display: grid;
  place-items: center;
  background: var(--bg-frame);
  border: 8px solid #f4efe0;
  border-radius: 4px;
  box-shadow: 0 0 0 1px var(--bg-frame), 0 0 0 9px #f4efe0;
  overflow: hidden;
  transition: filter 400ms ease, opacity 400ms ease;
  flex-shrink: 0;
}
.avatar-wrap[hidden] { display: none; }
.avatar-wrap.stale { filter: sepia(0.4) hue-rotate(-20deg); }
.avatar-wrap.cold { filter: saturate(0.5) brightness(0.7) sepia(0.6); }
.avatar-wrap.harvested { opacity: 0.5; filter: saturate(0.3); }
.avatar-svg {
  width: 224px;
  height: 224px;
  transform-origin: 50% 60%;
  shape-rendering: crispEdges;
  transition: transform 80ms linear;
}

/* Controller — 6-button grid showing which ACTION was pressed. */
.controller {
  width: 280px;
  background: var(--bg-frame);
  border: 8px solid #f4efe0;
  border-radius: 4px;
  box-shadow: 0 0 0 1px var(--bg-frame), 0 0 0 9px #f4efe0;
  padding: 14px;
  box-sizing: border-box;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  font-family: var(--ff-mono);
  flex-shrink: 0;
}
.controller-btn {
  height: 50px;
  background: var(--bg-2);
  color: var(--faint);
  border: 2px solid var(--rule);
  border-radius: 2px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 22px;
  font-weight: 700;
  letter-spacing: 1px;
  transition: transform 180ms cubic-bezier(0.2, 0.8, 0.3, 1.2),
              background 80ms ease,
              box-shadow 200ms ease;
}
.controller-btn.active {
  background: var(--accent);
  color: var(--bg);
  border-color: #f4efe0;
  transform: scale(1.06);
  box-shadow: 0 0 24px color-mix(in oklab, var(--accent) 70%, transparent);
}

/* Player controls — transport strip. */
.player-controls {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  height: 64px;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 0 24px;
  background: color-mix(in oklab, var(--bg) 90%, transparent);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border-top: 1px solid var(--rule-soft);
  z-index: 10;
  font-family: var(--ff-mono);
  font-size: 12px;
  letter-spacing: 0.04em;
  color: var(--muted);
}
.player-controls[hidden] { display: none; }
.player-btn {
  background: transparent;
  border: 1px solid var(--rule);
  color: var(--text-2);
  padding: 4px 10px;
  border-radius: 2px;
  cursor: pointer;
  font-family: var(--ff-mono);
  font-size: 12px;
  letter-spacing: 0.04em;
  transition: border-color 120ms ease, color 120ms ease, background 120ms ease;
}
.player-btn:hover { border-color: var(--accent-quiet); color: var(--accent); }
.player-btn.active {
  background: var(--accent-soft);
  border-color: var(--accent-quiet);
  color: var(--accent);
}

.play-btn { min-width: 34px; font-size: 13px; text-align: center; }
.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 4px 8px;
}
.icon-btn svg { width: 15px; height: 15px; fill: currentColor; display: block; }
/* The grid glyph is stroke-drawn (outline + interior lines); a CSS fill
   would flood the box into a solid square and bury the grid lines. */
.grid-btn svg { fill: none; stroke: currentColor; }

/* Scrub track wraps the range input so level markers can overlay it. */
.scrub-track {
  position: relative;
  flex: 1;
  display: flex;
  align-items: center;
  min-width: 0;
}
.scrub-markers {
  position: absolute;
  left: 7px;
  right: 7px;
  top: 50%;
  height: 16px;
  transform: translateY(-50%);
  pointer-events: none;
}
.scrub-marker {
  position: absolute;
  top: 0;
  width: 2px;
  height: 16px;
  margin-left: -1px;
  border-radius: 1px;
  background: var(--hypothesis);
  box-shadow: 0 0 5px color-mix(in oklab, var(--hypothesis) 70%, transparent);
}
/* Resume seam — a structural join between harvested segments. Cooler
 * (info blue) so it reads distinct from the warm level-chapter ticks. */
.scrub-marker.resume {
  width: 2px;
  height: 22px;
  top: -3px;
  background: var(--info);
  box-shadow: 0 0 5px color-mix(in oklab, var(--info) 70%, transparent);
}
.scrub-bar {
  flex: 1;
  appearance: none;
  -webkit-appearance: none;
  height: 4px;
  background: var(--rule);
  border-radius: 2px;
  cursor: pointer;
}
.scrub-bar::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--accent);
  cursor: pointer;
}
.scrub-bar::-moz-range-thumb {
  width: 14px;
  height: 14px;
  border: 0;
  border-radius: 50%;
  background: var(--accent);
  cursor: pointer;
}
.scrub-pos {
  min-width: 90px;
  text-align: right;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.rate-group { display: flex; gap: 4px; }
.live-edge-btn {
  background: color-mix(in oklab, var(--diff-add) 15%, transparent);
  border-color: color-mix(in oklab, var(--diff-add) 50%, transparent);
  color: var(--diff-add);
}
.live-edge-btn:hover {
  border-color: var(--diff-add);
  color: var(--diff-add);
}
/* When the scrubber is already AT the live edge, the button stops
 * being an action and becomes a status indicator. */
.live-edge-btn.at-live-edge {
  background: transparent;
  border-color: color-mix(in oklab, var(--diff-add) 50%, transparent);
  color: var(--diff-add);
  cursor: default;
  animation: pulse-dot 1.6s ease-in-out infinite;
}
.live-edge-btn.at-live-edge:hover {
  border-color: color-mix(in oklab, var(--diff-add) 50%, transparent);
}
