/* Bach admin console — brass = brand/structure, claret = attention/agent
   action, ink ground, serif page titles, mono for structural labels/ids.
   Design rule: NO colored left-accent rails anywhere — emphasis comes from
   background fills, accent text, and full hairline borders only. */
:root{
  --ground:#14151b; --panel:#1a1c24; --panel-2:#20222c; --panel-3:#262935;
  --line:#2d3040; --line-2:#383c4e; --ink:#e9e4d6; --muted:#9a978a; --faint:#6d6c62;
  --brass:#cda24e; --brass-soft:#b8934a; --claret:#c65f56;
  --run:#5f93d6; --ok:#6fbf88; --warn:#d6a95c; --fail:#c9605a; --skip:#5b5e6d; --park:#b083d9; --scheduled:#8fa6bf;
  --str:#cca46e; --num:#7fb4e0; --bool:#c58fd0; --key:#9fd0b0;
  --radius:8px; --r-sm:6px;
  --serif:"Hoefler Text","Iowan Old Style",Palatino,Georgia,serif;
  --sans:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  --mono:ui-monospace,"Cascadia Code","SF Mono","JetBrains Mono",Menlo,monospace;
  --sbw:236px;
}
@media (prefers-color-scheme: light){:root{
  --ground:#e8e5db; --panel:#f3f0e8; --panel-2:#ece8dd; --panel-3:#e3dfd2;
  --line:#d4cfc1; --line-2:#c7c1b0; --ink:#24251f; --muted:#5f5d52; --faint:#8a8778;
  --brass:#8f6d1e; --brass-soft:#a07f30; --claret:#a8483f;
  --run:#3a6fb0; --ok:#3f7d51; --warn:#8a6420; --fail:#a8483f; --skip:#b4b0a2; --park:#7a4fa0; --scheduled:#55708a;
  --str:#8a5a1e; --num:#2f5f96; --bool:#8a4f9a; --key:#3f7d51;
}}
:root[data-theme="dark"]{
  --ground:#14151b; --panel:#1a1c24; --panel-2:#20222c; --panel-3:#262935;
  --line:#2d3040; --line-2:#383c4e; --ink:#e9e4d6; --muted:#9a978a; --faint:#6d6c62;
  --brass:#cda24e; --brass-soft:#b8934a; --claret:#c65f56;
  --run:#5f93d6; --ok:#6fbf88; --warn:#d6a95c; --fail:#c9605a; --skip:#5b5e6d; --park:#b083d9; --scheduled:#8fa6bf;
  --str:#cca46e; --num:#7fb4e0; --bool:#c58fd0; --key:#9fd0b0;
}
:root[data-theme="light"]{
  --ground:#e8e5db; --panel:#f3f0e8; --panel-2:#ece8dd; --panel-3:#e3dfd2;
  --line:#d4cfc1; --line-2:#c7c1b0; --ink:#24251f; --muted:#5f5d52; --faint:#8a8778;
  --brass:#8f6d1e; --brass-soft:#a07f30; --claret:#a8483f;
  --run:#3a6fb0; --ok:#3f7d51; --warn:#8a6420; --fail:#a8483f; --skip:#b4b0a2; --park:#7a4fa0; --scheduled:#55708a;
  --str:#8a5a1e; --num:#2f5f96; --bool:#8a4f9a; --key:#3f7d51;
}
*{box-sizing:border-box}
@media (prefers-reduced-motion: reduce){*,*::before,*::after{animation-duration:.001ms!important;transition-duration:.001ms!important}}
body{margin:0;background:var(--ground);color:var(--ink);font-family:var(--sans);font-size:14px;line-height:1.55;-webkit-font-smoothing:antialiased}
a{color:inherit;text-decoration:none}
:focus-visible{outline:2px solid var(--brass);outline-offset:2px;border-radius:3px}
.mono{font-family:var(--mono)}

/* ---------- app shell ---------- */
.app{display:grid;grid-template-columns:var(--sbw) 1fr;min-height:100vh}
.sidebar{background:var(--panel);border-right:1px solid var(--line);display:flex;flex-direction:column;position:sticky;top:0;height:100vh}
.sb-brand{font-family:var(--serif);font-size:29px;font-weight:600;letter-spacing:.01em;padding:20px 20px 16px;display:flex;align-items:baseline;gap:9px;border-bottom:1px solid var(--line)}
.sb-brand .mk{font-family:var(--mono);font-size:10px;font-weight:400;color:var(--brass);letter-spacing:.14em;transform:translateY(-4px)}
.sb-nav{padding:14px 12px;flex:1;overflow-y:auto}
.sb-sec{font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--faint);padding:14px 10px 6px}
.sb-link{display:flex;align-items:center;gap:11px;padding:8px 11px;border-radius:var(--r-sm);color:var(--muted);cursor:pointer;font-size:13.5px;margin:1px 0}
.sb-link .ic{width:16px;text-align:center;opacity:.8}
.sb-link:hover{color:var(--ink);background:var(--panel-2)}
.sb-link.active{color:var(--ink);background:var(--panel-3);font-weight:500}
.sb-link.active .ic{color:var(--brass);opacity:1}
.sb-link .badge{margin-left:auto;background:var(--claret);color:#fff;font-family:var(--mono);font-size:10px;padding:1px 7px;border-radius:99px}
.sb-foot{border-top:1px solid var(--line);padding:12px;display:flex;align-items:center;gap:10px}
.avatar{width:30px;height:30px;border-radius:50%;background:linear-gradient(135deg,var(--brass),var(--claret));display:grid;place-items:center;color:#181614;font-weight:600;font-size:13px;flex-shrink:0}
.sb-foot .who{font-size:12.5px;min-width:0}
.sb-foot .who b{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sb-foot .who span{color:var(--faint);font-family:var(--mono);font-size:10.5px}
.sb-foot .out{margin-left:auto;color:var(--faint);cursor:pointer;font-size:15px;background:none;border:0;padding:0}
.sb-foot .out:hover{color:var(--claret)}

/* ---------- main / topbar ---------- */
.main{min-width:0;display:flex;flex-direction:column}
.topbar{height:56px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:16px;padding:0 24px;position:sticky;top:0;background:color-mix(in srgb,var(--ground) 90%,transparent);backdrop-filter:blur(8px);z-index:20}
.crumb{font-family:var(--mono);font-size:12.5px;color:var(--muted);display:flex;align-items:center;gap:7px}
.crumb a{cursor:pointer}.crumb a:hover{color:var(--ink)}
.crumb .sep{color:var(--faint)}
.crumb b{color:var(--ink);font-weight:500}
.tb-right{margin-left:auto;display:flex;align-items:center;gap:10px}
.env-pill{font-family:var(--mono);font-size:11px;color:var(--muted);border:1px solid var(--line);border-radius:99px;padding:4px 10px;display:flex;align-items:center;gap:6px}
.env-pill .d{width:7px;height:7px;border-radius:50%;background:var(--ok)}
.content{padding:26px 30px 60px;width:100%}

/* ---------- headings ---------- */
.page-h{font-family:var(--serif);font-size:29px;font-weight:600;margin:0 0 4px;letter-spacing:-.3px}
.page-sub{color:var(--muted);margin:0 0 24px;font-size:14.5px}
.sec-h{font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--faint);margin:28px 0 12px;display:flex;align-items:center;gap:10px}
.sec-h .count{color:var(--muted);letter-spacing:0}

/* ---------- buttons ---------- */
.btn{font-family:var(--mono);font-size:12.5px;padding:8px 14px;border-radius:var(--r-sm);border:1px solid var(--line-2);background:var(--panel-2);color:var(--ink);cursor:pointer;display:inline-flex;align-items:center;gap:7px;line-height:1}
.btn:hover{border-color:var(--brass);background:var(--panel-3)}
.btn.primary{background:var(--brass);border-color:var(--brass);color:#17140c;font-weight:600}
.btn.primary:hover{background:var(--brass-soft)}
.btn.danger{color:var(--claret);border-color:color-mix(in srgb,var(--claret) 40%,var(--line-2))}
.btn.danger:hover{background:color-mix(in srgb,var(--claret) 14%,var(--panel-2));border-color:var(--claret)}
.btn.sm{padding:5px 10px;font-size:11.5px}
.btn.ghost{background:transparent;border-color:transparent;color:var(--muted)}
.btn.ghost:hover{color:var(--ink);background:var(--panel-2)}
.btn:disabled{opacity:.5;cursor:not-allowed}
.btn-row{display:flex;gap:8px;flex-wrap:wrap;align-items:center}

/* ---------- status pills ---------- */
.pill{font-family:var(--mono);font-size:11px;padding:3px 9px;border-radius:99px;display:inline-flex;align-items:center;gap:6px;border:1px solid transparent;white-space:nowrap}
.pill .d{width:7px;height:7px;border-radius:50%}
.pill.running{color:var(--run);background:color-mix(in srgb,var(--run) 15%,transparent)} .pill.running .d{background:var(--run);animation:pulse 1.6s infinite}
.pill.ok{color:var(--ok);background:color-mix(in srgb,var(--ok) 15%,transparent)} .pill.ok .d{background:var(--ok)}
.pill.failed{color:var(--fail);background:color-mix(in srgb,var(--fail) 15%,transparent)} .pill.failed .d{background:var(--fail)}
.pill.waiting{color:var(--claret);background:color-mix(in srgb,var(--claret) 16%,transparent)} .pill.waiting .d{background:var(--claret);animation:pulse 1.6s infinite}
.pill.skipped{color:var(--skip);background:color-mix(in srgb,var(--skip) 18%,transparent)} .pill.skipped .d{background:var(--skip)}
/* "reused" (forked-run steps carried over from the parent) maps onto the
   skipped pill palette (see PILL in console.js) — no separate .pill.reused
   rule needed; the label text alone ("reused") carries the distinction. */
.pill.parked{color:var(--park);background:color-mix(in srgb,var(--park) 15%,transparent)} .pill.parked .d{background:var(--park)}
.pill.stopped{color:var(--faint);background:var(--panel-2)} .pill.stopped .d{background:var(--faint)}
/* Scheduled (not-yet-fired) runs: muted blue-grey, tone matching the legacy chip. */
.pill.scheduled{color:var(--scheduled);background:color-mix(in srgb,var(--scheduled) 16%,transparent)} .pill.scheduled .d{background:var(--scheduled)}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.35}}

/* ---------- cards / stat tiles ---------- */
.grid{display:grid;gap:16px}
.tiles{grid-template-columns:repeat(4,1fr)}
.tiles.three{grid-template-columns:repeat(3,1fr)}
.tile{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:16px 18px}
.tile .lab{font-family:var(--mono);font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--faint)}
.tile .big{font-family:var(--serif);font-size:34px;font-weight:600;margin-top:6px;line-height:1}
.tile .big small{font-size:16px;color:var(--muted);font-family:var(--sans)}
.tile .foot{font-size:12px;color:var(--muted);margin-top:8px}
.tile.attention{border-color:color-mix(in srgb,var(--claret) 45%,var(--line));background:color-mix(in srgb,var(--claret) 6%,var(--panel))}
.tile.attention .big{color:var(--claret)}
.card{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius)}
.card .card-h{padding:14px 18px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:12px}
.card .card-h h3{font-family:var(--serif);font-size:17px;font-weight:600;margin:0}
.card .card-h .act{margin-left:auto;display:flex;gap:8px}
.card .card-b{padding:16px 18px}
.card .card-b.flush{padding:0}

/* ---------- tables ---------- */
table.tbl{width:100%;border-collapse:collapse;font-size:13px}
.tbl th{text-align:left;font-family:var(--mono);font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--faint);font-weight:500;padding:10px 16px;border-bottom:1px solid var(--line)}
.tbl td{padding:12px 16px;border-bottom:1px solid var(--line);vertical-align:middle}
.tbl tr:last-child td{border-bottom:0}
.tbl tbody tr.click{cursor:pointer}
.tbl tbody tr.click:hover{background:var(--panel-2)}
.tbl tbody tr.sel{background:var(--panel-2)}
.tbl .name{font-weight:500}
.tbl .sub{color:var(--faint);font-family:var(--mono);font-size:11.5px}
.tbl .num{font-family:var(--mono);font-variant-numeric:tabular-nums;color:var(--muted)}

/* ---------- forms ---------- */
.field{margin-bottom:16px}
.field > label{display:block;font-size:12.5px;font-weight:500;margin-bottom:6px}
.field .help{font-size:12px;color:var(--faint);margin-top:5px}
/* Hover-help affordance (help() in console.js): a small "?" after a field
   label; hover reveals a one-line tip. Selectors are tag-qualified
   (span.help) so they don't collide with the unrelated .field .help hint
   divs above. No colored accent rail — dark card, existing tokens only. */
span.help{display:inline-flex;align-items:center;justify-content:center;width:14px;height:14px;
  border:1px solid var(--line-2);border-radius:50%;color:var(--faint);font-size:9.5px;
  font-family:var(--mono);font-weight:400;cursor:help;position:relative;flex:none;
  vertical-align:middle;user-select:none;text-transform:none;letter-spacing:normal;margin-left:5px}
span.help:hover{color:var(--ink);border-color:var(--muted)}
/* Tip is position:fixed so an ancestor's overflow:hidden (e.g. .tr-item, which
   clips its body) can't cut it off; installHelpTips() sets left/top from the
   icon's on-screen rect on hover. CSS still toggles visibility. */
span.help .tip{display:none;position:fixed;transform:translateX(-50%);
  width:230px;background:#000;border:1px solid var(--line-2);border-radius:var(--r-sm);
  padding:8px 10px;font-size:11.5px;line-height:1.45;color:var(--ink);font-family:var(--sans);
  font-weight:400;text-transform:none;letter-spacing:normal;text-align:left;z-index:200;
  box-shadow:0 6px 22px rgba(0,0,0,.55);pointer-events:none}
span.help:hover .tip{display:block}
.input{width:100%;background:var(--ground);border:1px solid var(--line-2);border-radius:var(--r-sm);padding:9px 11px;color:var(--ink);font-family:var(--sans);font-size:13.5px;outline:none}
.input:focus{border-color:var(--brass)}
.input.mono{font-family:var(--mono);font-size:12.5px}
/* secret input with show/hide */
.secret{display:flex;align-items:stretch;border:1px solid var(--line-2);border-radius:var(--r-sm);background:var(--ground);overflow:hidden}
.secret input{flex:1;background:transparent;border:0;outline:none;color:var(--ink);font-family:var(--mono);font-size:12.5px;padding:9px 11px;letter-spacing:.5px;min-width:0}
.secret button{border:0;border-left:1px solid var(--line);background:var(--panel-2);color:var(--muted);padding:0 11px;cursor:pointer;font-size:13px}
.secret button:hover{color:var(--ink)}
.secret.set{border-color:color-mix(in srgb,var(--ok) 45%,var(--line-2))}
.f-sec{font-family:var(--mono);font-size:10.5px;text-transform:uppercase;letter-spacing:.1em;color:var(--faint);margin:22px 0 12px;display:flex;align-items:center;gap:10px}
.f-sec::after{content:"";flex:1;height:1px;background:var(--line)}
.tag{font-family:var(--mono);font-size:10.5px;padding:2px 8px;border-radius:99px;background:var(--panel-3);color:var(--muted)}
.tag.brass{color:var(--brass);background:color-mix(in srgb,var(--brass) 14%,transparent)}
.tag.claret{color:var(--claret);background:color-mix(in srgb,var(--claret) 12%,transparent)}

/* ---------- tabs ---------- */
.tabs{display:flex;gap:2px;border-bottom:1px solid var(--line);margin-bottom:20px}
.tab{font-family:var(--mono);font-size:12.5px;padding:10px 15px;color:var(--muted);cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-1px;background:none;border-top:0;border-left:0;border-right:0}
.tab:hover{color:var(--ink)}
.tab.on{color:var(--ink);border-bottom-color:var(--brass)}
.tab .n{color:var(--faint);margin-left:6px}

/* ---------- pipeline page: shared status dots ---------- */
.dt{width:8px;height:8px;border-radius:50%;flex-shrink:0;display:inline-block}
.dt.ok{background:var(--ok)} .dt.run{background:var(--run)} .dt.fail{background:var(--fail)}
.dt.park{background:var(--park)}
.dt.gatep{background:var(--ground);border:1.5px solid var(--claret)}   /* waiting = hollow claret ring */
.dt.skip{background:var(--ground);border:1.5px solid var(--brass-soft)} /* legacy skip → reused look */
.dt.reuse{background:var(--ground);border:1.5px solid var(--brass-soft)}/* reused = won't run */
.dt.pend{background:var(--ground);border:1.5px solid var(--line-2)}     /* pending = will run */
.dt.canc{background:var(--ground);border:1.5px dashed var(--faint)}     /* cancelled */

/* ---------- inspect tab: horizontal metro strip ---------- */
.metro-strip{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:14px 18px 6px;margin-bottom:20px}
.ms-hd{display:flex;gap:12px;align-items:center;font-family:var(--mono);font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--faint);margin-bottom:2px}
.ms-hd .rid{margin-left:auto;text-transform:none;letter-spacing:0;font-size:11px;color:var(--muted)}
.ms-svg{display:block;width:100%;overflow:visible}
.ms-svg .spine{stroke:var(--line-2);stroke-width:2.6;fill:none}
.ms-svg .br{stroke:var(--brass-soft);stroke-width:2.2;fill:none}
.ms-svg .br.skipln{stroke:var(--skip);stroke-dasharray:5 4}
.ms-svg .st{fill:var(--panel);stroke-width:2.6}
.ms-svg .st.ok{stroke:var(--ok)} .ms-svg .st.run{stroke:var(--run);animation:pulse 1.6s infinite}
.ms-svg .st.fail{stroke:var(--fail);fill:var(--fail)}
.ms-svg .st.skip{stroke:var(--skip);stroke-dasharray:3 2.4}
.ms-svg .st.reuse{stroke:var(--brass-soft)}
.ms-svg .st.pend{stroke:var(--line-2)} .ms-svg .st.gatep{stroke:var(--claret)}
.ms-svg .st.park{stroke:var(--park);fill:var(--park)}
.ms-svg .st.canc{stroke:var(--faint);stroke-dasharray:3 2.4}
.ms-svg .halo{fill:none;stroke:var(--brass);stroke-width:1.4}
.ms-svg .leader{stroke:var(--line-2);stroke-width:1;fill:none}
.ms-svg text{font-family:var(--mono);font-size:10.5px;fill:var(--muted)}
.ms-svg text.nm{fill:var(--ink);font-size:11px}
.ms-svg text.xn{fill:var(--brass);font-size:9px}
.ms-svg text.du{fill:var(--faint);font-size:9.5px}
.ms-svg .mini{stroke:none;fill:var(--panel-3)}
.ms-svg .mini.ok{fill:var(--ok)} .ms-svg .mini.run{fill:var(--run)} .ms-svg .mini.fail{fill:var(--fail)}
.ms-svg .mini.skip{fill:var(--skip)} .ms-svg .mini.gatep{fill:var(--claret)} .ms-svg .mini.park{fill:var(--park)}
.ms-svg .mini.reuse{fill:var(--brass-soft)} .ms-svg .mini.canc{fill:var(--faint)}
/* Redeploy nudge: a hash-router SPA keeps running old JS in an open tab; on
   the next SSE reconnect we detect a new build and offer a reload. */
.reload-nudge{position:fixed;right:20px;bottom:20px;z-index:9999;display:flex;align-items:center;gap:12px;
  background:var(--panel-3);border:1px solid var(--brass-soft);border-radius:var(--r-sm);
  padding:10px 12px 10px 16px;box-shadow:0 12px 34px rgba(0,0,0,.34);font-size:13px;color:var(--ink)}
.reload-nudge button{font-family:var(--mono);font-size:12px;padding:6px 13px;border-radius:var(--r-sm);
  border:1px solid var(--brass);background:var(--brass);color:#1a1408;font-weight:600;cursor:pointer}
.reload-nudge button:hover{filter:brightness(1.06)}
.ms-hit{cursor:pointer}

/* ---------- inspect tab: run inspector (docked step rail) ---------- */
.lc-card{display:flex;min-height:320px}
.lc-rail{width:250px;flex-shrink:0;background:var(--ground);border-right:1px solid var(--line);border-radius:var(--radius) 0 0 var(--radius);padding:10px 8px;overflow:hidden}
/* Fixed height so a column header's on-screen offset is exactly RAIL_HDR_H
   in console.js — the spine's row-center math walks the same renderRail()
   loop that emits this markup, so header height must be a known constant,
   not content-driven, for the two to provably agree pixel-for-pixel. */
.rsec{font-family:var(--mono);font-size:9.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--faint);height:24px;box-sizing:border-box;padding:0 9px 0 64px;display:flex;align-items:center;gap:8px;white-space:nowrap;position:relative;z-index:1}
.rsec::after{content:"";flex:1;height:1px;background:var(--line)}
/* Rows: a fixed grid (caret-slot | dot | label | trailing) so the dot column
   never drifts. The leading 14px slot holds the real expand caret on a
   foreach row and an empty spacer (.car-sp) everywhere else, so every row
   variant (plain, foreach, branch) puts the dot in the SAME column - before
   this, a plain row's dot sat flush left while a foreach row's dot sat one
   caret+gap to the right of it. Dot center = 8(row pad) + 14(caret col) +
   9(the grid's column gap, between caret col and dot col) + 12(half of
   24px dot col) = 43px from the row's left edge; drawSpine()'s ON
   constant is defined against this same geometry (see console.js). */
.re{display:grid;grid-template-columns:14px 24px 1fr auto;align-items:center;gap:9px;height:30px;padding:0 8px;border-radius:var(--r-sm);cursor:pointer;color:var(--muted);font-family:var(--mono);font-size:11.5px;position:relative;z-index:1}
.re .dt{justify-self:center;position:relative;z-index:2}
.re .dt.small{width:6px;height:6px}
.re:hover{color:var(--ink)}
.re.on{background:var(--panel-2);color:var(--ink)}
.re.dimmed{opacity:.34}
.re.need .rlbl{color:var(--brass)}
.re.feed .rlbl{color:var(--ink)}
.re .rlbl{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.re .xn{color:var(--brass);font-size:10px}
.re .du{font-size:10px;color:var(--faint);white-space:nowrap}
/* trailing meta is one grid cell (duration / mini-dots / ↻) so it can never
   overflow the row into an implicit grid row */
.rtrail{display:flex;align-items:center;gap:7px;justify-self:end;min-width:0}
.re .car{color:var(--faint);width:12px;background:none;border:0;padding:0;cursor:pointer;font-size:11px;font-family:var(--mono);flex-shrink:0}
.re .car:hover{color:var(--ink)}
/* expanded foreach sub-step: shifts right by the detour offset (the spine dives
   in to thread it); smaller dot + dimmer label mark it a child */
.re.br2{padding-left:21px}
.re.br2 .rlbl{color:var(--faint);font-size:11px}
/* may-re-run: a compact symbol, not a pill — always fits the trailing cell */
.may{color:var(--run);font-size:13px;line-height:1;cursor:default}
.minidots{display:flex;gap:3px;margin-left:auto}
.minidots .dt{width:6px;height:6px}
.lc-main{flex:1;min-width:0}
.lc-main .step-detail{border:0;background:transparent;margin-top:0}

/* Detour backbone: the rows themselves are the positioning context (not
   .lc-rail) so the rail-lineage header line above them can take its own
   height without shifting the spine's y=0 origin out from under the rows
   it was measured against. */
.rail-rows{position:relative}
.spine-svg{position:absolute;left:8px;top:0;z-index:0;overflow:visible;pointer-events:none}
.spine-svg path{fill:none;stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}
.spine-svg .needs{stroke:var(--brass)}
.spine-svg .feeds{stroke:var(--run)}
.rail-preview{font-family:var(--mono);font-size:11px;color:var(--ink);margin:2px 8px 8px;padding:7px 10px;
  border:1px solid color-mix(in srgb,var(--run) 38%,var(--line-2));border-radius:var(--r-sm);
  background:color-mix(in srgb,var(--run) 12%,var(--panel));overflow-wrap:anywhere}
.rail-preview b{color:var(--run)}
.rail-lineage{font-family:var(--mono);font-size:10.5px;color:var(--muted);padding:2px 10px 8px;overflow-wrap:anywhere}
.rail-lineage b{color:var(--brass)}
.rail-lineage .f{color:var(--ink)}

/* ---------- timeline tab: full-page node graph + popover ---------- */
.tl-stage{position:relative;background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:30px 26px}
.tl-canvas{position:relative;margin:0 auto}
.ndx{position:absolute;width:170px;background:var(--panel-2);border:1px solid var(--line);border-radius:var(--r-sm);padding:10px 12px;font-family:var(--mono);cursor:pointer;transition:border-color .12s,box-shadow .12s,transform .12s}
.ndx:hover{border-color:var(--brass-soft);transform:translateY(-1px)}
.ndx.sel{border-color:var(--brass);box-shadow:0 8px 22px rgba(0,0,0,.18)}
.ndx .nm{font-size:12px;display:flex;justify-content:space-between;align-items:center;gap:6px;color:var(--ink)}
.ndx .nm > span:first-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ndx .xn{color:var(--brass);font-size:10px}
.ndx .dv{font-size:10px;color:var(--faint);margin-top:5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ndx .meta{display:flex;justify-content:space-between;font-size:10.5px;color:var(--muted);margin-top:4px;font-variant-numeric:tabular-nums}
.ndx .dots{display:flex;gap:3px;margin-top:6px;flex-wrap:wrap}
.ndx .dots .dt{width:6px;height:6px}
.ndx.stack{box-shadow:3px 3px 0 -1px var(--panel-2),3px 3px 0 0 var(--line),6px 6px 0 -1px var(--panel-2),6px 6px 0 0 var(--line)}
svg.edges{position:absolute;left:0;top:0;pointer-events:none;overflow:visible}
svg.edges path{fill:none;stroke-width:1.7;transition:stroke .12s,opacity .12s}
svg.edges.dimmed path{opacity:.25}
svg.edges.dimmed path.hot{opacity:1;stroke:var(--brass);stroke-width:2.2}
.e-ok{stroke:var(--brass-soft);opacity:.85} .e-idle{stroke:var(--line-2)} .e-skip{stroke:var(--skip);stroke-dasharray:4 3}
/* popover */
.pop{position:absolute;width:340px;background:var(--panel);border:1px solid var(--brass);border-radius:var(--radius);box-shadow:0 22px 60px rgba(0,0,0,.4);z-index:5;opacity:0;transform:translateY(4px);transition:opacity .14s,transform .14s;pointer-events:none}
.pop::before{content:"";position:absolute;left:-7px;top:26px;width:12px;height:12px;background:var(--panel);border-left:1px solid var(--brass);border-bottom:1px solid var(--brass);transform:rotate(45deg)}
.pop.left::before{left:auto;right:-7px;transform:rotate(225deg)}
.pop.on{opacity:1;transform:none;pointer-events:auto}
.pop .ph{display:flex;align-items:center;gap:9px;padding:11px 14px;border-bottom:1px solid var(--line)}
.pop .ph h5{margin:0;font-family:var(--mono);font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pop .ph .drv{margin-left:auto;font-family:var(--mono);font-size:10.5px;color:var(--faint);white-space:nowrap}
.pop .kv{padding:10px 14px;grid-template-columns:92px 1fr;font-size:12px}
.pop .kv .v{overflow-wrap:anywhere;word-break:break-word;min-width:0}
.pop .plog{margin:0 14px 12px;background:var(--ground);border:1px solid var(--line);border-radius:var(--r-sm);padding:9px 11px;font-family:var(--mono);font-size:10.5px;color:var(--muted);line-height:1.65;white-space:pre-wrap;overflow-wrap:anywhere}
.pop .plog .t{color:var(--faint)} .pop .plog .g{color:var(--ok)} .pop .plog .r{color:var(--fail)}
.pop .pf{display:flex;justify-content:space-between;padding:9px 14px;border-top:1px solid var(--line);font-family:var(--mono);font-size:11px;color:var(--faint)}
.pop .pf a{color:var(--brass);cursor:pointer}

/* step detail */
.step-detail{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);margin-top:6px}
.step-detail .sd-h{padding:13px 16px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:12px}
.step-detail .sd-h h4{font-family:var(--mono);font-size:13.5px;margin:0}
.kv{display:grid;grid-template-columns:130px 1fr;gap:8px 16px;padding:14px 16px;font-size:13px}
.kv .k{color:var(--faint);font-family:var(--mono);font-size:11.5px}
.kv .v{font-family:var(--mono);font-size:12px;overflow-wrap:anywhere}
/* file-typed input: filename link (no rail), opens the reading viewer */
.filelink{color:var(--brass);cursor:pointer;text-decoration:none;font-family:var(--mono)}
.filelink:hover{text-decoration:underline}
.filelink + .filelink{margin-left:8px}
/* long text input: truncated black code block, opens the viewer on the full value */
.codepreview{display:block;background:var(--panel-3);border:1px solid var(--line);border-radius:var(--r-sm);padding:7px 10px;font-family:var(--mono);font-size:11.5px;color:var(--muted);white-space:pre-wrap;overflow:hidden;cursor:pointer;max-height:5.4em}
.codepreview:hover{border-color:var(--brass-soft);color:var(--ink)}
.vtag{font-family:var(--mono);font-size:10.5px;color:var(--faint);background:var(--ground);border:1px solid var(--line);border-radius:99px;padding:1px 8px;white-space:nowrap}
/* Section headers + grids inside the step detail share the kv's 16px inset. */
.step-detail .sec-h{padding:0 16px;margin:22px 0 12px}
.fan-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(168px,1fr));gap:12px;padding:0 16px 18px}
.fan-card{display:flex;flex-direction:column;gap:10px;text-align:left;padding:13px 14px;background:var(--panel-2);border:1px solid var(--line);border-radius:var(--r-sm);cursor:pointer;font:inherit;color:var(--ink);transition:border-color .12s,transform .12s}
.fan-card:hover{border-color:var(--brass-soft);background:var(--panel-3);transform:translateY(-1px)}
.fan-card.on{border-color:var(--brass)}
.fan-card .fc-top{display:flex;align-items:center;gap:8px}
.fan-card .fc-id{font-size:13px;color:var(--ink);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fan-card .fc-top .pill{margin-left:auto}

/* override & re-run panel (step inspector) — house rule: no colored accent
   rails; the "edited" marker is an inset bar on the input itself. */
.ov-panel{border:1px solid var(--line-2);border-radius:var(--r-sm);background:var(--panel-3);margin:12px 16px}
.ov-h{font-family:var(--mono);font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);padding:9px 12px;border-bottom:1px solid var(--line)}
.ov-empty{padding:9px 12px;font-size:12.5px}
.ov-loading{padding:9px 12px;font-size:12px;margin:12px 16px}
.ov-field{display:grid;grid-template-columns:120px 1fr;gap:10px;align-items:center;padding:9px 12px;border-bottom:1px solid var(--line)}
.ov-label{font-family:var(--mono);font-size:12px;color:var(--muted)}
.ov-in{width:100%;background:var(--panel);color:var(--ink);border:1px solid var(--line-2);border-radius:4px;padding:6px 9px;font-family:var(--mono);font-size:12.5px}
.ov-in:focus{outline:2px solid var(--brass);outline-offset:1px}
.ov-edited .ov-in{border-color:var(--brass-soft);box-shadow:inset 2px 0 0 var(--brass)}
.ov-actions{display:flex;gap:10px;padding:11px 12px}
.fan-card .fc-meta{font-size:11px;color:var(--faint);letter-spacing:.02em}
/* Step outputs: produced media/files, previewed inline. */
.out-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:14px;padding:0 16px 18px}
.out-item{display:flex;flex-direction:column;gap:7px;padding:0;background:none;border:0;text-align:left;font:inherit;color:var(--muted);cursor:pointer}
.out-item[data-art]:hover .out-thumb{border-color:var(--brass)}
.out-thumb{width:100%;aspect-ratio:16/10;object-fit:cover;border-radius:var(--r-sm);border:1px solid var(--line);display:block;background:var(--ground)}
/* Audio/video players span the full grid width so they fill the panel
   (thumbnails/filelinks stay in the auto-fill grid). */
.out-item.out-wide{grid-column:1/-1;cursor:default}
.out-cap{font-size:11px;color:var(--faint);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cp-prev{color:var(--muted)}
.fl-gap{color:var(--faint)}
.fl-pending{color:var(--faint);font-family:var(--mono);cursor:default}
.logbox{margin:0 16px 16px;background:var(--ground);border:1px solid var(--line);border-radius:var(--r-sm);padding:12px 14px;font-family:var(--mono);font-size:11.5px;color:var(--muted);line-height:1.7;overflow-x:auto;white-space:pre-wrap}
.logbox .t{color:var(--faint)} .logbox .g{color:var(--ok)} .logbox .r{color:var(--fail)}

/* gate callout (attention, but NO left rail) */
.gate{background:color-mix(in srgb,var(--claret) 9%,var(--panel));border:1px solid color-mix(in srgb,var(--claret) 45%,var(--line));border-radius:var(--radius);padding:18px 20px}
.gate .g-top{display:flex;align-items:center;gap:11px;margin-bottom:6px}
.gate h3{font-family:var(--serif);font-size:19px;margin:6px 0 4px;font-weight:600}
.gate p{color:var(--muted);margin:0 0 14px;font-size:13.5px}
.gate .g-age{margin-left:auto;font-family:var(--mono);font-size:11px;color:var(--faint)}
.g-quote{background:var(--ground);border:1px solid var(--line);border-radius:var(--r-sm);margin-bottom:12px;overflow:hidden}
.g-quote .gq-h{display:flex;justify-content:space-between;gap:10px;padding:7px 13px;border-bottom:1px solid var(--line);font-family:var(--mono);font-size:10.5px;color:var(--muted)}
.g-quote .gq-h span{color:var(--faint)}
.g-quote .gq-b{padding:11px 13px;font-size:13px;color:var(--muted);line-height:1.6;font-style:italic}
.g-mail{background:var(--ground);border:1px solid var(--line);border-radius:var(--r-sm);margin-bottom:12px;overflow:hidden}
.g-mail .gm-h{padding:9px 13px;border-bottom:1px solid var(--line);display:flex;flex-direction:column;gap:3px}
.g-mail .gm-row{display:flex;gap:10px;font-family:var(--mono);font-size:11px}
.g-mail .gm-row span{color:var(--faint);width:52px;flex-shrink:0;text-transform:uppercase;font-size:9.5px;letter-spacing:.08em;padding-top:1px}
.g-mail .gm-row b{color:var(--ink);font-weight:500}
.g-mail .gm-b{padding:12px 14px;font-size:13.5px;color:var(--ink);line-height:1.65;white-space:pre-wrap}
.g-media{position:relative;max-width:100%;border:1px solid var(--line);border-radius:var(--r-sm);margin-bottom:12px;overflow:hidden;background:var(--ground)}
.g-media video,.g-media img,.g-media audio{display:block;width:100%;max-width:100%}
.aplayer{max-width:100%;background:var(--ground);border:1px solid var(--line);border-radius:var(--r-sm);padding:10px;outline:none}
.aplayer:focus-visible{border-color:var(--brass)}
.aplayer .wave{display:block;width:100%;height:48px;cursor:pointer}
.mp-ctrl{display:flex;align-items:center;gap:8px;margin-top:8px}
.mp-time{font-size:11.5px;color:var(--muted);font-variant-numeric:tabular-nums;white-space:nowrap}
.mp-spacer{flex:1}
.mp-vol{width:84px;accent-color:var(--brass)}
.mp-play{min-width:34px;justify-content:center}
.vplayer{max-width:100%;background:#000;border:1px solid var(--line);border-radius:var(--r-sm);overflow:hidden;outline:none}
.vplayer:focus-visible{border-color:var(--brass)}
.vplayer video{display:block;width:100%;max-width:100%}
.vplayer .mp-ctrl{margin-top:0;padding:8px 10px;background:var(--panel-2)}
.mp-track{flex:1;height:6px;background:var(--line-2);border-radius:3px;cursor:pointer;position:relative}
.mp-fill{position:absolute;left:0;top:0;height:100%;width:0;background:var(--brass);border-radius:3px}
.g-facts{display:grid;grid-template-columns:132px 1fr;gap:0;background:var(--ground);border:1px solid var(--line);border-radius:var(--r-sm);overflow:hidden;margin-bottom:12px}
.g-facts .k,.g-facts .v{padding:9px 14px;border-bottom:1px solid var(--line)}
.g-facts>:nth-last-child(-n+2){border-bottom:0}
.g-facts .k{font-family:var(--mono);font-size:11.5px;color:var(--faint);background:var(--panel-2);border-right:1px solid var(--line);padding-top:10px}
.g-facts .v{font-size:12.5px;color:var(--ink);font-family:var(--mono);min-width:0}
.g-files{font-family:var(--mono);font-size:11.5px;color:var(--faint);margin-bottom:12px}
.g-files a{color:var(--brass);cursor:pointer;text-decoration:none}
/* Overview gate card: compact structured preview of a presented JSON file
   (first few rows of a mini-table). Reuses the renderOutput .out classes at a
   tighter size; no accent rails. */
.g-prev{background:var(--ground);border:1px solid var(--line);border-radius:var(--r-sm);margin-bottom:12px;overflow:hidden}
.g-prev .g-prev-h{display:flex;align-items:center;gap:10px;padding:7px 13px;border-bottom:1px solid var(--line);font-family:var(--mono);font-size:10.5px}
.g-prev .g-prev-h .filelink{color:var(--brass);cursor:pointer;text-decoration:none}
.g-prev .g-prev-h .filelink:hover{text-decoration:underline}
.g-prev .g-prev-b>.muted{display:inline-block;padding:9px 13px;font-size:12px}
.g-prev .out-scroll{margin:0;border:0;border-radius:0}
.g-prev table.out{font-size:12px}
.g-prev table.out th{padding:6px 12px;position:static}
.g-prev table.out td{padding:6px 12px;max-width:220px}
.g-prev .cards,.g-prev .chips{padding:11px 13px}
/* kvo fills the card flush — the .g-prev border/header is its frame, no box-in-box */
.g-prev .kvo{margin:0;border:0;border-radius:0}
.g-prev .g-prev-b>.rawchip{margin:9px 13px}
.g-prev-more{padding:7px 13px;border-top:1px solid var(--line);font-family:var(--mono);font-size:10.5px;color:var(--faint)}
.g-note{margin:2px 0 12px;max-width:640px}
.g-note .input{font-size:12.5px;padding:8px 11px}

/* drawer */
.scrim{position:fixed;inset:0;background:rgba(0,0,0,.5);z-index:50;display:none}
.scrim.on{display:block}
.drawer{position:fixed;top:0;right:0;height:100vh;width:min(520px,94vw);background:var(--panel);border-left:1px solid var(--line);z-index:60;transform:translateX(100%);transition:transform .18s ease;display:flex;flex-direction:column}
.drawer.on{transform:translateX(0)}
.drawer .dh{padding:18px 22px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:12px}
.drawer .dh h3{font-family:var(--serif);font-size:19px;margin:0;font-weight:600}
.drawer .dh .x{margin-left:auto;cursor:pointer;color:var(--faint);font-size:18px;background:none;border:0}
.drawer .db{padding:20px 22px;overflow-y:auto;flex:1}
.drawer .df{padding:14px 22px;border-top:1px solid var(--line);display:flex;gap:10px;justify-content:flex-end}

/* reading viewer */
.vscrim{position:fixed;inset:0;background:rgba(12,10,6,.5);opacity:0;pointer-events:none;transition:.15s;z-index:70}
.vscrim.on{opacity:1;pointer-events:auto}
.viewer{position:fixed;top:4vh;bottom:4vh;left:50%;width:min(1040px,90vw);background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);display:flex;flex-direction:column;z-index:71;opacity:0;pointer-events:none;transform:translate(-50%,10px);transition:.18s;box-shadow:0 24px 70px rgba(0,0,0,.35)}
.viewer.on{opacity:1;pointer-events:auto;transform:translate(-50%,0)}
.viewer-hd{display:flex;justify-content:space-between;align-items:center;gap:14px;padding:14px 20px;border-bottom:1px solid var(--line);flex-shrink:0}
.viewer-hd h3{margin:0;font-size:15px;font-family:var(--mono)}
.viewer-bd{overflow:auto;padding:20px 24px;font-family:var(--mono);font-size:12.5px;line-height:1.75;white-space:pre-wrap;color:var(--ink);flex:1}
.viewer-bd video,.viewer-bd img{max-width:100%;border-radius:var(--r-sm);white-space:normal}

/* rich mode: block cards instead of preformatted text */
.viewer-bd.rich{white-space:normal;font-family:var(--sans)}
.viewer-bd.rich .tr-item{margin-bottom:12px;max-width:980px}
/* transcript viewer: docked score rail (recessed band) + scroll column */
.viewer-bd.dock{padding:0;display:flex;overflow:hidden}
.v-nav{width:208px;flex-shrink:0;background:var(--ground);border-right:1px solid var(--line);padding:14px 10px;overflow-y:auto}
.v-nav .sect{font-family:var(--mono);font-size:9.5px;text-transform:uppercase;letter-spacing:.12em;color:var(--faint);padding:14px 10px 5px;display:flex;align-items:center;gap:8px}
.v-nav .sect::after{content:"";flex:1;height:1px;background:var(--line)}
.v-nav .sect:first-child{padding-top:2px}
.v-nav button{border:0;background:none;text-align:left;cursor:pointer;padding:7px 10px;display:flex;gap:11px;align-items:baseline;color:var(--muted);border-radius:var(--r-sm);width:100%;font-family:var(--mono)}
.v-nav .no{font-size:11px;color:var(--faint);font-variant-numeric:tabular-nums;flex-shrink:0}
.v-nav .role{font-size:10.5px;text-transform:uppercase;letter-spacing:.06em;display:block;color:var(--muted)}
.v-nav .role.r-model,.v-nav .role.r-agent{color:var(--claret)}
.v-nav .role.r-tool{color:var(--brass)}
.v-nav .role.r-output{color:var(--ok)}
.v-nav .sub{display:block;font-size:10px;color:var(--faint);margin-top:2px;text-transform:none;letter-spacing:0}
.v-nav button:hover .sub{color:var(--muted)}
.v-nav button.on{background:var(--panel-2)}
.v-nav button.on .no{color:var(--brass);font-weight:700}
.v-nav button.on .sub{color:var(--ink)}
.v-scroll{flex:1;min-width:0;overflow-y:auto;padding:18px 24px}
.v-scroll .tr-wrap{padding:0;max-width:980px}
/* scroll-past-end: pad ≈ the scroll viewport minus one header, so even
   the last (shortest) block can reach the top and win the scrollspy */
.v-scroll .v-pad{height:calc(100% - 60px)}

/* step transcript blocks (llm/agent I/O + interleaved spawn tool calls) */
.tr-wrap{padding:0 16px 16px;display:flex;flex-direction:column;gap:10px}
.tr-item{border:1px solid var(--line);border-radius:var(--r-sm);background:var(--ground);overflow:hidden}
.tr-hd{display:flex;gap:10px;align-items:center;padding:8px 12px;border-bottom:1px solid var(--line);font-family:var(--mono);font-size:10px;line-height:1.3;letter-spacing:.08em;text-transform:uppercase}
.tr-hd .role{font-weight:700;color:var(--muted)}
.tr-item.r-agent .tr-hd .role,.tr-item.r-model .tr-hd .role{color:var(--claret)}
.tr-item.r-tool .tr-hd .role{color:var(--brass)}
.tr-item.r-output .tr-hd .role{color:var(--ok)}
.tr-hd .meta{color:var(--faint);margin-left:auto;text-transform:none;letter-spacing:0;font-size:10.5px;text-align:right}
/* Collapsed failed llm.audit retry attempts (superseded by the accepted
   Response). Native <details> — no JS. */
.tr-retries{border:1px dashed var(--line-2);border-radius:var(--r-sm)}
.tr-retries>summary{cursor:pointer;list-style:none;padding:8px 12px;font-family:var(--mono);font-size:11px;color:var(--faint);user-select:none}
.tr-retries>summary::-webkit-details-marker{display:none}
.tr-retries>summary::before{content:"▸ ";color:var(--faint)}
.tr-retries[open]>summary::before{content:"▾ "}
.tr-retries>summary:hover{color:var(--muted)}
.tr-retries[open]>summary{border-bottom:1px solid var(--line)}
.tr-retries .tr-item{opacity:.55;margin:10px}
/* Agent Transcript turn cards — collapsed by default, one per tool/terminal
   block, distinct from the .tr-retries dashed/muted look via a brass
   marker (no accent rail; same disclosure mechanics). */
.tr-turn{border:1px solid var(--line);border-radius:var(--r-sm)}
.tr-turn>summary{cursor:pointer;list-style:none;padding:8px 12px;font-family:var(--mono);font-size:11px;color:var(--muted);user-select:none}
.tr-turn>summary::-webkit-details-marker{display:none}
.tr-turn>summary::before{content:"▸ ";color:var(--brass)}
.tr-turn[open]>summary::before{content:"▾ ";color:var(--brass)}
.tr-turn>summary:hover{color:var(--ink)}
.tr-turn[open]>summary{border-bottom:1px solid var(--line)}
.tr-turn .tr-item{margin:10px}
.tr-bd{padding:10px 12px;font-family:var(--mono);font-size:11.5px;line-height:1.65;color:var(--ink);white-space:pre-wrap;overflow-x:auto}
.tr-bd .dim{color:var(--muted)} .tr-bd .ok-t{color:var(--ok)}
.tr-bd a{color:var(--brass);cursor:pointer;text-decoration:none}

/* llm.audit clarity: prepended above the transcript blocks — the model's
   "response" is emit-tool JSON, not prose, so this frames what the three
   sections below actually are. No accent rail; same panel language as
   the rest of the transcript. */
.callout{background:var(--panel-3);border:1px solid var(--line);border-radius:var(--r-sm);padding:12px 14px;font-size:12.5px;line-height:1.55;color:var(--muted)}
.callout b{color:var(--ink)}
.callout code{font-family:var(--mono);font-size:11.5px;color:var(--brass)}
.stages{display:flex;gap:10px}
.stage{flex:1;min-width:0;background:var(--panel-3);border:1px solid var(--line-2);border-radius:var(--r-sm);padding:10px 12px}
.stage .n{font-family:var(--mono);font-size:11px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--brass)}
.stage .d{font-size:11.5px;color:var(--muted);margin-top:4px}

/* segmented mini toggle (step detail header: Overview | Transcript) */
.seg{display:inline-flex;border:1px solid var(--line-2);border-radius:var(--r-sm);overflow:hidden;font-family:var(--mono);font-size:11.5px}
.seg button{border:0;background:var(--ground);color:var(--muted);padding:7px 13px;cursor:pointer;border-right:1px solid var(--line)}
.seg button:last-child{border-right:0}
.seg button.on{background:color-mix(in srgb,var(--brass) 16%,var(--ground));color:var(--brass);font-weight:600}
.seg.mini button{padding:4px 10px;font-size:10.5px}
.seg.mini button.agent-on{background:color-mix(in srgb,var(--claret) 15%,var(--ground));color:var(--claret);font-weight:600}

/* misc */
.screen{display:none}.screen.on{display:block}
.row-between{display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap}
.muted{color:var(--muted)} .brass{color:var(--brass)} .faint{color:var(--faint)}
.list-reset{list-style:none;margin:0;padding:0}
.feed li{display:flex;gap:12px;padding:10px 0;border-bottom:1px solid var(--line);font-size:13px}
.feed li:last-child{border-bottom:0}
.feed .ts{font-family:var(--mono);font-size:11px;color:var(--faint);white-space:nowrap;min-width:62px}
.divide{height:1px;background:var(--line);margin:24px 0}
.empty{color:var(--faint);font-size:13px;padding:14px 16px}
@media(max-width:920px){.app{grid-template-columns:1fr}.sidebar{display:none}.tiles,.tiles.three{grid-template-columns:1fr 1fr}}

/* ---------- overview v2 ---------- */
/* Header row: title left, mono vitals right. */
.ov-hd{display:flex;justify-content:space-between;align-items:flex-end;gap:16px;margin-bottom:20px}
.ov-vitals{font-family:var(--mono);font-size:11px;color:var(--faint);text-align:right;line-height:1.8;white-space:nowrap}
.ov-vitals b{color:var(--muted);font-weight:500}
.tile .foot.mono{font-family:var(--mono);font-size:11.5px}
/* 12-bucket 2h sparkline (runs · 24h tile) */
.spark{display:flex;align-items:flex-end;gap:2px;height:26px;margin:8px 0 6px}
.spark i{flex:1;background:color-mix(in srgb,var(--brass) 55%,transparent);border-radius:1.5px;min-height:2px}
.spark i.hot{background:var(--brass)}
.spark i.f{background:var(--fail)}
/* thin budget/split bar (spend tile) */
.bud{height:5px;border-radius:3px;background:var(--panel-3);margin:10px 0 8px;overflow:hidden}
.bud i{display:block;height:100%;background:var(--brass);border-radius:3px}
/* two-column body: stacked left cards, activity stretched right */
.ov-grid{display:grid;grid-template-columns:1.45fr 1fr;gap:18px;align-items:stretch;margin-top:22px}
.ov-right{display:flex;flex-direction:column;min-width:0}
.ov-right .card{flex:1}
.ov-left{min-width:0}
/* gate carousel */
.car-hd{display:flex;align-items:center;gap:10px;margin:0 0 12px}
.car-nav{margin-left:auto;display:flex;gap:6px;align-items:center}
.car-nav button{border:1px solid var(--line-2);background:var(--panel-2);color:var(--muted);border-radius:var(--r-sm);width:26px;height:24px;cursor:pointer;font-size:12px;line-height:1;padding:0}
.car-nav button:hover{color:var(--ink);border-color:var(--brass)}
.car-dots{display:flex;gap:5px;margin-right:6px}
.car-dots i{width:7px;height:7px;border-radius:50%;background:var(--panel-3);border:1px solid var(--line-2)}
.car-dots i.on{background:var(--claret);border-color:var(--claret)}
.gate-car{overflow:hidden;position:relative;margin-bottom:6px;-webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 46px),transparent);mask-image:linear-gradient(90deg,#000 calc(100% - 46px),transparent)}
.gate-track{display:flex;gap:16px;align-items:flex-start;transition:transform .28s cubic-bezier(.4,0,.2,1)}
.gate-track .gate{flex:0 0 calc(100% - 52px);margin-bottom:4px!important;opacity:.45;transition:opacity .28s}
.gate-track .gate.front{opacity:1}
.gate-track .gate:not(.front){cursor:pointer}
@media (prefers-reduced-motion: reduce){.gate-track,.gate-track .gate{transition:none}}
/* pipelines at a glance — fixed columns so every dot strip aligns */
.pl-row{display:grid;grid-template-columns:minmax(0,1fr) 168px 112px 96px;gap:14px;align-items:center;padding:11px 16px;border-bottom:1px solid var(--line);cursor:pointer}
.pl-row:last-child{border-bottom:0}
.pl-row:hover{background:var(--panel-2)}
.pl-row .nm{font-family:var(--mono);font-size:13px;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pl-row .tg{font-size:11px;color:var(--faint);font-family:var(--mono);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.hist{display:flex;gap:3px;align-items:center;width:162px}
.hist i{width:8px;height:8px;border-radius:2.5px;background:var(--ok);opacity:.85;flex-shrink:0}
.hist i.f{background:var(--fail)}.hist i.r{background:var(--run)}.hist i.w{background:var(--claret)}
.hist i.e{background:var(--panel-3);border:1px solid var(--line-2);opacity:1}
.pl-row .nx{font-family:var(--mono);font-size:10.5px;color:var(--faint);text-align:right;white-space:nowrap}
.pl-row .nx b{display:block;color:var(--muted);font-weight:500;font-size:11.5px}
/* running now: segmented per-step progress */
.rn-row{padding:11px 16px;border-bottom:1px solid var(--line);cursor:pointer}
.rn-row:last-child{border-bottom:0}
.rn-row:hover{background:var(--panel-2)}
.rn-top{display:flex;align-items:center;gap:10px}
.rn-top .nm{font-family:var(--mono);font-size:12.5px;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rn-top .t{margin-left:auto;font-family:var(--mono);font-size:10.5px;color:var(--faint)}
.rn-cancel{border:1px solid var(--line);background:transparent;color:var(--faint);font-size:10.5px;
  padding:2px 8px;border-radius:5px;cursor:pointer;opacity:0;transition:opacity .12s,color .12s,border-color .12s}
.rn-row:hover .rn-cancel{opacity:1}
.rn-cancel:hover{color:var(--fail);border-color:var(--fail)}
.prog{display:flex;gap:3px;margin-top:8px}
.prog i{flex:1;height:4px;border-radius:2px;background:var(--panel-3)}
.prog i.d{background:var(--ok)}.prog i.a{background:var(--run)}.prog i.g{background:var(--claret)}.prog i.x{background:var(--fail)}
.rn-sub{font-family:var(--mono);font-size:10.5px;color:var(--faint);margin-top:6px}
/* activity feed */
.ov-feed{padding:6px 0}
.ov-feed li{display:flex;gap:10px;padding:6px 16px;font-size:12px;align-items:baseline}
.ov-feed .ts{font-family:var(--mono);font-size:10.5px;color:var(--faint);width:40px;flex-shrink:0}
.ov-feed .k{font-family:var(--mono);font-size:12px;overflow-wrap:anywhere}
.ov-feed .k b{color:var(--ink);font-weight:500}
.ov-feed .k .ok{color:var(--ok)}.ov-feed .k .fail{color:var(--fail)}
.ov-feed .k .wt{color:var(--claret)}.ov-feed .k .m{color:var(--muted)}
/* service cards (overview triage) — plain hairline cards, no accent rails */
.svc-cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:12px}
.svc-card{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
  padding:14px 16px;cursor:pointer;display:flex;flex-direction:column;gap:8px;transition:border-color .12s,background .12s}
.svc-card:hover{border-color:var(--line-2);background:var(--panel-2)}
.svc-top{display:flex;align-items:center;gap:10px}
.svc-nm{font-family:var(--serif);font-size:16px;font-weight:600;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.svc-top .pill{margin-left:auto}
.svc-desc{font-size:12.5px;color:var(--muted);line-height:1.4;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.svc-foot{display:flex;align-items:center;gap:10px;margin-top:auto}
.svc-counts{font-family:var(--mono);font-size:11px;color:var(--faint)}
.svc-foot .btn{margin-left:auto}
/* --- service page: scheduled runs --- */
.sched-row{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.2fr) auto auto;gap:14px;
  align-items:center;padding:11px 16px;border-bottom:1px solid var(--line)}
.sched-row:last-child{border-bottom:0}
.sched-id{display:flex;align-items:center;gap:10px;min-width:0}
.sched-id .nm{font-family:var(--mono);font-size:13px;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sched-params{font-size:11.5px;color:var(--faint);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* --- service page: triggers table --- */
.trig-tbl td .name{font-family:var(--mono);font-size:12.5px}
.trig-tbl tr.trig-off td{opacity:.55}
.trig-act{text-align:right;white-space:nowrap}
.trig-act .btn{margin-left:6px}
/* enable toggle: a small pill switch (brass when on) */
.trig-tog{position:relative;width:34px;height:18px;border-radius:99px;border:1px solid var(--line-2);
  background:var(--panel-3);cursor:pointer;padding:0;transition:background .12s}
.trig-tog .knob{position:absolute;top:1px;left:1px;width:14px;height:14px;border-radius:50%;
  background:var(--faint);transition:left .12s,background .12s}
.trig-tog.on{background:color-mix(in srgb,var(--brass) 30%,var(--panel-3));border-color:var(--brass)}
.trig-tog.on .knob{left:17px;background:var(--brass)}
.card-note{padding:11px 16px;border-top:1px solid var(--line);font-size:11.5px;color:var(--faint)}
/* --- service page: firing log --- */
.fl-row{display:flex;align-items:center;gap:10px;padding:10px 16px;border-bottom:1px solid var(--line)}
.fl-row:last-child{border-bottom:0}
.fl-row[data-href]{cursor:pointer}
.fl-row[data-href]:hover{background:var(--panel-2)}
.fl-src{font-size:11.5px;color:var(--muted);white-space:nowrap}
.fl-inf{color:var(--faint);cursor:help}
.fl-arrow{color:var(--faint)}
.fl-pipe{font-family:var(--mono);font-size:12.5px;color:var(--ink);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.fl-when{font-size:11.5px;margin-left:auto;white-space:nowrap}
.fl-out{flex-shrink:0}
/* --- service page: trigger form panels --- */
.tf-panel[hidden]{display:none}
/* --- service page: bridges --- */
.br-row{display:flex;align-items:center;gap:12px;padding:11px 16px;border-bottom:1px solid var(--line)}
.br-row:last-child{border-bottom:0}
.br-dot{width:9px;height:9px;border-radius:50%;flex-shrink:0;background:var(--faint)}
.br-dot.up{background:var(--ok);box-shadow:0 0 0 3px color-mix(in srgb,var(--ok) 22%,transparent)}
.br-dot.down{background:var(--fail)}
.br-dot.unknown{background:transparent;border:1.5px dashed var(--faint)}
.br-id{display:flex;flex-direction:column;gap:2px;min-width:0}
.br-id .nm{font-family:var(--mono);font-size:13px;color:var(--ink)}
.br-meta{font-family:var(--mono);font-size:11px;color:var(--faint)}
/* --- service page: durable memory --- */
.mem-panel{display:block}
.mem-add{display:flex;gap:8px;align-items:center}
.mem-add .input{flex:1}
.mem-list{margin-top:12px}
.mem-grp{border-top:1px solid var(--line)}
.mem-grp:first-child{border-top:0}
.mem-th{display:flex;align-items:center;gap:8px;width:100%;text-align:left;background:none;border:0;
  cursor:pointer;padding:9px 2px;font-family:var(--mono);font-size:11px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--muted)}
.mem-th:hover{color:var(--ink)}
.mem-th .car{color:var(--faint);width:12px}
.mem-th .tp{color:var(--ink)}
.mem-th .n{margin-left:auto;color:var(--faint);letter-spacing:0}
.mem-item{display:flex;align-items:flex-start;gap:12px;padding:8px 2px 10px 20px}
.mem-tx{flex:1;font-size:13px;color:var(--ink);line-height:1.5;overflow-wrap:anywhere}
.mem-meta{display:flex;align-items:center;gap:8px;flex-shrink:0}
.mem-meta .mono{font-size:10.5px;color:var(--faint)}
.mem-x{background:none;border:0;color:var(--faint);cursor:pointer;font-size:12px;padding:0 2px;line-height:1}
.mem-x:hover{color:var(--claret)}
@media(max-width:1100px){.ov-grid{grid-template-columns:1fr}.ov-hd{flex-direction:column;align-items:flex-start}.ov-vitals{text-align:left}}

/* ---------- login (public page; shares the token system) ---------- */
.login-wrap{min-height:100vh;display:flex;align-items:center;justify-content:center;position:relative;overflow:hidden}
.login-score{position:absolute;inset:-5% -2%;width:104%;height:110%;pointer-events:none}
.login-score .idle{stroke:var(--line-2);opacity:.55}
.login-score .flow{stroke:var(--brass);opacity:.5;stroke-dasharray:1400;stroke-dashoffset:1400;animation:score-draw 2.8s ease-out .3s forwards}
.login-score .nd{fill:var(--panel-3);stroke:var(--line-2)}
.login-score .nd.on{fill:var(--brass);stroke:var(--brass);opacity:.55}
@keyframes score-draw{to{stroke-dashoffset:0}}
.login-card{position:relative;width:390px;max-width:calc(100vw - 48px);background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:38px 38px 30px;box-shadow:0 30px 80px rgba(0,0,0,.30)}
.login-eyebrow{font-family:var(--mono);font-size:10px;letter-spacing:.24em;text-transform:uppercase;color:var(--brass);margin-bottom:16px}
.login-mark{font-family:var(--serif);font-size:50px;font-weight:600;line-height:1;color:var(--ink);letter-spacing:-.01em}
.login-mark .op{font-family:var(--mono);font-size:12px;color:var(--faint);letter-spacing:.08em;margin-left:10px}
.login-rule{height:1px;background:linear-gradient(90deg,var(--brass),transparent 72%);margin:20px 0 8px}
.login-sub{font-size:13.5px;color:var(--muted);margin:0 0 24px}
.login-field{margin-bottom:14px}
.login-field label{display:block;font-family:var(--mono);font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--faint);margin-bottom:6px}
.login-field input{width:100%;background:var(--ground);border:1px solid var(--line-2);border-radius:var(--r-sm);padding:11px 12px;color:var(--ink);font-family:var(--mono);font-size:13px;outline:none}
.login-field input:focus{border-color:var(--brass)}
.login-btn{width:100%;border:0;border-radius:var(--r-sm);background:var(--brass);color:#17140c;font-family:var(--mono);font-weight:700;font-size:13px;letter-spacing:.05em;padding:12px;cursor:pointer;margin-top:8px}
.login-btn:hover{background:var(--brass-soft)}
.login-err{font-family:var(--mono);font-size:12px;color:var(--fail);min-height:18px;margin:10px 0 0}
.login-hint{font-size:12px;color:var(--faint);margin-top:10px;line-height:1.65}
.login-hint code{font-family:var(--mono);background:var(--panel-2);padding:1px 5px;border-radius:4px}
.login-foot{margin-top:22px;text-align:center;font-family:var(--mono);font-size:10px;letter-spacing:.18em;color:var(--faint);text-transform:uppercase}
.logbox .dim{color:var(--faint)}

/* ---- config drawer form controls (config ownership ladder, §7.1) ---- */
.fld-row{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:6px}
.fld-row label{font-size:12.5px;font-weight:500}
.select{width:100%;background:var(--ground);border:1px solid var(--line-2);border-radius:var(--r-sm);padding:9px 11px;color:var(--ink);font-family:var(--sans);font-size:13.5px;outline:none}
.select:focus{border-color:var(--brass)}
.unit{display:flex;align-items:stretch;border:1px solid var(--line-2);border-radius:var(--r-sm);background:var(--ground);overflow:hidden}
.unit input{flex:1;border:0;background:transparent;outline:none;color:var(--ink);font-family:var(--mono);font-size:12.5px;padding:9px 11px;min-width:0}
.unit .u{display:flex;align-items:center;padding:0 10px;border-left:1px solid var(--line);color:var(--faint);font-family:var(--mono);font-size:11px;white-space:nowrap}
.chipbox{display:flex;flex-wrap:wrap;gap:6px;padding:8px;border:1px solid var(--line-2);border-radius:var(--r-sm);background:var(--ground)}
.chip-i{font-family:var(--mono);font-size:11px;padding:3px 9px;border-radius:99px;border:1px solid var(--line-2);color:var(--faint);cursor:pointer;user-select:none;background:none}
.chip-i.on{color:var(--claret);border-color:color-mix(in srgb,var(--claret) 45%,var(--line-2));background:color-mix(in srgb,var(--claret) 10%,transparent)}
.agent-body{margin-top:8px;padding:12px;border:1px solid color-mix(in srgb,var(--claret) 30%,var(--line-2));border-radius:var(--r-sm);background:color-mix(in srgb,var(--claret) 5%,var(--panel-2))}
.a-lbl{font-family:var(--mono);font-size:10.5px;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);margin-bottom:6px}
.clamp{display:flex;align-items:center;gap:8px}
.clamp .dash{color:var(--faint)}

/* ---- library sub-tabs + registry browse/install ---- */
.subtabs{display:inline-flex;background:var(--panel-2);border:1px solid var(--line);border-radius:var(--r-sm);padding:3px;gap:2px}
.subtab{font-family:var(--mono);font-size:12px;padding:6px 13px;border-radius:5px;color:var(--muted);cursor:pointer;background:none;border:0}
.subtab:hover{color:var(--ink)}
.subtab.on{background:var(--panel-3);color:var(--ink)}
.chip-row{display:flex;gap:8px;flex-wrap:wrap}
.chip{font-family:var(--mono);font-size:11px;padding:4px 10px;border-radius:99px;border:1px solid var(--line-2);background:var(--panel-2);color:var(--muted);cursor:pointer;user-select:none}
.chip:hover{color:var(--ink)}
.chip.on{border-color:var(--brass);color:var(--brass)}
.chip .n{color:var(--faint);margin-left:2px}
.chip.on .n{color:var(--brass)}
.reg-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:14px}
@media(max-width:920px){.reg-grid{grid-template-columns:1fr}}
.reg-card{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:15px 17px;display:flex;flex-direction:column;gap:8px}
.reg-card .rc-top{display:flex;align-items:center;gap:10px}
.reg-card .rc-name{font-family:var(--mono);font-size:13.5px;color:var(--ink)}
.reg-card .rc-desc{font-size:12.5px;color:var(--muted);flex:1}
.reg-card .rc-foot{display:flex;align-items:center;gap:8px;margin-top:2px;flex-wrap:wrap}
.reg-card .reg-err{color:var(--fail);font-size:11px;flex-basis:100%}
.icon-tile{width:34px;height:34px;border-radius:8px;background:var(--panel-3);display:grid;place-items:center;font-size:15px;flex-shrink:0}

/* ---- run split-button (cancel/restart, resume/rerun-from-scratch) ---- */
.splitbtn{position:relative;display:inline-flex}
.splitbtn > .btn:first-child{border-top-right-radius:0;border-bottom-right-radius:0}
.splitbtn .sb-caret{border-top-left-radius:0;border-bottom-left-radius:0;border-left:0;padding:8px 9px}
.sb-menu{position:absolute;top:calc(100% + 4px);right:0;min-width:190px;background:var(--panel-2);
  border:1px solid var(--line-2);border-radius:var(--r-sm);box-shadow:0 10px 28px rgba(0,0,0,.32);
  padding:4px;display:none;z-index:30}
.splitbtn.open .sb-menu{display:block}
.sb-item{display:block;width:100%;text-align:left;background:none;border:0;color:var(--ink);
  font-family:var(--mono);font-size:12px;padding:7px 10px;border-radius:5px;cursor:pointer}
.sb-item:hover{background:var(--panel-3)}

.term{font-family:var(--mono);font-size:12.5px;background:#0d0e12;border:1px solid var(--line);
  border-radius:var(--r-sm);padding:12px 14px;overflow-x:auto}
.term-cmd{color:var(--ink);white-space:pre;margin:2px 0 8px}
.term-cmd .term-p{color:var(--ok);margin-right:8px}
.term pre{margin:0 0 10px;white-space:pre;color:var(--muted)}
.term pre:last-child{margin-bottom:0}
.term .term-out{color:var(--ink)}

/* Live stderr stream for a running step (Task 4's SSE endpoint) — no
   colored accent rail per house rule; same footprint as .term. */
.live-out{min-width:0;max-width:100%;max-height:360px;overflow:auto;background:var(--panel-3);
  border:1px solid var(--line);border-radius:var(--r-sm);padding:11px 13px;
  font-family:var(--mono);font-size:12.5px;line-height:1.55;color:var(--ink);
  white-space:pre-wrap;overflow-wrap:anywhere;word-break:normal}
.live-out:empty::before{content:"waiting for output…";color:var(--faint)}
.live-meta{font-family:var(--mono);font-size:11px;color:var(--faint);margin-bottom:6px}

/* ============================================================ output views
   Shape-driven renderer for a step's produced JSON: table / cards / key-value /
   list (+ chat / markdown below). Full-hairline borders + fills only, no
   left-accent rails. Reuses the tokens + the reading-viewer modal. */

/* per-file rendered block: filename + ⤢ raw header, then the renderer output
   (which supplies its own horizontal padding). No accent rails. */
.out-block{margin-bottom:4px}
.out-block-h{display:flex;align-items:center;gap:10px;padding:6px 16px 8px}
.out-block-h .out-cap{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.out-block-h .rawchip{margin-left:auto;flex:none}
.out-body>.muted{display:inline-block;padding:0 16px 14px}

/* table */
.out-scroll{margin:0 16px 18px;border:1px solid var(--line);border-radius:var(--r-sm);overflow-x:auto}
table.out{width:100%;border-collapse:collapse;font-size:12.5px}
table.out th{font-family:var(--mono);font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;
  color:var(--faint);text-align:left;font-weight:400;padding:9px 12px;background:var(--panel-2);
  border-bottom:1px solid var(--line);white-space:nowrap;position:sticky;top:0}
table.out td{padding:10px 14px;border-bottom:1px solid var(--line);color:var(--ink);vertical-align:top;
  max-width:320px}
table.out tbody tr:last-child td{border-bottom:0}
.rowx{cursor:pointer;transition:background .1s}
table.out tbody tr.rowx:hover{background:var(--panel-2)}
/* Cell text clamps to 2 lines so rows stay short + uniform (scannable); the
   full value is a row-click away (table/cards → item viewer). */
.ocell{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;
  overflow:hidden;overflow-wrap:anywhere;line-height:1.45;white-space:pre-line}
/* ⤢ expander + nested {…}/[N] chip: opens the full value in the reading viewer */
.cellx{background:none;border:0;color:var(--brass);font-family:var(--mono);font-size:12px;
  cursor:pointer;padding:0 0 0 4px;vertical-align:baseline}
.cellx:hover{color:var(--brass-soft);text-decoration:underline}
.cellx.nest{border:1px solid var(--line-2);border-radius:99px;padding:1px 8px;color:var(--muted)}
.cellx.nest:hover{color:var(--ink);border-color:var(--brass-soft);text-decoration:none}
.cellx.rawchip{border:1px solid var(--line-2);border-radius:99px;padding:3px 10px;color:var(--muted)}
.cellx.rawchip:hover{color:var(--ink);border-color:var(--brass-soft);text-decoration:none}

/* cards (the wide-table fallback) */
.cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:12px;padding:0 16px 18px}
.icard{display:flex;flex-direction:column;gap:7px;text-align:left;padding:13px 14px;background:var(--panel-2);
  border:1px solid var(--line);border-radius:var(--r-sm);cursor:pointer;font:inherit;color:var(--ink);
  transition:border-color .12s,transform .12s}
.icard:hover{border-color:var(--brass-soft);background:var(--panel-3);transform:translateY(-1px)}
.icard .ic-t{font-size:14px;color:var(--ink);font-weight:500;margin-bottom:2px;overflow-wrap:anywhere}
.icard .ic-f{display:grid;grid-template-columns:90px 1fr;gap:4px 10px;font-size:12px}
.icard .ic-k{font-family:var(--mono);font-size:10.5px;color:var(--faint)}
.icard .ic-v{color:var(--ink);overflow-wrap:anywhere}

/* key-value (single object → definition list) */
.kvo{display:grid;grid-template-columns:150px 1fr;gap:0;margin:2px 16px 16px;font-size:13px;
  border:1px solid var(--line);border-radius:var(--r-sm);overflow:hidden}
.kvo-k,.kvo-v{padding:9px 14px;border-bottom:1px solid var(--line)}
.kvo > :nth-last-child(-n+2){border-bottom:0}
.kvo-k{font-family:var(--mono);font-size:11.5px;color:var(--faint);background:var(--panel-2);
  border-right:1px solid var(--line);padding-top:10px}
.kvo-v{color:var(--ink);min-width:0}
.kvo-v.kv-num{color:var(--num);font-family:var(--mono)}
.kvo-v.kv-bool{color:var(--bool);font-family:var(--mono)}
/* single-line values: the value text truncates to one line; a ⤢ button that
   opens the full-value viewer is appended by applyKvTrunc() only when the
   text is actually clipped (measured post-layout, so it's width-accurate). */
.kvo-v,.g-facts .v{display:flex;align-items:center;gap:8px;white-space:nowrap;overflow:hidden}
.kv-txt{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.kv-more{flex:none;font-size:11px;line-height:1}
/* Inline raw/plain-text output inside an out-block (the header carries the
   ⤢ raw chip for the full text). */
.out-pre{margin:0 16px 14px;padding:11px 14px;background:var(--ground);border:1px solid var(--line);
  border-radius:var(--r-sm);font-family:var(--mono);font-size:11.5px;line-height:1.6;color:var(--ink);
  white-space:pre-wrap;overflow-wrap:anywhere;max-height:360px;overflow:auto}

/* list (scalar array → chips) */
.chips{display:flex;gap:8px;flex-wrap:wrap;padding:2px 16px 18px}
.ochip{font-family:var(--mono);font-size:11.5px;padding:3px 10px;border-radius:99px;
  border:1px solid var(--line);background:var(--panel-2);color:var(--ink)}

/* chat (messages array → role-labelled bubbles) */
.chat{display:flex;flex-direction:column;gap:12px;padding:2px 16px 18px}
.bubble{border:1px solid var(--line);border-radius:var(--r-sm);background:var(--panel-2);
  padding:9px 13px;max-width:min(760px,92%)}
.bubble .b-role{font-family:var(--mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--faint);margin-bottom:5px}
.bubble .b-body{font-size:13px;color:var(--ink)}
.bubble.assistant{align-self:flex-start}
.bubble.user{align-self:flex-end;background:color-mix(in srgb,var(--brass) 12%,var(--panel-2))}
.bubble.user .b-role{color:var(--brass-soft)}
.bubble.tool,.bubble.system{align-self:flex-start;background:var(--ground)}
.bubble.tool .b-body{font-family:var(--mono);font-size:11.5px;color:var(--muted)}
.bubble.system .b-role{color:var(--muted)}
.bubble.other{align-self:flex-start}

/* markdown (safe client render — headings/bold/italic/code/lists/paragraphs) */
.md{font-size:13.5px;color:var(--ink);line-height:1.6}
.md > :first-child{margin-top:0}
.md > :last-child{margin-bottom:0}
.md h1,.md h2,.md h3,.md h4,.md h5,.md h6{font-family:var(--serif);color:var(--ink);line-height:1.3;margin:16px 0 8px}
.md h1{font-size:20px} .md h2{font-size:17px} .md h3{font-size:15px}
.md h4,.md h5,.md h6{font-size:13.5px;font-family:var(--sans);font-weight:600}
.md p{margin:0 0 10px}
.md ul,.md ol{margin:0 0 10px;padding-left:22px}
.md li{margin:2px 0}
.md code{font-family:var(--mono);font-size:.88em;background:var(--panel-3);border:1px solid var(--line);
  border-radius:4px;padding:1px 5px}
.md strong{font-weight:600;color:var(--ink)}
.md em{font-style:italic}
.md-pre{background:var(--panel-3);border:1px solid var(--line);border-radius:var(--r-sm);
  padding:11px 13px;overflow-x:auto;margin:0 0 10px}
.md-pre code{background:none;border:0;padding:0;font-size:12px;color:var(--muted);white-space:pre}
/* Inside a step-detail Output section, standalone markdown keeps the 16px inset;
   markdown nested in a chat bubble does not (the bubble owns the padding). */
.step-detail .md{padding:0 16px 6px}
.bubble .md,.step-detail .bubble .md{padding:0;font-size:inherit}

/* item viewer (row/card → one object as a definition list in the reading modal) */
.iv{display:flex;flex-direction:column;gap:16px;max-width:820px}
.iv-row{display:grid;grid-template-columns:200px 1fr;gap:6px 22px;align-items:start}
.iv-k{font-family:var(--mono);font-size:12px;color:var(--ink);padding-top:1px;overflow-wrap:anywhere}
.iv-sub{color:var(--faint);font-size:10.5px;letter-spacing:.02em;margin-top:2px;line-height:1.4}
.iv-v{color:var(--ink);font-size:13.5px;overflow-wrap:anywhere}
.iv-text{white-space:pre-wrap}
.iv-chips{padding:0}
/* nested {…}/[N] chip → recurses into the viewer */
.ivnest{font-family:var(--mono);font-size:11.5px;padding:2px 10px;border-radius:99px;
  border:1px solid var(--line-2);background:var(--panel-2);color:var(--brass);cursor:pointer}
.ivnest:hover{border-color:var(--brass-soft);color:var(--brass-soft)}
@media (max-width:640px){.iv-row{grid-template-columns:1fr;gap:2px}}
.term .term-err{color:var(--fail)}

/* in-step approval gate review panel (approve step → present blocks + actions) */
.gate-wrap{padding:0 18px 18px}
.gate-intro{margin:14px 0 4px}
.gate-intro .q{font-family:var(--serif);font-size:20px;line-height:1.35;color:var(--ink);font-weight:600}
.step-detail .say{margin:2px 0 14px;font-size:13.5px;line-height:1.6;color:var(--muted)}
.facts{display:flex;flex-wrap:wrap;gap:8px;margin:2px 0 16px}
.fact{font-family:var(--mono);font-size:11.5px;color:var(--ink);background:var(--ground);
  border:1px solid var(--line);border-radius:99px;padding:4px 12px;overflow-wrap:anywhere}
.fact b{color:var(--faint);font-weight:600;margin-right:6px;text-transform:uppercase;letter-spacing:.05em;font-size:10.5px}
.gate-actions{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin-top:18px}
.gate-outcome{font-family:var(--mono);font-size:12px;font-weight:600;padding:5px 12px;border-radius:var(--r-sm)}
.gate-outcome.ok{color:var(--ok);background:color-mix(in srgb,var(--ok) 12%,transparent)}
.gate-outcome.no{color:var(--claret);background:color-mix(in srgb,var(--claret) 12%,transparent)}
.gate-note-ro{font-size:13px;color:var(--muted);font-style:italic}

/* structured input-override editor (Task 4): Tree/Raw JSON editor mounted
   in a .ov-struct row's value cell. Tab/pill look reuses the generic
   .seg/.pill rules above, scoped under .jtool so the smaller toolbar
   sizing here doesn't bleed into other .seg/.pill usages on the page. */
.jed{border:1px solid var(--line-2);border-radius:var(--r-sm);background:var(--panel-3);overflow:hidden}
.jtool{display:flex;align-items:center;gap:7px;padding:7px 9px;border-bottom:1px solid var(--line);background:var(--panel-2)}
.jtool .seg{display:inline-flex;border:1px solid var(--line-2);border-radius:5px;overflow:hidden;font-size:11px}
.jtool .seg button{background:none;border:0;color:var(--muted);font-family:var(--mono);font-size:11px;padding:4px 11px;cursor:pointer}
.jtool .seg button.on{background:var(--panel-3);color:var(--ink)}
.jtool .pill{margin-left:auto}
.tbtn{background:none;border:1px solid var(--line-2);border-radius:5px;color:var(--muted);font-family:var(--mono);font-size:11px;padding:4px 9px;cursor:pointer;display:inline-flex;align-items:center;gap:6px}
.tbtn:hover{color:var(--ink)}
.tbtn[aria-pressed="true"]{color:var(--brass);border-color:var(--brass-soft)}
.tbtn .sw{width:22px;height:13px;border-radius:99px;background:var(--line-2);position:relative;transition:background .12s}
.tbtn[aria-pressed="true"] .sw{background:var(--brass)}
.tbtn .sw::after{content:"";position:absolute;top:1.5px;left:1.5px;width:10px;height:10px;border-radius:50%;background:var(--panel);transition:left .12s}
.tbtn[aria-pressed="true"] .sw::after{left:9.5px}
.pill.bad{color:var(--fail);background:color-mix(in srgb,var(--fail) 15%,transparent)} .pill.bad .d{background:var(--fail)}
.shake{animation:shk .3s}
@keyframes shk{0%,100%{transform:translateX(0)}25%{transform:translateX(-3px)}75%{transform:translateX(3px)}}

.jraw{position:relative}
textarea.jta{display:block;width:100%;border:0;background:transparent;color:var(--ink);font-family:var(--mono);font-size:12.5px;line-height:1.65;padding:11px 12px;resize:vertical;min-height:160px;white-space:pre;overflow:auto;tab-size:2}
textarea.jta.wrap{white-space:pre-wrap;word-break:break-word}
textarea.jta:focus{outline:none}
.jerr{border-top:1px dashed var(--line-2);padding:6px 12px;color:var(--fail);font-family:var(--mono);font-size:11px;background:color-mix(in srgb,var(--fail) 8%,transparent)}

.jtree{padding:8px 12px 10px;font-family:var(--mono);font-size:12.5px;max-height:360px;overflow:auto}
.jnode > .jrow, .jleaf{display:flex;align-items:flex-start;gap:7px;padding:1.5px 0;min-height:25px}
.jkids{margin-left:8px;border-left:1px solid var(--line);padding-left:12px}
.caret{width:13px;height:20px;flex:0 0 13px;cursor:pointer;color:var(--faint);display:inline-flex;align-items:center;justify-content:center;transition:transform .1s;user-select:none;font-size:10px}
.caret.leaf{cursor:default;color:transparent}
.jnode.collapsed > .jrow > .caret{transform:rotate(-90deg)}
.jnode.collapsed > .jkids{display:none}
.jkey{color:var(--key);flex:0 0 auto;padding-top:3px}
.jkey.arr{color:var(--faint)}
.gcount{color:var(--faint);font-size:11px;padding-top:3px}
.summary{color:var(--faint);font-style:italic;padding-top:3px;display:none}
.jnode.collapsed > .jrow .summary{display:inline}
.leafwrap{flex:1 1 auto;min-width:0;display:flex;align-items:center;gap:8px}
textarea.leafin{flex:1 1 auto;min-width:0;background:var(--panel);border:1px solid var(--line);border-radius:4px;color:var(--str);font-family:var(--mono);font-size:12px;line-height:1.5;padding:3px 8px;resize:none;height:25px;white-space:nowrap;overflow-x:auto;overflow-y:hidden;scrollbar-width:thin}
.jtree.wrapon textarea.leafin{white-space:pre-wrap;overflow-x:hidden;height:auto}
textarea.leafin:focus{outline:2px solid var(--brass);outline-offset:1px;border-color:var(--brass-soft)}
input.leafin{background:var(--panel);border:1px solid var(--line);border-radius:4px;font-family:var(--mono);font-size:12px;padding:3px 8px}
input.leafin.num{color:var(--num);width:96px;flex:0 0 auto}
select.leafin{background:var(--panel);border:1px solid var(--line);border-radius:4px;color:var(--bool);font-family:var(--mono);font-size:12px;padding:3px 7px;flex:0 0 auto}
.jnull{color:var(--faint);font-style:italic;padding-top:3px}
.jleaf.edited textarea.leafin,.jleaf.edited input.leafin,.jleaf.edited select.leafin{border-color:var(--brass-soft);box-shadow:inset 2px 0 0 var(--brass)}
