/* ===== MadnessApps — Agent Platform theme =====
   Dark "cyber console" aesthetic: near-black canvas, neon blue→violet→magenta
   gradient (from the logo), glassy panels, angular display type. */
/* ── Design tokens ────────────────────────────────────────────────────────────
   Direction: "The Pane". Every run is now a real tmux pane that outlives this
   server and that you can attach to from any SSH shell (see docs/tmux-runner.md).
   The interface is a control surface for those panes, so it should read as
   precise instrument, not as a consumer app.

   Two rules hold this together:
     1. The brand gradient is spent ONCE, on live pane state — never on buttons
        or tabs. A gradient CTA is the thing every dark dashboard already does;
        here the gradient means "this pane is alive", which is the one fact the
        product exists to tell you.
     2. The interface speaks IBM Plex (a typeface family born on terminals); the
        MACHINE speaks JetBrains Mono inside the pane. Keeping those voices
        separate is deliberate — and JetBrains Mono stays in the terminal because
        it has the box-drawing coverage (─ │ ╭ ╰ ⏵⏵ ✻) Claude's TUI draws with.
        Swapping it for a prettier face visibly breaks the CLI's own rendering. */
:root {
  /* Ground: cool blue-ink rather than pure black — pure black flattens the panes
     against the page and makes the terminal look like a hole, not a surface. */
  --bg: #080a11;
  --bg-2: #0c0f18;
  --panel: rgba(19, 23, 34, 0.72);
  --panel-solid: #12161f;
  --panel-2: rgba(29, 34, 49, 0.7);
  --border: rgba(255, 255, 255, 0.07);
  --border-strong: rgba(255, 255, 255, 0.15);
  --text: #e9ecf4;
  --muted: #939cb4;
  --faint: #667090;

  /* Brand, taken from the MadnessApps mark: cyan → violet → magenta. */
  --cyan: #2dd4e8;
  --blue: #4d7cff;
  --violet: #7c6bf5;
  --magenta: #e0489e;
  --grad: linear-gradient(100deg, var(--cyan) 0%, var(--violet) 52%, var(--magenta) 100%);
  --grad-soft: linear-gradient(100deg, rgba(45, 212, 232, 0.16), rgba(224, 72, 158, 0.16));
  --accent: #8b93ff;

  --green: #34d399;
  --red: #ff5d8f;
  --yellow: #f0c04a;

  /* Plex Condensed for display: editorial authority, and clearly distinct from
     the body face at a glance — which a single-family scale never achieves. */
  --display: 'IBM Plex Sans Condensed', 'IBM Plex Sans', system-ui, sans-serif;
  --body: 'IBM Plex Sans', system-ui, -apple-system, sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  /* Tighter than before (was 14/10): precision reads as professional. */
  --radius: 10px;
  --radius-sm: 7px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--body);
  background: var(--bg);
  color: var(--text);
  height: 100vh;
  -webkit-font-smoothing: antialiased;
}

/* atmospheric background glow */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(1100px 600px at 12% -8%, rgba(77, 124, 255, 0.16), transparent 60%),
    radial-gradient(1000px 620px at 108% 112%, rgba(224, 72, 158, 0.16), transparent 60%),
    radial-gradient(800px 500px at 92% 4%, rgba(139, 92, 246, 0.1), transparent 60%),
    var(--bg);
}

button {
  font: inherit;
  font-family: var(--body);
  cursor: pointer;
  border: 1px solid var(--border-strong);
  background: var(--panel-2);
  color: var(--text);
  border-radius: var(--radius-sm);
  padding: 9px 16px;
  font-weight: 500;
  transition: transform 0.12s ease, border-color 0.15s ease, box-shadow 0.2s ease, background 0.2s ease;
}
button:hover { border-color: rgba(255, 255, 255, 0.28); transform: translateY(-1px); }
button:active { transform: translateY(0); }
/* Solid, not gradient. The brand gradient now means exactly one thing — "this
   pane is alive" (see .pane-dot.busy) — so spending it on every primary button
   would drain it of meaning and land us on the same neon-CTA dashboard as
   everyone else. A single confident violet does the job with less noise. */
button.primary {
  position: relative;
  border: none;
  background: var(--violet);
  color: #fff;
  font-weight: 600;
  box-shadow: 0 6px 22px -10px rgba(124, 107, 245, 0.75), inset 0 1px 0 rgba(255, 255, 255, 0.18);
}
button.primary:hover { background: #8b7bf7; box-shadow: 0 10px 28px -10px rgba(124, 107, 245, 0.85), inset 0 1px 0 rgba(255, 255, 255, 0.22); }
button.danger { color: var(--red); border-color: rgba(255, 93, 143, 0.4); background: rgba(255, 93, 143, 0.08); }
button.danger:hover { background: rgba(255, 93, 143, 0.16); }
button:disabled { opacity: 0.45; cursor: not-allowed; transform: none; box-shadow: none; }

input, select, textarea {
  font: inherit;
  font-family: var(--body);
  background: rgba(8, 10, 16, 0.6);
  color: var(--text);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  padding: 10px 12px;
  width: 100%;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--violet);
  box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.22);
}
textarea { resize: vertical; font-family: var(--mono); font-size: 13px; line-height: 1.55; }
/* keep autofilled fields on-theme (Chrome forces a light bg otherwise) */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--text);
  -webkit-box-shadow: 0 0 0 1000px rgba(10, 12, 18, 0.95) inset;
  caret-color: var(--text);
  transition: background-color 9999s ease-in-out 0s;
}
select { cursor: pointer; }
label { font-size: 13px; color: var(--muted); display: block; margin-bottom: 6px; }

/* ===== login ===== */
.login-wrap { display: flex; align-items: center; justify-content: center; height: 100vh; padding: 20px; }
.login-card {
  width: 360px;
  background: var(--panel);
  backdrop-filter: blur(18px);
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: 34px 30px;
  box-shadow: 0 30px 80px -30px rgba(0, 0, 0, 0.8), inset 0 1px 0 rgba(255, 255, 255, 0.05);
}
.login-card .logo { display: block; width: 184px; margin: 0 auto 18px; filter: drop-shadow(0 8px 26px rgba(139, 92, 246, 0.4)); }
.login-card h1 { margin: 0 0 4px; font-family: var(--display); font-size: 20px; font-weight: 600; letter-spacing: 0.02em; text-align: center; }
.login-card p { margin: 0 0 22px; color: var(--muted); font-size: 13px; text-align: center; }
.login-card .row { margin-bottom: 15px; }
.error { color: var(--red); font-size: 13px; min-height: 18px; margin-top: 8px; }

/* ===== app layout ===== */
.app { position: relative; display: grid; grid-template-columns: var(--sidebar-w, 290px) 1fr; height: 100vh; }
/* draggable sidebar width handle */
.sidebar-resizer {
  position: absolute; top: 0; bottom: 0; left: var(--sidebar-w, 290px);
  width: 8px; margin-left: -4px; cursor: col-resize; z-index: 60;
  background: transparent; transition: background 0.15s;
}
.sidebar-resizer:hover, .sidebar-resizer.drag { background: linear-gradient(180deg, transparent, rgba(124,139,255,0.55), transparent); }
.sidebar {
  background: linear-gradient(180deg, rgba(16, 18, 27, 0.86), rgba(10, 12, 18, 0.86));
  backdrop-filter: blur(14px);
  border-right: 1px solid var(--border);
  padding: 20px 18px;
  overflow-y: auto;
}
.sidebar h2 { font-family: var(--display); font-size: 11px; text-transform: uppercase; letter-spacing: 0.14em; color: var(--faint); margin: 26px 0 10px; font-weight: 600; }
.brand { display: flex; flex-direction: column; gap: 6px; padding-bottom: 6px; }
.brand .logo { width: 100%; max-width: 210px; filter: drop-shadow(0 6px 22px rgba(139, 92, 246, 0.38)); }
.brand strong {
  font-family: var(--display); font-size: 12px; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--faint); font-weight: 600;
}
.proj {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 12px; border-radius: var(--radius-sm); border: 1px solid transparent;
  cursor: pointer; font-size: 14px; font-weight: 500; transition: background 0.15s ease, border-color 0.15s ease;
}
.proj:hover { background: var(--panel-2); }
.proj.active { background: var(--grad-soft); border-color: rgba(139, 92, 246, 0.5); }
.proj-main { min-width: 0; flex: 1; }
.proj-name { display: block; }
.proj small { display: block; color: var(--muted); font-size: 11px; margin-top: 3px; word-break: break-all; font-family: var(--mono); }
.proj-del {
  flex: none; background: transparent; border: none; color: var(--muted); cursor: pointer;
  font-size: 14px; line-height: 1; padding: 4px 6px; border-radius: 6px; opacity: 0; transition: opacity 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.proj:hover .proj-del { opacity: 0.65; }
.proj-del:hover { opacity: 1; background: rgba(239, 68, 68, 0.15); color: #f87171; }

/* add-project: dynamic repository rows */
.dim { color: var(--muted); font-weight: 400; font-size: 12px; }
.repo-row { display: flex; gap: 8px; margin-bottom: 8px; align-items: center; }
.repo-row .repo-url { flex: 1 1 60%; }
.repo-row .repo-pat { flex: 1 1 34%; }
.repo-row .repo-remove {
  flex: none; width: 30px; height: 30px; border-radius: 6px; cursor: pointer;
  background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.1); color: var(--muted); font-size: 16px; line-height: 1;
}
.repo-row .repo-remove:hover { background: rgba(239,68,68,0.15); color: #f87171; }
#addRepoBtn { margin: 2px 0 10px; }

/* min-width:0 lets this grid item shrink to the track instead of its content's
   min-content width — without it a wide inner row forces horizontal page overflow */
.main { display: flex; flex-direction: column; min-width: 0; padding: 24px; overflow: hidden; position: relative; }

/* drag-and-drop overlay */
.drop-overlay {
  position: absolute; inset: 14px; z-index: 40;
  display: flex; align-items: center; justify-content: center;
  border: 2px dashed var(--violet); border-radius: 18px;
  background: rgba(139, 92, 246, 0.1); backdrop-filter: blur(3px);
  pointer-events: none;
}
.drop-overlay span {
  font-family: var(--display); font-size: 20px; letter-spacing: 0.04em;
  color: #d7c9ff; text-shadow: 0 2px 20px rgba(139, 92, 246, 0.6);
}
.topbar { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; }
.topbar h1 { font-family: var(--display); font-size: 20px; margin: 0; font-weight: 600; letter-spacing: 0.01em; }
.topbar-left { display: flex; align-items: center; gap: 14px; min-width: 0; }
.branch-pick { display: flex; align-items: center; gap: 6px; background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.08); border-radius: 8px; padding: 4px 8px; }
.branch-pick .branch-ico { color: var(--muted); font-size: 14px; }
.branch-pick select { background: transparent; border: none; color: var(--text); font-family: var(--mono); font-size: 12px; max-width: 240px; padding: 2px 4px; }
.branch-pick select:focus { outline: none; }
.branch-refresh { font-size: 14px; padding: 0 4px; line-height: 1; }
.who { color: var(--muted); font-size: 13px; margin-right: 8px; }

/* ===== multi_session: live sessions + conflict panel ===== */
.sessions-panel { background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.08); border-radius: 8px; padding: 8px 10px; margin-bottom: 10px; font-size: 12px; }
.sessions-panel .sess-head { color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: .04em; margin-bottom: 4px; }
.sessions-panel .sess-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 3px; }
.sessions-panel .sess-list li { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.sessions-panel .sess-open { color: var(--text); text-decoration: none; }
.sessions-panel .sess-open:hover { text-decoration: underline; }
.sessions-panel .sess-branch { color: var(--muted); font-family: var(--mono); font-size: 11px; }
.sessions-panel .sess-by { color: var(--muted); }
.sessions-panel .sess-nf { color: var(--muted); margin-left: auto; font-size: 11px; }
.sessions-panel .sess-warn { margin-top: 6px; padding: 6px 8px; border-radius: 6px; background: rgba(240,180,40,0.12); border: 1px solid rgba(240,180,40,0.35); color: #f0c040; }

/* ===== composer ===== */
.composer { display: flex; gap: 12px; margin-bottom: 10px; }
.composer textarea { flex: 1; min-height: 76px; }
.composer > div { display: flex; flex-direction: column; gap: 8px; min-width: 132px; }

/* attachments */
.attach-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
.attach-btn {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer; font-size: 13px; color: var(--muted);
  border: 1px dashed var(--border-strong); border-radius: var(--radius-sm); padding: 7px 12px;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.attach-btn:hover { color: var(--text); border-color: var(--violet); }
.attach-list { display: flex; gap: 8px; flex-wrap: wrap; }
.attach-chip {
  display: inline-flex; align-items: center; gap: 7px; font-size: 12px; font-family: var(--mono);
  background: var(--grad-soft); border: 1px solid rgba(139, 92, 246, 0.4);
  border-radius: 999px; padding: 4px 10px; color: var(--text);
}
.attach-chip button { all: unset; cursor: pointer; color: var(--muted); font-weight: 700; line-height: 1; }
.attach-chip button:hover { color: var(--red); }

/* reply bar */

/* ===== output console ===== */
.output {
  flex: 1; min-height: 180px; background: rgba(5, 6, 11, 0.82); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 18px; overflow-y: auto; font-family: var(--mono); font-size: 12.5px;
  white-space: pre-wrap; line-height: 1.6; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
}
/* drag handle above the console to set its height on desktop. When the user
   drags, JS switches .output from flex-fill to an explicit height. */
.output-resizer {
  flex: none; height: 10px; margin: -3px 0 3px; cursor: row-resize;
  border-radius: 6px; background: transparent; transition: background 0.15s ease;
}
.output-resizer::before {
  content: ''; display: block; width: 40px; height: 3px; margin: 3px auto 0;
  border-radius: 3px; background: var(--border-strong); transition: background 0.15s ease;
}
.output-resizer:hover::before, .output-resizer.drag::before { background: var(--accent); }
.output-resizer:hover, .output-resizer.drag { background: linear-gradient(90deg, transparent, rgba(124, 139, 255, 0.18), transparent); }

/* Expand/maximize: lift the console out of the flow to fill the viewport. */
.output.maximized {
  position: fixed; inset: 14px; z-index: 90; flex: none; height: auto;
  font-size: 13px; box-shadow: 0 30px 90px -30px rgba(0, 0, 0, 0.9), inset 0 1px 0 rgba(255, 255, 255, 0.04);
}
body.output-maximized { overflow: hidden; }
/* a maximized console makes the inline resize handle meaningless */
body.output-maximized .output-resizer { visibility: hidden; }
.output .line-assistant { color: var(--text); }
.output .line-system, .output .line-result { color: var(--muted); }
.output .line-stderr, .output .line-error { color: var(--red); }
.output .line-tool_result { color: var(--yellow); }
.output .line-tool_use { color: var(--accent); }
.output .line-thinking { color: var(--faint); font-style: italic; }
.output .line-you { color: #8fb4ff; font-weight: 600; }

.status-pill { font-family: var(--display); font-size: 11px; padding: 3px 12px; border-radius: 999px; border: 1px solid var(--border-strong); text-transform: uppercase; letter-spacing: 0.08em; }
.status-pill.running { color: var(--yellow); border-color: rgba(240, 192, 74, 0.4); background: rgba(240, 192, 74, 0.08); }
.status-pill.done { color: var(--green); border-color: rgba(70, 192, 139, 0.4); background: rgba(70, 192, 139, 0.08); }
.status-pill.error, .status-pill.killed { color: var(--red); border-color: rgba(255, 93, 143, 0.4); background: rgba(255, 93, 143, 0.08); }

/* ===== modals ===== */
.modal-bg { position: fixed; inset: 0; background: rgba(4, 5, 9, 0.66); backdrop-filter: blur(6px); display: flex; align-items: center; justify-content: center; z-index: 50; }
.modal { background: var(--panel); backdrop-filter: blur(20px); border: 1px solid var(--border-strong); border-radius: 18px; padding: 26px; width: 440px; box-shadow: 0 30px 90px -30px rgba(0, 0, 0, 0.85); }
.modal h3 { margin: 0 0 18px; font-family: var(--display); font-weight: 600; letter-spacing: 0.01em; }
.modal .row { margin-bottom: 14px; }
.modal .actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 20px; }

/* sidebar footer (About) */
.sidebar-foot { margin-top: 28px; padding-top: 14px; border-top: 1px solid var(--border); }

/* About modal */
.modal-about { width: 600px; max-width: 92vw; }
.about-body { display: flex; gap: 22px; align-items: stretch; }
.about-photo {
  width: 190px; flex: none; border-radius: 14px; object-fit: cover; align-self: flex-start;
  border: 1px solid var(--border-strong); box-shadow: 0 16px 40px -16px rgba(139, 92, 246, 0.6);
}
.about-text { display: flex; flex-direction: column; justify-content: center; }
.about-quote { font-size: 14px; line-height: 1.65; color: var(--text); font-style: italic; }
.about-name {
  font-family: var(--display); font-weight: 700; font-size: 19px; margin-top: 16px;
  background: var(--grad); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}
.about-title { font-family: var(--display); font-size: 12px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--faint); margin-top: 3px; }
@media (max-width: 560px) { .about-body { flex-direction: column; align-items: center; text-align: center; } }

.modal-wide { width: 780px; max-width: 92vw; }
.audit-grid { display: grid; grid-template-columns: 190px 1fr; gap: 14px; max-height: 62vh; }
.audit-grid.solo { grid-template-columns: 1fr; }
.audit-users, .audit-runs { overflow-y: auto; padding-right: 4px; }
.audit-users { border-right: 1px solid var(--border); }
.audit-user { padding: 9px 11px; border-radius: 8px; cursor: pointer; font-size: 13px; font-weight: 500; transition: background 0.15s ease; }
.audit-user:hover { background: var(--panel-2); }
.audit-user.active { background: var(--grad-soft); border: 1px solid rgba(139, 92, 246, 0.5); }
.audit-user small { display: block; color: var(--faint); font-size: 11px; margin-top: 2px; }
.audit-run { padding: 9px 11px; border-radius: 8px; cursor: pointer; border: 1px solid var(--border); margin-bottom: 7px; transition: border-color 0.15s ease, background 0.15s ease; }
.audit-run:hover { border-color: var(--violet); background: var(--panel-2); }
.audit-run .meta { font-size: 11px; color: var(--faint); font-family: var(--mono); margin-top: 4px; display: flex; gap: 8px; flex-wrap: wrap; }
.audit-run .badge { padding: 1px 7px; border-radius: 999px; border: 1px solid var(--border-strong); }
.audit-run .badge.done { color: var(--green); }
.audit-run .badge.error, .audit-run .badge.killed { color: var(--red); }
.audit-run .badge.running { color: var(--yellow); }

.hidden { display: none !important; }
.muted-link { background: none; border: none; color: var(--muted); padding: 5px 4px; font-size: 13px; text-align: left; transition: color 0.15s ease; }
.muted-link:hover { color: var(--text); background: none; transform: none; }
#historySearch { margin-bottom: 8px; font-size: 13px; padding: 7px 10px; }

/* find-in-output bar */
.output-find { display: flex; align-items: center; gap: 4px; margin-left: auto; }
.output-find input { width: 170px; font-size: 13px; padding: 6px 9px; }
.find-count { font-size: 12px; color: var(--muted); min-width: 56px; }
.find-nav { padding: 4px 6px; font-size: 12px; }
mark.find-hit { background: rgba(255, 214, 0, 0.35); color: inherit; border-radius: 2px; }
mark.find-hit.active { background: #ffd600; color: #111; }
/* Show ~5 recent runs; the rest scroll within this box. The exact height of the
   first 5 cards is set in JS (renderHistory); this is just a fallback. */
#history { max-height: 420px; overflow-y: auto; overflow-x: hidden; padding-right: 2px; }
#history::-webkit-scrollbar { width: 8px; }
#history::-webkit-scrollbar-thumb { background: var(--border-strong, #2a3344); border-radius: 8px; }
#history::-webkit-scrollbar-track { background: transparent; }
.history-item { display: flex; flex-direction: column; gap: 4px; font-size: 12px; padding: 8px 10px; border-radius: 8px; cursor: pointer; color: var(--muted); transition: background 0.15s ease, color 0.15s ease; }
.history-item:hover { background: var(--panel-2); color: var(--text); }
/* The run currently open on screen — kept highlighted so it's clear which run
   you're viewing/resuming (see markActiveRun / viewRun). */
.history-item.active { background: var(--panel-2); color: var(--text); box-shadow: inset 2px 0 0 0 var(--accent, #8b5cf6); }
.history-item .run-top { display: flex; align-items: center; gap: 6px; min-width: 0; }
.history-item .run-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text); }
/* status tag/chip */
.run-tag { flex: 0 0 auto; font-size: 10px; font-weight: 600; letter-spacing: 0.02em; padding: 2px 6px; border-radius: 999px; text-transform: uppercase; border: 1px solid var(--border); color: var(--muted); white-space: nowrap; }
.run-tag.run-running     { color: #34d399; border-color: rgba(52,211,153,.4);  background: rgba(52,211,153,.10); }
.run-tag.run-done        { color: #5eead4; border-color: rgba(94,234,212,.4);  background: rgba(94,234,212,.10); }
.run-tag.run-error       { color: #f87171; border-color: rgba(248,113,113,.4); background: rgba(248,113,113,.10); }
.run-tag.run-killed      { color: #fb923c; border-color: rgba(251,146,60,.4);  background: rgba(251,146,60,.10); }
.run-tag.run-interrupted { color: #fbbf24; border-color: rgba(251,191,36,.4);  background: rgba(251,191,36,.10); }
/* meta line: project · user · time */
.history-item .run-meta { display: flex; flex-wrap: wrap; gap: 4px 8px; font-size: 11px; color: var(--muted); padding-left: 1px; }
.history-item .run-meta .run-proj { color: var(--accent, #8b5cf6); opacity: .9; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
button.ghost { background: transparent; border: 1px solid var(--border, #444); color: var(--muted); font-size: 11px; padding: 2px 7px; border-radius: 6px; cursor: pointer; transition: background 0.15s ease, color 0.15s ease; }
button.ghost:hover { background: var(--panel-2); color: var(--text); }

/* git workflow bar */
.inline { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: var(--text); margin: 0; }
.inline input { width: auto; }
.git-opts { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 14px; margin-top: 14px; flex-basis: 100%; }
.git-field { display: flex; flex-direction: column; gap: 5px; }
.git-field input { width: 180px; }
.branch-preview { font-size: 13px; color: var(--muted); flex-basis: 100%; font-family: var(--mono); }
.branch-preview code { color: var(--text); background: var(--grad-soft); padding: 2px 8px; border-radius: 6px; border: 1px solid rgba(139, 92, 246, 0.3); }

/* modal tabs + hints */
.tabs { display: flex; gap: 6px; margin-bottom: 18px; }
.tab { font-size: 13px; padding: 8px 14px; }
.tab.active { background: var(--grad); border: none; color: #fff; }
.hint { font-size: 12px; color: var(--muted); margin: 4px 0 0; line-height: 1.55; }

/* users modal: section headings + searchable user picker */
.users-sub { font-family: var(--display); font-size: 12px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--faint); margin: 6px 0 12px; padding-top: 14px; border-top: 1px solid var(--border); }
.searchable { position: relative; }
.search-list {
  position: absolute; left: 0; right: 0; top: 100%; z-index: 5; margin-top: 4px;
  background: var(--panel-solid); border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  max-height: 200px; overflow-y: auto; box-shadow: 0 18px 40px -16px rgba(0,0,0,0.8);
}
.search-item { padding: 9px 12px; cursor: pointer; font-size: 13px; }
.search-item:hover, .search-item.active { background: var(--grad-soft); }
.search-item small { color: var(--faint); }
.hint code, label code { color: #c4b5fd; }

/* scrollbars */
/* Chromium/Edge (Windows + macOS) */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.1); border-radius: 8px; border: 2px solid transparent; background-clip: padding-box; }
::-webkit-scrollbar-thumb:hover { background: rgba(139, 92, 246, 0.45); background-clip: padding-box; }
/* Firefox (Windows): otherwise falls back to chunky light native bars that clash
   with the dark theme. Standard props give it the same slim, on-theme treatment. */
* { scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, 0.18) transparent; }

/* ===== Windows glyph normalization =====
   The UI uses Unicode/emoji as icons (☰ ⑃ ↻ 📎). On Windows these get swapped to
   Segoe UI Emoji — colorful, blocky, vertically misaligned — instead of the crisp
   monochrome marks the theme intends. Force text presentation so they render the
   same sleek way on every OS. No icon-font dependency. */
.menu-toggle, .branch-ico, .branch-refresh, .attach-btn, .drop-overlay span,
#changesRefresh {
  font-variant-emoji: text;       /* Chromium 131+/FF 132+/Safari 17.4+ */
  -webkit-font-feature-settings: normal;
}

/* Keyboard users get a clear, on-theme focus ring everywhere (mouse clicks don't).
   Mirrors the violet glow inputs already use. */
:focus-visible {
  outline: 2px solid var(--violet);
  outline-offset: 2px;
}
button:focus-visible, .proj:focus-visible, .attach-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.4);
}

/* Summary-mode approval modal */
.modal-approval { max-width: 640px; }
.approval-brief {
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 40vh;
  overflow-y: auto;
  margin: 10px 0 14px;
  padding: 12px 14px;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.1);
  font-size: 14px;
  line-height: 1.5;
}
#approvalComment { width: 100%; box-sizing: border-box; }

/* working-tree changes popup */
.changes-list {
  max-height: 46vh;
  overflow-y: auto;
  margin: 10px 0 12px;
  padding: 4px 2px;
  font-family: var(--mono);
  font-size: 12px;
}
.changes-repo {
  color: var(--text);
  font-family: var(--font);
  font-weight: 600;
  font-size: 13px;
  margin: 12px 0 6px;
  padding-bottom: 4px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.changes-repo:first-child { margin-top: 0; }
.changes-group { margin: 8px 0; }
.changes-group-title {
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 11px;
  color: var(--muted);
  margin-bottom: 4px;
}
.changes-file { padding: 2px 0; word-break: break-all; line-height: 1.5; }
.changes-code {
  display: inline-block;
  min-width: 1.4em;
  text-align: center;
  margin-right: 6px;
  border-radius: 3px;
  padding: 0 3px;
  background: rgba(255, 255, 255, 0.08);
}
.changes-staged .changes-code { color: #6ee7b7; background: rgba(16, 185, 129, 0.15); }
.changes-modified .changes-code { color: #fcd34d; background: rgba(245, 158, 11, 0.15); }
.changes-untracked .changes-code { color: #93c5fd; background: rgba(59, 130, 246, 0.15); }

/* ===== agent2 feature-flagged UI (§0/§3/§4/§8/§9) ===== */

/* §8 auto-generated run title chip in the topbar */
.run-title {
  font-family: var(--display);
  font-size: 13px;
  color: var(--text);
  padding: 3px 12px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: rgba(124, 139, 255, 0.10);
  white-space: nowrap;
  max-width: 320px;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* §3 preset checkbox row + §4 plan-first toggle: share the bar look */
.preset-bar, .planfirst-bar, .summary-bar, .teststep-bar, .modes-bar, .git-bar {
  background: var(--panel);
  backdrop-filter: blur(10px);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 11px 16px;
  margin-bottom: 12px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 14px;
}
/* Section name on the left of every option bar (e.g. "Quality:", "Git:") */
.preset-label, .section-label {
  font-size: 12px; color: var(--muted); text-transform: uppercase;
  letter-spacing: 0.08em; flex-shrink: 0; min-width: 56px;
}
.preset-chip { font-size: 13px; }

/* Visible hover tooltips on the option checkboxes (replaces the easy-to-miss
   native title tooltip; tipify() moves each title into data-tip). */
[data-tip] { position: relative; }
[data-tip]:hover::after {
  content: attr(data-tip);
  position: absolute; left: 0; bottom: calc(100% + 9px); z-index: 200;
  width: max-content; max-width: 340px;
  background: #0d1320; color: #e8eefc;
  border: 1px solid var(--border); border-radius: 9px;
  padding: 9px 12px; font-size: 12px; line-height: 1.5;
  font-weight: 400; text-transform: none; letter-spacing: 0; text-align: left;
  white-space: normal; box-shadow: 0 10px 30px rgba(0,0,0,.5); pointer-events: none;
}
[data-tip]:hover::before {
  content: ''; position: absolute; left: 16px; bottom: calc(100% + 3px); z-index: 201;
  border: 6px solid transparent; border-top-color: #0d1320; pointer-events: none;
}
.sess-title { font-family: var(--display); font-size: 13px; color: var(--text); margin-bottom: 2px; }

/* §9 collapsible tool/diff blocks */
.tool-block { border: 1px solid var(--border); border-radius: 10px; margin: 6px 0; background: rgba(255,255,255,0.02); overflow: hidden; }
.tool-block > summary {
  cursor: pointer; list-style: none; padding: 6px 12px;
  font-family: var(--mono); font-size: 12px; color: var(--muted);
  display: flex; align-items: center; gap: 8px; user-select: none;
}
.tool-block > summary::-webkit-details-marker { display: none; }
.tool-block > summary:hover { color: var(--text); background: rgba(255,255,255,0.03); }
.tool-block > summary .tb-caret { transition: transform 0.15s; color: var(--faint); }
.tool-block[open] > summary .tb-caret { transform: rotate(90deg); }
.tool-block .tb-body { padding: 4px 12px 10px 12px; white-space: pre-wrap; font-family: var(--mono); font-size: 12.5px; line-height: 1.5; border-top: 1px solid var(--border); }
.tb-add { color: var(--green); }
.tb-del { color: var(--red); }
.collapse-controls { display: inline-flex; gap: 8px; margin-left: 6px; }

/* §9 sticky tasks panel (TodoWrite / plan tasks) */
.tasks-panel { background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius); padding: 10px 14px; margin-bottom: 12px; }
.tasks-panel h4 { margin: 0 0 8px 0; font-family: var(--display); font-size: 12px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted); }
.task-row { font-size: 13px; padding: 3px 0; display: flex; gap: 8px; align-items: baseline; }
.task-row .tk-box { font-family: var(--mono); }
.task-row.done { color: var(--muted); text-decoration: line-through; }
.task-row.done .tk-box { color: var(--green); }
.task-row.in_progress .tk-box { color: var(--yellow); }

/* §3.1 design review popup */
.design-list { max-height: 60vh; overflow-y: auto; display: flex; flex-direction: column; gap: 14px; margin: 8px 0; }
.design-file { border: 1px solid var(--border); border-radius: 10px; padding: 10px; background: rgba(255,255,255,0.02); }
.design-file-head { display: flex; align-items: center; gap: 12px; margin-bottom: 8px; font-family: var(--mono); font-size: 12.5px; }
.design-name { flex: 1; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* iOS Safari ignores an iframe's CSS height (it sizes the iframe to its content)
   and won't scroll iframe content, so the fixed-height box must live on a wrapper
   that owns the scrolling — the iframe then fills it and the wrapper scrolls.
   Harmless on desktop (iframe is exactly the wrapper height; it scrolls internally). */
.design-frame-wrap { width: 100%; height: 260px; border: 1px solid var(--border); border-radius: 8px; background: #fff; overflow: auto; -webkit-overflow-scrolling: touch; }
.design-frame { display: block; width: 100%; height: 100%; min-height: 260px; border: 0; background: #fff; }
.design-comment { width: 100%; margin-top: 8px; }

/* §10 test-step bar shares the unified option-bar look (see .preset-bar group) */

/* ===== mobile menu controls (hidden on desktop) ===== */
/* hamburger lives in the topbar; only shown at phone/tablet widths */
.menu-toggle {
  display: none;
  flex: none;
  padding: 6px 11px;
  font-size: 18px;
  line-height: 1;
  border-radius: var(--radius-sm);
}
/* full-screen dim behind the slide-in sidebar */
.sidebar-scrim {
  position: fixed; inset: 0; z-index: 70;
  background: rgba(4, 5, 9, 0.6); backdrop-filter: blur(3px);
}

/* ===== large desktop monitors (common on Windows) =====
   No max-width anywhere means on big monitors the composer/bars and especially the
   mono console stretch edge-to-edge, so long stream-json lines are hard to track.
   Center the work column at a comfortable reading width; the atmospheric glow fills
   the gutter. The maximized console (position:fixed) is unaffected — full-bleed still. */
@media (min-width: 1700px) {
  .main { max-width: 1500px; width: 100%; margin-inline: auto; padding-inline: 32px; }
}

/* ===== responsive: tablet & phone ===== */
@media (max-width: 820px) {
  /* let the page grow and scroll instead of being pinned to 100vh — otherwise
     the stacked bars squeeze the output console (the CLI) down to nothing and
     it's clipped off-screen with no way to reach it */
  body { height: auto; }
  .app { grid-template-columns: 1fr; height: auto; min-height: 100vh; }
  .main { overflow: visible; }
  /* give the CLI output a usable height; it scrolls internally, page scrolls to it.
     Drag-to-resize is desktop-only — on touch the page just scrolls. */
  .output { flex: none; min-height: 60vh; height: auto !important; }
  .output-resizer { display: none; }
  .sidebar {
    position: fixed; top: 0; bottom: 0; left: 0; z-index: 80;
    width: min(86vw, 320px);
    transform: translateX(-100%);
    transition: transform 0.22s ease;
    box-shadow: 0 0 60px -10px rgba(0, 0, 0, 0.8);
  }
  .sidebar.open { transform: translateX(0); }
  /* the drag-to-resize handle makes no sense on touch — hide it */
  .sidebar-resizer { display: none; }
  .menu-toggle { display: inline-flex; align-items: center; justify-content: center; }

  .main { padding: 16px 14px; }
  .topbar { margin-bottom: 14px; gap: 8px; }
  .topbar h1 { font-size: 17px; }
  .topbar-left { gap: 8px; flex-wrap: wrap; }
  .branch-pick select { max-width: 150px; }
  .who { display: none; } /* free up space; identity still in the menu context */

  /* composer stacks: prompt on top, controls full-width below */
  .composer { flex-direction: column; gap: 10px; }
  .composer > div { min-width: 0; }
  .composer textarea { min-height: 110px; }

  /* option/git bars wrap comfortably */
  .git-opts { gap: 10px; }
  .git-field input { width: 100%; }
  .git-field { flex: 1 1 140px; }

  /* modals fill the screen with a small margin and scroll if tall */
  .modal,
  .modal-wide,
  .modal-about,
  .modal-approval {
    width: auto;
    max-width: none;
    margin: 0 12px;
    max-height: 90vh;
    overflow-y: auto;
  }
  .modal .actions { flex-wrap: wrap; }
  .modal .actions button { flex: 1 1 auto; }

  /* audit log: stack the user list above the run list */
  .audit-grid { grid-template-columns: 1fr; max-height: none; }
  .audit-users { border-right: none; border-bottom: 1px solid var(--border); max-height: 30vh; }

  /* add-project repo rows stack */
  .repo-row { flex-wrap: wrap; }
  .repo-row .repo-url, .repo-row .repo-pat { flex: 1 1 100%; }

  /* find-in-output bar wraps below the action buttons instead of overflowing */
  .output-find { margin-left: 0; flex-wrap: wrap; }
  .output-find input { width: 140px; }
}

/* phones: comfortable touch targets and tighter chrome */
@media (max-width: 540px) {
  .main { padding: 12px 11px; }
  .output { padding: 12px; font-size: 12px; }
  /* every tappable control gets a finger-friendly height */
  button, .attach-btn, .tab { min-height: 40px; }
  .muted-link { min-height: 36px; }
  .run-title { max-width: 160px; }
  .modal { padding: 20px 18px; }
  /* login card uses the full width with margins on tiny screens */
  .login-card { width: 100%; max-width: 360px; }
}

/* Option B — Local PC (workers) */
.localpc-bar { margin: 6px 0; }
.localpc-bar .hint { margin-left: 8px; font-size: 12px; }
.worker-list { margin: 8px 0; display: flex; flex-direction: column; gap: 8px; }
.worker-row { padding: 8px 10px; border: 1px solid var(--border, #2a3344); border-radius: 8px; font-size: 13px; }
.worker-token { margin: 10px 0; padding: 10px; border: 1px dashed #5eead4; border-radius: 8px; background: rgba(94,234,212,.05); }
.worker-token pre { white-space: pre-wrap; word-break: break-all; font-size: 12px; margin: 4px 0 10px; }
.local-proj-form { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.local-proj-form input, .local-proj-form select { padding: 6px 8px; }

/* "Test on local pc" per-run scope options in the composer */
.localpc-scope { display: inline-flex; align-items: center; gap: 8px; margin-left: 6px; }
.localpc-scope.hidden { display: none; }
.localpc-scope a { text-decoration: none; }

/* "Test on local pc" setup popup */
.lt-status { margin: 6px 0 4px; font-size: 13px; }
.lt-status code { font-size: 12px; }
.lt-ok { color: var(--green, #46c08b); font-weight: 600; }
.lt-bad { color: var(--red, #ff5d8f); font-weight: 600; }
.lt-changedir { margin: 6px 0 4px; }
.lt-changedir pre { white-space: pre-wrap; word-break: break-all; font-size: 12px; margin: 8px 0 4px; padding: 8px; border: 1px solid var(--border, #2a3344); border-radius: 6px; }
#localTestModal .local-proj-form input#ltDb { flex: 1 1 320px; }
#localTestModal textarea { width: 100%; box-sizing: border-box; }
#localTestModal h4 { margin: 14px 0 4px; }

/* Per-repo branch pickers for combined (multi-repo) projects */
.branch-multi { display: inline-flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.branch-repo { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; color: var(--muted, #9aa); }
.branch-repo select { max-width: 240px; }

/* Searchable branch control + spinner */
.branch-ctl { display: inline-flex; align-items: center; gap: 4px; }
.branch-input { width: 210px; max-width: 240px; padding: 4px 7px; font-size: 12px; border-radius: 6px; }
.branch-spin { font-size: 12px; color: var(--muted, #9aa); display: inline-block; }
.branch-spin.hidden { display: none; }
.branch-spin:not(.hidden) { animation: bpulse 0.9s ease-in-out infinite; }
@keyframes bpulse { 0%, 100% { opacity: .35; } 50% { opacity: 1; } }

/* Per-project commit identity badge */
.proj-commit { display: block; margin-top: 2px; color: var(--accent, #5eead4); font-size: 11px; opacity: .85; }

/* Per-project actions (Upload to GitHub / Download to PC) in the topbar. */
.proj-actions { display: inline-flex; align-items: center; gap: 6px; margin-left: 8px; }
.proj-actions.hidden { display: none; }
.proj-actions .muted-link { white-space: nowrap; }

/* Commit-target bar: which branch the End-session commit lands on (editable). */
.commit-bar {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  margin-top: 8px; padding: 8px 10px; font-size: 12.5px;
  border: 1px solid rgba(139, 92, 246, 0.35); border-radius: 8px;
  background: var(--grad-soft, rgba(139, 92, 246, 0.08));
}
.commit-bar.hidden { display: none; }
.commit-ico { font-size: 14px; color: var(--accent, #8b5cf6); }
.commit-lbl { color: var(--muted, #9aa); }
.commit-input {
  flex: 1 1 200px; min-width: 160px; max-width: 320px;
  padding: 4px 8px; font-size: 12.5px; border-radius: 6px;
  font-family: var(--mono); color: var(--text);
}
.commit-pub { font-size: 11.5px; }
.commit-pub .pub-yes { color: var(--ok, #34d399); }
.commit-pub .pub-no { color: var(--muted, #9aa); }
.commit-reset { font-size: 13px; }
.commit-reset.hidden { display: none; }
/* git-off commit box: branch shown for info (current branch), not editable. */
.commit-input.commit-input-ro { opacity: 0.75; cursor: default; }
/* Per-repo branch list for combined (multi-repo) projects — one row per sub-repo. */
.commit-repos { flex: 1 1 100%; display: flex; flex-direction: column; gap: 3px; margin-top: 2px; }
.commit-repos.hidden { display: none; }
.commit-repo-row { font-size: 11.5px; color: var(--muted, #9aa); display: flex; align-items: center; gap: 6px; }
.commit-repo-row .pub-yes { color: var(--ok, #34d399); }
.commit-repo-row .pub-no { color: var(--muted, #9aa); }
.commit-repo-name { color: var(--text); }
.commit-repo-arrow { opacity: 0.6; }
.commit-repo-branch { font-family: var(--mono); color: var(--accent, #8b5cf6); background: rgba(139, 92, 246, 0.10); padding: 0 5px; border-radius: 4px; }

/* Inline modes bar: Test-on-local-pc + Discuss (boxed like the other bars via
   the unified .preset-bar group above) */
.modes-bar .localpc-wrap { display: inline-flex; align-items: center; gap: 6px; }
.modes-bar .hidden { display: none; }

/* AskUserQuestion popup */
.ask-list { display: flex; flex-direction: column; gap: 16px; margin: 10px 0; max-height: 60vh; overflow: auto; }
.ask-q { border: 1px solid var(--line, #2a3344); border-radius: 10px; padding: 12px 14px; }
.ask-q-head { margin-bottom: 8px; }
.ask-chip { font-family: var(--mono, monospace); font-size: 11px; padding: 2px 7px; border-radius: 6px; background: rgba(94,234,212,.12); color: #5eead4; }
.ask-opt { display: flex; align-items: flex-start; gap: 10px; padding: 8px 6px; cursor: pointer; font-size: 13px; border-radius: 8px; }
.ask-opt:hover { background: rgba(255,255,255,0.03); }
/* the global `input{width:100%}` stretches the radio/checkbox box and makes the
   row look centered — pin selectors back to their natural size and align them. */
.ask-opt input[type="radio"], .ask-opt input[type="checkbox"] { width: auto; flex: 0 0 auto; margin: 3px 0 0; }
.ask-opt > span { flex: 1; min-width: 0; }
/* "Other" free-text: label on top, a full-width box below so you can read what you type */
.ask-other-row { display: block; padding: 8px 6px; }
.ask-other-head { display: flex; align-items: center; gap: 10px; margin-bottom: 7px; }
.ask-other-head input[type="radio"], .ask-other-head input[type="checkbox"] { width: auto; flex: 0 0 auto; }
.ask-other { width: 100%; box-sizing: border-box; padding: 10px 12px; font-size: 14px; line-height: 1.4; min-height: 44px; resize: vertical; }

/* Short laptops (e.g. the small MacBook Air): the stacked option bars squeeze the
   CLI output. On wide-but-short screens, let the main column scroll and guarantee
   the output a usable height so the CLI is always visible. */
@media (min-width: 821px) and (max-height: 880px) {
  .main { overflow-y: auto; }
  .output { min-height: 300px; }
  .composer textarea { min-height: 54px; }
  .composer { margin-bottom: 6px; }
  .preset-bar, .planfirst-bar, .summary-bar, .teststep-bar, .modes-bar, .localpc-bar, .git-bar { margin: 3px 0; }
}

/* CLI "design preview ready" download line */
.line-design-link { margin: 6px 0; padding: 7px 10px; border: 1px dashed var(--accent, #5eead4); border-radius: 8px; background: rgba(94,234,212,.06); font-size: 13px; }
.line-design-link a { color: var(--accent, #5eead4); margin: 0 2px; }

/* Clickable file paths in the CLI: the path opens in a new tab, ↓ downloads. */
.output a.cli-file { color: var(--accent, #5eead4); text-decoration: underline dotted; text-underline-offset: 2px; }
.output a.cli-file:hover { text-decoration: underline solid; background: rgba(94,234,212,.1); border-radius: 3px; }
.output a.cli-dl { color: var(--accent, #5eead4); text-decoration: none; font-weight: 700; margin: 0 4px 0 3px; padding: 0 3px; border-radius: 3px; }
.output a.cli-dl:hover { background: rgba(94,234,212,.18); }

/* ---- to-do list (todos feature) ---- */
.todo-add { display: flex; gap: 8px; margin-bottom: 14px; }
.todo-add #todoText { flex: 1; margin: 0; }
.todo-add #todoDue { width: 160px; margin: 0; flex: 0 0 auto; }
.todo-add button { flex: 0 0 auto; }
.todo-list { max-height: 52vh; overflow-y: auto; font-size: 14px; }
.todo-item { display: flex; align-items: flex-start; gap: 10px; padding: 10px 2px; border-bottom: 1px solid var(--border); }
.todo-item input[type="checkbox"] { width: auto; margin: 3px 0 0; flex: 0 0 auto; }
.todo-item .tt { flex: 1; min-width: 0; }
.todo-item .tx { word-break: break-word; color: var(--text, #e7e9ee); }
.todo-item.done .tx { text-decoration: line-through; opacity: .55; }
.todo-item .meta { font-size: 12px; color: var(--muted); margin-top: 3px; }
.todo-item .due { color: var(--accent); }
.todo-item .due.over { color: #f4707a; }
.todo-item .del { color: #f4707a; background: none; border: none; cursor: pointer; font-size: 12px; flex: 0 0 auto; padding: 2px 4px; }
.todo-item .del:hover { text-decoration: underline; }
.todo-empty { color: var(--muted); text-align: center; padding: 20px; }

/* ---- VS Code-like file changes (web) ---- */
.vc-repo { margin-bottom: 12px; }
.vc-repo-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 5px 2px; border-bottom: 1px solid var(--border); }
.link-danger { background: none; border: none; color: #f4707a; cursor: pointer; font-size: 12px; }
.link-danger:hover { text-decoration: underline; }
.vc-file { border-bottom: 1px solid rgba(255,255,255,0.05); }
.vc-top { display: flex; align-items: center; gap: 10px; padding: 7px 4px; cursor: pointer; border-radius: 6px; }
.vc-top:hover { background: var(--panel-2); }
.vc-badge { flex: 0 0 auto; width: 18px; text-align: center; font-weight: 700; font-size: 12px; }
.vc-badge.mod { color: #e2c08d; }
.vc-badge.add { color: #7ee787; }
.vc-badge.del { color: #f4707a; }
.vc-name { flex: 1; min-width: 0; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--mono); }
.vc-disc { flex: 0 0 auto; background: none; border: none; color: #f4707a; cursor: pointer; font-size: 15px; }
.vc-disc:hover { transform: scale(1.15); }
.vc-diff { margin: 0 0 6px; padding: 8px 10px; background: #07090d; border: 1px solid var(--border); border-radius: 6px; font: 12px/1.5 var(--mono); overflow-x: auto; max-height: 320px; overflow-y: auto; white-space: pre; }
.vc-diff .wdl.add { color: #7ee787; }
.vc-diff .wdl.del { color: #ffa198; }
.vc-diff .wdl.hunk { color: #79c0ff; }

/* ---- saved drafts (web) ---- */
.draft-row { display: flex; align-items: center; gap: 10px; padding: 9px 4px; border-bottom: 1px solid var(--border); }
.draft-info { flex: 1; min-width: 0; }
.draft-name { font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.draft-meta { font-size: 11px; margin-top: 2px; }

/* ---- second engine (ChatGPT): image gallery, lightbox, image-gen bar ---- */
.modal.wide { width: 720px; max-width: 92vw; }
.btn { display: inline-block; text-decoration: none; background: var(--panel); border: 1px solid var(--border-strong); color: var(--text, #eee); border-radius: 10px; padding: 8px 14px; font-size: 13px; cursor: pointer; }
.btn:hover { border-color: #8b5cf6; }
.imagegen-bar { display: flex; align-items: center; gap: 10px; }
/* live ChatGPT worker status pill next to the "🤖 ChatGPT engine" button */
.chatgpt-status { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: 999px; border: 1px solid var(--border-strong); white-space: nowrap; cursor: default; }
.chatgpt-status::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: currentColor; display: inline-block; }
/* inline image strip rendered into the live console */
.img-strip { margin: 10px 0; padding: 10px; border: 1px solid var(--border-strong); border-radius: 12px; background: rgba(139, 92, 246, 0.06); }
.img-strip-head { font-size: 12px; color: var(--muted); display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.img-thumbs, .gallery-grid { display: flex; flex-wrap: wrap; gap: 10px; }
.gallery-grid { margin: 14px 0; }
.img-thumb { width: 120px; height: 120px; object-fit: cover; border-radius: 10px; border: 1px solid var(--border-strong); cursor: pointer; transition: transform 0.12s ease, border-color 0.12s ease; }
.img-thumb:hover { transform: scale(1.03); border-color: #8b5cf6; }
.gallery-note { margin-bottom: 8px; }

/* ---- copyable command boxes (ChatGPT panel) ---- */
.cmd-row { display: flex; gap: 8px; align-items: center; margin: 6px 0; }
.cmd { flex: 1 1 auto; min-width: 0; overflow-x: auto; white-space: nowrap; background: rgba(0,0,0,0.28); border: 1px solid var(--border-strong); padding: 7px 9px; border-radius: 8px; font-size: 12px; user-select: all; -webkit-user-select: all; }
.copy-btn { flex: 0 0 auto; padding: 7px 11px; font-size: 12px; cursor: pointer; }

/* ---- inline colour swatches in run output + palette popup ---- */
.hex-chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--mono, monospace); font-size: .92em;
  padding: 1px 6px 1px 5px; border-radius: 6px;
  border: 1px solid var(--border-strong); background: rgba(255, 255, 255, 0.05);
  cursor: pointer; vertical-align: baseline; white-space: nowrap;
}
.hex-chip:hover { background: rgba(255, 255, 255, 0.1); }
.hex-dot {
  width: 12px; height: 12px; border-radius: 3px; flex: 0 0 auto;
  border: 1px solid rgba(0, 0, 0, 0.35);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.25);
}

.palette-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
  gap: 10px; margin-top: 6px;
}
.pal-cell {
  position: relative; height: 76px; border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong); cursor: pointer; padding: 0;
  display: flex; align-items: flex-end; justify-content: center;
}
.pal-cell:hover { outline: 2px solid var(--accent); outline-offset: 1px; }
.pal-hex {
  font-family: var(--mono, monospace); font-size: 11px; font-weight: 600;
  width: 100%; padding: 4px 0 5px; text-align: center;
  background: rgba(255, 255, 255, 0.82); color: #0f172a;
  border-bottom-left-radius: var(--radius-sm); border-bottom-right-radius: var(--radius-sm);
}
.pal-cell.on-dark .pal-hex { background: rgba(15, 23, 42, 0.6); color: #fff; }

/* ============================================================================
   Added features: empty-state gate, auto-compress bar, conflict override popup
   ============================================================================ */

/* ---- Feature 1: "select a project first" empty state ---- */
/* The hint only shows when nothing is selected; then the composer, console and
   recent-runs list are hidden (nothing is removed from the DOM). */
.no-project-hint { display: none; }
body.no-project .no-project-hint {
  display: flex; align-items: center; justify-content: center;
  min-height: 50vh; padding: 24px;
}
body.no-project #recentRunsSection,
body.no-project .main .composer,
body.no-project .main .attach-bar,
body.no-project .main .preset-bar,
body.no-project .main .planfirst-bar,
body.no-project .main .summary-bar,
body.no-project .main .compress-bar,
body.no-project .main .teststep-bar,
body.no-project .main .modes-bar,
body.no-project .main .git-bar,
body.no-project .main .tasks-panel,
body.no-project .main #sessionsPanel,
body.no-project .main #outputControls,
body.no-project .main #outputResizer,
body.no-project .main .output { display: none !important; }
.no-project-card {
  text-align: center; max-width: 420px;
  padding: 30px 34px; border-radius: var(--radius, 14px);
  background: var(--panel); border: 1px solid var(--border);
}
.no-project-emoji { font-size: 42px; margin-bottom: 8px; }
.no-project-card h2 { margin: 6px 0 8px; font-family: var(--display); }
.no-project-card p { margin: 0; color: var(--muted); font-size: 14px; }

/* ---- Feature 3: auto-compress bar + live context badge ---- */
.compress-bar { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.compress-pct {
  width: 58px; text-align: center; padding: 3px 4px;
  background: var(--panel-2); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius-sm, 8px);
}
.compress-pct:disabled { opacity: 0.5; }
.ctx-badge { margin-left: 6px; font-family: var(--mono); font-size: 12px; color: var(--muted); }
.ctx-badge.ctx-high { color: var(--yellow); font-weight: 600; }

/* ---- Feature 2: multi-session conflict override popup ---- */
.conflict-file { margin: 6px 0; font-size: 13px; }
.conflict-file code { color: var(--text); word-break: break-all; }
.conflict-diff-wrap {
  max-height: 320px; overflow: auto; margin: 8px 0;
  border: 1px solid var(--border); border-radius: var(--radius-sm, 8px);
  background: rgba(0, 0, 0, 0.35);
}
.conflict-diff {
  margin: 0; padding: 10px 12px; white-space: pre;
  font-family: var(--mono); font-size: 12px; line-height: 1.45; color: var(--text);
}

/* ── The pane (signature) ─────────────────────────────────────────────────────
   The one place the brand gradient is allowed, because it carries the single
   fact this product exists to tell you: your work is a live tmux pane on the
   VPS, it is still running, and you can attach to it yourself from any shell.
   Everything around it stays quiet so this reads. */
/* With the pane open, the console still carries PLATFORM messages — Claude's
   questions, errors, the git/commit bar — while the TUI's own output goes to the
   terminal. So it shrinks to a strip rather than hiding: hiding it silently
   swallowed every one of those messages for the whole run. It collapses entirely
   when there is nothing to say. */
.output.with-pane { flex: none; max-height: 128px; min-height: 0; }
.output.with-pane:empty { display: none; }

/* Taller than the text console it replaces: this one has a TUI in it, which needs
   room to draw its composer, output and footer. Drag the handle above to resize. */
.pane {
  flex: 1; min-height: 440px; display: flex; flex-direction: column;
  border: 1px solid var(--border); border-radius: var(--radius);
  background: #05070d; overflow: hidden;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
}
.pane.hidden { display: none; }

.pane-bar {
  display: flex; align-items: center; gap: 10px; flex: none;
  padding: 8px 12px; border-bottom: 1px solid var(--border);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.045), rgba(255, 255, 255, 0.012));
}

/* State dot. Detached/idle is a flat muted disc; a BUSY pane wears the brand
   gradient and breathes. That contrast is the whole point: you can tell across
   the room whether the machine is working. */
.pane-dot {
  width: 8px; height: 8px; border-radius: 50%; flex: none;
  background: var(--faint); transition: background 0.2s ease;
}
.pane-dot.busy {
  background: var(--grad); background-size: 200% 200%;
  animation: pane-breathe 2.4s ease-in-out infinite;
}
.pane-dot.dead { background: var(--red); }
@keyframes pane-breathe {
  0%, 100% { background-position: 0% 50%; box-shadow: 0 0 0 0 rgba(124, 107, 245, 0.5); }
  50% { background-position: 100% 50%; box-shadow: 0 0 0 4px rgba(124, 107, 245, 0); }
}

.pane-name {
  font-family: var(--mono); font-size: 11.5px; color: var(--text);
  letter-spacing: 0.02em;
}
.pane-state {
  font-family: var(--mono); font-size: 11px; color: var(--muted);
  text-transform: lowercase;
}
.pane-spacer { flex: 1; }

/* "tmux attach -t a3-42" — the keys to the machine, one click away. */
.pane-attach {
  font-family: var(--mono); font-size: 11px; color: var(--muted);
  background: rgba(255, 255, 255, 0.04); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 4px 9px; cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}
.pane-attach:hover { color: var(--text); border-color: var(--border-strong); background: rgba(255, 255, 255, 0.07); transform: none; }
.pane-attach.copied { color: var(--green); border-color: rgba(52, 211, 153, 0.45); }

.pane-term { flex: 1; min-height: 0; padding: 10px 12px; }
.pane-term .xterm { height: 100%; }
/* xterm draws its own scrollbar region; keep the viewport from double-scrolling */
.pane-term .xterm-viewport { overflow-y: auto; }

@media (prefers-reduced-motion: reduce) {
  .pane-dot.busy { animation: none; }
}
