:root {
  /* Chalkboard theme — dark slate-grey board, chalk-white text, blonde-wood frames.
     Colours are deliberately muted/chalky, never bright. */
  --bg: #333d40;          /* dark slate grey board (not black) */
  --bg-2: #191A1A;        /* recessed frame panels */
  --bg-3: #3c474b;        /* raised controls/chips */
  --panel: #191A1A;       /* side frames */
  --border: #515b5e;      /* subtle chalk line inside frames */
  --frame: #B69473;       /* the lines between frames */
  --divider: #B69473;     /* the thicker double line between the sessions list and the chat window */
  --text: #ece8df;        /* chalk white */
  --muted: #aab0a8;       /* faded chalk */
  --accent: #9bb089;      /* chalky sage — links/focus (muted, not bright) */
  --accent-2: #c0a575;    /* chalky wood accent */
  --tab: #7d9b66;         /* chalk green — collapse tabs (collapsed/closed state) */
  --tab-open: #c5524a;    /* tabs turn red while a side pane is open */
  --btn: #8fa8c6;         /* chalk blue — primary buttons */
  --center: #191A1A;      /* centre pane background — matches the side chat panes */
  --field: #212121;       /* text input fields */
  --code-bg: #0c0e13;     /* code blocks (dark; inverted to a light grey in light mode) */
  --user: #3a454a;        /* chalk-slate user bubble */
  --assistant: #303a3d;   /* chalk-slate assistant bubble */
  --danger: #c47b72;      /* chalky brick red */
  --good: #7d9b66;        /* chalk green */
  --radius: 12px;
  --content-w: 900px;
  --tab-w: 34px;          /* collapsed side-frame width — wide enough to pad the corner icons evenly */
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  --sans: "Gill Sans", "Gill Sans MT", "Gill Sans Nova", "Gill Sans Std", Calibri, "Trebuchet MS", sans-serif;
}

/* ---------- Light mode ---------- */
/* Same interface as dark; only: greys inverted to light near-white, the sessions|chat double line
   goes red, all other lines/outlines go pale blue, white text → charcoal, chalk-green text → dark blue. */
:root[data-theme="light"] {
  --bg: #dfe3e5;          /* board → light slate grey */
  --bg-2: #f4f5f6;        /* recessed panels → near-white */
  --bg-3: #e7eaec;        /* raised controls/chips */
  --panel: #f4f5f6;       /* side frames → near-white */
  --center: #eceef0;      /* centre pane */
  --field: #fbfbfc;       /* text input fields → near-white */
  --user: #e4e9ec;        /* user bubble */
  --assistant: #eef1f3;   /* assistant bubble */
  --border: #9db8d4;      /* outlines → pale blue */
  --frame: #9db8d4;       /* frame lines → pale blue */
  --divider: #e06b6b;     /* the sessions|chat double divider → lighter red */
  --text: #414141;        /* white text → dark grey #414141 */
  --muted: #5f6b73;       /* faded text → muted charcoal */
  --accent: #1a338b;      /* chalk-green text/links → dark blue */
  --good: #1a338b;        /* chalk green → dark blue */
  --accent-2: #7a5a1f;    /* wood accent → darker bronze so Client/Matter text reads on light surfaces */
  --code-bg: #e6e9ed;     /* code blocks → light grey */
}
/* The "new messages" pill keeps its accent (now dark-red) fill in light mode, so its label must be
   light to stay legible — dark text is only correct over the dark-mode green fill. */
:root[data-theme="light"] .new-msg-pill { color: #f4f5f6; }
/* No drop-shadow on the centre pane in light mode, so the red double divider isn't shadowed. */
:root[data-theme="light"] #main { box-shadow: none; }
/* The incognito (inverted, near-white) send button needs a visible outline on the light background,
   to match the other (blue) send buttons. */
:root[data-theme="light"] .peer-ico.incognito:not(.is-default) { border-color: var(--btn); border-width: 1px; }
/* Status / error text was tinted for dark panels — darken it so it stays legible on light panels. */
:root[data-theme="light"] .pending-note { color: #8a5a00; }
:root[data-theme="light"] .pw-error,
:root[data-theme="light"] .msg-error,
:root[data-theme="light"] .login-error,
:root[data-theme="light"] .bubble-stop { color: #a11722; }
/* In light mode only the LLM send icons and the user avatars keep the light-grey tile (so the brand
   logos read on a consistent ground); ~1.8:1 vs the near-white UI matches the dark-grey-on-near-black
   step in dark mode. The other (non-chat) buttons drop the fill and show only their outline. */
:root[data-theme="light"] .msg .avatar,
:root[data-theme="light"] .send-ico { background: #b7b7b7; color: var(--text); }
:root[data-theme="light"] .icon-btn,
:root[data-theme="light"] .sb-nav-btn,
:root[data-theme="light"] .mini-btn { background: transparent; }

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
body {
  font-family: var(--sans);
  background: var(--center);   /* match the chat area so mobile overscroll / safe-area top & bottom blend in */
  color: var(--text);
  font-size: 0.9375rem;
  font-weight: 600;   /* Gill Sans has no 500 face (it renders as 400); 600 is the real "heavier" step */
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
button { font-family: inherit; cursor: pointer; }
/* Bold = a controlled Bold (700), not the UltraBold the 600 base would otherwise inherit
   (UA bolder maps 600 → 900). Keeps **bold** close to the body text instead of shouting. */
strong, b { font-weight: 700; }
/* Auto-hiding scrollbars: the thumb is transparent until you hover the scrolling pane, then it
   fades in in the frame/divider colour — brown in the dark theme, blue in light (var(--frame) is
   #B69473 in dark and #9db8d4 in light). */
* { scrollbar-width: thin; scrollbar-color: transparent transparent; }      /* Firefox: thin, hidden */
*:hover { scrollbar-color: var(--frame) transparent; }                       /* Firefox: reveal on hover */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: transparent; border-radius: 8px; transition: background .2s ease; }
:hover::-webkit-scrollbar-thumb { background: var(--frame); }                /* reveal when hovering the pane */
::-webkit-scrollbar-thumb:hover { background: var(--accent-2); }             /* highlight the bar itself */

/* ---------- Login ---------- */
.login-body { display: grid; place-items: center; background: radial-gradient(1200px 600px at 50% -10%, #1b2030, var(--bg)); }
.login-card {
  width: min(380px, 92vw); background: var(--panel); border: 1px solid var(--border);
  border-radius: 16px; padding: 32px 28px; display: flex; flex-direction: column; gap: 14px;
  box-shadow: 0 20px 60px rgba(0,0,0,.45);
}
.login-logo { font-size: 1.375rem; font-weight: 700; text-align: center; }
.login-sub { color: var(--muted); text-align: center; margin: -6px 0 8px; font-size: 0.8125rem; }
.login-card label { display: flex; flex-direction: column; gap: 6px; font-size: 0.8125rem; color: var(--muted); }
.login-card input {
  background: var(--field); border: 1px solid var(--border); color: var(--text);
  border-radius: 10px; padding: 11px 12px; font-size: 0.9375rem;
}
.login-card input:focus { outline: none; border-color: var(--accent); }
.login-card button {
  margin-top: 8px; background: var(--btn); color: #fff; border: 0; border-radius: 10px;
  padding: 12px; font-size: 0.9375rem; font-weight: 600;
}
.login-error { background: rgba(239,91,107,.12); border: 1px solid rgba(239,91,107,.4); color: #ffb3bc;
  padding: 10px 12px; border-radius: 10px; font-size: 0.8125rem; }

/* ---------- Layout: two framed panes (sessions + one conversation); centre casts a shadow ---------- */
#app { display: grid; --lw-open: 270px; --lw: var(--lw-open); grid-template-columns: var(--lw) 1fr; grid-template-rows: auto 1fr; height: 100vh; }
/* The top frame spans the full width of the screen, above both panes. */
#topbar { grid-column: 1 / -1; grid-row: 1; }
#app.left-collapsed  { --lw: var(--tab-w); }

#sidebar { grid-column: 1; grid-row: 2; position: relative; background: var(--panel); border-right: 3px double var(--divider); display: flex; flex-direction: column; min-width: 0; min-height: 0; }
/* A collapsed side frame shows only its corner icon and the "+" new-session button. */
#app.left-collapsed #sidebar > :not(.sb-listicon):not(.sb-new) { display: none; }
/* Clicking anywhere on the collapsed sidebar re-opens it. */
#app.left-collapsed #sidebar { cursor: pointer; }
.sb-head { display: flex; gap: 8px; padding: 12px; align-items: center; }

/* ---------- Minimize button + drag-to-resize handle (sidebar only) ---------- */
/* A quiet "−" button collapses the open sidebar (top-right). */
.pane-min { position: absolute; top: 12px; z-index: 8; width: 22px; height: 22px; padding: 0;
  border: 0; background: transparent; color: var(--muted); font-size: 1.25rem; line-height: 1;
  display: grid; place-items: center; border-radius: 6px; }
.pane-min:hover { color: var(--text); background: var(--bg-3); }
#sidebar .pane-min   { right: 7px; }
#app.left-collapsed  #sidebar .pane-min { display: none; }
/* Thin grab strip on the sidebar's inner edge; drag to resize. Hidden while collapsed. */
.resize-handle { position: absolute; top: 0; bottom: 0; width: 7px; z-index: 7; cursor: col-resize; }
.resize-handle:hover, .resize-handle.dragging { background: rgba(155,176,137,.30); }
.resize-left  { right: 0; }
#app.left-collapsed  .resize-left { display: none; }
.btn-primary { background: var(--btn); color: #fff; border: 0; border-radius: 10px; padding: 10px 14px; font-weight: 600; font-size: 0.875rem; }
.btn-primary:hover { filter: brightness(1.08); }
.btn-primary.send { padding: 0 18px; }
/* Per-response Stop — sits under the streaming bubble, abort just that model's turn. */
.bubble-stop { align-self: flex-start; margin-top: 8px; background: var(--bg-3); color: var(--danger);
  border: 1px solid var(--danger); border-radius: 8px; padding: 4px 12px; font-size: 0.75rem; font-weight: 600; cursor: pointer; }
.bubble-stop:hover { background: var(--danger); color: #fff; }
.btn-ghost { background: transparent; color: var(--muted); border: 1px solid var(--border); border-radius: 10px; padding: 9px 14px; }
.icon-btn { background: var(--bg-3); color: var(--text); border: 1px solid var(--border); border-radius: 9px; width: 38px; height: 38px; font-size: 0.9375rem; display: grid; place-items: center; }
.icon-btn:hover { border-color: var(--accent); }
#newChat { flex: none; }

.chat-list { flex: 1; overflow-y: auto; padding: 4px 8px; }
.chat-item { padding: 9px 10px; border-radius: 9px; cursor: pointer; display: flex; flex-direction: column; gap: 3px; position: relative; }
.chat-item:hover { background: var(--bg-2); }
.chat-item.active { background: var(--bg-3); }
.chat-item .title { font-size: 0.8438rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding-right: 60px; }
.chat-item .meta { font-size: 0.6875rem; color: var(--muted); display: flex; gap: 8px; }
.chat-item .row-actions { position: absolute; right: 6px; top: 7px; display: none; gap: 2px; }
.chat-item:hover .row-actions { display: flex; }
.chat-item .row-actions button { background: transparent; border: 0; color: var(--muted); padding: 3px 5px; border-radius: 6px; font-size: 0.8125rem; }
.chat-item .row-actions button:hover { background: var(--bg); color: var(--text); }

.sb-foot { padding: 16px 12px 18px; display: flex; flex-direction: column; align-items: flex-start; gap: 8px; font-size: 0.8125rem; }
.linklike { background: none; border: 0; padding: 0; color: var(--accent); font-size: 0.8125rem; cursor: pointer; }
.linklike:hover { text-decoration: underline; }
.pw-field { display: flex; flex-direction: column; gap: 6px; font-size: 0.8125rem; color: var(--muted); margin-bottom: 10px; }
.pw-field input { background: var(--field); border: 1px solid var(--border); color: var(--text); border-radius: 10px; padding: 10px 12px; font-size: 0.875rem; }
.pw-field input:focus { outline: none; border-color: var(--accent); }

/* Account / profile modal */
.profile-top { display: flex; gap: 16px; align-items: center; margin: 10px 0 16px; }
.profile-ava { width: 72px; height: 72px; border-radius: 50%; background: var(--user); display: grid; place-items: center;
  font-size: 2.375rem; line-height: 1; flex: none; overflow: hidden; }
.profile-ava-actions { display: flex; flex-direction: column; gap: 6px; align-items: flex-start; }
.profile-ava-hint { font-size: 0.6875rem; margin-top: 2px; }
.pw-error { color: var(--danger); font-size: 0.8125rem; background: rgba(239,91,107,.1); border: 1px solid rgba(239,91,107,.35); border-radius: 9px; padding: 8px 12px; margin-bottom: 8px; }
.pw-error[hidden] { display: none; }

/* ---------- Main (centre pane) ---------- */
#main { grid-column: 2; grid-row: 2; display: flex; flex-direction: column; min-width: 0; min-height: 0; position: relative;
  z-index: 3; background: var(--center); box-shadow: 0 0 26px 2px rgba(0,0,0,.55); }   /* centre pane; shadow cast OUT onto the side frames */
/* The top frame sits above everything and is never closeable. */
#topbar { display: flex; align-items: center; gap: 12px; padding: 10px 14px;
  background: var(--center); flex-wrap: wrap; position: relative; z-index: 5; }
/* Collapsing a side frame widens the reading column. */
#app.left-collapsed { --content-w: 1100px; }

/* ---------- Settings cog (far top-right) + model-settings modal ---------- */
/* The cog is an icon button (.icon-btn) like Share/Artifacts; only the SVG needs sizing. */
.settings-cog svg { width: 18px; height: 18px; display: block; }
/* Account chip + sign-out sit top-left; the action group (matter, cost, icons) is pushed right. */
#topbar .top-actions { margin-left: auto; }
.top-user { display: flex; align-items: center; gap: 10px; flex: none; }
/* Confidential banner — shown only while a session is open, centred in the top menu at 16px. */
.top-banner { display: none; }
#app.has-session .top-banner { display: block; flex: 1 1 auto; min-width: 0; text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-family: "Times New Roman", Times, serif; font-weight: 900; color: #c0151b; font-size: 1rem; letter-spacing: .08em; -webkit-text-stroke: 0.3px currentColor; }
.user-chip { display: inline-flex; align-items: center; gap: 8px; background: var(--bg-3); border: 1px solid var(--border);
  border-radius: 999px; padding: 4px 12px 4px 4px; color: var(--text); font-size: 0.8125rem; cursor: pointer; max-width: 240px; }
.user-chip:hover { border-color: var(--accent); }
.user-chip .user-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 150px; }
.user-ava { width: 26px; height: 26px; border-radius: 50%; background: var(--user); display: grid; place-items: center;
  font-size: 0.9375rem; line-height: 1; flex: none; overflow: hidden; }
.top-user .logout { color: var(--muted); text-decoration: none; font-size: 0.75rem; white-space: nowrap; }
.top-user .logout:hover { color: var(--accent); }
/* Uploaded avatar fills its round/rounded tile (chip, message, mention, profile). */
.ava-img { width: 100%; height: 100%; object-fit: cover; border-radius: inherit; display: block; }
/* Small avatar tile for user lists (Manage Users / Add collaborators) — uploaded pic or animal emoji. */
.row-ava { display: inline-grid; place-items: center; flex: none; width: 24px; height: 24px; border-radius: 6px; overflow: hidden; background: var(--bg-3); font-size: 0.9375rem; line-height: 1; vertical-align: middle; }
/* The settings modal stacks one control group per provider, divider between each. */
.settings-card { width: min(620px, 94vw); }
.settings-card .controls { flex-direction: column; flex-wrap: nowrap; flex: none; gap: 16px; margin-top: 6px; }
.settings-card .ctl-group { border-right: 0; border-bottom: 1px solid var(--border); padding: 4px 0 16px; }
.settings-card .ctl-group:last-child { border-bottom: 0; padding-bottom: 0; }

/* #ctlGroups is the only .controls container; it lives inside the settings modal (rule above). */
.controls { display: flex; gap: 10px 16px; align-items: flex-start; min-width: 0; }
/* One control group per provider; the brand icon sits inline with the Model/Effort/Thinking/Temp controls. */
.ctl-group { display: flex; gap: 10px; align-items: flex-start; flex-wrap: wrap; padding: 2px 10px 2px 0; border-right: 1px solid var(--border); }
.ctl-group:last-child { border-right: 0; }
/* Provider icon sits inline, on the SAME row as the Model/Effort/Thinking/Temp controls. */
.ctl-group > .ctl-head { align-self: center; font-size: 0.6562rem; letter-spacing: .05em; text-transform: uppercase; color: var(--accent); font-weight: 700; margin: 0 4px 0 0; }
/* Provider icon (replaces the "Claude (Anthropic)" / "ChatGPT (OpenAI)" text labels). */
.ctl-head img { height: 24px; width: auto; max-width: 130px; display: block; object-fit: contain; }
.ctl-head.emoji { font-size: 1.375rem; line-height: 24px; color: var(--text); }
.ctl { display: flex; flex-direction: column; font-size: 0.6562rem; color: var(--muted); gap: 3px; text-transform: uppercase; letter-spacing: .04em; }
/* Keep a control's label and its inline value (e.g. "Temp 0.7") on one line, above the input. */
.ctl-lbl { white-space: nowrap; }
.ctl select, .ctl input[type=range] { font-size: 0.8125rem; }
.ctl select { background: var(--bg-3); color: var(--text); border: 1px solid var(--border); border-radius: 8px; padding: 6px 8px; }
.ctl-check { flex-direction: row; align-items: center; gap: 6px; text-transform: none; letter-spacing: 0; font-size: 0.8125rem; color: var(--text); padding-top: 12px; }
.ctl.disabled { opacity: .4; pointer-events: none; }
.ctl input[type=range] { width: 90px; accent-color: var(--accent); }
.usage { display: flex; gap: 8px; }
.usage-chip { background: var(--bg-3); border: 1px solid var(--border); border-radius: 999px; padding: 6px 11px; font-size: 0.75rem; font-variant-numeric: tabular-nums; white-space: nowrap; cursor: pointer; }
.usage-chip:hover { border-color: var(--accent); }

/* ---------- Model-catalog freshness notice (admin) ---------- */
.model-notice { display: flex; gap: 12px; align-items: flex-start; justify-content: space-between;
  margin: 10px 20px 0; padding: 10px 14px; border: 1px solid var(--border); border-left: 3px solid var(--accent);
  border-radius: 10px; background: var(--bg-3); font-size: 0.8125rem; color: var(--text); }
.model-notice[hidden] { display: none; }   /* author rule must win over .model-notice{display:flex} so [hidden] hides it */
.model-notice .mn-body { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.model-notice .mn-row { line-height: 1.5; overflow-wrap: anywhere; }
.model-notice .mn-warn { color: var(--text); }
.model-notice .mn-info { color: var(--accent); }
.model-notice .mn-id { color: var(--muted); font-size: 0.75rem; }
.model-notice .mn-muted { color: var(--muted); }
.model-notice code { background: var(--bg); border: 1px solid var(--border); border-radius: 5px; padding: 0 5px; font-size: 0.75rem; }
.model-notice .mn-actions { display: flex; gap: 8px; align-items: center; flex: none; white-space: nowrap; }
.model-notice .mn-when { color: var(--muted); font-size: 0.6875rem; }
.model-notice .mn-recheck { background: var(--bg); color: var(--text); border: 1px solid var(--border); border-radius: 7px; padding: 4px 10px; font-size: 0.75rem; cursor: pointer; }
.model-notice .mn-recheck:hover { border-color: var(--accent); }
.model-notice .mn-x { background: transparent; border: 0; color: var(--muted); font-size: 0.9375rem; line-height: 1; cursor: pointer; padding: 2px 4px; }
.model-notice .mn-x:hover { color: var(--text); }

/* ---------- Messages ---------- */
.messages { flex: 1; overflow-y: auto; padding: 24px 0; }
.empty-state { height: 100%; display: grid; place-content: center; text-align: center; color: var(--muted); gap: 8px; }
.empty-logo { font-size: 1.75rem; font-weight: 700; color: var(--text); }

.msg { max-width: var(--content-w); margin: 0 auto 22px; padding: 0 20px; display: flex; gap: 14px; }
.msg .avatar { width: 45px; height: 45px; border-radius: 10px; flex: none; display: grid; place-items: center; font-size: 1.5rem; font-weight: 700; overflow: hidden; }
.msg.user .avatar { background: var(--user); }
.msg.assistant .avatar { background: var(--bg-3); color: var(--text); }
/* Every avatar sits on the same grey tile (inherited from .msg.assistant .avatar); brand logos
   just get a little padding so they don't run edge-to-edge. */
.msg.assistant.prov-anthropic .avatar,
.msg.assistant.prov-openai .avatar,
.msg.assistant.prov-gemini .avatar,
.msg.assistant.prov-perplexity .avatar { padding: 6px; }
/* The OpenAI mark has a white interior, so it reads on the dark tile as-is — do NOT invert it
   (inversion would blank out the white). Light mode also leaves it un-filtered. */
/* Nano Banana's avatar is the 🍌 emoji — give it room to read at glyph size. */
.msg.assistant.prov-gemini-image .avatar { font-size: 1.6875rem; }
.msg.assistant .avatar img { width: 100%; height: 100%; object-fit: contain; display: block; }
/* Fallback tile shown when a brand logo (.brand-ico) fails to load — a centered initial. */
.ico-letter { display: grid; place-items: center; width: 100%; height: 100%;
  min-width: 1.3em; min-height: 1.3em; font-weight: 700; font-size: .95em; line-height: 1; color: var(--text); }
.msg .body { min-width: 0; flex: 1; position: relative; }
.msg .name { font-size: 0.75rem; color: var(--muted); margin-bottom: 4px; display: flex; gap: 8px; align-items: center; padding-right: 26px; }
.msg .name .badge { background: var(--bg-3); border: 1px solid var(--border); border-radius: 6px; padding: 1px 7px; font-size: 0.6875rem; }
.msg .name .ts { font-variant-numeric: tabular-nums; opacity: .85; }
.msg.flash .bubble { animation: cc-flash 1.5s ease-out; }
@keyframes cc-flash { 0% { box-shadow: 0 0 0 2px var(--accent); } 100% { box-shadow: 0 0 0 0 rgba(0,0,0,0); } }
.bubble { background: var(--field); border: 1px solid var(--border); border-radius: var(--radius); padding: 12px 16px; overflow-wrap: anywhere; }
.msg.user .bubble { background: var(--field); }

/* Incognito toggle — top-right corner of every bubble. Hides this message from the model. */
.incognito-btn { position: absolute; top: -2px; right: 0; z-index: 2; width: 24px; height: 22px; padding: 0;
  background: transparent; border: 0; color: var(--muted); border-radius: 6px; display: grid; place-items: center;
  opacity: 0; transition: opacity .12s; cursor: pointer; }
.incognito-btn svg { width: 15px; height: 15px; display: block; }
.incognito-btn:hover { color: var(--text); background: var(--bg-3); }
.msg:hover .incognito-btn { opacity: 1; }
@media (hover: none) { .incognito-btn { opacity: 1; } }
.msg.no-seq .incognito-btn { display: none; }   /* no toggle until the message has a server seq */
/* An incognito (hidden-from-AI) message: lighter-grey bubble + an active toggle that stays visible. */
/* Incognito = lighter grey. .msg.hidden.peer beats the later, equal-specificity .msg.peer .gp-text rule. */
.msg.hidden .bubble, .msg.hidden.peer .gp-text { background: var(--bg-3); border-style: dashed; }
.msg.hidden .incognito-btn { opacity: 1; color: var(--accent-2); }

/* Markdown */
.bubble p { margin: 0 0 10px; }
.bubble p:last-child { margin-bottom: 0; }
.bubble h1, .bubble h2, .bubble h3 { margin: 14px 0 8px; line-height: 1.25; }
.bubble h1 { font-size: 1.4em; } .bubble h2 { font-size: 1.25em; } .bubble h3 { font-size: 1.1em; }
.bubble ul, .bubble ol { margin: 0 0 10px; padding-left: 22px; }
.bubble li { margin: 3px 0; }
.bubble a { color: var(--accent); }
.bubble code { background: var(--code-bg); border: 1px solid var(--border); border-radius: 5px; padding: 1px 5px; font-family: var(--mono); font-size: .9em; }
.bubble pre { background: var(--code-bg); border: 1px solid var(--border); border-radius: 10px; padding: 12px 14px; overflow-x: auto; position: relative; margin: 0 0 10px; }
.bubble pre code { background: none; border: 0; padding: 0; font-size: 0.8125rem; line-height: 1.5; }
.bubble blockquote { border-left: 3px solid var(--border); margin: 0 0 10px; padding-left: 12px; color: var(--muted); }
.bubble table { border-collapse: collapse; margin: 0 0 10px; font-size: 0.8125rem; }
.bubble th, .bubble td { border: 1px solid var(--border); padding: 5px 9px; }
.copy-btn { position: absolute; top: 6px; right: 6px; background: var(--bg-3); border: 1px solid var(--border); color: var(--muted); border-radius: 6px; padding: 3px 8px; font-size: 0.6875rem; opacity: 0; transition: opacity .15s; }
.bubble pre:hover .copy-btn { opacity: 1; }

.thinking { margin-bottom: 8px; border: 1px dashed var(--border); border-radius: 10px; overflow: hidden; }
.thinking summary { cursor: pointer; padding: 7px 12px; font-size: 0.7812rem; color: var(--muted); user-select: none; }
.thinking .think-body { padding: 0 12px 10px; font-size: 0.8125rem; color: var(--muted); white-space: pre-wrap; }

.attachments { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.att-chip { background: var(--bg-3); border: 1px solid var(--border); border-radius: 8px; padding: 4px 9px; font-size: 0.75rem; display: flex; gap: 6px; align-items: center; }

.files { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.file-chip { background: var(--bg-3); border: 1px solid var(--accent); border-radius: 9px; padding: 7px 12px; font-size: 0.8125rem; color: var(--text); text-decoration: none; display: inline-flex; gap: 8px; align-items: center; }
.file-chip:hover { background: var(--bg); }
/* Generated images (e.g. Nano Banana) render inside the bubble, scaled to its width — the bubble
   background is the frame. Multiple images stack with a small gap. */
.bubble-img-link { display: block; }
.bubble-img-link + .bubble-img-link { margin-top: 8px; }
.bubble-img { display: block; max-width: 100%; max-height: 70vh; height: auto; border-radius: 8px; }

.msg-foot { display: flex; gap: 8px; align-items: center; margin-top: 8px; flex-wrap: wrap; }
.msg-usage { font-size: 0.6875rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.dl-wrap { position: relative; }
.dl-menu { position: absolute; bottom: 28px; right: 0; background: var(--bg-3); border: 1px solid var(--border); border-radius: 9px; padding: 5px; display: none; flex-direction: column; min-width: 150px; z-index: 5; box-shadow: 0 12px 30px rgba(0,0,0,.4); }
.dl-menu.open { display: flex; }
.dl-menu button { background: transparent; border: 0; color: var(--text); text-align: left; padding: 7px 10px; border-radius: 6px; font-size: 0.8125rem; }
.dl-menu button:hover { background: var(--bg); }
.mini-btn { background: var(--bg-3); border: 1px solid var(--border); color: var(--muted); border-radius: 7px; padding: 4px 9px; font-size: 0.75rem; }
.mini-btn:hover { color: var(--text); border-color: var(--accent); }
.msg-error { color: var(--danger); font-size: 0.8125rem; background: rgba(239,91,107,.1); border: 1px solid rgba(239,91,107,.35); border-radius: 9px; padding: 8px 12px; margin-top: 8px; }

/* Copy / Quote / Download actions live INSIDE every bubble, as quiet icons in the bottom-right. */
.bubble-actions { display: flex; gap: 2px; align-items: center; justify-content: flex-end; margin-top: 10px; opacity: 0; transition: opacity .12s; }
.bubble-actions .act-btn { background: transparent; border: 0; color: var(--muted); border-radius: 6px;
  width: 26px; height: 24px; font-size: 0.875rem; line-height: 1; display: grid; place-items: center; cursor: pointer; }
.bubble-actions .act-btn:hover { color: var(--text); background: var(--bg-3); }
.bubble-actions .act-btn.ok { color: var(--good); }
.bubble-actions .act-btn svg { width: 15px; height: 15px; display: block; }
/* quote.png is a white glyph on transparent. A plain <img> works in every browser/CSP (a CSS mask
   does not). It's a touch larger than the line icons since its ink sits in the corners, and held at
   ~0.62 opacity so the white reads as the same muted grey as the copy/download icons (full on hover). */
.bubble-actions .act-btn img { width: 18px; height: 18px; display: block; opacity: .62; }
.bubble-actions .act-btn:hover img { opacity: 1; }
/* quote.png is WHITE ink — on the near-white light-mode bubble it would vanish. Invert it to dark so
   it reads like the other (currentColor) action icons. Applies in both desktop and mobile light mode. */
:root[data-theme="light"] .bubble-actions .act-btn img { filter: invert(1); }
.bubble-actions .act-btn .ico-fallback svg { width: 16px; height: 16px; display: block; }
/* The user's own bubbles keep their actions hidden until hover. */
/* Copy / Quote / Download / Reply reveal on hover for every bubble. */
.msg:hover .bubble-actions { opacity: 1; }
@media (hover: none) { .bubble-actions { opacity: 1; } }

.cursor::after { content: "▋"; animation: blink 1s step-end infinite; color: var(--accent); }
@keyframes blink { 50% { opacity: 0; } }

/* ---------- Composer ---------- */
#composer { padding: 12px 20px 16px; background: var(--center); position: relative; }
.composer-row { max-width: var(--content-w); margin: 0 auto; display: flex; gap: 8px; align-items: flex-end; position: relative; }
/* Left controls: the post-to-chat stack with the attach button at its bottom. */
.left-controls { display: flex; flex-direction: column; gap: 6px; align-self: flex-end; align-items: center; }
/* Post-to-chat stack: two blue paper-airplanes (normal / incognito), drag to reorder. The incognito
   one is the colour-inverse of normal; the one in use (Enter default) gets a chalk-green border. */
.peer-stack { display: flex; flex-direction: column; gap: 6px; }
.peer-ico { width: 44px; height: 44px; border-radius: 11px; background: var(--btn); border: 2px solid transparent;
  color: #fff; display: grid; place-items: center; padding: 0; position: relative; }
.peer-ico:hover { filter: brightness(1.08); }
.peer-ico svg { width: 18px; height: 18px; display: block; }
.peer-ico.incognito { background: #eef2f7; color: var(--btn); }            /* inverted colours = incognito */
.peer-ico.incognito:hover { background: #fff; filter: none; }
.peer-ico.is-default { border-color: var(--good); }                       /* chalk-green border = currently in use */
.peer-ico[draggable=true] { cursor: grab; }
.peer-ico.dragging { opacity: .4; }
.peer-ico.drop-before { box-shadow: 0 -3px 0 var(--good); }
.peer-ico.drop-after  { box-shadow: 0 3px 0 var(--good); }
#input {
  flex: 1; resize: none; background: var(--field); border: 1px solid var(--frame); color: var(--text);
  border-radius: 12px; padding: 14px; font-size: 0.9375rem; font-family: inherit;
  min-height: 144px; max-height: 320px; line-height: 1.5; overflow-y: auto;   /* = the three stacked send buttons (3×44 + 2×6) */
}
#input:focus { outline: none; border-color: var(--accent); }
.left-controls .icon-btn { align-self: center; width: 44px; }   /* attach sits under the chat-send stack */

/* Vertical, reorderable stack of model send-buttons (Anthropic / OpenAI / Fork=both). */
/* Send targets in a 2-column grid (filled row by row in send-order), so 5 providers + fork
   stay compact instead of one tall column. */
.send-stack { display: grid; grid-template-columns: repeat(2, 44px); grid-auto-flow: row; gap: 6px; justify-content: end; align-content: start; }
.send-stack.locked { opacity: .5; pointer-events: none; }
.send-ico { width: 44px; height: 44px; border-radius: 11px; background: var(--bg-3); border: 1px solid var(--border);
  display: grid; place-items: center; padding: 7px; position: relative; color: var(--text); }
.send-ico:hover { border-color: var(--accent); }
.send-ico svg, .send-ico img { width: 100%; height: 100%; display: block; object-fit: contain; }
.send-ico .emoji { font-size: 1.5rem; line-height: 1; display: grid; place-items: center; width: 100%; height: 100%; }
.send-ico[draggable=true] { cursor: grab; }
.send-ico.dragging { opacity: .4; }
.send-ico.drop-before { box-shadow: 0 -3px 0 var(--accent); }
.send-ico.drop-after  { box-shadow: 0 3px 0 var(--accent); }
.send-ico .grip { position: absolute; top: 1px; left: 0; right: 0; text-align: center; font-size: 0.5rem; line-height: 1; color: var(--muted); opacity: 0; }
.send-ico:hover .grip { opacity: .7; }
.send-stack:disabled, .send-stack.busy { opacity: .5; pointer-events: none; }
.attach-chips { max-width: var(--content-w); margin: 0 auto 8px; display: flex; flex-wrap: wrap; gap: 6px; }
.attach-chips:empty { display: none; margin: 0; }
.up-chip { background: var(--bg-3); border: 1px solid var(--border); border-radius: 8px; padding: 4px 8px; font-size: 0.75rem; display: flex; gap: 6px; align-items: center; }
.up-chip .x { cursor: pointer; color: var(--muted); }
.up-chip .x:hover { color: var(--danger); }
.up-chip.uploading { opacity: .6; }
.composer-hint { display: none; }   /* model summary line removed */
.pending-note { max-width: var(--content-w); margin: 0 auto 8px; font-size: 0.7812rem; color: #ffd9a0;
  background: rgba(255,176,32,.10); border: 1px solid rgba(255,176,32,.35); border-radius: 9px; padding: 7px 12px; text-align: center; }
.pending-note[hidden] { display: none; }
/* "Replying to <model>" banner above the composer while a follow-up to an LLM answer is staged. */
.reply-chip { max-width: var(--content-w); margin: 0 auto 8px; display: flex; align-items: center; gap: 8px;
  background: var(--bg-3); border: 1px solid var(--border); border-left: 3px solid var(--accent);
  border-radius: 9px; padding: 6px 10px; font-size: 0.7812rem; }
.reply-chip[hidden] { display: none; }
.reply-chip .reply-label { color: var(--accent); font-weight: 600; white-space: nowrap; }
.reply-chip .reply-snip { color: var(--muted); flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.reply-chip .reply-x { background: none; border: 0; color: var(--muted); cursor: pointer; font-size: 0.8125rem; line-height: 1; padding: 0 2px; }
.reply-chip .reply-x:hover { color: var(--text); }
/* Quote staged above the single composer (same look as the reply chip). */
.quote-chip { max-width: var(--content-w); margin: 0 auto 8px; display: flex; align-items: center; gap: 8px;
  background: var(--bg-3); border: 1px solid var(--border); border-left: 3px solid var(--accent); border-radius: 9px; padding: 6px 10px; font-size: 0.7812rem; }
.quote-chip[hidden] { display: none; }
.quote-chip .q-label { color: var(--accent); font-weight: 600; white-space: nowrap; }
.quote-chip .q-snip { color: var(--muted); flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.quote-chip .q-x { background: none; border: 0; color: var(--muted); cursor: pointer; font-size: 0.8125rem; line-height: 1; padding: 0 2px; }
.quote-chip .q-x:hover { color: var(--text); }
/* "New messages" pill — appears when a chat note arrives while you're scrolled up. */
.new-msg-pill { position: absolute; left: 50%; transform: translateX(-50%); top: -16px; background: var(--accent);
  color: #0c0e13; border: 0; border-radius: 999px; padding: 5px 14px; font-size: 0.75rem; font-weight: 600; cursor: pointer;
  box-shadow: 0 4px 14px rgba(0,0,0,.4); z-index: 6; }
.new-msg-pill[hidden] { display: none; }
/* @-mention autocomplete dropdown, anchored just above the textarea row (inside .composer-row). */
.mention-menu { position: absolute; left: 0; right: 0; bottom: calc(100% + 6px);
  background: var(--bg-3); border: 1px solid var(--border); border-radius: 10px; padding: 5px; z-index: 20;
  box-shadow: 0 -8px 30px rgba(0,0,0,.45); max-height: 260px; overflow-y: auto; }
.mention-menu[hidden] { display: none; }
.mention-item { display: flex; align-items: center; gap: 9px; padding: 7px 9px; border-radius: 7px; cursor: pointer; font-size: 0.8438rem; }
.mention-item.active, .mention-item:hover { background: var(--bg); }
.mention-item img { width: 20px; height: 20px; object-fit: contain; border-radius: 5px; background: #f4f1ea; padding: 2px; flex: none; }
.mention-item .m-ava { width: 20px; height: 20px; display: grid; place-items: center; background: var(--user); border-radius: 5px; font-size: 0.75rem; flex: none; }
.mention-item .m-ava-img { width: 20px; height: 20px; object-fit: cover; border-radius: 50%; flex: none; display: block; }
.mention-item .m-name { flex: 1; }
.mention-item .m-tag { font-size: 0.625rem; text-transform: uppercase; letter-spacing: .03em; color: var(--muted); border: 1px solid var(--border); border-radius: 5px; padding: 0 5px; }
/* @-mentions highlighted inside rendered messages. */
.mention { color: var(--accent); font-weight: 700; }
.send:disabled, .btn-primary:disabled { opacity: .45; cursor: not-allowed; filter: none; }

/* ---------- Modal ---------- */
.modal { position: fixed; inset: 0; background: rgba(0,0,0,.6); display: grid; place-items: center; z-index: 50; }
.modal[hidden] { display: none; }   /* author rule must win over .modal{display:grid} so [hidden] hides it */
.modal-card { background: var(--panel); border: 1px solid var(--border); border-radius: 14px; padding: 22px; width: min(560px, 92vw); }
.modal-card h3 { margin: 0 0 4px; }
.modal-card .muted { color: var(--muted); font-size: 0.8125rem; margin: 0 0 12px; }
.modal-card textarea { width: 100%; background: var(--field); border: 1px solid var(--border); color: var(--text); border-radius: 10px; padding: 12px; font-family: var(--mono); font-size: 0.8125rem; resize: vertical; }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 14px; }
.muted { color: var(--muted); }

/* ---------- Sidebar: admin toggle + shared/owner tags ---------- */
.sb-admin { display: flex; align-items: center; gap: 7px; padding: 4px 14px 8px; font-size: 0.7812rem; color: var(--muted); }
.sb-admin-btn { display: block; margin: 0 14px 8px; background: var(--bg-3); color: var(--text); border: 1px solid var(--border); border-radius: 8px; padding: 6px 10px; font-size: 0.7812rem; text-align: left; width: calc(100% - 28px); }
.sb-admin-btn:hover { border-color: var(--accent); }
.sb-nav-btn { display: block; margin: 0 12px 6px; background: var(--bg-3); color: var(--text); border: 1px solid var(--border); border-radius: 8px; padding: 7px 10px; font-size: 0.8125rem; text-align: left; width: calc(100% - 24px); }
.sb-nav-btn:hover { border-color: var(--accent); }
.matter-chip { color: var(--accent); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }

/* ---------- Usage & billing ---------- */
.usage-card { width: min(780px, 94vw); }
.usage-filters { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; margin-bottom: 12px; }
.usage-filters label { font-size: 0.75rem; color: var(--muted); display: flex; align-items: center; gap: 6px; }
.usage-filters input[type=date], .usage-filters select { background: var(--bg-2); border: 1px solid var(--border); color: var(--text); border-radius: 8px; padding: 6px 8px; font-size: 0.8125rem; }
.usage-filters .btn-primary { padding: 7px 14px; }
.usage-summary { max-height: 46vh; overflow-y: auto; }
.usage-summary h4 { margin: 14px 0 6px; font-size: 0.8125rem; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.usage-tot { font-size: 0.9375rem; }
.usage-tot b { font-size: 1.125rem; }
.u-table { width: 100%; border-collapse: collapse; font-size: 0.8125rem; font-variant-numeric: tabular-nums; }
.u-table th { text-align: left; color: var(--muted); font-weight: 500; border-bottom: 1px solid var(--border); padding: 5px 8px; }
.u-table td { padding: 5px 8px; border-bottom: 1px solid var(--bg-3); }
.usage-invoice-row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border); }
.usage-invoice-row label { font-size: 0.75rem; color: var(--muted); display: flex; align-items: center; gap: 6px; }
.usage-invoice-row select { background: var(--bg-2); border: 1px solid var(--border); color: var(--text); border-radius: 8px; padding: 6px 8px; font-size: 0.8125rem; }
.users-list { display: flex; flex-direction: column; gap: 6px; margin: 0 0 14px; max-height: 320px; overflow-y: auto; }
.user-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; background: var(--bg-2); border: 1px solid var(--border); border-radius: 9px; padding: 8px 11px; flex-wrap: wrap; }
.user-name { font-size: 0.8438rem; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.user-acts { display: flex; gap: 6px; flex-wrap: wrap; }
.user-acts button { background: var(--bg-3); border: 1px solid var(--border); color: var(--muted); border-radius: 7px; padding: 4px 9px; font-size: 0.75rem; }
.user-acts button:hover { color: var(--text); border-color: var(--accent); }
.user-acts button.danger:hover { color: var(--danger); border-color: var(--danger); }
.src-tag { background: var(--bg-3); border: 1px solid var(--border); color: var(--muted); border-radius: 6px; padding: 0 6px; font-size: 0.625rem; text-transform: uppercase; letter-spacing: .03em; }
/* Admin: per-user animal-icon picker — expands onto its own line under the user row. */
.animal-picker { flex-basis: 100%; display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; padding-top: 8px; border-top: 1px dashed var(--border); }
.animal-picker[hidden] { display: none; }
.animal-opt { background: var(--bg-3); border: 1px solid var(--border); border-radius: 7px; padding: 3px 6px; font-size: 1.0625rem; line-height: 1.2; cursor: pointer; }
.animal-opt:hover { border-color: var(--accent); }
.animal-opt.sel { border-color: var(--accent); background: var(--bg); }
.animal-default { font-size: 0.75rem; color: var(--muted); padding: 4px 9px; }
.animal-note { flex-basis: 100%; font-size: 0.6875rem; margin-top: 4px; }
.user-add { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 10px; }
.user-add input[type=text], .user-add input[type=password] { flex: 1; min-width: 120px; background: var(--field); border: 1px solid var(--border); color: var(--text); border-radius: 9px; padding: 9px 11px; font-size: 0.875rem; }
.user-add input:focus { outline: none; border-color: var(--accent); }
.role-tag { background: var(--accent-2); color: #fff; border-radius: 6px; padding: 0 6px; font-size: 0.625rem; font-weight: 600; text-transform: uppercase; letter-spacing: .03em; }
.shared-badge { font-size: 0.6875rem; margin-right: 4px; }
.owner-note { color: var(--accent); }

/* ---------- Topbar actions ---------- */
.top-actions { display: flex; gap: 6px; align-items: center; }
.top-actions .icon-btn { position: relative; }
.icon-btn:disabled { opacity: .35; pointer-events: none; }
.icon-btn.shared { border-color: var(--accent); }
.top-actions .count { font-size: 0.625rem; margin-left: 2px; color: var(--accent); font-weight: 600; }
/* Session members shown in the topbar (right of the matter, left of the action icons). */
.top-actions .member-list { font-size: 0.6875rem; color: var(--muted); max-width: 200px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.top-actions .member-list:empty { display: none; }
/* Topbar "more" overflow sheet (mobile only; desktop shows the actions inline). */
.top-more { display: none; }
.more-sheet { display: flex; flex-direction: column; gap: 2px; padding: 8px; }
.more-item { display: flex; align-items: center; gap: 12px; width: 100%; text-align: left; background: transparent; border: 0; color: var(--text); font-size: 1rem; padding: 14px 12px; border-radius: 10px; text-decoration: none; cursor: pointer; }
.more-item:hover { background: var(--bg-3); }
/* The session $cost (moved off the mobile topbar) rides at the right of the "Usage & billing" row. */
.more-item .mi-cost { margin-left: auto; color: var(--muted); font-variant-numeric: tabular-nums; font-size: 0.8125rem; }
.more-item .mi-cost:empty { display: none; }
.more-item .mi-ico { width: 22px; text-align: center; font-size: 1.15rem; flex: none; }
.more-close { justify-content: center; color: var(--muted); margin-top: 4px; }

/* ---------- Chat (peer) notes, rendered inline in the one conversation ---------- */
/* A peer note adopts the standard .msg row layout (avatar + body). Its text sits in a recessed,
   dashed card so it reads as side-channel chat that is NOT sent to the AI (vs solid .bubble LLM rows). */
.msg.peer .avatar { background: var(--user); }
.msg.peer .gp-author { font-size: 0.75rem; color: var(--muted); margin-bottom: 4px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; padding-right: 26px; }
.msg.peer .gp-text { font-size: 0.875rem; overflow-wrap: anywhere; background: var(--field); border: 1px dashed var(--border); border-radius: var(--radius); padding: 10px 14px; }
.msg.peer .gp-text p { margin: 0 0 6px; } .msg.peer .gp-text p:last-child { margin: 0; }
/* Your own chat notes carry an accent left-edge so they're distinguishable from others'. */
.msg.peer.me .gp-text { border-left: 3px solid var(--accent); }
.msg.peer.flash .gp-text { animation: cc-flash 1.5s ease-out; }
.msg.peer .gp-reply { background: transparent; border: 0; color: var(--accent); cursor: pointer; font-size: 1rem; font-weight: 700; line-height: 1; padding: 0 4px; }
.msg.peer .gp-reply:hover { color: var(--text); }
.msg.peer .gp-foot { margin-top: 6px; display: flex; gap: 6px; align-items: center; justify-content: flex-end; opacity: 0; transition: opacity .12s; }
.msg.peer:hover .gp-foot { opacity: 1; }
@media (hover: none) { .msg.peer .gp-foot { opacity: 1; } }
.msg.peer .gp-foot:empty { display: none; }
.msg.peer .gp-foot .mini-btn { padding: 2px 8px; font-size: 0.6875rem; }
.msg.peer .gp-msg-fwd { display: flex; gap: 4px; align-items: center; }
.msg.peer .gp-msg-fwd-ico { width: 16px; height: 16px; padding: 0; border: 0; background: transparent; cursor: pointer; display: grid; place-items: center; opacity: .85; }
.msg.peer .gp-msg-fwd-ico:hover { opacity: 1; }
.msg.peer .gp-msg-fwd-ico img { width: 100%; height: 100%; object-fit: contain; display: block; }
.msg.peer .gp-msg-fwd-ico .emoji { font-size: 0.875rem; line-height: 1; }
/* Quote block embedded in a peer note (click to jump to the quoted source message). */
.msg.peer .gp-quote-block { border-left: 3px solid var(--accent); background: rgba(127,127,127,.10); border-radius: 6px; padding: 5px 9px; margin-bottom: 6px; cursor: pointer; }
.msg.peer .gp-quote-block:hover { background: rgba(127,127,127,.18); }
.msg.peer .gp-quote-from { font-size: 0.6562rem; color: var(--accent); font-weight: 600; margin-bottom: 2px; }
.msg.peer .gp-quote-body { font-size: 0.75rem; color: var(--muted); overflow-wrap: anywhere; }

/* Inline session rename — click the title to edit it in place. */
.chat-item .title.editable { cursor: text; }
.chat-item .title-edit { width: 100%; font: inherit; font-size: 0.8438rem; background: var(--field); border: 1px solid var(--accent); color: var(--text); border-radius: 6px; padding: 2px 6px; }
.chat-item .title-edit:focus { outline: none; }

/* The per-message "Quote" affordance is quiet on inputs; the assistant footer always shows it */
.msg-foot:empty { display: none; }
.msg.user .msg-foot { opacity: 0; transition: opacity .12s; }
.msg.user:hover .msg-foot { opacity: 1; }
@media (hover: none) { .msg.user .msg-foot { opacity: 1; } }

/* ---------- Share + Artifacts lists ---------- */
.share-list { display: flex; flex-direction: column; gap: 6px; margin: 0 0 12px; max-height: 220px; overflow-y: auto; }
.modal-card h4 { margin: 8px 0 6px; font-size: 0.8125rem; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.share-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; background: var(--bg-2); border: 1px solid var(--border); border-radius: 9px; padding: 8px 11px; font-size: 0.8438rem; }
.mini-btn.primary { background: var(--btn); color: #fff; border-color: var(--btn); }
.art-list { display: flex; flex-direction: column; gap: 8px; max-height: 360px; overflow-y: auto; }
.art-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; background: var(--bg-2); border: 1px solid var(--border); border-radius: 9px; padding: 9px 12px; flex-wrap: wrap; }
.art-row .muted { font-size: 0.7188rem; }

/* ---------- Sidebar header / new-session / collapsed strip ---------- */
.sb-head { padding: 14px 12px 2px; }
/* List icon pinned to the top-left corner of the left pane — same spot whether open or collapsed. */
.sb-listicon { position: absolute; top: 14px; left: 7px; z-index: 7; color: var(--muted); display: inline-flex; }
.sb-listicon svg { width: 20px; height: 20px; }
.sb-new { margin: 46px 12px 10px; display: flex; align-items: center; justify-content: center; gap: 6px; white-space: nowrap; }
.sb-new .ico { display: none; font-size: 1.125rem; line-height: 1; }
/* Collapsed left frame: only the corner icon and a square "+" remain. */
#app.left-collapsed #sidebar .sb-new { margin: 120px auto 0; width: 24px; height: 24px; min-width: 0; padding: 0; }
#app.left-collapsed #sidebar .sb-new .lbl { display: none; }
#app.left-collapsed #sidebar .sb-new .ico { display: block; }

/* ---------- Bottom-left pane: nav buttons sit above the identity row ---------- */
.sb-foot .sb-nav-btn { margin: 0 0 6px; width: 100%; }

/* ---------- Top: editable client/matter text (left) + right-aligned actions ---------- */
.matter-text { font-size: 0.8125rem; color: var(--accent-2); cursor: text; border: 1px dashed transparent; border-radius: 6px; padding: 3px 7px; white-space: nowrap; max-width: 300px; overflow: hidden; text-overflow: ellipsis; }
.matter-text:hover { border-color: var(--border); }
.matter-text.locked { cursor: default; }
.matter-text.locked:hover { border-color: transparent; }
.matter-text .ph { color: var(--muted); }
.matter-edit { display: inline-flex; gap: 6px; align-items: center; }
.matter-edit input { font: inherit; font-size: 0.8125rem; background: var(--field); border: 1px solid var(--accent); color: var(--text); border-radius: 6px; padding: 3px 7px; }
.matter-edit input.num { width: 130px; } .matter-edit input.name { width: 200px; }

/* ---------- Brand ---------- */
.empty-sub { font-family: "Times New Roman", Times, serif; font-weight: 900; color: #c0151b; font-size: 1.5rem; letter-spacing: .08em; margin: -2px 0 8px; -webkit-text-stroke: 0.4px currentColor; }

/* ---------- Mobile / touch: side frames become off-canvas overlays ----------
   Keyed off (pointer:coarse) too, NOT width alone: on iOS, a single element wider
   than the viewport can blow the layout viewport past 860px, which would silently
   drop these rules and fall back to the desktop grid (the "shrunk desktop" bug).
   pointer:coarse is width-independent, so a phone keeps the mobile layout regardless. */
@media (max-width: 860px), (pointer: coarse) {
  #app { grid-template-columns: minmax(0, 1fr); }   /* minmax(0,…), not 1fr (= minmax(auto,1fr)): the auto-min let wide content stretch the column past the viewport */
  /* Single column: keep the centre pane in column 1 (side frames are fixed overlays). */
  #main { grid-column: 1; }
  #sidebar { position: fixed; top: 0; height: 100vh; z-index: 40; width: min(280px, 86vw); left: 0; }
  /* Collapsed → a slim strip at the edge showing just the corner icon; tap it to open. */
  #app.left-collapsed #sidebar { display: none; }   /* phone: a closed drawer is fully hidden (chat is full-width); the topbar hamburger / tapping a session opens it */
  #app:not(.left-collapsed)  #sidebar     { box-shadow: 0 0 0 100vmax rgba(0,0,0,.45); }
  .resize-handle { display: none; }   /* no drag-resize on touch */
  .usage { width: 100%; }
}


/* ===========================================================================
   MOBILE BUILD (appended; source-order overrides win, desktop preserved).
   Honors enlarged text (rem type + dvh + no fixed text-box heights on touch),
   keeps both the light and dark "chalkboard" themes, and turns the composer
   into the paperclip-outside / @-textarea-airplane in-field layout on touch.
   =========================================================================== */

/* Respect the user's browser/OS text-size preference. Every font-size in this
   sheet is now rem, so that preference flows through; body is 0.9375rem
   (= 15px at a 16px default) so desktop renders pixel-identical to before. */
html { font-size: 100%; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

/* Dynamic viewport: the composer no longer hides under mobile browser chrome. */
#app { height: 100dvh; }

/* Safety net: never let a too-wide element (e.g. a long matter name or member
   list in the topbar) make the page wider than the screen. On iOS Safari a page
   wider than the layout viewport triggers a zoom-out-to-fit that renders the whole
   app as a shrunk desktop layout (pinch-to-zoom) even though (max-width:860px)
   matches. Clipping horizontal overflow at the root pins the page to device width.
   Intentional horizontal scrollers (code blocks, tables, usage table) keep their
   own inner overflow-x:auto, so no content is lost. */
html, body { overflow-x: hidden; }

/* Modals scroll internally instead of clipping a tall card off-screen. */
.modal-card { max-height: 90dvh; overflow-y: auto; }
.usage-summary { overflow-x: auto; }
/* Wide markdown tables scroll inside their bubble rather than the whole page. */
.bubble table { display: block; overflow-x: auto; max-width: 100%; }

/* Composer clears the iOS home indicator. */
#composer { padding-bottom: max(16px, env(safe-area-inset-bottom)); }

/* Login fields stay >= 16px so iOS never zooms on focus (they still scale up). */
.login-card input, .login-card button { font-size: max(1rem, 16px); }

/* The new in-field controls + mobile chrome are hidden until a touch / small screen. */
.input-field { display: contents; }   /* transparent on desktop: textarea stays a flex child */
.field-btn, .field-left, .field-right, #navBtn.nav-btn, .drawer-scrim, .hidden-pill { display: none; }

/* ---- Small-screen / touch tier: layout. Also keyed off pointer:coarse (see the
   note above) so a viewport blow-out can't disengage the mobile layout on a phone. ---- */
@media (max-width: 860px), (pointer: coarse) {
  #sidebar { height: 100dvh; }
  /* Real, tappable backdrop behind the open drawer (replaces the box-shadow scrim). */
  #app:not(.left-collapsed) #sidebar { box-shadow: none; }
  #app:not(.left-collapsed) .drawer-scrim { display: block; position: fixed; inset: 0; background: rgba(0,0,0,.45); z-index: 39; }
  #navBtn.nav-btn { display: grid; }
  /* Usage & Manage Users moved into the ⋯ menu, so drop the sidebar footer on mobile (the buttons
     stay in the DOM — the ⋯ "Manage users" item triggers the hidden #usersBtn). */
  .sb-foot { display: none; }
  .msg { padding: 0 12px; gap: 10px; }
  /* The chat feed scrolls VERTICALLY only. overflow-y:auto makes the browser compute overflow-x:auto
     too, turning .messages into its own horizontal scroller (the page-level overflow-x:hidden can't
     reach inside it) — that was the left/right scroll + blank gutter on the right. Inner scrollers
     (code blocks, tables) keep their own overflow-x:auto, so nothing wide is lost. */
  .messages { overflow-x: hidden; }
  /* The "forward this note to a model" LLM icons under a chat bubble — 50% larger on touch (16→24px). */
  .msg.peer .gp-msg-fwd-ico { width: 24px; height: 24px; }
  .msg.peer .gp-msg-fwd-ico .emoji { font-size: 1.3rem; }
  /* Modals dock to the bottom as sheets. */
  .modal { place-items: end center; }
  .modal-card { width: 100%; max-width: 100%; border-radius: 14px 14px 0 0; padding-bottom: max(22px, env(safe-area-inset-bottom)); }
  /* Dense modal internals stack instead of overflowing a narrow screen. */
  .usage-filters, .usage-invoice-row, .user-add { flex-direction: column; align-items: stretch; }
  .settings-card .ctl-group { flex-direction: column; }
  .ctl input[type=range] { width: 100%; }
  /* Cap long topbar text to the available width so it ellipsizes, instead of
     stretching the page wider than the screen. (Was max-width:none, which on these
     white-space:nowrap elements let a long matter name / member list / display name
     run off on one line and force horizontal overflow. This is ONE of three wide-content
     sources behind the "shrunk desktop" symptom — see also .top-actions and the brand
     text below, plus the minmax(0,1fr) grid track fix — confirmed via #ccdiag.) */
  .top-user { min-width: 0; flex-shrink: 1; }
  .user-chip { max-width: 100%; min-width: 0; }
  .matter-text, .top-actions .member-list, .user-chip .user-name { max-width: 100%; min-width: 0; }
  /* ---- Phase 3: compact single-row mobile topbar (it used to wrap to ~half the screen). ----
     Zones: [☰ sessions] · [matter title — flex] · [⋯]. The account chip, theme, sign-out,
     members/share, artifacts, the settings cog, and the $cost chip all move into the ⋯ sheet
     (#moreSheet) — the cost is surfaced on that sheet's "Usage & billing" row. */
  #topbar { flex-wrap: nowrap; gap: 6px; padding: 8px 10px; }
  /* Top icon buttons (☰ / ⋯) get the same fill as the text input field. The #topbar ID keeps this
     winning over the light-mode "transparent .icon-btn" rule. */
  #topbar .icon-btn { background: var(--field); }
  #topbar .top-user, #topbar #shareBtn, #topbar #artBtn, #topbar #settingsBtn, #topbar .usage { display: none; }
  #app #topbar .top-banner { display: none; }   /* out-specifies #app.has-session .top-banner */
  #topbar .top-actions { margin-left: 0; flex: 1; min-width: 0; gap: 6px; flex-wrap: nowrap; align-items: center; }
  .top-actions .member-list { display: none; }
  .matter-text { flex: 1; min-width: 0; }
  .usage { width: auto; }
  .top-more { display: grid; font-size: 1.4rem; line-height: 1; }
  /* Empty-state brand wraps to the screen instead of sizing to its unwrapped single-line
     max-content (.empty-state is place-content:center, so the line never wrapped —
     "PRIVILEGED & CONFIDENTIAL" measured 366px on a 320px iPhone: the +46px overflow). */
  .empty-logo, .empty-sub { max-width: calc(100vw - 32px); overflow-wrap: anywhere; }
  .empty-sub { font-size: 1.125rem; }
}

/* ---- Mobile composer tier: triggers on a NARROW VIEWPORT or any touch device, so the redesigned
   composer reliably appears on phones even if the browser doesn't report pointer:coarse. ---- */
@media (max-width: 860px), (pointer: coarse) {
  /* The desktop drag stacks are touch-dead; hide them and use the in-field controls. */
  .composer-row .peer-stack, .composer-row .send-stack { display: none; }

  /* Padding below the input field, halved (16px → 8px); safe-area floor kept for the home indicator. */
  #composer { padding-bottom: max(8px, env(safe-area-inset-bottom)); }

  /* The bordered field wraps @ + textarea + hidden-toggle + airplane. */
  .input-field {
    display: flex; align-items: flex-end; gap: 4px; flex: 1; min-width: 0; position: relative;
    border: 1px solid var(--frame); background: var(--field); border-radius: 20px;
    /* 2px on left/right/bottom = the @ and send gaps in the bottom corners.
       Top stays 0 so the 4-line textarea drives the height. */
    padding: 0 2px 2px;
  }
  .input-field.hidden-armed { border-style: dashed; border-color: var(--accent-2); border-width: 1.5px; }

  /* 📎 attach moves INTO the field, stacked above @, as a compact left column; the old
     outside attach/peer column is removed on touch. */
  .composer-row .left-controls { display: none; }
  /* Both side columns get the SAME fixed width so the textarea is centered between them. */
  .field-left { display: flex; flex-direction: column; flex: none; gap: 2px; width: 2.5rem; }
  .field-left .field-btn { width: 1.9rem; height: 1.6rem; min-width: 30px; min-height: 26px; border-radius: 8px; }
  .field-left .field-btn svg { width: 16px; height: 16px; }
  /* 📎 attach is pinned to the TOP-LEFT corner (out of flow). The .field-left ancestor selector keeps
     this winning over the later .field-btn { position: relative } rule. */
  .field-left .attach-in-field { position: absolute; top: 4px; left: 2px; z-index: 1; font-size: 1.05rem; }
  /* @ sits flush in the bottom-left corner (place-items end/start pushes the glyph into the corner of
     its button). Zero padding so its gap to the field's left/bottom edges equals the send button's
     (both are then just the field's 6px padding). */
  .field-left .at-btn { width: 2.5rem; height: 2.5rem; min-width: 40px; min-height: 40px; font-size: 2.25rem; line-height: 1;
    place-items: end start; padding: 0 0 2px 0; }

  /* The paper-airplane send is the only thing left in .field-right flow → it sits bottom-right.
     The incognito (Hidden-from-AI) toggle is pinned to the TOP-RIGHT corner (out of flow), so it
     stays fixed there as the textarea grows. The .field-right ancestor selector keeps this winning
     over the later .field-btn sizing/position rules. */
  /* Same width as .field-left (centers the textarea); send is right-aligned so it keeps its 6px
     gap from the right border (matching the 6px bottom gap). */
  .field-right { display: flex; flex-direction: column; align-items: flex-end; flex: none; gap: 4px; width: 2.5rem; }
  .field-right .hide-toggle { position: absolute; top: 4px; right: 2px; z-index: 1; width: 2rem; height: 2rem; min-width: 32px; min-height: 32px; border-radius: 50%; }

  /* Default = one line (fits the content); grows to 2 lines max then scrolls. Line-height based
     so it tracks text size; font-size max(1rem,16px) never drops below the iOS no-zoom floor. */
  #input {
    border: 0; background: transparent; border-radius: 0; padding: 6px 2px 0; align-self: flex-start;
    /* Four text lines tall (fixed), with no bottom padding so the text fills down to the bottom edge. */
    min-height: calc(1.5em * 4 + 6px); max-height: calc(1.5em * 4 + 6px);
    font-size: max(1rem, 16px); line-height: 1.5; flex: 1; min-width: 0;
  }

  .field-btn {
    display: grid; place-items: center; flex: none; border: 0; background: transparent;
    width: 2.75rem; height: 2.75rem; min-width: 44px; min-height: 44px; padding: 0;
    color: var(--muted); border-radius: 50%; position: relative;
  }
  .field-btn svg { width: 20px; height: 20px; display: block; }
  .at-btn { font-size: 1.25rem; font-weight: 700; }
  .hide-toggle[aria-pressed="true"] { color: var(--accent-2); background: var(--bg-3); }

  /* Paper-airplane send: filled chalk-blue; inverts to incognito colours when Hidden is armed. */
  .send-air { background: var(--btn); color: #fff; width: 2.2rem; height: 2.2rem; min-width: 35px; min-height: 35px; }
  .send-air svg { width: 20px; height: 20px; }
  .send-air.incognito { background: #eef2f7; color: var(--btn); }
  /* Visible "holding..." ramp while the user presses to arm Hidden. */
  .send-air.holding { box-shadow: 0 0 0 3px var(--accent-2); }
  /* When the live text @mentions a model, tint the plane so a tap clearly routes to the AI. */
  .send-air.routes-llm { background: var(--accent); }

  /* Attach sits OUTSIDE the field, to its left, as a round button; bump touch targets. */
  .composer-row .left-controls .icon-btn { border-radius: 50%; }
  .icon-btn { width: 44px; height: 44px; }

  /* "Hidden from AI - team only" status pill above the row — shown only while armed. */
  .hidden-pill.armed {
    display: flex; align-items: center; gap: 5px; align-self: flex-start;
    font-size: 0.6875rem; font-weight: 700; color: var(--accent-2);
    background: var(--bg-3); border-radius: 999px; padding: 3px 10px; margin: 0 0 6px;
  }
  .hidden-pill.armed svg { width: 13px; height: 13px; display: block; }
}

/* The inverted incognito airplane needs a visible outline on the light theme,
   matching the existing .peer-ico.incognito treatment. */
:root[data-theme="light"] .send-air.incognito { border: 1px solid var(--btn); }
