/* LLM Gateway — semantic theme aliases (WS4 S4.4, docs/roadmap.md).
   This layer maps the app's long-lived semantic names (--bg, --text, ...)
   onto the design-token custom properties that static/theme.css generates
   from design/tokens/*.tokens.json (the single source of truth for the
   product's look, light AND dark). To re-theme the suite: edit a token
   value, then run  go generate ./internal/web  — which rewrites theme.css
   for both themes; nothing in this file needs to change. Do not hardcode
   palette values here; new look values belong in the token files. */

:root, :root[data-theme="dark"] {
  /* surfaces */
  --bg: var(--color-surface-sunken);
  --card: var(--color-surface-default);
  --card2: var(--color-surface-hover);
  /* lines */
  --border: var(--color-line-default);
  --border2: var(--color-line-subtle);
  /* text */
  --text: var(--color-ink-primary);
  --muted: var(--color-ink-muted);
  /* actions & status (the suite accent is the teal brand hue) */
  --primary: var(--color-accent-default);
  --primary-h: var(--color-accent-hover);
  --on-primary: var(--color-ink-inverse);
  --danger: var(--color-danger-default);
  --warn: var(--color-warning-default);
  --info: var(--color-info-default);
  --accent: var(--color-warning-default);
  --brand: var(--color-brand-500);
  /* chart series hues (consumed by charts.js / inline styles) */
  --chart-1: var(--color-success-default);
  --chart-2: var(--color-info-default);
  --chart-3: var(--color-warning-default);
  /* shape & depth */
  --shadow: var(--shadow-sm);
  --radius: var(--radius-xl);
  --radius-s: var(--radius-md);
  /* legacy names consumed by inline style="" rules and older CSS */
  --ok: var(--color-success-default);
  --err: var(--color-danger-default);
  --fg: var(--color-ink-primary);
  --hover: var(--color-surface-active);
  color-scheme: dark;
}

[data-theme="light"] {
  color-scheme: light;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  font-family: system-ui, -apple-system, sans-serif;
  background: var(--bg);
  color: var(--text);
  font-size: 14.5px;
  line-height: 1.5;
  transition: background .2s, color .2s;
}
a { color: var(--info); text-decoration: none; }
a:hover { text-decoration: underline; }
code, .mono { font-family: ui-monospace, 'SF Mono', Menlo, monospace; font-size: .9em; }

:focus-visible { outline: 2px solid var(--info); outline-offset: 2px; border-radius: 4px; }

/* ---------- shell ---------- */
.shell { display: flex; min-height: 100vh; }
.sidebar {
  width: 216px; flex-shrink: 0;
  background: var(--card);
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh;
}
.brand {
  display: flex; align-items: center; gap: 10px;
  padding: 16px 16px 14px;
  border-bottom: 1px solid var(--border2);
  font-weight: 600; font-size: 15px;
}
.brand-mark { color: var(--brand); font-size: 18px; display: flex; }
.brand-mark .brand-svg { width: 20px; height: 20px; display: block; }
.auth-card h1 .brand-svg { width: 22px; height: 22px; }
.nav { flex: 1; min-height: 0; overflow-y: auto; padding: 10px 8px; display: flex; flex-direction: column; gap: 2px; }
.nav-group { display: flex; flex-direction: column; gap: 2px; }
.nav-items { display: flex; flex-direction: column; gap: 2px; }
.nav-section {
  display: flex; align-items: center; gap: 6px; width: 100%; text-align: left;
  border: 0; background: none; cursor: pointer; color: var(--muted);
  font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .06em;
  padding: 14px 10px 4px; border-radius: var(--radius-s);
}
.nav-section:hover { color: var(--text); }
.nav-chevron {
  width: 6px; height: 6px; margin-left: auto; flex-shrink: 0;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg) translate(-1px, -1px); transition: transform .15s ease;
  opacity: .6;
}
.nav-group.collapsed .nav-chevron { transform: rotate(-45deg) translate(-1px, -1px); }
.nav-group.collapsed .nav-items { display: none; }
.nav-item {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px; border-radius: var(--radius-s);
  color: var(--text); font-size: 14px; text-decoration: none;
  border: 0; background: none; cursor: pointer; width: 100%; text-align: left;
}
.nav-item svg { flex-shrink: 0; opacity: .8; }
.nav-item:hover { background: var(--card2); text-decoration: none; }
.nav-item.active { background: color-mix(in srgb, var(--primary) 15%, transparent); color: var(--primary-h); }
.sidebar-footer { border-top: 1px solid var(--border2); padding: 10px 8px; flex-shrink: 0; }
.account-row { display: flex; align-items: center; gap: 2px; padding: 2px 2px 0; }
.identity { display: flex; align-items: center; gap: 8px; min-width: 0; flex: 1; padding: 6px 8px; border-radius: 8px; }
.avatar {
  width: 28px; height: 28px; border-radius: 50%;
  background: color-mix(in srgb, var(--info) 20%, transparent); color: var(--info);
  display: flex; align-items: center; justify-content: center;
  font-weight: 600; font-size: 13px; flex-shrink: 0;
}
.id-name { font-size: 13.5px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; flex-shrink: 0; border-radius: 8px;
  border: 0; background: none; color: var(--muted); cursor: pointer; text-decoration: none;
}
.icon-btn:hover { background: var(--card2); color: var(--text); }
.icon-btn svg { width: 18px; height: 18px; }

.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.main.plain { max-width: 980px; margin: 0 auto; }
a.identity { color: inherit; text-decoration: none; border-radius: 8px; }
a.identity:hover { background: var(--card2); }

/* ---------- shared components ---------- */
.page { padding: 20px 24px; max-width: 1100px; width: 100%; margin: 0 auto; }
.page.full { max-width: none; }
.page-head { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 18px; }
.page-head .hamburger {
  display: none; width: 36px; height: 36px; flex-shrink: 0;
  align-items: center; justify-content: center;
  background: none; border: 1px solid var(--border); border-radius: 8px;
  font-size: 17px; cursor: pointer; color: var(--text);
}
.hamburger { display: none; }
.hamburger svg { width: 16px; height: 16px; }
.backdrop { display: none; }

@media (max-width: 720px) {
  .page-head .hamburger { display: flex; }
}
.page-head h1 { font-size: 18px; margin: 0; flex: 1; }

.card {
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 16px 20px; margin-bottom: 18px;
  box-shadow: var(--shadow);
}
.card h2 { font-size: 13px; text-transform: none; color: var(--muted); margin: 0 0 12px; font-weight: 500; }

.btn {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--card2); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius-s);
  padding: 6px 12px; font-size: 13.5px; cursor: pointer;
}
.btn:hover { background: var(--border2); text-decoration: none; }
.btn.primary { background: var(--primary); border-color: var(--primary); color: var(--on-primary); }
.btn.primary:hover { background: var(--primary-h); }
.btn.danger { background: none; border-color: color-mix(in srgb, var(--danger) 40%, transparent); color: var(--danger); }
.btn.danger:hover { background: color-mix(in srgb, var(--danger) 15%, transparent); }
.btn.sm { padding: 3px 9px; font-size: 12.5px; }
.btn:disabled { opacity: .5; cursor: wait; }

input, textarea, select {
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius-s);
  padding: 7px 10px; font-size: 14px; font-family: inherit;
}
input:focus, textarea:focus, select:focus { border-color: var(--info); outline: none; }

table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.tablewrap { overflow-x: auto; -webkit-overflow-scrolling: touch; max-width: 100%; }

/* Mobile: tables become compact card lists */
@media (max-width: 720px) {
  .tablewrap { overflow-x: visible; }
  .tablewrap table, .tablewrap table tbody { display: block; width: 100%; }
  .tablewrap table thead { display: none; }
  .tablewrap table tr {
    display: block;
    background: var(--card2);
    border: 1px solid var(--border2);
    border-radius: 10px;
    padding: 10px 12px;
    margin-bottom: 10px;
  }
  /* Label in a fixed left column, value flows as normal text on the right.
     (A flex row here spread every inline piece of a cell across the line.) */
  .tablewrap table tbody td {
    display: block; position: relative;
    border-bottom: 0; padding: 5px 0 5px 84px; min-height: 1.7em;
    text-align: right; white-space: normal;
    min-width: 0; overflow-wrap: anywhere;
    background: none !important;
  }
  .tablewrap table tbody td::before {
    content: attr(data-label);
    position: absolute; left: 0; top: 6px; width: 76px;
    text-align: left; color: var(--muted); font-size: 12px; font-weight: 500;
    white-space: normal; overflow-wrap: normal;
  }
  /* Placeholder rows ("No data yet") and unlabelled cells use the full width. */
  .tablewrap table tbody td:not([data-label]) { padding-left: 0; text-align: left; }
  .tablewrap table tbody td:not([data-label])::before { content: none; }
  .tablewrap table tbody td > * { max-width: 100%; }
  .tablewrap table tbody td .btn { margin-top: 2px; }
  .tablewrap table tbody td[style] { white-space: normal !important; }
  .tablewrap table tbody td code { overflow: hidden; text-overflow: ellipsis; }
}
th { text-align: left; color: var(--muted); font-weight: 500; padding: 8px; border-bottom: 1px solid var(--border); }
td { padding: 9px 8px; border-bottom: 1px solid var(--border2); }
tbody tr:nth-child(even) td { background: color-mix(in srgb, var(--card2) 40%, transparent); }
tbody tr:hover td { background: color-mix(in srgb, var(--info) 6%, transparent); }

.badge { font-size: 11.5px; padding: 2px 9px; border-radius: 999px; white-space: nowrap; }
.badge.ok { background: color-mix(in srgb, var(--primary) 18%, transparent); color: var(--chart-1); }
.badge.grace { background: color-mix(in srgb, var(--warn) 18%, transparent); color: var(--warn); }
.badge.off { background: var(--border2); color: var(--muted); }
.badge.bad { background: color-mix(in srgb, var(--danger, #f85149) 18%, transparent); color: var(--danger, #f85149); }
.badge.role-admin { background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--accent); }

.flash { padding: 10px 14px; border-radius: var(--radius-s); margin-bottom: 14px; font-size: 13.5px; display: none; }
.flash.err { background: color-mix(in srgb, var(--danger) 13%, transparent); color: var(--danger); }
.flash.okm { background: color-mix(in srgb, var(--primary) 13%, transparent); color: var(--primary-h); }
.secret {
  font-family: ui-monospace, monospace; background: var(--bg);
  border: 1px dashed var(--warn); border-radius: var(--radius-s);
  padding: 10px 12px; margin-top: 8px; word-break: break-all; font-size: 13px; color: var(--accent);
}
.muted { color: var(--muted); font-size: 12.5px; }

.statgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px; }
.stat {
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 14px 16px; box-shadow: var(--shadow);
  border-top: 2px solid var(--primary);
}
.stat .v { font-size: 22px; font-weight: 600; letter-spacing: -.01em; }
.stat .l { font-size: 12px; color: var(--muted); margin-top: 2px; }

/* ---------- charts (inline SVG) ---------- */
.chart-wrap { width: 100%; overflow-x: auto; }
/* Segmented control (RangePicker, ViewToggle). */
.seg { display: inline-flex; flex-wrap: wrap; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
.seg button { background: none; border: 0; border-right: 1px solid var(--border); color: var(--muted);
  font: inherit; font-size: 12.5px; padding: 5px 10px; cursor: pointer; }
.seg button:last-child { border-right: 0; }
.seg button:hover { color: var(--text); }
.seg button[aria-pressed="true"] { background: var(--card2); color: var(--text); font-weight: 600; }
/* Accent picker (Settings → Appearance): named swatches + "Default". */
.acc { display: inline-flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.acc button { display: inline-flex; align-items: center; gap: 6px; border: 1px solid var(--border);
  background: none; border-radius: 999px; padding: 4px 10px 4px 4px; cursor: pointer;
  font: inherit; font-size: 12.5px; color: var(--muted); }
.acc button:hover { color: var(--text); }
.acc button[aria-pressed="true"] { border-color: var(--text); color: var(--text); font-weight: 600; }
.acc-swatch { width: 16px; height: 16px; border-radius: 50%; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .15); }
.rangepick { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.rp-custom { display: inline-flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.rp-custom input { padding: 4px 6px; font-size: 13px; }
.panel-head { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.panel-head h2 { margin: 0; }
.panel-tools { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; justify-content: flex-end; flex: 1 1 auto; min-width: 0; }
.panel-tools > * { min-width: 0; max-width: 100%; }
/* Horizontal bars (Charts.hbars). */
.hbars { display: flex; flex-direction: column; gap: 6px; }
.hbar { display: grid; grid-template-columns: minmax(80px, 180px) 1fr auto; gap: 10px; align-items: center; font-size: 13px; }
.hb-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hb-track { height: 12px; background: var(--border2); border-radius: 6px; overflow: hidden; }
.hb-fill { height: 100%; border-radius: 6px; }
.hb-val { font-variant-numeric: tabular-nums; color: var(--muted); min-width: 48px; text-align: right; }
.chart-wrap svg { display: block; width: 100%; height: auto; }
.chart-legend { display: flex; gap: 16px; flex-wrap: wrap; margin-bottom: 8px; }
.chart-legend span { font-size: 12px; color: var(--muted); display: inline-flex; align-items: center; gap: 6px; }
.chart-legend i { width: 10px; height: 10px; border-radius: 2px; display: inline-block; }
.chart-legend .legend-item { font-size: 12px; color: var(--muted); display: inline-flex; align-items: center; gap: 6px; }
.chart-legend .legend-swatch { width: 10px; height: 10px; border-radius: 2px; display: inline-block; flex: none; }

.chart-bar { transition: opacity .15s; }
.chart-bar:hover { opacity: .75; }
.chart-tooltip {
  font-size: 11px; fill: var(--muted);
}
.axis-line { stroke: var(--border); stroke-width: 1; }
.axis-text, .chart-tick { font-size: 10.5px; fill: var(--muted); }
.grid-line { stroke: var(--border2); stroke-width: 1; stroke-dasharray: 3 3; }

/* ---- admin config editor ---- */
.cfggrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 12px 20px; }
.cfgfield { display: flex; flex-direction: column; gap: 4px; font-size: 13px; }
.cfglabel { color: var(--muted); font-size: 12px; font-weight: 500; }
.cfghint { color: var(--muted); font-size: 11.5px; line-height: 1.4; }
.cfgtoggle { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; padding: 8px 0; }
.cfgtoggle input { width: auto; }
.cfgtoggle span { font-size: 12.5px; font-weight: 600; color: var(--text); }
.cfgbox { border: 1px solid var(--border); border-radius: 10px; padding: 12px; margin: 10px 0; }
.cfgbox .members { margin: 10px 0; display: flex; flex-direction: column; gap: 6px; }
.memberrow, .pairrow { display: flex; gap: 8px; align-items: end; flex-wrap: wrap; }
.memberrow .mf:first-child, .memberrow .mf:nth-child(2) { flex: 2 1 180px; }
.pairrow .mf { flex: 1 1 140px; }
.mf { display: flex; flex-direction: column; gap: 3px; font-size: 12px; flex: 1 1 120px; }
.mf span { color: var(--muted); font-size: 11px; font-weight: 500; }
.mf input { font-size: 12.5px; padding: 6px 8px; }
.mf-check { flex: 0 0 auto; flex-direction: row; align-items: center; gap: 6px; padding: 8px 0; cursor: pointer; }
.mf-check span { font-size: 12px; }
.mf-num { flex: 0 1 90px; }
.rowlegend { display: flex; gap: 8px; font-size: 10.5px; color: var(--muted); font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; }
.rowlegend span:first-child, .rowlegend span:nth-child(2) { flex: 2 1 180px; }
.rowlegend span:nth-child(3) { flex: 1 1 140px; }
.rowlegend span:nth-child(4) { flex: 0 1 90px; }
.rowlegend span:last-child { flex: 0 0 34px; }
.delbtn, .btn.small { padding: 6px 10px; font-size: 12px; }
.memberrow .btn.small, .pairrow .btn.small { flex: 0 0 34px; }
table.mini { border-collapse: collapse; font-size: 12.5px; margin-top: 8px; }
table.mini th, table.mini td { padding: 4px 14px 4px 0; text-align: left; }
table.mini th { color: var(--muted); font-weight: 500; font-size: 11.5px; }
table.mini tr th:first-child { text-align: right; color: var(--text); }
@media (max-width: 768px) {
  .memberrow, .pairrow { flex-direction: column; align-items: stretch; }
  .rowlegend { display: none; }
}

/* ---------- login ---------- */
body.auth { display: flex; align-items: center; justify-content: center; min-height: 100vh; }
.auth-card {
  background: var(--card); border: 1px solid var(--border); border-radius: 14px;
  padding: 34px; width: 340px; box-shadow: var(--shadow);
}
.auth-card h1 { font-size: 17px; margin: 0 0 4px; display: flex; align-items: center; gap: 8px; }
.auth-card .sub { color: var(--muted); font-size: 13px; margin: 0 0 18px; }
.auth-card label { display: block; font-size: 13px; color: var(--muted); margin: 12px 0 4px; }
.auth-card input { width: 100%; }
.auth-card button { width: 100%; margin-top: 20px; background: var(--primary); color: var(--on-primary); border: 0; border-radius: var(--radius-s); padding: 9px; font-size: 14.5px; cursor: pointer; }
.auth-card button:hover { background: var(--primary-h); }
.auth-error { color: var(--danger); font-size: 13px; margin-top: 12px; }
/* FR-5 federated sign-in: the "or" divider + the IdP link (rendered only
   when the oidc section is live). */
.auth-or { display: flex; align-items: center; gap: 10px; margin: 18px 0 4px; }
.auth-or::before, .auth-or::after { content: ""; flex: 1; height: 1px; background: var(--border); }
.auth-or span { color: var(--muted); font-size: 12px; }
.auth-oidc { display: block; width: 100%; margin-top: 14px; padding: 9px; text-align: center;
  font-size: 14.5px; color: var(--brand); background: var(--card2); border: 1px solid var(--border);
  border-radius: var(--radius-s); text-decoration: none; cursor: pointer; }
.auth-oidc:hover { border-color: var(--brand); }

/* ---------- chat ---------- */
body.chatpage { overflow: hidden; }
.chat-shell { display: flex; height: 100dvh; min-width: 0; }
.chat-main { display: flex; flex-direction: column; height: 100dvh; flex: 1; min-width: 0; }
/* Conversation list: a panel beside the chat (a drawer on phones). */
.convos { width: 264px; flex-shrink: 0; display: flex; flex-direction: column; gap: 8px; padding: 12px 10px;
  border-right: 1px solid var(--border); background: var(--card); min-height: 0; }
.convos-head { display: flex; gap: 6px; }
.convos-new { flex: 1; justify-content: center; display: inline-flex; align-items: center; gap: 6px; }
.convos-close, .convos-btn { display: none; }
@media (min-width: 901px) { .chat-head #newchat { display: none; } }
.convo-search { width: 100%; font-size: 13px; padding: 6px 9px; }
.convo-list { flex: 1; overflow-y: auto; min-height: 0; display: flex; flex-direction: column; gap: 1px; margin: 0 -4px; padding: 0 4px; }
.convo-group { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); padding: 10px 8px 4px; }
.convo-group.convo-proj { color: var(--primary-h, var(--primary)); font-size: 11.5px; }
.convo-ws { color: var(--muted); cursor: pointer; font-size: 11.5px; margin-left: 4px; }
.convo-ws:hover { color: var(--primary-h); }
/* "New project" row: a static link to the projects home (the create form
   lives there; the drawer row only has to be discoverable). Muted by
   default, primary on hover, like the .convo rows. */
.convo-newproj { display: block; padding: 7px 8px; margin-top: 2px; border-radius: 8px;
  color: var(--muted); font-size: 13px; text-decoration: none; }
.convo-newproj:hover { color: var(--primary-h); background: var(--card2); }
.convo { position: relative; display: flex; align-items: center; gap: 6px; padding: 7px 8px; border-radius: 8px;
  cursor: pointer; color: var(--text); text-decoration: none; min-width: 0; }
.convo:hover, .convo:focus-visible { background: var(--card2); outline: none; }
.convo.active { background: color-mix(in srgb, var(--primary) 16%, transparent); }
.convo .c-text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.convo .c-title { font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.convo .c-meta { font-size: 11.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.convo .c-actions { display: none; gap: 2px; }
.convo:hover .c-actions, .convo.active .c-actions, .convo:focus-within .c-actions { display: flex; }
.convo .c-actions button { background: none; border: 0; color: var(--muted); cursor: pointer; padding: 3px 5px; border-radius: 5px; font-size: 13px; }
.convo .c-actions button:hover { color: var(--text); background: var(--border2); }
.convo .c-actions button.del:hover { color: var(--danger); }
.convo-empty { padding: 12px 8px; font-size: 13px; }
.convos-foot { font-size: 11.5px; margin: 0; padding: 6px 4px 0; border-top: 1px solid var(--border2); }
.convos-backdrop { display: none; }
/* New-chat welcome */
.welcome { margin: auto; max-width: 560px; text-align: center; padding: 24px 8px; }
.welcome h2 { font-size: 22px; margin: 0 0 6px; }
.welcome .w-sub { color: var(--muted); font-size: 13.5px; margin: 0 0 18px; }
/* One-line Projects CTA on the welcome screen (the pointer to the organizing
   unit of the product). Muted intro line; the link takes the accent color. */
.welcome .w-cta { color: var(--muted); font-size: 12.5px; margin: 0 0 14px; }
.welcome .w-cta a { color: var(--primary); text-decoration: none; }
.welcome .w-cta a:hover { text-decoration: underline; }
.welcome .w-starters { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 8px; text-align: left; }
.welcome .w-starters button { background: var(--card); border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px;
  color: var(--text); font: inherit; font-size: 13.5px; cursor: pointer; text-align: left; }
.welcome .w-starters button:hover { border-color: var(--muted); }
@media (max-width: 900px) {
  .convos { position: fixed; top: 0; bottom: 0; left: 0; z-index: 60; width: min(300px, 86vw);
    transform: translateX(-100%); transition: transform .2s ease; box-shadow: 4px 0 16px rgba(0,0,0,.4); }
  .convos.open { transform: translateX(0); }
  .convos-close, .convos-btn { display: inline-flex; align-items: center; }
  .convos-backdrop.show { display: block; position: fixed; inset: 0; z-index: 59; background: rgba(0,0,0,.5); }
  /* In the workspace the chat panel is the containing block: the drawer and
     its backdrop cover the panel, not the whole viewport. */
  .ws-chatpanel .convos, .ws-chatpanel .convos-backdrop.show,
  .ws-chatpanel .ctx, .ws-chatpanel .ctx-backdrop.show { position: absolute; }
}
/* Context panel: what the model knows in the current scope (a project, or
   General when none is selected). Always an overlay drawer on the right —
   it never squeezes the conversation. */
.ctx { position: fixed; top: 0; bottom: 0; right: 0; z-index: 62; width: min(400px, 92vw);
  background: var(--card); border-left: 1px solid var(--border);
  transform: translateX(100%); transition: transform .2s ease; box-shadow: -4px 0 16px rgba(0,0,0,.4);
  display: flex; flex-direction: column; }
.ctx.open { transform: translateX(0); }
.ctx-backdrop { display: none; }
.ctx-backdrop.show { display: block; position: fixed; inset: 0; z-index: 61; background: rgba(0,0,0,.5); }
.ctx-head { display: flex; align-items: center; gap: 6px; padding: 10px 12px; border-bottom: 1px solid var(--border); }
.ctx-head h2 { font-size: 15px; margin: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ctx-scope { color: var(--primary); font-size: 13px; font-weight: 500; }
.ctx-body { flex: 1; overflow-y: auto; padding: 12px 14px; display: flex; flex-direction: column; gap: 14px; }
.ctx-sec { display: flex; flex-direction: column; gap: 6px; }
.ctx-sec h3 { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); margin: 0; }
.ctx-sec h3 .ctx-n { color: var(--text); font-weight: 500; }
.ctx-text { font-size: 13px; line-height: 1.45; color: var(--text); white-space: pre-wrap; word-break: break-word;
  max-height: 9.5em; overflow-y: auto; margin: 0; padding: 8px 10px; background: var(--card2);
  border: 1px solid var(--border2); border-radius: 8px; }
.ctx-text.clamp { display: -webkit-box; -webkit-line-clamp: 6; -webkit-box-orient: vertical; overflow: hidden; max-height: none; }
.ctx-empty { font-size: 12.5px; color: var(--muted); margin: 0; }
.ctx-row { display: flex; align-items: center; gap: 8px; font-size: 13px; padding: 5px 8px; border-radius: 7px;
  background: var(--card2); border: 1px solid var(--border2); }
.ctx-row .ctx-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; }
.ctx-row .ctx-meta { font-size: 11.5px; color: var(--muted); white-space: nowrap; }
.ctx-row .ctx-mem { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12.5px; color: var(--text); }
.ctx-row .ctx-tag { flex: none; font-size: 10px; font-weight: 600; letter-spacing: .3px; color: var(--muted);
  border: 1px solid var(--border2); border-radius: 99px; padding: 0.5px 6px; background: var(--card2); }
.ctx-pill { font-size: 11px; font-weight: 600; padding: 1.5px 8px; border-radius: 99px; border: 1px solid var(--border);
  color: var(--muted); background: var(--card); white-space: nowrap; }
.ctx-pill.on { color: var(--primary); border-color: color-mix(in srgb, var(--primary) 40%, transparent);
  background: color-mix(in srgb, var(--primary) 12%, transparent); }
.ctx-pill.off { color: var(--muted); }
.ctx-link { font-size: 12.5px; color: var(--primary); text-decoration: none; }
.ctx-link:hover { text-decoration: underline; }
.ctx-note { font-size: 12px; color: var(--muted); margin: 0; }
.ctx-ws { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 10px;
  border: 1px solid var(--border); border-radius: 9px; background: var(--card2); }
.chat-head {
  display: flex; align-items: center; gap: 10px; padding: 10px 16px;
  background: var(--card); border-bottom: 1px solid var(--border);
}
.chat-head h1 { font-size: 15px; margin: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-head select { max-width: 150px; font-size: 13px; padding: 5px 8px; }
.chat-head #project { max-width: 130px; }
.chat-head .btn-label { display: none; }
@media (min-width: 600px) {
  .chat-head .btn-label { display: inline; }
}
/* #projHome: icon-only on phones (the button's extra width would crowd the
   selects); the global .btn-label rules above are untouched. */
@media (max-width: 900px) { .chat-head #projHome .btn-label { display: none; } }
#msgs {
  flex: 1; overflow-y: auto;
  max-width: 820px; width: 100%; margin: 0 auto; padding: 24px 20px;
  display: flex; flex-direction: column; gap: 20px;
}
body.chatpage .main { height: 100dvh; }

/* message rows: avatar gutter layout like ChatGPT/Claude */
.msg-row { display: flex; gap: 12px; max-width: 100%; }
.msg-row.user { flex-direction: row-reverse; }
.msg-row .avatar {
  width: 30px; height: 30px; border-radius: 50%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 600; margin-top: 2px;
}
.msg-row.user .avatar { background: color-mix(in srgb, var(--info) 22%, transparent); color: var(--info); }
.msg-row.assistant .avatar { background: color-mix(in srgb, var(--primary) 20%, transparent); color: var(--chart-1); }
.msg { min-width: 0; max-width: calc(100% - 42px); word-wrap: break-word; line-height: 1.6; font-size: 14.5px; }
.msg-row.user .msg {
  background: var(--card); border: 1px solid var(--border);
  border-radius: 14px 14px 4px 14px; padding: 10px 16px;
}
.msg-row.assistant .msg { padding: 2px 4px; border: 0; background: none; }
.msg.assistant { font-size: 15px; }
/* Attach confirmation: a centered system line in the message stream. It's
   DOM-only (never sent to the model), so it reads as UI feedback, not chat. */
.attach-note {
  align-self: center; max-width: calc(100% - 42px);
  font-size: 12px; color: var(--muted);
  background: var(--card2); border: 1px solid var(--border2);
  border-radius: 999px; padding: 4px 14px;
  text-align: center; line-height: 1.5;
}
.attach-note.err {
  color: var(--danger, #f85149);
  border-color: color-mix(in srgb, var(--danger, #f85149) 40%, transparent);
  background: color-mix(in srgb, var(--danger, #f85149) 12%, transparent);
}
.msg.assistant .thinking {
  color: var(--muted); font-size: 12.5px;
  border-left: 2px solid var(--border); padding-left: 10px;
  margin-bottom: 10px;
}
.msg .thinking-label {
  font-size: 11px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--muted); cursor: pointer; user-select: none;
  display: inline-flex; align-items: center; gap: 4px;
}
.msg .thinking-label:hover { color: var(--text); }
.msg .thinking-body.collapsed { display: none; }
.msg .msg-actions { margin-top: 8px; display: flex; gap: 6px; opacity: 0; transition: opacity .15s; }
.msg:hover .msg-actions, .msg-row.user:hover .msg-actions { opacity: 1; }
.msg .statsline {
  margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--border2);
  font-size: 11.5px; color: var(--muted); font-family: ui-monospace, monospace;
}
.msg details.nerd { margin-top: 6px; font-size: 12px; color: var(--muted); }
.msg details.nerd > summary { cursor: pointer; user-select: none; width: max-content; }
.msg details.nerd > summary:hover { color: var(--text); }
.msg details.nerd table { margin-top: 6px; border-collapse: collapse; font-family: ui-monospace, monospace; font-size: 11.5px; }
.msg details.nerd th { text-align: left; font-weight: normal; color: var(--muted); padding: 2px 14px 2px 0; white-space: nowrap; vertical-align: top; }
.msg details.nerd a.nerd-more { display: inline-block; margin-top: 6px; font-size: 11.5px; }
.msg details.nerd td { color: var(--text); padding: 2px 0; overflow-wrap: anywhere; }
.toolchip {
  display: flex; align-items: center; gap: 8px;
  font-size: 12.5px; color: var(--muted);
  background: var(--card2); border: 1px solid var(--border2);
  border-radius: 8px; padding: 6px 10px; margin-bottom: 6px;
  font-family: ui-monospace, monospace;
  max-width: 100%;
}
.toolchip .t-arg { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; }
.toolchip .t-status { flex-shrink: 0; font-size: 11px; }
.toolchip.running .t-status { color: var(--warn); animation: pulse 1.2s infinite; }
.toolchip.done .t-status { color: var(--chart-1); }
@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: .4; } }

/* typing indicator */
.typing { display: inline-flex; gap: 4px; padding: 8px 2px; }
.typing i {
  width: 7px; height: 7px; border-radius: 50%; background: var(--muted);
  animation: bounce 1.2s infinite;
}
.typing i:nth-child(2) { animation-delay: .15s; }
.typing i:nth-child(3) { animation-delay: .3s; }
@keyframes bounce { 0%,60%,100% { transform: translateY(0); opacity: .5; } 30% { transform: translateY(-4px); opacity: 1; } }
.md p:last-child { margin-bottom: 0; }
.md h3, .md h4, .md h5 { margin: 10px 0 4px; }
.md ul, .md ol { margin: 4px 0 8px; padding-left: 22px; }
.md li { margin: 2px 0; }
/* nested lists inside an item: tighter, no top margin on the first nest */
.md li > ul, .md li > ol { margin: 2px 0 0; }
.md hr { border: 0; border-top: 1px solid var(--border); margin: 10px 0; }
.md blockquote.md-quote {
  margin: 8px 0; padding: 6px 12px;
  border-left: 3px solid var(--border);
  background: var(--card2); border-radius: 0 6px 6px 0;
  color: var(--muted);
}
.md blockquote.md-quote p { margin: 0 0 4px; }
.md blockquote.md-quote p:last-child { margin-bottom: 0; }
/* markdown tables: a panel (.md-tbl) with an action bar (TSV / Markdown /
   CSV) over a horizontally scrollable table (.md-table) */
.md-tbl {
  margin: 8px 0;
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden; /* clip the toolbar's square corners to the panel radius */
}.md-tblbar {
  display: flex; justify-content: space-between; align-items: center; gap: 6px;
  padding: 5px 8px; background: var(--card2);
  border-bottom: 1px solid var(--border);
}
.md-tbltitle { font-size: 11.5px; color: var(--muted); }
.md-tblbar button:first-of-type { margin-left: auto; }
.md-icobtn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; padding: 0; border: 0; border-radius: 6px;
  background: transparent; color: var(--muted); cursor: pointer;
}
.md-icobtn:hover { background: var(--bg); color: var(--text); }
.md-table { margin: 0; overflow-x: auto; }
/* separate + spacing 0 (not collapse): a pinned leading column keeps its
   border in collapse mode's sticky cells (Safari drops it). */
.md-table table { border-collapse: separate; border-spacing: 0; width: 100%; font-size: 13px; }
.md-table th, .md-table td { padding: 6px 10px; border-bottom: 1px solid var(--border); vertical-align: top; overflow-wrap: anywhere; }
.md-table th { background: var(--card2); font-weight: 600; }
.md-table tbody tr:last-child td { border-bottom: none; }
/* sticky leading column: wide tables scroll without losing the row label */
.md-table th:first-child, .md-table td:first-child { position: sticky; left: 0; z-index: 1; }
.md-table td:first-child { background: var(--card2); }
.md code {
  background: var(--bg); border: 1px solid var(--border);
  border-radius: 4px; padding: 1px 5px; font-size: .88em;
}
.codeblock { margin: 10px 0; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
.codebar {
  display: flex; justify-content: space-between; align-items: center;
  background: var(--card2); color: var(--muted);
  font-size: 11.5px; padding: 5px 12px; border-bottom: 1px solid var(--border);
}
.codeblock pre {
  margin: 0; padding: 12px 14px; overflow-x: auto;
  font-family: ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 13px; line-height: 1.5; background: var(--bg);
}
/* codebar action group (copy + download + preview) */
.codebar-actions { display: flex; align-items: center; gap: 4px; }
.codepreview { display: block; width: 100%; height: 340px; border: 0; border-top: 1px solid var(--border); background: #fff; }
.msg.user .md p { color: #fff; }
.msg .meta { font-size: 11px; color: var(--muted); margin-top: 6px; }
/* composer: floating rounded card with tool row (ChatGPT-style) */
#promptwrap {
  max-width: 820px; width: 100%; margin: 0 auto 12px; padding: 0 12px;
}
#promptbar {
  display: flex; flex-direction: column;
  background: var(--card); border: 1px solid var(--border);
  border-radius: 18px; padding: 10px 14px 8px; box-shadow: var(--shadow);
}
#promptbar:focus-within { border-color: var(--muted); }
#prompt {
  flex: 1; resize: none; border: 0; background: none;
  font-size: 15px; line-height: 1.5; max-height: 180px; padding: 4px 2px 8px;
}
#prompt:focus { outline: none; }
.composer-tools {
  display: flex; align-items: center; gap: 8px;
  border-top: 1px solid var(--border2); padding-top: 8px;
}
.tool-toggle {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12.5px; color: var(--muted);
  border: 1px solid var(--border); border-radius: 999px;
  padding: 4px 12px; cursor: pointer; user-select: none;
  transition: all .15s;
}
.tool-toggle input { display: none; }
.tool-toggle svg { width: 13px; height: 13px; }
.tool-toggle .globe { display: inline-flex; }
.tool-toggle .globe svg { width: 13px; height: 13px; }
.tool-toggle:hover { border-color: var(--muted); color: var(--text); }
.tool-toggle.on {
  background: color-mix(in srgb, var(--primary) 16%, transparent);
  border-color: var(--primary); color: var(--primary-h);
}
button.tool-toggle { background: none; font-family: inherit; font-size: 12.5px; }
button.tool-toggle:disabled { opacity: .5; cursor: default; }
/* On phones the four chips (Attach · Web · Connectors · Send) crowd the
   composer row and push Send off the right edge. Drop the three secondary
   tool-chip labels to icon-only; keep Send's label (the primary action) and
   the title/aria tooltips carry the meaning. Mirrors .chat-head .btn-label. */
@media (max-width: 720px) {
  .composer-tools .tool-label { display: none; }
  .composer-tools .tool-toggle { padding: 6px 8px; }
}
.toolchip.warn { color: var(--warn, #d29922); }
dialog.connectors {
  width: min(620px, calc(100vw - 32px)); max-height: calc(100vh - 48px); overflow: auto;
  background: var(--card); color: var(--text); border: 1px solid var(--border); border-radius: 12px; padding: 16px 18px;
}
dialog.connectors::backdrop { background: rgba(0, 0, 0, .5); }
.cx-head { display: flex; align-items: center; justify-content: space-between; }
.cx-head h2 { margin: 0; font-size: 17px; }
.cx-intro { font-size: 13px; margin: 8px 0 12px; }
.cx-built { margin-top: 2px; }
.cx-built + .cx-built { border-top: 1px solid var(--border2); margin-top: 12px; padding-top: 10px; }
.cx-item { border: 1px solid var(--border2); border-radius: 8px; padding: 10px 12px; margin-bottom: 8px; display: flex; flex-direction: column; gap: 5px; font-size: 13px; }
.cx-line { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; min-width: 0; }
.cx-url { color: var(--muted); overflow-wrap: anywhere; min-width: 0; }
.cx-on { display: inline-flex; gap: 6px; align-items: center; cursor: pointer; }
.cx-form { border-top: 1px solid var(--border2); margin-top: 12px; padding-top: 10px; display: flex; flex-direction: column; gap: 8px; }
.cx-sub { font-weight: 600; font-size: 13px; }
.cx-row { display: flex; gap: 8px; flex-wrap: wrap; }
.cx-row label { display: flex; flex-direction: column; gap: 3px; font-size: 12px; font-weight: 600; flex: 0 1 160px; min-width: 0; }
.cx-row label.cx-grow { flex: 1 1 220px; }
.cx-row input { width: 100%; font-weight: normal; }
.cx-actions { display: flex; gap: 6px; flex-wrap: wrap; }
.cx-ok { color: var(--ok, #3fb950); font-size: 13px; }
.cx-err { color: var(--err, #f85149); font-size: 13px; overflow-wrap: anywhere; }
.cx-hint { font-size: 12px; margin: 0; }
.cx-row[hidden], .cx-hint[hidden] { display: none; }
.cx-row select { width: 100%; font-weight: normal; }
.cx-quick { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; font-size: 12.5px; }
.cx-chip { background: var(--card2); border: 1px solid var(--border); border-radius: 999px; color: var(--text);
  font: inherit; font-size: 12.5px; padding: 3px 10px; cursor: pointer; }
.cx-chip:hover { border-color: var(--muted); }
/* ---- model-access rows: one visual language for every "what the chat
     can access" control (the Connectors built-in tools, the project tool
     overrides, the chat context panel). A row = a name, a one-line
     description of what the model can do, and a control (a real switch, or
     the Inherit/On/Off tri-state for per-project overrides). ---- */
.acr { display: flex; align-items: flex-start; gap: 10px; padding: 10px 12px;
  border: 1px solid var(--border2); border-radius: 8px; margin-bottom: 8px;
  background: var(--card2); font-size: 13px; }
.acr-text { min-width: 0; }
.acr-text strong { font-size: 13px; }
.acr-desc { font-size: 12px; color: var(--muted); margin-top: 2px; line-height: 1.45; }
/* A switch (styled checkbox — keyboard-accessible, it IS a checkbox). */
.switch { position: relative; display: inline-block; width: 34px; height: 20px; flex: none; margin-top: 1px; }
.switch input { position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer; }
.switch .track { position: absolute; inset: 0; border-radius: 999px; background: var(--card);
  border: 1px solid var(--border); transition: background .15s, border-color .15s; pointer-events: none; }
.switch .thumb { position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 999px;
  background: var(--muted); transition: transform .15s, background .15s; pointer-events: none; }
.switch input:checked ~ .track { background: color-mix(in srgb, var(--primary) 18%, transparent); border-color: var(--primary); }
.switch input:checked ~ .thumb { transform: translateX(14px); background: var(--primary); }
.switch input:focus-visible ~ .track { outline: 2px solid var(--primary); outline-offset: 2px; }
/* Tri-state segmented control: inherit your personal setting / on / off. */
.seg { display: inline-flex; flex: none; border: 1px solid var(--border); border-radius: 8px;
  overflow: hidden; background: var(--card); }
.seg label { position: relative; }
.seg input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.seg span { display: block; padding: 3.5px 10px; font-size: 12px; font-weight: 600; color: var(--muted);
  border-left: 1px solid var(--border2); transition: background .1s, color .1s; pointer-events: none; white-space: nowrap; }
.seg label:first-child span { border-left: 0; }
.seg input:checked + span { background: color-mix(in srgb, var(--primary) 14%, transparent); color: var(--primary-h, var(--primary)); }
.seg input:focus-visible + span { outline: 2px solid var(--primary); outline-offset: -2px; }
/* Context-panel tool rows: name over description, state pill on the right. */
.ctx-tool { display: flex; flex-direction: column; gap: 1px; flex: 1; min-width: 0; }
.ctx-desc { font-size: 11.5px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---- Business links page ---- */
.links-list { display: flex; flex-direction: column; gap: 8px; }
.link-row { display: flex; align-items: flex-start; gap: 12px; padding: 12px 14px; }
.link-main { min-width: 0; flex: 1; }
.link-title { font-weight: 600; font-size: 14px; }
.link-url { font-size: 12px; word-break: break-all; margin-top: 2px; }
.link-note { font-size: 12.5px; margin-top: 4px; }
.link-actions { display: flex; gap: 6px; flex: none; }
.lf-grid { display: grid; grid-template-columns: 70px 1fr; gap: 8px 10px; align-items: center; }
.lf-grid label { font-size: 12.5px; color: var(--muted); }
.lf-actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 12px; }

/* ---- Business documents page ---- */
.bd-wrap { display: flex; flex-direction: column; gap: 14px; }
.bd-biz-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.bd-biz-head h2 { flex: 1; font-size: 15px; color: var(--fg); margin: 0; }
.bd-docs { display: flex; flex-direction: column; gap: 4px; }
.bd-doc { display: flex; align-items: baseline; gap: 10px; padding: 6px 8px; border-radius: 6px; }
.bd-doc:hover { background: var(--card2); }
.bd-doc-title { font-size: 13.5px; }
.bd-doc-meta { font-size: 11.5px; }
.cx-find { border-top: 1px solid var(--border2); margin-top: 12px; padding-top: 10px; font-size: 13px; }
.cx-find p { margin: 4px 0 6px; font-size: 12.5px; }
.cx-dirs { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 3px; }
.cx-tools { margin: 4px 0 0; padding-left: 18px; font-size: 12.5px; max-height: 180px; overflow: auto; }
.composer-hint {
  text-align: center; font-size: 11px; color: var(--muted);
  margin: 8px 0 0; opacity: .8;
}

.session-list { list-style: none; margin: 0; padding: 0; }
.session-list li {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px; border: 1px solid var(--border2); border-radius: var(--radius-s);
  margin-bottom: 8px; cursor: pointer;
}
.session-list li:hover { background: var(--card2); border-color: var(--border); }
.session-list .s-title { flex: 1; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.session-list .s-meta { color: var(--muted); font-size: 12px; white-space: nowrap; }
.session-list .s-actions { display: flex; gap: 4px; opacity: 0; }
.session-list li:hover .s-actions { opacity: 1; }

@media (max-width: 720px) {
  .hamburger {
    display: flex; position: static;
    width: 36px; height: 36px; align-items: center; justify-content: center;
    background: none; border: 1px solid var(--border);
    border-radius: var(--radius-s); font-size: 17px; cursor: pointer;
    color: var(--text); flex-shrink: 0;
  }
  .chat-head .hamburger, .page-head .hamburger { display: flex; }
  .backdrop {
    display: none; position: fixed; inset: 0; z-index: 55;
    background: rgba(0,0,0,.55);
  }
  .backdrop.show { display: block; }
  .sidebar {
    position: fixed; left: 0; top: 0; z-index: 58;
    width: min(290px, 86vw);
    padding-top: env(safe-area-inset-top);
    transform: translateX(-100%); transition: transform .2s ease;
    box-shadow: 4px 0 16px rgba(0,0,0,.4);
  }
  .sidebar.open { transform: translateX(0); }
  .sidebar-footer { padding-bottom: max(10px, env(safe-area-inset-bottom)); }
  .nav-item { padding: 11px 10px; }
  .nav-section { padding: 14px 10px 6px; }
  body.drawer-open { overflow: hidden; }
  .chat-main { height: 100vh; padding-top: 0; }
  .chat-head { padding: 8px 10px; gap: 8px; flex-wrap: wrap; }
  body.chatpage .chat-head { order: -1; }
  .msg { max-width: 92%; }
  .page { padding: 14px; }
  .page-head { flex-wrap: wrap; }
  .statgrid { grid-template-columns: repeat(2, 1fr); }
  table { font-size: 12.5px; }
}

@media (min-width: 721px) {
  .hamburger, .backdrop { display: none !important; }
}

/* capability badges (Models, Routing) */
.capbs { display: inline-flex; flex-wrap: wrap; gap: 4px; vertical-align: middle; }
.capb { font-size: 11px; line-height: 1; padding: 3px 7px; border-radius: 999px; border: 1px solid var(--border); color: var(--muted); background: var(--card2); white-space: nowrap; }
.capb.strong { color: var(--brand); border-color: color-mix(in srgb, var(--brand) 45%, transparent); }
.capb.guess { border-style: dashed; }

/* ---- vault (at-rest encryption) unlock modal + settings status ---- */
.vlt-overlay { position: fixed; inset: 0; z-index: 9999; display: flex; align-items: center; justify-content: center; background: color-mix(in srgb, #000 55%, transparent); }
.vlt-card { background: var(--card); border: 1px solid var(--border); border-radius: 12px; padding: 18px 20px; width: min(400px, 92vw); box-shadow: 0 12px 40px rgba(0,0,0,.35); }
.vlt-card h3 { margin: 0 0 6px; font-size: 15px; }
.vlt-sub { font-size: 12.5px; color: var(--muted); margin: 0 0 12px; line-height: 1.45; }
.vlt-card input { width: 100%; padding: 8px 10px; border-radius: 8px; border: 1px solid var(--border); background: var(--card2); color: var(--text); font-size: 14px; }
.vlt-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 12px; }
.vlt-err { color: var(--danger, #d33); font-size: 12.5px; margin-top: 10px; }

/* ---- ShareBox: the unified sharing dialog (docs/fr3-share-ui.md) ---- */
.share-overlay { position: fixed; inset: 0; z-index: 9999; display: flex; align-items: center; justify-content: center; background: color-mix(in srgb, #000 55%, transparent); }
.share-card { background: var(--card); border: 1px solid var(--border); border-radius: 12px; padding: 18px 20px; width: min(460px, 94vw); box-shadow: 0 12px 40px rgba(0,0,0,.35); }
.share-card h3 { margin: 0 0 6px; font-size: 15px; }
.share-sub { font-size: 12.5px; color: var(--muted); margin: 0 0 12px; line-height: 1.45; }
.share-list { display: flex; flex-direction: column; gap: 6px; margin-bottom: 12px; }
.share-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 6px 8px; border: 1px solid var(--border); border-radius: 8px; background: var(--card2); }
.share-user { font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.share-ctl { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.share-tag { font-size: 11.5px; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.share-role { font-size: 12.5px; padding: 4px 6px; border-radius: 6px; border: 1px solid var(--border); background: var(--card); color: var(--text); }
.share-add { display: flex; gap: 6px; margin-top: 4px; }
.share-add input { flex: 1; min-width: 0; padding: 7px 9px; border-radius: 8px; border: 1px solid var(--border); background: var(--card2); color: var(--text); font-size: 13.5px; }
.share-add select { font-size: 12.5px; padding: 4px 6px; border-radius: 6px; border: 1px solid var(--border); background: var(--card); color: var(--text); }
.share-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 14px; }
.share-err { color: var(--danger, #d33); font-size: 12.5px; margin: 10px 0; }

/* ---- Files: the shared file store component (static/files.js, docs/files-ui.md) ---- */
.files-comp { background: var(--card); border: 1px solid var(--border); border-radius: 10px; padding: 14px 16px; }
.files-comp-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.files-title { margin: 0; font-size: 14.5px; }
.files-badges { display: inline-flex; gap: 4px; align-items: center; }
.files-badge { font-size: 11px; color: var(--muted); border: 1px solid var(--border); border-radius: 999px; padding: 1px 8px; background: var(--card2); white-space: nowrap; }
.files-badge.sm { font-size: 10.5px; padding: 0 6px; }
.files-count { font-size: 12px; white-space: nowrap; }
.files-list { display: flex; flex-direction: column; gap: 6px; }
.files-list-empty { padding: 10px 8px; border: 1px dashed var(--border); border-radius: 8px; }
.files-list.drop-active { outline: 2px dashed var(--primary); outline-offset: 2px; }
.files-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 7px 9px; border: 1px solid var(--border); border-radius: 8px; background: var(--card2); }
.files-row-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.files-row-main .files-badge { align-self: flex-start; }
.files-name { font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.files-meta { font-size: 11.5px; }
.files-row-acts { display: flex; gap: 6px; flex-shrink: 0; }
.files-state { font-size: 13px; padding: 10px 4px; display: flex; align-items: center; gap: 10px; }
.files-state-err { color: var(--danger, #d33); }
.files-foot { font-size: 12px; margin: 10px 0 0; line-height: 1.4; }
.files-flash { font-size: 12.5px; padding: 7px 10px; border-radius: 8px; margin-bottom: 10px; }
.files-flash.ok { color: var(--primary); background: color-mix(in srgb, var(--primary) 12%, transparent); }
.files-flash.err { color: var(--danger, #d33); background: color-mix(in srgb, var(--danger, #d33) 12%, transparent); }

/* S1.2 document semantics: the tree view (folders nest; unfiled files under
   the virtual Inbox), the Tree/All view toggle, and the class/origin badges
   that tag each file (the S1.7 viewer layer will render them). */
.files-viewtoggle { display: inline-flex; gap: 4px; align-items: center; }
.files-viewbtn.active { background: var(--primary); color: var(--on-primary); border-color: var(--primary); }
.files-tree { display: flex; flex-direction: column; gap: 4px; }
/* A collapsible folder (a path segment). Folders nest; each level indents
   via the body's left padding (cumulative, so deeper folders nest further). */
.files-folder { margin-left: 0; }
.files-folder-head { display: flex; align-items: center; gap: 6px; padding: 5px 9px; border: 1px solid var(--border); border-radius: 8px; background: var(--card); cursor: pointer; user-select: none; }
.files-folder-head:hover { border-color: var(--primary); }
.files-caret { display: inline-block; width: 10px; text-align: center; color: var(--muted); font-size: 11px; }
.files-folder-head .files-caret::before { content: '\25B8'; }       /* collapsed */
.files-folder-head.open .files-caret::before { content: '\25BE'; }   /* expanded */
.files-folder-name { font-size: 13px; font-weight: 600; }
.files-folder-count { font-size: 11px; margin-left: auto; }
.files-folder-body { display: flex; flex-direction: column; gap: 4px; margin: 2px 0 0 12px; padding-left: 12px; border-left: 1px solid var(--border); }
.files-folder-body.collapsed { display: none; }
/* The document class icon on a file name + the class/origin badges. */
.files-class-icon { font-size: 12px; opacity: .85; }
.files-badge.files-class { background: var(--card); }
.files-badge.files-origin { background: var(--card2); }
/* S1.7: an openable file's name is a link-styled affordance. */
.files-row-openable .files-name { color: var(--primary); cursor: pointer; }
.files-row-openable .files-name:hover { text-decoration: underline; }

/* S1.7 viewer layer ("anything that can be shown, should be"): a full-screen
   overlay (a real page-level modal, not a page component). Styles are
   token-based (the S4.4 re-skin restyles them with the rest of the app). */
.viewer-overlay { position: fixed; inset: 0; z-index: 300; display: flex; align-items: center;
  justify-content: center; background: color-mix(in srgb, #000 62%, transparent); padding: 18px; }
.viewer-panel { width: 100%; max-width: 1100px; height: 100%; max-height: calc(100dvh - 36px);
  display: flex; flex-direction: column; background: var(--card);
  border: 1px solid var(--border); border-radius: 12px; box-shadow: var(--shadow); overflow: hidden; }
.viewer-head { display: flex; align-items: center; gap: 10px; padding: 10px 14px;
  border-bottom: 1px solid var(--border); background: var(--card2); flex-shrink: 0; }
.viewer-title { font-size: 14px; font-weight: 600; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; min-width: 0; flex: 1; }
.viewer-size { font-size: 11.5px; }
.viewer-body { flex: 1; min-height: 0; overflow: auto; padding: 12px 14px; display: flex;
  flex-direction: column; gap: 10px; }
.viewer-foot { display: flex; align-items: center; gap: 8px; padding: 10px 14px;
  border-top: 1px solid var(--border); background: var(--card2); flex-shrink: 0; }
.viewer-status { font-size: 12px; }
.viewer-status.err { color: var(--danger); }
.viewer-state { font-size: 13px; padding: 18px 6px; }
.viewer-state-err { color: var(--danger); }
.viewer-note { font-size: 12px; color: var(--muted); }
.viewer-toolbar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.viewer-json-err { color: var(--warn); }
.viewer-toggle { display: inline-flex; gap: 4px; }
.viewer-toggle .btn.active { background: var(--primary); color: var(--on-primary); border-color: var(--primary); }
/* image: a scrollable stage (drag-to-pan via native scroll) + the zoom bar. */
.viewer-zoombar { display: flex; gap: 6px; }
.viewer-stage { flex: 1; min-height: 200px; overflow: auto; background:
  repeating-conic-gradient(color-mix(in srgb, var(--text) 6%, transparent) 0% 25%,
  color-mix(in srgb, var(--text) 3%, transparent) 0% 50%) 0 0 / 24px 24px;
  border: 1px solid var(--border); border-radius: 8px; }
.viewer-stage-inner { min-width: 100%; min-height: 100%; display: flex; align-items: center;
  justify-content: center; padding: 14px; box-sizing: border-box; }
.viewer-img { max-width: none; box-shadow: var(--shadow); background: #fff; }
/* G6 image toolset (canEdit only): the toolbar row above the stage, the
   live edit canvas, and the small form controls (width % / color /
   thickness). Non-editors render none of this — just the zoom bar + img. */
.viewer-imgtools { padding-top: 2px; }
.viewer-imgc { touch-action: none; }            /* the pen draws, not pans */
.viewer-imgres, .viewer-imgthick { width: 62px; }
.viewer-imgcolor { width: 30px; height: 22px; padding: 1px; cursor: pointer; }
.viewer-imgres, .viewer-imgthick, .viewer-imgcolor {
  font: inherit; font-size: 12.5px; padding: 3px 5px; box-sizing: border-box;
  border: 1px solid var(--border); border-radius: 6px; background: var(--card2);
  color: var(--text); }
.viewer-ink .btn.active { background: var(--primary); color: var(--on-primary);
  border-color: var(--primary); }
/* pdf: the browser's native paged viewer. */
.viewer-pdf { flex: 1; min-height: 420px; width: 100%; border: 1px solid var(--border);
  border-radius: 8px; background: #fff; }
/* sheet: a bordered table (the grid); the editing variant makes cells
   contenteditable (the browser's outline signals the editable state). */
.viewer-table-wrap { flex: 1; overflow: auto; border: 1px solid var(--border); border-radius: 8px; }
.viewer-table { border-collapse: collapse; font-size: 12.5px; font-variant-numeric: tabular-nums; }
.viewer-table th, .viewer-table td { border-right: 1px solid var(--border);
  border-bottom: 1px solid var(--border); padding: 4px 8px; white-space: nowrap; }
.viewer-table th { position: sticky; top: 0; background: var(--card2); font-weight: 600;
  text-align: left; }
.viewer-table tbody tr:hover td { background: color-mix(in srgb, var(--primary) 6%, transparent); }
.viewer-table.editing td { white-space: pre-wrap; min-width: 90px; cursor: text; }
.viewer-table.editing td[contenteditable]:focus { outline: 2px solid var(--primary);
  outline-offset: -2px; background: color-mix(in srgb, var(--primary) 10%, transparent); }
/* text: a pre (capped) + the markdown preview (the .md styles are the shared
   renderer's, loaded with markdown.js where present). */
.viewer-pre { margin: 0; padding: 10px 12px; font-size: 12.5px; line-height: 1.5;
  white-space: pre-wrap; word-break: break-word; font-family: ui-monospace, SFMono-Regular,
  Menlo, Consolas, monospace; background: var(--card2); border: 1px solid var(--border);
  border-radius: 8px; overflow: auto; max-height: 60vh; }
.viewer-json-edit { flex: 1; min-height: 240px; width: 100%; box-sizing: border-box; resize: vertical;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12.5px;
  line-height: 1.5; padding: 10px 12px; color: var(--text); background: var(--card2);
  border: 1px solid var(--border); border-radius: 8px; }
.viewer-json-edit:focus { outline: 2px solid var(--primary); outline-offset: -1px; }
/* G4: the pane's History affordance — an inline revision timeline under the
   body (seq · size · time + an author badge), toggled from the foot. */
.viewer-history { display: flex; flex-direction: column; gap: 4px;
  padding: 8px 10px; font-size: 12px; background: var(--card2);
  border: 1px solid var(--border); border-radius: 8px; }
.viewer-hist-head { font-size: 11px; font-weight: 600; letter-spacing: .02em;
  text-transform: uppercase; }
.viewer-hist-list { display: flex; flex-direction: column; gap: 4px; }
.viewer-hist-row { display: flex; align-items: center; gap: 8px; }
.viewer-hist-seq { font-weight: 600; font-variant-numeric: tabular-nums; }
.viewer-hist-time { margin-left: auto; }
@media (max-width: 640px) {
  .viewer-overlay { padding: 0; }
  .viewer-panel { max-width: none; max-height: 100dvh; height: 100%; border-radius: 0;
    border: 0; }
}

/* ---- unified workspace (project home + tabbed workspace) ---- */
/* Toasts (shared; created by app.js toast()). Bottom-right, transient. */
#toasts { position: fixed; right: 18px; bottom: 18px; z-index: 200; display: flex; flex-direction: column; gap: 8px; pointer-events: none; }
.toast { pointer-events: auto; cursor: default; font-size: 13.5px; padding: 10px 14px; border-radius: 9px;
  border: 1px solid var(--border); background: var(--card); box-shadow: var(--shadow);
  color: var(--text); max-width: 360px; opacity: 0; transform: translateY(8px); transition: all .2s ease; }
.toast.in { opacity: 1; transform: none; }
.toast.out { opacity: 0; transform: translateY(8px); }
.toast.ok { border-color: color-mix(in srgb, var(--primary) 45%, transparent); }
.toast.ok::before { content: "✓ "; color: var(--primary); font-weight: 700; }
.toast.err { border-color: color-mix(in srgb, var(--danger) 45%, transparent); }
.toast.err::before { content: "⚠ "; color: var(--danger); font-weight: 700; }

/* The tabbed workspace fills the viewport (like chat): no page padding/scroll. */
.page.workspace { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow: hidden;
  padding: 0; margin: 0; max-width: none; height: 100dvh; }
body.ws { overflow: hidden; }
body.ws .main { height: 100dvh; }
.ws-head { display: flex; align-items: center; gap: 12px; padding: 10px 16px; border-bottom: 1px solid var(--border);
  background: var(--card); flex-shrink: 0; }
.ws-head .ws-title { display: flex; align-items: center; gap: 9px; min-width: 0; }
.ws-head .ws-title h1 { font-size: 16px; margin: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ws-head .ws-mark { color: var(--brand); display: inline-flex; }
/* The project switcher in the workspace header (a real <select>, styled to
   match the header buttons). */
.ws-switcher { font: inherit; font-size: 13px; font-weight: 600; color: var(--text); padding: 5px 9px;
  border-radius: 8px; border: 1px solid var(--border); background: var(--card2); max-width: 200px; }
.ws-tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--border); background: var(--card);
  padding: 0 12px; flex-shrink: 0; overflow-x: auto; }
.ws-tab { appearance: none; background: none; border: 0; border-bottom: 2px solid transparent; cursor: pointer;
  font: inherit; font-size: 13.5px; color: var(--muted); padding: 9px 12px; display: inline-flex; align-items: center; gap: 7px;
  white-space: nowrap; }
.ws-tab:hover { color: var(--text); }
.ws-tab[aria-selected="true"] { color: var(--text); border-bottom-color: var(--primary); }
.ws-tab .ws-n { font-size: 11px; color: var(--muted); }
.ws-tab[aria-selected="true"] .ws-n { color: var(--primary); }
.ws-body { flex: 1; min-height: 0; display: flex; }
.ws-panel { display: none; }
.ws-panel.active { display: flex; flex: 1; min-width: 0; min-height: 0; flex-direction: column; overflow: hidden; }
/* chat tab: the chat shell is mounted natively (no iframe) and fills the
   panel. The panel is the containing block, so the shell's 100dvh becomes
   "fill the panel" and the mobile drawers/backdrop stay inside it. */
.ws-panel.ws-chatpanel { position: relative; }
.ws-panel.ws-chatpanel .chat-shell { flex: 1; min-height: 0; height: auto; }
.ws-panel.ws-chatpanel .chat-main { height: 100%; min-height: 0; }
/* The chat shell's hamburger only toggles the app sidebar (absent here); the
   conversation drawer opens via the "Chats" button instead. */
.ws-chatpanel .chat-head .hamburger { display: none; }
/* The workspace header already shows the project; the per-group
   "Workspace →" label in the drawer would just re-load this same page. */
.ws-chatpanel .convo-ws { display: none; }
/* The workspace back link (focused surface: no app sidebar to go back through). */
.ws-back { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px;
  border-radius: 8px; border: 1px solid var(--border); background: var(--card2); color: var(--muted);
  font-size: 15px; line-height: 1; text-decoration: none; flex-shrink: 0; }
.ws-back:hover { color: var(--text); border-color: var(--muted); text-decoration: none; }
/* generic scroll panels inside the workspace (docs/mems/settings/overview) */
.ws-scroll { flex: 1; overflow-y: auto; padding: 16px 20px 40px; max-width: 860px; width: 100%; margin: 0 auto; box-sizing: border-box; }
.ws-empty { padding: 26px; text-align: center; color: var(--muted); font-size: 13.5px; }

/* Overview: the at-a-glance card */
.ov-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; }
.ov-stat { border: 1px solid var(--border); background: var(--card); border-radius: 10px; padding: 12px 14px; }
.ov-stat .ov-v { font-size: 22px; font-weight: 650; }
.ov-stat .ov-l { font-size: 12px; color: var(--muted); margin-top: 2px; }
.ov-ident { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border: 1px solid var(--border);
  border-radius: 10px; background: var(--card); }
.ov-ident .oi-name { font-size: 14.5px; font-weight: 600; }
.ov-ident .oi-sub { font-size: 12px; color: var(--muted); }
.ov-sec { margin-top: 20px; }
.ov-sec h3 { font-size: 12px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); margin: 0 0 8px; }
.ov-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 9px 12px;
  border: 1px solid var(--border); border-radius: 8px; background: var(--card2); margin: 6px 0; font-size: 13.5px; text-decoration: none; color: var(--text); }
a.ov-row:hover { border-color: var(--muted); }
.ov-row .muted { font-size: 12px; }

/* Settings tab reuses the card look */
.ws-card { border: 1px solid var(--border); border-radius: 10px; background: var(--card); padding: 14px 16px; margin-top: 14px; }
.ws-card h2 { font-size: 15px; margin: 0 0 2px; }
.ws-card .sub { font-size: 12.5px; color: var(--muted); margin: 0 0 12px; }

/* Documents: sidebar (Files | Web sources) + detail pane. */
.docs-split { display: grid; grid-template-columns: 260px minmax(0, 1fr); gap: 14px; margin-top: 6px; }
.docs-side { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.docs-side-group { display: flex; flex-direction: column; gap: 4px; }
.docs-side-h { display: flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600;
  text-transform: none; color: var(--muted); margin: 0; }
.docs-side-h svg { flex-shrink: 0; opacity: .8; }
.docs-side-n { margin-left: auto; font-weight: 400; opacity: .8; }
.docs-side-list { display: flex; flex-direction: column; gap: 3px; max-height: 42vh; overflow: auto; }
.docs-side-empty { font-size: 12px; color: var(--muted); padding: 4px 2px; }
.docs-side-item { display: flex; flex-direction: column; gap: 1px; text-align: left; width: 100%;
  border: 1px solid transparent; border-radius: 8px; background: transparent; color: var(--text);
  padding: 7px 9px; cursor: pointer; font: inherit; }
.docs-side-item:hover { background: var(--card2); }
.docs-side-item.on { border-color: var(--border); background: var(--card2); }
.dsi-name { font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dsi-meta { font-size: 11px; color: var(--muted); }
.dsi-url { font-size: 11px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dsi-kind { display: inline-block; font-size: 9.5px; font-weight: 700; letter-spacing: .04em;
  border: 1px solid var(--border); border-radius: 999px; padding: 0 5px; margin-left: 4px;
  color: var(--muted); background: var(--card); vertical-align: 1px; flex-shrink: 0; }
.docs-main { min-width: 0; }
.docs-detail { border: 1px solid var(--border); border-radius: 8px; background: var(--bg); padding: 12px 14px; min-height: 120px; }
.docs-detail-head { display: flex; align-items: flex-start; gap: 10px; justify-content: space-between; }
.docs-detail-title { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.docs-detail-title strong { font-size: 14px; word-break: break-word; }
.docs-detail-actions { display: flex; gap: 6px; flex-shrink: 0; }
.docs-detail-url { font-size: 11.5px; margin: 6px 0 0; word-break: break-all; }
.docs-text { margin: 10px 0 0; font-size: 12.5px; line-height: 1.5; white-space: pre-wrap; word-break: break-word;
  max-height: 46vh; overflow: auto; font-family: var(--mono, ui-monospace, monospace); }
@media (max-width: 900px) { .docs-split { grid-template-columns: 1fr; } }
/* The documents panel uses a split layout; give it more room than the
   default 860px reading column. */
#panel-documents .ws-scroll { max-width: 1080px; }
.memform { display: flex; flex-direction: column; gap: 8px; margin-bottom: 6px; }
.memform textarea, .memform input { width: 100%; resize: vertical; min-height: 56px; max-height: 200px;
  font: inherit; padding: 9px 11px; border-radius: 8px; border: 1px solid var(--border); background: var(--card2); color: var(--text); }
.memform input { min-height: 0; }
#status { font-size: 13px; min-height: 18px; }
.empty { padding: 16px; text-align: center; color: var(--muted); }
.btn.small { padding: 4px 10px; font-size: 12.5px; }
.btn.danger { color: var(--danger); border-color: var(--danger); }
.btn.danger:hover { background: color-mix(in srgb, var(--danger) 12%, transparent); }
.toolrow { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text); margin-right: 16px; }
#ctxText { font-size: 13.5px; line-height: 1.6; background: var(--card2); border: 1px solid var(--border);
  border-radius: 8px; padding: 10px 12px; white-space: pre-wrap; max-height: 220px; overflow: auto; }
.ctxrow { display: flex; align-items: center; gap: 10px; margin-top: 10px; flex-wrap: wrap; }
.ctxrow label { font-size: 13px; display: inline-flex; align-items: center; gap: 6px; }
.tools-note { font-size: 12px; color: var(--muted); margin-top: 8px; }
.danger-zone { border-color: color-mix(in srgb, var(--danger) 40%, transparent); }
.danger-zone h2 { color: var(--danger); }

/* ---- projects home (the grid you switch between) ---- */
.proj-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 12px; margin-top: 14px; }
.proj-card { display: block; border: 1px solid var(--border); border-radius: 12px; background: var(--card);
  padding: 14px 16px; text-decoration: none; color: var(--text); transition: border-color .12s, transform .12s; }
.proj-card:hover { border-color: var(--muted); transform: translateY(-1px); }
.proj-card .pc-name { font-size: 15px; font-weight: 650; display: flex; align-items: center; gap: 8px; }
.proj-card .pc-name svg { color: var(--brand); }
.proj-card .pc-sys { font-size: 12.5px; color: var(--muted); margin-top: 6px; min-height: 18px;
  overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.proj-card .pc-meta { display: flex; gap: 12px; margin-top: 12px; font-size: 12px; color: var(--muted); }
.proj-card .pc-meta b { color: var(--text); font-weight: 600; }
.proj-create { margin-top: 16px; display: flex; gap: 10px; align-items: flex-start; border: 1px solid var(--border);
  border-radius: 10px; background: var(--card); padding: 12px 14px; }
.proj-create .pc-fields { flex: 1; display: flex; flex-direction: column; gap: 8px; }
.proj-create input, .proj-create textarea { font: inherit; padding: 8px 10px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--card2); color: var(--text); resize: vertical; min-height: 44px; }
.proj-create input { min-height: 0; }

/* ---- notes page: the private notes app (static/notes.js) ---- */
.notes-toolbar { display: flex; flex-direction: column; gap: 6px; margin-bottom: 16px; }
.notes-toolbar h1 { margin: 0; display: flex; align-items: baseline; gap: 10px; }
.notes-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 6px; }
.notes-actions textarea { width: 100%; min-height: 90px; margin-top: 2px; font: inherit;
  font-size: 13px; padding: 8px 10px; border-radius: 8px; border: 1px solid var(--border);
  background: var(--card2); color: var(--text); resize: vertical; }
.notes-flash { margin-top: 8px; font-size: 13px; padding: 8px 12px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--card2); }
.notes-flash.ok { border-color: color-mix(in srgb, var(--primary) 50%, transparent); }
.notes-flash.err { border-color: color-mix(in srgb, var(--danger) 50%, transparent); color: var(--danger); }
.notes-layout { display: grid; grid-template-columns: 280px minmax(0, 1fr); gap: 14px; align-items: start; }
.notes-list { border: 1px solid var(--border); border-radius: 10px; background: var(--card);
  padding: 10px 12px; display: flex; flex-direction: column; gap: 8px; }
.notes-search { font: inherit; padding: 7px 10px; border-radius: 8px; border: 1px solid var(--border);
  background: var(--card2); color: var(--text); }
.groups-section { display: flex; flex-direction: column; gap: 6px; padding-bottom: 8px;
  border-bottom: 1px solid var(--border2); }
.groups-head { display: flex; align-items: center; justify-content: space-between; }
.groups-head span { font-size: 11px; text-transform: uppercase; letter-spacing: .5px; color: var(--muted); }
.groups-tree { display: flex; flex-direction: column; gap: 2px; max-height: 34vh; overflow: auto; }
.group-row { display: flex; align-items: center; gap: 4px; padding: 5px 8px; border-radius: 8px;
  cursor: pointer; border: 1px solid transparent; font: inherit; font-size: 13px;
  background: transparent; color: var(--text); width: 100%; text-align: left; }
.group-row:hover { background: var(--card2); }
.group-row.on { border-color: var(--border); background: var(--card2); }
.group-row .g-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.group-row .g-count { font-size: 11px; color: var(--muted); }
.group-row .g-actions { display: none; gap: 2px; }
.group-row:hover .g-actions { display: flex; }
.group-row .g-actions button { border: none; background: transparent; cursor: pointer;
  font-size: 11px; padding: 1px 4px; border-radius: 4px; color: var(--muted); font-family: inherit; }
.group-row .g-actions button:hover { background: var(--card); color: var(--text); }
.note-group-select { font: inherit; font-size: 12.5px; padding: 4px 8px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--card2); color: var(--text); max-width: 220px; }
.notes-items { display: flex; flex-direction: column; gap: 4px; max-height: 60vh; overflow: auto; }
/* Multi-select bar: shows while one or more notes are selected. */
.notes-bulk { display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  padding: 6px 8px; border: 1px solid var(--border); border-radius: 8px; background: var(--card2); }
.notes-bulk .note-group-select { max-width: 150px; flex: 1; }
.notes-item { text-align: left; border: 1px solid transparent; border-radius: 8px; background: transparent;
  padding: 8px 10px; cursor: pointer; color: var(--text); font: inherit; display: flex; align-items: center;
  gap: 8px; width: 100%; }
.notes-item:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.notes-item:hover { background: var(--card2); }
.notes-item.on { border-color: var(--border); background: var(--card2); }
.notes-item .ni-check { display: flex; align-items: center; flex-shrink: 0; cursor: pointer; padding: 2px 0; }
.notes-item .ni-check input { margin: 0; accent-color: var(--primary); cursor: pointer; }
.notes-item .ni-body { flex: 1; min-width: 0; }
.notes-item .ni-title { font-size: 13.5px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.notes-item .ni-snippet { font-size: 12px; color: var(--muted); margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.notes-item .ni-date { font-size: 11px; color: var(--muted); margin-top: 3px; }
.notes-empty, .notes-foot { font-size: 12px; margin: 4px 0; }
.notes-editor { border: 1px solid var(--border); border-radius: 10px; background: var(--card);
  padding: 12px 14px; display: flex; flex-direction: column; gap: 10px; min-height: 60vh; }
.notes-editor-head { display: flex; gap: 10px; align-items: center; }
#noteTitle { flex: 1; font: inherit; font-weight: 600; font-size: 15px; padding: 7px 10px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--card2); color: var(--text); }
#noteContent { flex: 1; min-height: 320px; resize: vertical; font: inherit; font-size: 14px; line-height: 1.55;
  padding: 10px 12px; border-radius: 8px; border: 1px solid var(--border); background: var(--card2); color: var(--text); }
.notes-editor-foot { display: flex; gap: 10px; align-items: center; font-size: 12px; }
.notes-locked { border: 1px solid var(--border); border-radius: 10px; background: var(--card2);
  padding: 18px 20px; margin-top: 14px; display: flex; flex-direction: column; gap: 10px; }
.notes-locked h2 { font-size: 15px; margin: 0; }
.notes-locked p { font-size: 13px; color: var(--muted); margin: 0; }
.notes-locked input { font: inherit; padding: 8px 10px; border-radius: 8px; border: 1px solid var(--border);
  background: var(--card); color: var(--text); max-width: 320px; }

/* Import panel: two columns (text/file | KeePass database) with drop zones. */
.import-panel { margin-top: 10px; border: 1px solid var(--border); border-radius: 10px;
  background: var(--card); padding: 14px; }
.import-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.import-col { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.import-h { font-size: 13.5px; font-weight: 600; margin: 0; }
.import-sub { font-size: 12px; color: var(--muted); margin: -2px 0 2px; }
.import-area { width: 100%; min-height: 96px; font: inherit; padding: 9px 11px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--bg); color: var(--text); resize: vertical; }
.import-drop { display: flex; align-items: center; gap: 8px; padding: 10px 12px; border-radius: 8px;
  border: 1px dashed var(--border); background: var(--bg); color: var(--muted); font-size: 12.5px;
  cursor: pointer; overflow: hidden; }
.import-drop:hover { border-color: var(--primary); color: var(--text); }
.import-drop svg { flex-shrink: 0; opacity: .8; }
.import-drop span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.import-drop-sm { padding: 7px 10px; }
.import-drop.on { border-style: solid; border-color: var(--primary); color: var(--text); }
.import-field { display: flex; flex-direction: column; gap: 4px; font-size: 12.5px; }
.import-field > span:first-child { color: var(--muted); }
.import-field input[type="password"] { font: inherit; padding: 8px 10px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--bg); color: var(--text); }
.import-btn { align-self: flex-start; margin-top: 2px; }
@media (max-width: 800px) {
  .notes-layout { grid-template-columns: 1fr; }
  .notes-items { max-height: 28vh; }
  .import-grid { grid-template-columns: 1fr; }
}

/* ---- Bookkeeping (light bookkeeping, /bookkeeping) ---- */
.bookkeeping-toolbar { display: flex; flex-direction: column; gap: 6px; margin-bottom: 16px; }
.bookkeeping-toolbar h1 { margin: 0; display: flex; align-items: baseline; gap: 10px; }
.bookkeeping-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 4px; }
.bookkeeping-tabs { display: flex; gap: 6px; }
/* Grouped tab UI: the group bar wraps on narrow screens; each group's
   sub-pill row (.bk-subbar) reads as a second, lighter tier under its
   group — the nested row the Reports pane's #bookkeepingReportTabs sets. */
.bookkeeping-tabs[data-role="groupbar"] { flex-wrap: wrap; }
/* A little breathing room below the group bar so the two tiers read as
   distinct (group bar = primary, sub-pills = the selected group's leaves). */
.bk-subbar { margin: 14px 0 6px; }
.bk-subbar .btn { background: none; color: var(--muted); }
.bk-subbar .btn:hover { background: var(--card2); color: var(--text); }
/* The active leaf keeps its filled primary style (the general .btn.primary
   rule above has lower specificity than the muted tier and sits earlier
   in the sheet, so it must be re-asserted here). */
.bk-subbar .btn.primary { background: var(--primary); border-color: var(--primary); color: var(--on-primary); }
.bk-subbar .btn.primary:hover { background: var(--primary-h); }
.bk-group { display: block; }
.bk-group[hidden] { display: none; }
.bookkeeping-select { max-width: 240px; }
.bookkeeping-flash { font-size: 13px; padding: 8px 12px; border-radius: 8px; margin-top: 8px; }
.bookkeeping-flash.ok { background: color-mix(in srgb, var(--primary) 14%, transparent); }
.bookkeeping-flash.err { background: color-mix(in srgb, var(--danger, #f85149) 14%, transparent); color: var(--danger, #f85149); }
.bookkeeping-pane { display: flex; flex-direction: column; gap: 10px; }
.bookkeeping-pane[hidden] { display: none; }
.bookkeeping-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.bookkeeping-entries { display: flex; flex-direction: column; gap: 10px; }
.bookkeeping-entry-line { display: grid; grid-template-columns: minmax(120px, 220px) 1fr auto; gap: 10px; padding: 4px 0 4px 14px; border-top: 1px dashed var(--border2); font-size: 13px; }
.bookkeeping-amt { font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }
.bookkeeping-accounts { display: flex; flex-direction: column; gap: 6px; }
.bookkeeping-type { margin: 10px 0 2px; font-size: 12px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.bookkeeping-acct { display: flex; gap: 8px; align-items: center; padding: 8px 12px; }
.bookkeeping-tb { overflow-x: auto; }
.bookkeeping-table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.bookkeeping-table th, .bookkeeping-table td { padding: 7px 10px; border-bottom: 1px solid var(--border2); text-align: left; }
.bookkeeping-table th.bookkeeping-amt, .bookkeeping-table td.bookkeeping-amt { text-align: right; }
.bookkeeping-table tfoot th { border-top: 2px solid var(--border2); }
.bookkeeping-editor { position: fixed; inset: 0; background: color-mix(in srgb, var(--bg, #111) 55%, transparent); display: flex; align-items: flex-start; justify-content: center; padding: 6vh 16px; z-index: 60; }
.bookkeeping-editor[hidden] { display: none; }
.bookkeeping-editor-card { background: var(--card, var(--bg, #1a1a1a)); border: 1px solid var(--border2); border-radius: 12px; padding: 16px; width: min(760px, 100%); max-height: 86vh; overflow: auto; }
.bookkeeping-line select { max-width: 220px; }
.bookkeeping-balance { font-size: 12.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.bookkeeping-balance.unbalanced { color: var(--danger, #f85149); }
.bookkeeping-check { display: flex; gap: 6px; align-items: center; font-size: 13px; }
/* Dashboard stat cards. */
.bookkeeping-dash { display: flex; gap: 10px; flex-wrap: wrap; }
.bookkeeping-dash .bookkeeping-stat { flex: 1 1 150px; }
.bookkeeping-stat { background: var(--card, var(--bg, #1a1a1a)); border: 1px solid var(--border2); border-radius: 10px; padding: 12px 14px; }
.bookkeeping-stat h3 { margin: 0 0 4px; font-size: 12px; font-weight: 500; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.bookkeeping-stat .num { font-size: 20px; font-weight: 600; font-variant-numeric: tabular-nums; }
/* Reconcile tab (B2): the difference card while non-zero (the ticks must
   close the gap before the statement can be closed) + the checked tick
   labels on the cleared-line table (a writer can untick to reopen). */
.bookkeeping-recon-diff { border-color: color-mix(in srgb, var(--danger, #f85149) 45%, var(--border2)); }
.bookkeeping-recon-diff h3 { color: var(--danger, #f85149); }
.bookkeeping-recon-diff .num { color: var(--danger, #f85149); }
.bookkeeping-recon-cleared { color: var(--muted); }
/* Generic row list (customers, vendors, invoices, bills). */
.bookkeeping-list { display: flex; flex-direction: column; gap: 8px; }
.bookkeeping-listrow { display: flex; gap: 10px; align-items: center; padding: 8px 12px; }
.bookkeeping-listrow > .name { font-weight: 500; }
.bookkeeping-listrow .muted { margin-left: 0; }
.bookkeeping-status { font-size: 11.5px; padding: 2px 8px; border-radius: 999px; background: var(--border2); color: var(--muted); }
.bookkeeping-status.paid, .bookkeeping-status.cleared { background: color-mix(in srgb, var(--primary) 18%, transparent); color: var(--chart-1); }
.bookkeeping-status.partial, .bookkeeping-status.pending { background: color-mix(in srgb, var(--warn) 18%, transparent); color: var(--warn); }
.bookkeeping-status.overdue, .bookkeeping-status.cancelled, .bookkeeping-status.failed { background: color-mix(in srgb, var(--danger, #f85149) 18%, transparent); color: var(--danger, #f85149); }
/* Import preview. */
.bookkeeping-import-preview { display: flex; flex-direction: column; gap: 8px; }
.bookkeeping-import-table { font-size: 12.5px; }
.bookkeeping-import-table td, .bookkeeping-import-table th { padding: 4px 8px; }
.bookkeeping-err { color: var(--danger, #f85149); }

/* Receipts strip + Files tab chips (docs/bookkeeping-files-plan.md C2).
   Chips mirror the msg-attachment chip shape: name + size + a download link,
   and a delete × when the caller can delete (uploader or manager). */
.bookkeeping-file-list { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.bookkeeping-file-list:empty { display: none; }
.bookkeeping-file-chip { display: inline-flex; align-items: center; gap: 4px; max-width: 300px;
  padding: 4px 6px 4px 4px; border: 1px solid var(--border2); border-radius: 999px;
  background: color-mix(in srgb, var(--card, var(--bg, #1a1a1a)) 60%, transparent); font-size: 12.5px; }
.bookkeeping-file-chip-name { display: inline-flex; align-items: center; gap: 4px; max-width: 260px;
  overflow: hidden; text-decoration: none; color: inherit; }
.bookkeeping-file-chip-name:hover { color: var(--primary); }
.bookkeeping-file-chip-name > span:nth-child(2) { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bookkeeping-file-ico { font-size: 12px; }
.bookkeeping-file-chip .muted { font-size: 11px; }
.bookkeeping-file-x { border: 0; background: transparent; color: var(--muted); cursor: pointer;
  font-size: 14px; line-height: 1; padding: 2px 5px; border-radius: 999px; }
.bookkeeping-file-x:hover { color: var(--danger, #f85149); background: color-mix(in srgb, var(--danger, #f85149) 12%, transparent); }
.bookkeeping-receipts { border: 1px dashed var(--border2); border-radius: 8px; padding: 8px 10px; }
@media (max-width: 800px) {
  .bookkeeping-entry-line { grid-template-columns: 1fr auto; }
  .bookkeeping-entry-line .muted { display: none; }
}

/* ---- Msg (team messaging, /msg) ---- */
.msg-page { display: flex; gap: 14px; height: calc(100vh - 120px); min-height: 420px; }
.msg-sidebar { width: 230px; flex-shrink: 0; display: flex; flex-direction: column; border-right: 1px solid var(--border2); padding-right: 10px; }
.msg-side-head { display: flex; align-items: center; justify-content: space-between; padding: 2px 4px 8px; }
.msg-channels { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; }
.msg-side-search { padding: 0 2px 8px; }
.msg-side-search input { width: 100%; box-sizing: border-box; }
.msg-channel { display: flex; align-items: center; gap: 6px; padding: 6px 8px; border-radius: 8px; cursor: pointer; font-size: 13.5px; }
.msg-channel:hover { background: color-mix(in srgb, var(--primary) 8%, transparent); }
.msg-channel.active { background: color-mix(in srgb, var(--primary) 16%, transparent); }
.msg-channel.not-member { opacity: .65; }
.msg-channel-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.msg-badge { background: var(--border2); border-radius: 999px; font-size: 11px; padding: 1px 7px; }
.msg-badge.mention { background: color-mix(in srgb, var(--danger, #f85149) 22%, transparent); color: var(--danger, #f85149); }
/* Direct messages + Channels sections (msg D1). */
.msg-section-head { display: flex; align-items: center; justify-content: space-between; padding: 8px 4px 4px; font-size: 11.5px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted, #8b949e); }
.msg-empty-section { font-size: 12.5px; padding: 2px 8px 4px; }
/* Team sections: the team is the workspace (Slack parity). A team header
   carries the caller's team role on the right. */
.msg-team-head { padding-top: 12px; color: var(--fg, #e6edf3); font-weight: 600; }
.msg-team-role { text-transform: none; letter-spacing: 0; font-size: 10.5px; font-weight: 400; color: var(--muted, #8b949e); }
.msg-archived-notice { margin: 0 2px 6px; padding: 8px 10px; border: 1px solid var(--border2); border-radius: 8px;
  background: color-mix(in srgb, var(--muted, #8b949e) 10%, transparent); color: var(--muted, #8b949e); font-size: 12.5px; }
/* Timeline readability (Slack parity): date dividers, the unread "New" line,
   grouped consecutive messages, and the permalink highlight. */
.msg-day { display: flex; align-items: center; gap: 10px; margin: 12px 0 4px; color: var(--muted, #8b949e); font-size: 11.5px; }
.msg-day::before, .msg-day::after { content: ''; flex: 1; border-top: 1px solid var(--border2); }
.msg-newdivider { display: flex; align-items: center; gap: 10px; margin: 8px 0; color: var(--danger, #f85149); font-size: 11.5px; font-weight: 600; }
.msg-newdivider::before, .msg-newdivider::after { content: ''; flex: 1; border-top: 1px solid var(--danger, #f85149); }
.msg-grouped { padding-top: 0; }
.msg-highlight { background: color-mix(in srgb, var(--primary) 18%, transparent); transition: background .4s; }
/* Activity view: cross-channel unread + mentions, grouped by team. */
.msg-activity { flex: 1; overflow-y: auto; padding: 4px 2px; }
.msg-activity[hidden] { display: none; }
.msg-activity-head { display: flex; align-items: center; gap: 8px; padding: 6px 4px 10px; border-bottom: 1px solid var(--border2); }
.msg-activity-item { padding: 8px 10px; border-radius: 8px; cursor: pointer; }
.msg-activity-item:hover { background: color-mix(in srgb, var(--primary) 8%, transparent); }
.msg-activity-top { display: flex; align-items: center; gap: 8px; }
.msg-activity-last { font-size: 12.5px; margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.msg-activity-row { border-bottom: 1px solid var(--border2); margin-bottom: 4px; }
/* Archived channels: read-only, grouped at the bottom of the sidebar. */
.msg-channel.archived { opacity: .6; }
.msg-channel.archived .msg-channel-name::after { content: ' · archived'; font-size: 10.5px; color: var(--muted, #8b949e); }
/* Edit history: the "(edited)" marker + the prior-version list. */
.msg-edited { background: none; border: 0; padding: 0; margin-left: 2px; color: var(--muted, #8b949e); font-size: 11px; cursor: pointer; text-decoration: underline dotted; }
.msg-edited:hover { color: var(--fg, #e6edf3); }
.msg-edits-list { display: flex; flex-direction: column; gap: 10px; max-height: 60vh; overflow-y: auto; padding: 4px 2px; }
.msg-edit-row { border-left: 2px solid var(--border2); padding-left: 10px; }
.msg-edit-meta { font-size: 11.5px; margin-bottom: 2px; }
/* Emoji picker: a small floating palette anchored to a reaction button. */
.msg-emoji-picker { position: fixed; z-index: 90; display: grid; grid-template-columns: repeat(8, 1fr); gap: 2px;
  padding: 6px; background: var(--bg2, #161b22); border: 1px solid var(--border2); border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0,0,0,.35); }
.msg-emoji-picker button { font-size: 18px; line-height: 1; padding: 4px; border: 0; background: none; cursor: pointer; border-radius: 6px; }
.msg-emoji-picker button:hover { background: color-mix(in srgb, var(--primary) 18%, transparent); }
.msg-dragover { outline: 2px dashed var(--primary); outline-offset: -6px; }
.msg-activity-last mark { background: color-mix(in srgb, var(--primary) 30%, transparent); color: inherit; border-radius: 3px; padding: 0 1px; }
.msg-actions .btn.on { color: var(--primary); border-color: var(--primary); }
.msg-people { display: flex; flex-direction: column; max-height: 320px; overflow-y: auto; }
.msg-person { padding: 8px 10px; border-radius: 8px; cursor: pointer; font-size: 13.5px; }
.msg-person:hover { background: color-mix(in srgb, var(--primary) 10%, transparent); }
.msg-me { padding: 8px 4px 0; border-top: 1px solid var(--border2); }
.msg-main { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.msg-empty { flex: 1; display: flex; align-items: center; justify-content: center; }
.msg-empty[hidden] { display: none; }
.msg-room { flex: 1; display: flex; flex-direction: column; min-height: 0; }
.msg-room[hidden] { display: none; }
.msg-room-head { display: flex; flex-direction: column; gap: 2px; border-bottom: 1px solid var(--border2); padding-bottom: 8px; }
.msg-room-title { display: flex; align-items: center; gap: 8px; }
.msg-room-actions { display: flex; gap: 6px; margin-top: 6px; flex-wrap: wrap; }
.msg-searchbar, .msg-searchresults, .msg-pinlist { display: flex; flex-direction: column; gap: 6px; padding: 8px 0; border-bottom: 1px solid var(--border2); }
.msg-searchbar[hidden], .msg-searchresults[hidden], .msg-pinlist[hidden] { display: none; }
.msg-pin { padding: 6px 8px; border-left: 3px solid var(--border2); font-size: 13px; }
.msg-search-hit { cursor: pointer; }
.msg-search-hit:hover { border-left-color: var(--primary, #58a6ff); background: rgba(88,166,255,.06); }
.msg-messages { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 4px; padding: 10px 2px; }
.msg-msg { padding: 6px 10px; border-radius: 10px; }
.msg-msg:hover { background: color-mix(in srgb, var(--primary) 5%, transparent); }
.msg-msg.deleted { opacity: .6; }
.msg-msg-head { display: flex; align-items: baseline; gap: 8px; }
.msg-sender { font-size: 13.5px; }
.msg-mentions { font-size: 11.5px; color: var(--warn, #d29922); }
.msg-body { font-size: 13.5px; white-space: pre-wrap; word-break: break-word; }
.msg-body blockquote { margin: 4px 0; padding: 2px 0 2px 10px; border-left: 3px solid var(--border); color: var(--muted); }
.msg-preview { margin: 4px 0; }
.msg-preview-card { display: flex; gap: 10px; max-width: 520px; padding: 8px; border: 1px solid var(--border); border-radius: 8px; text-decoration: none; color: inherit; background: var(--card); }
.msg-preview-card:hover { border-color: var(--primary); }
.msg-preview-card img { width: 72px; height: 72px; object-fit: cover; border-radius: 6px; flex: none; }
.msg-preview-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.msg-preview-site { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .02em; }
.msg-preview-title { font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.msg-preview-desc { font-size: 12px; color: var(--muted); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.msg-msg-foot { display: flex; align-items: center; gap: 8px; margin-top: 2px; }
.msg-reactions { display: flex; gap: 4px; flex-wrap: wrap; }
.msg-reaction { font-size: 12px; padding: 1px 8px; border-radius: 999px; border: 1px solid var(--border2); background: transparent; cursor: pointer; }
.msg-reaction.mine { border-color: var(--primary); color: var(--primary); }
.msg-actions { display: none; gap: 2px; padding: 2px; border-radius: 8px; background: var(--card); border: 1px solid var(--border); }
.msg-msg:hover .msg-actions { display: inline-flex; }
.msg-msg.menu-open .msg-actions { display: inline-flex; }
.msg-actions .btn { min-width: 28px; min-height: 24px; justify-content: center; font-size: 14px; }
.msg-star { padding: 0 4px; border: none; background: transparent; font-size: 15px; line-height: 1; color: var(--muted); }
.msg-star:hover { color: var(--accent); }
.msg-star.on { color: var(--accent); }
.msg-pinned { font-size: 11px; }
.msg-editbar { display: flex; align-items: center; gap: 8px; padding: 4px 12px; font-size: 12px; color: var(--muted); border-top: 1px solid var(--border); background: color-mix(in srgb, var(--accent) 8%, transparent); }
.msg-editbar[hidden] { display: none; }
.msg-shortcuts { display: flex; flex-direction: column; gap: 6px; font-size: 13px; }
.msg-shortcuts > div { display: flex; gap: 10px; align-items: baseline; }
.msg-shortcuts kbd { min-width: 64px; padding: 1px 6px; border: 1px solid var(--border); border-radius: 4px; background: var(--card2); font-size: 11.5px; text-align: center; }
.msg-more { position: fixed; z-index: 90; display: flex; flex-direction: column; gap: 2px; min-width: 180px; max-width: calc(100vw - 16px); max-height: 60vh; overflow: auto; padding: 6px; background: var(--card); border: 1px solid var(--border); border-radius: 8px; box-shadow: var(--shadow); }
.msg-more[hidden] { display: none; }
.msg-more .btn { justify-content: flex-start; text-align: left; }
.msg-composer { border-top: 1px solid var(--border); padding: 8px 12px 10px; background: var(--card); }
.msg-composer-row { display: flex; gap: 8px; align-items: flex-end; }
.msg-composer textarea { flex: 1; resize: none; min-height: 44px; }
/* Msg attachments (docs/msg-attachments-ui-plan.md): the pending strip sits
 * above the composer row; message attachments render inline below the body.
 * Image thumbs open the same room-gated URL full-size in a new tab; the
 * server's Content-Disposition: attachment then drives the download. */
.msg-pending { display: flex; flex-wrap: wrap; gap: 6px; padding: 2px 0 6px; }
.msg-pending[hidden] { display: none; }
.msg-pending-chip { display: inline-flex; align-items: center; gap: 5px; max-width: 260px;
  padding: 3px 5px 3px 8px; border: 1px solid var(--border2); border-radius: 8px;
  font-size: 12px; background: color-mix(in srgb, var(--primary) 6%, transparent); }
.msg-pending-chip.uploading { opacity: .65; }
.msg-pending-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.msg-pending-size { font-size: 11px; }
.msg-pending-x { border: 0; background: transparent; color: var(--muted); cursor: pointer;
  font-size: 15px; line-height: 1; padding: 0 2px; border-radius: 4px; }
.msg-pending-x:hover { color: var(--danger, #f85149); background: color-mix(in srgb, var(--danger, #f85149) 12%, transparent); }
.msg-atts { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }
.msg-atts:empty { display: none; }
.msg-att-chip { display: inline-flex; align-items: center; gap: 4px; max-width: 320px;
  padding: 3px 10px; border: 1px solid var(--border2); border-radius: 8px;
  font-size: 12.5px; color: var(--text); background: color-mix(in srgb, var(--primary) 8%, transparent); }
.msg-att-chip:hover { border-color: var(--primary); }
.msg-att-chip > span:first-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.msg-att-img { display: inline-block; max-width: 240px; }
.msg-att-thumb { display: block; max-width: 240px; max-height: 160px; object-fit: cover;
  border: 1px solid var(--border2); border-radius: 8px; }
.msg-att-thumb:hover { border-color: var(--primary); }
.msg-editor { position: fixed; inset: 0; background: color-mix(in srgb, var(--bg, #111) 55%, transparent); display: flex; align-items: flex-start; justify-content: center; padding: 8vh 16px; z-index: 60; }
.msg-editor[hidden] { display: none; }
.msg-editor-card { background: var(--card, var(--bg, #1a1a1a)); border: 1px solid var(--border2); border-radius: 12px; padding: 16px; width: min(520px, 100%); max-height: 80vh; overflow: auto; }
.msg-editor-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.msg-editor-row { display: flex; gap: 8px; align-items: center; margin: 8px 0; }
.msg-members-list { display: flex; flex-direction: column; gap: 6px; margin: 8px 0; }
.msg-member-row { display: flex; gap: 8px; align-items: center; padding: 6px 8px; border: 1px solid var(--border2); border-radius: 8px; font-size: 13.5px; }
/* Msg live presence (D3, docs/msg-slack-parity-plan.md): the channel
 * header's online count and the per-sender online dot (the room's live
 * subscription set, delivered as the `presence` frame). */
.msg-online-count { font-size: 11.5px; color: var(--ok, #3fb950);
  background: color-mix(in srgb, var(--ok, #3fb950) 14%, transparent);
  border-radius: 999px; padding: 1px 8px; white-space: nowrap; }
.msg-online-dot { display: inline-block; width: 8px; height: 8px; border-radius: 999px;
  background: var(--ok, #3fb950); margin-left: 4px; vertical-align: baseline;
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--ok, #3fb950) 30%, transparent); }
/* @mention autocomplete (D3): a list that floats above the composer while
 * typing `@name`; the selected row reads as active. */
.msg-mention-popup { position: relative; z-index: 40; max-height: 200px; overflow-y: auto;
  border: 1px solid var(--border2); border-radius: 8px; margin: 2px 0 4px;
  background: var(--card, var(--bg, #1a1a1a));
  box-shadow: 0 4px 16px color-mix(in srgb, #000 35%, transparent); }
.msg-mention-popup[hidden] { display: none; }
.msg-mention-row { display: flex; align-items: center; gap: 8px; padding: 6px 10px;
  font-size: 13.5px; cursor: pointer; }
.msg-mention-row:hover, .msg-mention-row.active { background: color-mix(in srgb, var(--primary) 14%, transparent); }
.msg-mention-role { margin-left: auto; font-size: 11px; color: var(--muted, #8b949e); }
/* :emoji: autocomplete reuses the mention popup shell with a glyph + name. */
.msg-emoji-row { display: flex; align-items: center; gap: 8px; padding: 6px 10px;
  font-size: 13.5px; cursor: pointer; }
.msg-emoji-row:hover, .msg-emoji-row.active { background: color-mix(in srgb, var(--primary) 14%, transparent); }
.msg-emoji-glyph { width: 22px; text-align: center; font-size: 18px; }
.msg-emoji-name { color: var(--muted, #8b949e); font-size: 12px; }
/* Reaction details popover: who reacted with a pill. */
.msg-react-pop { position: fixed; z-index: 60; min-width: 140px; max-width: 220px;
  padding: 6px 8px; border: 1px solid var(--border2); border-radius: 8px;
  background: var(--card, var(--bg, #1a1a1a));
  box-shadow: 0 4px 16px color-mix(in srgb, #000 35%, transparent); font-size: 12.5px; }
.msg-react-pop[hidden] { display: none; }
.msg-react-pop-head { font-weight: 600; margin-bottom: 4px; }
.msg-react-pop-row { color: var(--muted, #8b949e); padding: 1px 0; }
/* User profile popover (click a sender). */
.msg-profile-pop { position: fixed; z-index: 60; min-width: 200px; max-width: 250px;
  padding: 10px; border: 1px solid var(--border2); border-radius: 10px;
  background: var(--card, var(--bg, #1a1a1a));
  box-shadow: 0 6px 20px color-mix(in srgb, #000 40%, transparent); }
.msg-profile-pop[hidden] { display: none; }
.msg-profile-head { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.msg-profile-avatar { width: 34px; height: 34px; border-radius: 50%; display: inline-flex;
  align-items: center; justify-content: center; color: #fff; font-weight: 600; font-size: 15px; }
.msg-profile-name { font-weight: 600; font-size: 13.5px; }
.msg-profile-meta { font-size: 11.5px; color: var(--muted, #8b949e); display: flex; align-items: center; gap: 4px; }
/* Cross-channel search filters (sidebar). */
.msg-side-search { display: flex; gap: 4px; }
.msg-side-search input { flex: 1; min-width: 0; }
.msg-filter-panel { display: flex; flex-direction: column; gap: 4px; padding: 6px 8px;
  border: 1px solid var(--border2); border-radius: 8px; margin: 4px 0;
  background: var(--card, var(--bg, #1a1a1a)); }
.msg-filter-panel[hidden] { display: none; }
.msg-filter-panel label { display: flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--muted, #8b949e); }
.msg-filter-panel input { flex: 1; min-width: 0; font-size: 12px; }
.msg-filter-actions { display: flex; gap: 4px; }
.msg-filter-chips { display: flex; flex-wrap: wrap; gap: 4px; padding: 2px 0 4px; }
.msg-filter-chips[hidden] { display: none; }
.msg-filter-chip { display: inline-flex; align-items: center; gap: 4px; font-size: 11px;
  border: 1px solid var(--border2); border-radius: 999px; padding: 1px 6px; color: var(--muted, #8b949e); }
.msg-filter-chip button { border: 0; background: none; color: inherit; cursor: pointer; padding: 0; font-size: 12px; }
/* Custom emoji images (reactions, palette, autocomplete, manager). */
.msg-emoji-img { width: 18px; height: 18px; object-fit: contain; vertical-align: -3px; }
.msg-emoji-list { display: flex; flex-wrap: wrap; gap: 6px; padding: 4px 0 8px; max-width: 100%; }
.msg-emoji-item { display: inline-flex; align-items: center; gap: 4px; font-size: 12px;
  border: 1px solid var(--border2); border-radius: 6px; padding: 2px 6px; max-width: 100%; }
.msg-editor-row input[type="file"] { min-width: 0; max-width: 100%; }
.msg-editor-head { gap: 8px; }
/* "Also send to channel" under the thread composer. */
.msg-thread-also { display: flex; align-items: center; gap: 6px; padding: 4px 10px;
  font-size: 12px; color: var(--muted, #8b949e); cursor: pointer; }
.msg-thread-also[hidden] { display: none; }
/* A thread reply that also appears in the timeline. */
.msg-thread-chip { font-size: 10.5px; color: var(--muted, #8b949e);
  border: 1px solid var(--border2); border-radius: 4px; padding: 0 4px; margin-left: 4px; }
/* Per-channel notification preference (a segmented row in the header menu). */
.msg-notify-pref { display: inline-flex; align-items: center; gap: 4px; padding: 2px 4px; }
.msg-notify-pref[hidden] { display: none; }
.msg-notify-pref .btn.on { background: color-mix(in srgb, var(--primary) 22%, transparent);
  border-color: var(--primary); }
/* Msg reminders (E3b, docs/msg-reminders-plan.md): the pending-reminders list
 * reuses the pin list's row shape (msg-pin) with a cancel ×; the "Remind me"
 * picker reuses the editor card (msg-editor / msg-editor-card) that the
 * New-channel panel uses. */
.msg-reminderslist { display: flex; flex-direction: column; gap: 6px; padding: 8px 0;
  border-bottom: 1px solid var(--border2); }
.msg-reminderslist[hidden] { display: none; }
.msg-reminder { display: flex; gap: 8px; align-items: center; position: relative; padding-left: 24px; }
.msg-reminder-x { position: absolute; left: 0; border: 0; background: transparent; color: var(--muted);
  cursor: pointer; font-size: 15px; line-height: 1; padding: 2px 4px; border-radius: 999px; }
.msg-reminder-x:hover { color: var(--danger, #f85149); background: color-mix(in srgb, var(--danger, #f85149) 12%, transparent); }
@media (max-width: 800px) {
  .msg-reminder { flex-wrap: wrap; }
}
/* Msg threads (D2, docs/msg-slack-parity-plan.md): the thread side panel
 * slides in over the message list (right rail), with the thread root
 * pinned at top (read-only, a bordered msg-msg), its replies below, and a
 * slim composer at the bottom. The "N replies" affordance on a parent in
 * the timeline opens it. */
.msg-thread { position: fixed; top: 64px; right: 8px; bottom: 16px; width: 360px; max-width: calc(100vw - 32px);
  z-index: 70;
  display: flex; flex-direction: column; min-height: 0;
  background: var(--card, var(--bg, #1a1a1a)); border: 1px solid var(--border2);
  border-radius: 12px; box-shadow: 0 12px 40px color-mix(in srgb, #000 45%, transparent); }
.msg-thread[hidden] { display: none; }
.msg-thread-head { display: flex; align-items: center; gap: 8px; padding: 10px 12px;
  border-bottom: 1px solid var(--border2); }
.msg-thread-head strong { font-size: 13px; text-transform: uppercase; letter-spacing: .04em; }
.msg-thread-parent { padding: 8px 12px 0; }
.msg-thread-parent .msg-msg { border: 1px solid var(--border2); border-radius: 10px; background: var(--card2, transparent); }
.msg-thread-replies { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 2px;
  padding: 8px 12px; }
.msg-thread-composer { display: flex; gap: 6px; align-items: center; padding: 8px 12px;
  border-top: 1px solid var(--border2); }
.msg-thread-composer input { flex: 1; min-width: 0; }
/* The "N replies" affordance on a thread root in the timeline (opens the
 * panel); styled distinct from the hover-only actions so it is always
 * visible (a thread summary, not a transient control). */
.msg-thread-summ { margin: 4px 0 0; }
.msg-thread-open { border: 0; background: transparent; color: var(--primary); cursor: pointer;
  font-size: 12px; font-weight: 600; padding: 2px 6px; border-radius: 6px; }
.msg-thread-open:hover { background: color-mix(in srgb, var(--primary) 12%, transparent); }
@media (max-width: 800px) {
  .msg-thread { width: calc(100vw - 16px); }
}
@media (max-width: 800px) {
  .msg-page { flex-direction: column; height: auto; }
  .msg-sidebar { width: 100%; border-right: none; border-bottom: 1px solid var(--border2); padding-bottom: 8px; }
  .msg-messages { max-height: 50vh; }
}

/* The UA's [hidden] { display: none } loses to any author display value
 * (.btn, .msg-empty, .books-pane…). Make hidden win, everywhere. */
[hidden] { display: none !important; }

/* ---- Notes (/quicknotes) ---- */
.qn-page { display: flex; flex-direction: column; gap: 14px; height: calc(100vh - 120px); min-height: 460px; }
.qn-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.qn-head h1 { margin: 0; }
.qn-head-actions { display: flex; gap: 8px; align-items: center; }
.qn-search { padding: 6px 10px; border-radius: 8px; border: 1px solid var(--border);
  background: var(--card2); color: var(--text); font: inherit; font-size: 13px; min-width: 200px; }
.qn-layout { flex: 1; display: grid; grid-template-columns: 300px 1fr; gap: 14px; min-height: 0; }
.qn-list { display: flex; flex-direction: column; gap: 4px; overflow-y: auto;
  border-right: 1px solid var(--border2); padding-right: 10px; }
.qn-list-empty { padding: 16px 10px; font-size: 13px; }
.qn-item { text-align: left; border: 1px solid transparent; border-radius: 10px;
  background: transparent; padding: 9px 11px; cursor: pointer; color: var(--text);
  font: inherit; display: block; width: 100%; }
.qn-item:hover { background: var(--card2); }
.qn-item.on { border-color: var(--border); background: var(--card2); }
.qn-item:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.qn-item-title { font-size: 13.5px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.qn-item-preview { font-size: 12px; color: var(--muted); margin-top: 2px; overflow: hidden;
  text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.qn-item-date { font-size: 11px; color: var(--muted); margin-top: 4px; }
.qn-editor { display: flex; flex-direction: column; min-height: 0; }
.qn-empty-state { flex: 1; display: flex; align-items: center; justify-content: center; }
.qn-pane { flex: 1; display: flex; flex-direction: column; min-height: 0; gap: 8px; }
.qn-pane-head { display: flex; align-items: baseline; gap: 12px; border-bottom: 1px solid var(--border2); padding-bottom: 6px; }
.qn-title { flex: 1; border: none; background: transparent; color: var(--text);
  font-size: 20px; font-weight: 600; font-family: inherit; padding: 2px 0; }
.qn-title:focus { outline: none; }
.qn-meta { font-size: 11.5px; white-space: nowrap; }
.qn-body { flex: 1; width: 100%; resize: none; border: 1px solid var(--border); border-radius: 10px;
  background: var(--card2); color: var(--text); font: inherit; font-size: 14px; line-height: 1.6;
  padding: 12px 14px; min-height: 200px; }
.qn-pane-foot { display: flex; align-items: center; gap: 8px; }
@media (max-width: 800px) {
  .qn-page { height: auto; }
  .qn-layout { grid-template-columns: 1fr; }
  .qn-list { max-height: 32vh; border-right: none; border-bottom: 1px solid var(--border2); padding-bottom: 8px; }
}

/* Inbox unread badge (FR-2) */
.nav-badge { background: var(--danger, #f85149); color: #fff; border-radius: 999px;
  font-size: 10.5px; font-weight: 600; padding: 1px 7px; margin-left: auto;
  font-variant-numeric: tabular-nums; }
.nav-item .nav-badge { margin-left: auto; }

/* Bookkeeping: model-suggested categories (advisory chip in the import preview) */
.bookkeeping-suggest { color: var(--primary); font-weight: 600; }

/* Chat: staged-write confirmation (platform app write tools) */
.toolchip.writeconfirm { display: inline-flex; align-items: center; gap: 10px; flex-wrap: wrap; border-color: var(--primary); }
.toolactions { display: inline-flex; gap: 6px; }

/* FR-9 search palette (Ctrl/Cmd+K). A lightweight overlay on existing pages. */
.pal-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,.45); z-index: 900; display: none; }
.pal-backdrop.open { display: block; }
.pal { position: fixed; top: 12vh; left: 50%; transform: translateX(-50%); width: min(640px, 92vw);
  max-height: 70vh; background: var(--bg, #fff); color: var(--fg, #111); border: 1px solid var(--border, #ddd);
  border-radius: 12px; box-shadow: 0 20px 60px rgba(0,0,0,.35); z-index: 901; display: none; flex-direction: column; overflow: hidden; }
.pal.open { display: flex; }
.pal-input { width: 100%; box-sizing: border-box; border: 0; border-bottom: 1px solid var(--border, #ddd);
  padding: 14px 16px; font-size: 16px; background: transparent; color: inherit; outline: none; }
.pal-body { overflow-y: auto; padding: 6px 0; }
.pal-group-head { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  color: var(--muted, #888); padding: 8px 16px 4px; }
.pal-row { padding: 8px 16px; cursor: pointer; display: flex; flex-direction: column; gap: 2px; }
.pal-row.sel { background: var(--hover, #f2f2f2); }
.pal-title { font-size: 14px; }
.pal-snippet { font-size: 12px; color: var(--muted, #888); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pal-foot { padding: 8px 16px; border-top: 1px solid var(--border, #ddd); font-size: 12px; color: var(--muted, #888); }
.pal-empty { padding: 16px; color: var(--muted, #888); font-size: 13px; }

/* Documents (collaborative editing) — the "docs" app. */
.docs-layout { display: flex; gap: 14px; height: calc(100vh - 150px); min-height: 420px; }
.docs-sidebar { width: 230px; flex-shrink: 0; display: flex; flex-direction: column;
  border-right: 1px solid var(--border2); padding-right: 10px; }
.docs-side-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.docs-list { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; }
.docs-item { padding: 8px 10px; border-radius: var(--radius-s, 6px); cursor: pointer;
  border: 1px solid transparent; }
.docs-item:hover { background: var(--card2); }
.docs-item.active { background: var(--card2); border-color: var(--border2); }
.docs-item .t { font-size: 13.5px; }
.docs-item .m { font-size: 11px; color: var(--muted); margin-top: 2px; }
.docs-item .p { font-size: 10.5px; color: var(--muted); margin-top: 1px; opacity: .8;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.docs-item .del { float: right; border: 0; background: none; color: var(--muted); cursor: pointer;
  font-size: 13px; padding: 0 2px; }
.docs-item .del:hover { color: var(--danger); }
/* G5: the office-spreadsheet convert affordance (a second float-right
   button beside the delete, only on xlsx/ods file rows). */
.docs-item .del.conv { margin-left: 10px; font-size: 11px; }
.docs-item .del.conv:hover { color: var(--text); }
.docs-side-foot { padding-top: 8px; border-top: 1px solid var(--border2); }
/* Team libraries: each team's shared Documents space, above the personal
   library. Folded by default when it would crowd the list. */
.docs-teams { max-height: 40%; overflow-y: auto; border-bottom: 1px solid var(--border2);
  padding-bottom: 6px; margin-bottom: 6px; }
.docs-team { margin-bottom: 2px; }
.docs-team-head { display: flex; align-items: center; gap: 6px; padding: 5px 8px;
  border-radius: var(--radius-s, 6px); cursor: pointer; user-select: none; }
.docs-team-head:hover { background: var(--card2); }
.docs-team-caret { font-size: 10px; color: var(--muted); width: 10px; }
.docs-team-name { font-size: 12px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .04em; color: var(--muted); overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; flex: 1; }
.docs-team-count { font-size: 11px; }
.docs-team-add { padding: 0 6px; line-height: 1.4; }
.docs-team-body { display: flex; flex-direction: column; gap: 2px; padding-left: 6px; }
.docs-team-empty { font-size: 12px; padding: 4px 10px; }
.docs-team-actions { display: flex; gap: 4px; padding: 0 0 4px 2px; }
.docs-team-actions .btn { font-size: 11px; padding: 1px 6px; line-height: 1.5; }
.docs-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
/* The unified library's file pane (the collapsed Documents app): the shared
   FileViewer (viewer.js) docked in the main area for non-docs rows. It and
   the editor are mutually exclusive — one at a time. */
.docs-pane { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.docs-pane[hidden] { display: none; }
.docs-pane .viewer-panel { max-width: none; border-radius: 0; border: 0; box-shadow: none; }
.docs-side-actions { display: inline-flex; gap: 4px; }
.docs-item .files-class-icon { margin-right: 6px; opacity: .9; }
.docs-empty { flex: 1; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 6px; }
.docs-empty[hidden] { display: none; }
.docs-editor-wrap { flex: 1; display: flex; flex-direction: column; gap: 10px; min-height: 0; }
.docs-editor-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
/* flex-basis 180px with min-width 0: the title keeps a stable width and
   truncates rather than re-wrapping when the meta cluster beside it changes
   (the save indicator's label cycles on every keystroke). */
.docs-title { flex: 1 1 180px; min-width: 0; border: 0; background: none; color: var(--text);
  font-size: 19px; font-weight: 600; padding: 4px 0; outline: none; }
.docs-editor-meta { display: flex; align-items: center; gap: 8px; }
.docs-canvas { flex: 1; overflow-y: auto; min-height: 160px; padding: 12px 16px;
  border: 1px solid var(--border2); border-radius: var(--radius-s, 6px); background: var(--card);
  line-height: 1.6; font-size: 14.5px; }
.docs-canvas[data-readonly="true"] { background: transparent; border-style: dashed; color: var(--muted); }
.docs-presence { font-size: 12px; color: var(--muted); }
.docs-members { display: flex; flex-direction: column; gap: 6px; }
.docs-members strong { font-size: 12px; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.docs-member-row { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.docs-member-row .u { flex: 1; }
.docs-member-row select { border: 1px solid var(--border2); background: var(--card2);
  color: var(--text); border-radius: var(--radius-s, 6px); font-size: 12px; padding: 2px 6px; }
.docs-comment-list { display: flex; flex-direction: column; gap: 6px; }
.docs-comment { padding: 8px 10px; border: 1px solid var(--border2); border-radius: var(--radius-s, 6px);
  background: var(--card); font-size: 13px; }
.docs-comment.resolved { opacity: .55; }
.docs-comment .c-head { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--muted); margin-bottom: 3px; }
.docs-comment .c-anchor { font-size: 12px; color: var(--brand); font-style: italic; margin-bottom: 3px; }
.docs-comment .c-body { white-space: pre-wrap; }
.docs-comment .c-acts { margin-top: 4px; }
.docs-comment .c-acts button { font-size: 11px; }
.docs-comment-add { display: flex; gap: 8px; margin-top: 6px; }
.docs-comment-input { flex: 1; }

/* search */
.docs-search { padding: 0 10px 8px; }
.docs-search-input { width: 100%; box-sizing: border-box; border: 1px solid var(--border2); background: var(--card);
  color: var(--text); border-radius: var(--radius-s, 6px); font-size: 12.5px; padding: 5px 8px; }
.docs-item .s { margin-top: 4px; font-size: 11.5px; color: var(--muted); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }

/* S2.3 — the formatting toolbar (token-driven, no raw hex) */
.docs-toolbar { display: flex; align-items: center; gap: var(--sp-1); flex-wrap: wrap;
  padding: var(--sp-1) var(--sp-2); border: 1px solid var(--border2);
  border-radius: var(--radius-s, 6px); background: var(--card2); }
.docs-toolbar[hidden] { display: none; }
.docs-tb { display: inline-flex; align-items: center; justify-content: center;
  min-width: 28px; height: 26px; padding: 0 6px; cursor: pointer;
  font: inherit; font-size: 12px; color: var(--text);
  background: transparent; border: 1px solid transparent;
  border-radius: var(--radius-s, 6px); }
.docs-tb:hover { background: var(--card); border-color: var(--border2); }
.docs-tb:disabled { opacity: .45; cursor: default; }
.docs-tb strong, .docs-tb em, .docs-tb code { font-size: 12.5px; }
.docs-tb-sep { width: 1px; height: 18px; background: var(--border2); margin: 0 4px; }
.docs-tb-select { height: 26px; padding: 0 6px; font: inherit; font-size: 12px;
  color: var(--text); background: var(--card); border: 1px solid var(--border2);
  border-radius: var(--radius-s, 6px); }
/* ProseMirror's own DOM inside the canvas */
.docs-canvas .ProseMirror { outline: none; min-height: 100%; }
.docs-canvas .ProseMirror p { margin: 0 0 .7em; }
.docs-canvas .ProseMirror h1, .docs-canvas .ProseMirror h2, .docs-canvas .ProseMirror h3 {
  margin: 1.1em 0 .5em; line-height: 1.25; font-weight: 600; color: var(--text); }
.docs-canvas .ProseMirror h1 { font-size: 1.6em; }
.docs-canvas .ProseMirror h2 { font-size: 1.32em; }
.docs-canvas .ProseMirror h3 { font-size: 1.14em; }
.docs-canvas .ProseMirror blockquote { margin: .8em 0; padding-left: .9em;
  border-left: 3px solid var(--primary); color: var(--muted); }
.docs-canvas .ProseMirror pre { margin: .8em 0; padding: .7em .9em; overflow-x: auto;
  background: var(--card2); border: 1px solid var(--border2);
  border-radius: var(--radius-s, 6px); font-family: var(--font-family-mono, monospace); font-size: 12.5px; }
.docs-canvas .ProseMirror ul, .docs-canvas .ProseMirror ol { margin: .6em 0; padding-left: 1.5em; }
.docs-canvas .ProseMirror li { margin: .2em 0; }
.docs-canvas .ProseMirror hr { border: 0; border-top: 1px solid var(--border2); margin: 1.2em 0; }
.docs-canvas .ProseMirror img { max-width: 100%; height: auto; border-radius: var(--radius-s, 6px); }
.docs-canvas .ProseMirror table { border-collapse: collapse; margin: .8em 0; width: 100%; }
.docs-canvas .ProseMirror td, .docs-canvas .ProseMirror th {
  border: 1px solid var(--border2); padding: 6px 9px; font-size: 13px; }
.docs-canvas .ProseMirror a { color: var(--primary); text-decoration: underline; }

/* editor action buttons */
.docs-editor-head .btn { margin-left: 4px; }

/* S2.5 — filed-under line + save-state indicator (token-driven) */
.docs-filed { font-size: 11.5px; color: var(--muted); max-width: 34ch; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.docs-filed[hidden] { display: none; }
.docs-save { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; color: var(--muted);
  white-space: nowrap; }
/* The label cycles Saved -> Saving… -> Saved on every edit, and ranges from 5
   to 13 characters ("Reconnecting…", "Saved 59m ago"). Left in normal flow it
   widens the meta cluster on each keystroke; the flex:1 title shrinks to
   compensate and, at narrow widths, the wrap threshold flips — the header
   jumps while typing.
   Fix: give the indicator a fixed slot wide enough for its longest label and
   right-align the text inside it, so the dot stays put and the text grows
   leftward into reserved space. The title then never changes width. */
.docs-save { flex: none; width: 13ch; justify-content: flex-end; overflow: hidden; }
#docsSaveText { overflow: hidden; text-overflow: ellipsis; }
.docs-save-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--ok, var(--success, var(--brand)));
  transition: background .15s ease; }
.docs-save[data-state="saving"] .docs-save-dot { background: var(--warn); }
.docs-save[data-state="offline"] .docs-save-dot,
.docs-save[data-state="error"] .docs-save-dot { background: var(--danger); }
.docs-save[data-state="reconnecting"] .docs-save-dot { background: var(--info); }
.docs-save[data-state="offline"],
.docs-save[data-state="error"] { color: var(--danger); }

/* S2.6 — dual chrome modes. Focus (default): a quiet centered sheet with a
   receding chrome. Classic: always-on toolbar over a full-width,
   left-aligned pane. Both derive from the tokens, so light/dark and a
   per-user accent apply without extra rules. */
.docs-mode-seg { margin-left: 2px; }

/* focus mode (the Obsidian-style default) */
html[data-docs-mode="focus"] .docs-canvas-outer { align-items: center; }
html[data-docs-mode="focus"] .docs-canvas {
  width: 100%; max-width: 46rem; margin: 0 auto; padding: 28px 34px;
  border: 0; background: transparent; font-size: 15.5px; line-height: 1.75;
}
html[data-docs-mode="focus"] .docs-editor-head { opacity: .82; transition: opacity .15s ease; }
html[data-docs-mode="focus"] .docs-editor-head:hover,
html[data-docs-mode="focus"] .docs-editor-head:focus-within { opacity: 1; }
/* A viewer's read-only cue must survive the focus treatment: the base
   .docs-canvas[data-readonly] rule is outranked by the focus rule above, so
   restate it at matching specificity (dashed outline + muted ink). */
html[data-docs-mode="focus"] .docs-canvas[data-readonly="true"] {
  outline: 1px dashed var(--border2); outline-offset: 6px; color: var(--muted);
}

/* classic mode: the traditional always-on, full-width treatment */
html[data-docs-mode="classic"] .docs-canvas-outer { align-items: stretch; }
html[data-docs-mode="classic"] .docs-canvas {
  width: 100%; max-width: none; padding: 12px 16px; font-size: 14.5px;
  border: 1px solid var(--border2); background: var(--card);
}
html[data-docs-mode="classic"] .docs-editor-head { opacity: 1; }

/* live cursors */
.docs-canvas-outer { position: relative; flex: 1; min-height: 160px; display: flex; flex-direction: column; }
.docs-caret-layer { position: absolute; inset: 0; pointer-events: none; overflow: hidden; z-index: 2; }
.docs-caret { position: absolute; width: 2px; height: 18px; border-radius: 1px; }
.docs-caret-tag { position: absolute; top: -15px; left: -2px; font-size: 9.5px; font-weight: 600; color: #fff;
  padding: 0 4px; border-radius: 3px; white-space: nowrap; line-height: 13px; }
.docs-caret-sel { position: absolute; border-radius: 2px; }

/* AI assist + history panels */
.docs-ai-panel, .docs-history-panel { border: 1px solid var(--border2); border-radius: var(--radius-s, 6px);
  background: var(--card); padding: 10px 12px; display: flex; flex-direction: column; gap: 8px; }
.docs-ai-head { display: flex; align-items: center; gap: 10px; }
.docs-ai-head strong { font-size: 12.5px; }
.docs-ai-head .btn { margin-left: auto; }
.docs-ai-model { font-size: 11px; }
.docs-ai-controls { display: flex; align-items: center; gap: 8px; }
.docs-ai-input { flex: 1; border: 1px solid var(--border2); background: var(--card2, var(--card));
  color: var(--text); border-radius: var(--radius-s, 6px); font-size: 13px; padding: 5px 8px; }
.docs-ai-out { font-size: 13px; line-height: 1.5; white-space: pre-wrap; word-break: break-word;
  max-height: 260px; overflow-y: auto; }
.docs-history-list { display: flex; flex-direction: column; gap: 4px; max-height: 260px; overflow-y: auto; }
.docs-history-row { display: flex; align-items: center; justify-content: space-between; gap: 10px;
  font-size: 12.5px; padding: 4px 8px; border: 1px solid var(--border2); border-radius: var(--radius-s, 6px); }
.docs-history-row .m { font-size: 11.5px; color: var(--muted); }
.docs-history-row .btn[disabled] { opacity: .5; cursor: default; }

/* ---------- contextual chat dock (S2) ----------
   The same chat engine, opened against a context group ("Apps:Documents").
   Wide screens: a right-hand dock that squeezes the page (never covers it).
   Phones: a full-screen sheet — a fixed right panel cannot work on a 390px
   viewport, and the app is phone-first. */
.ctx-dock {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 63;
  width: min(420px, 40vw);
  background: var(--card); border-left: 1px solid var(--border);
  display: flex; flex-direction: column;
  box-shadow: -4px 0 16px rgba(0,0,0,.28);
}
.ctx-dock[hidden] { display: none; }
.ctx-dock-head {
  display: flex; align-items: center; gap: 6px;
  padding: 10px 12px; border-bottom: 1px solid var(--border);
  flex: none;
}
.ctx-dock-head strong { font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ctx-dock-body { flex: 1; min-height: 0; }
.ctx-dock-frame { width: 100%; height: 100%; border: 0; display: block; background: var(--bg); }

/* Squeeze the page rather than covering it. The shell is the app's main
   column; shifting it keeps every page usable with the dock open. The same
   margin is reserved while the tab is merely present (ctx-tab-on), so the
   tab never sits on top of the page's own content. */
body.ctx-dock-open .shell { margin-right: min(420px, 40vw); }
body.ctx-tab-on:not(.ctx-dock-open) .shell { margin-right: 30px; }

/* The launcher: a persistent vertical tab on the right edge, labelled with
   what is in focus ("Documents"), so it reads as "chat about this" rather
   than as a second Chat app. Present throughout the experience on any page
   that has a context to talk about. */
.ctx-tab {
  position: fixed; right: 0; top: 50%; transform: translateY(-50%);
  z-index: 62;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 14px 7px; cursor: pointer;
  background: var(--card); color: var(--muted);
  border: 1px solid var(--border); border-right: 0;
  border-radius: 10px 0 0 10px;
  font: inherit; font-size: 11.5px; font-weight: 600;
  letter-spacing: .04em;
  box-shadow: -2px 0 10px rgba(0,0,0,.18);
  transition: color .15s ease, background .15s ease, right .18s ease;
}
.ctx-tab:hover { color: var(--primary); background: var(--card2); }
.ctx-tab[aria-expanded="true"] { color: var(--on-primary); background: var(--primary);
  border-color: color-mix(in srgb, var(--primary) 70%, black); }
.ctx-tab[hidden] { display: none; }
.ctx-tab-icon svg { width: 16px; height: 16px; display: block; }
.ctx-tab-label { writing-mode: vertical-rl; text-orientation: mixed;
  max-height: 9em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* The dock sits to the tab's left, so the tab is never covered by it. The tab
   is 32px wide, so it parks exactly on the dock's left edge. */
body.ctx-dock-open .ctx-tab { right: calc(min(420px, 40vw) - 32px); }

@media (max-width: 900px) {
  /* Phone/tablet: a full-screen sheet, not a dock. */
  .ctx-dock { width: 100vw; border-left: 0; box-shadow: none; }
  body.ctx-dock-open .shell { margin-right: 0; }
  body.ctx-tab-on:not(.ctx-dock-open) .shell { margin-right: 0; }
  /* Phones: the dock is a full-screen sheet, so the tab hides while it is
     open (the sheet's own close button is the way out). */
  body.ctx-dock-open .ctx-tab { display: none; }
  /* Narrow screens cannot spare an edge strip: the tab becomes a compact
     pill in the bottom-right corner, above the safe area. */
  .ctx-tab {
    top: auto; bottom: 18px; transform: none;
    flex-direction: row; gap: 7px; padding: 9px 13px;
    border: 1px solid var(--border); border-radius: 999px; right: 14px;
    box-shadow: 0 4px 14px rgba(0,0,0,.35);
  }
  .ctx-tab-label { writing-mode: horizontal-tb; max-height: none; max-width: 8em;
    overflow: hidden; text-overflow: ellipsis; }
}

/* Icon-only toolbar button (the docs chat launcher): same footprint as its
   text siblings, with the SVG sized to the label it replaces. */
.docs-icon-btn { display: inline-flex; align-items: center; justify-content: center; padding: 5px 9px; }
.docs-icon-btn svg { width: 15px; height: 15px; }
