/* Emberfall Chronicle — design system lifted from the canvas (docs/08). Dark, log-viewer density. */
:root{
  --bg:#0b0d10; --panel:#10141a; --panel2:#151a21; --ink:#dbe2ea; --ink-dim:#aeb7c2;
  --ink-faint:#566070; --line:rgba(255,255,255,.09); --line2:rgba(255,255,255,.14);
  --accent:#d9a441; --accent-hi:#e8c06c; --accent-soft:rgba(217,164,65,.14);
  --combat:#e2574c; --roleplay:#5b8fd9; --social:#5b8fd9; --exploration:#5fbf9f; --chitchat:#8b93a1; --break:#4a5058;
  --cmb:#e2574c; --dmg:#e08a3c; --gld:#d4b054; --itm:#9fbf5f; --loc:#4fb3a5; --npc:#5b8fd9; --mls:#b07fe0;
  --sans:'IBM Plex Sans',system-ui,-apple-system,Segoe UI,Roboto,sans-serif;
  --mono:'JetBrains Mono',ui-monospace,SFMono-Regular,Menlo,monospace;
}
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{background:var(--bg);color:var(--ink);font-family:var(--sans);font-size:14px;line-height:1.5}
a{color:var(--accent);text-decoration:none}
a:hover{color:var(--accent-hi)}
h1,h2,h3{font-weight:600;margin:0}

/* layout */
.layout{display:grid;grid-template-columns:210px 1fr;grid-template-rows:1fr auto;min-height:100vh}
.rail{grid-row:1/3;background:#0c0f13;border-right:1px solid var(--line);padding:14px 10px;position:sticky;top:0;height:100vh;overflow:auto}
.rail .brand{font:700 13px var(--mono);color:var(--accent);padding:6px 8px 14px;letter-spacing:.04em}
.rail a{display:block;color:var(--ink-dim);padding:7px 10px;border-radius:6px;font-size:13px}
.rail a:hover{background:rgba(255,255,255,.05);color:var(--ink)}
.rail a.active{background:rgba(217,164,65,.14);color:var(--accent-hi)}
.rail .sec{font:700 9px var(--mono);letter-spacing:.14em;color:var(--ink-faint);padding:16px 10px 6px}
/* NOTE: no `overflow` here — the page scrolls on the WINDOW. An overflow on .main would make it
   the containing block for position:sticky, and since .main itself doesn't scroll the sticky rail
   would scroll away. Wide content uses its own overflow-x wrappers (tables/pre/.scroll). */
.main{padding:22px 26px 40px;max-width:1180px}
.statusbar{grid-column:1/3;border-top:1px solid var(--line);background:#0c0f13;padding:7px 16px;font:11px var(--mono);color:var(--ink-faint);display:flex;gap:18px;flex-wrap:wrap;align-items:center}
.statusbar .beat{color:var(--accent)}

/* breadcrumb */
.crumbs{display:flex;align-items:center;gap:8px;font-size:12.5px;color:var(--ink-faint);margin-bottom:18px;flex-wrap:wrap}
.crumbs a{color:var(--ink-dim)} .crumbs .sep{color:var(--ink-faint)}
.crumbs .here{color:var(--ink)}
.crumbs .navbtns{margin-left:auto;display:flex;gap:6px}

/* cards / panels */
.panel{background:var(--panel);border:1px solid var(--line);border-radius:8px;box-shadow:0 2px 12px rgba(0,0,0,.45)}
.pad{padding:16px 18px}
.grid{display:grid;gap:16px}
.cols-2{grid-template-columns:1fr 1fr}
.cols-3{grid-template-columns:repeat(3,1fr)}
.hd{font:700 10px var(--mono);letter-spacing:.12em;color:var(--ink-faint);margin:0 0 10px}
.muted{color:var(--ink-faint)} .dim{color:var(--ink-dim)}
.pagetitle{font-size:20px;font-weight:700;margin-bottom:2px}
.sub{color:var(--ink-faint);font-size:12.5px;margin-bottom:18px}

/* chips */
.chip{font:600 10.5px var(--mono);padding:2px 6px;border-radius:5px;background:rgba(255,255,255,.08);color:var(--ink-dim);display:inline-block}
.cite{font:600 10px var(--mono);padding:2px 6px;border-radius:4px;background:#dbe2ea;color:#0b0d10;white-space:nowrap}
.tag{font-size:10.5px;padding:2px 7px;border-radius:10px;border:1px solid var(--line2);color:var(--ink-dim)}
.ecode{font:700 9.5px var(--mono);padding:2px 5px;border-radius:3px;color:#0b0d10}
.tl-facet{cursor:pointer;transition:opacity .15s} .tl-facet.off{opacity:.28}
.tl-ev{gap:8px}
.pill{font:600 10px var(--mono);padding:2px 7px;border-radius:9px}

/* tabs */
.tabs{display:flex;gap:4px;border-bottom:1px solid var(--line);margin:14px 0 16px}
.tabs a{padding:8px 14px;color:var(--ink-dim);border-bottom:2px solid transparent;font-size:13px}
.tabs a.active{color:var(--ink);border-bottom-color:var(--accent)}

/* tables */
table{border-collapse:collapse;width:100%;font-size:13px}
th{text-align:left;font:700 9.5px var(--mono);letter-spacing:.1em;color:var(--ink-faint);padding:8px 10px;border-bottom:1px solid var(--line)}
td{padding:8px 10px;border-bottom:1px solid var(--line);vertical-align:top}
tr:hover td{background:rgba(255,255,255,.02)}
.num{font-family:var(--mono)}

/* session rows / lists */
.srow{display:flex;align-items:center;gap:12px;padding:9px 12px;border-bottom:1px solid var(--line)}
.srow:hover{background:rgba(255,255,255,.03)}
.snum{font:700 11px var(--mono);color:var(--accent);width:38px}

/* transcript */
.tline{display:grid;grid-template-columns:64px 96px 1fr;gap:12px;padding:5px 0;border-bottom:1px solid rgba(255,255,255,.04)}
.tline .ts{font:11px var(--mono);color:var(--ink-faint)}
.tline .who{font-weight:600;font-size:12.5px}
.tline.dm{background:rgba(217,164,65,.05)}
.tline.hide-cc{display:none}
.evchip{display:inline-block;margin-left:8px}

/* attendance */
.att{display:flex;gap:6px;flex-wrap:wrap}
.ini{width:26px;height:26px;border-radius:50%;display:flex;align-items:center;justify-content:center;font:700 10px var(--mono);color:#0b0d10}
.ini.absent{opacity:.28;filter:grayscale(1)}

/* mode bar */
.modebar{display:flex;height:12px;border-radius:3px;overflow:hidden;border:1px solid var(--line)}
.modebar span{display:block;height:100%}
/* mode TIMELINE bar — sequential segments in play order (vs .modebar's aggregate time-spent) */
.modeline{display:flex;height:20px;border-radius:4px;overflow:hidden;border:1px solid var(--line)}
.modeline span{display:block;height:100%}

/* heartbeat / matrix */
.matrix td,.matrix th{padding:6px 8px;text-align:center}
.matrix td.sess{text-align:left;font:600 11px var(--mono)}
.cell{display:inline-flex;align-items:center;gap:5px;font:10px var(--mono)}
.dot{width:8px;height:8px;border-radius:50%;display:inline-block}
.dot.receiving{background:var(--accent);animation:pulse 1.4s infinite}
.dot.complete{background:#5fbf7f}
.dot.stale{background:#e08a3c}
.dot.backfill{background:#e2574c}
/* H3: suspect is a non-blocking badge layered next to a state dot (never its own state) — an
   informational row-count-drop flag on an already-active version, not a hold. */
.dot.suspect{background:#d9a441;box-shadow:0 0 0 2px rgba(217,164,65,.3)}
.dot.absent{background:#2a3038}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.3}}
.banner{background:linear-gradient(90deg,rgba(217,164,65,.16),rgba(217,164,65,.05));border:1px solid rgba(217,164,65,.4);border-radius:8px;padding:12px 16px;margin-bottom:16px;display:flex;align-items:center;gap:14px}

/* buttons */
.btn{font:600 12px var(--sans);padding:6px 12px;border-radius:6px;border:1px solid var(--line2);background:var(--panel2);color:var(--ink);cursor:pointer}
.btn:hover{border-color:var(--accent);color:var(--accent-hi)}
.btn.sm{font-size:11px;padding:4px 9px}
.btn.gold{background:var(--accent);color:#0b0d10;border-color:var(--accent)}
.btn.danger{color:var(--ink-faint);border-color:transparent}
.btn.danger:hover{color:#fff;background:var(--combat);border-color:var(--combat)}

/* svg maps/graphs */
.stage{position:relative;background:#0c0f13;border:1px solid var(--line);border-radius:8px;overflow:hidden}
svg .edge{stroke:rgba(255,255,255,.14)}
svg .node{cursor:pointer}
svg .node:hover circle{stroke:var(--accent-hi);stroke-width:2}
svg text{fill:var(--ink-dim);font:10px var(--sans)}
.area{fill:rgba(91,143,217,.10);stroke:rgba(91,143,217,.5);stroke-dasharray:4 3}
.pin{cursor:pointer}
.pin:hover circle{stroke:var(--accent-hi)}

/* related-items list (reusable) */
.rlist{margin-bottom:14px}
.rlist .rhd{font:700 9.5px var(--mono);letter-spacing:.1em;color:var(--ink-faint);display:flex;justify-content:space-between;padding:6px 0;border-bottom:1px solid var(--line)}
.rrow{display:flex;align-items:center;gap:8px;padding:6px 0;border-bottom:1px solid rgba(255,255,255,.04);font-size:13px}
.rrow.sel{background:var(--accent-soft);border-radius:6px;padding-left:8px;padding-right:8px}
a.rrow{color:var(--ink)} a.rrow:hover{background:rgba(255,255,255,.04)}
a.tag{cursor:pointer} a.tag:hover{border-color:var(--accent);color:var(--accent-hi)}

/* proposal cards */
.prop{border:1px solid var(--line2);border-radius:8px;padding:12px 14px;margin-bottom:10px;background:var(--panel2)}
.prop .k{font:700 9px var(--mono);letter-spacing:.12em;color:var(--accent);margin-bottom:5px}
.prop .acts{display:flex;gap:8px;margin-top:10px}

/* form inputs (events config, filters) */
.inp{background:var(--panel2);border:1px solid var(--line2);color:var(--ink);border-radius:6px;
  padding:6px 9px;font:12.5px var(--sans);width:100%}
.inp:focus{outline:none;border-color:var(--accent)}
textarea.inp{resize:vertical}

.flex{display:flex;gap:10px;align-items:center}
.wrap{flex-wrap:wrap}
.right{margin-left:auto}
.spacer{height:16px}
code,pre{font-family:var(--mono);font-size:12px}
pre{background:#0c0f13;border:1px solid var(--line);border-radius:6px;padding:12px;overflow:auto;white-space:pre-wrap}

/* responsive two-column: side-by-side on wide screens, stacked on narrow (session Overview) */
.cols-2-resp{display:grid;grid-template-columns:1fr 1fr;gap:16px;align-items:start}
@media(max-width:820px){.cols-2-resp{grid-template-columns:1fr}}

/* transcript overlays/rails — toggled via classes on .transcript (see app.js) */
.btn.on{background:var(--accent);color:#0b0d10;border-color:var(--accent)}
.scene-head{font:700 10px var(--mono);letter-spacing:.1em;color:var(--accent);
  margin:16px 0 4px;padding-top:8px;border-top:1px dashed var(--line2)}
.transcript.ov-mode .tline{border-left:3px solid var(--m);padding-left:8px}
/* mode tint OFF → collapse the tint gutter entirely (no reserved space) */
.transcript:not(.ov-mode) .tline{border-left:0;padding-left:0}
.transcript:not(.ov-events) .evchip{display:none}
.transcript:not(.ov-scenes) .scene-head{display:none}
/* timestamps OFF → drop the ts column so the rest shifts left (was visibility:hidden = empty gutter) */
.transcript:not(.ov-ts) .tline .ts{display:none}
.transcript:not(.ov-ts) .tline{grid-template-columns:96px 1fr}
/* DIGEST BEAT rows have no speaker → ts + text only (2 col). Scope to .dbeat, NOT all .tblock —
   the transcript STREAM view also uses .tblock but keeps its speaker column (3 col via .tline). */
.tline.dbeat{grid-template-columns:64px 1fr}
.transcript:not(.ov-ts) .tline.dbeat{grid-template-columns:1fr}
.transcript.cc-hidden .tline[data-mode="chitchat"]{display:none}
.tline.noise{opacity:.38}
.tline.noise .chip{background:var(--bad);color:#0b0d10}
.tblock span:last-child{line-height:1.55}

/* transcript + scene/event rail side by side */
.tgrid{display:grid;grid-template-columns:1fr 156px;gap:16px;align-items:start}
/* transcript scene/event rail — its OWN class (.trail); do NOT reuse .rail (the left nav uses
   that, and its grid-row/height/background rules would leak and swap the columns). */
@media(max-width:820px){.tgrid{grid-template-columns:1fr} .trail{display:none}}
.trail{position:relative;position:sticky;top:12px;height:74vh;border-left:1px solid var(--line2);margin-left:4px}
.trail-scene{position:absolute;left:0;transform:translateY(-50%);font:9px var(--mono);color:var(--accent);
  cursor:pointer;white-space:nowrap;padding-left:8px;border-left:2px solid var(--accent);max-width:150px;overflow:hidden;text-overflow:ellipsis}
.trail-scene:hover{color:var(--accent-hi)}
.trail-dot{position:absolute;left:-4px;width:8px;height:8px;border-radius:50%;cursor:pointer;
  transform:translateY(-50%);border:1px solid rgba(0,0,0,.4)}
.trail-dot:hover{transform:translateY(-50%) scale(1.6)}
/* mode band: a colored strip on the rail showing the mode at each point in time */
.trail-mode{position:absolute;left:-3px;width:4px;border-radius:2px;opacity:.55}
/* minimap viewport window: a translucent box showing the portion of the transcript on screen
   (JS sets top + height from scroll). Makes the rail read as a real minimap. */
#trail-cursor{position:absolute;left:-7px;right:-2px;min-height:6px;
  background:rgba(217,164,65,.12);border-top:2px solid var(--accent);
  border-bottom:2px solid var(--accent);z-index:1;pointer-events:none;transition:top .05s linear}
/* composable rail: the overlay tabs toggle which marks appear here (prototype 1a) */
#trail:not(.ov-events) .trail-dot{display:none}
#trail:not(.ov-scenes) .trail-scene{display:none}
#trail:not(.ov-mode) .trail-mode{display:none}


/* multi-part session summary (markdown abstract + Combat/Inventory sections) */
.md{font-size:13.5px;line-height:1.5;color:var(--ink)}
.md p{margin:0 0 8px}
.md p:last-child{margin-bottom:0}
.md h3,.md h4,.md h5,.md h6{margin:12px 0 5px;color:var(--ink);font-family:var(--sans)}
.md h3{font-size:15px}.md h4{font-size:13.5px}.md h5,.md h6{font-size:12px;color:var(--ink-dim);text-transform:uppercase;letter-spacing:.03em}
.md ul{margin:4px 0 8px;padding-left:20px}
.md li{margin:2px 0}
.md code{background:var(--panel2);border:1px solid var(--line);border-radius:3px;padding:0 4px;font-size:12px}
.md strong{color:var(--ink)}
.summary-sec{margin-top:12px;border-top:1px solid var(--line);padding-top:10px}
.summary-sec-h{font:700 12px var(--sans);color:var(--accent-hi);letter-spacing:.02em;margin-bottom:4px}

/* ---- Entity Web graph explorer (R8-3) ---- */
.gx-bar{margin:12px 0 12px}
.gx-bar-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap;padding:5px 0}
.gx-bar-row+.gx-bar-row{border-top:1px solid rgba(255,255,255,.05)}
.gx-lab{font:700 9.5px var(--mono);letter-spacing:.12em;color:var(--ink-faint);white-space:nowrap}
.gx-select{background:var(--panel2);color:var(--ink);border:1px solid var(--line2);border-radius:6px;padding:5px 8px;font:600 12px var(--sans)}
.gx-select.sm{padding:3px 6px;font-size:11px}
.gx-search{flex:1;min-width:150px;background:var(--panel2);color:var(--ink);border:1px solid var(--line2);border-radius:6px;padding:6px 10px;font-size:12.5px}
.gx-spacer{flex:1}
.gx-filters{gap:6px}
.gx-chip{font:600 10.5px var(--mono);padding:3px 8px;border-radius:12px;background:rgba(255,255,255,.05);color:var(--ink-dim);border:1px solid var(--line2);cursor:pointer}
.gx-chip:hover{color:var(--ink);border-color:var(--accent)}
.gx-chip.on{background:var(--accent-soft);color:var(--accent-hi);border-color:var(--accent)}
.gx-chip .gx-ct{opacity:.55;margin-left:3px}
.gx-scrub input[type=range]{width:130px}
.gx-main{display:flex;gap:14px;align-items:stretch;margin-bottom:12px}
.gx-canvas{flex:1;min-width:0;height:600px}
.gx-side{width:330px;flex:none;overflow:auto;max-height:600px}
.gx-sel-kind{font:700 10px var(--mono);letter-spacing:.1em;text-transform:uppercase}
.gx-sel-name{margin:2px 0 4px;font:700 17px var(--sans);color:var(--ink)}
.gx-actions{display:flex;gap:6px;flex-wrap:wrap;margin:8px 0}
.gx-relgrp{padding:5px 0;border-bottom:1px solid rgba(255,255,255,.05);font-size:12.5px;line-height:1.9}
.gx-nb{display:inline-block;margin:0 4px 2px 0;padding:1px 7px;border-radius:9px;background:rgba(255,255,255,.05);color:var(--ink-dim);border:1px solid var(--line)}
.gx-nb:hover{color:var(--accent-hi);border-color:var(--accent)}
.gx-relrow{padding:6px 0;border-bottom:1px solid rgba(255,255,255,.05);font-size:12.5px}
.gx-relrow .tag{margin-right:6px}
.gx-props{font:11px var(--mono);color:var(--ink-faint);margin-top:3px;word-break:break-all}
.gx-counts{font-size:12px;color:var(--ink-dim);margin:6px 0}
.gx-help{font-size:12px;line-height:1.6}
.gx-warn{background:rgba(226,87,76,.12);border:1px solid rgba(226,87,76,.3);border-radius:6px;padding:7px 9px;font-size:11.5px;color:#f0a59d;margin:8px 0}
.gx-focusnote{font-size:11.5px;color:var(--accent-hi);margin-bottom:6px}
.gx-toast{margin-top:10px;background:var(--accent-soft);border:1px solid var(--accent);border-radius:6px;padding:7px 9px;font-size:12px;color:var(--accent-hi)}
.gx-legend{display:flex;gap:12px;flex-wrap:wrap;align-items:center;font:600 10.5px var(--mono);color:var(--ink-faint);padding:2px 2px 14px}
.gx-legend .gx-lg{display:inline-flex;align-items:center;gap:5px}
.gx-legend .gx-lg i{width:10px;height:10px;border-radius:50%;display:inline-block}
.gx-legend .gx-lg b{width:14px;height:3px;border-radius:2px;display:inline-block}
.gx-legend .gx-lg-t{color:var(--ink-dim);letter-spacing:.12em;margin-right:2px}
@media (max-width:900px){.gx-main{flex-direction:column}.gx-side{width:auto;max-height:none}.gx-canvas{height:440px}}
/* [hidden] must beat the author display:flex on these rows/legend */
.gx-bar-row[hidden],.gx-legend[hidden]{display:none}

/* ---- change-log full-diff (R14-1) ---- */
.cl-full{margin-top:5px}
.cl-full>summary{cursor:pointer;font:600 10.5px var(--mono);color:var(--ink-faint);letter-spacing:.06em;list-style:none;padding:2px 0}
.cl-full>summary:hover{color:var(--accent-hi)}
.cl-full[open]>summary{color:var(--ink-dim)}
.cl-field{margin:6px 0;border-top:1px solid rgba(255,255,255,.05);padding-top:5px}
.cl-key{font:700 10px var(--mono);color:var(--accent-hi);letter-spacing:.08em;margin-bottom:3px}
.cl-cols{display:grid;grid-template-columns:1fr 1fr;gap:8px}
@media (max-width:820px){.cl-cols{grid-template-columns:1fr}}
.cl-side{border-radius:6px;padding:6px 8px;min-width:0}
.cl-b{background:rgba(226,87,76,.08);border:1px solid rgba(226,87,76,.2)}
.cl-a{background:rgba(95,191,159,.08);border:1px solid rgba(95,191,159,.2)}
.cl-lbl{font:700 9px var(--mono);letter-spacing:.12em;text-transform:uppercase;color:var(--ink-faint);margin-bottom:3px}
.cl-pre{margin:0;font:11.5px/1.5 var(--mono);color:var(--ink);white-space:pre-wrap;word-break:break-word;max-height:340px;overflow:auto}
.cl-empty{font:11px var(--mono);color:var(--ink-faint);font-style:italic}

/* ---- backfill runner: activity monitor (live logs + streaming tokens) ---- */
.mon-head{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:12px}
.mon-title{display:flex;align-items:center;gap:10px;min-width:0}
.mon-meta{display:flex;align-items:center;gap:14px;flex-wrap:wrap;font:11px var(--mono);color:var(--ink-faint)}
.mon-meta b{color:var(--ink-dim);font-weight:600}
.mon-meta .mon-model{color:var(--accent-hi)}
.mon-grid{display:grid;grid-template-columns:1.15fr 1fr;gap:14px;align-items:start}
@media(max-width:900px){.mon-grid{grid-template-columns:1fr}}
.mon-col{display:flex;flex-direction:column;min-width:0}
.mon-col-hd{display:flex;align-items:center;justify-content:space-between;gap:8px;
  font:700 9px var(--mono);letter-spacing:.14em;color:var(--ink-faint);padding:0 2px 6px}
.mon-follow{display:flex;align-items:center;gap:5px;font:600 9px var(--mono);letter-spacing:.08em;
  color:var(--ink-faint);cursor:pointer;text-transform:uppercase}
.mon-follow input{cursor:pointer}
.mon-live{display:flex;align-items:center;gap:6px}
/* the terminal panes */
.mon-box{height:280px;overflow:auto;background:#080a0d;border:1px solid var(--line);
  border-radius:7px;padding:9px 11px;box-shadow:inset 0 1px 10px rgba(0,0,0,.5);
  font:11.5px/1.6 var(--mono);color:var(--ink);scrollbar-width:thin}
.mon-box.stream{white-space:pre-wrap;word-break:break-word;color:var(--ink-dim)}
.mon-box::-webkit-scrollbar{width:9px;height:9px}
.mon-box::-webkit-scrollbar-thumb{background:rgba(255,255,255,.12);border-radius:5px}
.mon-box .placeholder{color:var(--ink-faint);font-style:italic}
/* one log line: dim timestamp, icon, colored body — grid keeps the body aligned */
.mon-ln{display:grid;grid-template-columns:auto auto 1fr;gap:7px;padding:1px 0;align-items:baseline}
.mon-ln .t{color:var(--ink-faint);font-size:10.5px}
.mon-ln .i{width:13px;text-align:center}
.mon-ln .b{word-break:break-word}
.mon-ln.tool{background:rgba(217,164,65,.06);border-radius:4px;margin:1px -4px;padding:1px 4px}
.mon-ln.tool .b{color:var(--accent-hi)}
.mon-ln.result .b{color:var(--ink-dim);padding-left:6px}
.mon-ln.ok .b{color:var(--exploration)}
.mon-ln.warn .b{color:var(--dmg,#e08a3c)}
.mon-ln.err .b{color:var(--combat)}
.mon-ln.head .b{color:var(--accent-hi)}
/* blinking cursor tail on the live stream while tokens flow */
.mon-cursor{display:inline-block;width:7px;height:13px;vertical-align:text-bottom;margin-left:1px;
  background:var(--accent);animation:mon-blink 1s steps(1) infinite}
.mon-idle .mon-cursor{display:none}
@keyframes mon-blink{0%,50%{opacity:1}50.01%,100%{opacity:0}}
