/* Visual Claude - stage chrome. The palette variables are injected from Swift
   (VC.theme) so the scene always matches the native app; the values here are
   only fallbacks for a cold load. */
:root {
  --bg: #0E0D0C;
  --chrome: #161413;
  --surface: #2A2622;
  --border: #322E29;
  --text: #F4EFE6;
  --text-dim: #ADA392;
  --muted: #6E6557;
  --accent: #CBA76A;     /* liquid champagne voice - Claude */
  --tool: #8E8C82;       /* brushed pewter - machine actions */
  --attention: #7C93AC;  /* needs-you steel */
  --success: #6FA084;
  --danger: #BD5742;
  --diff-add: #82B58F;   /* additions - matches the native diff palette */
  --diff-del: #C96A52;   /* deletions */
  --syntax-keyword: #C5A3FF;
  --syntax-string: #9BCB83;
  --syntax-comment: #756D60;
  --syntax-type: #E0BE72;
  --syntax-function: #7FB4D8;
  --syntax-number: #D79A6B;
  --syntax-literal: #73C7C7;
  --syntax-operator: #A79B8A;
  --hud-font: 12px ui-monospace, "SF Mono", Menlo, monospace;
  color-scheme: dark;
}

* { box-sizing: border-box; }

.syn-keyword { color: var(--syntax-keyword); }
.syn-string { color: var(--syntax-string); }
.syn-comment { color: var(--syntax-comment); font-style: italic; }
.syn-type { color: var(--syntax-type); }
.syn-function { color: var(--syntax-function); }
.syn-number { color: var(--syntax-number); }
.syn-literal { color: var(--syntax-literal); }
.syn-operator { color: var(--syntax-operator); }
.syn-add { color: var(--diff-add); }
.syn-del { color: var(--diff-del); }

html, body {
  margin: 0;
  height: 100%;
  width: 100%;
  overflow: hidden;
  background: transparent;       /* the native surface shows through */
  -webkit-font-smoothing: antialiased;
  cursor: default;
  -webkit-user-select: none;
  user-select: none;
  -webkit-user-drag: none;
  -webkit-touch-callout: none;
}

#bg, #scene {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  -webkit-user-select: none;
  user-select: none;
  -webkit-user-drag: none;
}
#bg { z-index: 0; }
#scene { z-index: 1; }

#logic-layer {
  position: fixed;
  inset: 0;
  /* Behind every agent canvas/window, but above the ambient backdrop. Interaction
     stays on #canvashit; this SVG is visual-only. */
  z-index: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  overflow: visible;
}

#logic-queue-layer {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: visible;
}

.logic-queued-stack {
  position: absolute;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  gap: 7px;
  filter: drop-shadow(0 16px 30px rgba(0, 0, 0, 0.52));
}

.logic-queued-prompt {
  padding: 10px 12px 11px;
  border-radius: 8px;
  border: 1px solid color-mix(in srgb, var(--attention) 58%, var(--border));
  background: color-mix(in srgb, var(--attention) 14%, var(--chrome));
  color: var(--text);
  font: 600 13px/1.46 -apple-system, system-ui, "SF Pro Text", sans-serif;
  letter-spacing: 0.005em;
  max-height: 114px;
  overflow: hidden;
}

.logic-queued-prompt::before {
  content: "queued prompt";
  display: block;
  margin-bottom: 8px;
  color: color-mix(in srgb, var(--attention) 76%, var(--text));
  font: 650 9.5px/1 ui-monospace, "SF Mono", Menlo, monospace;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

.logic-queued-text {
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  white-space: normal;
  overflow: hidden;
  overflow-wrap: anywhere;
}

.logic-queued-more {
  align-self: flex-start;
  padding: 4px 8px 5px;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--attention) 40%, transparent);
  background: color-mix(in srgb, var(--attention) 10%, var(--chrome));
  color: color-mix(in srgb, var(--attention) 74%, var(--text-dim));
  font: 650 9px/1 ui-monospace, "SF Mono", Menlo, monospace;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.logic-link {
  fill: none;
  stroke: color-mix(in srgb, var(--muted) 72%, transparent);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.82;
  filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.42));
}
.logic-link.is-done,
.logic-link.is-fired {
  stroke: color-mix(in srgb, var(--success) 84%, var(--accent));
  opacity: 0.96;
}
.logic-link.is-blocked {
  stroke: color-mix(in srgb, var(--tool) 74%, transparent);
  stroke-dasharray: 5 7;
}
.logic-link.is-preview {
  stroke: var(--accent);
  stroke-width: 2.4;
  stroke-dasharray: 7 7;
  opacity: 0.98;
}
.logic-gate {
  filter: drop-shadow(0 18px 34px rgba(0, 0, 0, 0.52));
}
.logic-body {
  fill: color-mix(in srgb, var(--chrome) 84%, #000);
  stroke: color-mix(in srgb, var(--border) 72%, var(--accent));
  stroke-width: 1.4;
}
.logic-gate.is-fired .logic-body {
  fill: color-mix(in srgb, var(--success) 24%, var(--chrome));
  stroke: color-mix(in srgb, var(--success) 78%, var(--accent));
}
.logic-gate.is-empty .logic-body {
  stroke: color-mix(in srgb, var(--border) 88%, var(--muted));
}
.logic-port {
  fill: var(--bg);
  stroke: color-mix(in srgb, var(--accent) 70%, var(--border));
  stroke-width: 1.4;
}
.logic-gate.is-fired .logic-port {
  stroke: var(--success);
}
.logic-plus {
  fill: color-mix(in srgb, var(--surface) 92%, var(--bg));
  stroke: color-mix(in srgb, var(--accent) 78%, var(--border));
  stroke-width: 1.5;
}
.logic-plus.is-active {
  fill: color-mix(in srgb, var(--accent) 28%, var(--surface));
  stroke: var(--accent);
}
.logic-plus-mark {
  stroke: var(--text);
  stroke-width: 1.7;
  stroke-linecap: round;
  opacity: 0.92;
}
.logic-label {
  fill: var(--text);
  font: 700 11px/1 ui-monospace, "SF Mono", Menlo, monospace;
  letter-spacing: 0.08em;
  dominant-baseline: middle;
  pointer-events: none;
}

/* General Canvas: one transparent <canvas> per agent orb, ALL filling the whole
   viewport over the shared #bg backdrop and ALL sharing the same world coordinates (no
   lanes). Each orb parks wherever it's dragged, so orbs can be placed anywhere and
   overlap; DOM order among these z1 canvases sets the stacking (newest / last-raised on
   top). They sit at #scene's layer (above the backdrop, below the rail) and take no
   pointer events: the single #canvashit overlay routes every click. */
.world-canvas {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  display: block;
  pointer-events: none;
}

/* The General Canvas' single hit layer. It sits above the orb canvases (z1) and
   below the rail/panels (z3+), and only takes pointer events in canvas mode - vc.js
   resolves each click to the TOPMOST orb with something under it and re-aims the
   composer ONLY when the click hits that workspace's orb (empty space pans instead). */
#canvashit {
  position: fixed;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-user-drag: none;
}
/* In canvas mode the overlay drives Excalidraw-style navigation: scroll to zoom,
   drag empty space to pan. `touch-action: none` + `overscroll-behavior: none` keep
   WKWebView from hijacking those wheel/pinch gestures for native page scroll/zoom.
   The base cursor invites the drag; vc.js swaps it to a pointer over an orb and to
   grabbing mid-pan. */
html.canvasmode #canvashit,
body.canvasmode #canvashit {
  pointer-events: auto;
  cursor: grab;
  touch-action: none;
  overscroll-behavior: none;
}

/* Canvas mode drops the single-session DOM chrome that can't map onto a stack of
   orbs: the faux terminal (multi-agent → no shared shell), the live action HUD,
   and the task/todo list. The DOM thought bubble is hidden too: Claude orbs paint
   their own canvas bubble, while Codex orbs collect those beats in an intermediary
   window. Only the orbs and the right-side prompt rail remain; the brand stays. */
html.canvasmode #scene,
body.canvasmode #scene,
html.canvasmode #terminal,
body.canvasmode #terminal,
html.canvasmode #subterminals,
body.canvasmode #subterminals,
html.canvasmode #thought,
body.canvasmode #thought,
html.canvasmode #action,
body.canvasmode #action,
html.canvasmode #tasks,
body.canvasmode #tasks,
html.canvasmode #speed,
body.canvasmode #speed { display: none !important; }

/* Right-edge scrim: darkens only the rail band so the prompt + reply stay
   legible while the open stage to its left reads clean. The darkening is
   confined to the reply rail (right ~third) and fully transparent across the
   open stage - the orb travels out to files there (colX maxes at ~0.55·W) and
   must never pass under the scrim, or it reads as dimmed when it goes right. */
#scrim {
  position: fixed;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: linear-gradient(270deg,
    color-mix(in srgb, var(--bg) 84%, transparent) 0%,
    color-mix(in srgb, var(--bg) 76%, transparent) 20%,
    color-mix(in srgb, var(--bg) 38%, transparent) 31%,
    transparent 40%);
}

html.canvasmode #scrim,
body.canvasmode #scrim {
  display: none;
}

/* General Canvas: with the scrim gone, the prompt history needs the same
   grounded side-panel surface as the sub-agent inspector instead of floating
   directly over the orb stage. */
html.canvasmode #content,
body.canvasmode #content {
  background: var(--bg);
  border-left: 1px solid color-mix(in srgb, var(--border) 82%, transparent);
  box-shadow: -18px 0 34px color-mix(in srgb, var(--bg) 54%, transparent);
}

/* The conversation, docked to the right as a quiet rail and scrollable: the orb
   + file constellation own the open stage to its left; this is the running
   narration, off to the side. The whole rail scrolls so earlier exchanges stay
   reachable above the live one - scroll up for history. */
#content {
  position: fixed;
  top: 0;
  right: 0;
  z-index: 3;
  width: min(360px, 34%);
  height: 100%;
  padding: 44px 22px 26px 18px;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  overflow-y: auto;
  overscroll-behavior: contain;
  pointer-events: auto;          /* the rail is a scrollable panel */
  opacity: 1;
  transform: translateX(0);
  transition:
    transform 0.22s cubic-bezier(0.22, 1, 0.36, 1),
    opacity 0.18s ease,
    box-shadow 0.22s cubic-bezier(0.22, 1, 0.36, 1);
  will-change: transform, opacity;
  /* Soften the top edge so the scrollback dissolves under the chrome rather
     than colliding with the wordmark / catch-up pill above it. */
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 40px, #000 100%);
}
#content::-webkit-scrollbar { width: 7px; }
#content::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; }

html.canvasmode.canvas-rail-hidden #content,
body.canvasmode.canvas-rail-hidden #content {
  opacity: 0;
  transform: translateX(calc(100% + 18px));
  pointer-events: none;
  box-shadow: none;
}

/* ─── Focus mode ──────────────────────────────────────────────────────────
   Right-clicking an orb → "Focus" lifts that one agent into its own window: a
   fixed full-width band across the TOP of the page (height = --focus-band-h)
   shows only the orb + its file constellation, floating on a smooth grid-less
   surface (vc.js VCBg.setFocus). The prompt-history rail docks directly beneath
   the band as a full-width, independently scrollable record of that agent's
   prompts/replies. Every sibling orb, logic gate, queue, HUD and the orb's own
   boxy side panels are hidden; pan/zoom are off. A top-left button exits. */
html.focusmode .world-canvas,
body.focusmode .world-canvas { display: none; }
html.focusmode .world-canvas.focused-world,
body.focusmode .world-canvas.focused-world { display: block; }

/* Everything that belongs to the multi-orb surface (not this one agent) goes. */
html.focusmode #logic-layer,
body.focusmode #logic-layer,
html.focusmode #logic-queue-layer,
body.focusmode #logic-queue-layer,
html.focusmode #canvas-filediffs,
body.focusmode #canvas-filediffs,
html.focusmode #promptpin,
body.focusmode #promptpin,
html.focusmode #hud,
body.focusmode #hud,
html.focusmode #diffpop,
body.focusmode #diffpop { display: none !important; }

/* The rail becomes the page beneath the band: docked at --focus-band-h, full
   width, solid, and scrolling on its own. The empty region above it (0 → band
   height) is where the fixed orb canvas shows through on the smooth surface, so
   the band reads as a separate window the records scroll under.
   Selector carries `.canvasmode` too (focus is always a canvas sub-state) so it
   outranks the later `html.canvasmode #content` rule, which would otherwise win
   the source-order tie and shrink the rail back to a 420px right-of-band column. */
html.focusmode.canvasmode #content,
body.focusmode.canvasmode #content {
  z-index: 30;
  top: var(--focus-band-h, 46vh);
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: auto;
  padding: 0;
  background: var(--bg);
  border-left: 0;
  border-top: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
  box-shadow: 0 -22px 46px color-mix(in srgb, #000 36%, transparent);
  opacity: 1;
  transform: none;
  pointer-events: auto;
  -webkit-mask-image: none;
}

/* The transcript spans the full width of the page beneath the band - the whole
   window is the record, not a column off to one side - with breathing room at the
   top where it meets the band's lower edge. */
html.focusmode #log,
body.focusmode #log {
  flex: 0 0 auto;
  background: transparent;
  padding: 30px 0 64px;
}
html.focusmode #log > .turn,
body.focusmode #log > .turn {
  width: 100%;
  max-width: none;
  margin-left: 0;
  margin-right: 0;
  padding-left: clamp(28px, 5vw, 96px);
  padding-right: clamp(28px, 5vw, 96px);
  box-sizing: border-box;
}

/* Exit-focus button, pinned top-left above the page (below the question modal). */
#focus-exit {
  position: fixed;
  top: 14px;
  left: 14px;
  z-index: 40;
  display: none;
  align-items: center;
  gap: 7px;
  height: 30px;
  padding: 0 12px 0 10px;
  border: 1px solid color-mix(in srgb, var(--border) 80%, transparent);
  border-radius: 8px;
  background: color-mix(in srgb, var(--chrome) 86%, transparent);
  -webkit-backdrop-filter: blur(9px);
  backdrop-filter: blur(9px);
  color: var(--text);
  font: 600 12px/1 -apple-system, system-ui, "SF Pro Text", sans-serif;
  cursor: pointer;
  box-shadow: 0 6px 20px color-mix(in srgb, #000 40%, transparent);
  transition: border-color 0.14s ease, background 0.14s ease;
}
html.focusmode #focus-exit,
body.focusmode #focus-exit { display: inline-flex; }
#focus-exit:hover {
  border-color: color-mix(in srgb, var(--accent) 48%, var(--border));
  background: color-mix(in srgb, var(--surface) 70%, transparent);
}
#focus-exit:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--accent) 65%, transparent);
  outline-offset: 2px;
}
#focus-exit .fx-arrow {
  width: 8px;
  height: 8px;
  border-left: 1.6px solid currentColor;
  border-bottom: 1.6px solid currentColor;
  transform: rotate(45deg);
  margin-right: 1px;
  opacity: 0.85;
}

/* The transcript: a vertical stack of turns (prompt + reply), oldest at the top.
   `flex: 0 0 auto` so turns keep their natural height and overflow the rail
   (which then scrolls) instead of being squeezed to fit. */
#log { flex: 0 0 auto; display: flex; flex-direction: column; }

/* One conversation turn. A hairline divider above every turn but the first marks
   the boundaries between exchanges as you scroll back. */
.turn {
  padding-top: 18px;
  margin-top: 18px;
  border-top: 1px solid color-mix(in srgb, var(--border) 50%, transparent);
}
.turn:first-child { padding-top: 0; margin-top: 0; border-top: 0; }

/* The user's prompt: a small left-aligned header above its reply. Flows with the
   rail (no inner scroll) - a long prompt just makes the rail taller. Labelled
   with a faint eyebrow, no loud framing. */
.turn-prompt {
  pointer-events: auto;
  text-align: left;
  font: 600 14px/1.5 -apple-system, system-ui, "SF Pro Text", sans-serif;
  letter-spacing: 0.005em;
  color: var(--text);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.turn-prompt::before {
  content: "prompt";
  display: block;
  font: 600 9.5px/1 ui-monospace, "SF Mono", Menlo, monospace;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 9px;
}
.turn-prompt.hidden { display: none; }

/* Sticky prompt bar: the active prompt docked at the rail's top once it has
   scrolled out of view, so the running reply always shows which task it answers.
   A fixed bar the exact width of the prompt text column (rail width minus its
   18/22 side padding), aligned to the prompt's right edge - the web twin of the
   native session's pin bar. Sits above #content's top mask so it stays crisp, and
   takes no pointer events so the wheel scrolls the rail beneath it. */
#promptpin {
  position: fixed;
  top: 12px;
  right: 22px;
  width: calc(min(360px, 34%) - 40px);
  z-index: 4;
  pointer-events: none;
  padding: 7px 0 8px;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--bg) 92%, transparent) 0%,
    color-mix(in srgb, var(--bg) 86%, transparent) 72%,
    color-mix(in srgb, var(--bg) 68%, transparent) 100%);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  opacity: 0;
  transform: translateY(-6px);
  transition: opacity 0.2s ease, transform 0.2s ease;
}
#promptpin.show { opacity: 1; transform: none; }
html.canvasmode.canvas-rail-hidden #promptpin,
body.canvasmode.canvas-rail-hidden #promptpin {
  opacity: 0 !important;
  transform: translateX(calc(100% + 28px)) !important;
}
/* The docked text: a single truncated line, styled like the prompt it mirrors.
   `nowrap` collapses the prompt's newlines to spaces, matching the native bar. */
.pp-text {
  display: block;
  font: 600 13px/1.4 -apple-system, system-ui, "SF Pro Text", sans-serif;
  letter-spacing: 0.005em;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
@media (prefers-reduced-motion: reduce) {
  #content { transition: opacity 0.12s linear; transform: none; }
  html.canvasmode.canvas-rail-hidden #content,
  body.canvasmode.canvas-rail-hidden #content { transform: none; }
  #promptpin { transition: opacity 0.12s linear; transform: none; }
  #promptpin.show { transform: none; }
  html.canvasmode.canvas-rail-hidden #promptpin,
  body.canvasmode.canvas-rail-hidden #promptpin { transform: none !important; }
}

/* Thumbnails of any images attached to the turn: a small wrapping strip just
   under the prompt text, matching the composer's attachment chips. */
.turn-media {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 10px;
  pointer-events: auto;
}
.turn-media.hidden { display: none; }
.prompt-thumb {
  width: 56px;
  height: 56px;
  object-fit: cover;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--surface);
  cursor: pointer;
  transition: border-color 120ms ease;
}
.prompt-thumb:hover { border-color: var(--accent); }

/* The model's reply: the actual answer, so keep it readable. Flows beneath its
   prompt within the scrolling rail (no inner scroll of its own). */
.turn-output {
  margin-top: 14px;
  width: 100%;
  pointer-events: auto;
  text-align: left;
  color: var(--text);
  font: 400 13px/1.62 -apple-system, system-ui, "SF Pro Text", sans-serif;
  overflow-wrap: anywhere;
}

/* When the turn carries a user message - prompt text and/or attached media - a
   hairline rule separates that message from the reply below it, a clear hand-off
   from question to answer. Continuations that reuse the open turn with no prompt
   header (and autonomous beats) leave both hidden, so the reply flows on unbroken. */
.turn-prompt:not(.hidden) ~ .turn-output,
.turn-media:not(.hidden) ~ .turn-output {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
}

/* Rendered Markdown inside the reply (see md.js). Tuned for the narrow rail. */
.turn-output > :first-child { margin-top: 0; }
.turn-output > :last-child { margin-bottom: 0; }
.turn-output p { margin: 0 0 12px; }
.turn-output strong { font-weight: 650; color: var(--text); }
.turn-output em { font-style: italic; }
.turn-output h1, .turn-output h2, .turn-output h3, .turn-output h4 {
  color: var(--text); line-height: 1.3; font-weight: 650; margin: 16px 0 8px;
}
.turn-output h1 { font-size: 17px; }
.turn-output h2 { font-size: 15px; }
.turn-output h3 { font-size: 14px; }
.turn-output h4 { font-size: 13px; letter-spacing: 0.01em; }
.turn-output ul, .turn-output ol { margin: 0 0 12px; padding-left: 20px; }
.turn-output li { margin: 0 0 4px; }
.turn-output li::marker { color: var(--muted); }
.turn-output code {
  font: 12px/1.4 ui-monospace, "SF Mono", Menlo, monospace;
  background: color-mix(in srgb, var(--surface) 65%, transparent);
  border: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
  border-radius: 4px; padding: 1px 5px; overflow-wrap: anywhere;
}
.turn-output pre {
  margin: 0 0 12px; padding: 10px 12px; overflow-x: auto;
  background: color-mix(in srgb, var(--surface) 55%, transparent);
  border: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
  border-radius: 8px;
}
.turn-output pre code { background: none; border: 0; padding: 0; font-size: 11.5px; }
.turn-output blockquote {
  margin: 0 0 12px; padding: 6px 12px; border-radius: 6px;
  background: color-mix(in srgb, var(--surface) 42%, transparent);
  color: var(--text-dim); font-style: italic;
}
.turn-output hr {
  border: 0; margin: 16px 0;
  border-top: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
}
.turn-output .md-lnk { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; }
.turn-output table {
  display: block; width: 100%; overflow-x: auto; border-collapse: collapse;
  margin: 0 0 12px; font-size: 12px;
}
.turn-output th, .turn-output td {
  border: 1px solid color-mix(in srgb, var(--border) 80%, transparent);
  padding: 5px 8px; text-align: left; white-space: nowrap;
}
.turn-output th { background: color-mix(in srgb, var(--surface) 52%, transparent); color: var(--text); font-weight: 600; }
.turn-output td { color: var(--text-dim); }

/* Tool calls interleaved into the reply, mirroring how a normal session shows
   the steps Claude takes between prose. A quiet monospace chip: a tinted dot,
   the tool's real name, and a short subject. */
.turn-output .tool-step {
  display: flex; align-items: baseline; gap: 8px;
  margin: 0 0 11px; padding: 2px 0;
  font: 11.5px/1.45 ui-monospace, "SF Mono", Menlo, monospace;
  color: var(--text-dim);
}
.turn-output .tool-step .ts-dot {
  flex: none; align-self: center; width: 6px; height: 6px; border-radius: 50%;
  background: var(--tool);
  box-shadow: 0 0 7px color-mix(in srgb, var(--tool) 65%, transparent);
}
.turn-output .tool-step .ts-verb { flex: none; white-space: nowrap; color: var(--text); font-weight: 600; }
.turn-output .tool-step .ts-subj {
  color: var(--muted); min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Tint the dot by act: writes/edits warmer than the cool read/search/run beats;
   spawns and asks louder; plan updates muted. */
.turn-output .tool-step.act-edit .ts-dot,
.turn-output .tool-step.act-write .ts-dot {
  background: var(--accent);
  box-shadow: 0 0 7px color-mix(in srgb, var(--accent) 65%, transparent);
}
.turn-output .tool-step.act-spawn .ts-dot,
.turn-output .tool-step.act-ask .ts-dot {
  background: var(--attention);
  box-shadow: 0 0 7px color-mix(in srgb, var(--attention) 65%, transparent);
}
.turn-output .tool-step.act-todo .ts-dot { background: var(--muted); box-shadow: none; }
/* A spawned agent / workflow chip is a button into its side detail panel - same
   drill-down a normal session's agent card offers. Reads as quietly interactive:
   pointer + a faint hover wash, with a chevron that slides in on hover/focus. */
.turn-output .tool-step.clickable {
  cursor: pointer; border-radius: 6px;
  margin-left: -6px; margin-right: -6px; padding-left: 6px; padding-right: 6px;
  transition: background .12s ease;
}
.turn-output .tool-step.clickable:hover {
  background: color-mix(in srgb, var(--attention) 12%, transparent);
}
.turn-output .tool-step.clickable:focus-visible {
  outline: 1px solid color-mix(in srgb, var(--attention) 55%, transparent);
  outline-offset: 1px;
}
.turn-output .tool-step .ts-go {
  margin-left: auto; align-self: center; color: var(--muted); font-weight: 600;
  opacity: 0; transform: translateX(-3px);
  transition: opacity .12s ease, transform .12s ease;
}
.turn-output .tool-step.clickable:hover .ts-go,
.turn-output .tool-step.clickable:focus-visible .ts-go { opacity: .8; transform: none; }
/* Dimmer still once folded into the reasoning disclosure. */
.turn-output .reason-body .tool-step { margin-bottom: 8px; }

/* Reasoning disclosure: collapsed once the turn lands, re-openable. */
.turn-output .reason-toggle {
  appearance: none; -webkit-appearance: none; background: none; border: 0;
  cursor: pointer; display: inline-flex; align-items: center; gap: 7px;
  margin: 0 0 16px; padding: 0;
  font: 600 9.5px/1 ui-monospace, "SF Mono", Menlo, monospace;
  letter-spacing: 0.22em; text-transform: uppercase; color: var(--muted);
}
.turn-output .reason-toggle:hover { color: var(--text-dim); }
.turn-output .reason-toggle .chev { display: inline-block; transition: transform 0.18s ease; }
.turn-output .reason-toggle.open .chev { transform: rotate(90deg); }
.turn-output .reason-body {
  margin: 0 0 16px; padding: 0 0 14px;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 55%, transparent);
  color: var(--text-dim); font-size: 12.5px;
}
.turn-output .reason-body :first-child { margin-top: 0; }
.turn-output .final-answer { color: var(--text); }
@media (prefers-reduced-motion: reduce) { .turn-output .reason-toggle .chev { transition: none; } }

/* General Canvas expanded output popup. The compact Codex intermediary/final
   window is painted on the canvas; this fixed overlay is the readable enlargement
   and intentionally ignores canvas pan/zoom/drag transforms. */
#canvas-output-expanded {
  position: fixed;
  inset: 0;
  z-index: 72;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: color-mix(in srgb, var(--bg) 72%, transparent);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.16s ease;
}
#canvas-output-expanded.hidden { display: none; }
#canvas-output-expanded.show {
  opacity: 1;
  pointer-events: auto;
}

.coe-panel {
  width: min(70vw, calc(100vw - 48px));
  height: min(70vh, calc(100vh - 48px));
  min-width: min(560px, calc(100vw - 48px));
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--border) 78%, var(--accent));
  border-radius: 10px;
  background: color-mix(in srgb, var(--chrome) 93%, #000);
  box-shadow: 0 32px 88px -34px rgba(0, 0, 0, 0.86), 0 1px 0 rgba(255, 255, 255, 0.035) inset;
  transform: translateY(6px) scale(0.992);
  transition: transform 0.18s cubic-bezier(0.22, 1, 0.36, 1);
  user-select: text;
  -webkit-user-select: text;
}
#canvas-output-expanded.show .coe-panel { transform: none; }

.coe-head {
  flex: 0 0 auto;
  min-height: 42px;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px 10px 15px;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 66%, transparent);
  background: color-mix(in srgb, var(--surface) 34%, transparent);
}
.coe-copy { min-width: 0; }
.coe-title {
  font: 600 10px/1 ui-monospace, "SF Mono", Menlo, monospace;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
}
.coe-meta {
  margin-top: 4px;
  font: 500 11.5px/1.25 -apple-system, system-ui, "SF Pro Text", sans-serif;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.coe-close {
  flex: 0 0 auto;
  margin-left: auto;
  width: 26px;
  height: 26px;
  appearance: none;
  -webkit-appearance: none;
  border: 1px solid color-mix(in srgb, var(--border) 80%, transparent);
  border-radius: 6px;
  background: color-mix(in srgb, var(--chrome) 70%, transparent);
  cursor: pointer;
  position: relative;
  transition: background 0.14s ease, border-color 0.14s ease;
}
.coe-close::before,
.coe-close::after {
  content: "";
  position: absolute;
  left: 7px;
  right: 7px;
  top: 12px;
  height: 1.5px;
  border-radius: 1px;
  background: var(--text-dim);
}
.coe-close::before { transform: rotate(45deg); }
.coe-close::after { transform: rotate(-45deg); }
.coe-close:hover {
  background: color-mix(in srgb, var(--surface) 62%, transparent);
  border-color: color-mix(in srgb, var(--accent) 42%, var(--border));
}
.coe-close:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--accent) 65%, transparent);
  outline-offset: 2px;
}

.coe-body.turn-output {
  flex: 1 1 auto;
  min-height: 0;
  margin: 0;
  padding: 22px 28px 28px;
  overflow: auto;
  font-size: 14px;
  line-height: 1.66;
}
.coe-body.turn-output pre code { font-size: 12.5px; }
.coe-body::-webkit-scrollbar { width: 8px; height: 8px; }
.coe-body::-webkit-scrollbar-thumb { background: var(--border); border-radius: 5px; }

/* AskUserQuestion picker docked at the foot of the expanded window. Bounded so a
   long question set scrolls internally while the output above keeps its space. */
.coe-ask {
  flex: 0 1 auto;
  max-height: 48%;
  overflow: auto;
  padding: 16px 28px 22px;
  border-top: 1px solid color-mix(in srgb, var(--border) 66%, transparent);
  background: color-mix(in srgb, var(--surface) 22%, transparent);
  pointer-events: auto;
}
.coe-ask.hidden { display: none; }
.coe-ask .ask-card { margin: 0; }
.coe-ask::-webkit-scrollbar { width: 8px; height: 8px; }
.coe-ask::-webkit-scrollbar-thumb { background: var(--border); border-radius: 5px; }
@media (max-width: 760px) {
  .coe-ask { padding: 14px 18px 18px; }
}

@media (max-width: 760px) {
  .coe-panel {
    width: calc(100vw - 28px);
    height: min(76vh, calc(100vh - 28px));
    min-width: 0;
  }
  .coe-body.turn-output { padding: 18px 18px 22px; }
}
@media (prefers-reduced-motion: reduce) {
  #canvas-output-expanded, .coe-panel, .coe-close { transition: none; }
  .coe-panel { transform: none; }
}

/* Interactive AskUserQuestion panel, at the foot of the transcript below the live
   turn. Claude is paused here; this is the one moment the scene is fully
   interactive, so it reads as an accent-tinted "needs you" card and takes pointer
   events. Flows with the rail - raising it scrolls the rail down to it. */
#askdock {
  flex: 0 0 auto;
  margin-top: 18px;
  pointer-events: auto;
}
#askdock.hidden { display: none; }

.ask-card {
  border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
  background: color-mix(in srgb, var(--accent) 12%, var(--chrome));
  border-radius: 10px;
  padding: 14px;
}

.ask-eyebrow {
  font: 600 9.5px/1 ui-monospace, "SF Mono", Menlo, monospace;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 12px;
}

.ask-block { margin-bottom: 16px; }
.ask-block:last-of-type { margin-bottom: 12px; }

.ask-head {
  font: 600 10px/1 ui-monospace, "SF Mono", Menlo, monospace;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 7px;
}

.ask-q {
  font: 600 13px/1.45 -apple-system, system-ui, "SF Pro Text", sans-serif;
  color: var(--text);
  margin-bottom: 9px;
  overflow-wrap: anywhere;
}

/* One selectable option: glyph + label/description, the native OptionRow's twin. */
.ask-opt {
  display: flex;
  gap: 9px;
  padding: 8px 9px;
  margin-bottom: 6px;
  border: 1px solid var(--border);
  background: var(--chrome);
  border-radius: 7px;
  cursor: pointer;
  transition: background 0.14s ease, border-color 0.14s ease;
}
.ask-opt:hover { background: color-mix(in srgb, var(--surface) 50%, var(--chrome)); }
.ask-opt.sel {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  border-color: color-mix(in srgb, var(--accent) 60%, transparent);
}

/* The radio/checkbox mark, drawn in CSS so no SF Symbols are needed. */
.ask-mark {
  flex: 0 0 auto;
  width: 15px;
  height: 15px;
  margin-top: 1px;
  border: 1.5px solid var(--muted);
  background: transparent;
  position: relative;
}
.ask-opt[data-multi="0"] .ask-mark { border-radius: 50%; }
.ask-opt[data-multi="1"] .ask-mark { border-radius: 4px; }
.ask-opt.sel .ask-mark { border-color: var(--accent); }
.ask-opt[data-multi="0"].sel .ask-mark::after {
  content: ""; position: absolute; inset: 3px; border-radius: 50%; background: var(--accent);
}
.ask-opt[data-multi="1"].sel .ask-mark {
  background: var(--accent);
}
.ask-opt[data-multi="1"].sel .ask-mark::after {
  content: ""; position: absolute; left: 4px; top: 1px; width: 4px; height: 8px;
  border: solid var(--bg); border-width: 0 2px 2px 0; transform: rotate(45deg);
}

.ask-optbody { min-width: 0; }
.ask-lab {
  font: 600 12.5px/1.3 -apple-system, system-ui, "SF Pro Text", sans-serif;
  color: var(--text);
  overflow-wrap: anywhere;
}
.ask-desc {
  margin-top: 2px;
  font: 400 11.5px/1.4 -apple-system, system-ui, "SF Pro Text", sans-serif;
  color: var(--text-dim);
  overflow-wrap: anywhere;
}

/* Free-text "Other" field, revealed when its row is picked. */
.ask-other {
  width: 100%;
  margin: 2px 0 6px;
  padding: 7px 9px;
  border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  border-radius: 7px;
  background: color-mix(in srgb, var(--surface) 60%, transparent);
  color: var(--text);
  font: 400 12.5px/1.4 -apple-system, system-ui, "SF Pro Text", sans-serif;
  outline: none;
}
.ask-other::placeholder { color: var(--muted); }
.ask-other[hidden] { display: none; }

.ask-err {
  margin: 0 0 10px;
  color: var(--danger);
  font: 400 11.5px/1.4 -apple-system, system-ui, "SF Pro Text", sans-serif;
}
.ask-err[hidden] { display: none; }

.ask-submit {
  appearance: none; -webkit-appearance: none;
  width: 100%;
  padding: 9px 12px;
  border: 0;
  border-radius: 7px;
  background: var(--accent);
  color: var(--bg);
  font: 600 12.5px/1 -apple-system, system-ui, "SF Pro Text", sans-serif;
  cursor: pointer;
  transition: background 0.14s ease, opacity 0.14s ease;
}
.ask-submit:disabled { background: var(--surface); color: var(--muted); cursor: default; }
.ask-submit.sent { background: transparent; color: var(--success); cursor: default; }

@media (prefers-reduced-motion: reduce) {
  .ask-opt, .ask-submit { transition: none; }
}

/* Faux terminal: a small, read-only shell log docked top-right just left of the
   prompt rail (which owns the right `min(360px, 34%)`). Mirrors the Bash commands
   Claude runs and their output - never an interactive shell. Always present, and
   a FIXED size: the box never grows/shrinks with content; the body scrolls. */
#terminal {
  position: fixed;
  top: 40px;
  right: calc(min(360px, 34%) + 14px);
  z-index: 3;
  width: 300px;
  height: 290px;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-radius: 9px;
  background: color-mix(in srgb, var(--chrome) 88%, #000);
  box-shadow: 0 16px 44px -22px rgba(0, 0, 0, 0.65);
  overflow: hidden;
  pointer-events: auto;
}

/* Title bar: traffic-light dots + a quiet "claude - zsh" label. */
#term-bar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 9px;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
  background: color-mix(in srgb, var(--surface) 38%, transparent);
}
.td { width: 8px; height: 8px; border-radius: 50%; }
.td-r { background: #BD5742; }
.td-y { background: #C9A24B; }
.td-g { background: #6FA084; }
#term-title {
  margin-left: 5px;
  font: 600 9.5px/1 ui-monospace, "SF Mono", Menlo, monospace;
  letter-spacing: 0.04em;
  color: var(--muted);
}

/* Scrollback. Follows the bottom as new commands land (see vc.js). */
#term-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 8px 10px 9px;
  font: 10px/1.45 ui-monospace, "SF Mono", Menlo, monospace;
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 10px, #000 100%);
}
#term-body::-webkit-scrollbar { width: 6px; }
#term-body::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; }
/* Idle hint before any command runs, so the empty frame still reads as a shell. */
#term-body:empty::before { content: "❯"; color: var(--muted); opacity: 0.6; }

/* One command and its output. */
.tcmd { margin: 0 0 7px; }
.tcmd:last-child { margin-bottom: 0; }
/* The command line: a ❯ prompt glyph with a hanging indent so wrapped commands
   align past it. */
.tcmd-line {
  color: var(--text);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  padding-left: 13px;
  text-indent: -13px;
}
.tcmd-line::before { content: "❯ "; color: var(--accent); }
/* While the command is in flight (no result yet), a blinking caret trails it. */
.tcmd.run .tcmd-line::after {
  content: "▋";
  color: var(--accent);
  animation: tblink 1s steps(2, jump-none) infinite;
}
@keyframes tblink { 50% { opacity: 0; } }
/* The captured output - dim by default, danger-tinted on error. */
.tcmd-out {
  margin-top: 2px;
  color: var(--text-dim);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.tcmd-out.err { color: var(--danger); }
@media (prefers-reduced-motion: reduce) { .tcmd.run .tcmd-line::after { animation: none; } }

/* Task list: Claude's live plan (TodoWrite / Task*), docked just left of the faux
   terminal at the same top. Auto-height up to the terminal's vertical envelope,
   then the body scrolls; hidden entirely until the first task arrives. Mirrors the
   text transcript's checklist - ○ pending, ◐ in-progress (accent), ✓ done (struck). */
#tasks {
  position: fixed;
  top: 40px;
  right: calc(min(360px, 34%) + 328px);   /* terminal gutter (14) + width (300) + gap (14) */
  z-index: 3;
  width: 264px;
  max-height: 290px;                       /* matches the terminal's height envelope */
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-radius: 9px;
  background: color-mix(in srgb, var(--chrome) 88%, #000);
  box-shadow: 0 16px 44px -22px rgba(0, 0, 0, 0.65);
  overflow: hidden;
  pointer-events: auto;
}
#tasks.hidden { display: none; }

/* Header: a "Tasks" label + a done/total tally, same chrome as the terminal bar. */
#tasks-bar {
  flex: 0 0 auto;
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 7px 11px;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
  background: color-mix(in srgb, var(--surface) 38%, transparent);
}
#tasks-title {
  font: 600 11px/1 ui-monospace, "SF Mono", Menlo, monospace;
  letter-spacing: 0.08em;
  color: var(--text);
}
#tasks-count {
  margin-left: auto;
  font: 600 10px/1 ui-monospace, "SF Mono", Menlo, monospace;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}

/* Scrollable list of rows; the active task is kept in view as the plan advances. */
#tasks-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 8px 11px 9px;
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 8px, #000 100%);
}
#tasks-body::-webkit-scrollbar { width: 6px; }
#tasks-body::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; }

.task-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 3px 0;
  font: 12px/1.45 -apple-system, system-ui, "SF Pro Text", sans-serif;
}
.task-mark {
  flex: 0 0 auto;
  width: 13px;
  text-align: center;
  font: 11px/1.45 ui-monospace, "SF Mono", Menlo, monospace;
  color: var(--muted);
}
.task-label {
  flex: 1 1 auto;
  min-width: 0;
  overflow-wrap: anywhere;
  color: var(--text-dim);
}
.task-row.is-pending .task-mark  { color: var(--muted); }
.task-row.is-pending .task-label { color: var(--text-dim); }
.task-row.is-active  .task-mark  { color: var(--accent); }
.task-row.is-active  .task-label { color: var(--text); font-weight: 600; }
.task-row.is-done    .task-mark  { color: var(--success); }
.task-row.is-done    .task-label { color: var(--muted); text-decoration: line-through; }

/* Sub-agent terminals: stacked directly below the main #terminal, same right
   gutter. Each spawned agent that runs a shell command gets its own window here
   (built by vc.js), so the metaphor holds - one orb, one terminal. The column
   clips at the viewport's foot; the cap (SUBTERM_MAX) keeps it from overflowing. */
#subterminals {
  position: fixed;
  top: 342px;                                  /* #terminal top (40) + height (290) + gap (12) */
  right: calc(min(360px, 34%) + 14px);
  z-index: 3;
  width: 300px;
  max-height: calc(100vh - 354px);
  display: flex;
  flex-direction: column;
  gap: 10px;
  overflow: hidden;
  pointer-events: none;                        /* the boxes themselves re-enable it */
}
/* One sub-agent terminal - the main terminal's chrome at a shorter, fixed height
   so a couple stack within reach below it. Eases in as the agent's first command
   lands. The tool-blue title ties it back to the cool clone orb that drives it. */
.subterm {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  height: 168px;
  border: 1px solid var(--border);
  border-radius: 9px;
  background: color-mix(in srgb, var(--chrome) 88%, #000);
  box-shadow: 0 16px 44px -22px rgba(0, 0, 0, 0.65);
  overflow: hidden;
  pointer-events: auto;
  animation: subterm-in 0.28s cubic-bezier(0.22, 0.61, 0.36, 1);
}
@keyframes subterm-in {
  from { opacity: 0; transform: translateY(-7px); }
  to   { opacity: 1; transform: none; }
}
/* The agent settled: fade + collapse the terminal away in step with its clone orb
   dissolving on the canvas, then vc.js detaches it on transitionend. The negative
   margin swallows the column gap so the terminals below slide up cleanly. */
.subterm.leaving {
  animation: none;                             /* cancel the enter keyframes if mid-flight */
  pointer-events: none;
  opacity: 0;
  height: 0;
  margin-top: -10px;                           /* == #subterminals gap */
  transform: translateY(-6px);
  transition: opacity 0.3s ease,
              transform 0.3s ease,
              height 0.42s cubic-bezier(0.4, 0, 0.2, 1),
              margin-top 0.42s cubic-bezier(0.4, 0, 0.2, 1);
}
.subterm-bar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 9px;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
  background: color-mix(in srgb, var(--surface) 38%, transparent);
}
.subterm-title {
  margin-left: 5px;
  min-width: 0;
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font: 600 9.5px/1 ui-monospace, "SF Mono", Menlo, monospace;
  letter-spacing: 0.04em;
  color: var(--tool);                          /* cool blue - matches the clone orb */
}
.subterm-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 8px 10px 9px;
  font: 10px/1.45 ui-monospace, "SF Mono", Menlo, monospace;
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 10px, #000 100%);
}
.subterm-body::-webkit-scrollbar { width: 6px; }
.subterm-body::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; }
.subterm-body:empty::before { content: "❯"; color: var(--muted); opacity: 0.6; }

/* ----------------------------------------------------------- diff popup ----
   A small card docked beside the file the orb just edited/wrote, scrolling
   through what changed: removed lines (−, red wash) then added lines (+, green
   wash), with a +N/−M tally. One reused element - a fresh file action replaces
   it rather than stacking. Non-interactive: the pointer falls through to the
   canvas below (node picking still works). Positioned in CSS px by vc.js. */
#diffpop {
  position: fixed;
  z-index: 3;
  width: 322px;
  min-width: 322px;
  max-width: 322px;
  pointer-events: none;
  opacity: 0;
  transform: translateY(7px) scale(0.985);
  transition: opacity .26s cubic-bezier(.16, .84, .44, 1),
              transform .26s cubic-bezier(.16, .84, .44, 1);
  will-change: opacity, transform;
}
#diffpop.hidden { display: none; }
#diffpop.show { opacity: 1; transform: none; }

.dp-card {
  position: relative;
  width: 100%;
  border: 1px solid color-mix(in srgb, var(--border) 86%, var(--accent));
  border-radius: 11px;
  background: color-mix(in srgb, var(--chrome) 93%, #000);
  box-shadow: 0 24px 60px -26px rgba(0, 0, 0, 0.82), 0 1px 0 rgba(255, 255, 255, 0.03) inset;
  overflow: hidden;
}

/* A small caret on the side facing the file row (only when the card is anchored
   to a leaf; the fallback corner placement has none). */
#diffpop.anchored .dp-card::before {
  content: "";
  position: absolute;
  top: 50%;
  left: -5px;
  margin-top: -4.5px;
  width: 9px;
  height: 9px;
  background: color-mix(in srgb, var(--chrome) 93%, #000);
  border-left: 1px solid color-mix(in srgb, var(--border) 86%, var(--accent));
  border-bottom: 1px solid color-mix(in srgb, var(--border) 86%, var(--accent));
  transform: rotate(45deg);
}
#diffpop.anchored.flip .dp-card::before {
  left: auto;
  right: -5px;
  border-left: 0;
  border-bottom: 0;
  border-right: 1px solid color-mix(in srgb, var(--border) 86%, var(--accent));
  border-top: 1px solid color-mix(in srgb, var(--border) 86%, var(--accent));
}

/* Header: a kind tag, the file name, a dim path crumb, and the +N/−M tally. */
.dp-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 9px 12px;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  background: color-mix(in srgb, var(--surface) 30%, transparent);
}
.dp-kind {
  flex: none;
  padding: 3px 6px;
  border-radius: 5px;
  font: 600 9px/1 ui-monospace, "SF Mono", Menlo, monospace;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.dp-kind.is-edit { color: var(--accent); background: color-mix(in srgb, var(--accent) 16%, transparent); }
.dp-kind.is-create { color: var(--success); background: color-mix(in srgb, var(--success) 16%, transparent); }
.dp-name {
  flex: 0 1 auto;
  min-width: 0;
  font: 600 12px/1.2 ui-monospace, "SF Mono", Menlo, monospace;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dp-dir {
  flex: 1 1 auto;
  min-width: 0;
  font: 10.5px/1.2 ui-monospace, "SF Mono", Menlo, monospace;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dp-stat {
  flex: none;
  display: flex;
  gap: 7px;
  font: 600 10.5px/1 ui-monospace, "SF Mono", Menlo, monospace;
  font-variant-numeric: tabular-nums;
}
.dp-stat .dp-add { color: var(--diff-add); }
.dp-stat .dp-del { color: var(--diff-del); }

/* Body: one row per diff line, scrolled programmatically by vc.js (overflow is
   clipped - there's no user scrollbar). The `max-height` is load-bearing: it's
   what makes the body taller than its content so `scrollTop` has room to move.
   Remove it and the auto-scroll silently becomes a no-op. */
.dp-body {
  height: 208px;
  max-height: 208px;
  overflow: hidden;
  padding: 6px 0;
  font: 11px/1.55 ui-monospace, "SF Mono", Menlo, monospace;
}
.dp-line {
  display: flex;
  padding-right: 12px;
  white-space: pre;
}
.dp-sign {
  flex: none;
  width: 20px;
  text-align: center;
  color: var(--muted);
  -webkit-user-select: none;
  user-select: none;
}
.dp-code {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--text-dim);
}
.dp-line.is-add { background: color-mix(in srgb, var(--diff-add) 13%, transparent); }
.dp-line.is-add .dp-sign { color: var(--diff-add); }
.dp-line.is-add .dp-code { color: color-mix(in srgb, var(--diff-add) 32%, var(--text)); }
.dp-line.is-del { background: color-mix(in srgb, var(--diff-del) 13%, transparent); }
.dp-line.is-del .dp-sign { color: var(--diff-del); }
.dp-line.is-del .dp-code { color: color-mix(in srgb, var(--diff-del) 32%, var(--text)); }
.dp-line.is-ctx .dp-code { color: var(--muted); }

/* Hunk boundary between a MultiEdit's separate replacements. */
.dp-gap {
  height: 0;
  margin: 6px 12px;
  border-top: 1px dashed color-mix(in srgb, var(--border) 70%, transparent);
}
.dp-more {
  padding: 5px 12px 2px;
  font: 10px/1.3 ui-monospace, "SF Mono", Menlo, monospace;
  color: var(--muted);
}

@media (prefers-reduced-motion: reduce) {
  #diffpop { transition: opacity .12s linear; transform: none; }
  #diffpop.show { transform: none; }
}

/* ------------------------------------------------------------- thought bubble --
   Claude's extended-thinking, floated as a small chat bubble above the orb. The
   wrapper's left/top is set by scene.js each frame to track the reasoning orb; the
   card is anchored by its bottom-left (translate Y -100%) so the tail near its left
   edge points straight down at the orb. Non-interactive; text set via textContent. */
#thought {
  position: fixed;
  z-index: 4;
  width: 264px;
  max-width: 40vw;
  pointer-events: none;
  transform: translate(-21px, -100%);   /* card bottom at the anchor; tail (≈21px from left) over the orb */
  opacity: 0;
  transition: opacity .3s ease;
  will-change: left, top, opacity;
}
#thought.hidden { display: none; }
#thought.show { opacity: 1; }

.th-card {
  position: relative;
  border: 1px solid color-mix(in srgb, var(--border) 80%, var(--accent));
  border-radius: 13px;
  background: color-mix(in srgb, var(--chrome) 92%, #000);
  box-shadow: 0 18px 44px -22px rgba(0, 0, 0, 0.8), 0 1px 0 rgba(255, 255, 255, 0.03) inset;
  padding: 9px 13px 10px;
}
/* Tail: a small diamond poking down toward the orb, near the card's left edge. */
.th-card::after {
  content: "";
  position: absolute;
  left: 16px;
  bottom: -5px;
  width: 10px;
  height: 10px;
  background: color-mix(in srgb, var(--chrome) 92%, #000);
  border-right: 1px solid color-mix(in srgb, var(--border) 80%, var(--accent));
  border-bottom: 1px solid color-mix(in srgb, var(--border) 80%, var(--accent));
  transform: rotate(45deg);
}
.th-label {
  display: block;
  font: 600 9px/1 ui-monospace, "SF Mono", Menlo, monospace;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent);
  opacity: 0.82;
  margin-bottom: 5px;
}
.th-text {
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
  color: var(--text-dim);
  font-size: 12.5px;
  line-height: 1.42;
  font-style: italic;
}

@media (prefers-reduced-motion: reduce) {
  #thought { transition: opacity .12s linear; }
}

/* --------------------------------------------------- click-to-inspect diff ----
   Regular Visual Claude tabs use the docked #filediff panel beneath the faux
   terminal. General Canvas uses .canvas-fd cards in #canvas-filediffs: standalone,
   draggable inspectors anchored near the orb/file tree that opened them. */
body.inspecting #subterminals { display: none; }
#canvas-filediffs {
  position: fixed;
  inset: 0;
  z-index: 6;
  pointer-events: none;
}
#filediff {
  position: fixed;
  top: 342px;                                  /* #terminal top (40) + height (290) + gap (12) */
  right: calc(min(360px, 34%) + 14px);         /* same gutter as #terminal */
  z-index: 4;                                  /* above #subterminals (3) */
  width: 300px;                                /* same width as #terminal */
  max-height: calc(100vh - 354px);             /* clip at the viewport foot */
}
#filediff,
.canvas-fd {
  display: flex;
  flex-direction: column;
  border: 1px solid color-mix(in srgb, var(--border) 84%, var(--accent));
  border-radius: 9px;
  background: color-mix(in srgb, var(--chrome) 92%, #000);
  box-shadow: 0 18px 48px -22px rgba(0, 0, 0, 0.7);
  overflow: hidden;
  pointer-events: auto;
}
#filediff { animation: filediff-in 0.24s cubic-bezier(0.22, 0.61, 0.36, 1); }
#filediff.hidden { display: none; }
.canvas-fd {
  position: absolute;
  width: min(420px, calc(100vw - 24px));
  height: min(380px, calc(100vh - 24px));
  min-width: 260px;
  min-height: 132px;
  max-width: none;
  max-height: none;
  box-shadow: 0 24px 70px -28px rgba(0, 0, 0, 0.82), 0 1px 0 rgba(255, 255, 255, 0.04) inset;
  transform-origin: top left;
  will-change: left, top, transform;
  animation: canvas-filediff-in 0.18s ease-out;
}
.canvas-fd .fd-head { cursor: grab; }
.canvas-fd.dragging {
  box-shadow: 0 30px 84px -28px rgba(0, 0, 0, 0.9), 0 0 0 1px color-mix(in srgb, var(--accent) 24%, transparent);
}
.canvas-fd.resizing {
  box-shadow: 0 30px 84px -28px rgba(0, 0, 0, 0.9), 0 0 0 1px color-mix(in srgb, var(--accent) 28%, transparent);
}
.canvas-fd.dragging .fd-head { cursor: grabbing; }
.canvas-fd.resizing .fd-head { cursor: default; }
.canvas-fd .fd-empty {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: center;
}
@keyframes filediff-in {
  from { opacity: 0; transform: translateY(-7px); }
  to   { opacity: 1; transform: none; }
}
@keyframes canvas-filediff-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Header: a create/edit tag, the file name, the +N/−M tally, and a close ×. */
.fd-head {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 8px 7px 11px;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
  background: color-mix(in srgb, var(--surface) 38%, transparent);
}
.fd-kind {
  flex: none;
  padding: 3px 6px;
  border-radius: 5px;
  font: 600 8.5px/1 ui-monospace, "SF Mono", Menlo, monospace;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.fd-kind.is-edit { color: var(--accent); background: color-mix(in srgb, var(--accent) 16%, transparent); }
.fd-kind.is-create { color: var(--success); background: color-mix(in srgb, var(--success) 16%, transparent); }
.fd-name {
  flex: 0 1 auto;
  min-width: 0;
  font: 600 11.5px/1.2 ui-monospace, "SF Mono", Menlo, monospace;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.fd-stat {
  flex: none;
  display: flex;
  gap: 7px;
  margin-left: auto;
  font: 600 10px/1 ui-monospace, "SF Mono", Menlo, monospace;
  font-variant-numeric: tabular-nums;
}
.fd-stat .fd-add { color: var(--diff-add); }
.fd-stat .fd-del { color: var(--diff-del); }
.fd-close {
  flex: none;
  appearance: none; -webkit-appearance: none;
  width: 18px; height: 18px;
  padding: 0; border: 0; border-radius: 5px;
  background: transparent;
  color: var(--muted);
  font-size: 0;
  cursor: pointer;
  position: relative;
  z-index: 4;
  transition: background 0.12s ease, color 0.12s ease;
}
.fd-close::before,
.fd-close::after {
  content: "";
  position: absolute;
  left: 5px;
  right: 5px;
  top: 8px;
  height: 1.4px;
  border-radius: 1px;
  background: currentColor;
}
.fd-close::before { transform: rotate(45deg); }
.fd-close::after { transform: rotate(-45deg); }
.fd-close:hover { background: color-mix(in srgb, var(--surface) 60%, transparent); color: var(--text); }

.fd-resize {
  position: absolute;
  z-index: 3;
  pointer-events: auto;
  touch-action: none;
}
.fd-resize-n {
  top: 0;
  left: 14px;
  right: 14px;
  height: 8px;
  cursor: ns-resize;
}
.fd-resize-e {
  top: 14px;
  right: 0;
  bottom: 14px;
  width: 8px;
  cursor: ew-resize;
}
.fd-resize-s {
  left: 14px;
  right: 14px;
  bottom: 0;
  height: 8px;
  cursor: ns-resize;
}
.fd-resize-w {
  top: 14px;
  left: 0;
  bottom: 14px;
  width: 8px;
  cursor: ew-resize;
}
.fd-resize-ne,
.fd-resize-se,
.fd-resize-sw,
.fd-resize-nw {
  width: 18px;
  height: 18px;
}
.fd-resize-ne {
  top: 0;
  right: 0;
  cursor: nesw-resize;
}
.fd-resize-se {
  right: 0;
  bottom: 0;
  cursor: nwse-resize;
}
.fd-resize-sw {
  left: 0;
  bottom: 0;
  cursor: nesw-resize;
}
.fd-resize-nw {
  top: 0;
  left: 0;
  cursor: nwse-resize;
}
.fd-resize-se::before {
  content: "";
  position: absolute;
  right: 5px;
  bottom: 5px;
  width: 7px;
  height: 7px;
  border-right: 1px solid color-mix(in srgb, var(--muted) 72%, transparent);
  border-bottom: 1px solid color-mix(in srgb, var(--muted) 72%, transparent);
  opacity: 0.55;
}
.canvas-fd:hover .fd-resize-se::before,
.canvas-fd.resizing .fd-resize-se::before {
  opacity: 0.9;
}
.fd-resize-n:hover,
.canvas-fd.resizing-n .fd-resize-n,
.fd-resize-s:hover,
.canvas-fd.resizing-s .fd-resize-s {
  background: color-mix(in srgb, var(--accent) 22%, transparent);
}
.fd-resize-e:hover,
.canvas-fd.resizing-e .fd-resize-e,
.fd-resize-w:hover,
.canvas-fd.resizing-w .fd-resize-w {
  background: color-mix(in srgb, var(--accent) 22%, transparent);
}
.fd-resize-ne:hover,
.canvas-fd.resizing-ne .fd-resize-ne,
.fd-resize-se:hover,
.canvas-fd.resizing-se .fd-resize-se,
.fd-resize-sw:hover,
.canvas-fd.resizing-sw .fd-resize-sw,
.fd-resize-nw:hover,
.canvas-fd.resizing-nw .fd-resize-nw {
  background: color-mix(in srgb, var(--accent) 18%, transparent);
}

/* Body: a real scrollable diff. One row per line - a line-number gutter, the
   +/−/space sign, then the code, green for additions and red for deletions. */
.fd-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;                              /* both axes - long lines scroll sideways */
  padding: 6px 0 8px;
  font: 10.5px/1.5 ui-monospace, "SF Mono", Menlo, monospace;
}
.fd-body::-webkit-scrollbar { width: 7px; height: 7px; }
.fd-body::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; }

/* Inner scroll surface: sized to the widest line (max-content) so it - not the
   panel - sets the horizontal scroll extent. Every row then stretches to 100% of
   *this*, so the +/− backgrounds run the full width even when scrolled sideways. */
.fd-rows {
  width: max-content;
  min-width: 100%;                             /* …but never narrower than the panel */
}

.fd-line {
  display: flex;
  align-items: baseline;
  padding-right: 10px;
  white-space: pre;
  min-width: 100%;                             /* fill the widest-line surface, not the panel */
}
.fd-num {
  flex: none;
  width: 34px;
  padding-right: 8px;
  text-align: right;
  color: var(--muted);
  opacity: 0.7;
  -webkit-user-select: none;
  user-select: none;
}
.fd-sign {
  flex: none;
  width: 14px;
  text-align: center;
  color: var(--muted);
  -webkit-user-select: none;
  user-select: none;
}
.fd-code {
  flex: none;                                  /* natural width - scroll instead of ellipsis-truncate */
  color: var(--text-dim);
}
.fd-line.is-add { background: color-mix(in srgb, var(--diff-add) 13%, transparent); }
.fd-line.is-add .fd-sign { color: var(--diff-add); }
.fd-line.is-add .fd-code { color: color-mix(in srgb, var(--diff-add) 34%, var(--text)); }
.fd-line.is-del { background: color-mix(in srgb, var(--diff-del) 13%, transparent); }
.fd-line.is-del .fd-sign { color: var(--diff-del); }
.fd-line.is-del .fd-code { color: color-mix(in srgb, var(--diff-del) 34%, var(--text)); }
.fd-line.is-ctx .fd-code { color: var(--muted); }

/* Hunk header (@@ …): a quiet band separating runs of changes. */
.fd-hunk {
  padding: 5px 12px 4px;
  margin: 4px 0;
  color: var(--tool);
  background: color-mix(in srgb, var(--tool) 9%, transparent);
  border-top: 1px solid color-mix(in srgb, var(--border) 55%, transparent);
  border-bottom: 1px solid color-mix(in srgb, var(--border) 55%, transparent);
  font: 9.5px/1.4 ui-monospace, "SF Mono", Menlo, monospace;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.fd-hunk:first-child { margin-top: 0; border-top: 0; }

/* Empty / binary states. */
.fd-empty {
  padding: 16px 14px;
  color: var(--muted);
  font: 11px/1.5 -apple-system, system-ui, sans-serif;
  text-align: center;
}
.fd-more {
  padding: 6px 12px 2px;
  font: 9.5px/1.3 ui-monospace, "SF Mono", Menlo, monospace;
  color: var(--muted);
}
@media (prefers-reduced-motion: reduce) {
  #filediff, .canvas-fd { animation: none; }
  .fd-close { transition: none; }
}

#hud {
  position: fixed;
  inset: 0;
  z-index: 4;
  pointer-events: none;
  font: var(--hud-font);
}

/* Dim app mark, top-left. Present but never loud. */
#brand {
  position: absolute;
  top: 12px;
  left: 16px;
  display: flex;
  align-items: center;
  gap: 8px;
  letter-spacing: 0.06em;
  font-size: 11px;
  font-weight: 650;
  color: var(--muted);
  opacity: 0.72;
}
#brand img {
  width: 26px;
  height: 26px;
  border-radius: 7px;
  object-fit: cover;
  box-shadow: 0 0 18px color-mix(in srgb, var(--accent) 26%, transparent);
}

/* Catch-up indicator, top-right - only visible while the choreographer is
   compressing playback to catch the stream. */
#speed {
  position: absolute;
  top: 14px;
  right: 16px;
  padding: 3px 9px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--attention) 14%, transparent);
  color: var(--attention);
  font-variant-numeric: tabular-nums;
  font-size: 11px;
  letter-spacing: 0.04em;
  transition: opacity 0.45s ease, transform 0.45s ease;
}
#speed.hidden {
  opacity: 0;
  transform: translateY(-4px);
}

/* The live action line, bottom-left. The verb is a cool/warm small-caps tag;
   the target is the file or subject. Crossfades between beats. */
#action {
  position: absolute;
  left: 20px;
  bottom: 22px;
  max-width: min(70ch, 76%);
  display: flex;
  align-items: baseline;
  gap: 10px;
  transition: opacity 0.32s ease;
}
#action.idle { opacity: 0; }

#verb {
  text-transform: uppercase;
  letter-spacing: 0.16em;
  font-size: 10.5px;
  font-weight: 600;
  color: var(--tool);
  white-space: nowrap;
}
#verb.voice { color: var(--accent); }
#verb.attn { color: var(--attention); }
#verb.good { color: var(--success); }
#verb.bad { color: var(--danger); }

#target {
  color: var(--text-dim);
  font-size: 12.5px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
  #speed, #action { transition: none; }
}

/* Pipeline report ----------------------------------------------------------
   Docked in the lower band of the stage when a turn's final reply is a complete
   HTML walkthrough (Output → Pipeline). Spans from the left edge to the prompt
   rail; the canvas scene lifts up to clear it (VCScene.setReserveBottom, sized
   to this panel's height by vc.js). The model's document mounts in a sandboxed
   iframe - opaque origin, injected CSP + theme - so it can't reach the parent,
   the network, or the disk. Cleared on the next turn. */
#report {
  position: fixed;
  left: 16px;
  right: calc(min(360px, 34%) + 14px);
  bottom: 14px;
  top: 50%;
  z-index: 3;
  display: flex;
  flex-direction: column;
  border: 1px solid color-mix(in srgb, var(--border) 88%, var(--accent));
  border-radius: 12px;
  background: color-mix(in srgb, var(--chrome) 92%, #000);
  box-shadow: 0 28px 70px -30px rgba(0, 0, 0, 0.85), 0 1px 0 rgba(255, 255, 255, 0.03) inset;
  overflow: hidden;
  pointer-events: auto;
  opacity: 0;
  transform: translateY(12px) scale(0.992);
  transition: opacity .34s cubic-bezier(.16, .84, .44, 1),
              transform .34s cubic-bezier(.16, .84, .44, 1);
  will-change: opacity, transform;
}
#report.hidden { display: none; }
#report.show { opacity: 1; transform: none; }

/* Slim header: a "pipeline" eyebrow, the document's own <title>, and a close ×
   (the next turn also clears the panel). */
.re-head {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px 10px 8px 13px;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
  background: color-mix(in srgb, var(--surface) 30%, transparent);
}
.re-eyebrow {
  flex: 0 0 auto;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font: 600 9px/1 ui-monospace, "SF Mono", Menlo, monospace;
  color: var(--accent);
  opacity: 0.9;
}
.re-title {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font: 12px/1.3 -apple-system, system-ui, sans-serif;
  color: var(--text-dim);
}
.re-close {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--muted);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  transition: background .16s ease, color .16s ease;
}
.re-close:hover { background: color-mix(in srgb, var(--surface) 60%, transparent); color: var(--text); }

/* The model's document. Opaque background (its own styles paint over it). */
.re-frame {
  flex: 1 1 auto;
  width: 100%;
  border: 0;
  display: block;
  background: var(--bg);
}

/* The rail stand-in shown in place of the raw HTML code block: a quiet chip that
   points at the live report below. */
.report-note {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 12px;
  border: 1px solid color-mix(in srgb, var(--border) 86%, var(--accent));
  border-radius: 9px;
  background: color-mix(in srgb, var(--surface) 34%, transparent);
  font: 12px/1.4 -apple-system, system-ui, sans-serif;
  color: var(--text-dim);
}
.report-note .rn-glyph { flex: 0 0 auto; color: var(--accent); font-size: 12px; }
.report-note .rn-title { color: var(--text); font-weight: 600; }

/* While a report is docked, the bottom-left HUD action line would float over the
   panel - drop it (the rail already carries the turn's outcome). */
body.reporting #action { display: none; }

@media (prefers-reduced-motion: reduce) {
  #report { transition: none; }
}

/* General Canvas readability: the file tree stays at its compact canvas scale,
   but the transcript rail and its interactive panels get a larger type scale. */
html.canvasmode #content,
body.canvasmode #content {
  width: min(420px, 38%);
  padding: 46px 24px 28px 20px;
}
html.canvasmode #promptpin,
body.canvasmode #promptpin {
  right: 24px;
  width: calc(min(420px, 38%) - 44px);
}
html.canvasmode .pp-text,
body.canvasmode .pp-text {
  font: 600 15px/1.42 -apple-system, system-ui, "SF Pro Text", sans-serif;
}
html.canvasmode .turn-prompt,
body.canvasmode .turn-prompt {
  font: 600 16px/1.58 -apple-system, system-ui, "SF Pro Text", sans-serif;
}
html.canvasmode .turn-prompt::before,
body.canvasmode .turn-prompt::before {
  font: 600 11.5px/1 ui-monospace, "SF Mono", Menlo, monospace;
}
html.canvasmode .turn-output,
body.canvasmode .turn-output {
  font: 400 15.5px/1.68 -apple-system, system-ui, "SF Pro Text", sans-serif;
}
html.canvasmode .turn-output h1,
body.canvasmode .turn-output h1 { font-size: 20px; }
html.canvasmode .turn-output h2,
body.canvasmode .turn-output h2 { font-size: 18px; }
html.canvasmode .turn-output h3,
body.canvasmode .turn-output h3 { font-size: 16.5px; }
html.canvasmode .turn-output h4,
body.canvasmode .turn-output h4 { font-size: 15.5px; }
html.canvasmode .turn-output code,
body.canvasmode .turn-output code {
  font: 14px/1.45 ui-monospace, "SF Mono", Menlo, monospace;
}
html.canvasmode .turn-output pre code,
body.canvasmode .turn-output pre code {
  font-size: 13.5px;
}
html.canvasmode .turn-output table,
body.canvasmode .turn-output table {
  font-size: 14px;
}
html.canvasmode .turn-output .tool-step,
body.canvasmode .turn-output .tool-step {
  font: 13.5px/1.5 ui-monospace, "SF Mono", Menlo, monospace;
}
html.canvasmode .turn-output .reason-toggle,
body.canvasmode .turn-output .reason-toggle {
  font: 600 11.5px/1 ui-monospace, "SF Mono", Menlo, monospace;
}
html.canvasmode .turn-output .reason-body,
body.canvasmode .turn-output .reason-body {
  font-size: 14.5px;
}
html.canvasmode .ask-eyebrow,
body.canvasmode .ask-eyebrow {
  font: 600 11.5px/1 ui-monospace, "SF Mono", Menlo, monospace;
}
html.canvasmode .ask-head,
body.canvasmode .ask-head {
  font: 600 12px/1 ui-monospace, "SF Mono", Menlo, monospace;
}
html.canvasmode .ask-q,
body.canvasmode .ask-q {
  font: 600 15.5px/1.5 -apple-system, system-ui, "SF Pro Text", sans-serif;
}
html.canvasmode .ask-lab,
body.canvasmode .ask-lab {
  font: 600 14.5px/1.36 -apple-system, system-ui, "SF Pro Text", sans-serif;
}
html.canvasmode .ask-desc,
body.canvasmode .ask-desc {
  font: 400 13.5px/1.44 -apple-system, system-ui, "SF Pro Text", sans-serif;
}
html.canvasmode .ask-other,
body.canvasmode .ask-other {
  font: 400 14.5px/1.44 -apple-system, system-ui, "SF Pro Text", sans-serif;
}
html.canvasmode .ask-err,
body.canvasmode .ask-err {
  font: 400 13.5px/1.44 -apple-system, system-ui, "SF Pro Text", sans-serif;
}
html.canvasmode .ask-submit,
body.canvasmode .ask-submit {
  font: 600 14.5px/1 -apple-system, system-ui, "SF Pro Text", sans-serif;
}
html.canvasmode .report-note,
body.canvasmode .report-note {
  font: 14px/1.48 -apple-system, system-ui, sans-serif;
}

/* While a container is scrolling, drop its descendants from hit-testing so a
   stale :hover left under a stationary cursor clears (see vc.js). The scroller
   keeps its own pointer events, so scrolling itself is unaffected; the next
   mousemove removes the class and restores normal hover. */
.vc-scroll-no-hover * { pointer-events: none; }
