/* Panel UI styles. Dark scheme matching the existing operator panel.
   Kept variable-driven so we can swap palette later without hunting through
   selectors. */

:root {
  --bg: #0e0f12;
  --bg-elev-1: #15171c;
  --bg-elev-2: #1a1d23;
  --border: #262931;
  --border-strong: #353944;
  --text: #d8dde6;
  --text-muted: #8b91a0;
  --text-dim: #5e6470;
  --accent: #6ea8ff;
  --accent-strong: #4a8dff;
  --success: #5ed4a3;
  --warning: #f0b46a;
  --danger: #f06a6a;
  --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
}

* {
  box-sizing: border-box;
}

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.5;
}

#root {
  max-width: 1800px;
  margin: 0 auto;
  /* Tight horizontal padding — operators want screen real estate. */
  padding: 14px 10px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  /* Floor the workspace to the viewport but let the page grow taller when
     the operator drags the grid / console to bigger sizes. The page
     scrolls once total widget height exceeds the viewport. */
  min-height: 100vh;
}

/* ── Top instructions panel ──────────────────────────────────────────── */
.top-panel {
  background: var(--bg-elev-1);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 16px;
}
.top-panel-text {
  margin: 0;
  font-size: 12.5px;
  color: var(--text-muted);
  line-height: 1.5;
}
.top-panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.top-panel-title {
  margin: 0;
  font-size: 13px;
  font-weight: 700;
  color: var(--text);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.top-panel-body {
  margin-top: 12px;
  display: grid;
  gap: 12px;
}
/* Collapsed state — toggled by main.ts via .is-collapsed on .top-panel.
   The body is hidden; the panel shrinks to just its header row. */
.top-panel.is-collapsed > .top-panel-body {
  display: none;
}
.top-panel.is-collapsed {
  padding-top: 10px;
  padding-bottom: 10px;
}
.top-panel-warning {
  padding: 9px 12px;
  background: rgba(240, 106, 106, 0.07);
  border: 1px solid rgba(240, 106, 106, 0.3);
  border-radius: 7px;
  color: var(--text);
  font-size: 12px;
  line-height: 1.5;
}
.top-panel-warning strong {
  color: var(--danger);
}
.top-panel-section h3 {
  margin: 0 0 6px;
  font-size: 11px;
  font-weight: 700;
  color: var(--text);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.top-panel-section ul {
  margin: 0;
  padding-left: 18px;
  display: grid;
  gap: 6px;
}
.top-panel-section li {
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--text-muted);
}
.top-panel-section li strong {
  color: var(--text);
  font-weight: 700;
}
.top-panel-section li em {
  font-style: italic;
  color: var(--text);
}

/* ── Workspace (resizable splitter layout) ─────────────────────────────
   The .workspace flex container fills whatever vertical space #root has
   left after the TopPanel. Inside it: left-pane | splitter | right-pane.
   The right-pane is a column flex with three sections separated by
   horizontal splitters. Two sections (launcher, console) carry a fixed
   pixel size via --launcher-h / --console-h on the workspace; the third
   (grid) absorbs slack via flex: 1 1 auto. The left-pane width comes
   from --left-pane-w. All three vars are mutated by splitter.ts at
   drag time and persisted to localStorage. */

.workspace {
  /* Custom-props give us a single source of truth for widget sizes; both
     CSS and JS read/write them via style.setProperty. The grid + console
     defaults are intentionally large — the page scrolls, so making the
     live previews and the log pane spacious by default beats making the
     operator drag every session. */
  /* Default the left pane to 40% of the workspace width — the operator
     wanted the coach list and the right-side workspace at a 40/60 split
     by default. Once the operator drags the splitter, splitter.ts writes
     a pixel value into this var and it overrides the percentage. */
  --left-pane-w: 40%;
  --launcher-h: 360px;
  --grid-h: 720px;
  --console-h: 480px;
  --splitter-thickness: 6px;
  --splitter-hit: 10px;

  display: flex;
  flex-direction: row;
  flex: 1 1 auto;
  min-height: 0;
  min-width: 0;
  gap: 0;
}

.left-pane {
  flex: 0 0 var(--left-pane-w);
  min-width: 200px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  overflow: hidden;
  /* Pin the coach list to the viewport so it never stretches to match the
     right pane's full (potentially tall) height. The .coach-list inside
     already has its own overflow-y: auto for internal scrolling. */
  position: sticky;
  top: 14px;
  align-self: flex-start;
  max-height: calc(100vh - 28px);
}

.right-pane {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  gap: 0;
  padding-left: 14px;
}

/* Each section in the right pane. Two of them are fixed-sized (launcher,
   console) via the workspace's CSS vars; the third (grid) grows to fill. */
.right-pane-section {
  display: flex;
  flex-direction: column;
  min-height: 0;
  min-width: 0;
  overflow: hidden;
}
.right-pane-section[data-pane="launcher"] {
  flex: 0 0 var(--launcher-h);
}
.right-pane-section[data-pane="grid"] {
  flex: 0 0 var(--grid-h);
  min-height: 200px;
}
.right-pane-section[data-pane="console"] {
  flex: 0 0 var(--console-h);
  min-height: 120px;
}

/* Make the inner section content fill the wrapper so its scroll mechanics
   (launcher form scroll, console pane scroll) hit the right bounds. */
.right-pane-section > .launcher,
.right-pane-section > .grid-section,
.right-pane-section > .console-section {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: auto;
}

/* ── Splitters ────────────────────────────────────────────────────────
   Visible bar is `--splitter-thickness` wide; the hit area is wider
   (`--splitter-hit`) for grab tolerance, achieved by a pseudo-element so
   the layout cost stays at the visible thickness. */
.splitter {
  position: relative;
  background: var(--border);
  flex: 0 0 var(--splitter-thickness);
  z-index: 1;
  transition: background 100ms ease;
}
.splitter:hover,
.splitter.is-dragging {
  background: var(--accent);
}
.splitter::after {
  content: "";
  position: absolute;
  inset: 0;
  /* Extend the hit area outward in the drag axis. The axis-specific
     overrides below replace this with the right dimensions. */
}
.splitter-v {
  cursor: col-resize;
  /* Vertical bar between left & right pane. */
  margin: 0 4px;
  border-radius: 2px;
}
.splitter-v::after {
  left: calc(-1 * (var(--splitter-hit) - var(--splitter-thickness)) / 2);
  right: calc(-1 * (var(--splitter-hit) - var(--splitter-thickness)) / 2);
  top: 0;
  bottom: 0;
}
.splitter-h {
  cursor: row-resize;
  /* Horizontal bar between vertically-stacked widgets. */
  margin: 4px 0;
  border-radius: 2px;
}
.splitter-h::after {
  top: calc(-1 * (var(--splitter-hit) - var(--splitter-thickness)) / 2);
  bottom: calc(-1 * (var(--splitter-hit) - var(--splitter-thickness)) / 2);
  left: 0;
  right: 0;
}

/* While dragging, freeze the cursor + suppress text selection across the
   whole document. The body class is toggled by splitter.ts. */
body.is-resizing {
  cursor: col-resize;
  user-select: none;
}
body.is-resizing.is-resizing-y {
  cursor: row-resize;
}
body.is-resizing iframe {
  /* iframes swallow mousemove events from their parent. Disable pointer
     events on every iframe (i.e. agent live previews) for the duration
     of the drag so the splitter handler keeps tracking the cursor. */
  pointer-events: none;
}

@media (max-width: 900px) {
  /* Splitters are useless on narrow screens — fall back to a stacked
     no-splitter layout that scrolls the page. */
  #root {
    height: auto;
    min-height: 100vh;
  }
  .workspace {
    flex-direction: column;
  }
  .left-pane,
  .right-pane {
    flex: 0 0 auto;
    padding-left: 0;
  }
  .right-pane-section[data-pane="launcher"],
  .right-pane-section[data-pane="console"] {
    flex: 0 0 auto;
  }
  .splitter {
    display: none;
  }
}

/* ── Coach list section ──────────────────────────────────────────────── */
.coach-list-section {
  background: var(--bg-elev-1);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  /* Fill the left-pane height that the splitter layout above allocated;
     internal scrolling kicks in via .coach-list below. */
  flex: 1 1 auto;
  min-height: 0;
}
.coach-list-controls {
  display: grid;
  gap: 8px;
}
.coach-list-row {
  display: flex;
  gap: 8px;
}
.coach-search-wrap {
  flex: 1;
  position: relative;
  min-width: 0;
}
.coach-list-input {
  width: 100%;
  background: var(--bg-elev-2);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 7px 30px 7px 10px; /* extra right padding for the × */
  font: inherit;
  font-size: 12.5px;
  min-width: 0;
}
.coach-list-input:focus {
  outline: none;
  border-color: var(--accent);
}
.coach-search-clear {
  position: absolute;
  right: 4px;
  top: 50%;
  transform: translateY(-50%);
  width: 22px;
  height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  background: transparent;
  color: var(--text-dim);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  border-radius: 4px;
  padding: 0;
  font-family: inherit;
  transition: background 80ms ease, color 80ms ease;
}
.coach-search-clear:hover {
  background: var(--bg);
  color: var(--text);
}
.coach-list-add {
  padding: 6px 12px;
  font-size: 12.5px;
}
.coach-list-filters {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px 6px;
}
.coach-filter-field {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}
.coach-filter-field label {
  font-size: 10px;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.coach-filter-field select {
  background: var(--bg-elev-2);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 5px 8px;
  font: inherit;
  font-size: 11.5px;
  cursor: pointer;
  min-width: 0;
  width: 100%;
}
.coach-filter-field select:focus {
  outline: none;
  border-color: var(--accent);
}
.coach-filter-reset {
  font-size: 10.5px;
  padding: 3px 8px;
  align-self: flex-start;
  margin-top: 8px;
}

/* Sort & filter collapsible panel. Closed by default. */
.filters-collapsible {
  display: block;
}
.filters-summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 4px 0;
  user-select: none;
  outline: none;
}
.filters-summary::-webkit-details-marker {
  display: none;
}
.filters-summary::before {
  content: "▸";
  font-size: 10px;
  color: var(--text-muted);
  display: inline-block;
  transition: transform 120ms ease;
}
.filters-collapsible[open] > .filters-summary::before {
  transform: rotate(90deg);
}
.filters-collapsible > .coach-list-filters {
  margin-top: 8px;
  /* Bound the open filter panel so it doesn't push the coach list down
     when expanded. The filter grid scrolls internally instead. The reset
     button sits outside this container so it stays pinned visible below. */
  max-height: 280px;
  overflow-y: auto;
  padding-right: 4px;
}
/* Tiny pink dot beside the "Sort & filter" label when any filter is active —
   so the operator can see at a glance that the list is narrowed even when
   the panel is collapsed. Toggled by the client via a class. */
.filters-active-dot {
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: var(--accent);
  display: none;
  margin-left: auto;
  box-shadow: 0 0 6px var(--accent);
}
.filters-active-dot.is-active {
  display: inline-block;
}
/* Full-width filter field (used by the "added since" text input — it gets
   placeholder copy too long for half a column). */
.coach-filter-field-wide {
  grid-column: 1 / -1;
}
.coach-filter-field-wide input[type="text"] {
  background: var(--bg-elev-2);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 5px 8px;
  font: inherit;
  font-size: 11.5px;
  width: 100%;
}
.coach-filter-field-wide input[type="text"]:focus {
  outline: none;
  border-color: var(--accent);
}

/* Section dividers between search / filters / bulk / list. */
.coach-list-divider {
  border: 0;
  height: 1px;
  background: var(--border);
  margin: 2px 0;
}

/* ── Select-all header + bulk panel ──────────────────────────────────── */
.coach-bulk-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 11.5px;
  color: var(--text-muted);
}
.coach-select-all {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  user-select: none;
}
.coach-select-all input {
  margin: 0;
  cursor: pointer;
}
.coach-selection-count {
  font-size: 11px;
  color: var(--accent);
  font-weight: 600;
}
.coach-bulk-panel {
  background: var(--bg-elev-2);
  border: 1px solid var(--border-strong);
  border-radius: 7px;
  padding: 10px;
}
.coach-bulk-content {
  display: grid;
  gap: 8px;
}
.coach-bulk-info {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 12px;
}
.coach-bulk-flag-row {
  display: grid;
  grid-template-columns: 80px 1fr 1fr;
  gap: 6px;
  align-items: center;
}
.coach-bulk-flag-label {
  font-size: 11px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: 600;
}
.coach-bulk-btn {
  padding: 5px 10px;
  font-size: 11.5px;
}
.coach-bulk-divider {
  border: 0;
  height: 1px;
  background: var(--border);
  margin: 2px 0;
}
.coach-bulk-delete {
  width: 100%;
}

.coach-list {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 4px 2px;
}
.coach-list-empty {
  padding: 28px 16px;
  text-align: center;
  color: var(--text-dim);
  font-size: 12.5px;
}

/* Row */
.coach-row {
  /* Grid: [select checkbox] [main column].
     Subtle background + border so every row reads as a distinct card. */
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 8px;
  align-items: start;
  padding: 8px 10px;
  border-radius: 7px;
  margin-bottom: 4px;
  background: rgba(255, 255, 255, 0.018);
  border: 1px solid var(--border);
  cursor: pointer;
  font-size: 12.5px;
}
.coach-row:hover {
  background: var(--bg-elev-2);
  border-color: var(--border-strong);
}
.coach-row.open {
  background: var(--bg-elev-2);
  border-color: var(--accent);
  cursor: default;
}
.coach-row.selected {
  border-color: var(--accent);
  background: rgba(110, 168, 255, 0.05);
}
.coach-row.hidden {
  opacity: 0.55;
}
.coach-row.hidden .coach-row-name {
  text-decoration: line-through;
  text-decoration-color: var(--text-dim);
}

/* Leading select checkbox column. */
.coach-row-check {
  display: flex;
  align-items: center;
  justify-content: center;
  padding-top: 2px;
  cursor: pointer;
}
.coach-row-check-empty {
  width: 14px; /* preserve the column width for drafts (no checkbox) */
}
.coach-row-checkbox {
  margin: 0;
  cursor: pointer;
}

.coach-row-main {
  min-width: 0; /* lets long names truncate instead of overflowing the row */
}

.coach-row-top {
  display: flex;
  align-items: center;
  gap: 8px;
}
/* When the row is expanded, pin the name/handle header to the top of the
   coach-list scroll container so the operator always sees which coach
   they're editing while scrolling through the editor fields. */
.coach-row.open .coach-row-top {
  position: sticky;
  top: -1px;
  background: var(--bg-elev-2);
  padding: 6px 4px;
  margin: -6px -4px 4px -4px;
  border-bottom: 1px solid var(--border);
  z-index: 3;
}

/* ── Inline V/A/I flag pills (collapsed rows) ─────────────────────────── */
.coach-flag-pills {
  display: inline-flex;
  gap: 3px;
}
.coach-flag-pill {
  height: 20px;
  padding: 0 8px;
  border-radius: 4px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.02em;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text-dim);
  cursor: pointer;
  font-family: inherit;
  transition: background 80ms ease, color 80ms ease, border-color 80ms ease;
}
.coach-flag-pill:hover {
  border-color: var(--border-strong);
  color: var(--text);
}
.coach-flag-pill.on {
  border-color: currentColor;
}
.coach-flag-visible.on {
  background: rgba(94, 212, 163, 0.16);
  color: var(--success);
}
.coach-flag-approved.on {
  background: rgba(217, 70, 168, 0.16);
  color: #ed7cc4;
}
.coach-flag-ignore.on {
  background: rgba(240, 106, 106, 0.16);
  color: var(--danger);
}
.coach-row-name {
  font-weight: 600;
}
.coach-row-handle {
  font-family: var(--mono);
  opacity: 0.55;
  font-size: 11px;
}
.coach-row-sub {
  margin-top: 3px;
  font-size: 11px;
  color: var(--text-dim);
}
.grow {
  flex: 1;
}

/* Status dot + avatar */
.coach-dot {
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: var(--text-dim);
  flex: 0 0 auto;
}
.coach-dot-on {
  background: var(--success);
  box-shadow: 0 0 6px var(--success);
}
.coach-dot-draft {
  background: var(--accent);
  box-shadow: 0 0 6px var(--accent);
}
.coach-dot-seed {
  background: #6aa5ff;
  box-shadow: 0 0 6px #6aa5ff;
}
.coach-avatar {
  width: 22px;
  height: 22px;
  flex: 0 0 auto;
  border-radius: 5px;
  overflow: hidden;
  background: linear-gradient(135deg, #3c78d7, #d946a8);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  font-weight: 700;
  color: rgba(255, 255, 255, 0.85);
}
.coach-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Tags */
.coach-tag {
  font-size: 9.5px;
  padding: 1px 6px;
  border-radius: 4px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 700;
}
.coach-tag-seed {
  background: rgba(106, 165, 255, 0.12);
  color: #8ab8ff;
  border: 1px solid rgba(106, 165, 255, 0.3);
}
.coach-tag-scraped {
  background: var(--bg);
  color: var(--text-muted);
  border: 1px solid var(--border);
}
.coach-tag-hidden {
  background: rgba(240, 106, 106, 0.12);
  color: var(--danger);
  border: 1px solid rgba(240, 106, 106, 0.32);
}
.coach-tag-approved {
  background: rgba(217, 70, 168, 0.12);
  color: #ed7cc4;
  border: 1px solid rgba(217, 70, 168, 0.32);
}
.coach-tag-ignore {
  background: rgba(255, 255, 255, 0.04);
  color: rgba(255, 255, 255, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.18);
  text-decoration: line-through;
}

/* Inline editor */
.coach-editor {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px dashed var(--border);
  display: grid;
  gap: 8px;
}
.coach-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.coach-field label {
  font-size: 10.5px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Help tooltip — a small "?" pill that reveals an explanatory tooltip on
   hover or keyboard focus. Pure CSS, no JS. Lives anywhere an inline element
   can sit (next to field labels, beside individual checkbox labels, etc). */
.help-tooltip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 13px;
  height: 13px;
  margin-left: 5px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.07);
  border: 1px solid rgba(255, 255, 255, 0.12);
  color: rgba(255, 255, 255, 0.55);
  font-family: ui-sans-serif, system-ui, sans-serif;
  font-size: 9.5px;
  font-weight: 700;
  line-height: 1;
  text-transform: none;
  letter-spacing: 0;
  cursor: help;
  user-select: none;
  position: relative;
  vertical-align: middle;
}
.help-tooltip:hover,
.help-tooltip:focus-visible {
  outline: none;
  background: rgba(217, 70, 168, 0.18);
  border-color: rgba(217, 70, 168, 0.42);
  color: #ed7cc4;
}
.help-tooltip-body {
  display: none;
  position: absolute;
  bottom: calc(100% + 7px);
  /* Anchor to the icon's left edge and extend rightward into the editor
     so first-column fields (name, etc) don't clip off the panel's left
     side. The editor is wide enough that a 240px tooltip extending right
     stays comfortably inside the viewport. */
  left: -4px;
  transform: none;
  width: max-content;
  max-width: 240px;
  padding: 7px 9px;
  background: #15151c;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 6px;
  font-family: ui-sans-serif, system-ui, sans-serif;
  font-size: 11.5px;
  font-weight: 400;
  font-style: normal;
  line-height: 1.4;
  letter-spacing: 0;
  text-transform: none;
  color: rgba(255, 255, 255, 0.88);
  z-index: 20;
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.45);
  pointer-events: none;
  white-space: normal;
  text-align: left;
}
.help-tooltip:hover .help-tooltip-body,
.help-tooltip:focus-visible .help-tooltip-body,
.help-tooltip:focus-within .help-tooltip-body {
  display: block;
}
.coach-field input[type="text"],
.coach-field input[type="number"],
.coach-field input[type="url"],
.coach-field select,
.coach-field textarea {
  background: var(--bg-elev-1);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 5px 8px;
  font: inherit;
  font-size: 12px;
}
.coach-field input:focus,
.coach-field select:focus,
.coach-field textarea:focus {
  outline: none;
  border-color: var(--accent);
}
.coach-field textarea {
  min-height: 50px;
  resize: vertical;
  font-family: inherit;
}
.coach-field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}
/* Manual avatar-replace row under the avatar_url field: URL input + the
   "Update image" button sitting flush on its right. */
.coach-avatar-replace-row {
  display: flex;
  gap: 6px;
  align-items: center;
}
.coach-avatar-replace-row input[type="url"] {
  flex: 1 1 auto;
  min-width: 0;
  background: var(--bg-elev-1);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 5px 8px;
  font: inherit;
  font-size: 12px;
}
.coach-avatar-replace-row input[type="url"]:focus {
  outline: none;
  border-color: var(--accent);
}
.coach-avatar-replace-row .btn-secondary {
  flex: 0 0 auto;
  white-space: nowrap;
}

.coach-checks,
.coach-editor-checks {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 10px;
  background: var(--bg-elev-1);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 5px 8px;
}
.coach-checks label,
.coach-editor-checks label {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 11.5px;
  color: var(--text);
  cursor: pointer;
}
.coach-checks input,
.coach-editor-checks input {
  margin: 0;
}
/* Clickable URL chips rendered under the `links` JSON textarea and the
   `source_urls` newline-list textarea. Lets the operator one-click out to
   each URL without having to copy from the textarea. Greyed-out (.dead)
   chip for entries with no clickable URL. */
.link-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 6px;
  margin-top: 6px;
}
.link-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 8px;
  font-size: 11.5px;
  color: var(--text);
  text-decoration: none;
  background: var(--bg-elev-1);
  border: 1px solid var(--border);
  border-radius: 999px;
  max-width: 100%;
}
.link-chip:hover {
  background: rgba(110, 168, 255, 0.1);
  border-color: var(--accent);
  color: var(--accent);
}
.link-chip .plat {
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 9.5px;
  font-weight: 700;
  opacity: 0.7;
}
.link-chip .val {
  font-family: var(--mono);
  font-size: 11px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 220px;
}
.link-chip.dead {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}

.coach-editor-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 4px;
}
.coach-editor-actions .btn-primary,
.coach-editor-actions .btn-secondary,
.coach-editor-actions .btn-ghost {
  padding: 6px 12px;
  font-size: 12.5px;
}

/* ── Confirm dialog ──────────────────────────────────────────────────── */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(2px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
  animation: modal-fade 120ms ease;
}
@keyframes modal-fade {
  from { opacity: 0; }
  to { opacity: 1; }
}
.modal-card {
  background: var(--bg-elev-1);
  border: 1px solid var(--border-strong);
  border-radius: 10px;
  padding: 20px 22px;
  min-width: 320px;
  max-width: 460px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
}
.modal-title {
  margin: 0 0 8px 0;
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
}
.modal-body {
  margin: 0 0 16px 0;
  font-size: 13px;
  color: var(--text-muted);
  line-height: 1.5;
}
.modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}
.modal-actions .btn-primary,
.modal-actions .btn-secondary,
.modal-actions .btn-danger {
  padding: 7px 14px;
  font-size: 13px;
  font: inherit;
  font-size: 13px;
  border-radius: 6px;
  cursor: pointer;
  border: 1px solid var(--border-strong);
}
.btn-danger {
  background: rgba(240, 106, 106, 0.16);
  color: var(--danger);
  border-color: rgba(240, 106, 106, 0.5);
  font-weight: 600;
}
.btn-danger:hover {
  background: rgba(240, 106, 106, 0.28);
  border-color: var(--danger);
}

/* Toast */
.coach-toast {
  position: fixed;
  right: 20px;
  bottom: 20px;
  padding: 8px 14px;
  background: var(--bg-elev-1);
  border: 1px solid var(--border-strong);
  border-radius: 7px;
  font-size: 12.5px;
  color: var(--text);
  opacity: 0;
  transition: opacity 160ms ease;
  z-index: 50;
  pointer-events: none;
}
.coach-toast.show {
  opacity: 1;
}
.coach-toast.err {
  border-color: rgba(240, 106, 106, 0.5);
  color: var(--danger);
}
.coach-toast.ok {
  border-color: rgba(94, 212, 163, 0.5);
  color: var(--success);
}

/* ── Launcher ─────────────────────────────────────────────────────────── */
.launcher {
  background: var(--bg-elev-1);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 18px 20px;
}
.launcher-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
}
.launcher-header h1 {
  font-size: 18px;
  font-weight: 600;
  margin: 0;
  letter-spacing: -0.01em;
}
.launcher-header-right {
  display: flex;
  align-items: center;
  gap: 12px;
}
.launcher-body {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-height: 0;
}
/* Collapsed state — toggled by main.ts. Body hides, header stays. The
   surrounding right-pane-section also gets .is-collapsed so its
   pixel-height flex-basis falls back to content-fit (see below). */
.launcher.is-collapsed > .launcher-body {
  display: none;
}
.launcher.is-collapsed {
  padding-bottom: 14px;
  margin-bottom: 0;
}
.launcher.is-collapsed .launcher-header {
  margin-bottom: 0;
}
/* When the launcher pane is collapsed, the section it lives in needs to
   collapse with it (otherwise the fixed --launcher-h leaves a tall empty
   box). The splitter just below is also hidden — drag stops making sense.
   Uses :has() to react to the .is-collapsed class on the inner .launcher
   without requiring extra class plumbing in the client toggle code. */
.right-pane-section[data-pane="launcher"]:has(> .launcher.is-collapsed) {
  flex: 0 0 auto;
  min-height: 0;
}
.right-pane-section[data-pane="launcher"]:has(> .launcher.is-collapsed)
  + .splitter[data-target="launcher"] {
  display: none;
}

/* ── Shared collapse/expand button ────────────────────────────────────────
   Used by the TopPanel and the Launcher headers. Click flips `.is-collapsed`
   on the panel; main.ts persists the open/closed state to localStorage. */
.panel-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--bg-elev-2);
  border: 1px solid var(--border);
  color: var(--text-muted);
  border-radius: 6px;
  padding: 5px 12px;
  font: inherit;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
  user-select: none;
  transition: border-color 80ms ease, color 80ms ease, background 80ms ease;
}
.panel-toggle:hover {
  border-color: var(--accent);
  color: var(--text);
  background: var(--bg-elev-1);
}
.panel-toggle:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
.panel-toggle-caret {
  display: inline-block;
  font-size: 10px;
  line-height: 1;
  transition: transform 140ms ease;
}
.panel-toggle.is-collapsed .panel-toggle-caret {
  transform: rotate(-90deg);
}
/* Anchor-flavoured variant — same chrome, no caret. Used for the "Sign
   out" link in the launcher header. */
.panel-toggle-link {
  text-decoration: none;
  color: var(--text-muted);
}
.panel-toggle-link:hover {
  color: var(--text);
}

/* ── Login / Logout pages ────────────────────────────────────────────── */
.login-body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  margin: 0;
  padding: 0;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}
.login-shell {
  width: 100%;
  max-width: 420px;
  padding: 32px 24px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}
.login-header {
  text-align: center;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.login-title {
  margin: 0;
  font-size: 26px;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--text);
}
.login-title-dot {
  color: var(--accent);
}
.login-title-sub {
  color: var(--text-muted);
  font-weight: 600;
  margin-left: 4px;
}
.login-tagline {
  margin: 0;
  color: var(--text-muted);
  font-size: 13px;
}
.login-mount {
  display: flex;
  justify-content: center;
  min-height: 360px;
}
.login-loading {
  color: var(--text-dim);
  font-size: 13px;
  padding: 32px;
  text-align: center;
}
.login-error {
  background: rgba(240, 106, 106, 0.08);
  border: 1px solid rgba(240, 106, 106, 0.4);
  color: var(--danger);
  border-radius: 8px;
  padding: 12px 16px;
  font-size: 13px;
  margin: 0;
}
.status-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  border-radius: 999px;
  background: var(--bg-elev-2);
  border: 1px solid var(--border);
  font-size: 13px;
}
.status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--text-dim);
}
.status-idle .status-dot { background: var(--text-dim); }
.status-running .status-dot {
  background: var(--success);
  box-shadow: 0 0 0 0 rgba(94, 212, 163, 0.6);
  animation: pulse 1.6s ease-out infinite;
}
.status-stopping .status-dot { background: var(--warning); }
.status-error .status-dot { background: var(--danger); }
@keyframes pulse {
  0% { box-shadow: 0 0 0 0 rgba(94, 212, 163, 0.5); }
  70% { box-shadow: 0 0 0 8px rgba(94, 212, 163, 0); }
  100% { box-shadow: 0 0 0 0 rgba(94, 212, 163, 0); }
}

.task-form {
  display: grid;
  gap: 14px;
}
.row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 14px;
}
.two-col {
  grid-template-columns: repeat(2, 1fr);
}

.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.field label {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.field input[type="number"],
.field input[type="text"],
.field textarea,
.field select {
  background: var(--bg-elev-2);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text);
  padding: 8px 10px;
  font-family: inherit;
  font-size: 13px;
  outline: none;
  transition: border-color 80ms ease;
}
.field input[type="number"]:focus,
.field textarea:focus,
.field select:focus {
  border-color: var(--accent);
}
.help {
  font-size: 11px;
  color: var(--text-dim);
}

.notes-templates {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.notes-template-chip {
  background: var(--bg-elev-2);
  border: 1px solid var(--border);
  color: var(--text-muted);
  border-radius: 999px;
  padding: 3px 10px;
  font-size: 11px;
  cursor: pointer;
  transition: border-color 80ms ease, color 80ms ease, background 80ms ease;
}
.notes-template-chip:hover {
  border-color: var(--accent);
  color: var(--text);
  background: var(--bg-elev-1);
}

.multi-check {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  background: var(--bg-elev-2);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px;
}
.multi-check-item {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 8px;
  border-radius: 4px;
  background: var(--bg-elev-1);
  font-size: 12px;
  cursor: pointer;
  user-select: none;
}
.multi-check-item input {
  margin: 0;
}

.actions {
  display: flex;
  align-items: center;
  gap: 12px;
  padding-top: 4px;
}
.btn-primary, .btn-secondary, .btn-ghost {
  font: inherit;
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  padding: 8px 16px;
  cursor: pointer;
  transition: background 80ms ease, border-color 80ms ease;
}
.btn-primary {
  background: var(--accent-strong);
  color: white;
  border-color: var(--accent-strong);
  font-weight: 600;
}
.btn-primary:hover:not(:disabled) {
  background: var(--accent);
  border-color: var(--accent);
}
.btn-secondary {
  background: var(--bg-elev-2);
  color: var(--text);
}
.btn-secondary:hover:not(:disabled) {
  border-color: var(--danger);
  color: var(--danger);
}
.btn-ghost {
  background: transparent;
  color: var(--text-muted);
  border-color: var(--border);
  padding: 6px 12px;
  font-size: 12px;
}
.btn-ghost:hover { color: var(--text); border-color: var(--border-strong); }
button:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.hint {
  color: var(--text-dim);
  font-size: 12px;
}

/* ── Section header (grid + console share this) ───────────────────────── */
.section-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 8px;
}
.section-header h2 {
  font-size: 14px;
  font-weight: 600;
  margin: 0;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.section-hint {
  font-size: 12px;
  color: var(--text-dim);
}

/* ── Agent grid ───────────────────────────────────────────────────────── */
.grid-section {
  background: var(--bg-elev-1);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px;
  /* Fill the right-pane slot; the grid inside grows to absorb everything
     after the small header so larger drag-to-resize → bigger iframes. */
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-height: 0;
}
.agent-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 8px;
  flex: 1 1 auto;
  min-height: 120px;
}
.agent-cell {
  /* Per-cell color set inline via style.setProperty("--agent-color", …) by
     the client (deterministic per agent id). Default to the global accent
     so the cell still has a colour even before JS attaches anything. */
  --agent-color: var(--accent);
  background: var(--bg-elev-2);
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  /* Left rail in the agent's color so the operator can match cell ↔ coach
     row at a glance. Subtle by default; the flash / sustained pulse
     classes below thicken & glow it. */
  box-shadow: inset 3px 0 0 0 var(--agent-color);
  transition: box-shadow 160ms ease;
}
.agent-cell-label {
  font-family: var(--mono);
  font-size: 11px;
  padding: 4px 8px;
  background: var(--bg-elev-1);
  border-bottom: 1px solid var(--border);
  color: var(--text-muted);
  letter-spacing: 0.04em;
  display: flex;
  align-items: center;
  gap: 8px;
}
.agent-cell-id {
  font-weight: 700;
  color: var(--agent-color);
}
.agent-cell-activity {
  font-family: var(--mono);
  font-size: 10.5px;
  padding: 3px 8px;
  background: var(--bg-elev-1);
  border-bottom: 1px solid var(--border);
  color: var(--text-muted);
  letter-spacing: 0.02em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.agent-cell-activity:empty {
  display: none;
}

/* Brief flash on every successful save (any mode). Triggered by the client
   adding `.agent-cell-flash` and removing it ~1.4s later — the keyframe
   animates the glow fade. */
.agent-cell-flash {
  animation: agent-save-flash 1.4s ease-out;
}
@keyframes agent-save-flash {
  0% {
    box-shadow:
      inset 3px 0 0 0 var(--agent-color),
      0 0 0 0 var(--agent-color);
  }
  20% {
    box-shadow:
      inset 3px 0 0 0 var(--agent-color),
      0 0 0 4px color-mix(in srgb, var(--agent-color) 38%, transparent);
  }
  100% {
    box-shadow:
      inset 3px 0 0 0 var(--agent-color),
      0 0 0 0 transparent;
  }
}

/* Sustained pulse while an enrich agent is actively working a coach. */
.agent-cell-enriching {
  animation: agent-enriching 1.8s ease-in-out infinite;
}
@keyframes agent-enriching {
  0%, 100% {
    box-shadow:
      inset 3px 0 0 0 var(--agent-color),
      0 0 0 0 color-mix(in srgb, var(--agent-color) 0%, transparent);
  }
  50% {
    box-shadow:
      inset 3px 0 0 0 var(--agent-color),
      0 0 0 3px color-mix(in srgb, var(--agent-color) 30%, transparent);
  }
}

/* ── Coach row enrichment highlight ────────────────────────────────────
   Mirrors the cell's sustained pulse on the matching coach card in the
   left-pane directory list. Set inline by the client via
   `style.setProperty("--agent-color", …)`. */
.coach-row-enriching {
  --agent-color: var(--accent);
  position: relative;
  animation: coach-row-enriching 1.8s ease-in-out infinite;
  border-color: color-mix(in srgb, var(--agent-color) 50%, var(--border));
}
@keyframes coach-row-enriching {
  0%, 100% {
    box-shadow: 0 0 0 0 color-mix(in srgb, var(--agent-color) 0%, transparent);
  }
  50% {
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--agent-color) 35%, transparent);
  }
}
.coach-row-enriching-label {
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--agent-color);
  padding: 2px 8px 4px;
  letter-spacing: 0.02em;
}
.agent-cell-sid {
  margin-left: auto;
  font-size: 10px;
  opacity: 0.55;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 60%;
}
.agent-cell-pending {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-dim);
  font-size: 12.5px;
  padding: 16px;
  text-align: center;
}
.agent-cell iframe {
  width: 100%;
  flex: 1;
  min-height: 200px;
  border: 0;
  background: #000;
}

/* ── Console ──────────────────────────────────────────────────────────── */
.console-section {
  background: var(--bg-elev-1);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px;
  /* Fill the console pane the splitter layout allocated; the inner
     console-pane scrolls internally. */
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 0;
}
.console-controls {
  display: inline-flex;
  align-items: center;
  gap: 12px;
}
.toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--text-muted);
  cursor: pointer;
}
.console-pane {
  background: #060709;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 12px;
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.45;
  color: var(--text);
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
  white-space: pre-wrap;
  word-break: break-word;
  margin: 0;
}
.console-empty {
  color: var(--text-dim);
  font-style: italic;
}
.console-line {
  display: block;
}
.console-line.event-error { color: var(--danger); }
.console-line.event-coach_saved { color: var(--success); }
.console-line.event-iter_start { color: var(--text-muted); }
.console-line.event-tool_use { color: var(--text); }
.console-line.event-debug { color: var(--text-dim); }
