/* ReClaude — flight recorder for the context window.
   Green-velvet / forest instrument panel: deep forest surfaces, brass accent.
   Categorical palette re-validated (dataviz six checks) against surface #0f1a13:
   user #4a8fdd · attachment #27a578 · assistant #c08618 · tool/sidechain #8a5fe8 · event/compact #d75d84 */

/* ---------- themes ----------
   Six presets; :root carries Forest as the default. Categorical palettes are
   validated per mode with the dataviz six checks (dark surface #0f1a13, light
   surface #f4f2ec) — light mode gets its own darker set, not the dark one
   reused. Canvas colours are variables too, so the tape follows the theme. */
:root {
  --bg: #0f1a13; --panel: #16241b; --panel-2: #1d2f23; --line: #294032;
  --ink: #e2eae2; --muted: #90a998; --faint: #5f7a68; --accent: #e9b949;
  --k-user: #4a8fdd; --k-attach: #27a578; --k-assistant: #c08618;
  --k-tool: #8a5fe8; --k-event: #d75d84;
  --c-curve: #c08618; --c-curve-fill: rgba(192,134,24,0.26);
  --c-hair: rgba(226,234,226,0.35); --c-band: rgba(226,234,226,0.08);
  --c-viewport: rgba(226,234,226,0.12); --c-grid: rgba(226,234,226,0.10);
  --c-gaptext: rgba(226,234,226,0.75); --c-gapline: rgba(144,169,152,0.45);
  --c-gapfill: rgba(95,122,104,0.16); --c-shadow: rgba(0,14,7,0.55);
  --mono: ui-monospace, "SF Mono", "Cascadia Code", Menlo, Consolas, monospace;
  --sans: "Avenir Next", "Futura", "Helvetica Neue", system-ui, sans-serif;
}
[data-theme="instrument"] {
  --bg: #14181f; --panel: #1b2029; --panel-2: #222834; --line: #2e3542;
  --ink: #dfe4ec; --muted: #8b94a7; --faint: #5d6577; --accent: #f0b429;
  --c-hair: rgba(223,228,236,0.35); --c-band: rgba(223,228,236,0.08);
  --c-viewport: rgba(223,228,236,0.12); --c-grid: rgba(223,228,236,0.10);
  --c-gaptext: rgba(223,228,236,0.75); --c-gapline: rgba(139,148,167,0.45);
  --c-gapfill: rgba(93,101,119,0.16); --c-shadow: rgba(0,0,0,0.55);
}
[data-theme="ember"] {
  --bg: #191512; --panel: #221d19; --panel-2: #2b2521; --line: #3a322c;
  --ink: #ece4dc; --muted: #a3958a; --faint: #6f6357; --accent: #e0904f;
  --c-hair: rgba(236,228,220,0.35); --c-band: rgba(236,228,220,0.08);
  --c-viewport: rgba(236,228,220,0.12); --c-grid: rgba(236,228,220,0.10);
  --c-gaptext: rgba(236,228,220,0.75); --c-gapline: rgba(163,149,138,0.45);
  --c-gapfill: rgba(111,99,87,0.16); --c-shadow: rgba(14,8,4,0.55);
}
/* light modes: darker categorical set, validated against #f4f2ec */
[data-theme="paper"], [data-theme="linen"], [data-theme="sage"] {
  --k-user: #3574c4; --k-attach: #1a7d5e; --k-assistant: #946412;
  --k-tool: #7145d6; --k-event: #bd3055;
  --c-curve: #946412; --c-curve-fill: rgba(148,100,18,0.16);
  --c-hair: rgba(30,30,30,0.35); --c-band: rgba(30,30,30,0.07);
  --c-viewport: rgba(30,30,30,0.10); --c-grid: rgba(30,30,30,0.10);
  --c-gaptext: rgba(40,38,34,0.8); --c-gapline: rgba(90,86,78,0.45);
  --c-gapfill: rgba(120,116,106,0.14); --c-shadow: rgba(60,55,45,0.22);
}
[data-theme="paper"] {
  --bg: #f4f2ec; --panel: #fbfaf6; --panel-2: #eceadf; --line: #d9d5ca;
  --ink: #2a2723; --muted: #6b665c; --faint: #938d80; --accent: #b07a12;
}
[data-theme="linen"] {
  --bg: #eef1f4; --panel: #f9fbfc; --panel-2: #e3e8ee; --line: #ccd4dc;
  --ink: #1f2933; --muted: #5c6b7a; --faint: #8b98a5; --accent: #a35a09;
}
[data-theme="sage"] {
  --bg: #eef2ec; --panel: #f8faf6; --panel-2: #e2e9de; --line: #cbd6c5;
  --ink: #1f2a20; --muted: #5d6b5b; --faint: #8b9a88; --accent: #8a6d1f;
}

* { box-sizing: border-box; margin: 0; }
html, body { height: 100%; }
body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.55;
}
.app { position: relative; max-width: 1500px; margin: 0 auto; padding: 0 clamp(14px, 2.5vw, 36px); min-height: 100vh; }
.makers-mark { position: absolute; top: clamp(14px,2.5vw,26px); right: clamp(14px,3vw,30px); width: 30px; height: auto; opacity: .5; z-index: 20; pointer-events: none; }

a { color: var(--k-user); text-decoration: none; }
a:hover { text-decoration: underline; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.eyebrow {
  font-size: 11px; letter-spacing: .18em; text-transform: uppercase;
  color: var(--muted); font-weight: 600;
}

/* ---------- header ---------- */
.masthead { padding: 34px 0 10px; display: flex; align-items: baseline; gap: 18px; flex-wrap: wrap; }
/* the wordmark is a portmanteau — it has to keep its mixed case to read as
   Re + Claude, so no uppercasing here and only enough tracking to stay airy */
.masthead h1 { font-size: 23px; font-weight: 700; letter-spacing: .06em; }
.masthead h1 .dim { color: var(--accent); }
.masthead .sub { color: var(--muted); font-size: 13px; }
.crumb { padding: 22px 0 4px; font-size: 13px; color: var(--muted); }

/* ---------- search ---------- */
.searchbar { display: flex; gap: 12px; align-items: center; padding: 8px 0 2px; }
.search-input {
  flex: 1; max-width: 620px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
  color: var(--ink); font: 13px var(--mono); padding: 9px 14px;
}
.search-input:focus { outline: none; border-color: var(--accent); }
.search-input::placeholder { color: var(--faint); }
.prompt.hit { color: var(--accent); }
.prompt.hit .snip { color: var(--muted); }

/* ---------- session list ---------- */
.session-list { display: flex; flex-direction: column; gap: 10px; padding: 18px 0 60px; }
.session-card {
  display: block; background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
  padding: 14px 18px; color: inherit;
  transition: border-color .15s, transform .09s cubic-bezier(.2,.7,.3,1);
}
.session-card:hover { border-color: var(--accent); text-decoration: none; }
.session-card .row1 { display: flex; gap: 12px; align-items: baseline; flex-wrap: wrap; }
.session-card .title { font-weight: 600; font-size: 16px; }
.session-card .proj { font-family: var(--mono); font-size: 12px; color: var(--k-attach); }
.session-card .prompt { color: var(--muted); font-size: 13px; margin-top: 4px; font-family: var(--mono); }
.session-card .stats { display: flex; gap: 16px; margin-top: 8px; font-size: 12px; color: var(--faint); flex-wrap: wrap; }
.session-card .stats b { color: var(--muted); font-weight: 600; }
.empty-state { padding: 60px 0; color: var(--muted); max-width: 620px; }
.empty-state h2 { color: var(--ink); margin-bottom: 10px; font-size: 18px; }
.empty-state code { font-family: var(--mono); background: var(--panel-2); padding: 2px 7px; border-radius: 4px; font-size: 13px; color: var(--accent); }
.empty-state p { margin: 8px 0; }

/* ---------- banner ---------- */
.banner {
  border: 1px solid var(--line); border-left: 3px solid var(--accent); border-radius: 6px;
  background: var(--panel); color: var(--muted);
  font-size: 12.5px; padding: 7px 12px; margin: 0 0 8px;
}
.banner code { font-family: var(--mono); color: var(--accent); background: var(--bg); padding: 1px 6px; border-radius: 4px; }

/* ---------- the tape (signature instrument) ---------- */
.tape-wrap {
  position: sticky; top: 0; z-index: 10;
  background: var(--bg); padding: 8px 0 4px;
  border-bottom: 1px solid var(--line);
}
.tape-head { display: flex; justify-content: space-between; align-items: baseline; padding-bottom: 4px; gap: 10px; flex-wrap: wrap; }
.legend-row { align-items: center; }
.legend-right { display: flex; gap: 14px; align-items: center; flex-wrap: wrap; justify-content: flex-end; margin-left: auto; }
/* tabular figures: the readout is rewritten on every scrub — proportional digits
   would make the whole line's metrics twitch */
.tape-head .readout { font-family: var(--mono); font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; font-feature-settings: "tnum"; }
.tape-head .readout b { color: var(--accent); font-weight: 600; }
canvas.tape { width: 100%; height: 106px; display: block; cursor: crosshair; border-radius: 6px; background: var(--panel); }
.tape-tip {
  position: fixed; pointer-events: none; z-index: 50; display: none;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 6px;
  padding: 6px 10px; font-family: var(--mono); font-size: 11.5px; color: var(--ink);
  max-width: 340px; box-shadow: 0 4px 18px var(--c-shadow);
}
.tape-tip .k { color: var(--muted); }
.zoom-ctl { display: inline-flex; gap: 8px; align-items: center; }
.zoom-ctl button {
  background: var(--panel-2); color: var(--muted); border: 1px solid var(--line);
  border-radius: 5px; font: 600 11px var(--mono); padding: 2px 9px; cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(223,228,236,.045);
  transition: transform .09s cubic-bezier(.2,.7,.3,1), border-color .12s, background-color .12s, box-shadow .12s, color .12s;
}
.zoom-ctl button:hover { color: var(--accent); border-color: var(--accent); }
.legend-item {
  cursor: pointer; padding: 1px 7px; border-radius: 5px; border: 1px solid transparent; user-select: none;
  box-shadow: inset 0 1px 0 rgba(223,228,236,.045);
  transition: transform .09s cubic-bezier(.2,.7,.3,1), border-color .12s, background-color .12s, box-shadow .12s, color .12s;
}
.legend-item:hover { color: var(--ink); border-color: var(--line); }
.legend-item.on { color: var(--ink); border-color: var(--accent); background: rgba(233, 185, 73, 0.08); }
.mini-btn {
  background: var(--panel-2); color: var(--muted); border: 1px solid var(--line);
  border-radius: 5px; font: 600 11px var(--mono); padding: 2px 9px; cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(223,228,236,.045);
  transition: transform .09s cubic-bezier(.2,.7,.3,1), border-color .12s, background-color .12s, box-shadow .12s, color .12s;
}
.mini-btn:hover { color: var(--accent); border-color: var(--accent); }
.mini-btn:disabled { color: var(--faint); border-color: var(--line); opacity: .55; cursor: default; }
.mini-btn:disabled:hover { color: var(--faint); border-color: var(--line); }

/* ---------- snapshot selector strip ---------- */
.snap-strip { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }
.snap-chip {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  background: var(--panel); color: var(--muted); border: 1px solid var(--line);
  border-radius: 8px; padding: 7px 12px; cursor: pointer; text-align: left;
  font: 12px var(--mono); user-select: none;
  box-shadow: inset 0 1px 0 rgba(223,228,236,.045);
  transition: transform .09s cubic-bezier(.2,.7,.3,1), border-color .12s, background-color .12s, box-shadow .12s, color .12s;
}
.snap-chip:hover { color: var(--ink); border-color: var(--accent); }
.snap-chip.on { color: var(--ink); border-color: var(--accent); background: rgba(233, 185, 73, 0.08); }
.snap-chip-name { font-weight: 700; font-size: 11px; letter-spacing: .08em; text-transform: uppercase; }
.snap-chip.on .snap-chip-name { color: var(--accent); }
.snap-chip-time { font-size: 11.5px; }
.snap-chip-meta { font-size: 10.5px; color: var(--faint); }

/* ---------- session layout ---------- */
.session-body { display: grid; grid-template-columns: minmax(280px, 340px) minmax(0, 1fr) minmax(0, 1fr); gap: 16px; padding: 14px 0 80px; align-items: start; }
@media (max-width: 1100px) { .session-body { grid-template-columns: 1fr; } }

.rail { border: 1px solid var(--line); border-radius: 8px; background: var(--panel); overflow: hidden; }
.rail-map { width: 100%; height: 38px; display: block; background: var(--panel-2); border-bottom: 1px solid var(--line); cursor: pointer; }
.zoom-edge {
  font: 600 10px var(--mono); letter-spacing: .06em; color: var(--accent);
  padding: 3px 12px; background: rgba(233, 185, 73, 0.06);
  border-top: 1px dashed rgba(233, 185, 73, 0.45); border-bottom: 1px dashed rgba(233, 185, 73, 0.45);
}
.rec.zoom-out { opacity: 0.35; }
.rail.collapsed .rail-map, .rail.collapsed .rail-search, .rail.collapsed .rail-list, .rail.collapsed .rail-head label, .rail.collapsed #railCount { display: none; }
.rail.collapsed .rail-head { border-bottom: none; justify-content: center; padding: 9px 4px; }
.session-body.rail-collapsed { grid-template-columns: 46px minmax(0, 1fr) minmax(0, 1fr); }
.rail-head { display:flex; justify-content: space-between; align-items:center; padding: 9px 12px; border-bottom: 1px solid var(--line); transition: box-shadow .18s ease; }
.rail-head label { font-size: 12px; color: var(--muted); display: flex; gap: 6px; align-items: center; cursor: pointer; }
.rail-list { max-height: calc(100vh - 220px); overflow-y: auto; overscroll-behavior: contain; }
.rec {
  display: grid; grid-template-columns: 10px 118px 1fr; gap: 10px; align-items: baseline;
  padding: 6px 12px; cursor: pointer; border-left: 3px solid transparent;
  font-family: var(--mono); font-size: 12.5px;
  transition: background-color .1s linear, border-left-color .14s cubic-bezier(.2,.7,.3,1);
}
.rec:hover { background: var(--panel-2); }
.rec.sel { background: var(--panel-2); border-left-color: var(--accent); }
.rec .dot { width: 8px; height: 8px; border-radius: 2px; align-self: center; transition: transform .12s cubic-bezier(.2,.7,.3,1); }
.rec .dot-hollow { background: transparent; border: 2px solid; width: 8px; height: 8px; }
.rec .kind { color: var(--muted); font-size: 11px; letter-spacing: .04em; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rec .prev { color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rec.sidechain { opacity: .45; }
.rec.ctx-out .prev, .rec.ctx-out .kind { color: var(--faint); }
.rec.compact-row { background: rgba(215,93,132,.08); transition: background .14s ease, box-shadow .14s ease; }

/* ---------- context panel ---------- */
.ctx-panel { min-width: 0; }
/* full-width view switcher: nine tabs and their controls on one row — no wrap,
   no horizontal scrolling, everything always visible */
.panel-head { display: flex; gap: 12px; align-items: center; padding: 10px 0 8px; }
.panel-head .tabs { margin-bottom: 0; flex: 0 1 auto; flex-wrap: nowrap; justify-content: flex-start; }
.tab-sep { width: 1px; align-self: stretch; background: var(--line); margin: 3px 4px; flex: none; }
.panel-head .sortish { margin-left: auto; }
/* the finder heads the pane it filters, spanning its full width */
.panel-search { padding: 0 0 8px; }
.panel-search .sq { width: 100%; max-width: none; }
body.session-mode .ctx-panel .panel-search {
  position: sticky; top: 0; z-index: 5; background: var(--bg); padding: 2px 0 8px;
}
body.session-mode .ctx-panel.stuck .panel-search { box-shadow: 0 6px 8px -6px var(--c-shadow); }
@media (max-width: 1100px) { .panel-head, .panel-head .tabs { flex-wrap: wrap; } }
.rail-search { padding: 6px 10px; border-bottom: 1px solid var(--line); }
.rail-search .sq { width: 100%; max-width: none; }
.search-input.sq { padding: 5px 10px; font-size: 12px; border-radius: 6px; }
.tabs { display: flex; gap: 4px; margin-bottom: 10px; flex-wrap: wrap; }
.tabs button {
  background: var(--panel); color: var(--muted); border: 1px solid var(--line);
  border-radius: 6px; padding: 5px 11px; font: 600 11.5px var(--sans);
  letter-spacing: .04em; text-transform: uppercase; cursor: pointer;
  white-space: nowrap; display: inline-flex; align-items: baseline; gap: 5px;
  box-shadow: inset 0 1px 0 rgba(226,234,226,.045);
  transition: transform .09s cubic-bezier(.2,.7,.3,1), border-color .12s, background-color .12s, box-shadow .12s, color .12s;
}
.tabs button.on { color: var(--bg); background: var(--accent); border-color: var(--accent); }
/* counts ride along without spending a tab's worth of width */
.tabs .tab-n { font: 600 9.5px var(--mono); letter-spacing: 0; color: var(--faint); }
.tabs button.on .tab-n { color: rgba(15, 26, 19, .6); }
/* no overflow:hidden here — it would trap position:sticky summaries; corner
   clipping is handled with per-edge radii instead */
.layer { border: 1px solid var(--line); border-radius: 8px; background: var(--panel); margin-bottom: 12px; }
.layer > summary { border-radius: 7px 7px 0 0; }
.layer:not([open]) > summary { border-radius: 7px; }
.layer > summary {
  list-style: none; cursor: pointer; padding: 9px 14px;
  display: flex; gap: 10px; align-items: baseline;
}
.layer > summary::-webkit-details-marker { display: none; }
.layer > summary:hover { background: var(--panel-2); }
.layer > summary .badge { margin-left: auto; font-family: var(--mono); font-size: 11px; color: var(--faint); }
.layer .body { border-top: 1px solid var(--line); padding: 12px 14px; }
.layer .note { font-size: 12px; color: var(--faint); font-style: italic; margin-bottom: 8px; }
pre.block {
  font-family: var(--mono); font-size: 12.5px; line-height: 1.5; color: var(--ink);
  white-space: pre-wrap; word-break: break-word;
  background: var(--bg); border: 1px solid var(--line); border-radius: 6px;
  padding: 10px 12px; overflow-x: auto; max-height: 480px; overflow-y: auto;
  overscroll-behavior: contain;
}
.kv { display: grid; grid-template-columns: max-content 1fr; gap: 3px 16px; font-family: var(--mono); font-size: 12.5px; }
.kv .k { color: var(--muted); }
.gauge { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.gauge .num { font-family: var(--mono); font-size: 26px; font-weight: 700; color: var(--accent); }
.gauge .parts { font-family: var(--mono); font-size: 12px; color: var(--muted); }
.chiplist { display: flex; flex-wrap: wrap; gap: 6px; }
.chip { font-family: var(--mono); font-size: 11.5px; background: var(--bg); border: 1px solid var(--line); border-radius: 999px; padding: 2px 10px; color: var(--ink); }
.chip-f {
  cursor: pointer; user-select: none; border-color: var(--chip-c, var(--line));
  box-shadow: inset 0 1px 0 rgba(223,228,236,.045);
  transition: transform .09s cubic-bezier(.2,.7,.3,1), border-color .12s, background-color .12s, box-shadow .12s, color .12s;
}
.chip-f:hover { background: var(--panel-2); }
/* ON ring is an inset shadow, not an outline — the outline belongs to focus alone */
.chip-f.on { background: var(--chip-c); border-color: var(--chip-c); color: var(--bg); box-shadow: none; font-weight: 600; }
.chip.new { border-color: var(--k-attach); color: var(--k-attach); }

/* message thread inside context tab */
.msg {
  border: 1px solid var(--line); border-radius: 8px; margin-bottom: 8px; overflow: hidden; background: var(--panel);
  transition: box-shadow .12s ease, border-color .12s ease, background-color .12s ease;
}
.msg > summary { list-style: none; cursor: pointer; padding: 7px 12px; display: flex; gap: 10px; align-items: baseline; font-family: var(--mono); font-size: 12.5px; }
.msg > summary::-webkit-details-marker { display: none; }
.msg > summary .role { font-weight: 700; font-size: 11px; letter-spacing: .1em; text-transform: uppercase; }
.msg > summary .prev { color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; flex: 1; }
.msg > summary .tok-d { font-size: 10.5px; color: var(--accent); white-space: nowrap; }
.msg .dur-d, .msg.mrow .dur-d { font-size: 10.5px; color: var(--faint); white-space: nowrap; margin-right: 2px; }
.msg > summary .tok-d.neg { color: var(--k-event); }
.msg .body { border-top: 1px solid var(--line); padding: 10px 12px; }
.msg.m-user > summary .role { color: var(--k-user); }
.msg.m-assistant > summary .role { color: var(--k-assistant); }
.msg.m-attachment > summary .role { color: var(--k-attach); }
.msg.m-system > summary .role, .msg.m-compact > summary .role { color: var(--k-event); }
.msg.m-tool > summary .role { color: var(--k-tool); }
.blk { margin-bottom: 8px; }
.blk .blk-tag { font-family: var(--mono); font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--faint); margin-bottom: 3px; }

.ctx-group { margin-bottom: 22px; }
.group-head { margin: 2px 2px 8px; color: var(--accent); }
/* inset rather than a real 3px border: a border would jog the row's text 2px
   sideways the instant it is focused (same idiom as .pair-hl below) */
.msg.focus { box-shadow: inset 3px 0 0 var(--accent); border-color: var(--accent); }
.msg.focus > summary { background: rgba(233, 185, 73, 0.06); }

.two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 1100px) { .two-col { grid-template-columns: 1fr; } }

.pill-select { background: var(--panel-2); color: var(--ink); border: 1px solid var(--line); border-radius: 6px; font: 12px var(--mono); padding: 4px 8px; max-width: 100%; }
.warn { color: var(--k-event); font-size: 12.5px; }
.hint { color: var(--faint); font-size: 12px; }

@media (prefers-reduced-motion: reduce) { * { transition: none !important; } }

/* ---------- session mode: one scroll owner per pane ----------
   The page itself stops scrolling; the record rail and the context panel each
   scroll independently, so the wheel never grabs the wrong surface. */
body.session-mode { height: 100vh; overflow: hidden; }
body.session-mode .app { height: 100vh; display: flex; flex-direction: column; min-height: 0; max-width: none; }
body.session-mode #view { display: flex; flex-direction: column; flex: 1; min-height: 0; }
body.session-mode .session-body { flex: 1; min-height: 0; align-items: stretch; padding-bottom: 14px; }
body.session-mode .rail { display: flex; flex-direction: column; min-height: 0; }
body.session-mode .rail-list { flex: 1; max-height: none; }
body.session-mode .ctx-panel { overflow-y: auto; min-height: 0; overscroll-behavior: contain; padding-right: 2px; }
/* the whole range header card pins at panel level while events scroll beneath */
.range-head { margin-bottom: 4px; }
body.session-mode .ctx-panel .range-head {
  position: sticky; top: var(--pheadH, 46px); z-index: 4; background: var(--bg);
  padding-bottom: 8px;
}
/* depth only once rows are actually passing under it */
body.session-mode .ctx-panel.stuck .range-head::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 8px;
  pointer-events: none;
  background: linear-gradient(var(--c-shadow), transparent);
}
.range-card { border: 1px solid var(--line); border-radius: 8px; background: var(--panel); padding: 10px 14px; }
.rh-row { display: flex; justify-content: space-between; gap: 10px; align-items: baseline; flex-wrap: wrap; }
.rh-badge { font-family: var(--mono); font-size: 11px; color: var(--faint); }
.ctx-panel .layer.no-stick > summary { position: static !important; }

/* section headers stick just below the tab row while their content scrolls */
/* second-level heads pin *below* the summary card, never over it */
body.session-mode .ctx-panel .group-head,
body.session-mode .ctx-panel .layer > summary,
body.session-mode .ctx-panel .snap-strip {
  position: sticky; top: calc(var(--pheadH, 0px) + var(--rheadH, 0px)); z-index: 3;
}
body.session-mode .ctx-panel .layer > summary { background: var(--panel); }
body.session-mode .ctx-panel .group-head { background: var(--bg); padding-bottom: 5px; }
body.session-mode .ctx-panel .snap-strip { background: var(--bg); padding: 2px 0 6px; }

/* the switcher spans the app above the panes, so it needs no sticky offset;
   the depth cue moves to the panes themselves as content slides under them */
body.session-mode .panel-head {
  background: var(--bg);
  border-bottom: 1px solid var(--line);
}

@media (max-width: 1100px) {
  /* stacked single-column layout: fixed panes don't fit — revert to page scroll */
  body.session-mode { height: auto; overflow: auto; }
  body.session-mode .app, body.session-mode #view { display: block; height: auto; }
  body.session-mode .ctx-panel { overflow-y: visible; }
  body.session-mode .rail-list { max-height: 50vh; }
}

/* ---------- CodeMirror JSON blocks (theme: ctx) ---------- */
.cm-json { margin: 2px 0; }
.cm-json .CodeMirror {
  height: auto; font-family: var(--mono); font-size: 12.5px; line-height: 1.5;
  background: var(--bg); color: var(--ink);
  border: 1px solid var(--line); border-radius: 6px;
}
.cm-json .CodeMirror-scroll { max-height: 480px; overscroll-behavior: contain; }
.cm-tall .CodeMirror-scroll { max-height: 68vh; }
.cm-s-ctx .CodeMirror-gutters { background: var(--panel); border-right: 1px solid var(--line); }
.cm-s-ctx .CodeMirror-linenumber { color: var(--faint); font-size: 11px; }
.cm-s-ctx .CodeMirror-cursor { border-left-color: transparent; }
.cm-s-ctx .CodeMirror-selected { background: rgba(233, 185, 73, 0.15); }
.cm-s-ctx span.cm-string { color: #27a578; }
.cm-s-ctx span.cm-string.cm-property { color: #4a8fdd; }
.cm-s-ctx span.cm-number { color: #f0b429; }
.cm-s-ctx span.cm-atom { color: #8a5fe8; }   /* true / false / null */
.cm-s-ctx span.cm-punctuation, .cm-s-ctx span.cm-bracket { color: var(--muted); }
.cm-s-ctx .CodeMirror-activeline-background { background: transparent; }

/* ---------- agent sub-timeline lanes ---------- */
.lanes {
  position: relative; overflow: hidden; margin-top: 4px;
  background: rgba(0, 0, 0, 0.10); /* barely darker than the page — just enough to read as a surface */
  border-radius: 6px;
  /* gently inset: soft inner shadows top and bottom */
  box-shadow: inset 0 5px 5px -5px rgba(0, 0, 0, 0.45), inset 0 -5px 5px -5px rgba(0, 0, 0, 0.45);
  padding: 4px 0;
}
.lane-bar {
  position: absolute; height: 14px; box-sizing: border-box;
  background: rgba(138, 95, 232, 0.22); border: 1px solid var(--k-tool); border-radius: 4px;
  font: 10px/12px var(--mono); color: var(--ink); padding: 0 5px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer;
}
.lane-bar:hover { background: rgba(138, 95, 232, 0.45); }
.lane-bar.on { border-color: var(--accent); background: rgba(233, 185, 73, 0.18); }
.lane-chip {
  position: absolute; height: 14px; box-sizing: border-box;
  background: rgba(138, 95, 232, 0.35); border: 1px dashed var(--k-tool); border-radius: 4px;
  font: 700 10px/12px var(--mono); color: var(--ink); padding: 0 6px; text-align: center;
  white-space: nowrap; overflow: hidden; cursor: pointer;
}
.lane-chip:hover { background: rgba(138, 95, 232, 0.55); }
.lane-chip.on { border-color: var(--accent); }
.lane-pop {
  position: fixed; z-index: 60; min-width: 280px; max-width: 400px; max-height: 320px; overflow-y: auto;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px; padding: 9px 10px;
  box-shadow: 0 10px 28px var(--c-shadow); overscroll-behavior: contain;
}
.lane-pop-item { display: flex; gap: 8px; align-items: center; padding: 4px 7px; border-radius: 5px; cursor: pointer; font: 11.5px var(--mono); color: var(--ink); }
.lane-pop-item:hover { background: var(--panel); }
.lp-name { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lp-dur { color: var(--faint); white-space: nowrap; }
.lp-group { font: 700 10px var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--k-tool); padding: 6px 4px 2px; }

/* ---------- preview pane (third column) ---------- */
.preview-pane {
  border: 1px solid var(--line); border-radius: 8px; background: var(--panel);
  min-width: 0; display: flex; flex-direction: column; overflow: hidden;
}
.pv-head { display: flex; gap: 10px; align-items: center; padding: 8px 12px; border-bottom: 1px solid var(--line); flex-wrap: wrap; }
.pv-toggle { margin-left: auto; display: inline-flex; gap: 6px; }
.pv-body { padding: 12px 16px; overflow-y: auto; overscroll-behavior: contain; min-height: 0; flex: 1; }
/* Inside the preview pane nothing scrolls internally: strip scroll-container
   status entirely (Safari treats any scroll container with overscroll-behavior:
   contain as final for the wheel, even when it cannot move on that axis). */
.pv-body pre.block { max-height: none; overflow: visible; overscroll-behavior: auto; }
.pv-body .cm-json .CodeMirror-scroll {
  max-height: none;
  overflow: visible !important;
  margin-bottom: 0; margin-right: 0; padding-bottom: 0;
  overscroll-behavior: auto;
}
/* the pane is the single scroll owner — no CM block re-enables its own scroller */
.pv-img { max-width: 100%; border: 1px solid var(--line); border-radius: 6px; margin: 4px 0; display: block; }
.pv-empty { padding: 16px; }
.jsonl-rec { margin-bottom: 12px; border-left: 2px solid var(--line); padding-left: 10px; }
.mini-btn.on { color: var(--bg); background: var(--accent); border-color: var(--accent); }
body.session-mode .preview-pane { min-height: 0; }
@media (max-width: 1100px) { .pv-body { max-height: 60vh; } }

/* flat rows in the main view (expansion moved to the preview pane) */
.msg.mrow { display: flex; gap: 10px; align-items: baseline; padding: 7px 12px; font-family: var(--mono); font-size: 12.5px; cursor: pointer; transition: background-color .1s linear, box-shadow .14s; }
.msg.mrow .role { font-weight: 700; font-size: 11px; letter-spacing: .1em; text-transform: uppercase; }
.msg.mrow .prev { color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; flex: 1; }
.msg.mrow .tok-d { font-size: 10.5px; color: var(--accent); white-space: nowrap; }
.msg.mrow .tok-d.neg { color: var(--k-event); }
.msg.mrow:hover { background: var(--panel-2); }
/* paired call/result: a quiet left tick + faint wash, not an inspector outline */
.pair-hl { box-shadow: inset 3px 0 0 var(--k-tool); background: rgba(138, 95, 232, 0.05) !important; }
.msg.m-user .role { color: var(--k-user); }
.msg.m-assistant .role { color: var(--k-assistant); }
.msg.m-attachment .role { color: var(--k-attach); }
.msg.m-system .role, .msg.m-compact .role { color: var(--k-event); }
.msg.m-tool .role { color: var(--k-tool); }

/* ---------- agent focus mode ---------- */
.agent-focus-bar {
  display: flex; gap: 12px; align-items: center;
  padding: 7px 12px; margin: 0 0 6px;
  border: 1px solid var(--k-tool); border-left: 4px solid var(--k-tool);
  border-radius: 6px; background: rgba(138, 95, 232, 0.10);
  font-size: 12.5px; color: var(--ink);
}
.afb-label { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#afbBack { flex: none; }

/* ---------- file-version diffs ---------- */
.d-wrap span { display: block; }
.d-ctx { color: var(--faint); }
.d-del { color: #eba0b1; background: rgba(215, 93, 132, 0.12); }
.d-add { color: #8fd8bd; background: rgba(39, 165, 120, 0.12); }

/* === interaction: canvas & drag state (WS-A) === */
/* A zoom drag latches one pointer for the whole gesture — the canvas keeps its
   resting crosshair, but while the window-level handlers own the drag the
   cursor must not flicker as it crosses other elements.
   The universal selector restyles the whole document, so the class is only
   latched once a gesture is real: a plain click on the tape must not pay for it. */
body.dragging, body.dragging * { cursor: ew-resize !important; }
body.dragging { user-select: none; }
/* the readout's token counts and timestamps stay selectable: both canvases
   preventDefault on mousedown, so a drag can never start a selection anyway,
   and body.dragging covers the gesture window regardless */
.rail-map { transition: box-shadow .12s; }
.rail-map.scrubbing { box-shadow: inset 0 0 0 1px rgba(233, 185, 73, .35); }

/* === interaction: chrome & rows (WS-B) === */
/* Three intensities of one mechanism: a hairline cap at rest, a hard amber
   hairline in a soft bloom on keyboard focus, 1px of downward travel under the
   finger. Amber stays the STATE signal; travel is the TOUCH signal. */

/* on-state caps: the fill is already amber, so the raised edge reads white */
.tabs button.on,
.mini-btn.on,
.legend-item.on,
.snap-chip.on { box-shadow: inset 0 1px 0 rgba(255,255,255,.10); }

/* keyboard focus on small controls — hairline inside a bloom, not a floating box */
.mini-btn:focus-visible,
.zoom-ctl button:focus-visible,
.tabs button:focus-visible,
.legend-item:focus-visible,
.snap-chip:focus-visible,
.chip-f:focus-visible,
.lane-bar:focus-visible,
.lane-chip:focus-visible,
.lane-pop-item:focus-visible {
  outline: 1px solid var(--accent); outline-offset: 1px;
  box-shadow: 0 0 0 3px rgba(233,185,73,.12);
}
/* on + focused: keep the ON ring, add the bloom */
.chip-f.on:focus-visible { box-shadow: 0 0 0 3px rgba(233,185,73,.22); }

/* key travel — the cap bottoms out and springs back */
.mini-btn:active,
.zoom-ctl button:active,
.tabs button:active,
.legend-item:active,
.snap-chip:active,
.chip-f:active {
  transform: translateY(1px);
  box-shadow: inset 0 1px 3px rgba(0,0,0,.38);
}
/* the card stays on the deck: no hover lift, no drop shadow — it only sinks */
.session-card:active { transform: translateY(1px); }

/* row detent — the press is a dimmer draft of the selection tick, same channel */
.rec:active { background: var(--panel-2); border-left-color: rgba(233,185,73,.40); }
.msg.mrow:active { background: var(--panel-2); box-shadow: inset 3px 0 0 rgba(233,185,73,.40); }

/* keyboard focus on rows — same channels, one notch brighter, never an outline */
.rec:focus-visible {
  outline: none; background: var(--panel-2);
  border-left-color: rgba(233,185,73,.55);
  box-shadow: inset 0 0 0 1px rgba(233,185,73,.20);
}
.msg.mrow:focus-visible {
  outline: none; background: var(--panel-2);
  box-shadow: inset 3px 0 0 rgba(233,185,73,.55), inset 0 0 0 1px rgba(233,185,73,.20);
}
/* a committed selection never dims under press or focus */
.rec.sel:active, .rec.sel:focus-visible { border-left-color: var(--accent); }

/* the kind dot takes weight under the pointer — transform only, no layout */
.rec:hover .dot { transform: scale(1.15); }
/* the loudest fact in the rail answers the pointer in the rail's own grammar:
   hover deepens the wash, the left tick stays reserved for state. An inset bar
   here would start at the padding box — 3px inboard of every other row marker,
   since .rec carries a 3px transparent border-left. */
.rec.compact-row:hover { background: rgba(215,93,132,.16); }

/* inputs: the existing focus border gains depth instead of a detached ring */
.search-input:focus-visible,
.pill-select:focus-visible {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(233,185,73,.10);
}

/* === interaction: panel & headers (WS-C) === */

/* focus + pair highlight on the same row: amber bar first, violet beside it,
   so neither signal is swallowed by the other's inset shadow */
.msg.focus.pair-hl { box-shadow: inset 3px 0 0 var(--accent), inset 6px 0 0 var(--k-tool); }

/* the escape hatch announces where it dropped you; the fade ends on the row's
   resting colour rather than transparent, because an animation replaces the
   painted background outright and ending clear would flash the pane through */
@keyframes row-arrive { from { background: rgba(233, 185, 73, 0.16); } to { background: var(--panel); } }
.msg.arrived { animation: row-arrive .38s ease-out; }

/* sticky heads: shadow only once content is actually sliding underneath */
body.session-mode .ctx-panel.stuck .panel-head {
  box-shadow: 0 6px 8px -6px var(--c-shadow);
  border-bottom-color: var(--line);
}
.rail.scrolled .rail-head { box-shadow: 0 6px 8px -6px var(--c-shadow); }

/* second-level heads inherit the pane's signal; borders are reserved
   transparent up front so colouring them in never reflows the list */
body.session-mode .ctx-panel .group-head,
body.session-mode .ctx-panel .snap-strip,
body.session-mode .ctx-panel .layer > summary {
  border-bottom: 1px solid transparent;
  transition: border-color .18s ease;
}
body.session-mode .ctx-panel.stuck .group-head,
body.session-mode .ctx-panel.stuck .snap-strip,
body.session-mode .ctx-panel.stuck .layer > summary { border-bottom-color: var(--line); }
/* an open layer already draws a divider on its body: hand that line to the
   pinned summary instead of stacking a second one under it */
body.session-mode .ctx-panel.stuck .layer[open] > .body { border-top-color: transparent; }

@media (prefers-reduced-motion: reduce) { .msg.arrived { animation: none; } }

/* === integration guard: WS-B press/focus x WS-C focus row === */
/* WS-B drafts the amber tick at 40%/55% under press and keyboard focus, in the
   same inset channel WS-C now uses for the COMMITTED focus row — and .msg.mrow
   outranks .msg.focus. Restore full accent on the row that already owns the
   bar, keeping WS-B's focus bloom. Mirrors WS-B's own .rec.sel guard in the
   rail: travel is the touch signal, amber stays the state signal. */
.msg.focus:active { box-shadow: inset 3px 0 0 var(--accent); }
.msg.focus:focus-visible { box-shadow: inset 3px 0 0 var(--accent), inset 0 0 0 1px rgba(233,185,73,.20); }
.msg.focus.pair-hl:active { box-shadow: inset 3px 0 0 var(--accent), inset 6px 0 0 var(--k-tool); }
.msg.focus.pair-hl:focus-visible { box-shadow: inset 3px 0 0 var(--accent), inset 6px 0 0 var(--k-tool), inset 0 0 0 1px rgba(233,185,73,.20); }

/* ---------- theme switcher ----------
   Sits on the maker's mark centre line: same top, same 30px box height, so the
   two align however the clamp() resolves. */
.theme-pick {
  position: absolute; top: clamp(14px, 2.5vw, 26px);
  right: calc(clamp(14px, 3vw, 30px) + 40px);
  height: 30px; display: flex; align-items: center; z-index: 21;
}
.theme-btn, .theme-menu [role="option"] {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--panel); color: var(--muted);
  border: 1px solid var(--line); border-radius: 6px;
  font: 600 10.5px var(--mono); letter-spacing: .04em;
  padding: 4px 8px; cursor: pointer;
}
.theme-btn:hover, .theme-menu [role="option"]:hover { color: var(--ink); border-color: var(--accent); }
.theme-btn .caret { color: var(--faint); font-size: 9px; }
/* author display:flex would otherwise beat the UA rule for [hidden] */
.theme-menu[hidden] { display: none; }
.theme-menu {
  position: absolute; top: 32px; right: 0; z-index: 30;
  display: flex; flex-direction: column; gap: 3px; min-width: 148px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
  padding: 6px; box-shadow: 0 10px 28px var(--c-shadow);
}
.theme-menu [role="option"] { border-color: transparent; background: transparent; width: 100%; justify-content: flex-start; }
.theme-menu [role="option"][aria-selected="true"] { color: var(--ink); border-color: var(--accent); background: var(--panel-2); }
.theme-grp {
  font: 600 9px var(--mono); letter-spacing: .16em; text-transform: uppercase;
  color: var(--faint); padding: 4px 8px 2px;
}
/* each option carries the theme it selects: surface, panel edge, accent dot */
.theme-btn .sw, .theme-menu .sw {
  width: 13px; height: 13px; border-radius: 3px; border: 1px solid;
  display: inline-flex; align-items: center; justify-content: center; flex: none;
}
.theme-btn .sw i, .theme-menu .sw i { width: 5px; height: 5px; border-radius: 50%; display: block; }

/* ---------- narrow-screen gate ----------
   The app is a side-by-side instrument. Rather than stack it into a broken
   phone layout, say so — with an escape hatch for anyone who insists. */
.too-narrow { display: none; }
@media (max-width: 900px) {
  html:not(.force-narrow) body > .app { display: none; }
  html:not(.force-narrow) .too-narrow {
    display: flex; align-items: center; justify-content: center;
    min-height: 100vh; padding: 24px; background: var(--bg);
  }
}
.tn-card {
  max-width: 30rem; border: 1px solid var(--line); border-left: 4px solid var(--accent);
  border-radius: 10px; background: var(--panel); padding: 22px 24px; color: var(--muted);
}
.tn-mark { font-size: 21px; font-weight: 700; letter-spacing: .06em; color: var(--ink); margin-bottom: 14px; }
.tn-mark .dim { color: var(--accent); }
.tn-lead { color: var(--ink); font-size: 15px; margin-bottom: 10px; }
.tn-card p { font-size: 13.5px; line-height: 1.6; margin-bottom: 10px; }
.tn-meta { color: var(--faint); }
.tn-card .mini-btn { margin-top: 6px; }
