/* Design tokens: see docs/ui.md. Dark is the default; light follows the system preference, and
   data-theme on <html> forces either. Every rule below reads these, never raw colours. */
:root {
  color-scheme: dark;
  --bg: #08111f;
  --surface: #0d1b2f;
  --surface-2: #13243d;
  --surface-3: #1a2e4c;
  --fg: #e8eef7;
  --fg-2: #b8c5d8;
  --muted: #91a3bf;
  --accent: #7aaeff;
  --primary: #2563eb;
  --primary-hover: #1d4ed8;
  --on-primary: #ffffff;
  --border: rgba(125, 160, 225, 0.16);
  --border-strong: rgba(125, 160, 225, 0.32);
  --nav-bg: rgba(8, 17, 31, 0.86);
  --warm: #f0be78;
  --err: #ff8a80;
  --warn: #f5c451;
  --ok: #4fd6a0;
  --sev-critical: #ff8a80;
  --sev-high: #ffa366;
  --sev-medium: #f5c451;
  --sev-low: #4fd6a0;
  --sev-none: #91a3bf;
  --kev-bg: #dc2626;
  --kev-fg: #ffffff;
  --add: #4fd6a0;
  --del: #ff8a80;
  --tint: 15%;
  --shadow-card: inset 0 1px 0 rgba(255, 255, 255, 0.04);
  --shadow-pop: 0 8px 32px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.04);
  --ring: 0 0 0 3px rgba(37, 99, 235, 0.35);
  /* Chart series, in fixed order (validated categorical palette, dark surface) */
  --series-1: #3987e5;
  --series-2: #d95926;
  --series-3: #199e70;
  --series-4: #c98500;

  --font: Inter, "Segoe UI Variable", "Segoe UI", system-ui, -apple-system, Roboto, "Helvetica Neue", sans-serif;
  --mono: ui-monospace, "Cascadia Mono", "SF Mono", Menlo, Consolas, monospace;
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 20px;
  --sp-6: 24px;
  --r-sm: 6px;
  --r-md: 8px;
  --r-lg: 12px;
  --r-pill: 999px;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --t-fast: 150ms;
  --page-max: 1200px;
  --gutter: 16px;

  /* Derived */
  --card: var(--surface);
  --badge-bg: var(--surface-3);
  --brief-bg: color-mix(in srgb, var(--primary) 10%, var(--surface));
  --accent-tint: color-mix(in srgb, var(--primary) 18%, var(--surface));
  --hot-bg: color-mix(in srgb, var(--sev-high) var(--tint), var(--surface));
  --hot-fg: var(--sev-high);
  --due-bg: color-mix(in srgb, var(--warn) var(--tint), var(--surface));
  --due-fg: var(--warn);
}
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    color-scheme: light;
    --bg: #f4f6fa;
    --surface: #ffffff;
    --surface-2: #f1f4f9;
    --surface-3: #e6ebf3;
    --fg: #0f172a;
    --fg-2: #334155;
    --muted: #4b596d;
    --accent: #1d4ed8;
    --border: rgba(15, 23, 42, 0.12);
    --border-strong: rgba(15, 23, 42, 0.24);
    --nav-bg: rgba(244, 246, 250, 0.88);
    --warm: #7a5000;
    --err: #b42318;
    --warn: #7a5000;
    --ok: #116a3a;
    --sev-critical: #b42318;
    --sev-high: #a8320f;
    --sev-medium: #7a5000;
    --sev-low: #116a3a;
    --sev-none: #4b596d;
    --kev-bg: #c81e1e;
    --add: #116a3a;
    --del: #b42318;
    --tint: 11%;
    --shadow-card: 0 1px 2px rgba(15, 23, 42, 0.04), 0 8px 24px -16px rgba(15, 23, 42, 0.18);
    --shadow-pop: 0 2px 4px rgba(15, 23, 42, 0.06), 0 24px 64px -16px rgba(15, 23, 42, 0.28);
    --ring: 0 0 0 3px rgba(37, 99, 235, 0.22);
    /* Chart series (validated categorical palette, light surface) */
    --series-1: #2a78d6;
    --series-2: #eb6834;
    --series-3: #1baf7a;
    --series-4: #eda100;
  }
}
/* A forced light theme repeats the light values (no shared rule can apply them under both selectors). */
:root[data-theme="light"] {
  color-scheme: light;
  --bg: #f4f6fa; --surface: #ffffff; --surface-2: #f1f4f9; --surface-3: #e6ebf3;
  --fg: #0f172a; --fg-2: #334155; --muted: #4b596d; --accent: #1d4ed8;
  --border: rgba(15, 23, 42, 0.12); --border-strong: rgba(15, 23, 42, 0.24); --nav-bg: rgba(244, 246, 250, 0.88);
  --warm: #7a5000; --err: #b42318; --warn: #7a5000; --ok: #116a3a;
  --sev-critical: #b42318; --sev-high: #a8320f; --sev-medium: #7a5000; --sev-low: #116a3a; --sev-none: #4b596d;
  --kev-bg: #c81e1e; --add: #116a3a; --del: #b42318; --tint: 11%;
  --shadow-card: 0 1px 2px rgba(15, 23, 42, 0.04), 0 8px 24px -16px rgba(15, 23, 42, 0.18);
  --shadow-pop: 0 2px 4px rgba(15, 23, 42, 0.06), 0 24px 64px -16px rgba(15, 23, 42, 0.28);
  --ring: 0 0 0 3px rgba(37, 99, 235, 0.22);
  --series-1: #2a78d6; --series-2: #eb6834; --series-3: #1baf7a; --series-4: #eda100;
}

/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }  /* author display rules must not reveal hidden elements */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font: 14px/1.5 var(--font);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
::selection { background: var(--primary); color: var(--on-primary); }
h1, h2, h3, h4, h5 { line-height: 1.3; font-weight: 600; color: var(--fg); }
h2 { font-size: 20px; margin: var(--sp-5) 0 var(--sp-2); }
h3 { font-size: 16px; margin: var(--sp-4) 0 var(--sp-2); }
h4 { font-size: 14px; }
a { color: var(--accent); text-underline-offset: 2px; }
code, kbd, pre, samp { font-family: var(--mono); }
code { font-size: 0.9em; background: var(--surface-2); padding: 0 4px; border-radius: 4px; overflow-wrap: anywhere; }
details > summary { cursor: pointer; }
details > summary::marker { color: var(--muted); }

/* Focus: one visible ring everywhere; headings that take programmatic focus stay quiet. */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
h2[tabindex="-1"]:focus { outline: none; }

/* Motion: colour and border ease; nothing moves when the reader asks for less. */
a, button, input, select, textarea, .story, .market, .chip, .badge {
  transition: color var(--t-fast) var(--ease), background-color var(--t-fast) var(--ease),
    border-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0s !important;
    animation-duration: 0s !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
}

/* ---------- Header ---------- */
.top {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  max-width: var(--page-max);
  margin: 0 auto;
  padding: var(--sp-3) var(--gutter);
}
.top h1 {
  font-size: 16px;
  font-weight: 700;
  margin: 0;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  white-space: nowrap;
}
.top h1::before {
  content: "";
  width: 10px;
  height: 10px;
  border-radius: 3px;
  background: var(--primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 28%, transparent);
}
.chips { display: flex; gap: 6px; flex-wrap: wrap; margin-left: auto; }
.chips .chip {
  color: var(--warm);
  background: color-mix(in srgb, var(--warm) var(--tint), var(--surface));
  border-color: color-mix(in srgb, var(--warm) 30%, transparent);
  font-weight: 600;
}
.who { color: var(--muted); font-size: 13px; margin-left: auto; }
/* The read-only guest of a shared portal (docs/implementation.md#sharing-publicly): controls that write are gone. */
body.guest .writes { display: none !important; }
.demo-badge { background: var(--accent-tint); color: var(--accent); font-weight: 600; }
.chips:not([hidden]) + .who { margin-left: 0; }
.who button { margin-left: 8px; padding: 3px 10px; font-size: 13px; min-height: 28px; }

/* ---------- Layout ---------- */
main, .login { max-width: var(--page-max); margin: 0 auto; padding: 0 var(--gutter) var(--sp-6); }
.login { padding-top: var(--sp-6); }
.login form {
  display: grid;
  gap: var(--sp-2);
  max-width: 420px;
  padding: var(--sp-5);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
}
.login label { font-weight: 600; }

/* View headings carry a short marker bar. */
main > section > h2:first-child, .trend-head h2 { display: flex; align-items: center; gap: 10px; }
main > section > h2:first-child::before, .trend-head h2::before {
  content: "";
  flex: none;
  width: 4px;
  height: 18px;
  border-radius: var(--r-pill);
  background: var(--primary);
}
main > section > h2:empty::before { content: none; }

/* ---------- Navigation: the sticky view bar ---------- */
nav.tabs[aria-label="Views"] {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  flex-wrap: nowrap;
  gap: 2px;
  margin: 0 0 var(--sp-4);
  padding: 0;
  overflow-x: auto;
  scrollbar-width: none;  /* the cut-off last label shows the bar scrolls */
  background: var(--nav-bg);
  border: 0;
  border-bottom: 1px solid var(--border);
  border-radius: 0;
  -webkit-backdrop-filter: saturate(140%) blur(14px);
  backdrop-filter: saturate(140%) blur(14px);
  /* Full-bleed bar without widening the page */
  box-shadow: 0 0 0 100vmax var(--nav-bg);
  clip-path: inset(0 -100vmax);
}
nav.tabs[aria-label="Views"]::-webkit-scrollbar { display: none; }
nav.tabs[aria-label="Views"] button {
  flex: none;
  position: relative;
  background: none;
  border: 0;
  border-radius: 0;
  padding: 11px 10px;
  min-height: 0;
  color: var(--fg-2);
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
  box-shadow: none;
}
nav.tabs[aria-label="Views"] button:hover { color: var(--fg); background: none; }
nav.tabs[aria-label="Views"] button[aria-pressed="true"] { color: var(--fg); font-weight: 600; background: none; box-shadow: none; }
nav.tabs[aria-label="Views"] button[aria-pressed="true"]::after {
  content: "";
  position: absolute;
  left: 10px;
  right: 10px;
  bottom: 0;
  height: 2px;
  border-radius: 2px 2px 0 0;
  background: var(--primary);
}
nav.tabs[aria-label="Views"] button:focus-visible { outline-offset: -3px; border-radius: var(--r-sm); }

/* ---------- Segmented toggles: every other .tabs group ---------- */
.tabs {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 2px;
  padding: 3px;
  margin-bottom: var(--sp-3);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  max-width: 100%;
}
.tabs button {
  border: 0;
  background: none;
  border-radius: var(--r-sm);
  padding: 3px 12px;
  min-height: 26px;
  font-size: 13px;
  color: var(--fg-2);
}
.tabs button:hover:not(:disabled) { color: var(--fg); background: var(--surface-3); }
.tabs button[aria-pressed="true"], .tabs button[aria-pressed="true"]:hover:not(:disabled) {
  color: var(--fg);
  font-weight: 600;
  background: var(--surface);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2), inset 0 0 0 1px var(--border-strong);
}

/* ---------- Controls ---------- */
input, select, button, textarea {
  font: inherit;
  color: var(--fg);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-sm);
  padding: 5px 10px;
  min-height: 32px;
}
input[type=checkbox], input[type=radio] { min-height: 0; padding: 0; margin: 0; width: 15px; height: 15px; accent-color: var(--primary); }
input::placeholder, textarea::placeholder { color: var(--muted); opacity: 1; }
input:hover, select:hover, textarea:hover { border-color: color-mix(in srgb, var(--accent) 45%, var(--border-strong)); }
input:focus-visible, select:focus-visible, textarea:focus-visible { outline: none; border-color: var(--accent); box-shadow: var(--ring); }
button { cursor: pointer; font-weight: 500; background: transparent; line-height: 1.3; }
button:hover:not(:disabled) { background: var(--surface-2); border-color: color-mix(in srgb, var(--accent) 40%, var(--border-strong)); }
button:disabled { opacity: 0.55; cursor: progress; }
button[aria-pressed="true"] {
  background: var(--accent-tint);
  border-color: color-mix(in srgb, var(--accent) 55%, transparent);
  color: var(--accent);
  font-weight: 600;
}
/* A form's submit is its primary action. */
form button[type=submit], form button:not([type]) {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--on-primary);
  font-weight: 600;
}
form button[type=submit]:hover:not(:disabled), form button:not([type]):hover:not(:disabled) {
  background: var(--primary-hover);
  border-color: var(--primary-hover);
}
form[method=dialog] button { background: transparent; border-color: var(--border-strong); color: var(--fg); }
form[method=dialog] button:hover:not(:disabled) { background: var(--surface-2); border-color: var(--border-strong); }
.linkish, .linklike {
  border: 0;
  background: none;
  padding: 0;
  min-height: 0;
  color: var(--accent);
  cursor: pointer;
  text-align: left;
  font: inherit;
}
.linkish:hover:not(:disabled), .linklike:hover:not(:disabled) { background: none; text-decoration: underline; }
.linklike { text-decoration: underline; }
.check { display: inline-flex; gap: 6px; align-items: center; font-size: 13px; color: var(--fg-2); }
progress { vertical-align: middle; width: 160px; accent-color: var(--primary); }

/* ---------- Text roles ---------- */
.hint, .status, .meta { color: var(--muted); font-size: 13px; }
.error { color: var(--err); }
.action-state { font-size: 13px; }
.action-state.ok { color: var(--ok); }
.action-state.err { color: var(--err); }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* ---------- Badges and chips ---------- */
.badges { display: flex; flex-wrap: wrap; gap: 4px; }
.badge {
  display: inline-block;
  font-size: 11px;
  font-weight: 500;
  line-height: 1.6;
  padding: 0 7px;
  border-radius: var(--r-pill);
  background: var(--badge-bg);
  color: var(--fg-2);
}
button.badge-link { border: 0; min-height: 0; font: inherit; font-size: 11px; font-weight: 500; cursor: pointer; padding: 0 7px; color: var(--fg-2); }
button.badge-link:hover:not(:disabled), button.badge-link:focus-visible { text-decoration: underline; background: var(--badge-bg); color: var(--fg); }
.chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  line-height: 1.5;
  padding: 2px 10px;
  border-radius: var(--r-pill);
  background: var(--surface-2);
  border: 1px solid var(--border);
  white-space: nowrap;
}
.chip-row { display: flex; flex-wrap: wrap; gap: 6px; }
.chip-btn { font-size: 13px; border-radius: var(--r-pill); padding: 3px 12px; min-height: 0; }
.chip-x { border: 0; background: none; padding: 0 2px; min-height: 0; cursor: pointer; color: var(--muted); font-weight: 600; }
.chip-x:hover:not(:disabled) { background: none; color: var(--err); }
.chip-add { border-style: dashed; border-color: var(--border-strong); }
.chip-add:hover, .chip-add:focus-visible { border-style: solid; }
a.chip { text-decoration: none; color: var(--accent); }
a.chip:hover { text-decoration: underline; border-color: var(--border-strong); }

/* ---------- Cards and panels ---------- */
.story, .market, .fact, .stat-card, .briefing, .src-panel, .cvss-panel, .brief, .cvss-vector-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  min-width: 0;
}

/* ---------- Tables ---------- */
.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--shadow-card);
  margin: var(--sp-2) 0 var(--sp-4);
}
.table-wrap > table { margin: 0; }
table { border-collapse: collapse; }
.board, .vulns { width: 100%; font-size: 13px; font-variant-numeric: tabular-nums; }
.board th, .board td, .vulns th, .vulns td { text-align: left; padding: 7px 10px; border-bottom: 1px solid var(--border); }
.board th, .vulns th { background: var(--surface-2); color: var(--muted); font-size: 12px; font-weight: 600; white-space: nowrap; }
.board tbody tr:last-child td, .vulns tbody tr:last-child td { border-bottom: 0; }
.board tbody tr:hover td, .vulns tbody tr:hover td { background: color-mix(in srgb, var(--surface-2) 70%, transparent); }
.board tr.you td { font-weight: 600; color: var(--accent); }
.vulns th, .vulns td { white-space: nowrap; }

/* ---------- Dialog ---------- */
dialog {
  background: var(--surface);
  color: var(--fg);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-pop);
  max-width: min(440px, calc(100vw - 2 * var(--gutter)));
  padding: var(--sp-5);
}
dialog h2 { margin-top: 0; font-size: 16px; }
dialog::backdrop { background: rgba(2, 8, 20, 0.55); }
.keys { display: grid; grid-template-columns: auto 1fr; gap: 6px 14px; font-size: 13px; }
.keys dt { font-family: var(--mono); font-weight: 600; }
.keys dd { margin: 0; color: var(--fg-2); }

@media (forced-colors: active) {
  nav.tabs[aria-label="Views"] button[aria-pressed="true"]::after { background: Highlight; }
  .badge, .chip { border: 1px solid CanvasText; }
}

/* ---------- Views ---------- */

/* Filter bars and forms */
.filters { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.filters input[type=search], .filters input[name=entity] { flex: 1 1 160px; min-width: 0; }
.ask { display: flex; gap: 8px; margin-bottom: 10px; flex-wrap: wrap; align-items: center; }
.ask input { flex: 1 1 300px; min-width: 0; font-size: 15px; padding: 8px 12px; min-height: 38px; }
.ask button { min-height: 38px; padding: 0 16px; }
.query-help code { font-size: 12px; background: var(--surface-2); border: 1px solid var(--border); padding: 0 5px; }
.export-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin: 4px 0; }
.add-feed { margin: 8px 0; }
.add-feed > summary { font-weight: 600; padding: 4px 0; }
.watch-form { display: grid; gap: 8px; max-width: 640px; margin: 12px 0 24px; }
.watch-form input[type=number] { width: 70px; }
#env-chips { margin-bottom: 8px; }
.more { display: block; margin: 0 auto 24px; padding: 6px 20px; }
.pager { display: flex; gap: 12px; align-items: center; justify-content: center; margin: 8px 0 24px; flex-wrap: wrap; }
.trend-head { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 8px; }
.trend-head h2 { margin-bottom: var(--sp-2); }
.trend-head .tabs { margin: 0; }
.trend-head .hint { margin: 0; }

/* Briefings and answers */
.briefing {
  background: var(--brief-bg);
  border-left: 3px solid var(--primary);
  padding: 12px 16px;
  margin-bottom: 12px;
  overflow-wrap: anywhere;
}
.briefing-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.briefing h2 { font-size: 16px; margin: 0; }
.briefing ul { margin: 6px 0 0; padding-left: 20px; }
.briefing li { margin: 2px 0; }
.briefing li.alarm, .kev-yes, .alarm { color: var(--err); font-weight: 600; }
.alarm-box { border-left-color: var(--err); }
.ok-box { border-left-color: var(--ok); }
.alarm-box ul { margin: 4px 0 0; }
.pulse {
  display: block;
  width: 100%;
  margin-bottom: 10px;
  background: var(--accent-tint);
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
  color: var(--accent);
  font-weight: 600;
}
.answer { max-width: 90ch; }
.answer p { margin: 0 0 6px; }
.answer sup a, .brief sup a { text-decoration: none; font-weight: 600; }
.answer .answer-h { font-weight: 600; margin-top: 10px; }
.answer .answer-h:first-child { margin-top: 0; }
.answer ul, .answer ol { margin: 0 0 6px; padding-left: 22px; }
.answer li { margin: 2px 0; }
.answer li > ul, .answer li > ol { margin: 2px 0 0; }
.ask-sources { margin: 6px 0 0; padding-left: 20px; font-size: 13px; display: grid; gap: 2px; }
.ask-sources li.cited a { font-weight: 600; }

/* Story feed */
.stories { list-style: none; padding: 0; margin: 12px 0; display: grid; gap: 10px; }
.story { padding: 14px 16px; overflow-wrap: anywhere; }
.story:hover { border-color: var(--border-strong); }
.story.focused { border-color: var(--accent); box-shadow: var(--shadow-card), 0 0 0 1px var(--accent); }
.story h2 { font-size: 16px; margin: 6px 0 2px; line-height: 1.35; }
.story h2::before { content: none; }
.story a { color: var(--accent); text-decoration: none; }
.story a:hover { text-decoration: underline; }
.story h2 a { color: var(--fg); }
.story h2 a:hover { color: var(--accent); }
.story h2 a:visited { color: var(--fg-2); }
.story .meta { margin: 2px 0 6px; }
.domain { color: var(--muted); font-size: 12px; font-weight: 400; margin-left: 6px; }
.summary { margin: 6px 0; max-width: 110ch; color: var(--fg); }
.points { margin: 4px 0 6px; padding-left: 20px; font-size: 14px; max-width: 110ch; color: var(--fg-2); }
.points li { margin: 1px 0; }
.points li::marker { color: var(--muted); }
.also, .match, .scoop { font-size: 13px; color: var(--muted); margin: 4px 0; }
.scoop.won, li.won { color: var(--ok); font-weight: 600; }
li.lost { color: var(--muted); }
.hidden-story { opacity: 0.55; }
.actions { display: flex; gap: 6px; align-items: center; margin-top: 10px; flex-wrap: wrap; }
.actions button, .actions select, .rate button { min-height: 28px; padding: 2px 10px; font-size: 13px; }
.actions .story-link { font-size: 13px; padding: 0 4px; }
.rate { display: inline-flex; gap: 4px; align-items: center; }
.rate button[aria-pressed="true"] {
  color: var(--ok);
  background: color-mix(in srgb, var(--ok) var(--tint), var(--surface));
  border-color: color-mix(in srgb, var(--ok) 50%, transparent);
}
.rate select { font-size: 13px; }
.details { border-top: 1px solid var(--border); margin-top: 10px; padding-top: 8px; }
.details h3 { font-size: 13px; margin: 10px 0 6px; color: var(--fg-2); }
.timeline { list-style: none; padding: 0; margin: 0; display: grid; gap: 4px; font-size: 13px; }
.timeline li { display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; }
.timeline li.lead { font-weight: 600; }
.t-offset { color: var(--muted); min-width: 64px; font-variant-numeric: tabular-nums; font-family: var(--mono); font-size: 12px; }
.t-source { color: var(--muted); }
.geo-items { list-style: none; padding: 0; margin: 0; display: grid; gap: 8px; font-size: 13px; }
.geo-items .badge { font-size: 11px; }
.geo-summary { margin-top: 2px; }

/* Badges by meaning: tinted by hue; solid red only for act-now. */
.badge.kev, .badge.locked, .badge.due.urgent, .badge.lvl-red { background: var(--kev-bg); color: var(--kev-fg); font-weight: 600; }
.badge.hot { background: var(--hot-bg); color: var(--hot-fg); font-weight: 600; }
.badge.due { background: var(--due-bg); color: var(--due-fg); }
.badge.role-context, .badge.pick, .badge.h-live { background: var(--accent-tint); color: var(--accent); }
.badge.pick, .badge.h-live { font-weight: 600; }
.badge.sev-critical { background: var(--kev-bg); color: var(--kev-fg); font-weight: 600; }
.badge.sev-high { background: color-mix(in srgb, var(--sev-high) var(--tint), var(--surface)); color: var(--sev-high); font-weight: 600; }
.badge.sev-medium { background: color-mix(in srgb, var(--sev-medium) var(--tint), var(--surface)); color: var(--sev-medium); }
.badge.sev-low { background: color-mix(in srgb, var(--sev-low) var(--tint), var(--surface)); color: var(--sev-low); }
.badge.h-backfill, .badge.h-initial { background: var(--badge-bg); color: var(--muted); }
.badge.lvl { font-weight: 600; white-space: nowrap; align-self: flex-start; }
.badge.lvl-green { background: color-mix(in srgb, var(--ok) var(--tint), var(--surface)); color: var(--ok); }
.badge.lvl-amber { background: color-mix(in srgb, var(--warn) var(--tint), var(--surface)); color: var(--warn); }

/* KEV Futures, calls, leaderboard */
.markets, .calls { padding: 0; list-style: none; display: grid; gap: 10px; }
.calls li { font-size: 14px; }
.market { padding: 12px 16px; overflow-wrap: anywhere; }
.market-head { display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; }
.market-story { margin: 4px 0; }
.summary-line { font-weight: 600; }
.chronicle-summary { display: flex; flex-wrap: wrap; gap: 6px 18px; padding: 0; list-style: none; font-weight: 600; }

/* Trending */
.board.trending td { vertical-align: top; }
.board.trending td:last-child { min-width: 200px; }
.spark { display: inline-flex; align-items: flex-end; gap: 1px; height: 20px; }
.spark-bar { width: 4px; background: var(--accent); border-radius: 1px; opacity: 0.85; }
.delta { font-size: 12px; color: var(--muted); }
.delta.up { color: var(--ok); font-weight: 600; }
.code-links { padding-left: 18px; font-size: 14px; display: grid; gap: 4px; }

/* Briefs and notes in story details */
.brief { padding: 10px 14px; margin-bottom: 10px; font-size: 14px; border-radius: var(--r-md); }
.brief h4 { font-size: 13px; margin: 12px 0 4px; color: var(--fg-2); }
.brief p { margin: 0 0 6px; }
.brief-list { margin: 0 0 6px; padding-left: 20px; display: grid; gap: 3px; }
.brief-timeline { list-style: none; padding-left: 0; }
.brief-bar { display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; margin: 0 0 8px; font-size: 13px; }
.brief-excerpt { color: var(--muted); font-size: 12px; margin: 2px 0 4px; }
.notes { margin-top: 8px; }
.note-list { list-style: none; padding: 0; margin: 0 0 6px; display: grid; gap: 6px; font-size: 14px; }
.note-list li { border-left: 2px solid var(--border-strong); padding-left: 10px; }
.note-list p { margin: 2px 0; white-space: pre-wrap; }
.note-form { display: grid; gap: 6px; }
.note-form textarea { width: 100%; }
.note-form button, .watch-form button { justify-self: start; }

/* Indicators: monospace, inert text; the table scrolls inside its panel. */
.ioc-table code { overflow-wrap: anywhere; }
.ioc-table td { vertical-align: top; }
.ioc-table td:last-child { white-space: normal; min-width: 22em; }
.ioc-source + .ioc-source { margin-top: 6px; }
.ioc-snippet { display: block; font-size: 12px; color: var(--muted); overflow-wrap: anywhere; }
.ioc-published { font-size: 11px; }
.ioc-cards .ioc-repo-error { color: var(--err); }

/* Vulnerability list */
.vulns tr.kev-row td:first-child { color: var(--err); font-weight: 600; }
.vlist td { vertical-align: top; }
.vlist .v-id { min-width: 240px; max-width: 420px; overflow-wrap: anywhere; white-space: normal; }
.vlist .badge { white-space: nowrap; }
.v-link { font-weight: 600; font-variant-numeric: tabular-nums; font-family: var(--mono); font-size: 13px; }
.v-title { font-size: 14px; }
.v-desc { font-size: 13px; color: var(--muted); display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2;
  -webkit-box-orient: vertical; overflow: hidden; }
.v-aff { font-size: 13px; max-width: 220px; overflow-wrap: anywhere; white-space: normal; }
.v-upd, .v-epss { white-space: nowrap; font-size: 13px; }
.v-cov { font-size: 13px; min-width: 150px; max-width: 240px; white-space: normal; }
.lead-story { font-size: 13px; display: block; margin-top: 2px; }
#vuln-chips { margin: 8px 0 0; }
#vuln-chips .chip-x { text-decoration: none; }

/* CVE page */
.cve-page .spark { height: 40px; gap: 2px; }
.cve-page .spark-bar { width: 12px; }
.cve-subtitle { font-size: 16px; font-weight: 600; margin: 4px 0; }
.cve-about { display: flex; flex-wrap: wrap; gap: 6px 28px; margin: 0 0 10px; font-size: 14px; }
.cve-about > div { min-width: 0; }
.cve-about dt, .fact-label { font-size: 12px; font-weight: 600; color: var(--muted); }
.cve-about dd { margin: 0; overflow-wrap: anywhere; }
.cwe-list { list-style: none; padding: 0; margin: 0; }
.facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 160px), 1fr)); gap: 8px; margin: 10px 0; }
.fact { padding: 10px 12px; border-radius: var(--r-md); display: flex; flex-direction: column; align-items: flex-start;
  gap: 2px; overflow-wrap: break-word; }
.fact > * { max-width: 100%; }
.fact .meta { font-size: 12px; }
.fact .keys.compact { align-self: stretch; margin: 4px 0 0; }
.fact-line { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; }
.fact-value { font-size: 22px; line-height: 1.2; font-weight: 600; font-variant-numeric: tabular-nums; }
.fact.open, a.tile.current { border-color: var(--accent); box-shadow: var(--shadow-card), inset 0 0 0 1px var(--accent); }
a.tile { text-decoration: none; color: var(--fg); }
a.tile:hover { border-color: var(--border-strong); }
.keys.compact { gap: 0 10px; font-size: 13px; }
.keys.compact dt { font-family: inherit; font-weight: 400; color: var(--muted); }
code.vector { font-family: var(--mono); font-size: 12px; overflow-wrap: anywhere; }
.cvss-toggle { font-size: 13px; margin-top: 2px; }
.cvss-caret { display: inline-block; transition: transform var(--t-fast) var(--ease); }
.cvss-toggle[aria-expanded="true"] .cvss-caret { transform: rotate(90deg); }
.cvss-panel { border-color: color-mix(in srgb, var(--accent) 55%, transparent); padding: 4px 16px 14px; margin: -2px 0 12px; }
.cvss-panel h3 { font-size: 15px; margin: 10px 0 4px; }
.cvss-panel h4 { font-size: 14px; margin: 14px 0 6px; }
.cvss-table { margin: 0; font-size: 14px; }
.cvss-table th { font-size: 12px; color: var(--muted); font-weight: 600; white-space: nowrap; }
.cvss-table td { vertical-align: top; }
.cvss-table td:last-child { min-width: 12em; }
.cvss-table tr.primary td { background: var(--brief-bg); }
.cvss-score { white-space: nowrap; }
.cvss-vectors { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); gap: 10px; }
.cvss-vector-card { padding: 8px 12px; border-radius: var(--r-md); box-shadow: none; background: var(--surface-2); }
.cvss-vector-head { font-weight: 600; font-size: 13px; margin: 0 0 6px; }
.cvss-metrics { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 3px 14px; margin: 0; font-size: 14px; }
.cvss-metrics dt { color: var(--muted); }
.cvss-metrics dd { margin: 0; font-weight: 600; text-align: right; white-space: nowrap; }
.cvss-metrics dd code { font-weight: 400; font-size: 11px; }
.cve-section { border-top: 1px solid var(--border); margin-top: 16px; padding-top: 4px; overflow-wrap: anywhere; }
.cve-section h3 { font-size: 16px; }
.cve-section h4 { font-size: 14px; margin: 10px 0 4px; }
.affected { list-style: none; padding: 0; display: grid; gap: 8px; }
.affected .chip-row { margin-top: 4px; }
.mitigations { padding-left: 18px; display: grid; gap: 6px; font-size: 14px; }
.mitigations p { margin: 2px 0; }
.history { list-style: none; padding: 0; margin: 0; display: grid; gap: 8px; }
.history li { border-left: 3px solid var(--border-strong); padding-left: 10px; }
.history li.h-kev_added, .history li.h-exploit_code { border-left-color: var(--err); }
.history li.h-first_reported { border-left-color: var(--accent); }
.h-head { display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; font-size: 14px; }
.h-value { font-size: 13px; }
.h-value p { margin: 2px 0; }
.h-before { color: var(--muted); text-decoration: line-through; }
.h-list { list-style: none; padding: 0; margin: 2px 0; }
.h-list li { border: 0; padding: 0; }
.h-add { color: var(--add); }
.h-del { color: var(--del); }
.src-panel { padding: 8px 12px; margin: 6px 0; border-radius: var(--r-md); box-shadow: none; }
.src-panel summary { font-weight: 600; }
pre.raw { max-height: 420px; overflow: auto; font-size: 12px; background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--r-sm); padding: 8px 10px; white-space: pre-wrap; overflow-wrap: anywhere; }

/* Statistics and bars */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); gap: 12px; margin: 12px 0 24px; }
.stat-card { padding: 10px 14px 12px; }
.stat-card h3 { font-size: 14px; margin: 4px 0 8px; }
.stat-card .tabs { margin-bottom: 8px; }
.hbar-row { display: grid; grid-template-columns: minmax(80px, 2fr) minmax(60px, 2fr) auto; gap: 8px; align-items: center;
  font-size: 13px; margin: 4px 0; }
.hbar-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hbar-track { background: var(--surface-3); border-radius: var(--r-pill); height: 8px; overflow: hidden; }
.hbar { display: block; height: 100%; border-radius: var(--r-pill); background: var(--primary); }
.hbar.sev-critical { background: var(--sev-critical); }
.hbar.sev-high { background: var(--sev-high); }
.hbar.sev-medium { background: var(--sev-medium); }
.hbar.sev-low { background: var(--sev-low); }
.hbar.sev-none { background: var(--sev-none); }
.hbar-value { font-variant-numeric: tabular-nums; text-align: right; min-width: 40px; }

/* Sources review */
.review-table td { vertical-align: top; }
.review-table .num, .ops-table td.num, .ops-table th.num { text-align: right; font-variant-numeric: tabular-nums; }
.review-actions { white-space: nowrap; }
.review-actions .meta { display: block; white-space: normal; }
.review-actions button, .review-actions select { min-height: 28px; padding: 2px 8px; font-size: 13px; }
.board tbody tr.review-detail td, .review-detail td { background: var(--surface-2); }
.review-items { margin: 4px 0; padding-left: 0; list-style: none; font-size: 13px; }
.review-items li { padding: 5px 0; border-bottom: 1px solid var(--border); }
.review-items li:last-child { border-bottom: 0; }

/* Operations (#/ops) */
.ops-controls { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.ops-tiles { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
.ops-tiles .ops-tile { border-left-width: 3px; }
.ops-tile.lvl-green { border-left-color: var(--ok); }
.ops-tile.lvl-amber { border-left-color: var(--warn); }
.ops-tile.lvl-red { border-left-color: var(--err); }
.ops-grid { grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); }
.ops-card.wide { grid-column: 1 / -1; }
.ops-card h4 { font-size: 12px; font-weight: 600; margin: 12px 0 4px; color: var(--muted); }
.ops-card:focus { outline: 2px solid var(--accent); outline-offset: 2px; }
.ops-thresholds summary { font-size: 13px; color: var(--muted); }
.ops-table td { white-space: normal; vertical-align: top; }
.ops-table th .sort { font: inherit; font-weight: 600; color: var(--fg-2); white-space: nowrap; background: none; border: 0;
  padding: 0; min-height: 0; }
.ops-table th .sort:hover { color: var(--fg); background: none; }
.ops-table .badge.lvl { margin-right: 4px; }
.live-card { margin-bottom: 16px; }
.live-now { min-height: 2.6em; }
.live-now progress { width: min(240px, 100%); vertical-align: middle; }
.live-queues { grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }
.live-cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); gap: 12px 24px; }
.live-pane { min-width: 0; }
.live-scroll { height: 280px; overflow-y: auto; overscroll-behavior: contain; border: 1px solid var(--border);
  border-radius: var(--r-md); padding: 0 10px; background: var(--surface-2); }
.live-scroll:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.live-scroll h5 { font-size: 12px; font-weight: 600; color: var(--muted); margin: 8px 0 2px; }
.live-scroll > .hint { margin: 8px 0; }
.live-list { list-style: none; margin: 0; padding: 0; font-size: 13px; }
.live-list li { padding: 3px 0; border-bottom: 1px solid var(--border); overflow-wrap: anywhere; }
.live-list .badge { margin-right: 2px; }

/* Charts */
.ops-chart { margin: 8px 0 16px; }
.ops-chart figcaption { font-weight: 600; font-size: 14px; }
.chart-plot { position: relative; }
.ops-chart svg { width: 100%; height: auto; display: block; }
.ops-chart .grid { stroke: var(--border); stroke-width: 1; }
.ops-chart .axis { fill: var(--muted); font-size: 11px; }
.ops-chart .end-label { fill: var(--fg); font-size: 11px; }
.ops-chart .line { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.ops-chart .cross { stroke: var(--muted); stroke-width: 1; stroke-dasharray: 3 3; }
.ops-chart .dot { stroke: var(--surface); stroke-width: 2; }
.ops-chart .hit { fill: transparent; }
.line.s1 { stroke: var(--series-1); } .dot.s1, .key.s1 { fill: var(--series-1); background: var(--series-1); }
.line.s2 { stroke: var(--series-2); } .dot.s2, .key.s2 { fill: var(--series-2); background: var(--series-2); }
.line.s3 { stroke: var(--series-3); } .dot.s3, .key.s3 { fill: var(--series-3); background: var(--series-3); }
.line.s4 { stroke: var(--series-4); } .dot.s4, .key.s4 { fill: var(--series-4); background: var(--series-4); }
.chart-legend { display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: 13px; margin: 4px 0; }
.key { display: inline-block; width: 12px; height: 3px; border-radius: 2px; vertical-align: middle; }
.chart-tip { position: absolute; top: 4px; background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: var(--r-sm); padding: 4px 8px; font-size: 12px; pointer-events: none; box-shadow: var(--shadow-pop); }
.chart-data summary { font-size: 13px; color: var(--muted); }
.chart-data .table-wrap { max-height: 260px; overflow-y: auto; }

/* ---------- Phone widths ---------- */
@media (max-width: 600px) {
  .top { flex-wrap: wrap; gap: 6px 10px; padding-top: 10px; padding-bottom: 6px; }
  .chips { margin: 0; order: 3; width: 100%; }
  .fx-toggle { order: 4; }
  /* The column fills a phone screen, so light running behind it would cross text: grid and glow only. */
  .fx-streak, .fx-dot { display: none; }
  .who { margin-left: auto; }
  .filters > * { flex: 1 1 100%; }
  .filters > select, .filters > .check { flex: 1 1 calc(50% - 4px); min-width: 0; }
  .story { padding: 12px; }
  .board.trending th:nth-child(4), .board.trending td:nth-child(4),
  .board.trending th:nth-child(6), .board.trending td:nth-child(6) { display: none; }
  .vlist th:nth-child(3), .vlist td:nth-child(3), .vlist th:nth-child(5), .vlist td:nth-child(5) { display: none; }
  .vlist .v-id { min-width: 180px; }
  .fact-value { font-size: 18px; }
  .cvss-panel { padding: 4px 10px 10px; }
  /* Each score becomes a block: source and score on one line, version beside, the vector full width beneath */
  .cvss-table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .cvss-table tr { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: 2px 10px;
    padding: 6px 8px; border-bottom: 1px solid var(--border); }
  .cvss-table td { border: 0; padding: 0; }
  .cvss-table td.cvss-version { color: var(--muted); }
  .cvss-table td.cvss-vector { grid-column: 1 / -1; min-width: 0; }
  .cvss-metrics { font-size: 13px; }
  .ops-grid { grid-template-columns: 1fr; }
  .live-scroll { height: 200px; }
  .ops-chart .end-label { display: none; }
}
@media (forced-colors: active) {
  .ops-chart .line { stroke: CanvasText; }
  .key { forced-color-adjust: none; }
}

/* ---------- Background effects (docs/ui.md#background-effects) ----------
   One fixed layer behind the page: a faint grid, three slow glows, light running along a few grid lines,
   intersections that twinkle, fine grain, and a light that follows a mouse (fx.js). Only transform and
   opacity animate. Content sits above it; cards, panels and tables are opaque. */
:root {
  --fx-cell: 64px;
  --fx-line: rgba(148, 170, 214, 0.055);
  --fx-line-lit: rgba(150, 185, 255, 0.10);
  --fx-glow-1: rgba(37, 99, 235, 0.10);
  --fx-glow-2: rgba(87, 130, 216, 0.07);
  --fx-glow-3: rgba(240, 190, 120, 0.05);
  --fx-streak: rgba(122, 174, 255, 0.55);
  --fx-streak-head: #cfe0ff;
  --fx-spot: rgba(59, 130, 246, 0.06);
  --fx-grain: 0.03;
  --fx-warm-head: #f6d8a4;
  --fx-warm: rgba(240, 190, 120, 0.6);
}
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    --fx-line: rgba(15, 23, 42, 0.045);
    --fx-line-lit: rgba(37, 99, 235, 0.07);
    --fx-glow-1: rgba(37, 99, 235, 0.05);
    --fx-glow-2: rgba(87, 130, 216, 0.05);
    --fx-glow-3: rgba(240, 190, 120, 0.05);
    --fx-streak: rgba(37, 99, 235, 0.28);
    --fx-streak-head: rgba(37, 99, 235, 0.6);
    --fx-spot: rgba(37, 99, 235, 0.03);
    --fx-grain: 0.02;
    --fx-warm-head: rgba(176, 112, 20, 0.8);
    --fx-warm: rgba(176, 112, 20, 0.45);
  }
}
:root[data-theme="light"] {
  --fx-line: rgba(15, 23, 42, 0.045); --fx-line-lit: rgba(37, 99, 235, 0.07);
  --fx-glow-1: rgba(37, 99, 235, 0.05); --fx-glow-2: rgba(87, 130, 216, 0.05); --fx-glow-3: rgba(240, 190, 120, 0.05);
  --fx-streak: rgba(37, 99, 235, 0.28); --fx-streak-head: rgba(37, 99, 235, 0.6); --fx-spot: rgba(37, 99, 235, 0.03); --fx-grain: 0.02;
  --fx-warm-head: rgba(176, 112, 20, 0.8); --fx-warm: rgba(176, 112, 20, 0.45);
}

.top, main, .login { position: relative; z-index: 1; }
.fx { position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; contain: strict; }
.fx > * { position: absolute; pointer-events: none; }
:root[data-fx="off"] .fx { display: none; }

/* The grid: strongest under the header, fading down the screen. Drawn once; it never moves. */
.fx-grid, .fx-spot-grid {
  background-image:
    linear-gradient(var(--fx-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--fx-line) 1px, transparent 1px);
  background-size: var(--fx-cell) var(--fx-cell);
}
.fx-grid {
  inset: 0;
  -webkit-mask-image: radial-gradient(ellipse 90% 75% at 50% 0%, #000 35%, transparent 100%);
  mask-image: radial-gradient(ellipse 90% 75% at 50% 0%, #000 35%, transparent 100%);
}
/* Grain, under the content rather than over it, so it never touches text. */
.fx::after {
  content: "";
  position: absolute;
  inset: 0;
  opacity: var(--fx-grain);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 200px 200px;
}

/* Glows: soft radial washes drifting over half a minute. */
.fx-mesh { width: 70vmax; height: 50vmax; border-radius: 50%; will-change: transform; }
.fx-mesh-1 { top: -22vmax; left: -18vmax; background: radial-gradient(closest-side, var(--fx-glow-1), transparent);
  animation: fx-drift-1 26s ease-in-out infinite; }
.fx-mesh-2 { top: 18vh; right: -26vmax; background: radial-gradient(closest-side, var(--fx-glow-2), transparent);
  animation: fx-drift-2 32s ease-in-out infinite; }
.fx-mesh-3 { bottom: -30vmax; left: 20vw; background: radial-gradient(closest-side, var(--fx-glow-3), transparent);
  animation: fx-drift-3 38s ease-in-out infinite; }
@keyframes fx-drift-1 { 50% { transform: translate3d(8vw, 6vh, 0) scale(1.08); } }
@keyframes fx-drift-2 { 50% { transform: translate3d(-10vw, 8vh, 0) scale(0.94); } }
@keyframes fx-drift-3 { 50% { transform: translate3d(6vw, -8vh, 0) scale(1.05); } }

/* Light running along grid lines: a short streak with a bright head, mostly between runs. */
/* Over the content column it runs at a fifth of its strength, so it never crosses text at full light. */
.fx-run {
  inset: 0;
  --col: min(50%, calc(var(--page-max) / 2));
  -webkit-mask-image: linear-gradient(90deg, #000 calc(50% - var(--col) - 24px), rgba(0, 0, 0, 0.2) calc(50% - var(--col) + 24px),
    rgba(0, 0, 0, 0.2) calc(50% + var(--col) - 24px), #000 calc(50% + var(--col) + 24px));
  mask-image: linear-gradient(90deg, #000 calc(50% - var(--col) - 24px), rgba(0, 0, 0, 0.2) calc(50% - var(--col) + 24px),
    rgba(0, 0, 0, 0.2) calc(50% + var(--col) - 24px), #000 calc(50% + var(--col) + 24px));
}
.fx-run > * { position: absolute; pointer-events: none; }
.fx-streak { opacity: 0; will-change: transform, opacity; }
.fx-h { left: 0; width: 140px; height: 1px; margin-top: 0;
  background: linear-gradient(90deg, transparent, var(--fx-streak) 70%, var(--fx-streak-head)); }
.fx-v { top: 0; width: 1px; height: 140px;
  background: linear-gradient(180deg, transparent, var(--fx-streak) 70%, var(--fx-streak-head)); }
.fx-s1 { top: calc(var(--fx-cell) * 2); animation: fx-run-x 11s linear 1s infinite; }
.fx-s2 { top: calc(var(--fx-cell) * 6); animation: fx-run-x 15s linear 6s infinite; }
.fx-s3 { top: calc(var(--fx-cell) * 10); animation: fx-run-x 19s linear 11s infinite; }
.fx-s4 { left: calc(var(--fx-cell) * 1); animation: fx-run-y 13s linear 3s infinite; }
.fx-s5 { left: round(down, calc(100vw - 2 * var(--fx-cell)), var(--fx-cell)); animation: fx-run-y 17s linear 9s infinite; }
@keyframes fx-run-x {
  0% { transform: translate3d(-160px, 0, 0); opacity: 0; }
  4% { opacity: 1; }
  32% { opacity: 1; }
  40%, 100% { transform: translate3d(100vw, 0, 0); opacity: 0; }
}
@keyframes fx-run-y {
  0% { transform: translate3d(0, -160px, 0); opacity: 0; }
  4% { opacity: 1; }
  32% { opacity: 1; }
  40%, 100% { transform: translate3d(0, 100vh, 0); opacity: 0; }
}

/* Intersections that brighten now and then. */
.fx-dot { width: 3px; height: 3px; margin: -1px 0 0 -1px; border-radius: 50%; background: var(--fx-streak-head);
  opacity: 0; will-change: opacity, transform; animation: fx-twinkle 7s ease-in-out infinite; }
.fx-d1 { top: calc(var(--fx-cell) * 3); left: calc(var(--fx-cell) * 7); animation-delay: 0.5s; }
.fx-d2 { top: calc(var(--fx-cell) * 5); left: calc(var(--fx-cell) * 15); animation-delay: 2.5s; }
.fx-d3 { top: calc(var(--fx-cell) * 8); left: calc(var(--fx-cell) * 3); animation-delay: 4s; }
.fx-d4 { top: calc(var(--fx-cell) * 2); left: calc(var(--fx-cell) * 20); animation-delay: 5.5s; }
@keyframes fx-twinkle {
  0%, 100% { opacity: 0; transform: scale(0.6); }
  12% { opacity: 0.9; transform: scale(1.4); }
  30% { opacity: 0; transform: scale(0.6); }
}

/* The pointer light: a soft disc of glow with the grid drawn brighter inside it. fx.js moves the disc
   to the pointer and the grid inside it the other way, both by transform, so the lines stay put. */
.fx-spot {
  top: 0;
  left: 0;
  width: 520px;
  height: 520px;
  border-radius: 50%;
  overflow: hidden;
  opacity: 0;
  transition: opacity 400ms var(--ease);
  background: radial-gradient(closest-side, var(--fx-spot), transparent);
  -webkit-mask-image: radial-gradient(closest-side, #000 20%, transparent);
  mask-image: radial-gradient(closest-side, #000 20%, transparent);
  will-change: transform, opacity;
}
.fx-spot-grid { position: absolute; top: 0; left: 0; width: 100vw; height: 100vh; --fx-line: var(--fx-line-lit); will-change: transform; }
:root[data-fx-lit] .fx-spot { opacity: 1; }

/* A click on the page: light leaves the nearest grid intersection along its four lines, with a ring. fx.js
   adds the .fx-burst elements (24 at most) inside .fx-run, so they are dimmed over the content column
   as the streaks are, and removes each when its ring ends. */
.fx-burst { position: absolute; top: 0; left: 0; width: 0; height: 0; }
.fx-burst > i { position: absolute; display: block; pointer-events: none; will-change: transform, opacity;
  animation-delay: var(--d, 0ms) !important; animation-fill-mode: both !important; }
.fx-burst-ring { width: 160px; height: 160px; margin: -80px 0 0 -80px; border-radius: 50%;
  border: 1px solid var(--fx-streak-head); opacity: 0; animation: fx-ring 700ms var(--ease) forwards; }
.fx-burst-dot { width: 6px; height: 6px; margin: -3px 0 0 -3px; border-radius: 50%; background: var(--fx-streak-head);
  animation: fx-pop 500ms var(--ease) forwards; }
.fx-burst-ray { top: 0; left: 0; width: calc(var(--fx-cell) * var(--reach, 3)); height: 1px; margin-top: 0; transform-origin: 0 0;
  background: linear-gradient(90deg, var(--fx-streak-head), var(--fx-streak) 30%, transparent);
  animation: fx-ray 650ms var(--ease) forwards; }
/* Catching the light (fx.js): a bloom is a wider ring, a neighbour a small one; a run of catches warms. */
.fx-burst--big .fx-burst-ring { width: 260px; height: 260px; margin: -130px 0 0 -130px; border-width: 2px; }
.fx-burst--big .fx-burst-dot { width: 10px; height: 10px; margin: -5px 0 0 -5px; }
.fx-burst--small .fx-burst-ring { width: 72px; height: 72px; margin: -36px 0 0 -36px; }
.fx-burst--small .fx-burst-dot { width: 4px; height: 4px; margin: -2px 0 0 -2px; }
.fx-burst--warm { --fx-streak-head: var(--fx-warm-head); --fx-streak: var(--fx-warm); }
.fx-caught { visibility: hidden; }
.fx-burst-r90 { rotate: 90deg; }
.fx-burst-r180 { rotate: 180deg; }
.fx-burst-r270 { rotate: 270deg; }
@keyframes fx-ring { 0% { transform: scale(0.1); opacity: 0; } 6% { opacity: 0.9; } 100% { transform: scale(1); opacity: 0; } }
@keyframes fx-pop { 0% { transform: scale(0.4); opacity: 0; } 8% { opacity: 1; } 60% { transform: scale(1.6); opacity: 0.8; }
  100% { transform: scale(1); opacity: 0; } }
@keyframes fx-ray { 0% { transform: scaleX(0.05); opacity: 0; } 6% { opacity: 1; } 70% { opacity: 0.9; } 100% { transform: scaleX(1); opacity: 0; } }

/* A hidden tab runs nothing. */
:root[data-fx-paused] .fx *, :root[data-fx-paused] .fx::after { animation-play-state: paused; }

/* Reduced motion: the grid and the glows stay, still; nothing runs or follows the pointer. */
@media (prefers-reduced-motion: reduce) {
  .fx-mesh { animation: none; }
  .fx-streak, .fx-dot, .fx-spot, .fx-burst { display: none; }
}

/* The toggle in the header */
.fx-toggle { font-size: 12px; padding: 2px 10px; min-height: 26px; border-radius: var(--r-pill); white-space: nowrap; }
@media (forced-colors: active) {
  .fx { display: none; }
}

/* ---------- Column widths: short values stay on one line, long text takes the slack ----------
   Numbers, dates, IDs, statuses and button groups do not wrap; prose columns get a minimum width so a
   narrow screen scrolls the table inside its .table-wrap instead of breaking words. Browsers ignore
   min-width on a table cell, so each minimum is an empty full-width line (::after) of that width. */
.num, td.num { white-space: nowrap; }
.board.trending td:nth-child(1), .board.trending td:nth-child(1) .linkish,
.board.trending td:nth-child(3), .board.trending td:nth-child(5) { white-space: nowrap; }
.cve-page .spark { max-width: 100%; }
.cve-page .spark-bar { width: auto; flex: 0 1 12px; min-width: 3px; }
#review-decisions .board td:nth-child(1), #review-decisions .board td:nth-child(3),
#review-decisions .board td:nth-child(4) { white-space: nowrap; }
.chart-data th, .chart-data td:first-child { white-space: nowrap; }
/* Ops tables: the first column (a name) and columns marked wrap (free text) wrap; dates, counts, types,
   licences and durations do not. */
.ops-table td:not(:first-child):not(.wrap) { white-space: nowrap; }
.ops-table td.wrap::after { content: ""; display: block; height: 0; width: 12em; }
#review-decisions .board td:nth-child(2)::after, #review-decisions .board td:nth-child(5)::after,
.review-table td:nth-child(-n+3)::after, .ops-table td:first-child::after {
  content: "";
  display: block;
  height: 0;
}
#review-decisions .board td:nth-child(2)::after { width: 12em; }
#review-decisions .board td:nth-child(5)::after { width: 16em; }
.review-table td:nth-child(1)::after { width: 14em; }
.review-table td:nth-child(2)::after { width: 12.5em; }
.review-table td:nth-child(3)::after { width: 14em; }
.ops-table td:first-child::after { width: 12em; }
/* A badge is one label: it stays on one line, except in a narrow tile, where it wraps as a box, not a pill. */
.badge { white-space: nowrap; }
.fact .badge { white-space: normal; border-radius: var(--r-sm); }

/* ---------- Not found: the in-app view (#view-notfound) and the server's 404.html ---------- */
.notfound { text-align: center; padding: 56px 0 72px; max-width: 560px; margin: 0 auto; }
.notfound .nf-code {
  margin: 0;
  font-size: clamp(72px, 18vw, 128px);
  font-weight: 800;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--fg);
  text-shadow: 0 0 32px color-mix(in srgb, var(--primary) 45%, transparent);
}
.notfound h2 { justify-content: center; margin: 12px 0 6px; font-size: 22px; }
.notfound h2::before { content: none; }
.notfound .hint { font-size: 14px; }
.nf-actions { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; margin-top: 20px; }
.nf-actions a {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding: 0 18px;
  border-radius: var(--r-sm);
  border: 1px solid var(--border-strong);
  color: var(--fg);
  font-weight: 600;
  text-decoration: none;
}
.nf-actions a:hover { background: var(--surface-2); }
.nf-actions a.nf-primary { background: var(--primary); border-color: var(--primary); color: var(--on-primary); }
.nf-actions a.nf-primary:hover { background: var(--primary-hover); border-color: var(--primary-hover); }
.top h1 a.brand { color: inherit; text-decoration: none; display: inline-flex; align-items: center; gap: 10px; }
.top h1 + .fx-toggle { margin-left: auto; }

/* ---------- Phone layout: one column, secondary controls folded away ---------- */
.fold-toggle { display: none; }
.account { display: contents; }
@media (max-width: 600px) {
  /* Tap targets */
  button:not(.linkish):not(.linklike):not(.chip-x):not(.badge-link), select,
  input:not([type=checkbox]):not([type=radio]), .nf-actions a { min-height: 44px; }
  nav.tabs[aria-label="Views"] button { min-height: 44px; padding: 12px 10px; }
  .check { min-height: 44px; }

  /* Header: the brand and one Account button; chips, the user line, effects and Sign out fold into it. */
  .top { flex-wrap: wrap; padding-top: 8px; padding-bottom: 8px; gap: 8px; }
  .top h1 { font-size: 17px; }
  .fold-toggle {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 0 14px;
    font-weight: 600;
  }
  .fold-toggle::after { content: "\25BE"; color: var(--muted); transition: transform var(--t-fast) var(--ease); }
  .fold-toggle[aria-expanded="true"]::after { transform: rotate(180deg); }
  .menu-toggle { margin-left: auto; }
  .account { display: none; }
  .account.unfolded {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
    width: 100%;
    padding: 10px 12px 12px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-card);
  }
  .account .chips { order: 0; width: auto; margin: 0; }
  .account .who { margin: 0; display: flex; align-items: center; justify-content: space-between; gap: 8px; }
  .account .who button { min-height: 44px; margin: 0; padding: 0 16px; }
  .account .fx-toggle { order: 2; min-height: 44px; font-size: 13px; }

  /* Filter bars fold behind a Filters button; the Ask box and the parsed query stay in view. */
  section > .fold-toggle { width: 100%; justify-content: space-between; margin: 4px 0 8px; }
  section:not(.unfolded) > form.fold, section:not(.unfolded) > .query-help,
  section:not(.unfolded) > .export-row { display: none; }
  .ask { flex-wrap: nowrap; }
  .ask input { min-height: 44px; flex: 1 1 auto; font-size: 15px; }
  .ask button { flex: none; }
  .ask .action-state:empty { display: none; }

  /* Story cards: badges on one line that scrolls, the summary clamped until the card is opened, and the
     actions in an even grid. */
  .story { padding: 12px; }
  .story .badges { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
    -webkit-mask-image: linear-gradient(90deg, #000 85%, transparent); mask-image: linear-gradient(90deg, #000 85%, transparent); }
  .story .badges::-webkit-scrollbar { display: none; }
  .story .badges > * { flex: none; }
  .story h2 { font-size: 16px; }
  .story .summary { display: -webkit-box; -webkit-line-clamp: 4; line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden; }
  .story .points { display: none; }
  .story .also { display: -webkit-box; -webkit-line-clamp: 1; line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden; }
  .story:has(> .details:not([hidden])) .summary, .story:has(> .details:not([hidden])) .also { display: block; }
  .story:has(> .details:not([hidden])) .points { display: block; }
  .actions { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
  .actions .rate { display: contents; }
  .actions button, .actions select, .rate button { min-height: 44px; padding: 0 6px; }
  .actions .story-link { display: inline-flex; align-items: center; justify-content: center; min-height: 44px;
    border: 1px solid var(--border-strong); border-radius: var(--r-sm); text-decoration: none; }
  .actions .rate select { grid-column: 1 / -1; }
  .actions .action-state { grid-column: 1 / -1; }
  .actions .action-state:empty { display: none; }

  /* Ops and Sources: tighter cards, two tiles a row, shorter live panes. */
  .stat-card { padding: 10px 12px; }
  .ops-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .live-cols { gap: 10px; }
  .live-scroll { height: 160px; }
  .ops-controls { width: 100%; }
  .ops-controls button { flex: 1 1 auto; }
  .trend-head { align-items: flex-start; }
  .add-feed > summary { min-height: 44px; display: flex; align-items: center; gap: 8px; list-style: none; }
  .add-feed > summary::-webkit-details-marker { display: none; }
  .add-feed > summary::before { content: "B8"; color: var(--muted); transition: transform var(--t-fast) var(--ease); }
  .add-feed[open] > summary::before { transform: rotate(90deg); }
  .trend-head + .hint, main > section > h2 + .hint { font-size: 13px; }
}
/* One item of a comma-joined list with its comma. The item does not wrap, so its comma stays on its line;
   the item's own text (the link) may still wrap when it alone is wider than the line, since a break is
   allowed inside it but not at its edge with the comma. */
.nowrap-item { white-space: nowrap; }
.nowrap-item > * { white-space: normal; }
/* A chip is one unit on its line; only a chip longer than the whole line (a long CWE name) wraps inside. */
.chip { white-space: normal; max-width: 100%; }
