:root {
  color-scheme: dark;
  --bg: #0d1117;
  --fg: #e6edf3;
  --muted: #8b949e;
  --accent: #58a6ff;
  --border: #30363d;
  --card: #161b22;
  --ok: #3fb950;
  --warn: #d29922;
  --err: #f85149;
  --coach: #d29922;
  --player: #58a6ff;
  --tool: #a371f7;
}
*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font: 13px/1.5 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  overflow: hidden;
}

/* ---- app shell ---- */
.app {
  display: grid;
  grid-template-columns: 44px 1fr;
  height: 100vh;
  min-height: 0;
}
.app.env-open {
  grid-template-columns: 44px 1fr 340px;
}
@media (max-width: 900px) {
  .app.env-open { grid-template-columns: 44px 1fr 280px; }
}

/* ============================================================
   Mobile layout — phones < 700px wide.
   Two big changes:
     1. The left rail moves to the bottom and splits into two
        rows: agents on top, files+pause+env+settings beneath.
     2. The panes area becomes a horizontal swipe deck — one
        pane fills the screen at a time, scroll-snap to switch.
   Drag-to-move (HTML5 DnD), Split.js gutters, layout presets,
   and cancel-all are hidden — they don't fit single-pane swipe
   and HTML5 DnD doesn't work on touch anyway. EnvPane becomes
   a full-screen overlay.
   ============================================================ */
@media (max-width: 700px) {
  .app, .app.env-open {
    /* Override the inline-style grid-template-columns set by App. */
    grid-template-columns: 1fr !important;
    grid-template-rows: 1fr auto !important;
    /* Mobile browser chrome can make 100vh extend below the visible
       screen. Keep the bottom rail inside the live viewport. */
    height: 100svh;
    height: 100dvh;
    max-height: 100dvh;
    overflow: hidden;
  }
  /* Explicit grid-row placement: panes take the flexible top row,
     rail takes the auto-sized bottom row. */
  .panes { grid-row: 1; }
  /* Rail at the bottom — simple stacked flex.
       Row 1: rail-agents (own block, scrolls horizontally).
       Row 2: rail-bottom — a single flex-row container that holds
              ws-dot + rail-files + rail-controls (grow) + rail-env.
     Wrapping the bottom items in their own DOM container is the only
     approach that consistently survives Android Chrome (we tried
     display:contents, then explicit CSS Grid, then flex-wrap; each
     one reverted to vertical stacking on some Chromium build). */
  .rail {
    grid-row: 2;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    border-right: none;
    border-top: 1px solid var(--border);
    padding: 0 0 max(2px, env(safe-area-inset-bottom));
    gap: 0;
    overflow: visible;
    background: var(--bg);
  }
  .rail > .rail-ws-dot { display: none; }
  .rail .mobile-ws-dot {
    display: block;
    margin: 0 5px 0 2px;
    width: 7px;
    height: 7px;
    flex: 0 0 auto;
    align-self: center;
  }
  .rail-group {
    margin-top: 0 !important;
    flex-direction: row !important;
    align-items: center;
    gap: 3px;
    padding: 1px 4px;
  }
  .rail-group.rail-agents {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    border-bottom: 1px solid var(--border);
    padding: 1px 5px;
    gap: 0;
    justify-content: space-between;
  }
  .rail-group.rail-agents::-webkit-scrollbar { display: none; }
  /* All `!important` here because the mobile @media block sits BEFORE
     the desktop `.rail-bottom` rule in source order, so the cascade
     would otherwise let desktop values win on mobile screens.
     Flex (not grid) so the tools group can absorb whatever width is
     left after ws-dot + actions, and the 6 tool buttons compress
     evenly to fit on a single row even on narrow phones (kanban no
     longer wraps to a 2nd line). */
  .rail-bottom {
    display: flex !important;
    flex-direction: row !important;
    flex-wrap: nowrap !important;
    align-items: center !important;
    width: 100% !important;
    flex: 0 0 auto !important;
    padding: 1px 4px !important;
    gap: 2px !important;
    overflow-x: hidden;
  }
  .rail-group.rail-tools,
  .rail-group.rail-actions { flex-wrap: nowrap !important; }
  .rail-bottom .rail-group { padding: 0; }
  .rail-bottom .mobile-ws-dot { flex: 0 0 auto; }
  /* Hairline dividers are vertical-rail decoration only — the mobile
     bottom bar relies on the gap + flex grouping for visual breaks. */
  .rail-bottom > .rail-divider { display: none; }
  /* Tools (files/project/compass/kanban/recurrence/env) take all the
     remaining width; flex children shrink so 6 26px-buttons fit a
     ~280px-wide gap on a 360px screen without any of them dropping
     to a second line. justify-content: space-between spreads them
     evenly within the available space. */
  .rail-group.rail-tools {
    display: flex !important;
    flex: 1 1 auto;
    flex-direction: row !important;
    align-items: center;
    justify-content: space-between;
    gap: 0;
    min-width: 0;
  }
  /* Actions (pause + settings; cancel-all when working) sit at the
     right end with their natural content width. */
  .rail-group.rail-actions {
    display: flex !important;
    flex: 0 0 auto;
    flex-direction: row !important;
    align-items: center;
    gap: 3px;
  }
  .rail-group.rail-actions .rail-layout-presets {
    display: contents;
  }
  /* Compact gear footprint on mobile. flex-shrink: 1 lets the 7
     tools buttons (files / project / compass / playbook / kanban /
     recurrence / env) squeeze below the nominal width if a 320px
     phone needs it, instead of one wrapping to a second row. */
  .rail-bottom .gear {
    width: 22px;
    height: 22px;
    flex: 0 1 22px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    min-width: 16px;
    padding: 0 !important;
  }
  /* The project-switcher wrapper is a flex child of rail-tools (not
     the .gear button itself), so propagate the same shrink rule
     to it explicitly. */
  .rail-group.rail-tools .project-switcher {
    flex: 0 1 22px;
    min-width: 16px;
  }
  /* Override the desktop rail-actions size rules at mobile width too,
     so pause + settings can shrink alongside the tools instead of
     hogging fixed 26px each and forcing the row to wrap. */
  .rail-group.rail-actions .gear,
  .rail-group.rail-actions .gear.pause-toggle,
  .rail-group.rail-actions .gear.settings-toggle {
    width: 22px !important;
    height: 22px !important;
    min-width: 16px !important;
    flex: 0 1 22px !important;
    font-size: 13px !important;
  }
  .rail-bottom .gear.project-placeholder {
    width: 24px;
    font-size: 11px;
  }
  .rail-bottom .files-icon {
    width: 14px;
    height: 11px;
  }
  .rail-bottom .compass-icon,
  .rail-bottom .playbook-icon,
  .rail-bottom .recurrence-icon { width: 15px; height: 15px; }
  .rail-bottom .compass-icon svg,
  .rail-bottom .playbook-icon svg,
  .rail-bottom .recurrence-icon svg { width: 100%; height: 100%; }
  /* Tighter slot buttons on mobile so 11 slots fit without scroll on
     360px-wide phones. */
  .rail-group.rail-agents .slot {
    width: 25px;
    height: 24px;
    flex: 0 0 25px;
    border-radius: 5px;
  }
  .rail-group.rail-agents .slot-dot { display: none; }
  .rail-group.rail-agents .slot.open::before {
    width: 2px;
    top: 4px;
    bottom: 4px;
  }
  /* Hide controls that don't fit single-pane swipe view. */
  .gear.layout-preset,
  .gear.cancel-all { display: none; }

  /* Panes: full-width horizontal swipe. */
  .panes {
    overflow-x: auto !important;
    overflow-y: hidden !important;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
  }
  .pane-col {
    flex: 0 0 100% !important;
    min-width: 100% !important;
    max-width: 100%;
    border-right: none;
    scroll-snap-align: start;
    scroll-snap-stop: always;
  }
  /* Split.js gutters get in the way of swipe — hide them. The
     `+ .gutter +` adjacent-sibling combinators target the gutters
     Split.js injects between cols regardless of where they land. */
  .panes > .gutter,
  .pane-col > .gutter,
  .gutter.gutter-horizontal,
  .gutter.gutter-vertical { display: none !important; }
  /* DropZones (HTML5 DnD pane reorganization) don't work on touch. */
  .drop-zone { display: none !important; }
  /* Maximize button is meaningless in single-pane view. */
  .pane-maximize { display: none; }

  /* EnvPane: full-screen overlay when toggled open. */
  .env-pane {
    position: fixed;
    inset: 0;
    z-index: 30;
    border-left: none;
  }
  .env-resizer { display: none; }

  /* Pane input area on mobile — vertical stack: modes-row (with run
     button inside) → textarea. Run button is sticky-right inside the
     scrollable modes row so chip overflow can't push it off-screen. */
  .pane-input {
    padding: 6px 8px;
  }
  .pane-input > .pane-modes {
    margin: 0 0 4px;
    flex-wrap: nowrap !important;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    align-items: center;
    gap: 4px;
  }
  .pane-input > .pane-input-wrap { margin-top: 0; }
  .pane-modes-run {
    position: sticky;
    right: 0;
    min-height: 32px;
    padding: 4px 14px !important;
    font-size: 12px !important;
    flex: 0 0 auto;
  }
  /* Slash-commands chip — redundant on mobile; user can just type "/"
     in the prompt, the SlashMenu opens the same way. */
  .pane-mode-chip.pane-mode-slash { display: none; }
  .pane-modes-spacer { display: none; }
  /* CTX chip: tight pill, no track graph. */
  .pane-mode-chip.context-bar {
    gap: 3px;
    min-width: 0;
    padding: 1px 6px;
    border-radius: 9px;
  }
  .pane-mode-chip.context-bar .context-bar-label {
    min-width: 0;
    font-size: 9px;
  }
  /* Tighter chips overall on mobile so model/plan/effort/ctx fit. */
  .pane-mode-chip {
    padding: 1px 7px;
    font-size: 11px;
    border-radius: 9px;
  }
}

/* ---- left rail ---- */
.rail {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 8px 0;
  border-right: 1px solid var(--border);
  gap: 4px;
  overflow-y: auto;
}
/* Three logical groups in the rail (top → bottom):
     rail-agents   the team (Coach + 10 Players)
     rail-tools    files / project / compass / kanban / recurrence / env
     rail-actions  pause-play, layout presets, cancel-all, settings
   Agents sit at the top, then a hairline `rail-divider`, then tools,
   another divider, then actions. The actions group is pinned to the
   bottom via a `margin-top: auto` on its leading divider. */
.rail-group {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.rail-group.rail-agents { gap: 2px; }
/* Tighter vertical footprint for the 11 team slots — the rail was
   getting crowded once the bottom groups grew. Width stays 32 so the
   labels and ::before accent stripe geometry are unchanged. */
.rail-group.rail-agents .slot { height: 26px; }
.rail-group.rail-agents .slot.open::before { top: 4px; bottom: 4px; }
/* Desktop: rail-bottom is a transparent flex column that takes the
   remaining vertical space below rail-agents. Mobile (< 700px)
   overrides this to a 6-col grid inline. */
.rail-bottom {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex: 1 1 auto;
  width: 100%;
  gap: 4px;
}
/* Hairline section separator between agents / tools / actions. The
   second divider (the one after rail-tools, sitting just above
   rail-actions) gets `margin-top: auto` so the actions group sticks
   to the bottom of the rail regardless of how tall the rail is. */
.rail-divider {
  width: 22px;
  height: 1px;
  background: var(--border);
  flex: 0 0 1px;
  margin: 2px 0;
}
.rail-bottom > .rail-tools ~ .rail-divider { margin-top: auto; }
/* All buttons in rail-actions (cancel-all, pause, the two layout
   presets, settings) share a single footprint so the parent's flex
   `gap: 4px` reads as visually equal spacing between every button.
   Without this, the gears default to 32×32 while the layout presets
   were 24×20, making the gaps look uneven on a vertical rail. */
.rail-group.rail-actions .gear,
.rail-group.rail-actions .gear.pause-toggle,
.rail-group.rail-actions .gear.layout-preset,
.rail-group.rail-actions .gear.cancel-all,
.rail-group.rail-actions .gear.settings-toggle {
  width: 26px;
  height: 22px;
  padding: 0;
  font-size: 14px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
/* The two layout presets share a wrapper for the JSX conditional,
   but visually they should sit in the same column rhythm as their
   siblings (cancel-all, pause-toggle, settings). `display: contents`
   makes the wrapper layout-transparent so both inner buttons inherit
   the parent rail-actions group's 4px gap. */
.rail-group.rail-actions .rail-layout-presets {
  display: contents;
}
@keyframes ws-disconnected-pulse {
  0%, 100% { opacity: 1; box-shadow: 0 0 0 0 rgba(255, 80, 100, 0.5); }
  50%      { opacity: 0.4; box-shadow: 0 0 0 4px rgba(255, 80, 100, 0); }
}

.ws-dot {
  display: block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--err);
  animation: ws-disconnected-pulse 1.6s ease-in-out infinite;
  margin: 4px 0 10px;
}
.ws-dot.ok {
  background: var(--ok);
  animation: none;
  box-shadow: none;
}
.mobile-ws-dot { display: none; }
/* ---- Slot button design system ----
   Two orthogonal dimensions encoded in a single button:

   1. Work state → background tint + label color
        unused      no session_id ever       transparent / gray label
        state-idle  has session, idle         blue tint / blue label
        state-working                        amber tint / amber label, pulsing
        state-problem (error|cost_capped|cancelled)
                                             red tint / red label

   2. Comms state → small dot indicator (top-left of the button)
        green   ready, nothing pending
        blue    has unread inbox to address
        orange  idle with task, waiting for a reply

   Plus two binary modifiers:
        .open       3px accent stripe on the LEFT EDGE — primary
                    "where am I looking right now" signal.
        .locked     desaturated tint + tiny lock badge bottom-right.
                    Reads as "off the team" at a glance.
*/
.slot {
  position: relative;
  width: 32px;
  height: 32px;
  border-radius: 6px;
  border: 0;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 3px;
  transition: color 80ms, background 80ms, box-shadow 80ms, filter 80ms;
}
.slot:hover { filter: brightness(1.25); }
.slot .slot-label { line-height: 1; }
/* Inactive — never spawned. No background; just a muted number. */
.slot.unused {
  color: var(--muted);
  background: transparent;
}
/* Activated, idle. Blue tint + blue number. */
.slot.state-idle {
  background: rgba(88, 166, 255, 0.14);
  color: var(--accent);
}
/* Activated, currently running a turn. Glowing amber pulse. */
.slot.state-working {
  background: rgba(210, 153, 34, 0.18);
  color: var(--warn);
  animation: slot-working-pulse 2s ease-in-out infinite;
}
@keyframes slot-working-pulse {
  0%, 100% { box-shadow: 0 0 4px rgba(210, 153, 34, 0.35); }
  50%      { box-shadow: 0 0 12px rgba(210, 153, 34, 0.75); }
}
/* Activated but in trouble — error / cost-capped / cancelled all
   collapse to the same red signal so the user clicks in to see why. */
.slot.state-problem {
  background: rgba(248, 81, 73, 0.14);
  color: var(--err);
}
/* Pane currently open — left-edge accent stripe. Sits inside the
   button via ::before so it doesn't affect content layout, and works
   alongside any state-* background tint. */
.slot.open::before {
  content: "";
  position: absolute;
  left: 0;
  top: 5px;
  bottom: 5px;
  width: 3px;
  border-radius: 2px;
  background: var(--accent);
  box-shadow: 0 0 4px rgba(88, 166, 255, 0.6);
}
/* Locked — desaturated and dimmed; small lock badge bottom-right. */
.slot.locked {
  filter: grayscale(0.65) brightness(0.8);
  opacity: 0.75;
}
.slot.locked:hover { filter: grayscale(0.65) brightness(1); opacity: 1; }
.slot-lock {
  position: absolute;
  bottom: 1px;
  right: 1px;
  font-size: 8px;
  line-height: 1;
  pointer-events: none;
  filter: drop-shadow(0 0 2px var(--bg));
}
/* Comms-state dot. Sits inline next to the label (right side); a flex
   gap on .slot keeps a small breathing space. Only renders for
   activated agents. */
.slot-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  pointer-events: none;
  flex: 0 0 auto;
}
.slot-dot.dot-green  { background: var(--ok); }
.slot-dot.dot-blue   { background: var(--accent); box-shadow: 0 0 4px var(--accent); }
.slot-dot.dot-orange { background: #f0883e; box-shadow: 0 0 4px #f0883e; }
.gear {
  width: 32px;
  height: 32px;
  border: 0;
  background: transparent;
  color: var(--muted);
  font-size: 18px;
  cursor: pointer;
  padding: 0;
  line-height: 1;
}
.gear:hover { color: var(--fg); }
.gear.env-toggle { font-size: 16px; position: relative; }
.gear.env-toggle.active { color: var(--accent); }
/* Pending-review state on the env-toggle button. Triggered whenever
   the EnvPane has at least one item the human needs to read or act
   on — pending file-write proposals, AskUserQuestion prompts routed
   to the human, plan approvals, or human_attention escalations.
   Recolours the whole ▦ icon amber and pulses a soft amber glow
   around the button — same visual treatment as .slot.state-working
   so "needs attention" reads consistently across the rail. */
.gear.env-toggle.has-pending { color: var(--warn); }
.gear.env-toggle.has-pending .env-icon { color: var(--warn); }
.gear.env-toggle.has-pending {
  animation: env-toggle-pending-pulse 1.8s ease-in-out infinite;
}
@keyframes env-toggle-pending-pulse {
  0%, 100% { box-shadow: 0 0 4px rgba(210, 153, 34, 0.35); }
  50%      { box-shadow: 0 0 12px rgba(210, 153, 34, 0.85); }
}
/* Project switcher (Phase 3) — replaces the dashed `P` placeholder
   with a working dropdown. Pill shows the first 2 letters of the
   active project's name; menu lists all non-archived projects with
   a checkmark on the active one + a "New project…" footer. */
.project-switcher {
  position: relative;
}
.gear.project-pill {
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--panel, #1c1f26);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.gear.project-pill:hover { border-color: var(--accent, #e3a03a); color: var(--accent, #e3a03a); }
.gear.project-pill.open { border-color: var(--accent, #e3a03a); color: var(--accent, #e3a03a); }
.gear.project-pill.switching {
  cursor: wait;
  opacity: 0.6;
}
.project-pill-spinner {
  display: inline-block;
  font-size: 14px;
  font-weight: 700;
  animation: project-pill-spin 0.9s linear infinite;
}
@keyframes project-pill-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}
/* Multi-folder glyph: three stacked folder rectangles offset slightly,
   drawn in pure CSS (currentColor inherits the .gear hover/open
   accent), so it reads as "Projects" not "a folder". The back folder
   is the dimmest, the front the brightest, giving a quick depth cue
   without adding an SVG asset. */
.projects-icon {
  display: inline-block;
  position: relative;
  width: 18px;
  height: 14px;
}
.projects-icon-back,
.projects-icon-mid,
.projects-icon-front {
  position: absolute;
  border: 1px solid currentColor;
  border-radius: 2px;
  background: var(--panel, #1c1f26);
  box-sizing: border-box;
}
.projects-icon-back {
  left: 0; top: 0;
  width: 12px; height: 9px;
  opacity: 0.45;
}
.projects-icon-back::before {
  /* Folder tab on the back-most folder */
  content: "";
  position: absolute;
  left: 1px; top: -3px;
  width: 5px; height: 3px;
  border: 1px solid currentColor;
  border-bottom: 0;
  border-radius: 2px 2px 0 0;
  background: var(--panel, #1c1f26);
}
.projects-icon-mid {
  left: 3px; top: 2px;
  width: 12px; height: 9px;
  opacity: 0.7;
}
.projects-icon-mid::before {
  content: "";
  position: absolute;
  left: 1px; top: -3px;
  width: 5px; height: 3px;
  border: 1px solid currentColor;
  border-bottom: 0;
  border-radius: 2px 2px 0 0;
  background: var(--panel, #1c1f26);
}
.projects-icon-front {
  left: 6px; top: 4px;
  width: 12px; height: 9px;
}
.projects-icon-front::before {
  content: "";
  position: absolute;
  left: 1px; top: -3px;
  width: 5px; height: 3px;
  border: 1px solid currentColor;
  border-bottom: 0;
  border-radius: 2px 2px 0 0;
  background: var(--panel, #1c1f26);
}
.project-menu {
  /* Fixed positioning so the menu escapes the rail's overflow-y:auto
     scroll container. Coordinates are computed in JS from the
     button's bounding rect and passed via inline style. */
  position: fixed;
  min-width: 240px;
  max-height: 70vh;
  overflow-y: auto;
  background: var(--panel, #1c1f26);
  border: 1px solid var(--border);
  border-radius: 6px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
  z-index: 1000;
  padding: 4px 0;
  font-size: 12px;
}
.project-menu-head {
  padding: 6px 10px 4px;
  color: var(--muted);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
.project-menu-empty {
  padding: 8px 10px;
  color: var(--muted);
  font-style: italic;
}
.project-menu-item {
  display: flex;
  align-items: baseline;
  gap: 6px;
  width: 100%;
  padding: 5px 10px;
  background: transparent;
  border: 0;
  color: var(--fg);
  text-align: left;
  cursor: pointer;
}
.project-menu-item:hover { background: rgba(255, 255, 255, 0.05); }
.project-menu-item:disabled { cursor: not-allowed; opacity: 0.5; }
.project-menu-item.active .project-menu-name { color: var(--accent, #e3a03a); }
.project-menu-check {
  width: 12px;
  color: var(--accent, #e3a03a);
  font-weight: 700;
}
.project-menu-name {
  flex: 1 1 auto;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.project-menu-slug {
  font-family: var(--mono, monospace);
  color: var(--muted);
  font-size: 10px;
}
.project-menu-sep {
  height: 1px;
  background: var(--border);
  margin: 4px 0;
}
.project-menu-new {
  color: var(--accent, #e3a03a);
  font-weight: 600;
}

/* ---- environment pane ---- */
.env-pane {
  display: flex;
  flex-direction: column;
  min-height: 0;
  border-left: 1px solid var(--border);
  background: var(--bg);
  overflow: hidden;
  position: relative;
}
.env-resizer {
  position: absolute;
  left: -3px;
  top: 0;
  bottom: 0;
  width: 6px;
  cursor: col-resize;
  z-index: 20;
  background: transparent;
  transition: background 120ms ease;
}
.env-resizer:hover,
.env-resizer.dragging {
  background: var(--accent);
}
.env-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  background: var(--card);
}
.env-title {
  font-weight: 600;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
  flex: 1;
}
.env-close {
  background: transparent;
  border: 0;
  color: var(--muted);
  font-size: 18px;
  cursor: pointer;
  padding: 0 4px;
  line-height: 1;
}
.env-close:hover { color: var(--fg); }
.env-export {
  background: transparent;
  border: 0;
  color: var(--muted);
  font-size: 14px;
  cursor: pointer;
  padding: 0 4px;
  line-height: 1;
  margin-left: auto;
}
.env-export:hover { color: var(--fg); }
.env-export:disabled { opacity: 0.3; cursor: not-allowed; }
.env-body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 0;
}

.env-section {
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
}
.env-section:last-child { border-bottom: 0; }
.env-section-title {
  margin: 0 0 8px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
  display: flex;
  align-items: center;
  gap: 6px;
}
/* Collapsible env sections — same chevron + click pattern as the
   Settings drawer. Only sections marked `.env-section.collapsible`
   participate; messages/streams (Attention, Inbox, Timeline,
   KDrive errors) keep their existing layout. */
.env-section.collapsible > .env-section-title {
  cursor: pointer;
  user-select: none;
}
.env-section.collapsible > .env-section-title:hover { color: var(--fg); }
.env-section.collapsible > .env-section-title::before {
  content: "";
  display: inline-block;
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 4px 0 4px 6px;
  border-color: transparent transparent transparent currentColor;
  transition: transform 120ms ease;
  flex-shrink: 0;
}
.env-section.collapsible:not(.collapsed) > .env-section-title::before {
  transform: rotate(90deg);
}
.env-section.collapsible.collapsed > *:not(.env-section-title) {
  display: none !important;
}
.env-section.collapsible.collapsed > .env-section-title { margin-bottom: 0; }
.env-section.collapsible.collapsed { padding-bottom: 8px; }
.env-count {
  margin-left: auto;
  font-weight: 400;
  color: var(--fg);
  font-family: inherit;
  text-transform: none;
  letter-spacing: 0;
}
.env-empty {
  color: var(--muted);
  font-style: italic;
  font-size: 12px;
  padding: 4px 0;
}
.env-cost-hint {
  color: var(--muted);
  font-style: italic;
  font-size: 11px;
}

.env-cost-sub {
  color: var(--warn);
  font-size: 11px;
  margin-bottom: 6px;
}
/* Cost section: scope dropdown + reset button row sits between the
   section title and the cap bar. */
.env-cost-controls {
  display: flex;
  gap: 6px;
  align-items: center;
  margin-bottom: 6px;
}
.env-cost-scope {
  flex: 1 1 auto;
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 2px 6px;
  font-size: 11px;
  font-family: inherit;
  cursor: pointer;
}
.env-cost-scope:hover { border-color: var(--accent); }
.env-cost-reset {
  background: transparent;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 2px 8px;
  font-size: 11px;
  cursor: pointer;
}
.env-cost-reset:hover {
  border-color: var(--err);
  color: var(--err);
}

.env-cost-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.env-cost-row {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  padding: 3px 0;
}
.env-cost-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--muted);
  flex-shrink: 0;
}
.env-cost-dot.working { background: var(--warn); }
.env-cost-dot.idle    { background: var(--ok); }
.env-cost-dot.error   { background: var(--err); }
.env-cost-id {
  font-weight: 600;
  min-width: 34px;
  color: var(--fg);
}
.env-cost-name {
  flex: 1;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.env-cost-value {
  color: var(--fg);
  font-variant-numeric: tabular-nums;
}

/* ---- env decisions ---- */
.env-decision-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.env-decision-head {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  background: transparent;
  border: 0;
  color: var(--fg);
  font: inherit;
  font-size: 12px;
  text-align: left;
  padding: 4px 0;
  cursor: pointer;
}
.env-decision-head:hover { color: var(--coach); }
.env-decision-arrow { color: var(--muted); width: 10px; flex-shrink: 0; }
.env-decision-title { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.env-decision-meta { color: var(--muted); font-size: 10px; flex-shrink: 0; }

/* File-write proposal scope badge — small pill that lives left of the
   decision-title in the row header. Each scope gets its own accent so
   the human can scan a list of pending proposals and immediately see
   which are truth-lane edits vs. project CLAUDE.md edits. */
.env-fw-scope {
  flex-shrink: 0;
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding: 1px 6px;
  border-radius: 8px;
  border: 1px solid var(--border);
  color: var(--muted);
  background: var(--card);
}
.env-fw-scope-truth {
  border-color: var(--coach);
  color: var(--coach);
}
.env-fw-scope-project_claude_md {
  border-color: var(--ok, #56d364);
  color: var(--ok, #56d364);
}

/* Loud-by-design status banners inside the expanded proposal card.
   Each variant is a one-line strip with a left accent border; the
   user reads the strip first and gets the file metadata before
   scrolling into the diff body. The verbose phrasing is deliberate:
   it tells the human exactly what state the diff is in, which makes
   "no diff renders" trivial to self-diagnose. */
.env-fw-status {
  margin: 4px 0 4px 16px;
  padding: 6px 10px;
  font-size: 11px;
  line-height: 1.5;
  border-left: 3px solid var(--border);
  background: var(--card);
  color: var(--muted);
  border-radius: 0 3px 3px 0;
}
.env-fw-status code {
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 10px;
  color: var(--fg);
  background: var(--bg);
  padding: 1px 4px;
  border-radius: 2px;
}
.env-fw-status-loading { border-left-color: var(--muted); }
.env-fw-status-err {
  border-left-color: var(--err, #f85149);
  color: var(--err, #f85149);
}
.env-fw-status-new { border-left-color: var(--coach); color: var(--coach); }
.env-fw-status-nochange { border-left-color: var(--muted); font-style: italic; }
.env-fw-status-diff {
  border-left-color: var(--ok, #56d364);
  color: var(--ok, #56d364);
  font-variant-numeric: tabular-nums;
}
.env-decision-body {
  margin: 4px 0 8px 16px;
  padding: 8px 10px;
  background: var(--card);
  border-left: 2px solid var(--coach);
  border-radius: 0 3px 3px 0;
  font-size: 11px;
  color: var(--fg);
  white-space: pre-wrap;
  max-height: 300px;
  overflow-y: auto;
  line-height: 1.5;
}

/* Truth-proposal expanded view: summary line above the proposed-content
   pre, plus a row of approve/deny buttons below. The approve button uses
   a green accent so it's the visually obvious primary action; deny is a
   neutral button so it doesn't compete. Both disable themselves while
   the resolution call is in flight (busyId). */
.env-truth-summary {
  margin: 4px 0 4px 16px;
  font-size: 11px;
  color: var(--muted);
  font-style: italic;
}
.env-truth-actions {
  display: flex;
  gap: 8px;
  margin: 4px 0 8px 16px;
}
.env-truth-approve,
.env-truth-deny {
  font: inherit;
  font-size: 11px;
  padding: 3px 10px;
  border-radius: 3px;
  border: 1px solid var(--border);
  background: var(--card);
  color: var(--fg);
  cursor: pointer;
}
.env-truth-approve {
  border-color: var(--ok, #56d364);
  color: var(--ok, #56d364);
}
.env-truth-approve:hover:not(:disabled) {
  background: var(--ok, #56d364);
  color: var(--bg);
}
.env-truth-deny:hover:not(:disabled) {
  background: var(--border);
}
.env-truth-approve:disabled,
.env-truth-deny:disabled {
  opacity: 0.5;
  cursor: default;
}

/* ---- env timeline ---- */
.env-timeline-section .env-timeline {
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-height: 300px;
  overflow-y: auto;
  padding-right: 4px;
}
.env-tl-item {
  display: flex;
  gap: 6px;
  align-items: baseline;
  font-size: 11px;
  padding: 2px 0;
  line-height: 1.4;
  border-left: 2px solid var(--border);
  padding-left: 6px;
}
.env-tl-ts {
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}
.env-tl-who {
  color: var(--fg);
  font-weight: 600;
  flex-shrink: 0;
  min-width: 34px;
}
.env-tl-arrow { color: var(--muted); flex-shrink: 0; }
.env-tl-body {
  color: var(--fg);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.env-tl-started { border-left-color: var(--muted); }
.env-tl-started .env-tl-body { color: var(--muted); font-style: italic; }
.env-tl-text { border-left-color: var(--accent); }
.env-tl-error { border-left-color: var(--err); }
.env-tl-error .env-tl-body { color: var(--err); }
.env-tl-task { border-left-color: var(--warn); }
.env-tl-task .env-tl-body { color: var(--warn); }
.env-tl-msg { border-left-color: var(--tool); }
.env-tl-msg .env-tl-body { color: var(--tool); }
.env-tl-mem { border-left-color: var(--ok); }
.env-tl-mem .env-tl-body { color: var(--ok); }
.env-tl-decision { border-left-color: var(--coach); }
.env-tl-decision .env-tl-body { color: var(--coach); font-weight: 600; }
.env-tl-capped { border-left-color: var(--err); background: #281417; }
.env-tl-capped .env-tl-body { color: var(--err); white-space: normal; }
.env-tl-commit { border-left-color: var(--accent); }
.env-tl-commit .env-tl-body { color: var(--accent); }
.env-tl-attention { border-left-color: var(--err); background: #2c1a22; }
.env-tl-attention .env-tl-body { color: var(--err); font-weight: 600; }
.env-tl-assigned { border-left-color: var(--coach); }
.env-tl-assigned .env-tl-body { color: var(--fg); }
.env-tl-cancelled { border-left-color: var(--warn); }
.env-tl-cancelled .env-tl-body { color: var(--warn); }
.env-tl-paused { border-left-color: var(--warn); background: #2a2117; }
.env-tl-paused .env-tl-body { color: var(--warn); font-weight: 600; }

/* Pause toggle in LeftRail — active state uses warn color so the
   "harness is paused" state is impossible to miss. */
.pause-toggle.active {
  background: var(--warn);
  color: var(--bg);
  border-radius: 6px;
  box-shadow: 0 0 8px rgba(210, 153, 34, 0.6);
}
.cancel-all {
  color: var(--err);
}
.cancel-all:hover {
  background: rgba(255, 80, 100, 0.15);
  border-radius: 6px;
}

/* Layout preset buttons — tiny schematic icons drawn with nested spans
   so they visually match the layout they apply. */
.layout-preset { padding: 2px 4px; }
.layout-icon {
  display: inline-flex;
  gap: 2px;
  width: 18px;
  height: 14px;
  align-items: stretch;
  justify-content: center;
}
.layout-icon > span {
  flex: 1 1 0;
  border: 1px solid currentColor;
  border-radius: 1px;
  background: transparent;
}
.layout-icon-pairs > span {
  display: flex;
  flex-direction: column;
  gap: 1px;
  border: 0;
  padding: 0;
}
.layout-icon-pairs > span > i {
  flex: 1 1 0;
  border: 1px solid currentColor;
  border-radius: 1px;
  background: transparent;
}
.layout-preset:hover .layout-icon > span,
.layout-preset:hover .layout-icon-pairs > span > i {
  background: currentColor;
}

.env-msg-urgent .env-decision-head { color: var(--err); }
.env-msg-composer {
  background: var(--card, #1a1a1a);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 8px;
  margin-bottom: 8px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.env-msg-composer-row {
  display: flex;
  gap: 6px;
  align-items: center;
}
.env-msg-composer-label {
  color: var(--muted);
  font-size: 11px;
  min-width: 24px;
}
.env-msg-composer select,
.env-msg-composer-subject,
.env-msg-composer-body {
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 4px 6px;
  font: inherit;
  font-size: 12px;
}
.env-msg-composer-body {
  resize: vertical;
  min-height: 60px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  /* Without width:100%, the textarea falls back to its `cols`
     default (~20 chars) when it isn't inside a flex container — which
     is the case for the Project objectives editor (direct child of
     `.env-section`, not `.env-msg-composer`). border-box keeps the
     1px border + padding inside the 100% width so it doesn't
     overflow the section's right edge. */
  width: 100%;
  box-sizing: border-box;
}
.env-msg-composer select { flex: 1; }
.env-msg-preview {
  color: var(--muted);
  font-size: 11px;
  padding: 0 8px 6px 26px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.env-msg-subject {
  padding: 4px 8px 0 10px;
  font-weight: 600;
  color: var(--fg);
}

/* Pinned attention section: banner above the other env sections when
   any undismissed human_attention / pending_question / pending_plan
   events are live. Amber by default — signals "action needed" without
   the emergency-tone of red, which we reserve for .blocker items
   below (true urgencies set via coord_request_human urgency='blocker'). */
.env-section.env-attention {
  background: #2a1d0e;
  border: 1px solid #e3a03a;
  border-radius: 6px;
  padding: 8px 10px 10px;
  margin-bottom: 10px;
}
.env-section.env-attention .env-section-title {
  color: #e3a03a;
  display: flex;
  align-items: center;
  gap: 6px;
}
.env-attention-dismiss-all {
  margin-left: auto;
  background: transparent;
  border: 1px solid #e3a03a;
  color: #e3a03a;
  border-radius: 3px;
  font-size: 10px;
  padding: 1px 6px;
  cursor: pointer;
}
.env-attention-dismiss-all:hover { background: rgba(227, 160, 58, 0.12); }

/* Per-Player model overrides set by Coach via coord_set_player_model.
   Same amber treatment as .env-attention because the team policy
   says model changes should be the exception — having any active
   override is a soft warning the human should glance at. Renders
   nothing when the team is on defaults (overrides.length === 0). */
.env-section.env-model-overrides {
  background: #2a1d0e;
  border: 1px solid #e3a03a;
  border-radius: 6px;
  padding: 8px 10px 10px;
  margin-bottom: 10px;
}
.env-section.env-model-overrides .env-section-title { color: #e3a03a; }
.env-section.env-model-overrides .env-count {
  background: #e3a03a;
  color: #1d1f26;
  border-radius: 8px;
  font-size: 10px;
  padding: 1px 6px;
  margin-left: 4px;
  font-weight: 600;
}
.env-section.env-model-overrides .env-warn {
  font-size: 11px;
  color: #cdb98e;
  margin: 4px 0 6px;
  line-height: 1.4;
}
.env-section.env-model-overrides .env-model-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.env-section.env-model-overrides .env-model-list li {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  color: var(--fg);
}
.env-section.env-model-overrides .env-model-slot {
  font-weight: 600;
  min-width: 28px;
}
.env-section.env-model-overrides .env-model-arrow { color: #999; }
.env-section.env-model-overrides .env-model-list code {
  background: #1d1f26;
  padding: 1px 5px;
  border-radius: 3px;
  font-size: 10px;
}
.env-section.env-model-overrides .env-model-runtime {
  color: #888;
  font-size: 10px;
  margin-left: 2px;
}

/* kDrive sync failure banner — emitted by server/project_sync.py
   when retries exhaust. Same amber tone as .env-attention so it
   blends visually but with its own header so the user knows it's
   sync (operational), not an agent escalation. */
.env-section.env-kdrive-failed {
  background: #1d1f26;
  border: 1px solid #e3a03a;
  border-radius: 6px;
  padding: 8px 10px 10px;
  margin-bottom: 10px;
}
.env-section.env-kdrive-failed h2 {
  color: #e3a03a;
  font-size: 11px;
  margin: 0 0 6px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
.env-kdrive-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-height: 160px;
  overflow-y: auto;
}
.env-kdrive-row {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 11px;
  font-family: var(--mono, monospace);
  background: #14161c;
  padding: 3px 6px;
  border-left: 3px solid #e3a03a;
  border-radius: 3px;
}
.env-kdrive-op {
  color: #e3a03a;
  flex: 0 0 auto;
}
.env-kdrive-path {
  flex: 1 1 auto;
  color: var(--fg, #e6e6e6);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.env-kdrive-err {
  flex: 0 0 auto;
  color: var(--muted);
  max-width: 40%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.env-kdrive-hint {
  margin-top: 6px;
  font-size: 10px;
  color: var(--muted);
}
.env-attention-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.env-attention-item {
  background: #1a140a;
  border-left: 3px solid #e3a03a;
  padding: 6px 8px;
  border-radius: 3px;
}
/* Blocker urgency keeps the louder red treatment — this is reserved
   for coord_request_human urgency='blocker', genuine team-stopping
   issues. Routine questions / plan approvals stay amber above. */
.env-attention-item.blocker {
  border-left: 5px solid var(--err);
  background: #33131c;
}
.env-attention-head {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  color: var(--muted);
}
.env-attention-who { color: var(--fg); font-weight: 600; }
.env-attention-pill {
  background: var(--err);
  color: #fff;
  font-size: 9px;
  font-weight: 700;
  padding: 1px 5px;
  border-radius: 2px;
  letter-spacing: 0.5px;
}
.env-attention-ts { color: var(--muted); }
.env-attention-dismiss {
  margin-left: auto;
  background: transparent;
  border: 0;
  color: var(--muted);
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  padding: 0 3px;
}
.env-attention-dismiss:hover { color: var(--err); }
.env-attention-subject {
  margin-top: 3px;
  font-weight: 600;
  color: var(--fg);
}
.env-attention-body {
  margin-top: 3px;
  color: var(--fg);
  font-size: 12px;
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 140px;
  overflow-y: auto;
}

/* Structured-question answer form rendered inside an attention item
   when the event carries a `questions` payload (from coord_ask_question). */
.question-form {
  margin-top: 6px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.question-block {
  border-top: 1px dashed var(--border);
  padding-top: 6px;
}
.question-header {
  font-size: 10px;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 2px;
}
.question-text {
  font-size: 12px;
  color: var(--fg);
  margin-bottom: 4px;
}
.question-multi-tag {
  display: inline-block;
  font-size: 9px;
  padding: 1px 5px;
  margin-right: 5px;
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 8px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.question-options {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 12px;
}
.question-option {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  padding: 3px 4px;
  border-radius: 3px;
  cursor: pointer;
}
.question-option:hover { background: rgba(255,255,255,0.03); }
.question-option input[type="radio"],
.question-option input[type="checkbox"] {
  margin-top: 2px;
  flex: 0 0 auto;
}
.question-option-label {
  color: var(--fg);
  font-weight: 500;
  flex: 0 0 auto;
}
.question-option-desc {
  color: var(--muted);
  font-size: 11px;
  margin-left: 4px;
  flex: 1 1 auto;
}
.question-other .question-option-label { color: var(--muted); }
.question-other-input {
  flex: 1 1 auto;
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 2px 6px;
  font-size: 12px;
}
.question-form-actions {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 8px;
  margin-top: 4px;
}
.question-form-err {
  color: var(--err);
  font-size: 11px;
}

/* Countdown + extend button shared by QuestionForm and
   PlanApprovalForm. Thin row at the top of the form — clock colour
   shifts amber→red as the deadline approaches. */
.interaction-countdown {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 11px;
  margin-bottom: 6px;
  padding: 3px 6px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--border);
  border-radius: 3px;
}
.countdown-clock {
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-weight: 600;
  min-width: 60px;
}
.countdown-green { color: var(--ok, #3fb950); }
.countdown-amber { color: #e3a03a; }
.countdown-red {
  color: var(--err, #ff5a5a);
  animation: countdown-pulse 1s ease-in-out infinite;
}
@keyframes countdown-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.6; }
}
.countdown-extend {
  margin-left: auto;
  padding: 2px 8px;
  font-size: 11px;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--fg);
  border-radius: 3px;
  cursor: pointer;
}
.countdown-extend:hover { border-color: var(--accent); }
.countdown-extend:disabled { opacity: 0.5; cursor: wait; }
.countdown-err {
  color: var(--err);
  font-size: 10px;
}

/* Plan-approval form — rendered inside an attention item when a
   pending_plan event arrives (ExitPlanMode via can_use_tool). */
.plan-form {
  margin-top: 6px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.plan-body {
  max-height: 280px;
  overflow-y: auto;
  white-space: pre-wrap;
  word-break: break-word;
  background: #10131a;
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 8px 10px;
  margin: 0;
  font-size: 12px;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  color: var(--fg);
  line-height: 1.4;
}
.plan-comments {
  width: 100%;
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 4px 6px;
  font-size: 12px;
  font-family: inherit;
  resize: vertical;
}
.plan-actions {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
.plan-actions .plan-reject {
  color: var(--err);
  border-color: var(--err);
}
.plan-form-err {
  color: var(--err);
  font-size: 11px;
  margin-right: auto;
}

/* cost cap progress bar */
.env-cap-bar { margin-bottom: 8px; }
.env-cap-bar-label {
  font-size: 11px;
  color: var(--muted);
  margin-bottom: 3px;
  font-variant-numeric: tabular-nums;
}
.env-cap-bar-track {
  height: 4px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 2px;
  overflow: hidden;
}
.env-cap-bar-fill {
  height: 100%;
  background: var(--ok);
  transition: width 200ms, background-color 200ms;
}
.env-cap-bar-fill.warn { background: var(--warn); }
.env-cap-bar-fill.over { background: var(--err); }

/* task list inside env pane */
.env-task-filter {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--muted);
  border-radius: 3px;
  font-size: 10px;
  padding: 1px 6px;
  cursor: pointer;
  font-family: inherit;
}
.env-task-filter:hover { border-color: var(--accent); color: var(--fg); }
.env-task-cancel {
  margin-left: auto;
  background: transparent;
  border: 0;
  color: var(--muted);
  font-size: 14px;
  line-height: 1;
  padding: 0 4px;
  cursor: pointer;
}
.env-task-cancel:hover { color: var(--err); }
.env-task-branch {
  color: var(--muted);
  font-size: 11px;
  margin-right: 2px;
}
.env-task-child {
  border-left: 2px solid var(--border);
  padding-left: 6px;
}

.env-task-filter.active {
  background: var(--accent);
  color: var(--bg);
  border-color: var(--accent);
}
.env-task-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 10px;
}
.env-task {
  padding: 6px 8px;
  background: var(--card);
  border-radius: 3px;
  border-left: 3px solid var(--border);
  font-size: 12px;
}
.env-task.status-open        { border-left-color: var(--ok); }
.env-task.status-in_progress { border-left-color: var(--accent); }
.env-task.status-claimed     { border-left-color: var(--accent); }
.env-task.status-blocked     { border-left-color: var(--err); }
.env-task.status-done        { border-left-color: var(--muted); opacity: 0.6; }
.env-task.status-cancelled   { border-left-color: var(--muted); opacity: 0.5; }
.env-task-head {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 2px;
}
.env-task-status {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
}
.env-task-id { color: var(--muted); font-size: 10px; margin-left: auto; }
.env-task-title { color: var(--fg); word-break: break-word; }
.env-task-meta { color: var(--muted); font-size: 10px; margin-top: 2px; }

/* create task form */
.env-task-form {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding-top: 8px;
  border-top: 1px dashed var(--border);
}
.env-task-form input,
.env-task-form textarea,
.env-task-form select {
  width: 100%;
  padding: 6px 8px;
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: 3px;
  font: inherit;
}
.env-task-form textarea { resize: vertical; }
.env-task-row {
  display: flex;
  gap: 6px;
  align-items: center;
}
.env-task-row select { flex: 1; }
.env-task-row button { padding: 6px 14px; }

/* ---- pane region ---- */
.panes {
  display: flex;
  overflow: hidden;
  min-width: 0;
}
.empty {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  color: var(--muted);
  font-size: 13px;
  font-style: italic;
}
/* A column can hold 1+ panes stacked vertically. Multi-column layouts
   get horizontal Split.js gutters between .pane-col siblings; stacked
   columns get vertical Split.js gutters between .pane siblings. */
.pane-col {
  display: flex;
  flex-direction: column;
  flex: 1 1 0;
  min-width: 0;
  min-height: 0;
  border-right: 1px solid var(--border);
}
.pane-col:last-child { border-right: 0; }
.pane-col + .gutter + .pane-col { border-right: 0; }

.pane {
  display: flex;
  flex-direction: column;
  flex: 1 1 0;
  min-width: 0;
  min-height: 0;
  position: relative;
}
/* Edge-targeted drop indicators. A bright bar shows exactly where the
   dropped pane will land — top/bottom stacks inside this column, left/
   right creates a new column next to this one. */
.pane[class*="drop-edge-"]::before {
  content: "";
  position: absolute;
  background: var(--accent);
  box-shadow: 0 0 8px var(--accent);
  pointer-events: none;
  z-index: 15;
  border-radius: 2px;
}
.pane.drop-edge-top::before    { top: 0;    left: 0; right: 0; height: 4px; }
.pane.drop-edge-bottom::before { bottom: 0; left: 0; right: 0; height: 4px; }
.pane.drop-edge-left::before   { top: 0; bottom: 0; left: 0;  width: 4px; }
.pane.drop-edge-right::before  { top: 0; bottom: 0; right: 0; width: 4px; }
/* Tint the whole pane slightly so it's obvious it's the target. */
.pane[class*="drop-edge-"]::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(99, 179, 237, 0.05);
  pointer-events: none;
  z-index: 14;
}

/* Drop zones: invisible strips that highlight while a pane is being
   dragged. Horizontal strips sit at the bottom of each column and
   append to that column on drop; the vertical strip sits at the far
   right of .panes and opens a brand new column. */
.drop-zone {
  transition: background 80ms, border-color 80ms;
  position: relative;
  color: var(--muted);
  font-size: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0.45;
}
.drop-zone:hover { opacity: 0.9; }
.drop-zone-horizontal {
  flex: 0 0 14px;
  min-height: 14px;
  width: 100%;
  border-top: 1px dashed var(--border);
}
.drop-zone-horizontal::before {
  content: "+ drop or drag here to stack";
}
.drop-zone-vertical {
  flex: 0 0 18px;
  align-self: stretch;
  border-left: 1px dashed var(--border);
  writing-mode: vertical-rl;
  text-orientation: mixed;
}
.drop-zone-vertical::before {
  content: "+ new column";
}
.drop-zone.active {
  background: rgba(99, 179, 237, 0.2); /* accent-ish */
  box-shadow: inset 0 0 0 2px var(--accent);
  opacity: 1;
}
.drop-zone.active::before { content: ""; }
.drop-zone-label {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: var(--accent);
  font-size: 10px;
  white-space: nowrap;
  pointer-events: none;
}
.drop-zone-vertical .drop-zone-label {
  writing-mode: vertical-rl;
}
.pane-drag-handle {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1 1 auto;
  min-width: 0;
  cursor: grab;
  /* Tell the browser to use this element's bounds for the drag image,
     not just the text. */
  user-select: none;
}
.pane-drag-handle:active {
  cursor: grabbing;
}

/* ---- Split.js gutter between resizable panes ---- */
.gutter {
  background-color: var(--border);
  background-repeat: no-repeat;
  background-position: 50%;
  transition: background-color 80ms;
  flex-shrink: 0;
}
.gutter.gutter-horizontal {
  cursor: col-resize;
  background-image: linear-gradient(
    to bottom,
    transparent 0,
    transparent calc(50% - 12px),
    var(--muted) calc(50% - 12px),
    var(--muted) calc(50% + 12px),
    transparent calc(50% + 12px),
    transparent 100%
  );
  background-size: 1px 100%;
  background-position: 50% 50%;
  background-repeat: no-repeat;
}
.gutter.gutter-horizontal:hover {
  background-color: var(--accent);
}
.gutter.gutter-vertical {
  cursor: row-resize;
  background-image: linear-gradient(
    to right,
    transparent 0,
    transparent calc(50% - 12px),
    var(--muted) calc(50% - 12px),
    var(--muted) calc(50% + 12px),
    transparent calc(50% + 12px),
    transparent 100%
  );
  background-size: 100% 1px;
  background-position: 50% 50%;
  background-repeat: no-repeat;
}
.gutter.gutter-vertical:hover {
  background-color: var(--accent);
}

.pane-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--border);
  background: var(--card);
}
.pane-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--muted);
  flex-shrink: 0;
}
.pane-dot.working { background: var(--warn); }
.pane-dot.idle { background: var(--ok); }
.pane-dot.error { background: var(--err); }
.pane-id { font-weight: 600; }
.pane-name { color: var(--fg); }
/* Current-task pill — now icon-only. Tooltip carries the title. */
.pane-current-task {
  color: var(--accent);
  font-size: 13px;
  padding: 0 2px;
  cursor: help;
}
.pane-current-task-stage {
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--muted, #7e8694);
  padding-left: 2px;
}
.pane-lock {
  background: transparent;
  border: 0;
  padding: 0 3px;
  cursor: pointer;
  line-height: 0;
  display: inline-flex;
  align-items: center;
}
.pane-lock.unlocked { color: var(--ok); }
.pane-lock.locked   { color: var(--err); }
.pane-lock:hover    { filter: brightness(1.2); }
.pane-lock.busy     { opacity: 0.6; cursor: progress; }
.pane-lock[disabled] { cursor: progress; }
.pane-session-clear {
  background: transparent;
  border: 0;
  color: var(--muted);
  font-size: 13px;
  padding: 0 2px;
  cursor: pointer;
  line-height: 1;
  opacity: 0.7;
}
.pane-session-clear:hover { color: var(--err); opacity: 1; }
.pane-close {
  background: transparent;
  border: 0;
  color: var(--muted);
  font-size: 20px;
  cursor: pointer;
  padding: 0 4px;
  line-height: 1;
}
.pane-close:hover { color: var(--fg); }

.pane-cancel {
  background: transparent;
  border: 1px solid var(--err);
  color: var(--err);
  border-radius: 3px;
  padding: 1px 5px;
  font-size: 11px;
  cursor: pointer;
  line-height: 1;
}
.pane-cancel:hover { background: rgba(255, 80, 100, 0.15); }

/* Files-pane specifics */
.files-pane .files-body {
  display: flex;
  flex: 1 1 auto;
  min-height: 0;
}
.files-tree {
  /* The flex-basis is overridden inline (treeWidth state in
     FilesPane). Keep min-width as a hard floor so a too-aggressive
     drag can't make the tree disappear. */
  flex: 0 0 220px;
  min-width: 140px;
  max-width: 60%;
  border-right: 0;
  overflow-y: auto;
  padding: 6px 0;
  background: var(--card);
  font-size: 12px;
}
/* Vertical drag handle between the tree and the editor. Visually a
   thin separator with a grippable centerline that thickens on hover. */
.files-splitter {
  flex: 0 0 6px;
  cursor: col-resize;
  background: var(--border);
  position: relative;
  align-self: stretch;
  user-select: none;
  touch-action: none;
}
.files-splitter:hover { background: var(--accent); }
.files-splitter-grip {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 2px;
  height: 32px;
  background: var(--muted);
  border-radius: 1px;
  pointer-events: none;
}
.files-splitter:hover .files-splitter-grip { background: var(--bg); }
.files-tree-roots {
  display: flex;
  gap: 4px;
  padding: 4px 8px 8px;
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}
.files-root {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--muted);
  font: inherit;
  font-size: 11px;
  cursor: pointer;
  padding: 2px 8px;
  border-radius: 4px;
}
.files-root.active {
  border-color: var(--accent);
  color: var(--fg);
  background: rgba(88, 166, 255, 0.1);
}
.files-root-section {
  border-bottom: 1px solid var(--border);
}
.files-root-section:last-child { border-bottom: 0; }
.files-root-section.active .files-root-header {
  background: rgba(88, 166, 255, 0.08);
  color: var(--fg);
}
.files-root-header {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  background: transparent;
  border: 0;
  color: var(--muted);
  font: inherit;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  cursor: pointer;
  padding: 6px 10px;
  text-align: left;
}
.files-root-header:hover { background: rgba(255, 255, 255, 0.04); color: var(--fg); }
.files-root-icon {
  flex: 0 0 14px;
  text-align: center;
  font-size: 12px;
}
.files-root-label {
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.files-root-lock {
  flex: 0 0 auto;
  opacity: 0.65;
  font-size: 10px;
}
.files-root-caret {
  flex: 0 0 auto;
  color: var(--muted);
  font-size: 10px;
  margin-left: 4px;
}
.files-node {
  display: flex;
  gap: 6px;
  align-items: center;
  cursor: pointer;
  padding: 2px 8px;
  color: var(--muted);
}
.files-node:hover { background: rgba(255, 255, 255, 0.03); color: var(--fg); }
.files-node.selected { background: rgba(88, 166, 255, 0.15); color: var(--fg); }
.files-node-icon {
  flex: 0 0 12px;
  text-align: center;
  font-size: 11px;
}
.files-node-name {
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.files-editor {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.files-empty {
  color: var(--muted);
  font-style: italic;
  padding: 16px;
  text-align: center;
  font-size: 12px;
}
.files-err {
  color: var(--err);
  padding: 6px 10px;
  font-size: 12px;
  border-bottom: 1px solid var(--err);
}
.files-md-toolbar {
  display: flex;
  gap: 4px;
  padding: 4px 8px;
  border-bottom: 1px solid var(--border);
  background: var(--card);
}
.files-scope-badge {
  padding: 4px 10px;
  font-size: 10px;
  letter-spacing: 0.5px;
  border-bottom: 1px solid var(--border);
  background: var(--card);
  color: var(--muted);
  display: flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.files-scope-badge.files-scope-global {
  border-left: 2px solid #888;
}
.files-scope-badge.files-scope-project {
  border-left: 2px solid var(--accent);
  color: var(--fg);
}
.files-md-toolbar button {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--muted);
  font: inherit;
  font-size: 11px;
  cursor: pointer;
  padding: 2px 10px;
  border-radius: 3px;
}
.files-md-toolbar button.active {
  color: var(--fg);
  border-color: var(--accent);
  background: rgba(88, 166, 255, 0.1);
}
.files-textarea {
  flex: 1 1 auto;
  width: 100%;
  background: var(--bg);
  color: var(--fg);
  border: 0;
  outline: none;
  padding: 10px 12px;
  font-family: ui-monospace, Menlo, Consolas, "Fira Code", monospace;
  font-size: 13px;
  line-height: 1.5;
  resize: none;
}
.files-md-preview {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 12px 16px;
  line-height: 1.55;
  font-size: 14px;
}
/* Code-file preview: hljs-highlighted source. Keeps a single scrollable
   pre that fills the editor area, matching the textarea's footprint. */
.files-code-preview {
  flex: 1 1 auto;
  overflow: auto;
  background: var(--bg);
}
.files-code-preview pre.files-code {
  margin: 0;
  padding: 10px 12px;
  background: transparent;
  border: 0;
  font-family: ui-monospace, Menlo, Consolas, "Fira Code", monospace;
  font-size: 13px;
  line-height: 1.5;
  white-space: pre;
  overflow-x: auto;
}
.files-code-preview pre.files-code code.hljs {
  background: transparent;
  padding: 0;
  display: block;
}
.files-code-lang {
  margin-left: auto;
  font-family: ui-monospace, Menlo, Consolas, "Fira Code", monospace;
  font-size: 10px;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  align-self: center;
  padding-right: 8px;
}
/* Binary placeholder — shown for files outside the previewable text
   allowlist. The pane still selects them in the tree, just doesn't
   try to render their contents. */
.files-binary-card {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  color: var(--muted);
  padding: 32px;
  text-align: center;
}
.files-binary-title {
  color: var(--fg);
  font-size: 13px;
}
.files-binary-meta {
  font-family: ui-monospace, Menlo, Consolas, "Fira Code", monospace;
  font-size: 12px;
  word-break: break-all;
}
/* Shared markdown styling for the marked + DOMPurify + hljs pipeline.
   Used in two contexts: agent text/thinking events (.markdown class)
   and the files preview (.files-md-preview). The selectors target
   plain HTML (h1..h6, p, ul, table, …) since marked emits standard
   tags — the legacy hand-rolled renderer used .md-* classes. */
.markdown, .files-md-preview { line-height: 1.55; }
.markdown h1, .markdown h2, .markdown h3, .markdown h4, .markdown h5, .markdown h6,
.files-md-preview h1, .files-md-preview h2, .files-md-preview h3,
.files-md-preview h4, .files-md-preview h5, .files-md-preview h6 {
  margin: 1em 0 0.3em;
  font-weight: 600;
}
.markdown h1, .files-md-preview h1 { font-size: 1.5em; }
.markdown h2, .files-md-preview h2 { font-size: 1.25em; }
.markdown h3, .files-md-preview h3 { font-size: 1.1em; }
.markdown h4, .markdown h5, .markdown h6,
.files-md-preview h4, .files-md-preview h5, .files-md-preview h6 { font-size: 1em; }
.markdown p, .files-md-preview p { margin: 0.5em 0; }
.markdown ul, .markdown ol,
.files-md-preview ul, .files-md-preview ol {
  margin: 0.4em 0;
  padding-left: 1.6em;
}
.markdown li > ul, .markdown li > ol,
.files-md-preview li > ul, .files-md-preview li > ol {
  margin: 0.2em 0;
}
.markdown li, .files-md-preview li { margin: 0.15em 0; }
.markdown li > p, .files-md-preview li > p { margin: 0.2em 0; }
.markdown li > input[type="checkbox"],
.files-md-preview li > input[type="checkbox"] {
  margin-right: 6px;
  vertical-align: middle;
}
/* Inline code (not inside a <pre>) */
.markdown :not(pre) > code,
.files-md-preview :not(pre) > code {
  background: var(--card);
  border-radius: 3px;
  padding: 1px 5px;
  font-size: 0.9em;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
/* Code fences. The github-dark theme paints the inner <code>; keep
   the <pre> container styled so it merges with the harness UI. */
.markdown pre, .files-md-preview pre {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 10px 12px;
  overflow-x: auto;
  font-size: 12px;
  line-height: 1.4;
  margin: 0.6em 0;
}
.markdown pre code, .files-md-preview pre code {
  background: transparent !important;
  padding: 0 !important;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
/* GFM tables — readable grid with header band and zebra body rows. */
.markdown table, .files-md-preview table {
  border-collapse: collapse;
  margin: 0.6em 0;
  font-size: 0.95em;
  width: 100%;
  display: block;
  overflow-x: auto;
}
.markdown th, .markdown td,
.files-md-preview th, .files-md-preview td {
  border: 1px solid var(--border);
  padding: 5px 9px;
  text-align: left;
  vertical-align: top;
}
.markdown th, .files-md-preview th {
  background: var(--card);
  font-weight: 600;
}
.markdown tr:nth-child(even) td,
.files-md-preview tr:nth-child(even) td {
  background: rgba(255, 255, 255, 0.02);
}
/* Blockquote — left rail + muted text */
.markdown blockquote, .files-md-preview blockquote {
  margin: 0.6em 0;
  padding: 0.2em 0.9em;
  border-left: 3px solid var(--border);
  color: var(--muted);
}
.markdown hr, .files-md-preview hr {
  border: 0;
  border-top: 1px solid var(--border);
  margin: 1em 0;
}
.markdown a, .files-md-preview a { color: var(--accent); }
.markdown a:hover, .files-md-preview a:hover { text-decoration: underline; }
/* In-app file-link (DOMPurify hook tags any href starting with `/`).
   Distinct color + a small leading "📄" so the user can tell at a
   glance that clicking will open the Files pane, not a new tab. */
.markdown a.harness-file-link,
.files-md-preview a.harness-file-link {
  color: var(--warn);
  cursor: pointer;
}
.markdown a.harness-file-link::before,
.files-md-preview a.harness-file-link::before {
  content: "📄";
  margin-right: 4px;
  font-size: 0.85em;
  opacity: 0.8;
}
/* Slightly tighten the spacing at top/bottom of an event body so
   single-paragraph replies don't waste vertical space. */
.event-body.markdown > :first-child { margin-top: 0; }
.event-body.markdown > :last-child { margin-bottom: 0; }

/* Mermaid diagrams. The placeholder <pre> is what marked emits; the
   MutationObserver in markdown.js swaps its inner HTML to the rendered
   <svg>. Both states need styling because the placeholder is briefly
   visible while mermaid lazy-loads on first use. */
.md-mermaid {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 10px 12px;
  margin: 8px 0;
  overflow-x: auto;
  font-size: 12px;
  color: var(--muted);
}
.md-mermaid > code {
  /* While the placeholder is showing, render the source as readable
     text rather than as a code-block (mermaid's output is the goal,
     not the source). hljs hasn't touched it. */
  background: transparent;
  padding: 0;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  white-space: pre;
}
.md-mermaid.md-mermaid-rendered {
  background: transparent;
  border: 0;
  padding: 4px 0;
  text-align: center;
}
.md-mermaid.md-mermaid-rendered svg {
  max-width: 100%;
  height: auto;
}
.md-mermaid.md-mermaid-error {
  border-color: var(--err, #f85149);
  color: var(--err, #f85149);
}
.md-mermaid-err-title { font-weight: 600; margin-bottom: 6px; }
.md-mermaid-err-msg, .md-mermaid-err-src {
  background: rgba(0,0,0,0.25);
  padding: 6px 8px;
  border-radius: 4px;
  font-size: 11px;
  margin: 4px 0;
  white-space: pre-wrap;
  word-break: break-word;
}

/* KaTeX overrides. Inherit the harness foreground colour so equations
   read correctly in both pane chrome and files preview. The vendored
   katex.css sets explicit `color` on .katex; bumping our rule with
   higher specificity beats it without !important. */
.markdown .katex,
.files-md-preview .katex,
.event-body.markdown .katex {
  color: inherit;
}
/* Display-mode equations need a bit of breathing room and horizontal
   scroll for the wide ones (matrices, long alignments). */
.markdown .katex-display,
.files-md-preview .katex-display,
.event-body.markdown .katex-display {
  margin: 0.6em 0;
  overflow-x: auto;
  overflow-y: hidden;
  padding: 2px 0;
}

/* Callouts (Obsidian / GFM-Alerts compatible). The renderer in
   markdown.js emits .md-callout.md-callout-{theme} with a title row
   and body. Twelve themes share a single color-variable contract:
   each theme sets `--callout-color` and the rest cascades. The
   collapsible variant uses <details>/<summary>; the chevron is
   drawn via CSS so we don't depend on the browser's default marker
   shape. */
.md-callout {
  --callout-color: var(--accent);
  margin: 10px 0;
  border-left: 3px solid var(--callout-color);
  background: color-mix(in srgb, var(--callout-color) 8%, transparent);
  border-radius: 0 4px 4px 0;
  padding: 6px 12px 6px 12px;
}
.md-callout-title {
  color: var(--callout-color);
  font-weight: 600;
  font-size: 0.85em;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin: 0 0 4px 0;
  user-select: none;
}
.md-callout-body { font-size: 0.95em; }
.md-callout-body > :first-child { margin-top: 0; }
.md-callout-body > :last-child { margin-bottom: 0; }
/* Collapsible variant: <details>/<summary>. Hide the default
   browser disclosure triangle so we can draw our own. */
details.md-callout-collapsible > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 6px;
}
details.md-callout-collapsible > summary::-webkit-details-marker { display: none; }
details.md-callout-collapsible > summary::before {
  content: "";
  display: inline-block;
  width: 0;
  height: 0;
  border-left: 4px solid currentColor;
  border-top: 3px solid transparent;
  border-bottom: 3px solid transparent;
  transition: transform 0.12s ease;
}
details.md-callout-collapsible[open] > summary::before { transform: rotate(90deg); }
/* Theme palette — each theme just sets --callout-color. */
.md-callout-note     { --callout-color: #58a6ff; } /* blue (--accent) */
.md-callout-abstract { --callout-color: #2bbac5; } /* teal */
.md-callout-info     { --callout-color: #6ab4ff; } /* lighter blue */
.md-callout-todo     { --callout-color: #4493f8; } /* blue */
.md-callout-tip      { --callout-color: #2dd4bf; } /* cyan */
.md-callout-success  { --callout-color: #3fb950; } /* green */
.md-callout-question { --callout-color: #d29922; } /* yellow (--warn) */
.md-callout-warning  { --callout-color: #db7c2a; } /* orange */
.md-callout-failure  { --callout-color: #f85149; } /* red (--err) */
.md-callout-danger   { --callout-color: #ff6a69; } /* bright red */
.md-callout-example  { --callout-color: #a371f7; } /* purple */
.md-callout-quote    { --callout-color: #8b949e; } /* gray (--muted) */

.files-editor-foot {
  display: flex;
  gap: 12px;
  padding: 4px 10px;
  border-top: 1px solid var(--border);
  color: var(--muted);
  font-size: 11px;
  background: var(--card);
}
.files-editor-foot .dirty { color: var(--warn); }
.pane-files-save {
  background: var(--accent);
  color: var(--bg);
  border: 0;
  font: inherit;
  font-size: 11px;
  font-weight: 600;
  padding: 2px 10px;
  border-radius: 4px;
  cursor: pointer;
}
.pane-files-save:disabled { opacity: 0.5; cursor: wait; }

/* "+ new file" button — secondary action, neutral until hover, sits
   alongside save in the FilesPane header. */
.pane-files-new {
  background: transparent;
  color: var(--muted);
  border: 1px solid var(--border);
  font: inherit;
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 4px;
  cursor: pointer;
}
.pane-files-new:hover:not(:disabled) {
  color: var(--fg);
  border-color: var(--accent);
}
.pane-files-new:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* Files icon in LeftRail — file-tree glyph (a vertical trunk with
   three small horizontal "rows" branching off it). Drawn in pure CSS
   from currentColor so it picks up the gear hover/active accent.
   Reads as "tree of files" rather than "a folder", which the project
   switcher's multi-folder glyph already covers. */
.files-icon {
  display: inline-block;
  position: relative;
  width: 18px;
  height: 14px;
}
.files-icon-trunk {
  position: absolute;
  left: 3px; top: 1px; bottom: 1px;
  width: 1px;
  background: currentColor;
  opacity: 0.85;
}
.files-icon-row {
  position: absolute;
  height: 1px;
  background: currentColor;
  opacity: 0.85;
}
.files-icon-row::before {
  /* Branch line from the trunk to the row marker */
  content: "";
  position: absolute;
  left: -3px; top: 0;
  width: 3px;
  height: 1px;
  background: currentColor;
}
.files-icon-row::after {
  /* Small "file" rectangle at the end of the branch */
  content: "";
  position: absolute;
  right: 0; top: -2px;
  width: 8px;
  height: 5px;
  border: 1px solid currentColor;
  border-radius: 1px;
  background: transparent;
}
.files-icon-row-1 { left: 7px; top: 2px; right: 0; }
.files-icon-row-2 { left: 7px; top: 7px; right: 0; }
.files-icon-row-3 { left: 7px; top: 12px; right: 0; }
.gear.files-open.active { color: var(--fg); }

/* Recurrence rail icon — circular arrows (recurrence-specs.md §12.1).
   Inline SVG so the two arcs and arrowheads stay visually crisp at
   small sizes; uses currentColor so it inherits the rail's accent
   state like the other rail icons. */
.gear.recurrence-toggle { padding: 6px; line-height: 0; }
.gear.recurrence-toggle.active { color: var(--accent); }

/* Playbook open-book icon — match the rail's other inline-SVG icons.
   Without explicit flex centering the svg sat on the text baseline,
   nudging the glyph upward relative to the compass / recurrence
   buttons next to it. */
.gear.playbook-open { padding: 6px; line-height: 0; }
.gear.playbook-open.active { color: var(--accent); }

.pb-pane-head .pane-head-label { display: inline-flex; align-items: center; gap: 6px; }
.pb-pane-head .pane-head-actions { margin-left: auto; display: inline-flex; align-items: center; gap: 2px; }
.cmp-pane-head .pane-head-label { display: inline-flex; align-items: center; gap: 6px; }
.cmp-pane-head .pane-head-actions { margin-left: auto; display: inline-flex; align-items: center; gap: 2px; }
.playbook-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
}
.playbook-icon svg { width: 100%; height: 100%; display: block; }
/* Same hardening for the other rail SVG icons so the row reads
   evenly even if a future SVG has different intrinsic baseline. */
.gear.compass-open { padding: 6px; line-height: 0; }
.compass-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
}
.compass-icon svg { width: 100%; height: 100%; display: block; }
.recurrence-icon {
  display: inline-block;
  width: 18px;
  height: 18px;
}
.recurrence-icon svg {
  width: 100%;
  height: 100%;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Recurrence pane — a side panel that opens alongside the EnvPane
   (recurrence-specs.md §12.2). Reuses the env-pane visual language
   so the operator sees the two as siblings. Distinct .rec-* classes
   so styling can diverge later without ripple. */
.rec-pane {
  display: flex;
  flex-direction: column;
  min-height: 0;
  border-left: 1px solid var(--border);
  background: var(--bg);
  overflow: hidden;
}
.rec-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  background: var(--card);
}
.rec-title {
  font-weight: 600;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
  flex: 1;
}
.rec-close {
  background: transparent;
  border: 0;
  color: var(--muted);
  font-size: 18px;
  cursor: pointer;
  padding: 0 4px;
  line-height: 1;
}
.rec-close:hover { color: var(--fg); }
.rec-body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 0;
}
.rec-section {
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
}
.rec-section:last-child { border-bottom: 0; }
.rec-section-title {
  margin: 0 0 8px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
}
.rec-empty {
  color: var(--muted);
  font-style: italic;
  font-size: 12px;
  padding: 4px 0;
}
.rec-help {
  color: var(--muted);
  font-size: 11px;
  line-height: 1.45;
  margin: 0 0 10px;
  padding: 6px 8px;
  background: var(--card);
  border-left: 2px solid var(--border);
  border-radius: 0 3px 3px 0;
}
.rec-help code {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 2px;
  padding: 0 4px;
  font-size: 10px;
}
.rec-help em { color: var(--fg); font-style: normal; font-weight: 600; }
.rec-card {
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 8px 10px;
  margin-bottom: 8px;
  background: var(--card);
  font-size: 12px;
}
.rec-card:last-child { margin-bottom: 0; }
.rec-card-row {
  display: flex;
  gap: 8px;
  margin-bottom: 6px;
  align-items: center;
}
.rec-card-row:last-child { margin-bottom: 0; }
.rec-card-row label {
  width: 70px;
  flex-shrink: 0;
  color: var(--muted);
  font-size: 11px;
}
.rec-card-row input,
.rec-card-row textarea {
  flex: 1;
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--fg);
  font-family: inherit;
  font-size: 12px;
  padding: 4px 6px;
  border-radius: 3px;
}
.rec-card-row textarea {
  min-height: 36px;
  resize: vertical;
}
.rec-card-meta {
  font-size: 11px;
  color: var(--muted);
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}
.rec-status-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-right: 6px;
  vertical-align: middle;
}
.rec-status-dot.on { background: var(--ok, #4caf50); }
.rec-status-dot.off { background: var(--muted); opacity: 0.5; }
.rec-actions {
  display: flex;
  gap: 6px;
  margin-top: 6px;
  justify-content: flex-end;
}
.rec-actions button {
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--fg);
  padding: 3px 8px;
  font-size: 11px;
  border-radius: 3px;
  cursor: pointer;
}
.rec-actions button:hover { border-color: var(--accent); }
.rec-actions button.rec-delete:hover { border-color: var(--danger, #c64); }
.rec-add-btn {
  width: 100%;
  background: transparent;
  border: 1px dashed var(--border);
  color: var(--muted);
  padding: 6px;
  font-size: 11px;
  border-radius: 3px;
  cursor: pointer;
  margin-top: 4px;
}
.rec-add-btn:hover { border-color: var(--accent); color: var(--fg); }
.rec-error {
  color: var(--danger, #c64);
  font-size: 11px;
  padding: 4px 0;
}

.pane-gear, .pane-export, .pane-search-toggle, .pane-pop-out, .pane-maximize {
  background: transparent;
  border: 0;
  color: var(--muted);
  font-size: 14px;
  cursor: pointer;
  padding: 0 4px;
  line-height: 1;
}
.pane-gear:hover, .pane-export:hover, .pane-search-toggle:hover, .pane-pop-out:hover, .pane-maximize:hover { color: var(--fg); }
.pane-export:disabled { opacity: 0.3; cursor: not-allowed; }
.pane-search-toggle.active { color: var(--accent); }

/* When the panes area is in single-pane focus mode, hide drop zones
   (no multi-pane layout to drop into) and let the lone column fill
   the area. The .pane-col flex sizing already does the right thing
   when there's exactly one column. */
.panes.maximized .pane-col { flex: 1 1 100%; }

.pane-search {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  border-bottom: 1px solid var(--border);
  background: var(--card, #1a1a1a);
}
.pane-search-input {
  flex: 1 1 auto;
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 3px 6px;
  font: inherit;
  font-size: 12px;
}
.pane-search-count {
  color: var(--muted);
  font-size: 10px;
  white-space: nowrap;
}
.pane-setting-dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--accent);
  display: inline-block;
}

/* per-pane settings popover anchored under the header */
.pane-head { position: relative; }
.pane-settings-pop {
  position: absolute;
  top: 100%;
  right: 6px;
  z-index: 20;
  background: var(--panel, #1a1a1a);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 10px 12px;
  min-width: 260px;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);
  font-size: 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.pane-settings-row {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.pane-settings-label {
  color: var(--muted);
  min-width: 56px;
  display: flex;
  align-items: center;
  gap: 6px;
}
.pane-settings-select, .pane-settings-slider {
  flex: 1 1 auto;
  min-width: 0;
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 3px 4px;
}
.pane-settings-slider { padding: 0; }
.pane-settings-effort-val {
  min-width: 48px;
  text-align: right;
  color: var(--fg);
}
.pane-settings-hint {
  flex-basis: 100%;
  color: var(--muted);
  font-size: 11px;
  padding-left: 24px;
}
.pane-settings-runtime {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  font-size: 12px;
}
.pane-settings-runtime label {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  cursor: pointer;
}
.pane-settings-runtime-err {
  flex-basis: 100%;
  color: var(--err);
  font-size: 11px;
  padding-left: 24px;
}
.pane-settings-runtime-reset {
  background: transparent;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 3px;
  font-size: 11px;
  padding: 2px 8px;
  cursor: pointer;
  margin-left: auto;
}
.pane-settings-runtime-reset:hover:not(:disabled) { color: var(--fg); }
.pane-settings-runtime-reset:disabled { opacity: 0.5; cursor: default; }
.pane-settings-input {
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 3px 6px;
  font: inherit;
  font-size: 12px;
  flex: 1 1 auto;
  min-width: 0;
}
.pane-settings-identity-actions {
  display: flex;
  justify-content: flex-end;
  margin-top: -4px;
  margin-bottom: 2px;
}

.pane-settings-extras {
  flex-direction: column;
  align-items: stretch;
  gap: 4px;
}
.pane-settings-extras .pane-settings-label { min-width: 0; }
.pane-settings-extras-body {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
  padding: 2px 0;
}
.pane-settings-extra-item {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  color: var(--fg);
  cursor: pointer;
  user-select: none;
}
.pane-settings-extra-item input[type="checkbox"] { margin: 0; }
.pane-settings-extras-body .pane-settings-hint {
  flex-basis: 100%;
  margin-top: 2px;
}

.pane-settings-brief {
  flex-direction: column;
  align-items: stretch;
  gap: 4px;
}
.pane-settings-brief .pane-settings-label {
  min-width: 0;
}
.pane-settings-textarea {
  width: 100%;
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 6px 8px;
  font-family: inherit;
  font-size: 12px;
  line-height: 1.4;
  resize: vertical;
  min-height: 80px;
}
.pane-settings-brief-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.pane-settings-brief-save {
  background: var(--accent);
  color: var(--bg);
  border: 0;
  border-radius: 3px;
  padding: 3px 12px;
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
}
.pane-settings-brief-save:disabled {
  opacity: 0.4;
  cursor: default;
  background: var(--border);
  color: var(--muted);
}

.pane-settings-actions {
  display: flex;
  gap: 6px;
  justify-content: flex-end;
  margin-top: 2px;
}
.pane-settings-actions button {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--fg);
  border-radius: 3px;
  padding: 3px 10px;
  cursor: pointer;
  font-size: 11px;
}
.pane-settings-actions button:hover { border-color: var(--accent); }
.pane-settings-reset { color: var(--muted); }

.pane-body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 12px;
}
.loading {
  color: var(--muted);
  font-style: italic;
  padding: 4px 0;
}
.pane-load-older {
  display: block;
  width: 100%;
  margin: 0 0 8px 0;
  padding: 6px 10px;
  font-size: 11px;
  color: var(--muted);
  background: transparent;
  border: 1px dashed var(--border);
  border-radius: 4px;
  cursor: pointer;
  text-align: center;
}
.pane-load-older:hover:not(:disabled) {
  color: var(--fg);
  border-style: solid;
}
.pane-load-older:disabled {
  cursor: progress;
  opacity: 0.6;
}
.pane-empty-hint {
  color: var(--muted);
  font-size: 12px;
  line-height: 1.6;
  padding: 24px 16px;
  text-align: center;
  border: 1px dashed var(--border);
  border-radius: 6px;
  margin: 24px auto;
  max-width: 480px;
  background: var(--card);
}
.pane-empty-hint em {
  color: var(--fg);
  font-style: normal;
  background: var(--bg);
  padding: 1px 6px;
  border-radius: 3px;
}

/* Pending prompts: optimistic local echo of the user's just-submitted
   prompt before the real `agent_started` event lands. Renders below
   the timeline, above any streaming text, just above the composer.
   Three states:
     - sending: dashed border, dim, "sending…"
     - queued:  amber accent, "queued — will fire when agent is idle"
     - failed:  red accent
   The card is removed automatically by the reconciliation effect once
   the matching agent_started arrives (or by the user via the × button).
*/
.pane-pending-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 8px 0;
}
.pane-pending {
  border: 1px dashed var(--border);
  border-radius: 4px;
  padding: 6px 10px;
  background: var(--card);
  font-size: 12px;
}
.pane-pending-sending { border-color: var(--muted); opacity: 0.85; }
.pane-pending-queued  { border-color: var(--warn); border-style: solid; }
.pane-pending-failed  { border-color: var(--err); border-style: solid; }
.pane-pending-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--muted);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 3px;
}
.pane-pending-queued .pane-pending-meta { color: var(--warn); }
.pane-pending-failed .pane-pending-meta { color: var(--err); }
.pane-pending-cancel {
  margin-left: auto;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--muted);
  border-radius: 3px;
  padding: 0 6px;
  font-size: 12px;
  line-height: 1.4;
  cursor: pointer;
}
.pane-pending-cancel:hover { color: var(--err); border-color: var(--err); }
.pane-pending-body {
  color: var(--fg);
  white-space: pre-wrap;
  word-break: break-word;
}

/* ---- events ---- */
.event {
  padding: 6px 10px;
  margin-bottom: 6px;
  border-left: 3px solid var(--border);
  background: var(--card);
  border-radius: 0 4px 4px 0;
  word-break: break-word;
  /* Cheap virtualization: lets the browser skip layout/paint for
     event rows that are fully offscreen. The estimated intrinsic
     size lets it size the scroll track correctly even when most
     rows are unrendered — pick a value that's roughly the median
     row height so scroll position stays stable. Real measurement
     happens once the row scrolls into view.

     This pairs with the markdown-event memoization (so when a row
     does need to render we don't re-parse its content) to make
     long sessions cheap to scroll through. */
  content-visibility: auto;
  contain-intrinsic-size: auto 80px;
}
/* Streaming bubble + sticky turn header opt out — they need to
   stay laid out so the cursor + sticky-positioning behave
   correctly. content-visibility: auto can interact badly with
   `position: sticky` (the sticky header may not stick when its
   container is content-visibility-skipped). */
.event.streaming,
.event.turn-header {
  content-visibility: visible;
  contain-intrinsic-size: auto;
}
.event-meta {
  color: var(--muted);
  font-size: 11px;
  margin-bottom: 2px;
}
.event-body {
  white-space: pre-wrap;
}

/* Markdown-rendered bodies (text + thinking events). Marked wraps
   paragraphs in <p>, so we let normal block layout take over and drop
   the pre-wrap used for plain-text fallback. The element styles below
   are intentionally conservative — this is a chat pane, not a doc
   viewer, so we lean on defaults and only tweak what looks wrong
   inside dark narrow tiles. */
.event-body.markdown {
  white-space: normal;
}
.event-body.markdown > *:first-child { margin-top: 0; }
.event-body.markdown > *:last-child  { margin-bottom: 0; }
.event-body.markdown p {
  margin: 0 0 8px 0;
  white-space: pre-wrap;                    /* preserve single-line breaks within a paragraph */
}
.event-body.markdown h1,
.event-body.markdown h2,
.event-body.markdown h3,
.event-body.markdown h4 {
  margin: 10px 0 4px 0;
  color: var(--fg);
  font-weight: 600;
  line-height: 1.25;
}
.event-body.markdown h1 { font-size: 16px; }
.event-body.markdown h2 { font-size: 15px; }
.event-body.markdown h3 { font-size: 14px; }
.event-body.markdown h4 { font-size: 13px; }
.event-body.markdown strong { color: var(--fg); font-weight: 600; }
.event-body.markdown em     { font-style: italic; }
.event-body.markdown ul,
.event-body.markdown ol {
  margin: 2px 0 8px 0;
  padding-left: 20px;
}
.event-body.markdown li { margin: 1px 0; }
.event-body.markdown a {
  color: var(--accent);
  text-decoration: none;
}
.event-body.markdown a:hover { text-decoration: underline; }
.event-body.markdown code {
  background: #10131a;
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 0 4px;
  font-size: 12px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.event-body.markdown pre {
  background: #10131a;
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 8px 10px;
  margin: 4px 0 8px 0;
  overflow-x: auto;
  font-size: 12px;
  line-height: 1.4;
}
.event-body.markdown pre code {
  background: transparent;
  border: 0;
  padding: 0;
  font-size: inherit;
}
.event-body.markdown blockquote {
  margin: 4px 0 8px 0;
  padding: 2px 10px;
  border-left: 3px solid var(--muted);
  color: var(--muted);
}
.event-body.markdown table {
  border-collapse: collapse;
  margin: 4px 0 8px 0;
  font-size: 12px;
}
.event-body.markdown th,
.event-body.markdown td {
  border: 1px solid var(--border);
  padding: 3px 8px;
  text-align: left;
}
.event-body.markdown th { background: #10131a; }
.event-body.markdown hr {
  border: 0;
  border-top: 1px solid var(--border);
  margin: 8px 0;
}
/* Thinking body stays italic overall — override for code/pre so inline
   code reads cleanly inside italicized prose. */
.event.thinking .thinking-body.markdown code,
.event.thinking .thinking-body.markdown pre { font-style: normal; }

/* ----------------------------------------------------------------
   Three-tier visual language for the agent pane timeline.

   Tier 1 — direct dialogue with the human (this agent's text reply
            to the human, plus messages where human is on either end).
            Brightest content in the pane, full --fg contrast.

   Tier 2 — inter-agent dialogue (peer ↔ peer messages, broadcasts).
            Same shape as Tier 1 but accent-blue for body text + rail
            so the eye can sort "talking to me" from "talking to peer"
            at a glance.

   Tier 3 — narration of work (tool_use / tool_result / thinking /
            sys / lifecycle). Muted body so it fades into the
            background. Tool-specific colors (Read/Edit/Bash/Grep…)
            are kept on the LEFT BORDER as identity markers — only
            the body text dims.

   Errors and asks (red events, pending action) ignore the tiering
   and stay loud regardless.
   ---------------------------------------------------------------- */

/* Tier 1: agent's text reply + human-thread messages */
.event.text {
  border-color: var(--accent);
  color: var(--fg);
}
.event.text .event-body { color: var(--fg); }
.event.message_sent.human-thread {
  border-color: var(--accent);
  font-size: 13px;
}
.event.message_sent.human-thread .event-body {
  color: var(--fg);
  font-size: 13px;
}

/* Tier 2: peer-to-peer dialogue */
.event.message_sent.peer-thread {
  border-color: var(--accent);
  background: rgba(88, 166, 255, 0.05);
  font-size: 12px;
}
.event.message_sent.peer-thread .event-meta { color: var(--accent); }
.event.message_sent.peer-thread .event-body { color: var(--accent); }

/* Tier 3: muted work narration. The tool's identity color stays on
   the left border (set via .event.tool_use { border-color: var(--tool) }
   and similar) plus the small dot drawn by `summary::before` so cards
   remain scannable by tool type — only the body text dims.

   The per-category `.tool-name` color rules below (3277+) and the
   `.tool-name.tool-phrase` rule (3285+) used to set `color: var(--fg)`
   which made the friendly tool phrases ("Reading inbox", "Listing
   tasks", …) render in full white — defeating the tier-3 muting.
   These overrides are stronger than the tier-3 selectors below, so
   we override them HERE with !important to keep tier-3 truly muted. */
.event.tool_use { border-color: var(--tool); padding: 4px 10px; }
/* The tool-NAME word itself (Bash, Read, Edit, Grep…) keeps its
   per-category color — it's the identity marker that tells the eye
   which kind of work this card represents. We only mute the
   following text (the path / command / args), and the friendly verb
   phrases like "Reading inbox" / "Listing tasks" which carry no
   extra summary. */
.event.tool_use .event-body,
.event.tool_use .tool-card-body,
.event.tool_use .tool-summary,
.event.tool_use .tool-card .tool-name.tool-phrase {
  color: var(--muted) !important;
}
.event.tool_result .tool-result-body { color: var(--muted); }

/* Streaming bubble: same shape as a normal text event but tinted to
   read as "in progress" plus a blinking caret at the end so the eye
   sees the text actually growing rather than a static block. */
.event.streaming {
  border-color: var(--warn);
  border-style: dashed;
  opacity: 0.95;
}
.stream-cursor {
  display: inline-block;
  width: 0.5em;
  height: 1em;
  background: var(--warn);
  vertical-align: -2px;
  margin-left: 2px;
  animation: stream-cursor-blink 1s step-end infinite;
}
@keyframes stream-cursor-blink {
  0%, 50%  { opacity: 1; }
  51%, 100% { opacity: 0; }
}

/* Liveness placeholder shown between agent_started and the first
   child event (thinking/text/tool_use). Three amber dots animate in
   sequence so the pane reads as "agent is alive" instead of
   apparently stalled while the SDK subprocess spins up. Replaced by
   the real streaming bubbles or rendered events the moment they
   arrive. */
.pane-warming {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  margin: 4px 8px;
  color: var(--warn);
  font-size: 12px;
  font-style: italic;
  opacity: 0.85;
}
.pane-warming-dots {
  display: inline-flex;
  gap: 3px;
}
.pane-warming-dots i {
  display: inline-block;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--warn);
  animation: pane-warming-bounce 1.2s ease-in-out infinite;
}
.pane-warming-dots i:nth-child(2) { animation-delay: 0.18s; }
.pane-warming-dots i:nth-child(3) { animation-delay: 0.36s; }
@keyframes pane-warming-bounce {
  0%, 80%, 100% { opacity: 0.3; transform: translateY(0); }
  40%           { opacity: 1;   transform: translateY(-3px); }
}

/* Thinking blocks: muted, collapsed by default so a chatty turn
   doesn't drown the timeline. Header is clickable; body pre-wraps
   and is capped so runaway thoughts don't blow out the pane. */
.event.thinking {
  border-color: var(--muted);
  background: #121418;
  color: var(--muted);
  font-size: 12px;
}
.event.thinking.streaming {
  border-color: var(--warn);
  border-style: dashed;
}
.event.thinking .thinking-head {
  cursor: pointer;
  user-select: none;
}
.event.thinking .thinking-sub {
  color: var(--muted);
  opacity: 0.7;
  margin-left: 6px;
}
.event.thinking .thinking-body {
  white-space: pre-wrap;
  font-style: italic;
  max-height: 240px;
  overflow-y: auto;
  margin-top: 4px;
  padding-top: 4px;
  border-top: 1px dashed var(--border);
}
.event.tool_result {
  border-color: var(--tool);
  margin-left: 16px;
  background: #10131a;
  color: var(--muted);
  font-size: 12px;
}
.event.tool_result.error { color: var(--err); border-color: var(--err); }
.event.tool_result .tool-result-body {
  white-space: pre-wrap;
  max-height: 200px;
  overflow-y: auto;
  font-size: 11px;
  line-height: 1.4;
}
.event.result { border-color: var(--ok); color: var(--muted); font-size: 12px; }
.event.error { border-color: var(--err); color: var(--err); }
.event.task_created { border-color: var(--warn); }
/* task_assigned is an inter-agent comm act — same Tier-2 treatment as
   peer-thread message_sent so the eye groups them. */
.event.task_assigned {
  border-color: var(--accent);
  background: rgba(88, 166, 255, 0.05);
  color: var(--accent);
  font-size: 12px;
}
.event.task_assigned .event-meta { color: var(--accent); }
.event.task_assigned .event-body { color: var(--accent); }
/* coord_send_message and coord_assign_task tool_use cards are the
   moments the agent makes an inter-agent call. Tier-2 blue, overriding
   the tier-3 muted defaults set above. The `summary::before` dot keeps
   its category color (var(--ok) for coord) as the identity marker. */
.event.tool_use .tool-card.comm-tool {
  background: rgba(88, 166, 255, 0.05);
}
.event.tool_use .tool-card.comm-tool .tool-name,
.event.tool_use .tool-card.comm-tool .tool-name.tool-phrase,
.event.tool_use .tool-card.comm-tool .tool-summary {
  color: var(--accent) !important;
}
/* `.event.message_sent` styling lives in the tiering block above —
   modifier classes `.human-thread` (Tier 1) and `.peer-thread`
   (Tier 2) are added by the renderer based on from/to ids. */

/* `coord_request_human` escalations. Rendered as a prominent card
   (subject + full markdown body) so the message that just pinged the
   user on Telegram is readable inline in chat too. urgency=normal
   uses warn (amber); urgency=blocker uses err (red). */
.event.human_attention {
  border-left-color: var(--warn);
  background: rgba(210, 153, 34, 0.06);
}
.event.human_attention.urgency-blocker {
  border-left-color: var(--err);
  background: rgba(248, 81, 73, 0.07);
}
.event.human_attention .event-meta {
  color: var(--warn);
  font-weight: 600;
}
.event.human_attention.urgency-blocker .event-meta {
  color: var(--err);
}
.event.human_attention .event-body {
  color: var(--fg);
  margin-top: 4px;
}
.event.human_attention .ha-label {
  display: inline-block;
  text-transform: uppercase;
  font-size: 10px;
  letter-spacing: 0.5px;
  padding: 1px 6px;
  border: 1px solid currentColor;
  border-radius: 3px;
  margin-right: 8px;
}

/* System / progress events — single line, muted so they fade into
   the background vs. the main assistant text. Same shape as other
   .event entries but collapsed padding. */
.event.sys {
  border-color: var(--border);
  color: var(--muted);
  font-size: 11px;
  padding: 2px 10px;
}
.event.sys .event-meta {
  color: var(--muted);
  margin-bottom: 0;
}

/* Session break — loud horizontal divider. Marks the point where
   the next turn starts a fresh conversation (either human cleared,
   or resume failed). The eye should find this bar instantly when
   scrolling through a long pane. */
.event.session-break {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 10px 0;
  padding: 0;
  border: 0;
  background: transparent;
}
.event.session-break .session-break-rule {
  flex: 1;
  height: 0;
  border-top: 1px dashed var(--warn);
  opacity: 0.7;
}
.event.session-break .session-break-label {
  color: var(--warn);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  white-space: nowrap;
  padding: 2px 8px;
  border: 1px solid var(--warn);
  border-radius: 3px;
  background: rgba(210, 153, 34, 0.08);
}
.event.agent_started,
.event.agent_stopped,
.event.connected { color: var(--muted); font-size: 12px; }
.event .prompt { color: var(--fg); margin-top: 4px; }

/* Turn section — wraps each agent_started + its child events. Acts
   as the containing block for the sticky turn header so scrolling
   past one turn's bottom releases its sticky header before the next
   turn's header reaches top:0. Without this wrapper, two sticky
   headers stack at the top of the pane (visible as "two last prompts
   floating" when scrolled to the boundary between turns). */
.turn-section { display: block; }

/* Turn header — renders each agent_started event as a one-line
   collapsible bar that uses position: sticky to hover at the top of
   the scrolled pane-body. As the user scrolls further back in history,
   the next agent_started pushes the current one out of the sticky
   position, so the visible header always matches the prompt of the
   turn you're currently reading (Claude Code's pattern). The sticky
   element's containing block is the surrounding `.turn-section`, so
   when you scroll past the section's bottom the sticky behavior
   naturally exits instead of stacking with the next section's
   header. */
.event.agent_started.turn-header {
  position: sticky;
  top: 0;
  z-index: 5;
  background: var(--bg);
  border-left: 3px solid var(--accent);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  margin: 8px -12px;              /* cancel pane-body padding so it spans edge-to-edge */
  padding: 6px 12px;
  border-radius: 0;
}
.turn-header-row {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  user-select: none;
}
.turn-header-arrow {
  color: var(--accent);
  font-weight: 600;
  flex: 0 0 auto;
}
.turn-header-ts {
  color: var(--muted);
  font-size: 10px;
  flex: 0 0 auto;
}
.runtime-chip {
  width: 9px;
  height: 9px;
  flex: 0 0 9px;
  display: inline-block;
  border: 1px solid transparent;
}
.runtime-chip-claude {
  border-radius: 999px;
  background: var(--accent);
  box-shadow: 0 0 0 1px rgba(88, 166, 255, 0.22);
}
.runtime-chip-codex {
  border-radius: 2px;
  background: var(--ok);
  box-shadow: 0 0 0 1px rgba(63, 185, 80, 0.22);
}
.runtime-chip.compact {
  width: 7px;
  height: 7px;
  flex-basis: 7px;
}
.turn-header-prompt {
  color: var(--fg);
  flex: 1 1 auto;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-style: italic;
}
.turn-header-chev {
  color: var(--muted);
  flex: 0 0 auto;
}
/* Externally-triggered auto-wakes: tint the prompt accent-blue so
   the receiver spots at a glance that this turn was caused by
   someone else (peer message, Coach task assignment, human plan
   note, paused-Player escalation), distinct from ticks and internal
   SDK-retry wakes. */
.turn-header.wake-external .turn-header-prompt,
.turn-header.wake-external .turn-header-full {
  color: var(--accent);
}
/* Compact turn: muted badge instead of the full prompt dump. */
.turn-header.compact {
  border-left-color: var(--muted);
  opacity: 0.75;
}
.turn-header-compact-badge {
  flex: 1 1 auto;
  color: var(--muted);
  font-size: 12px;
  letter-spacing: 0.02em;
  font-style: italic;
}
.turn-header-full {
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px dashed var(--border);
  white-space: pre-wrap;
  color: var(--fg);
  font-size: 13px;
  line-height: 1.4;
}

/* ---- tool card ---- */
.tool-card summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
}
.tool-card summary::-webkit-details-marker { display: none; }
.tool-card summary::before {
  content: "⏺";
  font-size: 10px;
  color: var(--muted);
  line-height: 1;
  flex-shrink: 0;
}
.tool-card.category-read    summary::before { color: var(--accent); }
.tool-card.category-write   summary::before { color: var(--tool); }
.tool-card.category-run     summary::before { color: var(--warn); }
.tool-card.category-coord   summary::before { color: var(--ok); }

.tool-card .tool-name { color: var(--fg); font-weight: 600; }
.tool-card.category-read  .tool-name { color: var(--accent); }
.tool-card.category-write .tool-name { color: var(--tool); }
.tool-card.category-run   .tool-name { color: var(--warn); }
.tool-card.category-coord .tool-name { color: var(--ok); }

.tool-card .tool-summary { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; min-width: 0; }
/* Friendly verb-phrase variant: reads like a sentence, not a symbol.
   Normal weight, full-fg color, takes the row's remaining width. */
.tool-card .tool-name.tool-phrase {
  color: var(--fg);
  font-weight: 400;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tool-card pre {
  margin: 6px 0 0;
  padding: 6px 8px;
  background: var(--bg);
  border-radius: 3px;
  font-size: 11px;
  color: var(--muted);
  overflow-x: auto;
  max-height: 240px;
}

/* ---- inline tool result inside a tool card ---- */
.tool-result-inline {
  margin-top: 8px;
  padding-top: 6px;
  border-top: 1px dashed var(--border);
}
.tool-result-inline.error { border-top-color: var(--err); }
.tool-result-label {
  color: var(--muted);
  font-size: 11px;
  margin-bottom: 3px;
}
.tool-result-inline.error .tool-result-label { color: var(--err); }
.tool-result-inline pre {
  margin: 0;
  padding: 6px 8px;
  background: var(--bg);
  border-radius: 3px;
  font-size: 11px;
  color: var(--muted);
  max-height: 200px;
  overflow-y: auto;
  white-space: pre-wrap;
  word-break: break-word;
}
.tool-result-inline.error pre { color: var(--err); }

/* ---- Read-of-image card: inline image preview ---- */
.read-image {
  display: block;
  max-width: 100%;
  max-height: 400px;
  margin-top: 6px;
  border-radius: 3px;
  border: 1px solid var(--border);
  object-fit: contain;
}

/* ---- Edit diff card: side-by-side, color-only ----
   Two halves per row; matching context lines sit at the same y on
   both sides so the reader scans horizontally. Pure additions get a
   blank-left placeholder; pure removals get blank-right; a removed-
   then-added pair is zipped line-by-line so a modification reads as
   old → new across the row. No prefix gutter and no header band —
   the band color (red left / green right / hatched blank) carries
   all the signal.

   Half kinds: diff-ctx (muted, both sides identical), diff-add (green
   band, right), diff-del (red band, left), diff-blank (placeholder). */
/* Diff card — Monaco / Antigravity model. Two-tier color overlay:
   a low-alpha line band signals "this whole line changed", a brighter
   word band signals "this token specifically changed". Syntax
   highlighting is preserved on every line — the diff layer is a
   background, never a foreground replacement. No strikethrough,
   no border accents, no font-weight changes, no row separators —
   the chromatic subtlety is the whole point. */
/* Diff renderer — used by the Edit-tool diff card AND by the
   File-write proposal review (server/static/app.js:ProposalDiffView).
   Selectors target `.diff.diff-split` so both contexts get identical
   styling without duplicated rules. */
.diff.diff-split {
  margin-top: 6px;
  border-radius: 4px;
  overflow: hidden;
  border: 1px solid var(--border);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px;
  line-height: 1.45;
  max-height: 480px;
  overflow-y: auto;
  background: var(--card);
  /* Container query host — rows flip from side-by-side to stacked
     when the diff itself is too narrow (narrow pane on desktop or
     phone), independent of the viewport. */
  container-type: inline-size;
  container-name: edit-diff;
}
.diff.diff-split .diff-row {
  display: flex;
  align-items: stretch;
}
.diff.diff-split .diff-half {
  flex: 1 1 50%;
  min-width: 0;
  padding: 1px 8px;
  border-right: 1px solid var(--border);
  white-space: pre-wrap;
  word-break: break-word;
}
.diff.diff-split .diff-half:last-child { border-right: 0; }
/* Unchanged context rows span both columns — identical text twice
   would just be noise. Only changed rows keep the side-by-side
   split. */
.diff.diff-split .diff-half.diff-full {
  flex: 1 1 100%;
  border-right: 0;
}
/* Tier 1 — line band. ~15% alpha so syntax-colored text stays
   legible. Paired and pure changes get the SAME line tint; Monaco
   makes no distinction. The two-tier signal comes from the optional
   word band on top, not from differentiating the line. */
.diff.diff-split .diff-add {
  background: rgba(63, 185, 80, 0.15);
}
.diff.diff-split .diff-del {
  background: rgba(248, 81, 73, 0.15);
}
.diff.diff-split .diff-ctx {
  opacity: 0.62;
}
.diff.diff-split .diff-blank {
  /* Diagonal hatch on empty halves — Monaco's `diagonalFill`. Low
     alpha so it doesn't compete with content on the other side. */
  background: repeating-linear-gradient(
    -45deg,
    transparent,
    transparent 6px,
    rgba(255, 255, 255, 0.05) 6px,
    rgba(255, 255, 255, 0.05) 12px
  );
}
/* Tier 2 — word band. Painted on changed token ranges within paired
   modification lines. ~40% alpha sits visibly above the 15% line
   band but doesn't dominate the syntax color underneath. No bold,
   no border, no padding pill — just a brighter rectangle, exactly
   like Monaco. The contained text is already syntax-highlighted by
   hljs (per-segment). */
.diff.diff-split .diff-chg {
  background: rgba(255, 255, 255, 0); /* base; per-side overrides below */
}
.diff.diff-split .diff-del .diff-chg {
  background: rgba(248, 81, 73, 0.40);
}
.diff.diff-split .diff-add .diff-chg {
  background: rgba(63, 185, 80, 0.40);
}
/* Stacked layout: when the diff container itself is narrow (e.g. a
   single-column pane on a phone, or a stacked pane in a tight
   column), put the old block above the new block instead of crushing
   the side-by-side columns. Each half goes full-width and the
   between-halves divider becomes a horizontal rule. */
@container edit-diff (max-width: 520px) {
  .diff.diff-split .diff-row {
    flex-direction: column;
  }
  .diff.diff-split .diff-half {
    flex: 1 1 100%;
    border-right: 0;
    border-bottom: 1px solid color-mix(in srgb, var(--border) 50%, transparent);
  }
  .diff.diff-split .diff-half:last-child {
    border-bottom: 0;
  }
  /* Empty placeholders read as wasted vertical space when stacked.
     Hide them so a pure add reads as one green block, a pure remove
     as one red block. Side-by-side mode keeps them so the row align
     hint survives. */
  .diff.diff-split .diff-half.diff-blank {
    display: none;
  }
}
/* Lang badge in the summary line (e.g. "PYTHON", "MARKDOWN"). */
.tool-card.edit-card .tool-lang {
  margin-left: 8px;
  font-size: 10px;
  padding: 1px 6px;
  border-radius: 3px;
  background: var(--card);
  border: 1px solid var(--border);
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* ---- input ---- */
.pane-input {
  border-top: 1px solid var(--border);
  background: var(--card);
  padding: 8px 10px;
  flex-shrink: 0;
}
.attachments {
  display: flex;
  gap: 6px;
  margin-bottom: 6px;
  flex-wrap: wrap;
}
.attachment {
  position: relative;
  border: 1px solid var(--border);
  border-radius: 4px;
  overflow: hidden;
  background: var(--bg);
}
.attachment img {
  display: block;
  max-height: 60px;
  max-width: 100px;
}
.attachment .x {
  position: absolute;
  top: 2px;
  right: 2px;
  background: rgba(0, 0, 0, 0.65);
  border: 0;
  color: white;
  border-radius: 50%;
  width: 16px;
  height: 16px;
  font-size: 10px;
  cursor: pointer;
  padding: 0;
  line-height: 1;
}
.pane-input textarea {
  width: 100%;
  min-height: 60px;
  resize: vertical;
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 6px 8px;
  font: inherit;
}
/* Active Coach loops bar — one row per active loop (/loop, /repeat).
   Sits above the mode chips so the next-fire countdown is always in
   view when composing a prompt. */
.active-loops {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 6px;
}
.active-loop {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: rgba(88, 166, 255, 0.04);
  font-size: 12px;
}
.active-loop-toggle,
.active-loop-kill {
  background: transparent;
  border: none;
  color: var(--muted);
  cursor: pointer;
  font-size: 12px;
  padding: 0 2px;
  line-height: 1;
}
.active-loop-toggle:hover,
.active-loop-kill:hover { color: var(--fg); }
.active-loop-label {
  color: var(--accent);
  font-weight: 600;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.active-loop-countdown {
  font-family: ui-monospace, Menlo, Consolas, monospace;
  color: var(--fg);
  min-width: 44px;
}
.active-loop-prompt {
  flex: 1 1 auto;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.active-loop-err {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 3px 8px;
  border: 1px solid #c55;
  border-radius: 6px;
  background: rgba(204, 85, 85, 0.08);
  color: #e88;
  font-size: 11px;
}
.active-loop-err-x {
  margin-left: auto;
  background: transparent;
  border: none;
  color: inherit;
  cursor: pointer;
  font-size: 13px;
  padding: 0 2px;
  line-height: 1;
}

/* Compact mode chips shown right above the textarea. Each chip reads
   the current pane setting (model / plan / effort). Active chips pick
   up the accent color so a non-default setting is visible at a glance. */
.pane-modes {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 6px;
  flex-wrap: wrap;
}
.pane-modes-spacer { flex: 1 1 auto; }
.pane-mode-chip {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--muted);
  border-radius: 12px;
  font: inherit;
  font-size: 11px;
  padding: 2px 10px;
  cursor: pointer;
  transition: color 80ms, border-color 80ms, background 80ms;
}
.pane-mode-chip:hover { color: var(--fg); }
.pane-mode-chip.active {
  color: var(--accent);
  border-color: var(--accent);
  background: rgba(88, 166, 255, 0.08);
}
.pane-mode-slash { font-family: ui-monospace, Menlo, Consolas, monospace; }

/* Context-usage meter: small horizontal bar between the effort chip
   and the slash-commands spacer. Fill color goes green → amber → red
   as the session eats its window. Inherits chip styling so it sits
   cleanly with the rest of the pane-modes row. */
.pane-mode-chip.context-bar {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 8px;
  cursor: default;
  min-width: 72px;
}
.context-bar-label {
  color: var(--muted);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.context-bar-track {
  flex: 1 1 auto;
  height: 6px;
  min-width: 40px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--border);
  border-radius: 3px;
  overflow: hidden;
  display: block;
  position: relative;
}
.context-bar-fill {
  display: block;
  height: 100%;
  transition: width 250ms ease-out, background 250ms ease-out;
}

/* Dismissable info banner — used by /tools and /help to show output
   without pushing anything to the agent. */
.pane-info {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  background: var(--card);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 3px;
  padding: 6px 8px;
  margin-bottom: 6px;
  font-size: 12px;
  max-height: 180px;
  overflow-y: auto;
}
.pane-info-body {
  margin: 0;
  flex: 1 1 auto;
  white-space: pre-wrap;
  color: var(--fg);
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 11px;
  line-height: 1.5;
}
.pane-info-close {
  background: transparent;
  border: 0;
  color: var(--muted);
  cursor: pointer;
  font-size: 14px;
  padding: 0 4px;
}
.pane-info-close:hover { color: var(--fg); }

/* Slash-command autocomplete. Positioned absolutely above the textarea. */
.pane-input-wrap { position: relative; }
.slash-menu {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 100%;
  margin-bottom: 4px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 4px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
  max-height: 240px;
  overflow-y: auto;
  z-index: 10;
}
.slash-item {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 6px 10px;
  cursor: pointer;
  font-size: 12px;
}
.slash-item.selected,
.slash-item:hover {
  background: rgba(88, 166, 255, 0.12);
}
.slash-cmd {
  color: var(--accent);
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-weight: 600;
  flex: 0 0 auto;
  min-width: 72px;
}
.slash-desc {
  color: var(--muted);
  flex: 1 1 auto;
}

.primary {
  margin-left: auto;
  padding: 6px 14px;
  background: var(--accent);
  color: var(--bg);
  border: 0;
  border-radius: 4px;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
.primary:disabled { opacity: 0.5; cursor: not-allowed; }
/* Run button now lives inside .pane-modes (right next to the
   "/ commands" chip) instead of below the textarea. Tighter padding
   so it reads as a chip-sized control rather than a footer button,
   and override the global `.primary { margin-left: auto }` so it
   sits flush against the slash chip with the row's natural 6px gap.
   Setting `margin-top: 0` belt-and-braces against the historical
   chip-row vertical drift. */
.pane-mode-chip + .pane-modes-run,
.pane-modes-run {
  margin-left: 0;
  padding: 3px 12px;
  font-size: 12px;
  line-height: 1.5;
  align-self: center;
}

/* ---- settings drawer ---- */
.drawer-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  z-index: 100;
  display: flex;
  justify-content: flex-end;
  animation: fade-in 100ms ease-out;
}
@keyframes fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
.drawer {
  width: 460px;
  max-width: 100%;
  height: 100%;
  background: var(--bg);
  border-left: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  animation: slide-in 140ms cubic-bezier(0.2, 0.9, 0.3, 1);
}
@keyframes slide-in {
  from { transform: translateX(20px); }
  to { transform: translateX(0); }
}
.drawer-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--border);
  background: var(--card);
}
.drawer-title {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  flex: 1;
}
.drawer-close {
  background: transparent;
  border: 0;
  color: var(--muted);
  font-size: 22px;
  cursor: pointer;
  padding: 0 4px;
  line-height: 1;
}
.drawer-close:hover { color: var(--fg); }
.drawer-body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 16px;
}
.drawer-section {
  padding-bottom: 20px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 20px;
}
.drawer-section:last-child { border-bottom: 0; margin-bottom: 0; padding-bottom: 0; }

.drawer-refresh {
  /* h3 is now a flex container (for the collapse chevron) — push the
     refresh button to the right end of the title row via auto margin. */
  margin-left: auto;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--muted);
  border-radius: 3px;
  font-size: 11px;
  padding: 1px 6px;
  cursor: pointer;
  font-family: inherit;
}
.drawer-refresh:hover { border-color: var(--accent); color: var(--fg); }
.drawer-refresh:disabled { opacity: 0.5; cursor: not-allowed; }

.drawer-health-list {
  list-style: none;
  padding: 0;
  margin: 6px 0 0;
}
.drawer-health-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
  font-size: 12px;
}
.drawer-health-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex: 0 0 8px;
}
.drawer-health-row.ok .drawer-health-dot { background: var(--ok); }
.drawer-health-row.fail .drawer-health-dot { background: var(--err); }
.drawer-health-name {
  font-weight: 600;
  min-width: 80px;
}
.drawer-health-detail {
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.drawer-section h3 {
  margin: 0 0 10px;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  cursor: pointer;
  user-select: none;
  display: flex;
  align-items: center;
  gap: 8px;
}
.drawer-section h3:hover { color: var(--fg); }
/* CSS-drawn chevron — no emoji per project convention. Right-pointing
   triangle when collapsed, rotated 90deg when open. */
.drawer-section h3::before {
  content: "";
  display: inline-block;
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 4px 0 4px 6px;
  border-color: transparent transparent transparent currentColor;
  transition: transform 120ms ease;
  flex-shrink: 0;
}
.drawer-section:not(.collapsed) > h3::before {
  transform: rotate(90deg);
}
/* Collapsed state hides every direct child of the section except the
   h3 itself. Using `display: none` (not visibility/height) so collapsed
   sections take zero vertical space. */
.drawer-section.collapsed { padding-bottom: 12px; margin-bottom: 12px; }
.drawer-section.collapsed > *:not(h3) { display: none !important; }
.drawer-section.collapsed h3 { margin-bottom: 0; }
.drawer-section p { margin: 0 0 10px; color: var(--fg); }
.drawer-section p.muted { color: var(--muted); font-size: 12px; }
.drawer-section ol { margin: 0 0 10px; padding-left: 20px; }
.drawer-section ol li { margin-bottom: 4px; color: var(--fg); }
.drawer-section code {
  background: var(--card);
  padding: 1px 5px;
  border-radius: 3px;
  font-size: 12px;
}
.drawer-section a { color: var(--accent); }
.drawer-section a:hover { text-decoration: underline; }

/* Shared button row + styles inside drawer sections — used by the
   Claude auth pane (Refresh tokens / Sign out / View usage) so the
   three controls line up at the same height regardless of label
   length. */
.drawer-btn-row {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
  margin: 0;
}
.drawer-btn-row > .drawer-btn { margin-left: 0; }
.drawer-btn {
  height: 30px;
  padding: 0 14px;
  border-radius: 4px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--fg);
  font: inherit;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  text-decoration: none;
  white-space: nowrap;
}
.drawer-btn:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.05);
  border-color: var(--muted);
}
.drawer-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.drawer-btn.primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--bg);
  font-weight: 600;
}
.drawer-btn.primary:hover:not(:disabled) {
  filter: brightness(1.08);
  background: var(--accent);
}
.drawer-btn.danger { color: var(--err); border-color: var(--err); }
.drawer-btn.danger:hover:not(:disabled) {
  background: rgba(229, 89, 89, 0.08);
}
.drawer-btn .external-arrow {
  font-size: 10px;
  opacity: 0.7;
}
.drawer-disabled {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 12px;
  opacity: 0.7;
}
.drawer-disabled label {
  display: block;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
  margin-top: 8px;
  margin-bottom: 4px;
}
.drawer-disabled label:first-of-type { margin-top: 0; }
.drawer-disabled input {
  width: 100%;
  padding: 6px 8px;
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: 3px;
  font: inherit;
}
.drawer-disabled input:disabled { cursor: not-allowed; }

/* ---- scrollbars ---- */
*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; }
*::-webkit-scrollbar-thumb:hover { background: var(--muted); }

/* ---- Phase 4: Project switch modals (PROJECTS_SPEC.md §6) ---- */
.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}
.modal {
  background: var(--panel, #1c1f26);
  border: 1px solid var(--border);
  border-radius: 8px;
  min-width: 420px;
  max-width: 600px;
  max-height: 80vh;
  display: flex;
  flex-direction: column;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
}
.modal-head {
  padding: 14px 18px 8px;
  border-bottom: 1px solid var(--border);
}
.modal-head h2 {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--fg);
}
.modal-body {
  padding: 14px 18px;
  overflow-y: auto;
  font-size: 12px;
  color: var(--fg);
  line-height: 1.5;
}
.modal-body p { margin: 0 0 10px; }
.modal-body p:last-child { margin-bottom: 0; }
.modal-body code {
  font-family: var(--mono, monospace);
  background: rgba(255, 255, 255, 0.05);
  padding: 1px 4px;
  border-radius: 3px;
  font-size: 11px;
}
.modal-foot {
  padding: 10px 18px 14px;
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  border-top: 1px solid var(--border);
}
.modal-foot-note {
  flex: 1 1 auto;
  align-self: center;
  color: var(--muted);
  font-size: 11px;
  font-style: italic;
}
.modal-btn {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--fg);
  padding: 6px 14px;
  border-radius: 4px;
  cursor: pointer;
  font: inherit;
  font-size: 12px;
}
.modal-btn:hover { background: rgba(255, 255, 255, 0.05); }
.modal-btn.primary {
  background: var(--accent, #e3a03a);
  border-color: var(--accent, #e3a03a);
  color: #14161c;
  font-weight: 600;
}
.modal-btn.primary:hover { background: #f0b250; }
.modal-btn.ghost { color: var(--muted); }

/* Confirm modal specifics. */
.switch-confirm-steps {
  margin: 0 0 8px 0;
  padding-left: 22px;
  list-style: disc;
}
.switch-confirm-steps li {
  margin-bottom: 4px;
}
.switch-confirm-warn {
  background: #2a1d0e;
  border-left: 3px solid #e3a03a;
  padding: 6px 10px;
  margin-top: 10px;
  font-size: 11px;
}
.switch-confirm-err {
  background: #33131c;
  border-left: 3px solid var(--err, #d05050);
  padding: 6px 10px;
  margin-top: 10px;
  font-size: 11px;
}

/* Busy modal stepper. */
.switch-step-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.switch-step {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
  color: var(--muted);
  font-family: var(--mono, monospace);
  font-size: 12px;
}
.switch-step.ok { color: var(--fg); }
.switch-step.running {
  color: var(--accent, #e3a03a);
}
.switch-step.failed,
.switch-step.timed_out { color: var(--err, #d05050); }
.step-icon {
  display: inline-flex;
  width: 16px;
  height: 16px;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  flex: 0 0 auto;
}
.step-icon.ok { color: #5fb86a; }
.step-icon.err { color: var(--err, #d05050); }
.step-icon.running {
  color: var(--accent, #e3a03a);
  animation: switch-spin 1s linear infinite;
}
.step-icon.pending { color: var(--border); }
.step-label {
  flex: 1 1 auto;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
@keyframes switch-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}
.switch-shimmer {
  margin-top: 14px;
  height: 2px;
  background: linear-gradient(
    90deg,
    transparent 0%,
    var(--accent, #e3a03a) 50%,
    transparent 100%
  );
  background-size: 200% 100%;
  animation: switch-shimmer 1.4s linear infinite;
}
@keyframes switch-shimmer {
  from { background-position: 200% 0; }
  to   { background-position: -200% 0; }
}
.switch-busy-err {
  margin-top: 12px;
  background: #33131c;
  border-left: 3px solid var(--err, #d05050);
  padding: 6px 10px;
  font-size: 11px;
  color: var(--fg);
}

/* ---------------------------------------------------------------- Kanban */
/* Dashboard slot __kanban (Docs/kanban-specs.md §11). Mirrors the
   compass-pane pattern: pane shell reuses .pane / .pane-header /
   .pane-body, kanban-specific layout lives under .kbn-* classes. */

/* LeftRail icon — three vertical columns of stacked rectangles, the
   universal kanban-board glyph. CSS-drawn per the no-emoji rule. */
.kanban-icon {
  display: inline-block;
  width: 16px;
  height: 16px;
  position: relative;
}
.kanban-icon::before,
.kanban-icon::after,
.kanban-icon > span {
  content: "";
  position: absolute;
  top: 1px;
  width: 3px;
  height: 14px;
  background: currentColor;
  border-radius: 1px;
  opacity: 0.55;
}
.kanban-icon::before { left: 1px; }
.kanban-icon > span { left: 6.5px; opacity: 0.85; }
.kanban-icon::after { left: 12px; }
.gear.active .kanban-icon::before,
.gear.active .kanban-icon::after,
.gear.active .kanban-icon > span { opacity: 1; }

/* Pane shell */
.kbn-pane { display: flex; flex-direction: column; min-height: 0; }
.kbn-header .kbn-title { font-weight: 600; }
.kbn-header .pane-head-label {
  display: flex;
  align-items: baseline;
  gap: 8px;
  min-width: 0;
}
.kbn-head-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
}
.kbn-body {
  display: flex;
  flex-direction: column;
  min-height: 0;
  padding: 8px 8px 12px;
  gap: 10px;
}
.kbn-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.kbn-check-row {
  display: flex;
  gap: 12px;
  align-items: center;
  flex-wrap: wrap;
  margin-top: 10px;
  color: var(--muted);
  font-size: 12px;
}
.kbn-check-row label {
  display: inline-flex;
  gap: 6px;
  align-items: center;
}

/* Toolbar buttons */
.kbn-btn {
  background: transparent;
  border: 1px solid var(--border, #2c3340);
  color: var(--fg);
  padding: 4px 10px;
  font-size: 12px;
  border-radius: 4px;
  cursor: pointer;
  font-family: inherit;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-height: 26px;
}
.kbn-btn:hover:not(:disabled) {
  background: rgba(255,255,255,0.04);
  border-color: var(--accent, #6da3d4);
}
.kbn-btn:disabled { opacity: 0.45; cursor: default; }
.kbn-btn-primary {
  background: var(--accent, #6da3d4);
  color: #0a0e15;
  border-color: var(--accent, #6da3d4);
  font-weight: 600;
}
.kbn-btn-primary:hover:not(:disabled) {
  filter: brightness(1.08);
  background: var(--accent, #6da3d4);
}
.kbn-archive-toggle.active {
  border-color: var(--accent, #6da3d4);
  color: var(--accent, #6da3d4);
}

.kbn-icon-btn {
  width: 28px;
  height: 28px;
  padding: 0;
  border: 1px solid var(--border, #2c3340);
  border-radius: 4px;
  background: transparent;
  color: var(--muted, #7e8694);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.kbn-icon-btn:hover:not(:disabled) {
  color: var(--fg);
  border-color: var(--accent, #6da3d4);
  background: rgba(255,255,255,0.04);
}
.kbn-icon-btn:disabled { opacity: 0.45; cursor: default; }
.kbn-icon {
  width: 14px;
  height: 14px;
  display: inline-block;
  position: relative;
  flex: 0 0 auto;
}
.kbn-plus-icon::before,
.kbn-plus-icon::after,
.kbn-close-icon::before,
.kbn-close-icon::after {
  content: "";
  position: absolute;
  left: 2px;
  right: 2px;
  top: 6px;
  height: 1.5px;
  background: currentColor;
}
.kbn-plus-icon::after { transform: rotate(90deg); }
.kbn-close-icon::before { transform: rotate(45deg); }
.kbn-close-icon::after { transform: rotate(-45deg); }
.kbn-refresh-icon {
  border: 1.5px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
}
.kbn-refresh-icon::after {
  content: "";
  position: absolute;
  right: 0;
  top: 0;
  width: 4px;
  height: 4px;
  border-top: 1.5px solid currentColor;
  border-right: 1.5px solid currentColor;
  transform: rotate(22deg);
}
.kbn-chevron-icon {
  width: 10px;
  height: 10px;
}
.kbn-chevron-icon::before {
  content: "";
  position: absolute;
  inset: 2px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
}
.kbn-maximize-icon,
.kbn-restore-icon,
.kbn-popout-icon {
  border: 1.5px solid currentColor;
  border-radius: 1px;
}
.kbn-restore-icon::after,
.kbn-popout-icon::after {
  content: "";
  position: absolute;
  width: 8px;
  height: 8px;
  border: 1.5px solid currentColor;
  background: var(--bg, #0e1218);
}
.kbn-restore-icon::after {
  left: -3px;
  bottom: -3px;
}
.kbn-popout-icon::after {
  right: -3px;
  top: -3px;
}

.kbn-error {
  background: #33131c;
  border-left: 3px solid var(--err, #d05050);
  color: var(--fg);
  font-size: 12px;
  padding: 6px 10px;
  border-radius: 0 3px 3px 0;
}

/* Columns */
.kbn-columns {
  display: grid;
  grid-template-columns: minmax(180px, 0.8fr) repeat(4, minmax(220px, 1fr));
  gap: 10px;
  flex: 1;
  min-height: 0;
  overflow: auto;
}
.kbn-column {
  display: flex;
  flex-direction: column;
  background: rgba(255,255,255,0.015);
  border: 1px solid var(--border, #2c3340);
  border-radius: 4px;
  min-height: 240px;
  min-width: 0;
}
.kbn-column-head {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted, #7e8694);
  padding: 8px 10px;
  border-bottom: 1px solid var(--border, #2c3340);
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.kbn-count {
  background: rgba(255,255,255,0.06);
  color: var(--fg);
  border-radius: 9px;
  padding: 0 7px;
  font-size: 10px;
  font-weight: 600;
  min-width: 18px;
  text-align: center;
}
.kbn-column-body {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 8px;
  overflow: auto;
}
.kbn-empty {
  font-size: 11px;
  color: var(--muted, #7e8694);
  font-style: italic;
  padding: 6px 4px;
}

/* Backlog column */
.kbn-backlog-column { opacity: 0.9; }
.kbn-backlog-card { cursor: default; border-left-color: var(--muted, #7e8694); }
.kbn-backlog-card:hover { border-color: var(--border, #2c3340); }
.kbn-card-meta { display: flex; gap: 8px; align-items: center; }
.kbn-backlog-proposer {
  font-size: 10px; font-weight: 600; letter-spacing: 0.04em;
  color: var(--muted); background: rgba(255,255,255,0.06);
  border-radius: 3px; padding: 0 5px;
}
.kbn-card-age { font-size: 10px; color: var(--muted); }

/* Card */
.kbn-card {
  background: var(--bg, #0e1218);
  border: 1px solid var(--border, #2c3340);
  border-left: 3px solid var(--muted, #7e8694);
  border-radius: 3px;
  padding: 8px 9px;
  display: flex;
  flex-direction: column;
  gap: 5px;
  cursor: pointer;
  transition: border-color 0.12s;
}
.kbn-card:hover { border-color: var(--accent, #6da3d4); }
.kbn-card.expanded { border-color: var(--accent, #6da3d4); }
.kbn-card.kbn-pri-urgent { border-left-color: var(--err, #d05050); }
.kbn-card.kbn-pri-high { border-left-color: var(--warn, #e3a03a); }
.kbn-card.kbn-pri-normal { border-left-color: var(--accent, #6da3d4); }
.kbn-card.kbn-pri-low { border-left-color: var(--muted, #7e8694); }

.kbn-card-top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 6px;
}
.kbn-pri-pill {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex-shrink: 0;
}
.kbn-cancelled-chip {
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.06em;
  padding: 1px 5px;
  border-radius: 2px;
  background: rgba(208, 80, 80, 0.15);
  color: var(--err, #d05050);
  border: 1px solid var(--err, #d05050);
}
.kbn-trajectory {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--muted, #7e8694);
  font-family: var(--mono, monospace);
}
.kbn-traj-arrow {
  opacity: 0.5;
  font-size: 8px;
}
.kbn-traj-stage {
  padding: 1px 4px;
  border-radius: 2px;
  border: 1px solid var(--muted, #7e8694);
  opacity: 0.65;
}
.kbn-traj-stage.current {
  color: var(--accent, #6da3d4);
  border-color: var(--accent, #6da3d4);
  background: rgba(110, 163, 212, 0.18);
  opacity: 1;
}
.kbn-help {
  font-size: 11px;
  line-height: 1.4;
  color: var(--muted, #7e8694);
  background: rgba(125, 134, 148, 0.06);
  border-left: 2px solid var(--muted, #7e8694);
  padding: 6px 8px;
  margin: 8px 0;
  border-radius: 2px;
}
.kanban-flow-health {
  font-size: 11px;
  letter-spacing: 0.02em;
  color: var(--muted, #7e8694);
  padding: 4px 10px;
  border-top: 1px solid var(--border, #2a2f38);
  background: var(--bg-elev, rgba(20, 24, 30, 0.4));
  font-family: var(--mono, monospace);
}
.kanban-flow-health.alert {
  color: var(--err, #d05050);
  background: rgba(208, 80, 80, 0.08);
}
.kanban-flow-health.ok {
  color: var(--ok, #6dca8b);
}
.kbn-card-title {
  font-size: 13px;
  line-height: 1.32;
  color: var(--fg);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.kbn-card.expanded .kbn-card-title {
  display: block;
  overflow: visible;
}
.kbn-stage-label {
  font-size: 9px;
  letter-spacing: 0.08em;
  color: var(--muted, #7e8694);
  font-weight: 600;
}
.kbn-card-row {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
.kbn-flag {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.08em;
  padding: 1px 4px;
  border: 1px solid currentColor;
  border-radius: 2px;
}

/* Avatar / assignee */
.kbn-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  font-size: 10px;
  font-weight: 600;
  color: var(--fg);
  background: rgba(255,255,255,0.04);
  border-radius: 50%;
  flex-shrink: 0;
}
.kbn-avatar-hollow {
  border: 1.5px dashed var(--muted, #7e8694);
  background: transparent;
  color: var(--muted, #7e8694);
}
.kbn-avatar-filled {
  border: 1.5px solid var(--accent, #6da3d4);
  background: rgba(110, 163, 212, 0.18);
  color: var(--accent, #6da3d4);
}
.kbn-coach-chip,
.kbn-pool-chip,
.kbn-unassigned {
  font-size: 10px;
  color: var(--muted, #7e8694);
  padding: 1px 6px;
  border: 1px dashed var(--border, #2c3340);
  border-radius: 8px;
  background: transparent;
  font-family: inherit;
}
.kbn-coach-chip { color: var(--accent, #6da3d4); border-color: var(--accent, #6da3d4); }
.kbn-unassigned {
  color: var(--warn, #e3a03a);
  border-color: var(--warn, #e3a03a);
  cursor: pointer;
}
.kbn-unassigned:hover { background: rgba(227, 160, 58, 0.12); }

/* Markdown link row */
.kbn-card-links { display: flex; gap: 8px; flex-wrap: wrap; }
.kbn-link {
  font-size: 10px;
  color: var(--accent, #6da3d4);
  text-decoration: none;
}
.kbn-link:hover { text-decoration: underline; }

.kbn-compass-pip {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  margin-left: 4px;
  vertical-align: middle;
  opacity: 0.65;
}
.kbn-drift-banner {
  font-size: 11px;
  color: var(--err, #d05050);
  background: rgba(208, 80, 80, 0.08);
  border-left: 2px solid var(--err, #d05050);
  padding: 3px 6px;
  border-radius: 0 2px 2px 0;
}

.kbn-card-expanded {
  border-top: 1px solid var(--border, #2c3340);
  margin-top: 2px;
  padding-top: 7px;
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.kbn-card-description {
  font-size: 12px;
  line-height: 1.35;
  color: var(--fg);
  white-space: pre-wrap;
}
.kbn-card-facts {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  font-size: 10px;
  color: var(--muted, #7e8694);
}
.kbn-expanded-head {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted, #7e8694);
}
.kbn-history {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.kbn-history-row {
  display: grid;
  grid-template-columns: minmax(72px, 1fr) minmax(56px, 1fr) auto auto auto;
  gap: 6px;
  align-items: center;
  font-size: 10px;
  color: var(--fg);
  padding: 3px 0;
  border-top: 1px solid rgba(255,255,255,0.04);
}
.kbn-history-role {
  color: var(--accent, #6da3d4);
  font-weight: 600;
}
.kbn-history-state {
  border: 1px solid var(--border, #2c3340);
  border-radius: 2px;
  padding: 1px 4px;
  color: var(--muted, #7e8694);
}
.kbn-history-pass { color: var(--ok, #5fb86a); border-color: var(--ok, #5fb86a); }
.kbn-history-fail { color: var(--err, #d05050); border-color: var(--err, #d05050); }
.kbn-history-active { color: var(--warn, #e3a03a); border-color: var(--warn, #e3a03a); }
.kbn-history-done { color: var(--ok, #5fb86a); border-color: var(--ok, #5fb86a); }
.kbn-history-muted { color: var(--muted, #7e8694); }

.kbn-audit-column {
  gap: 0;
}
.kbn-audit-band {
  display: flex;
  flex-direction: column;
  min-height: 0;
  flex: 1 1 0;
}
.kbn-audit-band + .kbn-audit-band {
  border-top: 1px solid var(--border, #2c3340);
}
.kbn-audit-band-head {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted, #7e8694);
  padding: 6px 10px 0;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

/* Composer modal */
.kbn-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}
.kbn-modal {
  background: var(--bg, #0e1218);
  border: 1px solid var(--border, #2c3340);
  border-radius: 6px;
  padding: 14px 16px 12px;
  width: min(540px, 92vw);
  max-height: 88vh;
  overflow: auto;
  display: flex;
  flex-direction: column;
  gap: 10px;
  box-shadow: 0 16px 48px rgba(0,0,0,0.55);
}
.kbn-modal-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-weight: 600;
  font-size: 14px;
}
.kbn-label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted, #7e8694);
}
.kbn-input,
.kbn-textarea,
.kbn-select {
  background: rgba(255,255,255,0.025);
  border: 1px solid var(--border, #2c3340);
  color: var(--fg);
  padding: 6px 8px;
  font-size: 13px;
  font-family: inherit;
  border-radius: 3px;
}
.kbn-textarea { resize: vertical; min-height: 88px; }
.kbn-backlog-input {
  width: 100%;
  box-sizing: border-box;
  resize: vertical;
  min-height: 96px;
  max-height: 60vh;
  line-height: 1.45;
  white-space: pre-wrap;
}
.kbn-input:focus,
.kbn-textarea:focus,
.kbn-select:focus {
  outline: none;
  border-color: var(--accent, #6da3d4);
}
.kbn-modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding-top: 4px;
}

/* Archive drawer */
.kbn-archive-drawer {
  border: 1px solid var(--border, #2c3340);
  border-radius: 4px;
  background: rgba(255,255,255,0.012);
  display: flex;
  flex-direction: column;
  max-height: 360px;
  min-height: 0;
  overflow: hidden;
}
.kbn-archive-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border-bottom: 1px solid var(--border, #2c3340);
  font-size: 11px;
}
.kbn-archive-search { flex: 1; min-width: 140px; }
.kbn-date-filter { max-width: 142px; }
.kbn-archive-body {
  display: flex;
  flex-direction: column;
  overflow: auto;
  padding: 4px 8px;
}
.kbn-archive-row {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 6px 4px;
  border-bottom: 1px solid var(--border, #2c3340);
  cursor: pointer;
}
.kbn-archive-row:hover { background: rgba(255,255,255,0.025); }
.kbn-archive-row:last-child { border-bottom: none; }
.kbn-archive-row-title {
  font-size: 12px;
  color: var(--fg);
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
.kbn-archive-row-meta {
  font-size: 10px;
  color: var(--muted, #7e8694);
  display: flex;
  gap: 8px;
  align-items: center;
}
.kbn-archive-row-links { display: flex; gap: 6px; }
.kbn-archive-pager {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border-top: 1px solid var(--border, #2c3340);
  font-size: 11px;
}
.kbn-pager-info { color: var(--muted, #7e8694); }

/* EnvPane "Tasks live in the Kanban pane" hint card */
.kbn-env-hint {
  border: 1px dashed var(--border, #2c3340);
  border-radius: 3px;
  padding: 8px 10px;
  font-size: 11px;
  color: var(--muted, #7e8694);
  background: rgba(255,255,255,0.012);
}
.kbn-env-hint .kbn-env-hint-link {
  color: var(--accent, #6da3d4);
  background: transparent;
  border: none;
  padding: 0;
  font: inherit;
  cursor: pointer;
  text-decoration: underline;
}

/* Mobile reflow — phones get a single-column board with horizontal
   scroll between columns; archive drawer goes full width. */
@media (max-width: 700px) {
  .kbn-columns {
    grid-template-columns: 1fr;
    overflow-y: auto;
    overflow-x: hidden;
  }
  .kbn-column { min-height: 160px; }
  .kbn-archive-drawer { max-height: 60vh; }
  .kbn-modal { width: 96vw; max-height: 92vh; }
}
