:root {
  --bg:          #080b10;
  --panel:       #0e1420;
  --panel-2:     #131b28;
  --panel-3:     #1a2335;
  --border:      #1e2d42;
  --border-hi:   #2d4060;
  --text:        #dce8f5;
  --text-dim:    #6b84a0;
  --text-faint:  #3d5066;

  --state:       #ff8c42;
  --state-soft:  rgba(255,140,66,0.10);
  --config:      #b97fff;
  --config-soft: rgba(185,127,255,0.10);
  --flow:        #3d9aff;
  --flow-soft:   rgba(61,154,255,0.08);
  --class:       #00e5b0;
  --class-soft:  rgba(0,229,176,0.07);
  --verbatim:    #4a5568;
  --verbatim-soft: rgba(74,85,104,0.15);
  --view:        #06b6d4;
  --view-soft:   rgba(6,182,212,0.08);
  --import:      #ffd166;
  --import-soft: rgba(255,209,102,0.08);

  /* ── File group box — muted slate-blue, distinct from class (--class) ──
     Picked to read as "structural container, level above class" rather
     than another type colour. Slightly cool grey-blue so it recedes
     when the eye lands on the inner contents. */
  --file:        #7a98c4;
  --file-soft:   rgba(122,152,196,0.06);

  --edge-in:     #3d9aff;
  --edge-mut:    #ff8c42;
  --edge-call:   #b97fff;
  --edge-self:   #00e5b0;
  --edge-nest:   #ff5d8f;

  --match-strong: #00e5b0;
  --match-weak:   #ffd166;

  --class-border-dash: 6px;

  /* Height reserved at the bottom of the viewport for the chat dock
     (prompt-bar + chat-bar + history). Updated live by autocomplete.js
     via a ResizeObserver so the editor/viewer shrink to sit above the
     dock instead of being overlaid by an expanding chat history. */
  --dock-h: 84px;

  /* Top strip is now just the indeterminate loading animation — see
     .topbar / .topbar-loading-bar below. Anything that needs to clear
     the topbar (editor-panel, viewer-panel, mode toolbar, overlays)
     should reference this variable rather than hard-coding the height. */
  --topbar-h: 4px;

  /* ── CLI-style chat dock + terminal bubbles ──────────────────────
     One pane: the chat-dock parent paints --dock-bg; its children
     (chat-history, chat-bar, prompt-bar) are transparent so the dock
     reads as a single surface. Each theme overrides these below so
     light/midnight/blue/rusty don't end up with a black input box. */
  --dock-bg:         rgba(8,11,16,0.94);
  --input-bg:        rgba(0,0,0,0.32);
  --input-bg-focus:  rgba(0,0,0,0.42);
  --input-border:    rgba(255,255,255,0.06);
  --term-bg:         rgba(0,0,0,0.32);
  --term-out-bg:     rgba(0,0,0,0.45);
}

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; overflow: hidden; }
body {
  background: var(--bg);
  color: var(--text);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 12px;
}

/* ── Topbar ───────────────────────────────────────────────── */
/* Stripped to just the indeterminate loading animation — no buttons,
   no logo, no project chrome. Total height is --topbar-h (4px) so the
   editor/viewer reclaim the screen real estate. The loading bar sits
   absolutely positioned at bottom: 0 inside this strip. */
.topbar {
  position: fixed; top: 0; left: 0; right: 0; height: var(--topbar-h);
  background: rgba(8,11,16,0.90);
  backdrop-filter: blur(16px);
  z-index: 200;
}
.topbar .logo {
  font-family: 'Syne', sans-serif;
  font-weight: 800; font-size: 15px;
  letter-spacing: -0.5px;
  color: var(--text);
  display: flex; align-items: center; gap: 8px;
}
.topbar .logo .glyph {
  width: 22px; height: 22px;
  background: linear-gradient(135deg, var(--flow), var(--class));
  border-radius: 5px;
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700; color: #080b10;
}
.topbar .file {
  color: var(--text-dim); font-size: 11px;
  padding: 3px 8px; background: var(--panel-2);
  border: 1px solid var(--border); border-radius: 4px;
}
.topbar .spacer { flex: 1; }
.topbar .project-name {
  font-size: 11px; font-weight: 600;
  color: var(--flow); opacity: 0.8;
  font-family: 'Syne', sans-serif;
  letter-spacing: -0.3px;
}
/* ── Ultra-thin loading bar pinned to the bottom of the topbar.
       Indeterminate / decorative — slides a soft accent-coloured segment
       across the bar over 15s, then loops. Hook into the existing
       border-bottom by sitting flush against it (height: 2px) so the
       chrome reads as one solid line at rest and a moving highlight
       while "loading". Replace the animation duration / pause via JS
       later when we want it to reflect a real operation. ──────────── */
.topbar-loading-bar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: var(--border);
  overflow: hidden;
  pointer-events: none;
  z-index: 1;
}
.topbar-loading-bar::before {
  content: '';
  position: absolute;
  top: 0;
  left: -30%;
  width: 30%;
  height: 100%;
  background: linear-gradient(
    90deg,
    transparent 0%,
    var(--state) 50%,
    transparent 100%
  );
  animation: topbar-loading-slide 15s linear infinite;
}
@keyframes topbar-loading-slide {
  0%   { left: -30%; }
  100% { left: 100%; }
}

/* ── AIII sync completion indicator (right side of topbar) ───────── */
.sync-status {
  display: flex; align-items: center; gap: 8px;
  margin-left: 6px;
  font-size: 10px;
  color: var(--text-dim);
  font-family: 'JetBrains Mono', monospace;
}
.sync-status-bar {
  width: 56px; height: 6px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 3px;
  overflow: hidden;
  flex-shrink: 0;
}
.sync-status-fill {
  height: 100%; width: 0%;
  background: var(--state);
  transition: width 240ms ease, background-color 240ms ease;
}
.sync-status-fill.ok   { background: #2ec27e; }
.sync-status-fill.warn { background: #ffa657; }
.sync-status-fill.bad  { background: #f85149; }
.sync-status-label {
  min-width: 32px;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.btn {
  background: var(--panel-2); border: 1px solid var(--border);
  color: var(--text-dim); padding: 5px 12px; border-radius: 5px;
  font-size: 11px; font-family: 'JetBrains Mono', monospace;
  cursor: pointer; transition: all 0.15s; white-space: nowrap;
}
.btn:hover { border-color: var(--border-hi); color: var(--text); background: var(--panel-3); }

/* ── Split layout ─────────────────────────────────────────── */
/* Right edge reserves the collapsed stage-history rail (28px) so the rail
   sits next to the viewer panel instead of overlaying it. When the rail
   expands on hover, :has() pushes the layout further left so the expanded
   pane still sits beside the viewer rather than on top of it. */
.split-layout {
  position: fixed; top: var(--topbar-h); left: 0; right: 28px; bottom: var(--dock-h);
  display: flex;
  transition: right 0.2s ease;
}
body:has(.stage-history:hover) .split-layout { right: 240px; }

/* Viewer collapsed — editor takes the whole pane. The viewer-rail (right
   edge) is shown so the user can re-open. We also reserve 28px more on the
   right so the rail doesn't sit on top of the code. */
body.viewer-collapsed .split-layout { right: 56px; }
body.viewer-collapsed:has(.stage-history:hover) .split-layout { right: 240px; }
body.viewer-collapsed .editor-panel {
  flex: 1 1 100%;
  border-right: none;
}
body.viewer-collapsed .viewer-panel { display: none; }

/* ── Right-edge re-open rail (only visible when viewer collapsed) ───── */
.viewer-rail {
  position: fixed;
  top: var(--topbar-h); right: 28px;   /* sits to the LEFT of the stage-history rail */
  width: 28px; bottom: var(--dock-h);
  background: var(--panel-2);
  border-left: 1px solid var(--border);
  z-index: 140;                     /* below .stage-history's 150 so hover overlays */
  display: flex; flex-direction: column; align-items: center;
  padding: 6px 0;
  gap: 8px;
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
}
.viewer-rail[hidden] { display: none; }
.viewer-rail:hover { background: var(--panel-3); }
.viewer-rail-btn {
  width: 22px; height: 22px;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--text-dim);
  font-size: 13px; line-height: 1;
  cursor: pointer;
  transition: all 0.12s;
}
.viewer-rail:hover .viewer-rail-btn { color: var(--text); border-color: var(--border-hi); }
.viewer-rail-label {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  font-family: 'Syne', sans-serif;
  font-size: 9px; letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--text-faint);
  user-select: none;
}
/* When the user hovers the stage-history strip and it expands to 240px,
   it overlaps the rail. The rail stays where it is (28px from right)
   but visually is covered. We also fade it slightly to communicate the
   "temporary cover" intent the user described. */
body:has(.stage-history:hover) .viewer-rail { opacity: 0.5; }

/* ── Editor panel (left) ──────────────────────────────────── */
.editor-panel {
  flex: 0 0 50%;
  height: 100%;
  display: flex;
  flex-direction: column;
  background: var(--panel);
  border-right: 1px solid var(--border);
  overflow: hidden;
}

.editor-toolbar {
  display: flex; align-items: center; gap: 10px;
  padding: 6px 14px;
  border-bottom: 1px solid var(--border);
  background: var(--panel-2);
  flex-shrink: 0;
  height: 32px;
}
.editor-filename {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; color: var(--text-dim);
  letter-spacing: 0.2px;
}

/* ── Editor tabs strip ───────────────────────────────────── */
/* Horizontal row of open buffers, sits above the toolbar. Empty (no
   tabs open) collapses to height 0 so the layout cleanly disappears. */
.editor-tabs {
  display: flex;
  align-items: stretch;
  background: var(--panel);
  border-bottom: 1px solid var(--border);
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
  flex-shrink: 0;
  min-height: 0;
}
.editor-tabs:empty { display: none; }
.editor-tab {
  display: flex; align-items: center;
  gap: 6px;
  padding: 6px 6px 6px 12px;
  border-right: 1px solid var(--border);
  background: var(--panel-2);
  color: var(--text-faint);
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.1px;
  cursor: pointer;
  max-width: 220px;
  flex-shrink: 0;
  user-select: none;
  position: relative;
  transition: background 100ms, color 100ms;
}
.editor-tab:hover { background: var(--panel-3); color: var(--text-dim); }
.editor-tab.active {
  background: var(--bg);
  color: var(--text);
}
/* Active tab gets a top accent stripe in the asteris flow colour. */
.editor-tab.active::after {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: var(--flow);
}
.et-icon { font-size: 11px; line-height: 1; }
.et-label {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.et-close {
  width: 18px; height: 18px;
  padding: 0;
  background: transparent;
  border: none;
  border-radius: 3px;
  color: var(--text-faint);
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  opacity: 0.7;
  transition: opacity 100ms, background 100ms, color 100ms;
  flex-shrink: 0;
}
.et-close:hover {
  opacity: 1;
  background: var(--panel-3);
  color: var(--text);
}
.editor-tab.active .et-close:hover { background: var(--panel-2); }

.editor-save-status {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px; color: var(--text-faint);
  margin-left: auto;
  opacity: 0;
  transition: opacity 0.3s;
}
.editor-save-status.visible { opacity: 1; }

/* ── Editor body: contains the three stacked layers ──────── */
.editor-body {
  flex: 1;
  position: relative;
  overflow: hidden;
  background: var(--bg);
}

/* Shared font metrics — MUST match .code-editor exactly.
   Left padding budgets 54px for the line-number gutter + 8px breathing room
   between the gutter and the first character. Override with body.no-gutter
   when the gutter is hidden so code reclaims the space. */
.syntax-layer,
.code-editor {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 12px;
  line-height: 1.7;
  padding: 16px 18px 16px 62px;
  tab-size: 4;
  white-space: pre;
  overflow-wrap: normal;
  word-break: normal;
  box-sizing: border-box;
}

/* Syntax highlight layer — rendered HTML sits behind the textarea */
.syntax-layer {
  position: absolute;
  top: 0; left: 0;
  min-width: 100%;
  color: var(--text);
  pointer-events: none;
  z-index: 1;
  user-select: none;
}

/* Block overlay layer — coloured left-border bands per block.
   left:54px so bands start at the gutter's right edge rather than running
   through the line-number column. */
.block-overlay-layer {
  position: absolute;
  top: 0;
  left: 54px;
  right: 0;
  pointer-events: none;
  z-index: 0;
}

/* ── Line-number gutter ──────────────────────────────────── */
/* Sits left of the code stack. .gutter-inner is the scrollable surface
   we translateY()-sync to the textarea's scrollTop. */
.gutter-layer {
  position: absolute;
  top: 0; left: 0; bottom: 0;
  width: 54px;
  background: var(--panel-2);
  border-right: 1px solid var(--border);
  overflow: hidden;
  z-index: 3;
  user-select: none;
}
.gutter-inner {
  position: absolute;
  top: 0; left: 0; right: 0;
  padding-top: 16px;          /* match .code-editor padding-top */
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 10px;
  will-change: transform;
}
.gutter-line {
  height: 20.4px;              /* must equal LINE_H_PX */
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 4px;
  padding: 0 6px 0 2px;
  color: var(--text-faint);
  white-space: nowrap;
}
.gutter-line.folded-marker { color: var(--text-dim); font-style: italic; }
.gutter-num {
  display: inline-block;
  min-width: 22px;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.gutter-fold {
  width: 14px; height: 14px;
  padding: 0;
  background: transparent;
  border: none;
  cursor: pointer;
  color: var(--text-faint);
  font-size: 9px;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  pointer-events: auto;
  transition: color 100ms, transform 100ms;
}
.gutter-fold:hover { color: var(--text); transform: scale(1.2); }
.gutter-fold.folded { color: var(--flow); }
.gutter-fold[data-type="FLOW"]     { color: var(--flow); }
.gutter-fold[data-type="CLASS"]    { color: var(--class); }
.gutter-fold[data-type="IMPORT"]   { color: var(--import); }
.gutter-fold[data-type="STATE"]    { color: var(--state); }
.gutter-fold[data-type="CONFIG"]   { color: var(--config); }
.gutter-fold[data-type="VERBATIM"] { color: var(--verbatim); }
.gutter-fold[data-type="VIEW"]     { color: var(--view); }
.gutter-fold-spacer { width: 14px; height: 14px; display: inline-block; }

/* When the gutter is hidden, reclaim its left padding and reset overlay
   left so bands run the full width again. */
body.no-gutter .gutter-layer { display: none; }
body.no-gutter .syntax-layer,
body.no-gutter .code-editor { padding-left: 18px; }
body.no-gutter .block-overlay-layer { left: 0; }

/* Foldall toolbar button rotates its glyph based on aria-pressed state */
.btn-numbers[aria-pressed="false"],
.btn-foldall[aria-pressed="true"] { color: var(--flow); border-color: var(--flow); }

/* Actual textarea — transparent text so the syntax layer shows through */
.code-editor {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  background: transparent;
  color: transparent;
  caret-color: var(--flow);
  border: none; outline: none; resize: none;
  overflow-x: auto;
  overflow-y: auto;
  z-index: 2;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}
.code-editor::selection {
  background: rgba(61,154,255,0.22);
}

/* ── Block overlay bands ──────────────────────────────────── */
.bo-block {
  position: absolute;
  left: 0; right: 0;
  border-left: 2px solid transparent;
  transition: background 120ms ease, border-left-width 120ms ease, box-shadow 120ms ease;
}
.bo-block[data-type="FLOW"]     { border-left-color: var(--flow);     background: var(--flow-soft); }
.bo-block[data-type="CLASS"]    { border-left-color: var(--class);    background: var(--class-soft); }
.bo-block[data-type="IMPORT"]   { border-left-color: var(--import);   background: var(--import-soft); }
.bo-block[data-type="STATE"]    { border-left-color: var(--state);    background: var(--state-soft); }
.bo-block[data-type="CONFIG"]   { border-left-color: var(--config);   background: var(--config-soft); }
.bo-block[data-type="VERBATIM"] { border-left-color: var(--verbatim); background: var(--verbatim-soft); }

/* Hover state — band glows brighter and the left bar fattens to read
   as "active block under cursor". Driven by a JS toggle on mousemove
   (editor body) and by hover on the inspector globals list / chips. */
.bo-block.hover {
  border-left-width: 4px;
  filter: brightness(1.5) saturate(1.2);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.06);
}

/* ── Right-click block reference menu ─────────────────────── */
/* Floats over the editor at the cursor; one item per block action.
   Replaces the old left-gutter handle dots — right-click anywhere on
   an asteris band to pull up the same "Reference /id" action. */
.editor-ctx-menu {
  position: fixed;
  z-index: 1000;
  background: var(--panel);
  border: 1px solid var(--border-hi);
  border-radius: 6px;
  padding: 4px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.45);
  min-width: 200px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
}
.ecm-item {
  display: flex; align-items: center; gap: 8px;
  width: 100%;
  background: transparent;
  border: none;
  color: var(--text);
  padding: 7px 10px;
  border-radius: 4px;
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  font-size: inherit;
}
.ecm-item:hover { background: var(--panel-3); }
.ecm-label code {
  font-family: 'JetBrains Mono', monospace;
  color: var(--flow);
  background: transparent;
  padding: 0;
}
.ecm-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--text-faint);
  flex-shrink: 0;
}
.ecm-item[data-type="FLOW"]     .ecm-dot { background: var(--flow);     box-shadow: 0 0 6px var(--flow); }
.ecm-item[data-type="CLASS"]    .ecm-dot { background: var(--class);    box-shadow: 0 0 6px var(--class); }
.ecm-item[data-type="IMPORT"]   .ecm-dot { background: var(--import);   box-shadow: 0 0 6px var(--import); }
.ecm-item[data-type="STATE"]    .ecm-dot { background: var(--state);    box-shadow: 0 0 6px var(--state); }
.ecm-item[data-type="CONFIG"]   .ecm-dot { background: var(--config);   box-shadow: 0 0 6px var(--config); }
.ecm-item[data-type="VERBATIM"] .ecm-dot { background: var(--verbatim); box-shadow: 0 0 6px var(--verbatim); }
.ecm-item[data-type="VIEW"]     .ecm-dot { background: var(--view);     box-shadow: 0 0 6px var(--view); }

/* ── Syntax highlight token colours ─────────────────────────*/
.syn-kw      { color: var(--flow); }
.syn-defname { color: var(--class); font-weight: 500; }
.syn-str     { color: #e8976a; }
.syn-cmt     { color: var(--text-faint); font-style: italic; }
.syn-num     { color: #a8c57b; }
.syn-dec     { color: var(--config); }
.syn-builtin { color: #67d7e8; }
/* Highlight the active line via a JS-injected class on a sibling — not applicable for textarea.
   Instead, we style the active line indicator in the toolbar. */

/* ── Viewer panel (right) ─────────────────────────────────── */
.viewer-panel {
  flex: 1;
  height: 100%;
  position: relative;
  overflow: hidden;
}

/* Mode toggle pinned at the top of the viewer panel. */
.viewer-mode-toolbar {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 32px;
  display: flex; align-items: center; gap: 4px;
  padding: 0 10px;
  background: var(--panel-2);
  border-bottom: 1px solid var(--border);
  z-index: 4;
}
.vm-btn {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; letter-spacing: 0.3px;
  color: var(--text-faint);
  background: transparent;
  border: 1px solid transparent;
  border-radius: 4px;
  padding: 3px 10px;
  cursor: pointer;
  transition: color 120ms, background 120ms, border-color 120ms;
}
.vm-btn:hover { color: var(--text); }
.vm-btn[aria-pressed="true"] {
  color: var(--text);
  background: var(--panel-3);
  border-color: var(--border-hi);
}
.vm-spacer { flex: 1; }
.vm-collapse {
  background: transparent;
  border: 1px solid transparent;
  color: var(--text-faint);
  width: 22px; height: 22px;
  border-radius: 4px;
  font-size: 14px; line-height: 1;
  cursor: pointer;
  transition: all 0.12s;
}
.vm-collapse:hover {
  color: var(--text);
  background: var(--panel-3);
  border-color: var(--border-hi);
}
.viewer-mode-toolbar { display: flex; align-items: center; }

/* The canvas + inspector + plans pane all live below the 32px toolbar. */
.viewer-panel .canvas-wrap,
.viewer-panel .inspector-panel,
.viewer-panel .plans-panel {
  top: 32px;
}

/* ── Plans pane (viewer mode) ────────────────────────────────────────── */
.plans-panel {
  position: absolute; inset: 0;
  display: flex;
  background: var(--bg);
  color: var(--text);
  font-family: 'JetBrains Mono', monospace;
}
.plans-sidebar {
  width: 240px; flex-shrink: 0;
  border-right: 1px solid var(--border);
  background: var(--panel-2);
  display: flex; flex-direction: column;
}
.plans-sidebar-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
}
.plans-sidebar-title {
  font-family: 'Syne', sans-serif;
  font-weight: 600; font-size: 10px;
  letter-spacing: 0.5px;
  color: var(--text-faint);
  text-transform: uppercase;
}
.plans-refresh {
  background: transparent; border: 1px solid var(--border);
  color: var(--text-dim); border-radius: 4px;
  width: 22px; height: 22px;
  cursor: pointer; font-size: 11px;
}
.plans-refresh:hover { color: var(--text); border-color: var(--border-hi); }
.plans-list {
  flex: 1; overflow-y: auto;
  padding: 8px;
  display: flex; flex-direction: column; gap: 4px;
  scrollbar-width: thin; scrollbar-color: var(--border) transparent;
}
.plans-empty {
  font-size: 11px; color: var(--text-faint);
  padding: 14px; text-align: center;
  border: 1px dashed var(--border); border-radius: 6px;
}
.plans-empty code { color: var(--flow); }
.plans-list-item {
  display: flex; flex-direction: column; gap: 3px;
  background: transparent;
  border: 1px solid transparent; border-left: 2px solid transparent;
  border-radius: 5px;
  padding: 7px 9px;
  text-align: left;
  color: var(--text);
  font-family: inherit; font-size: 11px;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
}
.plans-list-item:hover { background: var(--panel-3); }
.plans-list-item.active {
  background: var(--flow-soft);
  border-color: var(--border-hi);
  border-left-color: var(--flow);
}
.plans-list-item .pli-row {
  display: flex; align-items: center; justify-content: space-between; gap: 6px;
}
.plans-list-item .pli-row.meta {
  color: var(--text-faint);
  font-size: 9px;
}
.pli-plan-title {
  font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pli-amb-pill {
  background: var(--state-soft);
  color: var(--state);
  border: 1px solid rgba(255,140,66,0.32);
  border-radius: 9px;
  padding: 1px 6px;
  font-size: 9px;
  text-transform: uppercase; letter-spacing: 0.3px;
}
.plans-hint {
  border-top: 1px solid var(--border);
  padding: 10px 12px;
  font-size: 10px;
  color: var(--text-faint);
}
.plans-hint code {
  color: var(--flow);
  background: var(--panel-3);
  padding: 1px 5px; border-radius: 3px;
}

.plans-detail {
  flex: 1; overflow-y: auto;
  padding: 18px 24px 32px;
  scrollbar-width: thin; scrollbar-color: var(--border) transparent;
  display: flex; flex-direction: column;
}
.plans-detail-empty {
  margin: auto;
  font-size: 12px; color: var(--text-faint);
  text-align: center;
}
.plans-detail-empty code { color: var(--flow); }
.plans-detail-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--border);
}
.plans-detail-title {
  font-family: 'Syne', sans-serif;
  font-size: 16px; font-weight: 700;
  letter-spacing: -0.3px;
  color: var(--text);
}
.plans-detail-meta {
  font-size: 10px; color: var(--text-faint);
  margin-top: 2px;
}
.plans-detail-delete {
  background: var(--panel-2); border: 1px solid var(--border);
  color: var(--text-dim);
  border-radius: 5px;
  padding: 5px 10px;
  font-family: inherit; font-size: 10px;
  cursor: pointer; transition: all 0.12s;
}
.plans-detail-delete:hover { color: #f85149; border-color: #f85149; background: rgba(248,81,73,0.08); }
.plans-detail-actions { display: flex; gap: 6px; }
.plans-detail-run {
  background: var(--class-soft);
  border: 1px solid var(--class);
  color: var(--class);
  border-radius: 5px;
  padding: 5px 12px;
  font-family: inherit; font-size: 10px; font-weight: 600;
  cursor: pointer; transition: all 0.12s;
}
.plans-detail-run:hover { background: var(--class); color: #06121e; }
.plans-detail-run-pill {
  display: inline-block;
  margin-left: 8px;
  padding: 1px 8px;
  border-radius: 9px;
  font-size: 9px;
  letter-spacing: 0.3px;
  text-transform: uppercase;
  border: 1px solid var(--border-hi);
  color: var(--text-dim);
  background: var(--panel-3);
}
.plans-detail-run-pill.status-done      { color: #2ec27e; border-color: rgba(46,194,126,0.4);  background: rgba(46,194,126,0.08); }
.plans-detail-run-pill.status-error     { color: #f85149; border-color: rgba(248,81,73,0.4);   background: rgba(248,81,73,0.08); }
.plans-detail-run-pill.status-running   { color: var(--flow); border-color: rgba(61,154,255,0.45); background: var(--flow-soft); }
.plans-detail-run-pill.status-cancelled { color: var(--text-faint); }
.plans-detail-diagram {
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 16px;
  overflow-x: auto;
  display: flex; justify-content: center;
}
.plans-detail-diagram .plan-svg { display: block; }
.plans-detail-ambig {
  margin-top: 14px;
  padding: 12px 14px;
  background: var(--state-soft);
  border: 1px solid rgba(255,140,66,0.32);
  border-radius: 7px;
  font-size: 11px;
}
.plans-detail-ambig ul { margin: 4px 0 0; padding-left: 18px; }
.plans-detail-ambig li { margin: 3px 0; color: var(--text); }
.plans-detail-ambig em { color: var(--text-dim); font-style: normal; }
.plans-detail-section-title {
  font-family: 'Syne', sans-serif;
  font-size: 10px; letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--state);
}
.plans-detail-md {
  margin-top: 14px;
  font-size: 11px; line-height: 1.55;
  color: var(--text-dim);
  white-space: pre-wrap;
}

/* ── /plan result rendered inside a chat bubble ─────────────────────── */
.cm-plan {
  border: 1px solid var(--border-hi);
  border-radius: 8px;
  background: var(--panel-2);
  padding: 12px 14px;
  display: flex; flex-direction: column; gap: 10px;
}
.cm-plan-head {
  display: flex; align-items: center; gap: 8px;
}
.cm-plan-title {
  font-family: 'Syne', sans-serif;
  font-weight: 700; font-size: 13px;
  color: var(--text);
}
.cm-plan-meta {
  margin-left: auto;
  font-size: 10px; color: var(--text-faint);
}
.cm-plan-diagram {
  overflow-x: auto;
  padding: 6px;
  background: var(--panel-3);
  border-radius: 6px;
  display: flex; justify-content: center;
}
.cm-plan-diagram .plan-svg { display: block; }
.cm-plan-ambig {
  background: var(--state-soft);
  border: 1px solid rgba(255,140,66,0.30);
  border-radius: 6px;
  padding: 8px 10px;
  font-size: 11px;
}
.cm-plan-ambig-title {
  font-family: 'Syne', sans-serif;
  font-size: 9px; letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--state);
  margin-bottom: 4px;
}
.cm-plan-ambig-list { margin: 0; padding-left: 18px; }
.cm-plan-ambig-list li { margin: 3px 0; color: var(--text); }
.amb-q { font-weight: 600; color: var(--text); }

/* Interactive answer form ------------------------------------------------- */
.amb-items { display: flex; flex-direction: column; gap: 10px; margin-top: 2px; }
.amb-item  { display: flex; flex-direction: column; gap: 5px; }
.amb-opts  { display: flex; gap: 5px; flex-wrap: wrap; }
.amb-opt {
  background: var(--panel-3);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 2px 8px;
  font-size: 10px;
  color: var(--text-dim);
}
/* Clickable chips in the answer form (vs. the static read-only chips
   that still appear in the Plans-tab summary). */
.amb-opt.selectable {
  cursor: pointer;
  font-family: inherit;
  transition: all 0.12s;
}
.amb-opt.selectable:hover {
  border-color: var(--state);
  color: var(--text);
}
.amb-opt.selectable.selected {
  background: var(--state);
  border-color: var(--state);
  color: #06121e;
  font-weight: 600;
}
.amb-text {
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 4px 8px;
  font-family: inherit;
  font-size: 11px;
  color: var(--text);
  width: 100%;
  box-sizing: border-box;
}
.amb-text:focus { outline: none; border-color: var(--state); }
.cm-plan-moreinfo {
  margin-top: 10px;
  width: 100%;
  box-sizing: border-box;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 5px 8px;
  font-family: inherit;
  font-size: 11px;
  color: var(--text);
  resize: vertical;
}
.cm-plan-moreinfo:focus { outline: none; border-color: var(--state); }
.cm-plan-resolve {
  margin-top: 8px;
  background: var(--state-soft);
  border: 1px solid var(--state);
  color: var(--state);
  border-radius: 5px;
  padding: 6px 12px;
  font-family: inherit; font-size: 10px; font-weight: 600;
  cursor: pointer; transition: all 0.12s;
}
.cm-plan-resolve:hover { background: var(--state); color: #06121e; }
.cm-plan-resolve.nudge { animation: amb-nudge 0.3s ease; }
@keyframes amb-nudge {
  0%, 100% { transform: translateX(0); }
  25%      { transform: translateX(-3px); }
  75%      { transform: translateX(3px); }
}
.cm-plan-md {
  font-size: 11px; color: var(--text-dim);
  line-height: 1.55;
}
.cm-plan-md p:first-child { margin-top: 0; }
.cm-plan-md p:last-child  { margin-bottom: 0; }
.cm-plan-actions {
  display: flex; justify-content: flex-end;
}
.cm-plan-open {
  background: var(--flow-soft);
  border: 1px solid rgba(61,154,255,0.35);
  color: var(--flow);
  border-radius: 5px;
  padding: 5px 10px;
  font-family: inherit; font-size: 10px;
  cursor: pointer; transition: all 0.12s;
}
.cm-plan-open:hover { background: var(--flow); color: #06121e; border-color: var(--flow); }
.cm-plan-run {
  background: var(--class-soft);
  border: 1px solid var(--class);
  color: var(--class);
  border-radius: 5px;
  padding: 5px 12px;
  font-family: inherit; font-size: 10px; font-weight: 600;
  cursor: pointer; transition: all 0.12s;
  margin-right: 6px;
}
.cm-plan-run:hover { background: var(--class); color: #06121e; }

/* ── Inline picker bubble (used by /agent no-args + /planexisting) ──── */
.cm-picker {
  background: var(--panel-2);
  border: 1px solid var(--border-hi);
  border-radius: 8px;
  padding: 10px 12px 12px;
  display: flex; flex-direction: column; gap: 8px;
}
.cm-picker-head {
  font-family: 'Syne', sans-serif;
  font-size: 11px; letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--text-faint);
}
.cm-picker-list {
  display: flex; flex-direction: column; gap: 4px;
}
.pkr-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px;
  background: var(--panel-3);
  border: 1px solid var(--border);
  border-left: 2px solid var(--border-hi);
  border-radius: 6px;
  padding: 8px 12px;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: all 0.12s;
}
.pkr-row:hover:not(:disabled) {
  background: var(--panel-2);
  border-color: var(--border-hi);
  border-left-color: var(--flow);
}
.pkr-row.selected {
  border-color: var(--flow);
  border-left-color: var(--flow);
  background: var(--flow-soft);
}
.pkr-row:disabled { opacity: 0.55; cursor: default; }
.pkr-row-main {
  display: flex; flex-direction: column; gap: 2px; min-width: 0;
}
.pkr-row-title {
  font-weight: 600; font-size: 12px;
  color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pkr-row-meta {
  font-size: 10px;
  color: var(--text-faint);
}
.pkr-pill {
  font-size: 9px;
  text-transform: uppercase; letter-spacing: 0.3px;
  padding: 1px 7px;
  border-radius: 9px;
  border: 1px solid var(--border);
  background: var(--panel-2);
  color: var(--text-faint);
}
.pkr-pill.open {
  color: var(--state);
  border-color: rgba(255,140,66,0.4);
  background: var(--state-soft);
}
.pkr-row.pkr-create {
  border-left-color: var(--class);
  background: var(--class-soft);
}
.pkr-row.pkr-create:hover:not(:disabled) {
  border-left-color: var(--class);
  background: rgba(0,229,176,0.12);
}
.pkr-row.pkr-create .pkr-row-title { color: var(--class); }
.pkr-empty {
  font-size: 11px;
  color: var(--text-faint);
  padding: 8px 12px;
  border: 1px dashed var(--border);
  border-radius: 6px;
  text-align: center;
}

/* ── /agent live run bubble ─────────────────────────────────────────── */
/* No box — the coloured vertical line lives on the parent .cm-content
   (see .cm-content:has(.cm-agent)). The agent block is just indented text. */
.cm-agent {
  display: flex; flex-direction: column; gap: 8px;
}
.cm-agent-head {
  display: flex; align-items: center; gap: 8px;
}
.cm-agent-title {
  font-family: 'Syne', sans-serif;
  font-weight: 700; font-size: 12px;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
  flex: 1; min-width: 0;
}
.cm-agent-meta {
  font-size: 10px; color: var(--text-faint);
}
.agent-stop,
.agent-resume {
  background: var(--panel-3);
  border: 1px solid var(--border);
  color: var(--text-dim);
  border-radius: 4px;
  padding: 3px 8px;
  font-family: inherit; font-size: 10px;
  cursor: pointer; transition: all 0.12s;
}
.agent-stop:hover { color: #f85149; border-color: #f85149; background: rgba(248,81,73,0.08); }
.agent-resume:hover { color: var(--flow); border-color: var(--flow); background: var(--flow-soft); }

.cm-agent.interrupted { border-left-color: var(--state); }
.agent-final.interrupted { color: var(--state); border-color: rgba(255,179,38,0.35); background: rgba(255,179,38,0.06); }

.cm-agent-steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex; flex-direction: column; gap: 4px;
  counter-reset: agentstep;
}
.agent-step {
  display: grid;
  grid-template-columns: 18px 1fr auto;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  background: var(--panel-3);
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 11px;
}
.agent-step.current {
  border-color: var(--flow);
  background: var(--flow-soft);
  box-shadow: inset 0 0 0 1px rgba(61,154,255,0.18);
}
.agent-step.status-done    { border-left: 2px solid #2ec27e; }
.agent-step.status-error   { border-left: 2px solid #f85149; background: rgba(248,81,73,0.06); }
.agent-step.status-running { border-left: 2px solid var(--flow); }
.agent-step.status-pending { border-left: 2px solid var(--text-faint); opacity: 0.78; }

.agent-step-glyph {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px;
  font-size: 12px;
  color: var(--text-dim);
}
.agent-step.status-done    .agent-step-glyph { color: #2ec27e; }
.agent-step.status-error   .agent-step-glyph { color: #f85149; }
.agent-step.status-running .agent-step-glyph { color: var(--flow); }
.agent-step-label {
  color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  min-width: 0;
}
.agent-step.status-pending .agent-step-label { color: var(--text-dim); }
.agent-step-tag {
  font-size: 9px;
  text-transform: uppercase; letter-spacing: 0.35px;
  color: var(--text-faint);
  padding: 1px 6px;
  border: 1px solid var(--border);
  border-radius: 9px;
  background: var(--panel-2);
}
.agent-step.status-done    .agent-step-tag { color: #2ec27e; border-color: rgba(46,194,126,0.4);  background: rgba(46,194,126,0.08); }
.agent-step.status-error   .agent-step-tag { color: #f85149; border-color: rgba(248,81,73,0.4);  background: rgba(248,81,73,0.08); }
.agent-step.status-running .agent-step-tag { color: var(--flow); border-color: rgba(61,154,255,0.45); background: var(--flow-soft); }
.agent-step-summary,
.agent-step-err {
  grid-column: 1 / -1;
  font-size: 10px;
  color: var(--text-faint);
  padding-left: 26px;
  margin-top: 2px;
}
.agent-step-err { color: #f85149; }
.agent-step-obs {
  grid-column: 1 / -1;
  font-size: 10px;
  color: var(--text-faint);
  padding-left: 26px;
  margin-top: 2px;
  font-variant-numeric: tabular-nums;
}
.agent-step-obs.verdict-done    { color: #2ec27e; }
.agent-step-obs.verdict-served  { color: #2ec27e; }
.agent-step-obs.verdict-crashed { color: #f85149; }
.agent-step-obs.verdict-stuck   { color: var(--state); }
.agent-step-obs.verdict-timeout { color: var(--state); }
.agent-step-obs.verdict-cancelled { color: var(--text-faint); }

.agent-step-env {
  grid-column: 1 / -1;
  font-size: 10px;
  color: var(--state);
  padding-left: 26px;
  margin-top: 2px;
  font-variant-numeric: tabular-nums;
  word-break: break-all;
}

.agent-final {
  padding: 8px 10px;
  background: var(--panel-3);
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 11px;
  color: var(--text);
}

/* ── Canvas ───────────────────────────────────────────────── */
.canvas-wrap {
  position: absolute; inset: 0;
  overflow: hidden; cursor: grab;
  background:
    radial-gradient(ellipse 80% 60% at 20% 20%, rgba(61,154,255,0.04) 0%, transparent 60%),
    radial-gradient(ellipse 60% 80% at 80% 80%, rgba(0,229,176,0.03) 0%, transparent 60%),
    var(--bg);
  transition: opacity 150ms ease;
}
.canvas-wrap.panning { cursor: grabbing; }

.canvas {
  position: absolute; top: 0; left: 0;
  width: 100%; height: 100%;
  transform-origin: 0 0;
}

.grid {
  position: absolute; inset: -6000px;
  background-image:
    linear-gradient(rgba(255,255,255,0.018) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,0.018) 1px, transparent 1px);
  background-size: 40px 40px;
  pointer-events: none;
}

/* ── SVG edges ────────────────────────────────────────────── */
svg.edges {
  position: absolute; top: -6000px; left: -6000px;
  width: 12000px; height: 12000px;
  overflow: visible; pointer-events: none;
}
svg.edges path {
  fill: none; stroke-width: 1.5;
  pointer-events: stroke; cursor: pointer;
  transition: opacity 0.2s, stroke-width 0.2s;
}
svg.edges path.dim { opacity: 0.06; }
svg.edges path.hi  { stroke-width: 2.5; filter: drop-shadow(0 0 5px currentColor); }

/* Cross-file import edges — drawn between file-boxes, not nodes.
   Heavier stroke + dashed pattern (set inline as stroke-dasharray on
   the element) reads as a different layer from the call/mut edges.
   The dim state for these is computed at the file-box level by
   refreshDimState — see render.js. */
svg.edges path.cross-file {
  stroke-width: 2;
  opacity: 0.65;
}
svg.edges path.cross-file:hover {
  opacity: 1;
  filter: drop-shadow(0 0 6px var(--import));
}
svg.edges path.cross-file.dim { opacity: 0.08; }

/* ── FILE canvas ─────────────────────────────────────────── */
/*
 * The file group box. Drawn behind class canvases (which are behind
 * nodes) by virtue of DOM order — render.js inserts file-canvas at
 * canvas.firstChild and class-canvas after.
 *
 * Visual contract: lighter than the class-canvas, dashed border in
 * --file (muted slate-blue), almost-transparent fill. The dashed
 * pattern is wider than class-canvas's so the two levels of nesting
 * read as different visual scales.
 */
.file-canvas {
  position: absolute;
  border: 1px dashed var(--file);
  border-radius: 18px;
  background: var(--file-soft);
  min-width: 320px; min-height: 140px;
  pointer-events: none;
  transition: opacity 0.2s, box-shadow 0.2s;
  /* Subtle inset shadow gives a recessed feel — pushes the file box
     visually behind the class boxes that sit inside it */
  box-shadow:
    0 0 30px rgba(122,152,196,0.04) inset,
    0 1px 0 rgba(255,255,255,0.02);
}
.file-canvas.dim { opacity: 0.2; }

/* Entry file — slightly stronger border + a faint outer glow.
   The architecture doc calls for a "subtle glow or badge"; we do both:
   the .entry-tag inside .file-label gives a discrete badge, and the
   box itself gets a barely-perceptible halo. */
.file-canvas.entry {
  border-color: var(--match-strong);
  border-width: 1.5px;
  box-shadow:
    0 0 30px rgba(0,229,176,0.06) inset,
    0 0 24px rgba(0,229,176,0.08),
    0 1px 0 rgba(255,255,255,0.02);
}

.file-label {
  position: absolute;
  top: -12px; left: 20px;
  background: var(--bg);
  padding: 2px 8px 2px 6px;
  font-family: 'JetBrains Mono', monospace;
  font-weight: 600; font-size: 10px;
  color: var(--file);
  letter-spacing: 0.1px;
  border: 1px solid var(--file);
  border-radius: 4px;
  pointer-events: auto;
  cursor: grab;
  user-select: none;
  display: flex; align-items: center; gap: 5px;
  -webkit-font-smoothing: antialiased;
  transition: background 0.12s, border-color 0.12s;
}
.file-label:hover { background: var(--panel-2); }
.file-canvas.dragging-file .file-label { cursor: grabbing; }

/* Collapse/expand button inside the file label */
.file-collapse-btn {
  background: none; border: none;
  color: inherit; font-size: 9px;
  padding: 0; margin: 0;
  cursor: pointer; line-height: 1;
  opacity: 0.65; flex-shrink: 0;
  transition: opacity 0.15s, transform 0.15s;
  pointer-events: auto;
}
.file-collapse-btn:hover { opacity: 1; }

/* Block-count badge — only shown when the band is collapsed */
.file-count-badge {
  display: none;
  font-size: 9px; padding: 1px 5px;
  background: rgba(122,152,196,0.12);
  border: 1px solid rgba(122,152,196,0.2);
  border-radius: 3px;
  color: var(--file); opacity: 0.85;
  margin-left: 1px;
}
.file-canvas.collapsed .file-count-badge { display: inline-block; }
.file-canvas.entry .file-count-badge {
  color: var(--match-strong);
  border-color: rgba(0,229,176,0.2);
  background: rgba(0,229,176,0.08);
}

/* Collapsed band — shrinks to a compact card showing name + AI overview */
.file-canvas.collapsed {
  min-height: 0 !important;
  height: auto !important;
  width: 240px !important;
  overflow: hidden;
  border-style: solid !important;   /* replace dashed with solid */
  border-radius: 8px;
  opacity: 0.95;
  transition: width 0.25s ease, opacity 0.2s;
  padding: 0;
}

/* Label flows inside the box when collapsed (overrides abs -12px position) */
.file-canvas.collapsed .file-label {
  position: relative !important;
  top: 0 !important; left: 0 !important;
  width: 100%;
  border-radius: 6px 6px 0 0;
  border-left: none; border-right: none; border-top: none;
  border-bottom: 1px solid var(--border);
  margin: 0;
  padding: 5px 10px;
  background: var(--panel-2);
}

/* Overview button on the label */
.file-overview-btn {
  background: none; border: none;
  color: inherit; font-size: 9px;
  padding: 0 1px; margin-left: 2px;
  cursor: pointer; opacity: 0.45;
  transition: opacity 0.15s;
  pointer-events: auto; flex-shrink: 0;
  line-height: 1;
}
.file-overview-btn:hover { opacity: 1; }

/* Overview text — sits just inside the top of the file-canvas */
.file-overview-text {
  position: absolute;
  top: 8px; left: 20px; right: 16px;
  font-size: 9px; line-height: 1.5;
  color: var(--file); opacity: 0.65;
  font-style: italic;
  pointer-events: none;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: opacity 0.2s;
}
.file-canvas.entry .file-overview-text { color: var(--match-strong); opacity: 0.7; }
/* When collapsed, overview text flows below the label */
.file-canvas.collapsed .file-overview-text {
  position: relative !important;
  top: 0 !important; left: 0 !important; right: 0 !important;
  display: block;
  padding: 6px 10px 8px;
  white-space: normal;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  font-size: 9px;
  line-height: 1.45;
  opacity: 0.85;
}
.file-canvas.entry .file-label {
  border-color: var(--match-strong);
  color: var(--match-strong);
}
.file-label .file-icon {
  font-size: 9px;
  opacity: 0.7;
}
.file-label .file-path {
  /* Tabular feel for paths — they're not natural prose */
  font-variant-ligatures: none;
}
.file-label .entry-tag {
  font-family: 'Syne', sans-serif;
  font-weight: 700; font-size: 8px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  padding: 1px 5px;
  background: rgba(0,229,176,0.12);
  border: 1px solid var(--match-strong);
  border-radius: 3px;
  color: var(--match-strong);
  margin-left: 2px;
}

/* ── CLASS canvas ─────────────────────────────────────────── */
.class-canvas {
  position: absolute;
  border: 1.5px dashed var(--class);
  border-radius: 14px;
  background: rgba(0,229,176,0.025);
  box-shadow: 0 0 40px rgba(0,229,176,0.05) inset;
  min-width: 280px; min-height: 120px;
  pointer-events: none;
  transition: opacity 0.2s;
}
.class-canvas.dim { opacity: 0.15; }

.class-label {
  position: absolute;
  top: -14px; left: 16px;
  background: var(--bg);
  padding: 2px 10px;
  font-family: 'Syne', sans-serif;
  font-weight: 700; font-size: 11px;
  color: var(--class);
  letter-spacing: 0.3px;
  border: 1px solid var(--class);
  border-radius: 4px;
  pointer-events: none;
  display: flex; align-items: center; gap: 6px;
}
.class-label .bases-tag {
  font-family: 'JetBrains Mono', monospace;
  font-weight: 400; font-size: 9px;
  color: var(--text-faint); letter-spacing: 0;
}

.class-instance-bar {
  position: absolute;
  bottom: 8px; left: 12px; right: 12px;
  display: flex; flex-wrap: wrap; gap: 4px;
  pointer-events: none;
}
.instance-chip {
  font-size: 9px; padding: 2px 6px;
  background: rgba(0,229,176,0.08);
  border: 1px solid rgba(0,229,176,0.2);
  border-radius: 3px; color: var(--class);
  font-family: 'JetBrains Mono', monospace;
}

/* ── Nodes ────────────────────────────────────────────────── */
.node {
  position: absolute;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 8px;
  min-width: 180px; max-width: 300px;
  cursor: grab; user-select: none;
  transition: border-color 0.2s, box-shadow 0.2s, opacity 0.2s;
  box-shadow: 0 2px 12px rgba(0,0,0,0.35);
}
.node.dragging { cursor: grabbing; z-index: 60; box-shadow: 0 8px 32px rgba(0,0,0,0.6); }
.node.dim       { opacity: 0.12; }
.node.hi        { box-shadow: 0 4px 24px rgba(0,0,0,0.5), 0 0 0 1.5px var(--accent); }

.node.state   { border-left: 3px solid var(--state);    --accent: var(--state); }
.node.config  { border-left: 3px solid var(--config);   --accent: var(--config); }
.node.flow    { border-left: 3px solid var(--flow);     --accent: var(--flow); min-width: 220px; }
.node.method  { border-left: 3px solid var(--class);    --accent: var(--class); min-width: 220px; }
.node.verbatim{ border-left: 3px solid var(--verbatim); --accent: var(--verbatim); min-width: 200px; }
.node.view    { border-left: 3px solid var(--view);     --accent: var(--view);     min-width: 220px; background: var(--view-soft); }
.node.import  { border-left: 3px solid var(--import);   --accent: var(--import); }

.node-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px 10px 7px;
  border-bottom: 1px solid var(--border);
  gap: 8px;
}
.node-head .left { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.node-head .id {
  font-weight: 600; font-size: 12px; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.node-head .class-owner {
  font-size: 9px; color: var(--class); opacity: 0.8;
}
.badge {
  font-size: 9px; font-weight: 600; letter-spacing: 0.4px;
  padding: 2px 6px; border-radius: 3px;
  text-transform: uppercase; flex-shrink: 0;
}
.node.state   .badge { background: var(--state-soft);    color: var(--state);    }
.node.config  .badge { background: var(--config-soft);   color: var(--config);   }
.node.flow    .badge { background: var(--flow-soft);     color: var(--flow);     }
.node.method  .badge { background: var(--class-soft);    color: var(--class);    }
.node.verbatim .badge{ background: var(--verbatim-soft); color: #8a9ab8;         }
.node.import  .badge { background: var(--import-soft);   color: var(--import);   }

.node-body { padding: 8px 10px; }
.node-body .val {
  font-size: 11px; color: var(--text-dim);
  word-break: break-word;
}

/* IMPORT block — source tag (small reference to the source file when
   the import resolves to another project file). Mirrors the
   import-coloured palette so the eye groups them. */
.node-body .import-source {
  font-size: 9px;
  color: var(--import);
  opacity: 0.75;
  margin-top: 4px;
  padding-top: 4px;
  border-top: 1px dashed rgba(255,209,102,0.15);
  font-family: 'JetBrains Mono', monospace;
  word-break: break-all;
}

.node-body .editable-val {
  cursor: pointer;
  border-radius: 3px;
  padding: 2px 4px;
  margin: -2px -4px;
  transition: all 0.15s;
}
.node-body .editable-val:hover {
  background: rgba(255,255,255,0.05);
  outline: 1px dashed var(--border-hi);
}
.node-body .editable-val.saving {
  color: var(--text-faint);
  font-style: italic;
}
.node-body .editable-val.flash-success {
  color: var(--match-strong);
  text-shadow: 0 0 6px rgba(0,229,176,0.3);
}
.inline-val-input {
  width: 100%;
  background: var(--bg);
  border: 1px solid var(--flow);
  color: var(--text);
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  padding: 2px 4px;
  border-radius: 3px;
  outline: none;
}
.inline-val-input.invalid {
  border-color: #f85149;
  color: #f85149;
  background: rgba(248,81,73,0.06);
}
.inline-val-input.shake {
  animation: val-shake 0.3s ease;
}
@keyframes val-shake {
  0%, 100% { transform: translateX(0); }
  25%      { transform: translateX(-4px); }
  75%      { transform: translateX(4px); }
}

.node-body .sig-chips {
  display: flex; flex-wrap: wrap; gap: 3px; margin-bottom: 6px;
}
.sig-chip {
  font-size: 9px; padding: 2px 5px; border-radius: 3px;
  display: inline-flex; align-items: center; gap: 3px;
}
.sig-chip.in   { background: rgba(61,154,255,0.10); color: var(--edge-in);  border: 1px solid rgba(61,154,255,0.2); }
.sig-chip.mut  { background: rgba(255,140,66,0.10); color: var(--edge-mut); border: 1px solid rgba(255,140,66,0.2); }
.sig-chip.self { background: rgba(0,229,176,0.08);  color: var(--class);    border: 1px solid rgba(0,229,176,0.2); }
.sig-chip.glob { background: rgba(185,127,255,0.08); color: var(--config);  border: 1px solid rgba(185,127,255,0.2); }
.sig-chip.ret  { background: rgba(61,154,255,0.06); color: var(--flow);     border: 1px solid rgba(61,154,255,0.15); }
.sig-chip.async-chip { background: rgba(255,209,102,0.08); color: var(--import); border: 1px solid rgba(255,209,102,0.2); }
.sig-chip.dec  { background: rgba(255,140,66,0.06); color: #ff8c42aa;       border: 1px solid rgba(255,140,66,0.15); }

.intent-text {
  font-size: 10px; line-height: 1.55;
  color: var(--text-dim);
  margin-top: 6px; padding-top: 6px;
  border-top: 1px dashed var(--border);
  max-height: 52px; overflow: hidden;
  position: relative;
}
.intent-text::after {
  content: ''; position: absolute; bottom: 0; left: 0; right: 0; height: 16px;
  background: linear-gradient(transparent, var(--panel));
  pointer-events: none;
}
.node.expanded .intent-text { max-height: none; }
.node.expanded .intent-text::after { display: none; }

.verbatim-lines {
  font-size: 10px; line-height: 1.6;
  color: var(--text-faint);
  max-height: 72px; overflow: hidden;
  white-space: pre;
  padding: 4px 0;
}
.node.expanded .verbatim-lines { max-height: none; }

/* ── Match states (autocomplete) ──────────────────────────── */
.node.match-strong {
  box-shadow: 0 4px 24px rgba(0,0,0,0.5), 0 0 0 2px var(--match-strong);
}
.node.match-weak {
  box-shadow: 0 4px 16px rgba(0,0,0,0.4), 0 0 0 1.5px var(--match-weak);
}
.node.match-traced {
  border-left-style: dotted;
  border-left-width: 4px;
}

.match-score {
  position: absolute;
  top: 6px; right: 6px;
  font-size: 9px; font-weight: 700;
  padding: 2px 5px; border-radius: 3px;
  font-family: 'JetBrains Mono', monospace;
  letter-spacing: 0.3px;
  pointer-events: none;
  background: var(--bg);
}
.node.match-strong .match-score {
  color: var(--match-strong);
  border: 1px solid var(--match-strong);
}
.node.match-weak .match-score {
  color: var(--match-weak);
  border: 1px solid var(--match-weak);
  font-size: 8px;
  padding: 1px 4px;
}

/* ── Detail panel ─────────────────────────────────────────── */
.detail {
  position: fixed; top: 64px; right: 16px;
  width: 340px; max-height: calc(100vh - 160px);
  background: rgba(14,20,32,0.97);
  backdrop-filter: blur(20px);
  border: 1px solid var(--border);
  border-radius: 10px; padding: 16px;
  overflow-y: auto; z-index: 150;
  display: none;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}
.detail.open { display: block; }
.detail h3 {
  margin: 0 0 2px; font-size: 14px; font-weight: 600;
  color: var(--text);
}
.detail .type-tag {
  font-size: 9px; font-weight: 600; letter-spacing: 0.5px;
  text-transform: uppercase; margin-bottom: 14px;
  padding: 3px 7px; border-radius: 3px; display: inline-block;
}
.detail .close {
  position: absolute; top: 12px; right: 12px;
  background: none; border: none; color: var(--text-dim);
  font-size: 16px; cursor: pointer; padding: 4px 8px;
  border-radius: 4px; font-family: 'JetBrains Mono', monospace;
}
.detail .close:hover { background: var(--panel-2); color: var(--text); }
.detail .section { margin-bottom: 14px; }
.detail .section h4 {
  margin: 0 0 6px; font-size: 9px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.5px; color: var(--text-faint);
  font-family: 'Syne', sans-serif;
}
.detail .content {
  background: var(--bg); border: 1px solid var(--border);
  border-radius: 6px; padding: 8px 10px;
  font-size: 11px; line-height: 1.6;
  white-space: pre-wrap; word-break: break-word;
  color: var(--text-dim);
}
.detail .pill {
  display: inline-block;
  background: var(--panel-2); border: 1px solid var(--border);
  padding: 2px 8px; border-radius: 4px;
  font-size: 10px; margin: 0 3px 3px 0;
  cursor: pointer; transition: all 0.12s;
}
.detail .pill:hover { border-color: var(--flow); color: var(--flow); }
.detail .flag {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 10px; padding: 3px 8px; border-radius: 4px;
  margin: 0 3px 3px 0;
}

/* ── Minimap ──────────────────────────────────────────────── */
.minimap {
  position: fixed; bottom: 100px; right: 16px;
  width: 180px; height: 120px;
  background: rgba(8,11,16,0.92);
  border: 1px solid var(--border); border-radius: 7px;
  overflow: hidden; z-index: 100;
}
.minimap svg { display: block; }
.minimap .viewport { fill: rgba(61,154,255,0.12); stroke: var(--flow); stroke-width: 1; }

/* ── Legend ───────────────────────────────────────────────── */
.legend {
  position: fixed; bottom: 100px; left: calc(50% + 16px);
  background: rgba(14,20,32,0.92);
  border: 1px solid var(--border); border-radius: 8px;
  padding: 10px 12px;
  display: flex; flex-direction: column; gap: 5px;
  font-size: 10px; color: var(--text-dim); z-index: 100;
}
.legend .row { display: flex; align-items: center; gap: 7px; }
.legend .swatch { width: 8px; height: 8px; border-radius: 2px; flex-shrink: 0; }
.legend .line   { width: 16px; height: 2px; border-radius: 1px; flex-shrink: 0; }
.legend .sep    { border-top: 1px solid var(--border); margin: 3px 0; }
.legend .dashed { width: 16px; height: 0; border-top: 2px dashed var(--class); flex-shrink: 0; }
/* Legend swatch for the file-box border, if you wire one up in the HTML */
.legend .dashed-file { width: 16px; height: 0; border-top: 1px dashed var(--file); flex-shrink: 0; }

/* ── Chat dock (fixed bottom; history grows upward) ──────────── */
.chat-dock {
  position: fixed; left: 0; right: 0; bottom: 0;
  z-index: 180;
  display: flex; flex-direction: column;
  pointer-events: none;             /* let clicks fall through empty space */
}
.chat-dock > * { pointer-events: auto; }

/* ── Prompt bar (input row — anchored at the bottom of the dock) ─ */
.prompt-bar {
  position: relative;
  min-height: 84px;
  background: rgba(8,11,16,0.94);
  backdrop-filter: blur(16px);
  border-top: 1px solid var(--border);
  display: flex; align-items: center;
}
.prompt-bar-inner {
  width: 100%;
  /* Full-width so the prompt feels like a terminal line spanning the
     editor pane. The previous max-width: 1200px + margin: auto
     centred a narrow column; that read as "chat box" rather than
     "shell". Side padding stays tight to lean into the terminal feel. */
  margin: 0;
  padding: 12px 20px;
  display: flex; align-items: flex-end;
  gap: 12px;
}
.prompt-status {
  display: flex; align-items: center; gap: 6px;
  font-size: 10px; color: var(--text-faint);
  text-transform: uppercase; letter-spacing: 0.4px;
  min-width: 84px;
  align-self: center; flex-shrink: 0;
  font-family: 'Syne', sans-serif; font-weight: 600;
}
.prompt-status-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--text-faint);
  transition: background 0.2s;
}
.prompt-bar.idle      .prompt-status-dot { background: var(--text-faint); }
.prompt-bar.typing    .prompt-status-dot { background: var(--flow); }
.prompt-bar.awaiting  .prompt-status-dot { background: var(--state); animation: pulse 1s infinite; }
.prompt-bar.asking    .prompt-status-dot { background: var(--match-strong); animation: pulse 0.8s infinite; }
.prompt-bar.done      .prompt-status-dot { background: var(--match-strong); }
.prompt-bar.error     .prompt-status-dot { background: #f85149; }
@keyframes pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.3; }
}

.prompt-input-wrap {
  flex: 1;
  display: flex;
  position: relative;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  transition: border-color 0.15s, background 0.15s;
}
.prompt-input-wrap:focus-within {
  border-color: var(--flow);
  background: var(--panel-3);
}

/* Highlight overlay behind the (transparent-text) textarea — renders
   /mentions as the same coloured chips used in chat answers. */
.prompt-input-hl {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  padding: 11px 14px;
  border: 1px solid transparent;
  border-radius: 8px;
  pointer-events: none;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  line-height: 1.55;
  color: var(--text);
  white-space: pre-wrap;
  word-break: break-word;
}
.prompt-input-hl-inner { will-change: transform; }
.mention-chip {
  color: var(--match-strong);
  background: rgba(0,229,176,0.08);
  box-shadow: inset 0 0 0 1px rgba(0,229,176,0.3);
  border-radius: 3px;
  padding: 1px 5px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
}
/* In the input overlay the chip must add zero layout advance (and match
   the 12px textarea metrics) so the caret stays glued to the text. */
.prompt-input-hl .mention-chip {
  font-size: 12px;
  padding: 0 5px;
  margin: 0 -5px;
}
.cm-bubble .mention-chip { cursor: pointer; transition: all 0.12s; }
.cm-bubble .mention-chip:hover {
  background: rgba(0,229,176,0.15);
  box-shadow: inset 0 0 0 1px var(--match-strong);
}

/* ── Slash block-mention menu ─────────────────────────────────────── */
.slash-menu {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 0;
  min-width: 280px;
  max-width: 460px;
  max-height: 248px;
  overflow-y: auto;
  background: var(--panel-2);
  border: 1px solid var(--border-hi);
  border-radius: 8px;
  box-shadow: 0 12px 40px rgba(0,0,0,0.55);
  padding: 4px;
  z-index: 300;
  scrollbar-color: var(--border) transparent;
}
.slash-menu[hidden] { display: none; }

/* ── Composer image attachments (paste / /image / /live) ─────────────── */
.prompt-attachments {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 6px 2px 4px;
}
.prompt-attachments[hidden] { display: none; }
.attach-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: 220px;
  padding: 3px 6px 3px 3px;
  background: var(--panel-2);
  border: 1px solid var(--border-hi);
  border-radius: 7px;
  font-size: 11px;
  color: var(--text-dim);
}
.attach-thumb {
  width: 28px; height: 28px;
  object-fit: cover;
  border-radius: 4px;
  flex: 0 0 auto;
}
.attach-label {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.attach-rm {
  flex: 0 0 auto;
  border: none; background: transparent; cursor: pointer;
  color: var(--text-faint); font-size: 12px; line-height: 1;
  padding: 2px;
}
.attach-rm:hover { color: var(--danger, #f85149); }

/* Thumbnails shown inside a sent user bubble. */
.cm-images {
  display: flex; flex-wrap: wrap; gap: 6px;
  margin: 4px 0 6px;
}
.cm-img {
  max-width: 240px; max-height: 180px;
  border-radius: 6px;
  border: 1px solid var(--border);
}
.slash-menu-hint {
  font-size: 10px; color: var(--text-faint);
  padding: 5px 8px 6px; letter-spacing: 0.02em;
}
.slash-item {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 8px; border-radius: 5px;
  cursor: pointer; user-select: none;
}
.slash-item.active { background: var(--panel-3); }
.slash-item-dot {
  width: 7px; height: 7px; border-radius: 50%;
  flex-shrink: 0; background: var(--dot, var(--text-dim));
}
.slash-item-id {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 12px; color: var(--text); white-space: nowrap;
}
.slash-item-id b { color: var(--flow); font-weight: 600; }
.slash-item-type {
  font-size: 9px; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--text-faint); margin-left: auto; flex-shrink: 0;
}
.slash-item-hint {
  font-size: 11px; color: var(--text-dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  flex: 1; min-width: 0;
}
.prompt-input {
  flex: 1;
  width: 100%;
  background: transparent;
  border: 1px solid transparent;
  color: transparent;                 /* text is drawn by .prompt-input-hl */
  caret-color: var(--text);
  padding: 11px 14px;
  border-radius: 8px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  line-height: 1.55;
  outline: none;
  resize: none;
  min-height: 42px;
  max-height: 168px;
  overflow-y: hidden;
  position: relative;
  z-index: 1;
  scrollbar-width: none;
}
.prompt-input::-webkit-scrollbar { display: none; }
.prompt-input::selection  { background: var(--border-hi); }
.prompt-input::placeholder { color: var(--text-faint); }

/* ── Send / clear buttons ─────────────────────────────────────────── */
.chat-send, .chat-clear {
  flex-shrink: 0;
  align-self: flex-end;
  background: var(--panel-2);
  border: 1px solid var(--border);
  color: var(--text-dim);
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.15s;
  font-family: 'JetBrains Mono', monospace;
  height: 42px;
}
.chat-send {
  width: 44px;
  font-size: 16px;
  color: var(--flow);
  border-color: var(--flow);
  background: var(--flow-soft);
}
.chat-send:hover { background: var(--flow); color: #06121e; }
.chat-send:disabled {
  opacity: 0.4; cursor: not-allowed;
  background: var(--panel-2); color: var(--text-faint); border-color: var(--border);
}
.chat-clear {
  width: 38px;
  font-size: 13px;
}
.chat-clear:hover { border-color: #f85149; color: #f85149; }

.prompt-expand {
  background: var(--panel-2); border: 1px solid var(--border);
  color: var(--text-dim);
  padding: 8px 14px;
  border-radius: 6px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  cursor: pointer;
  transition: all 0.15s;
  white-space: nowrap;
}
.prompt-expand:hover { border-color: var(--border-hi); color: var(--text); }
.prompt-expand.active {
  background: var(--flow-soft);
  border-color: var(--flow);
  color: var(--flow);
}

/* ── Chat history (grows upward above the input) ──────────────── */
.chat-history {
  max-height: 0;
  overflow: hidden;
  background: rgba(14,20,32,0.97);
  backdrop-filter: blur(20px);
  border-top: 1px solid transparent;
  opacity: 0;
  transition: max-height 0.28s ease, opacity 0.2s ease;
  display: flex;
  flex-direction: column;
}
.chat-history.has-history {
  max-height: 58vh;
  overflow-y: auto;
  opacity: 1;
  border-top-color: var(--border);
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}
/* Minimized — collapse the transcript but keep the bar + input */
body.chat-minimized .chat-history.has-history {
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  border-top-color: transparent;
}

/* ── Chat bar (count · token meter · minimize) ────────────────── */
/* Always visible — it carries the ⚙ settings and ⊞ projects icons (moved
   here from the old bottom-left dock), so it must be reachable even on a
   fresh page load with no chat transcript yet. */
.chat-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  height: 30px;
  padding: 0 24px;
  background: rgba(8,11,16,0.94);
  backdrop-filter: blur(16px);
  border-top: 1px solid var(--border);
  font-family: 'Syne', sans-serif;
  font-size: 10px; font-weight: 600;
  letter-spacing: 0.4px;
  color: var(--text-faint);
  text-transform: uppercase;
}
.chat-bar.show { display: flex; }
.chat-bar-title { color: var(--text-dim); }
.chat-bar-count { color: var(--text-faint); text-transform: none; letter-spacing: 0.2px; }

/* Settings + projects icons embedded in the chat-bar. The old bottom-
   left dock (.bl-dock) was deleted; these are the same buttons by id
   so settings.js still wires them up without changes. Size matches the
   .chat-min toggle on the right so the bar reads as balanced. */
.chat-bar-icon {
  width: 22px; height: 22px;
  border-radius: 50%;
  background: transparent;
  border: 1px solid transparent;
  color: var(--text-dim);
  font-size: 13px; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
  padding: 0;
  text-transform: none; letter-spacing: 0;
  opacity: 0.7;
  transition: opacity 140ms ease, color 140ms ease,
              border-color 140ms ease, background 140ms ease;
}
.chat-bar-icon:hover {
  opacity: 1;
  color: var(--text);
  border-color: var(--border-hi);
  background: var(--panel-3);
}
.chat-bar-icon.active {
  opacity: 1;
  color: var(--flow);
  border-color: var(--flow);
}
.chat-bar-spacer { flex: 1; }
.chat-tokens {
  display: inline-flex; align-items: center; gap: 4px;
  color: var(--match-strong);
  background: rgba(0,229,176,0.08);
  border: 1px solid rgba(0,229,176,0.30);
  padding: 2px 8px;
  border-radius: 4px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  text-transform: none; letter-spacing: 0;
  cursor: default;
}
.chat-cost {
  display: inline-flex; align-items: center;
  color: var(--state);
  background: rgba(255,140,66,0.10);
  border: 1px solid rgba(255,140,66,0.32);
  padding: 2px 8px;
  border-radius: 4px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  text-transform: none; letter-spacing: 0;
  cursor: help;
}
.chat-min {
  background: var(--panel-2);
  border: 1px solid var(--border);
  color: var(--text-dim);
  width: 26px; height: 20px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 11px; line-height: 1;
  transition: all 0.15s;
}
.chat-min:hover { border-color: var(--border-hi); color: var(--text); }

/* ── Active terminal status pill (chat-bar) ────────────────────────── */
/* Shown only while a /terminal bubble is still running. Surfaces the
   command + a Ctrl+C button so the user doesn't need to scroll up to
   find the bubble. Hidden via [hidden] attribute when nothing is live. */
.chat-term-status {
  display: inline-flex; align-items: center; gap: 6px;
  margin-left: 4px;
  padding: 2px 4px 2px 8px;
  border-radius: 4px;
  background: rgba(46,194,126,0.10);
  border: 1px solid rgba(46,194,126,0.35);
  color: #2ec27e;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  text-transform: none; letter-spacing: 0;
  max-width: 360px;
}
.chat-term-status[hidden] { display: none; }
.chat-term-status .cts-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: #2ec27e;
  box-shadow: 0 0 8px rgba(46,194,126,0.65);
  animation: cts-pulse 1.2s ease-in-out infinite;
}
@keyframes cts-pulse {
  0%, 100% { transform: scale(1);    opacity: 1; }
  50%      { transform: scale(1.25); opacity: 0.7; }
}
.chat-term-status .cts-label {
  color: var(--text-faint);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.3px;
  font-size: 9px;
}
.chat-term-status .cts-cmd {
  color: var(--text);
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 220px;
}
.chat-term-status .cts-count {
  color: var(--text-dim);
  border-left: 1px solid rgba(46,194,126,0.25);
  padding-left: 6px;
}
.chat-term-status[hidden] .cts-count,
.chat-term-status .cts-count[hidden] { display: none; }
.chat-term-status .cts-stop {
  background: transparent;
  border: 1px solid rgba(46,194,126,0.45);
  color: #2ec27e;
  width: 18px; height: 18px;
  border-radius: 3px;
  padding: 0; line-height: 1;
  cursor: pointer;
  font-size: 11px;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.chat-term-status .cts-stop:hover {
  background: #2ec27e;
  color: #06121e;
  border-color: #2ec27e;
}

/* ── Block widgets the router chose for a prompt ──────────────── */
.cm-blocks {
  display: flex; flex-wrap: wrap; gap: 5px;
  justify-content: flex-end;
  max-width: 80%;
  margin-top: 2px;
}
.cm-widget {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  color: var(--text-dim);
  background: var(--panel-2);
  border: 1px solid var(--border);
  padding: 2px 7px;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.12s;
  max-width: 180px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cm-widget:hover { border-color: var(--border-hi); color: var(--text); }
.cm-widget-dot {
  width: 6px; height: 6px; border-radius: 2px;
  background: var(--text-faint);
  flex-shrink: 0;
}
.cm-widget.flow     .cm-widget-dot { background: var(--flow); }
.cm-widget.state    .cm-widget-dot { background: var(--state); }
.cm-widget.config   .cm-widget-dot { background: var(--config); }
.cm-widget.class    .cm-widget-dot { background: var(--class); }
.cm-widget.verbatim .cm-widget-dot { background: var(--verbatim); }
.chat-history-inner {
  /* Full-width to match the prompt-bar. Same rationale as the
     prompt-bar-inner edit: a centred 1200px column read as "chat
     widget"; spanning the editor pane reads as "terminal session". */
  width: 100%;
  margin: 0;
  padding: 16px 20px 8px;
  display: flex; flex-direction: column;
  gap: 14px;
}

/* ── Message rows ─────────────────────────────────────────────── */
.chat-msg { display: flex; gap: 12px; }

.chat-msg.user {
  flex-direction: column;
  align-items: flex-end;
  gap: 5px;
}
.chat-msg.user .cm-meta {
  display: flex; align-items: center; gap: 8px;
  flex-wrap: wrap; justify-content: flex-end;
  max-width: 80%;
}
.chat-msg.user .cm-bubble {
  max-width: 80%;
  background: var(--flow-soft);
  border: 1px solid rgba(110,168,254,0.28);
  color: var(--text);
  padding: 9px 13px;
  border-radius: 12px 12px 3px 12px;
  font-size: 12px;
  line-height: 1.6;
  white-space: pre-wrap;
  word-break: break-word;
}

.cm-chip {
  font-family: 'Syne', sans-serif;
  font-weight: 700; font-size: 9px;
  letter-spacing: 0.6px;
  padding: 3px 8px;
  border-radius: 4px;
  text-transform: uppercase;
  display: inline-flex; align-items: center; gap: 6px;
  flex-shrink: 0;
}
.cm-chip.ask {
  color: var(--flow);
  background: var(--flow-soft);
  border: 1px solid rgba(110,168,254,0.4);
}
.cm-chip.edit {
  color: var(--state);
  background: rgba(255,140,66,0.12);
  border: 1px solid rgba(255,140,66,0.45);
}
.cm-chip.planning {
  color: var(--text-faint);
  background: var(--panel-2);
  border: 1px solid var(--border);
  text-transform: none;
  letter-spacing: 0.2px;
}
.cm-summary {
  font-size: 11px;
  color: var(--text-dim);
  font-style: italic;
}

/* ── Assistant message ────────────────────────────────────────── */
/* No avatar/logo — identity is a coloured vertical line on the left of
   the content, the full height of the generated text. Each message kind
   gets its own line colour so text / agent / plan read at a glance. The
   left indent (border + padding) matches the terminal bubble so every
   message kind in the chat lines up at the same x. */
.chat-msg.assistant { align-items: flex-start; }
.cm-content {
  flex: 1; min-width: 0;
  border-left: 2px solid var(--match-strong);   /* default: assistant text */
  padding-left: 12px;
}
/* Agent tasks get their own line colour. */
.cm-content:has(.cm-agent)  { border-left-color: var(--flow); }
/* Plan and picker are self-contained cards with their own border — no
   extra accent line, and they sit flush rather than indented. */
.cm-content:has(.cm-plan),
.cm-content:has(.cm-picker) { border-left: none; padding-left: 0; }
.cm-body {
  font-size: 12px;
  line-height: 1.65;
  color: var(--text);
}
.cm-body p { margin: 0 0 10px; }
.cm-body p:last-child { margin-bottom: 0; }
.cm-body strong { color: var(--text); font-weight: 600; }
.cm-body em     { color: var(--text-dim); font-style: italic; }
.cm-body code {
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 1px 5px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  color: var(--flow);
}
.cm-body code.block-ref {
  cursor: pointer;
  transition: all 0.12s;
  color: var(--match-strong);
  border-color: rgba(0,229,176,0.3);
  background: rgba(0,229,176,0.08);
}
.cm-body code.block-ref:hover {
  background: rgba(0,229,176,0.15);
  border-color: var(--match-strong);
}
.cm-pre {
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 10px 12px;
  overflow-x: auto;
  margin: 8px 0;
  scrollbar-width: thin;
}
.cm-pre code {
  background: none; border: none; padding: 0;
  color: var(--text-dim);
  font-size: 11px; line-height: 1.55;
  white-space: pre;
}

/* ── Revert affordance ────────────────────────────────────────── */
.cm-revert {
  margin-top: 10px;
  background: rgba(255,140,66,0.10);
  border: 1px solid rgba(255,140,66,0.40);
  color: var(--state);
  padding: 6px 11px;
  border-radius: 6px;
  font-family: 'Syne', sans-serif;
  font-weight: 600; font-size: 10px;
  letter-spacing: 0.3px;
  cursor: pointer;
  transition: all 0.15s;
}
.cm-revert:hover {
  background: rgba(255,140,66,0.20);
  border-color: var(--state);
}

/* ── Loading + error states ───────────────────────────────────── */
.cm-loading {
  display: flex; align-items: center; gap: 10px;
  color: var(--text-dim);
  font-size: 12px;
  padding: 2px 0;
}
.cm-spinner {
  width: 13px; height: 13px;
  border: 2px solid var(--border);
  border-top-color: var(--match-strong);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
  flex-shrink: 0;
}
@keyframes spin { to { transform: rotate(360deg); } }

.cm-error {
  background: rgba(248,81,73,0.08);
  border: 1px solid rgba(248,81,73,0.3);
  border-radius: 6px;
  padding: 11px 12px;
  color: #f85149;
}
.cm-error-detail {
  margin-top: 6px;
  font-size: 11px;
  color: var(--text-dim);
  font-family: 'JetBrains Mono', monospace;
  word-break: break-word;
}

/* ── Refresh-stranded turn ────────────────────────────────────── */
.cm-orphan {
  display: flex; align-items: center; gap: 10px;
  margin-top: 6px;
  padding: 8px 10px;
  background: rgba(255,140,66,0.06);
  border: 1px dashed rgba(255,140,66,0.30);
  border-radius: 6px;
  font-size: 11px;
  color: var(--text-dim);
}
.cm-orphan-label { letter-spacing: 0.2px; }
.cm-orphan-partial {
  opacity: 0.65;
  margin-bottom: 4px;
}
.cm-retry {
  background: rgba(255,140,66,0.12);
  border: 1px solid rgba(255,140,66,0.40);
  color: var(--state);
  padding: 4px 10px;
  border-radius: 6px;
  font-family: 'Syne', sans-serif;
  font-weight: 600; font-size: 10px;
  letter-spacing: 0.3px;
  cursor: pointer;
  transition: all 0.15s;
  margin-left: auto;
}
.cm-retry:hover {
  background: rgba(255,140,66,0.22);
  border-color: var(--state);
}

/* ── Reposition minimap & legend when the chat history is open ── */
.minimap, .legend { transition: bottom 0.25s ease; }
body.chat-bar-on .minimap,
body.chat-bar-on .legend {
  bottom: calc(84px + 30px + 8px);   /* clear the chat bar */
}
body.chat-open:not(.chat-minimized) .minimap,
body.chat-open:not(.chat-minimized) .legend {
  bottom: calc(84px + 30px + 58vh + 8px);
}

/* ── Trace panel (collapsible left sidebar of the viewer panel) ────── */
.trace-panel {
  position: fixed;
  top: var(--topbar-h); left: 50%;
  width: 320px;
  height: calc(100vh - var(--topbar-h) - var(--dock-h));
  background: rgba(14,20,32,0.97);
  backdrop-filter: blur(20px);
  border-right: 1px solid var(--border);
  z-index: 160;
  display: flex; flex-direction: column;
  transition: transform 0.25s ease, width 0.25s ease, opacity 0.25s ease;
}
.trace-panel.collapsed {
  transform: translateX(-320px);
  opacity: 0;
  pointer-events: none;
}

.trace-float-toggle {
  position: fixed;
  top: 56px; left: 50%;
  background: var(--panel);
  border: 1px solid var(--border);
  border-left: none;
  border-radius: 0 6px 6px 0;
  padding: 8px 10px;
  font-family: 'Syne', sans-serif;
  font-weight: 700; font-size: 9px;
  letter-spacing: 0.4px;
  color: var(--flow);
  cursor: pointer;
  z-index: 200;
  transition: opacity 0.25s, transform 0.25s;
  opacity: 0;
  pointer-events: none;
}
.trace-float-toggle.visible {
  opacity: 1;
  pointer-events: auto;
}
.trace-float-toggle:hover {
  background: var(--panel-2);
  border-color: var(--flow);
}

.trace-panel-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.trace-panel-title {
  font-family: 'Syne', sans-serif;
  font-weight: 700; font-size: 10px;
  letter-spacing: 0.6px;
  color: var(--text);
}
.trace-panel-collapse {
  background: none; border: none;
  color: var(--text-dim); font-size: 12px;
  cursor: pointer; padding: 4px 6px;
  border-radius: 3px;
}
.trace-panel-collapse:hover { background: var(--panel-2); color: var(--text); }

.trace-panel-body {
  flex: 1; overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}

.trace-section {
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
}
.trace-section-title {
  font-family: 'Syne', sans-serif;
  font-weight: 600; font-size: 9px;
  letter-spacing: 0.5px; color: var(--text-faint);
  margin-bottom: 6px; text-transform: uppercase;
}

.trace-run-row {
  display: flex; align-items: center; gap: 8px;
}
.trace-run-btn {
  background: rgba(61,154,255,0.12);
  border: 1px solid var(--flow);
  color: var(--flow);
  padding: 6px 16px; border-radius: 5px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; font-weight: 600;
  cursor: pointer; transition: all 0.15s;
}
.trace-run-btn:hover { background: rgba(61,154,255,0.2); }
.trace-run-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.trace-stop-btn {
  background: rgba(248,81,73,0.12);
  border: 1px solid #f85149; border-radius: 5px;
  color: #f85149; font-family: inherit; font-size: 10px;
  font-weight: 600; padding: 4px 10px; cursor: pointer;
  transition: background 0.15s;
}
.trace-stop-btn:hover { background: rgba(248,81,73,0.24); }
.trace-run-status {
  font-size: 10px; color: var(--text-faint);
  font-family: 'JetBrains Mono', monospace;
}
.trace-run-status.running { color: var(--state); }
.trace-run-status.done    { color: var(--match-strong); }
.trace-run-status.error   { color: #f85149; }

.trace-replay-row {
  display: flex; align-items: center; gap: 6px;
}
.trace-btn {
  background: var(--panel-2);
  border: 1px solid var(--border);
  color: var(--text-dim);
  padding: 4px 8px; border-radius: 3px;
  font-size: 11px; cursor: pointer;
  transition: all 0.12s; flex-shrink: 0;
}
.trace-btn:hover { border-color: var(--border-hi); color: var(--text); background: var(--panel-3); }

.trace-speed-row {
  display: flex; align-items: center; gap: 4px;
  margin-left: auto;
}
.trace-speed-label {
  font-size: 9px; color: var(--text-dim);
  font-family: 'JetBrains Mono', monospace;
  min-width: 28px;
}
.trace-speed {
  width: 50px; height: 3px; cursor: pointer;
}
.trace-counter {
  font-size: 9px; color: var(--text-faint);
  font-family: 'JetBrains Mono', monospace;
}

.trace-gantt-section { padding-bottom: 4px; }
.trace-gantt {
  position: relative;
  min-height: 40px;
  overflow-x: auto;
  overflow-y: visible;
}
.gantt-bar {
  position: absolute;
  border-radius: 2px;
  font-size: 8px;
  font-family: 'JetBrains Mono', monospace;
  font-weight: 500;
  color: rgba(255,255,255,0.8);
  padding: 1px 4px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: pointer;
  transition: opacity 0.12s, filter 0.12s;
  background: rgba(61,154,255,0.35);
  border: 1px solid rgba(61,154,255,0.4);
}
.gantt-bar:hover {
  filter: brightness(1.4);
  z-index: 10;
}
.gantt-bar.gantt-flow    { background: rgba(61,154,255,0.3); border-color: rgba(61,154,255,0.5); }
.gantt-bar.gantt-method  { background: rgba(0,229,176,0.3); border-color: rgba(0,229,176,0.5); color: var(--class); }
.gantt-bar.gantt-state   { background: rgba(255,140,66,0.3); border-color: rgba(255,140,66,0.5); }
.gantt-bar.gantt-verbatim{ background: rgba(74,85,104,0.3); border-color: rgba(74,85,104,0.5); }

.gantt-playhead {
  position: absolute; top: 0; bottom: 0;
  width: 2px;
  background: var(--flow);
  box-shadow: 0 0 6px var(--flow);
  z-index: 20;
  pointer-events: none;
  transition: left 0.1s linear;
}

.trace-log-section { flex: 1; display: flex; flex-direction: column; min-height: 100px; }
.trace-log {
  flex: 1; overflow-y: auto;
  font-size: 10px;
  font-family: 'JetBrains Mono', monospace;
  line-height: 1.6; color: var(--text-dim);
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}
.trace-log-item {
  padding: 2px 6px; border-radius: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  cursor: pointer; transition: all 0.12s;
}
.trace-log-item.current {
  background: rgba(61,154,255,0.15);
  color: var(--flow);
  border-left: 2px solid var(--flow);
}
.trace-log-item:hover {
  background: rgba(61,154,255,0.08);
}

@keyframes trace-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(61,154,255,0.4); }
  70%  { box-shadow: 0 0 0 10px rgba(61,154,255,0); }
  100% { box-shadow: 0 0 0 0 rgba(61,154,255,0); }
}
.node.trace-active {
  box-shadow: 0 4px 24px rgba(0,0,0,0.5), 0 0 0 2px var(--flow);
  animation: trace-pulse 0.6s ease-out;
}
.node.trace-hover {
  box-shadow: 0 4px 20px rgba(0,0,0,0.4), 0 0 0 1.5px var(--flow);
}

/* ── Terminal panel (embedded inside editor-panel) ────────────────── */
/* Nav bar is always docked at the bottom of the editor; body only
   appears when .open (added by runProcess / openTerminal). The × close
   button removes .open, collapsing back to just the nav bar. */
.terminal-panel {
  flex: 0 0 auto;
  min-height: 0;
  background: var(--panel);
  border-top: 1px solid var(--border);
  display: flex;
  flex-direction: column;
}
.terminal-panel.open { flex: 0 0 30%; }
.terminal-body { display: none; }
.terminal-panel.open .terminal-body { display: block; flex: 1; min-height: 0; }
/* xterm.js mounts inside .terminal-body. Give the inner .xterm a real
   height and let the viewport be transparent so our panel background
   (which follows the theme) shows through. */
.terminal-body .xterm          { height: 100%; padding: 6px 8px; }
.terminal-body .xterm-viewport { background: transparent !important; }

/* Run button inside the terminal nav bar */
.terminal-run {
  margin-right: 8px;
  padding: 2px 10px !important;
  font-size: 10px !important;
}
.terminal-preview {
  margin-right: 8px;
  padding: 2px 10px !important;
  font-size: 10px !important;
  background: rgba(0,229,176,0.12) !important;
  border-color: var(--match-strong, #00e5b0) !important;
  color: var(--match-strong, #00e5b0) !important;
}
.terminal-preview:hover {
  background: rgba(0,229,176,0.2) !important;
}

.terminal-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 6px 12px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.terminal-title {
  font-family: 'Syne', sans-serif;
  font-weight: 700; font-size: 9px;
  letter-spacing: 0.5px; color: var(--match-strong);
}
.terminal-close {
  background: none; border: none;
  color: var(--text-dim); font-size: 14px;
  cursor: pointer; padding: 2px 6px;
  border-radius: 3px;
}
.terminal-close:hover { background: var(--panel-2); color: var(--text); }

.terminal-body {
  flex: 1; overflow-y: auto;
  padding: 8px 12px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; line-height: 1.5;
  color: var(--text-dim);
  margin: 0;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}

/* ── Inspect nodes ──────────────────────────────────────────────────── */
.inspect-node {
  position: absolute;
  background: rgba(14,20,32,0.95);
  border: 1.5px solid var(--match-strong);
  border-radius: 8px;
  min-width: 160px;
  cursor: grab;
  user-select: none;
  z-index: 50;
  box-shadow: 0 2px 12px rgba(0,0,0,0.4), 0 0 0 0 rgba(0,229,176,0.2);
  transition: box-shadow 0.2s;
}
.inspect-node:hover {
  box-shadow: 0 4px 20px rgba(0,0,0,0.5), 0 0 8px rgba(0,229,176,0.15);
}

.inspect-header {
  display: flex; align-items: center; gap: 6px;
  padding: 6px 8px;
  border-bottom: 1px solid var(--border);
}
.inspect-icon {
  color: var(--match-strong);
  font-size: 12px; flex-shrink: 0;
}
.inspect-target {
  flex: 1;
  background: var(--panel-2);
  border: 1px solid var(--border);
  color: var(--text);
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  padding: 2px 4px; border-radius: 3px;
  outline: none;
}
.inspect-target:focus { border-color: var(--flow); }

/* ── Project picker overlay ──────────────────────────────────────────── */
.project-overlay {
  position: fixed; inset: 0;
  background: var(--bg);
  z-index: 500;
  display: flex; align-items: stretch; justify-content: stretch;
  opacity: 0; pointer-events: none;
  transition: opacity 0.2s ease;
}
.project-overlay.visible { opacity: 1; pointer-events: all; }

/* ── Dashboard shell (Projects + Settings tabs) ───────────────────── */
.dashboard {
  flex: 1;
  display: flex; flex-direction: column;
  background: var(--bg);
  font-family: 'JetBrains Mono', monospace;
  color: var(--text);
}

.dashboard-header {
  display: flex; align-items: center; gap: 16px;
  padding: 14px 24px;
  border-bottom: 1px solid var(--border);
  background: rgba(8,11,16,0.88);
  backdrop-filter: blur(12px);
}
.dashboard-brand {
  display: flex; align-items: center; gap: 12px;
}
.dashboard-glyph {
  width: 38px; height: 38px;
  background: linear-gradient(135deg, var(--flow), var(--class));
  border-radius: 9px;
  display: flex; align-items: center; justify-content: center;
  font-size: 19px; color: #080b10; font-weight: 700;
}
.dashboard-wordmark {
  font-family: 'Syne', sans-serif;
  font-weight: 800; font-size: 18px;
  letter-spacing: -0.4px;
}
.dashboard-subtitle {
  font-size: 10px; letter-spacing: 0.4px;
  color: var(--text-faint); text-transform: uppercase;
}
.dashboard-header-spacer { flex: 1; }
.dashboard-close {
  background: var(--panel-2); border: 1px solid var(--border);
  color: var(--text-dim);
  width: 32px; height: 32px;
  border-radius: 6px;
  font-size: 18px; line-height: 1;
  cursor: pointer; transition: all 0.15s;
}
.dashboard-close:hover { color: var(--text); border-color: var(--border-hi); }

.dashboard-body {
  flex: 1; min-height: 0;
  display: grid;
  grid-template-columns: 200px 1fr;
}

/* ── Sidebar tabs ─────────────────────────────────────────────────── */
.dashboard-nav {
  background: var(--panel);
  border-right: 1px solid var(--border);
  padding: 14px 10px;
  display: flex; flex-direction: column; gap: 4px;
}
.dashboard-nav-item {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px;
  background: transparent; border: 1px solid transparent;
  border-radius: 7px;
  color: var(--text-dim);
  font-family: inherit; font-size: 11px;
  letter-spacing: 0.3px; text-transform: uppercase;
  cursor: pointer;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.dashboard-nav-item .dn-icon { font-size: 14px; opacity: 0.85; }
.dashboard-nav-item:hover {
  background: var(--panel-2); color: var(--text);
}
.dashboard-nav-item.active {
  background: var(--flow-soft);
  color: var(--flow);
  border-color: rgba(61,154,255,0.35);
}

/* ── Main content area ────────────────────────────────────────────── */
.dashboard-main {
  overflow-y: auto;
  padding: 22px 32px 40px;
  scrollbar-width: thin; scrollbar-color: var(--border) transparent;
}
.dashboard-tab { display: flex; flex-direction: column; gap: 14px; }
.dashboard-tab[hidden] { display: none; }
.dashboard-tab-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border);
}
.dashboard-tab-title {
  margin: 0;
  font-family: 'Syne', sans-serif;
  font-size: 18px; font-weight: 700;
  letter-spacing: -0.3px;
  color: var(--text);
}
.dashboard-tab-hint {
  margin: 4px 0 0;
  font-size: 11px; color: var(--text-faint);
}
.dashboard-tab-actions {
  display: flex; gap: 8px; align-items: center;
}
.btn-dash-primary {
  background: var(--flow); color: #080b10;
  border: 1px solid var(--flow);
  border-radius: 6px;
  padding: 8px 14px;
  font-family: inherit; font-size: 11px; font-weight: 600;
  letter-spacing: 0.2px;
  cursor: pointer; transition: opacity 0.15s;
}
.btn-dash-primary:hover { opacity: 0.88; }
.btn-dash-secondary {
  background: var(--panel-2); color: var(--text-dim);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px 12px;
  font-family: inherit; font-size: 11px;
  cursor: pointer; transition: color 0.15s, border-color 0.15s;
}
.btn-dash-secondary:hover { color: var(--text); border-color: var(--border-hi); }

/* ── Status legend strip ──────────────────────────────────────────── */
.dashboard-legend {
  display: flex; gap: 14px; flex-wrap: wrap;
  font-size: 10px; color: var(--text-faint);
  letter-spacing: 0.2px;
}
.dl-item { display: inline-flex; align-items: center; gap: 6px; }
.dl-item .dot {
  width: 8px; height: 8px; border-radius: 50%;
  display: inline-block;
}
.dot-active { background: #2ec27e; box-shadow: 0 0 8px rgba(46,194,126,0.55); }
.dot-idle   { background: #ffa657; box-shadow: 0 0 8px rgba(255,166,87,0.45); }
.dot-off    { background: var(--text-faint); opacity: 0.55; }

.project-picker {
  display: flex; flex-direction: column; align-items: center;
  gap: 18px; text-align: center; max-width: 360px; width: 100%;
  padding: 0 24px;
}
.project-logo {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
}
.project-glyph {
  width: 56px; height: 56px;
  background: linear-gradient(135deg, var(--flow), var(--class));
  border-radius: 14px;
  display: flex; align-items: center; justify-content: center;
  font-size: 28px; color: #080b10; font-weight: 700;
}
.project-wordmark {
  font-family: 'Syne', sans-serif;
  font-weight: 800; font-size: 26px;
  color: var(--text); letter-spacing: -0.5px;
}
.project-tagline {
  font-size: 12px; color: var(--text-dim);
  margin: -8px 0 4px;
}
.project-actions {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  width: 100%;
}
.btn-project-open {
  width: 100%;
  background: var(--flow); color: #080b10;
  border: none; border-radius: 8px;
  padding: 13px 0; font-family: inherit;
  font-size: 13px; font-weight: 600; cursor: pointer;
  transition: opacity 0.15s;
}
.btn-project-open:hover   { opacity: 0.85; }
.btn-project-open:disabled { opacity: 0.45; cursor: default; }
.project-hint {
  font-size: 10px; color: var(--text-faint);
}
.project-error {
  font-size: 11px; color: #f85149; min-height: 16px;
}
.btn-project-skip {
  background: none; border: none;
  color: var(--text-dim); font-family: inherit; font-size: 10px;
  cursor: pointer; opacity: 0.55;
  text-decoration: underline; padding: 4px;
}
.btn-project-skip:hover { opacity: 1; }

.inspect-remove {
  background: none; border: none;
  color: var(--text-faint); font-size: 12px;
  cursor: pointer; padding: 2px 4px;
}
.inspect-remove:hover { color: #f85149; }

.inspect-value {
  padding: 8px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px; font-weight: 600;
  color: var(--text-faint);
  text-align: center;
  min-height: 32px;
  display: flex; align-items: center; justify-content: center;
}
.inspect-value.has-value {
  color: var(--match-strong);
  text-shadow: 0 0 8px rgba(0,229,176,0.3);
}

.inspect-sparkline {
  padding: 0 8px 6px;
}
.inspect-spark-svg {
  width: 100%;
  height: 50px;
  display: block;
}

/* ── Run button in topbar ─────────────────────────────────────────── */
.btn-run {
  background: rgba(61,154,255,0.12) !important;
  border-color: var(--flow) !important;
  color: var(--flow) !important;
}
.btn-run:hover {
  background: rgba(61,154,255,0.2) !important;
}
.btn-inspect {
  background: rgba(0,229,176,0.12) !important;
  border-color: var(--match-strong) !important;
  color: var(--match-strong) !important;
}
.btn-inspect:hover {
  background: rgba(0,229,176,0.2) !important;
}

/* ── Track button on nodes ────────────────────────────────────────── */
.node-track-btn {
  background: none;
  border: 1px solid var(--border);
  color: var(--text-faint);
  font-size: 10px;
  padding: 1px 5px;
  border-radius: 3px;
  cursor: pointer;
  transition: all 0.15s;
  flex-shrink: 0;
  margin-right: 4px;
}
.node-track-btn:hover {
  border-color: var(--match-strong);
  color: var(--match-strong);
  background: rgba(0,229,176,0.08);
}
.node-track-btn.active {
  border-color: var(--match-strong);
  color: var(--match-strong);
  background: rgba(0,229,176,0.15);
  box-shadow: 0 0 6px rgba(0,229,176,0.2);
}

/* ── Sparkline subgraph below nodes ───────────────────────────────── */
.node-sparkline {
  border-top: 1px solid var(--border);
  padding: 6px 8px 4px;
  background: rgba(0,0,0,0.15);
  border-radius: 0 0 8px 8px;
}

.sparkline-svg {
  width: 100%;
  height: 60px;
  display: block;
}
.sparkline-svg.sparkline-calls {
  height: 40px;
}

.spark-labels {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 2px 0 0;
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
}
.spark-label-min,
.spark-label-max {
  color: var(--text-faint);
}
.spark-label-current {
  color: var(--match-strong);
  font-weight: 600;
  transition: all 0.15s;
}
.spark-label-current.spark-flash {
  color: #fff;
  text-shadow: 0 0 8px var(--match-strong);
}

/* ── Ghost nodes (create-from-scratch preview) ─────────────────────────── */
.node.ghost {
  opacity: 0.3;
  pointer-events: none;
  border-style: dashed;
  animation: ghost-pulse 2.4s ease-in-out infinite;
}
@keyframes ghost-pulse {
  0%, 100% { opacity: 0.2; }
  50%       { opacity: 0.42; }
}

/* ── Create-from-scratch overlay ────────────────────────────────────────── */
.create-overlay {
  position: fixed; inset: 0;
  background: rgba(8,11,16,0.93);
  backdrop-filter: blur(20px);
  z-index: 600;
  display: flex; align-items: center; justify-content: center;
  opacity: 0; pointer-events: none;
  transition: opacity 0.2s ease;
}
.create-overlay.visible { opacity: 1; pointer-events: all; }

.create-picker {
  display: flex; flex-direction: column; align-items: center;
  gap: 18px; max-width: 540px; width: 100%; padding: 0 28px;
  text-align: center;
}

.create-logo {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
}
.create-glyph {
  width: 52px; height: 52px;
  background: linear-gradient(135deg, var(--flow), var(--class));
  border-radius: 13px;
  display: flex; align-items: center; justify-content: center;
  font-size: 26px; color: #080b10; font-weight: 700;
}
.create-wordmark {
  font-family: 'Syne', sans-serif;
  font-weight: 800; font-size: 24px;
  color: var(--text); letter-spacing: -0.5px;
}
.create-tagline {
  font-size: 13px; color: var(--text-dim);
  margin: -8px 0 2px;
}

.create-input-wrap { width: 100%; }
.create-input {
  width: 100%; resize: vertical;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text);
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px; line-height: 1.65;
  padding: 12px 14px;
  outline: none;
  transition: border-color 0.15s, background 0.15s;
  min-height: 76px;
}
.create-input:focus { border-color: var(--flow); background: var(--panel-3); }
.create-input::placeholder { color: var(--text-faint); }

.create-footer-row {
  display: flex; align-items: center; justify-content: space-between;
  width: 100%; gap: 12px;
}
.create-status {
  font-size: 10px; color: var(--text-dim);
  font-family: 'JetBrains Mono', monospace;
  flex: 1; text-align: left;
}
.create-status.error { color: #f85149; }

.btn-create-build {
  background: var(--flow); color: #080b10;
  border: none; border-radius: 7px;
  padding: 10px 22px;
  font-family: 'Syne', sans-serif;
  font-size: 12px; font-weight: 700; cursor: pointer;
  transition: opacity 0.15s; white-space: nowrap;
  flex-shrink: 0;
}
.btn-create-build:hover    { opacity: 0.85; }
.btn-create-build:disabled { opacity: 0.35; cursor: default; }

.create-progress-wrap {
  width: 100%; height: 2px;
  background: var(--border); border-radius: 1px; overflow: hidden;
}
.create-progress {
  height: 100%;
  background: linear-gradient(90deg, var(--flow), var(--class));
  border-radius: 1px;
  transition: width 0.4s ease;
}

.btn-create-cancel {
  background: none; border: none;
  color: var(--text-dim); font-family: inherit; font-size: 10px;
  cursor: pointer; opacity: 0.5;
  text-decoration: underline; padding: 4px;
}
.btn-create-cancel:hover { opacity: 1; }

.spark-empty {
  font-size: 9px;
  color: var(--text-faint);
  text-align: center;
  padding: 6px;
  font-style: italic;
}

.spark-text-timeline {
  max-height: 80px;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}
.spark-text-item {
  display: flex;
  gap: 6px;
  font-size: 9px;
  padding: 1px 0;
  border-bottom: 1px solid rgba(255,255,255,0.03);
}
.spark-text-func {
  color: var(--flow);
  min-width: 50px;
  flex-shrink: 0;
}
.spark-text-val {
  color: var(--text-dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ── Inspector panel ──────────────────────────────────────── */
.inspector-panel {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  overflow: hidden;
  background: var(--bg);
}

.inspector-globals {
  flex: 0 0 auto;
  max-height: 42%;
  display: flex; flex-direction: column;
  overflow: hidden;
  border-bottom: 1px solid var(--border);
}

.inspector-context {
  flex: 1;
  display: flex; flex-direction: column;
  overflow: hidden;
}

.inspector-section-header {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 16px 8px;
  border-bottom: 1px solid var(--border);
  background: var(--panel-2);
  flex-shrink: 0;
}
.inspector-section-title {
  font-family: 'Syne', sans-serif;
  font-weight: 700; font-size: 9px;
  letter-spacing: 0.7px;
  text-transform: uppercase;
  color: var(--text-faint);
}
.inspector-section-count {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px; color: var(--text-faint);
  margin-left: auto;
}

.inspector-globals-list {
  flex: 1; overflow-y: auto;
  padding: 4px 0;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}

.inspector-context-body {
  flex: 1; overflow-y: auto;
  padding: 12px 16px 20px;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
  transition: opacity 150ms ease;
}

.inspector-empty {
  font-size: 11px; color: var(--text-faint);
  font-style: italic; padding: 12px 0;
}

.inspector-divider { display: none; } /* handled by border-bottom on .inspector-globals */

/* ── Globals rows ─────────────────────────────────────────── */
.ig-row {
  display: flex; align-items: center; gap: 8px;
  padding: 5px 16px;
  cursor: pointer;
  transition: background 0.1s;
}
.ig-row:hover { background: var(--panel-2); }
.ig-row.ig-active { background: rgba(61,154,255,0.08); }

.ig-name {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; color: var(--text);
  flex-shrink: 0;
}
.ig-value {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; color: var(--text-dim);
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ig-module { color: var(--import); }
.ig-badge {
  font-family: 'Syne', sans-serif;
  font-size: 8px; font-weight: 700; letter-spacing: 0.4px;
  text-transform: uppercase;
  padding: 1px 5px; border-radius: 3px;
  flex-shrink: 0;
}
.ig-state   { background: var(--state-soft);   color: var(--state);   }
.ig-config  { background: var(--config-soft);  color: var(--config);  }
.ig-import  { background: var(--import-soft);  color: var(--import);  }

/* Editable value input inside globals rows */
.ig-input {
  flex: 1; min-width: 0;
  background: transparent; border: none; outline: none;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; color: var(--text-dim);
  padding: 0; cursor: text;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ig-input:focus {
  color: var(--text);
  background: var(--panel-3);
  border-radius: 3px;
  padding: 0 4px;
  box-shadow: 0 0 0 1px var(--border-hi);
}

/* Record indicator dot */
.ig-record-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--border-hi);
  flex-shrink: 0;
  transition: background 0.2s, box-shadow 0.2s;
  cursor: default;
}
.ig-record-dot.ig-recorded-observed {
  background: var(--flow);
  box-shadow: 0 0 4px var(--flow);
}
.ig-record-dot.ig-recorded-changed {
  background: var(--state);
  box-shadow: 0 0 5px var(--state);
}

/* ── VIEW node body ──────────────────────────────────────────── */
.view-preview-bar {
  display: flex; flex-wrap: wrap; gap: 4px; align-items: center;
  margin-bottom: 4px;
}
.view-lang-tag {
  padding: 1px 5px; border-radius: 3px; font-size: 9px; font-weight: 700;
  background: rgba(6,182,212,0.15); color: var(--view); letter-spacing: 0.3px;
}
.view-var-chip {
  padding: 1px 5px; border-radius: 3px; font-size: 9px;
  background: var(--panel-3); border: 1px solid var(--border); color: var(--view);
}
.view-html-snippet {
  font-size: 9px; color: var(--text-faint); white-space: pre;
  overflow: hidden; max-height: 44px; line-height: 1.4;
  font-family: 'JetBrains Mono', monospace;
}
.view-mini-iframe {
  display: block; width: 100%; height: 150px;
  border: none; border-radius: 4px; background: #fff;
  pointer-events: none; margin-bottom: 4px;
  transform-origin: top left;
}
.view-render-btn {
  margin-top: 2px; padding: 3px 8px; display: block;
  background: transparent; border: 1px solid var(--view);
  border-radius: 3px; color: var(--view); font-size: 9px; cursor: pointer;
}
.view-render-btn:hover { background: var(--view-soft); }

/* ── VIEW full preview overlay ───────────────────────────────── */
.view-preview-overlay {
  position: fixed; inset: 64px 16px 60px 16px; z-index: 500;
  background: var(--panel); border: 1px solid var(--view);
  border-radius: 10px; display: flex; flex-direction: column;
  box-shadow: 0 16px 48px rgba(0,0,0,0.6);
}
.vp-header {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 16px; border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.vp-title   { font-size: 13px; font-weight: 700; color: var(--text); flex: 1 }
.vp-badge   { background: var(--view-soft); color: var(--view); padding: 1px 6px;
               border-radius: 3px; font-size: 9px; font-weight: 700; margin-right: 6px; }
.vp-lang    { font-size: 10px; color: var(--view); }
.vp-close   { background: transparent; border: none; color: var(--text-dim);
               font-size: 18px; cursor: pointer; padding: 0 4px; }
.vp-close:hover { color: var(--text); }
.vp-body    { display: flex; flex: 1; overflow: hidden; }
.vp-sidebar {
  width: 220px; flex-shrink: 0; padding: 12px 14px;
  border-right: 1px solid var(--border); overflow-y: auto;
  display: flex; flex-direction: column; gap: 4px;
}
.vp-section-title {
  font-family: 'Syne', sans-serif; font-size: 8px; font-weight: 700;
  letter-spacing: 0.8px; color: var(--text-faint); margin-bottom: 4px;
}
.vp-vars    { display: flex; flex-direction: column; gap: 3px; }
.vp-var-row { display: flex; gap: 6px; align-items: baseline; }
.vp-var-k   { font-size: 9px; color: var(--view); min-width: 70px; flex-shrink: 0; }
.vp-var-v   { font-size: 10px; color: var(--text-dim); }
.vp-empty   { font-size: 10px; color: var(--text-faint); font-style: italic; }
.vp-prompt  {
  width: 100%; min-height: 56px; resize: vertical;
  background: var(--panel-3); border: 1px solid var(--border);
  border-radius: 4px; color: var(--text); font-size: 10px;
  padding: 6px 8px; font-family: inherit; outline: none; box-sizing: border-box;
}
.vp-prompt:focus { border-color: var(--view); }
.vp-ai-btn  {
  padding: 5px 12px; background: var(--view); border: none; border-radius: 4px;
  color: #080b10; font-weight: 700; font-size: 10px; cursor: pointer; margin-top: 4px;
}
.vp-ai-btn:disabled { opacity: 0.5; cursor: default; }
.vp-ai-status { font-size: 9px; color: var(--text-faint); margin-top: 4px; }
.vp-preview { flex: 1; overflow: hidden; }
.vp-iframe  { width: 100%; height: 100%; border: none; background: #fff; display: block; }

/* Inspector VIEW iframe + var styles */
.ic-view-iframe {
  width: 100%; height: 180px; border: 1px solid var(--border);
  border-radius: 4px; background: #fff; display: block; margin-top: 4px;
}
.ic-view-expand-btn {
  display: inline-block; margin-top: 6px; padding: 3px 10px;
  background: transparent; border: 1px solid var(--view);
  border-radius: 3px; color: var(--view); font-size: 10px; cursor: pointer;
}
.ic-view-expand-btn:hover { background: var(--view-soft); }
.ic-vp-vars { display: flex; flex-direction: column; gap: 4px; }
.ic-vp-var  { display: flex; gap: 6px; align-items: center; }
.ic-kv-k    { font-size: 9px; color: var(--view); min-width: 70px; flex-shrink: 0; }
.ic-view-src { font-size: 9px; max-height: 120px; overflow-y: auto; }
.ig-badge.ig-view { background: rgba(6,182,212,0.12); color: var(--view); }
.ig-view-lang { background: rgba(6,182,212,0.12); color: var(--view); font-size: 9px; }
.bo-block[data-type="VIEW"] { border-left-color: var(--view); background: var(--view-soft); }

/* ── Complex CONFIG/STATE value viewers ──────────────────────── */

.ig-row-complex {
  flex-direction: column; align-items: stretch;
  padding: 6px 16px 8px;
}
.ig-row-hd {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 6px;
}
.ig-row-hd .ig-name { flex: 1; }
.ig-row-body { width: 100%; }

.ig-mini-table {
  font-size: 10px; border-collapse: collapse;
  width: 100%; overflow-x: auto;
}
.ig-mt-head {
  display: flex; gap: 0; border-bottom: 1px solid var(--border);
  margin-bottom: 2px;
}
.ig-mt-row { display: flex; gap: 0; }
.ig-mt-row:nth-child(odd) { background: var(--panel-3); }
.ig-mt-cell {
  flex: 1; min-width: 0; padding: 2px 4px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  color: var(--text-dim);
}
.ig-mt-head .ig-mt-cell { color: var(--config); font-weight: 600; }
.ig-mt-more {
  font-size: 9px; color: var(--text-faint); padding: 2px 4px;
  font-style: italic;
}

.ig-val-chips {
  display: flex; flex-wrap: wrap; gap: 4px; align-items: center;
}
.ig-val-chip {
  padding: 1px 6px; border-radius: 3px;
  background: var(--panel-3); border: 1px solid var(--border);
  font-size: 10px; color: var(--text-dim);
}
.ig-chip-more { color: var(--text-faint); font-style: italic; }

.ig-kv-list { display: flex; flex-direction: column; gap: 2px; }
.ig-kv-row  { display: flex; gap: 6px; align-items: baseline; }
.ig-kv-k    { font-size: 9px; color: var(--config); min-width: 60px; flex-shrink: 0; }
.ig-kv-v    { font-size: 10px; color: var(--text-dim); }
.ig-kv-more { font-size: 9px; color: var(--text-faint); font-style: italic; }

.ig-scalar-long {
  font-size: 10px; color: var(--text-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 100%;
}

.ig-analyze-btn {
  margin-top: 4px; padding: 2px 8px;
  background: transparent; border: 1px solid var(--border);
  border-radius: 3px; color: var(--text-faint); font-size: 9px;
  cursor: pointer; display: block;
}
.ig-analyze-btn:hover { border-color: var(--config); color: var(--config); }
.ig-analyze-btn:disabled { opacity: 0.5; cursor: default; }

/* Editable value in context detail panel — same box as .ic-val */
.ic-val-input {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; color: var(--flow);
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 3px; padding: 1px 6px;
  outline: none; flex: 1;
  word-break: break-all;
}
.ic-val-input:focus {
  border-color: var(--border-hi);
  color: var(--text);
}

/* Complex value in context detail panel */
.ic-complex-val {
  margin-top: 4px;
}
.ic-complex-val .ig-mini-table,
.ic-complex-val .ig-val-chips,
.ic-complex-val .ig-kv-list { width: 100%; }

/* ── Context detail ───────────────────────────────────────── */
.ic-header {
  display: flex; align-items: flex-start; gap: 10px;
  margin-bottom: 4px;
}
.ic-name {
  font-family: 'JetBrains Mono', monospace;
  font-size: 15px; font-weight: 600; color: var(--text);
  flex: 1; word-break: break-all;
}
.ic-badge {
  font-family: 'Syne', sans-serif;
  font-size: 8px; font-weight: 700; letter-spacing: 0.5px;
  text-transform: uppercase;
  padding: 3px 7px; border-radius: 3px;
  flex-shrink: 0; margin-top: 3px;
}
.ic-badge-flow    { background: var(--flow-soft);     color: var(--flow);    }
.ic-badge-method  { background: var(--class-soft);    color: var(--class);   }
.ic-badge-state   { background: var(--state-soft);    color: var(--state);   }
.ic-badge-config  { background: var(--config-soft);   color: var(--config);  }
.ic-badge-import  { background: var(--import-soft);   color: var(--import);  }
.ic-badge-class   { background: var(--class-soft);    color: var(--class);   }
.ic-badge-verbatim{ background: var(--verbatim-soft); color: #8a9ab8;        }

.ic-owner {
  font-size: 10px; color: var(--class); opacity: 0.8;
  margin-bottom: 10px; margin-top: -2px;
}

.ic-intent {
  font-size: 11px; line-height: 1.6; color: var(--text-dim);
  margin: 10px 0 12px;
  padding: 10px 12px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-left: 3px solid var(--border-hi);
  border-radius: 0 5px 5px 0;
}

.ic-value-row {
  display: flex; align-items: baseline; gap: 8px;
  margin: 8px 0;
}
.ic-infer-btn {
  flex-shrink: 0; padding: 1px 6px; font-size: 9px;
  background: transparent; border: 1px solid var(--state);
  border-radius: 3px; color: var(--state); cursor: pointer;
  font-family: 'Syne', sans-serif; letter-spacing: 0.3px;
}
.ic-infer-btn:hover { background: rgba(139,92,246,0.12); }
.ic-infer-btn:disabled { opacity: 0.5; cursor: default; }
.ic-vl {
  font-family: 'Syne', sans-serif;
  font-size: 8px; font-weight: 600; letter-spacing: 0.5px;
  text-transform: uppercase; color: var(--text-faint);
  min-width: 44px; flex-shrink: 0;
}
.ic-val {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; color: var(--flow);
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 3px; padding: 1px 6px;
  word-break: break-all;
}
.ic-dim { color: var(--text-faint); }

.ic-section {
  margin: 10px 0 2px;
}
.ic-section-label {
  font-family: 'Syne', sans-serif;
  font-size: 8px; font-weight: 600; letter-spacing: 0.5px;
  text-transform: uppercase; color: var(--text-faint);
  margin-bottom: 5px;
}
.ic-chips { display: flex; flex-wrap: wrap; gap: 4px; }

.ic-chip {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; padding: 2px 7px; border-radius: 3px;
  cursor: default;
  transition: filter 0.1s;
}
.ic-chip[data-ctx-jump] {
  cursor: pointer;
}
.ic-chip[data-ctx-jump]:hover { filter: brightness(1.3); }
.ic-chip-in   { background: rgba(61,154,255,0.10);  color: var(--flow);   border: 1px solid rgba(61,154,255,0.25); }
.ic-chip-mut  { background: rgba(255,140,66,0.10);  color: var(--state);  border: 1px solid rgba(255,140,66,0.25); }
.ic-chip-self { background: rgba(0,229,176,0.08);   color: var(--class);  border: 1px solid rgba(0,229,176,0.2); }
.ic-chip-glob { background: rgba(185,127,255,0.08); color: var(--config); border: 1px solid rgba(185,127,255,0.2); }
.ic-chip-ref  { background: var(--panel-2); color: var(--text-dim); border: 1px solid var(--border); }
.ic-chip-flow { background: var(--flow-soft); color: var(--flow); border: 1px solid rgba(61,154,255,0.2); }

.ic-flags { display: flex; gap: 6px; flex-wrap: wrap; margin: 8px 0; }
.ic-flag {
  font-size: 10px; padding: 2px 7px; border-radius: 3px;
  background: var(--panel-2); color: var(--text-faint);
  border: 1px solid var(--border);
}

.ic-verbatim {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; line-height: 1.6;
  color: var(--text-dim);
  background: var(--panel-2);
  border: 1px solid var(--border); border-radius: 5px;
  padding: 8px 10px; margin: 8px 0;
  overflow-x: auto; white-space: pre;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}

/* ── Editor context filter ────────────────────────────────── */
/* Nodes/canvases outside the clicked context */
.node.ctx-hidden,
.class-canvas.ctx-hidden,
.file-canvas.ctx-hidden {
  opacity: 0 !important;
  pointer-events: none !important;
}
svg.edges path.ctx-hidden {
  opacity: 0 !important;
}

/* Per-node appear animation when context changes */
@keyframes ctx-node-appear {
  from { opacity: 0; transform: scale(0.95); }
  to   { opacity: 1; transform: scale(1.0); }
}
.node.ctx-appear {
  animation: ctx-node-appear 200ms ease forwards;
}

/* Active line indicator stripe in the editor */
.editor-panel .active-line-indicator {
  position: absolute;
  left: 0; right: 0;
  background: rgba(61,154,255,0.06);
  pointer-events: none;
}

/* ── Project sidebar ──────────────────────────────────────────────────── */
.project-sidebar {
  position: fixed;
  top: 40px; /* topbar height */
  left: 0;
  width: 220px;
  height: calc(100vh - 40px);
  background: var(--panel-2);
  border-right: 1px solid var(--border);
  transform: translateX(-220px);
  transition: transform 0.2s ease;
  z-index: 300;
  display: flex; flex-direction: column;
  overflow: hidden;
}
.project-sidebar.open { transform: translateX(0); }

.project-sidebar-header {
  display: flex; align-items: center;
  padding: 10px 12px 9px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.project-sidebar-title {
  font-family: 'Syne', sans-serif;
  font-weight: 700; font-size: 9px;
  letter-spacing: 0.7px; text-transform: uppercase;
  color: var(--text-faint); flex: 1;
}
.project-sidebar-close {
  background: none; border: none;
  color: var(--text-faint); cursor: pointer;
  font-size: 16px; line-height: 1; padding: 0 2px;
}
.project-sidebar-close:hover { color: var(--text); }

.project-sidebar-new {
  display: block; width: 100%;
  background: none; border: none; border-bottom: 1px solid var(--border);
  color: var(--flow); font-family: 'JetBrains Mono', monospace;
  font-size: 11px; padding: 9px 12px;
  text-align: left; cursor: pointer; flex-shrink: 0;
}
.project-sidebar-new:hover { background: var(--panel-3); }

.project-sidebar-list { overflow-y: auto; flex: 1; scrollbar-width: thin; scrollbar-color: var(--border) transparent; }

.psb-item {
  display: block; width: 100%;
  background: none; border: none; border-bottom: 1px solid rgba(255,255,255,0.04);
  padding: 9px 12px; text-align: left; cursor: pointer;
  color: var(--text); font-family: 'JetBrains Mono', monospace; font-size: 11px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.psb-item:hover { background: var(--panel-3); }
.psb-empty { padding: 14px 12px; color: var(--text-faint); font-size: 11px; }

/* ── Stage history strip ──────────────────────────────────────────────── */
/* Two states:
   - Collapsed rail (28px): pips centred, fully visible (the old 12px width
     clipped them at the page edge).
   - Expanded card list (240px on hover): each commit becomes its own pane
     with a quiet background, the pip on the left, and a timestamp + message
     stacked on the right with matched line-heights so they don't look offset. */
.stage-history {
  position: fixed;
  top: 40px;
  right: 0;
  width: 28px;
  height: calc(100vh - 40px);
  background: var(--panel-2);
  border-left: 1px solid var(--border);
  z-index: 150;
  overflow: hidden;
  transition: width 0.2s ease;
}
.stage-history:hover { width: 240px; }

.stage-history-track {
  display: flex; flex-direction: column;
  /* Tight, uniform rhythm in the collapsed rail; expanded gap is wider
     so the cards visibly separate. align-items:center shrink-wraps each
     dot to pip width and centres it in the rail — the old horizontal
     padding + scrollbar combo was producing visible asymmetry. */
  align-items: center;
  gap: 2px;
  padding: 6px 0;
  height: 100%;
  /* Hidden scrollbar in collapsed state so it can't eat right-edge pixels
     and visually shove the pips left. Wheel/trackpad scroll still works. */
  overflow-y: auto;
  scrollbar-width: none;
}
.stage-history-track::-webkit-scrollbar { display: none; }
.stage-history:hover .stage-history-track {
  align-items: stretch;
  gap: 4px;
  padding: 8px 6px;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}
.stage-history:hover .stage-history-track::-webkit-scrollbar { display: block; width: 6px; }
.stage-history:hover .stage-history-track::-webkit-scrollbar-thumb {
  background: var(--border); border-radius: 3px;
}

/* Each commit is a self-contained card. Collapsed it shrink-wraps to the
   pip (and the track centres it); on hover the card inflates, stretches
   to fill the rail, and the label slides in. */
.sh-dot {
  display: flex; align-items: center;
  gap: 8px;
  flex-shrink: 0;
  padding: 3px 4px;
  border: 1px solid transparent;
  border-radius: 6px;
  cursor: pointer;
  background: transparent;
  transition: background 120ms ease, border-color 120ms ease, padding 200ms ease;
  justify-content: center;
}
.stage-history:hover .sh-dot {
  padding: 8px 10px;
  background: var(--panel-3);
  border-color: var(--border);
  justify-content: flex-start;
  align-self: stretch;
}
.stage-history:hover .sh-dot:hover {
  border-color: var(--border-hi);
  background: var(--panel);
}

.sh-pip {
  width: 8px; height: 8px; border-radius: 50%;
  flex-shrink: 0;
  transition: box-shadow 0.15s, transform 0.15s;
}
.sh-dot:hover .sh-pip { transform: scale(1.15); }
.sh-dot.amber .sh-pip { background: var(--config); box-shadow: 0 0 6px var(--config); }
.sh-dot.green .sh-pip { background: #3fb950;       box-shadow: 0 0 6px #3fb950; }
.sh-dot.grey  .sh-pip { background: var(--border-hi); }

/* Label slides in on expand. flex:1 + min-width:0 lets the message ellipsis
   work even with the rigid pip on the left. */
.sh-label {
  display: flex; flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  opacity: 0;
  transform: translateX(-4px);
  transition: opacity 0.15s ease, transform 0.15s ease;
  pointer-events: none;
}
.stage-history:hover .sh-label {
  opacity: 1;
  transform: translateX(0);
}

/* Matched line-heights keep the two text rows visually aligned. */
.sh-ts {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9.5px;
  line-height: 1.25;
  color: var(--text-faint);
  letter-spacing: 0.2px;
  white-space: nowrap;
}
.sh-msg {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  line-height: 1.25;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ── Home button in topbar ───────────────────────────────────────────── */
.btn-home {
  margin-left: 6px;
  border-color: var(--border-hi) !important;
  color: var(--text) !important;
}
.btn-home:hover {
  background: var(--panel-3) !important;
}

/* ── Projects button in topbar ───────────────────────────────────────── */
.btn-projects {
  border-color: var(--border-hi) !important;
  color: var(--text) !important;
}

/* ── Topbar Run button in "stop" state ───────────────────────────────── */
.btn-run.btn-stop {
  background: rgba(248,81,73,0.12) !important;
  border-color: #f85149 !important;
  color: #f85149 !important;
}
.btn-run.btn-stop:hover { background: rgba(248,81,73,0.2) !important; }

/* ── Detected run-mode chip + sample-rate input (next to Run) ───────── */
.run-mode-chip {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  font-size: 10px;
  border-radius: 999px;
  border: 1px solid rgba(255,255,255,0.15);
  background: rgba(255,255,255,0.04);
  opacity: 0.75;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.run-mode-chip[data-mode="live"] {
  border-color: rgba(248,81,73,0.4);
  background: rgba(248,81,73,0.08);
  color: #f85149;
}
.run-mode-chip[data-mode="oneshot"] {
  border-color: rgba(63,185,80,0.4);
  background: rgba(63,185,80,0.08);
  color: #3fb950;
}
.run-mode-chip:empty { display: none; }
.sample-rate-label {
  margin-left: 6px;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  opacity: 0.75;
}
.sample-rate-input {
  width: 52px;
  background: rgba(255,255,255,0.06);
  color: inherit;
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 4px;
  padding: 1px 4px;
  font-size: 11px;
}

/* ── Project list (grid of cards) ───────────────────────────────────── */
.project-list-section { width: 100%; }
.project-list-section.hidden { display: none; }

.project-list-items {
  width: 100%;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 12px;
  margin: 6px 0 4px;
}

/* Loading / empty fill the grid */
.pli-loading, .pli-empty {
  grid-column: 1 / -1;
  padding: 28px;
  font-size: 11px;
  color: var(--text-faint); text-align: center;
  border: 1px dashed var(--border); border-radius: 8px;
  background: var(--panel-2);
}

/* Project card */
.pli-item {
  position: relative;
  display: flex; flex-direction: column; gap: 8px;
  background: var(--panel-2);
  border: 1px solid var(--border); border-left-width: 3px;
  border-radius: 9px;
  padding: 14px 14px 12px;
  cursor: pointer; text-align: left;
  color: var(--text);
  font-family: 'JetBrains Mono', monospace; font-size: 12px;
  transition: border-color 0.12s, background 0.12s, transform 0.12s;
}
.pli-item:hover {
  background: var(--panel-3);
  border-color: var(--border-hi);
  transform: translateY(-1px);
}

/* Status-driven left border accent */
.pli-item[data-status="active"] { border-left-color: #2ec27e; }
.pli-item[data-status="idle"]   { border-left-color: #ffa657; }
.pli-item[data-status="off"]    { border-left-color: var(--border-hi); }

.pli-row-top {
  display: flex; align-items: center; gap: 8px;
  min-width: 0;
}
.pli-dot {
  flex-shrink: 0;
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--text-faint);
}
.pli-item[data-status="active"] .pli-dot {
  background: #2ec27e;
  box-shadow: 0 0 10px rgba(46,194,126,0.65);
  animation: pli-pulse 1.4s ease-in-out infinite;
}
.pli-item[data-status="idle"] .pli-dot {
  background: #ffa657;
  box-shadow: 0 0 8px rgba(255,166,87,0.45);
}
@keyframes pli-pulse {
  0%, 100% { transform: scale(1);   opacity: 1; }
  50%      { transform: scale(1.18); opacity: 0.85; }
}

.pli-name {
  flex: 1;
  font-weight: 600; font-size: 13px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-family: 'Syne', sans-serif; letter-spacing: -0.2px;
}
.pli-status-tag {
  flex-shrink: 0;
  font-size: 9px; letter-spacing: 0.35px;
  text-transform: uppercase;
  padding: 2px 7px; border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--panel-3); color: var(--text-faint);
}
.pli-item[data-status="active"] .pli-status-tag {
  color: #2ec27e; border-color: rgba(46,194,126,0.4);
  background: rgba(46,194,126,0.08);
}
.pli-item[data-status="idle"] .pli-status-tag {
  color: #ffa657; border-color: rgba(255,166,87,0.4);
  background: rgba(255,166,87,0.08);
}

.pli-meta-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px;
  font-size: 10px; color: var(--text-faint);
}
.pli-meta { font-variant-numeric: tabular-nums; }
.pli-term-count {
  display: inline-flex; align-items: center; gap: 4px;
}
.pli-term-count[data-count="0"] { opacity: 0.4; }

.pli-actions {
  display: flex; gap: 6px;
  margin-top: 2px;
  padding-top: 8px;
  border-top: 1px dashed var(--border);
}
.pli-action {
  flex: 1;
  background: transparent; border: 1px solid var(--border);
  border-radius: 5px;
  padding: 5px 8px;
  color: var(--text-dim);
  font-family: inherit; font-size: 10px;
  letter-spacing: 0.2px;
  cursor: pointer; transition: all 0.12s;
}
.pli-action:hover { background: var(--panel-3); color: var(--text); border-color: var(--border-hi); }
.pli-action.danger:hover {
  color: #f85149; border-color: #f85149;
  background: rgba(248,81,73,0.08);
}
.pli-action.primary {
  color: var(--flow); border-color: rgba(61,154,255,0.35);
  background: var(--flow-soft);
}
.pli-action.primary:hover { background: var(--flow); color: #080b10; border-color: var(--flow); }

/* ── Inline "new project" form panel ──────────────────────────────── */
.new-project-form {
  display: none;
  background: var(--panel-2);
  border: 1px solid var(--border-hi);
  border-radius: 9px;
  padding: 16px;
  margin-top: 12px;
  flex-direction: column; gap: 10px;
}
.new-project-form.visible { display: flex; }

.new-project-label {
  font-size: 10px; letter-spacing: 0.3px;
  text-transform: uppercase;
  color: var(--text-faint);
}

.new-project-name-input {
  width: 100%; box-sizing: border-box;
  background: var(--panel-3); border: 1px solid var(--border);
  border-radius: 7px; color: var(--text);
  font-family: 'JetBrains Mono', monospace; font-size: 13px;
  padding: 11px 14px; outline: none;
}
.new-project-name-input:focus { border-color: var(--flow); }
.new-project-name-input::placeholder { color: var(--text-faint); }

.new-project-row {
  display: flex; gap: 8px; justify-content: flex-end;
}
.btn-cancel-new {
  background: none; border: 1px solid var(--border);
  border-radius: 6px; padding: 8px 14px;
  color: var(--text-dim); font-family: inherit; font-size: 11px;
  cursor: pointer;
}
.btn-cancel-new:hover { border-color: var(--border-hi); color: var(--text); }
.btn-create-project {
  background: var(--flow); color: #080b10;
  border: none; border-radius: 6px;
  padding: 8px 18px;
  font-family: inherit; font-size: 11px; font-weight: 600;
  cursor: pointer; transition: opacity 0.15s;
}
.btn-create-project:hover    { opacity: 0.85; }
.btn-create-project:disabled { opacity: 0.35; cursor: default; }

/* ── Settings panel when embedded in the dashboard ────────────────── */
/* When the user opens the Settings tab, project.js moves the existing
   #settings-panel element into .dashboard-settings-mount. Strip the
   popover positioning so it lays out as a normal block inside the
   dashboard pane. */
.dashboard-settings-mount {
  display: flex;
  justify-content: flex-start;
}
.dashboard-settings-mount > .settings-panel {
  position: static !important;
  inset: auto !important;
  margin: 0;
  width: 100%;
  max-width: 540px;
  box-shadow: none;
}
.dashboard-settings-mount > .settings-panel[hidden] {
  display: block !important;
}
/* No "×" inside the embedded panel — closing happens by switching tabs. */
.dashboard-settings-mount > .settings-panel .settings-close { display: none; }

/* ── File Explorer sidebar ─────────────────────────────────────────────── */
/* Two states (VS Code-style):
   .expanded → full tree (220px)
   .collapsed → narrow rail showing only a folder icon (40px) */
.file-explorer {
  position: fixed;
  top: var(--topbar-h); left: 0; bottom: 84px;
  background: var(--panel-2);
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
  transition: width 0.18s ease;
  z-index: 60;
  overflow: hidden;
}
.file-explorer.expanded  { width: 220px; }
.file-explorer.collapsed { width: 40px;  }

/* Drag-and-drop overlay — covers the whole explorer while a file is dragged
   over it. pointer-events:none so the underlying panel still receives the
   dragover/dragleave/drop events (otherwise the overlay would swallow them
   and the drop target would flicker). */
.fe-drop-overlay {
  position: absolute; inset: 0;
  display: none;
  align-items: center; justify-content: center;
  background: rgba(8,11,16,0.84);
  backdrop-filter: blur(3px);
  border: 2px dashed var(--flow);
  border-radius: 8px;
  z-index: 70;
  pointer-events: none;
}
.fe-drop-overlay.visible { display: flex; }
.fe-drop-inner  { text-align: center; color: var(--flow); font-family: 'Syne', sans-serif; }
.fe-drop-icon   { font-size: 30px; margin-bottom: 8px; }
.fe-drop-text   { font-size: 12px; font-weight: 700; letter-spacing: 0.5px; text-transform: uppercase; }

/* Rail folder-icon button — visible only when collapsed */
.fe-rail-btn {
  display: none;
  width: 40px; height: 40px;
  background: none; border: none;
  color: var(--text-dim);
  cursor: pointer;
  align-items: center; justify-content: center;
  padding: 0;
}
.fe-rail-btn:hover { color: var(--text); background: var(--panel-3); }
.file-explorer.collapsed .fe-rail-btn { display: flex; }
.file-explorer.collapsed .fe-content  { display: none; }

/* Expanded content wrapper */
.fe-content {
  display: flex; flex-direction: column;
  flex: 1; min-height: 0; min-width: 220px;
}

/* Shift the main layout to make room for the explorer.
   Always shifted by at least the rail width (40px); 220px when expanded.
   We deliberately don't set `width` here — the base .split-layout rule
   pins `right: 28px` so the layout naturally stops at the collapsed
   stage-history rail (and re-flows to right:240px when the rail expands
   on hover). Setting width: calc(100% - left) would override that and
   cause the layout to overlap the rail. */
.split-layout {
  left: 40px;
  transition: left 0.18s ease, right 0.18s ease;
}
.split-layout.explorer-expanded {
  left: 220px;
}

.fe-header {
  display: flex; align-items: center;
  padding: 8px 10px 7px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0; gap: 4px;
}
.fe-title {
  font-family: 'Syne', sans-serif;
  font-weight: 700; font-size: 9px;
  letter-spacing: 0.7px; text-transform: uppercase;
  color: var(--text-faint); flex: 1;
}
.fe-header-actions { display: flex; gap: 2px; }
.fe-action-btn {
  background: none; border: none;
  color: var(--text-dim); cursor: pointer;
  font-size: 13px; padding: 2px 5px; border-radius: 4px;
  line-height: 1; opacity: 0.7;
}
.fe-action-btn:hover { opacity: 1; background: var(--panel-3); color: var(--text); }

.fe-tree {
  flex: 1; overflow-y: auto; overflow-x: hidden;
  padding: 4px 0;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}

/* Tree items */
.fe-item {
  display: flex; align-items: center;
  padding: 3px 8px 3px 10px;
  cursor: pointer; font-size: 12px;
  color: var(--text-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  user-select: none; gap: 4px;
  border-radius: 3px; margin: 0 4px;
}
.fe-item:hover { background: var(--panel-3); color: var(--text); }
.fe-item.active { background: rgba(61,154,255,0.12); color: var(--flow); }

.fe-arrow { font-size: 9px; width: 10px; flex-shrink: 0; color: var(--text-faint); }
.fe-icon  { font-size: 11px; flex-shrink: 0; }
.fe-label { flex: 1; overflow: hidden; text-overflow: ellipsis; }
.fe-file-indent { width: 14px; flex-shrink: 0; }

.fe-dir-wrap { }
.fe-children { padding-left: 14px; }

/* Inline create / rename input */
.fe-inline-wrap {
  display: flex; align-items: center;
  padding: 3px 8px; margin: 1px 4px;
}
.fe-inline-input {
  flex: 1; background: var(--panel-3);
  border: 1px solid var(--flow); border-radius: 4px;
  color: var(--text); font-family: 'JetBrains Mono', monospace;
  font-size: 12px; padding: 2px 6px; outline: none;
}
.fe-rename-input { width: 100%; }

/* Context menu */
.fe-ctx-menu {
  position: fixed; z-index: 999;
  background: var(--panel-2); border: 1px solid var(--border);
  border-radius: 6px; padding: 4px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.5);
  min-width: 140px;
}
.fe-ctx-item {
  display: block; width: 100%;
  background: none; border: none; text-align: left;
  color: var(--text-dim); font-family: 'JetBrains Mono', monospace;
  font-size: 12px; padding: 6px 10px; cursor: pointer;
  border-radius: 4px;
}
.fe-ctx-item:hover { background: var(--panel-3); color: var(--text); }
.fe-ctx-item.danger:hover { background: rgba(248,81,73,0.12); color: #f85149; }

/* Topbar explorer button active state */
.btn-explorer.active { border-color: var(--flow); color: var(--flow); }

/* ── Bottom-left dock (settings + projects) ─────────────────────── */
/* Two hover-icon buttons fixed at the bottom-left, just above the
   chat-dock. Dim by default, brighten on hover. Visible but unobtrusive. */
.bl-dock {
  position: fixed;
  left: 14px;
  bottom: calc(var(--dock-h) + 14px);
  display: flex; flex-direction: column; gap: 8px;
  z-index: 250;
}
.bl-icon {
  width: 34px; height: 34px;
  border-radius: 50%;
  background: var(--panel-2);
  border: 1px solid var(--border);
  color: var(--text-dim);
  font-size: 16px; line-height: 1;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  opacity: 0.55;
  transition: opacity 140ms ease, border-color 140ms ease,
              color 140ms ease, background 140ms ease, transform 140ms ease;
}
.bl-icon:hover {
  opacity: 1;
  color: var(--text);
  border-color: var(--border-hi);
  background: var(--panel-3);
  transform: scale(1.08);
}
.bl-icon.active {
  opacity: 1;
  color: var(--flow);
  border-color: var(--flow);
}

/* ── Settings panel (popover anchored to bl-btn-settings) ───────── */
.settings-panel {
  position: fixed;
  left: 60px;
  /* Anchor just above the persistent chat chrome (chat-bar + prompt input),
     NOT above the full dock. Using --dock-h here pushed the panel above the
     entire chat transcript (up to 58vh tall) and clamped it against the top
     of the screen — "squished". --chrome-h tracks only the bar+input height,
     so the panel sits low and OVERLAYS the transcript (z-index 260 > dock's
     180). Falls back to 120px before the observer first measures. */
  bottom: calc(var(--chrome-h, 120px) + 14px);
  width: 320px;
  max-height: 70vh;
  display: flex; flex-direction: column;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 14px 36px rgba(0,0,0,0.55);
  z-index: 260;
  overflow: hidden;
  font-family: 'JetBrains Mono', monospace;
}
.settings-panel[hidden] { display: none; }
.settings-header {
  display: flex; align-items: center;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
  background: var(--panel-2);
}
.settings-title {
  font-family: 'Syne', sans-serif;
  font-weight: 700; font-size: 10px;
  letter-spacing: 0.7px;
  color: var(--text-faint);
  text-transform: uppercase;
  flex: 1;
}
.settings-close {
  background: none; border: none;
  color: var(--text-faint); cursor: pointer;
  font-size: 18px; line-height: 1; padding: 0 4px;
}
.settings-close:hover { color: var(--text); }

.settings-body {
  flex: 1; overflow-y: auto;
  padding: 6px 14px 14px;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}
.settings-section { padding: 12px 0; border-bottom: 1px solid var(--border); }
.settings-section:last-child { border-bottom: none; }
.settings-section-title {
  font-family: 'Syne', sans-serif;
  font-weight: 700; font-size: 9px;
  letter-spacing: 0.6px;
  color: var(--text-faint);
  text-transform: uppercase;
  margin-bottom: 10px;
}
.settings-row {
  display: flex; align-items: center;
  gap: 10px; margin-top: 8px;
}
.settings-row-col { flex-direction: column; align-items: stretch; }
.settings-label {
  font-size: 11px; color: var(--text-dim); flex: 1;
}
.settings-row-col .settings-label {
  margin-bottom: 4px; flex: 0;
}
.settings-input, .settings-select {
  width: 100%;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 5px;
  color: var(--text);
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  padding: 6px 8px;
  outline: none;
}
.settings-input:focus, .settings-select:focus { border-color: var(--flow); }
.settings-help {
  font-size: 10px; color: var(--text-faint);
  margin-top: 6px;
}
.settings-help a { color: var(--flow); text-decoration: none; }
.settings-help a:hover { text-decoration: underline; }
.settings-status {
  font-size: 10px; color: var(--text-faint);
  margin-top: 8px; min-height: 12px;
}
.settings-status.ok    { color: var(--class); }
.settings-status.err   { color: #f85149; }

/* ── Light theme — variable overrides only ──────────────────────── */
body.theme-light {
  --bg:          #f4f6fa;
  --panel:       #ffffff;
  --panel-2:     #eef1f6;
  --panel-3:     #e3e8f0;
  --border:      #d4dae3;
  --border-hi:   #b7c0cf;
  --text:        #1d2330;
  --text-dim:    #51607a;
  --text-faint:  #8a98ad;

  /* Block-type colors stay broadly the same hues but slightly darker so
     they read well on a light background. */
  --state:       #d96a1d;
  --state-soft:  rgba(217,106,29,0.10);
  --config:      #8550e0;
  --config-soft: rgba(133,80,224,0.10);
  --flow:        #1f6cd6;
  --flow-soft:   rgba(31,108,214,0.10);
  --class:       #009a78;
  --class-soft:  rgba(0,154,120,0.10);
  --verbatim:    #4a5568;
  --verbatim-soft: rgba(74,85,104,0.10);
  --view:        #0890a8;
  --view-soft:   rgba(8,144,168,0.10);
  --import:      #c89200;
  --import-soft: rgba(200,146,0,0.10);

  --file:        #5a7196;
  --file-soft:   rgba(90,113,150,0.06);

  --edge-in:     #1f6cd6;
  --edge-mut:    #d96a1d;
  --edge-call:   #8550e0;
  --edge-self:   #009a78;
  --edge-nest:   #c83669;

  --match-strong: #009a78;
  --match-weak:   #c89200;

  /* CLI-style chat dock overrides — the dock parent paints the surface
     and children stay transparent. Light theme uses a paper-white dock,
     a slightly grey input, and a near-white terminal output box so the
     monospace stream is high-contrast without going jet-black. */
  --dock-bg:        rgba(255,255,255,0.95);
  --input-bg:       rgba(0,0,0,0.04);
  --input-bg-focus: rgba(0,0,0,0.07);
  --input-border:   rgba(0,0,0,0.10);
  --term-bg:        rgba(0,0,0,0.04);
  --term-out-bg:    rgba(0,0,0,0.06);
}
body.theme-light .topbar { background: rgba(255,255,255,0.92); }
body.theme-light .bl-icon { background: var(--panel-2); }
body.theme-light .code-editor { caret-color: var(--flow); }
body.theme-light .topbar .logo .glyph { color: #ffffff; }

/* The chat dock baked in dark rgba() backgrounds in its base rules — they
   need explicit overrides in light mode so the bar/history don't read as
   black panels on a light page. */
body.theme-light .prompt-bar    { background: rgba(255,255,255,0.94); }
body.theme-light .chat-bar      { background: rgba(255,255,255,0.94); }
body.theme-light .chat-history  { background: rgba(238,241,246,0.97); }
body.theme-light .prompt-input::selection { background: rgba(31,108,214,0.20); }
body.theme-light .chat-send:hover { color: #ffffff; }
body.theme-light .mention-chip {
  background: rgba(0,154,120,0.10);
  box-shadow: inset 0 0 0 1px rgba(0,154,120,0.35);
}
body.theme-light .chat-tokens {
  background: rgba(0,154,120,0.10);
  border-color: rgba(0,154,120,0.35);
}
body.theme-light .chat-cost {
  background: rgba(217,106,29,0.10);
  border-color: rgba(217,106,29,0.35);
}
body.theme-light .slash-menu {
  box-shadow: 0 12px 32px rgba(31,40,60,0.18);
}

/* ── Theme dropdown sits in a horizontal row — keep it narrow so the
       label keeps its breathing room instead of being pinched. ──────── */
.settings-select-narrow {
  width: auto;
  min-width: 132px;
  flex: 0 0 auto;
}

/* ── Settings panel: shared button used for account actions + Home ──── */
.settings-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  color: var(--text-dim);
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  padding: 6px 12px;
  border-radius: 5px;
  cursor: pointer;
  text-decoration: none;
  transition: background 120ms, color 120ms, border-color 120ms;
}
.settings-btn:hover {
  background: var(--panel-3);
  border-color: var(--border-hi);
  color: var(--text);
}
.settings-btn-block {
  width: 100%;
  padding: 8px 12px;
}

/* ── Settings panel: account section ─────────────────────────────────── */
.settings-account-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
}
.settings-avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--panel-2);
  border: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--state);
  font-weight: 600;
  font-size: 14px;
  background-size: cover;
  background-position: center;
  flex-shrink: 0;
}
.settings-avatar.has-image { border-color: transparent; }
.settings-account-id { min-width: 0; flex: 1; }
.settings-account-name {
  font-size: 12px;
  color: var(--text);
  font-weight: 500;
  line-height: 1.2;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.settings-account-email {
  font-size: 10px;
  color: var(--text-dim);
  margin-top: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.settings-account-meta {
  margin: 0 0 12px;
  padding: 8px 0;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.settings-account-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 4px 0;
  font-size: 11px;
}
.settings-account-value { color: var(--text); }
.settings-plan-badge {
  display: inline-block;
  padding: 1px 8px;
  background: var(--state-soft);
  border: 1px solid var(--state);
  color: var(--state);
  border-radius: 999px;
  font-size: 10px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.settings-account-actions {
  display: flex;
  gap: 8px;
}
.settings-account-actions .settings-btn { flex: 1; }

/* ─────────────────────────────────────────────────────────────────────
   Midnight — very dark, cool violet/navy
   ───────────────────────────────────────────────────────────────────── */
body.theme-midnight {
  --bg:          #050616;
  --panel:       #0a0d24;
  --panel-2:     #0f1330;
  --panel-3:     #161b40;
  --border:      #1d2150;
  --border-hi:   #2a306a;
  --text:        #e8edff;
  --text-dim:    #8c92c4;
  --text-faint:  #4d5388;

  --state:       #ff7eb9;
  --state-soft:  rgba(255,126,185,0.10);
  --config:      #a98bff;
  --config-soft: rgba(169,139,255,0.10);
  --flow:        #4a90ff;
  --flow-soft:   rgba(74,144,255,0.08);
  --class:       #2dd4bf;
  --class-soft:  rgba(45,212,191,0.07);
  --verbatim:    #4a5568;
  --verbatim-soft: rgba(74,85,104,0.15);
  --view:        #06b6d4;
  --view-soft:   rgba(6,182,212,0.08);
  --import:      #ffd166;
  --import-soft: rgba(255,209,102,0.08);

  --file:        #7a98c4;
  --file-soft:   rgba(122,152,196,0.06);

  --edge-in:     #4a90ff;
  --edge-mut:    #ff7eb9;
  --edge-call:   #a98bff;
  --edge-self:   #2dd4bf;
  --edge-nest:   #ff5d8f;

  --match-strong: #2dd4bf;
  --match-weak:   #ffd166;

  /* CLI-style chat dock overrides for midnight — deep navy surface. */
  --dock-bg:        rgba(5,6,22,0.95);
  --input-bg:       rgba(15,19,48,0.55);
  --input-bg-focus: rgba(15,19,48,0.75);
  --input-border:   rgba(255,255,255,0.05);
  --term-bg:        rgba(10,13,36,0.65);
  --term-out-bg:    rgba(0,0,0,0.45);
}
body.theme-midnight .topbar       { background: rgba(5,6,22,0.90); }
body.theme-midnight .prompt-bar   { background: rgba(5,6,22,0.94); }
body.theme-midnight .chat-bar     { background: rgba(5,6,22,0.94); }
body.theme-midnight .chat-history { background: rgba(10,13,36,0.97); }

/* ─────────────────────────────────────────────────────────────────────
   Blue — saturated azure, brighter than the default dark
   ───────────────────────────────────────────────────────────────────── */
body.theme-blue {
  --bg:          #0f1f3d;
  --panel:       #142950;
  --panel-2:     #1a345f;
  --panel-3:     #213f70;
  --border:      #2a4677;
  --border-hi:   #3d5b98;
  --text:        #e6f0fc;
  --text-dim:    #9cb3d4;
  --text-faint:  #6080a8;

  --state:       #ff8c42;
  --state-soft:  rgba(255,140,66,0.12);
  --config:      #c594ff;
  --config-soft: rgba(197,148,255,0.12);
  --flow:        #6ec1ff;
  --flow-soft:   rgba(110,193,255,0.10);
  --class:       #5ee3c8;
  --class-soft:  rgba(94,227,200,0.10);
  --verbatim:    #5a6680;
  --verbatim-soft: rgba(90,102,128,0.15);
  --view:        #00d4f0;
  --view-soft:   rgba(0,212,240,0.08);
  --import:      #ffd166;
  --import-soft: rgba(255,209,102,0.10);

  --file:        #94b0d4;
  --file-soft:   rgba(148,176,212,0.06);

  --edge-in:     #6ec1ff;
  --edge-mut:    #ff8c42;
  --edge-call:   #c594ff;
  --edge-self:   #5ee3c8;
  --edge-nest:   #ff5d8f;

  --match-strong: #5ee3c8;
  --match-weak:   #ffd166;

  /* CLI-style chat dock overrides for blue — saturated azure surface. */
  --dock-bg:        rgba(15,31,61,0.95);
  --input-bg:       rgba(20,41,80,0.55);
  --input-bg-focus: rgba(20,41,80,0.75);
  --input-border:   rgba(255,255,255,0.06);
  --term-bg:        rgba(20,41,80,0.65);
  --term-out-bg:    rgba(0,0,0,0.40);
}
body.theme-blue .topbar       { background: rgba(15,31,61,0.90); }
body.theme-blue .prompt-bar   { background: rgba(15,31,61,0.94); }
body.theme-blue .chat-bar     { background: rgba(15,31,61,0.94); }
body.theme-blue .chat-history { background: rgba(20,41,80,0.97); }

/* ─────────────────────────────────────────────────────────────────────
   Rusty Leaf — matches the marketing landing page palette.
   Warm near-black, orange accent, all block-type colors leaning warm.
   ───────────────────────────────────────────────────────────────────── */
body.theme-rusty {
  --bg:          #0d0a08;
  --panel:       #1a1410;
  --panel-2:     #221912;
  --panel-3:     #2e2218;
  --border:      #2a2118;
  --border-hi:   #3d2f22;
  --text:        #f0eae3;
  --text-dim:    #a39a8b;
  --text-faint:  #6a5d4f;

  --state:       #ff9e5e;
  --state-soft:  rgba(255,158,94,0.12);
  --config:      #d68bff;
  --config-soft: rgba(214,139,255,0.10);
  --flow:        #ffb96a;
  --flow-soft:   rgba(255,185,106,0.10);
  --class:       #8ad48f;
  --class-soft:  rgba(138,212,143,0.10);
  --verbatim:    #6a5d4f;
  --verbatim-soft: rgba(106,93,79,0.18);
  --view:        #5fbfb0;
  --view-soft:   rgba(95,191,176,0.10);
  --import:      #ffd166;
  --import-soft: rgba(255,209,102,0.10);

  --file:        #b89678;
  --file-soft:   rgba(184,150,120,0.07);

  --edge-in:     #ffb96a;
  --edge-mut:    #ff9e5e;
  --edge-call:   #d68bff;
  --edge-self:   #8ad48f;
  --edge-nest:   #e85d8f;

  --match-strong: #8ad48f;
  --match-weak:   #ffd166;

  /* CLI-style chat dock overrides for rusty — warm near-black surface. */
  --dock-bg:        rgba(13,10,8,0.95);
  --input-bg:       rgba(34,25,18,0.65);
  --input-bg-focus: rgba(46,34,24,0.80);
  --input-border:   rgba(255,255,255,0.05);
  --term-bg:        rgba(26,20,16,0.70);
  --term-out-bg:    rgba(0,0,0,0.40);
}
body.theme-rusty .topbar       { background: rgba(13,10,8,0.90); }
body.theme-rusty .prompt-bar   { background: rgba(13,10,8,0.94); }
body.theme-rusty .chat-bar     { background: rgba(13,10,8,0.94); }
body.theme-rusty .chat-history { background: rgba(26,20,16,0.97); }

/* ════════════════════════════════════════════════════════════════════════
   Embedded terminal in chat + chats dropdown
   ──────────────────────────────────────────────────────────────────────── */

/* /terminal chat bubble — slim card with a $-prompt and a fixed-height
   scrolling output box. Output capped at ~25 lines so a chatty `pip install`
   doesn't push the rest of the conversation off-screen. */
.chat-msg.terminal {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 8px 0;
  /* Same indent as assistant text/agent (2px line + 12px pad = 14px),
     distinct green line. No outer box — just the line + the term-out bg. */
  padding-left: 12px;
  border-left: 2px solid #2ec27e;
  font-family: 'JetBrains Mono', monospace;
}
.chat-msg.terminal .cm-meta {
  display: flex; align-items: center; gap: 6px;
  margin: 0;
}
.chat-msg.terminal .term-cmd {
  font-size: 11.5px;
  color: var(--text);
  white-space: pre-wrap;
  word-break: break-all;
  line-height: 1.45;
}
.chat-msg.terminal .term-prompt {
  color: #2ec27e;
  font-weight: 600;
  margin-right: 6px;
  user-select: none;
}
.chat-msg.terminal .term-out {
  margin: 0;
  padding: 8px 10px;
  background: var(--term-out-bg);
  border-radius: 4px;
  font-size: 11px;
  line-height: 1.45;
  color: var(--text-dim);
  /* 25-line cap. line-height(1.45) × font-size(11) × 25 ≈ 400px */
  max-height: 400px;
  overflow-y: auto;
  white-space: pre-wrap;
  word-break: break-word;
  scrollbar-width: thin;
}
.chat-msg.terminal .term-out:empty::before {
  content: 'waiting for output…';
  color: var(--text-dim);
  opacity: 0.6;
  font-style: italic;
}
/* Right-cluster wrapper inside .cm-meta — holds the stop button (when
   running) and the collapse toggle. Pushed to the right edge of the
   meta row so the chips stay left-aligned. */
.term-meta-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
}
.term-cancel {
  padding: 2px 8px;
  font-size: 10px;
  font-family: inherit;
  background: rgba(248,81,73,0.10);
  color: #ff7b72;
  border: 1px solid rgba(248,81,73,0.30);
  border-radius: 3px;
  cursor: pointer;
}
.term-cancel:hover { background: rgba(248,81,73,0.18); }

.term-toggle {
  padding: 1px 7px;
  font-size: 11px;
  line-height: 1.2;
  font-family: 'JetBrains Mono', monospace;
  background: transparent;
  color: var(--text-dim);
  border: 1px solid var(--border);
  border-radius: 3px;
  cursor: pointer;
}
.term-toggle:hover {
  border-color: var(--border-hi);
  color: var(--text);
}
.chat-msg.terminal.collapsed .term-out { display: none; }

/* Chip variants used by terminal bubbles */
.cm-chip.terminal {
  background: rgba(138,212,143,0.14);
  color: var(--match-strong);
  border: 1px solid rgba(138,212,143,0.32);
}
.cm-chip.ai-term {
  background: rgba(125,200,255,0.14);
  color: #79c0ff;
  border: 1px solid rgba(125,200,255,0.32);
}
.cm-chip.running {
  background: rgba(255,209,102,0.12);
  color: var(--match-weak);
  border: 1px solid rgba(255,209,102,0.30);
  display: inline-flex; align-items: center; gap: 6px;
}
.cm-chip.done {
  background: rgba(138,212,143,0.10);
  color: var(--match-strong);
  border: 1px solid rgba(138,212,143,0.25);
}
.cm-chip.cancelled {
  background: rgba(248,81,73,0.10);
  color: #ff7b72;
  border: 1px solid rgba(248,81,73,0.30);
}

/* ── Chats dropdown — floating panel anchored under the "⌬ Chats" button.
      Per-project chat list, sorted by most recent activity. */
.chats-dropdown {
  position: fixed;
  top: -9999px;       /* off-screen until .open positions it */
  right: 16px;
  width: 340px;
  max-height: 70vh;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 12px 40px rgba(0,0,0,0.55);
  z-index: 500;
  opacity: 0;
  transform: translateY(-6px);
  pointer-events: none;
  transition: opacity 0.12s ease, transform 0.12s ease;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.chats-dropdown.open {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}
/* Stop button in the chat-bar — visible only while a turn is in flight
   (body.chat-busy added by runTurn, removed in its finally / by stop). */
.chat-stop {
  display: none;
  margin-right: 8px;
  padding: 2px 10px;
  font-size: 10px;
  font-family: 'JetBrains Mono', monospace;
  background: rgba(248,81,73,0.10);
  color: #ff7b72;
  border: 1px solid rgba(248,81,73,0.30);
  border-radius: 3px;
  cursor: pointer;
}
.chat-stop:hover { background: rgba(248,81,73,0.18); }
body.chat-busy .chat-stop { display: inline-block; }

.chats-dropdown-search {
  margin: 8px 12px 6px;
  padding: 6px 10px;
  background: var(--panel-3);
  border: 1px solid var(--border);
  border-radius: 5px;
  color: var(--text);
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  outline: none;
}
.chats-dropdown-search:focus {
  border-color: var(--flow);
}
.chats-dropdown-search::placeholder {
  color: var(--text-faint);
}

.chats-dropdown-header {
  padding: 10px 14px;
  font-family: 'Syne', sans-serif;
  font-weight: 700; font-size: 10px;
  letter-spacing: 0.6px;
  color: var(--match-strong);
  border-bottom: 1px solid var(--border);
  text-transform: uppercase;
}
.chats-dropdown-list {
  overflow-y: auto;
  flex: 1;
  padding: 4px 0;
}
.chats-dd-empty {
  padding: 16px 14px;
  font-size: 12px;
  color: var(--text-dim);
  text-align: center;
  font-style: italic;
}
.chats-dd-item.active {
  background: rgba(138,212,143,0.06);
  box-shadow: inset 3px 0 0 var(--match-strong);
}
.chats-dd-item {
  display: block;
  width: 100%;
  text-align: left;
  background: transparent;
  border: none;
  border-bottom: 1px solid rgba(255,255,255,0.04);
  padding: 10px 14px;
  cursor: pointer;
  font-family: inherit;
  color: var(--text);
  transition: background 0.08s ease;
}
.chats-dd-item:last-child { border-bottom: none; }
.chats-dd-item:hover { background: var(--panel-2); }
.chats-dd-row1 {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px;
  margin-bottom: 3px;
}
.chats-dd-name {
  font-weight: 600;
  font-size: 12.5px;
  color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  flex: 1;
}
.chats-dd-when {
  font-size: 10px;
  color: var(--text-dim);
  white-space: nowrap;
  flex-shrink: 0;
}
.chats-dd-row2 {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px;
}
.chats-dd-preview {
  font-size: 11px;
  color: var(--text-dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  flex: 1;
  font-family: 'JetBrains Mono', monospace;
}
.chats-dd-count {
  font-size: 10px;
  color: var(--text-dim);
  opacity: 0.7;
  white-space: nowrap;
  flex-shrink: 0;
}

/* ── Interactive shell mode (bare /terminal) ─────────────────────────
   When body.terminal-mode is set, the prompt-bar pretends to be a shell
   prompt — a $ glyph in front of the input, monospace input text, match-
   strong focus colour. Theme-aware via --term-bg / --term-out-bg so the
   shell look adapts: dim grey in light, deep navy in midnight, etc. */
body.terminal-mode .prompt-bar {
  /* !important needed to beat the CLI-merge rule that forces the prompt
     bar transparent so it blends with the dock surface. In shell mode we
     deliberately want a distinct background so the user sees the shift. */
  background: var(--term-out-bg) !important;
  border-top: 1px solid var(--match-strong) !important;
}
body.terminal-mode .prompt-input-wrap {
  background: var(--term-bg);
  border: 1px solid var(--match-strong);
  border-color: color-mix(in srgb, var(--match-strong) 40%, transparent);
  /* Default rule clears border-radius for the chat-mode flat look; shell
     mode wants the visible boxed prompt back. */
  border-radius: 8px;
}
body.terminal-mode .prompt-input-wrap:focus-within {
  border-color: var(--match-strong);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--match-strong) 10%, transparent);
}
body.terminal-mode .prompt-input-wrap::before {
  content: '$';
  display: flex; align-items: center;
  padding: 0 8px 0 12px;
  color: var(--match-strong);
  font-family: 'JetBrains Mono', monospace;
  font-weight: 700;
  font-size: 14px;
  user-select: none;
}
/* Make the input + highlight overlay sit to the right of the $ glyph.
   The textarea is a flex child so it sits after the ::before $ block
   naturally. The highlight overlay is position:absolute inset:0, so
   without a left offset its rendered glyphs would start at the wrap's
   left edge and overlap the $. Match the $ block's outer width:
   padding 12 + glyph (~8 at 14px JetBrains Mono) + padding 8 ≈ 28px;
   round to 30 for a small visual gap. */
body.terminal-mode .prompt-input,
body.terminal-mode .prompt-input-hl {
  padding-left: 0;
}
body.terminal-mode .prompt-input-hl {
  left: 30px;
}
body.terminal-mode .prompt-status::after {
  content: '· Esc to exit';
  opacity: 0.6;
  margin-left: 6px;
  font-weight: 400;
  text-transform: none;
}

/* Hide the standalone terminal panel — chat now owns the terminal UX via
   the /terminal slash command. We can't use `display: none` because the
   xterm.js renderer needs a real-sized container to initialise (the chat
   terminal bubbles piggyback on the WS that xterm's init opens). Pulling
   it out of layout with position:absolute keeps it functional but invisible
   AND removes it from the editor-panel flex so the chat dock owns that
   space. */
.terminal-panel {
  position: absolute !important;
  left: -99999px;
  top: 0;
  width: 600px;
  height: 400px;
  visibility: hidden;
  pointer-events: none;
}
.terminal-panel.open { flex: none !important; }   /* override the 30% open rule */

/* When the user clicks the Terminal toggle in the editor toolbar, bring
   the panel back on-screen as a floating overlay (bottom-right of the
   editor). The xterm.js renderer keeps the same container — we're just
   undoing the off-screen positioning. Esc / × hide it again. */
.terminal-panel.visible {
  position: fixed !important;
  left: auto;
  right: 16px;
  bottom: 16px;
  top: auto;
  width: min(720px, calc(100vw - 32px));
  height: min(420px, calc(100vh - 32px));
  visibility: visible;
  pointer-events: auto;
  z-index: 9000;
  box-shadow: 0 16px 60px rgba(0,0,0,0.5);
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg);
  display: flex;
  flex-direction: column;
}
.terminal-panel.visible .terminal-header {
  cursor: grab;
}
.btn.btn-terminal-toggle[aria-pressed="true"] {
  background: var(--accent, #ff9e5e);
  color: #1a0e00;
}

/* ════════════════════════════════════════════════════════════════════════
   CLI-style merged chat pane
   ──────────────────────────────────────────────────────────────────────── */

/* Chat dock reads as a single pane: history scrolls, the input is the last
   line of that same pane. Shared background + no border between history
   and prompt-bar = no visible seam. The chat-bar (CHAT / token meter /
   minimize) shrinks to a slim status strip rather than a separator.
   Background is driven by --dock-bg so each theme tints it appropriately
   (paper-white in light, deep navy in midnight, etc.). */
.chat-dock {
  background: var(--dock-bg);
  backdrop-filter: blur(16px);
  border-top: 1px solid var(--border);
}
.chat-history,
.chat-history.has-history,
.prompt-bar {
  background: transparent !important;
  border-top: none !important;
  backdrop-filter: none !important;
}
.prompt-bar { min-height: auto; }
.prompt-bar-inner { padding: 6px 16px 14px; }
.chat-history-inner { padding: 16px 16px 4px; }

/* The chat-bar shrinks to a slim status line. The "CHAT" title is hidden
   (it's redundant — the conversation IS the pane). Token meter + minimize
   stay since they carry real info. */
.chat-bar {
  padding: 4px 16px !important;
  border-top: none !important;
  background: transparent !important;
  font-size: 10px !important;
}
.chat-bar-title { display: none !important; }
.chat-bar-count { color: var(--text-faint); }

/* The 1-hop / send / clear buttons are removed from index.html — these
   rules keep cached old DOM (stale client tab) from showing them. */
#prompt-expand,
.prompt-expand,
#chat-send,
.chat-send,
#chat-clear,
.chat-clear { display: none !important; }

/* Input loses ALL its chrome — no background, no border, no rounded
   corners. The single 1px line above (.prompt-loading-bar) is the only
   visual separator from the chat history; the typing area below it is
   just text against the dock surface. Cleaner, more terminal-like. */
.prompt-input-wrap {
  background: transparent;
  border: 1px solid transparent;
  border-radius: 0;
}
.prompt-input-wrap:focus-within {
  background: transparent;
  border-color: transparent;
}

/* Status pill (dot + "idle / routing… / rebuilding…") is hidden in chat
   mode — its text is now rendered inside the active assistant bubble
   while a turn is in flight. Terminal mode still shows it because the
   "shell mode · Esc to exit" hint lives in this same pill. */
.prompt-status { display: none; }
body.terminal-mode .prompt-status {
  display: flex;
  min-width: 60px;
}
body.terminal-mode .prompt-status #prompt-status-text {
  font-size: 10px;
  opacity: 0.7;
}

/* The single 1px line above the typing area. Sits at the top edge of
   the prompt-bar. Static var(--border) by default; when body.chat-busy
   an indeterminate gradient sweeps along it left-to-right so the user
   has a visual cue that a turn is in flight (the textual cue lives in
   the assistant bubble). */
.prompt-loading-bar {
  position: absolute;
  top: 0;
  left: 0; right: 0;
  height: 1px;
  background: var(--border);
  overflow: hidden;
  pointer-events: none;
  z-index: 1;
}
.prompt-loading-bar::before {
  content: '';
  position: absolute;
  top: 0;
  left: -30%;
  width: 30%;
  height: 100%;
  background: linear-gradient(
    90deg,
    transparent 0%,
    var(--match-strong) 50%,
    transparent 100%
  );
  opacity: 0;
}
body.chat-busy .prompt-loading-bar::before {
  opacity: 1;
  animation: prompt-loading-slide 1.6s linear infinite;
}
@keyframes prompt-loading-slide {
  0%   { left: -30%; }
  100% { left: 100%; }
}

/* ── ⌬ Chats button — bumped visibility ──────────────────────────────
   User couldn't spot it in the toolbar. Subtle accent makes it stand
   out as "different mode" alongside Projects / Inspect / Preview. */
.btn-chats {
  border-color: rgba(138,212,143,0.40) !important;
  color: var(--match-strong) !important;
  background: rgba(138,212,143,0.08) !important;
}
.btn-chats:hover {
  background: rgba(138,212,143,0.18) !important;
  border-color: var(--match-strong) !important;
}

/* ── + New chat button ───────────────────────────────────────────── */
.btn-new-chat {
  color: var(--text-dim);
  border-color: var(--border);
}
.btn-new-chat:hover {
  color: var(--match-strong);
  border-color: rgba(138,212,143,0.40);
  background: rgba(138,212,143,0.06);
}

/* ── RUN tag chip (third intent type alongside ASK / EDIT) ──────────
   The classifier returns tag='run' when the user wants something
   executed in the shell instead of changed in code. Chip styling
   borrows from the terminal-bubble palette so the conversation
   visually links the routing decision to the resulting bubble. */
.cm-chip.run {
  background: rgba(138,212,143,0.14);
  color: var(--match-strong);
  border: 1px solid rgba(138,212,143,0.32);
}