
/* ── Responsive grid floor ────────────────────────────────────────────────────
   Every auto-fit/auto-fill track below uses minmax(min(Npx, 100%), 1fr) rather than
   minmax(Npx, 1fr). A bare px minimum is a floor the grid CANNOT go under, so on a viewport
   narrower than N the track itself overflows the page — which is why the Methodology cards
   (320px min) pushed the document to 330px on a 320px phone. min(Npx, 100%) keeps the identical
   layout when there is room and clamps to the container when there is not. */
/* ═══════════════════════════════════════════════════════════════════════════
   Blueprint Alpha — Dark Market Dashboard Theme
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* ── Surfaces — the 5-tier elevation ladder (kept) ──────────────────────── */
  --bg-base     : #080c14;
  --bg-surface  : #0d1220;
  --bg-card     : #111827;
  --bg-elevated : #1a2235;
  --bg-hover    : #1f2d45;
  --border      : #1e2d44;
  --border-dim  : #162035;
  --border-bright: #2a3d5c;   /* interactive/hover border */

  /* ── Accent + per-group tints (the IA "where am I" colour language) ──────── */
  --accent      : #3b82f6;                       /* Markets / primary */
  --accent-dim  : rgba(59, 130, 246, 0.12);
  --accent-glow : rgba(59, 130, 246, 0.25);
  --accent-research: #8b5cf6;                    /* Research group (purple) */
  --accent-signal  : #f59e0b;                    /* SEC & Signals group (amber) */

  --green       : #10b981;
  --green-dim   : rgba(16, 185, 129, 0.12);
  --red         : #ef4444;
  --red-dim     : rgba(239, 68, 68, 0.12);
  --yellow      : #f59e0b;
  --yellow-dim  : rgba(245, 158, 11, 0.12);
  --purple      : #8b5cf6;

  /* ── Text ramp — muted FIXED to pass WCAG AA (was #55677a = 2.7–3.4:1) ───── */
  --text-primary   : #e8eef8;
  --text-secondary : #8899aa;   /* 6.7:1 on base */
  --text-muted     : #7a8ca3;   /* 5.7 / 5.2 / 4.6:1 on base/card/elevated — all AA */
  --text-faint     : #55677a;   /* the old muted — DECORATIVE non-text ONLY (bar tracks, hairlines) */

  /* ── Typography ──────────────────────────────────────────────────────────── */
  --font      : 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans CJK SC', 'Noto Sans SC', 'Noto Sans TC', 'Hiragino Sans', 'Microsoft YaHei', sans-serif;
  --mono      : 'JetBrains Mono', 'Fira Code', 'Cascadia Code', monospace;
  /* Type scale */
  --fs-2xs : 0.6875rem;  /* 11px micro-labels */
  --fs-xs  : 0.75rem;    /* 12px table cells */
  --fs-sm  : 0.8125rem;  /* 13px secondary */
  --fs-base: 0.875rem;   /* 14px body */
  --fs-md  : 1rem;       /* 16px */
  --fs-lg  : 1.125rem;   /* 18px panel titles */
  --fs-xl  : 1.5rem;     /* 24px KPI values */
  --fs-2xl : 2rem;       /* 32px hero */

  /* ── Spacing — 4/8px grid (spend as hierarchy: hero surfaces breathe, tables stay tight) ── */
  --space-1: 4px;  --space-2: 8px;  --space-3: 12px; --space-4: 16px;
  --space-5: 24px; --space-6: 32px; --space-7: 48px; --space-8: 64px;

  /* ── Radius scale ────────────────────────────────────────────────────────── */
  --radius-xs : 4px;
  --radius-sm : 6px;
  --radius    : 10px;
  --radius-lg : 14px;
  --radius-pill: 999px;

  /* ── Elevation by light, not shadow (the premium-dark trick) ─────────────── */
  --elev-0 : none;                                              /* flat static: border only */
  --elev-1 : inset 0 1px 0 rgba(255, 255, 255, 0.04);          /* interactive: subtle top sheen */
  --elev-2 : 0 2px 8px rgba(0, 0, 0, 0.25), inset 0 1px 0 rgba(255, 255, 255, 0.05);   /* dropdowns/sticky */
  --elev-3 : 0 12px 32px rgba(0, 0, 0, 0.45), inset 0 1px 0 rgba(255, 255, 255, 0.06); /* palette/modals */
  --shadow    : 0 4px 24px rgba(0, 0, 0, 0.35);   /* legacy */
  --shadow-sm : 0 2px 8px rgba(0, 0, 0, 0.25);    /* legacy */
  --max-w     : 1440px;
}

/* ── Reset ─────────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html { scroll-behavior: smooth; color-scheme: dark; scrollbar-width: thin; scrollbar-color: var(--border) var(--bg-surface); -webkit-tap-highlight-color: transparent; }

body {
  font-family : var(--font);
  font-size   : 14px;
  background  : var(--bg-base);
  color       : var(--text-primary);
  line-height : 1.55;
  min-height  : 100vh;
  display     : flex;
  flex-direction: column;
  -webkit-font-smoothing: antialiased;
  /* Steadies EVERY inline number so columns + updating values stop jittering (premium-data cue). */
  font-variant-numeric: tabular-nums;
}

/* ── Quality floor: visible keyboard focus + reduced-motion (were both absent) ── */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition-duration: 0.01ms !important; }
}

/* ── Site Header ───────────────────────────────────────────────────────────── */
.site-header {
  background    : var(--bg-surface);
  border-bottom : 1px solid var(--border);
  padding       : 0.75rem 1.5rem;
  display       : flex;
  align-items   : center;
  justify-content: space-between;
  gap           : 1rem;
  position      : sticky;
  top           : 0;
  z-index       : 100;
}

.header-brand {
  display    : flex;
  align-items: baseline;
  gap        : 0.6rem;
}

.logo-icon {
  font-size : 1.4rem;
  color     : var(--accent);
  line-height: 1;
}

.logo-text {
  font-size  : 1.15rem;
  font-weight: 600;
  color      : var(--text-primary);
  letter-spacing: -0.01em;
}

.logo-sub {
  font-size : 0.78rem;
  color     : var(--text-muted);
}

.header-meta {
  display    : flex;
  align-items: center;
  gap        : 1.25rem;
}

.market-badge {
  display    : flex;
  align-items: center;
  gap        : 0.4rem;
  font-size  : 0.72rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  padding    : 0.25rem 0.6rem;
  border-radius: var(--radius-sm);
  border     : 1px solid transparent;
}

.market-badge.market-open {
  color             : var(--green);
  border-color      : var(--green);
  background        : var(--green-dim);
}

.market-badge.market-closed {
  color       : var(--text-muted);
  border-color: var(--border);
  background  : var(--bg-elevated);
}

.market-dot {
  width        : 7px;
  height       : 7px;
  border-radius: 50%;
  background   : currentColor;
}

.market-badge.market-open .market-dot {
  animation: pulse 1.8s ease-in-out infinite;
}

@keyframes pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%       { opacity: 0.4; transform: scale(0.8); }
}

.refresh-info {
  font-size : 0.78rem;
  color     : var(--text-muted);
  display   : flex;
  align-items: center;
  gap       : 0.35rem;
}

/* ── Tab Bar ───────────────────────────────────────────────────────────────── */
/* ── Navigation ────────────────────────────────────────────────────────────────
   Fifteen destinations in one bar. Measured, the content ran to 1,583px — so it
   overflowed on every common laptop (1280/1440/1536) and only recovered at phone
   widths where the wrap rule kicked in. Horizontal scrolling hid real destinations
   behind a gesture nobody performs on a desktop: Status was simply invisible.

   The fix is where the space was going. The three group labels cost 256px — 16% of
   the whole bar — to render inert text. They are lifted OUT of the horizontal flow
   and float above their segment as micro-caps tinted with that segment's accent.
   They now cost zero width and carry more than before: label and tabs are visibly
   bound by colour, so the domain grouping reads at a glance instead of being spelled
   out. The recovered space is spent on breathing room, not on cramming more in.

   The bar wraps rather than scrolls. A second row is honest; an off-screen tab is not. */
.tab-bar {
  background    : var(--bg-surface);
  border-bottom : 1px solid var(--border);
  display       : flex;
  align-items   : flex-end;
  gap           : 0;
  padding       : 0 1.5rem;
  position      : sticky;
  top           : 57px;            /* header height */
  z-index       : 99;
  overflow      : visible;
  flex-wrap     : wrap;
  row-gap       : 4px;
}
/* The label rail belongs to each GROUP, not to the bar. Putting the space on the bar looks identical
   until the bar wraps — then a group on the second row floats its label up into the first row and it
   lands on top of whatever is above it (SEC & SIGNALS sat across "Overview" at 1100px). Every group
   carrying its own rail means a wrapped row brings its labels with it. Ungrouped tabs take the same
   offset so all baselines line up. */
.tab-bar > .tab-btn { margin-top: var(--nav-rail, 13px); }

.tab-btn {
  background    : none;
  border        : none;
  border-bottom : 2px solid transparent;
  border-radius : var(--radius-xs) var(--radius-xs) 0 0;
  color         : var(--text-muted);
  cursor        : pointer;
  font-family   : var(--font);
  font-size     : 0.85rem;
  font-weight   : 500;
  letter-spacing: .005em;
  padding       : 0.62rem 0.85rem;
  transition    : color .15s, border-color .15s, background-color .15s;
  white-space   : nowrap;
  flex          : 0 0 auto;
}
.tab-btn:hover  { color: var(--text-primary); background: var(--bg-hover); }
.tab-btn:focus-visible { outline: 2px solid var(--nav-accent, var(--accent)); outline-offset: -2px; }

/* The active tab reads as a SEAT, not just an underline: the group's accent now also
   tints the label above it, so an underline alone no longer carries enough weight to
   say "you are here" among fifteen siblings. */
.tab-btn.active {
  color             : var(--nav-accent, var(--accent));
  border-bottom-color: var(--nav-accent, var(--accent));
  background        : color-mix(in srgb, var(--nav-accent, var(--accent)) 12%, transparent);
  font-weight       : 600;
}

/* ── Nav groups (domain clustering) ─────────────────────────────────────────── */
.nav-group {
  position    : relative;
  display     : flex;
  align-items : stretch;
  flex        : 0 0 auto;
  margin-left : 0.55rem;
  padding-top : var(--nav-rail, 13px);   /* the group's own label rail — survives wrapping */
  padding-left: 0.55rem;
  border-left : 1px solid var(--border);
}
.nav-group[data-accent="markets"]  { --nav-accent: var(--accent); }
.nav-group[data-accent="research"] { --nav-accent: var(--accent-research); }
.nav-group[data-accent="signals"]  { --nav-accent: var(--accent-signal); }

/* Absolutely positioned → zero horizontal cost. The group name is annotation, so it is
   set smaller than any other type on the page and never competes with the tabs. */
.nav-group-label {
  position      : absolute;
  top           : 1px;            /* inside the group's own rail, not above the group */
  left          : 0.55rem;
  font-size     : 9px;
  font-weight   : 700;
  text-transform: uppercase;
  letter-spacing: .16em;
  line-height   : 1;
  white-space   : nowrap;
  pointer-events: none;
  /* COLOUR IS SET ONCE, further down, in the accessibility block — see ".nav-group-label" there.
     Do not add a `color` here: an earlier rule with the same specificity loses silently, which is
     precisely how the accent tint appeared to be applied while the labels stayed grey. */
}

/* News and Status are utility surfaces, not a domain — they sit apart from the groups. */
.tab-btn.tab-news   { margin-left: 0.55rem; padding-left: 0.9rem; border-left: 1px solid var(--border); }
/* Status was on --text-faint, which this stylesheet documents as decorative-only and which measured
   3.21:1 here — below AA. It is a real destination, not a watermark; being the least-visited tab is a
   reason to rank it last, not a reason to make it hard to read. */
.tab-btn.tab-system { margin-left: auto; color: var(--text-muted); }
.tab-btn.tab-system:hover { color: var(--text-primary); }
.tab-btn.tab-system.active { color: var(--nav-accent, var(--accent)); }

/* Once the bar wraps, `margin-left:auto` would strand Status alone on its own row,
   right-aligned against nothing. Below the width where everything fits on one line it
   simply joins the flow. */
@media (max-width: 1180px) {
  .tab-btn.tab-system { margin-left: 0; }
}

/* ── Main Content ──────────────────────────────────────────────────────────── */
.main-content {
  flex   : 1;
  width  : min(100%, var(--max-w));
  margin : 0 auto;
  padding: 1.25rem 1.5rem;
}

/* ── Tab Panels ────────────────────────────────────────────────────────────── */
.tab-panel { display: none; }
.tab-panel.active { display: block; }

/* ── Toolbar ───────────────────────────────────────────────────────────────── */
.panel-toolbar {
  display    : flex;
  align-items: center;
  gap        : 1rem;
  margin-bottom: 1rem;
  flex-wrap  : wrap;
}

.panel-title {
  font-size  : 1.1rem;
  font-weight: 600;
  color      : var(--text-primary);
  margin-right: auto;
}

.toolbar-right {
  display   : flex;
  align-items: center;
  gap       : 0.5rem;
}

/* ── Search ────────────────────────────────────────────────────────────────── */
.search-input {
  background   : var(--bg-card);
  border       : 1px solid var(--border);
  border-radius: var(--radius-sm);
  color        : var(--text-primary);
  font-family  : var(--font);
  font-size    : 0.85rem;
  padding      : 0.4rem 0.75rem;
  width        : 220px;
  transition   : border-color 0.15s;
  outline      : none;
}

.search-input:focus {
  border-color: var(--accent);
  box-shadow  : 0 0 0 2px var(--accent-dim);
}

.search-input::placeholder { color: var(--text-muted); }

.search-dropdown {
  background   : var(--bg-elevated);
  border       : 1px solid var(--border);
  border-radius: var(--radius-sm);
  box-shadow   : var(--shadow);
  max-height   : 220px;
  overflow-y   : auto;
  position     : absolute;
  right        : 1.5rem;
  top          : calc(57px + 43px + 1.25rem + 42px);
  width        : 260px;
  z-index      : 200;
}

.search-dropdown.hidden { display: none; }

.search-item {
  cursor     : pointer;
  padding    : 0.5rem 0.75rem;
  font-size  : 0.85rem;
  display    : flex;
  gap        : 0.5rem;
  align-items: baseline;
  transition : background 0.1s;
}

.search-item:hover { background: var(--bg-hover); }
.search-item .sym  { font-family: var(--mono); font-weight: 500; color: var(--accent); min-width: 60px; }
.search-item .name { color: var(--text-muted); font-size: 0.78rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── Tables ────────────────────────────────────────────────────────────────── */
.table-wrap {
  overflow-x   : auto;
  border-radius: var(--radius);
  border       : 1px solid var(--border);
  -webkit-overflow-scrolling: touch;
  scrollbar-color: var(--border) var(--bg-elevated);   /* themed scrollbar on real devices */
  /* Scroll affordance: classic CSS "scrolling shadows" — a soft shadow appears on whichever
     edge has more table to scroll to (and disappears at the ends). Pure background, so it
     renders everywhere (unlike overlay scrollbars), telling the user a wide table can scroll. */
  background:
    linear-gradient(90deg, var(--bg-card), rgba(17, 24, 39, 0)) 0 0,
    linear-gradient(90deg, rgba(17, 24, 39, 0), var(--bg-card)) 100% 0,
    radial-gradient(farthest-side at 0 50%, rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0)) 0 0,
    radial-gradient(farthest-side at 100% 50%, rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0)) 100% 0;
  background-repeat: no-repeat;
  background-size: 34px 100%, 34px 100%, 22px 100%, 22px 100%;
  background-attachment: local, local, scroll, scroll;
}

.data-table {
  border-collapse: collapse;
  width           : 100%;
  font-size       : 0.83rem;
}

.data-table thead tr {
  background   : var(--bg-elevated);
  border-bottom: 1px solid var(--border);
}

.data-table th {
  color       : var(--text-muted);
  font-size   : 0.72rem;
  font-weight : 500;
  letter-spacing: 0.04em;
  padding     : 0.6rem 0.85rem;
  text-align  : left;
  text-transform: uppercase;
  white-space : nowrap;
}

.data-table th.num { text-align: right; }

.data-table tbody tr {
  border-bottom: 1px solid var(--border-dim);
  cursor       : pointer;
  transition   : background 0.1s;
}

.data-table tbody tr:last-child { border-bottom: none; }
.data-table tbody tr:hover      { background: var(--bg-hover); }
.data-table tbody tr.selected   { background: var(--accent-dim); }

.data-table td {
  color  : var(--text-primary);
  padding: 0.55rem 0.85rem;
}

.data-table td.num       { text-align: right; font-family: var(--mono); font-size: 0.82rem; white-space: nowrap; }
.data-table th.num         { white-space: nowrap; }
.data-table td.symbol-cell { font-family: var(--mono); font-weight: 500; font-size: 0.88rem; }
/* Trailing gutter so the last column's value is never clipped flush against the card edge. */
.data-table th:last-child, .data-table td:last-child { padding-right: 1rem; }

.loading-row { text-align: center; color: var(--text-muted); padding: 2rem !important; }

/* ── Frozen first column (.freeze-first) — keeps the identifier visible while a wide
      table scrolls horizontally. The header cell sits above the body cells (z-index). ── */
.data-table.freeze-first thead th:first-child,
.data-table.freeze-first tbody td:first-child { position: sticky; left: 0; }
.data-table.freeze-first tbody td:first-child { background: var(--bg-card); z-index: 1; box-shadow: 1px 0 0 var(--border-dim); }
.data-table.freeze-first thead th:first-child { background: var(--bg-elevated); z-index: 3; box-shadow: 1px 0 0 var(--border); }
/* keep the frozen cell's background in sync with row hover / selection */
.data-table.freeze-first tbody tr:hover td:first-child    { background: var(--bg-hover); }
.data-table.freeze-first tbody tr.selected td:first-child { background: var(--accent-dim); }

/* ── Proportional magnitude bar behind Change% (width ∝ |move|, tinted by direction) ── */
.chg-cell { position: relative; }
.chg-bar  { position: absolute; top: 5px; bottom: 5px; right: 0; border-radius: 2px; opacity: 0.16; pointer-events: none; }
.chg-cell.up   .chg-bar { background: var(--green); }
.chg-cell.down .chg-bar { background: var(--red); }
.chg-val  { position: relative; }

/* Colour helpers — high specificity so they win inside .data-table td */
.up,   .data-table td.up   { color: var(--green); }
.down, .data-table td.down { color: var(--red); }
.mid,  .data-table td.mid  { color: var(--accent); }
.flat, .data-table td.flat { color: var(--text-muted); }

/* ── Stock Detail Panel ─────────────────────────────────────────────────────── */
.detail-panel {
  background   : var(--bg-card);
  border       : 1px solid var(--border);
  border-radius: var(--radius);
  margin-top   : 1.25rem;
  overflow     : hidden;
}

.detail-panel.hidden { display: none; }

.detail-header {
  align-items  : center;
  background   : var(--bg-elevated);
  border-bottom: 1px solid var(--border);
  display      : flex;
  gap          : 1rem;
  padding      : 0.9rem 1.25rem;
  flex-wrap    : wrap;
}

.detail-title-block { display: flex; align-items: baseline; gap: 0.6rem; flex: 1; min-width: 0; }
.detail-symbol { font-family: var(--mono); font-size: 1.1rem; font-weight: 600; color: var(--accent); }
.detail-name   { font-size: 0.9rem; color: var(--text-secondary); }
.detail-sector { font-size: 0.75rem; color: var(--text-muted); background: var(--bg-base); padding: 0.15rem 0.4rem; border-radius: 3px; }

.detail-price-block { display: flex; align-items: baseline; gap: 0.5rem; flex-wrap: wrap; }
.detail-price  { font-family: var(--mono); font-size: 1.3rem; font-weight: 600; }
.detail-change { font-family: var(--mono); font-size: 0.9rem; }
.detail-crosscheck {
  flex-basis: 100%;
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--text-muted);
}
.detail-crosscheck.up   { color: var(--green); }
.detail-crosscheck.down { color: var(--red); }

.quality-badge {
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 600;
  padding: 0.1rem 0.45rem;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--bg-card);
  color: var(--text-secondary);
}
.quality-badge.up   { color: var(--green); border-color: var(--green); background: var(--green-dim); }
.quality-badge.down { color: var(--red);   border-color: var(--red);   background: var(--red-dim); }
.quality-badge.mid  { color: var(--accent); border-color: var(--accent); background: var(--accent-dim); }

.close-btn {
  background: none;
  border    : 1px solid var(--border);
  border-radius: var(--radius-sm);
  color     : var(--text-muted);
  cursor    : pointer;
  font-size : 1rem;
  height    : 30px;
  width     : 30px;
  transition: color .15s, border-color .15s, background .15s, transform .08s;
  flex-shrink: 0;
}

.close-btn:hover { color: var(--text-primary); border-color: var(--text-muted); }

.detail-body {
  display  : flex;
  flex-direction: column;
  gap      : 1rem;
  padding  : 1.25rem;
}

.indicators-row {
  display              : grid;
  gap                  : 1rem;
  grid-template-columns: repeat(3, 1fr);
}

/* ── Detail sub-tabs (Overview / Financials / Ownership / Filings / Sentiment) ── */
/* KPI chip row — summary-first read, sits between the header and the sub-nav. */
.detail-kpis {
  display  : flex;
  flex-wrap: wrap;
  gap      : var(--space-2);
  padding  : var(--space-3) var(--space-5) 0;
}
.detail-kpis:empty { display: none; }            /* no padding gap before fundamentals load */
.kchip {
  display      : flex;
  flex-direction: column;
  gap          : 2px;
  background   : var(--bg-base);
  border       : 1px solid var(--border);
  border-radius: var(--radius-sm);
  box-shadow   : var(--elev-1);
  padding      : var(--space-2) var(--space-3);
  min-width    : 74px;
}
.kchip-k { font-size: var(--fs-2xs); color: var(--text-muted); text-transform: uppercase; letter-spacing: .04em; }
.kchip-v { font-family: var(--mono); font-size: var(--fs-sm); font-weight: 600; color: var(--text-primary); }

.detail-subnav {
  display      : flex;
  align-items  : center;
  gap          : var(--space-1);
  padding      : 0 var(--space-5);
  margin-top   : var(--space-3);
  background   : var(--bg-elevated);
  border-top   : 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  overflow-x   : auto;
}
.detail-subtab-btn {
  background    : none;
  border        : none;
  border-bottom : 2px solid transparent;
  color         : var(--text-muted);
  cursor        : pointer;
  font-family   : inherit;
  font-size     : var(--fs-sm);
  font-weight   : 500;
  padding       : var(--space-3) var(--space-3);
  white-space   : nowrap;
  transition    : color .15s, border-color .15s;
}
.detail-subtab-btn:hover  { color: var(--text-secondary); }
.detail-subtab-btn.active { color: var(--accent); border-bottom-color: var(--accent); }
.detail-expandall {
  margin-left : auto;
  display     : inline-flex;
  align-items : center;
  gap         : var(--space-1);
  padding-left: var(--space-2);
  color       : var(--text-muted);
  font-size   : var(--fs-xs);
  cursor      : pointer;
  white-space : nowrap;
}
.detail-expandall input { cursor: pointer; accent-color: var(--accent); }
/* When expanded, the sub-tab buttons no longer gate visibility → drop the active accent. */
.detail-subnav.expanded .detail-subtab-btn.active { color: var(--text-muted); border-bottom-color: transparent; }

.detail-section { display: none; flex-direction: column; gap: 1rem; }
.detail-section.active { display: flex; }
.detail-body.expand-all .detail-section { display: flex; }
.detail-body.expand-all .detail-section + .detail-section {
  border-top : 1px solid var(--border);
  padding-top: 1.25rem;
}

@media (max-width: 900px) {
  .indicators-row { grid-template-columns: 1fr; }
}

.indicator-badge {
  font-family: var(--mono);
  font-size  : 0.82rem;
  padding    : 0.25rem 0.6rem;
  margin-top : 0.4rem;
  border-radius: var(--radius-sm);
  display    : inline-block;
}

.company-info {
  background   : var(--bg-elevated);
  border       : 1px solid var(--border);
  border-radius: var(--radius-sm);
  display      : grid;
  font-size    : 0.82rem;
  gap          : 0.5rem 1.5rem;
  grid-template-columns: repeat(auto-fill, minmax(min(200px, 100%), 1fr));
  padding      : 0.9rem 1rem;
}

.info-row { display: flex; flex-direction: column; gap: 0.1rem; }
.info-label { color: var(--text-muted); font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.04em; }
.info-val   { color: var(--text-primary); font-weight: 500; }
/* CC0 provenance note — spans the full grid width under the fact rows */
.info-src { grid-column: 1 / -1; color: var(--text-faint); font-size: var(--fs-2xs); padding-top: 0.15rem; border-top: 1px solid var(--border-dim); }
.info-src a { color: var(--text-muted); }
.info-src a:hover { color: var(--accent); }

/* ── Chart Cards ───────────────────────────────────────────────────────────── */
.chart-card {
  background   : var(--bg-card);
  border       : 1px solid var(--border);
  border-radius: var(--radius);
  overflow     : hidden;
}

.chart-card.full-width { width: 100%; }

.chart-card-header {
  align-items  : center;
  background   : var(--bg-elevated);
  border-bottom: 1px solid var(--border);
  display      : flex;
  gap          : 1rem;
  justify-content: space-between;
  padding      : 0.6rem 1rem;
}

.chart-card-header h3 {
  font-size  : 0.82rem;
  font-weight: 500;
  color      : var(--text-secondary);
  letter-spacing: 0.02em;
}

.chart-wrap    { padding: 0.75rem 1rem; position: relative; height: 240px; }
.chart-wrap-sm { height: 160px; }

/* ── Macro Tab ─────────────────────────────────────────────────────────────── */
.macro-kpi-grid {
  display              : grid;
  gap                  : 1rem;
  grid-template-columns: repeat(auto-fill, minmax(min(200px, 100%), 1fr));
  margin-bottom        : 1.25rem;
}

.kpi-card {
  background   : var(--bg-card);
  border       : 1px solid var(--border);
  border-radius: var(--radius);
  padding      : 0.9rem 1.1rem;
  transition   : border-color 0.2s;
}


.kpi-label        { color: var(--text-muted); font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 0.35rem; }
.kpi-value        { font-family: var(--mono); font-size: 1.5rem; font-weight: 600; line-height: 1; }
.kpi-sub          { color: var(--text-muted); font-size: 0.75rem; margin-top: 0.25rem; }
.kpi-change       { font-size: 0.78rem; margin-top: 0.15rem; }
.kpi-inverted-warn { color: var(--red); font-size: 0.75rem; font-weight: 600; margin-top: 0.35rem; }

.macro-charts-grid {
  display              : grid;
  gap                  : 1rem;
  grid-template-columns: 1fr 1fr;
}

@media (max-width: 768px) {
  .macro-charts-grid { grid-template-columns: 1fr; }
}

.skeleton-card {
  background   : var(--bg-card);
  border       : 1px solid var(--border);
  border-radius: var(--radius);
  height       : 100px;
  animation    : shimmer 1.5s ease-in-out infinite;
}

@keyframes shimmer {
  0%, 100% { opacity: 0.5; }
  50%       { opacity: 1; }
}

/* Shimmer SWEEP — a soft highlight glides across a grey block ("content loading"), nicer than an
   opacity pulse. Shared by the table skeletons (.skel-bar) and the panel/list loaders (.load-line). */
@keyframes shimmerSweep { 0% { background-position: 150% 0; } 100% { background-position: -150% 0; } }
.skel-bar, .load-line {
  border-radius: var(--radius-xs);
  background: linear-gradient(90deg,
    var(--bg-hover) 0%, var(--bg-hover) 40%,
    var(--border-bright) 50%,
    var(--bg-hover) 60%, var(--bg-hover) 100%);
  background-size: 220% 100%;
  animation: shimmerSweep 1.5s ease-in-out infinite;
}
/* Skeleton table rows (first-paint placeholder). */
.skel-bar {
  display      : inline-block;
  height       : 0.72em;
  min-width    : 20px;
  vertical-align: middle;
}
.data-table tbody tr.skeleton-row { cursor: default; }
.data-table tbody tr.skeleton-row:hover { background: none; }

/* Reusable animated loader for on-demand panels/lists: shimmering skeleton lines + a labelled
   accent spinner, so a slow fetch shows MOTION instead of a static grey word. */
.load-block { display: flex; flex-direction: column; gap: 0.55rem; padding: 0.7rem 0; }
.load-line  { height: 0.7rem; }
.load-label {
  margin-top: 0.15rem; display: inline-flex; align-items: center; gap: 0.45rem;
  color: var(--text-muted); font-size: var(--fs-xs);
}
.load-label::before {
  content: ""; width: 0.8em; height: 0.8em; border-radius: 50%; flex: 0 0 auto;
  border: 2px solid var(--border-bright); border-top-color: var(--accent);
  animation: spin 0.7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Chart-shaped loader — a tall shimmer block filling the fixed-height chart wrap + a labelled spinner. */
.chart-loading { display: flex; flex-direction: column; justify-content: center; gap: 0.6rem; height: 100%; padding: 0.6rem 0.2rem; }
.chart-skel    { flex: 1 1 auto; min-height: 60px; width: 100%; }

/* Bounded-scroll tables (.table-scroll) keep a long result set inside its own scroll
   region with a sticky header — the column labels never scroll away. top:0 sticks to the
   wrapper's own top (not the page), so it's robust to nav height / responsive changes. */
.table-wrap.table-scroll { max-height: 70vh; overflow-y: auto; }
.table-wrap.table-scroll thead th {
  position: sticky; top: 0; z-index: 2;
  background: var(--bg-elevated);          /* opaque — body rows must scroll under, not through */
}

/* ── Backtest Tab ──────────────────────────────────────────────────────────── */
.card {
  background   : var(--bg-card);
  border       : 1px solid var(--border);
  border-radius: var(--radius);
  padding      : 1.1rem 1.25rem;
  margin-bottom: 1.25rem;
}

.control-row {
  display  : flex;
  gap      : 1rem;
  flex-wrap: wrap;
  align-items: flex-end;
}

.control-group { display: flex; flex-direction: column; gap: 0.3rem; }
.control-group label { color: var(--text-muted); font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.04em; }

.control-input {
  background   : var(--bg-elevated);
  border       : 1px solid var(--border);
  border-radius: var(--radius-sm);
  color        : var(--text-primary);
  font-family  : var(--font);
  font-size    : 0.85rem;
  outline      : none;
  padding      : 0.45rem 0.75rem;
  transition   : border-color 0.15s;
}

.control-input:focus { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-dim); }
select.control-input { cursor: pointer; }

.control-group-btn { justify-content: flex-end; }
.control-group-wide { flex: 1 1 240px; min-width: 200px; }

/* Backtest tab — dynamic per-strategy params + secondary settings row */
.ts-params { display: flex; flex-wrap: wrap; gap: 0.75rem; margin: 0 0 0.5rem; }
.ts-params .control-group { min-width: 110px; }
.ts-settings { margin-top: 0.1rem; }
.ts-settings .control-group { min-width: 90px; }

.bt-message {
  color     : var(--text-muted);
  font-size : 0.82rem;
  margin-top: 0.6rem;
  min-height: 1.2rem;
}

/* Pre-run empty state (Backtest + Factor Lab) — fills the void below the controls until the
 * first run, then stays hidden. Dashed frame = "nothing here yet, and that's expected". */
.bt-empty {
  border       : 1px dashed var(--border);
  border-radius: var(--radius);
  margin       : 1.25rem 0;
  padding      : 2.25rem 1.5rem 2rem;
  text-align   : center;
}
.bt-empty-title { color: var(--text-primary); font-size: 1rem; font-weight: 600; margin: 0 0 0.4rem; }
.bt-empty-sub   { color: var(--text-muted); font-size: 0.82rem; line-height: 1.55; margin: 0 auto 1.1rem; max-width: 560px; }
.bt-empty-examples { display: flex; flex-wrap: wrap; gap: 0.5rem; justify-content: center; }
.bt-example {
  background   : transparent;
  border       : 1px solid var(--border);
  border-radius: var(--radius-pill);
  color        : var(--text-primary);
  cursor       : pointer;
  font-family  : var(--font);
  font-size    : 0.8rem;
  padding      : 0.4rem 0.9rem;
  transition   : border-color 0.15s, background 0.15s;
}
.bt-example:hover { background: var(--bg-elevated); border-color: var(--accent); }

.bt-stats-grid {
  display              : grid;
  gap                  : 1rem;
  grid-template-columns: repeat(auto-fill, minmax(min(160px, 100%), 1fr));
  margin-bottom        : 1.25rem;
}

.bt-stat-card {
  background   : var(--bg-card);
  border       : 1px solid var(--border);
  border-radius: var(--radius);
  padding      : 0.75rem 1rem;
  text-align   : center;
}

.bt-stat-label { color: var(--text-muted); font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.04em; }
.bt-stat-value { font-family: var(--mono); font-size: 1.25rem; font-weight: 600; margin-top: 0.25rem; }

/* ── Status Tab ────────────────────────────────────────────────────────────── */
.status-grid {
  display              : grid;
  gap                  : 1rem;
  grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr));
}

.status-card {
  background   : var(--bg-card);
  border       : 1px solid var(--border);
  border-radius: var(--radius);
  padding      : 1rem 1.1rem;
}

.status-card h3 { font-size: 0.82rem; font-weight: 500; color: var(--text-secondary); margin-bottom: 0.75rem; text-transform: uppercase; letter-spacing: 0.04em; }
.status-row     { display: flex; justify-content: space-between; align-items: baseline; padding: 0.25rem 0; border-bottom: 1px solid var(--border-dim); font-size: 0.82rem; }
.status-row:last-child { border-bottom: none; }
.status-key     { color: var(--text-muted); }
.status-val     { font-family: var(--mono); color: var(--text-primary); }
.status-val.ok  { color: var(--green); }
.status-val.err { color: var(--red); }
.status-val.warn{ color: var(--yellow); }

.budget-bar-wrap { margin-top: 0.5rem; }
.budget-bar-label{ display: flex; justify-content: space-between; font-size: 0.75rem; color: var(--text-muted); margin-bottom: 0.3rem; }
.budget-bar      { background: var(--bg-elevated); border-radius: 99px; height: 6px; overflow: hidden; }
.budget-bar-fill { background: var(--accent); border-radius: 99px; height: 100%; transition: width 0.4s ease; }
.budget-bar-fill.warn  { background: var(--yellow); }
.budget-bar-fill.danger{ background: var(--red); }

/* ── Shared Buttons ────────────────────────────────────────────────────────── */
.btn-primary {
  background   : var(--accent);
  border       : none;
  border-radius: var(--radius-sm);
  color        : #fff;
  cursor       : pointer;
  font-family  : var(--font);
  font-size    : 0.85rem;
  font-weight  : 500;
  padding      : 0.5rem 1.1rem;
  transition   : opacity 0.15s, transform 0.1s;
}

.btn-primary:hover   { filter: brightness(1.12); }
.btn-primary:active  { transform: scale(0.97); }
.btn-primary:disabled{ opacity: 0.45; cursor: not-allowed; }

.btn-secondary {
  background: transparent; border: 1px solid var(--border); border-radius: var(--radius-sm);
  color: var(--text-primary); cursor: pointer; font-family: var(--font); font-size: 0.85rem;
  padding: 0.5rem 1.1rem; transition: border-color 0.15s, opacity 0.15s;
}
.btn-secondary:hover   { border-color: var(--accent); }
.btn-secondary:disabled{ opacity: 0.45; cursor: not-allowed; }

/* Backtest ticker coverage hint */
.ts-coverage { font-size: 0.74rem; color: var(--text-muted); font-family: var(--mono); }
.ts-cov-warn { color: var(--yellow); }

/* Strategy comparison set */
.ts-compare-bar { display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.5rem; }
.ts-compare-chips { display: flex; flex-wrap: wrap; gap: 0.4rem; flex: 1 1 auto; }
.ts-chip { display: inline-flex; align-items: center; gap: 0.3rem; background: var(--bg-elevated); border: 1px solid var(--border);
  border-radius: 999px; padding: 0.2rem 0.6rem; font-size: 0.72rem; font-family: var(--mono); color: var(--text-primary); }
.ts-chip-x { background: none; border: none; color: var(--text-muted); cursor: pointer; font-size: 0.9rem; line-height: 1; padding: 0; }
.ts-chip-x:hover { color: var(--red); }
.ts-swatch { display: inline-block; width: 10px; height: 10px; border-radius: 2px; }

/* Parameter-sweep heatmap */
.ts-heatmap-wrap { overflow-x: auto; }
.ts-heatmap { border-collapse: collapse; font-size: 0.72rem; font-family: var(--mono); }
.ts-heatmap th { color: var(--text-muted); padding: 0.25rem 0.5rem; font-weight: 600; text-align: center; white-space: nowrap; }
.ts-heatmap th.ts-hm-axis { font-size: 0.68rem; text-align: right; }
.ts-hm-cell { text-align: center; padding: 0.35rem 0.5rem; color: #eef2f7; min-width: 46px; border: 1px solid rgba(0,0,0,0.25); }
.ts-hm-best { outline: 2px solid var(--accent); outline-offset: -2px; font-weight: 700; }

.btn-ghost {
  background   : none;
  border       : 1px solid var(--border);
  border-radius: var(--radius-sm);
  color        : var(--text-muted);
  cursor       : pointer;
  font-family  : var(--font);
  font-size    : 0.82rem;
  padding      : 0.35rem 0.75rem;
  transition   : all 0.15s;
}

.btn-ghost:hover { color: var(--text-primary); border-color: var(--text-muted); }

/* ── Utilities ─────────────────────────────────────────────────────────────── */
.hidden  { display: none !important; }
.mono    { font-family: var(--mono); }
.muted   { color: var(--text-muted); }
.small   { font-size: 0.78rem; }
.chart-legend { font-size: 0.75rem; color: var(--text-muted); display: flex; gap: 0.75rem; flex-wrap: wrap; }
.legend-item  { display: flex; align-items: center; gap: 0.3rem; }
.legend-dot   { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }

/* ── Site Footer ───────────────────────────────────────────────────────────── */
.site-footer {
  border-top: 1px solid var(--border);
  color     : var(--text-muted);
  display   : flex;
  flex-wrap : wrap;
  font-size : 0.72rem;
  gap       : 0.5rem 2rem;
  justify-content: space-between;
  margin-top: auto;
  padding   : 0.75rem 1.5rem;
}

/* ── Fundamentals panel (stock detail) ───────────────────────────────────────── */
.fundamentals-panel, .filings-panel { margin-top: 1.25rem; }
.events-panel, .earnings-panel, .institutional-panel, .ftd-panel { margin-top: 1.25rem; }

/* CFTC positioning table */
.positioning-section { margin-top: 1.5rem; }
.macro-section-title { font-size: 1rem; font-weight: 600; color: var(--text-primary); margin: 0 0 0.2rem; }
.cot-flag { display: inline-block; font-size: 0.68rem; font-weight: 600; padding: 0.05rem 0.4rem; border-radius: 999px; border: 1px solid var(--border); }
.cot-flag.up   { color: var(--green); border-color: var(--green); background: var(--green-dim); }
.cot-flag.down { color: var(--red);   border-color: var(--red);   background: var(--red-dim); }

/* Settlement fails (FTD) — amber/red/neutral badges, deliberately NEVER green */
.ftd-badge {
  display: inline-block; font-size: 0.72rem; font-weight: 600; text-transform: capitalize;
  padding: 0.05rem 0.45rem; border-radius: 999px; border: 1px solid var(--border);
  color: var(--text-secondary); margin-left: 0.4rem; vertical-align: middle;
}
.ftd-badge.down { color: var(--red);    border-color: var(--red);    background: var(--red-dim); }
.ftd-badge.mid  { color: var(--accent); border-color: var(--accent); background: var(--accent-dim); }
.ftd-stats { display: flex; flex-direction: column; gap: 0.2rem; font-size: 0.84rem; margin: 0.3rem 0 0.5rem; }
.ftd-caveat { font-size: 0.68rem; color: var(--text-muted); font-style: italic; margin-top: 0.5rem; line-height: 1.4; }

/* Earnings forward estimate — dashed to read as a projection, never a confirmed date */
.earn-est {
  border: 1px dashed var(--border); border-left: 3px dashed var(--accent);
  border-radius: var(--radius-sm); background: var(--bg-card);
  padding: 0.6rem 0.8rem; margin-bottom: 0.6rem;
  display: flex; flex-direction: column; gap: 0.25rem;
}
.earn-chip {
  display: inline-block; font-size: 0.6rem; font-weight: 700; letter-spacing: 0.05em;
  color: var(--accent); border: 1px solid var(--accent); border-radius: 3px; padding: 0 0.28rem; vertical-align: middle;
}
.earn-date { font-family: var(--mono); font-size: 1.05rem; font-weight: 600; color: var(--text-primary); margin: 0 0.3rem; }
/* No-estimate state: drop the accent border + chip colour so it never reads as a confident projection */
.earn-est-na { border-left-color: var(--border); }
.earn-est-na .earn-chip { color: var(--text-muted); border-color: var(--text-muted); }
.earn-na   { color: var(--text-secondary); font-size: 0.85rem; }
.earn-disc { font-size: 0.68rem; color: var(--text-muted); font-style: italic; }

/* Insider conviction-signal badge */
.insider-badge {
  display: inline-block; font-size: 0.72rem; font-weight: 600;
  padding: 0.05rem 0.45rem; border-radius: 999px; border: 1px solid var(--border);
  color: var(--text-secondary); margin-left: 0.4rem; vertical-align: middle;
}
.insider-badge.up   { color: var(--green); border-color: var(--green); background: var(--green-dim); }
.insider-badge.down { color: var(--red);   border-color: var(--red);   background: var(--red-dim); }
.fund-header {
  display: flex; align-items: baseline; gap: 0.75rem;
  border-top: 1px solid var(--border); padding-top: 1rem; margin-bottom: 0.75rem;
}
.fund-header h3 { font-size: 0.95rem; }
.fund-subhead {
  font-size: 0.85rem; margin: 1.1rem 0 0.5rem; color: var(--text-secondary); font-weight: 600;
}
.fund-grid {
  display: grid; gap: 0.5rem;
  grid-template-columns: repeat(auto-fill, minmax(min(135px, 100%), 1fr));
}
.fund-cell {
  background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 0.55rem 0.7rem; display: flex; flex-direction: column; gap: 0.15rem;
}
.fund-k { font-size: 0.7rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.03em; }
.fund-v { font-family: var(--mono); font-size: 0.95rem; color: var(--text-primary); font-weight: 500; }

/* Sector percentile rank tag + bar on each .fund-cell */
.fund-pct { font-size: 0.66rem; font-weight: 600; letter-spacing: 0.02em; margin-top: 0.1rem;
            padding: 0.05rem 0.3rem; border-radius: 3px; align-self: flex-start; }
.fund-pct.rank-top { color: var(--green); background: var(--green-dim); }
.fund-pct.rank-bot { color: var(--red);   background: var(--red-dim); }
.fund-pct.rank-mid { color: var(--text-secondary); background: var(--bg-card); }
.fund-bar { display: block; height: 3px; border-radius: 2px; background: var(--border); margin-top: 0.25rem; overflow: hidden; }
.fund-bar > i { display: block; height: 100%; }
.fund-cell.rank-top .fund-bar > i { background: var(--green); }
.fund-cell.rank-bot .fund-bar > i { background: var(--red); }
.fund-cell.rank-mid .fund-bar > i { background: var(--text-secondary); }

/* Factor / distress scores (Piotroski F, Altman Z, Beneish M) */
.factor-grid {
  display: grid; gap: 0.5rem;
  grid-template-columns: repeat(auto-fill, minmax(min(150px, 100%), 1fr));
}
.factor-cell {
  background: var(--bg-card); border: 1px solid var(--border); border-left-width: 3px;
  border-radius: var(--radius-sm); padding: 0.55rem 0.7rem;
  display: flex; flex-direction: column; gap: 0.2rem;
}
.factor-cell.up   { border-left-color: var(--green); }
.factor-cell.mid  { border-left-color: var(--accent); }
.factor-cell.down { border-left-color: var(--red); }
.factor-k { font-size: 0.7rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.03em; }
.factor-v { font-family: var(--mono); font-size: 1.15rem; color: var(--text-primary); font-weight: 600; }
.factor-cell.up   .factor-v { color: var(--green); }
.factor-cell.mid  .factor-v { color: var(--accent); }
.factor-cell.down .factor-v { color: var(--red); }
.factor-sub  { font-size: 0.8rem; color: var(--text-muted); font-weight: 400; }
.factor-zone { font-size: 0.72rem; text-transform: capitalize; color: var(--text-secondary); margin-left: 0.2rem; }

/* Financial statements (income / balance / cash flow) */
.stmt-grid {
  display: grid; gap: 0.75rem;
  grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
}
.stmt-card {
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 0.7rem 0.85rem;
}
.stmt-title {
  font-size: 0.78rem; font-weight: 600; color: var(--accent);
  margin-bottom: 0.5rem; padding-bottom: 0.35rem; border-bottom: 1px solid var(--border);
}
.stmt-card .info-row { padding: 0.18rem 0; }

/* Multi-year trend charts (detail panel) */
.trend-grid {
  display: grid; gap: 0.75rem;
  grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
}

/* Sortable table headers (screener) */
.sortable-table th.sortable { cursor: pointer; user-select: none; white-space: nowrap; transition: color 0.12s; }
.sortable-table th.sortable:hover { color: var(--text-primary); }
.sortable-table th.sorted { color: var(--accent); }

/* ── Filings list ────────────────────────────────────────────────────────────── */
.filings-list { display: flex; flex-direction: column; gap: 2px; }
.filing-row {
  display: grid; grid-template-columns: 64px 96px 1fr; align-items: center; gap: 0.75rem;
  padding: 0.4rem 0.6rem; border-radius: var(--radius-sm); text-decoration: none;
  color: var(--text-secondary); font-size: 0.8rem; transition: background 0.12s;
}
.filing-row:hover { background: var(--bg-hover); }
.filing-form {
  display: inline-block; text-align: center; font-weight: 600; font-size: 0.72rem;
  color: var(--accent); background: var(--accent-dim); border-radius: 4px; padding: 0.1rem 0.3rem;
}
.filing-date { color: var(--text-secondary); }
.filing-doc  { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── Scrollbar ─────────────────────────────────────────────────────────────── */
::-webkit-scrollbar       { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: var(--bg-surface); }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 99px; }
::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }

/* ── Media tone (GDELT) ─────────────────────────────────────────────────── */
.news-tone-panel:empty { display: none; }
.news-badge {
  display: inline-block; font-size: 0.72rem; font-weight: 600;
  padding: 0.05rem 0.45rem; border-radius: 999px; border: 1px solid var(--border);
  color: var(--text-secondary); margin-left: 0.4rem; vertical-align: middle;
}
.news-badge.up   { color: var(--green); border-color: var(--green); background: var(--green-dim); }
.news-badge.down { color: var(--red);   border-color: var(--red);   background: var(--red-dim); }
.news-pill {
  display: inline-block; font-size: 0.68rem; font-weight: 600; vertical-align: middle;
  padding: 0.03rem 0.4rem; border-radius: 999px; margin-left: 0.3rem;
  color: var(--text-muted); border: 1px solid var(--border); background: var(--bg-surface);
}
.news-headlines { display: flex; flex-direction: column; gap: 0.15rem; margin-top: 0.4rem; }
.news-headline {
  display: flex; justify-content: space-between; align-items: baseline; gap: 0.6rem;
  padding: 0.22rem 0.1rem; border-bottom: 1px solid var(--border); text-decoration: none;
}
.news-headline:last-child { border-bottom: none; }
.news-headline:hover .news-h-title { color: var(--accent); }
.news-h-title { color: var(--text-secondary); font-size: 0.8rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.news-h-meta  { font-size: 0.68rem; white-space: nowrap; flex-shrink: 0; }

/* ── 5%+ Holders (SEC 13D/13G) ──────────────────────────────────────────── */
.stakes-panel:empty { display: none; }
.stake-badge {
  display: inline-block; font-size: 0.72rem; font-weight: 600; vertical-align: middle;
  padding: 0.05rem 0.45rem; border-radius: 999px; margin-left: 0.4rem;
  color: var(--accent); border: 1px solid var(--accent); background: var(--accent-dim);
}
.stake-badge.activist { color: #f59e0b; border-color: #f59e0b; background: rgba(245,158,11,0.12); }
.stake-filer { font-weight: 500; }
.stake-form {
  display: inline-block; font-size: 0.7rem; font-weight: 600; font-family: var(--mono);
  padding: 0.02rem 0.4rem; border-radius: 4px; color: var(--text-secondary);
  border: 1px solid var(--border);
}
.stake-form.activist { color: #f59e0b; border-color: #f59e0b; background: rgba(245,158,11,0.10); }
.stake-purpose {
  font-size: 0.68rem; line-height: 1.35; margin-top: 0.15rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 240px;
}

/* ── Filings search tab ──────────────────────────────────────────────────── */
.filing-more-wrap { display: flex; justify-content: center; margin: 1rem 0 0.5rem; }
.filing-more-wrap .btn-ghost { min-width: 160px; }
.filing-more-wrap .btn-ghost.hidden { display: none; }
.control-input[type="date"] { color-scheme: dark; }

/* ── Revenue breakdown (SEC 10-K segments) ──────────────────────────────── */
.segments-panel:empty { display: none; }
.seg-grid { display: flex; flex-direction: column; gap: 0.6rem; }
.seg-section { }
.seg-subhead { font-size: 0.78rem; font-weight: 600; color: var(--text-secondary); margin: 0.2rem 0 0.15rem; }
.seg-flag {
  font-size: 0.64rem; font-weight: 600; color: var(--text-muted); vertical-align: middle;
  padding: 0.02rem 0.36rem; border-radius: 999px; border: 1px solid var(--border); margin-left: 0.3rem;
}
.seg-bar-cell { width: 42%; position: relative; vertical-align: middle; }
.seg-bar { display: inline-block; height: 8px; border-radius: 3px; background: var(--accent); opacity: 0.55; vertical-align: middle; }
.seg-pct { font-size: 0.7rem; color: var(--text-muted); font-family: var(--mono); margin-right: 0.4rem; display: inline-block; min-width: 42px; }

/* ── Reverse DCF (implied-growth lens) ──────────────────────────────────── */
.reverse-dcf-panel:empty { display: none; }
.rdcf-decline { font-size: 0.84rem; color: var(--text-secondary); padding: 0.4rem 0 0.4rem 0.7rem;
                border-left: 3px solid var(--border); line-height: 1.5; margin: 0.2rem 0 0.4rem; }
.rdcf-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.4rem; margin: 0.5rem 0; }
.rdcf-cell { display: flex; flex-direction: column; gap: 0.1rem; background: var(--bg-surface);
             border: 1px solid var(--border); border-radius: 6px; padding: 0.35rem 0.5rem; }
.rdcf-k { font-size: 0.66rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.02em; }
.rdcf-v { font-size: 0.86rem; font-weight: 600; font-family: var(--mono); }
.rdcf-sens { width: 100%; font-size: 0.78rem; margin: 0.25rem 0 0.5rem; border-collapse: collapse; }
.rdcf-sens th, .rdcf-sens td { padding: 0.3rem 0.5rem; text-align: right; border-bottom: 1px solid var(--border); }
.rdcf-sens thead th, .rdcf-sens tbody th { color: var(--text-muted); font-weight: 500; font-family: var(--mono); }
.rdcf-sens td.sorted { background: var(--accent-dim); font-weight: 700; color: var(--accent); }
@media (max-width: 720px) { .rdcf-grid { grid-template-columns: repeat(2, 1fr); } }
.rdcf-note { font-size: 0.72rem; color: var(--text-muted); font-style: italic; margin: 0.15rem 0 0.3rem; line-height: 1.4; }

/* ── Filing tone (finance-lexicon sentiment) ────────────────────────────── */
.filing-tone-panel:empty { display: none; }
.ftone-gauge { margin: 0.35rem 0 0.4rem; }
.ftone-track { position: relative; height: 8px; border-radius: 4px;
               background: linear-gradient(90deg, var(--red-dim), var(--bg-surface), var(--green-dim)); border: 1px solid var(--border); }
.ftone-mark { position: absolute; top: -3px; width: 3px; height: 14px; border-radius: 2px; background: var(--text-secondary); transform: translateX(-50%); }
.ftone-mark.up { background: var(--green); } .ftone-mark.down { background: var(--red); }
.ftone-scale { display: flex; justify-content: space-between; font-size: 0.62rem; margin-top: 0.15rem; }
.ftone-ownhist { font-size: 0.76rem; margin: 0.2rem 0; }
.ftone-dens { display: flex; flex-direction: column; gap: 0.2rem; margin: 0.4rem 0; }
.ftone-drow { display: grid; grid-template-columns: 84px 1fr 48px; align-items: center; gap: 0.4rem; font-size: 0.74rem; }
.ftone-dbar { height: 7px; background: var(--bg-surface); border: 1px solid var(--border); border-radius: 3px; overflow: hidden; }
.ftone-dfill { display: block; height: 100%; background: var(--accent); opacity: 0.6; }
.ftone-dfill.up { background: var(--green); } .ftone-dfill.down { background: var(--red); }
.ftone-dv { text-align: right; color: var(--text-muted); }
.ftone-chips { display: flex; flex-wrap: wrap; gap: 0.3rem; margin-top: 0.35rem; }
.ftone-chip { font-size: 0.68rem; padding: 0.05rem 0.4rem; border: 1px solid var(--border); border-radius: 999px; color: var(--text-secondary); font-family: var(--mono); }

/* ── Fund / ETF holdings (N-PORT) ───────────────────────────────────────── */
.fund-holdings-panel:empty { display: none; }
.fh-asof { display: inline-block; font-size: 0.7rem; font-weight: 600; vertical-align: middle;
           padding: 0.05rem 0.45rem; border-radius: 999px; margin-left: 0.4rem;
           color: var(--accent); border: 1px solid var(--accent); background: var(--accent-dim); }
.fh-short { font-size: 0.62rem; font-weight: 700; color: var(--red); border: 1px solid var(--red);
            border-radius: 3px; padding: 0 0.25rem; margin-left: 0.3rem; }

/* ── BLS inflation & labor ──────────────────────────────────────────────── */
.bls-section:empty { display: none; }
.bls-section { margin-top: 1.2rem; }
.bls-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(150px, 100%), 1fr)); gap: 0.5rem; margin: 0.5rem 0; }
.bls-card { background: var(--bg-surface); border: 1px solid var(--border); border-radius: 8px; padding: 0.5rem 0.6rem; }
.bls-card-k { font-size: 0.68rem; color: var(--text-muted); margin-bottom: 0.15rem; }
.bls-card-v { font-size: 1.1rem; font-weight: 700; font-family: var(--mono); }
.badge-sa, .badge-nsa { font-size: 0.56rem; font-weight: 700; padding: 0 0.25rem; border-radius: 3px; vertical-align: middle; }
.badge-sa { color: var(--text-muted); border: 1px solid var(--border); }
.badge-nsa { color: #f59e0b; border: 1px solid #f59e0b; }

/* Factor Lab — low-coverage warning banner */
.fl-warn {
  background: var(--yellow-dim, rgba(245, 158, 11, 0.12));
  border: 1px solid rgba(245, 158, 11, 0.4);
  color: var(--yellow, #f59e0b);
  border-radius: 6px;
  padding: 0.5rem 0.75rem;
  font-size: 0.8rem;
  margin-bottom: 0.75rem;
}

/* Honest-significance banner under the Factor Lab stats grid. */
.fl-sig {
  border-radius: 6px;
  padding: 0.6rem 0.85rem;
  font-size: 0.82rem;
  line-height: 1.45;
  margin-bottom: 1.25rem;
  border: 1px solid var(--border);
}
.fl-sig-pass { background: rgba(16, 185, 129, 0.10); border-color: rgba(16, 185, 129, 0.4); }
.fl-sig-warn { background: rgba(245, 158, 11, 0.10); border-color: rgba(245, 158, 11, 0.4); }
.fl-sig-fail { background: rgba(239, 68, 68, 0.10); border-color: rgba(239, 68, 68, 0.4); }
.fl-sig-badge { font-weight: 600; }
.fl-sig-pass .fl-sig-badge { color: var(--green, #10b981); }
.fl-sig-warn .fl-sig-badge { color: var(--yellow, #f59e0b); }
.fl-sig-fail .fl-sig-badge { color: var(--red, #ef4444); }
.fl-sig-body { color: var(--text-muted); font-family: var(--mono); font-size: 0.76rem; }
.fl-sig-caveat { color: var(--text-muted); font-style: italic; font-size: 0.72rem; margin-top: 0.35rem; }

/* Survivorship trust-note under the Factor Lab title. */
.fl-survivorship {
  font-size: 0.78rem; line-height: 1.5; color: var(--text-muted);
  background: rgba(59, 130, 246, 0.07); border: 1px solid rgba(59, 130, 246, 0.25);
  border-radius: 6px; padding: 0.6rem 0.85rem; margin: 0.25rem 0 1rem;
}
.fl-survivorship strong { color: var(--text); font-weight: 600; }

/* Composite builder — weight inputs per factor + sector-neutral toggle. */
.fl-composite { margin-bottom: 1rem; padding: 0.85rem 1rem; }
.fl-composite > summary { cursor: pointer; font-weight: 600; font-size: 0.9rem; }
.fl-weights-grid { display: grid; gap: 0.6rem 1rem; grid-template-columns: repeat(auto-fill, minmax(min(180px, 100%), 1fr)); }
.fl-weight { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; font-size: 0.8rem; color: var(--text-muted); }
.fl-weight input { width: 5rem; }
.fl-composite-actions { margin-top: 0.85rem; align-items: center; gap: 1rem; flex-wrap: wrap; }
.fl-checkbox { display: flex; align-items: center; gap: 0.4rem; font-size: 0.82rem; color: var(--text-muted); cursor: pointer; }
.fl-checkbox input { width: auto; }

/* Rebalance log — per-formation holdings count + one-way turnover. */
.fl-rebal-log { margin: 1rem 0 0.5rem; }
.fl-rebal-title { font-size: 0.95rem; margin: 0 0 0.5rem; }
.fl-rebal-table { font-size: 0.8rem; }
.fl-rebal-table td, .fl-rebal-table th { padding: 0.35rem 0.6rem; }

/* ═══════════════════════════════════════════════════════════════════════════
   Responsive — tablet & mobile. Wide data tables stay horizontally scrollable
   inside .table-wrap (overflow-x:auto); everything else reflows to one column,
   tightens padding, and stays touch-friendly. No element should force the page
   wider than the viewport (the tab bar now scrolls, see .tab-bar above).
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Laptop nav fit ───────────────────────────────────────────────────────────
   The bar needs ~1345px to hold all 16 tabs on one row once Commodities is added, so at 1280 and
   1366 — the two most common laptop widths — "News" and "Status" fell to a second row and sat at
   opposite ends of it, which reads as broken rather than as a deliberate second row. Trimming the
   horizontal padding and the group gutters buys ~130px and puts everything back on one line. The
   vertical padding, font size and hit targets are untouched. */
@media (min-width: 641px) and (max-width: 1439px) {
  .tab-bar   { padding: 0 0.75rem; }
  .tab-btn   { padding-left: 0.6rem; padding-right: 0.6rem; }
  .nav-group { margin-left: 0.4rem; padding-left: 0.4rem; }
}

/* Tablet / small laptop */
@media (max-width: 900px) {
  .site-header  { padding: 0.65rem 1rem; }
  .tab-bar      { padding: 0 0.6rem; }
  .main-content { padding: 1rem 1rem; }
}

/* Phone */
@media (max-width: 640px) {
  body { font-size: 13px; }

  /* Header: compact; wrap; drop the non-essential subtitle + refresh note */
  .site-header { flex-wrap: wrap; gap: 0.4rem 0.75rem; padding: 0.55rem 0.8rem; }
  .header-meta { gap: 0.6rem; }
  .header-brand { gap: 0.4rem; }
  .logo-text   { font-size: 1rem; }
  .logo-sub, .refresh-info { display: none; }
  .market-badge { font-size: 0.66rem; padding: 0.2rem 0.45rem; }

  /* Tab bar: WRAP to multiple rows so every tab is visible (no clipped "Fa..." tab) */
  /* Labels are hidden below, so the rail collapses to nothing and the rows close up. */
  .tab-bar { padding: 0.2rem 0.35rem; top: 53px; flex-wrap: wrap; --nav-rail: 0px; }
  .tab-btn { padding: 0.45rem 0.6rem; font-size: 0.8rem; border-bottom-width: 2px; }
  /* Drop the group labels + dividers on mobile. The bar already wraps to three rows here, so
     a floating label would collide with the row above it — and with every group broken across
     lines the label can no longer sit over its own tabs. The accent colour still carries the
     grouping, which is the part that survives the loss of the words. Reclaim the label rail. */
  .nav-group-label { display: none; }
  /* THE GROUP MUST BREAK, NOT JUST THE BAR. .tab-bar wraps, but each .nav-group is `flex: 0 0 auto`
     with no wrapping of its own, so a group is an ATOMIC flex item: "Markets" (Stocks · Heat Map ·
     Sectors · Crypto · Macro · Fuel · Commodities) measured 472px and could not break, forcing the
     document to 477px against a 390px viewport — every tab overflowed, including Overview, because
     the culprit is the nav rather than any panel. Wrapping inside the group is invisible here: the
     labels and dividers are already dropped above, so the tabs simply join the bar's own wrap. */
  /* flex-wrap ALONE DOES NOTHING HERE. The group is `flex: 0 0 auto` with the default
     `min-width: auto`, so it sizes to max-content and cannot shrink — and a flex container only
     wraps once its width is actually constrained. It must be given a width it can be held to:
     `flex: 1 1 100%` puts each group on its own row and `min-width: 0` lets it be narrower than
     its content, at which point the buttons inside finally break across lines. */
  .nav-group { border-left: none; margin-left: 0; padding-left: 0;
               flex-wrap: wrap; row-gap: 2px; flex: 1 1 100%; min-width: 0; }
  .tab-btn.tab-news { border-left: none; margin-left: 0; padding-left: 0.6rem; }
  .tab-btn.tab-system { margin-left: 0; }

  /* Content + section headings */
  .main-content { padding: 0.8rem 0.65rem; }
  h2 { font-size: 1.1rem; }
  .tab-title { font-size: 1.05rem; }

  /* Tables: denser cells (the wrapper scrolls horizontally for wide tables) */
  .data-table th, .data-table td { padding: 0.4rem 0.5rem; font-size: 0.78rem; }
  .data-table td.num, .data-table td.symbol-cell { font-size: 0.76rem; }
  .table-wrap { -webkit-overflow-scrolling: touch; }

  /* Cards & chart cards: less chrome */
  .card { padding: 0.85rem 0.85rem; margin-bottom: 0.9rem; }
  .chart-wrap    { height: 200px; padding: 0.5rem 0.6rem; }
  .chart-wrap-sm { height: 150px; }
  .chart-card-header { padding: 0.5rem 0.7rem; }

  /* Force the remaining fixed / multi-column grids to a single column */
  .indicators-row, .macro-charts-grid, .rdcf-grid { grid-template-columns: 1fr !important; }

  /* Controls: each control on its own full-width row + full-width button */
  .control-row { gap: 0.6rem; }
  .control-group { flex: 1 1 100%; }
  .control-group .control-input, .control-group select, .control-group input { width: 100%; }
  .control-group-btn { flex: 1 1 100%; }
  .control-group-btn .btn-primary { width: 100%; }

  /* KPI / stat numbers: a touch smaller so they don't dominate */
  .kpi-value { font-size: 1.3rem; }
  .bt-stat-value { font-size: 1.05rem; }

  /* Filing rows: shrink the fixed date/form columns so the title keeps room */
  .filing-row { grid-template-columns: 52px 78px 1fr; gap: 0.5rem; font-size: 0.78rem; }

  /* Fundamentals header: let the title/badge/source-caption wrap to their own lines
     instead of laddering the caption into 1-3 word fragments in a squeezed flex item. */
  .fund-header { flex-wrap: wrap; gap: 0.3rem 0.6rem; }

  /* Primary data tables: hide low-priority columns so the ESSENTIAL columns fit on a phone
     without horizontal scrolling (the key data is never clipped at rest). Swipe still reveals
     nothing hidden — these columns are simply dropped on small screens.
       Stocks  (1 SYMBOL, 2 COMPANY, 3 PRICE, 4 CHANGE, 5 CHANGE%, 6-10 OHLC/prev/updated):
               keep SYMBOL + PRICE + CHANGE + CHANGE%; drop COMPANY + OHLC/prev/updated.
       Crypto  (1 #, 2 Coin, 3 Price, 4 1h%, 5 24h%, 6 7d%, 7 MktCap, 8 Vol, 9 Supply):
               keep Coin + Price + 24h%; drop the rank, 1h%, 7d%, cap, volume, supply. */
  #tab-stocks .data-table th:nth-child(2), #tab-stocks .data-table td:nth-child(2),
  #tab-stocks .data-table th:nth-child(n+6), #tab-stocks .data-table td:nth-child(n+6) { display: none; }
  #tab-crypto .data-table th:nth-child(1), #tab-crypto .data-table td:nth-child(1),
  #tab-crypto .data-table th:nth-child(4), #tab-crypto .data-table td:nth-child(4),
  #tab-crypto .data-table th:nth-child(n+6), #tab-crypto .data-table td:nth-child(n+6) { display: none; }

  /* Factor Lab subtitle: smaller so it doesn't orphan a single word onto a second line */
  #tab-factorlab .tab-title span { font-size: 0.7rem; }
}

/* ── Signals tab: responsive grid of signal cards ──────────────────────────── */
.signals-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(360px, 100%), 1fr));
  gap: 16px;
  align-items: start;
}
/* min-width:0 — a grid item's default `auto` minimum is its CONTENT's min-content width, so a wide
   inner table drags the whole track past the viewport even when the grid is a single 1fr column. */
.signal-card { padding: 14px 16px; min-width: 0; }
.signal-card .table-wrap, .signal-card .data-table { max-width: 100%; }
.signal-card-title { margin: 0 0 10px; font-size: 0.95rem; }
.signal-card-note { margin-top: 8px; line-height: 1.4; }
.signal-card .data-table td, .signal-card .data-table th { padding: 5px 8px; }
@media (max-width: 640px) { .signals-grid { grid-template-columns: 1fr; } }

/* ═══════════════════════════ NEWS TAB ═══════════════════════════════════════ */
.news-controls {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 0.75rem; margin-bottom: 1rem;
}
.chip-row { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.chip {
  padding: 0.32rem 0.7rem; border: 1px solid var(--border); border-radius: 999px;
  background: var(--bg-surface); color: var(--text-secondary);
  font-size: 0.8rem; font-weight: 500; cursor: pointer; transition: color .12s ease, border-color .12s ease, background .12s ease, transform .08s ease;
}
.chip:hover { color: var(--text-primary); border-color: var(--text-muted); }
.chip.active { background: var(--accent-dim); color: var(--text-primary); border-color: var(--accent); }
.news-controls-right { display: flex; align-items: center; gap: 0.6rem; }
.news-toggle {
  display: inline-flex; align-items: center; gap: 0.35rem;
  font-size: 0.8rem; color: var(--text-secondary); cursor: pointer; user-select: none; white-space: nowrap;
}
.news-toggle input { accent-color: var(--accent); cursor: pointer; }
.news-ticker-input {
  padding: 0.4rem 0.65rem; border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--bg-surface); color: var(--text-primary);
  font-size: 0.8rem; font-family: var(--mono); width: 180px; max-width: 42vw;
}
.news-ticker-input:focus { outline: none; border-color: var(--accent); }

.news-list { display: flex; flex-direction: column; gap: 0.55rem; }
.news-item {
  background: var(--bg-card); border: 1px solid var(--border-dim);
  border-left: 3px solid var(--border); border-radius: var(--radius-sm);
  padding: 0.7rem 0.9rem; transition: border-color 0.12s ease, background 0.12s ease;
}
.news-item:hover { background: var(--bg-elevated); border-left-color: var(--text-muted); }
.news-item.news-imp-high { border-left-color: var(--red); }

.news-meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem;
  font-size: 0.72rem; color: var(--text-muted); margin-bottom: 0.3rem;
}
.news-sec {
  text-transform: uppercase; letter-spacing: 0.04em; font-weight: 700; font-size: 0.66rem;
  padding: 0.1rem 0.42rem; border-radius: 4px; background: var(--bg-hover); color: var(--text-secondary);
}
.news-sec-macro    { background: rgba(139, 92, 246, 0.15); color: #b9a3f5; }
.news-sec-earnings { background: var(--green-dim);  color: var(--green); }
.news-sec-ma       { background: var(--yellow-dim); color: var(--yellow); }
.news-sec-company  { background: var(--accent-dim); color: #7cb0f7; }
.news-sec-filings  { background: var(--bg-hover);   color: var(--text-secondary); }
.news-sec-signals  { background: rgba(20, 184, 166, 0.16); color: #5eead4; }   /* Blueprint own-analytics */
.news-sec-market   { background: rgba(129, 140, 248, 0.15); color: #a5b4fc; }   /* GDELT market-news breadth */
.news-attribution { margin-top: 1rem; padding-top: 0.6rem; border-top: 1px solid var(--border-dim); line-height: 1.5; }
.news-attribution a { color: var(--accent); text-decoration: none; }
.news-attribution a:hover { text-decoration: underline; }
.news-breaking { color: var(--red); font-size: 0.6rem; line-height: 1; animation: newsPulse 2s ease-in-out infinite; }
@keyframes newsPulse { 0%,100% { opacity: 1; } 50% { opacity: 0.35; } }
.news-time { font-family: var(--mono); }
.news-src  { color: var(--text-secondary); }
.news-tkr {
  font-family: var(--mono); font-weight: 600; font-size: 0.68rem;
  padding: 0.05rem 0.35rem; border-radius: 4px;
  background: var(--accent-dim); color: #7cb0f7; border: 1px solid var(--border);
  cursor: pointer; transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}
.news-tkr:hover { background: var(--accent); color: #fff; border-color: var(--accent); }
.news-title { font-size: 0.94rem; font-weight: 600; line-height: 1.35; margin: 0.1rem 0; }
.news-title a { color: var(--text-primary); text-decoration: none; }
.news-title a:hover { color: var(--accent); text-decoration: underline; }
.news-summary { font-size: 0.82rem; color: var(--text-secondary); line-height: 1.45; margin: 0.25rem 0 0; }
.news-more-wrap { display: flex; justify-content: center; margin-top: 1rem; }

@media (max-width: 640px) {
  .news-controls { flex-direction: column; align-items: stretch; }
  /* The control cluster could not WRAP — only its parent could — so toggle + input + buttons
     stayed on one 495px line and pushed the page. */
  .news-controls-right { justify-content: space-between; flex-wrap: wrap; row-gap: 0.5rem; }
  .news-left { min-width: 0; }
  #newsSections.chip-row { min-width: 0; }
  .news-ticker-input { flex: 1; width: auto; max-width: none; }
}

/* ─── Per-ticker news on the stock detail panel ─── */
.stock-news-panel { margin-top: 1rem; }
.stock-news-list { display: flex; flex-direction: column; gap: 0.3rem; margin-bottom: 0.4rem; }
.stock-news-item {
  display: flex; align-items: baseline; gap: 0.5rem;
  padding: 0.3rem 0; border-bottom: 1px solid var(--border-dim);
}
.stock-news-item:last-child { border-bottom: none; }
.stock-news-item .news-time { color: var(--text-muted); font-size: 0.72rem; white-space: nowrap; }
.stock-news-title { font-size: 0.82rem; line-height: 1.35; flex: 1; }
.stock-news-title a { color: var(--text-primary); text-decoration: none; }
.stock-news-title a:hover { color: var(--accent); text-decoration: underline; }
.stock-news-all { display: inline-block; font-size: 0.76rem; color: var(--accent); text-decoration: none; }
.stock-news-all:hover { text-decoration: underline; }

/* Watchlist quick-filter button — active state */
#newsWatchlist { white-space: nowrap; }
#newsWatchlist.active { background: var(--accent-dim); color: var(--text-primary); border-color: var(--accent); }

/* News Top/Latest mode toggle */
.news-left { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
.news-mode { display: inline-flex; border: 1px solid var(--border); border-radius: 999px; overflow: hidden; flex: 0 0 auto; }
.news-mode-btn {
  padding: 0.32rem 0.8rem; background: var(--bg-surface); color: var(--text-secondary);
  border: none; font-size: 0.8rem; font-weight: 600; cursor: pointer; transition: background 0.12s, color 0.12s;
}
.news-mode-btn:hover { color: var(--text-primary); }
.news-mode-btn.active { background: var(--accent); color: #fff; }

/* Upcoming economic-calendar strip (News tab) */
.news-calendar { display: flex; gap: 0.4rem; align-items: center; overflow-x: auto; padding-bottom: 0.5rem; margin-bottom: 0.75rem; scrollbar-width: thin; }
.news-calendar:empty { display: none; }
.news-cal-label { font-size: 0.74rem; font-weight: 700; color: var(--text-secondary); white-space: nowrap; flex: 0 0 auto; letter-spacing: 0.02em; }
.news-cal-item {
  flex: 0 0 auto; font-size: 0.74rem; padding: 0.25rem 0.6rem; border-radius: 999px;
  background: var(--bg-card); border: 1px solid var(--border-dim); border-left: 3px solid var(--text-muted);
  color: var(--text-secondary); white-space: nowrap;
}
.news-cal-item .news-cal-date { font-family: var(--mono); color: var(--text-primary); font-weight: 600; }
.news-cal-high { border-left-color: var(--red); }
.news-cal-med  { border-left-color: var(--yellow); }

/* ═══════════════════════════ HEAT MAP TAB ═══════════════════════════════════ */
.heatmap-bar { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: 0.6rem; flex-wrap: wrap; }
.heatmap-legend { display: inline-flex; align-items: center; gap: 0.5rem; }
.hm-leg-txt { font-size: 0.72rem; color: var(--text-muted); font-family: var(--mono); }
.hm-leg-grad { width: 120px; height: 10px; border-radius: 3px; border: 1px solid var(--border);
  background: linear-gradient(to right, #ef4444, #2a3441, #10b981); }

.heatmap-container { position: relative; width: 100%; border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: hidden; background: var(--bg-base); }
.hm-tile {
  position: absolute; box-sizing: border-box; border: 1px solid rgba(8, 12, 20, 0.55);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  overflow: hidden; cursor: pointer; color: #f2f6fc; line-height: 1.1; text-align: center;
  transition: outline 0.08s ease;
}
.hm-tile:hover { outline: 2px solid #fff; outline-offset: -2px; z-index: 5; }
.hm-sym { font-weight: 700; font-size: clamp(0.6rem, 1.2vw, 0.92rem); letter-spacing: -0.01em; text-shadow: 0 1px 2px rgba(0,0,0,0.4); }
.hm-chg { font-size: clamp(0.52rem, 0.9vw, 0.74rem); font-family: var(--mono); opacity: 0.92; text-shadow: 0 1px 2px rgba(0,0,0,0.4); }
.hm-sector-label {
  position: absolute; font-size: 0.68rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
  color: rgba(255,255,255,0.82); background: rgba(8,12,20,0.35); padding: 0.05rem 0.3rem; border-radius: 3px;
  pointer-events: none; z-index: 4; text-shadow: 0 1px 2px rgba(0,0,0,0.6);
  /* never spill onto neighbouring sectors: clamp to the sector rect (inline max-width) + ellipsis */
  box-sizing: border-box; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.hm-sector-label.hm-sector-link { pointer-events: auto; cursor: pointer; color: #fff; }
.hm-sector-label.hm-sector-link:hover { background: rgba(59,130,246,.55); }

/* ═══════════════════════════ SECTORS HUB ═══════════════════════════════════════ */
.sector-picker { display: flex; align-items: center; flex-wrap: wrap; gap: .5rem; margin: 0 0 var(--space-4); }
.sector-head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; margin-bottom: var(--space-3); }
.sector-head h3 { font-size: var(--fs-lg); font-weight: 600; }
.sector-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(360px, 100%), 1fr)); gap: var(--space-4); }
.sector-card { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: var(--space-4); box-shadow: var(--elev-1); min-width: 0; }
.sector-card-wide { grid-column: 1 / -1; }
.sector-card h4 { font-size: var(--fs-md); font-weight: 600; margin-bottom: var(--space-3); }

/* EIA fundamentals — inventory cells with a 5-yr seasonal band */
.eia-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(200px, 100%), 1fr)); gap: var(--space-3); }
.eia-cell { background: var(--bg-elevated); border: 1px solid var(--border-dim); border-radius: var(--radius); padding: var(--space-3); }
.eia-cell-head { display: flex; align-items: baseline; justify-content: space-between; gap: .5rem; }
.eia-cell-lbl { font-size: var(--fs-2xs); text-transform: uppercase; letter-spacing: .04em; color: var(--text-muted); }
.eia-cell-wow { font-family: var(--mono); font-size: var(--fs-2xs); font-variant-numeric: tabular-nums; }
.eia-cell-val { font-family: var(--mono); font-size: 1.15rem; font-weight: 700; color: var(--text-primary); margin: .15rem 0 .35rem; font-variant-numeric: tabular-nums; }
.eia-band-track { position: relative; height: 5px; border-radius: 3px; background: linear-gradient(90deg, var(--bg-hover), var(--border-bright)); }
.eia-band-avg { position: absolute; top: -2px; width: 1px; height: 9px; background: var(--text-faint); }
.eia-band-mark { position: absolute; top: -3px; width: 9px; height: 11px; border-radius: 2px; transform: translateX(-50%); background: var(--accent); box-shadow: 0 0 0 2px var(--bg-elevated); }
.eia-band-mark.up { background: var(--green); } .eia-band-mark.down { background: var(--red); }
.eia-band-lbl { display: block; font-size: 9.5px; margin-top: .25rem; }
.up  .eia-cell-wow, .eia-cell-wow.up  { color: var(--green); }
.down .eia-cell-wow, .eia-cell-wow.down { color: var(--red); }

/* SEC-event signal roll-up */
.sig-roll-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(200px, 100%), 1fr)); gap: var(--space-3); }
.sig-roll { background: var(--bg-elevated); border: 1px solid var(--border-dim); border-radius: var(--radius); padding: var(--space-3); }
.sig-roll-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: .35rem; font-size: var(--fs-xs); color: var(--text-secondary); font-weight: 600; }
.sig-roll-count { font-family: var(--mono); font-size: var(--fs-sm); font-weight: 700; color: var(--text-faint); background: var(--bg-hover); border-radius: 999px; min-width: 22px; text-align: center; padding: 0 .35rem; }
.sig-roll-count.on { color: var(--accent); background: var(--accent-dim); }
.sig-roll-names { display: flex; flex-direction: column; gap: .25rem; font-size: var(--fs-xs); }

/* COT positioning */
.pos-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(150px, 100%), 1fr)); gap: var(--space-3); }
.pos-cell { background: var(--bg-elevated); border: 1px solid var(--border-dim); border-radius: var(--radius); padding: var(--space-3); }
.pos-lbl { font-size: var(--fs-2xs); text-transform: uppercase; letter-spacing: .04em; color: var(--text-muted); }
.pos-net { font-family: var(--mono); font-size: 1.25rem; font-weight: 700; font-variant-numeric: tabular-nums; margin: .1rem 0; }
.pos-sub { font-size: 10px; font-family: var(--mono); }

/* Factor leaderboard */
.fb-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(150px, 100%), 1fr)); gap: var(--space-3); }
.fb-head { font-size: var(--fs-2xs); text-transform: uppercase; letter-spacing: .04em; color: var(--text-muted); margin-bottom: .35rem; }
.fb-row { display: flex; align-items: center; gap: .4rem; font-size: var(--fs-xs); padding: .12rem 0; }
.fb-rank { font-family: var(--mono); color: var(--text-faint); width: 1rem; }
.fb-pct { margin-left: auto; font-family: var(--mono); font-size: 10px; }

.sc-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(220px, 100%), 1fr)); gap: .1rem .9rem; }
.sc-row { display: flex; align-items: center; gap: .45rem; font-size: var(--fs-xs); padding: .16rem 0; border-bottom: 1px solid var(--border); }
.sc-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sc-cap { font-family: var(--mono); font-size: 10px; }
.sc-chg { margin-left: auto; font-family: var(--mono); font-variant-numeric: tabular-nums; }   /* .up/.down colored globally */

/* Health-Care hub: kind badges, priority/why chips, therapeutic-area pipeline table */
.hc-kind { font-family: var(--mono); font-size: 9px; font-weight: 700; padding: .05rem .3rem; border-radius: 3px; letter-spacing: .03em; flex: 0 0 auto; background: var(--bg-elevated); border: 1px solid var(--border); }
.hc-bio, .hc-p1 { color: #a855f7; border-color: #a855f755; }
.hc-dru, .hc-p2 { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 40%, transparent); }
.hc-gen, .hc-p3, .hc-na { color: var(--text-muted); }
.hc-classI { color: var(--red); border-color: var(--red); font-weight: 700; }
.hc-classII { color: var(--text-muted); }
.hc-prio { font-family: var(--mono); font-size: 9px; font-weight: 700; color: var(--green); border: 1px solid color-mix(in srgb, var(--green) 40%, transparent); border-radius: 3px; padding: .02rem .25rem; flex: 0 0 auto; }
.hc-why { flex: 1 1 auto; font-style: italic; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hc-table-wrap { overflow-x: auto; }
.hc-table { width: 100%; border-collapse: collapse; font-size: var(--fs-xs); font-variant-numeric: tabular-nums; }
.hc-table th { text-align: right; font-weight: 600; color: var(--text-muted); font-size: var(--fs-2xs); text-transform: uppercase; letter-spacing: .03em; padding: .25rem .5rem; border-bottom: 1px solid var(--border); }
.hc-table th:first-child, .hc-table td.hc-area { text-align: left; }
.hc-table td { text-align: right; padding: .22rem .5rem; font-family: var(--mono); border-bottom: 1px solid var(--border); }
.hc-table td.hc-area { font-family: var(--font); font-weight: 600; }
.hc-table td.hc-new { color: var(--green); }
.hc-table td.down { color: var(--red); }

/* Utilities hub: generation fuel-mix stacked bar + legend + sparklines */
.u-stack { display: flex; width: 100%; height: 26px; border-radius: var(--radius); overflow: hidden; border: 1px solid var(--border); }
.u-seg { height: 100%; }
.u-legend { display: flex; flex-wrap: wrap; gap: .1rem .9rem; margin-top: .5rem; }
.u-leg { font-size: var(--fs-xs); display: inline-flex; align-items: center; gap: .3rem; }
.u-dot { width: 9px; height: 9px; border-radius: 2px; display: inline-block; }
.u-ren { display: flex; align-items: center; gap: .5rem; margin-top: .5rem; }
.u-ren-spark { color: var(--green); width: 120px; height: 24px; flex: 0 0 auto; }
.u-spark { width: 100%; height: 24px; display: block; }
.u-metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr)); gap: var(--space-3); margin-top: var(--space-3); }
.u-metric { display: flex; flex-direction: column; gap: .1rem; background: var(--bg-elevated); border: 1px solid var(--border-dim); border-radius: var(--radius); padding: var(--space-3); color: var(--text-muted); }
.u-metric-lbl { font-size: var(--fs-2xs); text-transform: uppercase; letter-spacing: .04em; }
.u-metric-val { font-family: var(--mono); font-size: 1.15rem; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }

/* Consumer Staples hub: the margin/pass-through spread hero */
.u-hero { border-left: 3px solid var(--accent); }
.ms-hero { display: flex; align-items: baseline; gap: .9rem; flex-wrap: wrap; margin: .3rem 0 .2rem; }
.ms-val { font-family: var(--mono); font-size: 1.9rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.ms-verdict { font-size: var(--fs-sm); font-weight: 600; }
.ms-spark { width: 130px; height: 26px; margin-left: auto; flex: 0 0 auto; }
.ms-val.up, .ms-verdict.up, .ms-spark.up { color: var(--green); }
.ms-val.down, .ms-verdict.down, .ms-spark.down { color: var(--red); }

/* Industrials hub: federal-awards rows */
.fa-list .sc-row { gap: .5rem; }
.fa-recip { font-size: var(--fs-xs); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fa-list .sc-name { margin-left: auto; }
.fa-list .sc-chg { margin-left: .4rem; min-width: 4rem; text-align: right; font-weight: 600; }

/* Communication Services hub: revenue-shift ranked bars */
.cs-grid { display: flex; flex-direction: column; gap: .15rem; margin-top: .45rem; }
.cs-row { display: flex; align-items: center; gap: .6rem; font-size: var(--fs-xs); padding: .12rem 0; }
.cs-sub { flex: 0 0 46%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cs-bar { flex: 1 1 auto; height: 7px; background: color-mix(in srgb, var(--fg) 8%, transparent); border-radius: 4px; overflow: hidden; }
.cs-bar-fill { display: block; height: 100%; border-radius: 4px; }
.cs-bar-fill.up { background: var(--green); }
.cs-bar-fill.down { background: var(--red); }
.cs-yoy { flex: 0 0 3.4rem; text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; font-weight: 600; }
.cs-price { margin-right: .8rem; font-size: var(--fs-xs); white-space: nowrap; }

/* Theme picker (cross-sector hubs) — visually distinct from the sector row so the two are never confused. */
.theme-picker { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; margin-bottom: .5rem; }
.picker-label { font-size: var(--fs-2xs); text-transform: uppercase; letter-spacing: .05em; color: var(--text-muted); margin-right: .35rem; }
.chip-theme { border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); }
.chip-theme.active { background: color-mix(in srgb, var(--accent) 18%, transparent); border-color: var(--accent); }
.theme-disclosure { font-size: var(--fs-2xs); color: var(--text-muted); font-style: italic; line-height: 1.45;
  margin: .1rem 0 .6rem; padding-left: .6rem; border-left: 2px solid color-mix(in srgb, var(--accent) 40%, transparent); }
.tc-two { display: grid; grid-template-columns: 1fr 1fr; gap: .2rem 1.6rem; margin-top: .5rem; }
@media (max-width: 640px) { .tc-two { grid-template-columns: 1fr; } }

/* Technology hub: exploitation-pressure rows + federal IT flow.
   NOTE the INVERTED polarity — on the pressure card, UP IS BAD. A vendor above its own run-rate is `hot`
   (red); below it is `cool`. Do not reuse the .cs-bar-fill.up{green} semantics here. */
.tc-grid { display: flex; flex-direction: column; gap: .15rem; margin-top: .45rem; }
.tc-row { display: flex; align-items: center; gap: .6rem; font-size: var(--fs-xs); padding: .14rem 0; }
.tc-sym { flex: 0 0 3.6rem; }
.tc-bar { flex: 0 1 22%; height: 7px; background: color-mix(in srgb, var(--fg) 8%, transparent); border-radius: 4px; overflow: hidden; }
.tc-bar-fill { display: block; height: 100%; border-radius: 4px; }
.tc-bar-fill.hot { background: var(--red); }
.tc-bar-fill.cool { background: color-mix(in srgb, var(--green) 70%, transparent); }
.tc-val { flex: 0 0 3.2rem; text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; font-weight: 700; }
.tc-meta { flex: 1 1 auto; font-size: var(--fs-2xs); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Chip rows (prices, employment, trade, resellers). The chips are individually nowrap so a figure never
   splits across lines — which means the ROW must wrap, or a long label ("CDW Government: $274.36M") drags
   the whole page into horizontal scroll. */
.tc-chips { display: flex; flex-wrap: wrap; gap: .1rem .9rem; margin-top: .1rem; }
.tc-chips .cs-price { margin-right: 0; }
.tc-buckets { margin-top: .6rem; display: flex; flex-direction: column; gap: .3rem; }
.tc-bucket { font-size: var(--fs-2xs); line-height: 1.45; }
.tc-bucket-h { display: inline-block; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; font-size: var(--fs-2xs);
  color: var(--text-muted); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 0 .3rem; margin-right: .35rem; }
/* Federal IT rows are 4-column (ticker + prior FY + FY-to-date + run-rate), so they need the FULL card width.
   Putting them in the multi-column .sc-list grid squeezed each row into a ~240px cell and pushed the page into
   horizontal scroll at tablet widths. */
.fi-list { display: flex; flex-direction: column; gap: .05rem; }
.fi-row { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; font-size: var(--fs-xs); padding: .16rem 0; }
.fi-amt { margin-left: auto; font-family: var(--mono); font-variant-numeric: tabular-nums; font-weight: 600; }
.fi-cur { min-width: 6.5rem; text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; }
.fi-rr { min-width: 5.5rem; text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; font-weight: 600; }
@media (max-width: 640px) {
  .tc-sym { flex: 0 0 3rem; }
  .tc-meta { display: none; }                 /* the ratio + bar carry the read on a phone; the detail line would wrap and overflow */
  .fi-cur, .fi-rr { min-width: 0; }
}

/* Materials hub: mineral supply-security grid + cohort exposure */
.mm-grid { display: grid; grid-template-columns: 1fr 1fr; gap: .1rem .9rem; margin-top: .4rem; }
@media (max-width: 640px) { .mm-grid { grid-template-columns: 1fr; } }
.mm-row { display: flex; align-items: baseline; gap: .5rem; padding: .22rem 0; border-bottom: 1px solid var(--border); font-size: var(--fs-xs); }
.mm-name { font-weight: 600; flex: 1 1 40%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mm-crit { color: var(--amber, #d98324); margin-left: .2rem; }
/* An as-of stamp that has aged past what its source's cadence should allow. Amber, not red: the number
   is not wrong, it is old — and the reader has to be able to tell those apart. */
.stale-warn { color: var(--amber, #d98324) !important; font-weight: 600; }

/* Marks a composite whose weights were re-normalised over fewer legs than the full recipe — it is not on
   the same scale as its neighbours in the column, and a sortable column will otherwise rank them as if
   it were. Quiet: a caveat, not an error. */
.q-partial { color: var(--amber, #d98324); margin-left: .25rem; font-weight: 700; cursor: help; }

/* The OTHER names on a filing. On a 13D the issuer is display_names[0] and the activist is [1] — so a
   search for the activist returned rows that never mentioned them. The co-filer is now on the row. */
.filing-cofiler { color: var(--accent); font-size: var(--fs-2xs); cursor: help; }

/* The tab-level "How to read it" — the same .read-as block the hub cards use, lifted to the top of a tab
   that has no single hero card to hang it on. Sits under the .hub-brief, above the content. */
.tab-readas { margin: -.35rem 0 1rem; max-width: 92ch; }
.tab-readas .read-as { font-size: var(--fs-xs); }

/* A macro print has no good direction. Rising inflation and rising unemployment are not "up" in the sense
   the price tiles mean by it, and colouring them green because the number went up borrows a convention
   that does not apply. The arrow states the direction; the colour states nothing. (This is the same rule
   the BLS section already followed — the FRED grid was the one contradicting it.) */
.kpi-delta-neutral { color: var(--text-muted); font-weight: 600; }

/* A one-line footer under an Overview card saying what window/source the numbers above came from. Two
   cards on that page showed the same tickers over different windows from different feeds, and neither
   said so — so the same ticker could be green in one and red in the other, one panel apart. */
.ov-card-foot { margin: .5rem 0 0; padding-top: .45rem; border-top: 1px solid var(--border-dim);
  font-size: var(--fs-2xs); line-height: 1.45; color: var(--text-faint); }
.mm-nir { font-family: var(--mono); font-variant-numeric: tabular-nums; flex: 0 0 auto; }
.mm-src { flex: 0 0 auto; text-align: right; min-width: 6.5rem; }
.mm-src.mm-cn { color: var(--red); font-weight: 600; }
.mm-exp-row { gap: .5rem; align-items: baseline; }
.mm-exp { font-size: var(--fs-xs); margin-left: .3rem; }
.mm-cn-dot { color: var(--red); font-weight: 700; font-size: .64rem; border: 1px solid var(--red); border-radius: 3px; padding: 0 .18rem; }

/* Consumer Discretionary hub: auto safety-pressure rows */
.as-row { gap: .5rem; align-items: baseline; }
.as-count { font-family: var(--mono); font-weight: 700; font-variant-numeric: tabular-nums; min-width: 5.2rem; }
.as-sevwrap { display: inline-flex; gap: .3rem; flex-wrap: wrap; }
.as-sev { font-size: var(--fs-xs); font-weight: 700; padding: .04rem .34rem; border-radius: 999px; white-space: nowrap; }
.as-dnd { background: color-mix(in srgb, var(--red) 18%, transparent); color: var(--red); }
.as-fire { background: color-mix(in srgb, var(--amber, #d98324) 20%, transparent); color: var(--amber, #d98324); }
.as-units { font-size: var(--fs-xs); font-variant-numeric: tabular-nums; }
.as-row .sc-name { margin-left: auto; max-width: 12rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* FDIC banking-health failures strip */
.bank-fails { margin-top: var(--space-3); }
.bank-fail-row { display: flex; align-items: baseline; gap: .5rem; font-size: var(--fs-xs); padding: .18rem 0; border-bottom: 1px solid var(--border); }
.bf-name { font-weight: 600; }
.bf-loc { flex: 0 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bf-date { margin-left: auto; font-family: var(--mono); font-size: 10px; }
.bf-assets { font-family: var(--mono); font-variant-numeric: tabular-nums; min-width: 4.5rem; text-align: right; }

@media (max-width: 640px) { .sector-grid { grid-template-columns: 1fr; } .pos-grid { grid-template-columns: 1fr; } .sc-list { grid-template-columns: 1fr; } }

/* ═══════════════════════════ OVERVIEW (landing) ═══════════════════════════════ */
.ov-hero { margin-bottom: var(--space-5); }
.ov-title { font-size: var(--fs-xl); font-weight: 600; letter-spacing: -0.01em; margin-bottom: var(--space-1); }

/* Market pulse — KPI tile row */
.ov-pulse { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(150px, 100%), 1fr)); gap: var(--space-3); margin-bottom: var(--space-5); }
.ov-kpi {
  display: flex; flex-direction: column; gap: var(--space-1); text-align: left;
  background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius-lg);
  padding: var(--space-4); box-shadow: var(--elev-1); font-family: inherit;
}
button.ov-kpi { cursor: pointer; transition: transform 0.12s ease, border-color 0.12s ease, box-shadow 0.12s ease; }
button.ov-kpi:hover { transform: translateY(-1px); border-color: var(--border-bright); box-shadow: var(--elev-2); }
.ov-kpi-label { font-size: var(--fs-2xs); text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-muted); }
.ov-kpi-value { font-size: var(--fs-xl); font-weight: 600; font-variant-numeric: tabular-nums; }
.ov-kpi-sub { font-size: var(--fs-2xs); color: var(--text-muted); font-family: var(--mono); }

/* Card grid */
.ov-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-4); }
.ov-card { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: var(--space-4); box-shadow: var(--elev-1); display: flex; flex-direction: column; min-width: 0; }
.ov-card-head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: var(--space-3); }
.ov-card-head h3 { font-size: var(--fs-md); font-weight: 600; }
.ov-more { font-size: var(--fs-xs); color: var(--accent); text-decoration: none; white-space: nowrap; }
.ov-more:hover { text-decoration: underline; }

/* Movers */
.ov-movers { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4); }
.ov-mover-col { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.ov-mover-hd { font-size: var(--fs-2xs); text-transform: uppercase; letter-spacing: 0.05em; font-weight: 700; margin-bottom: var(--space-1); }
.ov-mover-hd.up { color: var(--green); } .ov-mover-hd.down { color: var(--red); }
.ov-mover { position: relative; display: flex; align-items: baseline; gap: var(--space-2); padding: var(--space-2); border-radius: var(--radius-sm); background: none; border: none; cursor: pointer; text-align: left; font-family: inherit; transition: background 0.1s ease; }
.ov-mover:hover { background: var(--bg-hover); }
/* Relative-magnitude underline (same language as the stocks-table Change% track) */
.ov-mover-bar { position: absolute; left: var(--space-2); bottom: 1px; height: 2px; border-radius: 1px; opacity: 0.45; pointer-events: none; }
.ov-mover-bar.up { background: var(--green); } .ov-mover-bar.down { background: var(--red); }
.ov-mover-sym { font-family: var(--mono); font-weight: 600; font-size: var(--fs-sm); color: var(--text-primary); }
.ov-mover-name { flex: 1; font-size: var(--fs-xs); color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ov-mover-chg { font-family: var(--mono); font-size: var(--fs-xs); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Mini heat map */
.ov-heatmap { position: relative; width: 100%; min-height: 240px; border-radius: var(--radius-sm); overflow: hidden; }

/* Compact news rows */
.ov-newslist { display: flex; flex-direction: column; }
.ov-news-item { display: flex; align-items: baseline; gap: var(--space-2); padding: var(--space-2) 0; border-bottom: 1px solid var(--border-dim); }
.ov-news-item:last-child { border-bottom: none; }
.ov-news-title { flex: 1; font-size: var(--fs-sm); line-height: 1.35; min-width: 0; }
.ov-news-title a { color: var(--text-primary); text-decoration: none; }
.ov-news-title a:hover { color: var(--accent); text-decoration: underline; }
.ov-news-time { font-size: var(--fs-2xs); color: var(--text-muted); font-family: var(--mono); white-space: nowrap; }

@media (max-width: 900px) {
  .ov-grid { grid-template-columns: 1fr; }
}

/* ── Command palette (⌘/Ctrl-K) — jump to any ticker or section from anywhere ── */
.cmdk {
  position: fixed; inset: 0; z-index: 200;
  display: flex; justify-content: center; align-items: flex-start;
  padding-top: 12vh;
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(2px);
}
.cmdk.hidden { display: none; }
.cmdk-panel {
  width: min(560px, 92vw);
  background: var(--bg-card);
  border: 1px solid var(--border-bright);
  border-radius: var(--radius-lg);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
  overflow: hidden;
}
.cmdk-input {
  width: 100%; box-sizing: border-box;
  background: transparent; border: none; border-bottom: 1px solid var(--border);
  color: var(--text-primary); font-family: var(--font); font-size: var(--fs-lg);
  padding: var(--space-4); outline: none;
}
.cmdk-input::placeholder { color: var(--text-faint); }
.cmdk-results { max-height: 46vh; overflow-y: auto; padding: var(--space-2); }
.cmdk-item {
  display: flex; align-items: baseline; gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm); cursor: pointer;
}
.cmdk-item.active { background: var(--accent-dim); }
.cmdk-kind  { font-size: var(--fs-2xs); text-transform: uppercase; letter-spacing: .05em; color: var(--text-faint); min-width: 56px; flex: 0 0 auto; }
.cmdk-label { font-family: var(--mono); font-weight: 600; color: var(--text-primary); flex: 0 0 auto; }
.cmdk-sub   { font-size: var(--fs-xs); color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cmdk-empty { padding: var(--space-4); color: var(--text-muted); text-align: center; }
.cmdk-hint  { display: flex; gap: var(--space-4); justify-content: flex-end; padding: var(--space-2) var(--space-3); border-top: 1px solid var(--border-dim); font-size: var(--fs-2xs); color: var(--text-faint); }
.cmdk-hint kbd { font-family: var(--mono); background: var(--bg-elevated); border: 1px solid var(--border); border-radius: 3px; padding: 0 4px; margin: 0 1px; }

/* ⌘K discoverability affordance in the header */
.cmdk-trigger {
  display: inline-flex; align-items: center; gap: var(--space-2);
  background: var(--bg-elevated); border: 1px solid var(--border);
  border-radius: var(--radius-pill); cursor: pointer;
  color: var(--text-muted); font-family: var(--font); font-size: var(--fs-xs);
  padding: 0.3rem 0.5rem 0.3rem 0.7rem; transition: border-color .15s, color .15s;
}
.cmdk-trigger:hover { color: var(--text-secondary); border-color: var(--border-bright); }
.cmdk-trigger kbd {
  font-family: var(--mono); font-size: var(--fs-2xs); color: var(--text-secondary);
  background: var(--bg-base); border: 1px solid var(--border); border-radius: var(--radius-xs); padding: 0 4px;
}
@media (max-width: 700px) { .cmdk-trigger span { display: none; } }   /* collapse to just the ⌘K key on mobile */

/* ── Collapsible methodology affordance — compacts always-on disclaimer walls ── */
/* The summary keeps the key caveat visible; the full method is one click away. */
.method-note {
  background   : var(--bg-elevated);
  border       : 1px solid var(--border-dim);
  border-radius: var(--radius-sm);
  padding      : var(--space-2) var(--space-3);
  margin       : var(--space-2) 0 var(--space-4);
  font-size    : var(--fs-xs);
}
.method-note summary {
  cursor      : pointer;
  color       : var(--text-secondary);
  display     : flex;
  align-items : center;
  gap         : var(--space-2);
  list-style  : none;
}
.method-note summary::-webkit-details-marker { display: none; }
.method-note summary::before { content: ""; }
.method-note summary::after {
  content: "▾"; margin-left: auto; color: var(--text-faint);
  transition: transform 0.15s ease; flex: 0 0 auto;
}
.method-note[open] summary { color: var(--text-primary); margin-bottom: var(--space-2); }
.method-note[open] summary::after { transform: rotate(180deg); }
.method-note summary strong { color: var(--text-primary); font-weight: 600; }
.method-note p { color: var(--text-muted); line-height: 1.5; margin: 0; }

/* ── Data & Methodology reference (Status tab) + compact source-tag component ── */
.method-page { margin-top: var(--space-6); }
.method-page-title {
  font-size: var(--fs-lg); font-weight: 600; color: var(--text-primary);
  margin: 0 0 var(--space-3); padding-bottom: var(--space-2); border-bottom: 1px solid var(--border);
}
.method-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); gap: var(--space-4); }
.method-card {
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--elev-1); padding: var(--space-4);
}
.method-card h4 {
  font-size: var(--fs-2xs); text-transform: uppercase; letter-spacing: .05em;
  color: var(--text-muted); margin: 0 0 var(--space-3);
}
.method-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-3); }
.method-list li { font-size: var(--fs-sm); line-height: 1.5; color: var(--text-secondary); }
.method-list strong { color: var(--text-primary); font-weight: 600; }

/* Source-tag component — a compact provenance chip reusable anywhere. */
.src-tag {
  display: inline-block; font-size: var(--fs-2xs); font-weight: 700;
  text-transform: uppercase; letter-spacing: .03em;
  padding: 0.05rem 0.4rem; border-radius: var(--radius-xs); margin-right: 0.35rem;
  vertical-align: middle; white-space: nowrap;
}
.src-tag.src-a  { background: var(--green-dim);   color: var(--green); }         /* public domain */
.src-tag.src-cc { background: var(--accent-dim);  color: #7cb0f7; }              /* CC0 / CC */
.src-tag.src-b  { background: var(--bg-hover);    color: var(--text-muted); }    /* licensed, dashboard-only */

/* ── Inline-SVG icon system (one stroke set, sized to the current font) ── */
.icon-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.icon {
  width: 1em; height: 1em; vertical-align: -0.125em;
  fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
  flex: 0 0 auto;
}
.close-btn .icon { width: 0.95rem; height: 0.95rem; vertical-align: middle; }
/* Buttons that pair an icon with a label — align and space them */
.btn-ghost, .btn-secondary, .news-mode-btn { display: inline-flex; align-items: center; gap: 0.4rem; }

/* Per-sub-tab empty state — replaces a blank Ownership/Filings/Sentiment void with a clear note */
.section-empty {
  color: var(--text-muted);
  font-size: var(--fs-sm);
  line-height: 1.55;
  padding: var(--space-5);
  text-align: center;
  background: var(--bg-elevated);
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  max-width: 640px;
  margin: var(--space-3) auto;
}

/* ── Catalyst-convergence watchlist (top of the Signals tab) ───────────────────── */
.wl-section { margin-bottom: var(--space-5); border-left: 3px solid var(--accent-signal); }
.wl-header { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--space-4); flex-wrap: wrap; margin-bottom: var(--space-3); }
.wl-title { font-size: var(--fs-lg); margin: 0 0 2px; }
.wl-controls { display: flex; align-items: center; gap: var(--space-3); flex-shrink: 0; }
.wl-toggle { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-xs); color: var(--text-secondary); cursor: pointer; white-space: nowrap; }
.wl-table td { vertical-align: middle; }
.wl-ticker { color: var(--accent); text-decoration: none; font-weight: 600; }
.wl-ticker:hover { text-decoration: underline; }
.wl-count { display: inline-block; min-width: 1.6em; text-align: center; font-weight: 700; color: var(--accent-signal);
  background: var(--yellow-dim); border-radius: var(--radius-pill); padding: 1px 8px; }
.wl-chips { display: flex; flex-wrap: wrap; gap: 5px; }
.wl-chip { font-size: var(--fs-2xs); padding: 2px 8px; border-radius: var(--radius-pill); border: 1px solid var(--border-bright);
  color: var(--text-secondary); background: var(--bg-elevated); white-space: nowrap; }
.wl-cat-own  { color: #7cb0ff; border-color: rgba(59,130,246,.4);  background: rgba(59,130,246,.10); }
.wl-cat-sup  { color: #f5c451; border-color: rgba(245,158,11,.4);  background: rgba(245,158,11,.10); }
.wl-cat-corp { color: #b79cff; border-color: rgba(139,92,246,.4);  background: rgba(139,92,246,.10); }
.wl-cat-earn { color: #4fd6c8; border-color: rgba(45,212,191,.4);  background: rgba(45,212,191,.10); }
.wl-cat-set  { color: #c9a892; border-color: rgba(180,140,110,.4); background: rgba(180,140,110,.10); }
.wl-cat-att  { color: #f19bd0; border-color: rgba(236,110,190,.4); background: rgba(236,110,190,.10); }

/* ── Intraday candlestick chart (the day-trader's view) ──────────────────────────── */
.idc-toolbar { display: flex; gap: var(--space-4); align-items: flex-end; flex-wrap: wrap; margin-bottom: var(--space-3); }
.idc-toolbar .control-group { margin: 0; }
.idc-card { padding: 0; overflow: hidden; }
.idc-head { display: flex; align-items: baseline; gap: var(--space-4) var(--space-5); flex-wrap: wrap;
  padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--border-dim); background: linear-gradient(180deg, rgba(255,255,255,.02), transparent); }
.idc-id { display: flex; align-items: baseline; gap: 8px; }
.idc-sym { font-size: 1.25rem; font-weight: 700; letter-spacing: .02em; color: var(--text-primary); }
.idc-meta { font-size: var(--fs-xs); }
.idc-quote { display: flex; align-items: baseline; gap: 10px; }
.idc-last { font-size: 1.25rem; font-weight: 700; }
.idc-chg { font-size: var(--fs-sm); font-weight: 600; }
.idc-chg.up, .up { color: var(--green); }
.idc-chg.down, .down { color: var(--red); }
.idc-ohlc { display: flex; gap: 14px; flex-wrap: wrap; font-size: var(--fs-xs); color: var(--text-muted); margin-left: auto; }
.idc-ohlc b { color: var(--text-secondary); font-weight: 600; margin-left: 3px; }
.idc-ohlc .up { color: var(--green); } .idc-ohlc .down { color: var(--red); }
.idc-vwap-k b, .idc-vwap-k { color: #e8b23a !important; }
.idc-plot { position: relative; width: 100%; height: clamp(340px, 47vh, 520px); cursor: crosshair; }
#idcBase, #idcOverlay { position: absolute; inset: 0; }
#idcOverlay { pointer-events: auto; }
.idc-chart-msg { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  color: var(--text-muted); font-size: var(--fs-sm); pointer-events: none; }
.idc-tip { position: absolute; z-index: 5; pointer-events: none; min-width: 158px; padding: 8px 10px;
  background: rgba(13,18,32,.96); border: 1px solid var(--border-bright); border-radius: var(--radius-sm);
  box-shadow: 0 8px 26px rgba(0,0,0,.5); font-family: var(--mono); font-size: var(--fs-2xs); }
.idc-tip-t { color: var(--text-primary); font-weight: 700; margin-bottom: 5px; letter-spacing: .02em; }
.idc-tip-g { display: grid; grid-template-columns: auto 1fr auto 1fr; gap: 2px 6px; }
.idc-tip-g span { color: var(--text-faint); } .idc-tip-g b { color: var(--text-secondary); font-weight: 600; text-align: right; }
.idc-tip-g b.up { color: var(--green); } .idc-tip-g b.down { color: var(--red); }
.idc-tip-r { display: flex; gap: 10px; margin-top: 5px; padding-top: 5px; border-top: 1px solid var(--border-dim); color: var(--text-muted); }
.idc-foot { padding: 8px var(--space-4); margin: 0; border-top: 1px solid var(--border-dim); }
.idc-section-title { font-size: var(--fs-lg); margin: var(--space-6) 0 var(--space-2); }
@media (max-width: 640px) { .idc-ohlc { margin-left: 0; width: 100%; } .idc-plot { height: 360px; } }
.idc-trade-bar { display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap;
  padding: 7px var(--space-4); border-top: 1px solid var(--border-dim); background: rgba(255,255,255,.015); }
.idc-trade-info { color: var(--text-muted); }
.idc-leg { font-weight: 700; }
.idc-leg.up { color: var(--green); } .idc-leg.down { color: var(--red); }

/* ── News: editorial cards with generated entity tiles (rebuild) ──────────────────── */
.news-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(340px, 100%), 1fr)); gap: var(--space-4); align-items: start; }
.news-card { display: grid; grid-template-columns: 52px 1fr; gap: var(--space-3); padding: var(--space-4);
  background: var(--bg-card); border: 1px solid var(--border); border-top: 2px solid var(--sec, var(--border-bright));
  border-radius: var(--radius); transition: border-color .15s ease, transform .15s ease, box-shadow .15s ease; }
.news-card:hover { border-color: var(--border-bright); transform: translateY(-2px); box-shadow: 0 12px 32px rgba(0,0,0,.4); }
/* section accents */
.news-card { --sec: var(--border-bright); --secDim: rgba(255,255,255,.03); }
.news-sec-market   { --sec: #3b82f6; --secDim: rgba(59,130,246,.13); }
.news-sec-macro    { --sec: #f59e0b; --secDim: rgba(245,158,11,.13); }
.news-sec-earnings { --sec: #10b981; --secDim: rgba(16,185,129,.13); }
.news-sec-ma       { --sec: #8b5cf6; --secDim: rgba(139,92,246,.13); }
.news-sec-company  { --sec: #2dd4bf; --secDim: rgba(45,212,191,.13); }
.news-sec-filings  { --sec: #7c8aa0; --secDim: rgba(124,138,160,.14); }
.news-sec-signals  { --sec: #f5c451; --secDim: rgba(245,196,81,.13); }
.news-card-breaking { --sec: var(--red); --secDim: rgba(239,68,68,.12); }
/* entity tile */
.news-tile { width: 52px; height: 52px; border-radius: var(--radius-sm); display: flex; align-items: center; justify-content: center; position: relative; flex-shrink: 0; }
.news-tile-mono { background: var(--tile); background-image: linear-gradient(150deg, rgba(255,255,255,.16), rgba(0,0,0,.24));
  color: #fff; font-family: var(--mono); font-weight: 700; font-size: 13px; letter-spacing: -.03em;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.18), 0 2px 8px rgba(0,0,0,.3); }
.news-tile-mono span { padding: 0 3px; }
.news-tile-mono em { position: absolute; bottom: -5px; right: -5px; font-size: 9px; font-style: normal; font-weight: 700;
  background: var(--bg-elevated); color: var(--text-secondary); border: 1px solid var(--border-bright); border-radius: 999px; padding: 0 5px; }
.news-tile-glyph { background: var(--secDim); color: var(--sec); border: 1px solid var(--sec); }
.news-tile-glyph { border-color: transparent; box-shadow: inset 0 0 0 1px var(--secDim); }
.news-tile-glyph svg { width: 26px; height: 26px; }
/* body */
.news-body { min-width: 0; }
.news-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-family: var(--mono); font-size: var(--fs-2xs); line-height: 1; margin-bottom: 6px; }
.news-sec-badge { color: var(--sec); font-weight: 700; text-transform: uppercase; letter-spacing: .05em; }
.news-meta .news-time { color: var(--text-muted); }
.news-meta .news-src { color: var(--text-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 40%; }
.news-meta .news-breaking { color: var(--red); font-weight: 700; }
.news-card .news-title { font-size: var(--fs-base); font-weight: 650; line-height: 1.34; margin: 0 0 5px; letter-spacing: -.005em; }
.news-card .news-title a { color: var(--text-primary); text-decoration: none; }
.news-card .news-title a:hover { color: var(--sec); }
.news-card .news-summary { font-size: var(--fs-sm); color: var(--text-muted); line-height: 1.46; margin: 0 0 9px;
  display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.news-chips { display: flex; gap: 5px; flex-wrap: wrap; }
/* featured lead — spans the grid, larger everything */
.news-card-lead { grid-column: 1 / -1; grid-template-columns: 92px 1fr; gap: var(--space-4); padding: var(--space-5);
  border-top-width: 3px; background: linear-gradient(180deg, var(--secDim), var(--bg-card) 62%); }
.news-card-lead .news-tile { width: 92px; height: 92px; border-radius: var(--radius); }
.news-card-lead .news-tile-mono { font-size: 22px; }
.news-card-lead .news-tile-glyph svg { width: 46px; height: 46px; }
.news-card-lead .news-title { font-size: 1.4rem; line-height: 1.22; font-weight: 700; margin-bottom: 7px; }
.news-card-lead .news-summary { font-size: var(--fs-base); -webkit-line-clamp: 3; line-clamp: 3; max-width: 68ch; margin-bottom: 11px; }
.news-card-lead .news-meta { font-size: var(--fs-xs); margin-bottom: 9px; }
@media (max-width: 660px) {
  .news-list { grid-template-columns: 1fr; }
  .news-card-lead { grid-template-columns: 60px 1fr; padding: var(--space-4); }
  .news-card-lead .news-tile { width: 60px; height: 60px; }
  .news-card-lead .news-tile-mono { font-size: 15px; }
  .news-card-lead .news-title { font-size: 1.12rem; }
}

/* ── News: real article thumbnails (GDELT socialimage) layered over the generated tile ──────────────── */
.news-card { grid-template-columns: 118px 1fr; }
.news-media { position: relative; width: 118px; align-self: stretch; min-height: 88px; border-radius: var(--radius-sm); overflow: hidden; background: var(--bg-elevated); }
.news-media .news-tile { position: absolute; inset: 0; width: 100%; height: 100%; border-radius: 0; box-shadow: none; }
.news-media .news-tile-mono { font-size: 20px; }
.news-media .news-tile-mono em { bottom: 4px; right: 4px; }
.news-media .news-tile-glyph svg { width: 34px; height: 34px; }
.news-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center; display: block; z-index: 1; background: var(--bg-elevated); }
/* featured lead — a larger (but still contained, not full-bleed) thumbnail */
.news-card-lead { grid-template-columns: 260px 1fr; }
.news-card-lead .news-media { width: 260px; min-height: 158px; border-radius: var(--radius); }
.news-card-lead .news-media .news-tile-mono { font-size: 34px; }
.news-card-lead .news-media .news-tile-glyph svg { width: 52px; height: 52px; }
@media (max-width: 660px) {
  .news-card { grid-template-columns: 96px 1fr; }
  .news-media { width: 96px; min-height: 74px; }
  .news-card-lead { grid-template-columns: 128px 1fr; }
  .news-card-lead .news-media { width: 128px; min-height: 96px; }
}

/* ══ News: image-dominant magazine cards (rebuild #2) ══════════════════════════════════ */
.news-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr)); gap: 14px; align-items: stretch; }
.ncard { --sec: var(--border-bright); --secDim: rgba(255,255,255,.04);
  position: relative; border-radius: 14px; overflow: hidden; min-height: 218px;
  border: 1px solid var(--border); background: var(--bg-card);
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease; }
.ncard:hover { transform: translateY(-3px); border-color: var(--border-bright); box-shadow: 0 18px 44px rgba(0,0,0,.55); }

/* — IMAGE card: photo fills, headline over a scrim — */
.ncard-img { display: block; }
.nc-fallback { position: absolute; inset: 0; z-index: 0; }
.nc-fallback .news-tile { position: absolute; inset: 0; width: 100%; height: 100%; border-radius: 0; box-shadow: none; }
.nc-fallback .news-tile-mono { font-size: 30px; }
.nc-fallback .news-tile-glyph svg { width: 44px; height: 44px; }
.nc-photo { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center; z-index: 1; transition: transform .5s ease; }
.ncard-img:hover .nc-photo { transform: scale(1.05); }
.nc-scrim { position: absolute; inset: 0; z-index: 2;
  background: linear-gradient(to top, rgba(6,9,15,.97) 0%, rgba(6,9,15,.9) 30%, rgba(6,9,15,.62) 52%, rgba(6,9,15,.24) 72%, rgba(6,9,15,0) 92%), rgba(6,9,15,.14); }
.nc-over { position: absolute; inset: auto 0 0 0; z-index: 3; padding: 15px 16px 14px; }
.nc-title { margin: 7px 0 0; font-weight: 700; letter-spacing: -.012em; }
.ncard-img .nc-title { color: #fff; font-size: 1.06rem; line-height: 1.26; text-shadow: 0 1px 14px rgba(0,0,0,.7);
  display: -webkit-box; -webkit-line-clamp: 3; line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.ncard-img .nc-title a { color: #fff; text-decoration: none; }
.ncard-img .nc-title a:hover { color: #fff; text-decoration: underline; text-underline-offset: 3px; }

/* — meta row — */
.nc-meta { display: flex; align-items: center; gap: 8px; font-family: var(--mono); font-size: 10px; line-height: 1; }
.nc-badge { color: #fff; background: var(--sec); padding: 3px 8px; border-radius: 999px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; box-shadow: 0 2px 8px rgba(0,0,0,.35); }
.nc-live { color: #fff; background: var(--red); padding: 3px 8px; border-radius: 999px; font-weight: 700; }
/* High-impact but NOT recent — a severity class, not a liveness claim. Deliberately calmer than
   .nc-live: it must never read as "happening now" (see newsImpactBadge). */
.nc-impact { color: var(--amber, #d98324); background: color-mix(in srgb, var(--amber, #d98324) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--amber, #d98324) 34%, transparent);
  padding: 2px 7px; border-radius: 999px; font-weight: 700; }
/* PROVENANCE: what kind of thing this row is. Primary = the government document itself (redistributable,
   what /v1 serves). Press = a third-party headline + link, dashboard-only. Blueprint = our own analytics.
   The tab header promises this distinction; the chip is where it is kept. */
.nc-prov { padding: 2px 7px; border-radius: 999px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .05em; border: 1px solid currentColor; background: transparent; cursor: help; }
.nc-prov-primary { color: var(--green); }
.nc-prov-press   { color: var(--text-faint); }
.nc-prov-bp      { color: var(--accent); }
.nc-meta-over .nc-prov-primary { color: #7ee2a8; }
.nc-meta-over .nc-prov-press   { color: rgba(255,255,255,.78); }
.nc-meta-over .nc-prov-bp      { color: #9ec5fe; }
.nc-meta-over .nc-time, .nc-meta-over .nc-src { color: rgba(255,255,255,.82); }
.nc-src { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 42%; }
.ncard .news-chips { display: flex; gap: 5px; flex-wrap: wrap; margin-top: 9px; }

/* — TEXT card: no image, typographic + section spine — */
.ncard-text { display: grid; grid-template-columns: 1fr 46px; gap: 12px; padding: 16px; border-top: 3px solid var(--sec); }
.ncard-text .nc-body { min-width: 0; display: flex; flex-direction: column; }
.ncard-text .nc-meta { margin-bottom: 8px; }
.ncard-text .nc-badge { color: var(--sec); background: var(--secDim); box-shadow: none; }
.ncard-text .nc-time { color: var(--text-muted); } .ncard-text .nc-src { color: var(--text-faint); }
.ncard-text .nc-title { color: var(--text-primary); font-size: 1.02rem; line-height: 1.3; margin: 0 0 8px; }
.ncard-text .nc-title a { color: var(--text-primary); text-decoration: none; }
.ncard-text .nc-title a:hover { color: var(--sec); }
.nc-sum { color: var(--text-muted); font-size: 13px; line-height: 1.5; margin: 0;
  display: -webkit-box; -webkit-line-clamp: 4; line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden; }
.nc-glyph { align-self: start; }
.nc-glyph .news-tile { width: 46px; height: 46px; }

/* — HERO lead: full-width, big — */
.ncard-lead { grid-column: 1 / -1; min-height: 384px; }
.ncard-lead.ncard-img .nc-over { padding: 26px 28px 24px; max-width: 74%; }
.ncard-lead.ncard-img .nc-title { font-size: 2.05rem; line-height: 1.12; -webkit-line-clamp: 3; line-clamp: 3; }
.ncard-lead.ncard-img .nc-scrim { background: linear-gradient(to top, rgba(6,9,15,.95) 0%, rgba(6,9,15,.7) 34%, rgba(6,9,15,.15) 66%, rgba(6,9,15,0) 100%),
  linear-gradient(to right, rgba(6,9,15,.55) 0%, rgba(6,9,15,0) 60%); }
/* Scoped to the IMAGE lead: the white sits on the photo scrim. A text lead has no scrim, so it keeps
   the normal muted summary colour — the hero can now be a government story, which never has a photo. */
.ncard-lead.ncard-img .nc-sum { color: rgba(255,255,255,.9); font-size: 15px; line-height: 1.5; margin-top: 10px; -webkit-line-clamp: 3; line-clamp: 3; display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden; }
.ncard-lead.ncard-text .nc-sum { font-size: 15px; line-height: 1.55; margin-top: 10px; -webkit-line-clamp: 4; line-clamp: 4; }
/* TEXT LEAD. Until the hero stopped filtering on image_url this rule was styled but never rendered —
   only press rows carry a photo, so the lead was always an image card. A government story leading the
   page has no photo, and the rotator pins every slide to inset:0, so the card is STRETCHED to the image
   hero's height: top-aligned text left a dead 250px void. It now centres in that space and carries a
   section-tinted wash + an oversized watermark glyph, so a primary document reads as a designed lead
   rather than a card that failed to load its picture. */
.ncard-lead.ncard-text { grid-template-columns: 1fr 128px; padding: 30px 34px; align-items: center;
  background: linear-gradient(135deg, color-mix(in srgb, var(--sec) 12%, var(--bg-card)) 0%, var(--bg-card) 58%); }
.ncard-lead.ncard-text .nc-body { justify-content: center; }
.ncard-lead.ncard-text .nc-title { font-size: 1.7rem; line-height: 1.18; }
.ncard-lead.ncard-text .nc-glyph { align-self: center; }
.ncard-lead.ncard-text .nc-glyph .news-tile { width: 128px; height: 128px; opacity: .5; }
.ncard-lead.ncard-text .nc-glyph .news-tile-glyph svg { width: 66px; height: 66px; }
.ncard-lead.ncard-text .nc-glyph .news-tile-mono { font-size: 34px; }
.ncard-breaking { --sec: var(--red); }

@media (max-width: 660px) {
  .news-list { grid-template-columns: 1fr; }
  .ncard { min-height: 190px; }
  .ncard-lead { min-height: 300px; }
  .ncard-lead.ncard-img .nc-over { max-width: 100%; padding: 18px; }
  .ncard-lead.ncard-img .nc-title { font-size: 1.4rem; }
}

/* ══ Live crawlers — fixed bottom ticker bar (stocks left · news right) ═══════════════════ */
body.has-ticker { padding-bottom: 40px; }
.tk-bar { position: fixed; left: 0; right: 0; bottom: 0; z-index: 200; display: none;
  height: 40px; align-items: stretch;
  background: linear-gradient(180deg, var(--bg-surface), var(--bg-base));
  border-top: 1px solid var(--border-bright); box-shadow: 0 -8px 24px rgba(0,0,0,.4); }
body.has-ticker .tk-bar { display: flex; }
.tk-seg { display: flex; align-items: center; min-width: 0; overflow: hidden; flex: 1.5; }
.tk-seg-news { flex: 1; }
.tk-seg.tk-empty { display: none; }
.tk-div { width: 1px; background: var(--border-bright); margin: 6px 0; flex-shrink: 0; }
.tk-label { flex-shrink: 0; align-self: center; margin: 0 12px; padding: 3px 9px; border-radius: 999px;
  font-family: var(--mono); font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .09em; }
.tk-label-mkt  { color: var(--accent); background: var(--accent-dim); }
.tk-label-news { color: var(--accent-signal); background: var(--yellow-dim); }
.tk-lane { flex: 1; min-width: 0; overflow: hidden; position: relative; height: 100%;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent); }
.tk-track { position: absolute; left: 0; top: 0; height: 100%; display: inline-flex; align-items: center;
  width: max-content; white-space: nowrap; animation: tk-scroll linear infinite; will-change: transform; }
.tk-lane:hover .tk-track { animation-play-state: paused; }
@keyframes tk-scroll { from { transform: translateX(0); } to { transform: translateX(-50%); } }
/* stock chip */
.tk-item { display: inline-flex; align-items: center; gap: 6px; font-family: var(--mono); font-size: 12px; padding: 0 15px; }
.tk-stk { cursor: pointer; }
.tk-stk b { color: var(--text-primary); font-weight: 700; letter-spacing: .02em; }
.tk-stk i { color: var(--text-secondary); font-style: normal; }
.tk-stk em { font-style: normal; font-weight: 600; }
.tk-stk em.up { color: var(--green); } .tk-stk em.down { color: var(--red); }
.tk-stk:hover b { color: var(--accent); }
/* news chip */
.tk-nws { text-decoration: none; color: var(--text-secondary); font-family: var(--font); font-size: 12.5px; gap: 8px; max-width: 46ch; }
.tk-nws .tk-h { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tk-nws:hover { color: var(--text-primary); }
.tk-dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; background: var(--sec, var(--accent-signal)); box-shadow: 0 0 8px var(--sec, var(--accent-signal)); }
@media (prefers-reduced-motion: reduce) { .tk-track { animation: none; } }
@media (max-width: 720px) { .tk-seg-news { display: none; } .tk-div { display: none; } .tk-seg { flex: 1; } }

/* ══ Premium polish pass — global primitives ═══════════════════════════════════════════ */
/* Text selection in brand accent (default blue-on-white selection looks unthemed on dark) */
::selection { background: rgba(59, 130, 246, .32); color: var(--text-primary); }

/* One consistent keyboard focus ring everywhere (buttons, links, chips, inputs, table rows) */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
.control-input:focus-visible, .news-ticker-input:focus-visible { outline-offset: 0; }

/* Press feedback: every button compresses slightly on :active — the "it responded" feel */
button:active, .btn-primary:active, .btn-secondary:active, .btn-ghost:active,
.tab-btn:active, .chip:active, .news-mode-btn:active { transform: translateY(1px) scale(.985); }
button, .chip, .news-mode-btn { transition: transform .08s ease, background .15s ease, color .15s ease, border-color .15s ease, box-shadow .15s ease; }

/* Tab switches get a subtle entrance — content settles instead of popping */
@keyframes panel-in { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: none; } }
.tab-panel.active { animation: panel-in .22s ease both; }

/* Data is numeric — keep digits fixed-width everywhere they appear so columns never shimmy */
.mono, .data-table td.num, .bt-stat-value, .idc-last, .tk-item { font-variant-numeric: tabular-nums; }

/* Overscroll: don't rubber-band the whole app chrome */
html { overscroll-behavior-y: none; }

@media (prefers-reduced-motion: reduce) {
  .tab-panel.active { animation: none; }
  button:active, .tab-btn:active, .chip:active { transform: none; }
}

/* Frosted sticky chrome: content scrolling beneath the header/nav reads through a glass blur */
@supports (backdrop-filter: blur(1px)) {
  .site-header { background: rgba(13, 18, 32, .78); backdrop-filter: blur(14px) saturate(1.4); }
  .tab-bar     { background: rgba(13, 18, 32, .72); backdrop-filter: blur(14px) saturate(1.4); }
  .tk-bar      { background: rgba(8, 12, 20, .82); backdrop-filter: blur(12px) saturate(1.3); }
}

/* ══ Premium polish pass — audit batch ═════════════════════════════════════════════════ */
/* A2 — ONE page-title system across all 13 tabs (was: 3 different treatments) */
.panel-title, .tab-title { font-size: var(--fs-xl); font-weight: 600; letter-spacing: -0.01em; line-height: 1.2; margin: 0; }
h2.tab-title { margin: 0 0 var(--space-3); }
.page-sub { font-size: var(--fs-sm); font-weight: 400; color: var(--text-muted); letter-spacing: 0; }

/* A4 — one card primitive (the Overview spec) everywhere */
.card, .kpi-card, .status-card, .chart-card { border-radius: var(--radius-lg); box-shadow: var(--elev-1); }

/* A5 — native widgets fully themed: custom select chevron + accent checkboxes */
select.control-input {
  appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%238899aa' fill='none' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 0.6rem center; padding-right: 2rem;
}
input[type="checkbox"], input[type="radio"], input[type="range"], progress { accent-color: var(--accent); }

/* A6 — palette hover + ticker-input focus parity */
.cmdk-item:hover { background: var(--bg-hover); }
.news-ticker-input:focus { box-shadow: 0 0 0 2px var(--accent-dim); }

/* A7 — inner scrollers never chain into the page */
.cmdk-results, .search-results, .table-wrap, .news-calendar, .tab-bar { overscroll-behavior: contain; }

/* Nav group labels are functional text, not decoration — they must stay legible, which is why the
   original rule lifted them off --text-faint.

   THIS IS THE ONLY PLACE .nav-group-label COLOUR IS SET. Each label is tinted with its group's own
   accent so the label and its tabs read as one unit, then lifted toward white because they are set at
   9px, where WCAG's small-text 4.5:1 threshold applies. The raw accents measure 5.08 / 4.41 / 8.70
   against this bar — the research purple fails on its own, and a tint that only some groups pass is
   worse than no tint at all. The mix keeps each hue identifiable while putting every one over the
   line. Do not set colour on the layout rule further up: same specificity, earlier position, and it
   loses silently. */
.nav-group-label { color: color-mix(in srgb, var(--nav-accent, var(--text-muted)) 72%, #fff); opacity: 1; }

/* B3 — a big stat number speaks mono everywhere (Overview now matches Macro/Backtest) */
.ov-kpi-value { font-family: var(--mono); font-variant-numeric: tabular-nums; }

/* B4 — card titles collapse to two tiers: title (fs-md/600) or uppercase kicker */
.chart-card-header h3, .status-card h3 {
  font-size: var(--fs-2xs); font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-muted); }
.chart-card-header h3 .muted, .chart-card-header h3 .small { text-transform: none; letter-spacing: 0; }
.signal-card-title { font-size: var(--fs-md); font-weight: 600; }
.wl-title { font-size: var(--fs-md); }

/* B5 — News toolbar rows share one geometry (segmented vs filter stays, sizes align) */
.news-mode-btn, .chip { font-size: 0.8rem; border-radius: var(--radius-pill); }

/* B6 — retire hardcoded color drift onto tokens */
.ts-hm-cell { color: var(--text-primary); }
.hm-tile { color: var(--text-primary); }
.idc-vwap-k b, .idc-vwap-k { color: var(--yellow) !important; }

/* Stocks: the CHANGE% magnitude bar becomes a clean underline track (was: a smear behind the glyphs) */
.chg-bar { top: auto; bottom: 4px; height: 3px; opacity: 0.55; border-radius: 2px; }

/* News hero: trim the void — slightly shorter, stronger floor so the headline always sits on solid ground */
.ncard-lead { min-height: 330px; }
/* Mobile: unified titles scale down together (keeps the pre-existing small-screen sizing) */
@media (max-width: 640px) { .panel-title, .tab-title { font-size: var(--fs-lg); } }

/* ══ Candle chart v2 — trading-grade interactions ══════════════════════════════════════ */
#idcOverlay { cursor: crosshair; }
#idcOverlay.idc-grabbing { cursor: grabbing; }
/* live-legend EMA toggle chips (inside the OHLC strip) */
.idc-ind { font-family: var(--mono); font-size: 10px; font-weight: 600; padding: 2px 8px; margin-left: 2px;
  border-radius: var(--radius-pill); border: 1px solid var(--border-bright); background: transparent;
  color: var(--text-faint); cursor: pointer; letter-spacing: .02em; }
.idc-ind::before { content: ''; display: inline-block; width: 10px; height: 2px; border-radius: 1px;
  background: var(--ind); margin-right: 5px; vertical-align: middle; opacity: .35; }
.idc-ind.on { color: var(--text-secondary); border-color: var(--ind); }
.idc-ind.on::before { opacity: 1; }
.idc-ind:hover { color: var(--text-primary); }
/* hovered-bar time chip in the legend */
.idc-t { color: var(--text-primary); background: var(--bg-elevated); border-radius: 4px; padding: 2px 7px; font-weight: 600; }
/* pulsing last-price dot */
.idc-pulse { position: absolute; z-index: 4; width: 6px; height: 6px; border-radius: 50%; pointer-events: none; }
.idc-pulse::after { content: ''; position: absolute; inset: -5px; border-radius: 50%;
  background: inherit; opacity: .5; animation: idc-pulse 2s ease-out infinite; }
@keyframes idc-pulse { 0% { transform: scale(.4); opacity: .55; } 70% { transform: scale(1.6); opacity: 0; } 100% { opacity: 0; } }
/* reset-zoom affordance (appears only when zoomed/panned) */
.idc-fit { position: absolute; right: 70px; bottom: 30px; z-index: 4; font-family: var(--mono); font-size: 10.5px;
  padding: 4px 10px; border-radius: var(--radius-pill); border: 1px solid var(--border-bright);
  background: rgba(13,18,32,.88); color: var(--text-secondary); cursor: pointer; backdrop-filter: blur(6px); }
.idc-fit:hover { color: var(--text-primary); border-color: var(--accent); }
@media (prefers-reduced-motion: reduce) { .idc-pulse::after { animation: none; } }

/* ══ Hover system: custom tooltip singleton + heat-map hover card ═══════════════════════ */
.ui-tip { position: fixed; z-index: 400; max-width: 340px; padding: 7px 11px;
  background: var(--bg-elevated); border: 1px solid var(--border-bright); border-radius: var(--radius-sm);
  color: var(--text-primary); font-size: var(--fs-xs); line-height: 1.4; pointer-events: none;
  box-shadow: 0 8px 24px rgba(0,0,0,.5); opacity: 0; transform: translateY(4px);
  transition: opacity .12s ease, transform .12s ease; }
.ui-tip.below { transform: translateY(-4px); }
.ui-tip.show { opacity: 1; transform: none; }
.hm-card { position: fixed; z-index: 400; width: 210px; padding: 12px 14px; pointer-events: none;
  background: rgba(13,18,32,.97); border: 1px solid var(--border-bright); border-radius: var(--radius);
  box-shadow: 0 16px 42px rgba(0,0,0,.55); opacity: 0; transform: translateY(4px) scale(.98);
  transition: opacity .14s ease, transform .14s ease; backdrop-filter: blur(8px); }
.hm-card.show { opacity: 1; transform: none; }
.hm-card-hd { display: flex; align-items: baseline; gap: 7px; margin-bottom: 4px; }
.hm-card-hd b { font-family: var(--mono); font-size: var(--fs-md); font-weight: 700; color: var(--text-primary); }
.hm-card-hd span { font-size: var(--fs-2xs); color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hm-card-chg { font-family: var(--mono); font-size: 1.35rem; font-weight: 700; margin-bottom: 8px; font-variant-numeric: tabular-nums; }
.hm-card-row { display: flex; justify-content: space-between; font-size: var(--fs-xs); padding: 2.5px 0; }
.hm-card-row span { color: var(--text-muted); }
.hm-card-row b { font-family: var(--mono); font-weight: 600; color: var(--text-secondary); }
.hm-card-ft { margin-top: 8px; padding-top: 7px; border-top: 1px solid var(--border-dim); font-size: var(--fs-2xs); color: var(--text-faint); }
.hm-card-spark { display: block; width: 178px; height: 34px; margin: 2px 0 6px; }

/* Ticker links in the signals tables — same link language as .wl-ticker, hover shows the card */
.sig-tkr { color: var(--accent); font-weight: 600; cursor: pointer; }
.sig-tkr:hover, .sig-tkr:focus-visible { text-decoration: underline; }
.sig-tkr-static { font-weight: 600; cursor: default; }   /* non-instrument (CIK-keyed PIT) — not clickable */
/* hovered tile gets a visible inner stroke (Finviz free tier doesn't; premium maps do) */
.hm-tile:hover, .hm-tile:focus-visible { box-shadow: inset 0 0 0 2px rgba(255,255,255,.55); z-index: 2; }
@media (prefers-reduced-motion: reduce) { .ui-tip, .hm-card { transition: none; } }

/* ══ Live legend (the key IS the readout — no floating box over the data) ═══════════════ */
.chart-legend { align-items: center; gap: 14px; }
.lgd { display: inline-flex; align-items: center; gap: 5px; font-size: 10.5px; color: var(--text-muted); white-space: nowrap; }
.lgd i { width: 10px; height: 3px; border-radius: 2px; background: var(--c); flex-shrink: 0; }
.lgd b { font-family: var(--mono); font-weight: 600; color: var(--text-primary); font-variant-numeric: tabular-nums; margin-left: 2px; }
.lgd-date { font-family: var(--mono); font-size: 10px; color: var(--text-primary); background: var(--bg-elevated);
  border: 1px solid var(--border-bright); border-radius: 4px; padding: 2px 7px; opacity: 0; transition: opacity .12s ease; }
.lgd-date:empty { padding: 0; border: 0; }
.lgd-date.on { opacity: 1; }
.lgd-meta { margin-left: auto; font-size: 0.7rem; color: var(--text-faint); white-space: nowrap; }
.lgd-mini { margin-left: auto; gap: 10px; overflow: hidden; }
@media (max-width: 900px) { .lgd-meta { display: none; } }

/* ══ Ticker bar v2: live in-place refresh + richer news chips ══════════════════════════ */
.tk-copy { display: inline-flex; align-items: center; }
.tk-label { cursor: pointer; border: 0; }
.tk-label:hover { filter: brightness(1.25); }
.tk-c.flat { color: var(--text-muted); }
@keyframes tk-flash-up   { 0% { background: rgba(38,194,129,.22); } 100% { background: transparent; } }
@keyframes tk-flash-down { 0% { background: rgba(239,75,93,.22); } 100% { background: transparent; } }
.tk-flash-up   { animation: tk-flash-up .9s ease-out; border-radius: 6px; }
.tk-flash-down { animation: tk-flash-down .9s ease-out; border-radius: 6px; }
.tk-sec { font-family: var(--mono); font-size: 9px; font-weight: 700; letter-spacing: .07em; color: var(--sec, var(--text-faint)); flex-shrink: 0; }
.tk-ago { font-family: var(--mono); font-size: 10px; color: var(--text-faint); flex-shrink: 0; }
.tk-dot-live { background: var(--red); box-shadow: 0 0 8px var(--red); animation: tk-live 1.6s ease-in-out infinite; }
@keyframes tk-live { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }

/* ══ News tab: day groups + fresh pill + sticky filters + image fade ═══════════════════ */
.news-day { grid-column: 1 / -1; display: flex; align-items: center; gap: 12px; margin: 6px 0 -4px; }
.news-day span { font-family: var(--mono); font-size: 10.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .08em; color: var(--text-muted); flex-shrink: 0; }
.news-day::after { content: ''; flex: 1; height: 1px; background: var(--border-dim); }
.news-fresh { position: sticky; top: 108px; z-index: 6; display: block; margin: 0 auto 10px;
  padding: 6px 16px; border-radius: var(--radius-pill); border: 1px solid var(--accent);
  background: rgba(13,18,32,.92); color: var(--accent); font-size: var(--fs-xs); font-weight: 600;
  cursor: pointer; backdrop-filter: blur(8px); box-shadow: 0 8px 24px rgba(0,0,0,.45); }
.news-fresh:hover { background: var(--accent-dim); }
.news-img { opacity: 0; transition: opacity .35s ease; }
.news-img.ld { opacity: 1; }
@media (min-width: 900px) {
  .news-controls { position: sticky; top: 98px; z-index: 5; padding: 8px 0;
    background: rgba(8,12,20,.85); backdrop-filter: blur(12px) saturate(1.3); }
}
@media (prefers-reduced-motion: reduce) { .tk-flash-up, .tk-flash-down, .tk-dot-live { animation: none; } .news-img { transition: none; opacity: 1; } }

/* ══ Tape sparklines + pinned index chips ═══════════════════════════════════════════════ */
.tk-spark { flex-shrink: 0; opacity: .9; }
.tk-idx { padding-left: 13px; }
.tk-idx b { color: var(--accent); }
.tk-idx + .tk-item:not(.tk-idx) { border-left: 1px solid var(--border-bright); padding-left: 15px; }

/* ══ Publisher favicons on news cards ═══════════════════════════════════════════════════ */
.nc-fav { width: 12px; height: 12px; border-radius: 3px; vertical-align: -2px; margin-right: 4px; }

/* ══ Rotating hero (Top mode) ═══════════════════════════════════════════════════════════ */
.news-hero-rot { grid-column: 1 / -1; position: relative; min-height: 330px; }
.nhr-slide { position: absolute; inset: 0; opacity: 0; transition: opacity .55s ease; pointer-events: none; }
.nhr-slide.on { opacity: 1; pointer-events: auto; }
.nhr-slide .ncard-lead { position: absolute; inset: 0; min-height: 0; }
.nhr-dots { position: absolute; right: 18px; top: 16px; z-index: 5; display: flex; gap: 7px; }
.nhr-dot { width: 8px; height: 8px; border-radius: 50%; border: 0; padding: 0; cursor: pointer;
  background: rgba(255,255,255,.28); transition: background .2s, transform .2s; }
.nhr-dot.on { background: #fff; transform: scale(1.25); }
.nhr-dot:hover { background: rgba(255,255,255,.6); }
@media (prefers-reduced-motion: reduce) { .nhr-slide { transition: none; } }
.tm-val { flex: 0 0 8rem; }        /* "halted since 2024" needs more room than a number does */

/* Attribution badge — CoinGecko's licence conditions on a PROMINENT display (no smaller than 10pt),
   so this is a compliance control, not decoration. Do not shrink it below 10px. */
.attrib-badge { font-size: 10px; color: var(--text-muted); text-decoration: none; border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: .1rem .4rem; margin-left: auto; white-space: nowrap; }
.attrib-badge:hover { color: var(--fg); border-color: var(--accent); }
.link-btn { background: none; border: none; color: var(--accent); cursor: pointer; font: inherit; padding: 0; text-decoration: underline; }
.lic-table { width: 100%; border-collapse: collapse; font-size: var(--fs-xs); }
.lic-table th { text-align: left; color: var(--text-muted); font-weight: 600; padding: .3rem .5rem; border-bottom: 1px solid var(--border); }
.lic-table td { padding: .3rem .5rem; border-bottom: 1px solid var(--border); vertical-align: top; }
.lic-pay-yes { color: var(--green); } .lic-pay-no { color: var(--red); font-weight: 700; } .lic-pay-cond { color: var(--amber, #d9a441); }
.lic-panel { max-width: 900px; max-height: 80vh; overflow-y: auto; padding: var(--space-4); }
.lic-head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: .6rem; }

/* A withheld figure must not borrow the colour of a good one. Neutral means neutral. */
.tc-bar-fill.unknown { background: color-mix(in srgb, var(--fg) 22%, transparent); }

/* ── Sector & Theme Intelligence: orientation layer ──────────────────────────────────────────────
   The dashboard's own vernacular is codes — tickers, form numbers, agency abbreviations. So a hub is
   tagged with a two-letter mono code rather than a pictogram: it reads as a filing tag, it is legible
   at 11px, and it does not decorate. */
.chip-code {
  display: inline-block; min-width: 1.55rem; margin-right: .45rem; padding: .05rem .2rem;
  font-family: var(--mono); font-size: var(--fs-2xs); font-weight: 700; letter-spacing: .03em;
  text-align: center; color: var(--text-muted);
  border: 1px solid var(--border); border-radius: 3px; background: color-mix(in srgb, var(--fg) 4%, transparent);
}
.chip.active .chip-code { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 55%, var(--border)); }
.chip-theme .chip-code { color: color-mix(in srgb, var(--accent) 80%, var(--fg)); }

/* The brief: what you are looking at, in plain language, before any number. A rule down the left
   rather than a box — it should read as an editor's note, not another panel competing for attention. */
.hub-brief {
  margin: .1rem 0 1rem; padding: .1rem 0 .1rem .85rem;
  border-left: 2px solid color-mix(in srgb, var(--accent) 60%, transparent);
  max-width: 78ch;
}
.hub-brief .eyebrow {
  display: block; font-size: var(--fs-2xs); text-transform: uppercase; letter-spacing: .09em;
  color: var(--text-muted); margin-bottom: .25rem;
}
.hub-brief p { font-size: var(--fs-sm); line-height: 1.6; color: color-mix(in srgb, var(--fg) 82%, transparent); margin: 0; }

/* Per-card orientation. The lede says what the card is; the read-as says how to read the number —
   which is the part a non-specialist actually needs and which no financial dashboard ever supplies. */
.card-lede { font-size: var(--fs-xs); line-height: 1.55; color: var(--text-muted); margin: -.15rem 0 .6rem; max-width: 74ch; }
.read-as {
  display: block; margin: .55rem 0 0; padding: .35rem .55rem;
  font-size: var(--fs-2xs); line-height: 1.5;
  color: color-mix(in srgb, var(--fg) 72%, transparent);
  background: color-mix(in srgb, var(--accent) 6%, transparent);
  border-left: 2px solid color-mix(in srgb, var(--accent) 45%, transparent); border-radius: 0 3px 3px 0;
}
.read-as b { color: var(--fg); font-weight: 600; }

/* ─────────────────────────── FUEL & ENERGY TAB ─────────────────────────────── */
.fuel-controls { display: flex; gap: var(--space-4); flex-wrap: wrap; align-items: flex-end;
  margin: var(--space-4) 0 var(--space-3); }
.fuel-ctl { display: flex; flex-direction: column; gap: var(--space-1); font-size: var(--fs-xs); }
.fuel-ctl > span { color: var(--text-muted); text-transform: uppercase; letter-spacing: .06em; font-size: var(--fs-2xs); }
.fuel-ctl select, .fuel-ctl input { background: var(--bg-elevated); color: var(--text-primary);
  border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 6px 10px; font: inherit; min-width: 190px; }
.fuel-ctl select:focus, .fuel-ctl input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.fuel-ctl-search input { min-width: 240px; }

.fuel-stage { position: relative; background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius-md); overflow: hidden; }
#fuelCanvas { display: block; width: 100%; height: auto; touch-action: none; }
#fuelCanvas:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.fuel-timeline { display: flex; align-items: center; gap: var(--space-3); margin-top: var(--space-3); }
.fuel-play { background: var(--bg-elevated); color: var(--text-primary); border: 1px solid var(--border);
  border-radius: var(--radius-pill); width: 38px; height: 38px; cursor: pointer; font-size: var(--fs-sm); flex: none; }
.fuel-play:hover { background: var(--bg-hover); }
.fuel-slider { flex: 1; accent-color: var(--accent); }
.fuel-period { font-variant-numeric: tabular-nums; color: var(--text-secondary); min-width: 6.5em; text-align: right; }

.fuel-legend-note { margin-top: var(--space-2); line-height: 1.5; }

.fuel-resolve { background: var(--bg-card); border: 1px solid var(--border);
  border-left: 3px solid var(--accent); border-radius: var(--radius-sm);
  padding: var(--space-3) var(--space-4); margin-bottom: var(--space-3); }
.fuel-resolve-head { margin: 0 0 var(--space-2); }
.fuel-resolve-miss { margin: 0; color: var(--text-secondary); }
.fuel-sub { margin: var(--space-3) 0 var(--space-1); color: var(--text-muted);
  font-size: var(--fs-2xs); text-transform: uppercase; letter-spacing: .06em; }
.fuel-list { margin: 0; padding-left: var(--space-4); line-height: 1.7; }
/* A caveat is not decoration — it is the reason the number above it can be misread. Amber, not muted. */
.fuel-warn { color: var(--yellow); background: var(--yellow-dim, rgba(240,160,60,.08));
  border-radius: var(--radius-xs); padding: var(--space-2) var(--space-3); margin: var(--space-2) 0; line-height: 1.55; }
.fuel-caveats { margin: var(--space-2) 0 0; padding-left: var(--space-4); color: var(--text-secondary);
  font-size: var(--fs-xs); line-height: 1.6; }
.fuel-caveats li { margin-bottom: var(--space-1); }

/* The key. With the hatch removed there is no texture to decode, so the distinction between a
   measured and an inherited price is stated in words, permanently, under the map. A definition list
   is the honest markup: each term genuinely has a definition. */
.fuel-key { margin-top: var(--space-4); background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius-md); padding: var(--space-4) var(--space-4) var(--space-3); }
.fuel-key-title { margin: 0 0 var(--space-3); font-size: var(--fs-2xs); font-weight: 700;
  text-transform: uppercase; letter-spacing: .14em; color: var(--text-muted); }
.fuel-key-list { margin: 0; display: grid; grid-template-columns: minmax(150px, max-content) 1fr;
  gap: var(--space-2) var(--space-4); align-items: baseline; }
.fuel-key-list dt { display: flex; align-items: baseline; gap: var(--space-2);
  font-size: var(--fs-xs); font-weight: 600; color: var(--text-primary); }
.fuel-key-list dd { margin: 0; font-size: var(--fs-xs); color: var(--text-secondary); line-height: 1.6; }
.fuel-key-list i { font-style: normal; color: var(--text-primary); font-weight: 600; }
.fuel-key-dot { width: 10px; height: 10px; border-radius: 2px; flex: none; align-self: center;
  border: 1px solid rgba(8,12,20,.7); }
/* Only no-data carries a chip. Measured and inherited render identically on the map, so two identical
   swatches would just raise a question the definition beside them then has to answer. */
.fuel-key-dot-none { background: #39424f; }

@media (max-width: 640px) {
  .fuel-key-list { grid-template-columns: 1fr; gap: var(--space-1) 0; }
  .fuel-key-list dd { margin-bottom: var(--space-2); }
}

.fuel-detail { margin-top: var(--space-3); }
.fuel-detail-card { background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius-md); padding: var(--space-4); }
.fuel-detail-card h3 { margin: 0 0 var(--space-2); font-size: var(--fs-lg); }
.fuel-big { font-size: var(--fs-2xl); font-variant-numeric: tabular-nums; margin: 0 0 var(--space-2); }

/* This six-column screen-reader fallback has a min-content width of ~474px, and `width: 100%`
   cannot shrink a table below that — so on a phone it pushed the whole document to 485px. It
   scrolls inside its own container, the same contract .table-wrap gives every other wide table. */
.fuel-table-fallback { margin-top: var(--space-4); overflow-x: auto; -webkit-overflow-scrolling: touch;
                       overscroll-behavior-x: contain; max-width: 100%; }
.fuel-table-fallback table { width: 100%; border-collapse: collapse; font-size: var(--fs-xs); }
.fuel-table-fallback th, .fuel-table-fallback td { text-align: left; padding: 4px 8px; border-bottom: 1px solid var(--border-subtle, var(--border)); }
.fuel-table-fallback th { color: var(--text-muted); font-weight: 600; }

@media (max-width: 720px) {
  .fuel-controls { gap: var(--space-2); }
  .fuel-ctl select, .fuel-ctl input, .fuel-ctl-search input { min-width: 0; width: 100%; }
  .fuel-ctl { flex: 1 1 100%; }
}

/* ── Globe interaction: stop three full-width blurs recomputing every frame ────────────────────
   .site-header, .tab-bar and .tk-bar each carry backdrop-filter: blur(14px). A backdrop-filter must
   re-sample and re-blur everything behind it whenever that content changes, so a canvas repainting
   at 60fps forces THREE full-width blurs per frame. That is compositor work, not canvas work, which
   is why the symptom is "the whole page lags while moving the globe" rather than a slow map, and why
   it never appeared in headless measurement: the renderer's own timer reports ~6ms a frame either
   way, because the cost is not in the render.

   While the pointer is down on the map, the blurs are swapped for the opaque colour they resolve to
   anyway. Visually near-identical against this dark surface; the difference is one paint instead of
   three blurs. Restored the moment the pointer is released. */
body.map-interacting .site-header,
body.map-interacting .tab-bar,
body.map-interacting .tk-bar { backdrop-filter: none !important; }
body.map-interacting .site-header { background: #0d1220; }
body.map-interacting .tab-bar     { background: var(--bg-surface); }
body.map-interacting .tk-bar      { background: #080c14; }

/* `contain: paint` tells the browser nothing inside can affect layout or paint outside the stage, so
   canvas repaints stop invalidating neighbouring regions.
   NOT will-change: transform. That was added here on a guess and removed after thinking about what it
   actually does: it promotes the canvas to its own compositor layer, and for a canvas whose CONTENT
   changes every frame rather than its transform, promotion means re-uploading the whole backing store
   as a texture on every single frame. An optimisation nobody measured is just a change. */
.fuel-stage { contain: paint; }

/* ── Commodities: the Public Record board ─────────────────────────────────────
   The three coverage states must be VISUALLY distinct, not three shades of grey.
   `none` ("nobody publishes this") is the most informative cell on the screen, so it is
   styled to be read rather than skipped — it is the product, not an absence. */
.cmd-coverage { display:flex; flex-wrap:wrap; gap:.75rem 1.25rem; align-items:center;
  margin:.75rem 0 1rem; padding:.6rem .8rem; background:var(--bg-card);
  border:1px solid var(--border-dim); border-radius:8px; font-size:var(--fs-2xs); }
.cmd-cov-chip { display:flex; gap:.45rem; align-items:baseline; }
.cmd-cov-chip > span { white-space:nowrap; }
.cmd-cov-asof { margin-left:auto; font-family:var(--mono); }

.cmd-live   { color:var(--green); }
.cmd-public { color:var(--yellow); }
.cmd-none   { color:var(--text-secondary); }
.cmd-mark   { font-size:.9em; margin-right:.4rem; }

/* The note is the substance of the cell: it names the source, or names whose product the
   missing number is. Clamped to keep rows scannable; full text stays in the title/DOM. */
#commoditiesTable td.cmd-live,
#commoditiesTable td.cmd-public,
#commoditiesTable td.cmd-none { max-width:24rem; }
.cmd-note { color:var(--text-muted); font-size:var(--fs-2xs); line-height:1.35;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
#commoditiesTable tr:hover .cmd-note { -webkit-line-clamp:unset; overflow:visible; }

.cmd-group td { background:var(--bg-elevated); color:var(--text-secondary);
  font-size:var(--fs-2xs); text-transform:uppercase; letter-spacing:.08em;
  font-weight:600; padding:.4rem .6rem; }
.cmd-row { cursor:pointer; }
.cmd-row:hover { background:var(--bg-hover); }
.cmd-name { font-weight:600; }
.cmd-inline-note { display:block; font-size:var(--fs-2xs); line-height:1.3; margin-top:.15rem; }

.cmd-detail { margin-top:1rem; }
.cmd-detail:empty { display:none; }
.cmd-detail-head { display:flex; align-items:center; justify-content:space-between; gap:1rem; }
.cmd-detail-head h3 { margin:0; font-size:var(--fs-sm, .8125rem); }
.cmd-detail-stats { display:flex; flex-wrap:wrap; gap:.5rem 1.5rem; margin:.6rem 0 .8rem; }
.cmd-detail-stats > div { display:flex; flex-direction:column; gap:.1rem; }
.cmd-detail-stats b { font-family:var(--mono); font-size:var(--fs-xs); }
.cmd-detail-stats span { font-size:var(--fs-2xs); }

.cmd-spark { background:var(--bg-card); border:1px solid var(--border-dim);
  border-radius:8px; padding:.5rem; }
.cmd-spark svg { width:100%; height:120px; display:block; }
.cmd-spark-line { stroke:var(--accent); stroke-width:1.5; vector-effect:non-scaling-stroke; }
.cmd-spark-zero { stroke:var(--border-bright); stroke-width:1; stroke-dasharray:3 3;
  vector-effect:non-scaling-stroke; }

@media (max-width:720px) {
  .cmd-coverage { font-size:10px; gap:.5rem .75rem; }
  .cmd-cov-asof { margin-left:0; width:100%; }
  #commoditiesTable td.cmd-live,
  #commoditiesTable td.cmd-public,
  #commoditiesTable td.cmd-none { max-width:12rem; }
}

/* The `none` cell is a STATEMENT, not an absence — "no government body publishes this number".
   It is the one thing on this screen a competitor cannot copy without licensing a vendor or lying,
   so it gets a deliberate rule and tint rather than reading as the dimmest cell in the row. The
   `public` state stays quieter: "we haven't ingested it yet" is a fact about us, not about the world. */
#commoditiesTable td.cmd-none {
  background: linear-gradient(90deg, rgba(122,140,163,.10), transparent 60%);
  border-left: 2px solid var(--text-faint);
}
#commoditiesTable td.cmd-none .cmd-note { color: var(--text-secondary); }
#commoditiesTable td.cmd-public { border-left: 2px solid transparent; }

/* A held government-authored price. The KIND chip is load-bearing, not decoration: the number alone
   reads as "the price of beef" when it is specifically the national daily negotiated boxed-beef
   cutout, Choice 600-900 lb, reported in arrears. */
.cmd-price { display: flex; flex-wrap: wrap; align-items: baseline; gap: .3rem .45rem; margin-bottom: .3rem; }
.cmd-price b { font-family: var(--mono); font-size: var(--fs-sm, .8125rem); color: var(--text-primary); }
.cmd-price-unit { font-family: var(--mono); font-size: var(--fs-2xs); color: var(--text-secondary); }
.cmd-price-kind { font-size: 9.5px; text-transform: uppercase; letter-spacing: .06em; font-weight: 700;
  color: var(--green); background: var(--green-dim); padding: 1px 5px; border-radius: 999px; }
.cmd-price-spec { flex: 1 1 100%; font-size: var(--fs-2xs); color: var(--text-muted); line-height: 1.3; }
.cmd-asof { font-family: var(--mono); }
/* Quantities are NOT prices — a different chip colour so tonnes can never be skimmed as dollars. */
.cmd-qty-kind { color: var(--accent); background: var(--accent-dim); }
