/* ============================================================================
 * Deckard — components.css
 * Everything the render modules paint into: the shell layout, tabs, lanes,
 * rails, tool cards, diffs, thinking panels, context drawers, permission
 * prompts, image blocks, the shared file map, and footer alerts.
 *
 * Class contract for the other frontend modules (js/lanes.js, js/tabs.js,
 * js/render/*.js, js/filemap.js, js/permissions.js, js/login.js): use these
 * class names and data-attributes and the theme comes for free. All state is
 * expressed with data-* attributes, never with a color class, so the palette
 * stays enforced in ONE place.
 *
 *   .dk-lane           [data-state=<AgentState>] [data-lane=expanded|rail]
 *   .dk-rail           [data-state=<AgentState>]
 *   .dk-status-dot     [data-state=<AgentState>]
 *   .dk-tool-card      [data-state=pending|running|ok|error] [data-risky=true]
 *   .dk-perm           [data-pending=true|false] [data-risky=true]
 *   .dk-thinking       [data-streaming=true|false] [data-redacted=true]
 *   .dk-file-row       [data-conflict=true|false]
 *   .dk-tab            [data-active=true|false] [data-attention=true]
 *   .dk-footer-alert   [data-severity=conflict|error|info]
 *
 * Requires: theme.css (tokens) and motion.css (animations), in that order.
 * ==========================================================================*/

/* ==========================================================================
 * SHELL
 * ==========================================================================*/
#dk-app {
  display: none;                 /* app.js/login.js flips this on after auth */
  flex-direction: column;
  /* dvh, not vh: on phones 100vh includes the space UNDER the browser chrome and the virtual
     keyboard, which pinned the composer off-screen while typing. dvh tracks the real viewport
     (with interactive-widget=resizes-content in the meta). Old browsers fall back to the vh line. */
  height: 100vh;
  height: 100dvh;
  width: 100vw;
  overflow: hidden;
}
body[data-authed="true"] #dk-app { display: flex; }
body[data-authed="true"] #dk-login { display: none; }

/* Coding-mode chrome only exists in coding mode (§11). Chat mode is a single
   stream: no tabs, no lanes, no rails, no file map (§9). */
body[data-mode="chat"] #dk-tabbar,
body[data-mode="chat"] #dk-filemap,
body[data-mode="chat"] #dk-lanes { display: none; }
body[data-mode="coding"] #dk-chat { display: none; }

/* ---- top bar ---- */
#dk-topbar {
  display: flex;
  align-items: center;
  gap: var(--gap);
  height: var(--topbar-h);
  flex: 0 0 auto;
  padding: 0 var(--pad);
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}
.dk-brand {
  color: var(--amber);
  font-weight: 700;
  font-size: var(--fs-lg);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  text-shadow: var(--glow);
  user-select: none;
}
.dk-brand-sub {
  color: var(--amber-dim);
  font-size: var(--fs-micro);
  letter-spacing: 0.1em;
}
#dk-topbar .dk-spacer { flex: 1 1 auto; }

/* Mode switch (chat|coding). Server is authoritative — a role:'chat' user gets
   the coding control disabled AND the server rejects it anyway (§4). */
#dk-mode {
  display: flex;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
#dk-mode .dk-mode-btn {
  background: transparent;
  border: 0;
  color: var(--amber-dim);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  padding: 3px 10px;
  cursor: pointer;
  transition: background-color var(--t) var(--ease), color var(--t) var(--ease);
}
#dk-mode .dk-mode-btn:hover:not(:disabled) { background: var(--hover); color: var(--amber); }
#dk-mode .dk-mode-btn[data-active="true"] {
  background: var(--active);
  color: var(--amber);
  text-shadow: var(--glow);
}
#dk-mode .dk-mode-btn:disabled { opacity: 0.4; cursor: not-allowed; }

/* Connection + identity readout. Dim = fine, red = broken. */
/* Context-window meter (topbar). A small bar + % that fills as context is used; click for the
   compact/clear menu. Amber past 60%, red past 85% (near auto-compact). */
.dk-ctx {
  position: relative;
  display: flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  padding: 2px 6px;
  border-radius: var(--radius);
}
.dk-ctx:hover { background: var(--hover); }
.dk-ctx-bar {
  width: 60px;
  height: 6px;
  border-radius: 3px;
  background: rgb(var(--amber-rgb) / 12%);
  overflow: hidden;
}
.dk-ctx-fill {
  display: block;
  height: 100%;
  width: 0;
  background: var(--cyan);
  transition: width var(--t) var(--ease);
}
.dk-ctx[data-level="mid"] .dk-ctx-fill { background: var(--amber); }
.dk-ctx[data-level="high"] .dk-ctx-fill { background: var(--red); }
.dk-ctx-label { font-size: var(--fs-micro); color: var(--amber-dim); min-width: 2.4em; text-align: right; }
.dk-ctx[data-level="high"] .dk-ctx-label { color: var(--red); }
.dk-ctx-menu {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  z-index: 40;
  display: flex;
  flex-direction: column;
  min-width: 180px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 6px 24px rgb(0 0 0 / 45%);
  overflow: hidden;
}
.dk-ctx-act {
  text-align: left;
  padding: 7px 12px;
  background: none;
  border: none;
  color: var(--amber);
  font-size: var(--fs-base);
  cursor: pointer;
}
.dk-ctx-act:hover { background: var(--hover); }

.dk-conn {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--fs-micro);
  color: var(--amber-dim);
}
.dk-conn[data-status="open"] .dk-status-dot { background: var(--amber); }
.dk-conn[data-status="connecting"] .dk-status-dot { background: var(--cyan); }
.dk-conn[data-status="closed"] .dk-status-dot,
.dk-conn[data-status="error"] .dk-status-dot { background: var(--red); }
.dk-user { color: var(--amber-dim); font-size: var(--fs-micro); }
.dk-user[data-origin="remote"] { color: var(--red); }  /* stricter posture (§6) */

/* ---- tab bar (§9) ---- */
#dk-tabbar {
  display: flex;
  align-items: stretch;
  height: var(--tabbar-h);
  flex: 0 0 auto;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  overflow-x: auto;
  overflow-y: hidden;
}
#dk-tablist { display: flex; align-items: stretch; }
.dk-tab {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 10px;
  max-width: 240px;
  border-right: 1px solid var(--border);
  border-bottom: 2px solid transparent;
  background: transparent;
  color: var(--amber-dim);
  font-size: var(--fs-small);
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}
.dk-tab:hover { background: var(--hover); color: var(--amber); }
.dk-tab[data-active="true"] {
  background: var(--surface);
  color: var(--amber);
  border-bottom-color: var(--amber);
  text-shadow: var(--glow);
}
.dk-tab[data-attention="true"] { color: var(--red); border-bottom-color: var(--red); }
.dk-tab-title { overflow: hidden; text-overflow: ellipsis; }
.dk-tab-close {
  border: 0;
  background: transparent;
  color: var(--amber-dim);
  font-size: var(--fs-micro);
  line-height: 1;
  padding: 2px 3px;
  cursor: pointer;
}
.dk-tab-close:hover { color: var(--red); }
#dk-tab-new {
  border: 0;
  border-right: 1px solid var(--border);
  background: transparent;
  color: var(--amber-dim);
  padding: 0 12px;
  font-size: var(--fs-lg);
  line-height: 1;
  cursor: pointer;
  transition: color var(--t) var(--ease), background-color var(--t) var(--ease);
}
#dk-tab-new:hover { color: var(--amber); background: var(--hover); text-shadow: var(--glow); }
/* §4 allocation caveat (tabs.js) — dim amber, one line. Was emitted with no rule at all. */
.dk-tab-caveat { color: var(--amber-dim); font-size: var(--fs-micro); padding: 0 8px; }

/* ---- main work area ---- */
#dk-main {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

/* ==========================================================================
 * LANES & RAILS (§9)
 * Expanded lanes flex to share width; rails are fixed at --rail-w.
 * ==========================================================================*/
#dk-lanes {
  flex: 1 1 auto;
  display: flex;
  flex-direction: row;
  align-items: stretch;
  min-height: 0;
  overflow-x: auto;
  overflow-y: hidden;
  gap: 1px;
  background: var(--border);     /* the 1px gaps read as lane dividers */
}

.dk-lane {
  display: flex;
  flex-direction: column;
  min-width: var(--lane-min-w);
  flex: 1 1 0;
  min-height: 0;
  background: var(--bg);
  overflow: hidden;
}
.dk-lane[data-state="awaiting_permission"] { box-shadow: inset 0 0 0 1px var(--red); }
.dk-lane[data-state="error"] { box-shadow: inset 0 0 0 1px rgb(var(--red-rgb) / 55%); }
/* Lanes sharing a file link cyan; colliding on one link red (§10). */
.dk-lane[data-link="shared"] { box-shadow: inset 0 0 0 1px rgb(var(--cyan-rgb) / 45%); }
.dk-lane[data-link="conflict"] { box-shadow: inset 0 0 0 1px var(--red); }

.dk-lane-head {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
  padding: 6px var(--pad);
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}
/* Team member turn, rendered as an attributed block in the shared workspace's main log. */
.dk-team-turn { border-left: 3px solid var(--border); margin: 12px 0; padding: 6px 0 8px 14px; }
.dk-team-turn.lead { border-left-color: var(--cyan); }
.dk-team-turn-head { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; }
.dk-team-turn-av { width: 34px; height: 34px; border-radius: 8px; object-fit: cover; border: 1px solid var(--border); flex: 0 0 auto; }
.dk-team-turn-av-fb { display: inline-flex; align-items: center; justify-content: center; background: var(--raised-2, rgba(255,255,255,0.06)); color: var(--amber); font-weight: 700; font-family: var(--font-mono); }
.dk-team-turn-who { display: flex; align-items: baseline; gap: 8px; min-width: 0; flex-wrap: wrap; }
.dk-team-turn-name { color: var(--fg, var(--amber)); font-weight: 700; letter-spacing: 0.02em; }
.dk-team-turn-role { color: var(--cyan); font-size: var(--fs-micro); text-transform: uppercase; letter-spacing: 0.06em; }
.dk-team-turn-lead { color: var(--cyan); font-size: var(--fs-tiny, 11px); border: 1px solid var(--cyan); border-radius: 999px; padding: 0 6px; }
.dk-team-turn-body { color: var(--fg, var(--amber)); font-size: var(--fs-small); line-height: 1.55; }

/* Confirm-destroy modal (workspace close) */
.dk-confirm-overlay {
  position: fixed; inset: 0; z-index: 200; display: flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,0.55); opacity: 0; transition: opacity 0.15s var(--ease, ease);
}
.dk-confirm-overlay[data-open="true"] { opacity: 1; }
.dk-confirm-modal {
  width: min(420px, 92vw); background: var(--surface, #131318); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 18px 18px 14px; box-shadow: 0 12px 40px rgba(0,0,0,0.5);
  transform: translateY(6px); transition: transform 0.15s var(--ease, ease);
}
.dk-confirm-overlay[data-open="true"] .dk-confirm-modal { transform: translateY(0); }
.dk-confirm-title { color: var(--red); font-weight: 700; font-size: var(--fs-base, 1rem); letter-spacing: 0.02em; margin-bottom: 8px; }
.dk-confirm-body { color: var(--fg, var(--amber)); font-size: var(--fs-small); line-height: 1.5; }
.dk-confirm-foot { display: flex; justify-content: flex-end; gap: 8px; margin-top: 16px; }

/* Persona face on a team-member lane head — makes it obvious who owns this sub-window. */
.dk-lane-avatar {
  flex: 0 0 auto; width: 22px; height: 22px; border-radius: 6px; object-fit: cover;
  border: 1px solid var(--border);
}
.dk-lane-avatar-fallback {
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--raised-2, rgba(255,255,255,0.06)); color: var(--amber);
  font-family: var(--font-mono); font-size: var(--fs-micro); font-weight: 700; line-height: 1;
}
.dk-lane-name {
  color: var(--amber);
  font-size: var(--fs-small);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  text-shadow: var(--glow);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dk-lane-desc {
  color: var(--amber-dim);
  font-size: var(--fs-micro);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1 1 auto;
}
.dk-lane-usage { color: var(--amber-dim); font-size: var(--fs-micro); white-space: nowrap; }
.dk-lane-btn {
  border: 0;
  background: transparent;
  color: var(--amber-dim);
  cursor: pointer;
  padding: 0 4px;
  font-size: var(--fs-small);
  line-height: 1;
}
.dk-lane-btn:hover { color: var(--amber); }
.dk-lane-btn[data-danger="true"]:hover { color: var(--red); }

.dk-lane-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding: var(--pad);
  display: flex;
  flex-direction: column;
  gap: var(--gap);
  background: #000; /* operator preference: the text log reads on SOLID black, not the surface tint */
}
/* THE SQUASH BUG. The body is a column flex, which makes every message, tool card and
   permission card a FLEX ITEM — and flex items shrink (flex-shrink: 1) before the container
   scrolls. Once a turn outgrew the lane, the browser compressed every card toward zero height
   instead of overflowing: tool cards became 10-25px pulsing slivers with their guts clipped,
   and the permission card's approve/deny buttons were pushed outside its own overflow:hidden —
   a prompt you could see but never answer, so it timed out. Children must keep their natural
   height; the BODY is the thing that scrolls. */
.dk-lane-body > * { flex-shrink: 0; }

/* js/lanes.js nests a rail + a `.dk-lane-full` inside each `.dk-lane`, and its layout-critical
   flex is set inline (so it degrades with no stylesheet). These are the rest of its parts. */
.dk-lane-full { min-width: 0; }
.dk-lane-summary {
  flex: 0 0 auto;
  padding: 0 var(--pad) 6px;
  color: var(--amber-dim);
  font-size: var(--fs-micro);
}
.dk-lane-summary:empty { display: none; }
/* Drag-resizable divider between two expanded lanes (§9). */
.dk-lane-divider { background: var(--border); }
.dk-lane-divider:hover,
.dk-lane-divider.dk-dragging { background: var(--amber); box-shadow: var(--glow-box); }
/* §10 context drawer contents, seeded from the spawn prompt. */
/* ---- rail: a collapsed lane (~46px). Must never hide a block (§9). ---- */
.dk-rail {
  flex: 0 0 var(--rail-w);
  width: var(--rail-w);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 8px 0;
  background: var(--surface);
  border: 0;
  /* A <button> with no explicit color paints its children in the UA's `buttontext` — a fifth
     hue, outside the four-token palette (§18). Pin it so nothing inside a rail can fall back. */
  color: var(--amber);
  font-size: var(--fs-micro);
  cursor: pointer;
  overflow: hidden;
}
.dk-rail:hover { background: var(--hover); }
.dk-rail[data-state="awaiting_permission"] { box-shadow: inset 0 0 0 1px var(--red); }
.dk-rail-name {
  writing-mode: vertical-rl;
  text-orientation: mixed;
  color: var(--amber);
  font-size: var(--fs-micro);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1 1 auto;
  max-height: 100%;
}
.dk-rail-brief {
  writing-mode: vertical-rl;
  text-orientation: mixed;
  color: var(--amber-dim);
  font-size: var(--fs-micro);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-height: 40%;
}

/* Responsive auto-rail (§9). lanes.js enforces maxExpandedLanes; these are the
   width floors that make the degradation visible/consistent. */
@media (max-width: 900px) {
  :root { --lane-min-w: 280px; }
}
@media (max-width: 620px) {
  :root { --lane-min-w: 100%; }
  .dk-lane { min-width: 100%; }
}

/* ==========================================================================
 * MESSAGES (§8)
 * ==========================================================================*/
.dk-msg {
  border-left: 2px solid var(--border);
  padding: 2px 0 2px var(--pad);
}
/* WHO SAID WHAT is carried by COLOUR, not by a caption (the "you"/"agent" tags are gone).
   §11 already assigns the two hues: user input is cyan, agent output is amber. The border and
   the text agree, so the speaker is legible at a glance and from the corner of your eye.

   The user's text is deliberately RECESSIVE: you already know what you typed, and the agent's
   answer is the thing you came to read. So it is dimmed (but held well above the readability
   floor) and carries no phosphor bloom, while the border stays FULL cyan so you can still scan
   down the transcript and find where you spoke. Intensity carries state (§11) — this is the same
   trick the rails use, applied to the conversation. */
/* Your turns: a DARKER AMBER, laid out exactly like the agent's.
   Same family, different intensity — §11's rule that intensity carries state, applied to the
   conversation. You already know what you typed, so it sits back; the reply is the bright thing.
   No cyan (that hue means tool input / structural info elsewhere and was doing double duty here),
   no bar, no bullet. Indented to the same column as the agent's text so the transcript reads as
   one aligned document rather than two competing layouts. */
.dk-msg[data-role="user"] {
  border-left: 0;
  padding-left: calc(1.15em + 2px);
  color: rgb(var(--amber-rgb) / 62%);
  text-shadow: none;
}
/* No rule on the agent's turns. The bullet already marks where a reply starts, and the amber
   already says who is speaking — a vertical bar on top of both is a third redundant signal, and it
   boxed in the very content you are here to read. The user's turns keep their cyan bar: those you
   want to SKIP past, so a scan line is useful there and noise here. */
.dk-msg[data-role="assistant"] {
  border-left: 0;
  padding-left: 0;
  color: var(--amber);
  text-shadow: var(--glow);
}
.dk-msg[data-role="system"] { border-left-color: var(--border); color: var(--amber-dim); }
.dk-msg[data-role="error"] { border-left-color: var(--red); color: var(--red); }
.dk-msg-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 2px;
}.dk-msg-time { color: var(--amber-dim); font-size: var(--fs-micro); }
/* The mark that opens every agent turn (replaces the timestamp).
   Amber, lightly bloomed — it is agent output, so it takes the agent's hue (§11). Kept small so it
   reads as punctuation, NOT as a status dot: a status dot means something specific in this UI (§9)
   and that meaning has to stay unique.

   LAYOUT: the assistant block is a 2-column grid — a narrow gutter for the bullet, then the text.
   That puts the bullet on the SAME LINE as the text starts (not floating on a line above it), and
   because every following paragraph lives in column 2, the whole reply hangs indented against the
   bullet instead of sliding back under it. `align-self: baseline` is what actually pins the dot to
   the first line's baseline rather than the top of the box. */
.dk-msg[data-role="assistant"] {
  display: grid;
  grid-template-columns: 1.15em 1fr;
  column-gap: 2px;
  align-items: baseline;
}
.dk-msg[data-role="assistant"] > .dk-msg-body { grid-column: 2; min-width: 0; }
.dk-msg[data-role="assistant"] > .dk-msg-head { grid-column: 2; }
.dk-msg-bullet {
  grid-column: 1;
  align-self: baseline;
  color: var(--amber);
  font-size: 9px;
  text-shadow: var(--glow);
  opacity: 0.9;
}
/* render/message.js emits `.dk-msg-body`. Without the pre-wrap here, every newline in an
   assistant turn collapses and the agent's output renders as one run-on paragraph. */
.dk-msg-text,
.dk-msg-body {
  white-space: pre-wrap;
  word-break: break-word;
  font-size: var(--fs-base);
}
.dk-msg-text p,
.dk-msg-body p { margin: 0 0 6px; }
.dk-msg-text p:last-child,
.dk-msg-body p:last-child { margin-bottom: 0; }
.dk-msg-text code,
.dk-msg-body code {
  color: var(--cyan);
  background: rgb(var(--cyan-rgb) / 8%);
  padding: 0 3px;
  border-radius: var(--radius);
}
.dk-msg-text pre,
.dk-msg-body pre {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 6px 8px;
  overflow-x: auto;
  color: var(--cyan);
}

/* ---- system notices (render/message.js renderNotice) ----
   §11 reserves RED for exactly this: errors, denials, failures. The loudest one in the app is
   the §5 warning raised when apiKeySource !== 'oauth' — i.e. the build is about to bill
   pay-as-you-go. Unstyled, it rendered in the same amber as ordinary agent output and was
   indistinguishable from it, which defeats the whole premise of a limited palette. */
.dk-notice {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px;
  padding: 2px 0 2px var(--pad);
  border-left: 2px solid var(--border);
  color: var(--amber-dim);
  font-size: var(--fs-small);
}
.dk-notice[data-level="error"] {
  border-left-color: var(--red);
  color: var(--red);
  text-shadow: var(--glow-red);
}
.dk-notice-time { color: var(--amber-dim); font-size: var(--fs-micro); }
.dk-notice[data-level="error"] .dk-notice-time { color: inherit; opacity: 0.8; }
.dk-notice-text { word-break: break-word; }
.dk-notice-detail { flex: 1 1 100%; }
.dk-notice-detail > summary {
  color: var(--amber-dim);
  font-size: var(--fs-micro);
  cursor: pointer;
}

/* Compaction marker — a distinct, slightly louder amber rule so "the model just forgot the early
 * conversation" reads as a real event, not a stray info line. The rebuild summary folds behind the
 * disclosure; cap its height so a long summary scrolls in place instead of flooding the log. */
.dk-notice-compaction {
  border-left-color: var(--amber);
  color: var(--amber);
}
.dk-notice-compaction .dk-notice-text { font-weight: 600; letter-spacing: 0.02em; }
.dk-compaction-summary {
  max-height: 340px;
  overflow: auto;
  white-space: pre-wrap;
  margin-top: 4px;
}

/* ==========================================================================
 * THINKING PANEL (§8 — collapsible, expand-on-demand; cyan per §11)
 *
 * render/thinking.js builds a NATIVE <details class="dk-thinking"> with a
 * <summary class="dk-thinking-summary">, so the open/closed state IS the `open`
 * attribute — there is no data-open to key on, and keying on one meant the body
 * stayed display:none forever: the triangle turned and no thinking text ever
 * appeared. §1's whole point is rendering that reasoning, so it must be
 * `.dk-thinking[open]`.
 * ==========================================================================*/
.dk-thinking {
  border: 1px dashed var(--border-info);
  border-radius: var(--radius);
  background: rgb(var(--cyan-rgb) / 4%);
}
.dk-thinking-summary {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 8px;
  cursor: pointer;
  color: var(--cyan);                    /* §11: thinking is cyan */
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  user-select: none;
  list-style: none;                      /* replace the UA triangle with our own marker */
}
.dk-thinking-summary::-webkit-details-marker { display: none; }
.dk-thinking-summary::before {
  content: "▸";
  display: inline-block;
  transition: transform var(--t) var(--ease);
}
.dk-thinking[open] > .dk-thinking-summary::before { transform: rotate(90deg); }
.dk-thinking-summary:hover { background: rgb(var(--cyan-rgb) / 8%); }
/* A thinking block with NO text (current models: token estimate only) or a redacted one is a
   STATEMENT, not a panel: there is nothing inside to open, so drop the twisty, the pointer
   cursor and the hover invite — an expand affordance on an empty box reads as a broken control. */
.dk-thinking[data-empty="true"],
.dk-thinking[data-redacted="true"] { border-style: solid; border-color: rgb(var(--cyan-rgb) / 25%); }
.dk-thinking[data-empty="true"] > .dk-thinking-summary,
.dk-thinking[data-redacted="true"] > .dk-thinking-summary { cursor: default; pointer-events: none; }
.dk-thinking[data-empty="true"] > .dk-thinking-summary::before,
.dk-thinking[data-redacted="true"] > .dk-thinking-summary::before { content: ""; }
.dk-thinking[data-empty="true"] > .dk-thinking-summary:hover,
.dk-thinking[data-redacted="true"] > .dk-thinking-summary:hover { background: none; }
.dk-thinking-label { font-weight: 600; }
.dk-thinking-meta { color: var(--amber-dim); margin-left: auto; text-transform: none; }
.dk-thinking-body {
  display: none;
  margin: 0;
  padding: 6px 8px 8px;
  border-top: 1px dashed rgb(var(--cyan-rgb) / 30%);
  color: var(--cyan);
  font-size: var(--fs-small);
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 340px;
  overflow-y: auto;
}
.dk-thinking[open] > .dk-thinking-body { display: block; }
.dk-thinking[data-redacted="true"] > .dk-thinking-body::before {
  content: "[redacted thinking — the model's reasoning for this block is encrypted]";
  color: var(--amber-dim);
}

/* ==========================================================================
 * TOOL CARDS (§8 — name + FULL input before exec, result attached after)
 * ==========================================================================*/
/* Tool-run group (render/toolgroup.js): a run of consecutive tool calls folds into one
   collapsible block. Its body stacks the cards with the same gap the lane uses. */
.dk-tool-group {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: rgb(var(--amber-rgb) / 3%);
}
.dk-tool-group-summary {
  display: block; /* two rows: the title line, and the action line below it */
  padding: 4px 8px;
  cursor: pointer;
  color: var(--amber-dim);
  font-size: var(--fs-micro);
  letter-spacing: 0.08em;
  list-style: none;
  user-select: none;
}
.dk-tool-group-summary::-webkit-details-marker { display: none; }
.dk-tool-group-titlerow {
  display: flex;
  align-items: center;
  gap: 8px;
  text-transform: uppercase;
}
.dk-tool-group-titlerow::before {
  content: "▸";
  display: inline-block;
  transition: transform var(--t) var(--ease);
}
.dk-tool-group[open] > .dk-tool-group-summary .dk-tool-group-titlerow::before { transform: rotate(90deg); }
.dk-tool-group-summary:hover { background: rgb(var(--amber-rgb) / 6%); }
.dk-tool-group-label { font-weight: 600; }
.dk-tool-group-count { color: var(--amber); text-transform: none; }
/* Title-row stats: "· N chars · Ys" once settled. */
.dk-tool-group-current {
  margin-left: auto;
  color: var(--amber-dim);
  text-transform: none;
  letter-spacing: 0;
  white-space: nowrap;
}
/* The action line (row 2): what it is doing right now, below the title. Hidden when empty. */
.dk-tool-group-actionline {
  color: var(--amber-dim);
  text-transform: none;
  letter-spacing: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  padding-left: 14px; /* align under the title text, past the twisty */
}
.dk-tool-group-actionline:empty { display: none; }
/* PULSE while active (cyan = in progress, §11). Dot leads the title row. */
.dk-tool-group[data-active="true"] { border-color: rgb(var(--cyan-rgb) / 40%); }
.dk-tool-group[data-active="true"] > .dk-tool-group-summary { color: var(--cyan); }
.dk-tool-group[data-active="true"] > .dk-tool-group-summary .dk-tool-group-actionline { color: var(--cyan); }
.dk-tool-group[data-active="true"] > .dk-tool-group-summary .dk-tool-group-titlerow::after {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--cyan);
  animation: dk-pulse-cyan 1.1s var(--ease) infinite;
  margin-left: 4px;
}
.dk-tool-group-body {
  display: flex;
  flex-direction: column;
  gap: var(--gap);
  padding: 6px;
}

.dk-tool-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.dk-tool-head {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 8px;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  user-select: none;
}
.dk-tool-name {
  color: var(--amber);
  font-size: var(--fs-small);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-shadow: var(--glow);
}
.dk-tool-card[data-risky="true"] .dk-tool-name { color: var(--red); text-shadow: var(--glow-red); }
.dk-tool-summary {
  flex: 1 1 auto;
  color: var(--amber-dim);
  font-size: var(--fs-micro);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dk-tool-state {
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--amber-dim);
}
.dk-tool-card[data-state="running"] .dk-tool-state { color: var(--cyan); }
.dk-tool-card[data-state="ok"] .dk-tool-state { color: var(--amber); }
.dk-tool-card[data-state="error"] .dk-tool-state { color: var(--red); }

/* Tool INPUT is cyan (§11: tool inputs are informational/structural). */
.dk-tool-input {
  padding: 6px 8px;
  color: var(--cyan);
  font-size: var(--fs-small);
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 260px;
  overflow: auto;
  border-bottom: 1px solid var(--border);
}
.dk-tool-input .dk-key { color: var(--amber-dim); }
/* Bash commands get the exact-command treatment (§12). */
.dk-tool-cmd {
  display: block;
  padding: 6px 8px;
  background: rgb(var(--red-rgb) / 6%);
  border-left: 2px solid var(--red);
  color: var(--red);
  font-size: var(--fs-small);
  white-space: pre-wrap;
  word-break: break-all;
}

.dk-tool-result {
  padding: 6px 8px;
  color: var(--amber);
  font-size: var(--fs-small);
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 320px;
  overflow: auto;
}
.dk-tool-result[data-error="true"] { color: var(--red); }/* Collapsed tool card: keep the head, hide the guts. */
.dk-tool-card[data-open="false"] .dk-tool-input,
.dk-tool-card[data-open="false"] .dk-tool-extras,
.dk-tool-card[data-open="false"] .dk-tool-result,
.dk-tool-card[data-open="false"] .dk-diff { display: none; }

/* ---- tool-card sub-elements (render/toolcard.js emits these) ---- */
/* Destructive tools are red BEFORE they run (§11/§12) — the chip says why. */
.dk-tool-risky {
  border: 1px solid var(--red);
  border-radius: var(--radius);
  padding: 0 4px;
  color: var(--red);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
/* An Agent/Task call opens a lane — structural, therefore cyan (§11). */
.dk-tool-spawn {
  border: 1px solid var(--border-info);
  border-radius: var(--radius);
  padding: 0 4px;
  color: var(--cyan);
  font-size: var(--fs-micro);
}
.dk-tool-prompt { color: var(--amber-dim); user-select: none; }
.dk-tool-path { color: var(--cyan); word-break: break-all; }
.dk-tool-input-empty { color: var(--amber-dim); font-size: var(--fs-micro); }
.dk-tool-extras:empty { display: none; }

/* key -> value rows inside a tool input */
.dk-kv { margin: 0; display: grid; grid-template-columns: max-content 1fr; gap: 0 8px; }
.dk-kv-key { color: var(--amber-dim); font-size: var(--fs-micro); }
.dk-kv-val { margin: 0; color: var(--cyan); min-width: 0; word-break: break-word; }

.dk-tool-result-head { display: flex; gap: 8px; align-items: baseline; }
.dk-tool-result-label {
  color: var(--amber-dim);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.dk-tool-result[data-error="true"] .dk-tool-result-label { color: var(--red); }
.dk-tool-result-time { color: var(--amber-dim); font-size: var(--fs-micro); margin-left: auto; }
.dk-tool-result-body { margin: 0; color: inherit; }
.dk-tool-result-empty,
.dk-tool-result-truncated { color: var(--amber-dim); font-size: var(--fs-micro); }
.dk-tool-structured > summary {
  color: var(--amber-dim);
  font-size: var(--fs-micro);
  cursor: pointer;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

/* Fenced/preformatted code anywhere in the stream: cyan on the raised surface (§11). */
.dk-code {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 6px 8px;
  color: var(--cyan);
  overflow-x: auto;
}
.dk-code-inline {
  color: var(--cyan);
  background: rgb(var(--cyan-rgb) / 8%);
  padding: 0 3px;
  border-radius: var(--radius);
}

/* ==========================================================================
 * DIFF VIEWER (§8, §11 — removed RED, added CYAN by default; §19 flippable)
 * Colors come from --diff-add / --diff-del, which theme.js flips. NEVER
 * hardcode a diff color here.
 * ==========================================================================*/
.dk-diff {
  border-top: 1px solid var(--border);
  font-size: var(--fs-small);
  /* Long lines WRAP (user, 2026-07-16: "we have to scroll longer line edits") — prose edits in
     docs produce single 500-char lines, and a horizontal scrollbar hides most of the change. */
  overflow-x: hidden;
}
.dk-diff-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 8px;
  border-bottom: 1px solid var(--border);
  color: var(--amber-dim);
  font-size: var(--fs-micro);
}
.dk-diff-path { color: var(--amber); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dk-diff-stat-add { color: var(--diff-add); }
.dk-diff-stat-del { color: var(--diff-del); }
.dk-diff-flag {
  border: 1px solid currentColor;
  border-radius: var(--radius);
  padding: 0 4px;
  font-size: var(--fs-micro);
}
.dk-diff-flag[data-kind="new"] { color: var(--diff-add); }
.dk-diff-flag[data-kind="delete"] { color: var(--diff-del); }

.dk-diff-body { display: block; }
.dk-hunk { border-top: 1px dashed var(--border); }
.dk-hunk-header {
  padding: 2px 8px;
  color: var(--amber-dim);
  font-size: var(--fs-micro);
  background: var(--raised-2);
}
.dk-diff-line {
  display: flex;
  align-items: flex-start;
  gap: 0;
  white-space: pre-wrap; /* wrap long lines; indentation still renders */
  font-size: var(--fs-small);
  line-height: 1.45;
}
.dk-diff-gutter {
  flex: 0 0 auto;
  min-width: 3.5em;
  padding: 0 6px;
  text-align: right;
  color: var(--amber-dim);
  user-select: none;
  border-right: 1px solid var(--border);
  font-size: var(--fs-micro);
}
.dk-diff-sign { flex: 0 0 auto; width: 1.2em; text-align: center; user-select: none; }
.dk-diff-text {
  flex: 1 1 auto;
  padding-right: 8px;
  min-width: 0; /* lets the flex item shrink so wrapping happens INSIDE the row */
  white-space: pre-wrap;
  overflow-wrap: anywhere; /* even an unbroken 400-char token wraps rather than scrolls */
}

.dk-diff-line[data-kind="context"] { color: var(--amber-dim); }
.dk-diff-line[data-kind="add"] {
  color: var(--diff-add);
  background: rgb(var(--diff-add-rgb) / 10%);
}
.dk-diff-line[data-kind="del"] {
  color: var(--diff-del);
  background: rgb(var(--diff-del-rgb) / 10%);
}
.dk-diff-line[data-kind="add"] .dk-diff-sign::before { content: "+"; }
.dk-diff-line[data-kind="del"] .dk-diff-sign::before { content: "-"; }

.dk-diff-stats { margin-left: auto; display: flex; gap: 6px; }
.dk-diff-gap {
  padding: 1px 8px;
  color: var(--amber-dim);
  background: var(--raised-2);
  font-size: var(--fs-micro);
  user-select: none;
}
.dk-diff-empty,
.dk-diff-truncated {
  padding: 4px 8px;
  color: var(--amber-dim);
  font-size: var(--fs-micro);
}
/* §12: the model's anchor is not in the file, so this is the REQUESTED replacement, not a
   simulation. The operator must not mistake it for a real before/after — hence red. */
.dk-diff-stale {
  padding: 3px 8px;
  border-bottom: 1px solid var(--border-danger);
  background: rgb(var(--red-rgb) / 8%);
  color: var(--red);
  font-size: var(--fs-micro);
}

/* ==========================================================================
 * CONTEXT DRAWER (§10 — what this agent was actually spawned with. Cyan.)
 * ==========================================================================*/
.dk-drawer {
  border: 1px solid var(--border-info);
  border-radius: var(--radius);
  background: rgb(var(--cyan-rgb) / 3%);
}.dk-drawer[data-open="true"] .dk-drawer-body { display: block; }.dk-drawer-files li { display: flex; gap: 6px; font-size: var(--fs-micro); }
.dk-drawer-files li[data-conflict="true"] { color: var(--red); }

/* ==========================================================================
 * PERMISSION PROMPT (§12 — the exact command, beside approve/deny/always)
 * ==========================================================================*/
.dk-perm {
  background: var(--surface);
  border: 1px solid var(--border-danger);
  border-radius: var(--radius);
  overflow: hidden;
}

/* ==========================================================================
 * ASK-USER-QUESTION + PERMISSION SHEET DOCK (permissions.js).
 * Both the model asking a structured question AND a blocked permission request
 * dock ABOVE the composer (#dk-ask-dock sits between #dk-main and #dk-composer
 * in the flex column), pushing up over the text entry like every chat app's
 * question UI — never inline lane cards that the streaming log scrolls away
 * while the backend sits blocked on them.
 * Questions are INFO (cyan); permission-required is DANGER (red) (§11).
 * ==========================================================================*/
#dk-ask-dock {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-height: 55vh;
  overflow-y: auto;
  margin: 0 var(--pad);
}
#dk-ask-dock:empty { display: none; }
/* Docked permission cards get the same lifted-sheet look as .dk-ask, keeping
   their red border/pulse from motion.css. */
#dk-ask-dock .dk-perm {
  flex: 0 0 auto;
  box-shadow: 0 -6px 24px rgb(0 0 0 / 45%);
}
.dk-ask {
  background: var(--raised-2, var(--surface));
  border: 1px solid var(--border-info);
  border-radius: var(--radius);
  box-shadow: 0 -6px 24px rgb(0 0 0 / 45%), var(--glow-box-cyan, none);
  animation: dk-slide-in var(--t) var(--ease) both;
}
.dk-ask-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  border-bottom: 1px solid var(--border-info);
  color: var(--cyan);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.1em;
}
.dk-ask-badge {
  border: 1px solid var(--border-info);
  border-radius: var(--radius);
  padding: 1px 6px;
  font-weight: 700;
}
.dk-ask-from { color: var(--amber-dim); }
.dk-ask-head .dk-perm-expiry { margin-left: auto; color: var(--amber-dim); }
.dk-ask-body { padding: 8px 10px; display: flex; flex-direction: column; gap: 10px; }
.dk-ask-q-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 6px; }
.dk-ask-chip {
  flex: 0 0 auto;
  border: 1px solid var(--border-info);
  border-radius: var(--radius);
  padding: 1px 6px;
  color: var(--cyan);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.dk-ask-text { color: var(--amber); font-weight: 600; }
.dk-ask-opts { display: flex; flex-direction: column; gap: 6px; align-items: stretch; }
.dk-ask-opt {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  padding: 6px 10px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--amber);
  text-align: left;
  cursor: pointer;
}
.dk-ask-opt:hover { border-color: var(--border-info); background: rgb(var(--cyan-rgb) / 6%); }
.dk-ask-opt[data-selected="true"] {
  border-color: var(--cyan);
  background: rgb(var(--cyan-rgb) / 12%);
  box-shadow: var(--glow-box-cyan, none);
}
.dk-ask-opt-label { font-weight: 700; }
.dk-ask-opt-desc { color: var(--amber-dim); font-size: var(--fs-micro); }
.dk-ask-other {
  flex: 0 0 auto;
  padding: 6px 10px;
  background: var(--bg);
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  color: var(--amber);
  font-family: var(--font-mono);
  font-size: var(--fs-base);
}
.dk-ask-other:focus { outline: none; border-color: var(--cyan); border-style: solid; }
.dk-ask-actions {
  display: flex;
  gap: 6px;
  justify-content: flex-end;
  padding: 6px 10px 8px;
  border-top: 1px solid var(--border);
}
.dk-ask .dk-perm-btn[data-action="allow"]:disabled { opacity: 0.4; cursor: not-allowed; }
.dk-ask[data-resolved="true"] { opacity: 0.5; }

/* Empty coding screen (configure-first tabs: nothing auto-opens). */
.dk-tabs-empty {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  color: var(--amber-dim);
}
.dk-tabs-empty-title { color: var(--amber); font-size: var(--fs-lg); font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; }
.dk-tabs-empty-hint { font-size: var(--fs-base); }

/* Images collected into the artifacts dock (artifacts.js kind 'image'). */
.dk-artifact-image { display: flex; justify-content: center; padding: 8px; }
.dk-artifact-img {
  max-width: 100%;
  max-height: 60vh;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  cursor: zoom-in;
}
.dk-perm-head {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px 8px;
  border-bottom: 1px solid var(--border-danger);
  color: var(--red);
  font-size: var(--fs-small);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  text-shadow: var(--glow-red);
}
.dk-perm-title { padding: 6px 8px; color: var(--amber); font-size: var(--fs-small); }
.dk-perm-desc { padding: 0 8px 6px; color: var(--amber-dim); font-size: var(--fs-micro); }
/* The FULL, unredacted input — spec §12 requires showing the exact command. */
.dk-perm-input {
  margin: 0 8px 8px;
  padding: 6px 8px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--cyan);
  font-size: var(--fs-small);
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 240px;
  overflow: auto;
}
.dk-perm-actions {
  display: flex;
  gap: 6px;
  padding: 0 8px 8px;
  flex-wrap: wrap;
}
.dk-perm-btn {
  border: 1px solid var(--border);
  background: transparent;
  border-radius: var(--radius);
  padding: 3px 10px;
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  cursor: pointer;
  color: var(--amber-dim);
  transition: color var(--t) var(--ease), border-color var(--t) var(--ease),
    background-color var(--t) var(--ease), box-shadow var(--t) var(--ease);
}
.dk-perm-btn[data-action="allow"] { color: var(--amber); border-color: var(--amber); }
.dk-perm-btn[data-action="allow"]:hover { background: var(--active); box-shadow: var(--glow-box); }
.dk-perm-btn[data-action="always"] { color: var(--cyan); border-color: var(--cyan); }
.dk-perm-btn[data-action="always"]:hover {
  background: rgb(var(--cyan-rgb) / 14%);
  box-shadow: var(--glow-box-cyan);
}
.dk-perm-btn[data-action="deny"] { color: var(--red); border-color: var(--red); }
.dk-perm-btn[data-action="deny"]:hover {
  background: rgb(var(--red-rgb) / 16%);
  box-shadow: var(--glow-box-red);
}
.dk-perm-btn:disabled { opacity: 0.45; cursor: not-allowed; }
/* Remote + risky: re-auth required before allow (§6/§12). */
.dk-perm-reauth {
  padding: 0 8px 8px;
  color: var(--red);
  font-size: var(--fs-micro);
}
.dk-perm[data-resolved="true"] {
  border-color: var(--border);
  opacity: 0.6;
  animation: none;
}
.dk-perm-outcome { padding: 6px 8px; font-size: var(--fs-micro); color: var(--amber-dim); }
.dk-perm-outcome[data-decision="deny"],
.dk-perm-outcome[data-decision="timeout"] { color: var(--red); }
.dk-perm-expiry { color: var(--amber-dim); font-size: var(--fs-micro); margin-left: auto; }
.dk-perm-expiry[data-expired="true"] { color: var(--red); }

/* ---- permission-card sub-elements (js/permissions.js emits these) ---- */
.dk-perm-badge {
  border: 1px solid currentColor;
  border-radius: var(--radius);
  padding: 0 4px;
  font-size: var(--fs-micro);
}
.dk-perm-tool { color: var(--red); }
.dk-perm-name { color: var(--amber-dim); font-weight: 400; text-transform: none; }

/* §12: the EXACT command, verbatim and unmissable. Red, because approving it runs it. */
.dk-perm-cmd { margin: 0 8px 8px; }
.dk-perm-cmd-label {
  display: block;
  color: var(--amber-dim);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-bottom: 2px;
}
.dk-perm-cmd-text {
  margin: 0;
  display: block;
  padding: 6px 8px;
  background: rgb(var(--red-rgb) / 6%);
  border-left: 2px solid var(--red);
  color: var(--red);
  font-size: var(--fs-small);
  white-space: pre-wrap;
  word-break: break-all;
}
.dk-perm-cmd-desc { color: var(--amber-dim); font-size: var(--fs-micro); }

.dk-perm-input > summary {
  color: var(--amber-dim);
  font-size: var(--fs-micro);
  cursor: pointer;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.dk-perm-input-json {
  margin: 4px 0 0;
  color: var(--cyan);
  white-space: pre-wrap;
  overflow-wrap: anywhere; /* long JSON/file content wraps instead of forcing a horizontal scroll */
}

/* §10 soft-block: this prompt exists because two agents collided on one file. */
.dk-perm-conflict {
  margin: 0 8px 8px;
  padding: 4px 8px;
  border: 1px solid var(--red);
  border-radius: var(--radius);
  color: var(--red);
  font-size: var(--fs-micro);
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.dk-perm-conflict-label { text-transform: uppercase; letter-spacing: 0.08em; }

.dk-perm-diff:empty { display: none; }
.dk-perm-status { padding: 0 8px 6px; color: var(--amber-dim); font-size: var(--fs-micro); }
.dk-perm-status:empty { display: none; }
.dk-perm-status[data-level="error"] { color: var(--red); }

/* ==========================================================================
 * IMAGES (§13 — inline image blocks with a lightbox)
 * ==========================================================================*/
.dk-image {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  padding: 4px;
  display: inline-block;
  max-width: 100%;
}
.dk-image img {
  display: block;
  max-width: 100%;
  height: auto;
  cursor: zoom-in;
  border-radius: var(--radius);
  image-rendering: auto;
}
.dk-image-cap { color: var(--amber-dim); font-size: var(--fs-micro); padding: 2px 2px 0; }

#dk-lightbox {
  position: fixed;
  inset: 0;
  z-index: 1080;
  display: none;
  align-items: center;
  justify-content: center;
  background: rgb(var(--bg-rgb) / 94%);
  cursor: zoom-out;
}
#dk-lightbox[data-open="true"] { display: flex; }
#dk-lightbox img {
  max-width: 94vw;
  max-height: 90vh;
  border: 1px solid var(--border-strong);
  box-shadow: var(--glow-box);
}

/* ==========================================================================
 * SHARED FILE MAP (§10) — one strip per tab, conflicts in red
 * ==========================================================================*/
/* ---- §10 shared file map ------------------------------------------------
   filemap.js emits ~20 dk-filemap__* classes; none of them had a rule, so the
   whole strip rendered as unstyled text mashed into one line. Styled here. */
.dk-filemap__title {
  color: var(--amber-dim);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  white-space: nowrap;
}
.dk-filemap__count {
  color: var(--amber);
  font-size: var(--fs-micro);
  padding: 0 5px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--raised-2);
}
.dk-filemap__mode {
  color: var(--amber-dim);
  font-size: var(--fs-micro);
  text-transform: uppercase;
}
/* Conflicts are RED and must be impossible to miss (§10, §11). */
.dk-filemap__conflict-count {
  color: var(--red);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  padding: 0 5px;
  border: 1px solid var(--border-danger);
  border-radius: var(--radius);
  background: rgb(var(--red-rgb) / 10%);
  text-shadow: var(--glow-red);
  white-space: nowrap;
}

/* The rows scroll HORIZONTALLY inside the strip — the strip itself never grows
   and the page never scrolls sideways. */
.dk-filemap__rows {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 1 1 auto;
  min-width: 0;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
}
.dk-filemap__rows::-webkit-scrollbar { height: 0; }
.dk-filemap__empty {
  color: var(--amber-dim);
  font-size: var(--fs-micro);
  font-style: normal;
  white-space: nowrap;
}

.dk-filemap__row {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  flex: 0 0 auto;
  max-width: 340px;
  padding: 2px 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--raised-2);
  font-size: var(--fs-micro);
  transition: border-color var(--t) var(--ease);
}
.dk-filemap__row--shared { border-color: var(--border-info); }        /* cyan: shared */
.dk-filemap__row--conflict {                                          /* red: collision */
  border-color: var(--border-danger);
  background: rgb(var(--red-rgb) / 10%);
}

.dk-filemap__path {
  display: inline-flex;
  align-items: baseline;
  gap: 2px;
  min-width: 0;
}
.dk-filemap__dir {            /* the directory is noise — dim it and let it truncate */
  color: var(--amber-dim);
  max-width: 130px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  direction: rtl;             /* keep the END of the path, which is the informative part */
  text-align: left;
}
.dk-filemap__base { color: var(--amber); white-space: nowrap; }
.dk-filemap__row--conflict .dk-filemap__base { color: var(--red); }

.dk-filemap__agents { display: inline-flex; gap: 3px; }
.dk-filemap__agent {
  display: inline-flex;
  align-items: baseline;
  gap: 3px;
  padding: 0 4px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: transparent;
  color: var(--cyan);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  cursor: pointer;
  max-width: 130px;
  transition: background var(--t) var(--ease), border-color var(--t) var(--ease);
}
.dk-filemap__agent:hover { background: var(--hover); border-color: var(--cyan); }
.dk-filemap__agent-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dk-filemap__ops { color: var(--amber-dim); }
.dk-filemap__kind { color: var(--amber-dim); }
.dk-filemap__gated {
  color: var(--red);
  text-transform: uppercase;
  font-size: var(--fs-micro);
  padding: 0 4px;
  border: 1px solid var(--border-danger);
  border-radius: var(--radius);
  white-space: nowrap;
}

#dk-filemap {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: var(--gap);
  height: var(--filemap-h);
  padding: 0 var(--pad);
  background: var(--surface);
  border-top: 1px solid var(--border);
  overflow: hidden;
}
#dk-filemap[data-expanded="true"] {
  height: auto;
  max-height: 40vh;
  align-items: stretch;
  flex-direction: column;
  overflow-y: auto;
  padding-bottom: 6px;
}
.dk-filemap-label {
  flex: 0 0 auto;
  color: var(--amber-dim);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  cursor: pointer;
  padding: 4px 0;
}
.dk-filemap-label:hover { color: var(--amber); }
#dk-filemap-rows {
  display: flex;
  gap: var(--gap);
  overflow-x: auto;
  flex: 1 1 auto;
  align-items: center;
}
#dk-filemap[data-expanded="true"] #dk-filemap-rows {
  flex-direction: column;
  align-items: stretch;
  overflow-x: hidden;
}/* >1 agent, no mutation collision -> shared (cyan). Collision -> conflict (red). */
.dk-file-row[data-shared="true"] { border-color: var(--border-info); color: var(--cyan); }   /* mutations are red (§11) */
.dk-file-op[data-op="read"] { color: var(--cyan); }

/* ==========================================================================
 * FOOTER ALERTS (§10 — the third place a conflict must show)
 * ==========================================================================*/
#dk-footer {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: var(--gap);
  min-height: var(--footer-h);
  padding: 0 var(--pad);
  background: var(--surface);
  border-top: 1px solid var(--border);
  overflow-x: auto;
}
#dk-footer:empty { display: none; }
/* ==========================================================================
 * COMPOSER (the user's turn — cyan, because it is user input, §11)
 * ==========================================================================*/
#dk-composer {
  flex: 0 0 auto;
  display: flex;
  align-items: flex-end;
  gap: var(--gap);
  padding: 8px var(--pad);
  background: var(--surface);
  border-top: 1px solid var(--border);
}
.dk-prompt-sigil {
  color: var(--amber);
  font-weight: 700;
  text-shadow: var(--glow);
  padding-bottom: 6px;
  user-select: none;
}
#dk-input {
  flex: 1 1 auto;
  resize: none;
  min-height: 34px;
  max-height: 28vh;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  /* Text you are TYPING is amber, not cyan. §11 assigns cyan to user input, but that rule is
     about the sent message in the transcript — while composing, the caret and the glyphs it
     lays down should read as one thing, and an amber caret dragging cyan text behind it does
     not. The echoed message in the lane is still cyan. */
  color: var(--amber);
  caret-color: var(--amber);
  padding: 6px 8px;
  font-family: var(--font-mono);
  font-size: var(--fs-base);
  line-height: var(--lh);
}
#dk-input:focus { outline: none; border-color: var(--amber); box-shadow: var(--glow-box); }
#dk-input::placeholder { color: rgb(var(--amber-dim-rgb) / 85%); }
#dk-composer .dk-composer-actions { display: flex; gap: 6px; align-items: flex-end; }

/* Permission-mode control (§12): MANUAL quiet outline / EDIT amber / AUTO solid red — a gate
   that is OFF on a shell-granting tool is a state you should always be able to SEE. */
.dk-auto {
  flex: 0 0 auto;
  height: 34px;
  padding: 0 10px;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--amber-dim);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  cursor: pointer;
}
.dk-auto:hover { color: var(--amber); border-color: var(--border-amber, rgb(var(--amber-rgb) / 45%)); }
.dk-auto[data-mode="edit"] {
  color: var(--amber);
  border-color: var(--border-amber, rgb(var(--amber-rgb) / 45%));
  background: rgb(var(--amber-rgb) / 10%);
  font-weight: 700;
}
.dk-auto[data-mode="auto"] {
  background: var(--red);
  border-color: var(--red);
  color: var(--bg);
  font-weight: 700;
  box-shadow: var(--glow-box-red);
}

/* Lazy-history sentinel: the pill that says how much older history is parked above. */
.dk-history-more {
  align-self: center;
  margin: 8px auto;
  padding: 4px 14px;
  background: transparent;
  border: 1px dashed var(--border);
  border-radius: 12px;
  color: var(--amber-dim);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  cursor: pointer;
}
.dk-history-more:hover { color: var(--amber); border-color: var(--amber); }

/* A diff promoted to the conversation log (file edits are content, not tool plumbing). */
.dk-diff-block { margin: 10px 0; }

/* Icon action buttons: a square STOP and an up-arrow SEND. Fixed square hit target, glyph
   drawn in currentColor by the inline SVGs. */
.dk-send, .dk-cancel {
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--surface);
  cursor: pointer;
  transition: color var(--t) var(--ease), border-color var(--t) var(--ease), background var(--t) var(--ease);
}
/* SEND — amber "go", and GREYED + inert until there is something to send. */
.dk-send { color: var(--amber); border-color: var(--border-amber, rgb(var(--amber-rgb) / 45%)); }
.dk-send:hover:not(:disabled) { background: rgb(var(--amber-rgb) / 12%); box-shadow: var(--glow-box); }
.dk-send:disabled {
  color: var(--amber-dim);
  opacity: 0.4;
  cursor: not-allowed;
  border-color: var(--border);
  background: transparent;
}
/* STOP — red square (§11: red = interrupt/destructive). */
.dk-cancel { color: var(--red); border-color: var(--border-danger); }
.dk-cancel:hover:not(:disabled) { background: rgb(var(--red-rgb) / 12%); box-shadow: var(--glow-box-red); }
.dk-cancel:disabled { color: var(--amber-dim); opacity: 0.4; cursor: not-allowed; border-color: var(--border); }

/* ==========================================================================
 * CHAT MODE (§9 — single stream, no cockpit chrome)
 * ==========================================================================*/
#dk-chat {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: var(--pad) calc(var(--pad) * 2);
  display: flex;
  flex-direction: column;
  gap: var(--gap);
}
#dk-chat .dk-msg { max-width: 900px; width: 100%; align-self: center; }

/* ==========================================================================
 * LOGIN GATE (§6 — Google Sign-In. The ONLY thing visible before auth.)
 * ==========================================================================*/
#dk-login {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100vh;
  gap: var(--gap);
  background: var(--bg);
}
.dk-login-card {
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--glow-box);
  padding: 28px 32px;
  min-width: 320px;
  text-align: center;
}
.dk-login-card .dk-brand { font-size: 26px; display: block; margin-bottom: 4px; }
.dk-login-tag {
  color: var(--amber-dim);
  font-size: var(--fs-micro);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  margin-bottom: 20px;
}
#dk-gsi-button { display: flex; justify-content: center; min-height: 44px; }
#dk-login-error {
  margin-top: 14px;
  color: var(--red);
  font-size: var(--fs-small);
  min-height: 1em;
  text-shadow: var(--glow-red);
}
#dk-login-error:empty { display: none; }

/* ==========================================================================
 * SETTINGS PANEL (§19 flippables — wired by js/theme.js)
 * ==========================================================================*/
#dk-settings {
  position: fixed;
  top: var(--topbar-h);
  right: 0;
  z-index: 1070;
  width: 300px;
  max-width: 92vw;
  display: none;
  flex-direction: column;
  gap: 10px;
  padding: 12px;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: 0 0 0 var(--radius-lg);
  box-shadow: var(--glow-box);
}
#dk-settings[data-open="true"] { display: flex; }
.dk-setting { display: flex; flex-direction: column; gap: 3px; }
.dk-setting > label {
  color: var(--amber-dim);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.1em;
}
.dk-setting-hint { color: var(--amber-dim); font-size: var(--fs-micro); opacity: 0.8; }

/* ------------------------------------------------------------- misc bits - */

/* `hidden` MUST WIN.
 *
 * The UA's `[hidden] { display: none }` sits in the user-agent stylesheet, so ANY author rule
 * that sets `display` outranks it — and an inline `style.display` outranks that. js/lanes.js
 * collapses a lane by toggling `hidden` on the rail / the expanded body / the attention badges
 * (and it also sets a layout-critical inline `display: flex` so the layout survives with no CSS
 * at all). Without this guard, `.dk-rail { display: flex }` and that inline style both beat the
 * hidden attribute: the rail and the full lane render AT THE SAME TIME, the collapse-to-rail of
 * §9 never visibly happens, and the attention badge shows permanently.
 *
 * `!important` in an author sheet is the one thing that outranks a normal inline style, which is
 * exactly why it is warranted here and essentially nowhere else.
 */
[hidden] { display: none !important; }

.dk-empty {
  margin: auto;
  color: var(--amber-dim);
  font-size: var(--fs-small);
  text-align: center;
  padding: 24px;
}
/* The "no messages yet" placeholder retires ITSELF the moment real content exists. It used to be
 * removed by containerFor() in app.js as a side effect of merely RESOLVING a container, so a
 * render-nothing frame (agent_state) blanked the empty state before any message had landed.
 * Presence of content is a fact CSS can see — so CSS owns it. (.dk-empty is only minted inside
 * #dk-chat — index.html — lane bodies have no placeholder; extend this selector if that changes.) */
#dk-chat:has(.dk-msg, .dk-notice, .dk-tool-card, .dk-tool-group) > .dk-empty { display: none; }.dk-sep { color: var(--amber-dim); opacity: 0.5; }.dk-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ==========================================================================
 * IMAGE BLOCK SUB-ELEMENTS (§13)
 * render/image.js emits .dk-image-img / .dk-image-error / .dk-image-meta /
 * .dk-image-expand and the shared lightbox. Only `.dk-image img` was styled, so
 * the caption's expand control rendered as a native grey UA button — a fifth hue
 * (§18) on every screenshot in the cockpit.
 * ==========================================================================*/
.dk-image-img { cursor: zoom-in; }
.dk-image-cap {
  display: flex;
  align-items: center;
  gap: 6px;
}
.dk-image-meta { color: var(--amber-dim); font-size: var(--fs-micro); }
.dk-image-expand {
  margin-left: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: transparent;
  color: var(--amber-dim);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 0 5px;
  cursor: pointer;
  transition: color var(--t) var(--ease), border-color var(--t) var(--ease);
}
.dk-image-expand:hover { color: var(--amber); border-color: var(--amber); box-shadow: var(--glow-box); }
.dk-image-error { color: var(--red); font-size: var(--fs-micro); padding: 4px 6px; }

/* The lightbox is styled by ID (#dk-lightbox, above). These rules make it work even
   when image.js has to mint the overlay itself (no index.html), and style the close
   control, which had no rule at all. */
.dk-lightbox { cursor: zoom-out; }
.dk-lightbox-img { max-width: 94vw; max-height: 90vh; }
.dk-lightbox-close {
  position: absolute;
  top: 12px;
  right: 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--amber);
  font-family: var(--font-mono);
  font-size: var(--fs-lg);
  line-height: 1;
  padding: 2px 8px;
  cursor: pointer;
}
.dk-lightbox-close:hover { border-color: var(--red); color: var(--red); box-shadow: var(--glow-box-red); }

/* ==========================================================================
 * RAIL LIVENESS (§9 attention rule)
 * A collapsed lane must never hide that its agent is WORKING or BLOCKED. The dot
 * already pulses (motion.css); this puts the state on the rail itself so a live
 * agent reads as live at 46px wide.
 * ==========================================================================*/
.dk-rail[data-state="thinking"],
.dk-rail[data-state="streaming"],
.dk-rail[data-state="tool_running"] {
  box-shadow: inset 0 0 0 1px rgb(var(--cyan-rgb) / 40%);   /* cyan = in progress (§11) */
}
.dk-rail[data-attention="permission"],
.dk-rail[data-attention="error"] {
  box-shadow: inset 0 0 0 1px var(--red);                   /* red = you are blocked (§11) */
}
.dk-lane-stop:disabled { opacity: 0.35; cursor: not-allowed; }
.dk-lane-stop:not(:disabled) { color: var(--red); }

/* A KILLED LANE MUST BE UNMISSABLE (§11: red = denials, failed tasks, destructive).
   motion.css groups `cancelled` with idle/done and paints the dot dim amber, so a lane you
   just killed looked exactly like one that finished cleanly — the single most important thing
   to be able to tell apart after you hit stop. components.css loads last, so these win. */
.dk-status-dot[data-state="cancelled"] { background: var(--red); box-shadow: var(--glow-box-red); }
.dk-lane[data-state="cancelled"] { box-shadow: inset 0 0 0 1px rgb(var(--red-rgb) / 55%); }
.dk-lane[data-state="cancelled"] .dk-lane-name,
.dk-lane[data-state="cancelled"] .dk-lane-desc { color: var(--red); text-shadow: var(--glow-red); }
.dk-rail[data-state="cancelled"] { box-shadow: inset 0 0 0 1px rgb(var(--red-rgb) / 55%); }
.dk-rail[data-state="cancelled"] .dk-rail-name { color: var(--red); }

/* ==========================================================================
 * COMPOSER TRAY — attachments, paste chips, queued turns (js/composer.js)
 * Sits directly above #dk-composer. Cyan = user input / staged input (§11);
 * red = a rejection.
 * ==========================================================================*/
.dk-composer-tray {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 0 var(--pad);
  background: var(--surface);
}
.dk-composer-tray:empty { display: none; }
.dk-tray-row {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 0;
  min-width: 0;
}
/* `:first-child` would skip a hidden row and leave the visible one with no rule, so every
   row carries its own top border. */
.dk-tray-row { border-top: 1px solid var(--border); }

/* SLASH-COMMAND PREVIEW MENU (user, 2026-07-17): appears above the composer when the field
   starts with '/'. Arrow-navigable, Enter/Tab to run, click to run. */
.dk-slash-menu { display: none; flex-direction: column; padding: 4px; gap: 2px; }
.dk-slash-menu[data-on="true"] { display: flex; }
.dk-slash-item {
  display: flex;
  align-items: baseline;
  gap: 10px;
  width: 100%;
  padding: 6px 10px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius);
  text-align: left;
  cursor: pointer;
  font-family: var(--font-mono);
}
.dk-slash-item[data-selected="true"] { background: var(--surface); border-color: var(--amber); }
.dk-slash-name { color: var(--amber); font-weight: 700; font-size: var(--fs-small); flex: 0 0 auto; }
.dk-slash-desc { color: var(--amber-dim); font-size: var(--fs-micro); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dk-tray-label {
  flex: 0 0 auto;
  color: var(--amber-dim);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  white-space: nowrap;
}
.dk-tray-queue .dk-tray-label { color: var(--cyan); }   /* in flight = in progress (§11) */
.dk-tray-attach .dk-tray-label { color: var(--amber-dim); }   /* staged, not yet sent */
.dk-tray-btn {
  flex: 0 0 auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: transparent;
  color: var(--amber-dim);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 2px 6px;
  cursor: pointer;
  transition: color var(--t) var(--ease), border-color var(--t) var(--ease);
}
.dk-tray-btn:hover { color: var(--amber); border-color: var(--amber); box-shadow: var(--glow-box); }

.dk-chips {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 1 1 auto;
  min-width: 0;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
}
.dk-chips::-webkit-scrollbar { height: 0; }

.dk-chip {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
  max-width: 320px;
  border: 1px solid var(--border-info);
  border-radius: var(--radius);
  background: rgb(var(--cyan-rgb) / 6%);
  font-size: var(--fs-micro);
  overflow: hidden;
}
.dk-chip[data-kind="queued"] {
  border-style: dashed;                       /* not yet consumed by a turn */
}
.dk-chip-open {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--cyan);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  padding: 2px 6px;
  cursor: pointer;
}
.dk-chip-open:hover { background: rgb(var(--cyan-rgb) / 12%); }
.dk-chip-thumb {
  width: 20px;
  height: 20px;
  object-fit: cover;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  flex: 0 0 auto;
}
.dk-chip-icon { color: var(--cyan); flex: 0 0 auto; }
.dk-chip-name {
  color: var(--cyan);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.dk-chip-meta { color: var(--amber-dim); white-space: nowrap; flex: 0 0 auto; }
.dk-chip-remove {
  flex: 0 0 auto;
  border: 0;
  border-left: 1px solid var(--border);
  background: transparent;
  color: var(--amber-dim);
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  line-height: 1;
  padding: 3px 6px;
  cursor: pointer;
}
.dk-chip-remove:hover { color: var(--red); background: rgb(var(--red-rgb) / 12%); }

/* A rejected file (too big / unreadable) — red, inline, transient (§11). */
.dk-composer-notice {
  padding: 4px 0 6px;
  color: var(--red);
  font-size: var(--fs-micro);
  text-shadow: var(--glow-red);
}

/* Drop target: the composer lights CYAN while a file is over it (user input, §11). */
#dk-composer[data-dragover="true"] {
  outline: 1px dashed var(--cyan);
  outline-offset: -2px;
  background: rgb(var(--cyan-rgb) / 5%);
}

/* Pasted-text preview overlay (images reuse the §13 lightbox). */
.dk-preview {
  position: fixed;
  inset: 0;
  z-index: 1085;
  display: none;
  align-items: center;
  justify-content: center;
  background: rgb(var(--bg-rgb) / 92%);
}
.dk-preview[data-open="true"] { display: flex; }
.dk-preview-box {
  display: flex;
  flex-direction: column;
  width: min(900px, 92vw);
  max-height: 84vh;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--glow-box);
  overflow: hidden;
}
.dk-preview-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  border-bottom: 1px solid var(--border);
}
.dk-preview-title {
  flex: 1 1 auto;
  color: var(--amber);
  font-size: var(--fs-small);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dk-preview-close {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: transparent;
  color: var(--amber-dim);
  font-family: var(--font-mono);
  font-size: var(--fs-base);
  line-height: 1;
  padding: 1px 7px;
  cursor: pointer;
}
.dk-preview-close:hover { color: var(--red); border-color: var(--red); }
.dk-preview-body {
  margin: 0;
  padding: 10px;
  overflow: auto;
  color: var(--cyan);                    /* pasted text is USER INPUT (§11) */
  font-size: var(--fs-small);
  white-space: pre-wrap;
  word-break: break-word;
}

/* ==========================================================================
 * PERSONA ROSTER ROW (js/personas.js) — one row per saved agent in the roster.
 * ==========================================================================*/
.dk-agent-row {
  display: grid;
  /* Every row is its OWN grid, so any content-sized column (`auto`, or an unbounded `fr`) is
     measured per row and the columns land in different places on each line — the roster read as
     ragged. Two of them were also unbounded `fr`, so on a wide screen the name and tool columns
     ballooned to ~600px each and flung the metrics to the far edge.
     Fixed tracks everywhere except the tool (which absorbs the slack), so every row aligns and
     the STOP buttons form a single column. */
  grid-template-columns: 10px 200px 88px minmax(0, 1fr) 56px 72px 64px;
  align-items: center;
  gap: 8px;
  padding: 2px 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--raised-2);
  font-size: var(--fs-micro);
}
.dk-agent-row[data-state="awaiting_permission"] { border-color: var(--red); }
.dk-agent-row[data-state="error"],
.dk-agent-row[data-state="cancelled"] { border-color: rgb(var(--red-rgb) / 55%); }
.dk-agent-row[data-stopping="true"] { border-color: var(--red); background: rgb(var(--red-rgb) / 10%); }.dk-agent-name {
  border: 0;
  background: transparent;
  color: var(--amber);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  text-align: left;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: pointer;
  padding: 0;
}
.dk-agent-name:hover { text-shadow: var(--glow); }.dk-agent-row[data-state="thinking"] .dk-agent-state,
.dk-agent-row[data-state="streaming"] .dk-agent-state,
.dk-agent-row[data-state="tool_running"] .dk-agent-state { color: var(--cyan); }
.dk-agent-row[data-state="awaiting_permission"] .dk-agent-state,
.dk-agent-row[data-state="error"] .dk-agent-state,
.dk-agent-row[data-state="cancelled"] .dk-agent-state { color: var(--red); }
/* ==========================================================================
 * ARTIFACTS (js/artifacts.js) — a right-hand dock, newest first, versioned.
 * The rendered view of an 'html'/'svg' artifact is UNTRUSTED MODEL OUTPUT inside
 * a sandboxed iframe (no allow-same-origin) — see the note in artifacts.js.
 * ==========================================================================*/
.dk-artifacts {
  position: fixed;
  top: var(--topbar-h);
  right: 0;
  bottom: 0;
  z-index: 1060;
  width: min(480px, 96vw);
  display: none;
  flex-direction: column;
  background: var(--surface);
  border-left: 1px solid var(--border-strong);
  box-shadow: var(--glow-box);
}
.dk-artifacts[data-open="true"] { display: flex; }
.dk-artifacts-head {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
  padding: 6px var(--pad);
  border-bottom: 1px solid var(--border);
}
.dk-artifacts-title {
  flex: 1 1 auto;
  color: var(--amber);
  font-size: var(--fs-small);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  text-shadow: var(--glow);
}
.dk-artifacts-count {
  color: var(--amber-dim);
  font-size: var(--fs-micro);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0 5px;
}
.dk-artifacts-btn {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: transparent;
  color: var(--amber-dim);
  font-family: var(--font-mono);
  font-size: var(--fs-base);
  line-height: 1;
  padding: 1px 7px;
  cursor: pointer;
}
.dk-artifacts-btn:hover { color: var(--amber); border-color: var(--amber); }

.dk-artifacts-list {
  flex: 0 0 auto;
  max-height: 32%;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 6px var(--pad);
  border-bottom: 1px solid var(--border);
}
.dk-artifacts-empty { color: var(--amber-dim); font-size: var(--fs-micro); }
.dk-artifact-item {
  display: flex;
  align-items: baseline;
  gap: 6px;
  width: 100%;
  border: 1px solid transparent;
  border-radius: var(--radius);
  background: transparent;
  color: var(--amber-dim);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  text-align: left;
  padding: 3px 6px;
  cursor: pointer;
  transition: background-color var(--t) var(--ease), border-color var(--t) var(--ease);
}
.dk-artifact-item:hover { background: var(--hover); }
.dk-artifact-item[data-active="true"] {
  border-color: var(--border-strong);
  background: var(--active);
  color: var(--amber);
}
.dk-artifact-kind {
  flex: 0 0 auto;
  color: var(--cyan);                   /* structural metadata (§11) */
  text-transform: uppercase;
  letter-spacing: 0.06em;
  border: 1px solid var(--border-info);
  border-radius: var(--radius);
  padding: 0 4px;
}
.dk-artifact-title {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dk-artifact-version { flex: 0 0 auto; color: var(--amber-dim); }
.dk-artifact-when { flex: 0 0 auto; margin-left: auto; color: var(--amber-dim); font-size: var(--fs-micro); }

.dk-artifacts-view {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.dk-artifact { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
.dk-artifact-head {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
  flex-wrap: wrap;
  padding: 6px var(--pad);
  border-bottom: 1px solid var(--border);
}
.dk-artifact-head .dk-artifact-title { color: var(--amber); font-size: var(--fs-small); }
.dk-artifact-meta,
.dk-artifact-history { color: var(--amber-dim); font-size: var(--fs-micro); white-space: nowrap; }
.dk-artifact-btn {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: transparent;
  color: var(--amber-dim);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 1px 7px;
  cursor: pointer;
  transition: color var(--t) var(--ease), border-color var(--t) var(--ease);
}
.dk-artifact-btn:hover { color: var(--amber); border-color: var(--amber); box-shadow: var(--glow-box); }
.dk-artifact-btn[data-active="true"] { color: var(--cyan); border-color: var(--cyan); }

.dk-artifact-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
  padding: var(--pad);
  display: flex;
  flex-direction: column;
}
/* The jail. White is the only sane default backdrop for arbitrary model HTML, and it
   is INSIDE the frame — the app's own surfaces stay on the palette. */
.dk-artifact-frame {
  flex: 1 1 auto;
  width: 100%;
  min-height: 320px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
}
.dk-artifact-source {
  margin: 0;
  color: var(--cyan);
  font-size: var(--fs-small);
  white-space: pre-wrap;
  word-break: break-word;
}
.dk-artifact-code { display: flex; flex-direction: column; gap: 4px; min-height: 0; }
.dk-artifact-lang {
  align-self: flex-start;
  color: var(--cyan);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  border: 1px solid var(--border-info);
  border-radius: var(--radius);
  padding: 0 5px;
}

/* Markdown artifact — the safe subset renderer. Amber body, cyan code (§11). */
.dk-artifact-md { color: var(--amber); font-size: var(--fs-base); }
.dk-artifact-md .dk-md-h { margin: 10px 0 4px; }
.dk-artifact-md .dk-md-p { margin: 0 0 8px; white-space: pre-wrap; word-break: break-word; }
.dk-artifact-md .dk-md-list { margin: 0 0 8px; padding-left: 20px; }
.dk-artifact-md .dk-md-list li { margin: 2px 0; }
.dk-artifact-md .dk-md-quote {
  margin: 0 0 8px;
  padding: 2px 0 2px 8px;
  border-left: 2px solid var(--border-info);
  color: var(--cyan);
}
.dk-artifact-md .dk-md-hr { margin: 10px 0; }
.dk-artifact-md .dk-md-strong { color: var(--amber); font-weight: 700; text-shadow: var(--glow); }
.dk-artifact-md .dk-md-em { color: var(--amber); font-style: italic; }

/* The re-open handle — only present once the tab HAS an artifact. */
.dk-artifacts-handle {
  position: fixed;
  right: 0;
  top: 40%;
  z-index: 1059;
  border: 1px solid var(--border-strong);
  border-right: 0;
  border-radius: var(--radius) 0 0 var(--radius);
  background: var(--surface);
  color: var(--amber);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  writing-mode: vertical-rl;
  padding: 10px 3px;
  cursor: pointer;
}
.dk-artifacts-handle:hover { background: var(--hover); text-shadow: var(--glow); }

/* ============================================================================
 * §10 per-agent CONTEXT DRAWER — the real styles.
 *
 * context-drawer.js emits ~30 BEM `dk-drawer__*` classes. components.css styled eight
 * hyphenated `dk-drawer-*` names, so exactly ONE rule (.dk-drawer) was ever matching and the
 * drawer rendered as raw unpadded text. This is the third component in this codebase lost to the
 * same drift (see the file map and the tool cards) — every class below is copied from what the
 * JS actually emits, not from what it ought to.
 *
 * The drawer is INFORMATIONAL, so it is cyan (§11): it shows what an agent was actually told at
 * spawn, never an inference about what it "knows".
 * ==========================================================================*/
.dk-drawer__toggle {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  padding: 4px 8px;
  border: 0;
  background: transparent;
  color: var(--cyan);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  text-align: left;
  cursor: pointer;
  transition: background var(--t) var(--ease);
}
.dk-drawer__toggle:hover { background: rgb(var(--cyan-rgb) / 8%); }
.dk-drawer__chevron { color: var(--cyan); flex: 0 0 auto; }
.dk-drawer__title {
  color: var(--cyan);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.dk-drawer__label { color: var(--amber); }
.dk-drawer__meta { color: var(--amber-dim); margin-left: auto; }
.dk-drawer__conflicts {
  color: var(--red);
  border: 1px solid var(--border-danger);
  border-radius: var(--radius);
  padding: 0 4px;
  text-shadow: var(--glow-red);
}

/* THE PADDING. The body is the thing that was rendering flush against the border. */
.dk-drawer__body {
  padding: 8px 10px 10px;
  border-top: 1px solid var(--border-info);
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.dk-drawer__section { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.dk-drawer__section--isolated { opacity: 0.9; }
.dk-drawer__h {
  margin: 0;
  color: var(--amber-dim);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  text-shadow: none;
}
.dk-drawer__desc,
.dk-drawer__summary,
.dk-drawer__hint {
  margin: 0;
  color: var(--cyan);
  font-size: var(--fs-small);
  line-height: var(--lh);
}
.dk-drawer__hint { color: var(--amber-dim); }
.dk-drawer__none { color: var(--amber-dim); font-size: var(--fs-small); }
.dk-drawer__status {
  margin-left: 6px;
  padding: 0 4px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--amber-dim);
  font-size: var(--fs-micro);
  text-transform: uppercase;
}
.dk-drawer__status[data-status="error"],
.dk-drawer__status[data-status="cancelled"] { color: var(--red); border-color: var(--border-danger); }

/* The prompt the agent was handed, verbatim (§10: show what was PASSED IN). */
.dk-drawer__prompt,
.dk-drawer__raw-json {
  margin: 0;
  padding: 6px 8px;
  max-height: 220px;
  overflow: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--cyan);
  font-size: var(--fs-micro);
  line-height: 1.45;
  white-space: pre-wrap;
  word-break: break-word;
}

.dk-drawer__files,
.dk-drawer__mentions { display: flex; flex-wrap: wrap; gap: 4px; }
.dk-drawer__file,
.dk-drawer__mention {
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
  max-width: 100%;
  padding: 2px 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--raised-2);
  color: var(--amber);
  font-size: var(--fs-micro);
  cursor: default;
}
.dk-drawer__file--shared { border-color: var(--border-info); cursor: pointer; }
.dk-drawer__file--conflict {
  border-color: var(--border-danger);
  background: rgb(var(--red-rgb) / 10%);
  color: var(--red);
  cursor: pointer;
}
.dk-drawer__file-path { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dk-drawer__file-ops,
.dk-drawer__file-shared { color: var(--amber-dim); }

.dk-drawer__raw { margin-top: 2px; }
.dk-drawer__raw-summary {
  color: var(--amber-dim);
  font-size: var(--fs-micro);
  cursor: pointer;
  list-style: none;
  user-select: none;
}
.dk-drawer__raw-summary:hover { color: var(--cyan); }

/* The roster is one row per agent, one LINE per row. Clamp every text cell: a stray long value
   (a summary, a long path) must ellipsis, never wrap and never widen the grid. */
.dk-agent-name,
.dk-agent-tool,
.dk-agent-state {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
  text-align: left;
}
/* ============================================================================
 * SURFACE LADDER — break up the edges between panels.
 *
 * Everything used to sit on one flat near-black with only a hairline border between panels, so
 * the tab bar, the lanes and the composer all bled into each other. Give each layer a slightly
 * lighter near-black GREY: elevation is carried by grey, meaning is still carried by the four
 * hues (§11), so the two never compete. Overrides the earlier amber-tinted --surface.
 * ==========================================================================*/
#dk-topbar,
#dk-tabbar,
#dk-filemap,
#dk-footer,
#dk-composer,
.dk-agents { background: var(--surface-1); }

#dk-lanes { background: var(--bg); }

.dk-lane-full,
.dk-rail,
.dk-settings,
#dk-settings,
.dk-toolcard,
.dk-tool-card,
.dk-drawer,
.dk-artifacts { background: var(--surface-2); }

/* The tab you are ON is the top of the stack — lift it, don't just outline it. */
.dk-tab { background: var(--surface-1); border: 1px solid transparent; border-bottom: 0; }
.dk-tab:hover { background: var(--surface-2); }
.dk-tab[data-active="true"] {
  background: var(--surface-3);
  border-color: var(--border);
  border-bottom-color: transparent;
}

/* Rows that can be hovered read as pickable. */
.dk-agent-row:hover,
.dk-filemap__row:hover { background: var(--surface-3); }

/* The lane you are reading sits above the page it is on. */
.dk-lane-head { background: var(--surface-3); }

/* The lane header's usage readout ("24.8k tok · 4s") sat flush against the chevron on the right
   edge — give it room to breathe. */
.dk-lane-usage { padding-right: 10px; }
.dk-lane-head { padding-right: 6px; }

/* Roster rows are pickable: the name is a real control, so make it read like one. */
.dk-agent-name {
  background: transparent;
  border: 0;
  color: var(--amber);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  cursor: pointer;
  padding: 0;
}
.dk-agent-name:hover { color: var(--cyan); text-decoration: underline; }

/* ============================================================================
 * SYNTAX HIGHLIGHTING (render/highlight.js) — inside the four colors (§11).
 *
 * A conventional scheme wants six or eight hues; we have four, and each already MEANS something.
 * So: AMBER carries structure (keywords, tags, calls), CYAN carries values (strings, numbers,
 * attributes — cyan is already "data/input" everywhere else in this UI), AMBER-DIM carries the
 * scaffolding you read past (comments, punctuation).
 * RED is deliberately absent: red means DANGER here. Spending it on `for` would blunt it exactly
 * where it has to land — a destructive tool, a conflict, a denial.
 * ==========================================================================*/
.dk-code .tok-com  { color: var(--amber-dim); font-style: italic; }
.dk-code .tok-str  { color: var(--cyan); }
.dk-code .tok-num  { color: var(--cyan); }
.dk-code .tok-kw   { color: var(--amber); font-weight: 600; }
.dk-code .tok-fn   { color: var(--amber); }
.dk-code .tok-tag  { color: var(--amber); }
.dk-code .tok-punc { color: rgb(var(--amber-dim-rgb) / 90%); }

.dk-code {
  padding: 8px 10px;
  margin: 6px 0;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
  overflow-x: auto;              /* wide code scrolls INSIDE its box; the page never does */
  max-width: 100%;
}
.dk-code code { color: var(--amber); }

/* SILENT THINKING — no text means no disclosure arrow.
   The API returns no reasoning text (encrypted signature only), so there is nothing to expand.
   A <details> with a twisty promises content behind it; showing one that opens onto an
   explanation of why it is empty is a small lie told repeatedly. Strip the marker and render it
   as what it is: a one-line note that the model thought quietly. */
/* Silent thinking is a LINE, not a panel: plain cyan text, no border, no surface, no twisty.
   There is nothing behind it to open, so it must not look like there is. */
.dk-thinking[data-redacted="true"] {
  border: 0;
  background: none;
  padding: 0;
  margin: 2px 0;
}
.dk-thinking[data-redacted="true"] > .dk-thinking-summary {
  list-style: none;
  cursor: default;
  padding: 0;
  background: none;
}
.dk-thinking[data-redacted="true"] > .dk-thinking-summary::-webkit-details-marker { display: none; }
.dk-thinking[data-redacted="true"] > .dk-thinking-summary::marker { content: ''; }
.dk-thinking[data-redacted="true"] > .dk-thinking-body { display: none; }
.dk-thinking[data-redacted="true"] .dk-thinking-label {
  color: var(--cyan);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.dk-thinking[data-redacted="true"] .dk-thinking-meta,
.dk-thinking[data-redacted="true"] .dk-thinking-dot { display: none; }

/* The roster is a map of what is ON SCREEN, so it must agree with the screen: an agent whose lane
   is collapsed to a rail reads as PUT AWAY (dim), one you are actually looking at reads as live
   (bright). Intensity carries state (§11) — the same idea the rails themselves use. */
.dk-agent-row[data-lane-state="rail"] .dk-agent-name { color: var(--amber-dim); }
.dk-agent-row[data-lane-state="rail"] { opacity: 0.72; }
.dk-agent-row[data-lane-state="expanded"] .dk-agent-name {
  color: var(--amber);
  text-shadow: var(--glow);
}
.dk-agent-row[data-lane-state="rail"]:hover { opacity: 1; }

/* ============================================================================
 * MARKDOWN (render/message.js). The model writes markdown; we were showing the asterisks.
 *
 * The body no longer needs `white-space: pre-wrap`: the renderer now emits real blocks for lines,
 * paragraphs and lists, so pre-wrap would double every gap. Code blocks keep their own <pre>.
 * ==========================================================================*/
.dk-msg-body { white-space: normal; }
.dk-msg-body .dk-code,
.dk-msg-body pre { white-space: pre; }

.dk-md-p { margin: 0; }
.dk-md-break { height: 0.55em; }

.dk-md-b { color: var(--amber); font-weight: 700; text-shadow: var(--glow); }
.dk-md-i { font-style: italic; }
.dk-md-s { text-decoration: line-through; opacity: 0.7; }

.dk-md-h {
  color: var(--amber);
  font-weight: 700;
  text-transform: none;
  letter-spacing: 0.02em;
  text-shadow: var(--glow);
  margin: 8px 0 3px;
}
.dk-md-h1 { font-size: var(--fs-lg); }
.dk-md-h2 { font-size: var(--fs-base); }
.dk-md-h3, .dk-md-h4, .dk-md-h5, .dk-md-h6 { font-size: var(--fs-base); color: rgb(var(--amber-rgb) / 88%); }

.dk-md-list { margin: 2px 0 4px; padding-left: 1.3em; }
.dk-md-li { margin: 1px 0; }
.dk-md-li::marker { color: var(--amber-dim); }

.dk-md-quote {
  border-left: 2px solid var(--border);
  padding-left: 8px;
  margin: 3px 0;
  color: var(--amber-dim);
}
.dk-md-hr { border-top: 1px solid var(--border); margin: 8px 0; }
.dk-md-link { color: var(--cyan); }

/* Markdown tables (render/message.js formatInline). The wrapper scrolls horizontally so a wide
   table can never widen the lane (§9: lanes own their overflow). */
.dk-md-table-wrap { overflow-x: auto; margin: 6px 0; }
.dk-md-table {
  border-collapse: collapse;
  font-size: var(--fs-base);
  min-width: 50%;
}
.dk-md-th, .dk-md-td {
  border: 1px solid var(--border);
  padding: 3px 10px;
  text-align: left;
  vertical-align: top;
}
.dk-md-th {
  color: var(--amber);
  font-weight: 700;
  background: rgb(var(--amber-rgb) / 6%);
}
.dk-md-table tbody tr:nth-child(even) { background: rgb(var(--amber-rgb) / 3%); }

/* ============================================================================
 * LANE LAYOUT — the orchestrator ABOVE, the subagents in a strip below.
 *
 * The orchestrator is the conversation: it takes your turns and spawns the rest. It is not a peer
 * of the subagents and must never be railed to 46px by a couple of busy ones (which is what the
 * old all-columns-equal layout allowed). It gets a full-width row on top; everything that collapses
 * expands and stacks horizontally lives underneath.
 * ==========================================================================*/
.dk-lane-group { gap: 6px; }

/* The orchestrator's row: a healthy slice of the height, resizable by the user, never collapsible.
   When there are no subagents at all it should take the whole tab. */
/* Heights are set inline by lanes.js as a fixed RATIO with a zero basis (3:2), so the split cannot
   drift with the content. No `resize` here: it made the height content-dependent, and the content
   is a transcript that grows while you watch it — the layout visibly walked around as text
   streamed. */
.dk-lane-main-host {
  min-height: 0;
  overflow: hidden;
}
.dk-lane-main-host > .dk-lane { flex: 1 1 auto; width: 100%; }
.dk-lane-main-host .dk-rail { display: none; }        /* nothing to collapse to */

/* The subagent strip. Collapses to nothing when no subagents are running, so a plain chat-style
   task does not carry an empty shelf. */
.dk-lane-strip {
  min-height: 0;
  border-top: 1px solid var(--border);
}
.dk-lane-strip[data-empty="true"] { display: none !important; }


/* ============================================================================
 * THE MACHINE ROOM — one pixel machine per agent, above the conversation.
 * It bobs while it works, carries a prop for what it is doing (document /
 * magnifier / gear), thinks in pixel bubbles, types, shakes red when blocked
 * on you (§9), grins when done, then hops off and cleans up after itself.
 * No controls on the row; hover a machine for its task and the stop action.
 * ==========================================================================*/
.dk-pager {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  flex: 0 0 auto;
  min-height: 46px;
  padding: 6px 10px 2px;
  background: var(--surface-1);
  /* The room sits BELOW the conversation, above the text entry — the edge goes on top. */
  border-top: 1px solid var(--border);
}
.dk-pager[data-empty="true"] { display: none; }

.dk-pager-agents {
  display: flex;
  gap: 14px;
  align-items: flex-end;
  flex: 1 1 auto;
  min-width: 0;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
}
.dk-pager-agents::-webkit-scrollbar { display: none; }

.dk-critter {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  flex: 0 0 auto;
  padding: 0 2px;
  background: transparent;
  border: 0;
  color: var(--amber-dim);
  font-family: var(--font-mono);
  cursor: pointer;
}
.dk-critter svg {
  width: 35px;
  height: 38px;
  overflow: visible;
  display: block;
}
.dk-critter-name {
  max-width: 9ch;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-size: var(--fs-micro);
  letter-spacing: 0.05em;
  color: var(--amber-dim);
}
.dk-critter:hover .dk-critter-name,
.dk-critter:focus-visible .dk-critter-name { color: var(--amber); }
.dk-critter:focus-visible { outline: 1px solid var(--amber); outline-offset: 2px; border-radius: var(--radius); }

/* Chassis — always the quiet amber of hardware at rest. */
.dk-critter .crt-body { fill: var(--surface); stroke: var(--amber-dim); stroke-width: 1; }
.dk-critter .crt-screen { fill: var(--bg); stroke: var(--amber-dim); stroke-width: 1; }
.dk-critter .crt-slot,
.dk-critter .crt-badge,
.dk-critter .crt-base { fill: var(--amber-dim); }

/* The face is the state (§11 palette): cyan while working, red when it needs you,
   amber for the endings. Exactly one face group shows per mood. */
.dk-critter [data-face],
.dk-critter [data-prop] { display: none; }
.dk-critter[data-mood="work"] [data-face="work"] { display: block; fill: var(--cyan); }
.dk-critter[data-mood="wait"] [data-face="wait"] { display: block; fill: var(--red); }
.dk-critter[data-mood="happy"] [data-face="happy"] { display: block; fill: var(--amber); }
.dk-critter[data-mood="sad"] [data-face="sad"] { display: block; fill: var(--red); }
.dk-critter[data-mood="flat"] [data-face="flat"] { display: block; fill: var(--amber-dim); }
.dk-critter[data-mood="sleep"] [data-face="sleep"] { display: block; fill: var(--amber-dim); }
.dk-critter[data-mood="sleep"] .crt-screen { stroke: var(--amber-dim); }
.dk-critter[data-mood="sleep"] [data-prop="zzz"] { display: block; fill: var(--amber-dim); }
.dk-critter[data-mood="wait"] .crt-screen,
.dk-critter[data-mood="sad"] .crt-screen { stroke: var(--red); }

/* Activity props — what the machine is DOING right now (thought bubble, typing
   hands, carried document, magnifier, gear). Shown only while working. */
.dk-critter[data-activity="think"] [data-prop="think"] { display: block; fill: var(--cyan); }
.dk-critter[data-activity="type"] [data-prop="type"] { display: block; fill: var(--amber-dim); }
.dk-critter[data-activity="doc"] [data-prop="doc"] { display: block; fill: var(--amber); }
.dk-critter[data-activity="doc"] .crt-doc-page { fill: var(--surface); stroke: var(--amber); stroke-width: 1; }
.dk-critter[data-activity="mag"] [data-prop="mag"] { display: block; fill: var(--cyan); }
.dk-critter[data-activity="mag"] .crt-mag-lens { fill: none; stroke: var(--cyan); stroke-width: 1; }
.dk-critter[data-activity="gear"] [data-prop="gear"] { display: block; fill: var(--amber-dim); }

/* Agent tooltip — one shared fixed card (lanes.js). Hoverable: it carries the stop button. */
.dk-agent-tip {
  position: fixed;
  z-index: 1090;
  max-width: 360px;
  padding: 8px 10px;
  background: var(--raised-2, var(--surface));
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 6px 24px rgb(0 0 0 / 45%);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
}
.dk-agent-tip-head { display: flex; gap: 10px; align-items: baseline; justify-content: space-between; }
.dk-agent-tip-name { color: var(--amber); font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; }
.dk-agent-tip-state { color: var(--cyan); white-space: nowrap; }
.dk-agent-tip-role { margin-top: 2px; color: var(--cyan); font-size: var(--fs-micro); font-weight: 600; text-transform: uppercase; letter-spacing: 0.07em; }
.dk-agent-tip-task { margin-top: 4px; color: var(--amber); white-space: pre-wrap; word-break: break-word; }
.dk-agent-tip-brief { margin-top: 4px; color: var(--amber-dim); }
.dk-agent-tip-stop {
  margin-top: 8px;
  padding: 2px 10px;
  background: transparent;
  border: 1px solid var(--red);
  border-radius: var(--radius);
  color: var(--red);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  cursor: pointer;
}
.dk-agent-tip-stop:hover { background: rgb(var(--red-rgb, 255 82 82) / 12%); }

/* A paged-away lane is hidden outright — no rails in the strip any more. */
.dk-lane-strip .dk-rail { display: none; }
.dk-lane-strip > .dk-lane[hidden] { display: none !important; }
.dk-lane-strip > .dk-lane { flex: 1 1 100%; min-width: 0; }

/* ============================================================================
 * FILE MAP, REWORKED — a chip that opens, not a permanent smear.
 *
 * It used to be a bar of file chips across the bottom of every tab. On a real task that is dozens
 * of files: an unreadable row of text, present every second of every session, for something you
 * glance at occasionally. Now it is one compact chip that expands into a panel.
 *
 * The one thing that is NEVER tucked away is a CONFLICT (§10 says a collision must be impossible
 * to miss): the chip itself goes red and states the count, and the panel opens on its own the first
 * time a conflict appears. Hiding the map is fine. Hiding a clobber is not.
 * ==========================================================================*/
#dk-filemap {
  position: relative;
  height: auto;
  min-height: 24px;
  padding: 2px var(--pad);
  overflow: visible;
}

.dk-filemap__chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 1px 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-2);
  color: var(--amber-dim);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  cursor: pointer;
  transition: border-color var(--t) var(--ease), color var(--t) var(--ease);
}
.dk-filemap__chip:hover { color: var(--amber); border-color: var(--amber); }
.dk-filemap__chevron { color: var(--amber-dim); }

/* A conflict is not hideable. */
.dk-filemap__chip[data-conflicts]:not([data-conflicts="0"]) {
  color: var(--red);
  border-color: var(--red);
  background: rgb(var(--red-rgb) / 12%);
  box-shadow: var(--glow-box-red);
}

/* The panel floats ABOVE the layout — opening the map must not shove the lanes around. */
.dk-filemap__panel {
  display: none;
  position: absolute;
  bottom: calc(100% + 4px);
  left: var(--pad);
  right: var(--pad);
  z-index: 40;
  max-height: 44vh;
  overflow: auto;
  padding: 8px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 -6px 18px rgb(0 0 0 / 55%);
}
#dk-filemap[data-open="true"] .dk-filemap__panel { display: block; }

/* Inside the panel the rows are a LIST — one file per line, readable. Not a horizontal smear. */
#dk-filemap .dk-filemap__rows {
  display: flex;
  flex-direction: column;
  gap: 3px;
  overflow: visible;
}
#dk-filemap .dk-filemap__row { max-width: 100%; width: 100%; }
#dk-filemap .dk-filemap__dir { max-width: 46ch; }

/* ============================================================================
 * CHAT MODE IS BARE (§9: "a SINGLE conversational stream. No tabs, no lanes, no rails, no file
 * map"). Anything born of the coding cockpit must be gone — not merely empty.
 *
 * These leaked because each was added later and self-mounted into the shell: the artifact dock is
 * position:fixed (so hiding #dk-lanes never touched it), and the pager/roster/footer are outside
 * the lane container. Hide them by MODE, at the top level, so a new cockpit widget cannot quietly
 * reappear in chat the way these did.
 * ==========================================================================*/
body[data-mode="chat"] .dk-artifacts,
body[data-mode="chat"] .dk-workflows,
body[data-mode="chat"] .dk-threads,
body[data-mode="chat"] .dk-shells-handle,
body[data-mode="chat"] .dk-threads-handle,
body[data-mode="chat"] .dk-workflows-handle,
body[data-mode="chat"] .dk-pager,
body[data-mode="chat"] .dk-agents,
body[data-mode="chat"] #dk-footer,
body[data-mode="chat"] .dk-lane-strip,
body[data-mode="chat"] .dk-lane-main-host,
body[data-mode="chat"] #dk-composer-tray { display: none !important; }

/* The composer always talks to the orchestrator, and the operator knows it — the label that
   used to say so here read as redundant chrome and was removed by request. The bare sigil is
   the whole cue. */

/* ============================================================================
 * PROCESS LEGIBILITY — the CLI's best trick, ported.
 *
 * A finished step must STOP COMPETING for your eye. The CLI dims a completed line to a fact and
 * keeps the running one bright; a transcript where every step shouts equally is one you cannot
 * skim. So: running = full strength + a live clock; done = recessive, folded, one-line outcome.
 *
 * (Not copied from the CLI: its green=done / red=error convention. Red MEANS danger here (§11) and
 * there is no green in the palette. Intensity carries done-ness instead — which is the same idea
 * the rails and the roster already use.)
 * ==========================================================================*/
.dk-tool-card[data-state="ok"] {
  opacity: 0.62;
  border-color: var(--border);
  background: var(--raised-2);
  transition: opacity var(--t) var(--ease);
}
.dk-tool-card[data-state="ok"]:hover { opacity: 1; }
.dk-tool-card[data-state="ok"] .dk-tool-name { color: var(--amber-dim); }
.dk-tool-card[data-state="ok"][data-open="false"] .dk-tool-body,
.dk-tool-card[data-state="ok"][data-open="false"] .dk-tool-input { display: none; }

/* An error never recedes. */
.dk-tool-card[data-state="error"] { opacity: 1; border-color: var(--red); }
.dk-tool-card[data-state="error"] .dk-tool-name { color: var(--red); }

/* The live clock. Dim while running (it is context, not content); frozen when done. */
.dk-tool-elapsed {
  margin-left: auto;
  padding-left: 8px;
  color: var(--amber-dim);
  font-size: var(--fs-micro);
  font-variant-numeric: tabular-nums;   /* so the digits do not jitter as they tick */
}
.dk-tool-card[data-state="running"] .dk-tool-elapsed { color: var(--cyan); }

/* Running: the verb reads live. */
.dk-tool-card[data-state="running"] .dk-tool-name {
  color: var(--cyan);
  text-transform: lowercase;
}

/* "… +N lines" — always say what you are NOT showing. */
.dk-tool-more {
  display: block;
  width: 100%;
  margin-top: 2px;
  padding: 1px 6px;
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  background: transparent;
  color: var(--amber-dim);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  text-align: left;
  cursor: pointer;
}
.dk-tool-more:hover { color: var(--cyan); border-color: var(--cyan); }

/* Thinking, past tense: a fact you skim past, not a live line. */
.dk-thinking[data-redacted="true"][data-done="true"] .dk-thinking-label { color: var(--amber-dim); }

/* The agent roster is gone — the machine room carries agent presence now. Kill any stragglers. */
.dk-agents, #dk-composer-tray .dk-agents { display: none !important; }

/* THE EDGE, stated on the orchestrator itself.
   The agents above are delegated work; the orchestrator below is YOUR conversation. Its header is
   the seam between them, so it carries a hard rule and a dark-amber bar — dark enough to read as
   chrome rather than content, bright enough that the boundary is never ambiguous. */
.dk-lane-main-host {
  border-top: 2px solid var(--amber-dim);
}
.dk-lane-main-host .dk-lane-head {
  background: linear-gradient(180deg, rgb(var(--amber-rgb) / 16%), rgb(var(--amber-rgb) / 7%));
  border-bottom: 1px solid rgb(var(--amber-dim-rgb) / 70%);
  box-shadow: inset 0 1px 0 rgb(var(--amber-rgb) / 22%);
}
.dk-lane-main-host .dk-lane-name,
.dk-lane-main-host .dk-lane-title { color: var(--amber); text-shadow: var(--glow); }

/* ============================================================================
 * SUBAGENT LANE: LOG vs OUTPUT.
 *
 * The transcript and the final report used to be STACKED, so the report squashed the log and
 * neither could be read. They are two views of the same lane now — exactly one is on screen — and
 * a finished agent shows its OUTPUT by default, because once it is done the thing you were waiting
 * for is its answer, not a replay of how it got there.
 * ==========================================================================*/
.dk-lane[data-view="log"] .dk-lane-summary { display: none; }
.dk-lane[data-view="output"] .dk-lane-body { display: none; }

.dk-lane-summary {
  padding: 8px 10px;
  color: var(--amber);
  border-top: 0;
}

/* The segmented switch in the lane header. */
.dk-lane-views { display: inline-flex; gap: 0; margin-left: 6px; }
.dk-lane-view-btn {
  padding: 0 6px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--amber-dim);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  cursor: pointer;
}
.dk-lane-view-btn:first-child { border-radius: var(--radius) 0 0 var(--radius); }
.dk-lane-view-btn:last-child { border-radius: 0 var(--radius) var(--radius) 0; border-left: 0; }
.dk-lane-view-btn[data-active="true"] {
  color: var(--amber);
  background: rgb(var(--amber-rgb) / 14%);
  border-color: var(--amber);
}
/* Nothing to show yet: an agent that has not reported has no output view. Say so by disabling it
   rather than offering an empty pane. */
.dk-lane-view-btn:disabled { opacity: 0.35; cursor: default; }

/* ============================================================================
 * CONTEXT DRAWER = A HOVER POPOVER ON THE HEADER, not a block in the conversation.
 *
 * It was mounted at the top of the lane BODY, so the spawn prompt and file list sat inside the
 * transcript, shoved the actual conversation down, and read like something the agent had said.
 * It is not content — it is metadata ABOUT the agent (§10: what was passed IN). So it hangs off
 * the header: hover to see it, and the header button still pins it open.
 * ==========================================================================*/
.dk-lane-head { position: relative; overflow: visible; }

.dk-lane-head > .dk-drawer {
  position: absolute;
  top: calc(100% + 2px);
  left: 0;
  right: 0;
  z-index: 60;
  display: none;
  max-height: 50vh;
  overflow: auto;
  background: var(--surface-2);
  border: 1px solid var(--border-info);
  border-radius: var(--radius);
  box-shadow: 0 8px 22px rgb(0 0 0 / 65%);
}
/* Hover to peek; the drawer's own toggle (or the header button) pins it. */
.dk-lane-head:hover > .dk-drawer,
.dk-lane-head > .dk-drawer.dk-drawer--open,
.dk-lane-head > .dk-drawer:hover { display: block; }

/* Its own summary row is redundant inside a popover that only exists while you point at it. */
.dk-lane-head > .dk-drawer > .dk-drawer__toggle { display: none; }
.dk-lane-head > .dk-drawer > .dk-drawer__body { border-top: 0; }

/* ---- Orchestrator header: a real dark-amber bar, not a tint ---------------
   It is the seam between delegated work above and your conversation below, so it should read as
   chrome at a glance — a bar you can find without looking for it. */
.dk-lane-main-host .dk-lane-head {
  background: linear-gradient(180deg, #3a2408, #2a1a06);
  border-top: 1px solid var(--amber);
  border-bottom: 1px solid var(--amber-dim);
  box-shadow: inset 0 1px 0 rgb(var(--amber-rgb) / 30%), 0 2px 8px rgb(0 0 0 / 50%);
}
.dk-lane-main-host .dk-lane-head .dk-lane-name,
.dk-lane-main-host .dk-lane-head .dk-lane-title {
  color: var(--amber);
  text-shadow: var(--glow);
  letter-spacing: 0.08em;
}

/* Fold sits at the FAR LEFT of the pager bar — it is the handle for the whole section, so it reads
   as the section's own control rather than as one more button in the cluster on the right. */
.dk-pager { padding-left: 6px; }
/* The agents bar gets the SAME dark-amber treatment as the orchestrator header. They are the two
   section titles in the cockpit, and they should read as a matched pair of chrome bars framing the
   work between them — not as one styled header and one anonymous strip. */
.dk-pager {
  background: linear-gradient(180deg, #3a2408, #2a1a06);
  border-top: 1px solid var(--amber-dim);
  border-bottom: 1px solid var(--amber-dim);
  box-shadow: inset 0 1px 0 rgb(var(--amber-rgb) / 30%), 0 2px 8px rgb(0 0 0 / 45%);
}
/* ============================================================================
 * HYDRATION VEIL — cover the replay, reveal the result.
 *
 * On reload the server replays the entire history as a burst of frames, each appending a div and
 * each shifting the scroll. Watching that is watching the app assemble itself: it flickers, it
 * jumps, and it lands mid-transcript. Cover the workspace while it happens and lift the cover once
 * the burst has drained and the scroll is where it belongs.
 *
 * It ALWAYS lifts (two failsafes in app.js). A veil that can stick is a dead app; a flicker is
 * only a flicker.
 * ==========================================================================*/
#dk-hydrate {
  position: absolute;
  inset: 0;
  z-index: 80;
  display: none;
  align-items: center;
  justify-content: center;
  gap: 10px;
  background: var(--bg);
  color: var(--amber-dim);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.12em;
}
body[data-hydrating="true"] #dk-hydrate { display: flex; }

/* The reveal is a fade, not a cut — a hard swap reads as a glitch. */
#dk-main { position: relative; }
body[data-hydrating="true"] #dk-lanes,
body[data-hydrating="true"] #dk-chat { opacity: 0; }
/* The prompt dock lives OUTSIDE #dk-main, so the veil doesn't cover it — hide it (and the
   machine room) during load or replayed permission/question cards show through the panel. */
body[data-hydrating="true"] #dk-ask-dock,
body[data-hydrating="true"] .dk-pager { opacity: 0; pointer-events: none; }
#dk-lanes, #dk-chat { opacity: 1; transition: opacity 160ms var(--ease); }/* The loading PANEL (user, 2026-07-17): centered card, pixel-Mac motif, calm status. */
.dk-hydrate-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 26px 34px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: 0 8px 40px rgb(0 0 0 / 45%);
}
.dk-hydrate-mac { color: var(--amber); }
.dk-hydrate-mac svg { width: 44px; height: 48px; }
.dk-hydrate-mac .dk-hydrate-eye { fill: var(--cyan); animation: dk-hydrate-blink 1.4s steps(1, end) infinite; }
.dk-hydrate-mac .dk-hydrate-eye:nth-of-type(2) { animation-delay: 0.2s; }
@keyframes dk-hydrate-blink { 0%, 70%, 100% { opacity: 1; } 80% { opacity: 0.15; } }
.dk-hydrate-text { color: var(--amber); font-size: var(--fs-small); text-transform: none; letter-spacing: 0.04em; }
.dk-hydrate-sub { color: var(--amber-dim); font-size: var(--fs-micro); text-transform: none; letter-spacing: 0.02em; }
@media (prefers-reduced-motion: reduce) { .dk-hydrate-mac .dk-hydrate-eye { animation: none; } }

/* An EXPANDED tool result is not clamped. The 320px cap stops a long output swallowing the lane by
   default — but once you have explicitly asked to see the rest, capping it again just means the
   expander appears not to work. Expanding is a deliberate act; honour it. */
.dk-tool-result[data-expanded="true"] {
  max-height: none;
  overflow: visible;
}

/* Rename-in-place: double-click a tab title. Sized and coloured like the label it replaces, so the
   bar does not jump when you start editing — a layout shift on double-click reads as a bug. */
.dk-tab-rename {
  min-width: 60px;
  max-width: 160px;
  padding: 0 2px;
  border: 1px solid var(--amber);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--amber);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  line-height: inherit;
  outline: none;
  box-shadow: var(--glow-box);
}

/* ============================================================================
 * RELAYS PANEL (§14) — the machines Deckard can reach. Owner-only, a viewer.
 * ==========================================================================*/
.dk-relays-btn { position: relative; }
.dk-relays-count {
  margin-left: 5px;
  padding: 0 4px;
  border-radius: var(--radius);
  background: var(--raised-2);
  color: var(--amber);
  font-size: var(--fs-micro);
}

/* A real modal: full-screen backdrop + centered dialog (2x the old cramped slide-in). */
.dk-relays-overlay {
  position: fixed; inset: 0; z-index: 120;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,0.55);
  opacity: 0; pointer-events: none; transition: opacity 0.15s var(--ease, ease);
}
.dk-relays-overlay[data-open="true"] { opacity: 1; pointer-events: auto; }
.dk-relays-panel {
  width: min(840px, 94vw);
  max-height: 86vh;
  overflow: auto;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 16px 48px rgb(0 0 0 / 55%);
  transform: translateY(8px);
  transition: transform 0.15s var(--ease, ease);
}
.dk-relays-overlay[data-open="true"] .dk-relays-panel { transform: translateY(0); }
.dk-relays-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
  background: var(--surface-1);
  position: sticky; top: 0; z-index: 1;
}
.dk-relays-title { color: var(--amber); text-transform: uppercase; letter-spacing: 0.08em; font-size: var(--fs-small); }
.dk-relays-close { border: 0; background: transparent; color: var(--amber-dim); font-size: 20px; cursor: pointer; line-height: 1; }
.dk-relays-close:hover { color: var(--red); }
.dk-relays-list { display: flex; flex-direction: column; gap: 10px; padding: 14px 16px; }
/* Right-aligned action-button group so the row never scatters when buttons are added. */
.dk-relay-actions { display: flex; align-items: center; gap: 6px; margin-left: auto; flex: 0 0 auto; }

.dk-relay {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--raised-2);
  padding: 8px 10px;
}
.dk-relay[data-enabled="false"] { opacity: 0.6; }
.dk-relay-top { display: flex; align-items: center; gap: 7px; }
.dk-relay-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--amber-dim); flex: 0 0 auto; }
.dk-relay-dot[data-status="connected"] { background: var(--amber); box-shadow: var(--glow); }
.dk-relay-dot[data-status="idle"] { background: var(--amber-dim); }
.dk-relay-dot[data-status="in-use"] { background: var(--cyan); box-shadow: var(--glow-cyan); }
.dk-relay-dot[data-status="paused"] { background: var(--amber-dim); }
.dk-relay-dot[data-status="unreachable"] { background: var(--red); box-shadow: var(--glow-red); }
.dk-relay-name { color: var(--amber); font-weight: 600; }
.dk-relay-status { color: var(--amber-dim); font-size: var(--fs-micro); text-transform: uppercase; }
/* Pending (trust-on-first-use) relay: cyan status + a prominent approve button. */
.dk-relay-status[data-status="pending"] { color: var(--cyan); }
.dk-relay-approve {
  margin-left: 8px;
  padding: 2px 12px;
  border-radius: var(--radius);
  border: 1px solid var(--cyan);
  background: rgb(var(--cyan-rgb) / 12%);
  color: var(--cyan);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  cursor: pointer;
}
.dk-relay-approve:hover { background: rgb(var(--cyan-rgb) / 22%); box-shadow: var(--glow-box-cyan, none); }
.dk-relay-pending-note { color: var(--amber-dim); font-size: var(--fs-micro); padding: 2px 0 4px; }.dk-relay-url { color: var(--amber-dim); font-size: var(--fs-micro); margin: 3px 0; word-break: break-all; }.dk-relay-tools { display: flex; flex-wrap: wrap; gap: 3px; margin-top: 5px; }
.dk-relay-toolsummary { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; }
.dk-relay-version { color: var(--cyan); font-family: var(--font-mono); font-size: var(--fs-micro); }
.dk-relay-update-btn { font-size: var(--fs-micro); padding: 2px 8px; border-radius: 999px; background: transparent; border: 1px solid var(--border); color: var(--amber-dim); cursor: pointer; }
.dk-relay-update-btn:hover { border-color: var(--cyan); color: var(--cyan); }
.dk-relay-update-btn[data-armed="true"] { border-color: var(--red); color: var(--red); }
.dk-relay-version-old { color: var(--red); }
.dk-relay-machine { color: var(--amber-dim); font-size: var(--fs-micro); }
.dk-relay-tool {
  padding: 0 5px; border: 1px solid var(--border); border-radius: var(--radius);
  color: var(--amber-dim); font-size: var(--fs-micro);
}
/* A tool the relay exposes but the backend does NOT allow-list is dead weight — dim it further. */
.dk-relay-tool[data-allowed="false"] { opacity: 0.45; text-decoration: line-through; }
.dk-relay-error { color: var(--red); font-size: var(--fs-micro); margin-top: 5px; }

/* Relay panel — interactive controls (§14). */
.dk-relay-toggle {
  margin-left: auto;
  padding: 0 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: transparent;
  color: var(--amber-dim);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  cursor: pointer;
}
.dk-relay-toggle[data-on="true"] { color: var(--amber); border-color: var(--amber); background: rgb(var(--amber-rgb) / 12%); }
.dk-relay-toggle:hover { border-color: var(--amber); }
.dk-relay-status { margin-left: 8px; }/* Tool chips are now BUTTONS (allow/deny). Allowed = cyan (Deckard may call it); denied = struck. */
button.dk-relay-tool { cursor: pointer; font-family: var(--font-mono); }
.dk-relay-tool[data-allowed="true"] { color: var(--cyan); border-color: var(--border-info); opacity: 1; text-decoration: none; }
.dk-relay-tool[data-allowed="false"] { color: var(--amber-dim); opacity: 0.6; text-decoration: line-through; }
.dk-relay-tool:hover { border-color: var(--amber); }

/* ---- relay card: label as primary, identifier dim beside it, + an edit affordance ---- */
.dk-relay-id { color: var(--amber-dim); font-weight: 400; font-size: var(--fs-micro); margin-left: 6px; }
.dk-relay-edit {
  margin-left: auto; font-family: var(--font-mono); font-size: var(--fs-micro);
  padding: 1px 8px; background: transparent; color: var(--amber-dim);
  border: 1px solid var(--border); cursor: pointer; text-transform: uppercase; letter-spacing: 0.06em;
}
.dk-relay-edit:hover { color: var(--amber); border-color: var(--amber); }
/* When an edit button is present it eats the margin-left:auto; keep status/toggle pinned right. */
.dk-relay-edit + .dk-relay-toggle { margin-left: 8px; }

/* ═══ per-relay EDIT modal (§14) — Deckard palette; red = danger ONLY ═══════════════════ */
.dk-relay-overlay {
  /* TOPMOST: above the relays panel (70), the dock rail + panels (1057/1200) and the machine
     room — an open modal is the foreground task; edge handles were bleeding through it. */
  position: fixed; inset: 0; z-index: 1300; display: none;
  align-items: flex-start; justify-content: center;
  background: rgb(0 0 0 / 68%); padding: 5vh 12px; overflow-y: auto;
}
.dk-relay-overlay[data-open="true"] { display: flex; }
.dk-relay-modal {
  width: 100%; max-width: 560px; background: var(--surface);
  border: 1px solid var(--border-strong); box-shadow: var(--glow-box);
  font-family: var(--font-mono); color: var(--amber);
  display: flex; flex-direction: column; max-height: 90vh;
}
.dk-relay-modal-head {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px; border-bottom: 1px solid var(--border);
}
.dk-relay-modal-title {
  color: var(--amber); font-size: var(--fs-lg); font-weight: 600;
  text-shadow: var(--glow); letter-spacing: 0.04em; word-break: break-word;
}
.dk-relay-modal-close {
  margin-left: auto; border: 0; background: transparent; color: var(--amber-dim);
  font-size: 20px; line-height: 1; cursor: pointer; padding: 0 4px;
}
.dk-relay-modal-close:hover { color: var(--red); }
.dk-relay-modal-loading { padding: 20px 14px; color: var(--amber-dim); }
.dk-relay-modal-body { padding: 4px 14px 16px; overflow-y: auto; }

.dk-relay-section { padding: 12px 0; border-bottom: 1px solid var(--border); }
.dk-relay-section:last-child { border-bottom: 0; }
.dk-relay-h {
  color: var(--amber-dim); font-size: var(--fs-micro); text-transform: uppercase;
  letter-spacing: 0.1em; font-weight: 400; margin: 0 0 8px;
}
.dk-relay-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 6px; }
.dk-relay-input {
  flex: 1 1 200px; min-width: 0; font-family: var(--font-mono); font-size: var(--fs-small);
  background: var(--bg); color: var(--amber); border: 1px solid var(--border); padding: 6px 8px;
}
.dk-relay-input:focus { outline: none; border-color: var(--amber); }
.dk-relay-note { color: var(--amber-dim); font-size: var(--fs-micro); margin-top: 6px; word-break: break-word; }
.dk-relay-idcode { color: var(--cyan); background: var(--bg); padding: 0 4px; }
.dk-relay-mbtn {
  font-family: var(--font-mono); font-size: var(--fs-micro); padding: 6px 12px; cursor: pointer;
  background: transparent; color: var(--amber); border: 1px solid var(--border); flex: 0 0 auto;
}
.dk-relay-mbtn:hover { border-color: var(--amber); }
.dk-relay-mbtn.small { padding: 3px 8px; }
.dk-relay-mbtn.danger { color: var(--red); border-color: var(--border-danger); }
.dk-relay-mbtn.danger:hover { border-color: var(--red); background: rgb(var(--red-rgb) / 8%); }

/* folders: path + a segmented none/read/write control + remove */
.dk-relay-folder { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; padding: 6px 0; border-bottom: 1px solid rgb(var(--amber-dim-rgb) / 18%); }
.dk-relay-folder:last-of-type { border-bottom: 0; }
.dk-relay-fpath { flex: 1 1 220px; word-break: break-all; color: var(--amber); font-size: var(--fs-small); }
.dk-relay-deny { flex-basis: 100%; color: var(--amber-dim); font-size: var(--fs-micro); }
.dk-relay-seg { display: inline-flex; border: 1px solid var(--border); flex: 0 0 auto; }
.dk-relay-segbtn {
  border: 0; border-right: 1px solid var(--border); background: transparent; color: var(--amber-dim);
  font-family: var(--font-mono); font-size: var(--fs-micro); padding: 3px 10px; cursor: pointer;
  text-transform: uppercase; letter-spacing: 0.04em;
}
.dk-relay-segbtn:last-child { border-right: 0; }
.dk-relay-segbtn:hover { color: var(--amber); }
.dk-relay-segbtn.on.none { color: var(--bg); background: var(--amber-dim); }
.dk-relay-segbtn.on.read { color: var(--bg); background: var(--cyan); }
.dk-relay-segbtn.on.write { color: #fff; background: var(--red); }

/* ── §9 TAB SETTINGS modal — reuses the relay-modal shell, adds a footer, a target-relay ──── */
/*    select, and env-var key/value rows. Kept visually identical to "edit relay". */
.dk-relay-mbtn.primary { color: var(--bg); background: var(--amber); border-color: var(--amber); }
.dk-relay-mbtn.primary:hover { background: var(--amber-dim); border-color: var(--amber-dim); }
.dk-relay-modal-foot {
  display: flex; gap: 8px; justify-content: flex-end;
  padding: 12px 0 2px; margin-top: 4px; border-top: 1px solid var(--border);
}

/* ==========================================================================
 * TEAMS (§ teams / docs/teams.md) — the roster modal, editor, and run chip.
 * Reuses the relay-modal shell; only the team-specific rows/pickers live here.
 * ==========================================================================*/
.dk-teams-btn { position: relative; }
.dk-flex-spacer { flex: 1 1 auto; }
.dk-empty-note {
  color: var(--muted, var(--amber-dim)); font-size: var(--fs-small);
  line-height: 1.5; padding: 8px 2px;
}
.dk-field-label {
  color: var(--amber-dim); font-family: var(--font-mono); font-size: var(--fs-micro);
  text-transform: uppercase; letter-spacing: 0.08em; margin: 12px 0 4px;
}
.dk-team-row {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 2px; border-bottom: 1px solid var(--border);
}
.dk-team-row-info { flex: 1 1 auto; min-width: 0; }
.dk-team-row-name { color: var(--amber); font-weight: 600; font-size: var(--fs-small); }
.dk-team-row-meta {
  color: var(--amber-dim); font-size: var(--fs-micro); font-family: var(--font-mono);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dk-team-members {
  display: flex; flex-direction: column; gap: 2px;
  max-height: 200px; overflow-y: auto;
  border: 1px solid var(--border); border-radius: var(--radius); padding: 6px;
}
.dk-team-member { display: flex; align-items: center; gap: 8px; padding: 3px 4px; cursor: pointer; }
.dk-team-member:hover { background: var(--raised-2, rgba(255,255,255,0.03)); }
.dk-team-member-who { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.dk-team-member-name { color: var(--fg, var(--amber)); font-size: var(--fs-small); }
.dk-team-member-role { color: var(--dim, rgba(255,255,255,0.45)); font-size: var(--fs-tiny, 11px); text-transform: uppercase; letter-spacing: 0.04em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dk-team-lead-wrap { margin-top: 2px; }
.dk-team-goal { width: 100%; min-height: 64px; resize: vertical; }
.dk-team-cap { width: 90px; }

/* The floating run chip — a live "who is speaking now" readout, bottom-left, out of the way. */
.dk-team-chip {
  position: fixed; left: 14px; bottom: 14px; z-index: 60;
  max-width: 60vw; padding: 6px 8px 6px 12px; border-radius: 999px;
  background: var(--surface, #131318); border: 1px solid var(--border);
  color: var(--amber); font-family: var(--font-mono); font-size: var(--fs-micro);
  box-shadow: 0 4px 14px rgba(0,0,0,0.4);
  display: flex; align-items: center; gap: 8px;
  opacity: 0; transform: translateY(6px); transition: opacity 0.2s, transform 0.2s;
  pointer-events: none;
}
.dk-team-chip[data-on="true"] { opacity: 1; transform: translateY(0); pointer-events: auto; }
.dk-team-chip[data-kind="running"] { border-color: var(--cyan); color: var(--cyan); }
.dk-team-chip[data-kind="error"] { border-color: var(--red); color: var(--red); }
.dk-team-chip-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dk-team-chip-stop {
  flex: 0 0 auto; cursor: pointer; font-family: var(--font-mono); font-size: var(--fs-micro);
  padding: 2px 9px; border-radius: 999px; white-space: nowrap;
  background: rgb(var(--red-rgb, 220 60 60) / 14%); color: var(--red);
  border: 1px solid rgb(var(--red-rgb, 220 60 60) / 45%);
}
.dk-team-chip-stop:hover { background: rgb(var(--red-rgb, 220 60 60) / 26%); }


/* Run dialog: where-to-run picker */
.dk-team-target { display: flex; flex-direction: column; gap: 6px; margin: 4px 0 2px; }
.dk-team-target-opt { display: flex; align-items: flex-start; gap: 10px; padding: 8px 10px; cursor: pointer;
  border: 1px solid var(--border); border-radius: var(--radius); }
.dk-team-target-opt:hover { border-color: var(--amber); }
.dk-team-target-opt.disabled { opacity: 0.5; cursor: not-allowed; }
.dk-team-target-opt input { margin-top: 3px; }
.dk-team-target-title { color: var(--fg, var(--amber)); font-size: var(--fs-small); }
.dk-team-target-sub { color: var(--dim, rgba(255,255,255,0.45)); font-size: var(--fs-micro); margin-top: 2px; }

/* ==========================================================================
 * SCHEDULES (§ schedules) — the roster modal + cadence builder. Reuses the
 * relay-modal shell; only the schedule rows + cron builder live here.
 * ==========================================================================*/
.dk-schedules-btn { position: relative; }
.dk-sched-row {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 2px; border-bottom: 1px solid var(--border);
}
.dk-sched-row[data-enabled="false"] { opacity: 0.55; }
.dk-sched-toggle {
  flex: 0 0 auto; width: 26px; height: 26px; border-radius: 50%;
  border: 1px solid var(--border); background: transparent; color: var(--amber-dim);
  font-size: 14px; cursor: pointer; line-height: 1;
}
.dk-sched-row[data-enabled="true"] .dk-sched-toggle { color: var(--cyan); border-color: var(--cyan); }
.dk-sched-info { flex: 1 1 auto; min-width: 0; }
.dk-sched-name { color: var(--amber); font-weight: 600; font-size: var(--fs-small); }
.dk-sched-meta {
  color: var(--amber-dim); font-size: var(--fs-micro); font-family: var(--font-mono);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dk-sched-err { color: var(--red); font-size: var(--fs-micro); font-family: var(--font-mono); }
.dk-sched-prompt { width: 100%; min-height: 56px; resize: vertical; }
.dk-sched-cadence {
  display: flex; flex-direction: column; gap: 8px;
  border: 1px solid var(--border); border-radius: var(--radius); padding: 10px;
}
/* The cadence mode is a compact picker, not a full-width bar (user, 2026-07-19). */
.dk-sched-mode { flex: 0 0 auto; width: auto; min-width: 160px; align-self: flex-start; }
.dk-sched-cadence-opts { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.dk-sched-inline { display: inline-flex; align-items: center; gap: 6px; }
.dk-sched-word { color: var(--amber-dim); font-size: var(--fs-small); }
.dk-sched-num { width: 68px; }
.dk-sched-dow { width: auto; }
.dk-sched-cron-preview {
  color: var(--cyan); font-family: var(--font-mono); font-size: var(--fs-micro);
}
.dk-sched-tz { display: flex; align-items: center; gap: 8px; }
.dk-sched-tz-label { color: var(--amber-dim); font-size: var(--fs-micro); text-transform: uppercase; letter-spacing: 0.08em; }
.dk-sched-tz .dk-relay-input { flex: 1 1 auto; }

/* ==========================================================================
 * AGENT INTERVIEWER (§13) — a short chat at the top of the new-agent form that
 * drafts the whole persona. Sits above the charter fields it fills.
 * ==========================================================================*/
.dk-persona-interview {
  margin: 4px 0 14px; padding: 12px; border: 1px solid var(--cyan);
  border-radius: var(--radius); background: rgb(43 217 196 / 5%);
}
.dk-persona-interview-start { width: 100%; }
.dk-persona-interview-hint { margin-top: 6px; color: var(--amber-dim); font-size: var(--fs-micro); line-height: 1.5; }
.dk-persona-interview-log { display: flex; flex-direction: column; gap: 6px; max-height: 260px; overflow-y: auto; margin-bottom: 8px; }
.dk-persona-interview-msg {
  max-width: 88%; padding: 6px 10px; border-radius: 10px; font-size: var(--fs-small); line-height: 1.4;
  white-space: pre-wrap; word-break: break-word;
}
.dk-persona-interview-msg[data-role="interviewer"] {
  align-self: flex-start; background: var(--raised-2, rgba(255,255,255,0.04)); color: var(--fg, var(--amber));
  border: 1px solid var(--border);
}
.dk-persona-interview-msg[data-role="user"] {
  align-self: flex-end; background: rgb(43 217 196 / 12%); color: var(--cyan); border: 1px solid var(--cyan);
}
.dk-persona-interview-msg.thinking { opacity: 0.6; letter-spacing: 3px; }
.dk-persona-interview-err { color: var(--red); font-size: var(--fs-micro); margin: 4px 0; }
.dk-persona-interview-done { color: var(--cyan); font-size: var(--fs-micro); margin: 4px 0 8px; }
.dk-persona-interview-inputrow { display: flex; gap: 6px; }
.dk-persona-interview-inputrow .dk-persona-interview-input { flex: 1 1 auto; }
.dk-tab-select {
  flex: 1 1 200px; min-width: 0; font-family: var(--font-mono); font-size: var(--fs-small);
  background: var(--bg); color: var(--amber); border: 1px solid var(--border); padding: 6px 8px;
}
.dk-tab-select:focus { outline: none; border-color: var(--amber); }
/* standing instructions — a multi-line input styled like the rest of the modal's fields */
.dk-tab-sysprompt {
  flex: 1 1 100%; width: 100%; min-width: 0; resize: vertical;
  font-family: var(--font-mono); font-size: var(--fs-small);
  background: var(--bg); color: var(--amber); border: 1px solid var(--border); padding: 6px 8px;
}
.dk-tab-sysprompt:focus { outline: none; border-color: var(--amber); }
.dk-tab-envlist { display: flex; flex-direction: column; gap: 6px; margin-top: 6px; }
.dk-tab-envrow { display: flex; gap: 6px; align-items: center; }
.dk-tab-envkey { flex: 0 1 40%; text-transform: none; }
.dk-tab-envval { flex: 1 1 60%; }

/* capability rows + toggles */
.dk-relay-capline { display: flex; align-items: center; gap: 12px; padding: 6px 0; }
.dk-relay-capname { color: var(--amber); flex: 1; font-size: var(--fs-small); }
.dk-relay-sub { margin: 2px 0 8px 10px; padding-left: 10px; border-left: 1px solid var(--border); }
.dk-relay-sub .dk-relay-capname { color: var(--amber-dim); }
.dk-relay-sublabel { display: block; color: var(--amber-dim); font-size: var(--fs-micro); margin: 8px 0 4px; }
.dk-relay-tog {
  min-width: 62px; text-align: center; font-family: var(--font-mono); font-size: var(--fs-micro);
  padding: 4px 10px; cursor: pointer; background: transparent; border: 1px solid var(--border); flex: 0 0 auto;
}
.dk-relay-tog.on { color: var(--cyan); border-color: var(--border-info); }
.dk-relay-tog.on.danger { color: var(--red); border-color: var(--border-danger); }
.dk-relay-tog.off { color: var(--amber-dim); }
.dk-relay-tog:hover { border-color: var(--amber); }
.dk-relay-warn {
  border-left: 2px solid var(--red); padding: 6px 10px; margin: 6px 0;
  color: var(--red); font-size: var(--fs-micro); background: rgb(var(--red-rgb) / 6%);
}

@media (max-width: 520px) {
  .dk-relay-overlay { padding: 2vh 6px; }
  .dk-relay-fpath { flex-basis: 100%; }
}

/* ============================================================================
 * WORKFLOWS PANEL — watch a workflow execute: runs, their agents, narration.
 * Left-side popout, mirror of the artifacts dock. NEVER auto-opens; a new run
 * pulses the handle (motion.css).
 * ==========================================================================*/
.dk-workflows {
  position: fixed;
  top: var(--topbar-h);
  left: 0;
  bottom: 0;
  z-index: 1060;
  width: min(520px, 96vw);
  display: none;
  flex-direction: column;
  background: var(--surface-2, var(--surface));
  border-right: 1px solid var(--border-strong);
  box-shadow: var(--glow-box);
}
.dk-workflows[data-open="true"] { display: flex; }
.dk-workflows-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  border-bottom: 1px solid var(--border);
  color: var(--amber);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.1em;
}
.dk-workflows-count {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0 6px;
  color: var(--amber-dim);
}
.dk-workflows-close {
  margin-left: auto;
  width: 22px;
  height: 20px;
  padding: 0;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--amber);
  font-family: var(--font-mono);
  cursor: pointer;
}
.dk-workflows-close:hover { border-color: var(--amber); background: var(--hover); }
.dk-workflows-list { flex: 1 1 auto; overflow-y: auto; padding: 8px; display: flex; flex-direction: column; gap: 8px; }
.dk-workflows-empty { color: var(--amber-dim); font-size: var(--fs-micro); padding: 12px; }

.dk-workflows-handle,
.dk-shells-handle {
  position: fixed;
  left: 0;
  top: 40%;
  z-index: 1059;
  border: 1px solid var(--border-strong);
  border-left: 0;
  border-radius: 0 var(--radius) var(--radius) 0;
  background: var(--surface);
  color: var(--amber);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 8px 4px;
  writing-mode: vertical-rl;
  cursor: pointer;
}
.dk-workflows-handle:hover,
.dk-shells-handle:hover { background: var(--hover); text-shadow: var(--glow); }

.dk-wf-card {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  padding: 8px 10px;
}
.dk-wf-card[data-status="running"] { border-color: var(--border-info); }
.dk-wf-card[data-status="failed"],
.dk-wf-card[data-status="killed"] { border-color: var(--border-danger); }
.dk-wf-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.dk-wf-name { color: var(--amber); font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; }
.dk-wf-status { color: var(--cyan); font-size: var(--fs-micro); text-transform: uppercase; }
.dk-wf-card[data-status="completed"] .dk-wf-status { color: var(--amber-dim); }
.dk-wf-card[data-status="failed"] .dk-wf-status,
.dk-wf-card[data-status="killed"] .dk-wf-status { color: var(--red); }
.dk-wf-elapsed, .dk-wf-usage { margin-left: auto; color: var(--amber-dim); font-size: var(--fs-micro); }
.dk-wf-usage { margin-left: 0; }
.dk-wf-desc { margin-top: 4px; color: var(--amber-dim); font-size: var(--fs-micro); }

.dk-wf-agents { margin-top: 6px; display: flex; flex-direction: column; gap: 3px; }
.dk-wf-agent { display: flex; flex-direction: column; min-width: 0; }
.dk-wf-agent-head {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 3px 2px;
  background: transparent;
  border: 0;
  text-align: left;
  cursor: pointer;
  font-size: var(--fs-micro);
  color: var(--amber-dim);
  font-family: var(--font-mono);
}
.dk-wf-agent-head:hover { background: var(--hover); }
.dk-wf-agent-head .dk-status-dot { flex: 0 0 auto; }
.dk-wf-agent-name { color: var(--amber); flex: 0 0 auto; }
.dk-wf-agent-desc { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; min-width: 0; flex: 1 1 auto; }
.dk-wf-agent-meta { flex: 0 0 auto; }
.dk-wf-agent-prompt {
  margin: 4px 0 4px 14px;
  padding: 5px 8px;
  max-height: 140px;
  overflow: auto;
  border-left: 2px solid var(--border);
  color: var(--amber-dim);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.dk-wf-agent-log {
  margin: 2px 0 4px 14px;
  max-height: 120px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

/* Aggregate stats + output + error on a workflow card. */
.dk-wf-stats { display: flex; flex-wrap: wrap; gap: 4px 12px; margin: 2px 0 4px; }
.dk-wf-stat { color: var(--amber-dim); font-size: var(--fs-micro); }
.dk-wf-output { display: flex; gap: 6px; margin-top: 6px; align-items: baseline; }
.dk-wf-output-label { color: var(--amber-dim); font-size: var(--fs-micro); text-transform: uppercase; letter-spacing: 0.08em; flex: 0 0 auto; }
.dk-wf-output-path { color: var(--cyan); font-size: var(--fs-micro); overflow-wrap: anywhere; }
.dk-wf-error {
  margin: 4px 0;
  padding: 4px 8px;
  border-left: 2px solid var(--red);
  color: var(--red);
  font-size: var(--fs-micro);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.dk-wf-log {
  margin-top: 6px;
  max-height: 140px;
  overflow-y: auto;
  border-top: 1px solid var(--border);
  padding-top: 4px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.dk-wf-log-line { color: var(--amber); font-size: var(--fs-micro); white-space: pre-wrap; word-break: break-word; }
.dk-wf-log-line::before { content: '› '; color: var(--cyan); }

.dk-wf-loose-label {
  color: var(--amber-dim);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  margin: 4px 0;
}
.dk-wf-loose { display: flex; flex-direction: column; gap: 3px; }

/* ---- Tab memory (§15) — the notes list + purge inside tab settings -------- */
.dk-tab-memcount { margin-left: 8px; color: var(--amber-dim); font-weight: 400; }
.dk-tab-memlist {
  max-height: 180px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-bottom: 6px;
}
.dk-tab-memempty { color: var(--amber-dim); font-size: var(--fs-micro); padding: 4px 0; }
.dk-tab-memhead {
  display: flex;
  gap: 8px;
  align-items: baseline;
  width: 100%;
  padding: 3px 6px;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  text-align: left;
  cursor: pointer;
  min-width: 0;
}
.dk-tab-memhead:hover { border-color: var(--amber); background: var(--hover); }
.dk-tab-memname { color: var(--amber); flex: 0 0 auto; }
.dk-tab-memdesc { color: var(--amber-dim); overflow: hidden; white-space: nowrap; text-overflow: ellipsis; min-width: 0; }
.dk-tab-membody {
  margin: 2px 0 4px;
  padding: 6px 8px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--amber);
  font-size: var(--fs-micro);
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 160px;
  overflow-y: auto;
}
.dk-tab-mempurge { color: var(--red); border-color: var(--border-danger); }
.dk-tab-mempurge:hover:not(:disabled) { background: rgb(var(--red-rgb, 255 69 58) / 12%); border-color: var(--red); }
.dk-tab-mempurge[data-armed="true"] { background: rgb(var(--red-rgb, 255 69 58) / 18%); border-color: var(--red); }
.dk-tab-mempurge:disabled { opacity: 0.4; cursor: default; }

/* ============================================================================
 * THREADS PANEL (§9) — the tab's task board. Right-side popout under the
 * artifacts handle; list -> detail with a back button. Never auto-opens; a
 * fresh agent-created thread pulses the handle (motion.css).
 * ==========================================================================*/
.dk-threads {
  position: fixed;
  top: var(--topbar-h);
  right: 0;
  bottom: 0;
  z-index: 1058;
  width: min(480px, 96vw);
  display: none;
  flex-direction: column;
  background: var(--surface-2, var(--surface));
  border-left: 1px solid var(--border-strong);
  box-shadow: var(--glow-box);
}
.dk-threads[data-open="true"] { display: flex; }
.dk-threads-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  border-bottom: 1px solid var(--border);
  color: var(--amber);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.1em;
}
.dk-threads-count { border: 1px solid var(--border); border-radius: var(--radius); padding: 0 6px; color: var(--amber-dim); }
.dk-threads-close {
  margin-left: auto;
  width: 22px;
  height: 20px;
  padding: 0;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--amber);
  font-family: var(--font-mono);
  cursor: pointer;
}
.dk-threads-close:hover { border-color: var(--amber); background: var(--hover); }
.dk-threads-list { flex: 1 1 auto; overflow-y: auto; padding: 8px; display: flex; flex-direction: column; gap: 6px; }
.dk-threads-empty { color: var(--amber-dim); font-size: var(--fs-micro); padding: 10px 4px; }

.dk-threads-handle {
  position: fixed;
  right: 0;
  top: 55%;
  z-index: 1057;
  border: 1px solid var(--border-strong);
  border-right: 0;
  border-radius: var(--radius) 0 0 var(--radius);
  background: var(--surface);
  color: var(--amber);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 8px 4px;
  writing-mode: vertical-rl;
  cursor: pointer;
}
.dk-threads-handle:hover { background: var(--hover); text-shadow: var(--glow); }

.dk-thread-newbtn {
  align-self: flex-start;
  padding: 3px 10px;
  background: transparent;
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  color: var(--amber-dim);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  cursor: pointer;
}
.dk-thread-newbtn:hover { color: var(--amber); border-color: var(--amber); }
.dk-thread-new { display: flex; flex-direction: column; gap: 4px; }
.dk-thread-new-title, .dk-thread-new-body {
  width: 100%;
  padding: 5px 8px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--amber);
  font-family: var(--font-mono);
  font-size: var(--fs-base);
}
.dk-thread-new-actions { display: flex; gap: 6px; }
.dk-thread-new-save, .dk-thread-new-cancel {
  padding: 2px 10px;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--amber);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  cursor: pointer;
}
.dk-thread-new-save { border-color: var(--amber); }
.dk-thread-new-save:hover, .dk-thread-new-cancel:hover { background: var(--hover); }

.dk-thread-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  width: 100%;
  padding: 5px 8px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  text-align: left;
  cursor: pointer;
  min-width: 0;
}
.dk-thread-row:hover { border-color: var(--amber); background: var(--hover); }
.dk-thread-row[data-status="resolved"] { opacity: 0.55; }
.dk-thread-row .dk-status-dot { flex: 0 0 auto; align-self: center; }
.dk-thread-title { color: var(--amber); font-weight: 700; flex: 0 1 auto; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dk-thread-origin { color: var(--amber-dim); flex: 0 0 auto; }
.dk-thread-preview { color: var(--amber-dim); flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dk-thread-when { color: var(--amber-dim); flex: 0 0 auto; }

.dk-thread-back {
  align-self: flex-start;
  padding: 2px 10px;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--amber);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  cursor: pointer;
}
.dk-thread-back:hover { background: var(--hover); border-color: var(--amber); }
.dk-thread-detail {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.dk-thread-detail[data-status="active"] { border-color: var(--border-info); }
.dk-thread-detail-title { margin: 0; color: var(--amber); font-size: var(--fs-base); text-transform: none; }
.dk-thread-meta { color: var(--amber-dim); font-size: var(--fs-micro); }
.dk-thread-body { color: var(--amber); font-size: var(--fs-base); overflow-wrap: break-word; }
.dk-thread-actions { display: flex; gap: 8px; margin-top: 4px; }
.dk-thread-call, .dk-thread-cycle, .dk-thread-delete {
  padding: 3px 12px;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--amber);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  cursor: pointer;
}
.dk-thread-call { border-color: var(--amber); }
.dk-thread-call:hover { background: var(--hover); text-shadow: var(--glow); }
.dk-thread-cycle:hover { border-color: var(--cyan); color: var(--cyan); }
.dk-thread-delete { color: var(--red); border-color: var(--border-danger); margin-left: auto; }
.dk-thread-delete:hover { background: rgb(var(--red-rgb, 255 69 58) / 12%); }
.dk-thread-delete[data-armed="true"] { background: rgb(var(--red-rgb, 255 69 58) / 18%); border-color: var(--red); }

/* ============================================================================
 * DOCK RAIL SHIFT (user, 2026-07-16): threads + artifacts live on the LEFT now,
 * high on the edge, threads ABOVE artifacts and tight together; workflows keeps
 * the rail's third slot. Panels open from the left to match their handles.
 * ==========================================================================*/
.dk-threads,
.dk-artifacts {
  right: auto;
  left: 0;
  border-left: 0;
  border-right: 1px solid var(--border-strong);
}
.dk-threads-handle,
.dk-artifacts-handle,
.dk-workflows-handle,
.dk-shells-handle {
  right: auto;
  left: 0;
  border: 1px solid var(--border-strong);
  border-left: 0;
  border-radius: 0 var(--radius) var(--radius) 0;
}
.dk-threads-handle { top: 18%; }
.dk-artifacts-handle { top: calc(18% + 115px); }
.dk-workflows-handle { top: calc(18% + 230px); }

/* ============================================================================
 * DOCKED, NOT OVERLAID (user, 2026-07-16): an open left panel PUSHES the chat
 * inward instead of covering it, and the other handles ride its right edge so
 * no button ever floats over an open panel. One left panel at a time (the
 * modules coordinate via the dk-dock-open event); body[data-dock-left] is the
 * shell's signal. All three panels share one width so the push is stable.
 * ==========================================================================*/
:root { --dock-w: min(480px, 90vw); }
.dk-threads,
.dk-artifacts,
.dk-workflows,
.dk-shells { width: var(--dock-w); }

#dk-main,
#dk-composer,
#dk-ask-dock {
  transition: margin-left var(--t) var(--ease);
}
body[data-dock-left="true"] #dk-main,
body[data-dock-left="true"] #dk-composer,
body[data-dock-left="true"] #dk-ask-dock {
  margin-left: var(--dock-w);
}
body[data-dock-left="true"] .dk-threads-handle,
body[data-dock-left="true"] .dk-artifacts-handle,
body[data-dock-left="true"] .dk-workflows-handle,
body[data-dock-left="true"] .dk-shells-handle {
  left: var(--dock-w);
}

/* ============================================================================
 * READING COLUMN (user, 2026-07-16): the conversation is a centered column,
 * not wall-to-wall text — easier to read, and it breathes next to a docked
 * threads/artifacts panel. The scroll container stays full width (scrollbar at
 * the screen edge); only the CONTENT is capped. Composer and the prompt dock
 * align to the same column so the eye tracks one axis.
 * ==========================================================================*/
:root { --read-w: 940px; }
.dk-lane-body,
#dk-chat { overflow-anchor: none; } /* lazy-history prepends compensate scroll manually */

.dk-lane-body > *,
#dk-chat > * {
  width: min(var(--read-w), 100%);
  align-self: center;
  margin-inline: auto;
}
#dk-composer { padding-inline: max(var(--pad), calc((100% - var(--read-w)) / 2)); }
#dk-ask-dock {
  width: min(var(--read-w), calc(100% - 2 * var(--pad)));
  margin-inline: auto;
}

/* ============================================================================
 * ALIVE PULSE (user, 2026-07-16): the agent is working but nothing is visibly
 * streaming — three staggered amber pixels above the composer say "still
 * alive" for exactly as long as the main agent is busy.
 * ==========================================================================*/
#dk-alive {
  display: flex;
  gap: 8px;
  align-items: baseline;
  order: 9999; /* the lane body is a flex column — the pulse is ALWAYS visually last */
  padding: 2px 0;
  font-family: var(--font-mono);
  color: var(--amber);
}
.dk-alive-prompt { color: var(--amber-dim); }

/* ---- Inline HTML artifact (sandboxed) — the page in the conversation ---- */
.dk-inline-html {
  margin: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  overflow: hidden;
}
.dk-inline-html-frame {
  display: block;
  width: 100%;
  height: 380px;
  border: 0;
  background: var(--bg);
}
.dk-inline-html-cap {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 8px;
  border-top: 1px solid var(--border);
  color: var(--amber-dim);
  font-size: var(--fs-micro);
}
.dk-inline-html-title { text-transform: uppercase; letter-spacing: 0.06em; }
.dk-inline-html-open {
  margin-left: auto;
  padding: 1px 8px;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--amber);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  cursor: pointer;
}
.dk-inline-html-open:hover { border-color: var(--amber); background: var(--hover); }

/* ============================================================================
 * DOCK RAIL (user, 2026-07-16: handles "nearly touching"). One fixed flex
 * column owns all three handles — a couple of pixels apart regardless of each
 * label's length — and the whole rail shifts right when a panel is open.
 * Order: threads, artifacts, workflows.
 * ==========================================================================*/
#dk-dock-rail {
  position: fixed;
  left: 0;
  top: 18%;
  z-index: 1057;
  display: flex;
  flex-direction: column;
  gap: 3px;
  transition: left var(--t) var(--ease);
}
body[data-dock-left="true"] #dk-dock-rail { left: var(--dock-w); }
#dk-dock-rail .dk-threads-handle,
#dk-dock-rail .dk-artifacts-handle,
#dk-dock-rail .dk-workflows-handle,
#dk-dock-rail .dk-shells-handle {
  position: static;
  top: auto;
  left: auto;
  right: auto;
}
.dk-threads-handle { order: 1; }
.dk-artifacts-handle { order: 2; }
.dk-workflows-handle { order: 3; }
.dk-shells-handle { order: 4; }
body[data-mode="chat"] #dk-dock-rail { display: none !important; }

/* ---- Composer autosize, natively (no per-keystroke JS reflow) ------------- */
#dk-input {
  field-sizing: content;
  min-height: 2.2em;
  max-height: 220px;
}

/* ---- Machine room, seamless (user, 2026-07-16): no band, no edge — the
   machines just stand on the black between the conversation and the composer. */
.dk-pager {
  background: transparent;
  border-top: 0;
  border-bottom: 0;
}

/* Dock-aware column centering: % padding resolves against the PARENT (still full width), so
   the pushed composer kept its full-width centering pad and crushed the input to a stub
   (user, 2026-07-16 "text field shrinks too much"). Subtract the dock from the math and the
   input lands at the same size as with the dock closed. */
body[data-dock-left="true"] #dk-composer {
  padding-inline: max(var(--pad), calc((100% - var(--dock-w) - var(--read-w)) / 2));
}
body[data-dock-left="true"] #dk-ask-dock {
  margin-left: calc(var(--dock-w) + max(var(--pad), (100% - var(--dock-w) - var(--read-w)) / 2));
  margin-right: max(var(--pad), calc((100% - var(--dock-w) - var(--read-w)) / 2));
}


/* TABS ARE GLOBAL CHROME (user, 2026-07-16): the bar stays full-width and left-anchored;
   the panels and the rail start BELOW it instead of overlapping/pushing it. */
.dk-threads,
.dk-artifacts,
.dk-workflows,
.dk-shells { top: calc(var(--topbar-h) + var(--tabbar-h)); }
#dk-dock-rail { top: calc(18% + var(--tabbar-h)); }

/* The tab bar rides INSIDE #dk-main, so the dock push was dragging it to mid-screen
   (user: "tabs move to the center"). Pull it back to the true left edge and span the full
   viewport — the panels start below its row, so nothing covers it. */
#dk-tabbar { transition: margin-left var(--t) var(--ease), width var(--t) var(--ease); }
/* With a dock open the bar rides the pushed #dk-main: it starts AT THE PANEL'S RIGHT EDGE —
   left-anchored in the visible space, never underneath the panel (user, 2026-07-17: "the tabs
   don't shift to make them visible"). The old full-width pull-back put the first tabs under
   the open panel. */

/* ---- Jump to latest (user, 2026-07-16): floats center-bottom over the chat when the log is
   scrolled off its bottom; click pins back down. ---- */
#dk-main { position: relative; }
#dk-jump {
  position: absolute;
  bottom: 14px;
  left: 50%;
  transform: translateX(-50%) translateY(6px);
  z-index: 40;
  padding: 4px 14px;
  /* Dim-amber PILL (user, 2026-07-17): --raised-2 read as no background at all over the log. */
  background: var(--amber-dim);
  border: 1px solid var(--amber);
  border-radius: 12px;
  color: var(--bg);
  font-weight: 700;
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  cursor: pointer;
  box-shadow: 0 4px 16px rgb(0 0 0 / 50%);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--t) var(--ease), transform var(--t) var(--ease);
}
#dk-jump[data-on="true"] {
  opacity: 1;
  pointer-events: auto;
  transform: translateX(-50%) translateY(0);
}
#dk-jump:hover { background: var(--amber); }

/* ---- Markdown FULL VIEW — a reading surface, not a 480px strip ------------ */
.dk-md-full {
  position: fixed;
  inset: 0;
  z-index: 1200;
  display: none;
  flex-direction: column;
  background: var(--bg);
}
.dk-md-full[data-open="true"] { display: flex; }
.dk-md-full-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 16px;
  border-bottom: 1px solid var(--border);
  color: var(--amber);
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.dk-md-full-close {
  margin-left: auto;
  width: 28px;
  height: 24px;
  padding: 0;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--amber);
  font-family: var(--font-mono);
  cursor: pointer;
}
.dk-md-full-close:hover { border-color: var(--amber); background: var(--hover); }
.dk-md-full-page {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 24px 0 60px;
}
/* HTML full view: the sandboxed iframe fills the surface. */
.dk-md-full-frame { flex: 1 1 auto; display: flex; padding: 12px; }
.dk-md-full-frame > .dk-artifact-frame,
.dk-md-full-frame > iframe { flex: 1 1 auto; width: 100%; height: 100%; border: 0; border-radius: 8px; background: #fff; }
.dk-md-full-page > * {
  width: min(var(--read-w), 92%);
  margin-inline: auto;
}

/* The old streaming caret is retired (user, 2026-07-16): the in-log prompt block (#dk-alive)
   is the one "working" signal now — two blinking cursors is one too many. */
.dk-cursor { display: none !important; }

/* Share button: cyan when the artifact is live-shared; the unshare ✕ is red. */
.dk-artifact-share[data-active="true"] { color: var(--cyan); border-color: var(--cyan); }
.dk-artifact-unshare { color: var(--red); border-color: var(--border-danger, var(--red)); }
.dk-share-toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%) translateY(8px);
  z-index: 1400;
  max-width: 90vw;
  padding: 8px 16px;
  background: var(--surface);
  border: 1px solid var(--cyan);
  border-radius: var(--radius);
  color: var(--cyan);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--t) var(--ease), transform var(--t) var(--ease);
  box-shadow: 0 6px 24px rgb(0 0 0 / 50%);
}
.dk-share-toast[data-on="true"] { opacity: 1; transform: translateX(-50%) translateY(0); }

/* Side handles are TABS (user, 2026-07-16): the open panel's handle stays visible and
   HIGHLIGHTED instead of vanishing — obvious state, and one click swaps or closes. */
.dk-threads-handle[data-active="true"],
.dk-artifacts-handle[data-active="true"],
.dk-workflows-handle[data-active="true"] {
  background: var(--surface-3, var(--hover));
  color: var(--amber);
  border-color: var(--amber);
  text-shadow: var(--glow);
}

/* ============================================================================
 * DYNAMIC AGENTS (personas.js) — the AGENTS menu, avatars, and activity.
 * The modals reuse the relay-modal shell (dk-relay-*); only agent-specific
 * bits live here. The message chip is emitted by render/message.js.
 * ==========================================================================*/
.dk-personas-btn { position: relative; }

/* The avatar, everywhere it appears: 20px inline (messages / lane header),
 * 32px in list rows, 64px as the detail preview. Round, cover-cropped. */
.dk-persona-avatar {
  width: 20px; height: 20px; border-radius: 50%; object-fit: cover;
  flex: 0 0 auto; vertical-align: middle; border: 1px solid var(--border);
}
.dk-persona-avatar.row { width: 64px; height: 64px; }
.dk-persona-avatar.preview { width: 64px; height: 64px; }
.dk-persona-avatar-fallback.row { font-size: var(--fs-lg); }
/* No image yet — a round initial in the avatar's place. */
.dk-persona-avatar-fallback {
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--raised-2, var(--surface)); color: var(--amber);
  font-family: var(--font-mono); font-size: var(--fs-micro); line-height: 1;
}
.dk-persona-avatar-fallback.preview { font-size: var(--fs-lg); }

/* ---- list modal: rows with a big avatar, a two-line info column, chevron ---- */
.dk-persona-list { display: flex; flex-direction: column; gap: 8px; padding: 12px 2px; }
.dk-persona-empty { color: var(--amber-dim); font-size: var(--fs-micro); padding: 8px 0; }
.dk-persona-row {
  display: flex; align-items: center; gap: 14px; width: 100%;
  padding: 12px 14px; background: transparent; border: 1px solid var(--border);
  border-radius: var(--radius); font-family: var(--font-mono); font-size: var(--fs-small);
  color: var(--amber); text-align: left; cursor: pointer; min-width: 0;
  transition: border-color var(--t) var(--ease), background-color var(--t) var(--ease);
}
.dk-persona-row:hover { border-color: var(--amber); background: var(--hover); }
/* The avatar rides inside a padded square tile whose fill is a shade off the row — the frame
   gives the picture form and holds it away from the row border (user, 2026-07-19). */
.dk-persona-avatarframe {
  flex: 0 0 auto; display: flex; align-items: center; justify-content: center;
  padding: 8px; border-radius: 12px;
  background: var(--raised-2, rgba(255,255,255,0.05));
  border: 1px solid var(--border);
}
.dk-persona-row:hover .dk-persona-avatarframe { border-color: rgb(var(--amber-rgb, 255 176 0) / 40%); }
.dk-persona-avatar.row { border-radius: 8px; }
.dk-persona-rowcol { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.dk-persona-rowtop { display: flex; align-items: center; gap: 8px; min-width: 0; }
.dk-persona-rowname {
  flex: 0 1 auto; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
  font-size: var(--fs-base, var(--fs-small)); font-weight: 600; letter-spacing: 0.02em;
}
/* Role IS the title: bright, sits directly under the name. */
.dk-persona-rowrole {
  color: var(--cyan); font-size: var(--fs-micro); font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.07em;
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
.dk-persona-rowmeta {
  color: var(--amber-dim); font-size: var(--fs-micro); text-transform: uppercase; letter-spacing: 0.06em;
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
.dk-persona-rowdesc {
  color: var(--muted, var(--amber-dim)); font-size: var(--fs-micro); line-height: 1.4;
  overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2;
  -webkit-box-orient: vertical; white-space: normal; opacity: 0.85;
}
.dk-persona-badge {
  flex: 0 0 auto; padding: 1px 7px; border-radius: 999px;
  background: var(--raised-2, var(--surface)); color: var(--amber-dim); font-size: var(--fs-micro);
  border: 1px solid var(--border);
}
.dk-persona-badge.chat { color: var(--cyan); border-color: var(--cyan); }
.dk-persona-chevron { flex: 0 0 auto; color: var(--amber-dim); font-size: var(--fs-lg); align-self: center; }

/* ---- detail modal ---- */
.dk-persona-idrow { align-items: center; }
.dk-persona-foot .dk-persona-back { margin-right: auto; }
.dk-tab-mempurge.dk-persona-delete { flex: 0 0 auto; }

/* ---- activity: 'doing now' + 'recent', mirroring the dk-tab-memlist idioms ---- */
.dk-persona-activity {
  max-height: 200px; overflow-y: auto;
  display: flex; flex-direction: column; gap: 2px; margin-bottom: 6px;
}
.dk-persona-actlabel {
  color: var(--amber-dim); font-size: var(--fs-micro); text-transform: uppercase;
  letter-spacing: 0.1em; margin: 6px 0 2px;
}
.dk-persona-actlabel:first-child { margin-top: 0; }
.dk-persona-actempty { color: var(--amber-dim); font-size: var(--fs-micro); padding: 2px 0; }
.dk-persona-actrow,
.dk-persona-tabrow {
  display: flex; gap: 8px; align-items: baseline; min-width: 0;
  padding: 2px 6px; font-size: var(--fs-micro);
}
.dk-persona-actwhen { flex: 0 0 auto; color: var(--amber-dim); }
.dk-persona-actglyph { flex: 0 0 auto; color: var(--cyan); }
.dk-persona-actsummary { color: var(--amber); overflow: hidden; white-space: nowrap; text-overflow: ellipsis; min-width: 0; }
.dk-persona-tabtitle { color: var(--amber); overflow: hidden; white-space: nowrap; text-overflow: ellipsis; min-width: 0; }

/* ---- the message-header chip (render/message.js) — avatar + name atop an assistant block.
 *      Spans the text column of the assistant grid (the .dk-msg-head grid-column:2 rule),
 *      dim so it labels the reply without competing with it. ---- */
.dk-msg-agenthead {
  display: flex; align-items: center; gap: 6px;
  color: var(--amber-dim); font-size: var(--fs-micro); margin-bottom: 2px;
}
.dk-msg-agentname { letter-spacing: 0.04em; }

/* ---- the orchestrator lane header avatar (app.js decorates lanes.js's DOM) ---- */
.dk-lane-head .dk-persona-avatar { width: 16px; height: 16px; margin-right: 4px; }

/* ============================================================================
 * DYNAMIC AGENTS v2 (personas.js) — the WIDE two-column detail: structured
 * charter form + lessons on the left, activity + dreams review on the right.
 * Still the relay-modal shell; dk-modal-wide just gives it room to breathe.
 * ==========================================================================*/
.dk-relay-modal.dk-modal-wide { width: min(920px, 96vw); max-width: none; max-height: 92vh; }

/* Two columns on wide, one under 800px. minmax(0,…) so long lesson/dream text
 * ellipsizes inside its column instead of blowing the grid out sideways. */
.dk-persona-detailgrid {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  column-gap: 24px; align-items: start;
}
@media (max-width: 800px) { .dk-persona-detailgrid { grid-template-columns: minmax(0, 1fr); } }
.dk-persona-col { min-width: 0; }

/* ---- charter form: label + control rows, labels mirroring the doc keys (§3) ---- */
.dk-persona-chrow { display: flex; gap: 8px; align-items: center; margin-top: 6px; min-width: 0; }
.dk-persona-chlabel {
  flex: 0 0 128px; color: var(--amber-dim); font-size: var(--fs-micro);
  letter-spacing: 0.04em;
}
.dk-persona-chrow .dk-relay-input,
.dk-persona-chrow .dk-tab-select { flex: 1 1 auto; }
/* the 0-1 dials — amber thumb, live cyan readout beside */
.dk-persona-chrange { flex: 1 1 auto; min-width: 0; accent-color: var(--amber); }
.dk-persona-chval { flex: 0 0 36px; text-align: right; color: var(--cyan); font-size: var(--fs-micro); }

/* ---- lessons: read-only 'confidence · text (n ep)' rows; retired collapsed ---- */
.dk-persona-lessons { display: flex; flex-direction: column; gap: 2px; }
.dk-persona-lessonrow {
  display: flex; gap: 8px; align-items: baseline; min-width: 0;
  padding: 2px 0; font-size: var(--fs-micro);
}
.dk-persona-lessonconf { flex: 0 0 auto; color: var(--cyan); }
.dk-persona-lessontext { color: var(--amber); min-width: 0; }
.dk-persona-lessonfrom { flex: 0 0 auto; color: var(--amber-dim); }
.dk-persona-lessons-retired summary {
  cursor: pointer; color: var(--amber-dim); font-size: var(--fs-micro); margin-top: 4px;
}
.dk-persona-lessons-retired .dk-persona-lessontext { color: var(--amber-dim); text-decoration: line-through; }

/* ---- dreams: header ('dreams' + dream now), then run rows newest-first ---- */
.dk-persona-dreamhead { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.dk-persona-dreamhead .dk-relay-h { margin: 0; flex: 1 1 auto; }
.dk-persona-dreamnow { flex: 0 0 auto; }
.dk-persona-dreamnow:disabled { opacity: 0.4; cursor: not-allowed; }
.dk-persona-dreams { display: flex; flex-direction: column; gap: 4px; max-height: 340px; overflow-y: auto; }

/* a run: status dot (running reuses the pulsing lane dot), when, summary, status word */
.dk-persona-dreamrow {
  display: flex; gap: 8px; align-items: center; width: 100%;
  padding: 4px 6px; background: transparent; border: 1px solid var(--border);
  border-radius: var(--radius); font-family: var(--font-mono); font-size: var(--fs-micro);
  color: var(--amber); text-align: left; cursor: pointer; min-width: 0;
}
.dk-persona-dreamrow:hover { border-color: var(--amber); }
.dk-persona-dreamdot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; }
.dk-persona-dreamdot[data-status="proposed"] { background: var(--amber); box-shadow: var(--glow-box); }
.dk-persona-dreamdot[data-status="approved"] { background: var(--amber-dim); }
.dk-persona-dreamdot[data-status="rejected"],
.dk-persona-dreamdot[data-status="failed"] { background: rgb(var(--red-rgb) / 55%); }
.dk-persona-dreamwhen { flex: 0 0 auto; color: var(--amber-dim); }
.dk-persona-dreamsum { flex: 1 1 auto; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; min-width: 0; }
.dk-persona-dreamstatus { flex: 0 0 auto; color: var(--amber-dim); text-transform: uppercase; letter-spacing: 0.06em; }

/* expanded run body: proposals + (for 'proposed') the approve/reject pair */
.dk-persona-dreambody { display: flex; flex-direction: column; gap: 4px; padding: 2px 6px 8px 22px; }
.dk-persona-proposal { display: flex; gap: 8px; align-items: baseline; min-width: 0; font-size: var(--fs-micro); }
.dk-persona-propkind { flex: 0 0 auto; white-space: nowrap; }
.dk-persona-propkind.lesson { color: var(--amber); }
.dk-persona-propkind.retire { color: var(--red); }
.dk-persona-proptext { color: var(--amber); min-width: 0; }
.dk-persona-propmeta { flex: 0 0 auto; color: var(--amber-dim); }
.dk-persona-dreamerr { color: var(--red); font-size: var(--fs-micro); }
.dk-persona-dreambtns { display: flex; gap: 8px; margin-top: 2px; }

/* ============================================================================
 * PHONE LAYOUT (user, 2026-07-16: "deep review of the UX vs a phone").
 * One breakpoint, one philosophy: on a narrow/tall screen nothing PUSHES and
 * nothing OVERLAPS — panels and modals become full-screen sheets, the dock
 * rail becomes a chip row in the tab bar (edge tabs sat ON TOP of the
 * conversation and even modals), and every control clears a 44px thumb.
 * ==========================================================================*/
@media (max-width: 720px) {
  /* Taller tab bar: 40px tabs inside the desktop 34px bar were CLIPPED (overflow-y hidden),
     which killed half of every tab's tap area — "the tab list doesn't work on mobile". Tabs
     stretch to fill the bar instead of carrying their own min-height. */
  :root { --read-w: 100%; --tabbar-h: 48px; }

  /* -- Docks: full-screen sheets. The push (margin-left) made chat a 39px sliver. */
  body[data-dock-left="true"] #dk-main,
  body[data-dock-left="true"] #dk-composer,
  body[data-dock-left="true"] #dk-ask-dock { margin-left: 0; }
  body[data-dock-left="true"] #dk-tabbar { margin-left: 0; width: 100%; }
  body[data-dock-left="true"] #dk-composer { padding-inline: var(--pad); }
  body[data-dock-left="true"] #dk-ask-dock {
    margin-inline: auto;
    width: min(var(--read-w), calc(100% - 2 * var(--pad)));
  }
  .dk-threads,
  .dk-artifacts,
  .dk-workflows {
    width: 100vw;
    top: var(--topbar-h);
    bottom: 0;
    z-index: 1200; /* above the rail and the machine room */
  }

  /* -- Dock rail: a horizontal chip row at the right end of the tab bar. The
        vertical edge tabs overlapped conversation text, permission cards and
        open modals; a chip row occupies real layout space in existing chrome. */
  #dk-dock-rail {
    flex-direction: row;
    gap: 4px;
    left: auto;
    right: 6px;
    top: calc(var(--topbar-h) + 8px); /* vertically centered in the 48px bar */
  }
  body[data-dock-left="true"] #dk-dock-rail { left: auto; }
  #dk-dock-rail .dk-threads-handle,
  #dk-dock-rail .dk-artifacts-handle,
  #dk-dock-rail .dk-workflows-handle {
    writing-mode: horizontal-tb;
    padding: 6px 10px;
    min-height: 32px;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius);
    font-size: 9px;
  }
  /* Tabs stop short of the chips so the two rows share the line without collision.
     flex:none on the list is LOAD-BEARING: squeezed by this padding, the list SHRANK to
     21px while its tabs overflowed it, and the + button laid out on top of them — every
     tap on a tab hit + instead ("the tab list doesn't work on mobile"). The list keeps its
     content width and the BAR scrolls. Stretch fills the 48px bar with tappable tab. */
  /* !important: tabs.js sets inline align-items:center on the bar/list, and inline loses
     only to !important. Stretch is what makes a tab's tap area the full 48px row. */
  #dk-tabbar { padding-right: 250px; align-items: stretch !important; }
  #dk-tablist { flex: 0 0 auto; align-items: stretch !important; }
  .dk-tab-new { flex: 0 0 auto; }

  /* -- Modals: full-screen sheets. 90vh centered boxes left slivers of stale
        UI visible around them, and the 920px agents modal has no room anyway. */
  .dk-relay-overlay { padding: 0; }
  .dk-relay-modal,
  .dk-relay-modal.dk-modal-wide {
    width: 100vw;
    max-width: none;
    height: 100dvh;
    max-height: none;
    border: 0;
  }

  /* -- Composer: the textarea owns the full row; actions drop to their own row
        beneath (the placeholder wrapped to four lines beside three buttons). */
  #dk-composer { flex-wrap: wrap; }
  #dk-composer #dk-input { flex: 1 1 100%; }
  #dk-composer .dk-composer-actions { margin-left: auto; }
  .dk-auto { height: 44px; min-width: 64px; }
  .dk-send,
  .dk-cancel { width: 44px; height: 44px; }

  /* -- Armed close: the first tap turns the X red and unmistakable; only the second closes. */
  .dk-tab-close[data-armed="true"] {
    color: var(--bg);
    background: var(--red);
    border-radius: var(--radius);
    font-weight: 700;
  }

  /* -- Touch targets: tabs stretch to the 48px bar (align-items: stretch does the work —
        a min-height under overflow-y:hidden just clips). Close X gets a padded hit area. */
  .dk-tab { max-width: 46vw; }
  .dk-tab-close { padding: 10px 8px; margin: -10px -8px; }
  .dk-tab-new { min-width: 48px; }
  .dk-mode-btn { min-height: 36px; }

  /* -- Prompt/question dock: never bury the conversation under stacked cards. */
  #dk-ask-dock { max-height: 55dvh; overflow-y: auto; }
  .dk-perm-btn { min-height: 44px; }
  .dk-ask-opt { min-height: 44px; }

  /* -- Panel close buttons are the ONLY way out of a full-screen sheet — thumb-size them. */
  .dk-threads-close,
  .dk-artifacts .dk-artifacts-btn,
  .dk-workflows-close {
    min-width: 44px;
    min-height: 44px;
  }

  /* -- Machine room: smaller idle footprint on a short screen. */
  .dk-critter svg { width: 34px; height: 34px; }

  /* -- Home-bar safe area: the send row must clear the iOS/Android gesture strip. */
  #dk-composer { padding-bottom: calc(8px + env(safe-area-inset-bottom)); }

  /* -- Jump-to-latest: thumb-size the pill. */
  #dk-jump { min-height: 44px; padding: 10px 18px; }

  /* -- Wide content never forces a page scroll; it scrolls inside its box. */
  .dk-tool-card,
  .dk-md-table-wrap { max-width: 100%; overflow-x: auto; }

  /* -- Lane header buttons ("context") were 12px tall. */
  .dk-lane-btn { min-height: 32px; padding: 6px 10px; }

  /* -- Machine room: first critter was clipped at the screen edge. */
  .dk-pager { padding-inline: 10px; }
}

/* ============================================================================
 * MOBILE TAB DRAWER (user, 2026-07-16: "slide out menu on the right for tabs").
 * Desktop never sees any of this — the button and drawer exist in the DOM but
 * stay display:none until the phone breakpoint.
 * ==========================================================================*/
.dk-tabdrawer,
.dk-tabdrawer-scrim,
.dk-tabdrawer-btn { display: none; }

@media (max-width: 720px) {
  /* The strip gives way to ONE button: active tab name + count + menu glyph. */
  #dk-tablist,
  #dk-tab-new,
  .dk-tab-caveat { display: none !important; }
  .dk-tabdrawer-btn {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1 1 auto;
    min-width: 0;
    height: 100%;
    padding: 0 12px;
    background: transparent;
    border: 0;
    color: var(--amber);
    font-family: var(--font-mono);
    font-size: var(--fs-base);
    text-align: left;
    cursor: pointer;
  }
  .dk-tabdrawer-btn-title {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 700;
  }
  .dk-tabdrawer-btn-count { color: var(--amber-dim); font-size: var(--fs-micro); }
  .dk-tabdrawer-btn-caret { margin-left: auto; color: var(--amber-dim); font-size: 14px; }

  .dk-tabdrawer-scrim {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 1280;
    background: rgb(0 0 0 / 55%);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--t) var(--ease);
  }
  .dk-tabdrawer-scrim[data-open="true"] { opacity: 1; pointer-events: auto; }

  .dk-tabdrawer {
    display: flex;
    flex-direction: column;
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: min(84vw, 360px);
    z-index: 1290; /* under modals (1300), over everything else */
    background: var(--surface);
    border-left: 1px solid var(--border-strong);
    transform: translateX(100%);
    transition: transform var(--t) var(--ease);
  }
  .dk-tabdrawer[data-open="true"] { transform: none; box-shadow: -12px 0 40px rgb(0 0 0 / 55%); }

  .dk-tabdrawer-head {
    display: flex;
    align-items: center;
    padding: 10px 8px 10px 14px;
    border-bottom: 1px solid var(--border);
  }
  .dk-tabdrawer-title {
    color: var(--amber);
    font-size: var(--fs-micro);
    text-transform: uppercase;
    letter-spacing: 0.1em;
  }
  .dk-tabdrawer-close {
    margin-left: auto;
    min-width: 44px;
    min-height: 44px;
    background: transparent;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    color: var(--amber);
    font-family: var(--font-mono);
    font-size: 16px;
    cursor: pointer;
  }

  .dk-tabdrawer-list { flex: 1 1 auto; overflow-y: auto; padding: 6px; display: flex; flex-direction: column; gap: 4px; }
  .dk-tabdrawer-row {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 52px;
    padding: 0 4px 0 12px;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    color: var(--amber-dim);
    font-family: var(--font-mono);
    font-size: var(--fs-base);
    cursor: pointer;
  }
  .dk-tabdrawer-row[data-active="true"] {
    color: var(--amber);
    border-color: var(--amber);
    background: var(--surface);
  }
  .dk-tabdrawer-row-title {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .dk-tabdrawer-row-close {
    flex: 0 0 auto;
    min-width: 44px;
    min-height: 44px;
    background: transparent;
    border: 0;
    border-radius: var(--radius);
    color: var(--amber-dim);
    font-family: var(--font-mono);
    font-size: 16px;
    cursor: pointer;
  }
  .dk-tabdrawer-row-close[data-armed="true"] {
    color: var(--bg);
    background: var(--red);
    font-weight: 700;
  }

  .dk-tabdrawer-new {
    margin: 8px;
    min-height: 48px;
    background: transparent;
    border: 1px dashed var(--border);
    border-radius: var(--radius);
    color: var(--amber-dim);
    font-family: var(--font-mono);
    font-size: var(--fs-base);
    cursor: pointer;
  }
  .dk-tabdrawer-new:active { color: var(--amber); border-color: var(--amber); }
}

/* MINI MACHINE in the tab strip / drawer (user, 2026-07-17): the machine-room sprite as the
   tab's status icon — same data-mood/data-activity animations, sized for a tab row. The old
   status dot yields to it in the strip (attention now reads as the 'wait' face). */
.dk-critter-mini {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  width: 20px;
  height: 20px;
  pointer-events: none;
}
.dk-critter-mini svg { width: 20px; height: 20px; }
.dk-critter-mini .dk-critter-name { display: none; }
.dk-tab .dk-tab-dot { display: none; }

/* MODAL SCROLL PERF (user, 2026-07-17: "scrolling within the agent and workspace modals is
   laggy"). Long lists under text-shadow glow repaint expensively on every scrolled frame —
   inside modal scroll bodies the glow goes off and rows skip offscreen rendering entirely. */
.dk-relay-modal-body,
.dk-relay-modal-body * { text-shadow: none !important; }
.dk-relay-modal-body { overscroll-behavior: contain; }
.dk-relay-modal-body > * { content-visibility: auto; contain-intrinsic-size: auto 60px; }

/* PRE-AUTH: no cockpit chrome on the login/loading screen — the dock rail was floating over
   it ("also the threads tabs on that screen", 2026-07-17). */
body:not([data-authed="true"]) #dk-dock-rail,
body:not([data-authed="true"]) .dk-threads-handle,
body:not([data-authed="true"]) .dk-artifacts-handle,
body:not([data-authed="true"]) .dk-workflows-handle,
body:not([data-authed="true"]) .dk-shells-handle { display: none !important; }

/* ============================================================================
 * OVERVIEW — mission control (user, 2026-07-17). One station per workspace:
 * big machine + terminal it feeds, sub-minis wandering below, dialog bubbles
 * for tool chatter, and answerable prompt popups floating over the machine.
 * ==========================================================================*/
.dk-tab-overview { border-right: 1px solid var(--border); }
.dk-tab-overview .dk-tab-title { color: var(--cyan); letter-spacing: 0.08em; text-transform: uppercase; font-size: var(--fs-micro); }
.dk-tab-overview[data-active="true"] { background: var(--surface); border-bottom: 2px solid var(--cyan); }
.dk-tabdrawer-overview .dk-tabdrawer-row-title { color: var(--cyan); }

.dk-overview-pane {
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
  flex-direction: column;
  overflow-y: auto;
  background: var(--bg);
}
/* Mission control owns the screen: the prompt dock, file map and machine room stand down —
   their information is IN the overview (popups, status lines, the machines themselves). */
body[data-overview="true"] #dk-ask-dock,
body[data-overview="true"] #dk-filemap,
body[data-overview="true"] #dk-composer,
body[data-overview="true"] #dk-dock-rail,
body[data-overview="true"] .dk-threads,
body[data-overview="true"] .dk-artifacts,
body[data-overview="true"] .dk-workflows,
body[data-overview="true"] .dk-shells,
body[data-overview="true"] #dk-jump,
body[data-overview="true"] .dk-pager { display: none !important; }
.dk-ov-head { display: flex; align-items: baseline; gap: 12px; padding: 14px 18px 6px; }
.dk-ov-title { color: var(--cyan); font-size: var(--fs-lg); letter-spacing: 0.12em; text-transform: uppercase; }
.dk-ov-tagline { color: var(--amber-dim); font-size: var(--fs-micro); }
.dk-ov-field {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}
.dk-ov-empty { color: var(--amber-dim); font-family: var(--font-mono); padding: 24px; }

/* A workspace wanders the field: transform-driven random walk, everything rides along. */
.dk-ov-workspace {
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  width: 210px;
  transition: transform 2.6s ease-in-out;
  will-change: transform;
}
.dk-ov-workspace[data-state="awaiting_permission"] .dk-ov-name { color: var(--red); }
.dk-ov-workspace[data-state="error"] .dk-ov-name { color: var(--red); }

/* OBJECTIVE pellet (user, 2026-07-17): the thing a working workspace chases, Pac-Man style. Lives
   on the field; hops when caught. Hidden unless the workspace is working. */
.dk-ov-goal {
  position: absolute;
  top: 0;
  left: 0;
  width: 14px;
  height: 14px;
  margin: 8px; /* so translate positions its center-ish */
  border-radius: 50%;
  background: var(--cyan);
  box-shadow: 0 0 10px rgb(var(--cyan-rgb, 0 229 255) / 70%);
  transform: translate(var(--gx, 0), var(--gy, 0));
  transition: transform 1.3s ease-in-out, opacity 0.4s var(--ease);
  opacity: 0;
  pointer-events: none;
  z-index: 1;
}
.dk-ov-goal[data-on="true"] { opacity: 1; }
/* The pulse is a child pseudo so it doesn't fight the position transform. */
.dk-ov-goal[data-on="true"]::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: inherit;
  animation: dk-ov-goal-pulse 0.9s ease-in-out infinite;
}
@keyframes dk-ov-goal-pulse {
  0%, 100% { transform: scale(1); opacity: 0.9; }
  50% { transform: scale(0.55); opacity: 0.5; }
}
@media (prefers-reduced-motion: reduce) { .dk-ov-goal[data-on="true"]::after { animation: none; } }
.dk-ov-name {
  background: transparent;
  border: 0;
  padding: 0;
  color: var(--amber);
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: var(--fs-base);
  cursor: pointer;
}
.dk-ov-name:hover { text-shadow: var(--glow); }
.dk-ov-big { width: 64px; height: 64px; position: relative; }
.dk-ov-big svg { width: 64px; height: 64px; }
.dk-ov-big .dk-critter-name { display: none; }

.dk-ov-subs {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  min-height: 0;
}
.dk-ov-sub {
  position: absolute;
  top: 0;
  left: 0;
  width: 30px;
  height: 44px; /* room for the caption under the machine */
  z-index: 2;
  /* The chase: each beat retargets a spot near the parent; the long transition IS the pursuit. */
  transition: transform 1.5s ease-in-out, opacity 0.6s var(--ease);
  will-change: transform;
}
.dk-ov-sub svg { width: 30px; height: 30px; }
.dk-ov-sub .dk-critter-name { display: none; }
/* What each little agent is doing: a tiny caption UNDER it — one per sub, never a pile of
   overlapping speech bubbles (user, 2026-07-17: "without it getting noisy"). */
.dk-ov-sublabel {
  position: absolute;
  top: 32px;
  left: 50%;
  transform: translateX(-50%);
  max-width: 74px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--amber-dim);
  font-family: var(--font-mono);
  font-size: 8px;
  text-align: center;
  opacity: 0;
  transition: opacity 0.3s var(--ease);
  pointer-events: none;
}
/* HOVER-ONLY (user, 2026-07-17: "hide the subagents info unless you mouse over them"). The
   label keeps the mini's LATEST activity; pointing at the machine reveals it. */

/* Thought bubble: the workspace's current state, floating off the machine's head. Two trailing
   dots sell the "thought" read; hidden entirely when idle. */
/* Workflow band: the busiest run's name + narration. It had NO styling, so it dumped as a raw
   text block under every station (user, 2026-07-19). Hide it and reveal ONLY on station hover. */
.dk-ov-wfband {
  position: absolute;
  top: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 5;
  max-width: 220px;
  padding: 4px 10px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--amber-dim);
  font-family: var(--font-mono);
  font-size: 10px;
  line-height: 1.4;
  text-align: center;
  white-space: normal;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s var(--ease, ease);
}
.dk-ov-wfband[data-status="running"] { border-color: var(--cyan); color: var(--cyan); }
/* Reveal only while hovering the station, and only when there IS a run to show. */
.dk-ov-workspace:hover .dk-ov-wfband[data-on="true"] { opacity: 1; }

.dk-ov-think {
  position: absolute;
  bottom: calc(100% + 10px);
  left: calc(100% - 10px);
  z-index: 4;
  max-width: 180px;
  padding: 4px 10px;
  background: var(--surface);
  border: 1px solid var(--cyan);
  border-radius: 12px;
  color: var(--cyan);
  font-family: var(--font-mono);
  font-size: 10px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: 0;
  transition: opacity 0.3s var(--ease);
  pointer-events: none;
}
.dk-ov-think[data-on="true"] { opacity: 1; }
.dk-ov-think::before,
.dk-ov-think::after {
  content: '';
  position: absolute;
  background: var(--surface);
  border: 1px solid var(--cyan);
  border-radius: 50%;
}
.dk-ov-think::before { width: 6px; height: 6px; left: -6px; bottom: -7px; }
.dk-ov-think::after { width: 3px; height: 3px; left: -12px; bottom: -13px; }

.dk-ov-packet {
  position: absolute;
  z-index: 5;
  width: 7px;
  height: 7px;
  border-radius: 2px;
  background: var(--amber);
  box-shadow: 0 0 8px rgb(var(--amber-rgb) / 60%);
  transition: transform 0.7s var(--ease), opacity 0.7s var(--ease);
  pointer-events: none;
}
.dk-ov-packet[data-kind="err"] { background: var(--red); box-shadow: 0 0 8px rgb(var(--red-rgb) / 60%); }

/* Dialog bubble: what the machine is DOING, in words. */
.dk-ov-say {
  position: absolute;
  bottom: calc(100% + 6px);
  right: calc(100% - 8px);
  z-index: 6;
  max-width: 220px;
  padding: 3px 8px;
  background: var(--bg);
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  color: var(--amber);
  font-family: var(--font-mono);
  font-size: 10px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: 0;
  transition: opacity 0.25s var(--ease);
  pointer-events: none;
}
.dk-ov-say[data-on="true"] { opacity: 1; }
.dk-ov-say::after {
  content: '';
  position: absolute;
  top: 100%;
  right: 10px;
  border: 4px solid transparent;
  border-top-color: var(--border-strong);
}

/* Prompt popup, floating over the station — answer without leaving mission control. */
.dk-ov-pop {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 10;
  width: min(260px, 85%);
  padding: 8px 10px;
  background: var(--bg);
  border: 1px solid var(--red);
  border-radius: var(--radius);
  box-shadow: 0 6px 24px rgb(0 0 0 / 55%);
  font-family: var(--font-mono);
}
.dk-ov-pop[data-below="true"] { bottom: auto; top: calc(100% + 8px); }
.dk-ov-pop[data-kind="ask"] { border-color: var(--cyan); }
.dk-ov-pop-title { color: var(--amber); font-size: var(--fs-micro); font-weight: 700; margin-bottom: 6px; overflow-wrap: anywhere; }
.dk-ov-pop-brief { color: var(--amber-dim); font-size: 10px; margin-bottom: 6px; overflow-wrap: anywhere; }
.dk-ov-pop-actions { display: flex; gap: 6px; }
.dk-ov-pop-btn {
  flex: 1 1 auto;
  min-height: 30px;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--amber);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  cursor: pointer;
}
.dk-ov-pop-btn[data-action="allow"] { border-color: var(--amber); }
.dk-ov-pop-btn[data-action="always"] { border-color: var(--cyan); color: var(--cyan); }
.dk-ov-pop-btn[data-action="deny"] { border-color: var(--red); color: var(--red); }
.dk-ov-pop-btn:hover { background: var(--hover); }
.dk-ov-pop-opts { display: flex; flex-direction: column; gap: 4px; }
.dk-ov-pop-opt {
  min-height: 30px;
  text-align: left;
  padding: 4px 8px;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--amber);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  cursor: pointer;
}
.dk-ov-pop-opt:hover { border-color: var(--cyan); color: var(--cyan); }
.dk-ov-pop-more {
  margin-top: 6px;
  background: transparent;
  border: 0;
  color: var(--amber-dim);
  font-family: var(--font-mono);
  font-size: 10px;
  text-decoration: underline;
  cursor: pointer;
}

@media (prefers-reduced-motion: reduce) { .dk-ov-sub { transition: opacity 0.6s var(--ease); } }
@media (max-width: 720px) {
  .dk-ov-workspace { width: 160px; }
}

/* ============================================================================
 * ULTRACODE PERF (2026-07-17): the two measured-but-misscoped fixes, applied
 * to the surface that actually hurts — the unbounded transcript.
 * ==========================================================================*/
/* Offscreen transcript blocks skip style/layout/paint entirely. */
.dk-lane-body > .dk-msg,
.dk-lane-body > .dk-tool-group,
.dk-lane-body > .dk-diff-block,
#dk-chat > .dk-msg {
  content-visibility: auto;
  contain-intrinsic-size: auto 120px;
}
/* Glow is chrome, not body text: a 6px text-shadow on every bold/heading/tool-name re-rasters
   on each streaming reflow. Keep glow on singleton chrome (titles, buttons) — drop it from
   bulk in-transcript text. */
.dk-lane-body .dk-md-b,
.dk-lane-body .dk-md-h,
.dk-lane-body .dk-tool-name,
#dk-chat .dk-md-b,
#dk-chat .dk-md-h { text-shadow: none; }


/* ============================================================================
 * SHELLS PANEL (user, 2026-07-17): a per-workspace terminal log of every Bash /
 * shell_exec the agent runs — command + captured output, newest last.
 * ==========================================================================*/
.dk-shells {
  position: fixed;
  right: auto;
  left: 0;
  bottom: 0;
  z-index: 70;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border-right: 1px solid var(--border-strong);
  transform: translateX(-100%);
  transition: transform var(--t) var(--ease);
}
.dk-shells[data-open="true"] { transform: none; box-shadow: 12px 0 40px rgb(0 0 0 / 45%); }
.dk-shells-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 8px 10px 14px;
  border-bottom: 1px solid var(--border);
}
.dk-shells-title { color: var(--amber); font-size: var(--fs-micro); text-transform: uppercase; letter-spacing: 0.1em; }
.dk-shells-count {
  min-width: 20px;
  text-align: center;
  padding: 0 5px;
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--amber-dim);
  font-size: var(--fs-micro);
}
.dk-shells-close {
  margin-left: auto;
  min-width: 28px;
  min-height: 28px;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--amber);
  font-family: var(--font-mono);
  cursor: pointer;
}
.dk-shells-close:hover { background: var(--hover); border-color: var(--amber); }
.dk-shells-list { flex: 1 1 auto; overflow-y: auto; padding: 8px; display: flex; flex-direction: column; gap: 8px; }
.dk-shells-empty { color: var(--amber-dim); font-size: var(--fs-micro); padding: 12px 4px; }

.dk-shell {
  flex: 0 0 auto; /* NEVER shrink — a flex column with overflow scrolls, it does not squish rows
                     (user, 2026-07-17: "showed right once then broke" = flex-shrink crushing). */
  border: 1px solid var(--border);
  border-left: 2px solid var(--amber-dim);
  border-radius: var(--radius);
  background: var(--bg);
  overflow: hidden;
}
/* Spacer between the ACTIVE (running) shells on top and the finished ones below. */
.dk-shells-divider {
  flex: 0 0 auto;
  height: 1px;
  margin: 4px 2px;
  background: var(--border);
  position: relative;
}
.dk-shells-divider::after {
  content: 'done';
  position: absolute;
  right: 4px;
  top: -7px;
  padding: 0 5px;
  background: var(--surface);
  color: var(--amber-dim);
  font-family: var(--font-mono);
  font-size: 8px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}
.dk-shell[data-status="running"] { border-left-color: var(--cyan); }
.dk-shell[data-status="ok"] { border-left-color: var(--amber-dim); }
.dk-shell[data-status="error"] { border-left-color: var(--red); }
.dk-shell-cmd {
  display: flex;
  align-items: baseline;
  gap: 6px;
  width: 100%;
  padding: 6px 8px;
  background: transparent;
  border: 0;
  text-align: left;
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  white-space: nowrap;
  overflow: hidden;
}
.dk-shell-cmd:hover { background: var(--hover); }
.dk-shell-cmd-text { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--amber); }
.dk-shell-when { flex: 0 0 auto; color: var(--amber-dim); font-size: var(--fs-micro); }
.dk-shell-chars { flex: 0 0 auto; color: var(--amber-dim); font-size: var(--fs-micro); min-width: 40px; text-align: right; }
.dk-shell-script {
  margin: 0;
  padding: 6px 8px;
  border-top: 1px solid var(--border);
  max-height: 200px; /* a 200-line PowerShell script must not make one row fill the panel */
  overflow: auto;
  color: var(--amber);
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.dk-shell-caret { color: var(--amber-dim); flex: 0 0 auto; width: 12px; }
.dk-shell-sigil { color: var(--amber); font-weight: 700; flex: 0 0 auto; }
.dk-shell-meta {
  padding: 0 8px 4px;
  color: var(--amber-dim);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
}
.dk-shell[data-status="error"] .dk-shell-meta { color: var(--red); }
.dk-shell-live {
  display: flex;
  gap: 6px;
  padding: 2px 8px 6px;
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  color: var(--cyan);
}
.dk-shell-live .dk-shell-sigil { color: var(--cyan); }
.dk-shell-live-block { color: var(--cyan); animation: dk-alive-blink 1.1s steps(1, end) infinite; }
@media (prefers-reduced-motion: reduce) { .dk-shell-live-block { animation: none; opacity: 0.6; } }
:root[data-motion="off"] .dk-shell-live-block { animation: none !important; opacity: 0.6; }
/* A running row's left bar keeps pulsing so a collapsed running shell still reads as alive. */
.dk-shell[data-status="running"] { animation: dk-shell-running-edge 1.6s ease-in-out infinite; }
@keyframes dk-shell-running-edge {
  0%, 100% { border-left-color: var(--cyan); }
  50% { border-left-color: rgb(var(--cyan-rgb, 0 229 255) / 35%); }
}
@media (prefers-reduced-motion: reduce) { .dk-shell[data-status="running"] { animation: none; } }

.dk-shell-out {
  margin: 0;
  padding: 6px 8px;
  border-top: 1px solid var(--border);
  max-height: 260px;
  overflow: auto;
  color: var(--amber-dim);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
