:root {
  --bg: #13161a;
  --panel: #1a1e23;
  --panel-2: #22272e;
  --line: #303741;
  --fg: #edf0f4;
  --muted: #949ca8;
  --dim: #68717d;
  --accent: #ffb52e;
  --good: #49cc8d;
  --bad: #ec6666;
}

* { box-sizing: border-box; }
html, body {
  height: 100%;
  margin: 0;
  overflow: hidden;
}
body {
  display: flex;
  flex-direction: column;
  background: var(--bg);
  color: var(--fg);
  font: 14px/1.5 system-ui, -apple-system, "Segoe UI", sans-serif;
}
button, input, select, textarea { color: inherit; font: inherit; }
button, select, input, textarea {
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--panel-2);
}
button { padding: 6px 11px; cursor: pointer; white-space: nowrap; }
button:hover:not(:disabled) { border-color: #505966; }
button:disabled { cursor: not-allowed; opacity: .4; }
button.primary { border-color: var(--accent); background: var(--accent); color: #251800; font-weight: 700; }
button.danger { border-color: var(--bad); background: var(--bad); color: #2a0c0c; font-weight: 700; }
button.ghost { background: transparent; }
select, input, textarea { padding: 7px 9px; outline: none; }
select:focus, input:focus, textarea:focus { border-color: var(--accent); }
textarea { width: 100%; resize: vertical; font: 12px/1.55 ui-monospace, SFMono-Regular, Menlo, monospace; }
.hidden { display: none !important; }

#topbar {
  display: flex;
  flex: none;
  align-items: center;
  gap: 10px;
  height: 54px;
  padding: 0 14px;
  border-bottom: 1px solid var(--line);
  background: var(--panel);
}
.brand { margin-right: 6px; font-weight: 800; letter-spacing: -.02em; }
.brand span { margin-left: 4px; color: var(--accent); }
.spacer { flex: 1; }
.cost { color: var(--muted); font: 11px ui-monospace, monospace; white-space: nowrap; }
.status { color: var(--muted); font-size: 12px; white-space: nowrap; }
.status.running { color: var(--accent); }
.status.done { color: var(--good); }
.status.error, .status.stopped, .status.done-with-errors { color: var(--bad); }

main { display: flex; flex: 1; min-height: 0; }
.board {
  position: relative;
  flex: 1;
  overflow: hidden;
  cursor: grab;
  user-select: none;
  background: radial-gradient(circle at 1px 1px, #252a31 1px, transparent 0) 0 0 / 28px 28px;
}
.board.hidden { display: none; }
.board.panning { cursor: grabbing; }
.board img { pointer-events: none; -webkit-user-drag: none; }
.board-world { position: absolute; inset: 0 auto auto 0; transform-origin: 0 0; }
.board-edges { position: absolute; inset: 0 auto auto 0; overflow: visible; pointer-events: none; }
/* Beneath the cards, so group backdrops never cover their own contents. */
.board-regions { position: absolute; inset: 0 auto auto 0; }
.board-nodes { position: absolute; inset: 0 auto auto 0; }

/* Concept cards are wider; the layout maths reads the same numbers from
   board.cardSize, so these two variables are the only place sizes are set. */
.board.concept { --card-w: 260px; --thumb-h: 165px; }
.board.debug { --card-w: 230px; --thumb-h: 150px; }

.empty {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 30px;
  color: var(--dim);
  text-align: center;
  pointer-events: none;
}
.failure-banner {
  position: absolute;
  top: 14px;
  left: 14px;
  z-index: 8;
  max-width: min(620px, calc(100% - 28px));
  padding: 11px 14px;
  border-color: #72383d;
  border-left: 3px solid var(--bad);
  background: #2a181b;
  color: #f2c5c8;
  text-align: left;
  white-space: normal;
  box-shadow: 0 8px 24px #0007;
}
.failure-banner strong { display: block; color: #ff9399; font-size: 12px; text-transform: uppercase; }
.failure-banner span { display: block; margin-top: 3px; font-size: 12px; }
.zoom {
  position: absolute;
  right: 15px;
  bottom: 15px;
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 5px 7px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--panel);
}
.zoom button { padding: 2px 9px; }
.zoom span { min-width: 42px; color: var(--muted); text-align: center; font: 11px ui-monospace, monospace; }

.card {
  position: absolute;
  width: var(--card-w, 210px);
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
  cursor: pointer;
  transition: border-color .12s, box-shadow .12s;
}
.card:hover { border-color: #56606e; }
.card.selected { border-color: var(--accent); box-shadow: 0 0 0 2px #ffb52e35; }
/* The one node the drawer is showing, when several are selected. */
.card.primary { box-shadow: 0 0 0 3px #ffb52e70; }
.card.root { border-color: #687485; }
.card.entity { border-style: dashed; }
.card.entity.done, .card.entity.unsatisfied { border-style: solid; }
.card.entity.done { border-color: var(--good); }
.card.entity.error, .card.entity.unsatisfied { border-color: var(--bad); }
.card.attempt.latest { border-color: var(--accent); }
.card.polish { border-color: #7161a8; }
.card.polish.done { border-color: #a98df0; }
.card.polish.error, .card.polish.stopped, .card.polish.critic-rejected { border-color: var(--bad); }
.card .thumb {
  display: block;
  width: 100%;
  height: var(--thumb-h, 174px);
  object-fit: contain;
  background: repeating-conic-gradient(#272c33 0 25%, #313740 0 50%) 0 0 / 18px 18px;
}
.card .placeholder {
  display: grid;
  place-items: center;
  height: var(--thumb-h, 174px);
  padding: 16px;
  color: var(--dim);
  background: var(--panel-2);
  text-align: center;
}
.card.working .placeholder, .card.retrying .placeholder { animation: pulse 1.5s infinite ease-in-out; }
.card.retrying { border-color: #d6a84c; }
@keyframes pulse { 50% { opacity: .35; } }
.card .meta {
  display: flex;
  align-items: center;
  gap: 7px;
  min-height: 42px;
  padding: 7px 9px;
  border-top: 1px solid var(--line);
}
.card .label { min-width: 0; overflow: hidden; font-weight: 700; text-overflow: ellipsis; white-space: nowrap; }
.card .sub { margin-left: auto; color: var(--dim); font: 10px ui-monospace, monospace; white-space: nowrap; }
.badge {
  flex: none;
  padding: 1px 5px;
  border-radius: 4px;
  background: var(--panel-2);
  color: var(--muted);
  font-size: 10px;
}
.badge.good { background: var(--good); color: #052a17; }
.badge.bad { background: var(--bad); color: #310c0c; }

#drawer {
  width: var(--drawer-w, 420px);
  flex: none;
  overflow-y: auto;
  border-left: 1px solid var(--line);
  background: var(--panel);
}
/* The panel's drag handle. A sibling, not a child: #drawer scrolls, and a child
   would scroll away from the edge it resizes. */
#drawer-resize {
  flex: none;
  width: 6px;
  cursor: col-resize;
  background: transparent;
  transition: background 0.12s;
}
#drawer-resize:hover, body.drawer-resizing #drawer-resize { background: var(--accent); }
/* Nothing under the pointer may take the drag: a selection across the board, or
   an iframe swallowing the moves once the pointer leaves the handle. */
body.drawer-resizing { user-select: none; cursor: col-resize; }
body.drawer-resizing iframe { pointer-events: none; }
.drawer-empty { padding: 22px; color: var(--dim); }
.drawer-section { padding: 16px; border-bottom: 1px solid var(--line); }
.drawer-title { font-size: 17px; font-weight: 700; }
.drawer-sub { margin-top: 3px; color: var(--dim); font-size: 12px; }
.drawer-section h3 {
  margin: 0 0 10px;
  color: var(--dim);
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
}
.drawer-section p { white-space: pre-wrap; }
.drawer-action { width: 100%; margin-top: 10px; }
.drawer-img {
  display: block;
  width: 100%;
  max-height: 380px;
  object-fit: contain;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: #0e1013;
  cursor: zoom-in;
}
.bbox-map {
  display: block;
  width: 100%;
  max-height: 420px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: #0e1013;
  cursor: zoom-in;
}
.box {
  padding: 9px 11px;
  border-left: 2px solid var(--accent);
  border-radius: 0 5px 5px 0;
  background: var(--panel-2);
  font: 12px ui-monospace, monospace;
}
.box + .box { margin-top: 6px; }
.box.percent { border-left-color: var(--good); color: #bcebd3; }
.kv { width: 100%; border-collapse: collapse; font-size: 12px; }
.kv td { padding: 3px 0; vertical-align: top; }
.kv td:first-child { width: 42%; color: var(--dim); }
.kv td:last-child { text-align: right; font-family: ui-monospace, monospace; }
.prompt-view {
  max-height: 260px;
  margin: 0;
  padding: 10px;
  overflow: auto;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: #101317;
  color: #cbd1d9;
  white-space: pre-wrap;
  font: 11px/1.5 ui-monospace, monospace;
}
.error-stack {
  max-height: 260px;
  margin: 10px 0 0;
  padding: 10px;
  overflow: auto;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: #101317;
  color: #aeb6c1;
  white-space: pre-wrap;
  font: 10.5px/1.5 ui-monospace, monospace;
}
.warn { color: var(--bad); }

.chat-history { display: grid; gap: 9px; margin-top: 12px; }
.chat-turn {
  padding: 9px 10px;
  border: 1px solid var(--line);
  border-left: 2px solid var(--dim);
  border-radius: 5px;
  background: #15191e;
}
.chat-turn.assistant { border-left-color: var(--accent); }
.chat-turn.tool { border-left-color: var(--good); }
.chat-turn.user { border-left-color: #77a7e8; }
.chat-head { display: flex; justify-content: space-between; gap: 8px; color: var(--dim); font-size: 10px; text-transform: uppercase; }
.chat-head code { color: var(--muted); text-transform: none; }
.chat-turn p { margin: 6px 0 0; font-size: 12px; }
.chat-turn pre {
  max-height: 180px;
  margin: 7px 0 0;
  padding: 7px;
  overflow: auto;
  border-radius: 4px;
  background: #0e1115;
  color: #b9c0ca;
  white-space: pre-wrap;
  font: 10.5px/1.45 ui-monospace, monospace;
}
/* Every image in the drawer is capped and letterboxed; without this a 1024px
   generation renders at natural size and overflows the panel. Click opens the
   lightbox for a full-size look. */
.chat-image, .drawer-image {
  display: block;
  width: 100%;
  max-height: 260px;
  margin-top: 8px;
  object-fit: contain;
  border-radius: 5px;
  cursor: zoom-in;
}
/* The concept preview is the main thing you are looking at, so give it more. */
.drawer-image { max-height: 340px; background: repeating-conic-gradient(#272c33 0 25%, #313740 0 50%) 0 0 / 18px 18px; }

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 70;
  display: grid;
  place-items: center;
  padding: 30px;
  background: #080a0de8;
  cursor: zoom-out;
}
/* Viewport units, not percentages: the lightbox centres its child in an
   auto-sized grid track, so `max-height: 100%` has nothing definite to resolve
   against and a tall image overflows the screen. */
.lightbox img { max-width: calc(100vw - 60px); max-height: calc(100vh - 60px); border-radius: 8px; }
.lightbox .bbox-map { width: min(94vw, 1500px); max-height: 92vh; border-radius: 8px; }

.modal {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  place-items: center;
  padding: 24px;
  background: #07090cc8;
}
.sheet {
  width: 430px;
  max-height: 100%;
  padding: 22px;
  overflow-y: auto;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--panel);
}
.sheet.wide { width: min(780px, 100%); }
.sheet h2 { margin: 0 0 17px; font-size: 18px; }
.modal-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 20px; }
.modal-head h2 { margin-bottom: 2px; }
.modal-head p { margin: 0 0 18px; color: var(--dim); font-size: 12px; }
.field { display: block; margin-bottom: 15px; }
.field > span { display: block; margin-bottom: 5px; color: var(--muted); font-size: 12px; }
.field input, .field select { width: 100%; max-width: none; }
.field small { display: block; margin-top: 4px; color: var(--dim); font-size: 11px; }
.field.toggle {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 11px 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #171b20;
}
.field.toggle input { width: auto; margin-top: 3px; accent-color: var(--accent); }
.field.toggle > span { margin: 0; color: var(--text); font-size: 13px; font-weight: 700; }
.field.toggle small { font-weight: 400; }
.row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.row.thirds { grid-template-columns: 1fr 1fr 1fr; }
details { margin: 0 0 13px; border: 1px solid var(--line); border-radius: 8px; background: #171b20; }
summary { padding: 10px 12px; color: var(--muted); cursor: pointer; font-size: 12px; font-weight: 700; }
details .field { padding: 0 12px; }
/* Wraps because a drawer is narrow and a flow's action row can carry four
   buttons — resume, re-run, and the two exports. Overflowing is worse than
   a second line. */
.actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 9px; }
.actions.sticky { position: sticky; bottom: -22px; margin: 0 -22px -22px; padding: 14px 22px; border-top: 1px solid var(--line); background: var(--panel); }
.upload-preview { margin-bottom: 15px; text-align: center; }
.upload-preview img { max-width: 100%; max-height: 230px; border-radius: 7px; }
.upload-preview div { color: var(--dim); font: 11px ui-monospace, monospace; }
.error { padding: 9px 11px; border-radius: 6px; background: #2b1618; color: #f3a1a1; font-size: 12px; }

.model-chip {
  display: inline-block;
  padding: 2px 8px;
  border: 1px solid #3f4a58;
  border-radius: 10px;
  background: #11151b;
  color: #93a4b8;
  font: 600 10px/1.6 ui-monospace, monospace;
  letter-spacing: .3px;
  white-space: nowrap;
}

/* The overseer's own transcript: reasoning and one in/out pair per invocation. */
/* The left column of the workspace, not a sheet over it: a conversation is read
   against the board it belongs to, and the board keeps its camera while you do.
   Resizable, because a transcript is mostly prose and the board is mostly not. */
.transcript {
  display: flex;
  flex: none;
  flex-direction: column;
  width: 480px;
  min-width: 320px;
  max-width: 70vw;
  overflow: hidden;
  border-right: 1px solid var(--line);
  background: var(--panel);
  resize: horizontal;
}
.transcript.hidden { display: none; }
#transcript-body { flex: 1; overflow-y: auto; }
.transcript-head {
  display: flex;
  flex: none;
  align-items: center;
  gap: 12px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--line);
  background: #1b2129;
  font-size: 13px;
}
.transcript-head > div { flex: 1; color: var(--muted); }
.transcript-follow {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--dim);
  font-size: 12px;
  cursor: pointer;
}
.ts-step { padding: 18px; border-bottom: 1px solid var(--line); }

/* The two things the overseer does that are not operations: thinking, and
   saying. Set apart from the step cards so the eye can skip either one, and
   distinct from each other because a summary of thought and a decision stated
   out loud are not the same claim. */
.ts-block {
  padding: 14px 18px;
  border-bottom: 1px solid var(--line);
  border-left: 3px solid transparent;
}
.ts-block > header {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 6px;
}
.ts-block .ts-said {
  margin: 0;
  font-size: 13px;
  line-height: 1.5;
  white-space: pre-wrap;
}
.ts-block.reasoning {
  border-left-color: #5c4f86;
  background: #171622;
}
.ts-block.reasoning .ts-label { border-color: #5c4f86; color: #c3b3f0; }
.ts-block.reasoning .ts-said { color: var(--muted); font-style: italic; }
.ts-block.text { border-left-color: #3f6a7d; background: #141b20; }
.ts-block.text .ts-label { border-color: #3f6a7d; color: #9fd0e2; }
/* A block still being written: the caret says the text is not final. */
.ts-block.streaming .ts-said::after {
  content: '▌';
  margin-left: 2px;
  color: var(--accent);
  animation: pulse 1.1s infinite ease-in-out;
}
.ts-step.failed { background: #1e1416; }
.ts-step.brief { background: #141a22; }
.ts-step.verdict { background: #12211a; }
.ts-step > header {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 10px;
  flex-wrap: wrap;
}
.ts-label {
  padding: 3px 9px;
  border: 1px solid #a98df0;
  border-radius: 12px;
  background: #241d38;
  color: #e8dcff;
  font: 800 12px ui-monospace, monospace;
}
.ts-op { color: var(--text); font-size: 12px; font-weight: 800; letter-spacing: .7px; }
.ts-from { color: var(--dim); font-size: 12px; }
.ts-step p { margin: 0 0 8px; font-size: 13px; line-height: 1.45; white-space: pre-wrap; }
.ts-step .ts-told { color: var(--muted); font-size: 12px; }
/* Two images side by side is a wide layout, and this column is not. They stack
   below the width where a pair stops being legible. */
@media (max-width: 1400px) {
  .transcript { width: 440px; }
}
.ts-io {
  display: grid;
  grid-template-columns: 1fr 34px 1fr;
  align-items: center;
  gap: 10px;
  margin: 12px 0;
}
.ts-io figure { margin: 0; display: grid; gap: 6px; }
.ts-io figcaption { color: var(--dim); font: 700 10px ui-monospace, monospace; letter-spacing: 1px; }
.ts-io img {
  width: 100%;
  max-height: 290px;
  object-fit: contain;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #0b0d10;
  cursor: zoom-in;
}
.ts-arrow { color: #a98df0; font-size: 22px; text-align: center; }
/* One image, not a pair: a mask preview or a generation, which is what a stage
   agent gets back from its own calls. */
.ts-single { margin: 12px 0; }
.ts-single figure { margin: 0; display: grid; gap: 6px; }
.ts-single figcaption { color: var(--dim); font: 700 10px ui-monospace, monospace; letter-spacing: 1px; }
.ts-single img {
  width: 100%;
  max-height: 320px;
  object-fit: contain;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #0d1117;
  cursor: zoom-in;
}
.ts-args {
  margin: 0 0 8px;
  padding: 8px 10px;
  border-radius: 8px;
  background: #0f141a;
  color: var(--muted);
  font: 11px ui-monospace, monospace;
  white-space: pre-wrap;
}
.ts-brief {
  max-height: 290px;
  overflow: auto;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #0f1319;
  color: var(--muted);
  font-size: 11px;
  white-space: pre-wrap;
}
.ts-open { margin-top: 4px; font-size: 11px; }
.strip-open { padding: 4px 9px; font-size: 11px; }

/* Discarded attempts stay visible but are clearly not the shipped asset. */
.card.discarded { opacity: .45; }
.card.discarded:hover { opacity: .75; }
.card.discarded .thumb { filter: grayscale(.6); }
.card.shipped { border-color: var(--good); box-shadow: 0 0 0 2px #2f9e6b55; }
.discard-mark, .ship-mark, .promoted-mark {
  position: absolute;
  top: 7px;
  right: 7px;
  width: 25px;
  height: 25px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  font-size: 14px;
  font-weight: 900;
  pointer-events: none;
}
.discard-mark { border: 2px solid #ff5f6d; background: #2b1214e0; color: #ff5f6d; }
.ship-mark { border: 2px solid var(--good); background: #10251be0; color: var(--good); }
/* Same green circled tick as a shipped asset: this node has a root now. */
.promoted-mark { border: 2px solid var(--good); background: #10251be0; color: var(--good); }

.io-section { background: #14171c; }
.io-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.io-cell { margin: 0; display: grid; gap: 5px; align-content: start; }
.io-cell figcaption {
  color: var(--dim);
  font: 700 10px/1 ui-monospace, monospace;
  letter-spacing: 1.2px;
}
.io-cell img {
  width: 100%;
  max-height: 190px;
  object-fit: contain;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: #0b0d10;
  cursor: zoom-in;
}
.io-blank {
  display: grid;
  place-items: center;
  height: 96px;
  border: 1px dashed var(--line);
  border-radius: 6px;
  color: var(--dim);
  font-size: 11px;
}
.io-cell small { color: var(--dim); font-size: 10px; line-height: 1.3; }

/* The entity drawer's opening statement: the crop against what the polish work
   made of it. Taller than a stage's input/output pair, because this is the
   comparison the drawer is opened for rather than one step's evidence. */
.before-after { border-top: 2px solid var(--accent); }
.before-after .io-pair { gap: 12px; margin-top: 10px; }
.before-after .io-cell img { max-height: 260px; }
.before-after .io-cell small { text-align: center; }
.before-after .drawer-action { margin-top: 12px; }
.box.ship { border-left-color: var(--good); color: #bcebd3; }
.box.discard { border-left-color: var(--bad); color: #f3b3b3; }
.badge.attempt { background: #2a2333; color: #d9c9ff; }

/* Pinned overseer strip: the whole agentic polish context, from any node. */
.overseer-strip {
  position: sticky;
  top: 0;
  z-index: 3;
  background: linear-gradient(#1d1930, #191c22);
  border-bottom: 1px solid #4a3d70;
}
/* Wraps rather than squeezing: the crop strip carries two controls beside its
   heading, and `flex: 1` alone crushed the title to one letter per line. */
.strip-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.strip-head h3 { margin: 0; flex: 1 0 auto; white-space: nowrap; }
.step-strip {
  display: flex;
  align-items: center;
  gap: 4px;
  overflow-x: auto;
  padding: 10px 2px 4px;
}
.step-chip {
  display: grid;
  justify-items: center;
  gap: 2px;
  flex: 0 0 auto;
  width: 74px;
  padding: 6px 4px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #14171c;
  color: var(--muted);
  cursor: pointer;
  font: inherit;
}
.step-chip:hover { border-color: var(--accent); }
.step-chip.active { border-color: #a98df0; background: #241d38; color: var(--text); }
.step-chip.done { border-left: 3px solid var(--good); }
.step-chip.error, .step-chip.critic-rejected, .step-chip.stopped { border-left: 3px solid var(--bad); }
.step-chip img, .step-blank {
  width: 56px;
  height: 42px;
  object-fit: contain;
  border-radius: 4px;
  background: #0b0d10;
}
.step-label { font-size: 11px; font-weight: 800; letter-spacing: .4px; }
.step-sub { font-size: 9px; text-align: center; line-height: 1.15; color: var(--dim); }
.step-arrow { flex: 0 0 auto; color: #6c5fa0; font-size: 12px; }
.badge.step { background: #241d38; color: #d7c8ff; }

#drawer .drawer-fold {
  margin: 0;
  border: 0;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
  background: transparent;
}
#drawer .drawer-fold > summary {
  padding: 13px 16px;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: .8px;
}
#drawer .drawer-fold[open] > summary { color: var(--text); }
#drawer .drawer-fold .fold-body { padding: 0 16px 14px; }
#drawer .drawer-fold .drawer-section { padding: 12px 0 0; border: 0; }

@media (max-width: 900px) {
  #drawer { width: var(--drawer-w, 340px); }
  .row, .row.thirds { grid-template-columns: 1fr; }
  #topbar .brand { display: none; }
}

/* Animate stage */
.card.animate { border-color: #2f6b5a; }
.card.animate.selected { border-color: var(--accent); }
.card.animate .thumb.checkered,
.frame-strip img,
video.checkered {
  background-image:
    linear-gradient(45deg, #3a3f46 25%, transparent 25%),
    linear-gradient(-45deg, #3a3f46 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, #3a3f46 75%),
    linear-gradient(-45deg, transparent 75%, #3a3f46 75%);
  background-size: 16px 16px;
  background-position: 0 0, 0 8px, 8px -8px, -8px 0;
}
.drawer-video { width: 100%; border-radius: 10px; border: 1px solid var(--line); background: #12151a; }
.frame-strip {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  padding-bottom: 8px;
}
.frame-strip img {
  height: 76px;
  flex: 0 0 auto;
  border-radius: 6px;
  border: 1px solid var(--line);
  cursor: zoom-in;
}
.pair { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.pair figure { margin: 0; }
.pair figcaption { margin-top: 6px; font-size: 12px; color: var(--muted); }
.swatch {
  display: inline-block;
  width: 11px;
  height: 11px;
  border-radius: 3px;
  border: 1px solid var(--line);
  vertical-align: middle;
}
.drawer-warn { color: #f0c674; font-size: 13px; }
.field.dim { opacity: 0.45; }
.modal-note { margin: 0 0 12px; font-size: 12px; color: var(--muted); line-height: 1.5; }

/* Animate modal keyframes */
.keyframes { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-bottom: 6px; }
.keyframe {
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 12px;
  background: rgba(255, 255, 255, 0.02);
}
.keyframe h3 {
  margin: 0 0 10px;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 1.1px;
  text-transform: uppercase;
  color: var(--muted);
}
.keyframe-preview {
  aspect-ratio: 1;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: #12151a;
  display: grid;
  place-items: center;
  overflow: hidden;
  margin-bottom: 12px;
}
.keyframe-preview img { width: 100%; height: 100%; object-fit: contain; }
.keyframe-preview img:not([src]) { visibility: hidden; }
.keyframe .field { margin-bottom: 10px; }
.keyframe .field:last-child { margin-bottom: 0; }

/* Static tail trimming */
.trim-bar {
  display: flex;
  height: 26px;
  border-radius: 6px;
  overflow: hidden;
  border: 1px solid var(--line);
  margin: 10px 0;
  font-size: 11px;
  font-weight: 700;
}
.trim-keep {
  background: #2f6b5a;
  color: #cdf5e7;
  display: grid;
  place-items: center;
  min-width: 60px;
}
.trim-cut { background: repeating-linear-gradient(45deg, #3a2b2b, #3a2b2b 5px, #2c2222 5px, #2c2222 10px); }

/* Reprocess sliders */
.field.slider > span { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.field.slider > span b {
  font-variant-numeric: tabular-nums;
  color: var(--accent);
  font-weight: 700;
}
.field.slider input[type='range'] {
  width: 100%;
  accent-color: var(--accent);
  padding: 0;
  margin: 4px 0 2px;
}

/* Inpaint side panel */
#animate-modal.with-side { grid-auto-flow: column; gap: 16px; justify-content: center; align-items: center; }
.sheet.side { width: min(390px, 100%); }
.keyframe-actions { display: flex; gap: 8px; margin-bottom: 10px; }
button.small { padding: 5px 10px; font-size: 11px; }
.keyframe-flag {
  margin: 0 0 10px;
  padding: 7px 9px;
  border-radius: 6px;
  background: #2b2416;
  color: #e5c98a;
  font-size: 11px;
  line-height: 1.45;
}
.keyframe .field input:disabled, .keyframe .field select:disabled { opacity: 0.4; }
.inpaint-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 16px; }
.inpaint-pair figure { margin: 0; }
.inpaint-pair figcaption { margin-top: 5px; font-size: 11px; color: var(--muted); text-align: center; }
.inpaint-pair img, #inpaint-result-slot {
  width: 100%;
  aspect-ratio: 1;
  object-fit: contain;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: #12151a;
}
#inpaint-result-slot { display: grid; place-items: center; }
.inpaint-empty { color: var(--dim); font-size: 11px; }

/* ── tabs ──────────────────────────────────────────────────────────────── */
#tabstrip {
  display: flex;
  flex: none;
  align-items: center;
  gap: 4px;
  height: 40px;
  padding: 0 14px;
  border-bottom: 1px solid var(--line);
  background: var(--panel);
}
.tab {
  padding: 9px 13px;
  border: 0;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  background: transparent;
  color: var(--muted);
  font-weight: 700;
}
.tab:hover { color: var(--fg); }
.tab.active { color: var(--fg); border-bottom-color: var(--accent); }
.tab-actions { display: flex; align-items: center; gap: 9px; }
/* A pressed toggle, distinct from the primary action buttons. */
.tab-actions button.active { border-color: var(--accent); color: var(--accent); }
.tab-actions.hidden { display: none; }

/* The root strip: every screenshot in the project, with its live status, always
   on screen. The board camera can be anywhere — a root must still be one click
   away, and its progress readable while another root is focused. */
#root-strip {
  display: flex;
  flex: none;
  align-items: stretch;
  gap: 8px;
  padding: 8px 14px;
  overflow-x: auto;
  border-bottom: 1px solid var(--line);
  background: var(--panel);
}
#root-strip.hidden { display: none; }
.root-tab {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 11px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--panel-2);
  color: var(--muted);
  cursor: pointer;
  white-space: nowrap;
}
.root-tab:hover { border-color: #56606e; color: var(--fg); }
.root-tab.focused { border-color: var(--accent); color: var(--fg); background: #2a2416; }
.root-tab.busy { border-color: var(--accent); }
.root-tab img {
  width: 34px;
  height: 24px;
  border-radius: 3px;
  object-fit: cover;
  background: #0e1013;
}
.root-tab .root-tab-name { font-size: 12px; font-weight: 700; }
.root-tab .root-tab-meta { color: var(--dim); font: 10px ui-monospace, monospace; }
.root-tab .spinner {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
  animation: pulse 1.2s infinite ease-in-out;
}
#root-strip .empty-note { color: var(--dim); font-size: 12px; align-self: center; }

/* ── group and root regions ────────────────────────────────────────────── */
/* pointer-events must stay off the backdrop, or it swallows pan, marquee and
   drag over the empty parts of a group. The header opts back in. */
.region {
  position: absolute;
  pointer-events: none;
  border-radius: 16px;
  background: #ffffff03;
}
.region.divided { border-left: 4px dashed #4a5361; }
.region-head {
  position: absolute;
  top: 14px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 14px;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: var(--panel);
  pointer-events: auto;
  cursor: default;
  white-space: nowrap;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 1.1px;
  text-transform: uppercase;
  /* Heads are wider than the narrow bands of collapsed roots, so they overlap.
     Painting order alone would hand every overlap to the root further right;
     these layers hand it to the head being pointed at, and above all to the
     open root's, whose runs must always be reachable. */
  z-index: 1;
}
.region-head:hover,
.region-head:focus-within { z-index: 2; }
.region-head.expanded { z-index: 3; }
.region-head.expanded:hover,
.region-head.expanded:focus-within { z-index: 4; }
/* Bounded, so one long title cannot drag a head across its neighbours. */
.region-head .region-name {
  flex: 0 1 auto;
  max-width: 240px;
  overflow: hidden;
  color: var(--fg);
  text-overflow: ellipsis;
}
/* Kept inside its own band, so it can never sit over a neighbour's buttons. */
.region-head.collapsed {
  max-width: calc(100% - 24px);
  gap: 5px;
  padding: 4px 10px;
  font-size: 11px;
  letter-spacing: 0.8px;
}
.region-head.collapsed > * { flex: 0 0 auto; }
.region-head.collapsed .region-name { flex: 0 1 auto; min-width: 56px; max-width: 150px; }
.region-head.collapsed .count,
.region-head.collapsed .root-state { font-size: 10px; }
.region-head.collapsed button { padding: 2px 6px; font-size: 10px; }
.region-head .count {
  padding: 1px 7px;
  border-radius: 9px;
  background: var(--panel-2);
  color: var(--muted);
  font-size: 11px;
  letter-spacing: 0;
}
.region-head input {
  width: 190px;
  border-color: var(--accent);
  background: transparent;
  font-weight: 800;
  letter-spacing: 0;
  text-transform: none;
}
.region-head button { padding: 2px 8px; font-size: 11px; letter-spacing: 0; text-transform: none; }
.region-runs { display: flex; align-items: center; gap: 5px; }
.run-chip {
  padding: 2px 8px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--panel-2);
  color: var(--muted);
  font: 11px ui-monospace, monospace;
  letter-spacing: 0;
  text-transform: none;
  cursor: pointer;
}
.run-chip:hover { border-color: #56606e; color: var(--fg); }
.run-chip.active { border-color: var(--accent); color: var(--fg); }
.run-chip.error, .run-chip.done-with-errors { border-color: #72383d; color: #f2c5c8; }

/* A root's own status, so a column the board is not streaming still reads
   truthfully while its extraction runs. */
.root-state {
  padding: 1px 8px;
  border: 1px solid var(--line);
  border-radius: 9px;
  color: var(--muted);
  font-size: 11px;
  letter-spacing: 0;
  text-transform: none;
}
.root-state.running { border-color: var(--accent); color: var(--accent); }
.root-state.done { border-color: var(--good); color: var(--good); }
.root-state.error, .root-state.stopped, .root-state.done-with-errors {
  border-color: var(--bad);
  color: #f2c5c8;
}
.card .meta .root-state { border: 0; padding: 0; }
/* The collapsed screenshot is the way in, so make that legible. */
.card.rootcard { cursor: pointer; }
.card.rootcard:hover { border-color: var(--accent); }
.card.rootcard.working { border-color: var(--accent); }

/* ── marquee ───────────────────────────────────────────────────────────── */
/* A child of the board, not the world, so the camera transform never scales it. */
.board-marquee {
  position: absolute;
  z-index: 6;
  border: 1px solid var(--accent);
  background: #ffb52e18;
  pointer-events: none;
}

/* ── concept cards ─────────────────────────────────────────────────────── */
.card.upload { border-color: #5c6a7d; }
.card.generation, .card.revision { border-color: #3f6f9e; }
.card.generation.done, .card.revision.done { border-color: #66a8e0; }
.card.generation.error, .card.revision.error,
.card.generation.stopped, .card.revision.stopped { border-color: var(--bad); }
.card.pinned .meta::after {
  content: '📌';
  margin-left: auto;
  font-size: 10px;
  opacity: .75;
}

/* Backstop: nothing in the drawer may exceed its width, whatever markup a
   panel emits. A bare <pre> defaults to `white-space: pre`, which turns one long
   prompt into a page-wide horizontal scroll. */
#drawer-body img { max-width: 100%; }
#drawer-body pre { white-space: pre-wrap; overflow-wrap: anywhere; }
/* Long unbroken strings — a pasted URL, a slug, a 60-character asset name —
   would otherwise push the panel wider than its 420px. */
#drawer-body, #drawer-body li, #drawer-body p { min-width: 0; overflow-wrap: anywhere; }

/* Groups the asset's own metadata apart from the run's settings in the polish
   dialog, so it reads as "what this asset is" then "what to do to it". */
#polish-asset-fields {
  margin: 0 0 15px;
  padding: 12px 14px 2px;
  border: 1px solid var(--line);
  border-radius: 8px;
}
#polish-asset-fields legend {
  padding: 0 6px;
  color: var(--muted);
  font-size: 11px;
  letter-spacing: 1px;
  text-transform: uppercase;
}
#polish-replace-note:empty { display: none; }
.field.hidden { display: none; }

/* ── multi-selection bar in the drawer ─────────────────────────────────── */
.selection-bar {
  position: sticky;
  top: 0;
  z-index: 3;
  border-bottom: 1px solid #5b4d29;
  background: linear-gradient(#2a2416, #191c22);
}
.selection-bar h3 { margin: 0 0 8px; font-size: 12px; text-transform: uppercase; letter-spacing: 1px; }
.selection-bar .actions { display: flex; flex-wrap: wrap; gap: 7px; }

/* ── reference rows in the generate modal ──────────────────────────────── */
.ref-row {
  display: grid;
  grid-template-columns: 64px 1fr;
  gap: 10px;
  align-items: center;
  margin-bottom: 9px;
}
.ref-row img {
  width: 64px;
  height: 48px;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: #0e1013;
  object-fit: contain;
}
.ref-row .ref-name { color: var(--muted); font-size: 11px; }
/* Not inside a .field, so it needs its own full-width rule. */
.ref-row .ref-label { width: 100%; margin-top: 3px; }
.row { display: flex; gap: 12px; }
.row > .field { flex: 1; }

/* ── asset debugging ───────────────────────────────────────────────────────── */
.card.session { border-color: #5b7f8f; }
.card.session .task-preview {
  place-items: start stretch;
  overflow: hidden;
  color: var(--fg);
  font-size: 12px;
  line-height: 1.45;
  text-align: left;
  white-space: pre-wrap;
}
.card.reference { border-color: #687485; }
.drawer-img.checkered {
  background-image:
    linear-gradient(45deg, #3a3f46 25%, transparent 25%),
    linear-gradient(-45deg, #3a3f46 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, #3a3f46 75%),
    linear-gradient(-45deg, transparent 75%, #3a3f46 75%);
  background-size: 16px 16px;
  background-position: 0 0, 0 8px, 8px -8px, -8px 0;
}
.debug-strip { display: flex; flex-wrap: wrap; gap: 10px; }
.debug-strip figure { width: 108px; margin: 0; }
.debug-strip img {
  display: block;
  width: 108px;
  height: 74px;
  object-fit: contain;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--panel-2);
  cursor: zoom-in;
}
.debug-strip figcaption {
  margin-top: 4px;
  overflow: hidden;
  color: var(--fg);
  font-size: 11px;
  line-height: 1.35;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.debug-strip figcaption span { color: var(--dim); font-family: ui-monospace, monospace; }

/* The session picker. Scrolls inside the dialog rather than growing it, so the
   task field and the submit button stay reachable however many roots exist. */
.pick-list {
  max-height: 210px;
  overflow-y: auto;
  padding: 8px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel-2);
}
.pick-list.tall { max-height: 330px; }
.pick {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px;
  border: 1px solid transparent;
  border-radius: 8px;
  cursor: pointer;
}
.pick:hover { border-color: var(--line); }
.pick:has(input:checked) { border-color: var(--accent); background: #ffb52e12; }
/* `.field input` sizes text inputs to the full row; a checkbox inside a picker
   has to opt out of that or it eats the whole label. */
.pick input {
  flex: none;
  width: auto;
  padding: 0;
  border: 0;
  accent-color: var(--accent);
}
.pick img {
  flex: none;
  width: 68px;
  height: 46px;
  object-fit: contain;
  border-radius: 5px;
  background: #12151a;
}
.pick span { min-width: 0; flex: 1 1 auto; display: block; text-align: left; }
.pick strong { display: block; overflow: hidden; font-size: 12px; text-overflow: ellipsis; white-space: nowrap; }
.pick small { color: var(--dim); font-size: 11px; }
.pick.tile { flex-direction: column; align-items: stretch; gap: 5px; text-align: center; }
.pick.tile img { width: 100%; height: 62px; }
.pick.tile input { align-self: center; }
.pick-group + .pick-group { margin-top: 12px; }
.pick-group h4 { margin: 0 0 6px; font-size: 12px; }
.pick-run { margin-bottom: 10px; }
.pick-run-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 5px;
  color: var(--dim);
  font: 11px ui-monospace, monospace;
}
.pick-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); gap: 8px; }

/* Polished and raw are two versions of one extraction, not two kinds of session:
   both tabs stay ticked while you move between them, and the count says so, so a
   pick made on the tab you are not looking at is never quietly forgotten. */
.pick-tabs { display: flex; align-items: center; gap: 6px; margin: 6px 0; }
.pick-tab {
  padding: 4px 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--panel-2);
  color: var(--dim);
  font-size: 12px;
  cursor: pointer;
}
.pick-tab:hover { color: var(--fg); }
.pick-tab.active { border-color: var(--accent); color: var(--accent); background: #ffb52e12; }
.pick-count { margin-left: auto; color: var(--dim); font: 11px ui-monospace, monospace; }
.field-head { display: flex; align-items: baseline; gap: 10px; }
.field-head .pick-count { font-style: normal; }
.pick-variant.hidden { display: none; }

/* A linked session is one row that expands into the assets it generated: the
   link and the assets are ticked separately, because a session's code is worth
   borrowing whether or not it drew anything. */
.link-group + .link-group { margin-top: 14px; border-top: 1px solid var(--line); padding-top: 12px; }
.link-head { align-items: flex-start; }
.link-task {
  margin: 2px 0 8px 28px;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.link-record + .link-record { margin-top: 12px; border-top: 1px solid var(--line); padding-top: 12px; }
.link-record-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.link-record summary { cursor: pointer; color: var(--dim); font-size: 12px; }

/* Tool descriptions in a run form. Sixteen of them for the debug agent, each a
   paragraph long: as a flat list the last few sat below the fold of a dialog
   that already scrolls, so the group gets its own scroll and every prompt
   collapses to its name. Closed is the default — you come here to change one. */
details > summary > .count {
  margin-left: 4px;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--panel-2);
  color: var(--dim);
  font: 10px ui-monospace, monospace;
  font-style: normal;
}

.prompt-scroll {
  max-height: 52vh;
  overflow-y: auto;
  padding: 2px 8px 2px 2px;
  margin-top: 4px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel-2);
}
.prompt-scroll > .field + .prompt-item { margin-top: 10px; }
.prompt-item {
  margin: 6px 4px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--panel);
}
.prompt-item > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 7px 10px;
  color: var(--fg);
  font: 12px ui-monospace, SFMono-Regular, monospace;
  cursor: pointer;
  list-style: none;
}
.prompt-item > summary::-webkit-details-marker { display: none; }
.prompt-item > summary::after {
  content: 'edit';
  color: var(--dim);
  font-size: 11px;
}
.prompt-item[open] > summary {
  border-bottom: 1px solid var(--line);
  color: var(--accent);
}
.prompt-item[open] > summary::after { content: 'close'; }
.prompt-item:hover > summary { color: var(--accent); }
.prompt-item > textarea {
  display: block;
  width: calc(100% - 20px);
  margin: 10px;
}
.prompt-item > small {
  display: block;
  margin: -4px 10px 10px;
  color: var(--dim);
  font-size: 11px;
}

/* The call happening right now, at the end of the transcript. Given its own
   colour and a pulse because it is the one card in the log that is not history —
   everything above it has already happened. */
.flow-turn.active-call {
  border-color: #3d4450 #3d4450 #3d4450 var(--accent);
  border-left-width: 3px;
  background: #ffb52e0a;
}
.flow-turn.active-call .label { color: var(--accent); }
.active-head { display: flex; align-items: baseline; gap: 10px; margin-top: 6px; flex-wrap: wrap; }
.active-tool {
  font: 12px ui-monospace, SFMono-Regular, monospace;
  color: var(--accent);
}
.active-tool::before {
  content: '';
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-right: 7px;
  border-radius: 50%;
  background: var(--accent);
  animation: active-pulse 1.4s ease-in-out infinite;
}
@keyframes active-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }
@media (prefers-reduced-motion: reduce) {
  .active-tool::before { animation: none; }
}
.active-sub {
  margin: 8px 0 0;
  padding: 0;
  list-style: none;
  border-left: 1px solid var(--line);
}
.active-sub li {
  display: flex;
  gap: 8px;
  padding: 3px 0 3px 10px;
  font-size: 11px;
  color: var(--dim);
}
.active-sub li code { flex: none; color: var(--fg); font-family: ui-monospace, monospace; }
.active-sub li span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.active-sub li.result code { color: var(--dim); }
.active-sub li.failed code { color: var(--bad); }
.active-sub li:last-child code { color: var(--accent); }

/* The agent's own account of why it stopped — the closest thing to a conclusion
   a session now has, so it reads as a statement rather than as a field. */
.drawer-section.ending { border-left: 2px solid var(--good); }
.drawer-section.ending p { font-size: 13.5px; }

/* A turn's thinking, inline in the transcript. Marked apart from the tool cards
   without being a separate list: what the agent thought only means something
   next to what it then did. */
.flow-turn.thought-turn {
  border-style: dashed;
  border-color: #3d4450;
  background: transparent;
}
.flow-turn.thought-turn .label { color: var(--dim); }

/* Thinking and prose, each its own block in the stream — the same two things
   the extraction transcripts show, told apart the same way: a summary of
   thought and a line the agent meant for a reader are not the same claim. */
.flow-turn.block-turn { border-left-width: 3px; }
.flow-turn.block-turn .block-text {
  margin: 6px 0 0;
  font-size: 12.5px;
  line-height: 1.5;
  white-space: pre-wrap;
}
.flow-turn.block-turn.thinking {
  border-color: #3d4450 #3d4450 #3d4450 #5c4f86;
  background: #171622;
}
.flow-turn.block-turn.thinking .label { color: #c3b3f0; }
.flow-turn.block-turn.thinking .block-text { color: var(--muted); font-style: italic; }
.flow-turn.block-turn.said {
  border-color: #3d4450 #3d4450 #3d4450 #3f6a7d;
  background: #141b20;
}
.flow-turn.block-turn.said .label { color: #9fd0e2; }
/* Carrying a finished session on. Set apart from the action row above it: this
   one takes an instruction before it will do anything. */
.continue-panel {
  margin-top: 14px;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #141b20;
}
.continue-panel h4 { margin: 0 0 4px; font-size: 13px; }
.continue-panel textarea {
  width: 100%;
  margin: 8px 0;
  padding: 8px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--panel-2);
  color: var(--fg);
  font: inherit;
  font-size: 12.5px;
  resize: vertical;
}
.continue-calls {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-right: 10px;
  color: var(--dim);
  font-size: 12px;
}
.continue-calls input {
  width: 74px;
  padding: 4px 6px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--panel-2);
  color: var(--fg);
}
/* What a reader asked for, in the transcript where they asked for it. */
.flow-turn.note-turn {
  border-color: #3d4450 #3d4450 #3d4450 var(--accent);
  border-left-width: 3px;
  background: #1d1a12;
}
.flow-turn.note-turn .label { color: var(--accent); }
/* What the user told the agent (Papa, a Composer, a debug session), where they told it. */
.flow-turn.user-turn {
  border-color: #3d4450 #3d4450 #3d4450 #8ab4f8;
  border-left-width: 3px;
  background: #121a24;
}
.flow-turn.user-turn .label { color: #8ab4f8; }
.flow-turn.user-turn .block-text { white-space: pre-wrap; }

/* Still being written: the caret says the text is not final, and goes when the
   record lands and replaces the card. */
.flow-turn.block-turn.streaming .block-text::after {
  content: '▌';
  margin-left: 2px;
  color: var(--accent);
  animation: pulse 1.1s infinite ease-in-out;
}
.flow-turn .said {
  margin: 6px 0 0;
  color: var(--fg);
  font-size: 12.5px;
}
.flow-turn details.reasoning { margin-top: 8px; }
.flow-turn details.reasoning summary {
  cursor: pointer;
  color: var(--dim);
  font: 10px ui-monospace, SFMono-Regular, monospace;
}
.flow-turn details.reasoning p {
  margin: 6px 0 0;
  padding-left: 10px;
  border-left: 1px solid var(--line);
  color: var(--dim);
  font-size: 12px;
  white-space: pre-wrap;
}

/* ── the debug flow ────────────────────────────────────────────────────────── */
.card.render { border-color: #5a7f6a; }
.card.render.error { border-color: var(--bad); }
.region-head.running { border-color: var(--accent); }
.region-head.running .region-name::before {
  content: '';
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-right: 7px;
  border-radius: 50%;
  background: var(--accent);
  animation: pulse 1.4s infinite ease-in-out;
}
.debug-strip figure[data-goto-render] { cursor: pointer; }
.debug-strip figure[data-goto-render]:hover img { border-color: var(--accent); }
.debug-strip .io-blank {
  display: grid;
  place-items: center;
  width: 108px;
  height: 74px;
  border: 1px solid #72383d;
  border-radius: 6px;
  color: var(--dim);
  font-size: 11px;
}

.flow-log { display: flex; flex-direction: column; gap: 10px; }
.flow-turn {
  padding: 9px 10px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--panel-2);
}
.flow-turn.refused { border-color: #72383d; }
.flow-turn-head { display: flex; align-items: baseline; gap: 8px; }
.flow-turn-head .label { font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; }
.flow-turn-head .sub { margin-left: auto; color: var(--dim); font: 11px ui-monospace, monospace; }
.flow-turn p { margin: 6px 0 0; font-size: 12px; }
.flow-shot {
  display: block;
  width: 100%;
  margin-top: 8px;
  border-radius: 6px;
  cursor: zoom-in;
}
/* An image call's pictures side by side — before, mask and after; references and
   result — each captioned with its part, on a checker so transparency shows. The
   one still taking shape (an inpaint's mask so far) is outlined in the live colour. */
.tool-pictures { display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: 8px; margin-top: 8px; }
.tool-picture { margin: 0; min-width: 0; }
.tool-picture img {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  object-fit: contain;
  border: 1px solid var(--line);
  border-radius: 6px;
  cursor: zoom-in;
  background-image:
    linear-gradient(45deg, #3a3f46 25%, transparent 25%),
    linear-gradient(-45deg, #3a3f46 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, #3a3f46 75%),
    linear-gradient(-45deg, transparent 75%, #3a3f46 75%);
  background-size: 16px 16px;
  background-position: 0 0, 0 8px, 8px -8px, -8px 0;
}
.tool-picture.live img { border-color: var(--accent); }
.tool-picture figcaption { margin-top: 3px; overflow: hidden; color: var(--dim); font-size: 10px; text-align: center; text-overflow: ellipsis; white-space: nowrap; }
.tool-given { margin-top: 6px; }
.tool-given-label { color: var(--dim); font-size: 10px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; }
.tool-given p { max-height: 9em; margin: 2px 0 0; overflow: auto; white-space: pre-wrap; }
.prompt-view.small { max-height: 160px; font-size: 11px; }

.findings { display: flex; flex-direction: column; gap: 9px; margin-top: 10px; }
.finding {
  padding: 9px 10px;
  border: 1px solid var(--line);
  border-left-width: 3px;
  border-radius: 8px;
  background: var(--panel-2);
}
.finding.confirmed { border-left-color: var(--good); }
.finding.likely { border-left-color: var(--accent); }
.finding.guess { border-left-color: #72383d; }
.finding-head { display: flex; align-items: center; gap: 8px; }
.finding p { margin: 5px 0 0; font-size: 12px; }
ul.plain { margin: 0; padding-left: 18px; font-size: 12px; }
ul.plain li { margin-top: 4px; }

/* Generated assets: the inpaint result and the mask that made it. */
.card.generated.image { border-color: #8a6fb5; }
.card.generated.mask { border-color: #6b7480; }
.card.generated.error { border-color: var(--bad); }
.io-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.io-pair figure { margin: 0; }
.io-pair img {
  display: block;
  width: 100%;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--panel-2);
  cursor: zoom-in;
}
.io-pair figcaption {
  margin-top: 4px;
  color: var(--dim);
  font: 11px ui-monospace, monospace;
  text-align: center;
}
.io-pair .io-blank {
  display: grid;
  place-items: center;
  min-height: 90px;
  border: 1px dashed var(--line);
  border-radius: 6px;
  color: var(--dim);
  font-size: 11px;
  text-align: center;
}
.io-pair img.checkered {
  background-image:
    linear-gradient(45deg, #3a3f46 25%, transparent 25%),
    linear-gradient(-45deg, #3a3f46 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, #3a3f46 75%),
    linear-gradient(-45deg, transparent 75%, #3a3f46 75%);
  background-size: 14px 14px;
  background-position: 0 0, 0 7px, 7px -7px, -7px 0;
}
.debug-strip figure[data-goto-generated] { cursor: pointer; }
.debug-strip figure[data-goto-generated]:hover img { border-color: var(--accent); }

/* A failed session says so on its band header, and offers a way on. */
.region-head .count.bad { background: #3a2226; color: #f2c5c8; }
.region-head button.resume { border-color: var(--accent); color: var(--accent); }
.drawer-section .actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.drawer-section .actions button:disabled { opacity: 0.45; cursor: not-allowed; }

/* An inpaint's before-and-after, coloured the way a diff is: the frame carries
   the hue, never the image. Tinting the artwork would corrupt exactly the thing
   the pair exists to let you judge — a warm cast you added is indistinguishable
   from a warm cast the image model introduced. */
.io-pair.edit .before img { border-color: #8c4a4a; box-shadow: 0 0 0 3px #ec666618; }
.io-pair.edit .after img { border-color: #3f8560; box-shadow: 0 0 0 3px #49cc8d18; }
.io-pair.edit .before figcaption { color: #e9a3a3; }
.io-pair.edit .after figcaption { color: #86dcb4; }

/* A `replace` as a diff. Monospace, one line per row, with the sign in its own
   gutter so a line that begins with a minus in the code cannot be mistaken for a
   removal marker. */
.diff {
  margin-top: 8px;
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: #14171b;
  font: 11px/1.55 ui-monospace, SFMono-Regular, Menlo, monospace;
}
.diff-line { display: flex; gap: 8px; padding: 1px 8px 1px 0; white-space: pre; }
.diff-line .sign {
  flex: none;
  width: 20px;
  padding-left: 6px;
  color: var(--dim);
  text-align: center;
  user-select: none;
}
.diff-line code { min-width: 0; }
.diff-line.removed { background: #3a191c; color: #f3b7b7; }
.diff-line.removed .sign { color: #d97a7a; background: #4a1f23; }
.diff-line.added { background: #16311f; color: #a9e6c4; }
.diff-line.added .sign { color: #5fbf8c; background: #1c4029; }

/* Produced assets: drawn from scratch by a sub-agent, so they read as their own
   kind rather than as a variant of an inpaint. */
.card.generated.produced { border-color: #4d7fa8; }
.card.generated.upscaled { border-color: #4f9f8a; }
.card.generated.copy { border-color: #7a7f8a; }
.card.generated.keyed { border-color: #6f9f4f; }
.card.generated.generated { border-color: #a86fb5; }
/* Dropped with delete_asset: the key is gone from the run, the record is not.
   Faded rather than removed, because how the session got here is the subject. */
.card.generated.dropped { border-style: dashed; opacity: 0.55; }
.card.generated.dropped .thumb { filter: grayscale(0.6); }
.card.generated.produced .thumb,
.card.generated.upscaled .thumb,
.card.generated.copy .thumb,
.card.generated.keyed .thumb,
.card.generated.generated .thumb,
.debug-strip img.checkered,
.drawer-img.checkered {
  background-image:
    linear-gradient(45deg, #3a3f46 25%, transparent 25%),
    linear-gradient(-45deg, #3a3f46 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, #3a3f46 75%),
    linear-gradient(-45deg, transparent 75%, #3a3f46 75%);
  background-size: 14px 14px;
  background-position: 0 0, 0 7px, 7px -7px, -7px 0;
}
.debug-strip figure.kept img { border-color: var(--good); box-shadow: 0 0 0 2px #49cc8d30; }
.debug-strip figure.kept figcaption { color: #86dcb4; }

/* A render's verdict. Severity sits on the left edge of each fault, so the shape
   of the list says how bad the render is before a word is read. */
.card.render.verdict-clean { border-color: var(--good); }
.card.render.verdict-minor { border-color: #8a8f5c; }
.card.render.verdict-major { border-color: #b8863f; }
.card.render.verdict-blocking { border-color: var(--bad); }

ul.verdict { margin: 0; padding-left: 20px; font-size: 12px; }
ul.verdict li { margin-top: 5px; }
ul.verdict.good li::marker { color: var(--good); }

.faults { display: flex; flex-direction: column; gap: 8px; }
.fault {
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-left-width: 3px;
  border-radius: 8px;
  background: var(--panel-2);
}
.fault.blocking { border-left-color: var(--bad); }
.fault.major { border-left-color: #d59b45; }
.fault.minor { border-left-color: #8a8f5c; }
.fault-head { display: flex; align-items: center; gap: 8px; }
.fault p { margin: 4px 0 0; font-size: 12px; }

.verdict-lines { margin-top: 7px; display: flex; flex-direction: column; gap: 3px; }
.verdict-line { display: flex; gap: 7px; font-size: 11px; line-height: 1.45; }
.verdict-line .mark { flex: none; width: 12px; text-align: center; }
.verdict-line.good .mark { color: var(--good); }
.verdict-line.minor .mark { color: #a8ad72; }
.verdict-line.major .mark { color: #d59b45; }
.verdict-line.blocking .mark { color: var(--bad); }

/* the reference and the target style, side by side on a root's own card */
.thumb-pair{display:flex;gap:6px;width:100%}
.thumb-pair figure{margin:0;flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}
.thumb-pair figcaption{font-size:9px;letter-spacing:.04em;text-transform:uppercase;opacity:.6;text-align:center}

/* Framed by the factory, pinned to one game's project: the project picker is
   not a choice there, and the tab strip has one tab. Both rows go; the tab
   ACTIONS stay, because those are the verbs. */
body.pinned #topbar{display:none}
/* one tab is a mode picker with one mode; two is a choice, so the strip stays */
body.pinned #tabstrip .tab[data-tab="concept"]{display:none}

/* the two pictures in the drawer, side by side and zoomable */
.pair-panel{display:flex;gap:8px;margin-top:8px}
.pair-panel figure{margin:0;flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}
.pair-panel img{width:100%;border-radius:6px;cursor:zoom-in;display:block}
.pair-panel figcaption{font-size:10px;opacity:.6;text-align:center}

/* what an asset replaces, beside what it becomes */
.was-pair{display:flex;gap:4px;width:100%}
.was-pair figure{margin:0;flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.was-pair figcaption{font-size:8.5px;letter-spacing:.05em;text-transform:uppercase;opacity:.55;text-align:center}

/* the matching decision, on each row of the extraction list */
.match-line{display:flex;gap:8px;align-items:flex-start;margin:0 0 6px;padding:6px 8px;border-radius:6px}
.match-line.replaces{background:rgba(120,180,255,.10)}
.match-line.new{background:rgba(160,160,160,.10)}
.match-line img{width:38px;height:38px;object-fit:contain;border-radius:4px;flex:none;background:rgba(0,0,0,.15)}
.match-line p{margin:2px 0 0}
.match-tally{display:flex;gap:6px;flex-wrap:wrap;margin:6px 0}
.unclaimed-list{display:flex;flex-direction:column;gap:6px}
.unclaimed{display:flex;gap:8px;align-items:center}
.unclaimed img{width:34px;height:34px;object-fit:contain;border-radius:4px;background:rgba(0,0,0,.15);flex:none}
.unclaimed p{margin:1px 0 0}

/* Interrupting a running conversation, at the foot of the transcript it belongs
   to — beside what is being said rather than in a dialog over it. */
.transcript-say{display:flex;gap:8px;padding:10px 12px;border-top:1px solid var(--line, #2a2a33);flex:none}
.transcript-say input{flex:1;min-width:0}
.transcript-say.hidden{display:none}
/* An interruption in the transcript. Deliberately not styled like the agent's
   own blocks: the point of reading one is seeing that it came from outside. */
.ts-step.interjection{border-left:3px solid var(--amber, #f9ab00)}
.ts-step.interjection .ts-label{color:var(--amber, #f9ab00)}

/* A match the inventory judged not a straight swap. Floated clear of the card's
   top edge rather than laid into it: it is the one thing on the card there is
   something to DO about, and a board with three of these should read as three
   things to do at a glance. */

/* ---- one canvas, in the side panel ----
   The picture big at the top, then everything it has ever drawn. A canvas is a
   node on the board now, so its renders are its history rather than nodes of
   their own scattered across a row. */
.canvas-stage{
  display:grid;place-items:center;padding:10px;border-radius:8px;min-height:160px;
  background:
    linear-gradient(45deg,#2a2a36 25%,transparent 25%,transparent 75%,#2a2a36 75%) 0 0/12px 12px,
    linear-gradient(45deg,#2a2a36 25%,transparent 25%,transparent 75%,#2a2a36 75%) 6px 6px/12px 12px,
    #22222c;
}
.canvas-stage img,.canvas-stage canvas{max-width:100%;max-height:46vh;object-fit:contain;display:block}
.canvas-stage img{cursor:zoom-in}
/* The live player: the script itself, running at t, over the same checker.
   `width:100%` rather than `auto` so a wider panel makes a bigger picture —
   at `auto` the canvas stopped at its own pixel size and dragging the panel
   past that changed nothing. The bitmap is untouched; only its box grows, so
   the script still draws at the size the session configured. */
/* How tall the live player may get. Short of the window on purpose: the scrub
   slider and Play sit under it, and scrubbing while watching wants both in view
   at once. Raise it here if a bigger picture is worth scrolling for. */
.canvas-live{--live-max-h:70vh}
.canvas-live .canvas-stage canvas{
  width:100%;height:auto;max-height:var(--live-max-h);
  /* Capped on BOTH axes at the canvas's own shape, so a panel wider than the
     height allows shrinks the box rather than letterboxing a small picture in
     the middle of a big checkered one. --ar is width/height, written by the
     panel because only it knows the bitmap. */
  max-width:calc(var(--live-max-h) * var(--ar, 1));
  image-rendering:auto;
}

/* Scrub or loop. Both, because they answer different questions: the slider
   finds the frame that is wrong, playing shows whether the motion reads. */
.canvas-play{display:flex;align-items:center;gap:8px;margin-top:8px}
.canvas-play input[type=range]{flex:1;min-width:0}
.canvas-play select{flex:none}
.canvas-live .canvas-stage canvas{cursor:zoom-in}

/* The full-screen viewer (canvas-viewer.js): the image lightbox's dark overlay, with zoom, pan and, for an
   animated canvas, its player. The picture sits at its own pixel size and is scaled by transform. */
.viewer{position:fixed;inset:0;z-index:80;display:grid;grid-template-rows:auto 1fr auto;background:#080a0de8;color:#e8edf3}
.viewer-bar{display:flex;align-items:center;gap:12px;padding:10px 16px;border-bottom:1px solid #ffffff14;background:#0b0f14}
.viewer-title{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.viewer-zoom{display:flex;align-items:center;gap:6px}
.viewer-zoom [data-viewer-level]{min-width:52px;text-align:center;font-variant-numeric:tabular-nums}
.viewer-stage{position:relative;overflow:hidden;cursor:grab;touch-action:none}
.viewer-stage.dragging{cursor:grabbing}
.viewer-content{position:absolute;left:0;top:0;transform-origin:0 0}
.viewer-content img,.viewer-content canvas{display:block;max-width:none;max-height:none;user-select:none}
.viewer-content.pixelated img,.viewer-content.pixelated canvas{image-rendering:pixelated}
.viewer-play{margin:0;padding:10px 16px;border-top:1px solid #ffffff14;background:#0b0f14}
.viewer-play [data-live-error]{margin:0}

.canvas-history{display:flex;flex-direction:column;gap:4px;max-height:340px;overflow:auto}
.canvas-row{
  display:flex;align-items:center;gap:8px;padding:5px 6px;
  background:none;border:1px solid transparent;border-radius:7px;
  color:inherit;font:inherit;text-align:left;cursor:pointer;width:100%;
}
.canvas-row:hover{border-color:#3a3a48}
.canvas-row.on{border-color:#f9ab00;background:rgba(249,171,0,.08)}
.canvas-row.failed{opacity:.55}
.canvas-row:disabled{cursor:default}
.canvas-row-t{flex:none;width:38px;height:38px;display:grid;place-items:center;overflow:hidden;border-radius:5px;background:#22222c}
.canvas-row-t img{max-width:100%;max-height:100%;object-fit:contain}
.canvas-row-m{min-width:0;display:flex;flex-direction:column;gap:1px}
.canvas-row-m .drawer-sub{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* the canvas the agent called the result */
.card.result{outline:2px solid #f9ab00;outline-offset:-2px}

/* ---- the inventory, as three lists ---- */
.sheet-wide{width:min(860px,94vw);max-height:88vh;overflow:auto}
.inv-lists{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px}
.inv-list h4{margin:0 0 6px;font-size:12px;letter-spacing:.04em;text-transform:uppercase;color:var(--muted)}
.inv-list ol{margin:0;padding-left:18px;display:flex;flex-direction:column;gap:6px}
.inv-list li{font-size:12.5px;line-height:1.4}
.inv-list li small{display:block;color:var(--muted)}
.inv-list.reuse li{border-left:2px solid var(--accent, #5b8def);padding-left:8px;list-style:none;margin-left:-18px}
.inv-thumb{width:44px;height:44px;object-fit:contain;vertical-align:middle;margin-right:6px;background:var(--surface-2,#1b1b22);border-radius:4px}
/* the inventory object in the transcript: one block you can open */
.ts-inventory{border:1px solid var(--line,#2a2a33);border-radius:8px;padding:10px 12px;background:var(--surface-2,#17171d)}
.ts-inventory .inv-tally{display:flex;gap:8px;flex-wrap:wrap;margin:6px 0 10px}
.ts-chat-you{border-left:3px solid var(--accent,#5b8def);padding-left:10px}
/* the picker of generated assets */
.inject-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:10px}
.inject-cell{border:1px solid var(--line,#2a2a33);border-radius:8px;padding:8px;background:none;color:inherit;text-align:left;cursor:pointer;font:inherit}
.inject-cell:hover{border-color:var(--accent,#5b8def)}
.inject-cell img{width:100%;height:90px;object-fit:contain;background:var(--surface-2,#1b1b22);border-radius:4px}
.inject-cell b{display:block;margin-top:6px;font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.inject-cell small{display:block;color:var(--muted);font-size:11px}
.inject-cell.taken{opacity:.45;cursor:default}

/* One game-wide library, with one persistent workspace below it. */
.session-map { flex: none; border-bottom: 1px solid var(--border, #303844); padding: 9px 18px; background: #171c24; }
.session-map > summary { cursor: pointer; font-size: 13px; font-weight: 600; }
.session-map #map-state { margin: 10px 0; }
.session-map #map-search { max-width: 420px; width: 100%; }
#map-assets { display: flex; gap: 16px; overflow-x: auto; max-height: 280px; margin-top: 10px; }
#map-assets figure { flex: 0 0 170px; margin: 0; font-size: 12px; overflow-wrap: anywhere; }
#map-assets img { width: 150px; height: 120px; object-fit: contain; background: #252a33; cursor: zoom-in; }
.map-selection { display: grid; gap: 8px; margin: 12px 0; }
.map-selection label { display: flex; gap: 9px; align-items: center; font-size: 12px; }
.map-selection img { width: 48px; height: 48px; object-fit: contain; background: #252a33; }
.map-selection code { color: #9ba8b9; }
.drawer-section > .preview { width: 100%; max-height: 360px; object-fit: contain; }
@media (max-width: 800px) { #topbar { flex-wrap: wrap; height: auto; min-height: 58px; padding: 8px; } #topbar .brand { font-size: 16px; } }

/* Each require_assets request remains a distinct source → crops → polish tree. */
.region.extraction-group { background: #101b2538; border: 1px solid #435364; }
.card.extracted { height: 196px; }
.card.extracted .thumb, .card.extracted .placeholder { height: 120px; }
.card.extracted .extraction-meta { display: grid; gap: 3px; padding: 6px 9px; height: 74px; align-content: center; }
.extraction-meta .label { font-size: 12px; }
.extraction-state, .extraction-counts { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 10px; }
.extraction-counts { color: var(--dim); }
.extraction-state { color: var(--muted); }
.extraction-state.stage-failed { color: var(--bad); }
.extraction-state.stage-ready, .extraction-final-note { color: var(--good); }
.extraction-state.stage-cropping, .extraction-state.stage-polishing { color: var(--accent); }
.card.extraction-root { border-color: #66a8e0; }
.card.extraction-failed { border-color: var(--bad); }
.card.extracted > .extraction-fold { position: absolute; left: 6px; top: 6px; padding: 3px 6px; background: #10151eee; font-size: 10px; }
.extraction-in-use { position: absolute; right: 6px; top: 39px; padding: 3px 6px; border-radius: 4px; background: #193b5fee; color: #c5e4ff; font-size: 10px; font-weight: 700; }
.extraction-refine textarea { width: 100%; margin-bottom: 10px; }

/* The invocation timeline stays small; full streaming lives in its own panel. */
.context-timeline { display: grid; gap: 12px; }
.context-card { display: grid; gap: 8px; width: 100%; text-align: left; padding: 16px; border: 1px solid #526379; border-radius: 10px; background: #1c2530; color: #e5eaf0; cursor: pointer; }
.context-card:hover { border-color: #9ac5e9; }
.context-card span, .context-card small { color: #a6b4c4; }
.context-card p { margin: 0; font-size: 13px; white-space: pre-wrap; overflow-wrap: anywhere; }
.context-feedback { border-left: 2px solid #80b89a; padding: 10px 14px; overflow-wrap: anywhere; }
.context-feedback p { white-space: pre-wrap; }
#context-panel { position: fixed; top: 60px; bottom: 0; left: 0; width: min(650px, 65vw); z-index: 40; display: flex; flex-direction: column; background: #111820; border-right: 1px solid #526379; box-shadow: 8px 0 28px #0007; }
#context-panel.hidden { display: none; }
.context-panel-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 18px; border-bottom: 1px solid #384555; }
#context-transcript { overflow: auto; flex: 1; padding: 18px 18px 72px; min-height: 0; overflow-anchor: none; }
#context-transcript pre { white-space: pre-wrap; overflow-wrap: anywhere; max-height: none; }
#context-bottom { position: absolute; bottom: 20px; right: 24px; border-radius: 24px; box-shadow: 0 4px 20px #0008; }
/* Guidance for the session, under the latest context's transcript. */
.context-guidance { display: grid; gap: 6px; padding: 10px 18px 14px; border-top: 1px solid #384555; background: #111820; }
.context-guidance.hidden { display: none; }
.context-guidance textarea { width: 100%; min-height: 48px; resize: vertical; font: inherit; font-size: 13px; }
.context-guidance-actions { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
/* Guidance the agent has not read yet, by the input (reskin conversations and the debug panel). */
.queued-guidance { display: grid; gap: 6px; max-height: 160px; overflow: auto; padding: 8px 12px; border-top: 1px dashed #3d4450; background: #0f151d; }
.queued-guidance.hidden { display: none; }
.queued-note { border: 1px dashed #4a5566; border-left: 3px solid #8ab4f8; border-radius: 6px; padding: 6px 10px; opacity: .85; }
.queued-note p { margin: 2px 0 0; white-space: pre-wrap; font-size: 13px; }
.queued-label { font-size: 11px; letter-spacing: .04em; text-transform: uppercase; color: #8ab4f8; }
.queued-guidance small { color: #8b98a8; font-size: 12px; }
.queued-note.missed { border-left-color: #e0a458; }
.queued-note.missed .queued-label { color: #e0a458; }
.queued-note button { margin-top: 6px; }
#context-panel:has(.context-guidance:not(.hidden)) #context-bottom { bottom: calc(120px + var(--queued-h, 0px)); }
.tool-payload { margin: -4px 0 14px; font-size: 12px; }

.context-card p { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; }

/* Session navigation and the selected context share one left-hand panel. */
#session-sidebar { position: relative; display: flex; flex: 0 0 290px; width: 290px; min-width: 0; min-height: 0; overflow: hidden; border-right: 1px solid var(--line); background: var(--panel); }
#session-sidebar.showing-context { flex-basis: min(550px, 42vw); width: min(550px, 42vw); }
#session-list-panel { display: flex; flex-direction: column; min-height: 0; width: 100%; }
.session-list-head { padding: 16px 12px 12px; border-bottom: 1px solid var(--line); }
.session-list-head strong { display: block; margin-bottom: 10px; }
#session-count { color: var(--muted); font-weight: 400; }
#session-search { width: 100%; }
#session-list { flex: 1; overflow-y: auto; min-height: 0; padding: 8px; }
.session-list-row { display: flex; position: relative; margin-bottom: 6px; border: 1px solid transparent; border-radius: 8px; }
.session-list-row.selected { border-color: var(--accent); background: #30291d; }
.session-list-row > [data-select-session], .session-list-row > [data-select-project] { flex: 1; min-width: 0; padding: 12px 28px 12px 10px; border: 0; background: transparent; text-align: left; white-space: normal; }
.session-list-row:hover { background: var(--panel-2); }
.session-list-row strong { display: block; line-height: 1.4; overflow-wrap: anywhere; }
.session-list-row small { display: block; color: var(--muted); margin-top: 6px; font-size: 11px; }
.session-list-meta { display: flex; justify-content: space-between; gap: 8px; margin-top: 8px; font-size: 11px; color: var(--muted); }
.session-kind-badge { display: inline-block; margin: 6px 6px 0 0; padding: 2px 8px; border-radius: 999px; font-size: 11px; font-weight: 600; letter-spacing: .02em; white-space: nowrap; }
.session-kind-badge.visual-demo { background: #6d4bd8; color: #fff; }
.session-kind-badge.composer { background: #0f8a6a; color: #fff; }
.session-kind-badge.flavor { background: #c2185b; color: #fff; }
.session-kind-badge.concept { background: #b26a00; color: #fff; }
.region-head .session-kind-badge { margin: 0 8px; }
.session-status.running { color: var(--accent); }
.session-status.error { color: var(--bad); }
.session-status.settled { color: var(--good); }
.session-list-delete { position: absolute; right: 2px; top: 4px; padding: 2px 6px; border-color: transparent; color: var(--dim); }
#session-sidebar #context-panel { position: relative; inset: auto; width: 100%; flex: 1; min-width: 0; min-height: 0; box-shadow: none; border: 0; z-index: auto; }
#context-title { font-size: 13px; overflow-wrap: anywhere; }
#project-cost { color: var(--fg); }
@media (max-width: 1100px) { #session-sidebar { flex-basis: 230px; width: 230px; } #drawer { width: min(var(--drawer-w, 340px), 32vw); } }

/* Integration state from the embedding Reskin engine. */
.integration-badge { font-size: 11px; padding: 1px 6px; border-radius: 999px; border: 1px solid currentColor; white-space: nowrap; }
.integration-badge.integrated { color: var(--good); }
.integration-badge.active, .integration-badge.queued { color: var(--accent); }
.integration-badge.pending { color: var(--bad); }
.integration-badge.review { color: var(--muted); }

/* Embedded in the Reskin engine: no header of its own. Only the status line stays, as a toast. */
body.embedded #topbar {
  position: fixed;
  right: 16px;
  bottom: 14px;
  z-index: 60;
  height: auto;
  padding: 0;
  border: 0;
  background: none;
  pointer-events: none;
}
body.embedded #topbar > :not(#status) { display: none; }
body.embedded #status:not(:empty) {
  padding: 6px 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--panel);
  box-shadow: 0 8px 24px #0006;
  pointer-events: auto;
}

.project-group { margin-bottom: 14px; }
.project-group-head { position: sticky; top: -8px; z-index: 1; padding: 8px 6px 6px; background: var(--panel); color: var(--accent); font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; border-bottom: 1px solid var(--line); margin-bottom: 6px; }
.project-group-head span { color: var(--muted); font-weight: 400; }
/* The user's guidance images: small in the queued tray, larger in the transcript where the agent read them. */
.queued-thumbs { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }
.queued-thumbs img { height: 44px; border-radius: 4px; cursor: zoom-in; }
.guidance-images { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 6px; }
.guidance-image { margin: 0; }
.guidance-image img { display: block; max-width: 160px; max-height: 120px; border-radius: 6px; cursor: zoom-in; }
.guidance-image figcaption { font-size: 11px; color: #8ab4f8; margin-top: 2px; }
/* The debug panel's guidance images being attached, above the box. */
.guidance-thumbs { display: flex; flex-wrap: wrap; gap: 6px; }
.guidance-thumbs.hidden { display: none; }
.guidance-thumb { position: relative; margin: 0; width: 64px; }
.guidance-thumb img { display: block; width: 64px; height: 52px; object-fit: cover; border-radius: 4px; border: 1px solid #384555; }
.guidance-thumb button { position: absolute; top: 2px; right: 2px; width: 18px; height: 18px; padding: 0; line-height: 16px; border-radius: 9px; background: #000a; }
.guidance-thumb figcaption { font-size: 10px; color: #8b98a8; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.guidance-attach { cursor: pointer; margin-left: auto; margin-right: 8px; }
.context-guidance.dropping { outline: 2px dashed #8ab4f8; outline-offset: -4px; }
/* A reskin collection's Session debugs (?group=reskin): each reskin's sessions under a header that folds them away. */
.session-group { margin-bottom: 8px; }
.session-group > summary { position: sticky; top: -8px; z-index: 1; display: flex; flex-direction: column; gap: 3px; padding: 8px 6px 7px 20px; background: var(--panel); border-bottom: 1px solid var(--line); cursor: pointer; list-style: none; margin-bottom: 6px; }
.session-group > summary::-webkit-details-marker { display: none; }
.session-group > summary::before { content: "▸"; position: absolute; left: 6px; top: 8px; color: var(--muted); font-size: 11px; transition: transform .12s ease; }
.session-group[open] > summary::before { transform: rotate(90deg); }
.session-group-name { color: var(--accent); font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.session-group.current .session-group-name::after { content: " · on the board"; color: var(--muted); font-weight: 400; text-transform: none; letter-spacing: 0; }
.session-group-meta { display: flex; flex-wrap: wrap; gap: 4px 10px; color: var(--muted); font-size: 11px; }
.session-group:not([open]) { margin-bottom: 2px; }

/* ---- director flow: compare canvases in the canvas panel (debug.js critiqueSection, referenceVideoHtml) ----
   A compare canvas's render beside its reference with the critic's verdict; an
   animated_compare canvas's live player beside the reference recording. */
.canvas-pair{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;align-items:start}
.canvas-pair figure{margin:0;min-width:0}
.canvas-pair figcaption{margin-top:3px;text-align:center;font-variant-numeric:tabular-nums}
.canvas-pair .canvas-stage{padding:6px;min-height:0}
.canvas-live .canvas-pair .canvas-stage canvas{max-width:100%}
.canvas-ref-crop{position:relative;width:100%;aspect-ratio:var(--ar,1);overflow:hidden}
.canvas-ref-crop video{position:absolute;display:block;max-width:none}
.canvas-row-t.wide{width:76px}
.critique h3{display:flex;align-items:center;flex-wrap:wrap;gap:6px}
.critique-verdict.matches{background:var(--good);color:#052a17}
.critique-verdict.close{background:#d59b45;color:#2a1a00}
.critique-verdict.off{background:var(--bad);color:#310c0c}
.critique-total{color:var(--muted);font:11px ui-monospace,monospace;font-weight:400}
.critique-scores{display:flex;flex-wrap:wrap;gap:6px;margin:4px 0 8px}
.critique-score{display:flex;gap:5px;align-items:baseline;padding:2px 7px;border:1px solid var(--line);border-radius:5px;font-size:11px;color:var(--muted)}
.critique-score b{color:#e8edf3;font-variant-numeric:tabular-nums}
.critique-fixed{margin:0 0 8px;font-size:12px;color:var(--good)}
.critique .fault-head code{color:var(--muted);font-size:11px}
.critique-status.new{background:#24324a;color:#bcd3ff}
.critique-status.still{background:#3a3222;color:#f0d29a}
.critique-status.worse{background:#4a2222;color:#ffb3b3}
.critique-diff{margin-top:10px}
.critique-diff summary{cursor:pointer;font-size:12px;color:var(--muted)}
.critique-diff .canvas-stage{margin-top:6px}
/* ---- end director flow compare canvases ---- */
/* director flow: the player's controls wrap in a narrow drawer instead of crushing the slider and the readout. */
.canvas-play{flex-wrap:wrap}
.canvas-play input[type=range]{flex:1 1 140px;min-width:140px}
.canvas-play [data-live-readout]{white-space:nowrap;min-width:5.5em}
/* director flow (experimental): a picture per critic issue that shows that gap. */
.gap-illustration{margin:8px 0 2px}
.gap-illustration img{display:block;width:100%;height:auto;border-radius:6px;border:1px solid rgba(255,255,255,.08);cursor:zoom-in;background:#111}
.gap-illustration figcaption{margin-top:4px}
.gap-pending{font-style:italic}
/* A debug session's sub-agents (static/debug.js subagentCard / subagentSummary): one collapsible card per spawn. */
.flow-log .subagent-card{margin:8px 0 12px;border:1px solid var(--line,#2b2f38);border-left:3px solid #7c8cff;border-radius:8px;background:color-mix(in srgb,var(--panel,#15171c) 88%,#7c8cff 12%)}
.flow-log .subagent-card.done{border-left-color:#46b37a}
.flow-log .subagent-card.failed{border-left-color:#d9534f}
.flow-log .subagent-card>summary{display:flex;gap:8px;align-items:baseline;flex-wrap:wrap;padding:8px 10px;cursor:pointer;list-style:none}
.flow-log .subagent-card>summary::-webkit-details-marker{display:none}
.flow-log .subagent-card>summary::before{content:"▸";color:var(--muted,#8b929c)}
.flow-log .subagent-card[open]>summary::before{content:"▾"}
.subagent-name{font-weight:700;font-size:12px}
.subagent-role{font-size:11px;color:var(--muted,#8b929c)}
.subagent-task{flex:1 1 220px;overflow-wrap:anywhere}
.subagent-status{font-size:11px;text-transform:uppercase;letter-spacing:.04em;color:var(--muted,#8b929c)}
.subagent-card.running .subagent-status{color:#9aa6ff;animation:subagent-pulse 1.6s ease-in-out infinite}
.subagent-meta{font-size:11px;color:var(--muted,#8b929c)}
.subagent-card .subagent-prompt{margin:0 12px 6px}
.subagent-card .subagent-prompt summary{font-size:11px;color:var(--muted,#8b929c);cursor:pointer}
.subagent-card .subagent-body{margin:4px 10px 6px 16px;padding-left:10px;border-left:1px dashed var(--line,#2b2f38)}
.subagent-card .subagent-reply{margin:0 12px 10px;padding:8px 10px;border-radius:6px;background:rgba(255,255,255,.04)}
.subagent-card .subagent-reply .label{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--muted,#8b929c)}
.subagent-thinking summary{cursor:pointer;list-style:none}
@keyframes subagent-pulse{50%{opacity:.45}}
.subagent-summary{margin:10px 0;padding:8px 10px;border:1px solid var(--line,#2b2f38);border-radius:8px}
.subagent-summary ul{margin:6px 0 0;padding-left:16px;display:grid;gap:4px;font-size:12px}
.subagent-summary li.running b{color:#9aa6ff}
.subagent-summary li.done b{color:#46b37a}
.subagent-summary li.failed b{color:#d9534f}
.subagent-summary .link{background:none;border:0;padding:0;color:inherit;cursor:pointer;text-align:left;font:inherit}
.subagent-summary .link:hover{text-decoration:underline}
/* The sub-agent dock (static/subagent-dock.js): running sub-agents stuck below a transcript, and their history. */
.subagent-dock{position:relative;flex:none;border-top:1px solid var(--line,#2b2f38);background:var(--panel,#15171c);font-size:12px;z-index:3}
.subagent-dock.hidden{display:none}
.subagent-dock-bar{display:flex;align-items:center;gap:8px;padding:6px 10px;min-height:34px}
.subagent-dock-running{display:flex;flex:1;gap:6px;overflow-x:auto;min-width:0}
.subagent-dock-idle{color:var(--muted,#8b929c)}
.subagent-chip{display:flex;align-items:center;gap:6px;flex:none;max-width:420px;padding:3px 10px;border:1px solid #7c8cff;border-radius:999px;background:color-mix(in srgb,var(--panel,#15171c) 80%,#7c8cff 20%);color:inherit;font:inherit;cursor:pointer}
.subagent-chip-dot{width:7px;height:7px;border-radius:50%;background:#9aa6ff;animation:subagent-pulse 1.6s ease-in-out infinite}
.subagent-chip-task{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:200px;color:var(--fg,#e6e8eb)}
.subagent-chip-meta{color:var(--muted,#8b929c);white-space:nowrap}
.subagent-dock-toggle{flex:none;padding:3px 10px;border:1px solid var(--line,#2b2f38);border-radius:6px;background:transparent;color:inherit;font:inherit;cursor:pointer}
.subagent-dock-history{position:absolute;left:8px;right:8px;bottom:100%;max-height:50vh;overflow:auto;margin-bottom:4px;padding:6px;border:1px solid var(--line,#2b2f38);border-radius:8px;background:var(--panel,#15171c);box-shadow:0 -6px 24px rgba(0,0,0,.4);display:grid;gap:4px}
.subagent-dock-history.hidden{display:none}
.subagent-history-row{display:grid;grid-template-columns:minmax(120px,auto) 1fr auto auto;gap:10px;align-items:baseline;padding:5px 8px;border:0;border-left:3px solid #46b37a;border-radius:4px;background:rgba(255,255,255,.03);color:inherit;font:inherit;text-align:left;cursor:pointer}
.subagent-history-row.running{border-left-color:#7c8cff}
.subagent-history-row.failed{border-left-color:#d9534f}
.subagent-history-row:hover{background:rgba(255,255,255,.07)}
.subagent-history-task{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.subagent-history-status,.subagent-history-meta{color:var(--muted,#8b929c);white-space:nowrap}
.subagent-card.subagent-flash{outline:2px solid #9aa6ff;outline-offset:2px}
.subagent-history-detail{padding:6px 10px 8px 14px;border-left:3px solid var(--line,#2b2f38);font-size:12px;white-space:pre-wrap;max-height:30vh;overflow:auto}
.subagent-history-detail .label{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--muted,#8b929c);margin-top:4px}
.subagent-history-detail p{margin:2px 0 6px}
/* director flow: the compare viewer (canvas-viewer.js openCompareViewer) — render | reference, the critic's list to the right. */
.compare-viewer{grid-template-rows:auto 1fr auto}
.compare-viewer .viewer-bar{flex-wrap:wrap;row-gap:6px}
.cv-nav{display:flex;align-items:center;gap:4px;padding:2px 6px;border:1px solid #ffffff1f;border-radius:7px}
.cv-nav.single [data-cv-context]{display:none}
.cv-nav button{min-width:30px;padding:3px 8px}
.cv-nav button:disabled{opacity:.3;cursor:default}
.cv-where{min-width:4em;text-align:center;font:12px ui-monospace,monospace;font-variant-numeric:tabular-nums;white-space:nowrap}
.cv-body{display:grid;grid-template-columns:minmax(0,1fr) clamp(300px,28vw,440px);min-height:0}
.cv-body .viewer-stage{min-height:0}
.cv-pair{display:flex;align-items:flex-start}
.cv-pair img,.cv-missing{display:block;flex:none;max-width:none;max-height:none;user-select:none;background:#111;box-shadow:0 0 0 1px #ffffff22}
.cv-pair .hidden{display:none}
.cv-missing{display:flex;align-items:center;justify-content:center;padding:24px;box-sizing:border-box;color:#ffb3b3;font-size:28px;text-align:center;background:repeating-linear-gradient(45deg,#1a1212 0 14px,#211616 14px 28px)}
.cv-tag{position:absolute;left:0;top:0;padding:2px 8px;border-radius:5px;background:#0b0f14d9;border:1px solid #ffffff22;font-size:12px;white-space:nowrap;pointer-events:none;z-index:1}
.cv-tag.hidden{display:none}
.cv-side{overflow:auto;padding:12px 14px 20px;border-left:1px solid #ffffff14;background:#0d1117;font-size:13px}
.cv-side-title{font-weight:700;font-size:14px}
.cv-side .drawer-sub{margin:2px 0 0}
.cv-note{margin:6px 0 0;font-size:12px;color:var(--muted)}
.cv-verdict{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin:12px 0 6px}
.cv-verdict .critique-verdict{font-size:13px;padding:3px 10px}
.cv-mode{background:#1f3340;color:#a8dcff}
.cv-scores{display:flex;flex-wrap:wrap;gap:4px 10px;margin:0 0 6px;font-size:11px;color:var(--muted)}
.cv-scores b{color:#e8edf3;font-variant-numeric:tabular-nums}
.cv-fixed{margin:0 0 6px;font-size:12px;color:var(--good)}
.cv-fixed.none{color:var(--muted)}
.cv-diff{margin:0 0 10px;font-size:11px;color:var(--muted)}
.cv-side .fault-head code{color:var(--muted);font-size:11px}
.cv-element{display:block;margin-top:4px;font-size:13px}
.cv-metric{display:flex;flex-wrap:wrap;align-items:baseline;gap:2px 8px;margin:6px 0 2px;padding:5px 8px;border-radius:6px;background:#ffffff0d;font-size:12px;font-variant-numeric:tabular-nums}
.cv-metric b{font-size:13px;color:#fff}
.cv-metric.none{color:var(--muted)}
.cv-q{font-weight:700;text-transform:uppercase;letter-spacing:.04em;font-size:10px;color:#a8dcff}
.cv-delta b{color:#ffd27a}
.cv-was{color:var(--muted)}
.cv-was.better{color:var(--good)}
.cv-was.worse{color:var(--bad)}
.cv-method{flex-basis:100%;font-size:11px;color:var(--muted)}
.cv-hint{margin:0;padding:6px 16px;border-top:1px solid #ffffff14;background:#0b0f14;font-size:11px;color:var(--muted)}
.canvas-compare-full{padding-top:0}
#canvas-big[data-compare-full]{cursor:zoom-in}
.compare-viewer{background:#080a0d}
.cv-swatch{display:inline-block;width:11px;height:11px;margin:0 4px -1px 0;border-radius:3px;box-shadow:0 0 0 1px #ffffff55}

/* critic trial A: the canvas score in the comparison view */
.cv-score { margin: 0 0 10px; padding: 8px 10px; border: 1px solid #3a414c; border-radius: 8px; background: #161a20; }
.cv-score.none { color: #8b929c; font-size: 12px; }
.cv-score-head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.cv-score-value { font-size: 28px; font-weight: 800; color: #e0c35f; }
.cv-score-max { color: #8b929c; }
.cv-trend.better { color: #49cc8d; } .cv-trend.worse { color: #ff6b6b; } .cv-trend.same { color: #8b929c; }
.cv-best { color: #8b929c; font-size: 12px; }
.cv-terms summary { cursor: pointer; color: #8b929c; font-size: 12px; margin-top: 4px; }
.cv-term { display: grid; grid-template-columns: 34px 1fr 70px; gap: 4px 8px; align-items: center; font-size: 11px; margin-top: 4px; }
.cv-term-el { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cv-term-bar { height: 6px; background: #2a2f38; border-radius: 3px; overflow: hidden; }
.cv-term-bar i { display: block; height: 100%; background: #e0c35f; }
.cv-term-v { grid-column: 2 / 4; color: #8b929c; }
