/* ============================================================
   Design tokens — dark theme (default).
   The whole app is themed through these variables; the light
   theme below re-declares the same names. Component rules should
   reference tokens, never raw hexes, wherever possible.
   ============================================================ */
:root {
  --bg: #101014;
  --bg-1: #141419;
  --bg-2: #17171c;
  --bg-3: #232329;
  --bg-hover: #2b2b33;
  --border: #33333c;
  --text: #ececf1;
  --text-dim: #b9b9c6;
  --text-faint: #94949f;
  /* Brand accent (indigo) — used for primary actions, active nav,
     focus rings and "in progress" state. */
  --accent: #6d6af8;
  --accent-2: #a5a3ff;
  --accent-soft: rgba(109, 106, 248, 0.16);
  --on-accent: #ffffff;
  --user-bubble: #2c2c38;
  --danger: #ef4444;
  --danger-soft: rgba(239, 68, 68, 0.12);
  --ok: #34c37e;
  --ok-soft: rgba(52, 195, 126, 0.12);
  --warn: #e0a458;
  --warn-soft: rgba(224, 164, 88, 0.12);
  --info: #4f8ff7;
  --info-soft: rgba(79, 143, 247, 0.12);
  /* The top bar's height. A token because four other things measure themselves against
     it — the off-canvas sidebar, its backdrop, and the two right-hand drawers — and a
     bar that grows by 4px with three of them left behind is a gap nobody can explain. */
  --topbar-h: 52px;
  /* Every left rail — Group Chat, Company, Inbox — is this wide, and so is the app
     sidebar they each stand in for. They were 280/264/264 and the furniture moved as
     you walked between the views. See "THE RAIL STANDARD" at the end of this file. */
  --rail-w: 264px;
  --radius: 12px;
  --radius-sm: 8px;
  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.35);
  --shadow-2: 0 8px 28px rgba(0, 0, 0, 0.45);
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono: "Cascadia Code", "Fira Code", Consolas, "Courier New", monospace;
  color-scheme: dark;
}

/* Light theme — professional workspace look. Activated by
   <html data-theme="light"> (set from localStorage / OS preference
   by an inline script in index.html before first paint). */
:root[data-theme="light"] {
  --bg: #f6f6f8;
  --bg-1: #fafafc;
  --bg-2: #ffffff;
  --bg-3: #f0f0f4;
  --bg-hover: #e9e9ef;
  --border: #e2e2ea;
  --text: #1e2026;
  --text-dim: #565b66;
  --text-faint: #6f7480;
  --accent: #5a55ee;
  --accent-2: #4640c8;
  --accent-soft: rgba(90, 85, 238, 0.10);
  --on-accent: #ffffff;
  --user-bubble: #e9e9f8;
  --danger: #d92d20;
  --danger-soft: rgba(217, 45, 32, 0.08);
  --ok: #17915b;
  --ok-soft: rgba(23, 145, 91, 0.10);
  --warn: #b45309;
  --warn-soft: rgba(180, 83, 9, 0.10);
  --info: #2563eb;
  --info-soft: rgba(37, 99, 235, 0.08);
  --shadow-1: 0 1px 2px rgba(16, 18, 28, 0.06);
  --shadow-2: 0 8px 28px rgba(16, 18, 28, 0.14);
  color-scheme: light;
}

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
body {
  font-family: var(--font);
  background: var(--bg);
  color: var(--text);
  font-size: 15px;
  line-height: 1.55;
}
button { font-family: inherit; cursor: pointer; }
.hidden { display: none !important; }

/* The shell is a COLUMN now: one bar across the top, everything else beneath it. The
   brand and the online switch used to sit inside the sidebar, which Company, Group Chat
   and the Inbox all hide — so each of those rails carried a duplicate, and the app's
   identity moved around as you navigated. */
#app { display: flex; flex-direction: column; height: 100vh; overflow: hidden; }
#app-body { flex: 1; min-height: 0; display: flex; }

/* ---- Top bar ---- */
#topbar {
  flex-shrink: 0; height: var(--topbar-h); display: flex; align-items: center; gap: 10px;
  padding: 0 14px; background: var(--bg-2); border-bottom: 1px solid var(--border);
  /* Above ordinary page content, BELOW every overlay — the settings modal (50), the
     task drawer (60) and the off-canvas sidebar (70) must all cover it, or a dialog
     opens with the app frame drawn on top of its own backdrop. */
  position: relative; z-index: 40;
}
#topbar .brand { padding: 0; }
/* Right edge, on its own — it is the only control up here and it changes how the whole
   workspace behaves, so it should not be crowded by anything. */
#topbar .reach-switch {
  margin: 0 0 0 auto; width: auto; gap: 10px; padding: 6px 12px; border-radius: 999px;
}

/* ---- Sidebar ---- */
#sidebar {
  width: var(--rail-w);
  flex-shrink: 0;
  background: var(--bg-2);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  padding: 14px;
  gap: 12px;
}
.brand { display: flex; align-items: center; gap: 9px; padding: 6px 6px 2px; }
.brand-logo { font-size: 24px; display: inline-flex; align-items: center; flex-shrink: 0; }
/* Quorai mascot mark — sizes to its container's font-size (1em) so it drops
   into the brand, empty-state and auth lockups without per-place tuning. */
.qmark { width: 1em; height: 1em; display: inline-block; vertical-align: middle; overflow: visible; }
/* Wordmark: "Quor" in text colour, "ai" in the mascot's cyan (matches the eyes). */
.wordmark { letter-spacing: -0.01em; }
.wm-ai { color: var(--text-dim); }
.brand-text { display: flex; align-items: center; }
.brand-text strong { font-size: 18px; font-weight: 700; line-height: 1; }
.brand-text small { color: var(--text-faint); font-size: 11px; }

.btn-new {
  background: var(--accent);
  color: var(--on-accent);
  border: none;
  border-radius: var(--radius);
  padding: 11px;
  font-size: 14px;
  font-weight: 600;
  transition: background .15s;
}
.btn-new:hover { background: var(--accent-2); }

.conversations { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; }
.conv-item {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 10px;
  border-radius: 9px;
  color: var(--text-dim);
  font-size: 13.5px;
  cursor: pointer;
  white-space: nowrap;
}
.conv-item:hover { background: var(--bg-hover); color: var(--text); }
.conv-item.active { background: var(--accent-soft); color: var(--text); }
/* The conversation you're currently in — pinned to the top of Recents and marked
   with an accent rail so you can jump back to it (chat, discussion, inbox chat)
   from any view, even before it has a title. Deliberately NOT a dot: a dot reads
   as "this one is running", which is a different question with its own marker
   below. Where-you-are is a rail plus weight; still-working is a spinner. */
.conv-item.current { color: var(--text); font-weight: 600; box-shadow: inset 2px 0 0 var(--accent); }
/* The row is a title with an optional second line under it ("2m · 1 queued"), so
   the text column is its own flex child — the title alone can no longer be `flex: 1`
   or it would stretch vertically inside that column instead of horizontally. */
.conv-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.conv-title { overflow: hidden; text-overflow: ellipsis; }
.conv-meta { font-size: 11px; color: var(--text-faint); overflow: hidden; text-overflow: ellipsis; }
.conv-item.working .conv-meta { color: var(--accent-2); }
.conv-del {
  opacity: 0; border: none; background: transparent; color: var(--text-faint);
  font-size: 14px; padding: 2px 4px; border-radius: 6px;
}
.conv-item:hover .conv-del { opacity: 1; }
.conv-del:hover { color: var(--danger); background: rgba(240,96,106,.12); }
/* A thread that's still working while you read another one. It LEADS the row (the
   eye lands there first, and it's the one question the list gets asked) and it is a
   spinner, not a dot — nothing else in Recents rotates, so "which one is running"
   is answered without comparing two similar dots. It must survive hover: pointing
   at a row to check it is exactly when the answer used to disappear. */
.conv-item.working .conv-title { color: var(--text); }
.conv-working {
  flex: none; width: 11px; height: 11px; border-radius: 50%;
  box-sizing: border-box;
  border: 2px solid var(--accent-soft);
  border-top-color: var(--accent);
  animation: conv-spin .8s linear infinite;
}
@keyframes conv-spin { to { transform: rotate(360deg); } }
/* A reply that landed while you were somewhere else. It trails the row and it is
   GREEN — the third thing this list has to say, and the only one that means "this
   is finished, go and read it". Indigo is spoken for twice over (the rail you're
   on, the spinner still going), so a third indigo mark would be the original bug
   again. Bold reads as unread the way every mail client has taught. */
.conv-item.unread .conv-title { color: var(--text); font-weight: 600; }
.conv-unread {
  flex: none; width: 7px; height: 7px; border-radius: 50%;
  background: var(--ok);
}
/* Nothing here reorders the list. A row that must be seen — the one you're in, one
   still working, one holding an unread reply — is let THROUGH the "See more" fold
   in its own position instead, so a click never moves the thing you clicked. */

/* One message pane per open thread; only the active one is shown. Panes keep their
   own DOM so a background reply streams on and switching back is instant. */
.msg-pane { display: block; }
.msg-pane.hidden { display: none; }

/* "Still working on the server" placeholder shown when a reopened conversation ends
   on a dangling user turn (e.g. a discussion the browser was refreshed away from,
   still completing server-side). Replaced by the real reply when the poll picks it up. */
.pending-reply { display: flex; align-items: center; gap: 8px; color: var(--text-dim); font-size: 13.5px; }
.pending-dots { display: inline-flex; gap: 3px; }
.pending-dots i { width: 5px; height: 5px; border-radius: 50%; background: var(--accent); opacity: .35; animation: pending-blink 1.2s infinite ease-in-out; }
.pending-dots i:nth-child(2) { animation-delay: .2s; }
.pending-dots i:nth-child(3) { animation-delay: .4s; }
@keyframes pending-blink { 0%, 80%, 100% { opacity: .25; } 40% { opacity: 1; } }

.btn-settings {
  background: var(--bg-3);
  color: var(--text-dim);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 10px;
  font-size: 13.5px;
}
.btn-settings:hover { background: var(--bg-hover); color: var(--text); }

/* ---- Main ---- */
#main { flex: 1; display: flex; flex-direction: column; min-width: 0; }
#chat-header {
  height: 52px; flex-shrink: 0;
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center; padding: 0 22px;
}
.model-badge {
  font-size: 12.5px; color: var(--text-dim);
  background: var(--bg-2); border: 1px solid var(--border);
  padding: 5px 12px; border-radius: 20px;
}
.model-badge .dot { color: var(--ok); }

/* ---- Messages ---- */
.messages { flex: 1; overflow-y: auto; padding: 26px 0; }
.msg-row { max-width: 780px; margin: 0 auto; padding: 6px 22px; display: flex; gap: 14px; }
.msg-row.user { flex-direction: row-reverse; }
.avatar {
  width: 30px; height: 30px; border-radius: 8px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center; font-size: 16px;
}
.avatar.user { background: var(--user-bubble); }
.avatar.assistant { background: var(--bg-3); }
.avatar.peer { background: rgba(255,255,255,0.07); }
/* Quorai mascot as the assistant avatar — clipped to the rounded-square tile so
   the mark stays centered inside it (no overflow spill). */
/* Match the group-chat icon: accent mark, centered with breathing room in the tile. */
.avatar-bot { width: 62%; height: 62%; overflow: hidden; display: block; color: var(--accent); }
.msg-body { flex: 1; min-width: 0; padding-top: 2px; display: flex; flex-direction: column; align-items: flex-start; }
.msg-row.user .msg-body { align-items: flex-end; }
/* AI avatar sits on the left, so reserve the same width on the right (avatar 30 +
   gap 14) so assistant content lines up with the user bubble's right edge. */
.msg-row.assistant .msg-body { padding-right: 44px; }
.msg-role { font-size: 12px; color: var(--text-faint); margin-bottom: 3px; font-weight: 600; }
.src-badge {
  display: inline-flex; align-items: center; gap: 3px;
  font-size: 10px; font-weight: 600; line-height: 1;
  padding: 2px 6px; border-radius: 999px; margin-left: 6px;
  border: 1px solid var(--border); vertical-align: middle; cursor: help;
}
.src-badge.peer { color: var(--ok); background: var(--ok-soft); border-color: transparent; }
.src-badge.local { color: var(--warn); background: var(--warn-soft); border-color: transparent; }
.msg-content {
  word-wrap: break-word; overflow-wrap: anywhere; max-width: 100%;
  background: var(--bg-2); border: 1px solid var(--border);
  border-radius: 14px; padding: 9px 14px;
}
.msg-row.user .msg-content { background: var(--user-bubble); border-color: transparent; }
.msg-content.msg-skip { color: var(--text-faint); font-style: italic; background: transparent; border-style: dashed; }
.msg-row.peer .msg-content { background: var(--bg-3); border-color: var(--border); }

/* Every CARD under an answer is one width — the column's.
   `.msg-body` is a flex column with `align-items: flex-start`, so a block child
   shrinks to its own content unless it says otherwise. Only the Workbench said so:
   the downloads card stopped at 520px and the send-approval at 560px, so one answer
   that made a file and then asked to send it drew three boxes with three different
   right edges, each starting from the same left one. This is the ONE place that
   decides it — a card added later joins the list rather than picking its own width.
   Chips, badges and attachments are inline-flex and are deliberately not here: they
   size to their content because that is what a chip IS. */
.msg-body > .wb-box,
.msg-body > .files-card,
.msg-body > .send-approve,
.msg-body > .proc-box,
.msg-body > .msg-error { align-self: stretch; width: 100%; box-sizing: border-box; }
/* An approval can also land straight in the pane (a card rebuilt outside a turn has no
   row to sit in), and an approved action that produced a file drops its downloads card
   in beside it. There they are ordinary blocks — full pane width — so they take the
   message column's own measurements instead, like .discussion-learn does. */
.msg-pane > .send-approve, #messages > .send-approve,
.msg-pane > .files-card, #messages > .files-card { max-width: 780px; margin: 10px auto; }
.discussion-sep {
  max-width: 780px; margin: 12px auto 4px; padding: 0 22px;
  display: flex; align-items: center; gap: 10px;
  font-size: 12px; color: var(--text-faint); font-weight: 600;
}
.discussion-sep::before, .discussion-sep::after {
  content: ""; flex: 1; height: 1px; background: var(--border);
}
.dl-vote { max-width: 780px; margin: 2px auto; padding: 0 22px; font-size: 12px; color: var(--text-faint); }
.dl-vote.yes { color: var(--ok); }
.dl-vote.no { color: var(--warn); }
.discussion-learn {
  max-width: 780px; margin: 8px auto; padding: 10px 16px; border-radius: 12px;
  border: 1px solid var(--border); font-size: 13px; line-height: 1.5;
}
.discussion-learn.ok { background: var(--ok-soft); border-color: transparent; }
.discussion-learn.no { background: var(--warn-soft); border-color: transparent; }
.dl-head { font-weight: 600; }
.dl-facts { margin: 6px 0 0; padding-left: 20px; }
.dl-facts li { margin: 4px 0; }
.dl-fact-text { vertical-align: middle; }
.dl-promote {
  margin-left: 8px; vertical-align: middle; font-size: 11px; line-height: 1.6;
  padding: 1px 9px; border-radius: 999px; border: 1px solid var(--border);
  background: var(--bg-2); color: var(--text-faint); cursor: pointer; white-space: nowrap;
}
.dl-promote:hover:not(:disabled) { background: var(--bg-hover); color: var(--text); border-color: var(--accent); }
.dl-promote.done { background: var(--ok-soft); color: var(--ok); border-color: transparent; }
.dl-promote:disabled { cursor: default; }
.dl-open-head { margin-top: 10px; color: var(--warn); }
.dl-open li { margin: 6px 0; }
.dl-open-why { font-size: 12px; color: var(--text-faint); margin-top: 2px; }
.peer-process {
  background: var(--bg-3); border: 1px solid var(--border); border-left: 3px solid var(--ok);
  border-radius: 10px; padding: 8px 12px; margin-bottom: 6px; max-width: 100%;
  max-height: 260px; overflow-y: auto;
}
.peer-process-title {
  font-size: 11px; text-transform: uppercase; letter-spacing: .4px;
  color: var(--text-faint); font-weight: 700; margin-bottom: 5px;
}
.proc-step { font-size: 12.5px; color: var(--text-dim); line-height: 1.5; margin: 2px 0; }
.proc-step.tool code { color: var(--accent-2); font-family: var(--mono); font-size: 11.5px; }

/* Collapsible "thinking" box (click header to expand) */
.proc-box { border: 1px solid var(--border); border-radius: 10px; background: var(--bg-3); margin-bottom: 6px; max-width: 100%; overflow: hidden; }
.proc-box.live { border-color: rgba(84,201,138,.5); }
.proc-head {
  display: flex; align-items: center; gap: 8px; width: 100%; text-align: left; cursor: pointer;
  background: none; border: none; color: var(--text-dim); padding: 8px 12px; font-size: 12.5px; font-weight: 600;
}
.proc-head:hover { background: var(--bg-hover); }
.proc-caret { transition: transform .15s; font-size: 10px; color: var(--text-faint); }
.proc-box:not(.collapsed) .proc-caret { transform: rotate(90deg); }
.proc-name { flex: 1; }
.proc-status { font-size: 11px; color: var(--text-faint); font-weight: 500; }
.proc-live { width: 8px; height: 8px; border-radius: 50%; background: transparent; flex-shrink: 0; }
.proc-box.live .proc-live { background: var(--ok); box-shadow: 0 0 7px var(--ok); animation: cn-pulse 1.1s ease-in-out infinite; }
.proc-body { max-height: 300px; overflow-y: auto; padding: 4px 12px 10px; border-top: 1px solid var(--border); }
.proc-box.collapsed .proc-body { display: none; }
.consult-thinking {
  max-width: 780px; margin: 0 auto; padding: 4px 22px 8px;
  display: flex; align-items: center; gap: 10px; color: var(--text-dim); font-size: 13.5px;
}
.dot-pulse {
  width: 9px; height: 9px; border-radius: 50%; background: var(--ok); flex-shrink: 0;
  animation: cn-pulse 1s ease-in-out infinite;
}
@keyframes cn-pulse { 0%,100% { opacity: .3; transform: scale(.8); } 50% { opacity: 1; transform: scale(1.1); } }
/* Live "the model is composing a tool call" heartbeat (writing code…). */
.tool-progress {
  display: flex; align-items: center; gap: 8px;
  margin: 6px 0 2px; font-size: 13px; color: var(--text-dim);
}
.tool-progress .tp-label { opacity: .9; }
.msg-content p { margin: 0 0 10px; }
.msg-content p:last-child { margin-bottom: 0; }
.msg-content ul, .msg-content ol { margin: 4px 0 10px; padding-left: 22px; }
.msg-content li { margin: 3px 0; }
.msg-content h1, .msg-content h2, .msg-content h3 { margin: 14px 0 8px; line-height: 1.3; }
.msg-content h1 { font-size: 1.35em; }
.msg-content h2 { font-size: 1.2em; }
.msg-content h3 { font-size: 1.08em; }
.msg-content a { color: var(--accent-2); }
.msg-content code {
  font-family: var(--mono); font-size: .88em;
  background: var(--bg-3); padding: 2px 5px; border-radius: 5px;
}
.msg-content pre {
  background: #0b0c10; border: 1px solid var(--border);
  border-radius: 10px; padding: 13px 15px; overflow-x: auto; margin: 8px 0 12px;
}
.msg-content pre code { background: none; padding: 0; font-size: .86em; line-height: 1.5; }
.msg-content blockquote {
  border-left: 3px solid var(--accent); margin: 8px 0; padding: 2px 14px; color: var(--text-dim);
}
.cursor::after { content: "▋"; color: var(--accent); animation: blink 1s steps(2) infinite; }
@keyframes blink { 50% { opacity: 0; } }

/* tool call chips */
.tool-chip {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--bg-3); border: 1px solid var(--border);
  border-radius: 9px; padding: 7px 11px; margin: 6px 0; font-size: 12.5px;
  color: var(--text-dim); cursor: pointer; max-width: 100%;
}
.tool-chip:hover { background: var(--bg-hover); }
.tool-chip .tool-icon { font-size: 14px; }
.tool-chip code { font-family: var(--mono); color: var(--accent-2); }
.tool-detail {
  font-family: var(--mono); font-size: 12px; color: var(--text-dim);
  background: #0b0c10; border: 1px solid var(--border); border-radius: 8px;
  padding: 8px 11px; margin: 2px 0 8px; white-space: pre-wrap; word-break: break-word;
}
.msg-error {
  background: rgba(240,96,106,.1); border: 1px solid rgba(240,96,106,.35);
  color: #ffb3b8; border-radius: 9px; padding: 10px 13px; font-size: 13.5px; margin-top: 4px;
}

/* empty state */
.empty-state { max-width: 560px; margin: 8vh auto 0; text-align: center; padding: 0 22px; }
.empty-logo { font-size: 52px; margin-bottom: 6px; }
.empty-state h1 { font-size: 26px; margin: 0 0 10px; }
.empty-state p { color: var(--text-dim); }
.suggestions { display: flex; flex-wrap: wrap; gap: 9px; justify-content: center; margin-top: 22px; }
.chip-suggest {
  background: var(--bg-2); border: 1px solid var(--border); color: var(--text-dim);
  border-radius: 20px; padding: 9px 15px; font-size: 13px;
}
.chip-suggest:hover { background: var(--bg-hover); color: var(--text); border-color: var(--accent); }
.link-btn { background: none; border: none; color: var(--accent-2); text-decoration: underline; font-size: inherit; padding: 0; }

/* ---- Composer ---- */
#composer { flex-shrink: 0; padding: 12px 22px 16px; border-top: 1px solid var(--border); }
.composer-inner {
  max-width: 780px; margin: 0 auto; display: flex; flex-direction: column; gap: 6px;
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 18px; padding: 10px 12px 10px 14px;
}
.composer-inner:focus-within { border-color: var(--accent); }
#input {
  width: 100%; resize: none; border: none; background: none; color: var(--text);
  font-family: inherit; font-size: 15px; line-height: 1.5; max-height: 200px; outline: none; padding: 4px 0 2px;
}
/* @mention autocomplete — pops above the composer box */
.composer-inner { position: relative; }
.mention-menu {
  position: absolute; bottom: 100%; left: 0; right: 0; margin-bottom: 8px;
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: var(--shadow-2); padding: 4px; max-height: 240px; overflow-y: auto; z-index: 40;
}
.mention-menu.hidden { display: none; }
.mention-item {
  display: flex; align-items: center; gap: 8px; padding: 7px 10px; border-radius: 8px;
  cursor: pointer; font-size: 13.5px; color: var(--text);
}
.mention-item.active, .mention-item:hover { background: var(--bg-hover); }
/* Same vocabulary as .cn-presence on the Members page: fill = a person is there,
   colour = whether we know. Keeping the surfaces in step matters more than the
   1px size difference — see the block above .cn-presence for why. */
.mention-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; box-sizing: border-box; }
.mention-dot.active { background: var(--ok); }
.mention-dot.idle { background: var(--warn); }
.mention-dot.away { background: transparent; border: 1.5px solid var(--ok); }
.mention-dot.online { background: transparent; border: 1.5px solid var(--ok); }
.mention-dot.unknown { background: transparent; border: 1.5px dashed var(--text-faint); opacity: .8; }
.mention-dot.offline { background: var(--text-faint); }
.mention-dot.local { background: var(--accent); }
.mention-name { font-weight: 600; }
.mention-hint { margin-left: auto; font-size: 11px; color: var(--text-faint); }

.composer-controls { display: flex; align-items: center; justify-content: flex-end; gap: 8px; }
.composer-controls-right { display: flex; align-items: center; gap: 8px; }
#attach-btn {
  width: 32px; height: 32px; padding: 0; border-radius: 50%; flex-shrink: 0;
  font-size: 15px; line-height: 1; justify-content: center;
}
#attach-btn svg { width: 16px; height: 16px; display: block; }
#composer.drag .composer-inner { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
/* File-attachment chips — pending row in the composer + chips on a sent message. */
.attach-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.msg-attachments { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }
.attach-chip {
  display: inline-flex; align-items: center; gap: 6px; max-width: 260px;
  background: var(--bg-3); border: 1px solid var(--border); border-radius: 999px;
  padding: 3px 10px; font-size: 12.5px; color: var(--text-dim);
}
.attach-chip .attach-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.attach-chip .attach-ico { flex-shrink: 0; }
.attach-x {
  border: none; background: none; color: var(--text-faint); cursor: pointer;
  font-size: 12px; padding: 0 0 0 2px; line-height: 1;
}
.attach-x:hover { color: var(--danger); }
.attach-eye {
  border: none; background: none; color: var(--text-faint); cursor: pointer;
  font-size: 12px; padding: 0 0 0 2px; line-height: 1;
}
.attach-eye:hover { color: var(--accent); }
.btn-send, .btn-stop {
  width: 32px; height: 32px; border-radius: 50%; border: none; flex-shrink: 0;
  font-size: 15px; display: flex; align-items: center; justify-content: center; cursor: pointer;
}
.btn-send { background: var(--accent); color: var(--on-accent); }
.btn-send:hover { background: var(--accent-2); }
.btn-send:disabled { background: var(--bg-3); color: var(--text-faint); cursor: default; }
.btn-stop { background: var(--bg-3); color: var(--text); border: 1px solid var(--border); }
.btn-stop:hover { background: var(--bg-hover); }
.composer-hint { text-align: center; color: var(--text-faint); font-size: 11.5px; margin-top: 8px; }

/* ---- composer controls (mode + model dropdowns) ---- */
.composer-bar { display: flex; align-items: center; justify-content: space-between; margin-top: 8px; padding: 0 2px; }
.composer-drop { position: relative; }
.drop-btn {
  display: inline-flex; align-items: center; gap: 6px; background: var(--bg-2);
  border: 1px solid var(--border); border-radius: 999px; padding: 5px 12px;
  color: var(--text-dim); font-size: 12.5px; font-weight: 600; cursor: pointer;
}
.drop-btn:hover { border-color: var(--accent); color: var(--text); }
.drop-btn .caret { font-size: 10px; opacity: .7; }
.drop-menu {
  position: absolute; bottom: calc(100% + 8px); left: 0; min-width: 240px; max-height: 320px; overflow-y: auto;
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 12px; padding: 6px;
  box-shadow: 0 12px 40px rgba(0,0,0,.5); z-index: 50;
}
.drop-menu.right { left: auto; right: 0; }
.drop-item {
  display: flex; flex-direction: column; gap: 1px; width: 100%; text-align: left;
  background: none; border: none; border-radius: 8px; padding: 8px 10px; cursor: pointer; color: var(--text);
}
.drop-item b { font-size: 13px; font-weight: 600; }
.drop-item span { font-size: 11.5px; color: var(--text-faint); }
.drop-item:hover { background: var(--bg-hover); }
.drop-item.active { background: var(--accent-soft); }
.drop-item.active b { color: var(--accent-2); }
.drop-manage { border-top: 1px solid var(--border); margin-top: 4px; border-radius: 0 0 8px 8px; color: var(--text-dim); font-size: 12.5px; flex-direction: row; }
.drop-empty { padding: 12px; font-size: 12.5px; color: var(--text-faint); text-align: center; }
/* Scope reminder under the model picker: the choice pins THIS chat, not the node. */
.drop-note { padding: 6px 10px 2px; font-size: 11px; color: var(--text-faint); }

/* ---- Settings modal ---- */
.overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,.55);
  display: flex; align-items: center; justify-content: center; z-index: 50; padding: 20px;
}
.modal {
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 16px;
  width: 100%; max-width: 480px; max-height: 90vh; display: flex; flex-direction: column;
}
.modal-head { display: flex; align-items: center; justify-content: space-between; padding: 18px 20px; border-bottom: 1px solid var(--border); }
.modal-head h2 { margin: 0; font-size: 17px; }
.icon-btn { background: none; border: none; color: var(--text-dim); font-size: 17px; }
.icon-btn:hover { color: var(--text); }
.modal-body { padding: 18px 20px; overflow-y: auto; display: flex; flex-direction: column; gap: 16px; }
.field { display: flex; flex-direction: column; gap: 6px; }
.field > span { font-size: 13px; color: var(--text-dim); font-weight: 600; }
.field em { font-style: normal; color: var(--text-faint); font-weight: 400; }
.field input[type=text], .field input[type=password], .field input:not([type=range]), .field select, .field textarea {
  background: var(--bg); border: 1px solid var(--border); color: var(--text);
  border-radius: 9px; padding: 10px 12px; font-size: 14px; font-family: inherit; width: 100%; outline: none;
}
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--accent); }
.field input[type=range] { width: 100%; accent-color: var(--accent); }
.model-row { display: flex; gap: 8px; }
.model-row input { flex: 1; }
/* QuorAI tier picker — stands in for the model-id input on managed nodes. */
.model-row .tier-select { flex: 1; min-width: 0; }
.btn-mini {
  background: var(--bg-3); border: 1px solid var(--border); color: var(--text);
  border-radius: 9px; padding: 0 14px; font-size: 13px; white-space: nowrap;
}
.btn-mini:hover { background: var(--bg-hover); }
.hint { color: var(--text-faint); font-size: 12px; }
.hint.ok { color: var(--ok); }
.hint.bad { color: var(--danger); }
/* The image-model field carries an inline Test button — proving a model can see is
   the only way to tell a working one from one that ignores images and answers anyway. */
.vision-row { display: flex; gap: 8px; align-items: center; }
.vision-row input, .vision-row select { flex: 1; min-width: 0; }
.vision-row + input { margin-top: 8px; }
#vision-key-row { margin-top: 8px; }
.key-set { color: var(--ok); }
.key-unset { color: var(--text-faint); }
.privacy-note { font-size: 12px; color: var(--text-faint); background: var(--bg); border: 1px solid var(--border); border-radius: 9px; padding: 10px 12px; margin: 0; }
.privacy-note code { font-family: var(--mono); color: var(--text-dim); }
.modal-foot { padding: 14px 20px; border-top: 1px solid var(--border); display: flex; justify-content: flex-end; }
/* ---- appDialog(): the in-app replacement for confirm()/prompt() ---- */
.dialog-modal { max-width: 460px; }
.dialog-body { font-size: 13.5px; line-height: 1.5; color: var(--text-dim); }
.dialog-body strong { color: var(--text); font-weight: 600; }
/* What is actually about to happen — the thing a browser confirm() cannot show. */
.dialog-target { margin-top: 10px; background: var(--bg); border: 1px solid var(--border);
  border-radius: 9px; padding: 9px 11px; font-family: var(--mono); font-size: 11.5px;
  color: var(--text-dim); word-break: break-all; }
.dialog-hint { font-size: 11.5px; color: var(--text-faint); }
.dialog-foot { gap: 8px; }
/* `appDialog({danger:true})` has always set this class; nothing ever styled it, so a
   "Delete" and an "OK" looked identical. Every irreversible action passes it. */
#dialog-ok.danger { background: var(--danger); border-color: var(--danger); color: #fff; }
#dialog-ok.danger:hover { filter: brightness(1.08); }
/* The permissions an extension asks for come through as a list. */
.dialog-body ul { margin: 8px 0 0; padding-left: 20px; }
.dialog-body li { margin: 3px 0; }
#dialog-input { resize: vertical; min-height: 66px; }
/* A destructive/outward confirm is visually distinct from an ordinary OK. */
.btn-primary.danger { background: var(--danger, #e03131); }
.btn-primary.danger:hover { background: color-mix(in srgb, var(--danger, #e03131) 85%, #000); }
.btn-primary { background: var(--accent); color: var(--on-accent); border: none; border-radius: 10px; padding: 10px 20px; font-size: 14px; font-weight: 600; }
.btn-primary:hover { background: var(--accent-2); }

/* ---- Marketplace ---- */
.modal-lg { max-width: 760px; }
.modal-sub { color: var(--text-faint); font-size: 12px; display: block; margin-top: 3px; }
.market-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 14px; }
/* Tools tab — first-class tool catalog grouped by connector / core compute */
#tools-grid { display: flex; flex-direction: column; gap: 12px; }

/* Heartbeat view — the system's rhythm (scheduled skills + proactive beat) */
.hb-section { margin-bottom: 24px; }
.hb-section-title { font-size: 12px; font-weight: 600; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 8px; }
.hb-list { display: flex; flex-direction: column; }
.hb-row { display: flex; align-items: center; gap: 12px; padding: 12px 4px; border-top: 1px solid var(--border); }
.hb-list .hb-row:first-child, .hb-section > .hb-row { border-top: none; }
.hb-row-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.hb-row-name { font-weight: 600; font-size: 14px; }
.hb-row-sub { font-size: 12px; color: var(--text-dim); }
.hb-row-sub.on { color: var(--accent); }
/* Heartbeat is a GRID OF CARDS, reusing the `market-card` surface the Marketplace and
   Skills grids already use. It was the only list in the app that read like a settings
   table, which is what made the page feel like a different product. `hb-card` changes
   nothing but the click affordance: a Heartbeat card is not a link — its controls are,
   so it must not take the pointer cursor or the hover-accent border a tile gets. */
.hb-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: 14px; }
.market-card.hb-card { cursor: default; }
.market-card.hb-card:hover { border-color: var(--border); box-shadow: var(--shadow-1); }
.hb-card-id { min-width: 0; }        /* let a long skill name ellipsize, not stretch the card */
.hb-card .market-card-name { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
/* The controls sit on one line and stay put as the card grows. */
.hb-card-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; width: 100%; }
.hb-card-actions .hb-select { flex: 1; min-width: 120px; }
/* Cadence reads as the card's status line — accented only when it is actually armed. */
.hb-when { font-size: 11.5px; color: var(--text-faint); }
.hb-when.on { color: var(--accent); }

/* Ownership: who a skill is FOR, and who answers for it. Described, not enforced —
   see docs/SHARED_SKILLS_PLAN.md. */
.hb-note { font-size: 12px; color: var(--text-dim); line-height: 1.5; margin: 0 0 10px; max-width: 62ch; }
.hb-chip { display: inline-block; font-size: 10.5px; font-weight: 600; letter-spacing: 0.03em;
  padding: 1px 7px; border-radius: 999px; margin-left: 6px; vertical-align: 1px;
  border: 1px solid var(--border); color: var(--text-dim); background: var(--bg-2); }
.hb-chip.scope-company { border-color: var(--accent); color: var(--accent); }
.hb-chip.scope-team    { border-color: var(--accent-2); color: var(--accent-2); }
.hb-owner { display: block; font-size: 11.5px; color: var(--text-faint); margin-top: 5px; }
.hb-owner.you  { color: var(--accent); }
/* Shared with nobody answerable is the state worth noticing, not a neutral fact. */
.hb-owner.none { color: var(--warn); }
.hb-toggle { border: 1px solid var(--border); background: var(--bg-3); color: var(--text-dim); border-radius: 999px; padding: 3px 13px; font-size: 12px; font-weight: 600; cursor: pointer; }
.hb-toggle.on { background: var(--accent-soft); color: var(--accent); border-color: transparent; }
.hb-select { background: var(--bg-3); border: 1px solid var(--border); border-radius: 8px; color: var(--text); padding: 5px 8px; font-size: 13px; }

/* Heartbeat borrows Company → Skills' card language wholesale (`skl-*`), so the only
   rules here are the ones that page has no equivalent for: a full-width field, a run's
   report panel, and the card that owns the open panel. */
.hb-section .skl-field.wide { flex: 1 1 100%; }
.hb-textarea { font-family: inherit; line-height: 1.45; resize: vertical; min-height: 46px; }
/* The panel spans the whole grid row rather than living inside its 330px card, because a
   report is long-form reading. Its card is marked `expanded` so the two read as one
   block instead of a card and an unrelated slab under it. */
.skl-card.expanded { border-color: var(--accent); border-left-color: var(--accent); }
.hb-panel { grid-column: 1 / -1; border: 1px solid var(--accent); border-radius: 12px;
  background: var(--bg-2); padding: 14px 16px; margin-top: -4px; }
/* Run now and On/Off are actions, not settings — they sit on the fields' baseline
   rather than above one, and keep their own width instead of stretching to a column. */
.skl-card-controls > .btn-mini,
.skl-card-controls > .hb-toggle { align-self: flex-end; flex: 0 0 auto; }
.hb-panel-head { display: flex; align-items: center; gap: 10px; font-weight: 600; font-size: 13.5px; margin-bottom: 10px; }
.hb-panel-n { font-size: 11.5px; font-weight: 500; color: var(--text-faint); }
.hb-panel-head .btn-mini { margin-left: auto; }
/* History beside the report — the same shape a skill page uses, so a person who has read
   one report knows how to read them all. It stacks on a narrow screen. */
.hb-panel-body { display: grid; grid-template-columns: minmax(180px, 240px) 1fr; gap: 16px; }
.hb-runs { display: flex; flex-direction: column; gap: 2px; max-height: 340px; overflow-y: auto; }
.hb-report { max-height: 420px; overflow-y: auto; font-size: 13.5px; line-height: 1.6; }
.hb-report > :first-child { margin-top: 0; }
@media (max-width: 780px) { .hb-panel-body { grid-template-columns: 1fr; } }

/* Lean schedule popover (from Heartbeat) */
.sched-modal-overlay { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.5); display: flex; align-items: center; justify-content: center; z-index: 1000; padding: 20px; }
.sched-modal { background: var(--bg-2); border: 1px solid var(--border); border-radius: 14px; width: 100%; max-width: 430px; padding: 20px; display: flex; flex-direction: column; gap: 14px; box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4); }
.sched-modal-head { display: flex; align-items: center; }
.sched-modal-head h2 { margin: 0; font-size: 16px; }
.sched-modal-x { margin-left: auto; background: none; border: none; color: var(--text-faint); font-size: 22px; line-height: 1; cursor: pointer; }
.sched-modal-x:hover { color: var(--text); }
.sched-modal-row { display: flex; gap: 8px; flex-wrap: wrap; }
.sched-modal-foot { display: flex; justify-content: flex-end; gap: 8px; }

/* Collapsible "About this skill" — keeps a long description out of the header */
.skill-about { margin-bottom: 14px; border: 1px solid var(--border); border-radius: 10px; padding: 0 14px; }
.skill-about summary { cursor: pointer; padding: 10px 0; font-size: 13px; font-weight: 600; color: var(--text-dim); list-style: none; }
.skill-about summary::-webkit-details-marker { display: none; }
.skill-about summary::before { content: "▸  "; }
.skill-about[open] summary::before { content: "▾  "; }
.skill-about p { margin: 0 0 12px; font-size: 13px; line-height: 1.6; color: var(--text-dim); white-space: pre-wrap; }

/* Access governance matrix (admin-only) — per-user plugin + skill grants */
#org-panel-access .access-head { display: flex; flex-direction: column; gap: 6px; margin-bottom: 18px; }
.access-switch { display: flex; align-items: center; gap: 8px; font-weight: 600; cursor: pointer; }
.access-matrix { display: flex; flex-direction: column; gap: 14px; }
.access-member { border: 1px solid var(--border); border-radius: 12px; padding: 14px 16px; background: var(--bg-2); }
.access-member.is-admin { opacity: 0.75; }
.access-member-head { display: flex; align-items: center; gap: 10px; margin-bottom: 4px; }
.access-role { font-size: 12px; color: var(--text-dim); text-transform: capitalize; }
.access-member-head .access-save { margin-left: auto; }
.access-group { margin-top: 12px; }
.access-group-title { display: flex; align-items: center; gap: 10px; font-size: 13px; font-weight: 600; margin-bottom: 8px; }
.access-all { margin-left: auto; font-weight: 400; font-size: 12px; color: var(--text-dim); display: flex; align-items: center; gap: 5px; cursor: pointer; }
.access-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.access-chip { display: flex; align-items: center; gap: 6px; padding: 5px 11px; border: 1px solid var(--border); border-radius: 999px; font-size: 12px; cursor: pointer; user-select: none; }
.access-chip:hover { background: var(--bg-hover); }
.access-chip.core { opacity: 0.7; cursor: default; }
.access-core { font-size: 10px; color: var(--text-faint); border: 1px solid var(--border); border-radius: 4px; padding: 0 4px; }

/* Home: AI output (Router) cards — one card per type, listing its items as rows */
.home-router-toggle { grid-column: 1 / -1; padding: 9px 14px; border: 1px dashed var(--border); border-radius: 10px; }
.home-router-toggle .access-switch { font-weight: 500; font-size: 13px; color: var(--text-dim); }
.home-card-count { font-size: 12px; font-weight: 600; color: var(--text-dim); background: var(--bg-3); border-radius: 999px; padding: 1px 8px; margin-left: 4px; }
.home-cardlist { display: flex; flex-direction: column; }
.home-cardrow { display: flex; align-items: flex-start; gap: 8px; padding: 10px 2px; border-top: 1px solid var(--border); }
.home-cardlist .home-cardrow:first-child { border-top: none; }
.home-cardrow.clickable { cursor: pointer; border-radius: 8px; }
.home-cardrow.clickable:hover { background: var(--bg-hover); }
.home-cardrow-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.home-cardrow-title { font-weight: 600; font-size: 14px; }
.home-cardrow-preview { font-size: 13px; color: var(--text-dim); line-height: 1.4; }
.home-cardrow-x { background: none; border: none; color: var(--text-faint); font-size: 16px; line-height: 1; cursor: pointer; padding: 2px 4px; flex-shrink: 0; }
.home-cardrow-x:hover { color: var(--text); }
.tool-group { border: 1px solid var(--border); border-radius: 12px; background: var(--bg-2); overflow: hidden; }
.tool-group-head { display: flex; align-items: center; gap: 10px; padding: 10px 14px; border-bottom: 1px solid var(--border); }
.tool-group-name { font-weight: 700; font-size: 14px; }
.tool-group-count { margin-left: auto; font-size: 12px; color: var(--text-faint); flex-shrink: 0; }
.tool-badge { font-size: 11px; font-weight: 600; padding: 2px 9px; border-radius: 999px; flex-shrink: 0; }
.tool-badge.core { background: var(--accent-soft); color: var(--accent-2); }
.tool-badge.on { background: var(--ok-soft); color: var(--ok); }
.tool-badge.off { background: var(--bg-3); color: var(--text-faint); }
.tool-row { display: flex; align-items: flex-start; gap: 12px; padding: 9px 14px; border-top: 1px solid var(--border); }
.tool-row:first-child { border-top: none; }
.tool-row-main { flex: 1; min-width: 0; }
.tool-name { font-family: var(--mono); font-size: 12.5px; color: var(--accent-2); background: none; border: none; padding: 0; }
.tool-desc { font-size: 12.5px; color: var(--text-dim); margin-top: 2px; }
.tool-needs { flex-shrink: 0; font-size: 11px; color: var(--text-faint); white-space: nowrap; }
.tool-needs.core { color: var(--ok); }
.market-controls { display: flex; gap: 10px; margin-bottom: 14px; max-width: 660px; }
.market-search { flex: 1; background: var(--bg-2); border: 1px solid var(--border); color: var(--text);
  border-radius: 10px; padding: 9px 12px; font-size: 14px; font-family: inherit; outline: none; }
.market-search:focus { border-color: var(--accent); }
.market-cat { background: var(--bg-2); border: 1px solid var(--border); color: var(--text);
  border-radius: 10px; padding: 9px 12px; font-size: 14px; font-family: inherit; outline: none; }
.market-cat:focus { border-color: var(--accent); }
.market-card {
  background: var(--bg); border: 1px solid var(--border); border-radius: 12px;
  padding: 15px; display: flex; flex-direction: column; gap: 10px; cursor: pointer; transition: border-color .15s;
}
.market-card:hover { border-color: var(--accent); }
.market-card-top { display: flex; gap: 12px; align-items: flex-start; }
.market-card-icon {
  font-size: 24px; width: 44px; height: 44px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg-3); border-radius: 11px;
}
.market-card-name { font-weight: 600; font-size: 15px; }
.market-card-cat { font-size: 11.5px; color: var(--text-faint); }
.market-card-sum { font-size: 13px; color: var(--text-dim); flex: 1; }
.ext-bundle { font-size: 11.5px; color: var(--text-faint); margin: -2px 0 2px; }
.ext-price { font-size: 12px; font-weight: 600; color: var(--text-dim); }
.ext-price.free { color: #6fce8f; }
.market-card-foot { display: flex; align-items: center; justify-content: space-between; }
/* Role editor: what the ticked SKILLS already connect to. Read-only — ticking these
   below would save a derived id as explicit and the two would drift. */
.cn-role-derived:not(:empty) {
  margin: -4px 0 10px; padding: 8px 10px; border-radius: var(--radius);
  background: var(--bg-2); border: 1px solid var(--border);
}
.cn-role-derived p { margin: 0; }

/* Addon policy: what allowing these skills ALSO permits. Approval without disclosure
   is not consent, so this sits next to the list being edited, not in a doc. */
.pol-implied {
  margin: 10px 0 4px; padding: 10px 12px; border-radius: var(--radius); font-size: 12.5px;
  line-height: 1.55; background: var(--bg-2); border: 1px solid var(--border);
}
.pol-imp-head { color: var(--text); margin-bottom: 6px; }
.pol-imp-row { color: var(--text-dim); padding: 2px 0; }
.pol-imp-row code { font-size: 11.5px; color: var(--text-faint); }
.pol-imp-foot { margin-top: 8px; color: var(--text-faint); font-size: 11.5px; }

/* Connections page: what depends on this connection. The reason the page exists — a
   connector that has stopped working otherwise says nothing about what stopped with it. */
.conn-usedby { font-size: 12.5px; color: var(--text-dim); flex: 1; line-height: 1.5; }
.conn-usedby.muted { color: var(--text-faint); }
.conn-advanced { margin-top: 22px; border-top: 1px solid var(--border); padding-top: 14px; }
.conn-advanced > summary {
  cursor: pointer; font-size: 13px; color: var(--text-dim); user-select: none; padding: 4px 0;
}
.conn-advanced > summary:hover { color: var(--text); }
.conn-advanced .hint { margin: 6px 0 12px; }
.cap-status {
  font-size: 11.5px; padding: 3px 9px; border-radius: 20px; border: 1px solid var(--border); color: var(--text-faint);
}
.cap-status.linked { color: var(--ok); border-color: rgba(84,201,138,.4); background: rgba(84,201,138,.1); }
/* Connected, but the member's role doesn't include it — the AI gets no tools for it. */
.cap-status.blocked {
  color: var(--warn); background: color-mix(in srgb, var(--warn) 12%, transparent);
  border-color: color-mix(in srgb, var(--warn) 40%, transparent);
}
.cap-role-warn {
  margin: 10px 0 4px; padding: 10px 12px; border-radius: var(--radius); font-size: 12.5px;
  line-height: 1.55; color: var(--text);
  background: color-mix(in srgb, var(--warn) 10%, var(--bg-2));
  border: 1px solid color-mix(in srgb, var(--warn) 38%, var(--border));
}
.cap-status.installed { color: var(--accent-2); border-color: rgba(154,140,255,.4); background: var(--accent-soft); }
.cap-status.disabled { color: #e0a458; border-color: rgba(224,164,88,.4); background: rgba(224,164,88,.1); }
.cap-status.warn { color: #e0a458; border-color: rgba(224,164,88,.4); background: rgba(224,164,88,.1); }
.market-card-action { font-size: 12.5px; color: var(--accent-2); font-weight: 600; cursor: pointer; }
.market-card-action:hover { text-decoration: underline; }

/* Roles tab: admin staffing (AI teammate / person) */
.role-seats { font-size: 12px; color: var(--text-faint); margin: 0 0 12px; }
.role-skills { font-size: 11.5px; color: var(--text-faint); min-height: 1em; }
.role-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.role-actions .btn-primary { padding: 7px 14px; font-size: 12.5px; }
.role-actions .btn-mini { padding: 6px 12px; font-size: 12.5px; height: auto; line-height: 1.9; }
.role-actions .recruit-btn { margin-left: auto; }
.role-note { font-size: 12.5px; color: var(--text-dim); display: flex; align-items: center; gap: 8px; }
.role-note.err { color: var(--danger); }
.role-spin {
  width: 14px; height: 14px; flex-shrink: 0; border-radius: 50%;
  border: 2px solid var(--border); border-top-color: var(--accent);
  animation: role-spin .7s linear infinite;
}
@keyframes role-spin { to { transform: rotate(360deg); } }
.role-person-form { display: flex; flex-direction: column; gap: 8px; border-top: 1px solid var(--border); padding-top: 10px; }
.role-person-form .cn-input { margin: 0; }
.role-person-form .cn-label { margin-top: 2px; }
.role-result { margin-top: 4px; }

/* capability detail modal */
.cap-head { display: flex; gap: 14px; align-items: center; }
.cap-head-icon { display: flex; flex-shrink: 0; }
.cap-head-tile { --ico-sz: 52px; }

/* ---- the detail-page head, shared by #view-capability and #view-skill ----
   A page, not a dialog: back, then the thing at full size, what it can do, and — for a
   connection, only once it is installed — where you set it up. Both pages use it so that
   arriving from either list lands on the same shape. */
.lib-back {
  display: inline-flex; align-items: center; gap: 6px; margin-bottom: 14px;
  padding: 6px 12px 6px 8px; border: 1px solid var(--border); border-radius: 999px;
  background: var(--bg-2); color: var(--text-dim); font: inherit; font-size: 13px;
}
.lib-back:hover { background: var(--bg-hover); color: var(--text); }
.lib-back svg { width: 15px; height: 15px; }

/* Top-aligned, not centred: the description runs to three lines on some skills, and a
   centred tile then floats halfway down the paragraph instead of sitting by the name. */
.cap-page-head { display: flex; align-items: flex-start; gap: 16px; padding-bottom: 16px; }
.cap-page-head .cap-head-icon { margin-top: 2px; }
.cap-page-head .cap-head-act { align-self: center; }
.cap-head-main { min-width: 0; }
.cap-head-main h1 { margin: 0; font-size: 26px; font-weight: 600; letter-spacing: -0.01em; }
.cap-sub { display: block; margin-top: 4px; font-size: 12.5px; color: var(--text-faint); }
.cap-head-act { margin-left: auto; display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.cap-state { display: inline-flex; align-items: center; }
/* The skill page's one control while the skill is not yours yet. */
.skill-head-act { margin-left: auto; display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.skill-head-act .btn-primary { padding: 9px 22px; font-size: 14px; border-radius: 999px; }
.cap-head-act .btn-primary { padding: 9px 22px; font-size: 14px; border-radius: 999px; }

#view-capability .cap-desc { max-width: 70ch; margin: 0 0 22px; }
#view-capability .cap-section { margin-bottom: 22px; }
/* The setup box is the one part that is a FORM, so it gets a surface of its own. */
.cap-setup {
  padding: 16px 18px; border: 1px solid var(--border); border-radius: 14px;
  background: var(--bg-1);
}
.cap-setup-foot { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.cap-page-foot {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  margin-top: 26px; padding-top: 16px; border-top: 1px solid var(--border);
}
.cap-page-foot .btn-ghost-danger { margin-left: auto; }
#view-capability .privacy-note { margin: 14px 0 0; }
.cap-desc { color: var(--text-dim); font-size: 13.5px; line-height: 1.65; margin: 0; }
.cap-section { display: flex; flex-direction: column; gap: 8px; }
.cap-section-title { font-size: 12px; font-weight: 600; color: var(--text-dim); text-transform: uppercase; letter-spacing: .03em; }
.cap-perms { display: flex; flex-wrap: wrap; gap: 7px; }
.cap-perm { font-size: 12px; background: var(--bg-3); border: 1px solid var(--border); border-radius: 8px; padding: 5px 10px; color: var(--text-dim); }
.cap-perm::before { content: "🔑 "; }
/* What the plugin gives the AI — one standard row per tool, ruled like a list rather
   than run together as prose. Built by capToolRows(); the connector's tools and the
   Agent Organization's both come through here. */
.cap-tools { display: flex; flex-direction: column; }
.cap-tool {
  display: grid; grid-template-columns: 30px minmax(0, 1fr); align-items: center; gap: 12px;
  padding: 9px 2px; border-bottom: 1px solid var(--border);
}
.cap-tool:last-child { border-bottom: 0; }
.cap-tool-ico {
  width: 30px; height: 30px; display: flex; align-items: center; justify-content: center;
  color: var(--text-faint);
  background: var(--bg-3); border: 1px solid var(--border); border-radius: 8px;
}
.cap-tool-ico .ico { width: 15px; height: 15px; }
.cap-tool-main { min-width: 0; }
.cap-tool-name {
  font-family: var(--mono); font-size: 12.5px; font-weight: 600; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cap-tool-desc {
  margin-top: 1px; font-size: 12px; color: var(--text-faint);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cap-field { display: flex; flex-direction: column; gap: 5px; margin-bottom: 12px; }
.cap-field > label { font-size: 12.5px; color: var(--text-dim); font-weight: 600; }
.cap-field .cap-help { font-size: 11.5px; color: var(--text-faint); }
.cap-field-check { flex-direction: row; align-items: center; gap: 8px; }
.cap-field input.set::placeholder { color: var(--ok); }
.cap-test { font-size: 13px; border-radius: 8px; padding: 9px 12px; }
.cap-test.ok { background: rgba(84,201,138,.1); border: 1px solid rgba(84,201,138,.4); color: #9be9bd; }
.cap-test.err { background: rgba(240,96,106,.1); border: 1px solid rgba(240,96,106,.35); color: #ffb3b8; }
.cap-help.warn { color: #ffb088; }
/* "this connector runs on another one's connection" — sits above the empty boxes, so
   they read as inherited rather than as unfinished setup. */
.cap-inherit {
  font-size: 13px; line-height: 1.5; border-radius: 8px; padding: 9px 12px;
  background: rgba(84,201,138,.08); border: 1px solid rgba(84,201,138,.32);
  color: var(--text-2, inherit);
}
.cap-inherit strong { color: var(--ok); }

/* oauth device-code flow */
.cap-oauth { display: flex; flex-direction: column; gap: 10px; }
.cap-oauth-status { font-size: 13.5px; padding: 9px 12px; border-radius: 9px; }
.cap-oauth-status.ok { background: rgba(84,201,138,.1); border: 1px solid rgba(84,201,138,.4); color: #9be9bd; }
.cap-oauth-flow { background: var(--bg); border: 1px solid var(--border); border-radius: 10px; padding: 13px 15px; display: flex; flex-direction: column; gap: 8px; }
.cap-oauth-flow p { margin: 0; font-size: 13.5px; }
.cap-oauth-flow a { color: var(--accent-2); }
.oauth-code { font-family: var(--mono); font-size: 19px; letter-spacing: 2px; background: var(--bg-3); border: 1px solid var(--border); border-radius: 8px; padding: 6px 12px; color: var(--accent-2); display: inline-block; }
.oauth-spin { color: var(--text-faint); }
.cap-oauth-row { display: flex; gap: 10px; align-items: center; }
/* Curated MCP directory (one-click server gallery) */
.mcp-dir-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 10px; margin: 8px 0 4px; }
.mcp-dir-card { background: var(--bg); border: 1px solid var(--border); border-radius: 10px; padding: 11px 12px; display: flex; flex-direction: column; gap: 6px; }
.mcp-dir-head { display: flex; align-items: center; gap: 7px; }
.mcp-dir-icon { font-size: 16px; }
.mcp-dir-head code { font-family: var(--mono); color: var(--accent-2); font-size: 13px; }
.mcp-dir-summary { flex: 1; }
.mcp-dir-actions { display: flex; align-items: center; }
.mcp-dir-form { display: flex; flex-direction: column; gap: 6px; border-top: 1px solid var(--border); padding-top: 8px; }
.cap-advanced { margin-top: 6px; }
.cap-advanced > summary { cursor: pointer; font-size: 12.5px; color: var(--text-dim); padding: 4px 0; }
.wa-qr { width: 240px; height: 240px; align-self: center; background: #fff; border-radius: 12px; padding: 10px; }
.cap-foot { justify-content: space-between; align-items: center; }
.cap-foot-right { display: flex; align-items: center; gap: 10px; }
.enable-toggle { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text-dim); cursor: pointer; }
.enable-toggle input { accent-color: var(--accent); width: 16px; height: 16px; }
.btn-ghost-danger { background: none; border: 1px solid rgba(240,96,106,.4); color: var(--danger); border-radius: 10px; padding: 9px 14px; font-size: 13px; }
.btn-ghost-danger:hover { background: rgba(240,96,106,.12); }

/* toast */
#toast {
  position: fixed; bottom: 22px; left: 50%; transform: translateX(-50%);
  background: var(--bg-3); border: 1px solid var(--border); color: var(--text);
  padding: 11px 18px; border-radius: 10px; font-size: 13.5px; z-index: 100;
  opacity: 0; transition: opacity .2s, transform .2s; pointer-events: none;
}
#toast.show { opacity: 1; transform: translateX(-50%) translateY(-4px); }
#toast.err { border-color: var(--danger); color: #ffb3b8; }

/* ===== App shell: ChatGPT-style sidebar + views ===== */
.side-nav { display: flex; flex-direction: column; gap: 1px; }
.side-item {
  display: flex; align-items: center; gap: 12px;
  width: 100%; text-align: left; background: none; border: none; cursor: pointer;
  color: var(--text); font-size: 14px; font-weight: 500; padding: 8px 10px; border-radius: 8px;
}
.side-item:hover { background: var(--bg-hover); }
.side-item.active { background: var(--bg-3); }
/* Monochrome icons: grayscale removes emoji colour; SVGs inherit currentColor. */
.side-item .si-ico {
  width: 20px; height: 18px; flex-shrink: 0; filter: grayscale(1);
  display: inline-flex; align-items: center; justify-content: center; font-size: 15px; opacity: .82;
}
.side-item .si-ico svg { width: 17px; height: 17px; display: block; }
.side-item:hover .si-ico, .side-item.active .si-ico { opacity: 1; }

/* Group Chat participants panel */
.gc-people { display: flex; flex-wrap: wrap; gap: 8px; padding: 10px 16px; border-bottom: 1px solid var(--border); }
.gc-person { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; color: var(--text-dim); background: var(--bg-3); border-radius: 8px; padding: 3px 9px; }
.gc-tag { font-size: 9px; font-weight: 700; background: var(--accent-soft); color: var(--accent-2); border-radius: 5px; padding: 0 5px; text-transform: uppercase; }
.side-item-dim { color: var(--text-faint); font-size: 13px; }
.side-item-kbd {
  margin-left: auto; font-size: 10.5px; color: var(--text-faint); font-weight: 600;
  background: var(--bg-3); border: 1px solid var(--border); border-radius: 5px; padding: 1px 6px;
}
.nav-badge {
  margin-left: auto; background: var(--danger); color: #fff; font-size: 10px; font-weight: 700;
  border-radius: 9px; padding: 1px 6px; min-width: 16px; text-align: center; line-height: 15px;
}

.side-section { display: flex; flex-direction: column; gap: 2px; margin-top: 8px; }
.side-section-title { font-size: 10.5px; text-transform: uppercase; letter-spacing: .06em; color: var(--text-faint); padding: 6px 10px 3px; font-weight: 600; }
.side-section-title.recents-title { display: flex; align-items: center; justify-content: space-between; padding-right: 6px; }
.recents-search-btn { background: none; border: none; color: var(--text-faint); cursor: pointer;
  padding: 3px; border-radius: 5px; display: inline-flex; align-items: center; }
.recents-search-btn:hover { color: var(--text); background: var(--bg-hover); }
.recents-search-btn svg { width: 14px; height: 14px; }

/* ---- Group Chat view ---- */
.gc-body { display: grid; grid-template-columns: 280px minmax(0, 1fr); gap: 14px; height: calc(100vh - 210px); min-height: 380px; }
.gc-list { display: flex; flex-direction: column; gap: 7px; overflow-y: auto; padding-right: 2px; }
.gc-item { display: flex; align-items: center; gap: 10px; text-align: left; width: 100%; background: var(--bg-2); border: 1px solid var(--border); border-radius: 10px; padding: 9px 11px; cursor: pointer; color: var(--text); font: inherit; }
.gc-item:hover { border-color: var(--accent); }
.gc-item.active { border-color: var(--accent); background: var(--accent-soft); }
.gc-item-ava { flex: 0 0 auto; width: 34px; height: 34px; border-radius: 9px; background: var(--bg-3); display: inline-flex; align-items: center; justify-content: center; font-size: 16px; }
.gc-item-main { display: flex; flex-direction: column; min-width: 0; flex: 1; gap: 2px; }
.gc-item-top { display: flex; align-items: center; gap: 6px; }
.gc-item-name { font-weight: 600; font-size: 13.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gc-item-sub { font-size: 11.5px; color: var(--text-faint); }
.gc-unread { width: 8px; height: 8px; border-radius: 50%; background: var(--danger); box-shadow: 0 0 6px var(--danger); }
.gc-newbtn { width: 100%; text-align: left; background: var(--bg-2); border: 1px solid var(--border); border-radius: 10px; padding: 9px 12px; color: var(--text); font: inherit; font-weight: 600; cursor: pointer; }
.gc-newbtn:hover { border-color: var(--accent); background: var(--bg-3); }
.gc-sec { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--text-faint); margin: 10px 4px 2px; }
.gc-pick { display: flex; flex-direction: column; gap: 2px; max-height: 320px; overflow-y: auto; margin-bottom: 6px; }
.gc-pick-row { display: flex; align-items: center; gap: 10px; padding: 7px 6px; border-radius: 8px; cursor: pointer; }
.gc-pick-row:hover { background: var(--bg-hover); }
.gc-pick-row > span { display: inline-flex; align-items: center; gap: 8px; font-size: 13.5px; }
.gc-pick-row .cn-ppl-avatar { width: 26px; height: 26px; font-size: 11px; border-radius: 7px; }
/* Group chat is now its own view — the composer no longer has a mode dropdown. */
#mode-drop { display: none; }
/* Group-chat private AI copilot: suggestions + auto-send toggle + assist tag */
.gc-head-actions { display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
.gc-cop-toggle { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-dim); cursor: pointer; white-space: nowrap; }
.gc-cop-toggle input { accent-color: var(--accent); }
.gc-suggest { display: flex; flex-direction: column; gap: 8px; padding: 8px 16px 0; }
.gc-suggest:empty { display: none; }
.gc-sug { border: 1px solid var(--border); border-radius: 12px; padding: 10px 12px; background: var(--bg); }
.gc-sug-reply { border-color: var(--accent); background: var(--accent-soft); }
.gc-sug-h { font-size: 12px; font-weight: 700; color: var(--text-dim); display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.gc-sug-conf { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; border-radius: 6px; padding: 1px 6px; background: var(--bg-3); color: var(--text-faint); }
.gc-sug-conf.high { background: rgba(31,157,85,.18); color: var(--ok, #1f9d55); }
.gc-sug-private { font-size: 10px; font-weight: 600; color: var(--text-faint); background: var(--bg-3); border-radius: 6px; padding: 1px 6px; }
.gc-sug-text { width: 100%; resize: vertical; min-height: 54px; background: var(--bg-2); border: 1px solid var(--border); border-radius: 8px; padding: 8px 10px; color: var(--text); font: inherit; font-size: 13.5px; line-height: 1.5; }
.gc-sug-body { font-size: 13.5px; color: var(--text); line-height: 1.5; }
.gc-sug-act { display: flex; gap: 8px; margin-top: 8px; }
.cn-assist-badge { font-size: 11px; opacity: .9; }

/* ===== Group Chat — full-bleed 3-column WhatsApp hub (rail | chat | Your AI) ===== */
.gc-hub { flex: 1; min-height: 0; display: grid; grid-template-columns: 280px minmax(0, 1fr) 460px; background: var(--bg); position: relative; }
.gc-rail { border-right: 1px solid var(--border); background: var(--bg-2); display: flex; flex-direction: column; min-height: 0; }
.gc-rail-head { display: flex; align-items: center; gap: 8px; padding: 14px 12px 10px; border-bottom: 1px solid var(--border); }
.gc-rail-head .cn-icon-btn svg { width: 18px; height: 18px; }
.gc-rail-title { font-weight: 700; font-size: 15px; flex: 1; }
/* Search the rail. Notifications and sound used to sit here as a permanent row; they
   are in the head's ⋯ menu now (gcOpenRailMenu), and this is what a chat rail actually
   needs above its list. */
.gc-rail-search { position: relative; padding: 10px 12px; border-bottom: 1px solid var(--border); }
.gc-rail-search .lib-search-ico { left: 24px; }
.gc-rail-search .lib-search { height: 34px; font-size: 13px; background: var(--bg); }

/* The in-app popup: the channel that always works — no permission, no OS, no service
   worker. Bottom-right, one card per room, click to open it. */
.gc-notices { position: fixed; right: 18px; bottom: 18px; z-index: 4000;
  display: flex; flex-direction: column; gap: 8px; max-width: 340px; }
.gc-notice { display: flex; align-items: flex-start; gap: 10px; cursor: pointer;
  padding: 11px 12px; border-radius: 12px; border: 1px solid var(--accent);
  background: var(--bg-2); box-shadow: var(--shadow-2, 0 8px 28px rgba(0,0,0,.35));
  animation: gc-notice-in .22s ease-out; }
.gc-notice:hover { background: var(--bg-hover); }
.gc-notice-ico { font-size: 15px; line-height: 1.3; flex: 0 0 auto; }
.gc-notice-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.gc-notice-top { font-size: 12px; color: var(--text-dim); overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.gc-notice-top b { color: var(--text); }
.gc-notice-tx { font-size: 12.5px; color: var(--text); line-height: 1.45;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.gc-notice-x { flex: 0 0 auto; border: none; background: none; color: var(--text-faint);
  cursor: pointer; font-size: 12px; padding: 0 2px; }
.gc-notice-x:hover { color: var(--text); }
@keyframes gc-notice-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

.gc-rail-list { flex: 1; min-height: 0; overflow-y: auto; padding: 10px; display: flex; flex-direction: column; gap: 4px; }
/* middle: the chat */
.gc-main { display: flex; flex-direction: column; min-width: 0; min-height: 0; background: var(--bg); }
.gc-main-head { display: flex; align-items: center; gap: 12px; padding: 11px 18px; border-bottom: 1px solid var(--border); cursor: pointer; background: var(--bg-2); }
.gc-main-head:hover { background: var(--bg-3); }
.gc-head-ava { width: 40px; height: 40px; border-radius: 12px; background: var(--bg-3); display: inline-flex; align-items: center; justify-content: center; font-size: 19px; flex-shrink: 0; }
.gc-head-text { flex: 1; min-width: 0; }
.gc-head-name { font-weight: 700; font-size: 15px; }
.gc-head-sub { font-size: 12px; color: var(--text-faint); margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Each participant carries its own presence dot. The comma is drawn by CSS so the
   dot never ends up on the wrong side of it. */
.gc-head-mem { display: inline-flex; align-items: center; gap: 4px; }
.gc-head-mem + .gc-head-mem::before { content: ", "; margin-right: 4px; color: var(--text-faint); }
.gc-head-mem .cn-presence { width: 7px; height: 7px; }
.gc-head-chev { color: var(--text-faint); font-size: 22px; flex-shrink: 0; }
.gc-thread { flex: 1; min-height: 0; overflow-y: auto; padding: 18px 22px; display: flex; flex-direction: column; gap: 10px; }
.gc-composer { display: flex; gap: 8px; padding: 12px 18px 16px; border-top: 1px solid var(--border); align-items: center; }
.gc-composer .cn-input { margin: 0; flex: 1; border-radius: 22px; padding: 11px 16px; }
.gc-comp-btn { flex-shrink: 0; width: 38px; height: 38px; border: none; background: none; border-radius: 50%; cursor: pointer; display: flex; align-items: center; justify-content: center; color: var(--text-dim); }
.gc-comp-btn svg { width: 20px; height: 20px; }
.gc-comp-btn:hover { background: var(--bg-hover); color: var(--text); }
/* emoji picker */
.gc-emoji-panel { display: flex; flex-wrap: wrap; gap: 2px; padding: 8px 14px; max-height: 180px; overflow-y: auto; border-top: 1px solid var(--border); background: var(--bg-2); }
.gc-emoji { border: none; background: none; font-size: 20px; line-height: 1; padding: 5px; border-radius: 8px; cursor: pointer; }
.gc-emoji:hover { background: var(--bg-hover); }
/* attachment preview before sending */
.gc-att-preview { display: flex; align-items: center; gap: 10px; padding: 8px 16px; border-top: 1px solid var(--border); background: var(--bg-2); }
.gc-att-thumb { width: 40px; height: 40px; object-fit: cover; border-radius: 8px; flex-shrink: 0; }
.gc-att-preview .gc-att-ico { font-size: 24px; flex-shrink: 0; }
.gc-att-pname { flex: 1; min-width: 0; font-size: 13px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gc-att-x { flex-shrink: 0; border: none; background: var(--bg-3); color: var(--text-dim); width: 24px; height: 24px; border-radius: 50%; cursor: pointer; font-size: 12px; }
.gc-att-x:hover { color: var(--text); }
/* attachment inside a message bubble */
.gc-att-imgwrap { display: block; margin: 2px 0 4px; }
.gc-att-img { max-width: min(280px, 100%); max-height: 340px; width: auto; height: auto; border-radius: 12px; display: block; }
.gc-att-file { display: flex; align-items: center; gap: 9px; margin: 2px 0 4px; padding: 8px 10px; border: 1px solid var(--border); border-radius: 10px; background: var(--bg-2); text-decoration: none; color: var(--text); max-width: 280px; }
.gc-att-file:hover { border-color: var(--accent); }
.gc-att-file .gc-att-ico { font-size: 20px; flex-shrink: 0; }
.gc-att-file .gc-att-meta { display: flex; flex-direction: column; min-width: 0; }
.gc-att-name { font-size: 12.5px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gc-att-sub { font-size: 11px; color: var(--text-faint); }
/* "Editing message" bar above the composer (shown while editing your own message) */
.gc-editbar { display: flex; align-items: center; gap: 9px; padding: 9px 18px; border-top: 1px solid var(--border);
  background: color-mix(in srgb, var(--accent) 12%, var(--bg-2)); font-size: 12.5px; }
.gc-editbar-i { color: var(--accent); font-size: 13px; }
.gc-editbar-t { flex: 1; font-weight: 600; color: var(--text); }
.gc-editbar-x { border: none; background: none; color: var(--text-dim); cursor: pointer; font-size: 14px; line-height: 1; padding: 3px 7px; border-radius: 7px; }
.gc-editbar-x:hover { background: var(--bg-hover); color: var(--text); }
.gc-composer .btn-send { flex: 0 0 auto; width: 42px; height: 42px; border-radius: 50%; border: none; background: var(--accent); color: #fff; font-size: 15px; cursor: pointer; }
.gc-composer .btn-send:hover { filter: brightness(1.08); }
.gc-empty-main { flex: 1; display: flex; align-items: center; justify-content: center; color: var(--text-faint); font-size: 14px; padding: 40px; text-align: center; }
/* right: Your AI panel — modern copilot chat */
.gc-ai { border-left: 1px solid var(--border); background: linear-gradient(180deg, var(--bg-2), var(--bg)); display: flex; flex-direction: column; justify-content: flex-start; align-items: stretch; min-height: 0; padding: 16px 14px 14px; }
.gc-ai-center { display: flex; flex-direction: column; align-items: center; width: 100%; min-height: 0; max-height: 100%; }
/* The Inbox panel's head, exactly: a small mark, the name, and the line that says what
   it is doing. It was a centred hero — eyebrow, 104px mark, caption — which spent the
   top third of the column saying "Your AI" to someone already looking at Your AI, and
   made the two panels read as two different features. */
.gc-ai-head {
  display: flex; flex-direction: row; align-items: center; gap: 10px; flex-shrink: 0;
  padding-bottom: 12px; border-bottom: 1px solid var(--border);
}
.gc-ai-id { min-width: 0; }
.gc-ai-head .gc-ai-logo { width: 38px; height: 38px; }
.gc-ai-head .gc-ai-logo svg { width: 30px; height: 30px; }
/* The big mark still exists — in the empty body, which is the one place there is room
   for it and the one time it is the thing to look at. */
.gc-ai-body .ibx-ai-empty .gc-ai-logo { width: 132px; height: 132px; }
.gc-ai-body .ibx-ai-empty .gc-ai-logo svg { width: 96px; height: 96px; }
.gc-ai-tip { font-size: 11.5px; color: var(--text-faint); text-align: center; max-width: 240px; margin: 10px auto 0; line-height: 1.5; }
.gc-ai-tip b { color: var(--accent-2); font-weight: 700; }
.gc-ai-hero { padding: 18px 16px 8px; display: flex; flex-direction: column; align-items: center; }
.gc-ai-eyebrow { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .1em; color: var(--text-faint); margin-bottom: 6px; }
.gc-ai-logo { position: relative; width: 104px; height: 104px; display: grid; place-items: center; }
.gc-ai-logo::before { content: ""; position: absolute; inset: 12px; border-radius: 50%; background: radial-gradient(circle, color-mix(in srgb, var(--accent) 55%, transparent), transparent 70%); filter: blur(12px); animation: gc-glow 4.5s ease-in-out infinite; }
.gc-ai-logo.thinking::before { animation-duration: 1.6s; }
.gc-ai-logo svg { position: relative; width: 76px; height: 76px; display: block; color: var(--accent); }
/* new-chat hero: the spinning logo, larger, no wordmark */
.empty-hero-logo { width: 150px; height: 150px; margin: 0 auto; }
.empty-hero-logo svg { width: 108px; height: 108px; }
.gc-ai-status { text-align: center; font-size: 12.5px; color: var(--text-dim); margin-top: 10px; min-height: 16px; }
.gc-ai-feed { width: 100%; flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 10px 2px 0; margin-top: 10px; display: flex; flex-direction: column; gap: 10px; }
/* ===== AI threads panel (server-side jobs as status cards) ================== */
.gc-ai-body { width: 100%; flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 14px 2px 6px; }
.gc-th-empty { color: var(--text-faint); font-size: 12.5px; line-height: 1.5; text-align: center; padding: 24px 10px; }
.gc-th-loading { display: flex; justify-content: center; padding: 26px 0; }
.gc-th-list { display: flex; flex-direction: column; gap: 8px; }
.gc-th-card { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left; border: 1px solid var(--border);
  background: var(--bg-2); border-radius: 12px; padding: 11px 12px; cursor: pointer; transition: border-color .12s, background .12s; }
.gc-th-card:hover { border-color: var(--accent); background: var(--accent-soft); }
.gc-th-card.waiting { border-color: color-mix(in srgb, var(--accent) 55%, var(--border)); }
/* the card body opens the thread; the mini buttons beside it stop / dismiss it */
.gc-th-open { flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; border: none; background: none;
  padding: 0; text-align: left; cursor: pointer; font: inherit; color: inherit; }
.gc-th-mini { flex-shrink: 0; width: 22px; height: 22px; display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--border); background: var(--bg-3); color: var(--text-faint); border-radius: 7px;
  font-size: 10px; line-height: 1; cursor: pointer; transition: color .12s, border-color .12s; }
.gc-th-mini:hover { color: var(--danger, #e03131); border-color: var(--danger, #e03131); }
.gc-th-mini.stop:hover { color: var(--text); border-color: var(--accent); }
.gc-th-title { flex: 1; min-width: 0; font-size: 13px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gc-th-badge { flex-shrink: 0; font-size: 10px; font-weight: 700; padding: 2px 8px; border-radius: 999px; background: var(--bg-3); color: var(--text-dim); white-space: nowrap; }
.gc-th-badge.thinking { background: var(--accent-soft); color: var(--accent-2); }
.gc-th-badge.waiting { background: rgba(224,168,0,.18); color: #e0a800; }
.gc-th-badge.complete { background: rgba(31,157,85,.18); color: var(--ok, #1f9d55); }
.gc-th-badge.error { background: rgba(224,49,49,.16); color: var(--danger, #e03131); }
.gc-th-badge.stopped { background: var(--bg-3); color: var(--text-faint); }
.gc-th-badge.sent { background: rgba(31,157,85,.14); color: var(--ok, #1f9d55); }
/* thread detail */
.gc-th-detail { display: flex; flex-direction: column; gap: 10px; }
.gc-th-dhead { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.gc-th-back { border: none; background: none; color: var(--accent-2); font-size: 13px; font-weight: 600; cursor: pointer; padding: 2px 2px; }
.gc-th-back:hover { text-decoration: underline; }
.gc-th-dtitle { font-size: 14px; font-weight: 700; color: var(--text); line-height: 1.35; }
.gc-th-steps { display: flex; flex-direction: column; gap: 5px; }
.gc-th-step { font-size: 11.5px; color: var(--text-dim); font-family: var(--mono); }
.gc-th-result.msg-content { background: var(--bg-3); border: 1px solid var(--border); border-radius: 12px; padding: 10px 12px; font-size: 13px; }
.gc-th-working { display: inline-flex; align-items: center; gap: 8px; color: var(--accent-2); font-size: 12.5px; font-weight: 600; }
.gc-th-err { color: var(--danger, #e03131); font-size: 12.5px; }
.gc-th-actions { display: flex; flex-direction: column; gap: 6px; margin-top: 2px; }
.gc-th-actions .gcx-choice, .gc-th-actions .gcx-a-send, .gc-th-actions .gcx-a-copy, .gc-th-actions .gcx-a-dismiss,
.gc-th-actions .gcx-a-stop {
  border: 1px solid var(--border); background: var(--bg-2); color: var(--text); border-radius: 9px; padding: 8px 11px;
  font-size: 12.5px; font-weight: 600; cursor: pointer; text-align: left; }
.gc-th-actions .gcx-choice:hover { border-color: var(--accent); background: var(--accent-soft); }
.gc-th-actions .gcx-a-stop:hover { border-color: var(--danger, #e03131); color: var(--danger, #e03131); }
.gc-th-actions .gcx-a-send.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.gc-th-actions .gcx-a-send.primary:hover { filter: brightness(1.08); }
/* "Other" — type a custom instruction */
.gc-th-other-wrap { margin-top: 2px; }
.gcx-a-other { width: 100%; border: 1px dashed var(--border); background: transparent; color: var(--text-dim);
  border-radius: 9px; padding: 8px 11px; font-size: 12.5px; font-weight: 600; cursor: pointer; text-align: left; }
.gcx-a-other:hover { border-style: solid; border-color: var(--accent); color: var(--text); }
.gc-th-other { display: flex; gap: 6px; }
.gc-th-other-input { flex: 1; min-width: 0; background: var(--bg-2); border: 1px solid var(--border); border-radius: 9px;
  padding: 8px 11px; color: var(--text); font: inherit; font-size: 12.5px; outline: none; }
.gc-th-other-input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.gc-th-other-go { flex-shrink: 0; border: none; background: var(--accent); color: #fff; border-radius: 9px;
  padding: 8px 14px; font-size: 12.5px; font-weight: 700; cursor: pointer; }
.gc-th-other-go:hover { filter: brightness(1.08); }
/* footer: quick-action chips + a pinned "Ask your AI" input */
/* Matches .ibx-ai-act: the things you can do, under what it has to say, divided by one
   line. Left-aligned like the rest of the panel — centred chips read as a landing page. */
.gc-ai-foot { flex-shrink: 0; padding-top: 12px; margin-top: 10px; border-top: 1px solid var(--border); }
.gc-ai-chips { display: flex; flex-wrap: wrap; gap: 6px; justify-content: flex-start; margin-bottom: 9px; }
.gc-chip { border: 1px solid var(--border); background: var(--bg-2); color: var(--text-dim); border-radius: 999px; padding: 5px 12px; font-size: 12px; font-weight: 600; cursor: pointer; transition: all .12s; }
.gc-chip:hover { border-color: var(--accent); color: var(--text); background: var(--accent-soft); }
.gc-ai-ask { display: flex; align-items: center; gap: 8px; }
.gc-ai-askinput { flex: 1; min-width: 0; background: var(--bg-2); border: 1px solid var(--border); border-radius: 20px; padding: 9px 14px; color: var(--text); font: inherit; font-size: 13px; outline: none; transition: border-color .12s, box-shadow .12s; }
.gc-ai-askinput:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.gc-ai-asksend { flex-shrink: 0; width: 36px; height: 36px; border: none; border-radius: 50%; background: var(--accent); color: #fff; font-size: 14px; cursor: pointer; display: flex; align-items: center; justify-content: center; }
.gc-ai-asksend:hover { filter: brightness(1.08); }
/* generated-file download card inside an AI feed item */
.gcx-file { display: flex; align-items: center; gap: 9px; margin-top: 8px; padding: 8px 10px; border: 1px solid var(--border); border-radius: 10px; background: var(--bg-2); text-decoration: none; color: var(--text); transition: border-color .12s, background .12s; }
.gcx-file:hover { border-color: var(--accent); background: var(--accent-soft); }
.gcx-file-ico { font-size: 18px; flex-shrink: 0; }
.gcx-file-meta { display: flex; flex-direction: column; min-width: 0; }
.gcx-file-name { font-size: 12.5px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gcx-file-sub { font-size: 11px; color: var(--text-faint); }
/* footer is tap-only (no typing) */
.gc-ai-foot-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.gc-ai-foot-label { font-size: 10.5px; color: var(--text-faint); }
.gc-ai-depth { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; color: var(--text-dim); cursor: pointer; user-select: none; }
.gc-ai-depth input { accent-color: var(--accent); cursor: pointer; }
/* AI clarification rendered as tap-choices */
.gcx-choices { margin-top: 9px; display: flex; flex-direction: column; gap: 6px; }
.gcx-choices-h { font-size: 11px; font-weight: 700; color: var(--text-faint); }
.gcx-choice { text-align: left; border: 1px solid var(--border); background: var(--bg-2); color: var(--text); border-radius: 10px; padding: 8px 11px; font-size: 12.5px; font-weight: 600; cursor: pointer; transition: border-color .12s, background .12s; }
.gcx-choice:hover { border-color: var(--accent); background: var(--accent-soft); }
/* proactive "suggested reply" draft card */
.gcx-conf.go { background: var(--accent-soft); color: var(--accent-2); }
.gcx-draft .gcx-body { border: 1px solid color-mix(in srgb, var(--accent) 42%, var(--border)); }
.gcx-a-send.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.gcx-a-send.primary:hover { filter: brightness(1.08); }
/* small "or:" select-only menu of other things the AI can do */
.gcx-more { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 8px; }
.gcx-more-lbl { font-size: 11px; color: var(--text-faint); }
.gcx-m { border: 1px dashed var(--border); background: transparent; color: var(--text-dim); border-radius: 999px; padding: 3px 10px; font-size: 11.5px; cursor: pointer; }
.gcx-m:hover { border-style: solid; border-color: var(--accent); color: var(--text); }
/* proactive wizard: a few tap-choices the AI detected */
.gcx-wizard .gcx-body { border: 1px solid color-mix(in srgb, var(--accent) 38%, var(--border)); }
.gcx-wz-list { display: flex; flex-direction: column; gap: 6px; margin: 7px 0 3px; }
.gcx-wz { text-align: left; border: 1px solid var(--border); background: var(--bg-2); color: var(--text); border-radius: 10px; padding: 8px 11px; font-size: 12.5px; font-weight: 600; cursor: pointer; transition: border-color .12s, background .12s; }
.gcx-wz:hover { border-color: var(--accent); background: var(--accent-soft); }
/* live workbench streamed into the panel: give it room, keep the answer plain */
.gcx-run .gcx-body { max-width: none; flex: 1; min-width: 0; }
.gcx-run .msg-content { background: transparent; border: none; padding: 2px 0; border-radius: 0; font-size: 13px; }
.gcx-run .tool-chip { font-size: 11.5px; }
.gcx-run .files-card, .gcx-run .tool-chip { margin-top: 8px; }
.gc-ai-foot { border-top: 1px solid var(--border); padding: 10px 12px 12px; display: flex; flex-direction: column; gap: 9px; background: var(--bg-2); }
.gc-ai-quick { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.gc-chip { border: 1px solid var(--border); background: var(--bg); color: var(--text-dim); border-radius: 999px; padding: 5px 12px; font-size: 12px; font-weight: 600; cursor: pointer; }
.gc-chip:hover { border-color: var(--accent); color: var(--text); }
.gc-switch { display: inline-flex; align-items: center; gap: 6px; margin-left: auto; cursor: pointer; font-size: 11px; color: var(--text-dim); white-space: nowrap; }
.gc-switch input { display: none; }
.gc-switch-tr { width: 30px; height: 17px; border-radius: 999px; background: var(--bg-3); position: relative; transition: background .15s; flex-shrink: 0; }
.gc-switch-tr::after { content: ""; position: absolute; top: 2px; left: 2px; width: 13px; height: 13px; border-radius: 50%; background: #fff; transition: transform .15s; }
.gc-switch input:checked + .gc-switch-tr { background: var(--accent); }
.gc-switch input:checked + .gc-switch-tr::after { transform: translateX(13px); }
.gc-ai-hint { font-size: 11.5px; color: var(--text-faint); text-align: center; line-height: 1.5; }
.gc-ai-hint b { color: var(--accent-2); font-weight: 700; }
.gc-ai-ask { display: flex; gap: 8px; align-items: center; }
.gc-ai-askin { flex: 1; border: 1px solid var(--border); background: var(--bg); color: var(--text); border-radius: 999px; padding: 9px 14px; font: inherit; font-size: 13px; outline: none; }
.gc-ai-askin:focus { border-color: var(--accent); }
.gc-ai-asksend { flex: 0 0 auto; width: 34px; height: 34px; border-radius: 50%; border: none; background: var(--accent); color: #fff; cursor: pointer; font-size: 13px; }
/* feed bubbles (personal-chat style) */
.gcx { display: flex; gap: 8px; max-width: 100%; }
.gcx-me { justify-content: flex-end; }
.gcx-ava { flex: 0 0 auto; width: 26px; height: 26px; border-radius: 8px; background: var(--bg-3); display: grid; place-items: center; align-self: flex-end; }
.gcx-ava svg { width: 16px; height: 16px; color: var(--accent); }
.gcx-body { border-radius: 15px; padding: 9px 12px; font-size: 13px; line-height: 1.5; max-width: 84%; }
.gcx-ai .gcx-body { background: var(--bg-3); color: var(--text); border-bottom-left-radius: 5px; }
.gcx-me .gcx-body { background: var(--accent-soft); color: var(--text); border-bottom-right-radius: 5px; }
.gcx-h { font-size: 11px; font-weight: 700; color: var(--text-dim); margin-bottom: 5px; display: flex; align-items: center; gap: 6px; }
.gcx-text { white-space: pre-wrap; }
.gcx-act { display: flex; gap: 6px; margin-top: 8px; flex-wrap: wrap; }
.gcx-act button { border: 1px solid var(--border); background: var(--bg-2); color: var(--text); border-radius: 8px; padding: 4px 10px; font-size: 12px; font-weight: 600; cursor: pointer; }
.gcx-act button.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.gcx .gc-sug-text { width: 100%; min-height: 46px; resize: vertical; background: var(--bg-2); border: 1px solid var(--border); border-radius: 8px; padding: 7px 9px; color: var(--text); font: inherit; font-size: 13px; margin-top: 2px; }
.gcx-conf { font-size: 9.5px; font-weight: 700; text-transform: uppercase; background: var(--bg-2); color: var(--text-faint); border-radius: 5px; padding: 1px 5px; }
.gcx-conf.high { background: rgba(31,157,85,.2); color: var(--ok, #1f9d55); }
.gcx-dots { display: inline-flex; gap: 4px; padding: 3px 0; }
.gcx-dots i { width: 6px; height: 6px; border-radius: 50%; background: var(--text-faint); animation: gc-td 1.2s ease-in-out infinite; }
.gcx-dots i:nth-child(2){animation-delay:.2s}.gcx-dots i:nth-child(3){animation-delay:.4s}
@keyframes gc-td { 0%,100%{opacity:.3;transform:translateY(0)} 50%{opacity:1;transform:translateY(-3px)} }
/* composer @ / search drawer */
.gc-main { position: relative; }
.gc-drawer { position: absolute; left: 18px; right: 18px; bottom: 72px; background: var(--bg-2); border: 1px solid var(--border); border-radius: 14px; box-shadow: 0 14px 44px rgba(0,0,0,.42); max-height: 260px; overflow-y: auto; z-index: 30; padding: 6px; }
.gc-drawer.hidden { display: none; }
.gc-drawer-h { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--text-faint); padding: 7px 9px 4px; }
.gc-drawer-item { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; background: none; border: none; border-radius: 9px; padding: 8px 10px; color: var(--text); font: inherit; cursor: pointer; }
.gc-drawer-item:hover, .gc-drawer-item.active { background: var(--bg-hover); }
.gc-di-cmd { font-weight: 700; color: var(--accent-2); }
.gc-di-desc { font-size: 12px; color: var(--text-faint); }
.gc-mention { color: var(--accent-2); font-weight: 600; }
/* message options button + read-receipt ticks (WhatsApp-style: all inside the bubble) */
.cn-smsg { position: relative; }
.gc-msg-btn { position: absolute; top: 0; right: 0; width: 38px; height: 26px; border: none; border-top-right-radius: 14px;
  background: linear-gradient(270deg, var(--bg-3) 58%, transparent); color: var(--text-dim); cursor: pointer;
  opacity: 0; font-size: 13px; line-height: 1; display: flex; align-items: center; justify-content: flex-end;
  padding: 0 7px 0 0; transition: opacity .12s; z-index: 2; }
.cn-smsg.mine .gc-msg-btn { background: linear-gradient(270deg, var(--user-bubble) 58%, transparent); }
.cn-smsg-body:hover .gc-msg-btn, .gc-msg-btn:focus-visible { opacity: 1; }
.gc-msg-btn:hover { color: var(--text); }
.gc-ticks { font-size: 11px; color: var(--text-faint); letter-spacing: -2px; }
.gc-ticks.seen { color: #53bdeb; }
.gc-msg-menu { position: fixed; z-index: 200; background: var(--bg-2); border: 1px solid var(--border); border-radius: 12px; box-shadow: 0 14px 44px rgba(0,0,0,.45); padding: 5px; min-width: 168px; }
.gc-msg-menu button { display: flex; align-items: center; gap: 12px; width: 100%; text-align: left; background: none; border: none; border-radius: 8px; padding: 9px 11px; color: var(--text); font: inherit; font-size: 13.5px; cursor: pointer; }
.gc-msg-menu button:hover { background: var(--bg-hover); }
.gc-mm-i { width: 18px; text-align: center; color: var(--text-dim); font-size: 14px; flex-shrink: 0; }
/* alive logo — exact motion from the Claude Design export: centre pulses, inner ring
   spins CW, outer ring spins CCW, the between-ring dots breathe. */
.gc-ai-logo .core, .gc-ai-logo .r1, .gc-ai-logo .r2, .gc-ai-logo .r3 { transform-origin: 60px 60px; transform-box: view-box; }
.gc-ai-logo .core { animation: qPulse 3.4s ease-in-out infinite; }
.gc-ai-logo .r1 { animation: qSpin 26s linear infinite; }
.gc-ai-logo .r2 { animation: qSpinRev 38s linear infinite; }
.gc-ai-logo .r3 { animation: qBreathe 4.2s ease-in-out infinite; }
.gc-ai-logo.thinking .core { animation-duration: 1.4s; }
.gc-ai-logo.thinking .r1 { animation-duration: 8s; }
.gc-ai-logo.thinking .r2 { animation-duration: 12s; }
.gc-ai-logo.thinking .r3 { animation-duration: 1.8s; }
@keyframes qSpin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
@keyframes qSpinRev { from { transform: rotate(360deg); } to { transform: rotate(0deg); } }
@keyframes qPulse { 0%,100% { transform: scale(1); } 50% { transform: scale(1.14); } }
@keyframes qBreathe { 0%,100% { opacity: 1; transform: scale(1); } 50% { opacity: .55; transform: scale(.86); } }
@keyframes gc-glow { 0%,100% { opacity: .3; transform: scale(.9); } 50% { opacity: .65; transform: scale(1.05); } }
@media (prefers-reduced-motion: reduce) { .gc-ai-logo .core, .gc-ai-logo .r1, .gc-ai-logo .r2, .gc-ai-logo .r3 { animation: none !important; } }
/* group info slide-over */
.gc-info-overlay { position: fixed; inset: 0; background: rgba(0,0,0,.4); z-index: 60; display: flex; justify-content: flex-end; }
.gc-info-overlay.hidden { display: none; }
.gc-info-panel { width: 360px; max-width: 92vw; height: 100%; background: var(--bg-2); border-left: 1px solid var(--border); overflow-y: auto; padding: 16px 18px 22px; display: flex; flex-direction: column; gap: 12px; }
.gc-info-sub { font-size: 12.5px; color: var(--text-faint); }
.gc-info-members { display: flex; flex-direction: column; gap: 2px; }
.gc-info-mrow { display: flex; align-items: center; gap: 10px; padding: 7px 4px; border-radius: 8px; font-size: 14px; }
.gc-info-mrow .cn-ppl-avatar { width: 30px; height: 30px; font-size: 12px; border-radius: 8px; }
.gc-info-mrow > span:first-of-type { display: inline-flex; align-items: center; gap: 6px; }
/* Push the state text to the right edge, same reading order as a Members card. */
.gc-info-mstate { margin-left: auto; font-size: 11.5px; color: var(--text-faint); white-space: nowrap; }
@media (max-width: 1040px) { .gc-hub { grid-template-columns: 260px minmax(0, 1fr); } .gc-ai { display: none; } }
.gc-view { min-width: 0; display: flex; flex-direction: column; background: var(--bg-2); border: 1px solid var(--border); border-radius: 12px; overflow: hidden; }
.skill-nav { display: flex; flex-direction: column; gap: 2px; max-height: 30vh; overflow-y: auto; }
.skill-nav:empty { display: none; }
.skill-nav .side-item.active { background: var(--accent-soft); }

.side-recents { flex: 1; min-height: 0; }
.side-recents .conversations { max-height: none; }
.conv-empty { color: var(--text-faint); font-size: 12.5px; padding: 8px 10px; }
.recents-search {
  background: var(--bg); border: 1px solid var(--border); color: var(--text);
  border-radius: 8px; padding: 7px 10px; font-size: 13px; margin: 2px 0 4px; outline: none;
}
.recents-search:focus { border-color: var(--accent); }

.account {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  background: none; border: none; border-top: 1px solid var(--border);
  padding: 12px 8px 4px; margin-top: 4px; color: var(--text); border-radius: 0;
}
.account:hover { background: var(--bg-hover); border-radius: 9px; }
.avatar-mini {
  width: 30px; height: 30px; border-radius: 50%; flex-shrink: 0;
  background: linear-gradient(135deg, #f0606a, #d64550); color: #fff;
  display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 700;
}
.account-text { display: flex; flex-direction: column; line-height: 1.25; }
.account-text strong { font-size: 13.5px; }
.account-text small { font-size: 11px; color: var(--text-faint); }

/* views */
.view { flex: 1; min-height: 0; display: flex; flex-direction: column; min-width: 0; }
.view.hidden { display: none; }

/* full-page header/body (marketplace + skill pages) */
.page-head { padding: 26px 30px 0; border-bottom: 1px solid var(--border); }
.page-head h1 { margin: 0 0 4px; font-size: 24px; }
.page-head > p { margin: 0 0 16px; color: var(--text-dim); font-size: 14px; max-width: 680px; }
.page-head-row { display: flex; align-items: center; gap: 14px; padding-bottom: 18px; }
.page-head-icon { font-size: 30px; width: 56px; height: 56px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center; background: var(--bg-3); border-radius: 14px; }
.page-head-row h1 { margin: 0; }
.page-head-row p { margin: 4px 0 0; color: var(--text-dim); font-size: 13.5px; max-width: 620px; }
.page-body { flex: 1; overflow-y: auto; padding: 22px 30px 40px; }

.market-tabs { display: flex; gap: 6px; }
.market-tab {
  background: none; border: none; color: var(--text-dim); font-size: 14px; font-weight: 600;
  padding: 9px 14px; border-radius: 9px 9px 0 0; border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.market-tab:hover { color: var(--text); }
.market-tab.active { color: var(--text); border-bottom-color: var(--accent); }

/* skill page */
/* The setup checklist — what this skill still needs, and a button that connects it
   here. It sits ABOVE the Run bar on the Summary tab (it used to be a row of chips on
   Settings, which is not the tab you land on). */
.skill-requires { display: flex; flex-direction: column; gap: 8px; margin-bottom: 18px; }
.skill-requires .setup-head {
  font-size: 13px; line-height: 1.5; color: var(--text);
  padding: 10px 12px; border-radius: var(--radius);
  background: color-mix(in srgb, var(--warn) 10%, var(--bg-2));
  border: 1px solid color-mix(in srgb, var(--warn) 38%, var(--border));
}
.skill-requires .setup-ok { font-size: 12.5px; color: var(--text-faint); }
.setup-row {
  display: flex; align-items: center; gap: 10px; padding: 8px 12px;
  border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-2);
}
.setup-row.has-note { align-items: flex-start; }
.setup-row .setup-ico { --ico-sz: 28px; font-size: 16px; flex-shrink: 0; }
.setup-row .setup-main { display: flex; flex-direction: column; gap: 2px; }
.setup-row .setup-name { font-weight: 600; font-size: 13.5px; }
/* What the SKILL says it needs from this connection (frontmatter `setup:`). */
.setup-row .setup-note { font-size: 12px; color: var(--text-dim); line-height: 1.45; max-width: 42ch; }
.setup-row .setup-why { flex: 1; font-size: 12px; color: var(--text-faint); text-align: right; }
/* Not fixable from here — the member's role withholds it, so there is no button. */
.setup-row .setup-why-blocked { font-size: 12px; color: var(--warn); }
/* Run, while the skill cannot work. Cosmetic — the server refuses it too. */
#skill-run.is-blocked { opacity: .5; cursor: not-allowed; }
/* The Settings tab is one form column, and everything in it shares its edge — the params
   were 620 wide and the schedule card beside them 820, which is most of why this page
   read as a pile of boxes rather than a page. */
#skill-panel-settings { max-width: 720px; }
.skill-params { display: flex; flex-direction: column; gap: 14px; }
.skill-param { display: flex; flex-direction: column; gap: 5px; }
.skill-param label { font-size: 13px; color: var(--text-dim); font-weight: 600; }
.skill-param input, .skill-param textarea, .skill-param select {
  background: var(--bg-2); border: 1px solid var(--border); color: var(--text);
  border-radius: 9px; padding: 10px 12px; font-size: 14px; font-family: inherit; outline: none; width: 100%;
}
.skill-param input:focus, .skill-param textarea:focus, .skill-param select:focus { border-color: var(--accent); }
.skill-param .cap-help { font-size: 11.5px; color: var(--text-faint); }
/* checkbox + multiselect params */
.skill-param .skp-check, .skill-param .skp-chk { flex-direction: row; display: inline-flex; align-items: center; gap: 7px; font-weight: 500; color: var(--text); cursor: pointer; }
.skill-param input[type="checkbox"] { width: auto; margin: 0; accent-color: var(--accent); }
.skp-multi { display: flex; flex-wrap: wrap; gap: 6px 16px; padding: 2px 0; }
.skp-multi .skp-chk { font-size: 13px; }
.skill-actions { display: flex; align-items: center; gap: 10px; margin: 18px 0; }
.btn-ghost { background: none; border: 1px solid var(--border); color: var(--text-dim); border-radius: 10px; padding: 9px 14px; font-size: 13px; cursor: pointer; }
.btn-ghost:hover { background: var(--bg-hover); color: var(--text); }
/* schedule card */
.skill-schedule { border: 1px solid var(--border); border-radius: 12px; padding: 14px 16px; margin: 18px 0; background: var(--bg-2); }
.sched-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 10px; }
.sched-title { font-weight: 600; font-size: 14px; }
.sched-status { font-size: 12px; color: var(--text-faint); }
.sched-status.on { color: #6fce8f; }
.sched-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.sched-input { background: var(--bg-1, var(--bg-2)); border: 1px solid var(--border); color: var(--text); border-radius: 9px; padding: 8px 10px; font-size: 13px; font-family: inherit; outline: none; }
.sched-input:focus { border-color: var(--accent); }
.sched-hint { font-size: 11.5px; color: var(--text-faint); margin: 10px 0 0; }
/* skill page tabs (Summary / Settings) */
/* The same pill tabs as Files, Memory, Skills and Heartbeat — a fourth tab style on the
   page you land on from any of them is how the app stopped looking like one product. */
.skill-tabs { display: flex; align-items: center; gap: 2px; flex-wrap: wrap; margin-bottom: 18px; }
.skill-tab {
  display: inline-flex; align-items: center; gap: 7px; height: 34px; padding: 0 14px;
  border: 0; border-radius: 999px; background: none; color: var(--text-dim);
  font: inherit; font-size: 13.5px; font-weight: 600; white-space: nowrap; cursor: pointer;
  transition: background .12s, color .12s;
}
.skill-tab:hover { background: var(--bg-2); color: var(--text); }
.skill-tab.active { background: var(--bg-3); color: var(--text); }
:root[data-theme="light"] .skill-tab.active { background: var(--bg-hover); }
.skill-summary-bar { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.skill-summary-meta { font-size: 12px; color: var(--text-faint); }
/* Findings: the run's structured half, as a list you work through. Statuses here
   survive the next run, so it is a working set and not a report. */
.skill-rows { border: 1px solid var(--border); border-radius: 12px; padding: 14px 16px;
  background: var(--bg-2); }
.rows-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 10px; }
.rows-title { font-size: 14px; font-weight: 700; }
.rows-filters { display: flex; gap: 6px; flex-wrap: wrap; }
.rowfilter { border: 1px solid var(--border); background: transparent; color: var(--text-dim);
  border-radius: 999px; padding: 3px 10px; font-size: 12px; cursor: pointer; }
.rowfilter:hover { color: var(--text); }
.rowfilter.active { background: var(--bg-3); color: var(--text); border-color: var(--accent); }
.rowfilter-n { opacity: .65; margin-left: 3px; }
.rows-scroll { overflow-x: auto; }
.rows-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.rows-table th { text-align: left; font-weight: 600; color: var(--text-faint); font-size: 11px;
  text-transform: uppercase; letter-spacing: .04em; padding: 6px 10px 6px 0; border-bottom: 1px solid var(--border); }
.rows-table td { padding: 8px 10px 8px 0; border-bottom: 1px solid var(--border-soft, var(--border));
  vertical-align: top; }
.rows-table tr.row-done td, .rows-table tr.row-dismissed td, .rows-table tr.row-resolved td { opacity: .55; }
.rows-table .row-actions { white-space: nowrap; text-align: right; }
.rows-table .row-actions .btn-mini { margin-left: 6px; }
.row-status { font-size: 11px; color: var(--text-faint); }
.row-note { font-size: 11px; color: var(--text-faint); margin-top: 3px; font-style: italic; }
.rows-foot { margin-top: 10px; font-size: 11.5px; }
.skill-result {
  border: 1px solid var(--border); border-radius: 12px; padding: 18px 20px; min-height: 120px;
  background: var(--bg-2);
}
.skill-result .msg-content { word-wrap: break-word; }
.skill-result .hint { color: var(--text-faint); }
/* digest: clean, readable rendering of the final result */
.digest { line-height: 1.62; font-size: 14.5px; color: var(--text); }
.digest h1, .digest h2 { font-size: 18px; margin: 20px 0 8px; font-weight: 700; letter-spacing: -.01em; }
.digest h1:first-child, .digest h2:first-child { margin-top: 2px; }
.digest h3 { font-size: 15px; margin: 16px 0 6px; font-weight: 700; }
.digest p { margin: 9px 0; }
.digest ul, .digest ol { margin: 8px 0; padding-left: 20px; }
.digest li { margin: 5px 0; }
.digest li::marker { color: var(--text-faint); }
.digest a { color: var(--accent); text-decoration: none; }
.digest a:hover { text-decoration: underline; }
.digest strong { color: var(--text); font-weight: 700; }
.digest hr { border: none; border-top: 1px solid var(--border); margin: 16px 0; }
.digest img { max-width: 100%; border-radius: 8px; margin: 6px 0; }
.run-error { display: flex; flex-direction: column; gap: 8px; }
.run-error-title { font-weight: 700; color: #ffb088; font-size: 15px; }
.run-error-msg { color: var(--text-dim); font-size: 13.5px; white-space: pre-wrap;
  background: rgba(255,160,90,.08); border: 1px solid rgba(255,160,90,.25); border-radius: 8px; padding: 10px 12px; }
/* ---- Summary: runs down the left, the run you picked on the right ----
   Every box on this tab used to set its own width (620 / 820 / 980 / none), so a page
   with four of them had four right-hand edges and read as broken. Width comes from the
   column now; nothing here declares its own. */
.skill-split {
  display: grid; grid-template-columns: minmax(190px, 240px) minmax(0, 1fr);
  gap: 20px; align-items: start;
}
/* No history yet (a skill that has never run) — the column track would otherwise stay,
   indenting the report by 210px against nothing. */
.skill-split:has(> .skill-runs.hidden) { grid-template-columns: minmax(0, 1fr); }
.skill-main { min-width: 0; display: flex; flex-direction: column; gap: 14px; }
/* The list follows you down a long report rather than scrolling away above it. */
.skill-runs {
  position: sticky; top: 0; display: flex; flex-direction: column; gap: 2px;
  max-height: calc(100vh - 220px); overflow-y: auto;
}
@media (max-width: 900px) {
  .skill-split { grid-template-columns: 1fr; }
  /* Stacked, the history goes UNDER the report — it is the older thing. */
  .skill-runs { order: 2; position: static; max-height: 320px; }
}
.skill-runs .runs-title {
  position: sticky; top: 0; z-index: 1; background: var(--bg);
  padding: 2px 12px 8px; margin: 0;
  font-size: 11px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--text-faint); font-weight: 700;
}
.run-row { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; cursor: pointer;
  background: none; border: 1px solid transparent; border-radius: 9px; padding: 8px 12px; color: var(--text-dim); font-size: 13px; }
.run-row:hover { background: var(--bg-2); }
.run-row.active { background: var(--bg-2); border-color: var(--border); color: var(--text); }
.run-when { font-weight: 600; }
.run-mark { color: var(--text-faint); font-size: 12px; }
.run-mark.error { color: #ffb088; }
.run-dot { margin-left: auto; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); flex: none; }

/* marketplace cards: install/open buttons */
.market-card .market-card-foot .btn-mini, .market-card .market-card-foot .btn-primary { padding: 6px 14px; font-size: 12.5px; }
.market-card-actions { display: flex; gap: 8px; align-items: center; }

/* ===== Task Manager ===== */
.tasks-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.tasks-actions { display: flex; gap: 8px; align-items: center; flex-shrink: 0; }
.tasks-toolbar { display: flex; align-items: center; gap: 10px; padding: 4px 0 16px; flex-wrap: wrap; }
.seg-group { display: inline-flex; background: var(--bg-2); border: 1px solid var(--border); border-radius: 9px; overflow: hidden; }
.seg { background: none; border: none; color: var(--text-dim); font-size: 13px; padding: 7px 13px; }
.seg.active { background: var(--accent-soft); color: var(--text); }
.tasks-select, .tasks-filter-input {
  background: var(--bg-2); border: 1px solid var(--border); color: var(--text);
  border-radius: 9px; padding: 7px 11px; font-size: 13px; font-family: inherit; outline: none;
}
.tasks-filter-input { flex: 1; min-width: 140px; max-width: 320px; }
.tasks-select:focus, .tasks-filter-input:focus { border-color: var(--accent); }
.tasks-count { color: var(--text-faint); font-size: 12.5px; margin-left: auto; }
.tasks-empty { color: var(--text-faint); text-align: center; padding: 50px 20px; }

/* board */
.tasks-board { display: flex; gap: 14px; align-items: flex-start; overflow-x: auto; padding-bottom: 10px; }
.task-col { flex: 1; min-width: 250px; background: var(--bg-2); border: 1px solid var(--border); border-radius: 12px; padding: 10px; }
.task-col-head { display: flex; align-items: center; gap: 8px; font-size: 12.5px; font-weight: 600; color: var(--text-dim); padding: 4px 6px 10px; }
.task-col-head .dotmark { width: 9px; height: 9px; border-radius: 50%; }
.task-col-head .col-count { margin-left: auto; color: var(--text-faint); font-weight: 500; }
.task-col-body { display: flex; flex-direction: column; gap: 8px; min-height: 12px; }

.task-card { background: var(--bg); border: 1px solid var(--border); border-radius: 10px; padding: 11px 12px; }
.task-card:hover { border-color: var(--bg-hover); }
.task-card-title { font-size: 14px; font-weight: 600; margin-bottom: 6px; line-height: 1.35; }
.task-meta { display: flex; flex-wrap: wrap; gap: 6px 10px; font-size: 12px; color: var(--text-dim); margin-bottom: 8px; }
.task-meta .tm { display: inline-flex; align-items: center; gap: 4px; }
.task-meta .tm-due { color: #e0a458; }
.tm-overdue { color: var(--danger); font-weight: 600; }
.home-overdue { color: var(--danger); font-weight: 600; }
.task-detail { font-size: 12.5px; color: var(--text-dim); margin: 4px 0 8px; }
/* AI suggested-reply modal */
.reply-task { background: var(--bg-2); border: 1px solid var(--border); border-radius: 9px; padding: 10px 12px; }
.reply-task-title { font-weight: 600; font-size: 13.5px; }
.reply-task-sub { font-size: 11.5px; color: var(--text-faint); margin-top: 2px; }
.reply-text { background: var(--bg-2); border: 1px solid var(--border); color: var(--text); border-radius: 9px;
  padding: 11px 13px; font-size: 14px; font-family: inherit; line-height: 1.5; outline: none; resize: vertical; width: 100%; }
.reply-text:focus { border-color: var(--accent); }
.reply-steer { background: var(--bg-2); border: 1px solid var(--border); color: var(--text); border-radius: 9px;
  padding: 9px 12px; font-size: 13px; font-family: inherit; outline: none; width: 100%; }
.reply-steer:focus { border-color: var(--accent); }
.task-card-foot { display: flex; align-items: center; gap: 8px; }
.task-status-sel { background: var(--bg-2); border: 1px solid var(--border); color: var(--text); border-radius: 7px; padding: 4px 7px; font-size: 12px; font-family: inherit; }
.task-link { font-size: 12px; color: var(--accent-2); text-decoration: none; }
.task-link:hover { text-decoration: underline; }
.task-card-actions { margin-left: auto; display: flex; gap: 4px; }
.task-ico-btn { background: none; border: none; color: var(--text-faint); font-size: 13px; padding: 3px 5px; border-radius: 6px; }
.task-ico-btn:hover { background: var(--bg-hover); color: var(--text); }

/* status pills / dots */
.st-todo { color: var(--text-dim); } .bg-todo { background: #6b7280; }
.st-in_progress { color: var(--accent-2); } .bg-in_progress { background: var(--accent); }
.st-ready { color: #7bb5ff; } .bg-ready { background: #4f8ff7; }
.st-blocked { color: #f0a060; } .bg-blocked { background: #e0a458; }
.st-done { color: var(--ok); } .bg-done { background: var(--ok); }

/* AI follow-up outcome on a task card */
.task-res { border-radius: 8px; padding: 8px 10px; margin: 2px 0 8px; font-size: 12.5px; border: 1px solid var(--border); }
.task-res.draft { background: rgba(79, 143, 247, 0.10); border-color: rgba(79, 143, 247, 0.35); }
.task-res.done { background: rgba(80, 200, 120, 0.08); border-color: rgba(80, 200, 120, 0.28); }
.task-res.blocked { background: rgba(224, 164, 88, 0.08); border-color: rgba(224, 164, 88, 0.28); }
.task-res-head { font-weight: 600; display: block; }
.task-res-body { color: var(--text-dim); margin-top: 4px; white-space: pre-wrap; line-height: 1.45; }
.task-res-btn { margin-top: 8px; }

/* Auto follow-up modal */
.fu-toggle { display: flex; align-items: center; gap: 9px; font-size: 13.5px; margin: 12px 0; cursor: pointer; }
.fu-toggle input { width: 16px; height: 16px; }
.fu-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 12px; }
.fu-status { font-size: 12px; color: var(--text-faint); margin-right: auto; }
.fu-tz-note { font-size: 12px; color: var(--text-dim); margin-top: 12px; }
.field-sub { color: var(--text-faint); font-weight: 400; font-size: 11.5px; font-style: normal; }
.tz-device-btn { display: inline-block; margin-top: 7px; font-size: 12px; text-align: left; }

/* saved-view tabs — each one is a row in `views`, not a hardcoded screen */
.tasks-views { display: flex; gap: 4px; flex-wrap: wrap; padding: 10px 0 0; }
.tasks-view-tab {
  background: none; border: 1px solid transparent; color: var(--text-dim);
  font-size: 13px; font-weight: 500; padding: 6px 13px; border-radius: 9px;
}
.tasks-view-tab:hover { background: var(--bg-2); color: var(--text); }
.tasks-view-tab.active { background: var(--accent-soft); border-color: var(--border); color: var(--text); }

/* project rail + board area */
.tasks-workspace { display: flex; gap: 16px; align-items: flex-start; }
.tasks-main { flex: 1; min-width: 0; }
.tasks-rail { width: 190px; flex-shrink: 0; display: flex; flex-direction: column; gap: 2px; }
.rail-head { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .05em;
  color: var(--text-faint); padding: 4px 8px 8px; }
.rail-item { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
  background: none; border: none; color: var(--text-dim); font-size: 13px;
  padding: 7px 9px; border-radius: 8px; }
.rail-item:hover { background: var(--bg-2); color: var(--text); }
.rail-item.active { background: var(--accent-soft); color: var(--text); font-weight: 600; }
.rail-label { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rail-count { color: var(--text-faint); font-size: 11.5px; font-weight: 500; }
.rail-muted .rail-label { font-style: italic; }
.rail-new { background: none; border: none; color: var(--text-faint); font-size: 12.5px;
  text-align: left; padding: 8px 9px; border-radius: 8px; margin-top: 4px; }
.rail-new:hover { background: var(--bg-2); color: var(--text); }
.rail-trash { display: flex; align-items: center; gap: 8px; padding: 6px 9px;
  font-size: 12.5px; color: var(--text-dim); }

/* Command palette (Ctrl+K) */
#palette-overlay { align-items: flex-start; }
.palette {
  width: 620px; max-width: 92vw; margin-top: 12vh;
  background: var(--bg); border: 1px solid var(--border); border-radius: 14px;
  box-shadow: 0 22px 60px rgba(0, 0, 0, .38); overflow: hidden;
  display: flex; flex-direction: column;
}
.palette-input {
  background: none; border: none; border-bottom: 1px solid var(--border);
  color: var(--text); font-size: 15px; font-family: inherit;
  padding: 15px 18px; outline: none; width: 100%;
}
.palette-results { max-height: 52vh; overflow-y: auto; padding: 6px; }
.palette-row {
  display: flex; align-items: center; gap: 11px; width: 100%; text-align: left;
  background: none; border: none; color: var(--text); padding: 9px 12px;
  border-radius: 9px; font-size: 13.5px;
}
.palette-row:hover, .palette-row.active { background: var(--accent-soft); }
.palette-ico { flex-shrink: 0; color: var(--text-faint); font-size: 13px; }
.palette-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.palette-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.palette-hint { font-size: 11.5px; color: var(--text-faint);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.palette-tag { font-size: 11px; color: var(--text-faint); flex-shrink: 0; font-family: var(--mono); }
.palette-empty { color: var(--text-faint); font-size: 12.5px; padding: 18px 14px; text-align: center; }
.palette-foot {
  border-top: 1px solid var(--border); padding: 8px 14px;
  font-size: 11px; color: var(--text-faint); display: flex; gap: 6px; align-items: center;
}
.palette-foot kbd {
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 5px;
  padding: 1px 5px; font-family: var(--mono); font-size: 10.5px;
}
.tm-label { background: var(--accent-soft); border-radius: 6px; padding: 1px 7px; font-size: 11px; }
.tm-shared { color: var(--accent-2); font-weight: 600; }
@media (max-width: 860px) {
  .tasks-workspace { flex-direction: column; }
  .tasks-rail { width: 100%; flex-direction: row; flex-wrap: wrap; }
  .rail-head { display: none; }
  .rail-item { width: auto; }
}

/* a subtask card sits under its parent, in the same column */
.task-card-sub { margin-left: 14px; border-left: 2px solid var(--accent-soft); }
.task-parent-hint { font-size: 11px; color: var(--text-faint); margin-bottom: 4px; }
.task-card-title { cursor: pointer; }
.task-meta .tm-proj { background: var(--bg-2); border: 1px solid var(--border);
  border-radius: 6px; padding: 1px 6px; font-size: 11px; }

/* The task number the drawer, the Inbox and the AI all refer to ("#217"). It was only
   ever on the panel, so a card the AI named by number was unfindable on the board. */
.task-num { color: var(--text-faint); font-weight: 600; font-variant-numeric: tabular-nums;
  font-size: .88em; margin-right: 6px; }
/* A description is Markdown; the card shows a stripped, capped preview of it, so keep
   it to two lines rather than letting one long paragraph own the card. */
.task-detail { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; }
.tt-sub { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; }

/* Reveal: a row opened from a link is scrolled to and flashed, so the drawer and the
   board agree about which task is being talked about. */
@keyframes task-flash-ring {
  0%   { box-shadow: 0 0 0 0 var(--accent); }
  35%  { box-shadow: 0 0 0 3px var(--accent); }
  100% { box-shadow: 0 0 0 0 rgba(124, 140, 255, 0); }
}
.task-card.task-flash { animation: task-flash-ring 2.4s ease-out; border-color: var(--accent); }
tr.task-flash td { background: var(--accent-soft); }
tr.task-flash { animation: task-flash-ring 2.4s ease-out; }
/* Pinned = the running view does not select this row; it is on the page because a link
   asked for it. Dashed, so it never reads as a view that quietly stopped filtering. */
.task-card-pinned { border-style: dashed; }
tr.tt-pinned td { border-top: 1px dashed var(--accent-soft); }
.task-meta .tm-pinned { color: var(--accent-2); }

/* ---- task detail drawer: the thread, history and structure of one task */
.task-drawer {
  position: fixed; top: var(--topbar-h); right: 0; bottom: 0; width: 440px; max-width: 92vw; z-index: 60;
  background: var(--bg); border-left: 1px solid var(--border);
  display: flex; flex-direction: column; box-shadow: -18px 0 40px rgba(0, 0, 0, .28);
}
.task-drawer.hidden { display: none; }
.task-drawer-head { display: flex; align-items: flex-start; gap: 10px;
  padding: 16px 16px 12px; border-bottom: 1px solid var(--border); }
.task-drawer-title { flex: 1; min-width: 0; }
.task-drawer-title h2 { font-size: 16px; line-height: 1.35; margin: 2px 0 0; }
.td-id { font-size: 11.5px; color: var(--text-faint); font-weight: 600; }
.task-drawer-head-actions { display: flex; gap: 2px; flex-shrink: 0; }
.task-drawer-body { flex: 1; overflow-y: auto; padding: 14px 16px; }
.td-props { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 14px; }
.td-prop { display: flex; flex-direction: column; gap: 4px; font-size: 11.5px; color: var(--text-faint); }
.td-prop select {
  background: var(--bg-2); border: 1px solid var(--border); color: var(--text);
  border-radius: 8px; padding: 6px 8px; font-size: 12.5px; font-family: inherit; outline: none;
}
.td-prop select:focus { border-color: var(--accent); }
.td-value { color: var(--text); font-size: 12.5px; padding: 6px 0; }
/* The description is rendered Markdown now, so it must not also collapse its own
   whitespace (pre-wrap would double every gap the <p> margins already provide). */
.td-details { font-size: 13px; color: var(--text-dim); line-height: 1.6; margin-bottom: 16px; }
.td-details > *:first-child { margin-top: 0; }
.td-details > *:last-child { margin-bottom: 0; }
.td-details p { margin: 0 0 9px; }
.td-details ul, .td-details ol { margin: 0 0 9px; padding-left: 20px; }
.td-details li { margin: 3px 0; }
.td-details strong { color: var(--text); font-weight: 600; }
.td-details code {
  font-family: var(--mono); font-size: 12px; background: var(--bg-2);
  border: 1px solid var(--border); border-radius: 5px; padding: 1px 5px;
}
.td-details pre {
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 8px;
  padding: 9px 11px; overflow-x: auto; margin: 0 0 9px;
}
.td-details pre code { background: none; border: none; padding: 0; }
.td-details a { color: var(--accent-2); }
.td-details h1, .td-details h2, .td-details h3, .td-details h4 {
  font-size: 12.5px; font-weight: 600; color: var(--text); margin: 12px 0 5px;
  text-transform: uppercase; letter-spacing: .04em;
}
.td-details blockquote {
  margin: 0 0 9px; padding-left: 10px; border-left: 2px solid var(--border);
  color: var(--text-faint);
}
.td-details table.md-table { font-size: 12px; border-collapse: collapse; margin-bottom: 9px; }
.td-details table.md-table th, .td-details table.md-table td {
  border: 1px solid var(--border); padding: 4px 8px; text-align: left;
}
.td-section { margin-bottom: 18px; }
.td-section-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.td-section-head h3 { font-size: 11.5px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .05em; color: var(--text-faint); margin: 0; }
.td-empty { font-size: 12.5px; color: var(--text-faint); line-height: 1.5; }
.td-links { display: flex; flex-direction: column; gap: 5px; }
.td-link { display: flex; align-items: center; gap: 8px; font-size: 12.5px; }
.td-link .dotmark { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.td-link-title { flex: 1; text-align: left; background: none; border: none; color: var(--text);
  font-size: 12.5px; padding: 3px 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.td-link-title:hover { color: var(--accent-2); text-decoration: underline; }
.td-link-who { color: var(--text-faint); font-size: 11.5px; flex-shrink: 0; }
.td-file-ico { flex-shrink: 0; font-size: 12px; }
a.td-link-title { text-decoration: none; }
/* A whole Inbox row is the target, so it needs the affordance a bare link has. */
.td-dupe-note { font-size: 12px; color: var(--text-faint); line-height: 1.5; margin: -2px 0 6px; }
.td-dupe-row { cursor: pointer; padding: 5px 6px; margin: 0 -6px; border-radius: 7px; }
.td-dupe-row:hover { background: var(--bg-hover); }
.td-dupe-row:hover .td-link-title { color: var(--accent-2); }
.td-inbox-row { cursor: pointer; padding: 5px 6px; margin: 0 -6px; border-radius: 7px; }
.td-inbox-row:hover { background: var(--bg-hover); }
.td-inbox-row:hover .td-link-title { color: var(--accent-2); }
.td-inbox-row.td-done .td-link-title { color: var(--text-dim); }
.td-inbox-row.td-done .td-file-ico { opacity: .5; }
/* Where the task came from — one quiet line under the description, not a field row. */
.td-source { display: flex; align-items: baseline; gap: 8px; font-size: 12.5px; margin: -6px 0 16px; }
.td-source-k { color: var(--text-faint); text-transform: uppercase; font-size: 10.5px; letter-spacing: .06em; }
.td-source-v { color: var(--text-dim); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
a.td-source-v { color: var(--accent-2); text-decoration: none; }
a.td-source-v:hover { text-decoration: underline; }
.td-tabs { margin-bottom: 4px; }
.td-thread { display: flex; flex-direction: column; gap: 10px; }
.td-msg { background: var(--bg-2); border: 1px solid var(--border); border-radius: 9px; padding: 9px 11px; }
.td-msg-ai { border-color: var(--accent-soft); }
.td-msg-head { display: flex; align-items: center; gap: 6px; font-size: 12px;
  font-weight: 600; color: var(--text-dim); margin-bottom: 4px; }
.td-msg-time { margin-left: auto; font-weight: 400; color: var(--text-faint); font-size: 11px; }
/* Markdown now, so the renderer owns the line breaks — pre-wrap on top of <p> tags
   would double every blank line. */
.td-msg-body { font-size: 13px; line-height: 1.55; }
.td-msg-body > *:first-child { margin-top: 0; }
.td-msg-body > *:last-child { margin-bottom: 0; }
.td-msg-body p { margin: 0 0 8px; }
.td-msg-body ul, .td-msg-body ol { margin: 0 0 8px; padding-left: 20px; }
.td-msg-body li { margin: 3px 0; }
.td-msg-body strong { color: var(--text); font-weight: 600; }
.td-msg-body a { color: var(--accent-2); text-decoration: none; font-weight: 600; }
.td-msg-body a:hover { text-decoration: underline; }
.td-history { display: flex; flex-direction: column; gap: 2px; }
.td-event { display: flex; align-items: baseline; gap: 8px; font-size: 12px;
  color: var(--text-dim); padding: 5px 0; border-bottom: 1px solid var(--border); }
.td-event:last-child { border-bottom: none; }
.td-event-what { flex: 1; }
.td-event-who { color: var(--text-faint); font-size: 11.5px; }
.td-event-time { color: var(--text-faint); font-size: 11px; flex-shrink: 0; }
.task-drawer-foot { display: flex; gap: 8px; align-items: flex-end;
  padding: 12px 16px; border-top: 1px solid var(--border); }
.task-drawer-foot.hidden { display: none; }
.task-drawer-foot textarea {
  flex: 1; background: var(--bg-2); border: 1px solid var(--border); color: var(--text);
  border-radius: 9px; padding: 9px 11px; font-size: 13px; font-family: inherit;
  line-height: 1.45; outline: none; resize: none;
}
.task-drawer-foot textarea:focus { border-color: var(--accent); }

/* table */
.tasks-table-wrap { overflow-x: auto; border: 1px solid var(--border); border-radius: 12px; }
table.tasks-table { width: 100%; border-collapse: collapse; font-size: 13px; }
table.tasks-table th { text-align: left; color: var(--text-faint); font-weight: 600; font-size: 11.5px; text-transform: uppercase; letter-spacing: .04em; padding: 10px 12px; border-bottom: 1px solid var(--border); }
table.tasks-table td { padding: 10px 12px; border-bottom: 1px solid var(--border); vertical-align: top; }
table.tasks-table tr:last-child td { border-bottom: none; }
table.tasks-table tr:hover td { background: var(--bg-2); }
.tt-title { font-weight: 600; cursor: pointer; }
.tt-title:hover { color: var(--accent-2); }
.tt-sub { color: var(--text-faint); font-size: 11.5px; }
.field-row { display: flex; gap: 12px; }
.field-row .field { flex: 1; }

/* markdown tables in chat */
.md-table { width: 100%; border-collapse: collapse; font-size: 13px; margin: 8px 0; }
.md-table th { text-align: left; color: var(--text-faint); font-weight: 600; font-size: 11.5px; text-transform: uppercase; letter-spacing: .04em; padding: 8px 10px; border-bottom: 1px solid var(--border); background: var(--bg-2); }
.md-table td { padding: 8px 10px; border-bottom: 1px solid var(--border); vertical-align: top; }
.md-table tr:last-child td { border-bottom: none; }
.md-table tr:hover td { background: var(--bg-2); }

/* ===== Router Pool ===== */
.router-pool-entry { display: flex; align-items: center; gap: 8px; padding: 8px; background: var(--bg-2); border-radius: 8px; margin-bottom: 6px; }
.router-pool-entry .priority { font-weight: 600; color: var(--accent); min-width: 20px; }
.router-pool-entry .provider { font-size: 12px; color: var(--text-faint); }
.router-pool-entry .model { flex: 1; font-weight: 500; }
.router-pool-entry .tags { font-size: 11px; color: var(--text-faint); }
.router-pool-entry .controls { display: flex; gap: 4px; }
.router-pool-entry button { background: transparent; border: none; cursor: pointer; padding: 2px 6px; border-radius: 4px; }
.router-pool-entry button:hover { background: var(--bg-3); }
.router-controls { display: flex; gap: 8px; margin-top: 10px; align-items: center; }

/* ===== Model Badge ===== */
.model-badge { display: inline-flex; align-items: center; gap: 4px; font-size: 11px; color: var(--text-faint); background: var(--bg-2); padding: 2px 8px; border-radius: 10px; margin-bottom: 6px; }
.model-badge::before { content: "🤖"; }

/* ===== Auth / onboarding ===== */
.auth-overlay {
  position: fixed; inset: 0; z-index: 200; background: var(--bg);
  display: flex; align-items: center; justify-content: center; padding: 24px; overflow-y: auto;
}
.auth-card {
  width: 100%; max-width: 420px; background: var(--bg-2); border: 1px solid var(--border);
  border-radius: 18px; padding: 26px 26px 22px; display: flex; flex-direction: column; gap: 14px;
}
.auth-brand { display: flex; align-items: center; gap: 11px; }
.auth-brand .brand-logo { font-size: 30px; }
.auth-brand strong { font-size: 16px; display: block; }
.auth-brand small { color: var(--text-faint); font-size: 12px; }
.auth-pane { display: flex; flex-direction: column; gap: 13px; }
.auth-pane h2 { margin: 4px 0 0; font-size: 19px; }
.wiz-step { display: flex; flex-direction: column; gap: 13px; }
.auth-card .field > span { font-size: 12.5px; }
.auth-card input, .auth-card select, .auth-card textarea {
  background: var(--bg); border: 1px solid var(--border); color: var(--text);
  border-radius: 9px; padding: 11px 12px; font-size: 14px; font-family: inherit; width: 100%; outline: none;
}
.auth-card input:focus, .auth-card select:focus, .auth-card textarea:focus { border-color: var(--accent); }
.auth-btn { width: 100%; padding: 12px; font-size: 15px; margin-top: 4px; }
.auth-error { background: rgba(240,96,106,.1); border: 1px solid rgba(240,96,106,.35); color: #ffb3b8; border-radius: 9px; padding: 9px 12px; font-size: 13px; }
.auth-switch { text-align: center; color: var(--text-dim); font-size: 13px; margin: 4px 0 0; }
.wiz-nav { display: flex; gap: 10px; align-items: center; }
.wiz-nav .btn-mini { padding: 11px 16px; }
.wiz-nav .auth-btn { flex: 1; margin-top: 0; }
.auth-dots { display: flex; gap: 6px; justify-content: center; }
.auth-dots .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--bg-hover); }
.auth-dots .dot.on { background: var(--accent); }

/* reachability toggle (sidebar, above the account row) */
.reach-switch {
  display: flex; justify-content: space-between; width: calc(100% - 8px);
  margin: 4px 4px 12px; padding: 10px 12px;
  border: 1px solid var(--border); border-radius: 12px; background: var(--bg-2);
  transition: border-color .2s ease, background .2s ease;
}
.reach-switch:hover { background: var(--bg-hover); }
.reach-switch .sw-label { font-size: 12.5px; font-weight: 600; color: var(--text-dim); }
/* ON = online (green) */
.reach-switch.on { background: rgba(34, 197, 94, .1); border-color: rgba(34, 197, 94, .4); }
.reach-switch.on .sw-label { color: #4ade80; }
/* starting / error = amber (overrides the checked-green track) */
.reach-switch.warn { border-color: rgba(245, 158, 11, .35); }
.reach-switch.warn input:checked + .track { background: #f59e0b; }
.reach-switch.warn .sw-label { color: #fbbf24; }

/* account row + logout */
.account-row { display: flex; align-items: center; gap: 6px; border-top: 1px solid var(--border);
  flex-shrink: 0; margin: 0 -14px -14px; padding: 8px 14px 14px; background: var(--bg-2); }
.account-row .account { flex: 1; border-top: none; margin-top: 0; padding-top: 6px; }
.logout-btn { background: none; border: 1px solid var(--border); color: var(--text-faint); border-radius: 9px; padding: 8px 11px; font-size: 15px; flex-shrink: 0; }
.logout-btn:hover { color: var(--danger); border-color: rgba(240,96,106,.4); background: rgba(240,96,106,.1); }
/* Persistent rail chrome (Company / Group Chat / Inbox): the user profile pinned at the
   bottom. The TOP half used to hold a copy of the brand and the online switch, because
   these views hide the app sidebar; the top bar now spans every view, so it renders
   nothing and takes no room — `:empty` rather than a deletion, because the hook is
   still the right place for something that belongs beside a rail's own list. */
.rail-chrome-top:empty { display: none; }
.rail-chrome-top { position: sticky; top: 0; z-index: 3; display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 12px 12px 10px; border-bottom: 1px solid var(--border); background: var(--bg-2); flex-shrink: 0; }
.rail-chrome-top .brand-logo { font-size: 22px; display: inline-flex; align-items: center; }
.rail-chrome-top .wordmark { font-size: 15px; }
.rail-chrome-top .rail-reach { margin-left: auto; }
.rail-foot.account-row { position: sticky; bottom: 0; z-index: 3; margin: 0; border-top: 1px solid var(--border);
  background: var(--bg-2); padding: 8px 12px 12px; flex-shrink: 0; }
.cn-rail .rail-chrome-top { margin: -18px -14px 4px; }
.cn-rail .rail-foot.account-row { margin: 4px -14px -18px; }
/* recents "see more / show less" toggle */
.conv-more { width: 100%; text-align: left; background: none; border: none; color: var(--accent-2);
  font-size: 12.5px; font-weight: 600; cursor: pointer; padding: 7px 10px; border-radius: 8px; }
.conv-more:hover { background: var(--bg-hover); }

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: var(--bg-3); border-radius: 8px; border: 2px solid var(--bg-2); }
::-webkit-scrollbar-thumb:hover { background: var(--bg-hover); }

/* ---- Agent Organization (P2P v2) ---- */
.org-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 22px; align-items: start; }
@media (max-width: 880px) { .org-grid { grid-template-columns: 1fr; } }
.org-chart { display: flex; flex-direction: column; gap: 6px; }
.org-node { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 8px 11px; background: var(--bg-2); border: 1px solid var(--border); border-radius: 10px; }
.org-node-name { font-weight: 600; }
.org-node-lvl { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--accent); background: rgba(122,108,255,.12); padding: 2px 7px; border-radius: 20px; }
.org-node-dom { font-size: 12px; color: var(--text-faint); }
.org-consult-form { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }
.org-consult-form label { font-size: 12px; color: var(--text-faint); margin-top: 4px; }
.org-consult-form select, .org-consult-form textarea { width: 100%; background: var(--bg-2); border: 1px solid var(--border); color: var(--text); border-radius: 9px; padding: 9px 11px; font: inherit; }
.org-consult-form textarea { resize: vertical; }
.org-consult-actions { display: flex; gap: 8px; margin-top: 8px; }
.org-consult-head { font-size: 13px; color: var(--text-faint); border-bottom: 1px solid var(--border); padding-bottom: 8px; margin-bottom: 10px; }
.org-consult-head b { color: var(--text); }
.org-peers { margin-top: 26px; border-top: 1px solid var(--border); padding-top: 18px; }
.peers-self { background: var(--bg-2); border: 1px solid var(--border); border-radius: 10px; padding: 12px 14px; margin-bottom: 12px; }
.peers-self-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.peers-label { font-size: 12px; color: var(--text-faint); margin-bottom: 4px; }
.peer-token { font-family: ui-monospace, monospace; font-size: 12px; color: var(--accent); word-break: break-all; }
.peers-token-wrap { flex: 1; min-width: 180px; }
.peer-token-input { width: 100%; margin-top: 4px; background: var(--bg-3); border: 1px solid var(--border); color: var(--text); border-radius: 8px; padding: 7px 10px; font: 12px ui-monospace, monospace; }
.peers-self-actions { display: flex; gap: 6px; }
.peers-hint { font-size: 12px; color: var(--text-faint); margin-top: 8px; }
.peers-hint code { color: var(--text); }
.peers-add { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.peers-add input { flex: 1; min-width: 130px; background: var(--bg-2); border: 1px solid var(--border); color: var(--text); border-radius: 9px; padding: 9px 11px; font: inherit; }
.peers-list { display: flex; flex-direction: column; gap: 6px; }
.peer-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 8px 11px; background: var(--bg-2); border: 1px solid var(--border); border-radius: 10px; }
.peer-row .peer-name { font-weight: 600; }
.peer-row .peer-url { font-size: 12px; color: var(--text-faint); flex: 1; }
.peer-state { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-faint); }
.peer-state.on { color: #46c98b; }
.peers-discovered { margin-bottom: 12px; }
.peers-disc-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
.peer-row.found { border-style: dashed; }
.peer-row.found .btn-mini { flex-shrink: 0; }

/* Agent Organization onboarding + members */
.org-onboarding { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 22px; }
.org-choice-card { background: var(--bg-2); border: 1px solid var(--border); border-radius: 14px; padding: 22px; }
.org-choice-ico { width: 44px; height: 44px; border-radius: 12px; background: var(--accent); color: var(--on-accent); display: flex; align-items: center; justify-content: center; font-size: 22px; margin-bottom: 14px; }
.org-choice-card h2 { margin: 0 0 8px; font-size: 18px; }
.org-choice-card p { margin: 0 0 18px; color: var(--text-faint); font-size: 13px; }
.org-choice-form { display: flex; flex-direction: column; gap: 6px; }
.org-choice-form label { font-size: 12px; color: var(--text-faint); margin-top: 4px; }
.org-choice-form input { width: 100%; background: var(--bg-1); border: 1px solid var(--border); color: var(--text); border-radius: 9px; padding: 9px 11px; font: inherit; }
.org-choice-form button { margin-top: 10px; }
.org-members { display: flex; flex-direction: column; gap: 8px; }
.org-member-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 10px 12px; background: var(--bg-2); border: 1px solid var(--border); border-radius: 10px; }
.org-member-name { font-weight: 600; }
.org-member-role { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; padding: 2px 7px; border-radius: 20px; }
.org-member-role.owner { color: var(--on-accent); background: var(--accent); }
.org-member-role.admin { color: var(--accent); background: rgba(122,108,255,.12); }
.org-member-role.member { color: var(--text-faint); background: rgba(128,128,128,.12); }
.org-member-extra { font-size: 12px; color: var(--text-faint); margin-left: auto; }

/* Simplified Agent Organization: profile + network + skills */
.org-profile { margin-bottom: 10px; }
.org-profile-card { background: var(--bg-2); border: 1px solid var(--border); border-radius: 14px; padding: 18px; max-width: 520px; }
.org-profile-head { display: flex; align-items: center; gap: 14px; margin-bottom: 18px; }
.org-avatar { width: 52px; height: 52px; border-radius: 50%; background: var(--accent); color: var(--on-accent); display: flex; align-items: center; justify-content: center; font-size: 18px; font-weight: 600; flex-shrink: 0; }
.org-avatar-mini { width: 38px; height: 38px; border-radius: 50%; background: rgba(122,108,255,.15); color: var(--accent); display: flex; align-items: center; justify-content: center; font-size: 14px; font-weight: 600; flex-shrink: 0; }
.org-profile-name { font-size: 17px; font-weight: 600; }
.org-profile-meta { font-size: 13px; color: var(--text-faint); }
.org-network { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 14px; }
.org-network-card { background: var(--bg-2); border: 1px solid var(--border); border-radius: 12px; padding: 14px; }
.org-network-card.remote { border-left: 3px solid var(--accent); }
.org-network-head { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.org-network-name { font-weight: 600; }
.org-network-meta { font-size: 12px; color: var(--text-faint); }
.org-skill-list { display: flex; flex-wrap: wrap; gap: 6px; }
.org-skill { font-size: 12px; background: rgba(122,108,255,.12); color: var(--accent); padding: 4px 10px; border-radius: 20px; }
.org-skill.none { background: rgba(128,128,128,.1); color: var(--text-faint); }

/* Agent Organization tabs */
.org-tabs { display: flex; gap: 6px; border-bottom: 1px solid var(--border); margin-bottom: 22px; }
.org-tab { background: transparent; border: none; color: var(--text-faint); padding: 10px 16px; font: inherit; cursor: pointer; border-bottom: 2px solid transparent; margin-bottom: -1px; }
.org-tab:hover { color: var(--text); }
.org-tab.active { color: var(--text); border-bottom-color: var(--accent); }

/* Agent Organization messages */
.org-messages-layout { display: flex; gap: 14px; height: 520px; max-height: 70vh; }
.org-message-peers { width: 220px; flex-shrink: 0; display: flex; flex-direction: column; gap: 6px; overflow-y: auto; }
.org-message-peer { display: flex; align-items: center; gap: 10px; padding: 10px 12px; background: var(--bg-2); border: 1px solid var(--border); border-radius: 10px; cursor: pointer; }
.org-message-peer:hover { background: var(--bg-hover); }
.org-message-peer.active { border-color: var(--accent); background: var(--accent-soft); }
.org-message-peer .peer-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--text-faint); }
.org-message-peer.enabled .peer-dot { background: var(--ok); }
.org-message-peer-name { font-weight: 600; font-size: 13px; }
.org-message-peer-url { font-size: 11px; color: var(--text-faint); overflow: hidden; text-overflow: ellipsis; }
.org-message-thread { flex: 1; display: flex; flex-direction: column; background: var(--bg-2); border: 1px solid var(--border); border-radius: 12px; overflow: hidden; }
.org-message-header { padding: 12px 14px; border-bottom: 1px solid var(--border); font-weight: 600; }
.org-message-header small { display: block; color: var(--text-faint); font-weight: 400; font-size: 12px; margin-top: 2px; }
.org-message-list { flex: 1; overflow-y: auto; padding: 14px; display: flex; flex-direction: column; gap: 10px; }
.org-message-empty { flex: 1; display: flex; align-items: center; justify-content: center; color: var(--text-faint); font-size: 14px; }
.org-message-bubble { max-width: 78%; padding: 10px 12px; border-radius: 12px; font-size: 13.5px; line-height: 1.45; }
.org-message-bubble.sent { align-self: flex-end; background: var(--user-bubble); border-bottom-right-radius: 4px; }
.org-message-bubble.received { align-self: flex-start; background: var(--bg-3); border-bottom-left-radius: 4px; }
.org-message-bubble .msg-time { display: block; font-size: 11px; color: var(--text-faint); margin-top: 6px; }
.org-message-bubble.delivery-fail { opacity: .7; border: 1px solid var(--danger); }
.org-message-input { display: flex; gap: 8px; padding: 12px 14px; border-top: 1px solid var(--border); }
.org-message-input input { flex: 1; background: var(--bg-3); border: 1px solid var(--border); color: var(--text); border-radius: 9px; padding: 9px 11px; font: inherit; }
.org-message-input button { flex-shrink: 0; }

/* Admin-controlled org settings */
.org-settings { display: flex; flex-direction: column; gap: 22px; }
.org-settings-section { background: var(--bg-2); border: 1px solid var(--border); border-radius: 12px; padding: 16px; }
.org-settings-section .side-section-title { margin: 0 0 10px; }
.invite-create { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.invite-create select,
.invite-create input { background: var(--bg-3); border: 1px solid var(--border); color: var(--text); border-radius: 8px; padding: 8px 10px; font: inherit; }
.invite-create input { width: 90px; }
.invite-create button { flex-shrink: 0; }
.invites-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.invites-table th { text-align: left; color: var(--text-faint); font-weight: 500; padding: 8px 10px; border-bottom: 1px solid var(--border); }
.invites-table td { padding: 10px; border-bottom: 1px solid var(--border); }
.invites-table code { font-size: 12px; background: var(--bg-3); padding: 3px 6px; border-radius: 5px; }
.org-members-list { display: flex; flex-direction: column; gap: 8px; }
.org-member-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 10px 12px; background: var(--bg-3); border: 1px solid var(--border); border-radius: 10px; }
.org-member-row select { background: var(--bg-2); border: 1px solid var(--border); color: var(--text); border-radius: 6px; padding: 5px 8px; font: inherit; }
.btn-danger { background: var(--danger); color: #fff; border: none; }
.btn-danger:hover { filter: brightness(1.1); }

/* ---- Agent Swarm (Kimi-style agent boxes) ---- */
.swarm-head { margin-bottom: 14px; }
.org-swarm { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 16px; }
.swarm-card {
  background: linear-gradient(145deg, var(--bg-2), #1a1c24);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  transition: transform .12s, box-shadow .12s, border-color .12s;
  position: relative;
  overflow: hidden;
}
.swarm-card:hover { transform: translateY(-3px); border-color: var(--accent); box-shadow: 0 8px 24px rgba(0,0,0,.35); }
.swarm-card.remote { border-left: 3px solid var(--accent); }
.swarm-card .swarm-glow {
  position: absolute; top: -30px; right: -30px; width: 80px; height: 80px;
  border-radius: 50%; background: radial-gradient(circle, rgba(255,255,255,.12), transparent 70%);
  pointer-events: none;
}
.swarm-head-row { display: flex; align-items: center; gap: 12px; }
.swarm-avatar {
  width: 44px; height: 44px; border-radius: 12px;
  background: var(--accent-soft); color: var(--accent);
  display: flex; align-items: center; justify-content: center;
  font-size: 20px; flex-shrink: 0;
}
.swarm-title { font-weight: 600; font-size: 15px; }
.swarm-peer { font-size: 11px; color: var(--text-faint); }
.swarm-type {
  align-self: flex-start; font-size: 10px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--accent); background: rgba(122,108,255,.12); padding: 3px 8px; border-radius: 20px;
}
.swarm-skills { display: flex; flex-wrap: wrap; gap: 5px; min-height: 28px; }
.swarm-skill { font-size: 11px; background: var(--bg-3); color: var(--text-dim); padding: 3px 8px; border-radius: 20px; }
.swarm-actions { display: flex; gap: 6px; margin-top: auto; }
.swarm-actions button { flex: 1; font-size: 12px; padding: 7px 0; border-radius: 8px; }

/* ---- A2A Feed (observed external consultations) ---- */
.org-feed { display: flex; flex-direction: column; gap: 10px; }
.feed-empty { color: var(--text-faint); padding: 30px; text-align: center; }
.feed-item {
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 12px;
  overflow: hidden; cursor: pointer; transition: border-color .12s;
}
.feed-item:hover { border-color: var(--accent); }
.feed-item.incoming { border-left: 3px solid var(--ok); }
.feed-item.outgoing { border-left: 3px solid var(--accent); }
.feed-summary { display: flex; align-items: center; gap: 12px; padding: 12px 14px; }
.feed-icon { font-size: 18px; flex-shrink: 0; }
.feed-main { flex: 1; min-width: 0; }
.feed-task { font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.feed-meta { font-size: 12px; color: var(--text-faint); }
.feed-time { font-size: 11px; color: var(--text-faint); flex-shrink: 0; }
.feed-transcript {
  background: #0b0c10; border-top: 1px solid var(--border);
  padding: 14px; font-size: 13px; line-height: 1.55;
  max-height: 360px; overflow-y: auto; white-space: pre-wrap;
}

/* ---- Connections sidebar section ---- */
.connection-row {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 7px 8px;
  border-radius: 9px;
  color: var(--text);
  font-size: 13.5px;
  transition: background .15s;
}
.connection-row:hover { background: var(--bg-hover); }
.connection-row.online .connection-dot { background: var(--ok); }
.connection-info {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 9px;
  min-width: 0;
  cursor: pointer;
}
.connection-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--text-faint);
  flex-shrink: 0;
}
.connection-meta { flex: 1; min-width: 0; }
.connection-name {
  display: flex;
  align-items: center;
  gap: 6px;
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.connection-url {
  font-size: 11px;
  color: var(--text-faint);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.connection-badge {
  background: var(--danger);
  color: #fff;
  font-size: 10px;
  min-width: 16px;
  height: 16px;
  border-radius: 8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 5px;
  flex-shrink: 0;
}
.connection-disconnect {
  opacity: 0;
  background: none;
  border: none;
  color: var(--text-faint);
  font-size: 13px;
  padding: 3px 6px;
  border-radius: 6px;
  cursor: pointer;
  flex-shrink: 0;
}
.connection-row:hover .connection-disconnect { opacity: 1; }
.connection-disconnect:hover { color: var(--danger); background: rgba(240,96,106,.12); }
.connection-empty {
  color: var(--text-faint);
  font-size: 12px;
  padding: 8px 10px;
}

/* ---- Memory view ----
   Library layout (see "LIBRARY SHELL" further down, shared with Files): the type
   chips are the tabs, groups are sections of one table, and a memory is a ROW —
   text, type, when. The categories are unchanged; only the furniture is. */
.mem-count { font-size: 13px; color: var(--text-faint); white-space: nowrap; }
.mem-expand { flex-shrink: 0; }

/* Column template for a memory row. `.mem-acts` is a fixed slot so the columns do
   not jump sideways when the hover actions appear. */
/* The icon track and the tile are ONE number — a track narrower than the tile is how
   the tile ends up sitting in the text's column. */
.mem-list.lib-table { --lib-cols: 26px minmax(0, 1fr) 168px 96px 64px; }
.mem-groups-hint { font-size: 12px; color: var(--text-faint); padding: 0 0 8px; }

/* collapsible groups — flat sections, not cards */
.mem-group { border-bottom: 1px solid var(--border); }
.mem-group:last-child { border-bottom: 0; }
.mem-group-head {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  background: none; border: none; color: var(--text-dim); font-size: 12.5px; font-weight: 600;
  padding: 12px 10px; cursor: pointer; border-radius: 10px;
}
.mem-group-head:hover { background: var(--bg-2); color: var(--text); }
.mem-caret { color: var(--text-faint); font-size: 15px; transition: transform .15s ease; flex-shrink: 0; }
.mem-group.open .mem-caret { transform: rotate(90deg); }
.mem-group-ico { font-size: 14px; flex-shrink: 0; display: inline-flex; align-items: center; }
.mem-group-ico .ico { width: 15px; height: 15px; }
.mem-group-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mem-group-count {
  flex-shrink: 0; font-size: 11.5px; font-weight: 600; color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}
.mem-group-body { display: none; flex-direction: column; padding: 0 0 6px; }
.mem-group.open .mem-group-body { display: flex; }

.mem-item {
  display: grid; grid-template-columns: var(--lib-cols); align-items: center; gap: 12px;
  padding: 9px 10px; border-radius: 10px; border-bottom: 1px solid var(--border);
  transition: background .12s;
}
.mem-item:last-child { border-bottom: 0; }
.mem-item:hover { background: var(--bg-2); }
/* Editing turns the row back into a block: a textarea, two selects and two buttons do
   not belong in a 1fr table cell. */
.mem-item:has(.mem-edit-input) { display: block; background: var(--bg-2); }
.mem-icon { --ico-sz: 26px; font-size: 15px; }
.mem-icon:not(.ico-tile) { display: inline-flex; align-items: center; justify-content: center; }
.mem-body { min-width: 0; }
.mem-text { font-size: 13.5px; line-height: 1.45; overflow-wrap: anywhere; }
.mem-cell {
  font-size: 12px; color: var(--text-faint); min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mem-when { font-variant-numeric: tabular-nums; }
/* The stacked meta line only exists on narrow screens, where the columns fold away. */
.mem-meta { display: none; font-size: 11.5px; color: var(--text-faint); margin-top: 3px; }
.mem-acts { display: flex; align-items: center; justify-content: flex-end; gap: 2px; }
.mem-score { font-size: 11px; color: var(--accent-2); font-weight: 700; flex-shrink: 0; }
.mem-del, .mem-edit { flex-shrink: 0; opacity: 0; }
.mem-item:hover .mem-del, .mem-item:hover .mem-edit { opacity: 1; }
.mem-item:focus-within .mem-del, .mem-item:focus-within .mem-edit { opacity: 1; }
.mem-src { text-transform: none; opacity: .85; }
.mem-status { text-transform: capitalize; color: var(--warn); }

/* Coarse pointers never hover, so actions that fade in are actions they cannot reach. */
@media (hover: none) {
  .mem-del, .mem-edit { opacity: .55; }
}
/* Narrow: drop the columns and let the row carry its own meta line. */
@media (max-width: 760px) {
  .mem-list.lib-table { --lib-cols: 24px minmax(0, 1fr) 64px; }
  .mem-item > .mem-cell, .lib-thead > .mem-cell { display: none; }
  .mem-meta { display: block; }
}
/* The skill a memory was learned in — the one piece of provenance worth reading at a
   glance, so it gets the accent rather than the muted treatment `.mem-src` has. */
.mem-skill { text-transform: none; color: var(--accent); font-weight: 600; }
/* Type + skill pickers, shared by the edit row and the "+ Remember" form. */
.mem-edit-class { display: flex; gap: 8px; margin: 6px 0; flex-wrap: wrap; }
.mem-edit-class select {
  background: var(--bg-2); color: var(--fg); border: 1px solid var(--border);
  border-radius: 6px; padding: 4px 8px; font-size: 13px; max-width: 100%;
}
.mem-add {
  background: var(--bg-1); border: 1px solid var(--border);
  border-radius: 10px; padding: 12px; margin-bottom: 10px;
}
.mem-add .mem-edit-input { width: 100%; }
.mem-edit-input { width: 100%; font: inherit; font-size: 14px; padding: 6px 8px; resize: vertical;
  background: var(--bg-1); color: var(--text); border: 1px solid var(--accent); border-radius: 8px; }
.mem-edit-actions { display: flex; gap: 6px; margin-top: 6px; }

/* ============================================================================
   AI OS Community Network — P2P community hub
   ========================================================================= */
.cn-hub {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: var(--rail-w) minmax(0, 1fr) 320px;
  background: var(--bg);
}
.cn-hub:has(#cn-detail.hidden) { grid-template-columns: var(--rail-w) minmax(0, 1fr) 0; }
.cn-empty { color: var(--text-faint); font-size: 13px; padding: 16px; line-height: 1.6; }
.cn-label { display: block; font-size: 12px; color: var(--text-faint); margin: 12px 0 5px; }
.cn-input {
  width: 100%; padding: 9px 11px; border: 1px solid var(--border); border-radius: 8px;
  background: var(--bg); color: var(--text); font-size: 14px; margin-bottom: 4px;
  font-family: inherit; box-sizing: border-box;
}
.cn-input:focus { outline: none; border-color: var(--accent); }
.cn-input.cn-mono { font-family: var(--mono); font-size: 12.5px; }
.cn-icon-btn {
  background: none; border: 1px solid transparent; color: var(--text-dim);
  width: 28px; height: 28px; border-radius: 7px; cursor: pointer; font-size: 14px;
  display: inline-flex; align-items: center; justify-content: center;
}
.cn-icon-btn:hover { background: var(--bg-hover); color: var(--text); }

/* ---- left rail ---- */
.cn-rail {
  border-right: 1px solid var(--border); background: var(--bg-2);
  display: flex; flex-direction: column; padding: 18px 14px; gap: 14px; overflow-y: auto;
}
.cn-rail-head { display: flex; align-items: center; gap: 10px; }
/* "‹ Company" nav box at the top of the rail (mirrors group chat's "‹ Chats") */
.cn-rail-nav-head { display: flex; align-items: center; gap: 8px; margin-top: 12px; padding-bottom: 10px; border-bottom: 1px solid var(--border); }
.cn-rail-nav-title { font-weight: 700; font-size: 15px; color: var(--text); }
.cn-logo {
  font-size: 20px; width: 40px; height: 40px; flex-shrink: 0; border-radius: 11px;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg-3); border: 1px solid var(--border);
}
.cn-rail-title { font-weight: 700; font-size: 14.5px; }
.cn-rail-sub { font-size: 11.5px; color: var(--text-faint); }
.cn-identity-card { background: var(--bg-3); border: 1px solid var(--border); border-radius: 10px; padding: 11px 12px; }
.cn-id-name { font-weight: 600; font-size: 13.5px; display: flex; align-items: center; gap: 7px; }
.cn-id-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 8px var(--ok); }
.cn-id-row { font-size: 11.5px; color: var(--text-dim); margin-top: 5px; }
.cn-id-row code { background: var(--bg); padding: 1px 5px; border-radius: 5px; font-size: 11px; }
.cn-rail-section {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 11px; text-transform: uppercase; letter-spacing: .5px; color: var(--text-faint); font-weight: 700;
  padding: 0 2px;
}
.cn-rail-list { display: flex; flex-direction: column; gap: 4px; }
.cn-rail-item {
  display: flex; align-items: center; gap: 10px; padding: 8px 9px; border-radius: 9px;
  background: none; border: 1px solid transparent; cursor: pointer; text-align: left; width: 100%; color: var(--text);
}
.cn-rail-item:hover { background: var(--bg-hover); }
.cn-rail-item.active { background: var(--accent-soft); border-color: var(--accent); }
.cn-rail-item-avatar {
  width: 32px; height: 32px; flex-shrink: 0; border-radius: 9px; background: var(--bg-3);
  display: flex; align-items: center; justify-content: center; font-weight: 700; color: var(--accent-2);
}
.cn-rail-item-text { display: flex; flex-direction: column; min-width: 0; }
.cn-rail-item-name { font-weight: 600; font-size: 13.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cn-rail-item-meta { font-size: 11px; color: var(--text-faint); }
.cn-rail-actions { display: flex; flex-direction: column; gap: 7px; margin-top: auto; padding-top: 10px; }
.cn-btn-block {
  width: 100%; padding: 9px; border-radius: 9px; border: 1px solid var(--accent);
  background: var(--accent); color: var(--on-accent); font-weight: 600; font-size: 13px; cursor: pointer;
}
.cn-btn-block:hover { background: var(--accent-2); }
.cn-btn-block.ghost { background: transparent; color: var(--text-dim); border-color: var(--border); }
.cn-btn-block.ghost:hover { background: var(--bg-hover); color: var(--text); }
.cn-btn-block.danger { background: transparent; color: var(--danger); border-color: rgba(239,68,68,.45); }
.cn-btn-block.danger:hover { background: rgba(239,68,68,.12); }

/* ==== Company redesign: full-bleed space + sidebar nav + admin + org chart ==== */
/* The Company view REPLACES the app sidebar with its own rail (a ← Back returns). */
body.cn-fullbleed #sidebar { display: none; }
body.cn-fullbleed .sidebar-toggle { display: none; }

.cn-back-btn {
  display: inline-flex; align-items: center; gap: 7px; align-self: flex-start;
  background: none; border: none; color: var(--text-dim); font-size: 12.5px; font-weight: 600;
  padding: 4px 8px 4px 4px; margin: -2px 0 2px; border-radius: 8px; cursor: pointer;
}
.cn-back-btn:hover { background: var(--bg-hover); color: var(--text); }
.cn-back-arrow { font-size: 15px; line-height: 1; }
.cn-rail-head-text { flex: 1; min-width: 0; }
.cn-rail-refresh { flex: 0 0 auto; margin-left: auto; }

/* Primary + admin navigation in the rail */
.cn-nav { display: flex; flex-direction: column; gap: 2px; }
.cn-nav-item {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  background: none; border: none; border-radius: 9px; padding: 8px 10px; cursor: pointer;
  color: var(--text-dim); font-size: 13.5px; font-weight: 500;
}
.cn-nav-item:hover { background: var(--bg-hover); color: var(--text); }
.cn-nav-item.active { background: var(--accent-soft); color: var(--text); font-weight: 600; }
.cn-nav-ico { width: 18px; flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; color: var(--text-dim); }
.cn-nav-item.active .cn-nav-ico { color: var(--text); }
.cn-nav-badge {
  margin-left: auto; background: var(--bg-3); color: var(--text-dim); border-radius: 999px;
  min-width: 18px; height: 18px; padding: 0 6px; font-size: 11px; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
}
.cn-nav-item.active .cn-nav-badge { background: var(--accent); color: var(--on-accent); }
.cn-nav-subaction {
  display: flex; align-items: center; gap: 10px; width: 100%;
  background: none; border: none; color: var(--accent); font-size: 12.5px; font-weight: 600;
  text-align: left; padding: 7px 10px; cursor: pointer; border-radius: 9px;
}
.cn-nav-subaction .cn-nav-ico { color: var(--accent); }
.cn-nav-subaction:hover { background: var(--bg-hover); }
/* Teams-you're-in sub-list nested under the Teams nav item */
.cn-nav-teams { display: flex; flex-direction: column; gap: 1px; margin: 1px 0 1px 0; }
.cn-nav-team {
  display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
  background: none; border: none; border-radius: 8px; padding: 6px 10px 6px 34px; cursor: pointer;
  color: var(--text-faint); font-size: 12.5px;
}
.cn-nav-team:hover { background: var(--bg-hover); color: var(--text); }
.cn-nav-team.active { color: var(--text); background: var(--bg-3); }
.cn-nav-team-ico { flex: 0 0 auto; font-size: 12px; }
.cn-nav-team-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.cn-nav-admin { display: flex; flex-direction: column; gap: 2px; padding-top: 8px; margin-top: 4px; border-top: 1px solid var(--border); }
.cn-nav-section-title {
  font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--text-faint); padding: 4px 10px 2px;
}

/* Admin sub-page header (one focused screen per admin nav item) */
.cn-admin-pagehead { margin: 2px 2px 14px; }
.cn-admin-pagehead h2 { margin: 0; font-size: 18px; }
.cn-admin-pagehead p { margin: 4px 0 0; color: var(--text-dim); font-size: 13px; max-width: 620px; line-height: 1.5; }

/* ---- Overview: the org hierarchy ---- */
.cn-overview { display: flex; flex-direction: column; gap: 18px; max-width: 960px; }
.cn-org-legend {
  display: flex; flex-wrap: wrap; gap: 14px; align-items: center; font-size: 12px;
  color: var(--text-dim); background: var(--bg-2); border: 1px solid var(--border);
  border-radius: 12px; padding: 10px 14px;
}
.cn-org-leg { display: inline-flex; align-items: center; gap: 6px; }
.cn-org-legend .ico, .cn-org-tier-h .ico, .cn-org-team-h .ico {
  width: 14px; height: 14px; flex-shrink: 0; color: var(--text-faint);
}
.cn-org-tier { display: flex; flex-direction: column; gap: 9px; }
.cn-org-tier-h {
  display: flex; align-items: center; gap: 7px;
  font-size: 12px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: var(--text-dim);
}
.cn-org-row { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 10px; }
.cn-org-team .cn-org-row { grid-template-columns: 1fr; }
.cn-org-card { cursor: default; }
.cn-org-card:hover { border-color: var(--border); background: var(--bg-2); }
.cn-org-card.active:hover { border-color: var(--accent); background: var(--accent-soft); }
.cn-org-node {
  display: inline-flex; align-items: center; gap: 8px; background: var(--bg-2);
  border: 1px solid var(--border); border-radius: 11px; padding: 8px 12px; min-width: 0;
}
.cn-org-node.you { border-color: var(--accent); background: var(--accent-soft); }
.cn-org-kind { font-size: 15px; flex: 0 0 auto; }
.cn-org-name { font-weight: 600; font-size: 13.5px; white-space: nowrap; }
.cn-org-job { color: var(--text-faint); font-size: 12px; border-left: 1px solid var(--border); padding-left: 8px; }
.cn-org-teams { display: flex; flex-wrap: wrap; gap: 12px; }
.cn-org-team { background: var(--bg-2); border: 1px solid var(--border); border-radius: 14px; padding: 12px 14px; min-width: 240px; }
.cn-org-team-h { display: flex; align-items: center; gap: 7px; font-weight: 700; font-size: 13.5px; margin-bottom: 9px; }
.cn-org-team .cn-org-node { background: var(--bg); }

/* ---- People & roles: Odoo-style directory → detail → org chart ---- */
.cn-people-wrap { display: flex; flex-direction: column; }
.cn-people-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.cn-people-head > div { min-width: 0; }
.cn-people-addbtn { flex: 0 0 auto; white-space: nowrap; }
.cn-ppl-addcol { max-width: 520px; }
.cn-ppl-addcol .cn-ppl-addsubmit { margin-top: 14px; }
/* Empty seat slots (People & roles) */
.cn-ppl-slot { border-style: dashed; align-items: center; }
.cn-ppl-slot:hover { border-color: var(--accent); background: var(--bg-hover); }
.cn-ppl-slot-plus {
  flex: 0 0 auto; width: 40px; height: 40px; border-radius: 9px; display: inline-flex;
  align-items: center; justify-content: center; font-size: 22px; color: var(--text-dim);
  border: 1px dashed var(--border);
}
/* Person / AI segmented toggle on the add form */
.cn-seg { display: inline-flex; gap: 4px; background: var(--bg-3); border-radius: 10px; padding: 3px; margin-bottom: 16px; }
.cn-seg-btn { display: inline-flex; align-items: center; gap: 7px; border: none; background: none; padding: 7px 14px; border-radius: 8px; cursor: pointer; color: var(--text-dim); font-size: 13px; font-weight: 600; }
.cn-seg-btn .ico { width: 15px; height: 15px; flex-shrink: 0; }
.cn-seg-btn.active { background: var(--bg-2); color: var(--text); }
.cn-ppl-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 12px; }
.cn-ppl-card {
  display: flex; gap: 12px; text-align: left; background: var(--bg); border: 1px solid var(--border);
  border-radius: 12px; padding: 12px 14px; cursor: pointer; align-items: flex-start; width: 100%;
}
.cn-ppl-card:hover { border-color: var(--accent); background: var(--bg-hover); }
.cn-ppl-avatar {
  flex: 0 0 auto; width: 40px; height: 40px; border-radius: 9px; display: inline-flex;
  align-items: center; justify-content: center; font-weight: 700; font-size: 16px;
  color: #fff; background: hsl(var(--ava-h, 260), 48%, 48%);
}
.cn-ppl-avatar.lg { width: 56px; height: 56px; font-size: 22px; border-radius: 12px; }
.cn-ppl-info { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.cn-ppl-name { font-weight: 600; font-size: 14px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.cn-ppl-job { color: var(--text-dim); font-size: 12.5px; }
.cn-ppl-meta { color: var(--text-faint); font-size: 12px; }
.cn-ppl-card .cn-role-chips { margin-top: 4px; display: flex; flex-wrap: wrap; gap: 4px; }

.cn-ppl-back {
  background: none; border: none; color: var(--text-dim); font-size: 13px; font-weight: 600;
  cursor: pointer; padding: 4px 6px; border-radius: 8px; margin-bottom: 10px;
}
.cn-ppl-back:hover { background: var(--bg-hover); color: var(--text); }
.cn-ppl-detail { border: 1px solid var(--border); border-radius: 14px; background: var(--bg); overflow: hidden; }
.cn-ppl-dhead { display: flex; align-items: center; gap: 14px; padding: 18px 20px; border-bottom: 1px solid var(--border); background: var(--bg-2); }
.cn-ppl-dhead-text { flex: 1; min-width: 0; }
.cn-ppl-dname { font-size: 18px; font-weight: 700; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.cn-ppl-djob { color: var(--text-dim); font-size: 13px; margin-top: 2px; }
.cn-ppl-dbody { display: grid; grid-template-columns: 1fr 328px; gap: 0; }
.cn-ppl-dcol { padding: 18px 20px; min-width: 0; }
.cn-ppl-dcol + .cn-ppl-dcol { border-left: 1px solid var(--border); }
.cn-ppl-org { background: var(--bg-2); }
.cn-ppl-field { margin-bottom: 18px; }
.cn-ppl-field .cn-role-opts { margin-top: 6px; }
/* Multi-role picker: a person may hold several job roles, one marked primary. */
.cn-jobrole-list { display: flex; flex-direction: column; gap: 2px; margin-top: 6px; }
.cn-jobrole-row { display: flex; align-items: center; gap: 8px; padding: 5px 8px; border-radius: 6px; cursor: pointer; }
.cn-jobrole-row:hover { background: var(--bg-3); }
.cn-jobrole-row.pending { opacity: .75; font-style: italic; }
.cn-jobrole-name { flex: 1; min-width: 0; }   /* icon + gap: see .cn-role-optname below */
.cn-jobrole-primary { display: flex; align-items: center; gap: 4px; font-size: 11px; color: var(--text-faint); cursor: pointer; }

/* Company-authored job roles (Admin → Job roles). */
.cn-corole-row { display: flex; align-items: center; gap: 10px; padding: 10px 0; border-bottom: 1px solid var(--border); }
.cn-corole-row:last-child { border-bottom: 0; }
.cn-corole-main { flex: 1; min-width: 0; }
.cn-corole-name { display: flex; align-items: center; gap: 7px; font-weight: 600; }
.cn-corole-name .ico { width: 15px; height: 15px; flex-shrink: 0; color: var(--text-faint); }
.cn-corole-sub { font-size: 12px; color: var(--text-faint); }
.cn-corole-grid { display: grid; grid-template-columns: 2fr 70px 1.4fr; gap: 10px; }
.cn-role-form { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--border); }
.cn-role-form .cn-label { display: block; margin-top: 12px; }
.cn-role-persona { min-height: 96px; font-family: inherit; resize: vertical; }
.cn-role-opt small { display: block; color: var(--text-faint); font-size: 11px; }
@media (max-width: 640px) { .cn-corole-grid { grid-template-columns: 1fr; } }

/* "What their AI can use" — the resolved effect of the selected role + grants. */
.cn-ppl-effective { padding-bottom: 16px; border-bottom: 1px solid var(--border); }
.cn-eff-row { display: flex; gap: 8px; align-items: baseline; margin: 6px 0; }
.cn-eff-row > div { display: flex; flex-wrap: wrap; gap: 4px; min-width: 0; }
.cn-eff-label { flex: 0 0 74px; font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-faint); }
.cn-org-chart-title { font-size: 12px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--text-dim); margin-bottom: 12px; }
.cn-org-chain { display: flex; flex-direction: column; gap: 6px; }
.cn-org-line {
  display: flex; align-items: center; gap: 9px; padding: 7px 9px; border-radius: 10px;
  margin-left: calc(var(--d, 0) * 20px); border: 1px solid transparent;
}
.cn-org-line.clickable { cursor: pointer; }
.cn-org-line.clickable:hover { background: var(--bg-hover); }
.cn-org-line.self { background: var(--accent-soft); border-color: var(--accent); }
.cn-org-line .cn-ppl-avatar { width: 30px; height: 30px; font-size: 13px; border-radius: 8px; }
.cn-org-line-text { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.cn-org-line-name { font-weight: 600; font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cn-org-line-job { color: var(--text-faint); font-size: 11.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cn-org-count {
  flex: 0 0 auto; background: var(--bg-3); color: var(--text-dim); border-radius: 999px;
  min-width: 22px; height: 22px; padding: 0 6px; font-size: 11px; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
}
@media (max-width: 820px) {
  .cn-ppl-dbody { grid-template-columns: 1fr; }
  .cn-ppl-dcol + .cn-ppl-dcol { border-left: none; border-top: 1px solid var(--border); }
}
/* Members & Teams reuse the People card look */
#cn-members-grid { display: block; }   /* inner .cn-ppl-grid drives the layout */
.cn-ppl-card.active { border-color: var(--accent); background: var(--accent-soft); }
.cn-member-tile:not([data-node]) { cursor: default; }
.cn-member-tile:not([data-node]):hover { border-color: var(--border); background: var(--bg); }
.cn-ppl-name .cn-presence { margin-right: 3px; }
.cn-relay-tag { font-size: 10px; opacity: .6; }
.cn-member-tile .cn-recruit-remove { margin-left: 8px; }
/* Team cards */
.cn-team-tile { align-items: center; }
.cn-team-ava {
  --ico-sz: 40px;
  flex: 0 0 auto; width: 40px; height: 40px; border-radius: 9px; display: inline-flex;
  align-items: center; justify-content: center; font-size: 20px;
}
.cn-team-ava:not(.ico-tile) { background: var(--bg-3); }
.cn-team-arrow { margin-left: auto; align-self: center; color: var(--text-faint); font-size: 20px; }
.cn-team-ava-stack { display: flex; margin-top: 5px; }
.cn-team-ava-stack .cn-ppl-avatar { width: 24px; height: 24px; font-size: 11px; border-radius: 6px; margin-left: -6px; border: 2px solid var(--bg-2); }
.cn-team-ava-stack .cn-ppl-avatar:first-child { margin-left: 0; }
/* Team detail: members as user cards (no role/scope) */
.team-members-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 10px; margin-bottom: 14px; }
.team-member-card { align-items: center; }
/* The lead is the one member with a consequence attached, so the card says so. */
.team-member-card.is-lead { border-color: var(--accent); }
.team-lead-chip {
  font-size: 10.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  padding: 1px 6px; border-radius: 999px; color: var(--accent);
  background: color-mix(in srgb, var(--accent) 16%, transparent);
}
.team-role-sel {
  font-size: 12px; padding: 2px 6px; border-radius: 8px; max-width: 140px;
  background: var(--bg-3); border: 1px solid var(--border); color: var(--text-dim);
}
.team-role-sel:hover { color: var(--text); border-color: var(--accent); }
.team-member-card .chip-x {
  margin-left: auto; flex: 0 0 auto; width: 24px; height: 24px; border-radius: 50%;
  border: none; background: none; color: var(--text-faint); font-size: 15px; line-height: 1;
  cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
}
.team-member-card .chip-x:hover { background: rgba(239,68,68,.14); color: var(--danger); }
/* Dashed "add member" tile that matches the member cards */
.team-add-tile {
  position: relative; display: flex; align-items: center; gap: 10px; cursor: pointer;
  border: 1px dashed var(--border); border-radius: 12px; padding: 12px 14px;
  color: var(--text-dim); font-size: 13.5px; font-weight: 600; background: transparent;
}
.team-add-tile:hover { border-color: var(--accent); color: var(--text); background: var(--bg-hover); }
.team-add-plus {
  flex: 0 0 auto; width: 40px; height: 40px; border-radius: 9px; display: inline-flex;
  align-items: center; justify-content: center; font-size: 20px; border: 1px dashed var(--border);
}
.team-add-tile .team-add-select { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; }

/* The page header shows the active section name (Overview/Members/Teams);
   renderCN toggles .hidden for admin panes, which carry their own title. */
.cn-main-head h1 { font-size: 18px; }
/* People detail: role input + unified save row + field hint */
.cn-ppl-saverow { display: flex; align-items: center; gap: 12px; margin-top: 2px; }
.cn-field-hint { color: var(--text-faint); font-size: 12px; margin: 2px 0 8px; }
/* Monochrome badges. The desaturating filter that used to sit on .cn-team-ava,
   .cn-org-tier-h, .cn-org-legend, .cn-type-chip and .cn-you-badge is GONE: it existed to
   stop full-colour emoji shouting on a grey page, and there are no emoji left in them —
   drained of colour, the outline glyphs that replaced them lost the one thing carrying
   their meaning (rose person / violet AI). Anything still holding an emoji keeps the
   filter through the rule below, so nothing got louder. */
#view-community-network .cn-role-badge { background: var(--bg-3); color: var(--text-dim); border: 1px solid var(--border); }
/* The one emoji left on these pages is the one an ADMIN typed for their own role. It
   keeps the desaturation, because the reason for it — a full-colour picture shouting on
   a grey page — is exactly what a hand-picked 🎯 or 💰 would do. */
#view-community-network .cn-emoji { filter: grayscale(1); }
/* Sidebar icons: outline SVG (no fill) */
.cn-nav-ico svg, .cn-nav-team-ico svg { width: 17px; height: 17px; display: block; }
.cn-nav-section-title svg { width: 14px; height: 14px; }
.cn-logo svg { width: 22px; height: 22px; }
.cn-icon-btn svg, .cn-back-arrow svg { width: 15px; height: 15px; display: block; }
.cn-btn-block svg { width: 15px; height: 15px; vertical-align: -3px; margin-right: 4px; }
.cn-nav-section-title { display: flex; align-items: center; gap: 7px; }

/* ---- Modern toggle switch ---- */
.aios-switch { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; user-select: none; }
.aios-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.aios-switch .track {
  position: relative; flex: 0 0 auto; width: 38px; height: 22px; box-sizing: border-box;
  background: #3c3c3c; border-radius: 999px;
  transition: background .22s ease;
}
.aios-switch .track::after {
  content: ""; position: absolute; top: 3px; left: 3px; width: 16px; height: 16px;
  background: #f4f4f5; border-radius: 50%;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .5);
  transition: transform .24s cubic-bezier(.34, 1.35, .5, 1);
}
.aios-switch input:checked + .track { background: #22c55e; }
.aios-switch input:checked + .track::after { transform: translateX(16px); }
.aios-switch input:focus-visible + .track { outline: 2px solid var(--accent-2); outline-offset: 2px; }
.aios-switch input:disabled + .track { opacity: .55; cursor: default; }
.aios-switch .sw-label { font-size: 13px; font-weight: 600; color: var(--text); letter-spacing: .1px; }

/* ---- Settings pane ---- */
.cn-settings-pane { display: flex; flex-direction: column; gap: 16px; }

/* ---- Company usage dashboard (admin, company-wide) ---- */
.cn-usage-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 2px 0 14px; }
.cn-usage-seg { display: inline-flex; background: var(--bg-3); border: 1px solid var(--border); border-radius: 10px; padding: 2px; gap: 2px; }
.cn-usage-seg button { appearance: none; background: none; border: none; color: var(--text-dim); font: inherit; font-size: 12.5px; font-weight: 600; padding: 5px 11px; border-radius: 8px; cursor: pointer; }
.cn-usage-seg button:hover { color: var(--text); }
.cn-usage-seg button.on { background: var(--bg); color: var(--text); box-shadow: 0 1px 2px rgba(0,0,0,.12); }
.cn-usage-export { margin-left: auto; font-size: 12.5px; font-weight: 600; color: var(--text-dim); text-decoration: none; border: 1px solid var(--border); border-radius: 10px; padding: 6px 12px; }
.cn-usage-export:hover { color: var(--text); border-color: var(--accent); }
.cn-usage-tabs { display: flex; flex-wrap: wrap; gap: 4px; margin: 22px 0 10px; border-bottom: 1px solid var(--border); }
.cn-usage-tab { appearance: none; background: none; border: none; border-bottom: 2px solid transparent; color: var(--text-dim); font: inherit; font-size: 13px; font-weight: 600; padding: 7px 10px; margin-bottom: -1px; cursor: pointer; }
.cn-usage-tab:hover { color: var(--text); }
.cn-usage-tab.on { color: var(--accent-2); border-bottom-color: var(--accent); }
.cn-usage-list { display: flex; flex-direction: column; }
.cn-usage-lrow { display: flex; align-items: center; gap: 12px; padding: 10px 4px; border-top: 1px solid var(--border); }
.cn-usage-lrow:first-child { border-top: none; }
.cn-usage-lmain { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
.cn-usage-lname { font-size: 13.5px; font-weight: 600; display: flex; align-items: center; gap: 7px; flex-wrap: wrap; word-break: break-word; }
.cn-usage-lmeta { font-size: 11.5px; opacity: .55; font-variant-numeric: tabular-nums; }
.cn-usage-lnum { text-align: right; font-size: 13px; font-variant-numeric: tabular-nums; white-space: nowrap; display: flex; flex-direction: column; gap: 1px; min-width: 104px; }
.cn-usage-lnum b { font-weight: 700; }
.cn-usage-lnum span { font-size: 11.5px; opacity: .55; }
.cn-usage-chip { font-size: 10.5px; font-weight: 600; letter-spacing: .02em; color: var(--text-faint); background: var(--bg-3); border-radius: 6px; padding: 1px 6px; }
.cn-usage-chip.cheap { color: var(--accent-2); background: var(--accent-soft); }
.cn-usage-chip.bad { color: var(--danger); background: var(--danger-soft); }
.cn-usage-stats-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 10px; margin: 4px 0 2px; }
.cn-usage-stat { background: var(--bg); border: 1px solid var(--border); border-radius: 12px; padding: 12px 14px; }
.cn-usage-stat-n { font-size: 1.7em; font-weight: 700; line-height: 1.1; font-variant-numeric: tabular-nums; }
.cn-usage-stat-l { opacity: .6; font-size: .78em; margin-top: 2px; }
.cn-usage-subhead { font-size: .76em; text-transform: uppercase; letter-spacing: .06em; opacity: .55; font-weight: 700; margin: 22px 0 8px; display: flex; align-items: center; gap: 8px; }
.cn-usage-count { background: var(--bg-3); color: var(--text-dim); border-radius: 9px; padding: 1px 7px; font-size: 11px; letter-spacing: 0; }
.cn-usage-members { display: flex; flex-direction: column; gap: 0; }
.cn-usage-mrow { display: flex; align-items: center; gap: 12px; padding: 9px 4px; border-top: 1px solid var(--border); }
.cn-usage-mrow:first-child { border-top: none; }
.cn-usage-mrow .cn-ppl-avatar { width: 32px; height: 32px; font-size: 13px; border-radius: 8px; flex: 0 0 auto; }
.cn-usage-mmain { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
.cn-usage-mname { font-size: 13.5px; font-weight: 600; display: flex; align-items: center; gap: 8px; }
.cn-usage-you { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; background: var(--accent-soft); color: var(--accent-2); border-radius: 6px; padding: 1px 6px; }
.cn-usage-pending { font-size: 10.5px; font-weight: 600; color: var(--text-faint); background: var(--bg-3); border-radius: 6px; padding: 1px 7px; }
.cn-usage-bar { height: 6px; border-radius: 4px; background: var(--bg-3); overflow: hidden; }
.cn-usage-bar > span { display: block; height: 100%; border-radius: 4px; background: var(--accent); min-width: 2px; }
.cn-usage-mnum { text-align: right; font-size: 13px; font-variant-numeric: tabular-nums; white-space: nowrap; display: flex; flex-direction: column; gap: 1px; min-width: 96px; }
.cn-usage-mnum b { font-weight: 700; }
.cn-usage-mturns { font-size: 11px; opacity: .55; }
.cn-usage-note { font-size: 12px; color: var(--text-faint); margin: 10px 0 0; }
.cn-usage-days { display: flex; flex-direction: column; gap: 0; }
.cn-usage-drow { display: flex; justify-content: space-between; gap: 12px; padding: 7px 4px; border-top: 1px solid var(--border); font-size: 13px; font-variant-numeric: tabular-nums; }
.cn-usage-drow:first-child { border-top: none; }
.cn-usage-drow > span:first-child { opacity: .8; }
.cn-usage-dcache { opacity: .6; min-width: 90px; text-align: right; }
.cn-usage-empty { opacity: .7; font-size: 13.5px; }
.cn-settings-card { background: var(--bg-2); border: 1px solid var(--border); border-radius: 12px; padding: 16px 18px; }
.cn-settings-card.danger { border-color: rgba(239,68,68,.3); }
/* Company → Skills — cards grouped by AUDIENCE.
   The groups are the model this page sets (who each skill is for), so they are the
   structure rather than a column: a card sits under Company / Team / Role /
   Individual and MOVES the moment its scope saves. Failure stays loud inside the
   group and gets its own filter, because five skills failing every morning with
   nobody told is why this page exists at all. */
/* The same two controls the library pages use — a search pill and a compact select.
   These are shared by Company → Skills and by Heartbeat's find bar, so they were the
   last place in the app still wearing the old square-input look. */
.skl-toolbar { display: flex; align-items: center; gap: 10px; margin: 2px 0 10px; flex-wrap: wrap; }
.skl-filter {
  flex: 1 1 220px; min-width: 0; max-width: 300px; height: 36px; padding: 0 14px;
  font: inherit; font-size: 13px; color: var(--text);
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 999px; outline: none;
}
.skl-filter::placeholder { color: var(--text-faint); }
.skl-filter:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.skl-alert { font-size: 12px; font-weight: 600; color: var(--danger); cursor: pointer;
  background: transparent; border: 1px solid transparent; border-radius: 999px; padding: 3px 10px; }
.skl-alert:hover { border-color: var(--danger); }
.skl-alert.on { background: color-mix(in srgb, var(--danger) 16%, transparent); border-color: var(--danger); }
.skl-allok { font-size: 12px; color: var(--text-faint); }
.skl-warn { font-size: 12px; color: var(--warn, #d98324); }

/* "Group by" — the same control on the three pages that list skills (Skills,
   Heartbeat, Company → Skills), so the way you re-cut a list is one thing to learn.
   Sized off .market-cat, which is the picker it sits beside on the Skills page. */
.skl-groupby { background: var(--bg-2); border: 1px solid var(--border); color: var(--text-dim);
  border-radius: 999px; height: 36px; padding: 0 12px; font: inherit; font-size: 13px; }
.skl-groupby:hover { color: var(--text); }
.skl-groupby:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
/* Heartbeat's find controls ride the right-hand end of the unread bar, so the count
   stays the first thing read on the page. */
.skl-find { display: flex; align-items: center; gap: 8px; margin-left: auto; flex-wrap: wrap; }
.skl-find .skl-filter { flex: 0 1 240px; }

.skl-group { margin-top: 18px; }
.skl-group-h { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  padding: 0 2px 8px; border-bottom: 1px solid var(--border); margin-bottom: 12px; }
.skl-group-t { font-size: 13px; font-weight: 700; letter-spacing: .01em; }
.skl-group-n { font-size: 11px; color: var(--text-faint);
  background: var(--bg-3); border-radius: 999px; padding: 1px 7px; }
.skl-group-bad { font-size: 11px; font-weight: 600; color: var(--danger); }
.skl-group-hint { font-size: 11.5px; color: var(--text-faint); }

/* auto-fill, so the cards reflow instead of stretching to one per row on a wide screen */
.skl-cards { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(330px, 1fr)); }
.skl-card {
  display: flex; flex-direction: column; gap: 8px; min-width: 0;
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 12px;
  padding: 13px 14px; border-left: 3px solid transparent;
}
.skl-card:hover { border-color: var(--text-faint); }
.skl-card.failing { border-left-color: var(--danger); background: rgba(239,68,68,.06); }
.skl-card.scheduled { border-left-color: var(--ok); }
.skl-card.off { opacity: .72; }
.skl-card.off:hover { opacity: 1; }
.skl-card-top { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; min-width: 0; }
/* The app's icon tile, at list size — the same glyph and hue this skill wears in the
   catalog, on Heartbeat and on its own page. */
.skl-card-icon { --ico-sz: 26px; font-size: 15px; line-height: 1; }
.skl-card-state { display: flex; flex-direction: column; gap: 2px; font-size: 12px; }
.skl-needs { color: var(--text-faint); font-size: 11px; }
.skl-card-controls { display: flex; gap: 8px; flex-wrap: wrap; margin-top: auto; padding-top: 4px; }
/* Wrap rather than shrink: three squeezed pickers turned a role name into
   "Product Data M". Two per line, the third drops under them. */
.skl-field { display: flex; flex-direction: column; gap: 3px; flex: 1 1 132px; min-width: 124px; }
.skl-field > span { font-size: 10px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--text-faint); }

/* State reads at a glance: a dot for the verdict, the detail under it, quietly. */
.skl-state { display: inline-flex; align-items: center; gap: 6px; color: var(--text-dim); }
.skl-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--text-faint); flex: none; }
.skl-state.ok { color: var(--ok); }
.skl-state.ok .skl-dot { background: var(--ok); }
.skl-state.bad { color: var(--danger); font-weight: 600; }
.skl-state.bad .skl-dot { background: var(--danger); }
.skl-state.off { color: var(--text-faint); }
.skl-state.off .skl-dot { background: transparent; border: 1px solid var(--text-faint); }
.skl-why { color: var(--text-faint); font-size: 11px; padding-left: 12px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.skl-chip {
  font-size: 10px; text-transform: uppercase; letter-spacing: .04em; padding: 1px 6px;
  border-radius: 999px; color: var(--accent);
  background: color-mix(in srgb, var(--accent) 16%, transparent);
}
/* Findings waiting on somebody reads as work, not as a feature label. */
.skl-chip.rows { color: var(--warn, #d98324);
  background: color-mix(in srgb, var(--warn, #d98324) 16%, transparent); }
/* What the skill is ABOUT is context, not status — it must not compete with the two
   chips that mean something is waiting. Shown only when the category is not already
   the heading above the card. */
.skl-chip.cat { color: var(--text-faint); background: var(--bg-3);
  text-transform: none; letter-spacing: 0; font-size: 10.5px; }
/* The name is a link into the skill; it must not look like a button. */
.skl-open { background: none; border: 0; padding: 0; font: inherit; font-weight: 600;
  font-size: 13.5px; color: inherit; cursor: pointer; text-align: left; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.skl-open:hover { text-decoration: underline; }
.skl-scope, .skl-ref, .skl-owner {
  width: 100%; font-size: 12px; padding: 4px 8px; border-radius: 8px;
  background: var(--bg-3); border: 1px solid var(--border); color: var(--text);
}
@media (max-width: 560px) {
  .skl-cards { grid-template-columns: 1fr; }
  .skl-card-controls { flex-direction: column; }
}
.cn-settings-h { font-weight: 700; font-size: 14px; margin-bottom: 6px; }
.cn-settings-card.danger .cn-settings-h { color: var(--danger); }
.cn-settings-desc { font-size: 13px; color: var(--text-dim); line-height: 1.5; margin: 0 0 12px; }
/* AI capabilities & limits card — label ↔ control rows */
.cn-ops-grid { display: flex; flex-direction: column; gap: 13px; margin: 6px 0 12px; }
.cn-ops-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.cn-ops-row > span { display: flex; flex-direction: column; font-size: 13.5px; line-height: 1.35; }
.cn-ops-row > span small { color: var(--text-dim); font-size: 11.5px; margin-top: 2px; }
.cn-ops-row .cn-input { flex: none; max-width: 240px; }
.cn-ops-row .cn-ops-num { max-width: 130px; }
@media (max-width: 560px) {
  .cn-ops-row { flex-direction: column; align-items: stretch; gap: 6px; }
  .cn-ops-row .cn-input, .cn-ops-row .cn-ops-num { max-width: none; }
}
/* "Which AI does which job" — one card per function, grouped by the part of the
   product a person recognises rather than by tier or by the module that implements it.
   Deliberately the same shape as Company → Skills (.skl-group-h / .skl-cards): both
   pages ask "here are N things, which ones do you want to change", and inventing a
   second card language for the same question is how a settings page stops feeling
   like one product.

   Each card carries what that function actually COST, because "should this run on the
   cheaper model" is unanswerable without knowing whether it runs twice a week or four
   hundred times. */
.cn-policy-group { margin-top: 18px; }
.cn-policy-group-head { display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; flex-wrap: wrap; padding: 0 2px 8px; border-bottom: 1px solid var(--border); }
.cn-policy-group-head b { font-size: 13px; font-weight: 700; letter-spacing: .01em; }
.cn-policy-group-count { font-size: 11px; color: var(--text-faint);
  background: var(--bg-3); border-radius: 999px; padding: 1px 8px; white-space: nowrap; }
/* Save — and the set-the-whole-group controls — sit in the group header, next to the
   group's own summary. The single button at the foot of the card is several screens from
   the switch you just flipped, and "put every background job on the cheaper model" is one
   decision rather than nine identical clicks. */
.cn-policy-group-actions { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.cn-policy-group-save { padding: 3px 12px; font-size: 12px; line-height: 1.6; }
/* Deliberately NOT styled like the per-card segmented control: these are actions that
   move nine switches, not a display of what the group currently is. That is what the
   tally beside them is for. */
.cn-policy-bulk { display: inline-flex; border: 1px solid var(--border); border-radius: 8px;
  overflow: hidden; }
.cn-policy-bulk button { background: none; border: 0; color: var(--text-dim);
  font-size: 11.5px; padding: 4px 10px; cursor: pointer; font-family: inherit;
  white-space: nowrap; transition: background .12s, color .12s; }
.cn-policy-bulk button + button { border-left: 1px solid var(--border); }
.cn-policy-bulk button:hover { background: var(--bg-3); color: var(--text); }
.cn-policy-bulk-effort { width: auto; margin-bottom: 0; padding: 4px 8px; font-size: 11.5px; }
.cn-policy-group > small { display: block; color: var(--text-faint); font-size: 11.5px;
  margin: 6px 2px 0; }

/* auto-fill so the cards reflow instead of stretching to one per row on a wide screen */
.cn-policy-grid { display: grid; gap: 12px; margin: 12px 0 4px;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); }
.cn-policy-card {
  display: flex; flex-direction: column; gap: 6px; min-width: 0;
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 12px;
  padding: 13px 14px; border-left: 3px solid transparent;
}
.cn-policy-card:hover { border-color: var(--text-faint); }
/* A card that is NOT on its default. Among 31 of them a deliberate choice is invisible
   otherwise — you would have to know every default by heart to spot one. The left edge
   carries state here exactly as it does on a skill card. */
.cn-policy-card.moved { border-left-color: var(--accent); }
.cn-policy-card-head { display: flex; align-items: center; gap: 2px; }
.cn-policy-card-head b { font-size: 13px; line-height: 1.3; }
/* Always in the DOM, shown only while the card is off its default — the dot has to be
   able to appear and disappear as switches move, without re-rendering the whole card
   (which would throw away every other unsaved change on the page). */
.cn-policy-moved { color: var(--accent); font-style: normal; margin-left: 6px;
  font-size: 15px; line-height: 0; display: none; }
.cn-policy-card.moved .cn-policy-moved { display: inline; }
.cn-policy-card > small { color: var(--text-faint); font-size: 11.5px; line-height: 1.4; }
.cn-policy-usage { display: flex; align-items: baseline; justify-content: space-between;
  gap: 8px; font-size: 11.5px; color: var(--text-dim); margin-top: 2px; }
.cn-policy-usage b { color: var(--text); font-size: 12px; }
.cn-policy-usage.quiet { color: var(--text-faint); font-style: italic; }
.cn-policy-card .cn-usage-bar { margin: 0; }
/* `margin-top: auto` bottom-aligns the controls: a card with no spend has no bar, so
   without it the switches sit at a different height from the card beside them and the
   row reads as ragged rather than as a set of comparable choices. */
.cn-policy-controls { display: flex; align-items: center; gap: 8px; margin-top: auto; padding-top: 8px; }
.cn-policy-controls .cn-input { flex: 1; min-width: 0; font-size: 12px; padding: 5px 8px; }

/* Segmented tier control. Radios, not a <select>: the whole point of a card is that its
   state is readable without opening anything first. */
.cn-policy-seg { display: inline-flex; flex: none; border: 1px solid var(--border);
  border-radius: 8px; overflow: hidden; }
.cn-policy-seg input { position: absolute; opacity: 0; pointer-events: none; }
.cn-policy-seg label { padding: 5px 10px; font-size: 12px; cursor: pointer; user-select: none;
  color: var(--text-dim); transition: background .12s, color .12s; }
.cn-policy-seg label + input + label { border-left: 1px solid var(--border); }
.cn-policy-seg input:checked + label { background: var(--accent); color: var(--on-accent); }
/* Keyboard users have to be able to see which segment holds focus. */
.cn-policy-seg input:focus-visible + label { outline: 2px solid var(--accent); outline-offset: -2px; }
@media (max-width: 560px) {
  .cn-policy-grid { grid-template-columns: 1fr; }
  .cn-policy-group-head { flex-direction: column; align-items: flex-start; gap: 6px; }
}
.mining-optout-row { display: flex; align-items: center; gap: 8px; }
.mining-optout-row input { width: auto; margin: 0; }
details.cn-settings-card > summary.cn-limits-summary { cursor: pointer; list-style: revert; user-select: none; }
details.cn-settings-card[open] > summary.cn-limits-summary { margin-bottom: 4px; }
.cn-invite-panel .cn-copyrow { margin-bottom: 12px; }
.cn-invite-panel code { font-size: 12.5px; color: var(--accent-2); word-break: break-all; }
.cn-invite-actions { display: flex; flex-wrap: wrap; gap: 8px; }

/* ---- Add a teammate (admin-only, managed nodes) ---- */
.cn-team-seats { font-size: 12px; color: var(--text-faint); margin: -6px 0 12px; }
.cn-team-form { display: flex; flex-direction: column; }
.cn-team-form .cn-label:first-of-type { margin-top: 0; }
.cn-req { color: var(--danger); font-size: 11px; font-weight: 600; }
.cn-opt { color: var(--text-faint); font-size: 11px; font-weight: 400; }
.cn-team-submit { align-self: flex-start; margin-top: 14px; }
.cn-team-submit:disabled { opacity: .6; cursor: default; }
.cn-team-error { color: var(--danger); font-size: 12.5px; margin-top: 10px; }
.cn-team-result { margin-top: 14px; border: 1px solid var(--accent); border-radius: 10px; padding: 14px; background: var(--accent-soft); }
.cn-team-result-h { font-weight: 700; font-size: 13.5px; color: var(--accent-2); margin-bottom: 6px; }
.cn-team-result .cn-copyrow { margin-top: 8px; }
.cn-team-cred-label { font-size: 11px; color: var(--text-faint); text-transform: uppercase; letter-spacing: .04em; min-width: 92px; }
.cn-team-ws { font-size: 12.5px; color: var(--text-dim); margin: 10px 0 0; }

/* ---- Teammates roster (admin-only convert person <-> AI) ---- */
.cn-members-list { display: flex; flex-direction: column; gap: 8px; }
.cn-member-row {
  display: flex; align-items: center; gap: 12px;
  background: var(--bg); border: 1px solid var(--border); border-radius: 10px;
  padding: 10px 12px;
}
.cn-member-info { min-width: 0; flex: 1; }
.cn-member-line1 { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.cn-member-nm { font-weight: 600; font-size: 13.5px; color: var(--text); }
.cn-member-line2 { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 3px; }
.cn-member-sub { font-size: 12px; color: var(--text-dim); word-break: break-all; }
.cn-member-job { font-size: 11px; color: var(--text-faint); }
.cn-member-job::before { content: "· "; }
.cn-member-act { flex-shrink: 0; }
.cn-member-act .cn-member-convert { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.cn-member-act .cn-member-convert:disabled { opacity: .7; cursor: default; }
.cn-type-chip {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 10.5px; font-weight: 700; padding: 2px 7px; border-radius: 6px;
  text-transform: uppercase; letter-spacing: .03em; white-space: nowrap;
}
/* The glyph inside a chip is BARE — the chip is already the container, and a tile
   inside a tile is what made these read as buttons. */
.cn-type-chip .ico { width: 12px; height: 12px; flex-shrink: 0; }
.cn-type-chip.person, .cn-type-chip.virtual { background: var(--bg-3); color: var(--text-dim); }
.cn-type-chip.person .ico { color: #f2708a; }
.cn-type-chip.virtual .ico { color: #8b7ff8; }
.cn-member-status {
  font-size: 10.5px; font-weight: 600; padding: 1px 6px; border-radius: 6px;
  background: rgba(255,255,255,.06); color: var(--text-faint);
}
.cn-member-status.active { color: var(--ok); }

/* Per-member role assignment (Teammates card + Company Members grid) */
.cn-member-roles-line, .member-roles-line { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 6px; }
.cn-roles-label { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; color: var(--text-faint); }
.cn-role-chips { display: inline-flex; gap: 5px; flex-wrap: wrap; }
/* A role chip carries the role's glyph, coloured by what the role is about (ic-* sets
   --ic) while the pill itself stays the accent wash. The text is the label — the glyph
   is what makes a column of eleven of them scannable, which is the whole reason a
   member card lists them at all. */
.cn-role-chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11px; background: var(--accent-soft); color: var(--accent-2);
  border-radius: 20px; padding: 3px 9px; white-space: nowrap;
}
.cn-role-chip .ico { width: 12px; height: 12px; flex-shrink: 0; color: var(--ic, currentColor); }
.cn-role-chip.empty { background: var(--bg-3); color: var(--text-faint); }
.cn-role-editor { flex-basis: 100%; margin-top: 8px; padding: 10px; background: var(--bg); border: 1px solid var(--border); border-radius: 10px; }
.cn-role-opts { display: flex; flex-direction: column; gap: 4px; max-height: 220px; overflow-y: auto; }
.cn-role-opt { display: flex; align-items: center; gap: 8px; font-size: 13px; padding: 3px 4px; border-radius: 6px; cursor: pointer; }
/* The role's glyph in a picker row and in the job-role list — same rule for both, so a
   role looks the same whether you are choosing it or reading it back. */
.cn-role-optname, .cn-jobrole-name { display: inline-flex; align-items: center; gap: 7px; min-width: 0; }
.cn-role-optname .ico, .cn-jobrole-name .ico {
  width: 14px; height: 14px; flex-shrink: 0; color: var(--ic, var(--text-faint));
}
.cn-role-opt:hover { background: var(--bg-2); }
.cn-role-bundle { font-size: 10.5px; color: var(--text-faint); margin-left: auto; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 45%; }
.cn-role-editor-act { display: flex; align-items: center; gap: 8px; margin-top: 10px; }
.cn-role-msg { font-size: 11.5px; color: var(--danger, #e5534b); }

/* ---- project teams ---- */
.cn-team-new { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.cn-team-new input { flex: 1; min-width: 140px; }
.cn-teams-list { display: flex; flex-direction: column; gap: 12px; }
.cn-team-block {
  background: var(--bg); border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px;
}
.cn-team-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.cn-team-head .cn-team-del { margin-left: auto; }
.cn-team-members { display: flex; flex-direction: column; gap: 6px; margin: 8px 0; }
.cn-team-mrow { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.cn-team-mnm { font-size: 13px; color: var(--text); flex: 1; min-width: 100px; }
.cn-team-mrow select, .cn-team-add select, .cn-team-new select {
  font-size: 12px; padding: 3px 6px; border-radius: 7px;
  background: var(--surface); color: var(--text); border: 1px solid var(--border);
}
.cn-team-add { margin-top: 4px; }

/* ---- center column ---- */
.cn-main { display: flex; flex-direction: column; min-width: 0; min-height: 0; }
.cn-main-head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 16px;
  padding: 20px 26px 14px; border-bottom: 1px solid var(--border);
}
.cn-main-head h1 { margin: 0; font-size: 21px; }
.cn-main-head p { margin: 4px 0 0; color: var(--text-dim); font-size: 13px; max-width: 560px; }
.cn-invite-box {
  display: flex; align-items: center; gap: 10px; background: var(--bg-2); border: 1px solid var(--border);
  border-radius: 10px; padding: 8px 12px; flex-shrink: 0;
}
.cn-invite-label { display: block; font-size: 10px; text-transform: uppercase; color: var(--text-faint); letter-spacing: .5px; }
.cn-invite-box code { font-size: 12px; color: var(--accent-2); word-break: break-all; max-width: 220px; display: inline-block; }
.cn-tabs { display: flex; gap: 4px; padding: 10px 22px 0; border-bottom: 1px solid var(--border); }
.cn-tab {
  background: none; border: none; border-bottom: 2px solid transparent; color: var(--text-dim);
  padding: 9px 12px; font-size: 13.5px; font-weight: 600; cursor: pointer; margin-bottom: -1px;
}
.cn-tab:hover { color: var(--text); }
.cn-tab.active { color: var(--text); border-bottom-color: var(--accent); }
.cn-tab-count {
  font-size: 11px; background: var(--bg-3); color: var(--text-dim); border-radius: 9px; padding: 1px 7px; margin-left: 3px;
}
.cn-tab-body { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.cn-pane { flex: 1; min-height: 0; overflow-y: auto; padding: 18px 22px; }
.cn-pane.hidden { display: none; }
.cn-pane[data-pane="chat"] { padding: 0; overflow: hidden; }

/* ---- members grid ---- */
.cn-members-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 12px; }
.cn-member-card {
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 12px; padding: 14px; cursor: pointer;
  transition: border-color .15s, transform .1s;
}
.cn-member-card:hover { border-color: var(--accent); transform: translateY(-1px); }
.cn-member-card.active { border-color: var(--accent); background: var(--accent-soft); }
.cn-member-card.you { cursor: default; border-style: dashed; }
.cn-member-card.you:hover { transform: none; }
.cn-member-top { display: flex; align-items: center; gap: 8px; }
.cn-member-name { font-weight: 600; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cn-you-badge { display: inline-flex; align-items: center; gap: 4px; font-size: 10px; background: var(--accent-soft); color: var(--accent-2); padding: 2px 6px; border-radius: 6px; font-weight: 700; }
.cn-you-badge .ico { width: 11px; height: 11px; flex-shrink: 0; }
.cn-role-badge {
  font-size: 10px; font-weight: 700; padding: 1px 7px; border-radius: 6px; margin-left: auto;
  text-transform: uppercase; letter-spacing: .3px; background: var(--bg-3); color: var(--text-dim); flex-shrink: 0;
}
.cn-role-badge.role-owner { background: rgba(255,255,255,.16); color: #fff; }
.cn-role-badge.role-admin { background: rgba(255,255,255,.11); color: var(--text); }
.cn-role-badge.role-manager { background: rgba(255,255,255,.08); color: var(--text-dim); }
.cn-role-badge.role-hr { background: rgba(255,255,255,.08); color: var(--text-dim); }
.cn-role-badge.role-finance { background: rgba(255,255,255,.08); color: var(--text-dim); }
.cn-detail-name .cn-role-badge { margin-left: 6px; }
.cn-detail-knowledge {
  font-size: 13px; color: var(--text-dim); line-height: 1.5; background: var(--bg-3);
  border-radius: 9px; padding: 10px 12px; margin: 14px 0 4px;
}
.cn-role-assign { display: flex; gap: 8px; align-items: center; }
.cn-role-assign .cn-input { margin: 0; }
.cn-makeowner-btn { margin-top: 10px; font-size: 12.5px; }
/* THE DOT VOCABULARY. Two independent facts share one dot, so each gets its own
   channel — mixing them is what made the old palette misleading:

     FILL   = is a PERSON there   (solid = yes, hollow = no)
     COLOUR = do we KNOW          (green = we have an answer, grey = we don't)

   The bug that forced this: `away` (we know they've stepped away) was grey while
   an unreadable person fell back to `online` and drew a GREEN ring — so the state
   we were certain about looked deader than the state we knew nothing about. And
   grey meant both "away" and "node down", which are opposite facts about whether
   the workspace can be reached at all.

   Under the rule above, `away` and `online` are the SAME statement — "reachable,
   nobody at the desk" — which is exactly right: an AI seat never has anyone at
   the desk, and an away colleague's AI is still picking things up. */
.cn-presence { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; box-sizing: border-box; }
/* Reachable, nobody at the desk — an AI seat, or a person who has stepped away.
   NOT a filled dot: filled is how a container running 24/7 came to look like a
   person being present. Only `.active` earns the solid green. */
.cn-presence.online { background: transparent; border: 1.5px solid var(--ok); }
.cn-presence.away   { background: transparent; border: 1.5px solid var(--ok); }
/* We cannot say. Dashed, because a solid grey ring would read as a fact about the
   person rather than an admission that we have none. */
.cn-presence.unknown { background: transparent; border: 1.5px dashed var(--text-faint); opacity: .8; }
/* Nothing is answering — the one grey that is a statement, not an absence of one. */
.cn-presence.offline { background: var(--text-faint); }
/* An AI recruit runs inside this workspace — never pinged, always up. Distinct
   from "online" (a peer node that answered a heartbeat) on purpose. */
.cn-presence.local { background: var(--accent); box-shadow: 0 0 7px var(--accent); }
/* A PERSON at their desk. `active` is the only solid green anywhere in the UI. */
.cn-presence.active { background: var(--ok); box-shadow: 0 0 7px var(--ok); }
.cn-presence.idle   { background: var(--warn); box-shadow: 0 0 6px var(--warn); }

/* Presence sharing: a one-line control right under the headline. */
.cn-presence-privacy {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: -6px 0 14px; font-size: 12px; color: var(--text-faint);
}

/* Members headline: reachable-now, split person vs AI. */
.cn-presence-summary {
  display: flex; align-items: center; flex-wrap: wrap; gap: 14px;
  margin: 0 0 14px; font-size: 12.5px; color: var(--text-dim);
}
.cn-presence-summary .cn-sum-strong {
  display: inline-flex; align-items: center; gap: 6px;
  font-weight: 650; color: var(--text);
}
/* Each figure carries its own glyph, so the row reads as a set of counts rather than a
   sentence — and they are the app's glyphs, at the size a line of 12.5px text can take. */
.cn-presence-summary .cn-sum-part {
  display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;
}
.cn-presence-summary .ico { width: 14px; height: 14px; flex-shrink: 0; color: var(--text-faint); }
.cn-presence-summary .cn-sum-unknown { color: var(--text-faint); cursor: help; }
.cn-member-skills { font-size: 12.5px; color: var(--text-dim); margin: 10px 0; min-height: 17px; }
.cn-member-foot { display: flex; align-items: center; justify-content: space-between; font-size: 11.5px; }
.cn-trust { color: #d0d0d0; letter-spacing: 1px; }
.cn-trust-n { color: var(--text-faint); letter-spacing: 0; margin-left: 2px; }
.cn-member-skillcount { color: var(--text-faint); }

/* ---- detail panel ---- */
.cn-detail { border-left: 1px solid var(--border); background: var(--bg-2); overflow-y: auto; padding: 18px; }
.cn-detail.hidden { display: none; }
.cn-detail-head { display: flex; align-items: flex-start; justify-content: space-between; }
.cn-detail-name { font-weight: 700; font-size: 16px; display: flex; align-items: center; gap: 8px; }
.cn-detail-sub { font-size: 12px; color: var(--text-faint); margin-top: 4px; word-break: break-all; }
.cn-detail-stats { display: flex; gap: 10px; margin: 16px 0; }
.cn-detail-stats > div { flex: 1; background: var(--bg-3); border-radius: 10px; padding: 10px; text-align: center; }
.cn-stat-n { display: block; font-weight: 700; color: #d0d0d0; }
.cn-detail-stats > div:last-child .cn-stat-n { color: var(--accent-2); }
.cn-stat-l { font-size: 10.5px; color: var(--text-faint); }
.cn-detail-actions { display: flex; gap: 8px; }
.cn-detail-actions .btn-primary { flex: 1; }
.cn-detail-section { font-size: 11px; text-transform: uppercase; letter-spacing: .5px; color: var(--text-faint); font-weight: 700; margin: 18px 0 8px; }
.cn-detail-skills { display: flex; flex-direction: column; gap: 6px; }
.cn-skill-chip {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  background: var(--bg-3); border-radius: 8px; padding: 7px 10px; font-size: 13px;
}
.cn-skill-ask { background: none; border: none; color: var(--accent-2); cursor: pointer; font-size: 12px; font-weight: 600; }
.cn-skill-ask:hover { text-decoration: underline; }
.cn-detail-id { display: block; background: var(--bg); border-radius: 8px; padding: 8px 10px; font-size: 11px; color: var(--text-dim); word-break: break-all; }

/* ---- chat ---- */
.cn-chat { flex: 1; min-height: 0; display: grid; grid-template-columns: 170px minmax(0, 1fr); }
.cn-chat-channels { border-right: 1px solid var(--border); padding: 14px 10px; display: flex; flex-direction: column; gap: 3px; overflow-y: auto; }
.cn-channel {
  background: none; border: none; color: var(--text-dim); text-align: left; padding: 7px 10px;
  border-radius: 8px; cursor: pointer; font-size: 13.5px; font-weight: 500;
}
.cn-channel:hover { background: var(--bg-hover); color: var(--text); }
.cn-channel.active { background: var(--accent-soft); color: var(--accent-2); font-weight: 600; }
.cn-channel.add { color: var(--text-faint); margin-top: 6px; }
.cn-chat-main { display: flex; flex-direction: column; min-height: 0; }
.cn-chat-messages { flex: 1; overflow-y: auto; padding: 18px 20px; display: flex; flex-direction: column; gap: 12px; }
.cn-msg { max-width: 78%; align-self: flex-start; }
.cn-msg.mine { align-self: flex-end; text-align: right; }
.cn-msg-meta { font-size: 11px; color: var(--text-faint); margin-bottom: 3px; }
.cn-msg-meta strong { color: var(--text-dim); }
.cn-msg-body {
  display: inline-block; background: var(--bg-3); padding: 8px 12px; border-radius: 12px;
  font-size: 14px; line-height: 1.45; white-space: pre-wrap; word-break: break-word; text-align: left;
}
.cn-msg.mine .cn-msg-body { background: var(--user-bubble); }
.cn-chat-composer { display: flex; gap: 10px; padding: 12px 18px; border-top: 1px solid var(--border); }
.cn-chat-composer .cn-input { margin: 0; }

/* ---- skill market ---- */
.cn-market-bar { margin-bottom: 14px; }
.cn-market-list { display: flex; flex-direction: column; gap: 8px; }
.cn-market-row {
  display: grid; grid-template-columns: 2fr 2fr auto auto; gap: 14px; align-items: center;
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 10px; padding: 11px 14px;
}
.cn-market-skill { display: flex; flex-direction: column; gap: 2px; }
.cn-market-skillname { font-weight: 600; font-size: 14px; }
.cn-market-type { font-size: 11px; color: var(--text-faint); text-transform: uppercase; }
.cn-market-peer { display: flex; align-items: center; gap: 7px; font-size: 13px; color: var(--text-dim); }
.cn-market-comm { color: var(--text-faint); }
.cn-market-trust { color: #d0d0d0; letter-spacing: 1px; font-size: 12px; }

/* ---- activity ---- */
.cn-requests-list { display: flex; flex-direction: column; gap: 8px; }
.cn-request {
  display: grid; grid-template-columns: 70px 1fr 1.2fr 90px; gap: 12px; align-items: center;
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 10px; padding: 10px 14px; font-size: 13px;
}
.cn-request-direction { font-size: 11px; font-weight: 700; }
.cn-request.incoming .cn-request-direction { color: var(--ok); }
.cn-request.outgoing .cn-request-direction { color: var(--accent-2); }
.cn-request-status { text-align: right; text-transform: capitalize; color: var(--text-dim); }
.cn-request-status.status-completed { color: var(--ok); }
.cn-request-status.status-failed { color: var(--danger); }
.cn-community-meta { font-size: 12px; color: var(--text-faint); }

/* ---- modals ---- */
.cn-modal-overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,.55); backdrop-filter: blur(3px);
  display: flex; align-items: center; justify-content: center; z-index: 1000;
}
.cn-modal-overlay.hidden { display: none; }
.cn-modal { background: var(--bg-2); border: 1px solid var(--border); border-radius: 14px; width: 460px; max-width: 92vw; max-height: 88vh; overflow-y: auto; box-shadow: 0 24px 60px rgba(0,0,0,.5); }
.cn-modal-head { display: flex; align-items: center; justify-content: space-between; padding: 16px 18px; border-bottom: 1px solid var(--border); }
.cn-modal-head h3 { margin: 0; font-size: 16px; }
.cn-modal-body { padding: 16px 18px 20px; }
.cn-modal-hint { font-size: 12.5px; color: var(--text-dim); margin: 0 0 6px; line-height: 1.5; }
.cn-modal-submit { width: 100%; margin-top: 14px; }
.cn-copyrow { display: flex; align-items: center; gap: 8px; background: var(--bg); border-radius: 8px; padding: 8px 10px; }
.cn-copyrow code { font-size: 12px; color: var(--accent-2); word-break: break-all; flex: 1; }
.cn-stars { display: flex; gap: 4px; font-size: 26px; }
.cn-star { cursor: pointer; color: var(--text-faint); transition: color .1s; }
.cn-star.on { color: #d0d0d0; }
.cn-ask-result { margin-top: 14px; }
.cn-ask-result.hidden { display: none; }
.cn-ask-ok { color: var(--ok); font-weight: 600; margin-bottom: 6px; }
.cn-ask-err { color: var(--danger); font-weight: 600; }

/* ---- generated files (downloads) ---- */
/* Width comes from the shared card rule in the Messages section — a card that sets
   its own max-width is a card that stops short of the answer above it. */
.files-card {
  margin: 8px 0; border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--bg-2); overflow: hidden;
}
.file-row { display: flex; align-items: center; gap: 10px; padding: 9px 12px; }
.file-row + .file-row { border-top: 1px solid var(--border); }
.file-icon { font-size: 18px; flex-shrink: 0; }
.file-info { flex: 1; min-width: 0; }
.file-name { font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.file-meta { font-size: 11px; color: var(--text-dim); }
a.file-dl { text-decoration: none; white-space: nowrap; flex-shrink: 0; }

/* ---- file viewer (look at it instead of downloading it) ----------------------
   One viewer, opened from the chat card and from the Files page. The body is a
   plain box and whatever goes in it (image, PDF frame, text) owns its own
   scrolling — a preview that scrolls the modal AND itself is two scrollbars
   arguing over one gesture. */
.preview-modal { max-width: 900px; height: 88vh; }
.preview-head-main { min-width: 0; }
.preview-head-main h2 { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.preview-acts { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.preview-body { flex: 1; min-height: 0; padding: 14px 16px; gap: 10px; }
.pv-wrap { flex: 1; min-height: 0; display: flex; align-items: center; justify-content: center; }
.pv-img {
  max-width: 100%; max-height: 100%; object-fit: contain; display: block;
  border-radius: var(--radius-sm); background: var(--bg-3);
}
.pv-frame {
  flex: 1; width: 100%; min-height: 0; background: #fff;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.pv-text {
  flex: 1; min-height: 0; overflow: auto; margin: 0; padding: 12px 14px;
  background: var(--bg-3); border: 1px solid var(--border); border-radius: var(--radius-sm);
  font-family: var(--mono); font-size: 12.5px; line-height: 1.55;
  white-space: pre-wrap; word-break: break-word;
}
.pv-note { flex-shrink: 0; font-size: 11.5px; color: var(--text-faint); }

/* ---- Office previews: a spreadsheet, a document and a deck ---------------------
   All three render on PAPER — white, dark ink — in both themes, exactly as the PDF
   frame above does. These files carry their own colours (a header fill chosen against
   Excel's white, a slide's theme background) and re-hosting them on a dark surface
   does not make them dark-mode, it makes them wrong. The modal chrome around them
   stays themed, so the page still belongs to the app. */
.pv-sheet, .pv-doc, .pv-deck {
  --paper: #ffffff; --ink: #17171d; --rule: #d8d8e0; --band: #f3f3f7;
  flex: 1; min-height: 0; overflow: auto;
}
.pv-sheet { display: flex; flex-direction: column; overflow: hidden; }

/* Sheet tabs sit on top rather than at the bottom: the modal's bottom edge is where
   the eye leaves, and with several sheets the tab strip is the first thing you need. */
.pv-tabs {
  display: flex; gap: 4px; flex-shrink: 0; overflow-x: auto; padding-bottom: 8px;
  scrollbar-width: thin;
}
.pv-tab {
  padding: 5px 12px; font: inherit; font-size: 12px; font-weight: 600; cursor: pointer;
  white-space: nowrap; color: var(--text-dim); background: var(--bg-3);
  border: 1px solid var(--border); border-radius: 999px;
}
.pv-tab:hover { color: var(--text); border-color: var(--accent); }
.pv-tab.on { color: #fff; background: var(--accent); border-color: var(--accent); }

.pv-grid-wrap { flex: 1; min-height: 0; overflow: auto; background: var(--paper); border: 1px solid var(--rule); border-radius: var(--radius-sm); }
.pv-grid-box { display: flex; flex-direction: column; min-width: min-content; }
.pv-grid { border-collapse: separate; border-spacing: 0; color: var(--ink); font-size: 12.5px; }
.pv-grid th, .pv-grid td {
  border-right: 1px solid var(--rule); border-bottom: 1px solid var(--rule);
  padding: 4px 8px; max-width: 460px; text-align: left; font-weight: 400;
  white-space: pre-wrap; word-break: break-word; vertical-align: top;
}
/* The letter/number gutters stay put while the grid scrolls — without them a wide
   sheet loses which column you are reading three screens in. */
.pv-grid thead th {
  position: sticky; top: 0; z-index: 2; background: var(--band); color: #55555f;
  font-size: 11px; font-weight: 600; text-align: center; min-width: 64px;
}
.pv-grid .pv-rowhead {
  position: sticky; left: 0; z-index: 1; background: var(--band); color: #55555f;
  font-size: 11px; font-weight: 600; text-align: right; min-width: 34px;
}
.pv-grid .pv-corner { position: sticky; left: 0; z-index: 3; min-width: 34px; }
.pv-grid td.num { text-align: right; font-variant-numeric: tabular-nums; }
.pv-grid td.b { font-weight: 700; }
.pv-grid td.hd { background: var(--band); font-weight: 600; }

/* Document flow. Sized like a page, not like the app's UI text. */
.pv-doc {
  background: var(--paper); color: var(--ink); border: 1px solid var(--rule);
  border-radius: var(--radius-sm); padding: 30px 38px; font-size: 14px; line-height: 1.65;
}
.pv-doc h1, .pv-doc h2, .pv-doc h3, .pv-doc h4, .pv-doc h5, .pv-doc h6 {
  margin: 20px 0 8px; line-height: 1.3; color: var(--ink);
}
.pv-doc h1 { font-size: 25px; }
.pv-doc h2 { font-size: 20px; }
.pv-doc h3 { font-size: 17px; }
.pv-doc h4, .pv-doc h5, .pv-doc h6 { font-size: 15px; }
.pv-doc > :first-child { margin-top: 0; }
.pv-doc p { margin: 0 0 10px; }
.pv-doc .pv-list { margin: 0 0 10px; padding-left: 26px; }
.pv-doc .pv-list li { margin: 2px 0; }
.pv-doc blockquote {
  margin: 10px 0; padding: 4px 14px; border-left: 3px solid var(--rule); color: #4a4a55;
}
.pv-doc .pv-figure { margin: 14px 0; }
.pv-doc .pv-figure img { max-width: 100%; border-radius: 4px; display: block; }
.pv-table-box { margin: 12px 0; overflow-x: auto; }
.pv-doctable { border-collapse: collapse; font-size: 13px; min-width: min-content; }
.pv-doctable th, .pv-doctable td {
  border: 1px solid var(--rule); padding: 6px 10px; text-align: left; vertical-align: top;
  white-space: pre-wrap;
}
.pv-doctable th, .pv-doctable td.b { background: var(--band); font-weight: 700; }

/* Slides: real geometry, scaled to fit. `.pv-stage` owns the post-scale height, since
   a transform does not change layout and the deck would otherwise overlap itself. */
.pv-deck { display: flex; flex-direction: column; gap: 18px; }
.pv-slide-wrap { display: flex; flex-direction: column; gap: 5px; }
.pv-slide-n { font-size: 11.5px; color: var(--text-faint); }
.pv-stage { overflow: hidden; }
.pv-slide {
  position: relative; transform-origin: top left; background: var(--paper);
  color: var(--ink); border: 1px solid var(--rule); border-radius: 4px;
  box-shadow: var(--shadow-1); overflow: hidden;
}
.pv-shape { position: absolute; overflow: hidden; }
.pv-shape.title { display: flex; flex-direction: column; justify-content: center; }
.pv-shape img { width: 100%; height: 100%; object-fit: contain; display: block; }
.pv-line { line-height: 1.25; margin-bottom: 2px; word-break: break-word; }
.pv-line.bullet { position: relative; padding-left: 1.1em; }
.pv-line.bullet::before { content: "•"; position: absolute; left: 0.2em; opacity: .55; }
.pv-slide-table { border-collapse: collapse; width: 100%; font-size: 13px; }
.pv-slide-table td { border: 1px solid var(--rule); padding: 3px 6px; }

/* ---- photometric files (.ies / .ldt) --------------------------------------
   The two plotted planes are the same quantity in the same unit, so they get two
   CATEGORICAL colours and a legend — not a light-to-dark ramp, which would read as one
   of them being "more". Both hues are readable on either theme's background, which is
   why they are declared here per theme rather than borrowed from --warn (amber means
   something else everywhere else in the app). */
.pv-phot { --ph-a: var(--accent); --ph-b: #12a5a5; display: flex; flex-direction: column; min-height: 0; }
:root[data-theme="light"] .pv-phot { --ph-b: #0b8785; }
.pv-phot-pane { overflow: auto; min-height: 0; }
.pv-phot-body { display: flex; flex-direction: column; gap: 14px; padding: 2px 2px 18px; }
.pv-phot-head { display: flex; flex-direction: column; gap: 2px; }
.pv-phot-title { margin: 0; font-size: 17px; }
.pv-phot-sub { font-size: 12.5px; color: var(--text-faint); }
.pv-phot-export { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 6px; }
.pv-phot-export-k { font-size: 11.5px; color: var(--text-faint); margin-right: 2px; }
.pv-phot-h { margin: 6px 0 0; font-size: 13px; letter-spacing: .02em; text-transform: uppercase; color: var(--text-faint); }
.pv-phot-class { font-size: 13.5px; color: var(--text-dim); }

.pv-phot-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; }
.pv-phot-tile { background: var(--bg-2); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 10px 12px; }
.pv-phot-tile-k { font-size: 11.5px; color: var(--text-faint); }
.pv-phot-tile-v { font-size: 21px; font-weight: 650; line-height: 1.25; }
.pv-phot-unit { font-size: 13px; font-weight: 500; color: var(--text-dim); }
.pv-phot-tile-n { font-size: 11px; color: var(--text-faint); }

.pv-phot-cols { display: grid; grid-template-columns: minmax(260px, 1fr) minmax(220px, 1fr); gap: 18px; align-items: start; }
@media (max-width: 720px) { .pv-phot-cols { grid-template-columns: 1fr; } }
.pv-phot-col { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.pv-phot-chart { background: var(--bg-2); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 6px; }
.pv-phot-legend { display: flex; flex-wrap: wrap; gap: 12px; padding: 4px 6px 2px; font-size: 12px; color: var(--text-dim); }
.pv-phot-key { display: inline-flex; align-items: center; gap: 6px; }
.pv-phot-swatch { width: 14px; height: 3px; border-radius: 2px; background: var(--ph-a); }
.pv-phot-swatch.s1 { background: var(--ph-b); }
.pv-phot-key-note { margin-left: auto; color: var(--text-faint); }

.ph-ring, .ph-spoke, .ph-axis { fill: none; stroke: var(--border); }
.ph-spoke { stroke-dasharray: 2 4; }
.ph-axis { stroke: var(--text-faint); }
.ph-tick { fill: var(--text-faint); font-size: 10px; }
.ph-tick.mid { text-anchor: middle; }
.ph-tick.end { text-anchor: end; }
.ph-line { fill: none; stroke: var(--ph-a); stroke-width: 2; stroke-linejoin: round; }
.ph-line.s1 { stroke: var(--ph-b); stroke-dasharray: 5 3; }

.pv-phot-pairs { border-collapse: collapse; font-size: 13px; width: 100%; }
.pv-phot-pairs th { text-align: left; font-weight: 500; color: var(--text-faint); padding: 3px 10px 3px 0; vertical-align: top; white-space: nowrap; }
.pv-phot-pairs td { padding: 3px 0; word-break: break-word; }
.pv-phot-tablebox { overflow: auto; border: 1px solid var(--border); border-radius: var(--radius-sm); }
.pv-phot-table { border-collapse: collapse; font-size: 13px; width: 100%; }
.pv-phot-table th, .pv-phot-table td { border-bottom: 1px solid var(--border); padding: 5px 10px; text-align: left; }
.pv-phot-table th { background: var(--bg-3); font-weight: 600; white-space: nowrap; }
.pv-phot-table th.sub { font-weight: 500; color: var(--text-faint); text-align: right; }
.pv-phot-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
.pv-phot-grid { font-size: 12px; }

/* One ordered quantity (glare), so one hue in three steps — and the step that matters
   is UGR<19, the line every office specification is written to. */
.pv-phot-ugrtable td.ugr.good { color: var(--ok); font-weight: 600; }
.pv-phot-ugrtable td.ugr.fair { color: var(--text-dim); }
.pv-phot-ugrtable td.ugr.poor { color: var(--warn); }
.pv-phot-ugr-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.pv-phot-ugr-value { font-size: 34px; font-weight: 650; line-height: 1; }
.pv-phot-ugr-rating { font-size: 13px; color: var(--text-dim); }
.pv-phot-room { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end; background: var(--bg-2); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 10px 12px; }
.pv-phot-field { display: flex; flex-direction: column; gap: 3px; font-size: 11.5px; color: var(--text-faint); }
.pv-phot-field input { width: 92px; padding: 5px 7px; background: var(--bg-3); color: var(--text); border: 1px solid var(--border); border-radius: 6px; font: inherit; font-size: 13px; }
.pv-phot-actions { display: flex; align-items: center; gap: 10px; }
.pv-phot-status { font-size: 12px; color: var(--text-faint); }
.pv-phot-warn { background: var(--warn-soft); border: 1px solid var(--warn); border-radius: var(--radius-sm); padding: 10px 12px; font-size: 13px; }
.pv-phot-warn-h { font-weight: 650; margin-bottom: 4px; }
.pv-phot-warn ul { margin: 0; padding-left: 18px; }
.pv-phot-warn li { margin: 2px 0; }

/* The Photometrics page reuses every renderer above; only the drop zone and the
   comparison wrapper are its own. */
.phot-drop {
  border: 1.5px dashed var(--border); border-radius: var(--radius); background: var(--bg-1);
  padding: 26px 18px; text-align: center; cursor: pointer; transition: border-color .12s, background .12s;
}
.phot-drop:hover, .phot-drop.on { border-color: var(--accent); background: var(--accent-soft); }
.phot-drop-in { display: flex; flex-direction: column; gap: 6px; align-items: center; pointer-events: none; }
.phot-drop-in button { pointer-events: auto; }
.phot-drop-ico { font-size: 26px; }
.phot-drop-note { font-size: 12.5px; color: var(--text-faint); }
.phot-status { margin: 12px 0 0; font-size: 13px; color: var(--text-dim); }
.phot-status.bad { color: var(--danger); }
.phot-compare { display: flex; flex-direction: column; gap: 10px; margin-top: 18px; }
.phot-report { margin-top: 18px; }
.phot-strip { margin-bottom: 8px; }
.phot-pane { min-height: 0; }
#view-photometrics .pv-phot-pane { overflow: visible; }

/* The file NAME is a click target on every surface that lists one, so it has to
   read as text and behave as a button. */
button.file-name, button.fv-name {
  display: block; max-width: 100%; font: inherit; font-size: 13px; font-weight: 600;
  color: var(--text); background: none; border: 0; padding: 0; text-align: left;
  cursor: pointer; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
button.file-name:hover, button.fv-name:hover { color: var(--accent-2); text-decoration: underline; }
.file-item .mem-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---- inline send approval (chat gate) ----------------------------------------
   The decision belongs where the request was made. Accent-framed while it waits on
   you; it settles in place to sent/not-sent so the transcript stays truthful. */
.send-approve {
  margin: 10px 0; padding: 12px 14px; border-radius: var(--radius);
  border: 1px solid color-mix(in srgb, var(--accent) 40%, var(--border));
  background: color-mix(in srgb, var(--accent) 7%, var(--bg-2));
}
.sa-head { display: flex; align-items: center; gap: 8px; }
.sa-ico { font-size: 15px; flex: none; }
.sa-title { font-size: 13.5px; font-weight: 700; color: var(--text); flex: 1; min-width: 0; overflow-wrap: anywhere; }
.sa-tag {
  flex: none; padding: 2px 8px; border-radius: 999px; font-size: 10.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .03em;
  background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--accent);
}
.sa-msg {
  margin-top: 9px; padding: 9px 11px; border-radius: 9px; background: var(--bg);
  border: 1px solid var(--border); font-size: 13px; line-height: 1.5; color: var(--text);
  white-space: pre-wrap; overflow-wrap: anywhere; max-height: 260px; overflow-y: auto;
}
.sa-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 11px; }
.sa-actions:empty { display: none; }
.sa-send {
  border: none; border-radius: 9px; padding: 7px 15px; font-size: 13px; font-weight: 600;
  background: var(--accent); color: var(--on-accent); cursor: pointer;
}
.sa-send:hover { filter: brightness(1.08); }
.sa-cancel {
  border: 1px solid var(--border); border-radius: 9px; padding: 7px 13px; font-size: 13px;
  background: var(--bg); color: var(--text-dim); cursor: pointer;
}
.sa-cancel:hover { color: var(--text); border-color: var(--accent); }
.send-approve button:disabled { opacity: .55; cursor: default; }
.sa-hint { margin-top: 8px; font-size: 11.5px; color: var(--text-faint); }
.sa-note { margin-top: 9px; font-size: 12px; color: var(--text-dim); overflow-wrap: anywhere; }
/* The record an approved action created — a draft Odoo order. Rendered as real
   anchors OUTSIDE the note's character clip, because opening it is the reader's
   next move and a URL inside a 300-char textContent clip is neither clickable nor,
   on a long result, even present. */
.sa-links { margin-top: 9px; display: flex; flex-wrap: wrap; gap: 8px; }
.sa-links a {
  font-size: 12px; font-weight: 600; text-decoration: none;
  padding: 6px 11px; border-radius: 8px;
  color: var(--ok);
  background: color-mix(in srgb, var(--ok) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--ok) 38%, transparent);
}
.sa-links a:hover { background: color-mix(in srgb, var(--ok) 20%, transparent); }
.send-approve.sent { border-color: color-mix(in srgb, var(--ok) 45%, var(--border)); background: var(--bg-2); }
.send-approve.sent .sa-tag { background: color-mix(in srgb, var(--ok) 16%, transparent); color: var(--ok); }
.send-approve.cancelled { border-color: var(--border); background: var(--bg-2); }
.send-approve.cancelled .sa-tag { background: color-mix(in srgb, var(--text-faint) 16%, transparent); color: var(--text-faint); }
.send-approve.cancelled .sa-msg { color: var(--text-faint); }
.cn-ask-result pre {
  background: var(--bg); border: 1px solid var(--border); border-radius: 8px; padding: 10px;
  font-size: 12.5px; white-space: pre-wrap; word-break: break-word; max-height: 240px; overflow-y: auto;
}

/* ---- consultation rooms ---- */
.btn-ask {
  background: linear-gradient(135deg, var(--accent), var(--accent-2)); color: var(--on-accent); border: none;
  border-radius: 9px; padding: 0 14px; font-size: 13px; font-weight: 600; cursor: pointer; white-space: nowrap;
}
.btn-ask:hover { filter: brightness(1.08); }
.btn-ask:disabled { opacity: .6; cursor: default; }
.cn-chan-group {
  display: flex; align-items: center; gap: 6px;
  font-size: 10px; text-transform: uppercase; letter-spacing: .5px; color: var(--text-faint);
  font-weight: 700; padding: 12px 10px 4px;
}
.cn-chan-group .ico { width: 13px; height: 13px; flex-shrink: 0; }
.cn-channel.room { display: flex; align-items: center; gap: 6px; }
.cn-room-n {
  margin-left: auto; font-size: 10px; background: var(--bg-3); color: var(--text-dim);
  border-radius: 8px; padding: 0 6px; line-height: 16px;
}
.cn-skill-chip.readonly { cursor: default; }
.cn-skill-type { font-size: 10px; color: var(--text-faint); text-transform: uppercase; }
.cn-detail-hint {
  font-size: 12px; color: var(--text-dim); background: var(--accent-soft); border-radius: 9px;
  padding: 10px 12px; margin-top: 14px; line-height: 1.5;
}
.cn-ai-badge {
  font-size: 9px; font-weight: 700; background: var(--accent); color: var(--on-accent);
  border-radius: 5px; padding: 1px 5px; margin-left: 5px; vertical-align: middle;
}
.cn-msg-system {
  align-self: center; text-align: center; font-size: 12px; color: var(--text-faint);
  background: var(--bg-2); border-radius: 10px; padding: 6px 12px; max-width: 90%;
}
.cn-msg-question {
  align-self: stretch; background: var(--bg-2); border-left: 3px solid var(--accent);
  border-radius: 8px; padding: 10px 14px; font-size: 14.5px; font-weight: 500; line-height: 1.5; white-space: pre-wrap;
}
.cn-msg-summary {
  align-self: stretch; background: linear-gradient(180deg, var(--accent-soft), transparent);
  border: 1px solid var(--accent); border-radius: 10px; padding: 12px 14px; font-size: 14px; line-height: 1.55; white-space: pre-wrap;
}
.cn-msg-tag {
  display: block; font-size: 10.5px; text-transform: uppercase; letter-spacing: .5px;
  color: var(--accent-2); font-weight: 700; margin-bottom: 6px;
}
.cn-howto {
  background: var(--accent-soft); border: 1px solid var(--border); border-radius: 10px;
  padding: 12px 14px; margin-bottom: 16px; font-size: 13px; color: var(--text-dim); line-height: 1.55;
}
.cn-howto strong { color: var(--text); }
.cn-discussion {
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 10px;
  padding: 11px 14px; margin-bottom: 8px;
}
.cn-disc-topic { font-weight: 600; font-size: 14px; margin-bottom: 3px; }

/* ---- Sessions (live P2P consultation viewer) ---- */
.cn-sessions { display: grid; grid-template-columns: 260px minmax(0, 1fr); gap: 14px; height: 100%; min-height: 0; }
.cn-sessions-list { display: flex; flex-direction: column; gap: 7px; overflow-y: auto; padding-right: 2px; }
.cn-session-item {
  text-align: left; width: 100%; background: var(--bg-2); border: 1px solid var(--border);
  border-radius: 10px; padding: 10px 12px; cursor: pointer; color: var(--text);
}
.cn-session-item:hover { border-color: var(--accent); }
.cn-session-item.active { border-color: var(--accent); background: var(--accent-soft); }
.cn-session-top { display: flex; align-items: center; gap: 8px; }
.cn-session-topic { font-weight: 600; font-size: 13.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cn-session-live { width: 8px; height: 8px; border-radius: 50%; background: var(--text-faint); flex-shrink: 0; }
.cn-session-live.on { background: var(--ok); box-shadow: 0 0 7px var(--ok); animation: cn-pulse 1.2s ease-in-out infinite; }
.cn-session-meta { font-size: 11.5px; color: var(--text-faint); margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cn-session-view {
  min-width: 0; min-height: 0; display: flex; flex-direction: column;
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 12px; overflow: hidden;
}
.cn-session-head {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 12px 16px; border-bottom: 1px solid var(--border);
}
.cn-session-title { font-weight: 600; font-size: 15px; display: flex; align-items: center; gap: 8px; }
.cn-session-sub { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-faint); margin-top: 3px; }
.cn-session-sub .ico { width: 13px; height: 13px; flex-shrink: 0; }
.cn-session-badge {
  font-size: 10px; font-weight: 700; letter-spacing: .5px; padding: 2px 8px; border-radius: 6px;
  background: var(--bg-3); color: var(--text-faint);
}
.cn-session-head .cn-session-badge { color: var(--ok); }
.cn-session-thread { flex: 1; min-height: 0; overflow-y: auto; padding: 16px; display: flex; flex-direction: column; gap: 12px; }
.cn-smsg { max-width: 78%; align-self: flex-start; }
.cn-smsg.mine { align-self: flex-end; }
.cn-smsg-body {
  position: relative; display: inline-flex; flex-direction: column; align-items: flex-start;
  background: var(--bg-3); padding: 6px 11px 4px; border-radius: 14px; max-width: 100%;
  box-shadow: 0 1px 1.5px rgba(0,0,0,.07);
}
.cn-smsg.mine .cn-smsg-body { background: var(--user-bubble); }
.cn-smsg-name { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 12px; font-weight: 700; color: var(--accent-2); margin-bottom: 1px; }
.cn-smsg-text { font-size: 13.5px; line-height: 1.45; white-space: pre-wrap; word-break: break-word; text-align: left; }
/* An AI-written bubble holds RENDERED Markdown. Borrow .msg-content's typography
   (lists, headings, code, tables) but strip its bubble chrome — this is already
   inside a bubble — and drop pre-wrap, which would double the gap between every
   block element. A wide table scrolls inside the bubble instead of stretching it. */
.cn-smsg-text.msg-content {
  background: none; border: none; border-radius: 0; padding: 0;
  white-space: normal; overflow-x: auto;
}
.cn-smsg-text.msg-content > :first-child { margin-top: 0; }
.cn-smsg-text.msg-content > :last-child { margin-bottom: 0; }
.cn-smsg-text.msg-content .md-table { font-size: 12px; }
.cn-smsg-text.msg-content .md-table th, .cn-smsg-text.msg-content .md-table td { padding: 5px 8px; }
/* tables and code need more room than a chat line does */
.cn-smsg.has-md { max-width: 92%; }
.cn-smsg-foot { align-self: flex-end; display: inline-flex; align-items: center; gap: 4px; margin-top: 1px;
  font-size: 10.5px; color: var(--text-faint); white-space: nowrap; line-height: 1.4; }
.cn-smsg .gc-edited { font-style: italic; opacity: .8; }
.cn-smsg-foot .cn-ai-badge, .cn-smsg-foot .cn-assist-badge { transform: scale(.9); }
.cn-session-composer { display: flex; gap: 8px; padding: 10px 14px; border-top: 1px solid var(--border); }
.cn-session-composer .cn-input { margin: 0; }

/* ===== Company redesign: chat layout + conclusion panel ==================== */
#view-chat { min-height: 0; }
.chat-layout { flex: 1; display: grid; grid-template-columns: minmax(0, 1fr) 360px; min-height: 0; }
.chat-layout:has(#conclusion-panel.hidden) { grid-template-columns: minmax(0, 1fr) 0; }
.chat-main { display: flex; flex-direction: column; min-width: 0; min-height: 0; }
/* Kimi-style new chat: float the composer directly under the logo, vertically
   centred, with the header pinned at the top. Reverts to the normal docked layout
   the moment the first message arrives (the .chat-empty class is dropped). */
.chat-main.chat-empty { position: relative; justify-content: center; }
.chat-main.chat-empty #chat-header { position: absolute; top: 0; left: 0; right: 0; z-index: 5; }
.chat-main.chat-empty #messages { flex: 0 0 auto; overflow: visible; padding: 0; }
.chat-main.chat-empty #empty-state { margin: 0 auto 40px; }
.chat-main.chat-empty .empty-logo { font-size: 60px; }
.chat-main.chat-empty #composer { border-top: none; padding-top: 0; }
.conclusion-panel {
  border-left: 1px solid var(--border); background: var(--bg-2);
  overflow-y: auto; padding: 16px 16px 20px; display: flex; flex-direction: column; gap: 14px;
}
.conclusion-panel .cp-head { display: flex; align-items: center; justify-content: space-between; }
.cp-title { font-weight: 700; font-size: 14px; }
.cp-close { background: none; border: none; color: var(--text-faint); font-size: 15px; }
.cp-close:hover { color: var(--text); }
.cp-section { display: flex; flex-direction: column; gap: 6px; }
.cp-section.cp-grow { flex: 1; min-height: 0; }
.cp-label { font-size: 11.5px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-faint); font-weight: 700; }
.cp-editable-hint { text-transform: none; letter-spacing: 0; color: var(--text-faint); font-weight: 500; }
.cp-minutes { font-size: 13.5px; background: var(--bg); border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px; }
.cp-minutes.hint { color: var(--text-faint); }
.cp-conclusion { flex: 1; min-height: 120px; resize: vertical; width: 100%;
  background: var(--bg); border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px;
  color: var(--text); font-family: inherit; font-size: 13.5px; }
.cp-actions { display: flex; gap: 8px; margin-top: 8px; flex-wrap: wrap; }
@media (max-width: 900px) {
  .chat-layout, .chat-layout:has(#conclusion-panel.hidden) { grid-template-columns: minmax(0, 1fr); }
  .conclusion-panel { position: fixed; top: 0; right: 0; bottom: 0; width: min(360px, 90vw); z-index: 40; }
}

/* Group Chat: the discussion conclusion rendered inline (Meeting-notes panel retired) */
.conclusion-inline { border-left: 3px solid var(--accent); background: var(--bg-1); }
.ci-title { font-weight: 700; font-size: 11px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--accent-2); margin-bottom: 6px; }

/* ===== Workbench: collapsed process box + slide-out panel ==================
   Width is the shared card rule's (see .msg-body > .wb-box in Messages). */
.wb-box {
  border: 1px solid var(--border); border-radius: 12px; background: var(--bg-1);
  overflow: hidden; margin: 4px 0 8px; }
.wb-box.live { border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); }
.wb-boxhead { display: flex; align-items: center; gap: 10px; padding: 9px 12px; cursor: pointer; user-select: none; }
.wb-boxhead:hover { background: var(--bg-2); }
.wb-ico { width: 22px; height: 22px; border-radius: 6px; background: var(--accent-soft);
  display: flex; align-items: center; justify-content: center; font-size: 12px; flex-shrink: 0; }
.wb-htitles { min-width: 0; }
.wb-title { font-weight: 600; font-size: 13px; }
.wb-sub { color: var(--text-faint); font-size: 12px; }
.wb-hsp { flex: 1; }
.wb-chev { color: var(--text-faint); font-size: 11px; transition: transform .2s; }
.wb-box:not(.collapsed) .wb-chev { transform: rotate(90deg); }
.wb-steps { display: flex; flex-direction: column; border-top: 1px solid var(--border);
  max-height: 340px; overflow-y: auto; }
.wb-box.collapsed .wb-steps { display: none; }
.wb-live { display: inline-flex; align-items: center; gap: 7px; color: var(--accent-2); font-weight: 600; }
.wb-pulse { width: 7px; height: 7px; border-radius: 50%; background: var(--accent);
  display: inline-block; flex-shrink: 0; animation: wb-pulse 1s infinite ease-in-out; }
@keyframes wb-pulse { 0%, 100% { opacity: .35; transform: scale(.85); } 50% { opacity: 1; transform: scale(1.15); } }
@media (prefers-reduced-motion: reduce) { .wb-pulse { animation: none; } }
.wb-step { display: flex; align-items: center; gap: 10px; padding: 8px 12px; border-left: 2px solid transparent; }
.wb-step.tool { cursor: pointer; }
.wb-step.tool:hover { background: var(--bg-2); }
.wb-step.active { background: var(--accent-soft); border-left-color: var(--accent); }
.wb-step.narration { display: block; padding: 6px 12px 6px 14px; }
/* A step belonging to a skill running inside the turn (`run_skill`): indented and
   dimmed so the assistant's own steps still read as the main thread of work. */
.wb-step.sub { padding-left: 30px; border-left: 2px solid var(--border); }
.wb-step.sub .wb-dot { width: 11px; height: 11px; }
.wb-step.sub .wb-slabel { font-size: 12.5px; color: var(--text-dim); }
.wb-narr { font-size: 13px; color: var(--text-dim); }
.wb-narr p { margin: 0 0 6px; }
.wb-narr p:last-child { margin-bottom: 0; }
.wb-step.think { align-items: flex-start; cursor: default; }
.wb-dot.think { background: var(--accent-soft); }
.wb-step.think.live .wb-dot.think { animation: wb-pulse 1s infinite ease-in-out; }
.wb-thinktext { font-size: 11.5px; color: var(--text-faint); white-space: pre-wrap; word-break: break-word;
  line-height: 1.5; margin-top: 3px; max-height: 120px; overflow-y: auto; }
.wb-step.pending { cursor: default; }
.wb-step.pending .wb-slabel { color: var(--accent-2); font-weight: 600; }
.wb-dot { width: 15px; height: 15px; border-radius: 50%; flex-shrink: 0; background: var(--bg-3); position: relative; }
.wb-step.running .wb-dot { background: var(--accent-soft); animation: wb-pulse 1s infinite ease-in-out; }
.wb-step.done .wb-dot { background: rgba(52, 195, 126, .2); }
.wb-step.done .wb-dot::after { content: "✓"; position: absolute; inset: 0; display: flex;
  align-items: center; justify-content: center; font-size: 9px; color: var(--ok); }
.wb-smain { flex: 1; min-width: 0; }
.wb-slabel { font-size: 13px; }
.wb-stool { font-family: var(--mono); font-size: 11px; color: var(--text-faint); margin-top: 1px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wb-sopen { font-size: 11px; color: var(--text-faint); opacity: 0; flex-shrink: 0; }
.wb-step.tool:hover .wb-sopen { opacity: 1; }

/* Below the bar, not over it: this panel slides in on the RIGHT, which is exactly
   where the online switch lives — covering it read as the control vanishing. */
.wb-panel { position: fixed; top: var(--topbar-h); right: 0; height: calc(100vh - var(--topbar-h)); width: min(440px, 92vw);
  background: var(--bg-1); border-left: 1px solid var(--border); z-index: 46;
  display: flex; flex-direction: column; box-shadow: -16px 0 44px rgba(0, 0, 0, .42);
  transition: transform .3s cubic-bezier(.4, 0, .2, 1); }
.wb-panel.hidden { transform: translateX(100%); }
.wb-p-head { display: flex; align-items: center; gap: 10px; padding: 12px 15px; border-bottom: 1px solid var(--border); }
.wb-p-ico { width: 24px; height: 24px; border-radius: 6px; background: var(--accent-soft);
  display: flex; align-items: center; justify-content: center; font-size: 13px; flex-shrink: 0; }
.wb-p-titles { flex: 1; min-width: 0; }
.wb-p-title { font-weight: 600; font-size: 14px; }
.wb-p-sub { color: var(--text-faint); font-size: 11.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wb-p-x { background: none; border: none; color: var(--text-faint); font-size: 15px; cursor: pointer;
  padding: 4px 7px; border-radius: 6px; }
.wb-p-x:hover { background: var(--bg-hover); color: var(--text); }
.wb-p-nav { display: flex; align-items: center; gap: 8px; padding: 8px 15px; border-bottom: 1px solid var(--border);
  font-size: 12px; color: var(--text-faint); }
.wb-p-navbtn { background: var(--bg-2); border: 1px solid var(--border); color: var(--text-dim);
  width: 26px; height: 26px; border-radius: 7px; cursor: pointer; font-size: 13px; }
.wb-p-navbtn:hover { border-color: var(--accent); color: var(--text); }
.wb-p-body { flex: 1; overflow-y: auto; padding: 15px; }
.wb-p-tool { display: inline-flex; align-items: center; gap: 7px; background: var(--bg-2);
  border: 1px solid var(--border); border-radius: 999px; padding: 4px 11px; font-family: var(--mono);
  font-size: 12px; color: var(--accent-2); margin-bottom: 12px; }
.wb-p-lbl { font-size: 11px; text-transform: uppercase; letter-spacing: .05em; color: var(--text-faint);
  margin: 13px 0 6px; font-weight: 600; }
.wb-p-io { background: var(--bg); border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px;
  font-family: var(--mono); font-size: 12px; line-height: 1.55; white-space: pre-wrap; word-break: break-word;
  color: var(--text-dim); overflow-x: auto; }
.wb-p-io.out { color: var(--text); }
.wb-p-io.running { display: flex; align-items: center; gap: 8px; color: var(--accent-2); }
.wb-backdrop { position: fixed; inset: 0; z-index: 45; display: none; }
@media (max-width: 900px) { .wb-backdrop:not(.hidden) { display: block; background: rgba(0, 0, 0, .4); } }

/* participant picker menu */
.drop-menu.wide { min-width: 260px; max-height: 340px; overflow-y: auto; }
.drop-section { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-faint);
  font-weight: 700; padding: 8px 12px 4px; }
.drop-empty { padding: 10px 12px; font-size: 12.5px; color: var(--text-faint); }
.drop-item.pick { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.drop-item.pick small { color: var(--text-faint); }
.drop-item.pick.on { background: var(--accent-soft); }

/* typing dots (a member is composing) */
.typing-dots { display: inline-flex; gap: 4px; align-items: center; }
.typing-dots span { width: 6px; height: 6px; border-radius: 50%; background: var(--text-faint);
  animation: td-bounce 1.2s infinite ease-in-out; }
.typing-dots span:nth-child(2) { animation-delay: .15s; }
.typing-dots span:nth-child(3) { animation-delay: .3s; }
@keyframes td-bounce { 0%, 80%, 100% { opacity: .3; transform: translateY(0); } 40% { opacity: 1; transform: translateY(-3px); } }

/* Company: members + teams management */
.members-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; flex-wrap: wrap; }
.company-members { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 12px; }
.member-card { background: var(--bg-2); border: 1px solid var(--border); border-radius: 12px; padding: 12px 14px; }
.member-top { display: flex; align-items: center; gap: 10px; }
.member-ico { --ico-sz: 32px; font-size: 20px; }
.member-name { font-weight: 600; }
.member-role { font-size: 12px; color: var(--text-faint); }
.member-top .member-fire { margin-left: auto; }
.member-skills { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.skill-tag { font-size: 11px; background: var(--bg-3); border: 1px solid var(--border); border-radius: 20px; padding: 2px 9px; color: var(--text-dim); }
.company-teams { display: flex; flex-direction: column; gap: 14px; }
.team-card { background: var(--bg-2); border: 1px solid var(--border); border-radius: 12px; padding: 14px; }
.team-head { display: flex; align-items: center; gap: 10px; }
.team-ico { font-size: 18px; }
.team-name-input { flex: 1; background: var(--bg); border: 1px solid var(--border); border-radius: 8px;
  padding: 6px 10px; color: var(--text); font-weight: 600; font-family: inherit; }
.team-purpose-input { width: 100%; margin-top: 8px; background: var(--bg); border: 1px solid var(--border);
  border-radius: 8px; padding: 6px 10px; color: var(--text); font-size: 13px; font-family: inherit; }
.team-members { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0; }
.team-chip { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px;
  background: var(--bg-3); border: 1px solid var(--border); border-radius: 20px; padding: 3px 6px 3px 11px; }
.team-chip .chip-x { background: none; border: none; color: var(--text-faint); font-size: 12px; line-height: 1; padding: 0 2px; }
.team-chip .chip-x:hover { color: var(--danger); }
.team-add-select { background: var(--bg); border: 1px solid var(--border); border-radius: 8px; padding: 6px 10px; color: var(--text); font-family: inherit; }
.recruit-btn { cursor: pointer; }
/* ---- software (dev) teams — unified into the Teams tab ---- */
.team-sw-toggle { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; color: var(--text-dim); cursor: pointer; white-space: nowrap; }
.team-sw-toggle input { cursor: pointer; }
.team-software { border-color: var(--accent); }
.team-soft { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 10px 0 4px; padding: 8px 10px; background: var(--accent-soft); border-radius: 8px; }
.team-mode { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-dim); }
.team-mode-sel, .team-role-sel { background: var(--bg); border: 1px solid var(--border); border-radius: 7px; padding: 3px 6px; color: var(--text); font-size: 12px; font-family: inherit; }
.team-repo { font-size: 12px; color: var(--ok); }
.team-run-sprint { margin-left: auto; }
.team-mrow { display: flex; align-items: center; gap: 8px; width: 100%; }
.team-software .team-members { flex-direction: column; align-items: stretch; }
.btn-mini.primary { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
/* ---- per-team knowledge & facts (the team's own shared context) ---- */
.team-kn { margin-top: 10px; border-top: 1px solid var(--border); padding-top: 8px; }
.team-kn > summary { cursor: pointer; font-size: 12.5px; color: var(--text-dim); user-select: none; list-style: none; }
.team-kn > summary::-webkit-details-marker { display: none; }
.team-kn > summary::before { content: "▸ "; color: var(--text-faint); }
.team-kn[open] > summary::before { content: "▾ "; }
.team-know { width: 100%; margin: 8px 0; background: var(--bg); border: 1px solid var(--border);
  border-radius: 8px; padding: 6px 10px; color: var(--text); font-size: 13px; font-family: inherit; resize: vertical; }
.team-facts { display: flex; flex-direction: column; gap: 6px; margin-bottom: 8px; }
.team-fact { display: flex; align-items: center; gap: 6px; }
.team-fact-k, .team-fact-v { background: var(--bg); border: 1px solid var(--border); border-radius: 7px;
  padding: 4px 8px; color: var(--text); font-size: 12.5px; font-family: inherit; }
.team-fact-k { flex: 0 0 34%; font-weight: 600; }
.team-fact-v { flex: 1; }
.team-fact .team-fact-x { background: none; border: none; color: var(--text-faint); cursor: pointer; padding: 0 4px; }
.team-fact .team-fact-x:hover { color: var(--danger); }
.team-flash { animation: teamFlash 1.4s ease; }
@keyframes teamFlash { 0%,100% { box-shadow: none; } 25% { box-shadow: 0 0 0 2px var(--accent); } }
/* ---- sidebar rail: teams nested under their company ---- */
.cn-rail-teams { display: flex; flex-direction: column; gap: 1px; margin: 1px 0 6px 14px;
  padding-left: 8px; border-left: 1px solid var(--border); }
.cn-rail-team { display: flex; align-items: center; gap: 7px; width: 100%; text-align: left;
  background: none; border: none; color: var(--text-dim); font-size: 12.5px; font-family: inherit;
  padding: 5px 8px; border-radius: 7px; cursor: pointer; }
.cn-rail-team:hover { background: var(--bg-3); color: var(--text); }
.cn-rt-ico { display: inline-flex; font-size: 12px; }
.cn-rt-ico .ico { width: 14px; height: 14px; color: var(--text-faint); }
.cn-rt-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---- Teams tab: clean list of teams (click a row to open its page) ---- */
.team-list { display: flex; flex-direction: column; gap: 8px; }
.team-list-row { display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 12px; padding: 12px 14px;
  color: var(--text); font-family: inherit; cursor: pointer; transition: border-color .12s, background .12s; }
.team-list-row:hover { border-color: var(--accent); background: var(--bg-3); }
.tlr-ico { font-size: 20px; }
.tlr-main { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.tlr-name { font-weight: 600; }
.tlr-meta { font-size: 12px; color: var(--text-dim); }
.tlr-arrow { font-size: 20px; color: var(--text-faint); }
/* ---- Team detail page: breadcrumb + Members/Settings sub-tabs ---- */
.team-detail-head { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; flex-wrap: wrap; }
.team-back { background: var(--bg-2); border: 1px solid var(--border); border-radius: 8px; padding: 5px 10px;
  color: var(--text-dim); font-family: inherit; font-size: 13px; cursor: pointer; }
.team-back:hover { color: var(--text); border-color: var(--accent); }
.team-crumb { font-size: 14px; color: var(--text-dim); }
.team-crumb b { color: var(--text); }
.team-type-badge { margin-left: auto; font-size: 12px; color: var(--text-dim);
  background: var(--bg-3); border: 1px solid var(--border); border-radius: 20px; padding: 4px 12px; }
.team-subtabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); margin-bottom: 16px; }
.team-subtab { display: inline-flex; align-items: center; gap: 7px;
  background: none; border: none; border-bottom: 2px solid transparent; margin-bottom: -1px;
  padding: 8px 14px; color: var(--text-dim); font-family: inherit; font-size: 13.5px; cursor: pointer; }
.team-subtab .ico { width: 15px; height: 15px; flex-shrink: 0; }
.team-subtab:hover { color: var(--text); }
.team-subtab.active { color: var(--text); border-bottom-color: var(--accent); }
.team-subbody { display: flex; flex-direction: column; gap: 12px; }
.team-subbody .team-members { flex-direction: column; align-items: stretch; margin: 0; }
.team-set-row { display: flex; flex-direction: column; gap: 6px; max-width: 640px; }
.team-set-row > label:first-child { font-size: 12px; color: var(--text-dim); font-weight: 600; }
.team-set-row .team-name-input, .team-set-row .team-purpose-input { margin: 0; width: 100%; }
.team-set-kn .team-kn-body { display: flex; flex-direction: column; gap: 8px; }
.team-set-kn .team-know { margin: 0; }
.team-set-danger { margin-top: 8px; padding-top: 12px; border-top: 1px solid var(--border); }

/* ===== Company dashboard: onboarding + settings overview ================== */
.cn-onboarding { padding: 40px 24px; display: flex; align-items: center; justify-content: center; }
.cn-onb-cards { display: grid; grid-template-columns: repeat(2, minmax(0, 320px)); gap: 20px; }
.cn-onb-card { background: var(--bg-2); border: 1px solid var(--border); border-radius: 16px;
  padding: 28px 24px; text-align: center; display: flex; flex-direction: column; align-items: center; gap: 8px; }
.cn-onb-ico { --ico-sz: 56px; font-size: 40px; }
.cn-onb-card h2 { margin: 4px 0 0; font-size: 18px; }
.cn-onb-card p { color: var(--text-dim); font-size: 13.5px; margin: 0 0 12px; }
.cn-onb-card .btn-primary { min-width: 180px; }
.btn-primary.ghost { background: transparent; color: var(--text); border: 1px solid var(--border); }
.btn-primary.ghost:hover { background: var(--bg-hover); }
.cn-set-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
.cn-set-stat { background: var(--bg); border: 1px solid var(--border); border-radius: 10px;
  padding: 12px; text-align: center; display: flex; flex-direction: column; gap: 2px; }
.cn-set-stat-n { font-size: 22px; font-weight: 700; }
.cn-set-stat-l { font-size: 11.5px; color: var(--text-faint); text-transform: uppercase; letter-spacing: .03em; }

/* ===== Group Chat participant picker: summary line + Setup popover ======== */
.participants-bar { position: relative; flex-shrink: 0; width: 100%; max-width: 780px;
  margin: 0 auto; padding: 8px 22px 0; }
.pbar-summary { display: flex; align-items: center; gap: 8px; width: 100%; cursor: pointer;
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 12px;
  padding: 7px 12px; color: var(--text-dim); font: inherit; font-size: 12.5px; text-align: left; }
.pbar-summary:hover { border-color: var(--accent); }
.pbar-sum-ico { font-size: 14px; flex-shrink: 0; }
.pbar-sum-lead { color: var(--text-faint); flex-shrink: 0; }
.pbar-sum-text { color: var(--text); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pbar-tag { flex-shrink: 0; font-size: 11px; padding: 1px 7px; border-radius: 999px;
  background: var(--accent-soft); color: var(--accent-2); }
.pbar-sum-edit { margin-left: auto; flex-shrink: 0; color: var(--text-faint); font-weight: 600; }

.pbar-popover { position: absolute; left: 22px; right: 22px; bottom: calc(100% - 2px);
  background: var(--bg-1); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: var(--shadow-2); padding: 12px; z-index: 50; max-height: 60vh; overflow-y: auto;
  display: flex; flex-direction: column; gap: 14px; }
.pbar-popover.hidden { display: none; }
.pbar-pop-sec { display: flex; flex-direction: column; gap: 4px; }
.pbar-pop-title { font-size: 11px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--text-faint); font-weight: 700; margin-bottom: 2px; }
.pbar-radio, .pbar-check { display: flex; align-items: flex-start; gap: 9px; padding: 6px 8px;
  border-radius: 8px; cursor: pointer; font-size: 13px; color: var(--text); }
.pbar-radio:hover, .pbar-check:hover { background: var(--bg-2); }
.pbar-radio input, .pbar-check input { margin-top: 2px; flex-shrink: 0; accent-color: var(--accent); }
.pbar-radio small, .pbar-check small { display: block; color: var(--text-faint); font-size: 11.5px; margin-top: 1px; }
.pbar-choose { display: flex; flex-direction: column; gap: 2px; margin: 2px 0 4px 26px;
  padding-left: 10px; border-left: 1px solid var(--border); }
.pbar-choose.hidden { display: none; }
.pbar-item { display: flex; align-items: center; gap: 8px; padding: 5px 8px; border-radius: 7px;
  cursor: pointer; font-size: 13px; color: var(--text); }
.pbar-item:hover { background: var(--bg-2); }
.pbar-item.lead { cursor: default; }
.pbar-item input { accent-color: var(--accent); flex-shrink: 0; }
.pbar-item .pbar-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pbar-item small { color: var(--text-faint); font-size: 11px; flex-shrink: 0; }
.pbar-av { width: 20px; height: 20px; border-radius: 50%; background: var(--bg-3); flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 700; }
.pbar-order { width: 18px; height: 18px; border-radius: 50%; flex-shrink: 0; font-size: 10.5px; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center; background: var(--accent); color: var(--on-accent); }
.pbar-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--text-faint); flex-shrink: 0; margin-left: auto; box-sizing: border-box; }
/* Same vocabulary again — fill = a person is there, colour = whether we know. */
.pbar-dot.active { background: var(--ok); }
.pbar-dot.idle { background: var(--warn); }
.pbar-dot.away { background: transparent; border: 1.5px solid var(--ok); }
.pbar-dot.online { background: transparent; border: 1.5px solid var(--ok); }
.pbar-dot.unknown { background: transparent; border: 1.5px dashed var(--text-faint); opacity: .8; }
.pbar-dot.offline { background: var(--text-faint); }
.pbar-dot.local { background: var(--accent); }
.pbar-moves { display: inline-flex; align-items: center; gap: 1px; margin-left: auto; }
.pbar-move { border: none; background: none; color: var(--text-faint); cursor: pointer; font-size: 10px;
  line-height: 1; padding: 3px; border-radius: 5px; }
.pbar-move:hover:not(:disabled) { background: var(--bg-hover); color: var(--text); }
.pbar-move:disabled { opacity: .3; cursor: default; }
.pbar-empty { font-size: 12.5px; color: var(--text-faint); padding: 4px; }

/* ---- Inbox / Action Center ---- */
.inbox-list { display: flex; flex-direction: column; gap: 12px; max-width: 780px; }
.inbox-group-title {
  font-size: 12px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: var(--text-dim); margin: 8px 2px 0; display: flex; align-items: center; gap: 8px;
}
.inbox-group-title.inbox-group-dim { color: var(--text-faint); }
.inbox-count {
  background: var(--accent); color: var(--on-accent); border-radius: 999px;
  min-width: 18px; height: 18px; padding: 0 5px; font-size: 11px; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
}
.inbox-count-dim { background: var(--bg-3); color: var(--text-dim); }
/* Collapsible "Recent" history header — same uppercase label language as a group title */
.inbox-recent-toggle {
  font-size: 12px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: var(--text-faint); margin: 10px 2px 0; padding: 4px 4px; width: 100%;
  display: flex; align-items: center; gap: 8px; background: none; border: none;
  cursor: pointer; text-align: left; border-radius: 8px;
}
.inbox-recent-toggle:hover { background: var(--bg-hover); color: var(--text-dim); }
.inbox-recent-caret { display: inline-block; transition: transform .15s ease; font-size: 10px; }
.inbox-recent-toggle.open .inbox-recent-caret { transform: rotate(90deg); }
/* --- One task's cards, folded into a single expandable line -------------------
   A task that fanned out into eleven approvals is ONE thing to decide about, so it
   reads as one row until you open it. Near-duplicate tasks merge into the same
   group, which is what the "N similar tasks" sub-label is telling you. */
.inbox-grp { margin: 2px 0; }
.inbox-grp-head {
  width: 100%; display: flex; align-items: center; gap: 9px; padding: 9px 10px;
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 10px;
  cursor: pointer; text-align: left; color: var(--text);
}
.inbox-grp-head:hover { border-color: var(--accent); background: var(--accent-soft); }
.inbox-grp-caret { flex-shrink: 0; width: 10px; display: inline-block; transition: transform .15s ease;
  font-size: 13px; line-height: 1; color: var(--text-dim); }
.inbox-grp-head:hover .inbox-grp-caret { color: var(--accent-2); }
.inbox-grp.open .inbox-grp-caret { transform: rotate(90deg); }
.inbox-grp-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.inbox-grp-title { font-size: 13px; font-weight: 600; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.inbox-grp-sub { font-size: 11.5px; color: var(--text-faint); }
/* An approval nearing its expiry: the age is the actionable fact, so it stops being
   grey furniture and starts reading as a deadline. */
.inbox-row-when.stale { color: var(--warn, #e0a800); font-weight: 700; }
.inbox-expired { color: var(--text-faint); border: 1px solid var(--border); border-radius: 5px;
  padding: 0 4px; font-size: 10px; text-transform: uppercase; letter-spacing: .04em; }
/* Decide the whole group in one go — sits above the individual rows, because for a
   task that fanned out into 25 sends the bulk action is the normal case. */
.inbox-grp-bulk { display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  margin: 6px 0 2px 21px; }
.inbox-grp-bulk .btn-primary, .inbox-grp-bulk .btn-mini { padding: 6px 12px; font-size: 12.5px; }
.inbox-grp-bulkhint { font-size: 11.5px; color: var(--text-faint); }
/* Indented + rail so an open group's rows read as belonging to it. */
.inbox-grp.open .inbox-grp-items {
  margin: 3px 0 8px 12px; padding-left: 9px; border-left: 2px solid var(--border);
  display: flex; flex-direction: column; gap: 2px;
}
/* --- Memory review: a night's compaction batch as a per-item checklist ---------
   Replaces the old body-as-wall-of-text for ref_type="compaction". Groups collapse
   (big batches start closed) and every row is independently tickable. */
.cmp-review { display: flex; flex-direction: column; gap: 10px; margin: 14px 0 4px; }
.cmp-lead { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; }
.cmp-lead-count { font-size: 13.5px; font-weight: 600; color: var(--text); }
.cmp-lead-count b { color: var(--accent); }
.cmp-lead-hint { font-size: 12.5px; color: var(--text-faint); }
/* The "what am I even approving?" banner. It sits ABOVE the groups and states what a
   tick and an untick each do — with 100+ rows the old faint one-line hint scrolled out
   of sight long before you reached a checkbox. */
.cmp-intro {
  display: flex; flex-direction: column; gap: 8px; padding: 12px 14px;
  border: 1px solid color-mix(in srgb, var(--accent) 30%, var(--border));
  border-radius: var(--radius); background: color-mix(in srgb, var(--accent) 7%, var(--bg-2));
}
.cmp-intro-lead { font-size: 13px; color: var(--text); line-height: 1.5; }
.cmp-legend { display: flex; flex-wrap: wrap; gap: 6px 20px; }
.cmp-leg { display: flex; align-items: baseline; gap: 7px; font-size: 12.5px; color: var(--text-dim); }
.cmp-leg b { color: var(--text); font-weight: 600; }
.cmp-box {
  flex: none; width: 14px; height: 14px; border-radius: 4px; border: 1.5px solid var(--border);
  background: var(--bg); font-size: 10px; line-height: 12px; text-align: center; align-self: center;
}
.cmp-box.on { background: var(--accent); border-color: var(--accent); color: #fff; }
/* What applying this whole group does — visible even while the group is collapsed. */
.cmp-gnote {
  padding: 0 12px 10px 33px; margin-top: -4px;
  font-size: 12px; line-height: 1.5; color: var(--text-faint);
}
.cmp-group.danger .cmp-gnote { color: var(--danger); }
/* Per-row verb, so a row read on its own still says what happens to it. */
.cmp-act {
  display: inline-block; margin-right: 7px; padding: 1px 7px; border-radius: 999px;
  font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em;
  vertical-align: 1px; background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: var(--accent);
}
.cmp-act.danger { background: color-mix(in srgb, var(--danger) 16%, transparent); color: var(--danger); }
.cmp-row.off .cmp-act { background: color-mix(in srgb, var(--text-faint) 14%, transparent); color: var(--text-faint); }
.cmp-group { border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-2); overflow: hidden; }
.cmp-group.danger { border-color: color-mix(in srgb, var(--danger) 45%, var(--border)); }
.cmp-ghead { display: flex; align-items: center; gap: 6px; padding-right: 8px; }
.cmp-gtoggle {
  flex: 1; min-width: 0; display: flex; align-items: center; gap: 9px;
  padding: 11px 12px; border: none; background: none; color: var(--text);
  font-size: 13.5px; font-weight: 600; text-align: left; cursor: pointer;
}
.cmp-gtoggle:hover { background: var(--bg-hover); }
.cmp-caret { color: var(--text-faint); font-size: 10px; transition: transform .15s ease; }
.cmp-group.open .cmp-caret { transform: rotate(90deg); }
/* Labels now name the ACTION ("Retire the old wording — …"), so they wrap rather than
   ellipsise — a truncated label is exactly what made the decision unreadable. */
.cmp-glabel { flex: 1; min-width: 0; line-height: 1.4; overflow-wrap: anywhere; }
.cmp-group.danger .cmp-glabel { color: var(--danger); }
.cmp-gcount { color: var(--text-faint); font-size: 12px; font-weight: 500; white-space: nowrap; }
.cmp-gcount b { color: var(--accent); font-weight: 700; }
.cmp-gall {
  border: 1px solid var(--border); background: var(--bg); color: var(--text-dim);
  border-radius: 7px; padding: 4px 9px; font-size: 11.5px; white-space: nowrap; cursor: pointer;
}
.cmp-gall:hover { color: var(--text); border-color: var(--accent); }
.cmp-rows { display: none; flex-direction: column; border-top: 1px solid var(--border); max-height: 420px; overflow-y: auto; }
.cmp-group.open .cmp-rows { display: flex; }
.cmp-row {
  display: flex; align-items: flex-start; gap: 10px; padding: 9px 12px;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 55%, transparent); cursor: pointer;
}
.cmp-row:last-child { border-bottom: none; }
.cmp-row:hover { background: var(--bg-hover); }
.cmp-row input { margin-top: 2px; accent-color: var(--accent); flex: none; cursor: pointer; }
.cmp-row-main { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.cmp-row-text { font-size: 13px; color: var(--text); line-height: 1.45; overflow-wrap: anywhere; }
.cmp-row-sub { font-size: 12px; color: var(--text-faint); overflow-wrap: anywhere; }
/* Unticked = "keep this as-is" — dim it so what you're APPLYING stays scannable. */
.cmp-row.off .cmp-row-text { color: var(--text-faint); text-decoration: line-through; text-decoration-color: var(--text-faint); }
.cmp-row.off .cmp-row-sub { opacity: .6; }
.cmp-group.danger .cmp-row-sub { color: var(--danger); }
/* Provenance chip on a mined suggestion — click to open the chat it came from. */
.cmp-prov {
  border: 1px solid var(--border); background: var(--bg-3); color: var(--text-dim);
  border-radius: 999px; padding: 1px 9px; font-size: 11px; cursor: pointer;
}
.cmp-prov:hover { color: var(--accent); border-color: var(--accent); }
/* "You already remember something similar" — the near neighbours of a mined proposal.
   Deliberately quiet: it is context for the tick, not a warning, and it must not
   out-shout the proposal itself. The rule sits left, so a row with neighbours is
   scannable as one at a glance. */
.cmp-row-known {
  margin-top: 3px; padding-left: 8px; border-left: 2px solid var(--border);
  display: flex; flex-direction: column; gap: 2px;
  font-size: 11.5px; color: var(--text-faint); line-height: 1.4;
}
.cmp-row-known b { font-weight: 600; color: var(--text-dim); }
.cmp-known-item { overflow-wrap: anywhere; }
.cmp-row.off .cmp-row-known { opacity: .55; }

/* --- Actionable digest: "what I'd do next", tickable, run in parallel ----------
   Reuses the .cmp-row anatomy so a review row and a proposal row read the same. */
.dact { margin: 16px 0 4px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-2); overflow: hidden; }
.dact-head { display: flex; flex-direction: column; gap: 3px; padding: 11px 13px 9px; border-bottom: 1px solid var(--border); }
.dact-title { font-size: 13.5px; font-weight: 700; color: var(--text); }
.dact-rows { display: flex; flex-direction: column; max-height: 380px; overflow-y: auto; }
.dact .cmp-row-sub { color: var(--accent); }
.dact .cmp-row.off .cmp-row-sub { color: var(--text-faint); }
.dact-tag {
  margin-left: 8px; padding: 1px 7px; border-radius: 999px; font-size: 10.5px;
  font-weight: 700; text-transform: uppercase; letter-spacing: .03em;
  background: color-mix(in srgb, var(--danger) 16%, transparent); color: var(--danger);
}
.dact .inbox-actions { padding: 11px 13px; border-top: 1px solid var(--border); margin: 0; }

.inbox-allclear { color: var(--text-faint); font-size: 13px; padding: 14px 4px 4px; }
.inbox-reading-sub { color: var(--text-faint); font-size: 12.5px; }
.inbox-card {
  background: var(--bg-2); border: 1px solid var(--border); border-left: 3px solid var(--border);
  border-radius: var(--radius); padding: 14px 16px; display: flex; flex-direction: column; gap: 10px;
}
.inbox-card.inbox-approval { border-left-color: var(--ok); }
.inbox-card.inbox-question { border-left-color: #e0a640; }
.inbox-card.inbox-status { border-left-color: #5a9bd8; }
.inbox-card.inbox-digest { border-left-color: #9b8cff; }
.inbox-card.inbox-dealt { opacity: .62; }
.inbox-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.inbox-kind {
  font-size: 11px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase;
  color: var(--text-dim); white-space: nowrap;
}
.inbox-title { font-weight: 600; color: var(--text); flex: 1; min-width: 0; }
.inbox-when { font-size: 11.5px; color: var(--text-faint); white-space: nowrap; margin-left: auto; }
.inbox-src-row { font-size: 12px; color: var(--text-faint); margin: -2px 0 2px; }
.inbox-src-row a { color: var(--accent-2); text-decoration: none; }
.inbox-src-row a:hover { text-decoration: underline; }
.inbox-src-when { white-space: nowrap; }
/* The card's own stamp is a date now, not just a time — give it room not to wrap. */
.idet-when { white-space: nowrap; }
.inbox-body { font-size: 13.5px; color: var(--text-dim); line-height: 1.6; }
.inbox-body.md p { margin: 0 0 6px; }
.inbox-body.md p:last-child { margin-bottom: 0; }
.inbox-body pre, .inbox-body code { font-family: var(--mono); font-size: 12.5px; }
.inbox-action-hint { font-size: 12px; color: var(--text-faint); }
.inbox-action-hint code { font-family: var(--mono); background: var(--bg-3); padding: 1px 5px; border-radius: 5px; }
.inbox-actions { display: flex; gap: 8px; flex-wrap: wrap; }
/* "✓ Task done" closes real work, so it reads as a settle rather than as another grey
   secondary — but it stays a mini button, because the primary on these cards is still
   answering the question, not abandoning it. */
.btn-taskdone { color: var(--ok); border-color: transparent; background: var(--ok-soft); }
.btn-taskdone:hover { background: var(--ok-soft); filter: brightness(1.12); }

/* The literal payload an Approve will send. Open by default — the whole point is
   that it is read before the button is pressed, not found by someone who went looking. */
.inbox-payload {
  background: var(--bg-2); border: 1px solid var(--border);
  border-radius: 9px; padding: 9px 11px; margin-bottom: 9px; font-size: 12.5px;
}
.inbox-payload > summary {
  cursor: pointer; font-weight: 600; color: var(--text-dim);
  font-size: 12px; list-style: none; display: flex; align-items: center; gap: 8px;
}
.inbox-payload > summary::-webkit-details-marker { display: none; }
.inbox-payload[open] > summary { margin-bottom: 8px; }
.pl-tool {
  margin-left: auto; font-family: var(--mono); font-size: 11px;
  color: var(--text-faint); background: var(--bg-3); padding: 1px 6px; border-radius: 5px;
}
.pl-body-wrap { display: flex; flex-direction: column; gap: 6px; }
.pl-row { display: flex; gap: 10px; align-items: baseline; }
.pl-key {
  color: var(--text-faint); font-size: 11.5px; font-weight: 600;
  min-width: 74px; flex-shrink: 0;
}
.pl-val { color: var(--text); word-break: break-word; }
/* An id with no resolved name: shown shortened (full value in the tooltip), and
   quietly, so it reads as plumbing rather than as the answer to "send it to whom?". */
.pl-idraw { color: var(--text-faint); font-family: var(--mono, ui-monospace, monospace); font-size: 12px; }
/* A resolved Teams name that links to the real chat/team/channel. */
.pl-row-wrap { flex-wrap: wrap; }
.pl-link { color: var(--accent); text-decoration: none; }
.pl-link:hover { text-decoration: underline; }

.pl-redacted { color: var(--text-faint); font-style: italic; }
.pl-block { display: flex; flex-direction: column; gap: 3px; }
.pl-body {
  margin: 0; max-height: 260px; overflow: auto; white-space: pre-wrap; word-break: break-word;
  background: var(--bg); border: 1px solid var(--border); border-radius: 7px;
  padding: 8px 10px; font-family: inherit; font-size: 12.5px; line-height: 1.5; color: var(--text);
}
/* A drafted message is Markdown. Shown as raw source, its comparison table was a wall
   of pipes at the exact moment the reader has to decide whether to send it — so the
   block renders the formatting and keeps the literal string behind "exact text".
   `pre-wrap` has to go in the rendered view: the block elements carry their own
   spacing, and pre-wrap would add the source's newlines on top of them. */
.pl-body.pl-rendered { white-space: normal; }
.pl-body.pl-rendered > :first-child { margin-top: 0; }
.pl-body.pl-rendered > :last-child { margin-bottom: 0; }
.pl-body.pl-rendered .md-table { font-size: 12px; margin: 6px 0; }
.pl-body.pl-rendered th, .pl-body.pl-rendered td {
  border: 1px solid var(--border); padding: 4px 8px; text-align: left;
}
.pl-body.pl-rendered th { background: var(--bg-2); font-weight: 600; }
.pl-hasmd .pl-key { display: flex; align-items: baseline; gap: 8px; }
.pl-raw-toggle {
  background: none; border: none; padding: 0; cursor: pointer; font: inherit;
  font-size: 11px; color: var(--accent); text-decoration: underline;
}
.pl-raw-toggle:hover { color: var(--accent-2); }
.inbox-answer { display: flex; flex-direction: column; gap: 8px; }
/* Where the answer goes — above the box, so it is read before it is needed. */
.inbox-dest { font-size: 12px; color: var(--text-faint); line-height: 1.5; }
.inbox-dest .inbox-taskref { font-weight: 600; }
.inbox-taskref {
  color: var(--accent-2); text-decoration: none; font-weight: 600;
  white-space: nowrap; max-width: 100%; overflow: hidden; text-overflow: ellipsis;
  display: inline-block; vertical-align: bottom;
}
.inbox-taskref:hover { text-decoration: underline; }
.inbox-answer-input {
  width: 100%; background: var(--bg); border: 1px solid var(--border); border-radius: 8px;
  color: var(--text); padding: 8px 10px; font-family: var(--font); font-size: 13px; resize: vertical;
}
.inbox-answer-input:focus { outline: none; border-color: var(--text-dim); }
.inbox-resolved { font-size: 12px; font-weight: 700; color: var(--text-faint); }
.inbox-card { cursor: pointer; }
.inbox-open-hint { font-size: 11px; color: var(--text-faint); }
.inbox-card:hover .inbox-open-hint { color: var(--text-dim); }
.inbox-card.inbox-dealt .inbox-open-hint { display: none; }

/* Inbox item detail modal — full problem + the AI's suggested answer */
.idet-modal { max-width: 600px; padding: 0 22px 22px; overflow-y: auto; }
.idet-loading { padding: 44px; text-align: center; color: var(--text-faint); }
.idet-head { display: flex; align-items: center; gap: 10px; position: sticky; top: 0;
  background: var(--bg-2); padding: 18px 0 12px; z-index: 1; }
.idet-when { font-size: 11.5px; color: var(--text-faint); margin-left: auto; }
.idet-close { border: none; background: none; color: var(--text-dim); font-size: 15px; cursor: pointer;
  width: 28px; height: 28px; border-radius: 8px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; }
.idet-close:hover { background: var(--bg-hover); color: var(--text); }
.idet-title { font-size: 18px; margin: 0 0 12px; color: var(--text); line-height: 1.35; }
.idet-suggest { margin: 14px 0; padding: 12px 14px; border-radius: 12px; background: var(--accent-soft); }
.idet-suggest-head { font-size: 12px; font-weight: 700; color: var(--accent-2); margin-bottom: 6px; }
.idet-suggestion { font-size: 13.5px; color: var(--text); line-height: 1.6; }
.idet-aic { font-size: 11.5px; font-weight: 600; color: var(--accent-2); margin-bottom: 8px;
  padding: 5px 9px; border-radius: 8px; background: var(--bg-2); display: inline-block; }
/* "Tick what's suggested" — turns the suggestion's prose into checkbox state on a
   tickable card. Sits under the suggestion because that is what it acts on, and stays a
   mini button: it only moves ticks, and the button that actually applies them is the
   primary one further down the card. */
.idet-apply-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 10px; }
.idet-apply { background: var(--bg-2); border: 1px solid var(--accent); color: var(--accent-2);
  font-weight: 600; cursor: pointer; }
.idet-apply:hover { background: var(--bg-hover); }
.idet-apply-hint { font-size: 11.5px; color: var(--text-faint); flex: 1; min-width: 160px; }
/* "Working out an Inbox item" bar shown atop a scoped chat/discussion (one-click settle) */
.inbox-settle-bar { display: flex; align-items: center; gap: 12px; margin: 8px 16px 0;
  padding: 8px 14px; border-radius: 10px; background: var(--accent-soft);
  border: 1px solid var(--accent); }
.inbox-settle-bar .isb-text { font-size: 12.5px; color: var(--text); font-weight: 500; }
.inbox-settle-bar .isb-title { color: var(--accent-2); font-weight: 600; margin-left: 6px; }
.inbox-settle-bar .isb-settle { margin-left: auto; border: 1px solid var(--accent);
  background: var(--accent); color: #fff; border-radius: 8px; padding: 6px 12px;
  font-size: 12.5px; font-weight: 600; cursor: pointer; white-space: nowrap; }
.inbox-settle-bar .isb-settle:hover { filter: brightness(1.08); }
.inbox-settle-bar .isb-settle:disabled { opacity: .6; cursor: default; }
.idet-suggestion.loading { color: var(--text-faint); font-style: italic; }
.idet-suggestion p { margin: 0 0 6px; } .idet-suggestion p:last-child { margin-bottom: 0; }
.idet-discuss-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 12px 0 4px; }
.idet-discuss { background: var(--bg-2); border: 1px solid var(--accent); color: var(--accent-2);
  border-radius: 999px; padding: 7px 16px; font-size: 13px; font-weight: 600; cursor: pointer; white-space: nowrap; }
.idet-discuss:hover { background: var(--accent-soft); color: var(--text); }
.idet-team { border-color: var(--border); color: var(--text-dim); }   /* secondary: bring the team in */
.idet-team:hover { border-color: var(--accent); color: var(--text); background: var(--bg-hover); }
.idet-discuss-hint { font-size: 11.5px; color: var(--text-faint); line-height: 1.5; }
.idet-actions { margin-top: 12px; }

/* ask_user — clickable guided choices in chat (the "offer options like Opus" tool) */
.user-choices { align-self: stretch; margin: 8px 0 4px; }
.uc-q { font-size: 13.5px; font-weight: 600; color: var(--text); margin-bottom: 8px; }
.uc-opts { display: flex; flex-direction: column; gap: 8px; }
.uc-opt { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; text-align: left;
  width: 100%; background: var(--bg-2); border: 1px solid var(--border); border-radius: 12px;
  padding: 10px 14px; cursor: pointer; color: var(--text); transition: background .12s, border-color .12s; }
.uc-opt:hover:not(:disabled) { background: var(--bg-hover); border-color: var(--accent); }
.uc-opt.on, .uc-opt.chosen { background: var(--accent-soft); border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.uc-opt:disabled { cursor: default; }
.uc-label { font-weight: 600; font-size: 13.5px; }
.uc-desc { font-size: 12px; color: var(--text-faint); line-height: 1.45; }
.uc-send { margin-top: 8px; background: var(--accent); color: var(--on-accent); border: none;
  border-radius: 999px; padding: 6px 16px; font-size: 13px; font-weight: 600; cursor: pointer; }
.uc-send:disabled { opacity: .5; cursor: default; }
.user-choices.answered { opacity: .75; }
/* Multi-question (tabbed) variant — ask several decisions at once. */
.mq-intro { font-size: 12.5px; color: var(--text-dim); margin-bottom: 8px; }
.mq-tabs { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px;
  border-bottom: 1px solid var(--border); padding-bottom: 8px; }
.mq-tab { display: inline-flex; align-items: center; gap: 5px; background: var(--bg-2);
  border: 1px solid var(--border); border-radius: 999px; padding: 5px 12px; font-size: 12.5px;
  font-weight: 600; color: var(--text-dim); cursor: pointer; transition: background .12s, color .12s, border-color .12s; }
.mq-tab:hover:not(:disabled) { border-color: var(--accent); }
.mq-tab.active { background: var(--accent-soft); border-color: var(--accent); color: var(--text); }
.mq-tab .mq-check { color: var(--accent); font-weight: 700; font-size: 11px; }
.mq-tab .mq-check.hidden { display: none; }
.mq-hint { font-size: 11.5px; color: var(--text-faint); margin-top: 6px; }
.mq-submit { margin-top: 10px; }
.uc-other .uc-label { color: var(--text-dim); }
.uc-otherbox { display: flex; gap: 8px; margin-top: 8px; }
.uc-otherbox.hidden { display: none; }
.uc-otherinput { flex: 1; background: var(--bg); border: 1px solid var(--border); border-radius: 10px;
  color: var(--text); padding: 8px 12px; font-family: var(--font); font-size: 13.5px; }
.uc-otherinput:focus { outline: none; border-color: var(--accent); }
.uc-othersend { background: var(--accent); color: var(--on-accent); border: none; border-radius: 999px;
  padding: 6px 16px; font-size: 13px; font-weight: 600; cursor: pointer; white-space: nowrap; }
.uc-othersend:disabled { opacity: .5; cursor: default; }
.inbox-result {
  font-size: 12.5px; color: var(--text-dim); line-height: 1.55;
  background: var(--bg); border: 1px solid var(--border); border-radius: 8px; padding: 8px 10px;
}

/* ============================================================
   REDESIGN LAYER (2026-07) — appended last so it wins the cascade.
   Upgrades hierarchy, spacing and readability across the app and
   makes every hardcoded dark-only colour work in the light theme.
   Component markup and class names are unchanged.
   ============================================================ */

/* ---- global polish ---- */
body { font-size: 14.5px; }
button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px;
}
h1, h2, h3 { letter-spacing: -0.01em; }

/* ---- sidebar ---- */
#sidebar { width: var(--rail-w); padding: 12px; gap: 10px; }
.brand { padding: 6px 8px 2px; }
.side-item {
  color: var(--text-dim); font-size: 13.5px; padding: 7px 10px; border-radius: 8px;
}
.side-item:hover { color: var(--text); }
.side-item.active, .skill-nav .side-item.active {
  background: var(--accent-soft); color: var(--text); font-weight: 600;
}
.side-section-title {
  font-size: 10px; letter-spacing: .09em; color: var(--text-faint);
  padding: 8px 10px 3px; font-weight: 700;
}
.nav-badge { background: var(--accent); color: var(--on-accent); }
#inbox-badge { background: var(--danger); color: #fff; }
.avatar-mini { background: linear-gradient(135deg, var(--accent), #9c6bf7); color: #fff; }
.logout-btn { padding: 7px 10px; display: inline-flex; align-items: center; justify-content: center; }
#theme-toggle:hover { color: var(--accent-2); border-color: var(--accent); background: var(--accent-soft); }

/* ---- chat: assistant text reads like a document, user keeps a bubble ---- */
.msg-row { max-width: 780px; }  /* match the composer width so chat + input align */
.msg-row.assistant .msg-content {
  background: transparent; border: none; border-radius: 0; padding: 2px 0;
  align-self: stretch;  /* fill the column so text lines up with the Workbench card */
}
.msg-row.user .msg-content { background: var(--user-bubble); border-radius: 16px 16px 4px 16px; max-width: 75%; }
.msg-row.peer .msg-content { border-radius: 16px 16px 16px 4px; }
.msg-content pre { color: #dfe3ea; }
.msg-content pre code { color: inherit; }
.tool-detail { color: #b9c0ca; }
.composer-inner { box-shadow: var(--shadow-1); }
.composer-inner:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }

/* ---- page scaffolding ---- */
.page-head { padding: 24px 32px 0; }
.page-head h1 { font-size: 21px; }
.page-body { padding: 22px 32px 44px; }
.page-head-icon { border-radius: 12px; font-size: 26px; width: 50px; height: 50px; }

/* ---- cards get depth; borders soften ---- */
.market-card, .task-card, .inbox-card, .gc-item, .skill-result, .skill-schedule {
  box-shadow: var(--shadow-1);
}
.market-card:hover { border-color: var(--accent); box-shadow: var(--shadow-2); }
.drop-menu { box-shadow: var(--shadow-2); }
.modal { box-shadow: var(--shadow-2); }

/* ---- tasks board ---- */
.task-col { background: var(--bg-2); }
:root[data-theme="light"] .task-col { background: #f1f1f5; border-color: transparent; }
:root[data-theme="light"] .task-card { background: var(--bg-2); }
.task-card { border-radius: 10px; }
.task-card:hover { border-color: var(--accent); }

/* ---- Home dashboard ---- */
/* Home's scroller and its reading column are the SAME element — `class="page-body
   home-body"` — so capping the width here capped the SCROLLING BOX, and its scrollbar
   sat ~190px in from the window edge while every other view's sat at the edge.
   The column is still 1180px and still centred; the PADDING centres it now, which
   leaves `.page-body` full width and puts its scrollbar back where the rest of the
   app keeps it. `max()` holds the normal 32px gutter on narrower screens. */
.home-body { padding-inline: max(32px, calc((100% - 1180px) / 2)); }
.home-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; padding: 14px 0 20px; flex-wrap: wrap; }
.home-head h1 { margin: 0; font-size: 26px; font-weight: 680; letter-spacing: -.02em; }
/* The old scale jumped 26px -> 13px with nothing between, so nothing read as a
   section. 16px/650 card headings (above) are the missing middle step. */
/* start, not stretch: a folded card must not be dragged to the height of an open
   neighbour, or the collapsed stack stops looking tidy. */
.home-grid { align-items: start; }
.home-date { margin: 4px 0 0; color: var(--text-faint); font-size: 13px; }
.home-quick { display: flex; gap: 8px; align-items: center; }
.home-quick .btn-mini { padding: 9px 14px; }
.home-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(148px, 1fr)); gap: 12px; margin-bottom: 18px; }
.home-stat-tile {
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 14px;
  padding: 15px 18px; display: flex; flex-direction: column; gap: 3px; align-items: flex-start;
  cursor: pointer; box-shadow: var(--shadow-1); text-align: left;
  transition: border-color .15s ease, transform .15s ease;
}
.home-stat-tile:hover { border-color: var(--accent); transform: translateY(-1px); }
.home-stat-n { font-size: 30px; font-weight: 700; line-height: 1.05; font-variant-numeric: tabular-nums; color: var(--text); }
.home-stat-n.ready { color: var(--accent-2); }
.home-stat-n.blocked { color: var(--warn); }
.home-stat-n.accent { color: var(--accent); }
.home-stat-label { font-size: 11.5px; color: var(--text-dim); text-transform: uppercase; letter-spacing: .05em; font-weight: 600; }

/* Inbox — full-bleed 4-column hub: folders | list | reading | Your AI.
   Same shell as Group Chat (.gc-hub), one column wider. */
.ibx-hub {
  flex: 1; min-height: 0; display: grid; background: var(--bg); position: relative;
  /* The rail REPLACES the app sidebar, so it is the app sidebar's width — `--rail-w`,
     which every rail in the product now shares. It was squeezed to 200 to buy room for
     the fourth column,
     which made the Inbox the one view where the left edge of the app moved when you
     navigated to it. The reading pane gives the room up instead; it is the column that
     can flex. The AI panel is the widest of the three fixed ones because it is no longer
     a sidebar: it holds the draft, the verbs and the ask, and 340px clipped all three. */
  grid-template-columns: var(--rail-w) 280px minmax(0, 1fr) 500px;
}
.ibx-rail { border-right: 1px solid var(--border); background: var(--bg-2); display: flex; flex-direction: column; min-height: 0; }
.ibx-rail-head { display: flex; align-items: center; gap: 8px; padding: 14px 12px 10px; border-bottom: 1px solid var(--border); }
.ibx-rail-title { font-weight: 700; font-size: 15px; flex: 1; }
/* 12px inset + the row's own 10px = the app sidebar's 22px text edge, so the folders sit
   exactly where the nav items they replaced did. */
.ibx-rail-list { flex: 1; min-height: 0; overflow-y: auto; padding: 10px 12px; display: flex; flex-direction: column; gap: 2px; }
/* A section head (Needs you / Updates / Done) is a destination in its own right — it
   holds everything in the folders under it — so it is a button too, just a heavier one.
   Touring three folders to clear your work is exactly what this avoids. */
.ibx-fold {
  display: flex; align-items: center; gap: 9px; width: 100%; text-align: left;
  border: none; background: none; color: var(--text-dim); cursor: pointer;
  border-radius: 9px; padding: 7px 10px 7px 22px; font: inherit; font-size: 13px;
}
.ibx-fold:hover { background: var(--bg-hover); color: var(--text); }
.ibx-fold.on { background: var(--accent-soft); color: var(--text); font-weight: 600; }
.ibx-fold-head { padding-left: 10px; margin-top: 10px; font-weight: 700; font-size: 13.5px; color: var(--text); }
.ibx-fold-head:first-child { margin-top: 0; }
/* Stroke icons, sized and dimmed exactly as the app sidebar's are, so the rail reads as
   the same piece of furniture. Colour comes from the row — one accent when selected,
   muted otherwise — which is the whole reason for dropping emoji. */
.ibx-ico { width: 17px; height: 17px; display: block; }
.ibx-fold-ico { flex-shrink: 0; display: flex; opacity: .72; }
.ibx-fold:hover .ibx-fold-ico, .ibx-fold.on .ibx-fold-ico { opacity: 1; }
.ibx-lh-title { display: inline-flex; align-items: center; gap: 8px; }
.ibx-ico.lh { width: 16px; height: 16px; }
/* The source line's markers: inline with the text they label, at its weight. */
.ibx-ico.xs { width: 13px; height: 13px; display: inline-block; vertical-align: -2px; opacity: .8; }
.ibx-fold-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Two badge weights on purpose. A decision waiting on you is loud; unread news is
   quiet. Same number, different urgency — see `counts()` in backend/inbox_view.py. */
.ibx-fold-n {
  flex-shrink: 0; font-size: 11px; font-weight: 700; min-width: 20px; text-align: center;
  padding: 1px 6px; border-radius: 999px; background: var(--bg-3); color: var(--text-dim);
}
.ibx-fold-n.loud { background: var(--accent); color: var(--on-accent, #fff); }
.ibx-listcol { display: flex; flex-direction: column; min-width: 0; min-height: 0; border-right: 1px solid var(--border); background: var(--bg); }
.ibx-listhead { flex-shrink: 0; padding: 13px 14px 9px; border-bottom: 1px solid var(--border); background: var(--bg-2); }
.ibx-lh-top { display: flex; align-items: center; gap: 8px; }
.ibx-lh-title { font-size: 14.5px; font-weight: 700; color: var(--text); }
.ibx-lh-n { font-size: 11.5px; color: var(--text-faint); }
.ibx-lh-read { margin-left: auto; font: inherit; font-size: 11.5px; padding: 2px 9px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--bg); color: var(--text-dim); cursor: pointer; }
.ibx-lh-read:hover { border-color: var(--accent); color: var(--text); }
.ibx-lh-blurb { font-size: 11.5px; color: var(--text-faint); line-height: 1.5; margin-top: 3px; }
/* Select all: the same 15px box the rows carry, so it reads as the column's own tick
   rather than a button that happens to sit above them. */
.ibx-lh-sel { margin-top: 8px; }
.ibx-lh-selall {
  display: inline-flex; align-items: center; gap: 7px; font: inherit; font-size: 11.5px;
  font-weight: 600; padding: 3px 10px 3px 6px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--bg); color: var(--text-dim); cursor: pointer;
}
.ibx-lh-selall:hover { border-color: var(--accent); color: var(--text); }
.ibx-lh-selall.on { border-color: var(--accent); color: var(--text); }
.ibx-lh-selbox {
  width: 15px; height: 15px; border-radius: 4px; flex-shrink: 0;
  border: 1.5px solid var(--border-strong, var(--border)); background: var(--bg);
  display: flex; align-items: center; justify-content: center;
  font-size: 10px; line-height: 1; color: var(--on-accent, #fff);
}
.ibx-lh-selall.on .ibx-lh-selbox { background: var(--accent); border-color: var(--accent); }
.ibx-read { min-width: 0; min-height: 0; overflow-y: auto; padding: 22px 26px 40px; background: var(--bg); }
/* Reading several at once. Each card keeps the reading pane's own layout — it IS that
   renderer — so the stack is separated by rules and spacing rather than by restyling the
   cards into something that looks like a different feature. */
.ibx-stack-head {
  display: flex; flex-direction: column; gap: 2px; margin-bottom: 14px; padding-bottom: 10px;
  border-bottom: 1px solid var(--border);
}
.ibx-stack-n { font-size: 13px; font-weight: 700; color: var(--text); }
.ibx-stack-sub { font-size: 11.5px; color: var(--text-faint); line-height: 1.5; }
.ibx-stack-hrow { display: flex; align-items: center; gap: 10px; }
.ibx-stack-all { flex-shrink: 0; }
/* A card folds to its title row. Fourteen fully-drawn cards is not a stack, it is one
   endless scroll — the fold is what lets you see the whole selection, open the one you
   are working on, and put it down again. */
.ibx-stack-card {
  display: block; margin: 0 0 10px; border-radius: 14px;
  border: 1px solid var(--border); background: var(--bg-2); overflow: hidden;
}
.ibx-stack-card.open { margin-bottom: 18px; }
.ibx-stack-hd {
  width: 100%; display: flex; align-items: center; gap: 9px; text-align: left;
  padding: 11px 14px; font: inherit; font-size: 13.5px; font-weight: 600; color: var(--text);
  background: none; border: 0; cursor: pointer;
}
.ibx-stack-hd:hover { background: var(--bg-3); }
.ibx-stack-caret { flex-shrink: 0; color: var(--text-faint); transition: transform .14s ease; }
.ibx-stack-card.open .ibx-stack-caret { transform: rotate(90deg); }
.ibx-stack-ico { flex-shrink: 0; display: inline-flex; opacity: .85; }
.ibx-stack-t { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ibx-stack-done {
  flex-shrink: 0; font-size: 10.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .06em; color: var(--text-faint);
}
.ibx-stack-when { flex-shrink: 0; font-size: 11px; font-weight: 500; color: var(--text-faint); }
.ibx-stack-body:not(:empty) { padding: 2px 16px 4px; border-top: 1px solid var(--border); }
.ibx-stack-card .idet-title { font-size: 16.5px; margin: 8px 0 12px; }
/* Where a row click lands you. Two seconds of accent edge, then back — long enough to
   find, short enough not to look like a selected state. */
.ibx-stack-card.flash { border-color: var(--accent); box-shadow: var(--shadow-1); }
.ibx-stack-more {
  font-size: 12px; color: var(--text-faint); line-height: 1.55; padding: 12px 14px;
  border: 1px dashed var(--border); border-radius: 12px;
}
.ibx-read .idet-head { display: flex; align-items: center; gap: 10px; }
.ibx-read .idet-title { margin: 10px 0 14px; font-size: 20px; }
/* The four slots. Each one is labelled, so a draft never has to be told apart from a
   report by its tone — the heading says which it is. */
.ibx-slot { margin: 0 0 16px; }
.ibx-slot-h {
  font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .09em;
  color: var(--text-faint); margin-bottom: 6px;
}
.ibx-slot-ask { border-left: 3px solid var(--accent); padding: 2px 0 2px 12px; }
.ibx-ask { font-size: 14px; color: var(--text); line-height: 1.55; }
.ibx-ask-det { font-size: 12.5px; color: var(--accent-2); margin-top: 4px; overflow-wrap: anywhere; }
.ibx-slot-none { font-size: 13px; color: var(--text-faint); font-style: italic; }
.ibx-slot-decide { border-top: 1px solid var(--border); padding-top: 14px; margin-top: 20px; }
/* The transcript sits last: it is reference material for the decision above it, so it
   must never push the buttons down the page on a long thread. */
.ibx-slot-thread { border-top: 1px solid var(--border); padding-top: 16px; margin-top: 22px; }
.ibx-settled {
  font-size: 12.5px; color: var(--text-dim); background: var(--bg-2); border: 1px solid var(--border);
  border-radius: 10px; padding: 9px 12px; margin-bottom: 16px;
}
/* "9 of 11" — this card's place in a fan-out, lifted out of the title so the title can
   be the subject. It is the only thing telling eleven near-identical rows apart. */
.ibx-seq {
  display: inline-block; font-size: 10.5px; font-weight: 700; color: var(--text-dim);
  background: var(--bg-3); border-radius: 5px; padding: 0 5px; margin-right: 6px;
}
.ibx-seq-big { font-size: 11px; padding: 1px 7px; }
/* Your AI, on the card you're reading. Mirrors .gc-ai so the two feel like one product. */
.ibx-ai {
  border-left: 1px solid var(--border); background: linear-gradient(180deg, var(--bg-2), var(--bg));
  display: flex; flex-direction: column; min-height: 0; padding: 16px 14px 14px;
}
.ibx-ai-head { display: flex; align-items: center; gap: 10px; flex-shrink: 0; padding-bottom: 12px; border-bottom: 1px solid var(--border); }
/* The same animated mark Group Chat uses (.gc-ai-logo drives the orbit + glow), sized
   for this panel. Reused rather than re-drawn so the two never drift apart. */
.ibx-ai-mark { position: relative; width: 42px; height: 42px; display: grid; place-items: center; flex: 0 0 auto; }
.ibx-ai-mark svg { position: relative; width: 34px; height: 34px; color: var(--accent); display: block; }
.ibx-ai-mark.sm { width: 38px; height: 38px; }
.ibx-ai-mark.sm svg { width: 30px; height: 30px; }
.ibx-ai-empty .ibx-ai-mark { width: 132px; height: 132px; }
.ibx-ai-empty .ibx-ai-mark svg { width: 96px; height: 96px; }
.ibx-ai-logo svg { width: 38px; height: 38px; color: var(--accent); display: block; }
.ibx-ai-logo.sm svg { width: 30px; height: 30px; }
/* The panel is a conversation: each step answers as it finishes, and nothing appears
   before the turn that produced it. */
.ibx-ai-body { display: flex; flex-direction: column; gap: 12px; }
.ibx-turn { animation: ibx-turn-in .2s ease-out; }
.ibx-turn.ai { background: var(--bg-2); border: 1px solid var(--border);
  border-radius: 4px 14px 14px 14px; padding: 12px 14px; }
.ibx-turn.ai.opts { background: none; border: none; padding: 0; }
/* Your pick reads as something you said, not as a button that silently changed the
   panel — so it sits on the other side, the way a reply does. */
.ibx-turn.me { align-self: flex-end; max-width: 85%; background: var(--accent);
  color: var(--on-accent, #fff); border-radius: 14px 14px 4px 14px; padding: 8px 13px;
  font-size: 12.5px; line-height: 1.45; }
.ibx-turn.draft .inbox-payload { margin: 8px 0 0; }
.ibx-ai-draft-h.plain { font-size: 10.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .09em; color: var(--text-faint); }
.ibx-opts-lead { font-size: 12.5px; color: var(--text-dim); margin-bottom: 8px; }
/* "Mark as done" sits apart from the choices: it is not one of them, it is the way out. */
.ibx-opts-quiet { margin-top: 10px; padding-top: 9px; border-top: 1px solid var(--border); }
.ibx-opt.quiet { background: none; border-color: transparent; color: var(--text-faint); font-size: 12.5px; }
.ibx-opt.quiet:hover { background: var(--bg-hover); border-color: var(--border); color: var(--text-dim); }
/* The live workbench inside an answer: every tool it calls, as it calls it. "Looking
   into it…" for eight seconds says nothing about whether it is reading Odoo, waiting on
   Teams, or stuck. */
.ibx-work { display: flex; flex-direction: column; gap: 1px; }
.ibx-work .ibx-step { padding: 3px 0; }
.ibx-work .wb-slabel { font-size: 12px; }
/* Once the answer is there the work is history: kept, folded small. */
.ibx-work-done { opacity: .5; margin-bottom: 6px; }
.ibx-work-done .wb-slabel { font-size: 11px; }
.ibx-answer { font-size: 13.5px; color: var(--text); line-height: 1.6; overflow-wrap: anywhere; }
.ibx-answer:empty { display: none; }
.ibx-answer p { margin: 0 0 7px; } .ibx-answer p:last-child { margin-bottom: 0; }
.ibx-answer ul, .ibx-answer ol { margin: 5px 0 8px; padding-left: 20px; }
.ibx-answer a { color: var(--accent-2); }
.ibx-answer table { font-size: 12px; display: block; overflow-x: auto; max-width: 100%; }
/* The gate between choosing and sending. It sits under the message it would send, so
   the words and the button that releases them are in one place. */
.ibx-gate { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--border); }
.ibx-gate-to { font-size: 11.5px; color: var(--accent-2); margin-bottom: 8px; overflow-wrap: anywhere; }
.ibx-gate-row { display: flex; flex-direction: column; gap: 6px; }
.ibx-gate-note { font-size: 11px; color: var(--text-faint); margin-top: 7px; line-height: 1.5; }
@keyframes ibx-turn-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.ibx-ai-name { font-size: 13.5px; font-weight: 700; color: var(--text); }
.ibx-ai-sub { font-size: 11.5px; color: var(--text-faint); }
.ibx-ai-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 14px 2px 6px; }
.ibx-ai-quiet { color: var(--text-faint); font-size: 12.5px; }
.ibx-ai-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 16px; height: 100%; text-align: center; }
.ibx-ai-emptytx { font-size: 13px; color: var(--text-faint); max-width: 270px; line-height: 1.65; }
.ibx-ai-foot { flex-shrink: 0; border-top: 1px solid var(--border); padding-top: 12px; }
/* The decision block. It sits under the AI's read of the card, because the order you
   want is "here's what I think, here's what you can do about it" — and in a 340px
   column the verbs have to stack, so each one gets a full line and can say what it
   does instead of being clipped to a word. */
.ibx-ai-act { flex-shrink: 0; border-top: 1px solid var(--border); padding-top: 12px; margin-top: 10px;
  max-height: 58%; overflow-y: auto; }
/* While the steps run there is nothing to act on yet. A wall of buttons under a
   "working it out…" list invites the click it is telling you to wait for. */
.ibx-ai-act.running { display: none; }
.ibx-ai-ask { font-size: 12.5px; color: var(--text); line-height: 1.5; }
.ibx-ai-askdet { font-size: 11.5px; color: var(--accent-2); margin-top: 3px; overflow-wrap: anywhere; }
/* What the AI thinks you might want to do, in its own words. Full-width rows rather
   than a wrapped row of chips: these are sentences, not verbs, and a sentence clipped
   to fit is worse than no suggestion. */
.ibx-ai-opts { display: flex; flex-direction: column; gap: 7px; }
.ibx-ai-opts:empty { display: none; }
.ibx-opts-wait { font-size: 12px; color: var(--text-faint); font-style: italic; padding: 4px 0; }
/* Nothing runs until it is asked for. Opening a card fired two model calls whether or
   not anyone wanted an opinion — on a 112-card inbox that made simply LOOKING cost
   money. */
.ibx-ai-idle { display: flex; flex-direction: column; align-items: flex-start; gap: 11px; padding: 6px 0 2px; }
.ibx-ai-idletx { font-size: 12.5px; color: var(--text-faint); }
/* The hero the panel rests in until it is asked to do something. */
.ibx-hero-tell { display: flex; gap: 6px; align-items: center; width: 100%; max-width: 320px; margin-top: 4px; }
.ibx-analyse {
  font: inherit; font-size: 13.5px; font-weight: 600; padding: 10px 18px; border-radius: 10px;
  border: 1px solid var(--accent); background: var(--accent); color: var(--on-accent, #fff);
  cursor: pointer;
}
.ibx-analyse:hover { filter: brightness(1.08); }
/* Reuses the chat workbench's step rows so "what the AI is doing" looks the same
   wherever you meet it. Each step is a call actually in flight — a real description,
   not a spinner cut into three. */
/* One step per line, each sitting directly above the reply it produced. A finished one
   is history — kept, quietly — while the one still running keeps its pulse. */
.ibx-step { padding: 2px 0; border-left: none; }
.ibx-step .wb-slabel { font-size: 12.5px; }
.ibx-step.done { opacity: .5; }
.ibx-step.done .wb-slabel { font-size: 11.5px; }
.ibx-ai-body > .ibx-step + .ibx-turn { margin-top: 2px; }
.ibx-ai-rec { margin-top: 4px; }
.ibx-opt {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  font: inherit; font-size: 13px; padding: 10px 13px; border-radius: 10px; cursor: pointer;
  border: 1px solid var(--border); background: var(--bg-2); color: var(--text);
}
.ibx-opt:hover { border-color: var(--accent); background: var(--bg-hover); }
.ibx-opt-ico { flex: 0 0 auto; width: 18px; text-align: center; color: var(--text-faint); font-size: 12px; }
.ibx-opt-label { flex: 1; min-width: 0; line-height: 1.4; }
/* The first one is what it would do; the rest are alternatives. */
.ibx-opt.lead { border-color: var(--accent); background: var(--accent-soft); font-weight: 600; }
.ibx-opt.go .ibx-opt-ico { color: var(--ok, #4caf50); }
.ibx-opt.no .ibx-opt-ico { color: var(--danger); }
.ibx-opt.ai .ibx-opt-ico { color: var(--accent-2); }
.ibx-ai-verbs { margin-top: 10px; }
.ibx-ai-verbs .inbox-actions { flex-direction: column; align-items: stretch; gap: 6px; }
.ibx-ai-verbs .inbox-actions button { width: 100%; text-align: center; }
.ibx-ai-verbs .btn-primary { padding: 9px 14px; font-size: 13px; }
.ibx-ai-verbs .inbox-answer { display: flex; flex-direction: column; gap: 7px; }
.ibx-ai-verbs .inbox-answer-input { width: 100%; min-height: 68px; }
.ibx-ai-verbs .inbox-dest { font-size: 11.5px; }
.ibx-ai-or { font-size: 11px; color: var(--text-faint); text-align: center; margin: 11px 0 7px;
  display: flex; align-items: center; gap: 8px; }
.ibx-ai-or::before, .ibx-ai-or::after { content: ""; flex: 1; height: 1px; background: var(--border); }
.ibx-ai-tell { display: flex; gap: 6px; align-items: center; margin-top: 11px; }
.ibx-ai-tellin { flex: 1; min-width: 0; background: var(--bg); border: 1px solid var(--border);
  border-radius: 999px; padding: 8px 13px; color: var(--text); font: inherit; font-size: 12.5px; outline: none; }
.ibx-ai-tellin:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.ibx-ai-tellgo { flex: 0 0 auto; width: 32px; height: 32px; border: none; border-radius: 50%;
  background: var(--accent); color: var(--on-accent, #fff); cursor: pointer; font-size: 14px; }
.ibx-ai-tellgo:hover { filter: brightness(1.08); }
.ibx-ai-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
/* The source line has no heading of its own — it reads as a byline under the title. */
.ibx-slot-src { margin-top: -4px; }
.ibx-chip {
  font: inherit; font-size: 12px; padding: 7px 12px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--accent); background: var(--bg-2); color: var(--accent-2);
}
.ibx-chip:hover { background: var(--accent-soft); color: var(--text); }
.ibx-chip-alt { border-color: var(--border); color: var(--text-dim); }
.ibx-chip-alt:hover { border-color: var(--accent); color: var(--text); }
.ibx-ai-hint { font-size: 11px; color: var(--text-faint); line-height: 1.55; margin-top: 9px; }
/* Narrow screens give ground in the order the columns can be spared: the list and the AI
   panel tighten first (a 1440 laptop keeps all four — the AI panel is the point of the
   redesign, so it is the last thing to go), then the AI panel moves, then the rail
   collapses to icons rather than disappearing. The RAIL holds `--rail-w` throughout: it
   is standing in for the app sidebar, and a sidebar that is a different width on one
   view reads as the app having shifted under you. */
@media (max-width: 1560px) { .ibx-hub { grid-template-columns: var(--rail-w) 260px minmax(0, 1fr) 440px; }
  .ibx-read { padding: 18px 20px 36px; } }
@media (max-width: 1320px) { .ibx-hub { grid-template-columns: var(--rail-w) 236px minmax(0, 1fr) 380px; } }
/* Narrow: the panel MOVES, it does not vanish. Every verb lives in it now, so hiding it
   left a window where you could read cards and do nothing about them. It becomes a
   drawer under the reading pane instead, and all four columns stay reachable. */
@media (max-width: 1120px) {
  .ibx-hub {
    grid-template-columns: var(--rail-w) minmax(0, 290px) minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr) auto;
    grid-template-areas: "rail list read" "rail list ai";
  }
  .ibx-rail { grid-area: rail; }
  .ibx-listcol { grid-area: list; }
  .ibx-read { grid-area: read; }
  .ibx-ai { grid-area: ai; display: flex; max-height: 46vh;
    border-left: 1px solid var(--border); border-top: 1px solid var(--border); }
  .ibx-ai-empty { padding: 14px 0; }
  .ibx-ai-empty .ibx-ai-mark { width: 64px; height: 64px; }
  .ibx-ai-empty .ibx-ai-mark svg { width: 46px; height: 46px; }
}
/* 920px is where the APP sidebar itself goes off-canvas, so that is where the rail may
   finally give up its width too — one breakpoint, not two 20px apart. */
@media (max-width: 920px) { .ibx-hub { grid-template-columns: 58px minmax(0, 240px) minmax(0, 1fr); }
  .ibx-rail-title, .ibx-fold-label { display: none; }
  .ibx-rail-head { justify-content: center; padding: 12px 4px 8px; }
  .ibx-fold { justify-content: center; padding: 9px 4px; position: relative; }
  .ibx-fold-n { position: absolute; top: 2px; right: 4px; min-width: 0; padding: 0 4px; font-size: 9.5px; }
  .ibx-fold-head { margin-top: 8px; } }
.inbox-list { display: flex; flex-direction: column; gap: 2px; max-width: none; flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 8px; }
.inbox-row { display: flex; align-items: flex-start; gap: 10px; width: 100%; text-align: left; background: none; border: none; border-left: 3px solid transparent; border-radius: 10px; padding: 10px 12px; cursor: pointer; color: var(--text); }
.inbox-row:hover { background: var(--bg-hover); }
.inbox-row.active { background: var(--accent-soft); border-left-color: var(--accent); }
.inbox-row.read { opacity: .68; }
/* Unread shouts a little; opened stops shouting but stays full strength, because it
   still needs deciding. Only a HANDLED row dims (.read above). */
.inbox-row:not(.seen) .inbox-row-title { font-weight: 700; }
.inbox-row.seen .inbox-row-title { font-weight: 500; }
/* Multi-select: a tick box per row, and a bar that appears only once something is
   ticked. The box is a span inside the row button (a real <input> inside a <button> is
   invalid), so it carries role="checkbox" and is intercepted before the row's own
   open-this-item handler. */
.inbox-pick {
  width: 15px; height: 15px; border-radius: 4px; flex-shrink: 0; margin-top: 2px;
  border: 1.5px solid var(--border-strong, var(--border)); background: var(--bg);
  display: flex; align-items: center; justify-content: center;
  font-size: 10px; line-height: 1; color: var(--on-accent, #fff);
}
.inbox-row:hover .inbox-pick { border-color: var(--accent); }
.inbox-pick.on { background: var(--accent); border-color: var(--accent); }
.inbox-row.picked { background: var(--accent-soft); }
/* Sticky so the verbs stay reachable while you scroll a long list ticking things. */
.inbox-selbar {
  position: sticky; top: 0; z-index: 3; display: flex; align-items: center;
  gap: 8px; flex-wrap: wrap; margin-bottom: 8px; padding: 8px 10px;
  border: 1px solid var(--accent); border-radius: 10px; background: var(--bg-2);
  box-shadow: var(--shadow-1);
}
.isel-count { font-size: 12.5px; font-weight: 600; color: var(--accent-2); margin-right: 2px; }
.isel-btn { display: inline-flex; align-items: center; gap: 6px; }
.isel-btn:disabled { opacity: .45; cursor: default; }
.isel-n {
  font-size: 11px; font-weight: 700; padding: 0 5px; border-radius: 6px;
  background: rgba(127, 127, 127, .22);
}
.isel-clear { margin-left: auto; }
/* A row's icon says which folder it is, so it carries the folder's colour rather than
   an emoji's. Muted until the row matters — a pending decision earns the accent. */
.inbox-row-ico { flex-shrink: 0; margin-top: 2px; display: flex; color: var(--text-faint); }
.inbox-row-ico .ibx-ico { width: 16px; height: 16px; }
.inbox-row:not(.read) .inbox-row-ico.ico-approval { color: var(--ok, #4caf50); }
.inbox-row:not(.read) .inbox-row-ico.ico-question { color: #e0a640; }
.inbox-row:not(.read) .inbox-row-ico.ico-escalation { color: var(--danger); }
.inbox-row:not(.read) .inbox-row-ico.ico-alert { color: var(--warn, #e0a800); }
.inbox-row:not(.read) .inbox-row-ico.ico-report { color: var(--text-dim); }
.inbox-kind .ibx-ico { width: 14px; height: 14px; }
.inbox-kind { display: inline-flex; align-items: center; gap: 6px; }
.inbox-kind.ico-approval { color: var(--ok, #4caf50); }
.inbox-kind.ico-question { color: #e0a640; }
.inbox-kind.ico-escalation { color: var(--danger); }
.inbox-kind.ico-alert { color: var(--warn, #e0a800); }
.inbox-row-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.inbox-row-top { display: flex; align-items: baseline; gap: 8px; }
.inbox-row-title { font-weight: 600; font-size: 13.5px; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.inbox-row-when { font-size: 11px; color: var(--text-faint); flex-shrink: 0; }
.inbox-row-sub { font-size: 12px; color: var(--text-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.inbox-row-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--accent); flex-shrink: 0; margin-top: 5px; }
.inbox-reading-empty { color: var(--text-faint); font-size: 14px; text-align: center; padding: 70px 20px; }
.idet-totask { margin-left: auto; white-space: nowrap; }
/* The orders a card names, SHOWN and linked. Sits under the source line, because an
   order number IS where the card came from. Empty until the lookup answers, so nothing
   is drawn for a reference that resolved to no record. */
.ibx-refs { display: flex; flex-direction: column; gap: 8px; margin: -2px 0 12px; }
.ibx-ord { border: 1px solid var(--border); border-radius: 11px; background: var(--bg-2);
  padding: 10px 12px; }
.ibx-ord-h { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ibx-ord-kind { font-size: 10.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .06em; color: var(--text-faint); }
.ibx-ord-ref { font-weight: 650; font-size: 13.5px; font-variant-numeric: tabular-nums; }
.ibx-ord-state { font-size: 11px; color: var(--text-dim); border: 1px solid var(--border);
  border-radius: 999px; padding: 1px 8px; }
.ibx-ord-h .ibx-ref { margin-left: auto; }
/* Two columns, label then value: a five-line order reads down the page rather than
   wrapping into a paragraph you have to parse. */
.ibx-ord-grid { display: grid; grid-template-columns: max-content minmax(0, 1fr);
  gap: 3px 14px; margin-top: 8px; font-size: 12.5px; }
.ibx-ord-k { color: var(--text-faint); font-size: 11.5px; white-space: nowrap; }
.ibx-ord-v { color: var(--text); overflow-wrap: anywhere; }
.ibx-ord-linked { display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  margin-top: 9px; padding-top: 8px; border-top: 1px solid var(--border); }
.ibx-ord-chip { display: inline-flex; align-items: center; gap: 6px; text-decoration: none;
  font-size: 11.5px; color: var(--text-dim); border: 1px solid var(--border);
  border-radius: 999px; padding: 2px 9px; font-variant-numeric: tabular-nums; }
.ibx-ord-chip:hover { border-color: var(--accent); color: var(--text); }
.ibx-ord-chip-s { color: var(--text-faint); font-size: 10.5px; }
.ibx-refs:empty { display: none; }
.ibx-ref { display: inline-flex; align-items: center; gap: 6px; text-decoration: none;
  white-space: nowrap; font-variant-numeric: tabular-nums; }
.ibx-ref:hover { border-color: var(--accent); color: var(--text); }
.ibx-ref-ico { width: 14px; height: 14px; color: var(--text-faint); }
.ibx-ref:hover .ibx-ref-ico { color: var(--accent); }
.ibx-ref-n { max-width: 240px; overflow: hidden; text-overflow: ellipsis; }
/* Housekeeping on the card: open the task, close it, get rid of the card. Quiet, because
   they are always there and none of them is the decision you came to make. */
.ibx-tools { margin-left: auto; display: flex; gap: 6px; flex-wrap: wrap; }
.ibx-tool { white-space: nowrap; text-decoration: none; }
.ibx-tool-quiet { opacity: .7; }
.ibx-tool-quiet:hover { opacity: 1; }
/* A message the AI wrote because nothing captured one — flagged as such, because a
   drafted message and a captured one are not the same promise. */
.ibx-draft { font-size: 13.5px; color: var(--text); line-height: 1.6; padding: 10px 13px;
  border-left: 3px solid var(--accent); border-radius: 0 10px 10px 0;
  background: var(--bg); margin-top: 8px; overflow-wrap: anywhere; }
.ibx-draft p { margin: 0 0 7px; } .ibx-draft p:last-child { margin-bottom: 0; }
.ibx-draft-note { font-size: 11px; color: var(--text-faint); margin-top: 7px; }

/* Memory review, one question at a time. The design job here is to stop 167 decisions
   looking like a job: answered rows collapse to a single line, so the list visibly
   shrinks as you work down it, and the two answers are the only things you can click. */
.brv { display: flex; flex-direction: column; gap: 10px; }
.brv-head { display: flex; align-items: center; gap: 10px; }
.brv-prog { font-size: 12.5px; font-weight: 600; color: var(--text-dim); white-space: nowrap; }
.brv-bar { flex: 1; height: 4px; border-radius: 999px; background: var(--bg-3); overflow: hidden; }
.brv-bar-fill { display: block; height: 100%; background: var(--accent); transition: width .25s ease; }
.brv-done { display: flex; flex-direction: column; gap: 2px; }
.brv-donerow {
  display: flex; align-items: center; gap: 8px; padding: 5px 9px; border-radius: 8px;
  background: var(--bg-2); font-size: 12px; color: var(--text-faint);
}
.brv-done-ico { flex-shrink: 0; font-weight: 700; }
.brv-donerow.yes .brv-done-ico { color: var(--ok, #4caf50); }
.brv-done-tx { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.brv-done-note { flex-shrink: 0; font-size: 11px; }
.brv-undo {
  flex-shrink: 0; border: none; background: none; font: inherit; font-size: 11.5px;
  color: var(--accent-2); cursor: pointer; text-decoration: underline; padding: 0;
}
.brv-rows { display: flex; flex-direction: column; gap: 10px; }
/* The whole row is the target — it is a <label>, so the sentence you are reading is
   what you click, not a 15px box at the end of it. */
.brv-row {
  border: 1px solid var(--border); border-radius: 12px; background: var(--bg-2);
  padding: 13px 15px; display: flex; align-items: flex-start; gap: 14px; cursor: pointer;
}
.brv-row:hover { border-color: var(--border-strong, var(--text-faint)); }
.brv-row.on { border-color: var(--accent); background: var(--accent-soft); }
.brv-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.brv-pick { flex: 0 0 auto; display: flex; align-items: center; padding-top: 1px; }
.brv-pick input { width: 17px; height: 17px; accent-color: var(--accent); cursor: pointer; }
.brv-row.danger { border-color: color-mix(in srgb, var(--danger) 45%, var(--border)); }
.brv-row.danger.on { background: color-mix(in srgb, var(--danger) 12%, transparent); }
.brv-row.working { opacity: .5; pointer-events: none; }
/* The two verbs, once, under the rows — sticky so they stay reachable while you work
   down a long batch instead of living at the bottom of a scroll. */
.brv-bar {
  position: sticky; bottom: 0; z-index: 2; display: flex; align-items: center; gap: 10px;
  flex-wrap: wrap; margin-top: 4px; padding: 10px 13px;
  border: 1px solid var(--border); border-radius: 12px; background: var(--bg-2);
  box-shadow: var(--shadow-1);
}
.brv-all { display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px;
  color: var(--text-dim); cursor: pointer; user-select: none; }
.brv-all input { width: 15px; height: 15px; accent-color: var(--accent); cursor: pointer; }
.brv-bar-n { font-size: 12px; color: var(--text-faint); margin-left: auto; }
.brv-bar .brv-yes, .brv-bar .brv-no { padding: 7px 16px; }
.brv-bar button:disabled { opacity: .45; cursor: default; }
.brv-q { font-size: 14px; font-weight: 600; color: var(--text); line-height: 1.45; }
.brv-texts { display: flex; flex-direction: column; gap: 5px; }
.brv-side { display: flex; align-items: baseline; gap: 8px; }
.brv-tag {
  flex-shrink: 0; font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .07em; color: var(--text-faint); background: var(--bg-3);
  border-radius: 5px; padding: 1px 6px;
}
.brv-tag.new { color: var(--accent-2); background: var(--accent-soft); }
.brv-tx { font-size: 13px; color: var(--text-dim); line-height: 1.5; overflow-wrap: anywhere; }
/* On a one-question card the two answers sit side by side, the same size: neither is
   the "safe" one to click through, because both directions are a real choice. */
.brv-acts { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 2px; }
.brv-yes, .brv-no {
  font: inherit; font-size: 13px; font-weight: 600; padding: 7px 15px; border-radius: 9px;
  cursor: pointer; border: 1px solid transparent;
}
.brv-yes { background: var(--accent); color: var(--on-accent, #fff); }
.brv-yes:hover { filter: brightness(1.08); }
.brv-yes.danger { background: var(--danger); }
.brv-no { background: var(--bg); border-color: var(--border); color: var(--text-dim); }
.brv-no:hover { border-color: var(--text-dim); color: var(--text); }
.brv-hint { font-size: 11.5px; color: var(--text-faint); }
.brv-hint.yes { color: var(--accent-2); }
.brv-foot { flex-direction: column; align-items: flex-start; gap: 6px; }
.brv-foot-hint, .brv-allrone { font-size: 11.5px; color: var(--text-faint); }
/* One question, not a review: no progress bar, no done-list, no footer. The thing
   itself is the biggest text on the card and the two answers sit right under it. */
.brv-one { gap: 12px; }
.brv-one-q { font-size: 15px; font-weight: 600; color: var(--text); }
.brv-one-thing {
  font-size: 15px; line-height: 1.55; color: var(--text); padding: 12px 15px;
  border-left: 3px solid var(--accent); border-radius: 0 10px 10px 0;
  background: var(--accent-soft); overflow-wrap: anywhere;
}
.brv-why { font-size: 12.5px; color: var(--text-faint); }
.brv-why > summary { cursor: pointer; padding: 4px 0; list-style: none; }
.brv-why > summary::-webkit-details-marker { display: none; }
.brv-why > summary::before { content: "▸ "; display: inline-block; transition: transform .15s; }
.brv-why[open] > summary::before { content: "▾ "; }
.brv-why > summary:hover { color: var(--text-dim); }
.brv-why .inbox-body { margin-top: 6px; }

/* The conversation a card came from, drawn AS a conversation. You are judging whether
   a drafted reply still makes sense, and who said what last is most of that judgement —
   so it gets avatars, bubbles and reading order rather than a stack of indented quotes. */
.ibx-thread { margin-top: 2px; }
.thr-loading, .thr-err { font-size: 12px; color: var(--text-faint); padding: 6px 0; }
.thr { border: 1px solid var(--border); border-radius: 12px; background: var(--bg-2); overflow: hidden; }
.thr-head {
  padding: 9px 14px; font-size: 12px; font-weight: 600; color: var(--text-dim);
  display: flex; align-items: center; gap: 8px; border-bottom: 1px solid var(--border);
  background: var(--bg-3);
}
.thr-head-main { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.thr-n { font-size: 11px; font-weight: 500; color: var(--text-faint); white-space: nowrap; }
/* The opening message is a POST: full width, no bubble, room to breathe, and its
   pictures at a size you can actually look at. What follows is chat. Treating both the
   same made "next Monday cannot" as prominent as the request itself. */
.thr-post { padding: 14px 16px 16px; }
.thr-post-head { display: flex; align-items: center; gap: 11px; margin-bottom: 10px; }
.thr-post-who { flex: 1; min-width: 0; }
.thr-post-name { font-size: 14.5px; font-weight: 700; color: var(--text); }
.thr-post-when { font-size: 11.5px; color: var(--text-faint); margin-top: 1px; }
.thr-post-tx { font-size: 14px; color: var(--text); line-height: 1.65; overflow-wrap: anywhere; }
.thr-post-tx p { margin: 0 0 9px; } .thr-post-tx p:last-child { margin-bottom: 0; }
.thr-post-tx ul, .thr-post-tx ol { margin: 6px 0 9px; padding-left: 20px; }
.thr-post-tx a { color: var(--accent-2); }
.thr-post-tx table { font-size: 12.5px; display: block; overflow-x: auto; max-width: 100%; }
.thr-replies { border-top: 1px solid var(--border); background: var(--bg); padding: 10px 14px 14px; }
.thr-replies-h { font-size: 10.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .08em; color: var(--text-faint); margin-bottom: 9px; }
.thr-msgs { padding: 12px 14px; display: flex; flex-direction: column; gap: 12px; }
.thr-msg { display: flex; gap: 10px; align-items: flex-start; margin-bottom: 9px; }
.thr-msg:last-child { margin-bottom: 0; }
.thr-ava {
  flex: 0 0 auto; width: 28px; height: 28px; border-radius: 50%; color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: 10.5px; font-weight: 700; letter-spacing: .02em; margin-top: 2px;
}
.thr-ava.lg { width: 40px; height: 40px; font-size: 14px; margin-top: 0; }
.thr-bubble {
  flex: 1; min-width: 0; background: var(--bg); border: 1px solid var(--border);
  border-radius: 4px 12px 12px 12px; padding: 9px 13px;
}
.thr-who { font-size: 12.5px; font-weight: 600; color: var(--text); display: flex;
  align-items: baseline; flex-wrap: wrap; gap: 6px; }
.thr-when { font-weight: 400; color: var(--text-faint); font-size: 11px; }
.thr-badge { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
  color: var(--accent-2); background: var(--accent-soft); border-radius: 5px; padding: 1px 6px; }
.thr-tx { font-size: 13.5px; color: var(--text); line-height: 1.6; margin-top: 4px; overflow-wrap: anywhere; }
.thr-tx p { margin: 0 0 7px; } .thr-tx p:last-child { margin-bottom: 0; }
.thr-tx ul, .thr-tx ol { margin: 4px 0 7px; padding-left: 20px; }
.thr-tx a { color: var(--accent-2); }
.thr-tx table { font-size: 12px; display: block; overflow-x: auto; max-width: 100%; }
/* Pictures, actually shown. Capped so a screenshot of a spreadsheet doesn't take over
   the pane; click opens it full size. */
.thr-imgs { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.thr-img { display: block; line-height: 0; border-radius: 8px; overflow: hidden;
  border: 1px solid var(--border); max-width: 100%; }
.thr-img img { display: block; max-width: 200px; max-height: 170px; width: auto; height: auto;
  object-fit: cover; background: var(--bg-3); }
/* On a post the pictures are usually the point — a photo of the parts, a screenshot of
   the order — so they get roughly twice the area they do on a reply. */
.thr-imgs.big { margin-top: 12px; gap: 10px; }
.thr-imgs.big img { max-width: 300px; max-height: 260px; }
.thr-img:hover { border-color: var(--accent); }
.thr-files { margin-top: 6px; display: flex; flex-wrap: wrap; gap: 8px; }
.thr-file { font-size: 11.5px; color: var(--accent-2); text-decoration: none; }
.thr-file:hover { text-decoration: underline; }
.thr-edited { font-size: 10.5px; color: var(--text-faint); font-weight: 400; margin-left: 6px; }
.thr-open { font-size: 11px; color: var(--accent-2); text-decoration: none; margin-left: 8px; font-weight: 400; }
.thr-open:hover { text-decoration: underline; }
.thr-clip, .thr-more { font-size: 11.5px; color: var(--warn, #e0a800); margin-top: 4px; }
.thr-retry { margin-left: 8px; font: inherit; font-size: 11.5px; border: none; background: none;
  color: var(--accent-2); text-decoration: underline; cursor: pointer; padding: 0; }
.thr-more { padding: 0 12px 10px; }
/* A long thread scrolls inside its own panel rather than pushing everything below it
   out of reach. It now sits BELOW the draft, so the decision buttons are above it and
   stay reachable either way. */
.thr-msgs { max-height: 52vh; overflow-y: auto; }
/* Two explicit columns rather than auto-fit: the work card carries most of the
   content and the ambient one should sit BESIDE it, not wrap under it leaving a
   third of the page blank. Collapses to one column below 900px (rule further down). */
/* One column. The 2fr/1fr split is what left Home ragged: it decided a card's WIDTH
   by the order it happened to load in, so Daily News rendered at 2fr and Weekly Sales
   at 1fr — the same kind of card, two different widths, with a hole beside each.
   Sections stack full-width; the digest cards get their own equal-width row below. */
.home-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; }
/* Peers of each other, so they share one row and stretch to a common height —
   `align-items: start` on the parent is what let their bottoms disagree. */
.home-skillrow {
  display: grid; gap: 16px; align-items: stretch;
  /* auto-FIT, not auto-fill: with a single digest card, auto-fill keeps the empty
     track and leaves a hole beside it — the exact ragged look this row was added to
     remove. auto-fit collapses the empties so one card fills the row. */
  grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
}
.home-card {
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 14px;
  padding: 16px 16px 12px; display: flex; flex-direction: column; gap: 10px;
  box-shadow: var(--shadow-1); min-height: 180px;
}
.home-card-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
/* A card heading was 13px dim uppercase while its own content was 14px near-white —
   the label was quieter than the thing it labelled, so the eye had no anchor. Real
   size, real weight, real colour; the row beneath can now be the quiet one. */
.home-card-head h2 { margin: 0; font-size: 16px; font-weight: 650; letter-spacing: -.01em; color: var(--text);
  display: inline-flex; align-items: center; gap: 9px; min-width: 0; }
/* A skill card's tile. Its header row centres rather than sitting on the baseline
   .home-fold uses everywhere else — a 26px tile on a baseline sits a third of its
   height too low. Scoped to these cards, so no other fold header shifts. */
.home-card-ico { --ico-sz: 26px; }
.home-card-skill .home-fold, .home-card-skill .home-card-head { align-items: center; }
.home-card-tools { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.home-card-link { background: none; border: none; color: var(--accent-2); font-size: 12.5px; font-weight: 600; padding: 2px 4px; border-radius: 6px; }
.home-card-link:hover { background: var(--accent-soft); }
.home-card-body { display: flex; flex-direction: column; gap: 6px; }

/* ===== Folding =============================================================
   Every card collapses to ONE line carrying its count and a one-line summary, so a
   folded Home still answers "is there anything for me?" in a single screen. Folded is
   the default: the list is what makes the page long, and it is one click away. */
.home-fold { display: flex; align-items: baseline; gap: 8px; min-width: 0; flex: 1;
  background: none; border: none; padding: 0; cursor: pointer; text-align: left; color: inherit; }
.home-fold-caret { flex-shrink: 0; width: 10px; font-size: 12px; line-height: 1; color: var(--text-faint);
  transition: transform .15s ease; }
.home-fold:hover .home-fold-caret, .home-act-lede:hover .home-fold-caret { color: var(--accent-2); }
/* Rotated when OPEN — i.e. when the card is NOT folded. */
.home-card:not(.folded) .home-fold-caret,
.home-ambient:not(.folded) .home-fold-caret,
.home-act:not(.folded) .home-fold-caret { transform: rotate(90deg); }
.home-fold .home-card-count { flex-shrink: 0; }
.home-fold h2 { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.home-card-sum { font-size: 12.5px; color: var(--text-faint); font-weight: 500; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
/* The fold itself. min-height goes too, so a folded card is exactly its header — that
   is what makes the collapsed stack read as an even, tidy list. */
.home-card.folded > .home-card-body,
.home-card.folded > .home-cardlist,
.home-card.folded > .home-also,
.home-ambient.folded > .home-ambient-body,
.home-act.folded > .home-act-body { display: none; }
.home-card.folded { min-height: 0; gap: 0; padding-bottom: 14px; }
.home-act.folded { padding-bottom: 16px; }
.home-act.folded .home-act-n { font-size: 30px; }

/* ===== TIER 1 · act now ====================================================
   Raised, accent-edged, and the only surface with buttons that act in place. */
.home-act {
  background: var(--bg-2); border: 1px solid var(--border); border-left: 3px solid var(--accent);
  border-radius: 14px; padding: 16px 18px 12px; margin-bottom: 16px;
  box-shadow: var(--shadow-2); display: flex; flex-direction: column; gap: 10px;
}
.home-act.clear { border-left-color: var(--ok, #1f9d55); box-shadow: var(--shadow-1); }
/* Reports sit OUTSIDE the count, so they must not look like part of the breakdown. */
.home-act-fyi { margin: 0; font-size: 12.5px; color: var(--text-faint); padding-left: 2px; }
.home-act-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.home-act-lede { display: flex; align-items: center; gap: 12px; min-width: 0; flex: 1;
  background: none; border: none; padding: 0; cursor: pointer; text-align: left; color: inherit; }
.home-act-n { font-size: 40px; font-weight: 700; line-height: 1; color: var(--accent);
  font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
.home-act.clear .home-act-n { color: var(--ok, #1f9d55); }
.home-act-what { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.home-act-title { font-size: 17px; font-weight: 650; letter-spacing: -.01em; }
.home-act-sub { font-size: 13px; color: var(--text-dim); }
.home-act-body { display: flex; flex-direction: column; gap: 4px; }
/* Two lines, no ellipsis: the end of "Approve 7/11 — sale.order #10859: Deliver 8…"
   is the part that tells you which one it is. */
.home-arow { display: flex; align-items: center; gap: 8px; border-radius: 10px; }
.home-arow:hover { background: var(--bg-hover); }
.home-arow-open { flex: 1; min-width: 0; display: flex; align-items: flex-start; gap: 10px;
  background: none; border: none; text-align: left; color: var(--text); padding: 9px 10px; cursor: pointer; }
.home-arow .home-row-title { white-space: normal; overflow: visible;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.home-arow.stale .home-row-sub { color: var(--warn, #e0a800); font-weight: 600; }
.home-act-btn { flex-shrink: 0; margin-right: 8px; background: var(--accent); color: var(--on-accent);
  border: none; border-radius: 9px; padding: 7px 13px; font-size: 12.5px; font-weight: 600; cursor: pointer; }
.home-act-btn:hover { filter: brightness(1.08); }

/* Header chips replace the old tile row: a "0" tile took a fifth of the width to say
   nothing, so a count of zero now simply isn't drawn. */
.home-chips { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-right: 6px; }
.home-chip { background: var(--bg-2); border: 1px solid var(--border); border-radius: 999px;
  padding: 5px 11px; font-size: 12.5px; color: var(--text-dim); cursor: pointer; }
.home-chip:hover { border-color: var(--accent); color: var(--text); }
.home-chip-n { color: var(--text); font-weight: 700; font-variant-numeric: tabular-nums; }
.home-chip-n.ready { color: var(--accent-2); }
.home-chip-n.blocked { color: var(--warn, #e0a800); }

/* "Also open" — what the plan did NOT already name. */
.home-also { margin-top: 2px; padding-top: 10px; border-top: 1px solid var(--border); }
.home-also-head { font-size: 12px; font-weight: 600; color: var(--text-faint);
  text-transform: uppercase; letter-spacing: .05em; padding: 0 2px 4px; }
.home-also-n { background: var(--bg-3); border-radius: 999px; padding: 1px 7px; margin-left: 4px; }

/* ===== TIER 3 · ambient ====================================================
   No border, no shadow, quieter type: the floor of the page. */
.home-ambient { margin-top: 16px; padding: 4px 2px 0; }
.home-ambient-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 4px; }
.home-ambient-head h2 { margin: 0; font-size: 13px; font-weight: 600; color: var(--text-faint);
  text-transform: uppercase; letter-spacing: .05em; }
.home-ambient-body { display: flex; flex-wrap: wrap; gap: 6px; }
.home-ambient-body .home-row { width: auto; flex: 1 1 300px; padding: 7px 10px; }
.home-ambient-body .home-row-title { font-weight: 500; color: var(--text-dim); }

.home-changed-row { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  background: none; border: none; border-radius: 9px; padding: 8px 10px; cursor: pointer;
  color: var(--text); font-size: 13.5px; }
.home-changed-row:hover { background: var(--bg-hover); }
.home-row {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  background: none; border: none; border-radius: 9px; padding: 8px 10px; cursor: pointer; color: var(--text);
}
.home-row:hover { background: var(--bg-hover); }
.home-row-ico { display: inline-flex; align-items: center; justify-content: center;
  font-size: 16px; width: 24px; text-align: center; flex-shrink: 0; }
.home-row-ico .ico { width: 16px; height: 16px; color: var(--ic, var(--text-faint)); }
.home-row-dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; margin: 0 8px 0 7px; }
.home-row-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; line-height: 1.45; }
/* Two lines before truncating. At one line these clipped mid-identifier — "…sale.order
   #108" — which is precisely the part that says which row this is. */
.home-row-title { font-size: 13.5px; font-weight: 600; display: -webkit-box; -webkit-line-clamp: 2;
  -webkit-box-orient: vertical; overflow: hidden; }
.home-row-sub { font-size: 12px; color: var(--text-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.home-row-go { color: var(--text-faint); font-size: 13px; }
.home-row:hover .home-row-go { color: var(--accent-2); }
.home-empty, .home-loading, .home-more { color: var(--text-faint); font-size: 13px; padding: 10px 6px; line-height: 1.5; }
/* .home-more became a <button> so it can open the Inbox — without this it inherits the
   default button chrome and renders as a grey slab across the card. */
button.home-more { background: none; border: none; width: 100%; text-align: left;
  cursor: pointer; border-radius: 9px; font-weight: 600; }
button.home-more:hover { background: var(--bg-hover); color: var(--accent-2); }
.home-task-stats { display: flex; flex-wrap: wrap; gap: 6px 14px; padding: 0 4px; }
.home-stat { font-size: 12.5px; color: var(--text-dim); }
.home-stat b { font-size: 15px; margin-right: 3px; }
.home-unread {
  background: var(--accent); color: var(--on-accent); border-radius: 999px;
  font-size: 10.5px; font-weight: 700; padding: 1px 7px; margin-left: 6px; vertical-align: 1px;
}
/* Home dashboard card for a skill that declares home_card — previews its latest run. */
.home-skillcard {
  text-align: left; background: none; border: 0; cursor: pointer; color: inherit;
  padding: 4px 2px; width: 100%;
}
.home-skillcard:hover { color: var(--accent); }
.home-skillcard-preview {
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
  color: var(--text-dim); font-size: 13px; line-height: 1.5;
}
.home-skillcard .home-row-sub { display: block; margin-top: 4px; }

/* ---- light-theme fixes for colours tuned for dark backgrounds ---- */
:root[data-theme="light"] .cap-test.ok { color: #116e43; background: var(--ok-soft); border-color: rgba(23,145,91,.35); }
:root[data-theme="light"] .cap-test.err,
:root[data-theme="light"] .auth-error,
:root[data-theme="light"] .msg-error { color: #b42318; }
:root[data-theme="light"] #toast.err { color: #b42318; }
:root[data-theme="light"] .cap-oauth-status.ok { color: #116e43; }
:root[data-theme="light"] .run-error-title, :root[data-theme="light"] .cap-help.warn { color: #b45309; }
:root[data-theme="light"] .req-chip.req-ok, :root[data-theme="light"] .req-chip.req-ok b { color: #116e43; }
:root[data-theme="light"] .req-chip.req-missing, :root[data-theme="light"] .req-chip.req-missing b { color: #b45309; }
:root[data-theme="light"] .ext-price.free { color: #116e43; }
:root[data-theme="light"] .st-ready { color: #2563eb; }
:root[data-theme="light"] .st-blocked { color: #b45309; }
:root[data-theme="light"] .task-meta .tm-due { color: #b45309; }
:root[data-theme="light"] .reach-switch.on .sw-label { color: #15803d; }
:root[data-theme="light"] .st-done { color: #116e43; }
:root[data-theme="light"] .st-in_progress { color: var(--accent-2); }

/* ---- responsive: off-canvas sidebar under 920px ---- */
/* In the bar now, not floating over the page — so it stops overlapping whatever the
   view happens to put in its top-left corner, and the padding hacks that used to make
   room for it can go. */
.sidebar-toggle {
  display: none; background: none; border: 1px solid var(--border); color: var(--text);
  border-radius: 9px; padding: 5px 10px; font-size: 15px; flex-shrink: 0;
}
.sidebar-toggle:hover { background: var(--bg-hover); }
#sidebar-backdrop { display: none; }
@media (max-width: 920px) {
  .sidebar-toggle { display: block; }
  #sidebar {
    position: fixed; inset: var(--topbar-h) auto 0 0; z-index: 70; transform: translateX(-102%);
    transition: transform .2s ease; box-shadow: var(--shadow-2); width: 280px;
  }
  body.sidebar-open #sidebar { transform: translateX(0); }
  body.sidebar-open #sidebar-backdrop {
    display: block; position: fixed; inset: var(--topbar-h) 0 0 0; z-index: 65; background: rgba(0,0,0,.45);
  }
  .home-grid { grid-template-columns: 1fr; }
}
/* The wordmark is the first thing to go on a phone; the mark alone still says whose
   app this is, and the switch keeps its label because "Online mode" IS the information. */
@media (max-width: 560px) {
  #topbar { padding: 0 10px; gap: 8px; }
  #topbar .brand-text { display: none; }
}

/* ---- task priority badges ---- */
.tm.pr-high { color: var(--danger); font-weight: 700; }
.tm.pr-medium { color: var(--warn); font-weight: 600; }
.tm.pr-low { color: var(--text-faint); }
table.tasks-table .tm.pr-high, table.tasks-table .tm.pr-medium, table.tasks-table .tm.pr-low {
  text-transform: capitalize;
}

/* ---- Home: Today's plan card ---- */
/* No longer spans the row — it is the wide COLUMN of the two now, so a full-width
   span would push everything else below it again. */
/* The name is the contract: a wide card spans BOTH columns. It only ever set
   min-height, so "Router output sits full-width right below Today's plan" was never
   true — the plan and all five router cards flowed into the 2fr/1fr columns like
   anything else, which is what left one column short and a hole beside it. */
.home-card-wide { min-height: 0; grid-column: 1 / -1; }
/* Type tabs on the router card: one bar with five counts, rather than five bars. */
/* row, explicitly: the card itself is a column flex, so an unqualified
   `display:flex` here inherited column and stretched every pill full-width. */
.home-tabs { display: flex; flex-direction: row; align-items: center;
  gap: 6px; flex-wrap: wrap; padding: 2px 0 6px; }
.home-tab { flex: 0 0 auto; }
.home-tab {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  font: inherit; font-size: 12.5px; padding: 4px 10px; border-radius: 999px;
  border: 1px solid var(--border); background: transparent; color: var(--text-dim);
}
.home-tab:hover { color: var(--text); border-color: var(--text-faint); }
.home-tab.on { background: var(--bg-3); color: var(--text); border-color: var(--accent); font-weight: 600; }
/* The kind's glyph, coloured by kind (ic-* sets --ic) — the tab row is the one place on
   Home where seven things have to be told apart at a glance. */
.home-tab .ico { width: 14px; height: 14px; flex-shrink: 0; color: var(--ic, var(--text-faint)); }
.home-tab-n { font-size: 11px; color: var(--text-faint); }
.home-tab.on .home-tab-n { color: var(--text-dim); }
/* A kind with something unread earns the accent — that is the only reason to look. */
.home-tab-n.unread { color: var(--accent); font-weight: 700; }
.home-card.folded > .home-tabs { display: none; }
.home-plan { font-size: 13.5px; line-height: 1.65; color: var(--text); padding: 2px 6px; }
.home-plan ul, .home-plan ol { margin: 4px 0; padding-left: 20px; }
.home-plan li { margin: 5px 0; }
.home-plan li::marker { color: var(--accent); }
.home-plan strong { color: var(--text); }

/* Each step is a target, not a sentence: the row opens the task/inbox item it names.
   ONE row shape for every step — a numbered gutter, the sentence, one count pill and
   one affordance on a shared right edge — so the list scans as a column instead of a
   ragged right-hand cloud of chips at eight different widths. */
.home-plan-steps { display: flex; flex-direction: column; }
.plan-step { border-radius: 10px; border: 1px solid transparent; }
.plan-step + .plan-step { margin-top: 1px; }
/* An opened step is a hairline box, not a fill — the chips inside it are the filled
   things, and filling their container too would flatten them into it. */
.plan-step.open { border-color: var(--border); }
.plan-step-head {
  display: flex; align-items: flex-start; gap: 10px; width: 100%; text-align: left;
  padding: 9px 10px; border-radius: 10px; color: var(--text);
}
.plan-step-head.clickable { cursor: pointer; }
.plan-step-head.clickable:hover { background: var(--bg-hover); }
/* The step's rank, in a fixed gutter — so every sentence starts on the same column
   and a wrapped second line lines up with the first. */
.plan-step-n {
  flex: 0 0 20px; width: 20px; height: 20px; line-height: 20px; text-align: center;
  font-size: 11px; font-weight: 700; border-radius: 6px;
  color: var(--accent); background: var(--accent-soft); margin-top: 1px;
}
.plan-step-main { flex: 1; min-width: 0; }
.plan-step-text { font-size: 13.5px; line-height: 1.5; }
.plan-step-sub {
  font-size: 11.5px; color: var(--text-faint); margin-top: 3px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.plan-step-head:hover .plan-step-sub { color: var(--text-dim); }
/* Says "8 items" once, instead of the row saying it above eight chips. */
.plan-step-count {
  flex: 0 0 auto; margin-top: 1px; font-size: 11px; font-weight: 600;
  color: var(--text-dim); background: var(--bg-3); border: 1px solid var(--border);
  border-radius: 999px; padding: 2px 8px; white-space: nowrap;
}
.plan-step-head:hover .plan-step-count { color: var(--text); border-color: var(--text-faint); }
.plan-step-go { flex: 0 0 12px; text-align: right; color: var(--text-faint); font-size: 12px; padding-top: 3px; }
.plan-step-head:hover .plan-step-go { color: var(--accent-2); }
/* Only when a step covers SEVERAL items — folded until asked for, then a left-aligned
   wrap under the sentence, indented to the same gutter (10 + 20 + 10). */
.plan-step-refs { display: none; flex-wrap: wrap; gap: 6px; padding: 0 10px 10px 40px; }
.plan-step.open > .plan-step-refs { display: flex; }
.plan-chip {
  display: inline-flex; align-items: center; gap: 6px; max-width: 100%;
  background: var(--bg-3); border: 1px solid var(--border); color: var(--text-dim);
  font-size: 11.5px; font-weight: 600; padding: 4px 10px; border-radius: 999px; cursor: pointer;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.plan-chip-ico { flex: 0 0 auto; }
.plan-chip:hover { border-color: var(--accent); color: var(--text); background: var(--accent-soft); }

/* ---- What you finished today stays on the plan, struck through ---- */
/* A done item used to vanish from its step, so the card could never show progress and
   a fully-cleared step read like one nobody had started. It is still clickable — you
   can look at what you did — it just stops asking for attention. */
.plan-step.done .plan-step-text { color: var(--text-dim); }
.plan-step.done .plan-step-n { color: var(--ok, #34d399); background: transparent; font-size: 13px; }
.plan-step-sub.done, .plan-chip.done { text-decoration: line-through; opacity: .72; }
.plan-chip.done { background: transparent; }
.plan-chip.done:hover { text-decoration: none; opacity: 1; }
.plan-step-count.done { color: var(--ok, #34d399); border-color: transparent; background: transparent; }
@media (max-width: 760px) {
  .plan-step-refs { padding-left: 10px; }
}

/* ---- Company knowledge card ---- */
.cn-knowledge-text { width: 100%; resize: vertical; font-family: var(--font); line-height: 1.55; }
/* Company knowledge is usually long — give it a tall default (still drag-resizable). */
#cn-knowledge-text { min-height: 420px; }
.cn-knowledge-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 10px; }
.cn-knowledge-row .btn-primary { margin-left: auto; }

/* ---- Reference packs (bundled documents, inside the Knowledge base card) ---- */
.cn-refpack { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border); }
.cn-refpack-h { font-size: 13px; font-weight: 600; margin-bottom: 4px; }
.cn-refpack-row { display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--border); }
.cn-refpack-row:last-child { border-bottom: 0; }
.cn-refpack-row > div { display: flex; flex-direction: column; min-width: 0; }
.cn-refpack-row strong { font-size: 13.5px; font-weight: 600; }
.cn-refpack-row small { color: var(--text-dim); font-size: 11.5px; margin-top: 2px; }

/* ---- Company → Skills: the author's scope recommendation ---- */
.skl-suggest { display: flex; align-items: center; justify-content: space-between;
  gap: 10px; margin: 8px 0 0; padding: 7px 9px; border-radius: 8px;
  background: rgba(99,102,241,.10); border: 1px solid rgba(99,102,241,.28); }
.skl-suggest span { font-size: 11.5px; line-height: 1.4; color: var(--text-dim); }
.skl-suggest strong { color: var(--text); font-weight: 600; }
.skl-suggest .btn-mini { flex: none; }

/* ---- Company → HR: the setup checklist ---- */
.cn-hrsetup-row { display: flex; align-items: flex-start; gap: 10px; padding: 9px 0;
  border-bottom: 1px solid var(--border); }
.cn-hrsetup-row:last-child { border-bottom: 0; }
.cn-hrsetup-row > div { display: flex; flex-direction: column; min-width: 0; }
.cn-hrsetup-row strong { font-size: 13.5px; font-weight: 600; }
.cn-hrsetup-row small { color: var(--text-dim); font-size: 11.5px; margin-top: 2px;
  line-height: 1.45; }
.cn-hrsetup-mark { flex: none; width: 18px; height: 18px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700; margin-top: 1px; }
.cn-hrsetup-row.ok .cn-hrsetup-mark { background: rgba(34,197,94,.16); color: #22c55e; }
.cn-hrsetup-row.todo .cn-hrsetup-mark { background: rgba(245,158,11,.16); color: #f59e0b; }

/* ---- People dates (the HR roster supplement, Company → HR) ---- */
#cn-hrroster-card { margin-top: 18px; }
.cn-hrroster-row { display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--border); }
.cn-hrroster-row:last-child { border-bottom: 0; }
.cn-hrroster-row > div { display: flex; flex-direction: column; min-width: 0; }
.cn-hrroster-row strong { font-size: 13.5px; font-weight: 600; }
.cn-hrroster-row small { color: var(--text-dim); font-size: 11.5px; margin-top: 2px; }
.cn-hrroster-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px;
  margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--border); }
.cn-hrroster-form .cn-input { flex: 1 1 180px; max-width: 260px; }
.cn-hrroster-f { display: flex; flex-direction: column; gap: 3px; font-size: 11.5px;
  color: var(--text-dim); }
.cn-hrroster-f .cn-input { max-width: 165px; }
.cn-hrroster-form .btn-primary { margin-left: auto; }

/* ---- Company knowledge BASE (documents, searched on demand) ----
   Distinct from the knowledge textarea above it: that is one blob carried in every
   prompt, this is a document list. The "Check what your AI would find" block at the
   bottom is deliberately part of the same card — authoring knowledge you can't test
   is how a company ends up with a full knowledge base and an AI that never cites it. */
.cn-kb-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
.cn-kb-actions .cn-input { flex: 1; min-width: 200px; }
.cn-kb-flag { font-size: 12.5px; color: var(--danger, #e03131); }
.cn-kb-editor { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
.cn-kb-scope-row { display: flex; align-items: center; gap: 10px; font-size: 13px; color: var(--text-dim); }
.cn-kb-scope-row .cn-input { flex: 1; }
.cn-kb-badge { display: inline-block; font-size: 11px; padding: 1px 7px; border-radius: 999px;
  border: 1px solid var(--border); color: var(--text-faint); margin-left: 6px; }
.cn-kb-badge.team { border-color: var(--accent); color: var(--accent); }
.cn-kb-list { display: flex; flex-direction: column; gap: 8px; }
.cn-kb-doc { display: flex; align-items: center; gap: 12px; background: var(--bg);
  border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px; }
.cn-kb-doc-main { flex: 1; min-width: 0; }
.cn-kb-doc-title { font-size: 14px; font-weight: 600; }
.cn-kb-doc-meta { font-size: 11.5px; color: var(--text-faint); margin-top: 2px; }
.cn-kb-doc-act { display: flex; gap: 6px; flex-shrink: 0; }
.cn-kb-doc-act button { background: transparent; border: 1px solid var(--border);
  border-radius: 8px; padding: 5px 10px; font-size: 12px; color: var(--text-dim); }
.cn-kb-doc-act button:hover { background: var(--bg-hover); color: var(--text); }
.cn-kb-empty { font-size: 13px; color: var(--text-faint); padding: 14px 2px; }
.cn-kb-try { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--border); }
.cn-kb-hits { display: flex; flex-direction: column; gap: 8px; }
.cn-kb-hit { background: var(--bg); border: 1px solid var(--border);
  border-left: 3px solid var(--accent); border-radius: 8px; padding: 9px 12px; }
.cn-kb-hit-h { font-size: 12.5px; font-weight: 600; display: flex; justify-content: space-between; gap: 10px; }
.cn-kb-hit-h span { color: var(--text-faint); font-weight: 500; }
.cn-kb-hit-t { font-size: 12.5px; color: var(--text-dim); line-height: 1.5; margin-top: 4px; white-space: pre-wrap; }

/* ---- escalation inbox cards (a report's decision relayed to their manager) ---- */
.inbox-card.inbox-escalation { border-left-color: var(--danger); }

/* ---- workspace company-management (admin) ---- */
.cn-policy-row { margin-bottom: 8px; }
.cn-policy-mode { width: auto; min-width: 220px; }
.cn-member-mgr { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-faint); }
.cn-member-mgr select {
  background: var(--bg); border: 1px solid var(--border); color: var(--text);
  border-radius: 7px; padding: 4px 7px; font-size: 12.5px; font-family: inherit; max-width: 170px;
}

/* --- Pin the logo/online (top) + profile (bottom); only the middle scrolls --- */
#sidebar { overflow: hidden; }
.side-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden; display: flex; flex-direction: column; gap: 12px; }
.side-scroll .side-recents { flex: 0 0 auto; }
.side-scroll .side-recents .conversations { flex: none; overflow: visible; max-height: none; }

/* Tasks toolbar: the automation controls moved to Heartbeat, so what remains is one
   board action plus a pointer to where the recurring version is configured. */
.tasks-auto-link {
  color: var(--text-faint); font-size: 12.5px; text-decoration: none;
  padding: 7px 11px; border-radius: 9px; border: 1px solid transparent;
}
.tasks-auto-link:hover { background: var(--bg-2); color: var(--text); border-color: var(--border); }
.tasks-empty .hint { margin: 6px 0; }
.tasks-empty button { margin: 10px 0 4px; }

/* Task picker — same shell as the command palette, with its own heading. */
#taskpick-overlay { align-items: flex-start; }
.taskpick-head {
  padding: 12px 18px 0; font-size: 12px; font-weight: 600;
  color: var(--text-faint); text-transform: uppercase; letter-spacing: .04em;
}
#taskpick-results .dotmark { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.taskpick-new { margin-left: auto; color: var(--accent-2); }

/* New / edit project dialog */
.pf-icon-input { text-align: center; font-size: 16px; }
.pf-colors { display: flex; gap: 8px; flex-wrap: wrap; padding-top: 4px; }
.pf-swatch {
  width: 26px; height: 26px; border-radius: 50%; border: 2px solid transparent;
  padding: 0; cursor: pointer;
}
.pf-swatch:hover { transform: scale(1.08); }
.pf-swatch.on { border-color: var(--text); box-shadow: 0 0 0 2px var(--bg); }
/* A project's colour on the rail — what makes it findable without reading. */
.rail-dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; }
.rail-edit { opacity: 0; color: var(--text-faint); font-size: 11px; padding: 0 2px; }
.rail-item:hover .rail-edit { opacity: 1; }
.rail-edit:hover { color: var(--text); }
.cn-warn-none { color: var(--text-dim); }
.cn-usage-lrow.drillable, .cn-usage-mrow.drillable { cursor: pointer; border-radius: 8px; }
.cn-usage-lrow.drillable:hover, .cn-usage-mrow.drillable:hover { background: var(--bg-3); }
.cn-usage-lrow.drillable:focus-visible, .cn-usage-mrow.drillable:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.cn-usage-drillhead { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin: 14px 0 6px; }
.cn-usage-back { appearance: none; background: var(--bg-3); border: 1px solid var(--border); color: var(--text-dim); font: inherit; font-size: 12.5px; font-weight: 600; padding: 5px 11px; border-radius: 9px; cursor: pointer; }
.cn-usage-back:hover { color: var(--text); border-color: var(--accent); }
.cn-usage-drilltitle { display: flex; align-items: center; gap: 8px; font-size: 14.5px; min-width: 0; word-break: break-word; }
.cn-usage-drillsub { font-size: 12px; opacity: .55; }
.cn-usage-budgetbar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; padding: 11px 13px; border: 1px solid var(--border); border-radius: 12px; background: var(--bg); margin: 0 0 12px; }
.cn-usage-budgetbar.warn { border-color: color-mix(in srgb, var(--warn, #f5a524) 55%, var(--border)); }
.cn-usage-budgetbar.over { border-color: color-mix(in srgb, var(--danger) 55%, var(--border)); }
.cn-usage-budgetlabel { font-size: 12.5px; font-weight: 700; opacity: .65; white-space: nowrap; }
.cn-usage-budgetoff { font-size: 12.5px; opacity: .55; flex: 1; min-width: 180px; }
.cn-usage-budgetmeter { position: relative; flex: 1; min-width: 140px; height: 8px; border-radius: 5px; background: var(--bg-3); overflow: visible; }
.cn-usage-budgetfill { display: block; height: 100%; border-radius: 5px; background: var(--accent); }
.cn-usage-budgetbar.warn .cn-usage-budgetfill { background: var(--warn, #f5a524); }
.cn-usage-budgetbar.over .cn-usage-budgetfill { background: var(--danger); }
.cn-usage-projmark { position: absolute; top: -3px; width: 2px; height: 14px; background: var(--text-faint); border-radius: 1px; }
.cn-usage-projmark.bad { background: var(--danger); }
.cn-usage-budgetnums { font-size: 13px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.cn-usage-budgetpct { opacity: .55; margin-left: 4px; }
.cn-usage-budgetedit { display: inline-flex; align-items: center; gap: 6px; }
.cn-usage-cur { opacity: .5; font-size: 13px; }
.cn-usage-budgetinput { width: 84px; padding: 5px 8px; font-size: 13px; }
.cn-usage-budgetnote { font-size: 11.5px; opacity: .55; }
.cn-usage-delta { font-weight: 700; font-variant-numeric: tabular-nums; }
.cn-usage-delta.up { color: var(--danger); }
.cn-usage-delta.down { color: var(--ok, #3fb950); }
.cn-usage-chip.warnchip { color: var(--warn); background: var(--warn-soft); }

/* ============================================================
   LIBRARY SHELL — the layout Files and Memory share
   One page shape for the two stores the AI keeps: a big title
   with the search beside it, a row of category tabs, and a
   table underneath. Prefixed `lib-` because neither page owns
   it; a third store should use it rather than invent a fourth
   toolbar. Column widths come from --lib-cols, declared by the
   page (`.files-list`, `.mem-list`) so the header row and the
   data rows can never disagree about them.
   ============================================================ */
.lib-body { padding-top: 30px; }
.lib-wrap { max-width: 1020px; margin: 0 auto; }

.lib-head { display: flex; align-items: flex-start; gap: 20px; padding-bottom: 22px; }
.lib-head-main { min-width: 0; }
.lib-title { margin: 0; font-size: 30px; font-weight: 600; letter-spacing: -0.02em; line-height: 1.2; }
.lib-sub { margin: 7px 0 0; font-size: 13px; color: var(--text-faint); max-width: 560px; }
.lib-head-tools { margin-left: auto; display: flex; align-items: center; gap: 10px; flex-shrink: 0; }

.lib-search-wrap { position: relative; width: 264px; }
.lib-search {
  width: 100%; height: 40px; padding: 0 14px 0 38px; font: inherit; font-size: 14px;
  color: var(--text); background: var(--bg-2); border: 1px solid var(--border);
  border-radius: 999px; outline: none;
}
.lib-search::placeholder { color: var(--text-faint); }
.lib-search:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.lib-search::-webkit-search-cancel-button { filter: grayscale(1) opacity(0.6); }
.lib-search-ico {
  position: absolute; left: 14px; top: 50%; transform: translateY(-50%);
  width: 15px; height: 15px; color: var(--text-faint); pointer-events: none;
}
/* The one create action a library page has. Inverted, so it is unmistakably the
   primary button without spending the accent on it. */
.lib-new {
  height: 40px; padding: 0 18px; border: 0; border-radius: 999px;
  font: inherit; font-size: 14px; font-weight: 600;
  background: var(--text); color: var(--bg);
}
.lib-new:hover { opacity: .88; }

.lib-bar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; padding-bottom: 10px; }
.lib-tabs { display: flex; align-items: center; gap: 2px; flex-wrap: wrap; min-width: 0; }
.lib-tab {
  display: inline-flex; align-items: center; gap: 7px; height: 34px; padding: 0 14px;
  border: 0; border-radius: 999px; background: none; color: var(--text-dim);
  font: inherit; font-size: 13.5px; font-weight: 600; white-space: nowrap;
  transition: background .12s, color .12s;
}
.lib-tab:hover { background: var(--bg-2); color: var(--text); }
.lib-tab.on { background: var(--bg-3); color: var(--text); }
/* --bg-3 sits a shade ABOVE the page in the dark theme and a shade BELOW it in the
   light one, where it lands within a couple of points of --bg — so the selected tab
   and the selected view button need the deeper token there or they read as unselected. */
:root[data-theme="light"] .lib-tab.on,
:root[data-theme="light"] .lib-iconbtn.on { background: var(--bg-hover); }
.lib-tab-n { font-size: 11.5px; font-weight: 600; color: var(--text-faint); font-variant-numeric: tabular-nums; }
.lib-tab.on .lib-tab-n { color: var(--text-dim); }

.lib-bar-end { margin-left: auto; display: flex; align-items: center; gap: 6px; }
.lib-summary {
  display: inline-flex; align-items: center; gap: 10px; white-space: nowrap;
  font-size: 12.5px; color: var(--text-faint); font-variant-numeric: tabular-nums;
}
.lib-iconbtn {
  width: 34px; height: 34px; flex-shrink: 0; display: inline-flex;
  align-items: center; justify-content: center;
  border: 0; border-radius: 999px; background: none; color: var(--text-dim);
  transition: background .12s, color .12s;
}
.lib-iconbtn:hover { background: var(--bg-2); color: var(--text); }
.lib-iconbtn.on { background: var(--bg-3); color: var(--text); }
.lib-iconbtn svg { width: 17px; height: 17px; }
.lib-linkbtn {
  background: none; border: 0; padding: 0 6px; font: inherit; font-size: 12.5px;
  color: var(--text-dim); white-space: nowrap;
}
.lib-linkbtn:hover { color: var(--text); }
/* The grouping switch is a control among icon buttons here, so it shrinks to match. */
.lib-seg { border-radius: 999px; }
.lib-seg .seg { font-size: 12.5px; padding: 6px 11px; }

/* The column header — Name / Modified / Size. Deliberately NOT sticky: the day
   headings below it are section headers of their own, and two bands pinned to the
   top of one scroller (this and the bulk bar) end up drawn over each other. */
.lib-thead {
  display: grid; grid-template-columns: var(--lib-cols); align-items: center; gap: 12px;
  padding: 6px 10px 8px; background: var(--bg); border-bottom: 1px solid var(--border);
  font-size: 12px; font-weight: 600; color: var(--text-faint);
}

/* ============================================================
   HEARTBEAT — one card per thing that runs on its own
   Name · switch · ⋯ on one line, a sentence, then when it runs
   and when it runs next. Every setting it used to wear moved
   into .hb-set, which the ⋯ menu lifts into a modal — the same
   elements, moved, never a second copy.
   ============================================================ */
.hb-grid { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(370px, 1fr)); }
.hb-card {
  display: flex; flex-direction: column; gap: 9px; min-width: 0;
  padding: 15px 16px 13px;
  background: var(--bg-1); border: 1px solid var(--border); border-radius: 14px;
}
.hb-card.failing { border-color: color-mix(in srgb, var(--danger) 45%, var(--border)); }
.hb-top { display: flex; align-items: center; gap: 11px; min-width: 0; }
.hb-ico { --ico-sz: 34px; }
.hb-name {
  flex: 1; min-width: 0; padding: 0; border: 0; background: none; text-align: left;
  font: inherit; font-size: 14.5px; font-weight: 600; color: var(--text); cursor: pointer;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.hb-name:hover { text-decoration: underline; }
.hb-top-end { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }
/* A count chip is short enough to sit beside the name; a label naming a role or a team
   is not, so those get a line of their own rather than a share of the title's width. */
.hb-top > .skl-chip { flex-shrink: 0; }
.hb-tags { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin-top: -2px; }

/* The switch. A real pill, because on/off is the card's headline state and a checkbox
   reads as one setting among several. */
.hb-switch {
  position: relative; width: 38px; height: 22px; flex-shrink: 0; padding: 0;
  border: 0; border-radius: 999px; background: var(--bg-hover); cursor: pointer;
  transition: background .15s;
}
.hb-switch i {
  position: absolute; top: 3px; left: 3px; width: 16px; height: 16px; border-radius: 50%;
  background: var(--text-faint); transition: transform .15s, background .15s;
}
.hb-switch.on { background: var(--accent); }
.hb-switch.on i { transform: translateX(16px); background: #fff; }
.hb-switch.dim { opacity: .45; cursor: default; }

.hb-more {
  width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center;
  gap: 3px; border: 0; border-radius: 8px; background: none; color: var(--text-faint);
}
.hb-more span { width: 3px; height: 3px; border-radius: 50%; background: currentColor; }
.hb-more:hover { background: var(--bg-3); color: var(--text); }

.hb-sub { margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--text-faint); }
.hb-foot {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding-top: 10px; border-top: 1px solid var(--border);
  font-size: 12px; color: var(--text-dim);
}
.hb-when { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }
.hb-when .ico { width: 14px; height: 14px; flex-shrink: 0; opacity: .8; }
.hb-next { margin-left: auto; color: var(--text-faint); }
.hb-card.failing .hb-when { color: var(--danger); }

/* The ⋯ menu. Fixed, so it is never clipped by the card's own overflow. */
.hb-menu {
  position: fixed; z-index: 80; min-width: 186px; padding: 6px;
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: var(--shadow-2);
}
.hb-menu-item {
  display: flex; align-items: center; gap: 10px; width: 100%; padding: 8px 10px;
  border: 0; border-radius: 8px; background: none; color: var(--text);
  font: inherit; font-size: 13.5px; text-align: left;
}
.hb-menu-item:hover { background: var(--bg-3); }
.hb-menu-item .ico { width: 16px; height: 16px; flex-shrink: 0; color: var(--text-faint); }
.hb-menu-item > span:not(.hb-menu-check) { flex: 1; min-width: 0; }
.hb-menu-gap { width: 16px; flex-shrink: 0; }
/* A toggle in a menu is a row with a tick, not a checkbox — the tick column is reserved
   whether or not it is on, so the labels do not shift when you switch one. */
.hb-menu-check { width: 14px; text-align: right; color: var(--accent); font-size: 13px; }
.hb-menu-item.danger, .hb-menu-item.danger .ico { color: var(--danger); }
.hb-menu-item.danger:hover { background: var(--danger-soft); }
/* A row that is only telling you something (why a thing is unavailable) — no hover,
   because there is nothing to click. */
.hb-menu-item.quiet { color: var(--text-faint); font-size: 12px; cursor: default; }
.hb-menu-item.quiet:hover { background: none; }

/* The settings sheet — the card's own controls, shown in a modal. */
.hb-set-modal { max-width: 520px; }
.hb-set-body .hb-set { display: flex; flex-wrap: wrap; gap: 12px; }
.hb-set-note { font-size: 12px; color: var(--text-faint); margin-right: auto; }

/* ============================================================
   ICON TILES — one outline set, coloured by subject
   The tile owns the colour (--ic) and the glyph inherits it, so
   an icon is styled by WHAT IT IS rather than per placement.
   Sizes come from the host (.cat-ico, .hb-ico, …) via --ico-sz;
   the tile is otherwise identical everywhere it appears.
   ============================================================ */
/* ⚠️ The size is a FALLBACK inside the value, never a declaration of its own.
   `--ico-sz: 40px` here and `--ico-sz: 24px` on the host are both one-class selectors,
   so the winner is whichever sits later in this file — and this block sits after most
   of them. Every tile whose host asked for a smaller size (a memory row's 24, a
   Heartbeat card's 34, a Company skill's 26, a detail head's 52) silently rendered at
   40 and overflowed its grid track: on Memory the tile spilled into the text column and
   the sentence started hard against the icon with no gap left. Written as a fallback,
   the host's value always wins, because there is nothing here to lose to. */
.ico-tile {
  --ic: var(--text-dim);
  width: var(--ico-sz, 40px); height: var(--ico-sz, 40px); flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: calc(var(--ico-sz, 40px) / 3.6);
  color: var(--ic);
  background: color-mix(in srgb, var(--ic) 13%, transparent);
  border: 1px solid color-mix(in srgb, var(--ic) 24%, transparent);
}
.ico-tile .ico { width: 55%; height: 55%; display: block; }
/* Bare glyph, no tile — for a row that is already inside one (a menu item, a footer). */
.ico-bare { background: none; border: 0; width: auto; height: auto; }

.ic-rose { --ic: #f2708a; }
.ic-amber { --ic: #e0a458; }
.ic-green { --ic: #34c37e; }
.ic-cyan { --ic: #35b7c8; }
.ic-violet { --ic: #8b7ff8; }
.ic-blue { --ic: #4f8ff7; }
.ic-teal { --ic: #2fb8a0; }
.ic-slate { --ic: #9aa1ad; }
/* The light theme's page is near-white, so a 13% wash of a light hue vanishes and the
   stroke itself is too pale to read. Deepen both rather than re-picking the palette. */
:root[data-theme="light"] .ico-tile {
  background: color-mix(in srgb, var(--ic) 15%, #fff);
  border-color: color-mix(in srgb, var(--ic) 34%, transparent);
  color: color-mix(in srgb, var(--ic) 78%, #000);
}

/* ============================================================
   CATALOG LIST — Skills and Connections
   The library shell above, with a two-column list under it. A
   catalog card is for READING: an icon, a name, one line, and
   one mark on the right saying where you stand with it. The
   work happens on the thing's own page, so the card carries at
   most one control and never a row of chips.
   ============================================================ */
/* A catalog is two columns of cards, so it gets more room than a table of files. */
.lib-wide { max-width: 1180px; }

.cat-list {
  display: grid; gap: 12px; align-content: start;
  grid-template-columns: repeat(auto-fill, minmax(370px, 1fr));
}
/* Loading / empty / "nothing matches" lines are sentences, not cards — they span. */
.cat-list > .hint, .cat-list > .mk-empty, .cat-list > p { grid-column: 1 / -1; }

.cat-card {
  display: grid; grid-template-columns: 40px minmax(0, 1fr) auto;
  align-items: center; gap: 14px; min-width: 0;
  padding: 13px 16px; cursor: pointer;
  background: var(--bg-1); border: 1px solid var(--border); border-radius: 14px;
  transition: background .12s, border-color .12s;
}
.cat-card:hover { background: var(--bg-2); border-color: var(--bg-hover); }
/* Part of Quorai: nothing to open, so it must not offer to be opened. */
.cat-static, .cat-static:hover { cursor: default; background: var(--bg-1); border-color: var(--border); }
.cat-locked { opacity: .72; }

/* The tile is an .ico-tile now; this only says how big it is here. The rule stays for
   the few cards still carrying an emoji (extensions, roles), which get the old plate. */
.cat-ico {
  --ico-sz: 40px;
  width: 40px; height: 40px; display: flex; align-items: center; justify-content: center;
  font-size: 21px; border-radius: 11px;
}
.cat-ico:not(.ico-tile) { background: var(--bg-3); border: 1px solid var(--border); }
.cat-main { min-width: 0; }
.cat-name {
  font-size: 14px; font-weight: 600; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* One line, always — the full text is in the card's tooltip and in full on its page.
   Two cards whose summaries wrap to different heights make a ragged column. */
.cat-sum {
  margin-top: 2px; font-size: 12.5px; color: var(--text-faint);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cat-sum.muted { opacity: .8; font-style: italic; }

.cat-act { display: flex; align-items: center; justify-content: flex-end; gap: 8px; }
.cat-check { font-size: 15px; color: var(--text-dim); line-height: 1; }
.cat-lock { font-size: 13px; opacity: .8; line-height: 1; }
.cat-note { font-size: 11.5px; color: var(--text-faint); white-space: nowrap; }
.cat-btn, .cat-act .cap-status { white-space: nowrap; }

@media (max-width: 620px) {
  .cat-list { grid-template-columns: 1fr; }
  .cat-card { padding: 12px 13px; gap: 12px; }
}

/* ============================================================
   Files view (#view-files)
   Namespaced `fv-` on purpose: `.file-row` / `.file-name` /
   `.file-meta` already belong to the chat download cards
   (renderFilesCard), and reusing them restyled those too.
   ============================================================ */
/* pick · icon · name · modified · size · actions */
.files-list.lib-table { --lib-cols: 18px 40px minmax(0, 1fr) 140px 88px 118px; }

/* Bulk bar — only rendered while something is ticked. */
.files-bulk {
  position: sticky; top: 0; z-index: 6;
  display: flex; align-items: center; gap: 10px; margin: 0 0 10px;
  padding: 8px 14px; border: 1px solid var(--accent); border-radius: 999px;
  /* The tint over an OPAQUE ground: --accent-soft is translucent, and a sticky bar you
     can read the scrolling rows through is a bar nobody trusts. */
  background: linear-gradient(var(--accent-soft), var(--accent-soft)), var(--bg);
}
.files-bulk-count { font-size: 13px; font-weight: 600; color: var(--accent-2); margin-right: auto; }
.files-bulk-del { color: var(--danger); border-color: var(--danger); }
.files-bulk-del:hover:not(:disabled) { background: var(--danger-soft); }
.files-bulk-del:disabled { opacity: 0.6; cursor: default; }

/* Day groups — a quiet label between stretches of table, not a card. */
.fv-group { margin-top: 14px; }
/* The first group sits right under the column header (list) or the toolbar (grid) —
   both count, since the header row is only rendered for the list view. */
.fv-group:first-child, .lib-thead + .fv-group { margin-top: 0; }
.fv-group-head {
  display: flex; align-items: center; gap: 8px; margin: 0;
  padding: 14px 10px 8px; font-size: 12px; font-weight: 600;
  color: var(--text-faint);
}
.fv-group-n { font-size: 11.5px; font-weight: 600; color: var(--text-faint); font-variant-numeric: tabular-nums; }
/* Take a whole day in one tick. Dim until the group (or the header) is hovered, so a
   column of boxes doesn't compete with the file names for attention. */
.fv-gpick { opacity: .5; transition: opacity .12s ease; }
.fv-group:hover .fv-gpick,
.fv-gpick:has(:checked),
.fv-gpick:has(:indeterminate) { opacity: 1; }
/* "Select all" sits with the count it acts on. A link, not a button: it changes what is
   ticked, it never touches a file. */
.fv-selall {
  background: none; border: none; padding: 0; cursor: pointer; font: inherit;
  font-size: 12px; color: var(--accent); white-space: nowrap;
}
.fv-selall:hover { color: var(--accent-2); text-decoration: underline; }

/* List rows */
.fv-row {
  display: grid; grid-template-columns: var(--lib-cols); align-items: center; gap: 12px;
  padding: 9px 10px; border-radius: 10px; border-bottom: 1px solid var(--border);
  transition: background .12s, opacity .15s;
}
.fv-row:last-child { border-bottom: 0; }
.fv-row:hover { background: var(--bg-2); }
.fv-row.sel { background: var(--accent-soft); }
.fv-row.going { opacity: 0.4; pointer-events: none; }

.fv-pick { display: flex; align-items: center; width: 16px; flex-shrink: 0; }
.fv-check { cursor: pointer; accent-color: var(--accent); margin: 0; transition: opacity .12s; }

/* One rounded tile whatever the file is, so a column of mixed types still lines up. */
.fv-ico {
  --ico-sz: 40px;
  width: 40px; height: 40px; display: flex; align-items: center; justify-content: center;
  font-size: 19px; border-radius: 11px;
}
.fv-ico:not(.ico-tile) { background: var(--bg-3); border: 1px solid var(--border); }
/* A grid card has a whole preview panel to fill, so the tile is simply bigger there. */
.fv-card-ico.ico-tile { --ico-sz: 60px; }
.fv-thumb {
  width: 40px; height: 40px; flex-shrink: 0; object-fit: cover;
  border-radius: 9px; background: var(--bg-3); border: 1px solid var(--border);
}
.fv-main { min-width: 0; }
.fv-name {
  display: block; width: 100%; text-align: left; padding: 0; border: 0; background: none;
  font: inherit; font-size: 13.5px; font-weight: 500; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
button.fv-name { cursor: pointer; }
button.fv-name:hover { text-decoration: underline; }
.fv-cell { font-size: 12.5px; color: var(--text-faint); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Size and time also live in the row itself, for the narrow layout that drops the
   columns. Hidden here rather than rebuilt there, so the two can't drift apart. */
.fv-meta { display: none; font-size: 11.5px; color: var(--text-faint); margin-top: 2px; }
.fv-acts { display: flex; align-items: center; justify-content: flex-end; gap: 2px; }

.fv-src {
  width: 26px; height: 26px; display: inline-flex; align-items: center; justify-content: center;
  padding: 0; font: inherit; font-size: 12px; cursor: pointer;
  color: var(--text-dim); background: none; border: 0; border-radius: 999px; flex-shrink: 0;
}
.fv-src:hover { background: var(--bg-3); color: var(--accent-2); }
.fv-del { flex-shrink: 0; }
.fv-del:hover { color: var(--danger); border-color: var(--danger); background: var(--danger-soft); }

/* Quiet the SECONDARY actions until a row is engaged, so a long list scans cleanly.
   Download is deliberately not among them: it is the reason this page exists, and a
   primary action you have to hover to discover is a hidden one.
   Gated on `hover: hover`, not a width — a tablet has a wide viewport and no pointer,
   so a max-width query would leave it unable to reach delete at all. */
@media (hover: hover) {
  .fv-row .fv-src, .fv-row .fv-del, .fv-check { opacity: 0; transition: opacity .12s; }
  .fv-row:hover .fv-src, .fv-row:hover .fv-del,
  .fv-row:focus-within .fv-src, .fv-row:focus-within .fv-del,
  .fv-row.sel .fv-src, .fv-row.sel .fv-del { opacity: 1; }
  .fv-row:hover .fv-check, .fv-row:focus-within .fv-check,
  .fv-row.sel .fv-check, .fv-check:checked { opacity: 1; }
  /* The whole tick-box chrome hides on a card, not just the input — a bordered
     empty square sitting on every thumbnail reads as a rendering fault. */
  .fv-card-pick { opacity: 0; transition: opacity .12s; }
  .fv-card:hover .fv-card-pick, .fv-card:focus-within .fv-card-pick,
  .fv-card.sel .fv-card-pick { opacity: 1; }
}

/* Grid — earns its place once the AI is producing charts and screenshots. */
.fv-grid { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); padding-top: 4px; }
.fv-card {
  position: relative; display: flex; flex-direction: column; overflow: hidden;
  background: var(--bg-2); border: 1px solid var(--border);
  border-radius: 14px; transition: border-color .12s, box-shadow .12s, opacity .15s;
}
/* A card is the one place the stacked meta line is the layout, not a fallback. */
.fv-card .fv-meta { display: block; }
.fv-card .fv-name { white-space: nowrap; }
.fv-card:hover { border-color: var(--accent); box-shadow: var(--shadow-1); }
.fv-card.sel { border-color: var(--accent); background: var(--accent-soft); }
.fv-card.going { opacity: 0.4; pointer-events: none; }
.fv-card-pick {
  position: absolute; top: 8px; left: 8px; z-index: 2; width: auto;
  padding: 3px; border-radius: 5px; background: var(--bg-1); border: 1px solid var(--border);
}
.fv-card-prev {
  display: flex; align-items: center; justify-content: center;
  aspect-ratio: 4 / 3; background: var(--bg-3); border-bottom: 1px solid var(--border);
}
.fv-card-img { width: 100%; height: 100%; object-fit: cover; display: block; }
.fv-card-ico { font-size: 40px; opacity: 0.85; }
.fv-card-body { padding: 9px 10px 4px; }
.fv-card-acts { display: flex; align-items: center; gap: 6px; padding: 4px 10px 9px; margin-top: auto; }
.fv-card-acts .file-dl, .fv-card-acts .fv-del { margin-left: auto; }
.fv-card-acts .fv-src { margin-right: auto; }
/* Preview joins the right-hand action group rather than opening a third gap. */
.fv-card-acts .file-open { margin-left: auto; }
.fv-card-acts .file-open + .file-dl { margin-left: 6px; }

/* The thumbnail is the other natural way to ask for a preview — it is a button
   wrapping the image, so it must add no chrome of its own. */
.fv-thumbbtn { display: flex; flex-shrink: 0; padding: 0; border: 0; background: none; cursor: pointer; }
button.fv-card-prev { width: 100%; padding: 0; border: 0; border-bottom: 1px solid var(--border); cursor: pointer; }

.linkish {
  font: inherit; font-size: inherit; color: var(--accent-2); background: none;
  border: 0; padding: 0 2px; cursor: pointer; text-decoration: underline;
}

/* Narrow: the Modified and Size columns fold away and the row's own meta line takes
   over — the same two numbers, stacked instead of ruled. */
@media (max-width: 760px) {
  .files-list.lib-table { --lib-cols: 18px 40px minmax(0, 1fr) 118px; }
  .fv-row > .fv-cell, .lib-thead > .fv-cell { display: none; }
  .fv-row .fv-meta { display: block; }
}
@media (max-width: 620px) {
  .lib-body { padding-top: 20px; }
  .lib-head { flex-wrap: wrap; gap: 14px; padding-bottom: 16px; }
  .lib-title { font-size: 24px; }
  .lib-head-tools { margin-left: 0; width: 100%; }
  .lib-search-wrap { flex: 1; width: auto; }
  .lib-bar-end { width: 100%; margin-left: 0; }
}

/* ===========================================================================
   Marketplace skill cards — who it's for, what it needs, and whether it's yours
   =========================================================================== */

/* The tab row is a .lib-bar; it needs nothing here beyond the space under it. */
#skills-controls { margin-bottom: 4px; }

/* Grouped, #skills-grid stops being a card list and becomes a column of sections, each
   holding its own .cat-list. The class is swapped in renderSkillsGrid rather than
   nesting, because a <section> inside a grid container becomes a grid ITEM and the
   whole group would collapse into one column. Headings are Company → Skills'
   (.skl-group-h), deliberately — the same shape wherever a skill list is grouped.
   This page no longer groups (the tabs do it); Heartbeat and Company → Skills still do. */
.mk-groups { display: block; }
.mk-groups > .skl-group:first-child { margin-top: 0; }

.mk-empty { color: var(--text-faint); font-size: 13px; padding: 26px 4px; grid-column: 1 / -1; }

/* ---- chat queue: messages typed while the AI was still working -------------
   These sit above the composer, NOT in the transcript, because nothing here has
   been said yet — each row is still editable and still cancellable. All colour
   comes from the token block at the top, so both themes follow automatically. */
.queue-list {
  display: flex; flex-direction: column; gap: 4px;
  margin: 0 0 8px; padding: 8px 10px;
  border: 1px dashed var(--border);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--accent) 5%, transparent);
}
.queue-head { font-size: 12px; color: var(--text-dim); margin-bottom: 2px; }
.queue-note { opacity: .75; margin-left: 4px; }
.queue-item {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; color: var(--text);
  padding: 4px 6px; border-radius: var(--radius-sm);
}
.queue-item:hover { background: var(--accent-soft); }
.queue-n {
  flex: none; min-width: 18px; height: 18px; line-height: 18px; text-align: center;
  font-size: 11px; border-radius: 50%;
  background: var(--accent-soft); color: var(--text-dim);
}
/* The message can be any length; it must never widen the composer. */
.queue-text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.queue-att { flex: none; font-size: 11px; color: var(--text-dim); }
.queue-actions { flex: none; display: flex; gap: 2px; }
.queue-btn {
  background: none; border: none; cursor: pointer;
  color: var(--text-dim); font-size: 12px; line-height: 1;
  padding: 3px 5px; border-radius: 4px;
}
.queue-btn:hover:not(:disabled) { background: var(--border); color: var(--text); }
.queue-btn:disabled { opacity: .3; cursor: default; }
.queue-x:hover { color: var(--warn); }

/* Send doubles as "queue" while a turn runs — same button, different promise. */
.btn-send.queueing { opacity: .85; }
.btn-send.queueing::after {
  content: "+"; font-size: 11px; vertical-align: super; margin-left: 1px;
}

/* ===================================================================
   THE RAIL STANDARD (2026-08)
   -------------------------------------------------------------------
   Group Chat, Company and the Inbox each replace the app sidebar with a
   left rail of their own, and each had grown its own idea of what a rail
   is: 280px vs 264, a padded scrolling container vs a fixed head over a
   scrolling list, flat nav rows vs bordered cards, three different active
   states. Walking between the three views, the furniture moved.

   One definition, applied to all three by grouping the selectors they
   already use — no class in app.js changes. The reference is the app
   sidebar itself (`.side-item`), because that is what these rails stand in
   for: same 264px, same row metrics, same accent-soft active state.

   Appended last, so it wins over the per-view rules above.
   =================================================================== */

/* 1 · Width. One number, from the grid parent that owns each rail. */
.gc-hub { grid-template-columns: var(--rail-w) minmax(0, 1fr) 460px; }
@media (max-width: 1040px) { .gc-hub { grid-template-columns: var(--rail-w) minmax(0, 1fr); } }

/* 2 · The container. The HEAD stays put and the LIST scrolls — a rail whose
   whole body scrolls takes its own title away when you go looking down it. */
.gc-rail, .cn-rail, .ibx-rail, .tsk-rail {
  border-right: 1px solid var(--border); background: var(--bg-2);
  display: flex; flex-direction: column; min-height: 0; padding: 0; gap: 0;
}
/* Company's body is one long scroller (nav + admin + companies + actions), so it
   keeps scrolling — but its children now carry the inset the container used to. */
.cn-rail { overflow-y: auto; padding-bottom: 10px; }
.cn-rail > * { padding-inline: 12px; }
/* …and the two pinned pieces stop compensating for a padding that is gone. */
.cn-rail .rail-chrome-top, .cn-rail .rail-foot.account-row { margin: 0; }

/* 3 · The head: one line, one weight, one border. */
.gc-rail-head, .ibx-rail-head, .tsk-rail-head, .cn-rail-nav-head {
  display: flex; align-items: center; gap: 8px;
  padding: 14px 12px 10px; margin: 0; border-bottom: 1px solid var(--border);
}
.gc-rail-title, .ibx-rail-title, .tsk-rail-title, .cn-rail-nav-title {
  font-weight: 700; font-size: 15px; color: var(--text); flex: 1; min-width: 0;
}
/* Company's identity block sits UNDER that head as content, not as a second head. */
.cn-rail-head { padding-top: 12px; padding-bottom: 4px; gap: 10px; }

/* 4 · The list. */
.gc-rail-list, .ibx-rail-list, .tsk-rail-list, .cn-nav, .cn-nav-admin, .cn-rail-list {
  display: flex; flex-direction: column; gap: 1px;   /* `.side-nav`'s */
}
/* Company is the only rail that stacks BLOCKS (identity, nav, admin, switcher,
   actions) rather than one list, so it carries the sidebar's 10px between them. */
.cn-rail { gap: 10px; }
/* An empty count is not a count. Without this the badge draws as a grey dot next to a
   row that simply has nothing to report. */
.cn-nav-badge:empty, .ibx-fold-n:empty, .nav-badge:empty { display: none; }
.gc-rail-list, .ibx-rail-list, .tsk-rail-list { flex: 1; min-height: 0; overflow-y: auto; padding: 10px 12px; }

/* 5 · The row — the app sidebar's `.side-item`, to the pixel. Flat, not a card: a
   bordered box per chat made the Group Chat rail read as a list of objects to manage
   rather than places to go. The numbers are not arbitrary; they are `.side-item`'s, so
   a nav row is the same object wherever you meet it.
     gap 12 · padding 7/10 · radius 8 · 13.5px/500 · text-dim */
.gc-item, .cn-nav-item, .cn-rail-item, .ibx-fold {
  display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  background: none; border: 1px solid transparent; border-radius: 8px;
  padding: 7px 10px; cursor: pointer; font: inherit; font-size: 13.5px;
  font-weight: 500; color: var(--text-dim);
}
/* The icon box, also the sidebar's: a 20×18 slot so labels line up whether or not the
   row's glyph is a wide one, dimmed until the row is yours. */
.cn-nav-ico, .ibx-fold-ico {
  width: 20px; height: 18px; flex: 0 0 auto; display: inline-flex;
  align-items: center; justify-content: center; opacity: .82;
}
.cn-nav-ico svg, .ibx-fold-ico svg, .ibx-ico { width: 17px; height: 17px; display: block; }
.gc-item:hover .cn-nav-ico, .cn-nav-item:hover .cn-nav-ico, .ibx-fold:hover .ibx-fold-ico,
.cn-nav-item.active .cn-nav-ico, .ibx-fold.on .ibx-fold-ico { opacity: 1; }
/* A nested row hangs under its parent's LABEL, not under its icon: 10 (row) + 20 (icon
   slot) + 12 (gap) = 42. Guessed indents are what made these lists look ragged. */
.cn-nav-team { padding-left: 42px; }
/* A section label: the sidebar's, 10px and wide-tracked, so it reads as a label rather
   than competing with the rows under it. (The Inbox's fold heads are BUTTONS — a
   destination, not a label — so they keep their weight.) */
.cn-nav-section-title, .cn-rail-section {
  font-size: 10px; letter-spacing: .09em; color: var(--text-faint);
  padding: 8px 10px 3px; font-weight: 700; text-transform: uppercase;
}
.gc-item:hover, .cn-nav-item:hover, .cn-rail-item:hover, .ibx-fold:hover {
  background: var(--bg-hover); border-color: transparent; color: var(--text);
}
.gc-item.active, .cn-nav-item.active, .cn-rail-item.active, .ibx-fold.on {
  background: var(--accent-soft); border-color: transparent;
  color: var(--text); font-weight: 600;
}
/* A folder still indents under its section head — that is structure, not decoration. */
.ibx-fold { padding-left: 22px; }
.ibx-fold-head { padding-left: 10px; }
/* Group Chat's rows carry an avatar and a second line, so they need the height back. */
.gc-item { padding: 8px 10px; }
.gc-item-ava { width: 30px; height: 30px; border-radius: 8px; font-size: 15px; }
.gc-item-name { font-weight: 600; }
.gc-item.active .gc-item-name, .gc-item.active .gc-item-sub { color: var(--text); }

/* 6 · Counts, right-aligned, one shape. */
.cn-nav-badge, .ibx-fold-n {
  margin-left: auto; min-width: 18px; height: 18px; padding: 0 6px;
  border-radius: 999px; font-size: 11px; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
}

/* ===================================================================
   TASKS — the four-panel hub (2026-08)
   -------------------------------------------------------------------
   Projects | the list | the task | your AI. The board and the table are
   gone: two ways to look at the same rows, neither of which could show a
   task beside its own context, because opening one slid a drawer over the
   list you picked it from.

   The rail, its head and its rows come from THE RAIL STANDARD above — this
   block only lays the columns out and styles what is genuinely new here:
   the list rows, the task pane, and the panel's two envelopes.
   =================================================================== */
.tsk-hub {
  flex: 1; min-height: 0; display: grid; background: var(--bg); position: relative;
  grid-template-columns: var(--rail-w) 330px minmax(0, 1fr) 460px;
}
.tsk-rail-head .cn-icon-btn svg { width: 18px; height: 18px; }
.tsk-rail-foot { margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--border); }

/* ---- the list ---- */
.tsk-listcol { border-right: 1px solid var(--border); background: var(--bg-2);
  display: flex; flex-direction: column; min-height: 0; min-width: 0; }
.tsk-listhead { padding: 12px 12px 10px; border-bottom: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 8px; }
.tsk-search { width: 100%; background: var(--bg); border: 1px solid var(--border);
  border-radius: 9px; color: var(--text); padding: 7px 10px; font: inherit; font-size: 13px; }
.tsk-search:focus { outline: none; border-color: var(--accent); }
.tsk-listhead-row { display: flex; align-items: center; gap: 6px; }
.tsk-listhead-row .tasks-select { flex: 1; min-width: 0; font-size: 12px; padding: 5px 7px; }
.tsk-listhead-row .tasks-count { margin-left: auto; font-size: 11.5px; color: var(--text-faint);
  white-space: nowrap; }
.tsk-list { flex: 1; min-height: 0; overflow-y: auto; padding: 6px; display: flex;
  flex-direction: column; gap: 1px; }
/* With nothing in it the list must not hold the column open, or the empty state that
   explains WHY it is empty gets pushed to the bottom of the screen. */
.tsk-list:empty { flex: 0 0 auto; padding: 0; }
.tsk-listcol .tasks-empty { padding: 26px 18px; text-align: center; }
/* A row is a row, on the standard's metrics — but two lines, because a task without its
   project and owner is a title you have to open to identify. */
.tsk-row { display: flex; align-items: flex-start; gap: 9px; width: 100%; text-align: left;
  background: none; border: 1px solid transparent; border-radius: 8px; padding: 7px 10px;
  cursor: pointer; font: inherit; color: var(--text-dim); }
.tsk-row:hover { background: var(--bg-hover); color: var(--text); }
.tsk-row.active { background: var(--accent-soft); color: var(--text); }
.tsk-row.pinned { box-shadow: inset 2px 0 0 var(--accent); }
.tsk-row-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.tsk-row-title { font-size: 13px; font-weight: 500; color: var(--text); line-height: 1.35;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.tsk-row-meta { font-size: 11px; color: var(--text-faint); overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.tsk-row-due { flex: 0 0 auto; font-size: 11px; }
.tsk-row-pr { flex: 0 0 auto; color: var(--danger); font-weight: 700; font-size: 12px; }
/* One dot, coloured by status: the fastest read on a list this dense, and the same
   vocabulary the board's columns used. */
.tsk-row-dot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; margin-top: 5px;
  background: var(--text-faint); }
.dot-todo { background: var(--text-faint); }
.dot-in_progress { background: var(--accent); }
.dot-ready { background: var(--info); }
.dot-blocked { background: var(--danger); }
.dot-done { background: var(--ok); }

/* ---- the task ---- */
.tsk-read { min-width: 0; overflow-y: auto; padding: 20px 26px 40px; background: var(--bg); }
.tsk-read-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
.tsk-read-tools { margin-left: auto; display: flex; gap: 6px; }
.tsk-chip { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px;
  color: var(--text-dim); border: 1px solid var(--border); border-radius: 999px; padding: 2px 10px; }
.tsk-chip .tsk-row-dot { margin-top: 0; }
.tsk-chip.pr-high { color: var(--danger); border-color: rgba(239, 68, 68, .4); }
.tsk-link-row { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
  background: none; border: none; border-radius: 8px; padding: 6px 8px; cursor: pointer;
  color: var(--text-dim); font: inherit; font-size: 13px; text-decoration: none; }
.tsk-link-row:hover { background: var(--bg-hover); color: var(--text); }
.tsk-controls { display: flex; gap: 12px; flex-wrap: wrap; }
.tsk-ctl { display: flex; flex-direction: column; gap: 4px; min-width: 150px; flex: 1; }
.tsk-ctl > span { font-size: 11px; color: var(--text-faint); }
.tsk-ctl select { background: var(--bg-2); border: 1px solid var(--border); border-radius: 8px;
  color: var(--text); padding: 6px 8px; font: inherit; font-size: 13px; }

/* ---- the panel's two envelopes ---- */
/* ONE inset, stated once. The Inbox panel puts its padding on the container
   (`.ibx-ai`), which cannot work here: the tab row and the composer both need a full-
   width border, and the feed between them scrolls. So the container has none and each
   of the three regions carries the SAME 14px — which is what stops the eye seeing three
   different margins down one 460px column. */
.tsk-ai { --tsk-pad: 14px;
  border-left: 1px solid var(--border); background: var(--bg-2); display: flex;
  flex-direction: column; min-height: 0; min-width: 0; padding: 0; }
.tsk-tabs { display: flex; gap: 6px; flex-shrink: 0;
  padding: var(--tsk-pad); border-bottom: 1px solid var(--border); }
.tsk-ai .ibx-ai-body { flex: 1 1 auto; min-height: 0; overflow-y: auto;
  padding: var(--tsk-pad); gap: 12px; }
/* The composer: same inset, its own rule rather than the Inbox's margin-plus-padding
   pair, which put an 11px gap above a 12px border and read as neither. */
.tsk-ai .ibx-ai-act { flex-shrink: 0; max-height: none; overflow: visible;
  margin: 0; padding: var(--tsk-pad); border-top: 1px solid var(--border); }
.tsk-ai .ibx-ai-tell { margin: 0; }
.tsk-tab { flex: 1; background: none; border: 1px solid var(--border); border-radius: 9px;
  padding: 7px 8px; cursor: pointer; font: inherit; font-size: 12px; font-weight: 600;
  color: var(--text-dim); display: inline-flex; align-items: center; justify-content: center; gap: 6px; }
.tsk-tab:hover { color: var(--text); border-color: var(--text-faint); }
.tsk-tab.on { background: var(--accent-soft); border-color: var(--accent); color: var(--text); }
.tsk-tab-n { font-size: 10.5px; font-weight: 700; color: var(--text-faint);
  background: var(--bg-3); border-radius: 999px; padding: 0 6px; min-width: 17px; }
.tsk-tab.on .tsk-tab-n { background: var(--accent); color: var(--on-accent); }
.tsk-note { display: flex; flex-direction: column; gap: 8px; }

/* ---- the log ---- */
.tsk-log { display: flex; flex-direction: column; gap: 1px; }
.tsk-log-row { display: flex; align-items: flex-start; gap: 9px; width: 100%; text-align: left;
  background: none; border: none; border-radius: 8px; padding: 7px 9px; cursor: pointer;
  color: var(--text-dim); font: inherit; }
.tsk-log-row:hover { background: var(--bg-hover); }
.tsk-log-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--border);
  flex: 0 0 auto; margin-top: 6px; }
.tsk-log-row.note .tsk-log-dot { background: var(--accent); }
.tsk-log-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.tsk-log-top { font-size: 12.5px; color: var(--text); }
.tsk-log-verb { color: var(--text-dim); font-weight: 400; }
.tsk-log-when { color: var(--text-faint); font-size: 11px; margin-left: 4px; }
.tsk-log-body { font-size: 12px; color: var(--text-faint); overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.tsk-log-open { padding: 8px 12px 12px 27px; font-size: 12.5px; color: var(--text-dim); }
.tsk-log-detail { display: flex; flex-direction: column; gap: 4px; overflow-wrap: anywhere; }
.tsk-log-k { font-size: 11px; color: var(--text-faint); text-transform: uppercase;
  letter-spacing: .05em; font-weight: 700; margin-right: 6px; }
.tsk-log-empty { padding: 18px 4px; }

/* Narrow screens give ground in the same order the Inbox does: the list and the panel
   tighten, then the panel becomes a drawer under the task rather than disappearing —
   every verb the AI offers lives in it. */
@media (max-width: 1560px) { .tsk-hub { grid-template-columns: var(--rail-w) 300px minmax(0, 1fr) 420px; }
  .tsk-read { padding: 18px 20px 36px; } }
@media (max-width: 1320px) { .tsk-hub { grid-template-columns: var(--rail-w) 264px minmax(0, 1fr) 360px; } }
@media (max-width: 1120px) {
  .tsk-hub {
    grid-template-columns: var(--rail-w) minmax(0, 300px) minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr) auto;
    grid-template-areas: "rail list read" "rail list ai";
  }
  .tsk-rail { grid-area: rail; }
  .tsk-listcol { grid-area: list; }
  .tsk-read { grid-area: read; }
  .tsk-ai { grid-area: ai; max-height: 46vh; border-left: 1px solid var(--border);
    border-top: 1px solid var(--border); }
}
@media (max-width: 920px) { .tsk-hub { grid-template-columns: 58px minmax(0, 260px) minmax(0, 1fr); }
  .tsk-rail-title, .tsk-rail .ibx-fold-label, .tsk-rail .ibx-fold-head { display: none; }
  .tsk-rail-head { justify-content: center; padding: 12px 4px 8px; }
  .tsk-rail .ibx-fold { justify-content: center; padding: 9px 4px; } }

/* ---- the panel's third envelope, and the pointer to it ---- */
/* Facts as a two-column key/value grid: eight labelled boxes down a 460px column is a
   scroll; eight rows is a glance. */
.tsk-facts { display: grid; grid-template-columns: max-content minmax(0, 1fr);
  gap: 4px 14px; padding: 4px 2px 14px; font-size: 12.5px; }
.tsk-fact-k { color: var(--text-faint); font-size: 11.5px; white-space: nowrap; }
.tsk-fact-v { color: var(--text); overflow-wrap: anywhere; }
.tsk-info-grp { padding-top: 12px; margin-top: 12px; border-top: 1px solid var(--border); }
.tsk-info-h { display: flex; align-items: center; gap: 8px; font-size: 11px;
  font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
  color: var(--text-faint); margin-bottom: 6px; }
.tsk-info-hint { font-size: 11.5px; color: var(--text-faint); line-height: 1.5;
  margin: -2px 0 7px; }
.tsk-link-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
/* The middle pane keeps a one-line pointer rather than five half-empty boxes. */
.tsk-rel-note { font-size: 12.5px; color: var(--text-faint); margin: 2px 0 14px; }
.tsk-rel-open { background: none; border: none; color: var(--accent-2); cursor: pointer;
  font: inherit; font-size: 12.5px; padding: 0; }
.tsk-rel-open:hover { text-decoration: underline; }

/* ===================================================================
   COMPANY, ON THE LIBRARY PAGE STYLE (2026-08)
   -------------------------------------------------------------------
   Skills, Connections, Memory and Files share one page look: a wide
   quiet title over a centred reading column, pill tabs, and cards that
   sit a shade above the page with a soft border. Company — including
   every admin sub-page — had its own: a 21px title in a bordered bar, a
   full-bleed pane, underlined tabs, and cards a shade BELOW the page.

   Same treatment as THE RAIL STANDARD above: the library's rules are
   applied to the classes Company already uses, so nothing in app.js
   changes. Appended last, so it wins.
   =================================================================== */

/* 1 · The page frame. FULL WIDTH with a margin, not a centred column: this is a
   directory and a set of control panels, not an article. Members is a grid of
   `auto-fill` cards, so the width buys columns rather than stretched cards, and the
   admin pages are label↔control rows that read better wide than tall.

   Still padding, never a max-width: the pane is the SCROLLER, and capping a scroller
   is what put Home's scrollbar 190px in from the window edge. Prose keeps its own cap
   further down — a 1,800px line of explanatory text is unreadable however wide the
   window is. */
.cn-pane { padding: 30px 32px 44px; }
.cn-pane[data-pane="chat"] { padding: 0; }

/* 2 · The head, in the library's voice: the title carries the page, the line
   under it is quiet, and there is no rule beneath — the content starts the
   moment the sentence ends. Aligned to the same column as the pane. */
.cn-main-head {
  padding: 30px 32px 0;
  border-bottom: 0; align-items: flex-end;
}
.cn-main-head h1, .cn-admin-pagehead h2 {
  margin: 0; font-size: 30px; font-weight: 600; letter-spacing: -0.02em; line-height: 1.2;
}
.cn-main-head p, .cn-admin-pagehead p {
  margin: 7px 0 0; font-size: 13px; color: var(--text-faint); max-width: 560px;
}
.cn-admin-pagehead { margin: 0 0 22px; }

/* 3 · Tabs as pills, not underlines. */
.cn-tabs { gap: 2px; padding: 8px 32px 10px; border-bottom: 0; }
.cn-tab {
  display: inline-flex; align-items: center; gap: 7px; height: 34px; padding: 0 14px;
  border: 0; border-bottom: 0; border-radius: 999px; background: none;
  color: var(--text-dim); font-size: 13.5px; font-weight: 600; margin-bottom: 0;
  transition: background .12s, color .12s;
}
.cn-tab:hover { background: var(--bg-2); color: var(--text); }
.cn-tab.active { background: var(--bg-3); color: var(--text); border-bottom-color: transparent; }
:root[data-theme="light"] .cn-tab.active { background: var(--bg-hover); }
.cn-tab-count { background: none; color: var(--text-faint); font-size: 11.5px;
  padding: 0; margin-left: 0; font-variant-numeric: tabular-nums; }

/* 4 · Cards. The library's card sits a shade ABOVE the page (`--bg-1`) with a
   14px radius and a soft shadow; Company's sat on `--bg`/`--bg-2`, which reads
   as a well rather than a card. One treatment, every kind of card here. */
.cn-ppl-card, .cn-member-row, .cn-team-tile, .cn-member-tile,
.cn-settings-card, .cn-identity-card, .cn-knowledge-row {
  background: var(--bg-1); border: 1px solid var(--border); border-radius: 14px;
  box-shadow: var(--shadow-1);
}
.cn-ppl-card, .cn-member-row, .cn-team-tile, .cn-member-tile { padding: 14px 16px; }
.cn-settings-card { padding: 18px 20px; }
.cn-ppl-card:hover, .cn-member-tile:hover, .cn-team-tile:hover {
  border-color: var(--accent); background: var(--bg-2);
}
/* A card's own heading, at the library's weight rather than a bold sentence. */
.cn-settings-h { font-size: 15px; font-weight: 600; letter-spacing: -0.01em; margin-bottom: 7px; }
.cn-settings-desc { font-size: 13px; color: var(--text-faint); max-width: 78ch; }
/* The explanatory paragraph on an admin page, likewise: the CARD goes full width
   because its controls do, but the sentence explaining it does not. */
.cn-admin-pagehead p { max-width: 78ch; }
.cn-settings-pane { gap: 18px; }

/* 5 · Grids breathe like the library's. */
.cn-ppl-grid { grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 14px; }
.cn-members-grid { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 14px; }
.cn-members-list { gap: 10px; }

/* ===========================================================================
   Mind maps (frontend/mindmap.js)

   The SVG itself carries no CSS — its colours are written in as literals, read
   from the tokens at draw time, so a DOWNLOADED .svg still looks like the map
   you were looking at. Only the frame around it is styled here.
   =========================================================================== */
.mm-embed { margin: 14px 0; }

/* A wide map scrolls inside its own box. Without this a big map widens the chat
   column and the whole page scrolls sideways. */
.mm-canvas {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-1);
  padding: 6px;
}
.mm-svg { display: block; max-width: 100%; height: auto; }

/* Interactive map: drag a box onto another to re-parent, drag the background to
   pan, ctrl/cmd+scroll to zoom. `touch-action: none` is required or the browser
   claims the gesture for scrolling and pointermove never fires on touch. */
.mm-live { touch-action: none; cursor: grab; user-select: none; }
.mm-live.mm-panning { cursor: grabbing; }
.mm-live:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.mm-node { cursor: grab; }
.mm-node rect { transition: filter .12s; }
.mm-node:hover rect:first-of-type { filter: brightness(1.14); }
.mm-node.mm-dragging { opacity: .45; cursor: grabbing; }

/* The node the drop would land on. A ring rather than a fill change, so the
   node's own colour still reads while it is highlighted. */
.mm-node.mm-drop rect:first-of-type {
  stroke: var(--ok); stroke-width: 3px; filter: brightness(1.2);
}

.mm-toggle { cursor: pointer; }
.mm-toggle:hover circle { filter: brightness(1.25); }

.mm-hint {
  font-size: 11px; color: var(--text-faint); align-self: center;
  margin-left: 2px;
}
@media (max-width: 640px) { .mm-hint { display: none; } }

/* The selected node, and the overlaid input used to rename it. The input is real
   HTML positioned over the SVG rect — SVG <text> cannot be typed into, and
   contenteditable drags in a caret model and pasted rich text we do not want. */
.mm-node.mm-sel rect:first-of-type { stroke: var(--accent-2); stroke-width: 2.5px; }
.mm-canvas { position: relative; }
.mm-edit {
  position: absolute; z-index: 5; font: inherit; font-size: 13px; font-weight: 600;
  padding: 0 12px; border-radius: 8px;
  border: 2px solid var(--accent); background: var(--bg-2); color: var(--text);
  box-shadow: var(--shadow-2);
}
.mm-edit:focus { outline: none; }

/* ---- the Mind maps page ---- */
.mm-grid {
  display: grid; gap: 14px; margin-top: 18px;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
}
.mm-card {
  text-align: left; font: inherit; cursor: pointer;
  padding: 16px; border-radius: var(--radius);
  border: 1px solid var(--border); background: var(--bg-1); color: var(--text);
  transition: border-color .15s, transform .15s, box-shadow .15s;
}
.mm-card:hover {
  border-color: var(--accent); transform: translateY(-2px); box-shadow: var(--shadow-1);
}
.mm-card-title { font-weight: 600; margin-bottom: 6px; }
.mm-card-meta { font-size: 12px; color: var(--text-faint); }

.mm-empty { margin-top: 24px; color: var(--text-dim); max-width: 52ch; }
.mm-empty p { margin: 0 0 10px; }

.mm-detail-head { display: flex; align-items: center; gap: 14px; margin: 4px 0 14px; }
.mm-detail-title { margin: 0; font-size: 18px; font-weight: 600; }

/* The page canvas gets a real height and the SVG scales into it. A chat map keeps
   its natural size — blowing a three-node map up to full width helps nobody. */
.mm-page-embed { flex: 1; display: flex; }
.mm-page-embed .mm-canvas { flex: 1; height: 68vh; overflow: hidden; padding: 0; }
.mm-canvas-fit { display: flex; }
.mm-svg-fit { width: 100%; height: 100%; max-width: none; }

.mm-btn.mm-danger:hover { border-color: var(--danger); color: var(--danger); }
.mm-btn.mm-save { border-color: var(--accent); color: var(--text); }
/* The primary action on this page: it is what people look for and could not find. */
/* The style bar. Acts on the selected node; a fixed palette rather than a colour
   picker, because these colours are written into a DOWNLOADED svg opened where our
   stylesheet does not exist — a free picker makes black-on-black one click away. */
/* The insertion caret, shown when a drag would drop a node BETWEEN two siblings
   rather than inside one. Positioned in screen space over the canvas, for the same
   reason drop targeting is: the browser already knows where the boxes are. */
.mm-caret {
  position: absolute; height: 3px; border-radius: 2px;
  background: var(--ok); box-shadow: 0 0 0 1px var(--bg-1);
  pointer-events: none; display: none; z-index: 4;
}

.mm-style {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  margin-top: 10px; padding: 10px 12px;
  border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-1);
}
.mm-style-label {
  font-size: 11px; color: var(--text-faint); margin-left: 10px; margin-right: 2px;
}
.mm-style-label:first-child { margin-left: 0; }
.mm-swatch {
  width: 20px; height: 20px; border-radius: 6px; cursor: pointer;
  border: 1px solid var(--border); padding: 0; background: transparent;
  transition: transform .12s, border-color .12s;
}
.mm-swatch:hover { transform: scale(1.15); border-color: var(--text); }
.mm-swatch:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* "Default" is a slash, not a colour — it CLEARS the key so the node goes back to
   its depth-based colour rather than baking today's theme in as a literal. */
.mm-swatch-none {
  background: linear-gradient(135deg, transparent 44%, var(--danger) 44%,
              var(--danger) 56%, transparent 56%);
}
.mm-btn.mm-mini { padding: 4px 9px; font-size: 11px; min-width: 28px; }

/* Connection state. Shown, not assumed — a person needs to know whether their
   edits are being shared or only kept locally. */
.mm-pill {
  align-self: center; font-size: 11px; padding: 4px 10px; border-radius: 999px;
  border: 1px solid var(--border); color: var(--text-faint); white-space: nowrap;
}
.mm-pill-live { border-color: var(--ok); color: var(--ok); background: var(--ok-soft); }
.mm-pill-retry { border-color: var(--warn); color: var(--warn); background: var(--warn-soft); }
.mm-save-needed { border-color: var(--warn); color: var(--warn); }

.mm-btn.mm-add { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.mm-btn.mm-add:hover { background: var(--accent-2); border-color: var(--accent-2); color: var(--on-accent); }

.mm-bar { display: flex; gap: 8px; margin-top: 8px; flex-wrap: wrap; }
.mm-btn {
  font: inherit; font-size: 12px; line-height: 1;
  padding: 7px 12px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--bg-2); color: var(--text-dim);
  cursor: pointer; transition: background .15s, color .15s, border-color .15s;
}
.mm-btn:hover { background: var(--bg-hover); color: var(--text); border-color: var(--accent); }
.mm-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* The format picker is a real <select> so it is keyboard- and screen-reader-correct
   without a hand-built popover. It only has to LOOK like the buttons beside it. */
.mm-pick { padding-right: 26px; appearance: none; -webkit-appearance: none; }
.mm-pick { background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                             linear-gradient(135deg, currentColor 50%, transparent 50%);
           background-position: calc(100% - 14px) 50%, calc(100% - 9px) 50%;
           background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; }
.mm-pick option { background: var(--bg-2); color: var(--text); }

/* An outline we could not parse is SHOWN, never swallowed — otherwise a model's
   malformed map looks like the answer simply stopped. */
.mm-failed pre {
  margin: 0; padding: 12px; overflow-x: auto;
  border: 1px dashed var(--warn); border-radius: var(--radius);
  background: var(--warn-soft); color: var(--text-dim);
  font-family: var(--mono); font-size: 12px; white-space: pre;
}

/* ---- Usage: the same breakdown as a table you can interrogate ----------------
   Bars answer "which is biggest" and nothing else. The table carries the three
   numbers they cannot: the share of the total, the average run, and the unit
   price — which is the only figure that actually compares two models. */
.cn-usage-tabend { margin-left: auto; display: inline-flex; align-items: center; gap: 8px; }
.cn-usage-find {
  height: 28px; min-width: 180px; padding: 0 10px; font: inherit; font-size: 12.5px;
  color: var(--text); background: var(--bg); border: 1px solid var(--border); border-radius: 999px;
}
.cn-usage-find:focus { outline: none; border-color: var(--accent); }
.cn-usage-seg { display: inline-flex; gap: 2px; background: var(--bg-3); border-radius: 8px; padding: 2px; }
.cn-usage-vbtn {
  border: 0; background: none; color: var(--text-faint); cursor: pointer;
  font: inherit; font-size: 12px; padding: 3px 9px; border-radius: 6px;
}
.cn-usage-vbtn.on { background: var(--bg-2); color: var(--text); }

.cn-ut { width: 100%; border-collapse: collapse; font-size: 12.5px; margin-top: 4px; }
.cn-ut th {
  text-align: right; font-size: 11px; font-weight: 600; color: var(--text-faint);
  padding: 7px 10px; border-bottom: 1px solid var(--border); white-space: nowrap; cursor: pointer;
  user-select: none;
}
.cn-ut th.l, .cn-ut td.l { text-align: left; }
.cn-ut th:hover { color: var(--text); }
.cn-ut th.on { color: var(--text); }
.cn-ut td {
  padding: 8px 10px; text-align: right; color: var(--text);
  border-bottom: 1px solid var(--border); font-variant-numeric: tabular-nums;
}
.cn-ut tbody tr { cursor: pointer; }
.cn-ut tbody tr:hover td { background: var(--bg-hover); }
.cn-ut-name { display: flex; align-items: center; gap: 7px; min-width: 0; }
.cn-ut-none { color: var(--text-faint); }

/* ============================================================================
   The account menu and the tabbed Settings modal
   ============================================================================ */
/* The account row is one button now — Settings, the theme and Log out were three
   controls crammed onto it, two of them unlabelled glyphs and one of them a sign-out. */
.account-caret { margin-left: auto; color: var(--text-faint); font-size: 16px; line-height: 1; }

.acct-menu {
  position: fixed; z-index: 300; min-width: 244px;
  background: var(--bg-2); border: 1px solid var(--border); border-radius: 14px;
  box-shadow: var(--shadow-2); padding: 6px;
}
.acct-menu-head { display: flex; align-items: center; gap: 10px; padding: 10px 10px 8px; }
.acct-menu-who { display: flex; flex-direction: column; min-width: 0; }
.acct-menu-who strong { font-size: 14px; line-height: 1.2; }
.acct-menu-who small { color: var(--text-faint); font-size: 12px; }
.acct-menu-rule { height: 1px; background: var(--border); margin: 4px 8px; }
.acct-menu-item {
  display: flex; align-items: center; gap: 11px; width: 100%;
  background: none; border: 0; border-radius: 9px; cursor: pointer;
  color: var(--text); font: inherit; font-size: 14px; padding: 9px 10px; text-align: left;
}
.acct-menu-item:hover { background: var(--bg-hover); }
.acct-menu-item svg { width: 17px; height: 17px; flex-shrink: 0; color: var(--text-dim); }

/* ---- the shell: a rail of sections, the settings beside it ----------------------
   A row of tabs above a scrolling column meant the section names scrolled away with the
   content and a long pane read as one endless form. The rail stays put. */
.set-body { display: grid; grid-template-columns: 210px minmax(0, 1fr); gap: 0; padding: 0; }
.set-nav {
  display: flex; flex-direction: column; gap: 2px; padding: 14px 10px;
  border-right: 1px solid var(--border); background: var(--bg-1);
  border-radius: var(--radius) 0 0 var(--radius);
}
.set-content { padding: 20px 22px; overflow-y: auto; min-width: 0; }
.set-search { position: relative; margin: 2px 2px 10px; }
.set-search svg {
  position: absolute; left: 9px; top: 50%; transform: translateY(-50%);
  width: 14px; height: 14px; color: var(--text-faint); pointer-events: none;
}
.set-search input {
  width: 100%; padding: 7px 10px 7px 29px; font-size: 13px;
  background: var(--bg-3); border: 1px solid var(--border); border-radius: 9px; color: var(--text);
}
.set-search input:focus { outline: none; border-color: var(--accent); }
.set-tab {
  display: flex; align-items: center; gap: 9px; width: 100%; text-align: left;
  appearance: none; background: none; border: 0; border-radius: 9px;
  color: var(--text-dim); font: inherit; font-size: 13.5px; font-weight: 600;
  padding: 8px 10px; cursor: pointer;
}
.set-tab svg { width: 16px; height: 16px; flex-shrink: 0; }
.set-tab:hover { color: var(--text); background: var(--bg-hover); }
.set-tab.on { color: var(--text); background: var(--bg-3); }
/* A section with nothing matching the search is not a section you can open. */
.set-tab.dim { opacity: .35; }

@media (max-width: 700px) {
  .set-body { grid-template-columns: minmax(0, 1fr); }
  .set-nav { flex-direction: row; overflow-x: auto; border-right: 0;
    border-bottom: 1px solid var(--border); border-radius: var(--radius) var(--radius) 0 0; }
  .set-search { display: none; }
  .set-tab span { white-space: nowrap; }
}
.set-pane-head { margin: 0 0 14px; }
.set-pane-head h3 { margin: 0 0 3px; font-size: 15px; }
.set-pane-head p { margin: 0; color: var(--text-faint); font-size: 12.5px; line-height: 1.5; }
.set-sub {
  font-size: 11.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-faint); margin: 20px 0 8px;
}

/* ---- the library ---- */
.lib-list { display: flex; flex-direction: column; gap: 6px; }
.lib-row {
  display: flex; align-items: center; gap: 10px; padding: 10px 12px;
  background: var(--bg-3); border: 1px solid var(--border); border-radius: 10px;
}
.lib-row-main { min-width: 0; flex: 1; }
.lib-row-name { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; font-size: 13.5px; font-weight: 600; }
.lib-row-sub { color: var(--text-faint); font-size: 12px; margin-top: 2px; }
/* An account with no key can be listed but never quietly selected as if it worked. */
.lib-row-cold { opacity: .72; }
.lib-tag {
  font-size: 10.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  padding: 2px 7px; border-radius: 999px; background: var(--bg-hover); color: var(--text-faint);
}
.lib-tag.you { background: var(--accent-soft); color: var(--accent-2); }
.lib-tag.warn { background: var(--warn-soft); color: var(--warn); }
.lib-add { display: flex; gap: 8px; flex-wrap: wrap; }

/* The Settings modal is two columns now, so it needs the room a 480px dialog does not
   have. Scoped to this one overlay: every other modal in the app is a single column and
   480 is right for them. */
#settings-overlay .modal { max-width: 860px; }
/* ⚠️ `.modal-body` is a flex column with a gap — correct for every other dialog, and
   wrong for a grid. The rail and the content are the two grid tracks; the gap between
   them would be a stripe of background down the middle. */
#settings-overlay .modal-body.set-body { display: grid; gap: 0; }
.set-content .field { margin-bottom: 16px; }
.set-content .field:last-child { margin-bottom: 0; }
/* Its own class, never `.hidden`: a field can be hidden because it does not apply (a
   provider with no key field) AND hidden because it does not match a search. One class
   doing both means clearing the search un-hides fields that were never meant to show. */
.hidden-by-search { display: none !important; }

/* ⚠️ A checkbox is not a text field. `.field input:not([type=range])` sets width:100%,
   which stretched the BOX to the width of the dialog — so it centred itself and pushed
   its label into whatever space was left, which is what "the tick box is misaligned"
   looks like. `:not()` carries its argument's specificity, so the old rule is (0,2,1)
   and this has to match it and come later. */
.field input[type=checkbox], .field input[type=radio] {
  width: auto; flex: 0 0 auto; margin: 0; accent-color: var(--accent);
}
/* Label beside the box, reading left to right, and aligned to the FIRST line so a
   two-line label does not float its box to the middle. */
.mining-optout-row { display: flex; align-items: flex-start; gap: 9px; }
.mining-optout-row > span { font-weight: 500; color: var(--text); }

/* ---- the library table and the job rows ---------------------------------------- */
.lib-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 0 0 8px; }
.lib-head .set-sub { margin: 0; }
.lib-tbl { width: 100%; border-collapse: collapse; font-size: 13px; }
.lib-tbl th {
  text-align: left; font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-faint); font-weight: 700; padding: 0 10px 6px; white-space: nowrap;
}
.lib-tbl td { padding: 9px 10px; border-top: 1px solid var(--border); vertical-align: middle; }
.lib-tbl tr:hover td { background: var(--bg-3); }
.lib-name { font-weight: 600; }
.lib-id { color: var(--text-faint); font-size: 11.5px; font-family: var(--mono); }
.lib-act { text-align: right; width: 1%; white-space: nowrap; }
.lib-row-cold td { opacity: .7; }

/* The keys nobody on a managed seat needs, folded away with a summary that says so. */
.lib-keys { margin-top: 20px; border: 1px solid var(--border); border-radius: 10px; background: var(--bg-1); }
.lib-keys > summary {
  cursor: pointer; padding: 11px 13px; display: flex; align-items: baseline; gap: 9px;
  font-size: 13px; font-weight: 600; user-select: none;
}
.lib-keys > summary small { color: var(--text-faint); font-weight: 400; font-size: 11.5px; }
.lib-keys-body { padding: 4px 13px 14px; display: flex; flex-direction: column; gap: 14px; }

/* A job and its thinking depth read as one decision, so they sit on one line. */
.job-row { display: flex; gap: 12px; align-items: flex-end; margin-bottom: 16px; }
.job-row .field { margin-bottom: 0; }
.job-model { flex: 1 1 auto; min-width: 0; }
.job-think { flex: 0 0 132px; }
@media (max-width: 620px) { .job-row { flex-direction: column; align-items: stretch; } .job-think { flex: 1 1 auto; } }

/* ---- the add-a-model form -------------------------------------------------------
   ⚠️ These controls are NOT inside a `.field`, so `.field input`/`.field select` never
   reached them and they rendered as the browser's own grey boxes on a dark dialog —
   which is what "the add model is not styled" was. Styled here against the same tokens,
   rather than by wrapping them in a `.field` that would stack them vertically. */
.lib-add { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin: 10px 0 0; }
.lib-add select, .lib-add input {
  background: var(--bg); border: 1px solid var(--border); color: var(--text);
  border-radius: 9px; padding: 9px 11px; font-size: 13.5px; font-family: inherit; outline: none;
  height: 38px; min-width: 0;
}
.lib-add select { flex: 0 0 168px; }
.lib-add #lib-model { flex: 2 1 190px; }
.lib-add #lib-model-other { flex: 2 1 190px; }
.lib-add #lib-key { flex: 2 1 200px; }
.lib-add select:focus, .lib-add input:focus { border-color: var(--accent); }
.lib-add .btn-primary, .lib-add .btn-secondary { height: 38px; padding: 0 16px; flex: 0 0 auto; }

/* ---- one row per account that needs a key ---- */
.key-row {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 11px 0; border-top: 1px solid var(--border);
}
.key-row:first-child { border-top: 0; }
.key-who { display: flex; align-items: center; gap: 8px; flex: 0 0 190px; font-size: 13.5px; }
.key-in { display: flex; gap: 8px; flex: 1 1 260px; min-width: 0; }
.key-in input {
  flex: 1; min-width: 0; background: var(--bg); border: 1px solid var(--border);
  color: var(--text); border-radius: 9px; padding: 9px 11px; font-size: 13.5px; outline: none;
}
.key-in input:focus { border-color: var(--accent); }
.lib-tag.ok { background: var(--ok-soft); color: var(--ok); }
/* The inline key editor a "no key" row swaps itself for. */
.lib-key-in {
  background: var(--bg); border: 1px solid var(--border); color: var(--text);
  border-radius: 8px; padding: 6px 9px; font-size: 12.5px; width: 190px; outline: none;
}
.lib-key-in:focus { border-color: var(--accent); }
.lib-act .btn-mini + .btn-mini { margin-left: 6px; }
