/* arc-witness replay viewer
 * Design language: dark theme matching arc-witness-envs/static/index.html
 *  - bg #1a1a2e, accent #e94560, panels #16213e, body Courier New
 */
* { box-sizing: border-box; margin: 0; padding: 0; }
:root {
  --bg:        #1a1a2e;
  --bg-card:   #16213e;
  --bg-deep:   #0f0f23;
  --fg:        #eee;
  --muted:    #8a8aa3;
  --accent:    #e94560;
  --ok:        #4fcc30;
  --warn:      #ffaa33;
  --bad:       #f93c31;
  --info:      #88d8f1;
  --border:    #333;
}
body {
  background: var(--bg); color: var(--fg);
  font: 14px/1.4 'Inter', system-ui, sans-serif;
  min-height: 100vh;
}
.mono { font-family: 'JetBrains Mono', 'Menlo', 'Courier New', monospace; }
.muted { color: var(--muted); }
.small { font-size: 12px; }

#topbar {
  display: flex; justify-content: space-between; align-items: center;
  padding: 10px 16px; border-bottom: 1px solid var(--border);
  background: var(--bg-deep);
}
#hdr-title { font-weight: 600; color: var(--accent); margin-right: 12px; }
/* structured Run · Game · Seed identity chips in the header */
#hdr-title .hdr-k {
  color: var(--muted); font-weight: 500; font-size: 11px; text-transform: uppercase;
  letter-spacing: .05em; margin: 0 4px 0 14px;
}
#hdr-title .hdr-k:first-child { margin-left: 0; }
#hdr-title .hdr-v {
  color: var(--fg); font-weight: 600;
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: 5px; padding: 2px 8px;
}
.hdr-lbl {
  color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: .05em;
  margin-right: -4px;
}
/* back-to-runs button: prominent, standard back-nav position (top-left) */
.btn-back {
  display: inline-block; margin-right: 14px; padding: 4px 12px;
  background: var(--bg-card); color: var(--info);
  border: 1px solid var(--info); border-radius: 6px;
  font-size: 12px; font-weight: 600; text-decoration: none; white-space: nowrap;
}
.btn-back:hover { background: var(--info); color: #10131f; }
.hdr-right { display: flex; gap: 12px; align-items: center; }
.hdr-right select, .hdr-right a {
  background: var(--bg-card); color: var(--fg);
  border: 1px solid var(--border); padding: 6px 10px;
  border-radius: 4px; text-decoration: none; font: inherit;
}
.hdr-right a:hover { border-color: var(--accent); }

#transport {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 16px; background: var(--bg-deep);
  border-bottom: 1px solid var(--border);
}
#transport button {
  background: var(--bg-card); color: var(--fg); border: 1px solid var(--border);
  padding: 4px 10px; border-radius: 4px; cursor: pointer; font: inherit;
  min-width: 36px;  /* keep play button's width stable across ▶ / ⏸ */
}
#transport button:hover { border-color: var(--accent); }
#transport button#btn-prev { transform: scaleX(-1); }
#step-counter { min-width: 90px; text-align: center; }
#scrubber { flex: 1; }
.speed-lbl { color: var(--muted); }
.speed-lbl select {
  background: var(--bg-card); color: var(--fg); border: 1px solid var(--border);
  padding: 2px 6px; border-radius: 4px; margin-left: 6px;
}

#stagebar {
  display: flex; height: 6px; width: 100%;
}
#stagebar .seg { height: 100%; }
#stagebar .seg[title]:hover { filter: brightness(1.4); }

#level-nav {
  display: flex; align-items: center; gap: 12px;
  padding: 8px 16px; background: var(--bg-deep);
  border-bottom: 1px solid var(--border);
}
#level-nav .lbl { color: var(--accent); }
#level-nav .filter-lbl { margin-left: auto; }
#level-nav select {
  background: var(--bg-card); color: var(--fg); border: 1px solid var(--border);
  padding: 2px 6px; border-radius: 4px; margin-left: 4px;
}
#level-buttons { display: inline-flex; gap: 4px; flex-wrap: wrap; }
#level-buttons .lvl-btn {
  background: var(--bg-card); color: var(--fg);
  border: 1px solid var(--border); padding: 3px 8px; border-radius: 4px;
  cursor: pointer; font: inherit; font-size: 12px;
}
#level-buttons .lvl-btn:hover { border-color: var(--accent); }
#level-buttons .lvl-btn.cur { background: var(--accent); border-color: var(--accent); color: #fff; }
#level-buttons .lvl-btn.completed { border-left: 3px solid var(--ok); }
#level-buttons .lvl-btn.retry { border-left: 3px solid var(--bad); }
#level-buttons .lvl-btn.failed { border-left: 3px solid var(--muted); }

/* Three-column layout, all columns stretched to the same height. The
 * canvas pane's natural height (~580px for the 512px game canvas) sets
 * the floor; we cap to viewport so the page stays single-screen. 220px ≈
 * topbar + transport + stagebar + level-nav, with slack for the level-nav
 * wrapping onto a second line on narrow viewports. */
#grid {
  display: grid; gap: 12px;
  grid-template-columns: 540px 1fr 1fr;
  align-items: stretch;
  height: calc(100vh - 220px);
  min-height: 580px;
  padding: 12px 16px;
}
.pane {
  background: var(--bg-deep);
  border: 1px solid var(--border); border-radius: 6px;
  padding: 10px 12px;
  min-height: 0;  /* allow flex/grid children to actually shrink and scroll */
}

/* Middle column: step-detail compact at top, action-history fills the
 * rest with internal scroll so the pane never overflows. */
#pane-now {
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
#pane-now > #step-detail { flex: 0 0 auto; }
#pane-now > h3 { flex: 0 0 auto; }
#pane-now > .action-history { flex: 1 1 auto; max-height: none; min-height: 0; }

/* Right column: scrollable memory pane above always-visible growth chart. */
#col-right {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 0;
}
/* The plan pane must never be flex-squeezed below its content: .pane's
   min-height:0 + no overflow means shrinking spills the action chips across
   the pane border (onto Memory). Memory below flexes + scrolls, so it absorbs
   the space instead. */
#pane-plan { flex: 0 0 auto; }
#pane-memory {
  flex: 1 1 auto;
  overflow-y: auto;
  min-height: 0;
}
#pane-growth {
  flex: 0 0 auto;
}

/* Force scrollbars to be visible on the two scroll containers — macOS
 * hides overlay scrollbars by default, which made it unclear that the
 * panes were scrollable. */
#pane-memory,
.action-history {
  scrollbar-width: thin;
  scrollbar-color: var(--border) var(--bg-card);
}
#pane-memory::-webkit-scrollbar,
.action-history::-webkit-scrollbar {
  width: 10px;
}
#pane-memory::-webkit-scrollbar-track,
.action-history::-webkit-scrollbar-track {
  background: var(--bg-card);
  border-radius: 5px;
}
#pane-memory::-webkit-scrollbar-thumb,
.action-history::-webkit-scrollbar-thumb {
  background: var(--border);
  border-radius: 5px;
}
#pane-memory::-webkit-scrollbar-thumb:hover,
.action-history::-webkit-scrollbar-thumb:hover {
  background: var(--accent);
}
.pane h2 { color: var(--accent); font-size: 14px; letter-spacing: .04em; text-transform: uppercase; margin-bottom: 8px; }
.pane h3, .pane h4 { color: var(--info); font-size: 12px; margin: 8px 0 4px; text-transform: uppercase; letter-spacing: .04em; }

.card {
  background: var(--bg-card); border: 1px solid #1f2c4f; border-radius: 4px;
  padding: 8px 10px; margin-bottom: 8px;
}

#game-canvas {
  display: block; width: 512px; height: 512px;
  border: 2px solid var(--accent);
  image-rendering: pixelated; image-rendering: crisp-edges;
  background: #000;
}
/* ── CRT tube look (toggle in the Game header; on by default) ───────────────
   Pure CSS overlay + filters — the canvas pixels are untouched, so nothing
   about the trace/replay data is altered. Matches the runs page cabinet art:
   scanlines + RGB aperture grille + phosphor glow + vignette + curved glass. */
#crt-frame { position: relative; width: 516px; }
#crt-frame.crt-on #game-canvas {
  filter: saturate(1.15) contrast(1.06) brightness(1.03)
          drop-shadow(0 0 6px rgba(120,200,255,.18));
  border-radius: 10px;
}
#crt-frame #crt-fx { display: none; }
#crt-frame.crt-on #crt-fx {
  display: block; position: absolute; inset: 2px; pointer-events: none;
  border-radius: 9px;
  background:
    /* scanlines */
    repeating-linear-gradient(to bottom,
      rgba(0,0,0,.28) 0 1px, transparent 1px 3px),
    /* RGB aperture grille */
    repeating-linear-gradient(to right,
      rgba(255,60,60,.05) 0 1px, rgba(60,255,60,.04) 1px 2px,
      rgba(60,120,255,.05) 2px 3px),
    /* vignette / curved-glass shading */
    radial-gradient(ellipse at center,
      transparent 58%, rgba(0,0,0,.28) 100%);
}
/* faint moving flicker band, like a refresh wave rolling down the tube */
#crt-frame.crt-on #crt-fx::after {
  content: ""; position: absolute; inset: 0; border-radius: 9px;
  background: linear-gradient(to bottom, transparent 0%,
    rgba(255,255,255,.045) 48%, rgba(255,255,255,.075) 50%,
    rgba(255,255,255,.045) 52%, transparent 100%);
  background-size: 100% 220%;
  animation: crt-roll 7s linear infinite;
}
@keyframes crt-roll {
  from { background-position: 0 -110%; }
  to   { background-position: 0 110%; }
}
@media (prefers-reduced-motion: reduce) {
  #crt-frame.crt-on #crt-fx::after { animation: none; }
}
.crt-toggle { font-size: 11px; color: var(--muted); font-weight: 400;
  margin-left: 10px; cursor: pointer; user-select: none; }
.crt-toggle input { vertical-align: middle; accent-color: var(--accent); }
#canvas-overlay { margin-top: 6px; min-height: 1.4em; text-align: center; }

#step-detail { line-height: 1.3; padding: 4px 6px; }
/* Compact 2-column table — rows separated by hairlines, tight padding. */
.kvp {
  display: grid;
  grid-template-columns: 138px 1fr;
  gap: 0;
  font-size: 12px;
}
.kvp dt, .kvp dd {
  padding: 3px 6px;
  border-bottom: 1px solid #1f2c4f;
}
.kvp dt:last-of-type, .kvp dd:last-of-type { border-bottom: none; }
.kvp dt { color: var(--muted); }
.kvp dd { color: var(--fg); }

.action-history {
  list-style: none; max-height: 480px; overflow-y: auto;
  border: 1px solid var(--border); border-radius: 4px; background: var(--bg-card);
  padding: 0;
}
.action-history li {
  display: flex; gap: 8px; padding: 3px 8px; font-family: 'Menlo', monospace; font-size: 12px;
  border-bottom: 1px solid #20284a;
}
.action-history li:last-child { border-bottom: none; }
.action-history li.cur { background: var(--accent); color: #fff; }
.action-history li .step { color: var(--muted); min-width: 36px; text-align: right; }
.action-history li.cur .step { color: #fff; }
.action-history .src-recon       { color: #4fcc30; }
.action-history .src-orai_plan   { color: #ffd24a; }
.action-history .src-t5_plan     { color: #88d8f1; }
.action-history .src-graph_solver { color: #c084fc; }
.action-history .src-frontier    { color: #ff8855; }
/* actor granularity (2026-07-23): the TRUE producer of each action — the
   stage-level source above hid harness actors (blind replay read "planning").
   Model-intended actions warm, harness actors cold/alert. */
.action-history .actor-llm_plan        { color: #ffd24a; }
.action-history .actor-t5_plan         { color: #88d8f1; }
.action-history .actor-graph_plan      { color: #c084fc; }
.action-history .actor-recon_probe     { color: #4fcc30; }
.action-history .actor-random_fallback { color: #ff8855; }
.action-history .actor-worker_filler   { color: #e94560; }
.action-history .actor-replay          { color: #e94560; }
.actor-flag { color: #e94560; font-size: 10px; border: 1px solid #e94560;
  border-radius: 8px; padding: 0 5px; margin-left: 4px; }
.actor-chip { font: 600 11px Menlo, monospace; border: 1px solid currentColor;
  border-radius: 8px; padding: 0 6px; }
.actor-chip.actor-llm_plan        { color: #ffd24a; }
.actor-chip.actor-t5_plan         { color: #88d8f1; }
.actor-chip.actor-graph_plan      { color: #c084fc; }
.actor-chip.actor-recon_probe     { color: #4fcc30; }
.actor-chip.actor-random_fallback { color: #ff8855; }
.actor-chip.actor-worker_filler,
.actor-chip.actor-replay          { color: #e94560; }
.action-history li.reset-marker  { background: #2a1414; color: var(--bad); justify-content: center; }
.action-history li.reset-marker.cur { background: var(--bad); color: #fff; }
/* ORAI (LLM-call) steps: the actions produced directly by a policy call —
   distinct from the plan-execution steps between them. */
.action-history li.orai {
  background: rgba(136, 216, 241, 0.08);
  border-left: 3px solid var(--info);
  padding-left: 5px;   /* 8px - 3px border, keeps text aligned with other rows */
}
.action-history li.orai.cur { background: var(--accent); }
.action-history li .orai-badge {
  margin-left: auto; align-self: center; white-space: nowrap;
  color: var(--info); font-size: 10px; font-weight: 600; letter-spacing: 0.3px;
}
.action-history li.cur .orai-badge { color: #fff; }
.orai-legend {
  font-size: 10px; font-weight: 500; color: var(--info);
  border: 1px solid var(--info); border-radius: 3px; padding: 0 4px;
  margin-left: 6px; text-transform: none; letter-spacing: 0; vertical-align: middle;
}
.action-history li.level-hdr {
  background: var(--bg-deep);
  color: var(--accent);
  font-weight: 600; font-size: 12px;
  border-top: 2px solid var(--accent);
  border-bottom: 1px solid var(--accent);
  padding: 6px 8px;
  position: sticky; top: 0;
  z-index: 1;
  display: grid; grid-template-columns: auto 1fr auto auto; gap: 8px;
  align-items: baseline;
}
.action-history li.level-hdr .lvl-stat { color: var(--ok); font-size: 11px; }
.action-history li.level-hdr.failed .lvl-stat { color: var(--muted); }
.action-history li.level-hdr.retry .lvl-stat { color: var(--bad); }
.action-history li.level-hdr .lvl-jump {
  font-size: 10px; color: var(--muted); cursor: pointer; text-decoration: underline;
}
.action-history li.level-hdr .lvl-jump:hover { color: var(--accent); }

.card-hdr {
  display: flex; align-items: baseline; justify-content: space-between;
  margin-bottom: 6px;
}
.card-hdr h4 { margin: 0; }

.legend { display: flex; gap: 10px; margin-bottom: 6px; font-size: 11px; }
.legend .leg.verified { color: var(--ok); }
.legend .leg.orai     { color: var(--info); }
.legend .leg.transfer { color: #c084fc; }
.legend .leg.disputed { color: var(--warn); }

.kn-rules { list-style: none; padding: 0; margin: 0; }
.kn-rules li {
  padding: 5px 6px; border-bottom: 1px solid #1f2c4f;
  font-size: 12px;
  display: grid; grid-template-columns: 50px 1fr auto; gap: 6px;
  align-items: baseline;
}
.kn-rules li:last-child { border-bottom: none; }
.kn-rules li .conf { color: var(--muted); font-family: 'Menlo', monospace; }
.kn-rules li.high .conf { color: var(--ok); }
.kn-rules li.disputed .conf { color: var(--warn); }
.kn-rules li.bad      .conf { color: var(--bad); }
.kn-rules li .text { line-height: 1.4; }
.kn-rules li .src {
  font-family: 'Menlo', monospace; font-size: 10px; color: var(--muted);
  border: 1px solid var(--border); padding: 1px 5px; border-radius: 3px;
  white-space: nowrap;
}
.kn-rules li.src-verified .src { color: var(--ok); border-color: var(--ok); }
.kn-rules li.src-orai     .src { color: var(--info); border-color: var(--info); }
.kn-rules li.src-transfer .src { color: #c084fc; border-color: #c084fc; }
.kn-rules li .born {
  display: block; color: var(--muted); font-family: 'Menlo', monospace;
  font-size: 10px; margin-top: 2px;
}
.kn-rules li.fresh { background: rgba(79, 204, 48, 0.06); }
.kn-rules li.fresh .born { color: var(--ok); }

#memory-spark {
  display: block; width: 100%; height: 60px;
  background: var(--bg-card); border-radius: 3px;
}

#kn-compacted { white-space: pre-wrap; max-height: 180px; overflow-y: auto; color: var(--fg); }

.kn-diff { list-style: none; padding: 0; margin: 0; font-size: 12px; }
.kn-diff li { padding: 3px 4px; }
.kn-diff li.add { color: var(--ok); }
.kn-diff li.add::before { content: "+ "; }
.kn-diff li.del { color: var(--bad); text-decoration: line-through; opacity: .8; }
.kn-diff li.del::before { content: "− "; text-decoration: none; }
.kn-diff li.none { color: var(--muted); font-style: italic; }

#reasoning {
  margin: 0 16px 12px;
}
/* Tall panels (board, response) get room; the two short ones (obs, rules) split
   the right column into EXACT halves of the board's height (rows are 1fr 1fr and
   the board — spanning both — is the only content driving them: obs/rules have
   min-height:0 + internal scroll, so the row heights come from the board alone).
   The row therefore always forms a solid rectangle. */
#reasoning-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  grid-template-rows: 1fr 1fr auto;
  grid-template-areas:
    "board obs"
    "board rules"
    "resp  resp";
  gap: 10px;
}
#reasoning-grid .card { margin-bottom: 0; }
#reasoning-grid .c-board { grid-area: board; }
#reasoning-grid .c-obs   { grid-area: obs; }
#reasoning-grid .c-rules { grid-area: rules; }
#reasoning-grid .c-resp  { grid-area: resp; }
#reasoning-grid .c-obs, #reasoning-grid .c-rules {
  min-height: 0;                       /* let the board, not our content, size the rows */
  display: flex; flex-direction: column;
}
#reasoning-grid .c-obs pre, #reasoning-grid .c-rules pre {
  flex: 1 1 auto; min-height: 0; max-height: none;   /* fill the half; scroll inside it */
}
#reasoning-grid pre {
  white-space: pre; overflow: auto; max-height: 320px;
  color: var(--fg); font-size: 11px; line-height: 1.35;
}
/* the board is the panel people read whole — let it use most of the viewport */
#reasoning-grid .c-board pre { max-height: 76vh; }
#reasoning-body {
  white-space: pre-wrap; max-height: 62vh; overflow-y: auto;
  color: var(--fg); font-size: 12px; line-height: 1.5;
}
#reasoning-body .meta { color: var(--info); }
#reasoning-body .add  { color: var(--ok); }
#reasoning-body .del  { color: var(--bad); }
#reasoning-body .plan { color: var(--accent); font-weight: 600; }

#fsm-help { margin: 0 16px 24px; }
#fsm-help p { margin-bottom: 8px; line-height: 1.5; }
.stage-help { list-style: none; padding-left: 0; }
.stage-help li { padding: 6px 0; line-height: 1.5; border-top: 1px solid var(--border); }
.stage-help li:first-child { border-top: none; }
.stage-pill {
  display: inline-block; padding: 1px 8px; margin-right: 6px;
  border-radius: 3px; color: #000;
  font-family: 'Menlo', monospace; font-size: 11px; font-weight: 600;
  vertical-align: baseline;
}

#reflections-list { margin: 0 16px 24px; }
#reflections-list ul { list-style: none; padding: 0; }
#reflections-list li {
  padding: 4px 8px; border-bottom: 1px solid var(--border); cursor: pointer;
  font-family: 'Menlo', monospace; font-size: 12px;
  display: grid; grid-template-columns: 60px 60px 1fr; gap: 12px;
}
#reflections-list li:hover { background: var(--bg-card); }
#reflections-list li.cur { background: var(--accent); color: #fff; }
#reflections-list li .step { color: var(--muted); }
#reflections-list li.cur .step { color: #fff; }
#reflections-list li .delta { color: var(--ok); }
#reflections-list li.cur .delta { color: #fff; }

#kbd-help {
  text-align: center; padding: 14px;
  border-top: 1px solid var(--border);
}

/* ── Plan pane (plan_suggested as direction chips, synced to the playhead) ── */
.plan-chips {
  display: flex; flex-wrap: wrap; gap: 6px;
  padding: 8px 0; font-size: 20px;
}
.plan-chip {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 30px; height: 30px; padding: 0 4px;
  border: 1px solid var(--border); border-radius: 6px;
  background: var(--bg-card); color: var(--muted);
}
.plan-chip.done     { color: var(--ok);  border-color: var(--ok);  background: rgba(79, 204, 48, 0.10); }
.plan-chip.diverged { color: var(--bad); border-color: var(--bad); background: rgba(249, 60, 49, 0.12); }
.plan-chip.pending  { opacity: 0.55; }
.plan-chip.current  { outline: 2px solid var(--info); outline-offset: 1px; }

/* ── D-pad: keyboard-style action keys under the board ── */
#dpad {
  display: flex; align-items: center; justify-content: center; gap: 18px;
  padding: 8px 2px 2px 2px;
}
.dpad-grid {
  display: grid; gap: 4px;
  grid-template-areas: ". u ." "l d r";
}
#key-up { grid-area: u; } #key-left { grid-area: l; }
#key-down { grid-area: d; } #key-right { grid-area: r; }
.dpad-side { display: flex; gap: 6px; }
.keycap {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 30px; font-size: 17px;
  border: 1px solid var(--border); border-bottom-width: 3px; border-radius: 6px;
  background: var(--bg-card); color: var(--muted);
  transition: background 80ms, color 80ms, border-color 80ms;
}
.keycap.active {
  color: #fff; background: var(--accent); border-color: var(--accent);
  border-bottom-width: 1px; transform: translateY(2px);   /* pressed-down look */
}
.keycap.key-confirm.active { background: var(--ok);  border-color: var(--ok); }
.keycap.key-reset.active   { background: var(--warn); border-color: var(--warn); color: #222; }
#dpad-label { min-width: 90px; text-align: center; }

/* ── Compare view (compare.html): two replays, one timeline ── */
#cmp-pickers {
  display: flex; align-items: center; gap: 14px;
  padding: 8px 16px; border-bottom: 1px solid var(--border);
}
#cmp-pickers select { max-width: 340px; }
#cmp-anchors button {
  margin-right: 4px; padding: 2px 8px;
  background: var(--bg-card); color: var(--fg);
  border: 1px solid var(--border); border-radius: 5px; cursor: pointer;
}
#cmp-anchors button:hover { border-color: var(--info); }
#cmp-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 12px; padding: 12px 16px;
}
.cmp-side { display: flex; flex-direction: column; align-items: flex-start; }
.cmp-side canvas { border: 1px solid var(--border); }
.cmp-dpad { display: flex; align-items: center; gap: 14px; padding: 6px 0 2px 0; }
.cmp-status { min-height: 18px; }
.cmp-plan { padding: 4px 0; font-size: 16px; }
.cmp-plan .plan-chip { min-width: 24px; height: 24px; font-size: 15px; }
/* compare-view D-pads use classes (ids must stay unique to the single view) */
.k-up { grid-area: u; } .k-left { grid-area: l; }
.k-down { grid-area: d; } .k-right { grid-area: r; }

/* btn-prev renders the SAME glyph as btn-next, mirrored — some fonts draw U+23EA
   (rewind) un-mirrored, making prev/next look identical and both right-pointing. */
#btn-prev { transform: scaleX(-1); }
