/* ══════ VARIABLES & RESET ══════ */
:root {
  --bg:#e8e8e8; --bg2:#e0e0e0; --bg3:#f1f1f1; --border:#d8d3cb;
  --text:black; --text2:#6b6460; --text3:#a8a29e;
  --accent:lightgray; --accent2:#6e6e6e; --acc-text:#fff;
  --accent-btn:#4a6fa5; --accent-btn2:#3d5c8a; --accent-btn-text:#fff;
  --user-bg:#3a3a3a; --user-fg:#fff; --ai-bg:#ede9e3; --ai-fg:#1c1917;
  --input-bg:#fff; --remote:#3b82f6;

  --shadow:0 1px 3px rgba(0,0,0,.10); --shadow-lg:0 4px 20px rgba(0,0,0,.14);
  --r:4px; --left-w:272px;
  --font:'DM Sans',system-ui,sans-serif; --mono:'DM Mono','Courier New',monospace;
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg:#181614; --bg2:#211f1c; --bg3:#2d2a27; --border:#3a3632;
    --text:#e8e3dc; --text2:#9a948d; --text3:#5c5751;
    --accent:#b8b8b8; --accent2:#d0d0d0; --accent-btn:#5b84bd; --accent-btn2:#71a0da; --user-bg:#3a3a3a; --user-fg:#e8e3dc;
    --ai-bg:#211f1c; --ai-fg:#e8e3dc; --input-bg:#2a2724; --remote:#5b9bf8;
    --scene-tint:rgba(255,238,205,.038); --scene-line:#544c3e;
    --shadow:0 1px 3px rgba(0,0,0,.3); --shadow-lg:0 4px 20px rgba(0,0,0,.5);
  }
}
*,*::before,*::after { box-sizing:border-box; margin:0; padding:0; }
html,body { height:100%; overflow:hidden; font-family: "sans-serif"; }
body { font-family:var(--font); color:var(--text); background:var(--bg); -webkit-font-smoothing:antialiased; }
button,input,textarea,select { font-family:var(--font); }
button { cursor:pointer; }
a { color:var(--accent); }
::-webkit-scrollbar { width:5px; height:5px; }
::-webkit-scrollbar-track { background:transparent; }
::-webkit-scrollbar-thumb { background:var(--border); border-radius:3px; }
::-webkit-scrollbar-thumb:hover { background:var(--text3); }

/* ══════ BASE COMPONENTS ══════ */
.btn { display:inline-flex; align-items:center; gap:.35rem; padding:.35rem .7rem; border-radius:var(--r);
  background:var(--bg3); border:1px solid var(--border); color:var(--text); font-size:13px; font-weight:500; line-height:1;
  white-space:nowrap; }
.btn:hover { background:var(--border); }
.btn:disabled { opacity:.45; cursor:default; }
.btn-primary { background:var(--accent-btn); border-color:transparent; color:var(--accent-btn-text); }
.btn-primary:hover { background:var(--accent-btn2); }
.btn-danger { color:#e44; border-color:transparent; background:transparent; }
.btn-danger:hover { background:rgba(228,68,68,.1); }
.btn-icon { padding:.3rem .45rem; font-size:14px; background:transparent; border-color:transparent; color:var(--text2); }
.btn-icon:hover { background:var(--bg3); color:var(--text); }

.field { margin-bottom:.7rem; }
.field label { display:block; font-size:11.5px; font-weight:600; letter-spacing:.04em; text-transform:uppercase; color:var(--text3); margin-bottom:.3rem; }
.field label .sub { font-weight:400; text-transform:none; letter-spacing:0; opacity:.6; }
.field input,.field textarea,.field select { width:100%; padding:.5rem .65rem; border-radius:var(--r);
  background:var(--input-bg); border:1.5px solid var(--border); color:var(--text); outline:none; }
.field input:focus,.field textarea:focus,.field select:focus { border-color:var(--accent); }
.field textarea { resize:vertical; min-height:80px; line-height:1.5; }
.field select option { background:var(--bg2); }
.field .hint { font-size:11.5px; color:var(--text3); margin-top:.25rem; }
/* Keyboard-shortcuts help overlay (the ? modal). */
.kbd-row { display:flex; align-items:center; justify-content:space-between; gap:1rem; padding:.4rem 0; border-bottom:1px solid var(--border); }
.kbd-row:last-child { border-bottom:none; }
.kbd-desc { font-size:13px; color:var(--text2); }
kbd { font-family:var(--mono); font-size:11.5px; background:var(--bg3); border:1px solid var(--border); border-radius:var(--r); padding:.15rem .45rem; color:var(--text); white-space:nowrap; }
.field-row { display:flex; gap:.6rem; }
.field-row > .field { flex:1; }
.section-label { font-size:11px; font-weight:600; letter-spacing:.06em; text-transform:uppercase; color:var(--accent); margin:1.1rem 0 .6rem; padding-bottom:.3rem; border-bottom:1px solid var(--border); }
/* Collapsible provider sub-section (a module's settings nested under a parent section). */
.settings-sub { margin:1.1rem 0 .6rem; }
.settings-sub > summary { list-style:none; cursor:pointer; user-select:none; display:flex; align-items:center; gap:.4rem;
  font-size:11px; font-weight:600; letter-spacing:.06em; text-transform:uppercase; color:var(--text2);
  padding-bottom:.3rem; border-bottom:1px solid var(--border); }
.settings-sub > summary::-webkit-details-marker { display:none; }
.settings-sub > summary::before { content:'▸'; font-size:9px; opacity:.8; }
.settings-sub[open] > summary::before { transform:rotate(90deg); }
.settings-sub > summary:hover { color:var(--accent2); }
.settings-sub[open] > summary { margin-bottom:.6rem; }
.section-label:first-child { margin-top:0; }
/* Top-level Settings accordion: one pane open at a time via native [name] grouping. */
.settings-acc { margin:0; }
.settings-acc + .settings-acc, .settings-acc:first-child { border-top:1px solid var(--border); }
.settings-acc > summary { list-style:none; cursor:pointer; user-select:none; display:flex; align-items:center; gap:.45rem;
  font-size:11px; font-weight:600; letter-spacing:.06em; text-transform:uppercase; color:var(--text2);
  padding:.7rem 0 .65rem; }
.settings-acc > summary::-webkit-details-marker { display:none; }
.settings-acc > summary::before { content:'▸'; font-size:9px; opacity:.8; transition:transform .15s; }
.settings-acc[open] > summary::before { transform:rotate(90deg); }
.settings-acc > summary:hover { color:var(--accent2); }
.settings-acc[open] > summary { color:var(--accent2); }
.settings-acc > .settings-fieldset { margin:0 0 .8rem; }
.settings-acc > .settings-fieldset > .section-label:first-child { display:none; }
/* Help modal: an accordion of module-contributed topics (reuses .settings-acc).
   Body text reads as prose rather than the compact form-hint style. */
.help-body { margin:0 0 .8rem; display:flex; flex-direction:column; gap:.55rem; }
.help-body > .help-p { font-size:13px; line-height:1.5; color:var(--text2); }
.help-body > .btn { align-self:flex-start; }
/* Top-level Settings group (General, Server, Advanced, …): a collapsible
   boxed fieldset holding that group's .settings-acc sections; one open at a
   time via native [name] grouping. */
.settings-group { border:1px solid var(--border); border-radius:var(--r); margin:0 0 .55rem; padding:0 .75rem; }
.settings-group > summary { list-style:none; cursor:pointer; user-select:none; display:flex; align-items:center; gap:.45rem;
  font-size:11px; font-weight:700; letter-spacing:.06em; text-transform:uppercase; color:var(--text3);
  padding:.65rem 0; margin:0 -.75rem; padding-left:.75rem; padding-right:.75rem; }
.settings-group > summary::-webkit-details-marker { display:none; }
.settings-group > summary::before { content:'▸'; font-size:9px; opacity:.8; transition:transform .15s; }
.settings-group[open] > summary::before { transform:rotate(90deg); }
.settings-group > summary:hover, .settings-group[open] > summary { color:var(--text); }
.settings-group[open] > summary { border-bottom:1px solid var(--border); }
.settings-group > .settings-acc:first-of-type { border-top:none; }
/* A Settings group that lives in its own sub-modal: label + hint + Open button. */
.settings-group-link { display:flex; align-items:center; gap:.75rem; border:1px solid var(--border); border-radius:var(--r);
  margin:0 0 .55rem; padding:.45rem .75rem; }
.settings-group-link-text { flex:1; min-width:0; }
.settings-group-link-label { font-size:11px; font-weight:700; letter-spacing:.06em; text-transform:uppercase; color:var(--text3); }
.settings-group-link-text > .hint { font-size:11.5px; color:var(--text3); margin-top:.15rem; }
/* A fieldset whose prerequisite toggle (e.g. "Enable memory") is off. */
/* A fieldset gated behind an enable toggle: dim + disable every direct child
   except a .gate-keep row (the toggle itself), so it can always be flipped back
   on. Dimming per-child (not the whole node) keeps the toggle at full opacity. */
.settings-fieldset-disabled > *:not(.gate-keep) { opacity:.45; pointer-events:none; }

.badge { font-size:10px; padding:.08rem .35rem; border-radius:4px; background:var(--bg3); color:var(--text2);
  display:inline-flex; align-items:center; gap:.2rem; font-weight:500; line-height:1.4; }
.badge.remote { color:var(--remote); background:color-mix(in srgb,var(--remote) 14%,transparent); }

/* ══════ LAYOUT ══════ */
#app { display:flex; height:100vh; overflow:hidden; }
#left-backdrop { display:none; }

#left-col { width:var(--left-w); min-width:var(--left-w); display:flex; flex-direction:column;
  background:var(--bg2); border-right:1px solid var(--border); overflow:hidden; container-type:inline-size; }
#left-header { display:flex; align-items:center; gap:.4rem; padding:.5rem .6rem .4rem; border-bottom:1px solid var(--border); flex-shrink:0; }
#app-title { font-size:15px; font-weight:600; flex:1; letter-spacing:-.01em; }
#app-title span { color:var(--accent); }
#close-left-btn { display:none; }

#search-wrap { padding:.4rem .6rem; flex-shrink:0; position:relative; }
#search-input { width:100%; padding:.4rem .7rem .4rem 2rem; border-radius:3px; background:var(--bg3);
  border:1px solid transparent; color:var(--text); font-size:13px; outline:none; }
#search-input:focus { background:var(--input-bg); border-color:var(--accent); }
#search-input::placeholder { color:var(--text3); }
#search-icon { position:absolute; left:1.05rem; top:50%; transform:translateY(-50%); color:var(--text3); font-size:13px; pointer-events:none; }

#thread-list { flex:1; overflow-y:auto; padding:.3rem .35rem; display:flex; flex-direction:column; gap:1px; font-size: 80%; }
#thread-list-empty { padding:.75rem .5rem; font-size:12.5px; color:var(--text3); text-align:center; }

.thr, .folder-item { font-size: 90%; display:flex; align-items: flex-start; gap:.55rem; padding: 0.5rem; border-radius:3px; cursor:pointer; text-decoration:none; color:inherit; background: var(--bg); margin-top: 0.5em; }
.thr:hover { background:var(--bg3); }
.thr.active { background:var(--accent); border: 1px solid var(--accent2); color:var(--acc-text); }
.thr.active .thr-char { opacity:.8; }
.thr-av { width:48px; height:48px; border-radius:3px; flex-shrink:0; background:var(--bg3); display:flex; align-items:center; justify-content:center; font-size:14px; overflow:hidden; background-size:cover; background-position:center; }
.thr.active .thr-av { background-color:rgba(255,255,255,.15); }
.thr-info { flex:1; min-width:0; }
.thr-name { font-weight:600; }
.thr-char { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; margin-top:1px; display:flex; align-items:center; gap:.25rem; }
.thr-cloud { color:var(--remote); }
.thr-snippet { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; margin-top:2px; color:var(--text3); font-style:italic; }
.thr.active .thr-snippet { opacity:.8; }
.thr-del { opacity:0; padding:.2rem .3rem; font-size:13px; background:transparent; border:none; color:inherit; border-radius:4px; flex-shrink:0; }
.thr:hover .thr-del { opacity:.5; }
.thr.active .thr-del { opacity:.6; }
.thr-del:hover { opacity:1 !important; background:rgba(0,0,0,.15); }

.folder-header { font-size:10.5px; font-weight:600; letter-spacing:.06em; text-transform:uppercase; color:var(--text3);
  padding:.55rem .6rem .2rem; margin-top:.2rem; }

.folder-back { display:flex; align-items:center; gap:.35rem; padding:.35rem .55rem; border-radius:3px; border:none;
  background:transparent; color:var(--text3); font-size:12.5px; font-weight:500; cursor:pointer; width:100%;
  text-align:left; margin-bottom:.15rem; }
.folder-back:hover { background:var(--bg3); color:var(--text2); }

.folder-item { text-align: start; border: none; }
.folder-item:hover { background:var(--bg3); }
.folder-item-icon { font-size:10px; color:var(--accent); flex-shrink:0; opacity:.8; }
.folder-item-name { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.folder-item-count { font-size:11px; color:var(--text3); flex-shrink:0; }

#new-chat-btn { display:flex; align-items:center; justify-content:center; gap:.4rem; margin:.3rem .4rem; padding:.45rem;
  border-radius:3px; border:1.5px dashed var(--border); background:transparent; color:var(--text3); font-size:13px; font-weight:500; cursor:pointer; flex-shrink:0; }
#new-chat-btn:hover { border-color:var(--accent); color:var(--accent); background:rgba(74,74,74,.06); }

/* Defaults to a full vertical stack — the sidebar is narrower than the
   buttons' combined natural width, so a row wrap would just break them
   across two uneven lines. Switches to a single row once the sidebar
   itself (the @container ancestor) is wide enough for all of them. */
#left-footer { display:flex; flex-direction:column; gap:.3rem; padding:.4rem; border-top:1px solid var(--border); flex-shrink:0; }
.lf-btn { font-size:12px; padding:.35rem .5rem; justify-content:center; }
@container (min-width: 380px) {
  #left-footer { flex-direction:row; flex-wrap:wrap; }
  .lf-btn { flex:1; min-width:fit-content; }
}

#mid-col { flex:1; display:flex; flex-direction:column; min-width:0; overflow:hidden; }

#char-select { flex:1; display:flex; flex-direction:column; padding:1.1rem 1.1rem .8rem; overflow:hidden; }
#char-select-top { display:flex; align-items:center; gap:.6rem; margin-bottom:.8rem; }
#char-select-top h2 { font-size:18px; font-weight:600; flex:1; letter-spacing:-.02em; }
#open-left-char { display:none; }
#char-grid { flex:1; overflow-y:auto; display:grid; grid-template-columns:repeat(auto-fill,minmax(220px,1fr)); gap:.5rem; align-content:start; }
#char-grid-empty { font-size:13px; color:var(--text3); padding:.5rem; grid-column:1/-1; }

.char-card { display:flex; flex-direction:column; gap:.4rem; padding:.7rem; border-radius:5px; background:var(--bg2);
  border:1.5px solid var(--border); cursor:pointer; position:relative; }
.char-card:hover { border-color:var(--accent); transform:translateY(-1px); box-shadow:var(--shadow-lg); }
.char-card-top { display:flex; align-items:center; gap:.6rem; }
.char-av-lg { width:44px; height:44px; border-radius:4px; flex-shrink:0; background:var(--bg3); display:flex; align-items:center; justify-content:center; font-size:22px; overflow:hidden; background-size:cover; background-position:center; }
.char-name { font-weight:600; font-size:14.5px; }
.char-namerow { display:flex; align-items:center; gap:.4rem; flex-wrap:wrap; }
.char-desc { font-size:12px; color:var(--text2); display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; line-height:1.5; }
.char-edit { position:absolute; top:.5rem; right:.5rem; opacity:0; font-size:11px; padding:.2rem .4rem; }
.char-card:hover .char-edit { opacity:1; }
#new-char-btn { margin-top:.75rem; align-self:flex-start; gap:.4rem; }

#chat { flex:1; display:flex; flex-direction:column; overflow:hidden; }
#chat-header { display:flex; align-items:center; gap:.5rem; padding:.45rem .7rem; border-bottom:1px solid var(--border); background:var(--bg2); flex-shrink:0; min-height:46px; }
#open-left-chat { display:none; }
#chat-av { width:28px; height:28px; border-radius:3px; flex-shrink:0; background:var(--bg3); display:flex; align-items:center; justify-content:center; font-size:13px; overflow:hidden; background-size:cover; background-position:center; }
#chat-title { font-weight:600; font-size:14.5px; flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; letter-spacing:-.01em; }
#chat-char { font-size:12px; color:var(--text3); white-space:nowrap; }
#opts-btn { padding:.3rem .5rem; font-size:16px; }
.opt { display:flex; align-items:center; gap:.5rem; width:100%; padding:.5rem .65rem; border-radius:3px; border:none; background:transparent;
  color:var(--text); font-size:13px; text-align:left; cursor:pointer; }
.opt:hover { background:var(--bg3); }
.opt-sep { height:1px; background:var(--border); margin:.3rem 0; }

#feed { flex:1; overflow-y:auto; overflow-anchor:none; padding:.8rem .9rem; display:flex; flex-direction:column; gap:.65rem; }
#feed-empty { text-align:center; color:var(--text3); font-size:13px; padding:2rem; }

.msg { display:flex; gap:.5rem; }
.msg-av { width:48px; height:48px; flex-shrink:0; background:var(--bg3); display:flex; align-items:center; justify-content:center; font-size:13px; overflow:hidden; background-size:cover; background-position:center; margin-top:.1rem; }
.msg-body { flex:1; min-width:0; }
.msg-meta { display:flex; align-items:center; gap:.3rem; margin-bottom:.25rem; }
.msg-name { font-weight:600; font-size: 90%; }
.msg-acts { display:flex; gap:.2rem;}
.msg-act { padding:.28rem .42rem; font-size:14px; cursor:pointer; border: none; border-radius:4px; line-height:1; }
.msg-order { font-size:90%; color:var(--text2); }
.msg-act:hover { background:var(--bg3); border-color:var(--border); color:var(--text); }
/* Edit is the one msg-act always visible (Regenerate/Delete are last-message-only)
   and the most-used — give it a persistent tint so it reads as a primary action
   rather than blending in with the ghost icon buttons around it. */
.msg-act-edit { font-size:15px; padding:.32rem .5rem; background:var(--bg3); color:var(--accent2); }
.msg-act-edit:hover { background:var(--border); color:var(--text); }
/* Inline regenerate/delete show on the true last message (see app-render.js)
   — driven purely by :has() so they stay correct as messages stream in/out
   without any JS re-render bookkeeping — and on the active "continue from
   here" branch point (.msg-acts-branch-tail, set in JS since that message
   isn't necessarily the last DOM node once later messages already exist). */
.msg-act-last-only { display:none; }
#feed .msg:not(:has(~ .msg)) .msg-act-last-only,
.msg-acts-branch-tail .msg-act-last-only { display:inline-block; }
.msg-variants { display:flex; align-items:center; gap:.1rem; }
.msg-variant-count { font-size:90%; color:var(--text2); min-width:2.1rem; text-align:center; }

.msg-bubble { line-height:1.6; overflow-wrap:break-word; }
.msg-bubble p { margin-bottom:.5rem; }
.msg-bubble p:last-child { margin-bottom:0; }
.msg-bubble pre { background:rgba(0,0,0,.22); border-radius:3px; overflow-x:auto; margin:.5rem 0; position:relative; border:1px solid rgba(255,255,255,.06); }
.msg-bubble pre code { padding:.75rem 1rem; display:block; font-size:12.5px; font-family:var(--mono); background:transparent; }
.msg-bubble code:not(pre code) { font-family:var(--mono); font-size:12.5px; background:rgba(0,0,0,.12); padding:.1rem .3rem; border-radius:3px; }
.msg.user .msg-bubble code:not(pre code) { background:rgba(255,255,255,.15); }
.copy-code-btn { position:absolute; top:.35rem; right:.35rem; padding:.2rem .45rem; font-size:11px; border-radius:4px;
  background:rgba(255,255,255,.08); border:1px solid rgba(255,255,255,.1); color:rgba(255,255,255,.6); cursor:pointer; }
.copy-code-btn:hover { background:rgba(255,255,255,.16); color:#fff; }
.msg-bubble img { max-width:100%; max-height:380px; margin:.3rem 0; display:block; }
.msg-bubble ul,.msg-bubble ol { padding-left:1.5rem; margin:.3rem 0; }
.msg-bubble li { margin-bottom:.2rem; }
.msg-bubble h1,.msg-bubble h2,.msg-bubble h3,.msg-bubble h4 { margin:.6rem 0 .25rem; font-weight:600; }
.msg-bubble blockquote { border-left:3px solid var(--accent); padding-left:.9rem; opacity:.8; margin:.3rem 0; font-style:italic; }
.msg-bubble table { border-collapse:collapse; width:100%; margin:.4rem 0; font-size:13px; }
.msg-bubble th,.msg-bubble td { border:1px solid var(--border); padding:.3rem .55rem; }
.msg-bubble th { background:var(--bg3); font-weight:600; font-size:12px; }
.msg-bubble hr { border:none; border-top:1px solid var(--border); margin:.6rem 0; }
.msg-bubble a { word-break:break-all; }
.msg-bubble em { opacity: 0.7; }
.stream-cursor::after { content:'▋'; animation:blink .7s step-start infinite; font-size:.85em; color:var(--accent); }
@keyframes blink { 50% { opacity:0; } }
.msg-instruction-badge { max-width:9rem; cursor:help; }
.msg-instruction-text { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-style:italic; min-width:0; }
.msg-reasoning { margin:.1rem 0 .5rem; border-left:2px solid var(--border); background:var(--bg3); border-radius:0 4px 4px 0; }
.msg-reasoning > summary { list-style:none; cursor:pointer; user-select:none; padding:.3rem .6rem; font-size:11px; font-weight:600;
  letter-spacing:.04em; text-transform:uppercase; color:var(--text3); display:flex; align-items:center; gap:.35rem; }
.msg-reasoning > summary::-webkit-details-marker { display:none; }
.msg-reasoning > summary::after { content:'▸'; font-size:9px; opacity:.7; margin-left:auto; transition:transform .15s; }
.msg-reasoning[open] > summary::after { transform:rotate(90deg); }
.msg-reasoning > summary:hover { color:var(--text2); }
.msg-reasoning .reason-body { padding:.1rem .65rem .5rem; font-size:12.5px; color:var(--text2); opacity:.85; }
.msg-reasoning .reason-body > :first-child { margin-top:0; }
.msg-reasoning .reason-body > :last-child { margin-bottom:0; }
.msg-hidden-badge { opacity:.75; }
.msg-collapse-btn { display:none; background:none; border:none; color:var(--text3); font-size:12px; cursor:pointer; padding:.3rem 0; margin-top:.2rem; width:100%; text-align:center; }
.msg-collapse-btn:hover { color:var(--text2); }
.msg-body.is-tall .msg-collapse-btn { display:block; }
.msg-body.is-tall.is-collapsed .msg-bubble { max-height:480px; overflow:hidden; mask-image:linear-gradient(to bottom, black 65%, transparent 100%); -webkit-mask-image:linear-gradient(to bottom, black 65%, transparent 100%); }

/* Content messages inside a scene: faint tint + rail + text inset. */
.msg.in-scene { position:relative; background:var(--scene-tint); border-left:2px solid var(--scene-line);
  border-radius:0 5px 5px 0; padding:.45rem .55rem .45rem .6rem; }
/* Fill the feed's .65rem flex gap above every non-opening scene item so the
   left rail is continuous rather than a stack of dashes. */
.msg.in-scene::before, .scene-marker-end::before { content:''; position:absolute; left:-2px; top:-.65rem; width:2px; height:.65rem; background:var(--scene-line); }

.typing { display:flex; gap:5px; padding:.35rem 0; }
.typing-dot { width:7px; height:7px; border-radius:50%; background:var(--text3); animation:bounce 1.2s infinite; }
.typing-dot:nth-child(2) { animation-delay:.2s; }
.typing-dot:nth-child(3) { animation-delay:.4s; }
@keyframes bounce { 0%,60%,100% { transform:translateY(0); opacity:.35; } 30% { transform:translateY(-5px); opacity:1; } }

#status { padding:.15rem .9rem; font-size:11.5px; background: beige; color: red; flex-shrink:0; min-height:0; }

#input-area { padding:.5rem .7rem .55rem; border-top:1px solid var(--border); background:var(--bg2); flex-shrink:0; }
#attach-row { display:flex; gap:.4rem; flex-wrap:wrap; margin-bottom:.4rem; }
.att-wrap { position:relative; display:inline-block; }
.att-thumb { width:54px; height:54px; border-radius:3px; object-fit:cover; border:2px solid var(--border); display:block; }
.att-rm { position:absolute; top:-5px; right:-5px; width:16px; height:16px; border-radius:50%; background:#c0392b; color:#fff;
  font-size:10px; line-height:16px; text-align:center; border:none; cursor:pointer; padding:0; }
#input-row { display:flex; align-items:flex-end; gap:.4rem; }
#msg-ta { flex:1; border-radius:var(--r); resize:none; min-height:38px; max-height:200px; overflow-y:auto; padding:.5rem .7rem; line-height:1.5; background:var(--input-bg); border:1.5px solid var(--border); color:var(--text); outline:none; }
#msg-ta:focus { border-color:var(--accent); }
#msg-ta::placeholder { color:var(--text3); }
#attach-btn { width:38px; height:38px; padding:0; font-size:17px; flex-shrink:0; }
#file-in { display:none; }
#send-btn { height:38px; padding:0 1rem; flex-shrink:0; }
#stop-btn { height:38px; padding:0 1rem; flex-shrink:0; background:#c0392b; border-color:transparent; color:#fff; display:none; }
#stop-btn:hover { background:#a93226; }
#ctx-counter { font-size:11px; color:var(--text3); text-align:right; margin-top:.3rem; min-height:1em; }
#msg-history-drop { position:absolute; bottom:calc(100% + 4px); left:0; right:0; max-height:220px; overflow-y:auto;
  background:var(--bg2); border:1.5px solid var(--accent); border-radius:var(--r); z-index:200; box-shadow:0 4px 16px #0004; }
#msg-history-drop button { display:block; width:100%; text-align:left; padding:.45rem .75rem; border:none; background:none;
  color:var(--text); font-size:13px; cursor:pointer; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
#msg-history-drop button:hover { background:var(--bg3); }
#msg-history-drop .mh-empty { padding:.5rem .75rem; color:var(--text3); font-size:12px; }
#cmd-complete-drop { position:absolute; bottom:calc(100% + 4px); left:0; right:0; max-height:220px; overflow-y:auto;
  background:var(--bg2); border:1.5px solid var(--accent); border-radius:var(--r); z-index:200; box-shadow:0 4px 16px #0004; }
#cmd-complete-drop button { display:flex; align-items:baseline; gap:.5rem; width:100%; text-align:left; padding:.4rem .75rem; border:none; background:none;
  color:var(--text); font-size:13px; cursor:pointer; white-space:nowrap; }
#cmd-complete-drop button code { color:var(--accent); }
#cmd-complete-drop button .cmd-desc { color:var(--text3); font-size:11.5px; overflow:hidden; text-overflow:ellipsis; }
#cmd-complete-drop button:hover, #cmd-complete-drop button.selected { background:var(--bg3); }

/* ══════ CAST BAR (multi-character quick replies) ══════ */
/* Collapse trigger for narrow screens — hidden on wide screens where the
   bar just shows inline (see the max-width:640px block below). */
#cast-toggle-btn { display:none; width:38px; height:38px; padding:0; font-size:15px; flex-shrink:0; }
#cast-bar { display:flex; align-items:center; flex-wrap:wrap; gap:.35rem; margin-bottom:.45rem; }
.cast-group { display:flex; align-items:center; gap:.35rem; flex-wrap:wrap; }
.cast-group.extras { margin-left:auto; padding-left:.6rem; border-left:1px solid var(--border); }
.cast-chip { display:inline-flex; align-items:center; gap:.35rem; padding:.22rem .5rem .22rem .3rem; border-radius:4px;
  background:var(--bg3); border:1px solid var(--border); color:var(--text); font-size:12px; font-weight:500; line-height:1;
  cursor:pointer; white-space:nowrap; }
.cast-chip:hover { border-color:var(--accent); background:var(--border); }
.cast-chip:disabled { opacity:.5; cursor:default; }
.cc-av { width:18px; height:18px; border-radius:50%; flex-shrink:0; background:var(--bg2); display:flex;
  align-items:center; justify-content:center; font-size:11px; overflow:hidden; background-size:cover; background-position:center; }
.cast-chip.add { padding:.22rem .55rem; color:var(--text2); border-style:dashed; }
.cast-chip.add:hover { color:var(--accent); }
.cast-chip.special { color:var(--text2); }
.cast-chip.special .cc-av { background:transparent; }
.cmd-hint { font-size:10.5px; color:var(--text3); white-space:nowrap; cursor:help; }
.cmd-hint code { font-family:var(--mono); background:var(--bg3); padding:0 .25rem; border-radius:3px; }

/* ══════ BRANCHING ("continue from here" insert mode) ══════ */
#insert-banner { display:flex; align-items:center; gap:.6rem; margin-bottom:.5rem; padding:.4rem .6rem;
  border:1px solid var(--accent); border-radius:4px; background:var(--bg3); }
#insert-banner .insert-banner-text { font-size:12px; color:var(--text); flex:1; }
#insert-banner .btn { flex-shrink:0; }
.cast-manage-row { display:flex; align-items:center; justify-content:space-between; gap:.5rem; padding:.5rem .6rem;
  border:1px solid var(--border); border-radius:var(--r); margin-bottom:.4rem; }
.cast-manage-row .cm-info { display:flex; align-items:center; gap:.5rem; min-width:0; }
.cast-manage-row .cm-name { font-weight:500; font-size:13px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.cast-manage-row .cm-main { font-size:10px; }

/* ══════ SCRATCHPAD ══════ */
.scratch-row { border:1px solid var(--border); border-radius:var(--r); padding:.55rem .65rem; margin-bottom:.6rem; }
.scratch-row-head { display:flex; align-items:center; gap:.5rem; margin-bottom:.4rem; }
.scratch-row-head .msg-name { flex:1; }
.scratch-row-acts { display:flex; gap:.4rem; flex-shrink:0; }
.scratch-row textarea { width:100%; min-height:56px; resize:vertical; line-height:1.45; padding:.45rem .6rem;
  border-radius:var(--r); background:var(--input-bg); border:1.5px solid var(--border); color:var(--text); }
.scratch-row textarea:focus { border-color:var(--accent); outline:none; }
.scratch-add-row { display:flex; flex-wrap:wrap; gap:.4rem; }
.scratch-av { width:18px; height:18px; border-radius:50%; flex-shrink:0; background:var(--bg3); display:flex;
  align-items:center; justify-content:center; font-size:11px; overflow:hidden; background-size:cover; background-position:center; }

/* ══════ TOAST ══════ */
.app-toast { position:fixed; top:.9rem; left:50%; transform:translateX(-50%); z-index:1100;
  display:flex; align-items:center; gap:.7rem; padding:.5rem .6rem .5rem .9rem;
  background:var(--bg2); border:1.5px solid var(--accent); border-radius:var(--r);
  box-shadow:0 8px 24px #0004; font-size:13px; color:var(--text); animation:app-toast-in .15s ease-out;
  max-width:calc(100vw - 1.6rem); }
@keyframes app-toast-in { from { opacity:0; transform:translateX(-50%) translateY(-8px); } to { opacity:1; transform:translateX(-50%) translateY(0); } }

/* Small grey hint pinned after the last feed message (e.g. auto-reply's
   "waiting for you" notice) — part of the feed's flex column, so it scrolls
   with the conversation instead of floating fixed. */
.feed-tail { color:var(--text3); font-size:12px; padding:0 .3rem; }

/* ══════ MODAL ══════ */
#modal-bg { position:fixed; inset:0; background:rgba(0,0,0,.55); z-index:1000; display:none; align-items:center; justify-content:center; padding:1rem; }
#modal-bg.open { display:flex; }
#modal-box { background:var(--bg); border-radius:6px; padding:1.1rem; min-width:300px; max-width:640px; width:100%; max-height:88vh;
  overflow-y:auto; box-shadow:0 20px 60px rgba(0,0,0,.35); border:1px solid var(--border); }
#modal-box h3 { font-size:16px; font-weight:600; margin-bottom:1.1rem; letter-spacing:-.02em; }
.modal-btns { display:flex; gap:.5rem; justify-content:flex-end; margin-top:1.1rem; flex-wrap:wrap; }

/* Blocks interaction with the rest of the app during a long-running,
   non-cancelable operation (e.g. parsing a large import file) — same
   full-screen backdrop as #modal-bg, but with no close affordance (no
   Escape, no backdrop click) since there's nothing to safely cancel into. */
#busy-overlay { position:fixed; inset:0; background:rgba(0,0,0,.55); z-index:1100; display:none; align-items:center; justify-content:center; padding:1rem; outline:none; }
#busy-overlay.open { display:flex; }
.busy-box { background:var(--bg); border-radius:6px; padding:1rem 1.3rem; display:flex; align-items:center; gap:.7rem; font-size:14px; box-shadow:0 20px 60px rgba(0,0,0,.35); border:1px solid var(--border); }
.busy-box .spinner { width:18px; height:18px; }

@media (max-width: 640px) {
  #left-col { position:fixed; left:0; top:0; bottom:0; z-index:500; width:min(85vw,320px); min-width:0; transform:translateX(-102%); }
  #left-col.open { transform:translateX(0); box-shadow:4px 0 24px rgba(0,0,0,.25); }
  #close-left-btn,#open-left-char,#open-left-chat { display:inline-flex !important; }
  #char-grid { grid-template-columns:1fr; }
  #left-backdrop { display:block; position:fixed; inset:0; z-index:499; background:rgba(0,0,0,.4);
    opacity:0; pointer-events:none; transition:opacity .15s; }
  #left-col.open ~ #left-backdrop { opacity:1; pointer-events:auto; }

  /* Cast bar collapses behind the + toggle; #input-area.cast-open (set in
     app-composer.js) reveals it again. */
  #cast-toggle-btn { display:inline-flex; }
  #cast-bar { display:none !important; }
  #input-area.cast-open #cast-bar { display:flex !important; }

  #send-btn .btn-label { display:none; }
  #send-btn { width:38px; padding:0; }
}

/* Hover-gated reveal (thr-del, char-edit) is unreachable on touch, which has
   no hover state — always show them when the pointer can't hover. */
@media (hover: none) {
  .thr-del, .char-edit { opacity:1; }
}
