:root {
  color-scheme: light;
  --blue: #1f3fbf;              /* interactive brand accent (links, focus, active) */
  --blue-hover: #0f2a8f;
  --blue-dark: #14286e;         /* ink on accent-soft surfaces */
  --blue-light: #eef2ff;        /* accent-soft surface */
  --on-accent: #ffffff;
  --accent-grad: linear-gradient(110deg, #1d44d8 0%, #5b5bf0 55%, #8b5cf6 100%);
  --accent-glow: rgba(79, 70, 229, 0.28);
  --ink: #111318;               /* primary solid button (New chat) */
  --on-ink: #ffffff;
  --bg: #f3f4f7;                /* app frame + sidebar */
  --surface: #ffffff;           /* main canvas, cards, composer */
  --surface-subtle: #f7f8fa;
  --surface-raise: #fbfcfd;
  --bubble: #f3f4f7;            /* assistant bubble */
  --hover: rgba(17, 19, 24, 0.05);
  --press: rgba(17, 19, 24, 0.08);
  --text: #16181d;
  --text-2: #3b4150;
  --muted: #6a7182;
  --border: #e4e6eb;
  --border-strong: #cfd3dc;
  --user: #e8edfd;
  --on-user: #16181d;
  --user-link: #1f3fbf;
  --overlay-weak: rgba(31, 63, 191, 0.12);
  --overlay-strong: rgba(31, 63, 191, 0.24);
  --focus-ring: rgba(31, 63, 191, 0.18);
  --shadow-xs: 0 1px 2px rgba(16, 24, 40, 0.05);
  --shadow-sm: 0 1px 2px rgba(16, 24, 40, 0.04), 0 4px 12px rgba(16, 24, 40, 0.06);
  --shadow-md: 0 12px 32px rgba(16, 24, 40, 0.12);
  --shadow-composer: 0 1px 2px rgba(16, 24, 40, 0.04), 0 6px 20px -10px rgba(16, 24, 40, 0.14);
  --radius: 14px;
  --radius-lg: 20px;
  --touch: 44px;
  --ok-bg: #dcf5e3; --ok-fg: #177245; --ok-border: #9bd7b3; --ok-soft: #f1fbf5;
  --warn-bg: #fdf3d7; --warn-fg: #8a6116; --warn-border: #e8cd82; --warn-soft: #fffaf0; --warn-ink: #654b19;
  --bad-border: #e5b0b5; --bad-soft: #fff6f7;
  --neutral-bg: #eef0f4;
  --info-border: #c3cdf0; --info-soft: #f6f8fe;
  --violet-bg: #eee9ff; --violet-fg: #573a9b;
  --danger: #b02a37; --danger-hover: #8f222c; --danger-bg: #fdecee; --danger-border: #f0bcc2;
}

@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;
    --blue: #8fa8ff;
    --blue-hover: #b3c4ff;
    --blue-dark: #d3ddff;
    --blue-light: #1c2340;
    --on-accent: #0a0f22;
    --accent-grad: linear-gradient(110deg, #6f8dff 0%, #8f86ff 55%, #b28cff 100%);
    --accent-glow: rgba(124, 118, 255, 0.3);
    --ink: #eef0f5;
    --on-ink: #0b0d12;
    --bg: #0b0d12;
    --surface: #14171e;
    --surface-subtle: #181c24;
    --surface-raise: #1b1f28;
    --bubble: #1d212b;
    --hover: rgba(255, 255, 255, 0.06);
    --press: rgba(255, 255, 255, 0.1);
    --text: #e9ebf1;
    --text-2: #c3c8d4;
    --muted: #9097a8;
    --border: #262b36;
    --border-strong: #353b49;
    --user: #26305a;
    --on-user: #eef1ff;
    --user-link: #c8d4ff;
    --overlay-weak: rgba(143, 168, 255, 0.16);
    --overlay-strong: rgba(143, 168, 255, 0.3);
    --focus-ring: rgba(143, 168, 255, 0.3);
    --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4), 0 4px 12px rgba(0, 0, 0, 0.35);
    --shadow-md: 0 12px 32px rgba(0, 0, 0, 0.5);
    --shadow-composer: 0 1px 2px rgba(0, 0, 0, 0.4), 0 10px 24px -12px rgba(0, 0, 0, 0.6);
    --ok-bg: #12351f; --ok-fg: #86e0a6; --ok-border: #2c6b42; --ok-soft: #10261a;
    --warn-bg: #3a2f10; --warn-fg: #f2ce77; --warn-border: #6d5a20; --warn-soft: #241c09; --warn-ink: #e6cd96;
    --bad-border: #7a3b43; --bad-soft: #2a1418;
    --neutral-bg: #1a1e27;
    --info-border: #35497e; --info-soft: #131a30;
    --violet-bg: #2a2350; --violet-fg: #c9bcff;
    --danger: #ff7b87; --danger-hover: #ff9aa3; --danger-bg: #2c1418; --danger-border: #6d2f37;
  }
}

* { margin: 0; padding: 0; box-sizing: border-box; }

[hidden] { display: none !important; }

html, body {
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
}

body {
  font-family: "Inter", "Aptos", "Segoe UI Variable", "Segoe UI", ui-sans-serif, system-ui, sans-serif;
  background: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

button, input, select, textarea { font: inherit; color: inherit; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; left: 8px; top: -64px; z-index: 100;
  min-height: var(--touch); background: var(--surface); color: var(--blue); padding: 10px 14px; border-radius: 10px;
  transition: top .15s;
  display: inline-flex; align-items: center;
}
/* Shadow only while visible: off-screen it bled a grey smear into the corner. */
.skip-link:focus { top: 8px; box-shadow: var(--shadow-md); }

:focus-visible { outline: 3px solid var(--blue); outline-offset: 2px; border-radius: 6px; }

/* Full-bleed shell: sidebar column + a raised main canvas. The conversation
   inside the canvas stays a centred column (--column) — full-width text lines
   are unreadable on wide monitors, so the shell grows and the prose does not. */
.app {
  --column: 780px;
  --sidebar-w: 272px;
  --pad: 24px;
  width: 100%;
  height: 100vh;
  height: 100dvh;
  display: grid;
  grid-template-columns: var(--sidebar-w) minmax(0, 1fr);
  background: var(--bg);
}

/* ---- icon buttons (history, language, close) ---- */
.icon-btn {
  width: var(--touch); min-width: var(--touch); height: var(--touch);
  padding: 0; flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; border-radius: 12px; background: transparent; color: var(--text-2);
  cursor: pointer; transition: background .15s, color .15s;
}
.icon-btn svg { display: block; }
.icon-btn:hover { background: var(--hover); color: var(--text); }
.icon-btn:active { background: var(--press); }
.icon-btn[aria-checked="true"] { color: var(--blue); }

/* ---- sidebar ---- */
.sidebar {
  display: flex; flex-direction: column; gap: 12px;
  min-height: 0; padding: 14px 12px 12px;
  background: var(--bg);
}
.sidebar:focus { outline: none; }
.sidebar-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 40px; padding-left: 6px; }
.brand { display: flex; align-items: center; gap: 10px; min-width: 0; }
.logo {
  width: 30px; height: 30px; flex: 0 0 auto; border-radius: 9px;
  display: grid; place-items: center;
  background: linear-gradient(140deg, #1d44d8, #003399); color: #fff;
  font-size: 12px; font-weight: 800; letter-spacing: -0.02em;
}
.brand-name { font-size: 15px; font-weight: 700; letter-spacing: -0.015em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sidebar-close { display: none; }

.search { position: relative; }
.search svg { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); color: var(--muted); pointer-events: none; }
.search input {
  width: 100%; height: 40px; padding: 0 12px 0 36px;
  border: 1px solid var(--border); border-radius: 12px;
  background: var(--surface); font-size: 13px; color: var(--text);
  box-shadow: var(--shadow-xs); transition: border-color .15s, box-shadow .15s;
}
.search input::placeholder { color: var(--muted); }
.search input:focus-visible { outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px var(--focus-ring); }

.history-list { flex: 1; min-height: 0; overflow-y: auto; margin-inline: -4px; padding-inline: 4px; scrollbar-width: thin; }
.history-group { font-size: 12px; font-weight: 600; color: var(--muted); padding: 14px 10px 6px; }
.history-group:first-child { padding-top: 4px; }
.history-empty { padding: 8px 10px; font-size: 13px; line-height: 1.55; color: var(--muted); }
.history-row { position: relative; display: flex; align-items: center; border-radius: 10px; }
.history-row + .history-row { margin-top: 1px; }
.history-row:hover { background: var(--hover); }
.history-open {
  flex: 1; min-width: 0; min-height: 36px; padding: 8px 10px;
  border: 0; border-radius: 10px; background: transparent; color: var(--text-2);
  font-size: 13px; text-align: left; cursor: pointer;
}
.history-open.is-current { background: var(--surface); color: var(--text); font-weight: 600; box-shadow: var(--shadow-xs); }
.history-title { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.history-delete {
  position: absolute; right: 3px; top: 50%; transform: translateY(-50%);
  width: 30px; height: 30px;
  border: 0; border-radius: 8px; background: transparent; color: var(--muted);
  font-size: 17px; line-height: 1; cursor: pointer;
  opacity: 0; transition: opacity .12s;
}
.history-row:hover .history-delete, .history-row:focus-within .history-delete { opacity: 1; }
/* Reserve room for the delete button only while it is showing. */
.history-row:hover .history-open, .history-row:focus-within .history-open { padding-right: 38px; }
.history-delete:hover { background: var(--danger-bg); color: var(--danger); }
.history-clear {
  align-self: flex-start; min-height: 32px; padding: 6px 10px;
  border: 0; border-radius: 8px; background: transparent;
  font-size: 12px; font-weight: 600; color: var(--muted); cursor: pointer;
}
.history-clear:hover { background: var(--danger-bg); color: var(--danger); }

/* Knowledge-base status sits where a profile card usually would. */
.kb-status {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 4px 8px 12px; border: 1px solid var(--border); border-radius: 14px;
  background: var(--surface); box-shadow: var(--shadow-xs);
}
.kb-dot { flex: 0 0 auto; width: 8px; height: 8px; border-radius: 50%; background: var(--ok-fg); box-shadow: 0 0 0 4px var(--ok-bg); }
.kb-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.kb-primary, .kb-secondary { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kb-primary { font-size: 13px; font-weight: 600; }
.kb-secondary { font-size: 12px; color: var(--muted); }
.kb-secondary:empty { display: none; }
.chip-help {
  flex: 0 0 auto; min-width: 36px; min-height: 36px; font-size: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; border-radius: 10px; background: transparent; cursor: pointer; color: var(--muted);
}
.chip-help::before {
  content: '?'; width: 20px; height: 20px; border-radius: 50%;
  border: 1px solid var(--border-strong); background: var(--surface);
  font-size: 11px; font-weight: 700; line-height: 18px; text-align: center;
}
.chip-help:hover::before { border-color: var(--blue); color: var(--blue); }
.chip-help[aria-expanded="true"]::before { background: var(--blue); border-color: var(--blue); color: var(--on-accent); }
.meta-help-text {
  padding: 10px 12px; font-size: 12px; line-height: 1.5; color: var(--muted);
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
}

.hotline {
  display: flex; align-items: center; gap: 8px; min-height: var(--touch);
  padding: 0 12px; border-radius: 12px; text-decoration: none;
  font-size: 13px; color: var(--text-2);
}
.hotline svg { flex: 0 0 auto; color: var(--blue); }
.hotline-number { margin-left: auto; font-weight: 700; color: var(--blue); font-variant-numeric: tabular-nums; }
.hotline:hover { background: var(--hover); }

.history-backdrop { position: fixed; inset: 0; z-index: 40; background: rgba(8, 10, 16, 0.42); }

/* ---- main canvas ---- */
.main {
  position: relative;
  display: flex; flex-direction: column;
  min-width: 0; min-height: 0;
  margin: 10px 10px 10px 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}

.topbar { display: flex; align-items: center; gap: 8px; padding: 12px 16px; min-height: 68px; }
#historyBtn { display: none; }
/* A title, not a control: the bordered pill with a shadow read as a button
   that did nothing when tapped. */
.model-pill {
  display: inline-flex; align-items: center; gap: 9px; min-width: 0;
  padding: 5px 4px;
}
.model-mark {
  width: 26px; height: 26px; flex: 0 0 auto; border-radius: 8px;
  display: grid; place-items: center; background: var(--accent-grad); color: #fff;
  font-size: 10px; font-weight: 800;
}
.model-name { font-size: 15px; font-weight: 650; letter-spacing: -0.01em; white-space: nowrap; }
.model-mode {
  font-size: 12px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  padding-left: 9px; border-left: 1px solid var(--border);
}
.model-mode:empty { display: none; }
.topbar-actions { margin-left: auto; display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }
.new-chat-btn {
  min-height: 40px; padding: 0 14px 0 12px; display: inline-flex; align-items: center; gap: 6px;
  border: 0; border-radius: 12px; background: var(--ink); color: var(--on-ink);
  font-size: 13px; font-weight: 600; cursor: pointer; box-shadow: var(--shadow-sm);
  transition: transform .12s, opacity .15s;
}
.new-chat-btn:hover { opacity: .9; }
.new-chat-btn:active { transform: scale(.98); }

/* ---- offline notice ---- */
.offline-bar {
  margin: 0 16px 8px; padding: 9px 14px; font-size: 12px; font-weight: 600; border-radius: 10px;
  background: var(--warn-bg); color: var(--warn-fg); border: 1px solid var(--warn-border);
}

/* ---- chat column ---- */
/* position: relative keeps the phone's visually-hidden absolute labels
   (.msg-author, table thead) inside this scroller. Without it their containing
   block was .main: they overflowed it, and scrollIntoView on a new question
   scrolled that overflow:hidden canvas, lifting the composer mid-screen. */
.chat {
  position: relative;
  flex: 1; min-height: 0; overflow-y: auto;
  display: flex; flex-direction: column;
  padding: 0 var(--pad);
  scrollbar-gutter: stable;
}
.chat:focus { outline: none; }
.thread { flex: 1 0 auto; display: flex; flex-direction: column; gap: 22px; padding: 12px 0 20px; }
.is-empty .thread { display: none; }

/* ---- empty state ---- */
/* Auto margins (not justify-content) centre the empty state: a centred flex
   column that overflows clips its top edge out of scroll reach. */
.welcome { margin: auto auto 0; padding: 40px 0 28px; width: 100%; max-width: var(--column); text-align: center; }
.orb {
  width: 64px; height: 64px; margin: 0 auto 22px; border-radius: 50%;
  background:
    radial-gradient(circle at 32% 28%, rgba(255,255,255,.95) 0 10%, rgba(255,255,255,0) 36%),
    radial-gradient(circle at 70% 75%, #8b5cf6 0%, rgba(139,92,246,0) 60%),
    radial-gradient(circle at 30% 70%, #60d5ff 0%, rgba(96,213,255,0) 55%),
    linear-gradient(140deg, #9fb4ff, #5b5bf0);
  box-shadow: 0 16px 40px -10px var(--accent-glow), inset -6px -8px 18px rgba(40, 30, 160, 0.3);
  animation: orb-float 6s ease-in-out infinite;
}
@keyframes orb-float { 50% { transform: translateY(-5px) scale(1.03); } }
.welcome-title { font-size: clamp(26px, 3.4vw, 36px); font-weight: 650; letter-spacing: -0.03em; line-height: 1.2; text-wrap: balance; }
.welcome-greeting { display: block; }
.accent { background: var(--accent-grad); -webkit-background-clip: text; background-clip: text; color: transparent; }
.welcome-lead { font-size: 15px; color: var(--muted); margin: 14px auto 0; max-width: 58ch; line-height: 1.6; text-wrap: pretty; }

.starters { margin: 0 auto auto; padding: 22px 0 32px; width: 100%; max-width: var(--column); }
.cards { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; }
.card {
  display: flex; flex-direction: column; align-items: flex-start; gap: 6px;
  min-height: 112px; padding: 14px; text-align: left; cursor: pointer;
  border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface);
  transition: border-color .15s, box-shadow .15s, transform .15s;
}
.card:hover { border-color: var(--border-strong); box-shadow: var(--shadow-sm); transform: translateY(-1px); }
.card:active { transform: none; background: var(--surface-subtle); }
.card .card-icon { width: 30px; height: 30px; border-radius: 9px; background: var(--blue-light); color: var(--blue); display: grid; place-items: center; margin-bottom: 4px; }
.card .card-icon svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.card .card-title { font-size: 14px; font-weight: 650; color: var(--text); letter-spacing: -0.01em; }
.card .card-desc { font-size: 13px; color: var(--muted); line-height: 1.45; }
.examples-label { font-size: 12px; font-weight: 600; color: var(--muted); margin: 22px 0 10px; }
.suggestions { display: flex; gap: 8px; flex-wrap: wrap; }
.suggestions button {
  min-height: 36px; padding: 7px 14px; font-size: 14px; text-align: left; cursor: pointer;
  border: 1px solid var(--border); border-radius: 999px; background: var(--surface); color: var(--text-2);
  transition: background .15s, border-color .15s;
}
.suggestions button:hover { background: var(--blue-light); border-color: transparent; color: var(--blue-dark); }

/* ---- composer ---- */
/* Sticky inside the scroller: centred under the greeting while empty, docked
   to the bottom once the thread fills the column. */
.composer-dock {
  position: sticky; bottom: 0; z-index: 3;
  width: 100%; max-width: var(--column); margin-inline: auto;
  padding: 10px 0 max(16px, env(safe-area-inset-bottom));
  background: linear-gradient(to bottom, transparent, var(--surface) 22px);
}
.is-empty .composer-dock { background: none; }
.log-notice {
  margin-top: 6px; padding-inline: 12px;
  text-align: center; font-size: 11.5px; line-height: 1.4; color: var(--muted);
}
.composer {
  display: flex; flex-direction: column; gap: 8px;
  padding: 12px 12px 10px 16px;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-composer);
  transition: border-color .15s, box-shadow .15s;
}
.composer:focus-within { border-color: var(--border-strong); box-shadow: var(--shadow-composer), 0 0 0 4px var(--focus-ring); }
.composer textarea {
  width: 100%; min-height: 28px; max-height: 200px; padding: 4px 2px;
  border: 0; outline: none; resize: none; background: transparent;
  font-size: 15px; line-height: 1.55; color: var(--text);
}
.composer textarea::placeholder { color: var(--muted); }
/* The card carries the focus ring for the field. */
.composer textarea:focus-visible { outline: none; }
.is-empty .composer textarea { min-height: 76px; }
.composer-bar { display: flex; align-items: center; gap: 8px; }
.composer-tools { flex: 1; min-width: 0; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.tool-chip {
  min-height: 34px; padding: 6px 11px; display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--border); border-radius: 10px; background: var(--surface);
  font-size: 13px; font-weight: 550; color: var(--text-2); cursor: pointer;
  transition: background .15s, border-color .15s, color .15s;
}
.tool-chip:hover { background: var(--surface-subtle); border-color: var(--border-strong); }
.tool-chip[aria-expanded="true"] { background: var(--blue-light); border-color: transparent; color: var(--blue-dark); }
.filter-count {
  background: var(--blue); color: var(--on-accent); border-radius: 10px;
  font-size: 11px; min-width: 18px; height: 18px; padding: 0 5px;
  display: inline-flex; align-items: center; justify-content: center;
}
.char-count { flex: 0 0 auto; font-size: 12px; font-weight: 600; color: var(--muted); font-variant-numeric: tabular-nums; }
.char-count.is-limit { color: var(--danger); }
.send-btn {
  flex: 0 0 auto; width: 40px; height: 40px; display: grid; place-items: center;
  border: 0; border-radius: 12px; background: var(--accent-grad); color: #fff; cursor: pointer;
  transition: opacity .15s, transform .12s;
}
.send-btn:hover { opacity: .92; }
.send-btn:active { transform: scale(.96); }
.send-btn .i-stop { display: none; }
.send-btn.stop { background: var(--ink); color: var(--on-ink); }
.send-btn.stop .i-send { display: none; }
.send-btn.stop .i-stop { display: block; }
/* Nothing to send yet: quieter, but still focusable and announced. */
.composer:has(textarea:placeholder-shown) .send-btn:not(.stop) { opacity: .4; }

/* ---- filter panel (inside the composer card) ---- */
.filter-panel { display: flex; flex-direction: column; gap: 10px; padding: 12px 0 4px; border-top: 1px solid var(--border); }
.presets { display: flex; gap: 6px; flex-wrap: wrap; }
.preset {
  min-height: 34px; padding: 6px 12px; font-size: 13px; font-weight: 600;
  border-radius: 999px; border: 1px solid var(--border); background: var(--surface); color: var(--blue-dark);
  cursor: pointer; transition: background .15s;
}
.sectors-block { display: flex; flex-direction: column; gap: 6px; }
.presets-label { font-size: 12px; font-weight: 600; color: var(--muted); }
.preset:hover, .preset[aria-pressed="true"] { background: var(--blue); border-color: var(--blue); color: var(--on-accent); }
.filter-fields { display: flex; gap: 12px; flex-wrap: wrap; }
.field { display: flex; flex-direction: column; gap: 4px; flex: 1 1 220px; min-width: 0; }
.field label { font-size: 12px; font-weight: 600; color: var(--muted); }
.field select {
  min-height: 40px; font-size: 14px; padding: 8px 10px;
  border: 1px solid var(--border); border-radius: 10px; background: var(--surface-subtle); color: var(--text);
}
.active-filters { display: flex; gap: 6px; flex-wrap: wrap; }
.active-filters:empty { display: none; }
.filter-chip {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 12px; font-weight: 600; color: var(--blue-dark);
  background: var(--blue-light); border-radius: 10px; padding: 2px 2px 2px 10px; min-height: 34px;
}
.filter-chip button {
  min-width: 30px; min-height: 30px; border: none; border-radius: 8px;
  background: transparent; color: var(--blue-dark); cursor: pointer;
  font-size: 14px; line-height: 1; display: inline-flex; align-items: center; justify-content: center;
}
.filter-chip button:hover { background: var(--overlay-weak); }

/* Bottom-sheet chrome for the filter panel; only phones show it (640px block). */
.sheet-head, .filter-backdrop { display: none; }

/* ---- jump to latest ---- */
/* A round icon at the right edge: centred and labelled, it sat on top of the
   very paragraph the reader had scrolled up to read. */
.jump-latest {
  position: absolute; right: 4px; bottom: calc(100% + 4px);
  width: 40px; height: 40px; padding: 0; display: grid; place-items: center;
  border-radius: 50%; border: 1px solid var(--border); background: var(--surface); color: var(--text-2);
  cursor: pointer; box-shadow: var(--shadow-sm);
}
.is-empty .jump-latest { display: none; }
.jump-latest:hover { color: var(--blue); }

/* ---- messages ---- */
.msg { display: flex; gap: 10px; width: 100%; max-width: var(--column); margin-inline: auto; }
.msg.user { justify-content: flex-end; }
.msg-avatar {
  flex: 0 0 auto; width: 30px; height: 30px; margin-top: 20px; border-radius: 50%;
  display: grid; place-items: center; background: var(--accent-grad); color: #fff;
  font-size: 11px; font-weight: 800;
}
.msg-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 5px; }
.msg-author { font-size: 12px; font-weight: 500; color: var(--muted); padding-left: 4px; }
.bubble {
  max-width: 100%; padding: 12px 16px; border-radius: var(--radius-lg);
  font-size: 15px; line-height: 1.65;
  overflow-wrap: anywhere;
}
.msg.assistant .bubble { background: var(--bubble); border-top-left-radius: 6px; }
.msg.user .bubble { max-width: min(80%, 62ch); background: var(--user); color: var(--on-user); border-bottom-right-radius: 6px; white-space: pre-wrap; }
.bubble p { margin: 0 0 10px; }
.bubble p:last-child { margin-bottom: 0; }
/* Rendered answer markdown only; the knowledge panel styles its own lists. */
:is(.answer-body, .stream-body) .md-h { margin-top: 16px; }
:is(.answer-body, .stream-body) .md-h:first-child { margin-top: 0; }
:is(.answer-body, .stream-body) :is(ul, ol) { margin: 0 0 10px; padding-left: 22px; }
:is(.answer-body, .stream-body) li { margin: 0 0 6px; padding-left: 2px; }
:is(.answer-body, .stream-body) li::marker { color: var(--muted); }
:is(.answer-body, .stream-body) :is(ul, ol):last-child { margin-bottom: 0; }
.bubble strong { font-weight: 700; }
.bubble a { color: var(--blue); text-decoration: underline; text-underline-offset: 2px; }
.msg.user .bubble a { color: var(--user-link); }
/* 24px is the WCAG 2.2 minimum target (2.5.8); neighbours like [14][15] get a
   gap so a thumb lands on one of them, not between. */
.cite {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 24px; min-height: 24px; text-align: center; vertical-align: 1px;
  font-size: 12px; font-weight: 700; line-height: 1; color: var(--blue);
  background: var(--blue-light); border-radius: 7px; padding: 0 6px;
  text-decoration: none; margin: 0 2px; cursor: pointer;
}
.bubble .cite { text-decoration: none; }
.cite:hover { background: var(--blue); color: var(--on-accent); }

/* ---- markdown tables ---- */
.table-wrap {
  margin: 10px 0; overflow-x: auto; -webkit-overflow-scrolling: touch;
  border-radius: 10px; background: var(--surface);
}
.table-wrap:focus-visible { outline: 3px solid var(--blue); outline-offset: 2px; }
.table-wrap.is-scrollable {
  background:
    linear-gradient(to right, var(--surface) 30%, rgba(255,255,255,0)) left / 24px 100% no-repeat,
    linear-gradient(to left, var(--surface) 30%, rgba(255,255,255,0)) right / 24px 100% no-repeat,
    radial-gradient(farthest-side at 0 50%, var(--overlay-weak), transparent) left / 12px 100% no-repeat,
    radial-gradient(farthest-side at 100% 50%, var(--overlay-weak), transparent) right / 12px 100% no-repeat,
    var(--surface);
  background-attachment: local, local, scroll, scroll, scroll;
}
.bubble table { border-collapse: collapse; width: 100%; font-size: 13px; min-width: 420px; }
/* The bubble breaks long tokens anywhere so URLs cannot escape it, but inside a
   table that shatters words into 4-character columns. Cells wrap on word
   boundaries and keep a floor width; the wrapper scrolls instead. */
.bubble th, .bubble td {
  border: 1px solid var(--border); padding: 6px 10px; text-align: left; vertical-align: top;
  overflow-wrap: break-word; word-break: normal; hyphens: none; min-width: 88px;
}
.bubble thead th { background: var(--blue-light); color: var(--blue-dark); font-weight: 700; position: sticky; top: 0; }
.bubble tbody tr:nth-child(even) { background: var(--surface-subtle); }
.bubble td.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ---- sources ---- */
.sources { margin-top: 12px; padding-top: 10px; border-top: 1px dashed var(--border-strong); }
.sources h4 { font-size: 12px; color: var(--muted); margin-bottom: 6px; font-weight: 700; }
.src-card {
  position: relative;
  display: block; padding: 10px 12px; margin-top: 6px;
  border: 1px solid var(--border); border-radius: 10px; background: var(--surface);
  scroll-margin-top: 12px;
}
/* The whole card is the link's target; the title alone was a 21px-tall strip. */
.src-card a::after { content: ''; position: absolute; inset: 0; border-radius: inherit; }
.src-card a {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden;
}

/* Folded extras: sources past the first three, and the answer details. */
.src-more > summary, .knowledge-panel > summary {
  display: inline-flex; align-items: center; gap: 6px; min-height: 36px; margin-top: 4px;
  font-size: 13px; font-weight: 600; color: var(--blue); cursor: pointer; list-style: none;
  border-radius: 8px;
}
.src-more > summary::-webkit-details-marker, .knowledge-panel > summary::-webkit-details-marker { display: none; }
.src-more > summary::before, .knowledge-panel > summary::before {
  content: ''; width: 6px; height: 6px; margin: 0 3px 0 1px;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(-45deg); transition: transform .15s;
}
.src-more[open] > summary::before, .knowledge-panel[open] > summary::before { transform: rotate(45deg); }
.src-more[open] > summary { margin-bottom: 0; }
.knowledge-panel > summary { color: var(--muted); }
.src-card:target { border-color: var(--blue); box-shadow: 0 0 0 2px var(--focus-ring); }
.src-card .src-head { display: flex; gap: 6px; align-items: baseline; }
.src-num { flex: 0 0 auto; white-space: nowrap; font-size: 12px; font-weight: 700; color: var(--blue); }
.src-card a { font-size: 14px; line-height: 1.45; font-weight: 600; color: var(--blue); text-decoration: none; }
.src-card a:hover { text-decoration: underline; }
.src-meta { font-size: 12px; color: var(--muted); margin-top: 2px; }

/* Sentence case on purpose. The most common production state is the
   "unverified" badge; in uppercase with letter-spacing it read like a system
   failure banner sitting on top of every answer. */
.mode-badge {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; font-weight: 650; line-height: 1.35;
  padding: 3px 10px; border-radius: 10px; margin-bottom: 8px;
}
.mode-badge::before { content: ''; flex: 0 0 auto; width: 6px; height: 6px; border-radius: 50%; background: currentColor; opacity: .7; }
.mode-badge.llm { background: var(--ok-bg); color: var(--ok-fg); }
.mode-badge.extractive, .mode-badge.unverified { background: var(--warn-bg); color: var(--warn-fg); }
.mode-badge.facts { background: var(--blue); color: var(--on-accent); }
.mode-badge.general { background: var(--violet-bg); color: var(--violet-fg); }

/* ---- answer actions ---- */
.answer-actions { margin-top: 10px; display: flex; gap: 8px; }
.copy-btn {
  min-height: 36px; padding: 6px 12px; font-size: 13px; font-weight: 600;
  border: 1px solid var(--border); border-radius: 9px;
  background: var(--surface); color: var(--muted); cursor: pointer;
  transition: background .15s, color .15s, border-color .15s;
}
.copy-btn:hover { background: var(--blue-light); color: var(--blue); border-color: transparent; }
.copy-btn.is-copied { background: var(--ok-bg); color: var(--ok-fg); border-color: var(--ok-border); }

/* ---- hybrid knowledge profile ---- */
.knowledge-panel { margin-top: 4px; }
.sources + .knowledge-panel { margin-top: 0; }
/* <details> does not lay out as flex everywhere yet; margins space the parts. */
.knowledge-panel > :not(summary) { margin-top: 8px; }
.provenance-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; font-size: 12px; }
.provenance-chip { padding: 3px 7px; border-radius: 12px; background: var(--blue-light); color: var(--blue-dark); }
.permission-policy, .opportunity-disclaimer { color: var(--muted); font-size: 12px; line-height: 1.5; }
.knowledge-gap { padding: 9px 10px; border: 1px solid var(--warn-border); border-radius: 10px; background: var(--warn-bg); }
.knowledge-gap strong { display: block; color: var(--warn-fg); font-size: 13px; line-height: 1.45; }
.knowledge-gap p { margin-top: 3px; font-size: 13px; line-height: 1.5; color: var(--warn-ink); }
.opportunity-box { padding: 9px 10px; border: 1px solid var(--info-border); border-radius: 10px; background: var(--info-soft); }
.opportunity-box h5 { color: var(--blue-dark); font-size: 13px; margin-bottom: 5px; }
.opportunity-group { font-size: 13px; line-height: 1.5; margin-top: 5px; }
.opportunity-group ul { margin: 3px 0 0 18px; }
.opportunity-group li { margin-top: 2px; }
.opportunity-disclaimer { margin-top: 7px !important; }

.stream-status { display: inline-flex; align-items: center; gap: 8px; color: var(--muted); }
.stream-status::before {
  content: ''; flex: 0 0 auto; width: 14px; height: 14px; border: 2px solid var(--border-strong);
  border-top-color: var(--blue); border-radius: 50%; animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ---- error / retry state ---- */
.msg-error {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
  padding: 10px 12px; border-radius: 12px;
  background: var(--danger-bg); border: 1px solid var(--danger-border);
  color: var(--text); font-size: 13px; line-height: 1.45;
}
.msg-error .error-icon {
  flex: 0 0 auto; width: 18px; height: 18px; border-radius: 50%;
  background: var(--danger); color: #fff; font-weight: 800; font-size: 12px;
  display: inline-flex; align-items: center; justify-content: center;
}
.msg-error .error-text { flex: 1 1 180px; min-width: 0; }
.retry-btn {
  flex: 0 0 auto; min-height: 40px; padding: 8px 16px;
  font-size: 13px; font-weight: 700; cursor: pointer;
  border: 1px solid var(--danger); border-radius: 10px;
  background: transparent; color: var(--danger); transition: background .15s;
}
.retry-btn:hover { background: var(--danger); color: #fff; }

/* live-streaming answer text + caret */
.stream-body::after {
  content: ''; display: inline-block; width: 2px; height: 1em; background: var(--blue); margin-left: 3px; vertical-align: -0.12em;
  animation: blink 1s steps(2, start) infinite;
}
@keyframes blink { 50% { opacity: 0; } }

/* retraction note: informative, not alarming */
.draft-note {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--blue-light); color: var(--blue-dark);
  border-radius: 10px;
  padding: 8px 12px; font-size: 13px; line-height: 1.4;
}
.draft-note-icon { flex: 0 0 auto; display: inline-block; width: 14px; height: 14px; border: 2px solid var(--overlay-weak); border-top-color: var(--blue); border-radius: 50%; animation: spin .9s linear infinite; }

/* ---- responsive ---- */
@media (max-width: 1023px) {
  .app { grid-template-columns: minmax(0, 1fr); }
  .main { margin: 0; border: 0; border-radius: 0; box-shadow: none; }
  #historyBtn { display: inline-flex; }
  .sidebar-close { display: inline-flex; }
  /* Off-canvas drawer. visibility:hidden (not just transform) keeps the closed
     drawer out of the tab order and the accessibility tree. */
  .sidebar {
    position: fixed; inset: 0 auto 0 0; z-index: 41;
    width: min(300px, 86vw);
    padding-top: max(14px, env(safe-area-inset-top));
    padding-bottom: max(12px, env(safe-area-inset-bottom));
    box-shadow: var(--shadow-md);
    transform: translateX(-100%); visibility: hidden;
    transition: transform .22s ease, visibility 0s linear .22s;
  }
  .nav-open .sidebar { transform: none; visibility: visible; transition: transform .22s ease; }
  .topbar { padding: 8px 12px; min-height: 60px; gap: 4px; }
  .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
  .history-backdrop { display: none !important; }
}
@media (max-width: 640px) {
  .app { --pad: 14px; }

  /* Header: a plain title and three ghost icons of one size. The solid black
     New chat square that appeared mid-conversation outweighed everything. */
  .model-mode { display: none; }
  .model-name { font-size: 15px; overflow: hidden; text-overflow: ellipsis; }
  .new-chat-btn {
    width: var(--touch); min-height: var(--touch); padding: 0; justify-content: center;
    background: transparent; color: var(--text-2); box-shadow: none;
  }
  .new-chat-btn:hover { background: var(--hover); color: var(--text); opacity: 1; }
  .new-chat-btn:active { background: var(--press); transform: none; }
  /* Icon-only on phones; the label stays as the accessible name. */
  .new-chat-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; }
  .offline-bar { margin-inline: var(--pad); }

  /* Empty state: greeting centred in the free space, a few suggestions, and
     the composer already at the bottom - where it stays after the first send
     instead of jumping there. */
  .welcome { margin: auto; padding: 24px 0 16px; }
  .orb { display: none; }
  .welcome-title { font-size: 22px; line-height: 1.3; }
  .welcome-greeting { font-size: 15px; font-weight: 600; color: var(--muted); letter-spacing: 0; margin-bottom: 6px; }
  .accent { background: none; color: inherit; }
  /* The campaign's two lines: "Tanya proyek apa saja," / "AI jawab tuntas." */
  .welcome-ask > span { display: block; }
  .welcome-lead { font-size: 14px; margin-top: 10px; }
  .is-empty .starters { order: 1; margin: 0 auto; padding: 0 0 12px; }
  .composer-dock { order: 2; }
  .is-empty .composer textarea { min-height: 28px; }
  .cards { display: none; }
  .examples-label { margin: 0 0 8px; }
  .suggestions { flex-direction: column; align-items: stretch; gap: 6px; }
  .suggestions button { border-radius: 14px; line-height: 1.4; }
  .suggestions button:nth-child(n + 5) { display: none; }

  .composer { padding: 10px 10px 8px 14px; border-radius: 18px; }

  /* Answers run the full width. The avatar, the author label and the grey
     bubble left the text 298px of a 390px screen, and said "assistant" three
     times per message; the user's bubble alone marks who is speaking. */
  .thread { gap: 20px; }
  .msg.assistant .msg-avatar { display: none; }
  .msg-author { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; }
  .msg.assistant .bubble { background: none; padding: 0; border-radius: 0; }
  .msg.user .bubble { max-width: 88%; padding: 10px 14px; }

  /* Tables become one card per row, every value labelled with its column: a
     420px-wide table in a phone column hid its last columns off-screen. */
  .table-wrap, .table-wrap.is-scrollable { overflow: visible; background: none; border-radius: 0; margin: 12px 0; }
  .bubble table { min-width: 0; font-size: 14px; }
  .bubble table, .bubble tbody, .bubble tr { display: block; width: 100%; }
  .bubble thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; }
  .bubble tr { padding: 10px 12px; border: 1px solid var(--border); border-radius: 12px; background: var(--surface); }
  .bubble tr + tr { margin-top: 8px; }
  .bubble tbody tr:nth-child(even) { background: var(--surface); }
  .bubble td {
    display: grid; grid-template-columns: minmax(0, 36%) minmax(0, 1fr); gap: 12px;
    width: 100%; min-width: 0; padding: 3px 0; border: 0; line-height: 1.5;
  }
  .bubble td::before { content: attr(data-label); color: var(--muted); font-size: 12px; font-weight: 600; line-height: 1.75; }
  .bubble td:first-child { display: block; padding: 0 0 8px; margin-bottom: 4px; border-bottom: 1px solid var(--border); font-weight: 650; }
  .bubble td:first-child::before { content: none; }
  .bubble td.num { text-align: left; white-space: normal; }

  /* Filters open as a bottom sheet. Inline, the panel grew the composer to
     ~400px and left its own toggle underneath it. */
  .filter-backdrop { display: block; position: fixed; inset: 0; z-index: 44; background: rgba(8, 10, 16, 0.42); }
  .filter-panel {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 45;
    max-height: 80dvh; overflow-y: auto; gap: 14px;
    padding: 6px 16px max(16px, env(safe-area-inset-bottom));
    background: var(--surface); border-top: 0; border-radius: 20px 20px 0 0; box-shadow: var(--shadow-md);
  }
  .sheet-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 52px; }
  .sheet-title { font-size: 16px; font-weight: 650; }
  .sheet-done {
    min-height: var(--touch); padding: 0 16px; border: 0; border-radius: 12px;
    background: var(--blue-light); color: var(--blue-dark); font-size: 14px; font-weight: 650; cursor: pointer;
  }
}
@media (pointer: coarse) {
  /* iOS Safari zooms the page into any field under 16px on focus, and stays
     zoomed: the single biggest source of the layout lurching on an iPhone. */
  .composer textarea, .search input, .field select { font-size: 16px; }
  .history-open { min-height: var(--touch); }
  .history-delete { opacity: 1; width: var(--touch); height: var(--touch); }
  .history-open, .history-row:hover .history-open { padding-right: 50px; }
  .tool-chip, .preset, .suggestions button, .filter-chip, .copy-btn,
  .src-more > summary, .knowledge-panel > summary { min-height: var(--touch); }
  .filter-chip button { min-width: 40px; min-height: 40px; }
  .send-btn, .jump-latest { width: var(--touch); height: var(--touch); }
  .field select { min-height: var(--touch); }
}

@media (forced-colors: active) {
  .accent { color: CanvasText; background: none; }
  .send-btn, .new-chat-btn, .composer, .kb-status, .model-pill { border: 1px solid ButtonText; }
}

@media (prefers-reduced-motion: reduce) {
  .stream-status::before, .draft-note-icon { animation: none; border-color: var(--blue); }
  .stream-body::after { animation: none; }
  .orb { animation: none; }
  .sidebar, .nav-open .sidebar { transition: none; }
  .card, .card:hover { transition: none; transform: none; }
}
