/* ============================================================
   NIGHTWIRE — threat-intel-v3 operator SPA
   Design system: Timeline Spine macrostructure.
   Cold ink + warm bone + cyanotype chrome. Ember reserved to
   KEV + CRITICAL only — never a button, nav item, or chart series.
   Self-hosted fonts: Newsreader (display/figures), Archivo (UI),
   IBM Plex Mono (data — stated Commit Mono fallback).
   ============================================================ */

/* ── Fonts (self-hosted, no external origins) ──────────────────────────── */
@font-face {
  font-family: 'Newsreader';
  font-style: normal; font-weight: 400 600;
  font-display: swap;
  src: url('/assets/fonts/newsreader-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Newsreader';
  font-style: italic; font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/newsreader-italic-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Archivo';
  font-style: normal; font-weight: 400 600;
  font-display: swap;
  src: url('/assets/fonts/archivo-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Commit Mono Fallback';
  font-style: normal; font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/ibmplexmono-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Commit Mono Fallback';
  font-style: normal; font-weight: 600;
  font-display: swap;
  src: url('/assets/fonts/ibmplexmono-600.woff2') format('woff2');
}

/* ── Tokens ──────────────────────────────────────────────────────────────── */
:root {
  /* color */
  --ink: #090C12;
  --plate: #111722;
  --plate-hi: #1A2231;
  --bone: #E9E4D8;
  --cyanotype: #5B8FB9;
  --ember: #FF5233;
  --dim: #8794A3;
  --hair: rgba(233, 228, 216, .09);
  --hair-strong: rgba(233, 228, 216, .16);

  /* severity heat ramp */
  --sev-critical: #FF5233;
  --sev-high: #F0872C;
  --sev-medium: #D9AE3F;
  --sev-low: #8A97A4;
  --sev-info: #5B8FB9;
  --breach-bg: #1E3A52;

  /* type */
  --f-display: 'Newsreader', 'Iowan Old Style', Georgia, serif;
  --f-ui: 'Archivo', -apple-system, 'Segoe UI', sans-serif;
  --f-mono: 'Commit Mono', 'Commit Mono Fallback', 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  --fs-signature: 44px;
  --fs-view-title: 26px;
  --fs-section-head: 15px;
  --fs-row-title: 13.5px;
  --fs-body: 13px;
  --fs-table: 12px;
  --fs-label: 10.5px;
  --fs-micro: 10.5px;

  /* space */
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 24px;

  /* layout */
  --rail-w: 216px;
  --rail-w-collapsed: 56px;
  --ribbon-h: 46px;
  --wire-h: 28px;
  --content-max: 1680px;
  --table-max: 1440px;
  --drawer-w: 480px;
  --radius: 3px;

  /* motion */
  --ease-out: cubic-bezier(.23, 1, .32, 1);
  --ease-drawer: cubic-bezier(.32, .72, 0, 1);
}

/* ── Reset ───────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  background: var(--ink);
  color: var(--bone);
  font-family: var(--f-ui);
  font-size: var(--fs-body);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
}
h1, h2, h3, p, ul, figure { margin: 0; padding: 0; }
ul { list-style: none; }
a { color: var(--cyanotype); text-decoration: none; }
a:hover { text-decoration: underline; }
button, input, select, textarea { font-family: inherit; font-size: inherit; color: inherit; }
button { cursor: pointer; }
code, .mono { font-family: var(--f-mono); }
.tnum { font-feature-settings: 'tnum' 1, 'lnum' 1; font-variant-numeric: tabular-nums lining-nums; }

/* focus ring — always visible, cyanotype */
:focus-visible {
  outline: 2px solid var(--cyanotype);
  outline-offset: 2px;
  border-radius: var(--radius);
}
::selection { background: rgba(91, 143, 185, .35); color: var(--bone); }

/* scrollbars — quiet */
::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--plate-hi); border-radius: 5px; border: 2px solid var(--ink); }

/* ── App shell ───────────────────────────────────────────────────────────── */
.app { display: flex; height: 100vh; width: 100vw; }

/* ── Left rail ───────────────────────────────────────────────────────────── */
.rail {
  width: var(--rail-w);
  flex-shrink: 0;
  background: var(--ink);
  border-right: 1px solid var(--hair);
  display: flex;
  flex-direction: column;
  position: relative;
  transition: width 160ms var(--ease-out);
}
.app.rail-collapsed .rail { width: var(--rail-w-collapsed); }

/* the cyanotype spine rule: runs down the sidebar edge, becomes content spine */
.rail::after {
  content: '';
  position: absolute; top: 0; right: -1px; bottom: 0; width: 1px;
  background: var(--cyanotype);
  opacity: .55;
}

.rail-brand {
  height: var(--ribbon-h);
  display: flex; align-items: center; gap: var(--sp-2);
  padding: 0 var(--sp-4);
  flex-shrink: 0;
  border-bottom: 1px solid var(--hair);
}
.rail-wordmark {
  font-family: var(--f-display);
  font-weight: 600;
  font-size: 17px;
  letter-spacing: .06em;
  color: var(--bone);
  white-space: nowrap;
  overflow: hidden;
}
.app.rail-collapsed .rail-wordmark::after { content: 'N\258C'; }
.app:not(.rail-collapsed) .rail-wordmark::after { content: 'NIGHTWIRE'; }
.rail-collapse-btn {
  margin-left: auto;
  background: none; border: none; color: var(--dim);
  width: 22px; height: 22px; display: flex; align-items: center; justify-content: center;
  border-radius: var(--radius); flex-shrink: 0;
}
.rail-collapse-btn:hover { background: var(--plate-hi); color: var(--bone); }
.app.rail-collapsed .rail-brand { padding: 0; justify-content: center; }
.app.rail-collapsed .rail-collapse-btn { margin-left: 0; }

.rail-nav { flex: 1; overflow-y: auto; padding: var(--sp-3) 0; }
.rail-section-label {
  font-family: var(--f-ui); font-weight: 600; font-size: var(--fs-label);
  letter-spacing: .10em; text-transform: uppercase; color: var(--dim);
  padding: var(--sp-3) var(--sp-4) var(--sp-1);
}
.app.rail-collapsed .rail-section-label { display: none; }

.rail-item {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: 7px var(--sp-4);
  color: var(--dim);
  cursor: pointer;
  position: relative;
  border-left: 2px solid transparent;
}
.rail-item:hover { background: var(--plate); color: var(--bone); }
.rail-item.active { color: var(--bone); background: var(--plate); border-left-color: var(--cyanotype); }
.rail-item.active .rail-icon { color: var(--cyanotype); }
.rail-icon { width: 16px; height: 16px; flex-shrink: 0; }
.rail-item-label { font-size: 13px; font-weight: 500; white-space: nowrap; overflow: hidden; flex: 1; }
.rail-count {
  font-family: var(--f-mono); font-size: 11px; color: var(--dim);
  display: flex; align-items: center; gap: 5px; flex-shrink: 0;
}
.rail-count .dot { width: 5px; height: 5px; border-radius: 50%; background: var(--ember); }
.app.rail-collapsed .rail-item-label,
.app.rail-collapsed .rail-count,
.app.rail-collapsed .rail-section-label { display: none; }
.app.rail-collapsed .rail-item { justify-content: center; padding: 9px 0; }
.app.rail-collapsed .rail-item.active { border-left: none; box-shadow: inset 2px 0 0 var(--cyanotype); }

.rail-footer {
  border-top: 1px solid var(--hair);
  padding: var(--sp-3) var(--sp-4);
  flex-shrink: 0;
}
.rail-identity { display: flex; align-items: center; gap: var(--sp-2); }
.rail-identity-avatar {
  width: 24px; height: 24px; border-radius: var(--radius); flex-shrink: 0;
  background: var(--plate-hi); color: var(--cyanotype);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--f-ui); font-weight: 600; font-size: 11px;
}
.rail-identity-text { min-width: 0; overflow: hidden; }
.rail-identity-name { font-size: 12px; color: var(--bone); font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rail-identity-role { font-size: 10.5px; color: var(--dim); text-transform: uppercase; letter-spacing: .06em; }
.app.rail-collapsed .rail-identity-text { display: none; }

/* ── Content region ──────────────────────────────────────────────────────── */
.content-region { flex: 1; min-width: 0; display: flex; flex-direction: column; height: 100vh; }

/* ── Top ribbon ──────────────────────────────────────────────────────────── */
.ribbon {
  height: var(--ribbon-h); flex-shrink: 0;
  display: flex; align-items: center; gap: var(--sp-4);
  padding: 0 var(--sp-4);
  border-bottom: 1px solid var(--hair);
}
.ribbon-collector { display: flex; align-items: center; gap: var(--sp-2); font-size: 12px; color: var(--dim); }
.collector-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--sev-low); flex-shrink: 0; }
.collector-dot.live { background: var(--sev-info); }
.collector-dot.stale { background: var(--sev-medium); }
.collector-dot.down { background: var(--sev-critical); }
.ribbon-sep { color: var(--hair-strong); }
.ribbon-spacer { flex: 1; }
.cmdk-trigger {
  display: flex; align-items: center; gap: var(--sp-2);
  background: var(--plate); border: 1px solid var(--hair-strong); border-radius: var(--radius);
  padding: 6px 10px; color: var(--dim); font-size: 12px;
}
.cmdk-trigger:hover { color: var(--bone); border-color: var(--cyanotype); }
.cmdk-trigger kbd {
  font-family: var(--f-mono); font-size: 10.5px; color: var(--dim);
  background: var(--plate-hi); border-radius: 2px; padding: 1px 5px;
}
.ribbon-live-paused { color: var(--sev-medium); font-size: 11.5px; display: none; align-items: center; gap: 6px; }
.ribbon-live-paused.show { display: flex; }

/* ── THE WIRE — signature intake strip ──────────────────────────────────── */
/* The single element the tool is meant to be remembered by: full 28px strip
   height, spans the content column (capped/centered at --content-max like
   .view above it, not the full rail-to-edge content-region), a visible
   baseline rule under the ticks, and ticks that actually fill the width —
   the previous max-width:10px cap left 48 ticks clustered in a fraction of
   the strip with the rest sitting empty, reading as decoration rather than
   the product's signature instrument. */
.wire {
  height: var(--wire-h); flex-shrink: 0;
  width: 100%; max-width: var(--content-max); margin: 0 auto;
  border-bottom: 1px solid var(--hair);
  display: flex; align-items: flex-end;
  gap: 1px; padding: 0 var(--sp-4);
  position: relative;
  cursor: crosshair;
  touch-action: none;
  background: var(--plate);
}
/* Baseline rule — a deliberate zero-axis under the ticks (distinct from the
   container's own bottom border), spanning the full strip edge-to-edge. */
.wire::before {
  content: '';
  position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: var(--hair-strong);
  pointer-events: none;
}
.wire-tick {
  flex: 1 1 0; min-width: 2px;
  border-radius: 1px 1px 0 0;
  background: var(--sev-info);
  opacity: .68;
  transform-origin: bottom;
  transition: none;
}
.wire-tick.kev { background: var(--ember); opacity: 1; }
.wire-tick[data-sev="critical"] { background: var(--sev-critical); opacity: .95; }
.wire-tick[data-sev="high"] { background: var(--sev-high); opacity: .85; }
.wire-tick[data-sev="medium"] { background: var(--sev-medium); opacity: .75; }
.wire-tick[data-sev="low"] { background: var(--sev-low); opacity: .68; }
.wire-tick.entering { animation: wireTickIn 160ms var(--ease-out); }
@keyframes wireTickIn { from { opacity: 0; transform: scale(.94); } }
.wire-scrub-band {
  position: absolute; top: 0; bottom: 0;
  background: rgba(91, 143, 185, .16);
  border-left: 1px solid var(--cyanotype); border-right: 1px solid var(--cyanotype);
  pointer-events: none; display: none;
}
.wire-scrub-band.show { display: block; }
.wire-clear {
  position: absolute; right: 6px; top: 3px;
  font-family: var(--f-mono); font-size: 10px; color: var(--cyanotype);
  background: var(--plate-hi); border: 1px solid var(--hair-strong); border-radius: var(--radius);
  padding: 1px 6px; display: none;
}
.wire-clear.show { display: block; }
@media (prefers-reduced-motion: reduce) { .wire-tick.entering { animation: none; } }

/* ── View container ──────────────────────────────────────────────────────── */
.view-scroll { flex: 1; overflow-y: auto; overflow-x: hidden; }
.view {
  max-width: var(--content-max); margin: 0 auto;
  padding: var(--sp-5) var(--sp-5) 64px;
}

.view-header { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--sp-4); margin-bottom: var(--sp-4); flex-wrap: wrap; }
.view-eyebrow { font-family: var(--f-ui); font-weight: 600; font-size: var(--fs-label); letter-spacing: .10em; text-transform: uppercase; color: var(--cyanotype); display: block; margin-bottom: 4px; }
.view-title { font-family: var(--f-display); font-weight: 500; font-size: var(--fs-view-title); line-height: 1.1; color: var(--bone); }
.view-tagline { font-size: 12.5px; color: var(--dim); margin-top: var(--sp-1); max-width: 640px; line-height: 1.5; }
.view-actions { display: flex; gap: var(--sp-2); flex-shrink: 0; }

.section-head { font-family: var(--f-display); font-weight: 500; font-size: var(--fs-section-head); color: var(--bone); margin-bottom: var(--sp-2); }
.axis-label { font-family: var(--f-ui); font-weight: 600; font-size: var(--fs-label); letter-spacing: .08em; text-transform: uppercase; color: var(--dim); margin-bottom: var(--sp-2); display: flex; align-items: center; gap: 6px; }
.axis-label .cyanotype { color: var(--cyanotype); }

/* ── Buttons ─────────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--plate); border: 1px solid var(--hair-strong); color: var(--bone);
  border-radius: var(--radius); padding: 7px 12px; font-size: 12.5px; font-weight: 500;
  transition: background-color 100ms, border-color 100ms, transform 140ms var(--ease-out);
}
.btn:hover { background: var(--plate-hi); border-color: var(--cyanotype); }
.btn:active { transform: scale(.97); }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn-primary { background: var(--cyanotype); border-color: var(--cyanotype); color: var(--ink); font-weight: 600; }
.btn-primary:hover { background: #6b9cc4; }
.btn-ghost { background: transparent; border-color: transparent; }
.btn-ghost:hover { background: var(--plate); border-color: var(--hair-strong); }
.btn-danger { color: var(--sev-critical); }
.btn-danger:hover { background: rgba(255, 82, 51, .1); border-color: var(--sev-critical); }
.btn-sm { padding: 5px 9px; font-size: 11.5px; }
.btn svg { width: 14px; height: 14px; }
.icon { width: 15px; height: 15px; }

/* ── Forms ───────────────────────────────────────────────────────────────── */
.field { display: flex; flex-direction: column; gap: 4px; margin-bottom: var(--sp-3); }
.field label { font-family: var(--f-ui); font-weight: 600; font-size: var(--fs-label); letter-spacing: .06em; text-transform: uppercase; color: var(--dim); }
.input, .select, textarea.input {
  background: var(--plate); border: 1px solid var(--hair-strong); color: var(--bone);
  border-radius: var(--radius); padding: 7px 10px; font-size: 12.5px;
  transition: border-color 100ms;
}
.input:focus, .select:focus, textarea.input:focus { border-color: var(--cyanotype); }
textarea.input { resize: vertical; font-family: var(--f-mono); }
.filter-bar { display: flex; gap: var(--sp-2); flex-wrap: wrap; margin-bottom: var(--sp-4); align-items: center; }
.filter-bar .input, .filter-bar .select { min-width: 140px; }
.toggle-field { display: flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--dim); }

/* ── Panels / cards (elevation via plate ramp, no shadows) ──────────────── */
.panel { background: var(--plate); border: 1px solid var(--hair); border-radius: var(--radius); }
.panel-header { padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--hair); display: flex; align-items: center; gap: var(--sp-2); }
.panel-body { padding: var(--sp-3); }
.stat-tile { background: var(--plate); border: 1px solid var(--hair); border-radius: var(--radius); padding: var(--sp-3); }
.stat-tile-label { font-family: var(--f-ui); font-weight: 600; font-size: var(--fs-label); letter-spacing: .08em; text-transform: uppercase; color: var(--dim); }
.stat-tile-value { font-family: var(--f-display); font-weight: 600; font-size: var(--fs-signature); line-height: 1; color: var(--bone); margin-top: var(--sp-2); }
.stat-tile.critical .stat-tile-value { color: var(--sev-critical); }
.bento { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--sp-3); margin-bottom: var(--sp-5); }
.bento > * { min-width: 0; }
.bento .stat-tile { grid-column: span 1; }

/* ── Rows: spine segments (Timeline Spine macrostructure) ───────────────── */
/* Each row's left edge is colored by its severity heat — stacked, these rows
   form the content spine. Axis label above the list states what's sorted on. */
.spine-list { display: flex; flex-direction: column; gap: var(--sp-2); }
.spine-row {
  background: var(--plate);
  border: 1px solid var(--hair);
  border-left: 3px solid var(--sev-info);
  border-radius: var(--radius);
  padding: var(--sp-2) var(--sp-3);
  cursor: pointer;
  transition: background-color 100ms;
  display: flex; align-items: center; gap: var(--sp-3);
  min-height: 34px;
}
.spine-row:hover { background: var(--plate-hi); }
.spine-row[data-sev="critical"] { border-left-color: var(--sev-critical); }
.spine-row[data-sev="high"] { border-left-color: var(--sev-high); }
.spine-row[data-sev="medium"] { border-left-color: var(--sev-medium); }
.spine-row[data-sev="low"] { border-left-color: var(--sev-low); }
.spine-row[data-sev="info"] { border-left-color: var(--sev-info); }
.spine-row.two-line { min-height: 76px; align-items: flex-start; }
.spine-row-main { flex: 1; min-width: 0; }
.spine-row-title { font-family: var(--f-ui); font-weight: 500; font-size: var(--fs-row-title); color: var(--bone); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.spine-row-sub { font-size: 12px; color: var(--dim); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.spine-row-meta { display: flex; align-items: center; gap: var(--sp-2); flex-shrink: 0; }
.spine-row-time { font-family: var(--f-mono); font-size: var(--fs-micro); color: var(--dim); flex-shrink: 0; white-space: nowrap; }
.spine-row-summary { font-size: 12.5px; color: var(--dim); margin-top: 4px; line-height: 1.5; }

/* ── Badges / chips ──────────────────────────────────────────────────────── */
.badge { display: inline-flex; align-items: center; gap: 4px; font-family: var(--f-ui); font-weight: 600; font-size: 10.5px; letter-spacing: .04em; text-transform: uppercase; padding: 2px 7px; border-radius: var(--radius); }
.badge-critical { color: var(--sev-critical); background: rgba(255, 82, 51, .12); }
.badge-high { color: var(--sev-high); background: rgba(240, 135, 44, .12); }
.badge-medium { color: var(--sev-medium); background: rgba(217, 174, 63, .12); }
.badge-low { color: var(--sev-low); background: rgba(138, 151, 164, .12); }
.badge-info { color: var(--sev-info); background: rgba(91, 143, 185, .12); }
.chip-kev { display: inline-flex; align-items: center; font-family: var(--f-ui); font-weight: 700; font-size: 10px; letter-spacing: .06em; padding: 2px 7px; border-radius: var(--radius); background: var(--ember); color: var(--ink); }
.chip-breach { display: inline-flex; align-items: center; font-family: var(--f-ui); font-weight: 600; font-size: 10px; letter-spacing: .04em; padding: 2px 7px; border-radius: var(--radius); background: var(--breach-bg); color: var(--bone); }
.chip-source { display: inline-flex; align-items: center; font-family: var(--f-mono); font-size: 10.5px; color: var(--dim); background: var(--plate-hi); padding: 2px 7px; border-radius: var(--radius); }
.chip-kind { display: inline-flex; align-items: center; font-family: var(--f-ui); font-size: 10.5px; color: var(--dim); background: var(--plate-hi); padding: 2px 7px; border-radius: var(--radius); text-transform: uppercase; letter-spacing: .04em; }

.epss-wrap { display: flex; align-items: center; gap: 6px; margin-top: 4px; }
.epss-track { width: 64px; height: 4px; background: var(--plate-hi); border-radius: 2px; overflow: hidden; }
.epss-fill { height: 100%; border-radius: 2px; transform-origin: left; }
.epss-fill.first-paint { animation: epssGrow 300ms var(--ease-out); }
@keyframes epssGrow { from { transform: scaleX(0); } }
.epss-label { font-family: var(--f-mono); font-size: 10px; color: var(--dim); }
.score-mono { font-family: var(--f-mono); font-size: 11.5px; }
.score-mono.high { color: var(--sev-critical); }
.score-mono.med { color: var(--sev-high); }
.score-mono.low { color: var(--dim); }
@media (prefers-reduced-motion: reduce) { .epss-fill.first-paint { animation: none; } }

/* ── Tables ──────────────────────────────────────────────────────────────── */
.table-scroll { overflow-x: auto; max-width: var(--table-max); }
table.data-table { width: 100%; border-collapse: collapse; font-family: var(--f-mono); font-size: var(--fs-table); }
table.data-table thead th {
  text-align: left; font-family: var(--f-ui); font-weight: 600; font-size: var(--fs-label);
  letter-spacing: .06em; text-transform: uppercase; color: var(--dim);
  padding: var(--sp-2) var(--sp-3); background: var(--plate-hi); border-bottom: 1px solid var(--hair-strong);
  position: sticky; top: 0; z-index: 1;
}
table.data-table tbody tr { border-left: 3px solid transparent; height: 34px; cursor: pointer; transition: background-color 100ms; }
table.data-table tbody tr:hover { background: var(--plate-hi); }
table.data-table tbody tr[data-sev="critical"] { border-left-color: var(--sev-critical); }
table.data-table tbody tr[data-sev="high"] { border-left-color: var(--sev-high); }
table.data-table tbody tr[data-sev="medium"] { border-left-color: var(--sev-medium); }
table.data-table tbody tr[data-sev="low"] { border-left-color: var(--sev-low); }
table.data-table tbody tr[data-sev="info"] { border-left-color: var(--sev-info); }
table.data-table td { padding: 6px var(--sp-3); border-bottom: 1px solid var(--hair); white-space: nowrap; }
/* single-line ellipsis, NOT wrap — table row density spec is 34px single-line;
   white-space:normal here would let a long title wrap to two lines and blow
   the "≥18 rows above the fold at 1440x900" budget on the patch board. */
table.data-table td.wrap { white-space: nowrap; max-width: 420px; overflow: hidden; text-overflow: ellipsis; }

/* ── Empty / loading / error ─────────────────────────────────────────────── */
.empty-state { text-align: center; padding: 56px var(--sp-4); color: var(--dim); }
.empty-state svg { width: 32px; height: 32px; margin-bottom: var(--sp-3); opacity: .5; }
.empty-state-text { font-size: 13px; max-width: 360px; margin: 0 auto; line-height: 1.5; }
.loading-row { display: flex; justify-content: center; padding: 48px; }
.loading-spin { width: 20px; height: 20px; border: 2px solid var(--hair-strong); border-top-color: var(--cyanotype); border-radius: 50%; animation: spin 700ms linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.error-banner { background: rgba(255, 82, 51, .08); border: 1px solid rgba(255, 82, 51, .3); border-radius: var(--radius); padding: var(--sp-3); color: var(--bone); font-size: 12.5px; margin-bottom: var(--sp-3); }
@media (prefers-reduced-motion: reduce) { .loading-spin { animation-duration: 1400ms; } }

/* ── Pagination ──────────────────────────────────────────────────────────── */
.pagination { display: flex; align-items: center; gap: var(--sp-3); margin-top: var(--sp-4); font-family: var(--f-mono); font-size: 11px; color: var(--dim); }

/* ── Toasts ──────────────────────────────────────────────────────────────── */
#toast-root { position: fixed; bottom: var(--sp-4); right: var(--sp-4); z-index: 900; display: flex; flex-direction: column; gap: var(--sp-2); }
.toast { background: var(--plate-hi); border: 1px solid var(--hair-strong); border-left: 3px solid var(--cyanotype); border-radius: var(--radius); padding: var(--sp-2) var(--sp-3); font-size: 12.5px; color: var(--bone); min-width: 220px; opacity: 1; transition: opacity 300ms; }
.toast.success { border-left-color: var(--sev-low); }
.toast.error { border-left-color: var(--sev-critical); }
.toast.info { border-left-color: var(--cyanotype); }

/* ── Dossier drawer (right side, replaces centered modal) ───────────────── */
.drawer-catch { position: fixed; inset: 0; z-index: 800; display: none; background: transparent; }
.drawer-catch.show { display: block; }
.dossier {
  position: fixed; top: 0; right: 0; bottom: 0; width: var(--drawer-w); max-width: 92vw;
  background: var(--plate); border-left: 1px solid var(--cyanotype);
  z-index: 801; transform: translateX(100%);
  transition: transform 220ms var(--ease-drawer);
  display: flex; flex-direction: column;
  overflow: hidden;
}
.dossier.open { transform: translateX(0); }
@media (prefers-reduced-motion: reduce) { .dossier { transition: none; } }
.dossier-head { padding: var(--sp-4); border-bottom: 1px solid var(--hair); flex-shrink: 0; position: relative; }
/* KEV baseline flare — rare-event only, plays once when a KEV dossier opens */
.dossier-head.kev-flare { animation: kevFlare 600ms ease-out; }
@keyframes kevFlare { from { background-color: rgba(255, 82, 51, .35); } to { background-color: transparent; } }
@media (prefers-reduced-motion: reduce) { .dossier-head.kev-flare { animation: none; } }
.dossier-close { position: absolute; top: var(--sp-3); right: var(--sp-3); background: none; border: none; color: var(--dim); width: 26px; height: 26px; border-radius: var(--radius); display: flex; align-items: center; justify-content: center; }
.dossier-close:hover { background: var(--plate-hi); color: var(--bone); }
.dossier-body { flex: 1; overflow-y: auto; padding: var(--sp-4); }
.dossier-section { margin-bottom: var(--sp-5); }
.dossier-actions { display: flex; gap: var(--sp-2); flex-wrap: wrap; margin-top: var(--sp-3); }
.citation-row { display: flex; align-items: center; gap: var(--sp-2); padding: 6px 0; border-bottom: 1px solid var(--hair); font-size: 12px; }
.citation-row a { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ioc-row { display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-2); background: var(--ink); border: 1px solid var(--hair); border-radius: var(--radius); margin-bottom: 6px; }
.ioc-row code { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 11.5px; }
.technique-row { display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-2) 0; border-bottom: 1px solid var(--hair); }
.technique-id { font-family: var(--f-mono); font-size: 11px; color: var(--cyanotype); flex-shrink: 0; width: 56px; }
.confidence-track { width: 60px; height: 3px; background: var(--plate-hi); border-radius: 2px; overflow: hidden; flex-shrink: 0; }
.confidence-fill { height: 100%; background: var(--cyanotype); }
.niche-score-card { background: var(--ink); border: 1px solid var(--hair); border-left: 3px solid var(--sev-info); border-radius: var(--radius); padding: var(--sp-3); margin-bottom: var(--sp-2); }
.niche-score-card.urgent { border-left-color: var(--sev-critical); }
.niche-score-card.elevated { border-left-color: var(--sev-high); }
.niche-score-card.watch { border-left-color: var(--sev-low); }

/* ── Command palette ─────────────────────────────────────────────────────── */
/* Raycast rule: no open/close animation on the palette itself. */
.cmdk-overlay { position: fixed; inset: 0; z-index: 950; display: none; background: rgba(9, 12, 18, .6); }
.cmdk-overlay.open { display: flex; align-items: flex-start; justify-content: center; padding-top: 12vh; }
.cmdk-box { width: 560px; max-width: 92vw; max-height: 60vh; background: var(--plate); border: 1px solid var(--cyanotype); border-radius: var(--radius); display: flex; flex-direction: column; overflow: hidden; }
.cmdk-input-wrap { display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--hair); flex-shrink: 0; }
.cmdk-input { flex: 1; background: none; border: none; color: var(--bone); font-size: 14px; }
.cmdk-input:focus { outline: none; }
.cmdk-list { overflow-y: auto; padding: var(--sp-2); }
.cmdk-item { display: flex; align-items: center; gap: var(--sp-3); padding: 8px var(--sp-3); border-radius: var(--radius); color: var(--dim); }
.cmdk-item .cmdk-label { color: var(--bone); font-size: 13px; flex: 1; }
.cmdk-item .cmdk-hint { font-family: var(--f-mono); font-size: 10.5px; color: var(--dim); }
.cmdk-item.active { background: var(--plate-hi); color: var(--cyanotype); }
.cmdk-item.active .cmdk-label { color: var(--bone); }
.cmdk-empty { padding: var(--sp-4); text-align: center; color: var(--dim); font-size: 12.5px; }

/* ── Digest markdown render ──────────────────────────────────────────────── */
.md-render { font-size: 13px; line-height: 1.65; color: var(--bone); }
.md-render h3 { font-family: var(--f-display); font-size: 18px; font-weight: 500; margin: var(--sp-4) 0 var(--sp-2); }
.md-render h4 { font-family: var(--f-display); font-size: 15px; font-weight: 500; margin: var(--sp-3) 0 var(--sp-1); }
.md-render p { margin-bottom: var(--sp-3); color: var(--dim); }
.md-render ul { margin: var(--sp-2) 0 var(--sp-3) var(--sp-4); list-style: disc; }
.md-render code { background: var(--ink); padding: 1px 5px; border-radius: 2px; font-size: 12px; }
.md-render a { color: var(--cyanotype); }

/* ── Data-class / breach detail chips ────────────────────────────────────── */
.data-class-chip { display: inline-block; font-size: 10.5px; color: var(--dim); background: var(--plate-hi); padding: 2px 6px; border-radius: var(--radius); margin: 0 4px 4px 0; }

/* ── Actor sparkline (recent-activity indicator, Known APTs view) ───────── */
.actor-spark { display: flex; align-items: flex-end; gap: 2px; height: 22px; flex-shrink: 0; }
.actor-spark-bar { width: 5px; min-height: 2px; background: var(--cyanotype); opacity: .55; border-radius: 1px 1px 0 0; }
.actor-spark-bar.zero { background: var(--hair-strong); opacity: 1; }
.actor-spark-bar.peak { opacity: .95; }

/* ── Known APTs board — card grid (project #417 rebuild) ─────────────────
   Cards replace the old spine-list table for Actors. auto-fill/minmax means
   the grid collapses to a single column on its own once available width
   drops below ~2×260px+gap (confirmed at 390px in VERIFY) — no forced
   breakpoint needed for the common case, but one is kept below as a safety
   net for narrower viewports where the rail's own responsive margin shifts
   the math. Status/momentum use --cyanotype (structural accent) rather than
   the severity ramp — these aren't severity, and --ember stays reserved to
   KEV/critical per the brief. */
.apt-toolbar { font-size: 12px; color: var(--dim); margin-bottom: var(--sp-2); }

.apt-chip-row { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-bottom: var(--sp-3); }
.filter-chip { display: inline-flex; align-items: center; gap: 4px; background: var(--plate-hi); border: 1px solid var(--hair-strong); border-radius: var(--radius); padding: 3px 4px 3px 9px; font-size: 11.5px; color: var(--bone); }
.filter-chip-x { background: transparent; border: none; color: var(--dim); font-size: 14px; line-height: 1; padding: 0 4px; cursor: pointer; transition: color 100ms; }
.filter-chip-x:hover { color: var(--bone); }

.apt-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: var(--sp-3); margin-bottom: var(--sp-3); }
.apt-card {
  background: var(--plate);
  border: 1px solid var(--hair);
  border-radius: var(--radius);
  padding: var(--sp-3);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  min-width: 0;
  transition: background-color 100ms, border-color 100ms;
}
.apt-card:hover, .apt-card:focus-visible { background: var(--plate-hi); border-color: var(--hair-strong); }
.apt-card-top { display: flex; align-items: center; justify-content: space-between; gap: 6px; }
.apt-rank { font-family: var(--f-mono); font-size: var(--fs-micro); color: var(--dim); }
.apt-card-name { font-family: var(--f-display); font-weight: 500; font-size: var(--fs-section-head); color: var(--bone); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.apt-figure-row { display: flex; align-items: flex-end; justify-content: space-between; gap: 8px; }
.apt-status-col { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; flex-shrink: 0; }
.apt-status { display: flex; align-items: center; gap: 5px; font-family: var(--f-ui); font-weight: 600; font-size: 10.5px; letter-spacing: .04em; color: var(--dim); white-space: nowrap; }
.apt-status-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--dim); flex-shrink: 0; }
.apt-status-dot.active { background: var(--cyanotype); }
.apt-momentum { font-family: var(--f-mono); font-size: 10.5px; color: var(--dim); white-space: nowrap; }
.apt-momentum.up { color: var(--cyanotype); }
.apt-spark-row { display: flex; align-items: center; gap: 8px; }
.apt-card-meta { font-size: 11.5px; color: var(--dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.apt-card-time { font-family: var(--f-mono); font-size: var(--fs-micro); color: var(--dim); }
.chip-new { display: inline-flex; align-items: center; font-family: var(--f-ui); font-weight: 700; font-size: 9.5px; letter-spacing: .06em; text-transform: uppercase; padding: 1px 6px; border-radius: var(--radius); border: 1px solid var(--cyanotype); color: var(--cyanotype); }
@media (max-width: 400px) { .apt-grid { grid-template-columns: 1fr; } }

/* ── Dashboard bento layout ──────────────────────────────────────────────── */
.dash-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-3); }
/* min-width:0 is required on every grid item here — without it a nowrapped
   row title's min-content width becomes a floor on the track's width, and
   the whole panel silently overflows its column instead of the text eliding.
   min-height gives Chart.js (maintainAspectRatio:false) a real box to fill —
   without it the canvas's container has no definite height to compute from. */
.dash-panel { grid-column: span 1; display: flex; flex-direction: column; min-width: 0; min-height: 340px; }
.dash-panel.span-2 { grid-column: span 2; }
.dash-panel.span-3 { grid-column: span 3; min-height: 280px; }
.dash-panel-body { flex: 1; overflow-y: auto; overflow-x: hidden; max-height: 360px; min-height: 0; }
.dash-panel-body.flush { padding: 0; }
.dash-panel-body:not(.flush) { padding: var(--sp-3); }
.sig-figure { font-family: var(--f-display); font-weight: 600; font-size: var(--fs-signature); line-height: 1; color: var(--bone); }
.sig-figure.critical { color: var(--sev-critical); }

/* Inline panel-header stat — where the four-KPI-card row's numbers now live
   (no four-KPI-card row, per the brief: the hero is THE WIRE plus one ranked
   list). Pushed to the header's trailing edge via panel-header's flex row. */
.dash-inline-stat { margin-left: auto; font-family: var(--f-mono); font-size: var(--fs-micro); color: var(--dim); white-space: nowrap; }
.dash-inline-stat .hot { color: var(--sev-critical); }

/* ── Exposure / niches / settings detail grids ───────────────────────────── */
.detail-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-4); }
.detail-grid > * { min-width: 0; }
.asset-row { display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-2) var(--sp-3); background: var(--plate); border: 1px solid var(--hair); border-radius: var(--radius); margin-bottom: 6px; }
.asset-row code { flex: 1; font-size: 12px; }

/* ── Niche persona editor ────────────────────────────────────────────────── */
.persona-pre { font-family: var(--f-mono); font-size: 11.5px; color: var(--dim); white-space: pre-wrap; word-break: break-word; background: var(--ink); padding: var(--sp-3); border-radius: var(--radius); border: 1px solid var(--hair); max-height: 140px; overflow-y: auto; }

/* ── Attribution line (cases / bookmarks) ────────────────────────────────── */
.attribution { font-family: var(--f-mono); font-size: 10.5px; color: var(--dim); }

/* ── Delivery rows ───────────────────────────────────────────────────────── */
.delivery-row { display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-2) var(--sp-3); background: var(--plate); border: 1px solid var(--hair); border-left: 3px solid var(--sev-low); border-radius: var(--radius); }
.delivery-row.failed { border-left-color: var(--sev-critical); }
.delivery-row.sent { border-left-color: var(--sev-low); }
.delivery-row.queued { border-left-color: var(--sev-info); }
.delivery-row.retrying { border-left-color: var(--sev-medium); }

/* ── Utility ─────────────────────────────────────────────────────────────── */
.hidden { display: none !important; }
.flex-row { display: flex; align-items: center; gap: var(--sp-2); }
.flex-between { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); }
.text-dim { color: var(--dim); }
.mt-3 { margin-top: var(--sp-3); }
.mb-3 { margin-bottom: var(--sp-3); }

/* ── Role gating: admin-only controls hidden for analyst + public role;
   hide-public controls hidden for public only (still visible to analyst) ── */
.admin-only.role-hidden { display: none !important; }
.hide-public.role-hidden { display: none !important; }

/* ── Public identity chip hint (replaces the role line for role:public) ── */
.rail-identity-role.public-hint { text-transform: none; letter-spacing: normal; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block; max-width: 152px; }

/* ── Responsive ──────────────────────────────────────────────────────────── */
@media (max-width: 900px) {
  /* Icon-only rail is unconditional below 900px — not just narrower, but
     actually collapsed (labels hidden). A width-only shrink here without
     also hiding .rail-item-label etc would leave full-width text overflowing
     a 56px strip into the content column underneath it. */
  .rail { position: fixed; z-index: 700; height: 100vh; width: var(--rail-w-collapsed); }
  .rail-collapse-btn { display: none; }
  .rail-brand { padding: 0; justify-content: center; }
  .rail-wordmark::after { content: 'N\258C' !important; }
  .rail-item { justify-content: center; padding: 9px 0; }
  .rail-item.active { border-left: none; box-shadow: inset 2px 0 0 var(--cyanotype); }
  .rail-item-label, .rail-count, .rail-section-label, .rail-identity-text { display: none; }
  .content-region { margin-left: var(--rail-w-collapsed); }
  .bento { grid-template-columns: repeat(2, 1fr); }
  .dash-grid { grid-template-columns: 1fr; }
  .dash-panel.span-2, .dash-panel.span-3 { grid-column: span 1; }
  .detail-grid { grid-template-columns: 1fr; }
  .view { padding: var(--sp-4) var(--sp-3) 48px; }
  .dossier { width: 100vw; max-width: 100vw; }
  .view-header { flex-direction: column; align-items: flex-start; }
}
@media (max-width: 480px) {
  .bento { grid-template-columns: 1fr 1fr; }
  .ribbon { gap: var(--sp-2); padding: 0 var(--sp-2); }
  .cmdk-trigger span:not(.mono) { display: none; }
}
