/*
  NewsBox v3 - design tokens, lifted from the signalgraph artboards.
  Vanilla CSS only: no Tailwind, no framework. Tokens here, components below.
*/

:root {
  /* Palette */
  --ink: #000000;
  --navy: #14213D;
  --amber: #FCA311;
  --line: #E5E5E5;
  --paper: #F4F4F2;
  --surface: #FFFFFF;

  --text: var(--ink);
  --text-muted: rgba(0, 0, 0, 0.55);
  --text-faint: rgba(0, 0, 0, 0.42);

  /* Neutral ramp for result pills and distributions.
     Deliberately NOT red/green: domain values are user-authored free text, so the app
     cannot know which answer is the "good" one and must not imply it. The ramp varies in
     lightness as well as hue, so it survives colour-vision differences and greyscale. */
  --ramp-1: #14213D;
  --ramp-2: #3A4A6B;
  --ramp-3: #6C7A93;
  --ramp-4: #9AA4B5;
  --ramp-5: #C7CCD6;
  --ramp-6: #E5E7EC;

  /* Type */
  --font-sans: "Plus Jakarta Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* Space + shape */
  --radius-sm: 8px;
  --radius: 10px;
  --radius-lg: 14px;
  --radius-pill: 999px;
  --gutter: 16px;
  --header-h: 60px;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--paper);
  color: var(--text);
  font-family: var(--font-sans);
  -webkit-font-smoothing: antialiased;
}

a { color: var(--navy); text-decoration: none; }
a:hover { color: var(--amber); }

button, input, select, textarea { font-family: inherit; font-size: inherit; }
button { cursor: pointer; }

/* Alpine sets this until it has initialised, so half-bound markup never flashes. */
[x-cloak] { display: none !important; }

.mono { font-family: var(--font-mono); }
.shell { max-width: 1280px; margin: 0 auto; padding: 30px 28px 72px; }

.app-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}

.app-header__inner {
  max-width: 1280px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 0 28px;
  min-height: var(--header-h);
}

.brand { display: flex; align-items: center; gap: 10px; flex: none; }
.brand__mark {
  width: 28px; height: 28px; border-radius: var(--radius-sm);
  background: var(--navy);
  display: flex; align-items: center; justify-content: center;
}
.brand__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--amber); }
.brand__name {
  font-size: 16px; font-weight: 700; letter-spacing: -0.02em; color: var(--navy);
}

.nav { display: flex; align-items: center; gap: 2px; margin-left: auto; }
.nav a {
  font-size: 13.5px; font-weight: 500; color: var(--navy);
  padding: 8px 11px; border-radius: var(--radius-sm);
}
.nav a:hover { background: rgba(229, 229, 229, 0.6); }
.nav a[aria-current="page"] { font-weight: 600; background: rgba(252, 163, 17, 0.16); }

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 20px 22px;
}

.empty {
  background: var(--surface);
  border: 1px dashed var(--line);
  border-radius: var(--radius-lg);
  padding: 44px;
  text-align: center;
}
.empty__title { margin: 0; font-size: 14px; font-weight: 600; color: var(--navy); }
.empty__body { margin: 6px 0 0; font-size: 13px; color: var(--text-muted); }

.page-title {
  margin: 0; font-size: 26px; font-weight: 700;
  letter-spacing: -0.025em; color: var(--navy);
}
.page-sub { margin: 6px 0 0; font-size: 13px; color: var(--text-muted); }

.status-strip {
  display: flex; gap: 8px; flex-wrap: wrap;
  margin-top: 18px; font-family: var(--font-mono); font-size: 11px;
}
.status-chip {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--line); background: var(--surface);
  border-radius: var(--radius-pill); padding: 5px 11px; color: var(--navy);
}
.status-chip__dot { width: 6px; height: 6px; border-radius: 50%; background: var(--ramp-4); }
.status-chip--ok .status-chip__dot { background: var(--amber); }
.status-chip--bad .status-chip__dot { background: var(--navy); }

/* Desktop: the nav is a row and the toggle does not exist. */
.nav-toggle {
  display: none;
  width: 36px; height: 36px;
  align-items: center; justify-content: center;
  border: 1px solid var(--line); background: var(--surface);
  border-radius: 9px; color: var(--navy); cursor: pointer;
}
.nav-toggle:hover { background: var(--navy); color: #fff; border-color: var(--navy); }

@media (max-width: 860px) {
  .shell { padding: 22px var(--gutter) 56px; }
  .app-header__inner { padding: 10px var(--gutter); gap: 10px; flex-wrap: wrap; }

  .nav-toggle { display: inline-flex; margin-left: auto; }

  /* The nav becomes a drawer under the header: hidden until the toggle opens it, then a
     full-width column. `order` puts it last in the wrapped row, so it sits below the
     brand and toggle regardless of its position in the markup. */
  .nav { display: none; }
  .nav--open {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    width: 100%;
    order: 10;
    margin-left: 0;
    gap: 2px;
    padding: 6px 0 4px;
    border-top: 1px solid var(--line);
  }
  .nav--open a { font-size: 15px; font-weight: 600; padding: 12px 10px; }
}

/* ============================================================
   Phase 1 components
   ============================================================ */

.page-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 20px; flex-wrap: wrap; margin-bottom: 20px;
}

.search { flex: 1 1 260px; max-width: 420px; }
.search input {
  width: 100%; height: 40px; border: 1px solid var(--line);
  background: rgba(229, 229, 229, 0.38); border-radius: var(--radius);
  padding: 0 14px; font-size: 13.5px; color: var(--text); outline: none;
}
.search input:focus { border-color: var(--navy); background: var(--surface); }

.chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 18px; }
.chip {
  display: inline-flex; align-items: center; gap: 7px; height: 34px; padding: 0 13px;
  border-radius: var(--radius-pill); font-size: 12.5px; font-weight: 600;
  border: 1px solid var(--line); background: var(--surface); color: var(--navy);
}
.chip:hover { border-color: var(--navy); }
.chip--on { background: var(--navy); color: #fff; border-color: var(--navy); }
.chip__count { font-size: 10.5px; opacity: 0.6; }

.layout { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 22px; align-items: start; }
.layout--wide { grid-template-columns: minmax(0, 1fr) 340px; }
.sidebar { display: flex; flex-direction: column; gap: 14px; position: sticky; top: calc(var(--header-h) + 16px); }

.record {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-lg); padding: 18px 20px 12px; margin-bottom: 10px;
}
.record:hover { border-color: var(--navy); }
.record__head { display: flex; align-items: flex-start; gap: 13px; }
.record__who { min-width: 0; flex: 1; }
.record__name { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 14.5px; }
.record__meta { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 4px; font-size: 11px; color: var(--text-muted); }
.record__body { margin: 12px 0; font-size: 14px; line-height: 1.55; white-space: pre-wrap; overflow-wrap: anywhere; }
.record__media { font-size: 10.5px; color: var(--text-faint); border: 1px dashed var(--line); border-radius: var(--radius-sm); padding: 10px; margin-bottom: 10px; }
.record__foot { display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap; border-top: 1px solid var(--line); padding-top: 10px; margin-top: 4px; }
.record__sources { display: flex; gap: 6px; flex-wrap: wrap; }
.record__id { font-size: 10px; color: var(--text-faint); }
.record__open { flex: none; font-size: 15px; padding: 2px 6px; color: var(--navy); }

.avatar {
  width: 42px; height: 42px; border-radius: 50%; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: rgba(229, 229, 229, 0.6); border: 1px solid var(--line);
  color: var(--navy); font-size: 11px;
}

.tag {
  display: inline-flex; align-items: center; gap: 5px;
  border: 1px solid var(--line); border-radius: var(--radius-pill);
  padding: 2px 8px; font-size: 10px; letter-spacing: 0.04em; color: var(--navy); white-space: nowrap;
}
.tag__dot { width: 5px; height: 5px; border-radius: 50%; background: var(--amber); }

.signals { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.signal {
  display: inline-flex; gap: 5px; font-size: 10.5px;
  background: rgba(229, 229, 229, 0.5); border-radius: var(--radius-sm); padding: 3px 8px;
}
.signal__label { color: var(--text-faint); }

.linklike { background: none; border: 0; padding: 0; font-size: 10.5px; color: var(--navy); text-decoration: underline; }

.card__head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; }
.card__title { font-size: 13px; font-weight: 700; color: var(--navy); }
.card__title--light { color: rgba(255, 255, 255, 0.6); font-size: 10px; letter-spacing: 0.08em; }
.card__action { font-size: 10px; color: var(--text-faint); }
.card--dark { background: var(--navy); color: #fff; border-color: var(--navy); }

.source-list { display: flex; flex-direction: column; gap: 2px; }
.source-row {
  display: flex; align-items: center; gap: 8px; width: 100%;
  background: none; border: 0; border-radius: var(--radius-sm);
  padding: 7px 8px; text-align: left; font-size: 13px; color: var(--navy);
}
.source-row:hover { background: rgba(229, 229, 229, 0.6); }
.source-row--on { background: rgba(252, 163, 17, 0.16); font-weight: 600; }
.source-row__dot { width: 6px; height: 6px; border-radius: 50%; background: var(--ramp-4); flex: none; }
.source-row__name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.source-row__count { font-size: 10.5px; color: var(--text-faint); }

.stat-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-top: 10px; }
.stat__value { font-size: 22px; font-weight: 700; letter-spacing: -0.02em; }
.stat__label { font-size: 9.5px; color: var(--text-faint); margin-top: 2px; }

.source-cards { display: flex; flex-direction: column; gap: 10px; }
.source-card { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; row-gap: 12px; padding: 14px 20px; }
.source-card__main { flex: 1 1 300px; min-width: 0; }
.source-card__stat { flex: none; width: 120px; }
.source-card__status { flex: none; width: 160px; }
.source-card__actions { display: flex; gap: 4px; margin-left: auto; }

.pill { display: inline-flex; align-items: center; gap: 6px; border-radius: var(--radius-pill); padding: 5px 10px; font-size: 11.5px; font-weight: 600; white-space: nowrap; }
.pill--on { background: rgba(252, 163, 17, 0.18); color: var(--ink); }
.pill--off { background: rgba(229, 229, 229, 0.75); color: var(--text-muted); }
.pill__dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }

.progress { margin-top: 8px; }
.progress__bar { height: 3px; background: var(--amber); border-radius: 2px; transition: width 0.3s ease; }
.progress__text { display: block; font-size: 9.5px; color: var(--text-faint); margin-top: 4px; }

.pulse { display: inline-flex; align-items: center; gap: 6px; font-size: 10px; color: var(--navy); margin-left: 12px; }
.pulse__dot { width: 7px; height: 7px; border-radius: 50%; background: var(--amber); animation: pulse 1.4s ease-in-out infinite; }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 38px; padding: 0 16px; border-radius: var(--radius);
  border: 1px solid var(--line); background: var(--surface);
  font-size: 13.5px; font-weight: 600; color: var(--navy);
}
.btn:hover:not(:disabled) { border-color: var(--navy); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
.btn--primary { background: var(--amber); border-color: var(--amber); color: var(--ink); font-weight: 700; }
.btn--primary:hover:not(:disabled) { background: var(--navy); border-color: var(--navy); color: #fff; }
.btn--ghost { background: transparent; border-color: rgba(255, 255, 255, 0.22); color: #fff; }
.btn--ghost:hover { background: rgba(255, 255, 255, 0.1); }

.icon-btn {
  width: 34px; height: 34px; display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--line); background: var(--surface); border-radius: 9px;
  color: var(--navy); font-size: 13px;
}
.icon-btn:hover { background: var(--navy); color: #fff; border-color: var(--navy); }
.icon-btn--danger:hover { background: var(--ink); border-color: var(--ink); }

.crumbs { display: flex; gap: 8px; font-size: 10px; color: var(--text-faint); margin-bottom: 12px; }

.steps { display: flex; flex-direction: column; gap: 14px; }
.step__head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.step__head h2 { margin: 0; font-size: 15px; font-weight: 700; color: var(--navy); }
.step__num { font-size: 10px; color: var(--text-faint); border: 1px solid var(--line); border-radius: 6px; padding: 2px 6px; }
.step__hint { margin: 0 0 14px; font-size: 12.5px; line-height: 1.5; color: var(--text-muted); }

.field { display: flex; flex-direction: column; gap: 6px; flex: 1 1 200px; }
.field__label { font-size: 9.5px; letter-spacing: 0.06em; color: var(--text-faint); }
.field input, .field select, .term-builder input, .term-builder select {
  height: 38px; border: 1px solid var(--line); border-radius: var(--radius);
  padding: 0 12px; font-size: 13.5px; background: var(--surface); color: var(--text); outline: none;
}
.field input:focus, .field select:focus { border-color: var(--navy); }
.field-row { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 12px; }

.term-builder { display: flex; flex-direction: column; gap: 10px; }
.term-builder__row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.term-builder__row input[type="text"] { flex: 1 1 220px; }
.term-builder__row select { flex: 0 1 180px; }

.term-list { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 14px; }
.term {
  display: inline-flex; align-items: center; gap: 8px;
  background: rgba(252, 163, 17, 0.14); border: 1px solid rgba(252, 163, 17, 0.5);
  border-radius: var(--radius-pill); padding: 5px 10px; font-size: 11.5px;
}
.term button { background: none; border: 0; font-size: 14px; line-height: 1; color: var(--text-muted); }
.term button:hover { color: var(--ink); }

.hint { margin: 0; font-size: 12px; color: var(--text-muted); }
.hint--bad { color: var(--ink); font-weight: 600; }
.hint--ok { color: var(--navy); font-weight: 600; }

.mode-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.mode {
  display: flex; flex-direction: column; gap: 4px; align-items: flex-start; text-align: left;
  border: 1px solid var(--line); background: var(--surface);
  border-radius: var(--radius); padding: 12px 14px;
}
.mode strong { font-size: 13.5px; color: var(--navy); }
.mode span { font-size: 12px; color: var(--text-muted); line-height: 1.45; }
.mode--on { border-color: var(--amber); background: rgba(252, 163, 17, 0.1); }

.checkbox { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; cursor: pointer; }
.checkbox--light { color: rgba(255, 255, 255, 0.85); margin-top: 14px; }
.toggles { display: flex; gap: 16px; flex-wrap: wrap; margin-top: 14px; }

.summary__name { margin: 8px 0 14px; font-size: 16px; font-weight: 700; }
.summary__rows { display: flex; flex-direction: column; gap: 7px; font-size: 12.5px; }
.summary__row { display: flex; justify-content: space-between; gap: 12px; color: rgba(255, 255, 255, 0.7); }
.summary__row .mono { color: #fff; }
.summary__actions { display: flex; gap: 8px; margin-top: 18px; flex-wrap: wrap; }

.alert { border-radius: var(--radius); padding: 12px 14px; font-size: 13px; margin-bottom: 14px; }
.alert--error { background: rgba(20, 33, 61, 0.06); border: 1px solid var(--navy); color: var(--navy); }

.skeleton { padding: 30px; text-align: center; font-size: 13px; color: var(--text-faint); }
.load-more { display: flex; justify-content: center; padding: 18px 0; }
.empty .btn { margin-top: 14px; }

.expand-row { display: flex; align-items: center; gap: 12px; margin-top: 10px; }
.btn--small { height: 30px; padding: 0 12px; font-size: 12px; }
.link-btn {
  background: none; border: none; padding: 0; cursor: pointer;
  font-size: 12px; color: var(--text-muted); text-decoration: underline;
}
.link-btn:hover { color: var(--navy); }

.tag--warn { border-color: var(--amber); color: var(--navy); }
.hint--error { color: var(--ink); }
.input--warn { border-color: var(--amber); }

/* Charts. The scroll container is what keeps a wide calendar or sankey from forcing the
   whole page sideways on a phone - the SVGs keep their intrinsic width and scroll inside. */
.chart-scroll { overflow-x: auto; padding-bottom: 4px; }
.chart__axis { font-family: var(--font-mono); font-size: 9px; fill: var(--text-muted); }
.chart__label { font-size: 11px; fill: var(--navy); }
.chart__tile { font-size: 11.5px; font-weight: 600; }
.chart__tile--sub { font-family: var(--font-mono); font-size: 10px; opacity: 0.85; }
.card__note { font-size: 10px; color: var(--text-muted); }

/* Dialog. Fixed rather than absolute so it is centred on the viewport regardless of how far
   down the timeline the record sits. */
.modal { position: fixed; inset: 0; z-index: 60; display: flex;
         align-items: center; justify-content: center; padding: 20px; }
.modal__backdrop { position: absolute; inset: 0; background: rgba(20, 33, 61, 0.45); }
.modal__panel {
  position: relative; width: 100%; max-width: 620px;
  max-height: calc(100vh - 40px); overflow-y: auto;
}
.record__foot-right { display: flex; align-items: center; gap: 14px; }
.draft-preview {
  margin: 10px 0 0; padding: 12px 14px; font-size: 13.5px; line-height: 1.5;
  background: rgba(229, 229, 229, 0.35); border-radius: var(--radius-sm);
}

.shell--narrow { max-width: 560px; }
.login { text-align: center; padding: 40px 32px; }
.login__actions { display: flex; flex-direction: column; gap: 10px; margin-top: 22px; }
.login__actions .btn { justify-content: center; text-decoration: none; }

@media (max-width: 980px) {
  .layout, .layout--wide { grid-template-columns: minmax(0, 1fr); }
  .sidebar { position: static; }
  .mode-grid { grid-template-columns: 1fr; }
  .source-card__stat, .source-card__status { width: auto; }
  .source-card__actions { margin-left: 0; width: 100%; }
}

/* ============================================================
   Phase 2 — analysis and results
   ============================================================ */

.question {
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 14px; margin-top: 10px; background: var(--surface);
}
.question__row { display: flex; align-items: center; gap: 8px; }
.question__row input { flex: 1; height: 38px; border: 1px solid var(--line); border-radius: var(--radius); padding: 0 12px; font-size: 13.5px; }
.question__domains { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-top: 10px; }
.question__domains input { height: 30px; border: 1px dashed var(--line); border-radius: var(--radius-pill); padding: 0 12px; font-size: 11.5px; min-width: 150px; }
.question__presets { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 10px; }
.question__presets .chip { height: 26px; font-size: 11px; padding: 0 10px; }

.editor-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--line); }

/*
  The result pill: a proportional background split across every domain value, with the
  question and the leading share laid over it. Colours come from the neutral ramp - see
  api.js for why this palette implies nothing about which answer is "good".
*/
.pill-stack { display: flex; flex-direction: column; gap: 10px; margin-bottom: 18px; }
.result-pill { position: relative; border-radius: var(--radius-pill); overflow: hidden; border: 1px solid var(--line); min-height: 52px; display: flex; align-items: center; }
.result-pill__bg { position: absolute; inset: 0; display: flex; }
.result-pill__seg { height: 100%; display: block; }
.result-pill__text { position: relative; display: flex; align-items: center; justify-content: space-between; gap: 16px; width: 100%; padding: 0 20px; }
.result-pill__text strong { font-size: 14px; font-weight: 700; color: #fff; text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5); }
.result-pill__headline { font-size: 14px; font-weight: 700; color: #fff; white-space: nowrap; text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5); }

.result-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 12px; }

.dist { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
.dist__row { display: flex; align-items: center; gap: 10px; font-size: 12.5px; }
.dist__label { flex: 0 0 96px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dist__track { flex: 1; height: 10px; background: rgba(229, 229, 229, 0.7); border-radius: 5px; overflow: hidden; }
.dist__bar { display: block; height: 100%; border-radius: 5px; }
.dist__value { flex: 0 0 110px; text-align: right; font-size: 10.5px; color: var(--text-muted); }

.trend { width: 100%; height: 190px; margin-top: 12px; overflow: visible; }

.legend { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 12px; font-size: 11.5px; }
.legend__item { display: inline-flex; align-items: center; gap: 6px; }
.legend__dot { width: 10px; height: 10px; border-radius: 3px; }

.cross { display: flex; flex-direction: column; gap: 12px; margin-top: 14px; }
.cross__row { display: flex; align-items: center; gap: 14px; }
.cross__head { flex: 0 0 150px; }
.cross__head div:first-child { font-size: 13px; font-weight: 600; }
.cross__total { font-size: 10px; color: var(--text-faint); margin-top: 2px; }
.cross__bar { flex: 1; display: flex; height: 30px; border-radius: var(--radius-sm); overflow: hidden; }
.cross__seg { display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 600; }

@media (max-width: 720px) {
  .cross__row { flex-direction: column; align-items: stretch; gap: 6px; }
  .cross__head { flex: none; }
  .result-pill__text { flex-direction: column; align-items: flex-start; gap: 2px; padding: 10px 16px; }
}

/*
  An answer chip is visually distinct from an engagement metric on purpose: one is a model's
  judgement and the other is a number the platform reported. Conflating them is how a
  dashboard starts presenting an inference as a measurement.
*/
.signal--answer {
  background: rgba(20, 33, 61, 0.1);
  color: var(--navy);
  font-weight: 600;
  border: 1px solid rgba(20, 33, 61, 0.18);
}

/* ============================================================
   Phase 4 — Talk to data
   ============================================================ */

.chat { display: flex; flex-direction: column; gap: 12px; }

.chat__thread {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-lg); padding: 20px;
  min-height: 420px; max-height: 62vh; overflow-y: auto;
  display: flex; flex-direction: column; gap: 14px;
}

.bubble { display: flex; gap: 12px; align-items: flex-start; }
.bubble--user { flex-direction: row-reverse; }

.bubble__avatar {
  width: 32px; height: 32px; flex: none;
  display: flex; align-items: center; justify-content: center;
  font-size: 9.5px; border-radius: 10px;
  background: var(--navy); color: #fff;
}
.bubble--user .bubble__avatar {
  background: rgba(229, 229, 229, 0.9); color: var(--navy); border-radius: 50%;
}

.bubble__body {
  max-width: 78%;
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 12px 16px; background: var(--surface);
}
.bubble--user .bubble__body {
  background: rgba(252, 163, 17, 0.14); border-color: rgba(252, 163, 17, 0.5);
}

.bubble__text { margin: 0; font-size: 13.5px; line-height: 1.6; white-space: pre-wrap; overflow-wrap: anywhere; }
.bubble__typing { font-size: 12px; color: var(--text-faint); font-style: italic; }
.bubble__cites { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 10px; }
.bubble__meta { font-size: 10px; color: var(--text-faint); margin-top: 8px; }

.cite {
  font-size: 10px; padding: 3px 8px; border-radius: var(--radius-pill);
  border: 1px solid var(--line); background: rgba(229, 229, 229, 0.5); color: var(--navy);
}
.cite:hover { border-color: var(--navy); background: var(--surface); }

.composer {
  display: flex; gap: 10px; align-items: flex-end;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-lg); padding: 12px 14px;
}
.composer textarea {
  flex: 1; border: 0; outline: none; resize: none;
  font-size: 13.5px; line-height: 1.5; background: transparent; color: var(--text);
}

.summary__row--light { color: var(--text-muted); }
.summary__row--light .mono { color: var(--text); }

/*
  A warning, not an error: the answer still works, it is just drawn from less than the user
  might assume. Distinguishing the two matters — treating "part of the corpus is not embedded
  yet" as a failure would train people to ignore it.
*/
.alert--warn {
  background: rgba(252, 163, 17, 0.12);
  border: 1px solid rgba(252, 163, 17, 0.55);
  color: var(--ink);
}

@media (max-width: 980px) {
  .bubble__body { max-width: 100%; }
  .chat__thread { max-height: none; }
}

/* ============================================================
   Phase 5 — the replier
   ============================================================ */

.chip--muted { opacity: 0.55; border-style: dashed; }
.signal--muted { opacity: 0.5; }

/* The original post, quoted above the draft so a reviewer sees what is being replied to. */
.reply__original {
  margin: 0 0 12px; padding: 10px 14px;
  border-left: 3px solid var(--line);
  font-size: 12.5px; line-height: 1.5; color: var(--text-muted);
  background: rgba(229, 229, 229, 0.3);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}

.reply__draft {
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 12px 14px; background: var(--surface);
}
.reply__text { margin: 0; font-size: 13.5px; line-height: 1.55; white-space: pre-wrap; }
.reply__editor {
  width: 100%; border: 0; outline: none; resize: vertical;
  font-size: 13.5px; line-height: 1.55; background: transparent; color: var(--text);
}
.reply__meta { margin-top: 8px; font-size: 10.5px; color: var(--text-faint); display: flex; gap: 6px; }

/*
  An over-length draft cannot be posted as-is, so it is marked rather than left to be
  discovered when someone pastes it and the platform refuses.
*/
.reply__over { color: var(--ink); font-weight: 700; }
.card--flagged { border-color: var(--amber); }

/* ============================================================
   Phase 6 — admin, offline, i18n
   ============================================================ */

.lang {
  height: 30px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--navy); font-size: 10.5px;
  padding: 0 6px; margin-left: 8px;
}

/* Offline reads as a state, not an error: the app still works, on a snapshot. */
.pulse--offline .pulse__dot { background: var(--ramp-3); animation: none; }

.setting {
  display: flex; align-items: flex-start; gap: 16px; flex-wrap: wrap;
  padding: 14px 0; border-bottom: 1px solid var(--line);
}
.setting:last-child { border-bottom: 0; }
.setting__main { flex: 1 1 340px; min-width: 0; }
.setting__key { font-size: 11.5px; color: var(--navy); font-weight: 600; }
.setting__help { font-size: 12px; line-height: 1.5; color: var(--text-muted); margin-top: 4px; }
.setting__input {
  flex: 0 1 220px; height: 36px; border: 1px solid var(--line);
  border-radius: var(--radius); padding: 0 12px; font-size: 12.5px; background: var(--surface);
}
.setting__input:focus { border-color: var(--navy); outline: none; }

/*
  The destructive panel is marked but not screaming. The real control is the typed
  confirmation phrase — colour alone trains people to click past it.
*/
.card--danger { border-color: var(--ink); }
.card--danger .card__title { color: var(--ink); }

.btn--danger { background: var(--ink); border-color: var(--ink); color: #fff; font-weight: 700; }
.btn--danger:hover:not(:disabled) { background: var(--navy); border-color: var(--navy); }
.btn--disabled { opacity: 0.45; pointer-events: none; }

/* ============================================================
   Record cards — the catalog list item
   ------------------------------------------------------------
   Replaces .source-card for the catalog tabs. The old layout put the actions in the same
   flex row as the title with `margin-left:auto`, which on a phone left them sitting on top
   of a long name. Here the actions are their own row and only join the title row once
   there is width to hold both.
   ============================================================ */

.recs { display: flex; flex-direction: column; gap: 12px; }

.rec { display: flex; flex-direction: column; gap: 14px; }

.rec__top { display: flex; gap: 14px; align-items: flex-start; min-width: 0; }

/* The type badge. Monospace and abbreviated so every card is the same width regardless of
   how long the entity's name is - it reads as a column, not as decoration. */
.rec__icon {
  flex: none; width: 46px; height: 46px; border-radius: var(--radius);
  display: flex; align-items: center; justify-content: center;
  background: rgba(229, 229, 229, 0.55); color: var(--text-muted);
  font-family: var(--font-mono); font-size: 9.5px; font-weight: 700; letter-spacing: 0.06em;
}

.rec__body { flex: 1; min-width: 0; }

.rec__title {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: 16px; font-weight: 700; color: var(--navy); letter-spacing: -0.015em;
  overflow-wrap: anywhere;
}

/* Clamped: a perspective description can be ten sentences, and a list of records is a place
   to recognise one, not to read it. */
.rec__sub {
  margin-top: 4px; font-size: 12.5px; line-height: 1.5; color: var(--text-muted);
  overflow-wrap: anywhere;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}

.rec__tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }

.rec__actions {
  display: flex; flex-wrap: wrap; gap: 8px;
  border-top: 1px solid var(--line); padding-top: 12px;
}
/* Full-width, labelled and thumb-sized on a phone. min-width keeps four actions from
   collapsing into unreadable slivers on the Generations card. */
.rec__actions .btn { flex: 1 1 0; min-width: 104px; justify-content: center; }

.rec__foot {
  display: flex; justify-content: space-between; align-items: center; gap: 10px;
  flex-wrap: wrap; font-size: 11px; color: var(--text-faint);
  border-top: 1px solid var(--line); padding-top: 12px;
}

@media (min-width: 760px) {
  /* Enough room for the actions to sit beside the record instead of under it. */
  .rec { flex-direction: row; align-items: flex-start; gap: 20px; }
  .rec__top { flex: 1; }
  .rec__actions {
    flex: none; flex-wrap: nowrap; border-top: 0; padding-top: 0;
  }
  .rec__actions .btn { flex: 0 0 auto; min-width: 0; }
  .rec__foot { flex-basis: 100%; }
}

/* The Generations card carries a footer, so its actions must not be pulled onto the title
   row - the footer belongs under both. */
.rec--stacked { flex-direction: column; }
@media (min-width: 760px) {
  .rec--stacked { flex-direction: column; }
  .rec--stacked .rec__actions { border-top: 1px solid var(--line); padding-top: 12px; }
}

/* The primary action sits under the heading rather than beside it: at phone width a
   right-floated button wrapped onto the title and covered it. */
.page-actions { display: flex; gap: 10px; flex-wrap: wrap; margin: -6px 0 18px; }

/* Destructive, but not shouting. Solid black on every card in a list reads as an alarm;
   the weight belongs on hover, when the pointer is already on it. */
.rec__del:hover:not(:disabled) { border-color: var(--ink); color: var(--ink); }

/* Informational, not a problem: the local-search note sits above the feed while the box
   holds text the server has not been asked about. Quieter than --warn on purpose - it is
   telling you where you are, not that something went wrong. */
.alert--info {
  background: rgba(229, 229, 229, 0.5);
  border: 1px solid var(--line);
  color: var(--text-muted);
}

/* The search box and the order control travel together in the page head, and wrap together
   onto their own line before either one gets squeezed. */
.head-tools { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; flex: 1 1 320px; }
.head-tools .search { flex: 1 1 200px; }

.sort { display: inline-flex; align-items: center; gap: 8px; flex: none; }
.sort__label { font-size: 9.5px; letter-spacing: 0.08em; color: var(--text-faint); }
.sort select {
  height: 40px; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--surface); color: var(--text); padding: 0 10px; font-size: 13px;
}
.sort select:focus { border-color: var(--navy); outline: none; }
