/* Quant table pagination — Prev/Next + numbered chips + range info.
   Sits directly under #quant-table. Hidden when ≤100 surviving rows. */
.quant-pagination {
  display: flex; align-items: center; gap: 8px;
  flex-wrap: wrap;
  padding: 10px 4px 14px;
  font-size: 12px;
}
.quant-pagination button {
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 4px;
  padding: 4px 10px; font: inherit; font-size: 12px;
  cursor: pointer;
  transition: border-color 80ms, color 80ms;
}
.quant-pagination button:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.quant-pagination button:disabled { opacity: 0.4; cursor: default; }
.quant-pagination .quant-page-prev,
.quant-pagination .quant-page-next {
  font-weight: 600;
}
.quant-pagination .quant-page-nums {
  display: inline-flex; gap: 4px; align-items: center;
  margin-left: 8px;
}
.quant-pagination .quant-page-num {
  min-width: 28px; padding: 4px 8px;
  font-variant-numeric: tabular-nums;
}
.quant-pagination .quant-page-num.active {
  background: var(--accent); color: var(--bg);
  border-color: var(--accent); font-weight: 700;
}
.quant-pagination .quant-page-num.active:hover { color: var(--bg); }
.quant-pagination .quant-page-ellipsis {
  color: var(--muted); padding: 0 4px;
}
.quant-pagination .quant-page-info {
  margin-left: auto; padding: 0 4px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Prominent count + capped-warning badges on the Quant description
   strip. Default font-size on the strip is 12px (set in the toolbar);
   bump the counts so they pop and color the cap warning so the user
   sees the cap is in effect without reading the rest of the line. */
#quant-desc .quant-desc-count {
  font-size: 16px;
  font-weight: 700;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
#quant-desc .quant-desc-total {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
#quant-desc .quant-desc-cap {
  color: #e4c98a;
  font-size: 11px;
  margin-left: 2px;
}

/* Stock count shown directly above the Quant table header. */
.quant-table-count {
  font-size: 12px;
  color: var(--muted, #8b949e);
  margin: 6px 0 4px;
}
.quant-table-count .quant-table-count-num {
  font-size: 15px;
  font-weight: 700;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.quant-table-count .quant-table-count-sub {
  font-size: 11px;
  margin-left: 2px;
}

:root {
  --bg: #0e1116;
  --panel: #161b22;
  --panel-2: #1c2128;
  --border: #30363d;
  --text: #e6edf3;
  --muted: #8b949e;
  --accent: #58a6ff;
  --green: #3fb950;
  --orange: #db8b1f;
  --red: #f85149;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; background: var(--bg); color: var(--text);
  font: 15px/1.5 -apple-system, BlinkMacSystemFont, "SF Pro Text", Helvetica, Arial, sans-serif; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

/* Finviz-style compact one-row header: logo on the left, primary nav inline,
   search anchored right. Tight vertical padding so the content area starts
   high on the page. */
header { padding: 6px 20px; border-bottom: 1px solid var(--border); }
header h1 { margin: 0; font-size: 22px; font-weight: 700; letter-spacing: -0.01em; }
.header-row { display: flex; align-items: center; gap: 24px; }
.site-brand { line-height: 1.1; flex-shrink: 0; font-size: 20px; margin: 0; }
.site-brand a { display: inline-block; color: var(--text); text-decoration: none; }
.site-brand-text { white-space: nowrap; font-weight: 600; }
.site-logo {
  display: block;
  height: 32px;
  width: auto;
  max-width: min(300px, 36vw);
  object-fit: contain;
}
.meta-strip { color: var(--muted); font-size: 12px; padding: 2px 20px 6px; }
#search {
  flex: 1; max-width: 520px; margin-left: auto;
  padding: 6px 12px; background: var(--panel);
  color: var(--text); border: 1px solid var(--border); border-radius: 7px;
  font: inherit; font-size: 13px;
}

/* Global breadcrumb bar: "← back · Themes / Theme / Sub-industry / Ticker".
   Visible on every view so the user always has a back-out path AND a
   site-map readout of where they are. */
.breadcrumb-bar {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 4px 20px 2px;
  font-size: 12px;
  color: var(--muted);
}
.breadcrumb-bar .back {
  color: var(--accent);
  text-decoration: none;
  font-weight: 600;
  font-size: 12px;
}
.breadcrumb-bar .back:hover { text-decoration: underline; }
.breadcrumb-bar .bc-sep-back { color: var(--border); }
.breadcrumb { color: var(--muted); font-size: 12px; padding: 0; }
.breadcrumb .current { color: var(--text); }
.breadcrumb .sep { margin: 0 4px; }
.breadcrumb a { color: var(--accent); text-decoration: none; }
.breadcrumb a:hover { text-decoration: underline; }

/* Profile view used to hide the breadcrumb; now keeps it visible so the
   sector-chain navigation back to Theme / Sub-industry stays available
   from inside a ticker page. */
body.view-ticker-detail .meta-strip { display: none; }
body.view-ticker-detail main { padding-top: 4px; max-width: none; }

main { padding: 4px 20px 40px; max-width: none; }

h2 { font-size: 18px; font-weight: 700; letter-spacing: -0.01em; margin: 8px 0 4px; }
h3 { font-size: 13px; font-weight: 600; margin: 12px 0 6px; color: var(--text); }
.muted { color: var(--muted); }

/* Compact one-row-per-subtheme listing. Was an oversize grid of cards
   with descriptions and ticker pills; now each entry is a slim row with
   subtheme name (link), avg 6M return, ticker count, and inline ticker
   chips. Reads like a table, not a brochure. */
.card-grid {
  display: flex; flex-direction: column; gap: 0;
  border: 1px solid var(--border); border-radius: 6px; overflow: hidden;
  background: var(--panel);
}
.card {
  display: flex; flex-direction: column; padding: 6px 12px;
  color: var(--text); text-decoration: none;
  border-bottom: 1px solid var(--border);
  min-height: 0;
}
.card:last-child { border-bottom: 0; }
.card:hover { background: var(--panel-2); text-decoration: none; }
.card:active { background: var(--panel-2); }
.card-subtheme-tag {
  display: inline-block; align-self: center;
  font-size: 10px; font-weight: 600; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.05em;
  margin: 0 6px 0 0; flex-shrink: 0;
}
.card-head { display: flex; align-items: center; justify-content: flex-start; gap: 10px; margin-bottom: 0; }
.card-pills { display: inline-flex; gap: 6px; flex-shrink: 0; align-items: center; margin-left: auto; }
.card-title { font-size: 13px; font-weight: 500; line-height: 1.3; flex: 0 0 auto; }
.card-stats { color: var(--muted); font-size: 12px; margin-bottom: 0; display: inline-flex; gap: 6px; align-items: center; }
.card-desc {
  color: var(--muted); font-size: 12px; line-height: 1.3;
  margin: 0; opacity: 0.8;
  flex: 1; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.clamp-3 {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
}
.card-examples { color: var(--muted); font-size: 12px; margin-top: auto; padding-top: 6px; font-family: ui-monospace, "SF Mono", Menlo, monospace; }

/* Theme-page subtheme rows are compact — title is a link, description
   clamped to one line, and ticker chips sit inline on the right. */
.card-expanded .card-title a { color: var(--accent); }
.card-expanded .card-title a:hover { color: var(--accent); text-decoration: underline; }
.card-stocks {
  display: inline-flex; flex-wrap: wrap; gap: 2px 4px;
  margin: 0; padding: 0; border: 0;
}
.card-stock-link {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 11px; font-weight: 500;
  padding: 0 4px; border-radius: 0;
  background: transparent; color: var(--muted);
  border: 0;
  transition: color 0.1s;
}
.card-stock-link:hover { color: var(--accent); text-decoration: underline; }

.return-pill, .ticker-pill, .k-pill {
  flex-shrink: 0; padding: 1px 7px; border-radius: 8px; font-size: 11px; font-weight: 600;
  font-variant-numeric: tabular-nums; background: var(--panel-2); color: var(--muted);
  border: 1px solid var(--border); line-height: 1.2;
}
.return-pill.ret-pos { background: rgba(63, 185, 80, 0.12);  border-color: rgba(63, 185, 80, 0.32);  color: var(--green); }
.return-pill.ret-neg { background: rgba(123, 175, 212, 0.12);  border-color: rgba(123, 175, 212, 0.32);  color: #7BAFD4; }

.toolbar { margin: 4px 0 8px; align-items: flex-end; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.toolbar > div:first-child { flex: 1; min-width: 240px; }
.toolbar h2 { margin: 0; }
.sort-controls { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.sort-controls .muted { font-size: 10px; text-transform: uppercase; letter-spacing: 0.05em; margin-right: 4px; font-weight: 600; }
/* One compact line: ticker/subtheme count on the left, Group picker on the right. */
.theme-meta {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin: 0 0 4px;
}
.chip {
  background: transparent; color: var(--muted); border: 0;
  padding: 0; font: inherit; font-size: 12px; cursor: pointer;
  transition: color 0.1s;
}
.chip:hover { color: var(--text); }
.chip.active { color: var(--accent); font-weight: 600; }
/* Dot separators between consecutive chips inside a chip container.
   Pure CSS — no markup change needed. */
#subtheme-filter-chips,
.screener-row > div.screener-months,
[data-returns-level],
.chart-toolbar {}
#subtheme-filter-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 0 8px; row-gap: 4px; }
#subtheme-filter-chips .chip + .chip::before { content: "·"; color: var(--border); margin-right: 8px; }
/* Meta chips ("Select all" / "Clear") sit at the head of the chip row with
   a subtle outline so they don't read as another subtheme. Suppress the
   dot separator on either side of them. */
#subtheme-filter-chips .chip-meta {
  border: 1px solid var(--border); border-radius: 3px;
  padding: 0 6px; font-size: 11px;
  text-transform: uppercase; letter-spacing: 0.04em;
}
#subtheme-filter-chips .chip-meta:hover { border-color: var(--accent); }
#subtheme-filter-chips .chip-meta + .chip::before,
#subtheme-filter-chips .chip + .chip-meta::before { content: ""; margin-right: 0; }
#subtheme-filter-chips .chip-meta + .chip-meta { margin-left: 4px; }

.subtheme-group { margin-bottom: 32px; }
.subtheme-header {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  margin: 0 0 14px; padding-bottom: 8px; border-bottom: 1px solid var(--border);
}
.subtheme-header h3 {
  margin: 0; font-size: 16px; font-weight: 600; color: var(--text);
}
.subtheme-header .muted { font-size: 12px; }

.row { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 8px; }
.btn {
  background: var(--panel); color: var(--text); border: 1px solid var(--border);
  border-radius: 6px; padding: 6px 12px; font: inherit; cursor: pointer;
}
.btn:hover { border-color: var(--accent); text-decoration: none; }

table {
  width: 100%; border-collapse: collapse; font-size: 11px;
  background: var(--panel); border: 1px solid var(--border); border-radius: 4px; overflow: hidden;
}
th, td { padding: 1px 6px; text-align: left; border-bottom: 1px solid var(--border); line-height: 1.2; vertical-align: middle; }
/* Long subtheme names blow up row height when allowed to wrap. Cap the
   column width and ellipsize; the full name still shows on hover (title)
   and clicks still navigate. */
#theme-stocks-table td:nth-child(3),
#theme-stocks-table th:nth-child(3),
#tickers-table .subtheme-col,
.subtheme-cell {
  max-width: 160px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
th { background: var(--panel-2); color: var(--muted); font-weight: 600; font-size: 10px;
     text-transform: uppercase; letter-spacing: 0.03em; padding: 3px 6px; }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
tr:last-child td { border-bottom: none; }
tr:hover td { background: var(--panel-2); }
tr.empty-row:hover td { background: transparent; }
tr.empty-row td {
  text-align: center; color: var(--muted); font-style: italic;
  padding: 14px 8px;
}

/* Column-set toggle. `.mode-trailing` shows trailing-return columns and
   hides the 12 monthly columns; `.mode-monthly` does the inverse. Apply
   the class to the <table> and the right cells disappear via CSS without
   re-rendering. */
table.mode-trailing .col-monthly,
table.mode-trailing .month-col,
table.mode-trailing .month-cell { display: none; }
table.mode-monthly .col-trailing { display: none; }

/* The toggle pills above each table. Plain text-button look, accent for
   the active mode. */
.table-mode-toggle {
  display: inline-flex; gap: 4px; align-items: center;
  font-size: 11px; margin-left: 12px;
}
.table-mode-toggle .muted {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.05em;
  font-weight: 600; margin-right: 2px;
}
.table-mode-toggle button {
  background: transparent; color: var(--muted); border: 1px solid var(--border);
  border-radius: 3px; padding: 1px 8px; font: inherit; font-size: 11px;
  cursor: pointer; text-transform: uppercase; letter-spacing: 0.04em;
}
.table-mode-toggle button:hover { color: var(--text); border-color: var(--accent); }
.table-mode-toggle button.active { color: var(--accent); border-color: var(--accent); font-weight: 600; }

/* Quant-page-only order toggle: identical look to .table-mode-toggle so the
   user sees a familiar pair of chips. Lives next to Trailing/Monthly on the
   desc line. */
.quant-order-toggle {
  display: inline-flex; gap: 4px; align-items: center;
  font-size: 11px; margin-left: 12px;
}
.quant-order-toggle .muted {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.05em;
  font-weight: 600; margin-right: 2px;
}
.quant-order-toggle button {
  background: transparent; color: var(--muted); border: 1px solid var(--border);
  border-radius: 3px; padding: 1px 8px; font: inherit; font-size: 11px;
  cursor: pointer; text-transform: uppercase; letter-spacing: 0.04em;
}
.quant-order-toggle button:hover { color: var(--text); border-color: var(--accent); }
.quant-order-toggle button.active { color: var(--accent); border-color: var(--accent); font-weight: 600; }

.badge { font-size: 11px; padding: 2px 6px; border-radius: 3px; background: var(--panel-2); }
.badge-approved { background: rgba(63, 185, 80, 0.15); color: var(--green); }
.badge-pending  { background: rgba(219, 139, 31, 0.15); color: var(--orange); }
.badge-flagged  { background: rgba(248, 81, 73, 0.15);  color: var(--red); }
.badge-rejected { background: rgba(139, 148, 158, 0.15); color: var(--muted); }

dl { display: grid; grid-template-columns: 200px 1fr; gap: 8px 18px; max-width: 900px; }
dt { color: var(--muted); font-size: 12px; }
dd { margin: 0; font-size: 13px; }

.search-row { display: block; padding: 8px 0; border-bottom: 1px solid var(--border); }
.search-row:last-child { border-bottom: none; }


.logo {
  display: inline-block; vertical-align: middle;
  border-radius: 4px; object-fit: contain; flex-shrink: 0;
}
/* Tickers without logo coverage collapse out of layout entirely
   so they don't leave a 22/40/56 px gap next to the symbol text. */
.logo.logo-missing { display: none; }
.ticker-cell { display: inline-flex; align-items: center; gap: 8px; }
#ticker-detail-view #td-ticker { display: flex; align-items: center; gap: 14px; }
/* Multi-window K-Ratio grid — always 2x2 (forced two rows × two columns)
   regardless of viewport width per user spec. Each cell mirrors the
   color rule of the price-header quote: green for positive K, yellow
   for negative, white for null/zero. Sits between the identity row and
   the Finviz grid; max-width keeps it from sprawling on wide screens. */
.td-kratio-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px 10px; margin: 8px 0 12px; max-width: 480px;
}
.td-kr-cell {
  background: var(--panel); border: 1px solid var(--border); border-radius: 4px;
  padding: 6px 10px; display: flex; flex-direction: column;
  font-feature-settings: "tnum" 1;
}
.td-kr-label { font-size: 10px; color: var(--muted); text-transform: uppercase;
  letter-spacing: 0.04em; }
.td-kr-value { font-size: 22px; font-weight: 700; line-height: 1.05; margin-top: 2px; }
.td-kr-value.td-kr-up   { color: #3fb950; }
.td-kr-value.td-kr-down { color: #f1c40f; }
.td-kr-value.td-kr-flat { color: #ffffff; }
/* Inline K-Ratio readout in the chart toolbar — recomputed on every range
   change so the value always matches what's plotted. Same color rule as
   the 2x2 K-Ratio box above. */
.td-chart-kratio {
  display: inline-flex; align-items: center; gap: 6px; margin-left: 14px;
  font-size: 12px; font-weight: 700; font-feature-settings: "tnum" 1;
}
.td-chart-kratio:empty { display: none; }
.td-chart-kratio-label { color: var(--muted); font-weight: 500; text-transform: uppercase;
  letter-spacing: 0.04em; font-size: 10px; }
.td-chart-kratio.td-chart-kratio-up   { color: #3fb950; }
.td-chart-kratio.td-chart-kratio-down { color: #f1c40f; }
.td-chart-kratio.td-chart-kratio-flat { color: #ffffff; }
/* Quote header — floats to the top right of the ticker detail page, above
   the heading row. Date/time on top in muted grey, large white price,
   colored change below (green +, yellow -, white flat). */
#ticker-detail-view .td-quote {
  float: right; text-align: right; margin: 0 0 8px 16px;
  font-feature-settings: "tnum" 1; line-height: 1.15;
}
.td-quote-ts { font-size: 11px; color: var(--muted); text-transform: uppercase;
  letter-spacing: 0.04em; }
.td-quote-price { font-size: 32px; font-weight: 700; color: #ffffff;
  letter-spacing: -0.01em; margin-top: 2px; }
.td-quote-change { font-size: 14px; font-weight: 600; margin-top: 2px; }
.td-quote-change.td-quote-up   { color: #3fb950; }
.td-quote-change.td-quote-down { color: #f1c40f; }
.td-quote-change.td-quote-flat { color: #ffffff; }
html.mobile-site #ticker-detail-view .td-quote {
  float: none; text-align: left; margin: 4px 0 8px 0;
}
html.mobile-site .td-quote-price { font-size: 26px; }

/* Semi relationship graph — D3 force-directed spider web. */
.graph-toolbar { display: flex; flex-direction: column; gap: 8px;
  margin: 8px 0 12px; }
.graph-toolbar-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.graph-edge-chip { padding: 4px 10px; border-radius: 14px; cursor: pointer;
  background: transparent; color: var(--text); font-size: 12px;
  border: 1px solid var(--border); display: inline-flex; align-items: center; gap: 6px; }
.graph-edge-chip:not(.active) { opacity: 0.5; }
.graph-swatch { display: inline-block; width: 10px; height: 10px; border-radius: 50%; }
.graph-layer-row { font-size: 11px; }
.graph-layer-swatch { display: inline-flex; align-items: center; gap: 4px;
  margin-right: 8px; text-transform: capitalize; }
.graph-wrap { width: 100%; overflow: hidden; border: 1px solid var(--border);
  border-radius: 8px; background: var(--bg); }
#semi-graph-svg { width: 100%; height: 720px; display: block; }
.graph-links line { transition: stroke-opacity 0.2s; }
.graph-links line.dim { stroke-opacity: 0.08 !important; }
.graph-node text { paint-order: stroke; stroke: rgba(13, 17, 23, 0.85);
  stroke-width: 3px; pointer-events: none; }
.graph-node.dim { opacity: 0.18; }
.graph-node circle { transition: r 0.15s; }
.graph-node:hover circle { stroke: #58a6ff; stroke-width: 2.5px; }
/* Subtheme-filter popover — search + theme-grouped checklist. Sits below the
   toolbar; max-height + scroll keeps long lists tractable. */
#subtheme-graph-filter-panel { background: var(--panel); border: 1px solid var(--border);
  border-radius: 6px; padding: 10px; margin: 8px 0; max-height: 460px; overflow-y: auto;
  display: flex; flex-direction: column; gap: 10px; }
.subtheme-filter-head { display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  position: sticky; top: -10px; background: var(--panel); padding-top: 4px;
  padding-bottom: 4px; z-index: 1; }
.subtheme-filter-head #subtheme-graph-search { flex: 1 1 220px; min-width: 0;
  padding: 6px 10px; background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 4px; font: inherit; font-size: 13px; }
.subtheme-filter-body { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 8px 14px; }
.subtheme-filter-group { display: flex; flex-direction: column; gap: 4px;
  border: 1px solid var(--border); border-radius: 4px; padding: 8px; background: var(--bg); }
.subtheme-filter-themehead { display: inline-flex; gap: 6px; align-items: center;
  cursor: pointer; font-size: 12px; }
.subtheme-filter-opts { display: flex; flex-direction: column; gap: 3px;
  padding-left: 18px; }
.subtheme-filter-opt { display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; cursor: pointer; }
.subtheme-filter-opt:hover { color: var(--accent); }
/* Quant-pipeline stage reorder buttons sit at the end of each stage card. */
.quant-stage-reorder { display: inline-flex; gap: 4px; margin-left: auto; align-self: end; }
.quant-stage-reorder .chip { padding: 2px 8px; border: 1px solid var(--border); border-radius: 4px; }
.quant-stage-reorder .chip[disabled] { opacity: 0.35; cursor: not-allowed; }
/* Show-by view dropdown above the pipeline. */
.quant-view-row {
  display: flex; align-items: center; gap: 8px; margin: 0 0 6px;
  font-size: 12px;
}
.quant-view-row select { width: auto; min-width: 130px; padding: 4px 8px;
  background: var(--bg); color: var(--text); border: 1px solid var(--border);
  border-radius: 4px; font: inherit; font-size: 12px; }
/* Quant table group rows (Themes / Subthemes views). Bolder strip + tinted
   bg so the aggregate stands out from the constituent stock rows that
   render below when expanded. */
#quant-table tr.quant-group-row { background: var(--panel); }
#quant-table tr.quant-group-row .quant-group-name strong { font-weight: normal; }
#quant-table tr.quant-child-row { background: transparent; }
#quant-table tr.quant-child-row td:first-child + td { padding-left: 28px; }
/* Subtle zebra striping on stock rows (group / child rows opt out so their
   own backgrounds keep showing through). */
#quant-table tbody tr:nth-child(even):not(.quant-group-row):not(.quant-child-row) {
  background: rgba(255, 255, 255, 0.025);
}
#quant-table tbody tr:nth-child(odd):not(.quant-group-row):not(.quant-child-row):hover,
#quant-table tbody tr:nth-child(even):not(.quant-group-row):not(.quant-child-row):hover {
  background: rgba(99, 179, 237, 0.06);
}
/* Slightly larger cell text for the Quant table — base 11px is too small to
   skim at distance. Header bumps a touch too so it stays in proportion. */
#quant-table { font-size: 13px; }
#quant-table th { font-size: 11px; }
.quant-group-name { display: inline-flex; align-items: center; gap: 6px; }
.quant-expand-btn {
  background: transparent; border: 1px solid var(--border); color: var(--text);
  width: 18px; height: 18px; line-height: 16px; padding: 0; border-radius: 3px;
  font-size: 10px; cursor: pointer; text-align: center;
}
.quant-expand-btn:hover { border-color: var(--accent); color: var(--accent); }
.quant-expand-btn.open { background: var(--accent); color: #0e1116; border-color: var(--accent); }
.graph-tooltip { position: fixed; z-index: 60; background: var(--panel);
  border: 1px solid var(--border); border-radius: 6px; padding: 8px 10px;
  font-size: 12px; pointer-events: none; box-shadow: 0 4px 12px rgba(0,0,0,0.4); }
/* Side panel that opens when a node is clicked. Fixed to the right edge
   of the viewport so it overlays the graph without reflowing it. */
.graph-panel { position: fixed; top: 80px; right: 16px; width: 380px;
  max-height: calc(100vh - 100px); overflow-y: auto; z-index: 70;
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 8px; padding: 14px 16px; box-shadow: 0 8px 24px rgba(0,0,0,0.5);
  font-size: 12px; }
.graph-panel-head { display: flex; align-items: flex-start; justify-content: space-between;
  gap: 8px; margin-bottom: 6px; }
.graph-panel-name { font-size: 16px; font-weight: 700; color: #e6edf3; }
.graph-panel-layer { font-size: 11px; text-transform: capitalize; }
.graph-panel-close { background: none; border: 0; color: var(--muted);
  font-size: 22px; cursor: pointer; padding: 0 4px; line-height: 1; }
.graph-panel-close:hover { color: var(--text); }
.graph-panel-desc { margin: 4px 0 10px; color: var(--text); font-size: 12px;
  line-height: 1.5; }
.graph-panel-open { display: inline-block; margin: 4px 0 12px;
  color: var(--accent); text-decoration: none; font-weight: 600; }
.graph-panel-open:hover { text-decoration: underline; }
.graph-panel-isolate { display: inline-block; margin: 0 0 12px;
  background: rgba(88, 166, 255, 0.10); color: var(--accent);
  border: 1px solid var(--accent); border-radius: 4px;
  padding: 5px 12px; font: inherit; font-size: 12px; font-weight: 600;
  cursor: pointer; }
.graph-panel-isolate:hover { background: rgba(88, 166, 255, 0.20); }
.graph-focus-pill { background: rgba(88, 166, 255, 0.10);
  border: 1px solid var(--accent); border-radius: 6px;
  padding: 6px 12px; font-size: 12px; color: var(--text);
  display: flex; align-items: center; gap: 10px; }
.graph-focus-pill button { background: none; border: 0; color: var(--accent);
  cursor: pointer; font: inherit; font-size: 12px; text-decoration: underline;
  margin-left: auto; padding: 0; }
.graph-focus-pill button:hover { color: #79c0ff; }
.graph-panel-group { margin: 10px 0; padding-top: 8px;
  border-top: 1px dashed rgba(140,149,159,0.18); }
.graph-panel-group:first-of-type { border-top: 0; padding-top: 0; }
.graph-panel-group-title { font-size: 11px; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--accent); margin-bottom: 4px; }
/* Bottlenecks bucket — orange-tinted so the critical-path dependencies
   stand out from the regular supplier/customer lists. */
.graph-panel-bottleneck { background: rgba(251, 140, 0, 0.06);
  border: 1px solid rgba(251, 140, 0, 0.30); border-radius: 6px;
  padding: 8px 10px; margin-top: 0; padding-top: 6px; }
.graph-panel-bottleneck + .graph-panel-group { border-top: 1px dashed rgba(140,149,159,0.18); padding-top: 8px; }
.graph-panel-bottleneck .graph-panel-group-title { color: #fb8c00; }
.graph-panel-list { margin: 0; padding-left: 16px; list-style: disc;
  color: var(--text); }
.graph-panel-list li { line-height: 1.5; margin-bottom: 4px; }
.graph-panel-jump { color: #e6edf3; font-weight: 600; text-decoration: none; }
.graph-panel-jump:hover { color: var(--accent); text-decoration: underline; }

/* Semi Subsectors — drill-down page from /#semi-ecosystem. Each layer
   is a section; each subsector is a block with a name + a vertical
   list of "Company Name (TICKER)" rows. Empty subsectors render a
   muted "no tickers yet" placeholder. */
.semi-sub-page { display: flex; flex-direction: column; gap: 22px; margin-top: 14px; }
.semi-sub-layer { background: var(--panel); border: 1px solid var(--border);
  border-radius: 8px; padding: 14px 18px; }
.semi-sub-layer-title { margin: 0 0 12px; font-size: 16px; font-weight: 700;
  color: var(--accent); letter-spacing: -0.01em; }
.semi-sub-block { margin: 0 0 14px; padding: 8px 12px; background: var(--bg);
  border: 1px solid var(--border); border-radius: 6px; }
.semi-sub-block:last-child { margin-bottom: 0; }
.semi-sub-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 4px; }
.semi-sub-name { font-size: 13px; font-weight: 600; color: #e6edf3; }
.semi-sub-count { font-size: 11px; font-family: ui-monospace, "SF Mono", Menlo, monospace; }
.semi-sub-list { margin: 4px 0 2px; padding-left: 16px; list-style: disc; color: var(--text); }
.semi-sub-list li { font-size: 12px; line-height: 1.7; }
.semi-sub-name-link { color: #e6edf3; font-weight: 600; text-decoration: none; }
.semi-sub-name-link:hover { color: #ffffff; text-decoration: underline; }
.semi-sub-ticker { color: var(--accent); text-decoration: none;
  font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 11px; }
.semi-sub-ticker:hover { text-decoration: underline; }
.semi-sub-priv { color: var(--muted);
  font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 11px; }
/* Research-lab subsection within a subsector — sits below the companies
   list, lightly indented and visually subordinate. */
.semi-sub-labs { margin-top: 6px; padding-top: 6px;
  border-top: 1px dashed rgba(140, 149, 159, 0.18); }
.semi-sub-labs-title { font-size: 10px; text-transform: uppercase;
  letter-spacing: 0.08em; margin-bottom: 3px; }
.semi-sub-labs-list li { font-size: 12px; line-height: 1.7; }
.semi-sub-lab-link { color: #d2a8ff; font-weight: 600; text-decoration: none; }
.semi-sub-lab-link:hover { color: #e7c8ff; text-decoration: underline; }
.semi-sub-empty { font-size: 11px; padding: 2px 0 2px 4px; font-style: italic; }
.semi-sub-link { color: var(--accent); font-size: 13px; text-decoration: none;
  font-weight: 600; }
.semi-sub-link:hover { text-decoration: underline; }

/* Semiconductor Ecosystem — curated grouped list of public + private
   names across the semi value chain. Each card: logo, company name,
   ticker (or 'Private'). Grid wraps responsively. */
.semi-page { display: flex; flex-direction: column; gap: 22px; margin-top: 14px; }
.semi-group { background: var(--panel); border: 1px solid var(--border);
  border-radius: 8px; padding: 14px 16px; }
.semi-group-title { margin: 0 0 10px; font-size: 14px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.04em; color: var(--accent); }
.semi-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 8px 14px;
}
.semi-card {
  display: flex; align-items: center; gap: 10px;
  padding: 6px 10px; border-radius: 6px; background: var(--bg);
  border: 1px solid var(--border);
}
.semi-card .logo { flex: 0 0 auto; border-radius: 4px; }
.semi-logo-placeholder { display: inline-block; width: 22px; height: 22px; flex: 0 0 auto;
  background: rgba(140, 149, 159, 0.08); border-radius: 4px; }
.semi-card-text { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.semi-name { font-size: 13px; color: var(--text); overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; display: block; }
/* Company-name link: bold off-white, distinct from the blue ticker link.
   Underlines only on hover so the row stays calm at rest. */
.semi-name-link { color: #e6edf3; font-weight: 700; text-decoration: none; }
.semi-name-link:hover { color: #ffffff; text-decoration: underline; }
.semi-meta { font-size: 11px; line-height: 1.2; margin-top: 2px; }
.semi-ticker { font-family: ui-monospace, "SF Mono", Menlo, monospace; color: var(--accent);
  text-decoration: none; }
.semi-ticker:hover { text-decoration: underline; }
.semi-priv { font-family: ui-monospace, "SF Mono", Menlo, monospace; color: var(--muted);
  font-size: 11px; }

/* Taxonomy page — nested tree of Sector → Industry → Theme → Subtheme
   → Subsector → Tickers. Indented via nested padding, no horizontal
   scrolling. Each row has a chevron toggle, name, and child/ticker count. */
.taxonomy-tree { margin-top: 12px; }
.tax-node { padding: 1px 0; }
.tax-row { display: flex; align-items: baseline; gap: 8px; padding: 3px 0; }
.tax-row:hover { background: rgba(88, 166, 255, 0.04); }
.tax-toggle {
  background: none; border: none; color: var(--muted); cursor: pointer;
  font-size: 11px; padding: 0 4px; width: 22px; text-align: left;
}
.tax-toggle:hover { color: var(--text); }
.tax-name { font-weight: 500; color: var(--text); }
.tax-meta { font-size: 11px; margin-left: 8px; }
.tax-children { padding-left: 22px; border-left: 1px dotted rgba(140, 149, 159, 0.18); margin-left: 6px; }
.tax-kind-sector   > .tax-row .tax-name { font-size: 18px; font-weight: 700; letter-spacing: -0.01em; }
.tax-kind-industry > .tax-row .tax-name { font-size: 15px; font-weight: 600; color: var(--accent); }
.tax-kind-theme    > .tax-row .tax-name { font-size: 14px; font-weight: 600; }
.tax-kind-subtheme > .tax-row .tax-name { font-size: 13px; font-weight: 500; }
.tax-kind-subsector > .tax-row .tax-name { font-size: 13px; font-weight: 400; color: var(--text); }
.tax-tickers {
  display: flex; flex-wrap: wrap; gap: 4px 14px; padding-top: 6px; padding-bottom: 6px;
}
.tax-ticker {
  display: inline-flex; flex-direction: column; gap: 2px;
  font-size: 12px; color: var(--text); text-decoration: none;
  padding: 4px 10px; border-radius: 4px; background: rgba(88, 166, 255, 0.06);
  min-width: 140px;
}
.tax-ticker:hover { background: rgba(88, 166, 255, 0.14); color: var(--accent); }
.tax-ticker .muted { font-size: 10px; }

/* Quant page — factor toggle + weight blocks sit side by side above the
   composite-score table. Each factor is a self-contained card so the read
   "this factor is on, this is the weight" is obvious at a glance. */
.quant-controls { display: flex; gap: 8px; flex-wrap: wrap; align-items: center;
  margin: 8px 0 12px; }
.quant-factor { display: flex; flex-direction: row; flex-wrap: wrap; gap: 4px 12px;
  background: var(--panel); border: 1px solid var(--border); border-radius: 4px;
  padding: 6px 10px; min-width: 200px; align-items: center; }

/* ── Finviz-style tabbed filter panel ────────────────────────────────── */
.quant-panel {
  background: var(--panel); border: 1px solid var(--border); border-radius: 8px;
  margin: 4px 0 14px;
}
.quant-tabs {
  display: flex; gap: 4px; padding: 4px 8px 0;
  border-bottom: 2px solid var(--accent);
  flex-wrap: wrap;
}
/* Inactive tabs read as dim, raised buttons; the active tab is a solid
   accent fill so the selected screen is unmistakable. */
.quant-tab {
  background: var(--panel-2); color: var(--muted);
  border: 1px solid var(--border); border-bottom: 0;
  border-radius: 6px 6px 0 0;
  padding: 6px 14px; font: inherit; font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.04em; cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px;
  transition: background 90ms, color 90ms, border-color 90ms;
}
.quant-tab:hover {
  background: var(--panel); color: var(--text);
  border-color: var(--accent);
}
.quant-tab.active {
  background: var(--accent); color: #0b1220;
  border-color: var(--accent); font-weight: 800;
}
.quant-tab-badge {
  background: var(--accent); color: #0b1220; font-size: 10px; font-weight: 700;
  padding: 0 6px; border-radius: 8px; min-width: 18px; text-align: center;
}
/* Invert the badge on the accent-filled active tab so it stays legible. */
.quant-tab.active .quant-tab-badge { background: #0b1220; color: var(--accent); }

/* ── Top-level Quant MODE tabs: Factor screener vs Ask AI ─────────────────
   Splits the two screeners so the page isn't jammed; swaps only the input
   panes (results table is shared below). Larger than the inner filter tabs. */
.quant-mode-tabs { display: flex; gap: 6px; margin: 2px 0 12px; }
.quant-mode-tab {
  flex: 0 0 auto; background: var(--panel-2); color: var(--muted);
  border: 1px solid var(--border); border-radius: 8px;
  padding: 8px 18px; font: inherit; font-size: 13px; font-weight: 700;
  letter-spacing: 0.02em; cursor: pointer;
  transition: background 90ms, color 90ms, border-color 90ms;
}
.quant-mode-tab:hover { color: var(--text); border-color: var(--accent); }
.quant-mode-tab.active { background: var(--accent); color: #0b1220; border-color: var(--accent); }
.quant-mode-pane { margin: 0 0 6px; }
/* Mobile: full-width, comfortably tappable mode tabs (one mode at a time). */
html.mobile-site .quant-mode-tabs { gap: 8px; margin-bottom: 10px; }
html.mobile-site .quant-mode-tab { flex: 1 1 0; text-align: center; min-height: 44px; font-size: 14px; padding: 10px 8px; }
/* Progressive funnel visualisation. Universe → stage 1 → stage 2 → final,
   one step per active stage, with the post-stage survivor count shown so
   the user can see how aggressively each filter is narrowing the pool. */
.quant-funnel {
  display: flex; align-items: stretch; gap: 4px; flex-wrap: wrap;
  padding: 6px 10px; border-bottom: 1px solid var(--border);
  background: var(--panel-2); font-size: 11px;
}
.quant-funnel-empty { padding: 6px 10px; font-style: italic; }
.quant-funnel-step {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  background: var(--bg); color: var(--text);
  border: 1px solid var(--accent); border-radius: 4px;
  padding: 3px 8px 3px 10px; min-width: 80px;
  position: relative;
}
.quant-funnel-step.quant-funnel-input {
  background: transparent; border-style: dashed; border-color: var(--border);
}
.quant-funnel-label { font-size: 10px; color: var(--muted); white-space: nowrap; }
.quant-funnel-step:not(.quant-funnel-input) .quant-funnel-label { color: var(--accent); font-weight: 600; }
.quant-funnel-count { font-size: 13px; font-weight: 700; color: var(--text); line-height: 1.1; margin-top: 1px; }
.quant-funnel-x {
  position: absolute; top: -7px; right: -7px;
  background: var(--panel); color: var(--muted); border: 1px solid var(--border);
  border-radius: 50%; width: 18px; height: 18px;
  font-size: 12px; line-height: 1; cursor: pointer; padding: 0;
}
.quant-funnel-x:hover { color: var(--red); border-color: var(--red); }
/* Inline editable threshold inside a funnel chip — lets the user retune a
   stage (or a duplicated stage) without going back to the catalog. */
.quant-funnel-label { display: inline-flex; align-items: center; gap: 0; }
.quant-funnel-pct {
  width: 36px; padding: 0 2px; margin: 0 2px;
  font: inherit; font-size: 10px; font-weight: 700; text-align: center;
  background: var(--panel); color: var(--text);
  border: 1px solid var(--border); border-radius: 2px;
  -moz-appearance: textfield;
}
.quant-funnel-pct::-webkit-outer-spin-button,
.quant-funnel-pct::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.quant-funnel-pct:focus { outline: none; border-color: var(--accent); }
.quant-funnel-metric { margin-left: 3px; }
/* Duplicate-stage button — sits just left of the × in the chip's top-right. */
.quant-funnel-dup {
  position: absolute; top: -7px; right: 13px;
  background: var(--panel); color: var(--muted); border: 1px solid var(--border);
  border-radius: 50%; width: 18px; height: 18px;
  font-size: 10px; line-height: 1; cursor: pointer; padding: 0;
}
.quant-funnel-dup:hover { color: var(--accent); border-color: var(--accent); }
/* Inline ← → buttons under each funnel step so the user can change the
   pipeline order without leaving the funnel. Disabled at the edges. */
.quant-funnel-reorder {
  display: flex; gap: 1px; margin-top: 1px;
}
.quant-funnel-arrow-btn {
  background: var(--panel); color: var(--muted); border: 1px solid var(--border);
  border-radius: 2px; width: 14px; height: 13px;
  font-size: 10px; line-height: 1; cursor: pointer; padding: 0;
}
.quant-funnel-arrow-btn:hover:not(:disabled) { color: var(--accent); border-color: var(--accent); }
.quant-funnel-arrow-btn:disabled { opacity: 0.3; cursor: default; }
/* Drag affordances on the funnel chips: a small grip icon + grab cursor,
   plus colour states for the dragged element and the drop-target's
   insert-before / insert-after edge. */
.quant-funnel-step[draggable="true"] {
  cursor: grab;
  /* Without user-select: none the browser will prefer selecting the chip's
     text on mousedown, which suppresses the dragstart event. Selecting
     a stage chip's text is never useful, so we just turn it off. */
  user-select: none;
  -webkit-user-select: none;
}
.quant-funnel-step[draggable="true"]:active { cursor: grabbing; }
.quant-funnel-grip {
  position: absolute; top: 3px; left: 5px;
  font-size: 11px; line-height: 1; color: var(--accent);
  letter-spacing: -1px;
  user-select: none; pointer-events: none;
  opacity: 0.7;
}
.quant-funnel-step[draggable="true"]:hover .quant-funnel-grip { opacity: 1; }
.quant-funnel-step.dragging { opacity: 0.35; }
.quant-funnel-step.drop-before { box-shadow: -3px 0 0 0 var(--accent); }
.quant-funnel-step.drop-after  { box-shadow:  3px 0 0 0 var(--accent); }
.quant-funnel-arrow {
  display: inline-flex; align-items: center; color: var(--accent);
  font-size: 18px; font-weight: 700; padding: 0 2px;
}
/* Finviz-style dense filter grid: many filters in a small footprint.
   Auto-fill minmax keeps the columns wide enough to fit "K-Ratio 6M" +
   threshold + unit on one line at typical widths, but tight enough to
   fit ~5 columns on a desktop screen. */
.quant-filter-grid {
  /* Two-column factor grid so we use the horizontal space the page has.
     Each cell holds one full filter row (label · preset · dir · input · unit).
     Flows COLUMN-major (top→bottom, then left→right): --qf-rows (set inline
     from the catalog length) fixes the row count so the left column fills
     first. Falls back to a single column on narrow viewports. */
  display: grid;
  grid-template-columns: repeat(2, minmax(290px, 1fr));
  grid-auto-flow: column;
  grid-template-rows: repeat(var(--qf-rows, 1), auto);
  max-width: 1100px;
  gap: 2px 28px; padding: 8px 10px;
}
@media (max-width: 760px) {
  .quant-filter-grid {
    grid-template-columns: 1fr; max-width: 560px;
    grid-auto-flow: row; grid-template-rows: auto;
  }
}
.quant-filter-empty { padding: 12px 8px; font-style: italic; font-size: 11px; }
.quant-filter-row {
  /* Fixed 5-column row layout: label | preset | dir | input | unit.
     Children pin to columns by class so inputs line up vertically across
     rows regardless of which optional controls a given factor has. */
  display: grid; grid-template-columns: 96px 80px 54px 52px auto;
  align-items: center; gap: 5px;
  padding: 2px 4px; border-radius: 3px;
  font-size: 11px; min-height: 22px;
}
.quant-filter-row > .quant-filter-label { grid-column: 1; }
.quant-filter-row > .quant-preset { grid-column: 2; }
.quant-filter-row > .quant-filter-dir,
.quant-filter-row > .quant-filter-gap-dir { grid-column: 3; }
.quant-filter-row > .quant-filter-input,
.quant-filter-row > .quant-filter-gap-input { grid-column: 4; }
.quant-filter-row > .quant-filter-unit { grid-column: 5; justify-self: start; }
/* Inline per-row clear (×) — injected on active rows only. Pinned to the
   row's right edge (absolute) so it sits at a consistent spot regardless of
   how many controls a given row template has. Accent (not red) on hover. */
.quant-filter-row { position: relative; }
.quant-filter-clear {
  position: absolute; right: 2px; top: 50%; transform: translateY(-50%);
  background: transparent; border: 0; color: var(--muted);
  font-size: 14px; line-height: 1; cursor: pointer; padding: 0 4px;
}
.quant-filter-clear:hover { color: var(--accent); }
/* Revgrowth/eg/gm rows have their own 7-col template (no preset slot),
   so their dir/pct controls pin to that template's columns directly. */
.quant-filter-row--revgrowth > .quant-rg-dir,
.quant-filter-row--revgrowth > .quant-eg-dir,
.quant-filter-row--revgrowth > .quant-gm-dir,
.quant-filter-row--revgrowth > .quant-sg-dir,
.quant-filter-row--revgrowth > .quant-mcg-dir { grid-column: 2; }
.quant-filter-row--revgrowth > .quant-rg-pct,
.quant-filter-row--revgrowth > .quant-eg-pct,
.quant-filter-row--revgrowth > .quant-gm-pp,
.quant-filter-row--revgrowth > .quant-sg-pct,
.quant-filter-row--revgrowth > .quant-mcg-pct { grid-column: 3; }
/* Growth rows (Rev / EPS / GM) — grid with a 7-column track so every
   element pins to a fixed column, lining up with the standard rows
   (label col 1, dir col 2, primary input col 3, unit col 4). */
.quant-filter-row--revgrowth {
  grid-template-columns: 96px 42px 50px minmax(10px, auto) auto 32px auto;
}
.quant-filter-row--revgrowth > .quant-rg-years,
.quant-filter-row--revgrowth > .quant-eg-years,
.quant-filter-row--revgrowth > .quant-gm-years,
.quant-filter-row--revgrowth > .quant-sg-years,
.quant-filter-row--revgrowth > .quant-mcg-years { grid-column: 6; }
.quant-filter-row--revgrowth > .quant-rg-pct,
.quant-filter-row--revgrowth > .quant-eg-pct,
.quant-filter-row--revgrowth > .quant-gm-pp,
.quant-filter-row--revgrowth > .quant-rg-years,
.quant-filter-row--revgrowth > .quant-eg-years,
.quant-filter-row--revgrowth > .quant-gm-years,
.quant-filter-row--revgrowth > .quant-sg-pct,
.quant-filter-row--revgrowth > .quant-mcg-pct,
.quant-filter-row--revgrowth > .quant-sg-years,
.quant-filter-row--revgrowth > .quant-mcg-years {
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 3px; padding: 1px 4px;
  font: inherit; font-size: 11px;
}
/* Growth-row child positions are pinned explicitly so the standard 5-col
   filter-unit rule (which puts any .quant-filter-unit at col 5) doesn't
   collide with the 5th DOM child ("past" span). With both at col 5 the
   browser pushes the "past 3 yr" tail to an implicit second visual row
   — fixed by giving each DOM position its own grid-column. */
.quant-filter-row--revgrowth > *:nth-child(4) { grid-column: 4; }
.quant-filter-row--revgrowth > *:nth-child(5) { grid-column: 5; }
.quant-filter-row--revgrowth > *:nth-child(7) { grid-column: 7; }
/* Share-count / market-cap rows use a word direction select (Increase /
   Decrease) instead of ≥/≤, so widen column 2 to fit it. Must follow the
   --revgrowth template above so this grid-template-columns wins. */
.quant-filter-row--growthdir {
  grid-template-columns: 96px 84px 50px minmax(10px, auto) auto 32px auto;
}
.quant-filter-row--growthdir > .quant-sg-dir,
.quant-filter-row--growthdir > .quant-mcg-dir { grid-column: 2; }
/* GM-expansion-streak row: label | ≥ | min input | yrs. Self-contained 4-col
   grid (label col lines up with the other rows at 96px) so it doesn't depend
   on the 7-col revgrowth template's class-pinned columns. */
.quant-filter-row--gmstreak {
  grid-template-columns: 96px 42px 52px auto;
}
.quant-filter-row--gmstreak > .quant-gmstreak-op { grid-column: 2; justify-self: end; }
.quant-filter-row--gmstreak > .quant-gmstreak-min {
  grid-column: 3; width: 44px;
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 3px; padding: 1px 4px;
  font: inherit; font-size: 11px;
}
.quant-filter-row--gmstreak > .quant-gmstreak-unit { grid-column: 4; justify-self: start; }
.quant-filter-row--gmstreak.active > .quant-gmstreak-min { border-color: var(--accent); }
/* Theme/Subtheme taxonomy rows — slightly taller, with extra breathing
   room below so they feel distinct from the fundamental/technical rows. */
.quant-filter-row--tax {
  min-height: 28px;
  margin-bottom: 8px;
}
/* Mkt-cap range row: label | (col-2 spacer) | min | "to" | max | $B.
   Re-uses the standard grid so the min input lands at col 3, lining
   up vertically with the other percentile / threshold inputs. */
.quant-filter-row--mcap {
  grid-template-columns: 96px 80px 42px 52px minmax(8px, auto) 52px auto;
}
.quant-filter-row--mcap > .quant-mcap-range-min { grid-column: 4; }
.quant-filter-row--mcap > .quant-mcap-sep      { grid-column: 5; }
.quant-filter-row--mcap > .quant-mcap-range-max { grid-column: 6; }
.quant-filter-row--mcap > .quant-filter-unit   { grid-column: 7; }
.quant-filter-row--mcap > .quant-mcap-range-min,
.quant-filter-row--mcap > .quant-mcap-range-max {
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 3px; padding: 1px 4px;
  font: inherit; font-size: 11px;
}
.quant-filter-row--mcap.active > .quant-mcap-range-min,
.quant-filter-row--mcap.active > .quant-mcap-range-max { border-color: var(--accent); }
.quant-filter-row--mcap > .quant-mcap-sep { font-size: 10px; color: var(--muted); justify-self: center; }

/* Index-membership row: label + 2 inline checkboxes. */
.quant-filter-row--index { display: flex; align-items: center; gap: 12px; padding: 2px 4px; border-radius: 4px; min-height: 22px; }
.quant-filter-row--index > .quant-filter-label { width: 96px; flex-shrink: 0; text-align: right; }
.quant-index-cb { display: inline-flex; align-items: center; gap: 4px; font-size: 11px; cursor: pointer; color: var(--text); }
.quant-index-cb input { margin: 0; cursor: pointer; }

/* SMA filter rows (50-day / 200-day MA): label + direction dropdown + optional pp + %. */
.quant-filter-row--ma { display: flex; align-items: center; gap: 5px; padding: 2px 4px; border-radius: 4px; min-height: 22px; }
.quant-filter-row--ma > .quant-filter-label { width: 96px; flex-shrink: 0; text-align: right; }
.quant-filter-row--ma > .quant-ma-dir { width: 68px; flex-shrink: 0; background: var(--bg); color: var(--text); border: 1px solid var(--border); border-radius: 3px; padding: 1px 4px; font: inherit; font-size: 11px; }
.quant-filter-row--ma > .quant-ma-pct { width: 52px; flex-shrink: 0; background: var(--bg); color: var(--text); border: 1px solid var(--border); border-radius: 3px; padding: 1px 4px; font: inherit; font-size: 11px; }
.quant-filter-row--ma.active > .quant-ma-dir,
.quant-filter-row--ma.active > .quant-ma-pct { border-color: var(--accent); }

/* Preset "Quick set" dropdown lives between the label and the ≥/≤
   selector (pinned to grid-column 2 of the standard 5-col row template).
   Picking a preset writes the inputs and the re-render resets the
   dropdown to "Quick…" — the ≥/≤ + input are the source of truth. */
.quant-filter-row > .quant-preset {
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 3px;
  padding: 1px 2px; font: inherit; font-size: 11px;
  min-width: 0; max-width: 100%;
}

/* Returns-constraint rows live in their own right-hand column (see
   .quant-filter-col--returns below). Each row: period · dir · value · basis · ×.
   Flex-laid so the 5 controls + remove button stay on one line. */
.quant-filter-row--retchip { display: flex; flex-wrap: nowrap; align-items: center; gap: 6px; padding: 2px 4px; border-radius: 4px; min-height: 22px; }
.quant-filter-row--retchip > .quant-ret-period { width: 84px; flex-shrink: 0; }
.quant-filter-row--retchip > .quant-ret-dir    { width: 44px; flex-shrink: 0; }
.quant-filter-row--retchip > .quant-ret-val    { width: 56px; flex-shrink: 0; }
.quant-filter-row--retchip > .quant-ret-basis  { width: 78px; flex-shrink: 0; }
.quant-filter-row--retchip > .quant-ret-period,
.quant-filter-row--retchip > .quant-ret-dir,
.quant-filter-row--retchip > .quant-ret-basis {
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 3px; padding: 1px 4px;
  font: inherit; font-size: 11px;
}
.quant-filter-row--retchip > .quant-ret-val {
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 3px; padding: 1px 4px;
  font: inherit; font-size: 11px;
}
.quant-filter-row--retchip.active > .quant-ret-val,
.quant-filter-row--retchip.active > .quant-ret-period { border-color: var(--accent); }
.quant-filter-row--retchip > .quant-ret-rm {
  background: none; border: 0; color: var(--muted);
  font-size: 14px; line-height: 1; padding: 0 4px; cursor: pointer;
}
.quant-filter-row--retchip > .quant-ret-rm:hover { color: var(--text); }
/* Three-column Technical-tab layout. Left section = factor stack split
   into two sub-columns so the 10+ filter factors use horizontal space
   instead of producing a long vertical scroll. Right section = Returns
   chip list with its own header. Outer grid: factors take 2 fractional
   units, Returns takes 1 — keeps the chip list tight and the factors
   readable. */
.quant-filter-cols {
  display: grid; grid-template-columns: 2fr 1fr;
  gap: 4px 28px; padding: 8px 10px;
  max-width: 1400px;
}
.quant-filter-cols .quant-filter-col {
  display: grid;
  grid-template-columns: repeat(2, minmax(290px, 1fr));
  grid-auto-flow: column;                                 /* top→bottom, then left→right */
  grid-template-rows: repeat(var(--qf-rows, 1), auto);
  gap: 2px 24px;
  align-content: start;
}
.quant-filter-cols .quant-filter-col--returns {
  display: flex; flex-direction: column; gap: 2px;
}
@media (max-width: 1100px) {
  .quant-filter-cols { grid-template-columns: 1fr; }
  .quant-filter-cols .quant-filter-col { grid-template-columns: repeat(2, minmax(280px, 1fr)); }
}
@media (max-width: 760px) {
  .quant-filter-cols .quant-filter-col {
    grid-template-columns: 1fr;
    grid-auto-flow: row; grid-template-rows: auto;
  }
}

/* Prescreens tab — grid of named filter chains. Each card lists what
   filters it'll apply and a single Apply button to commit. The active
   card (the one most recently applied) gets a subtle accent border so
   the user can see which preset their funnel currently came from. */
.quant-prescreen-intro {
  padding: 6px 12px 4px;
  font-size: 11px;
  max-width: 1100px;
  line-height: 1.5;
}
.quant-prescreen-scope {
  margin: 4px 10px 10px;
  padding: 8px 12px;
  font-size: 12px;
  line-height: 1.5;
  max-width: 1100px;
  border-radius: 6px;
  border: 1px solid var(--border);
}
.quant-prescreen-scope.active {
  border-color: var(--accent);
  background: rgba(47, 125, 215, 0.08);
}
.quant-prescreen-scope.active strong { color: var(--accent); }
.quant-prescreen-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
  gap: 12px;
  padding: 8px 10px 12px;
  max-width: 1400px;
}
.quant-prescreen-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 10px 12px 12px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 6px;
  transition: border-color 90ms ease, background 90ms ease;
}
.quant-prescreen-card:hover {
  border-color: var(--accent);
}
.quant-prescreen-card.active {
  border-color: var(--accent);
  background: rgba(99, 179, 237, 0.06);
}
.quant-prescreen-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  justify-content: space-between;
}
.quant-prescreen-name {
  margin: 0;
  font-size: 13px;
  font-weight: 700;
  color: #e4c98a;
  letter-spacing: 0.01em;
}
.quant-prescreen-badge {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--accent);
  background: rgba(99, 179, 237, 0.12);
  border: 1px solid rgba(99, 179, 237, 0.4);
  border-radius: 3px;
  padding: 1px 6px;
}
.quant-prescreen-desc {
  margin: 0;
  font-size: 11px;
  color: var(--muted);
  line-height: 1.45;
}
.quant-prescreen-chips {
  margin: 4px 0 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.quant-prescreen-chips li {
  font-size: 11px;
  color: var(--text);
  padding: 2px 0 2px 12px;
  position: relative;
  line-height: 1.4;
}
.quant-prescreen-chips li::before {
  content: "•";
  position: absolute;
  left: 2px;
  color: var(--accent);
}
.quant-prescreen-apply {
  align-self: flex-start;
  margin-top: 4px;
  background: var(--accent);
  color: var(--bg);
  border: 0;
  border-radius: 4px;
  padding: 5px 12px;
  font: inherit;
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
  letter-spacing: 0.01em;
  transition: filter 90ms ease;
}
.quant-prescreen-apply:hover {
  filter: brightness(1.1);
}
.quant-prescreen-card.active .quant-prescreen-apply {
  background: transparent;
  color: var(--accent);
  border: 1px solid var(--accent);
}

/* ── Picks tracker ─────────────────────────────────────────────────────
   Compact dashboard for the per-pick $100 portfolio: summary tiles up
   top, ticker form, chart, table of picks with sell / delete actions. */
.picks-summary {
  display: flex; flex-wrap: wrap; gap: 10px;
  margin: 4px 0 14px;
}
.picks-summary-empty {
  font-size: 12px; padding: 6px 0;
}
.picks-tile {
  flex: 0 0 auto;
  min-width: 130px;
  padding: 8px 12px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 6px;
}
.picks-tile-label {
  font-size: 10px;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 2px;
}
.picks-tile-value {
  font-size: 18px;
  font-weight: 700;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.picks-tile-sub {
  font-size: 10px;
  margin-top: 1px;
}
.picks-form {
  display: flex; align-items: center; gap: 8px;
  margin: 0 0 14px;
}
.picks-form input[type="text"] {
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 4px;
  padding: 6px 10px; font: inherit; font-size: 13px;
  width: 180px; letter-spacing: 0.04em; text-transform: uppercase;
}
.picks-form input[type="text"]:focus { border-color: var(--accent); outline: none; }
#picks-form-msg { font-size: 11px; }
#picks-chart-wrap {
  margin: 6px 0 14px;
  padding: 6px 8px 4px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 6px;
}
#picks-chart-host { width: 100%; height: 280px; }
.picks-chart-legend {
  display: flex; gap: 14px; align-items: center;
  padding: 4px 4px 2px; font-size: 11px;
}
.picks-legend-swatch {
  display: inline-block; width: 18px; height: 3px;
  vertical-align: middle; margin-right: 4px; border-radius: 2px;
}
.picks-legend-swatch--picks { background: #4DA6FF; }
.picks-legend-swatch--anti  { background: #E8A33D; }
.picks-legend-swatch--spy   { background: #bdbdbd; }
#picks-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
}
#picks-table th, #picks-table td {
  padding: 6px 10px;
  border-bottom: 1px solid var(--border);
  text-align: left;
}
#picks-table th {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  font-weight: 600;
}
#picks-table td.num, #picks-table th.num { text-align: right; font-variant-numeric: tabular-nums; }
#picks-table td.pos { color: #4cd084; }
#picks-table td.neg { color: #7BAFD4; }
.picks-ticker { color: var(--accent); text-decoration: none; font-weight: 700; }
.picks-ticker:hover { text-decoration: underline; }
.picks-badge {
  display: inline-block; padding: 1px 6px;
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.04em;
  border-radius: 3px; font-weight: 600;
}
.picks-badge--open   { background: rgba(99, 179, 237, 0.15); color: #4DA6FF; border: 1px solid rgba(99,179,237,0.4); }
.picks-badge--closed { background: rgba(255,255,255,0.06);   color: var(--muted); border: 1px solid var(--border); }
/* Type badges: Pick (long, blue) vs Anti (short, amber). */
.picks-badge--pick { background: rgba(77,166,255,0.12); color: #4DA6FF; border: 1px solid rgba(77,166,255,0.4); }
.picks-badge--anti { background: rgba(232,163,61,0.14); color: #E8A33D; border: 1px solid rgba(232,163,61,0.45); }
/* Anti-pick add buttons (profile + charts): amber outline to distinguish
   from the accent-filled "+ Pick" button without using red. */
.td-add-anti {
  background: transparent; color: #E8A33D;
  border: 1px solid rgba(232,163,61,0.55); border-radius: 4px;
  font-size: 11px; padding: 3px 10px; cursor: pointer; font-weight: 600; letter-spacing: 0.01em;
}
.td-add-anti:hover:not(:disabled) { background: rgba(232,163,61,0.12); }
.td-add-anti:disabled { opacity: 0.7; cursor: default; }
/* Ticker profile "+ Add to picks" — sits inline with the company name
   so the user can fire it off without leaving the page. */
.td-name-row {
  display: flex; align-items: baseline; flex-wrap: wrap;
  gap: 10px; margin: 0 0 6px;
}
.td-name-row > h3 { margin: 0; }
.td-add-pick {
  font-size: 11px; padding: 3px 10px;
  background: var(--accent); color: var(--bg);
  border: 0; border-radius: 4px; cursor: pointer;
  font-weight: 600; letter-spacing: 0.01em;
}
.td-add-pick:hover:not(:disabled) { filter: brightness(1.1); }
.td-add-pick:disabled { background: rgba(255,255,255,0.08); color: var(--muted); cursor: default; }
#td-add-pick-msg { font-size: 11px; }
#td-add-pick-msg a { color: var(--accent); text-decoration: none; }
#td-add-pick-msg a:hover { text-decoration: underline; }

/* ── Watchlists page ───────────────────────────────────────────────────
   Sidebar of named lists + main pane for the selected list's tickers. */
.watchlists-layout {
  display: grid;
  grid-template-columns: 240px 1fr;
  gap: 16px;
  align-items: start;
}
.watchlists-sidebar {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 10px;
  position: sticky;
  top: 8px;
}
.watchlists-sidebar-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}
.wl-new-form {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 4px 0 10px;
  padding: 8px;
  background: rgba(255,255,255,0.03);
  border-radius: 4px;
}
.wl-new-form input {
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 3px;
  padding: 4px 8px; font: inherit; font-size: 12px;
}
.wl-new-form input:focus { border-color: var(--accent); outline: none; }
.wl-new-form > div { display: flex; gap: 4px; }
.wl-list { list-style: none; margin: 0; padding: 0; }
.wl-list-empty { font-size: 11px; padding: 8px 4px; }
.wl-list-item {
  display: flex; justify-content: space-between; align-items: center;
  padding: 6px 8px;
  border-radius: 3px;
  cursor: pointer;
  font-size: 12px;
  transition: background 80ms;
}
.wl-list-item:hover { background: rgba(255,255,255,0.04); }
.wl-list-item.active { background: rgba(99,179,237,0.12); color: var(--accent); }
.wl-list-name { font-weight: 500; }
.wl-list-count { font-size: 11px; font-variant-numeric: tabular-nums; }
.watchlists-main { min-width: 0; }
.wl-detail-empty { padding: 40px 12px; text-align: center; font-size: 13px; }
.wl-detail-head {
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
  margin-bottom: 8px;
}
.wl-detail-name {
  margin: 0; font-size: 18px; font-weight: 700; color: #e4c98a;
}
.wl-add-form {
  display: flex; align-items: center; gap: 8px;
  margin: 4px 0 12px;
}
.wl-add-form input {
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 4px;
  padding: 5px 10px; font: inherit; font-size: 12px;
  width: 180px; letter-spacing: 0.04em; text-transform: uppercase;
}
.wl-add-form input:focus { border-color: var(--accent); outline: none; }
#wl-add-msg { font-size: 11px; }
#wl-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
}
#wl-table th, #wl-table td {
  padding: 6px 10px;
  border-bottom: 1px solid var(--border);
  text-align: left;
}
#wl-table th {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--muted); font-weight: 600;
}
#wl-table td.num, #wl-table th.num { text-align: right; font-variant-numeric: tabular-nums; }
#wl-table td.pos { color: #4cd084; }
#wl-table td.neg { color: #7BAFD4; }
.wl-ticker { color: var(--accent); text-decoration: none; font-weight: 700; }
.wl-ticker:hover { text-decoration: underline; }

.td-watchlist-picker { display: inline-flex; }
.td-watchlist-select {
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 4px;
  padding: 4px 8px; font: inherit; font-size: 11px;
  cursor: pointer;
}
.td-watchlist-select:hover { border-color: var(--accent); }

@media (max-width: 760px) {
  .watchlists-layout { grid-template-columns: 1fr; }
  .watchlists-sidebar { position: static; }
}

.picks-actions { white-space: nowrap; }
.picks-actions .btn { margin-left: 4px; }
.picks-actions .btn:first-child { margin-left: 0; }
.btn-sm { font-size: 11px; padding: 3px 10px; border-radius: 3px; }
.btn-ghost { background: transparent; border: 1px solid var(--border); color: var(--muted); cursor: pointer; }
.btn-ghost:hover { color: var(--text); border-color: var(--accent); }
.picks-row.is-closed { opacity: 0.78; }
@media (max-width: 720px) {
  .picks-summary { gap: 6px; }
  .picks-tile { min-width: 0; flex: 1 1 calc(50% - 6px); }
  #picks-chart-host { height: 220px; }
}
.quant-filter-col-header {
  font-size: 11px; font-weight: 600; color: var(--muted);
  padding: 2px 4px 4px;
  text-transform: uppercase; letter-spacing: 0.04em;
}
.quant-ret-add {
  align-self: flex-start; margin-top: 6px;
  background: none; border: 0; color: var(--accent);
  font-size: 11px; padding: 4px 6px; cursor: pointer; text-align: left;
}
.quant-ret-add:hover { text-decoration: underline; }
/* Re-apply the subtle zebra inside the returns column so the rhythm
   matches the left column's banded rows. */
.quant-filter-col--returns .quant-filter-row--retchip { background: rgba(255, 255, 255, 0.015); }
.quant-filter-col--returns .quant-filter-row--retchip:nth-of-type(even) { background: rgba(255, 255, 255, 0.05); }
.quant-filter-col--returns .quant-filter-row--retchip.active { background: rgba(99, 179, 237, 0.08); }

@media (max-width: 720px) {
  .quant-filter-cols { grid-template-columns: 1fr; }
}
/* ⓘ help link next to a filter label — opens a floating explanation popover. */
.quant-help-link {
  display: inline-block; margin-left: 4px;
  color: var(--accent); text-decoration: none;
  font-size: 11px; cursor: pointer; line-height: 1;
}
.quant-help-link:hover { text-decoration: underline; }
.quant-help-popover {
  position: absolute; z-index: 1000;
  background: var(--panel); border: 1px solid var(--accent);
  border-radius: 6px; padding: 12px 14px 10px;
  width: 360px; max-width: calc(100vw - 24px);
  font-size: 12px; line-height: 1.55; color: var(--text);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
}
.quant-help-popover h4 { margin: 0 0 6px; font-size: 13px; color: var(--accent); }
.quant-help-popover p  { margin: 0 0 6px; }
.quant-help-popover ul { margin: 0 0 6px 18px; padding: 0; }
.quant-help-popover li { margin: 0 0 2px; }
.quant-help-popover strong { color: var(--text); }
.quant-help-popover em { color: var(--muted); font-style: italic; }
.quant-help-close {
  position: absolute; top: 4px; right: 6px;
  background: none; border: 0; cursor: pointer;
  color: var(--muted); font-size: 16px; line-height: 1; padding: 2px 6px;
}
.quant-help-close:hover { color: var(--text); }
/* Clean zebra-band on filter rows — odd rows lighter, even rows slightly
   heavier. Active rows always pop with the blue accent tint regardless
   of parity. */
.quant-filter-row { background: rgba(255, 255, 255, 0.015); border-radius: 4px; }
.quant-filter-row:nth-child(even) { background: rgba(255, 255, 255, 0.05); }
.quant-filter-row.active,
.quant-filter-row:nth-child(even).active { background: rgba(99, 179, 237, 0.08); }
/* Finviz-style label: right-aligned so the label visually butts up against
   its input, tan/gold color so labels stand out from the white-ish numeric
   inputs and dark background. */
.quant-filter-label {
  color: #c4a86e;
  text-align: right;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.quant-filter-row.active .quant-filter-label { color: #e4c98a; font-weight: 600; }
.quant-filter-input {
  width: 52px; background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 3px; padding: 1px 4px;
  font: inherit; font-size: 11px;
}
.quant-filter-row.active .quant-filter-input { border-color: var(--accent); }
.quant-filter-dir,
.quant-filter-gap-dir {
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 3px; padding: 1px 2px;
  font: inherit; font-size: 10px;
}
/* Match the regular filter input styling so the composite Gap row blends
   with its peers. */
.quant-filter-gap-input {
  width: 52px; background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 3px; padding: 1px 4px;
  font: inherit; font-size: 11px;
}
.quant-filter-row.active .quant-filter-gap-input { border-color: var(--accent); }
/* Anchor button for the taxonomy pickers — looks like a flat select. */
.quant-tax-btn {
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 3px;
  padding: 2px 8px; font: inherit; font-size: 11px; cursor: pointer;
  grid-column: 2 / -1; min-width: 0; text-align: left;
  text-overflow: ellipsis; overflow: hidden; white-space: nowrap;
}
.quant-tax-btn:hover { border-color: var(--accent); }
.quant-filter-row.active .quant-tax-btn { border-color: var(--accent); color: var(--accent); }

/* Always-visible Sector + Industry buttons above the Quant tabs. The
   inner .quant-tax-btn re-uses the picker chrome but here it sits in a
   flat horizontal row instead of inside the per-tab filter grid, so we
   override the grid-column to auto and give it explicit min-widths. */
.quant-top-filters {
  display: flex; gap: 12px; align-items: center; flex-wrap: wrap;
  padding: 6px 10px 8px; border-bottom: 1px solid var(--border);
  margin-bottom: 6px;
}
.quant-top-tax {
  display: flex; align-items: center; gap: 6px;
  flex: 1 1 280px; min-width: 240px;
}
.quant-top-tax-label {
  font-size: 11px; color: var(--muted); font-weight: 600;
  letter-spacing: 0.02em; white-space: nowrap; min-width: 54px;
}
.quant-top-tax .quant-tax-btn {
  grid-column: auto; flex: 1 1 auto; min-width: 180px;
  padding: 4px 10px; font-size: 12px;
}
.quant-top-tax.active .quant-tax-btn { border-color: var(--accent); color: var(--accent); }
/* Floating taxonomy picker — Finviz-style "Match any of the following"
   checkbox grid. Width clamped in JS based on viewport. */
.quant-tax-pop {
  width: 520px; max-height: 480px;
  background: var(--panel); border: 1px solid var(--accent);
  border-radius: 6px; box-shadow: 0 12px 32px rgba(0,0,0,0.55);
  display: flex; flex-direction: column;
  font-size: 12px;
}
.quant-tax-head {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px; border-bottom: 1px solid var(--border);
}
.quant-tax-head strong { font-size: 12px; }
.quant-tax-search {
  flex: 1; background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 3px;
  padding: 3px 8px; font: inherit; font-size: 11px;
}
.quant-tax-actions {
  display: flex; align-items: center; gap: 12px;
  padding: 6px 12px; border-bottom: 1px solid var(--border);
  font-size: 11px;
}
.quant-tax-count { margin-left: auto; }
.quant-tax-grid {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 2px 14px; padding: 8px 12px; overflow-y: auto;
  flex: 1;
}
.quant-tax-cell {
  display: flex; align-items: center; gap: 6px;
  padding: 2px 0; font-size: 11px; cursor: pointer;
}
.quant-tax-cell input { margin: 0; cursor: pointer; }
.quant-tax-cell:hover { color: var(--accent); }
.quant-tax-foot {
  display: flex; justify-content: flex-end;
  padding: 8px 12px; border-top: 1px solid var(--border);
}
.quant-filter-unit { font-size: 10px; min-width: 14px; }
.quant-factor-head { display: inline-flex; align-items: center; gap: 6px;
  font-size: 11px; color: var(--text); cursor: pointer; }
.quant-factor-head .muted { font-size: 10px; }
.quant-weight { display: inline-flex; align-items: center; gap: 4px;
  font-size: 11px; color: var(--muted); }
.quant-w-input { width: 60px; background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 3px; padding: 2px 6px;
  font: inherit; font-size: 11px; }
/* The factor <select> needs to be wide enough to show full labels like
   "Weekly StdDev" without ellipsis — otherwise users can't tell at a
   glance which factor is selected on the previous stage card. */
.quant-w-input.quant-stage-factor { width: 150px; }
/* Live 1D cell — the value came from the intraday quote, not the EOD recompute.
   Subtle dotted underline signals "hover for detail" without shouting. */
#quant-table td.quant-live-1d { text-decoration: underline dotted rgba(139,148,158,0.6); text-underline-offset: 2px; cursor: help; }
.quant-actions { display: flex; align-items: flex-end; gap: 8px; flex-wrap: wrap; }
/* Apply is the primary commit action: filled accent. The "pending" class is
   added by markQuantDirty() while edits are uncommitted (green = act). */
.btn.quant-apply {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--bg);
  font-weight: 700;
}
.btn.quant-apply:hover { filter: brightness(1.08); }
.btn.quant-apply.pending {
  background: var(--green);
  border-color: var(--green);
  color: var(--bg);
  box-shadow: 0 0 0 2px rgba(63, 185, 80, 0.30);
}

/* ── Color Vision Deficiency page (#colors) ──────────────────────────────── */
#colors-view { max-width: 820px; margin: 0 auto; }
#colors-view #cvd-title { margin: 0 0 4px; }
#colors-view #cvd-intro { margin: 0 0 14px; max-width: 760px; }
.cvd-scheme-title {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: 18px; margin: 4px 0 12px;
}
.cvd-swatch {
  display: inline-block; width: 18px; height: 18px; border-radius: 3px;
  border: 1px solid #555; vertical-align: middle;
}
.cvd-hex { font-size: 11px; color: var(--muted); font-weight: 400; letter-spacing: .02em; }
.cvd-block-h {
  font-size: 11px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--muted); margin-bottom: 6px; padding-bottom: 3px;
  border-bottom: 1px solid var(--border);
}
.cvd-svg {
  display: block; width: 100%; height: auto;
  background: #161b22; border: 1px solid var(--border); border-radius: 4px;
}
.cvd-svg-bars { background: #000; }   /* bar graph: black background (task #5) */
/* Numbers: same size as the Quant table cells (13px), listed vertically. */
.cvd-numbers-block { width: 110px; flex: 0 0 auto; }
.cvd-numbers { display: flex; flex-direction: column; gap: 3px;
  font-variant-numeric: tabular-nums; font-size: 13px; font-weight: 400; }
/* Numbers + the 2×2 graph grid share ONE row. */
.cvd-top-row { display: flex; gap: 16px; align-items: flex-start; }
.cvd-2x2 {
  flex: 1 1 auto; display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 16px; align-items: start;
}
.cvd-cell { min-width: 0; }
/* Scheme selector: a single horizontal row BELOW the charts, options divided
   by separators. Selecting one swaps which scheme is shown. */
.cvd-radios-row {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 12px;
  margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--border);
  /* Offset by the numbers column (110px width + 16px row gap) so the options
     center relative to the CHARTS, not the full panel. Divider stays full-width. */
  padding-left: 126px;
}
.cvd-radio {
  display: inline-flex; align-items: center; gap: 6px;
  white-space: nowrap; font-size: 13px; cursor: pointer;
}
.cvd-radio input { accent-color: var(--accent); cursor: pointer; }
.cvd-radio-sep { color: var(--muted); user-select: none; }

/* ── Theme heat map (#heatmap) ───────────────────────────────────────────── */
.hm-controls { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 4px 0 14px; }
#hm-meta { font-size: 12px; }
.hm-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  grid-auto-rows: 88px;            /* every box the same height */
  gap: 8px;
}
.hm-box {
  display: flex; flex-direction: column; justify-content: center; gap: 4px;
  height: 100%; padding: 10px 12px; border-radius: 6px; overflow: hidden;
  border: 1px solid rgba(255,255,255,0.06); text-decoration: none;
  transition: transform .06s ease, box-shadow .06s ease;
}
.hm-box:hover { transform: translateY(-1px); box-shadow: 0 0 0 1px var(--accent); }
.hm-box-name {
  font-size: 12px; line-height: 1.2; font-weight: 600; opacity: 0.92;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.hm-box-sub { font-size: 11px; font-weight: 400; opacity: 0.72; line-height: 1.15; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hm-box-val { font-size: 19px; font-weight: 700; font-variant-numeric: tabular-nums; }

/* ── Heat-map treemap (desktop): boxes are absolutely positioned with size
   proportional to company count; renderHeatmap sets left/top/width/height +
   font-size inline. The grid container becomes a positioned canvas. */
.hm-grid.hm-treemap { display: block; position: relative; gap: 0; grid-auto-rows: initial; }
.hm-treemap .hm-box {
  position: absolute; height: auto;
  justify-content: flex-start; align-items: flex-start;
  gap: 1px; padding: 3px 6px; border: none; border-radius: 4px;
}
.hm-treemap .hm-box:hover { transform: none; box-shadow: inset 0 0 0 2px var(--accent); z-index: 5; }
.hm-treemap .hm-box-name { -webkit-line-clamp: 3; line-height: 1.12; opacity: 1; }
.hm-treemap .hm-box-val { opacity: 0.95; line-height: 1.1; }

/* Hover popup — name + return + company count. Follows the cursor. */
.hm-tip {
  position: fixed; z-index: 200; pointer-events: none;
  background: var(--panel-2); border: 1px solid var(--border); border-radius: 8px;
  padding: 8px 11px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.55);
  font-size: 12px; min-width: 150px; max-width: 300px;
}
.hm-tip[hidden] { display: none; }
.hm-tip-name { font-weight: 700; font-size: 13px; margin-bottom: 4px; color: var(--text); }
.hm-tip-row { display: flex; gap: 14px; justify-content: space-between; line-height: 1.5; }
.hm-tip-row .muted { color: var(--muted); }
.hm-tip-ret { font-variant-numeric: tabular-nums; font-weight: 700; }
/* Traditional heat-map hover: sparkline + 1D/1M/3M row. */
.hm-tip .hm-spark { display: block; width: 196px; height: 44px; margin: 6px 0; }
.hm-tip-spark-row { display: flex; gap: 10px; justify-content: space-between; font-size: 12px; font-variant-numeric: tabular-nums; white-space: nowrap; margin-bottom: 5px; }
.hm-tip-spark-row .muted { font-size: 10px; margin-right: 1px; }

/* ── Heat-map "By sector / By theme" toggle (desktop only) ─────────────────── */
.hm-mode-toggle { display: inline-flex; border: 1px solid var(--border); border-radius: 7px; overflow: hidden; }
.hm-mode-toggle a { padding: 6px 12px; font-size: 12px; font-weight: 600; color: var(--muted); text-decoration: none; background: var(--panel); white-space: nowrap; }
.hm-mode-toggle a + a { border-left: 1px solid var(--border); }
.hm-mode-toggle a:hover { color: var(--text); }
.hm-mode-toggle a.active { background: var(--accent); color: #07111f; }
html.mobile-site .hm-mode-toggle { display: none; }   /* sector market-map is desktop-only */

/* ── Finviz-style sector market map: sectors → sub-industries → stock tiles.
   Reuses #hm-grid.hm-treemap (position:relative canvas). Stock tiles are
   coloured red/green inline by renderSectorMap (the deliberate Finviz palette
   exception). */
.hm-treemap .hm-secbox {
  position: absolute; z-index: 1; border: 1px solid rgba(0,0,0,0.7);
  background: rgba(0,0,0,0.16); border-radius: 2px; text-decoration: none;
}
.hm-treemap .hm-secbox:hover { box-shadow: inset 0 0 0 2px var(--accent); z-index: 6; }
.hm-treemap .hm-subbox { position: absolute; z-index: 1; border: 1px solid rgba(0,0,0,0.45); pointer-events: none; }
.hm-treemap .hm-seclabel {
  position: absolute; z-index: 5; display: flex; align-items: center; padding: 0 6px;
  font-size: 11px; font-weight: 700; letter-spacing: 0.04em;
  color: rgba(255,255,255,0.85); background: rgba(0,0,0,0.28); text-decoration: none; overflow: hidden;
}
.hm-treemap .hm-seclabel span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hm-treemap .hm-seclabel:hover { background: rgba(88,166,255,0.28); color: #fff; }
.hm-treemap .hm-sublabel {
  position: absolute; z-index: 4; font-size: 9px; font-weight: 600;
  color: rgba(255,255,255,0.5); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; pointer-events: none;
}
.hm-treemap .hm-sm {
  position: absolute; z-index: 3; display: flex; flex-direction: column;
  align-items: center; justify-content: center; overflow: hidden; line-height: 1.05; text-decoration: none;
}
.hm-treemap .hm-sm:hover { z-index: 7; box-shadow: inset 0 0 0 1.5px #fff; }
.hm-sm-tk { font-weight: 700; }
.hm-sm-v { opacity: 0.92; font-variant-numeric: tabular-nums; }
.quant-screens-group { display: inline-flex; align-items: center; gap: 8px; }
.quant-screen-select {
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 4px;
  padding: 6px 10px; font: inherit; font-size: 13px;
  cursor: pointer; min-width: 160px;
}
.quant-screen-select:hover { border-color: var(--accent); }

.screener-filters { display: flex; flex-direction: column; gap: 10px; margin: 14px 0 22px; }
.screener-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.screener-row .screener-label { color: var(--muted); font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.06em; min-width: 96px; }
.screener-months { display: inline-flex; gap: 6px; flex-wrap: wrap; }
.chip-clear { background: none; border: none; color: var(--muted); font-size: 12px;
  cursor: pointer; text-decoration: underline; padding: 4px 6px; margin-left: 6px; }
.chip-clear:hover { color: var(--text); }

.k-input { background: var(--panel); color: var(--text); border: 1px solid var(--border);
  border-radius: 6px; padding: 6px 10px; font: inherit; font-size: 13px; width: 90px;
  font-variant-numeric: tabular-nums; }
.k-input:focus { outline: none; border-color: var(--accent); }

.min-pct-grid { display: inline-flex; gap: 6px; flex-wrap: wrap; }
.min-pct { display: inline-flex; align-items: center; gap: 4px;
  background: var(--panel); border: 1px solid var(--border); border-radius: 6px;
  padding: 2px 6px 2px 8px; font-size: 12px; }
.min-pct span { color: var(--muted); font-weight: 600; min-width: 22px; }
.min-pct input { background: transparent; color: var(--text); border: none;
  font: inherit; font-size: 12px; width: 50px; padding: 4px 2px;
  font-variant-numeric: tabular-nums; }
.min-pct input:focus { outline: none; }
.min-pct:focus-within { border-color: var(--accent); }

#screener-table .screener-sub-row td { background: var(--panel-2); font-weight: 700;
  border-top: 1px solid var(--border); }
#screener-table .screener-sub-row a { color: var(--text); }
#screener-table .screener-sub-header td { opacity: 0.7; font-weight: 600; }
#screener-table .screener-tick-row td:first-child { padding-left: 24px; }

.chart-toolbar { display: flex; align-items: center; gap: 8px; margin: 4px 0 6px;
  font-size: 13px; flex-wrap: wrap; }
.chart-toolbar .muted { font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.06em; margin-right: 4px; }
/* Chart-type dropdown — same compact look as the chips it replaces. */
.chart-type-select {
  background: var(--panel); color: var(--text);
  border: 1px solid var(--border); border-radius: 4px;
  padding: 3px 6px; font: inherit; font-size: 12px;
}
.chart-type-select:hover { border-color: var(--accent); }
.chart-type-select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* Color customisation popover anchored under the "colors…" link. */
.chart-colors-pop {
  position: relative;
  background: var(--panel); border: 1px solid var(--accent);
  border-radius: 6px; padding: 10px 12px;
  margin: 4px 0 8px; max-width: 380px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.4);
  font-size: 12px;
}
.chart-colors-row {
  display: flex; align-items: center; gap: 8px; margin: 4px 0;
}
.chart-colors-row label {
  flex: 1; color: var(--muted); font-size: 11px;
}
.chart-colors-row input[type="color"] {
  width: 28px; height: 22px; padding: 0;
  background: var(--bg); border: 1px solid var(--border); border-radius: 3px;
  cursor: pointer;
}
.chart-colors-row input[type="text"] {
  width: 78px; background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 3px;
  padding: 3px 6px; font: inherit; font-size: 11px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.chart-colors-actions {
  display: flex; align-items: center; justify-content: flex-end;
  gap: 8px; margin-top: 8px;
}

/* Overlay toggles — checkbox-backed pills sitting next to Range/Style chips.
   The color swatch on the left of each pill mirrors the line color in the
   chart so the legend is implicit. */
.chart-toggle {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 13px; border-radius: 16px;
  background: var(--panel); color: var(--muted); border: 1px solid var(--border);
  font-size: 13px; cursor: pointer; user-select: none;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.chart-toggle:hover { color: var(--text); border-color: var(--accent); }
.chart-toggle input { margin: 0; cursor: pointer; }
.chart-toggle.active { color: var(--text); }
.chart-toggle[data-overlay-color="sub"].active   { border-color: #f0883e; background: rgba(240,136,62,0.10); }
.chart-toggle[data-overlay-color="sp500"].active { border-color: #6e7681; background: rgba(110,118,129,0.14); }
.chart-toggle[data-overlay-color="xlk"].active   { border-color: #a371f7; background: rgba(163,113,247,0.12); }
/* Indicator pill borders mirror the line colors in the chart so the legend
   is implicit. Keep in sync with the COLORS map in app.js. */
.chart-toggle[data-overlay-color="sma20"].active  { border-color: #ffd33d; background: rgba(255,211,61,0.10); }
.chart-toggle[data-overlay-color="sma50"].active  { border-color: #ff7b72; background: rgba(255,123,114,0.10); }
.chart-toggle[data-overlay-color="sma200"].active { border-color: #d2a8ff; background: rgba(210,168,255,0.10); }
.chart-toggle[data-overlay-color="ema9"].active   { border-color: #56d4dd; background: rgba(86,212,221,0.10); }
.chart-toggle[data-overlay-color="ema21"].active  { border-color: #7ee787; background: rgba(126,231,135,0.10); }
.chart-toggle[data-overlay-color="bb"].active     { border-color: #adbac7; background: rgba(173,186,199,0.10); }
.chart-toggle[data-overlay-color="rsi"].active    { border-color: #ffd33d; background: rgba(255,211,61,0.10); }
.chart-toggle[data-overlay-color="macd"].active   { border-color: #58a6ff; background: rgba(88,166,255,0.10); }

#tv-chart-wrap {
  position: relative;
  margin-bottom: 22px;
  border: 1px solid var(--border); border-radius: 8px; overflow: hidden;
  background: var(--bg);
  /* 75% width, centered — chart sits in a tighter frame so the page reads
     less chart-dominant and the surrounding context (returns, breadcrumb,
     compare strip) stays visible alongside it. */
  max-width: 75%;
  margin-left: auto;
  margin-right: auto;
}
/* Viewport-relative height (75% of the previous fit-above-the-fold target)
   so the chart shrinks proportionally with the width reduction. */
#tv-chart { height: max(285px, calc((100vh - 230px) * 0.75)); }
#tv-chart > div { height: 100%; }
#tv-chart-legend {
  position: absolute; top: 8px; left: 12px; z-index: 3;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 12px; line-height: 1.55;
  color: var(--text);
  pointer-events: none;
  background: rgba(14,17,22,0.78);
  padding: 6px 10px; border-radius: 6px; border: 1px solid var(--border);
  max-width: calc(100% - 24px);
  white-space: nowrap;
}
#tv-chart-legend .lg-title { font-weight: 600; color: var(--text); margin-right: 6px; }
#tv-chart-legend .lg-up    { color: var(--green); }
#tv-chart-legend .lg-down  { color: #7BAFD4; }
#tv-chart-legend .lg-key   { color: var(--muted); margin-right: 3px; }
#tv-chart-legend .lg-sep   { color: var(--muted); margin: 0 6px; }
#tv-chart-legend .lg-row   { display: block; }

/* Profile page: tightened so the chart fits above the fold on a typical
   laptop (~768–900px). Ticker + company sit on one line, "← back" inline. */
#ticker-detail-view .back { margin: 0 12px 0 0; vertical-align: middle; }
#ticker-detail-view #td-ticker  { display: inline-flex; align-items: center; gap: 10px; font-size: 22px; font-weight: 700; letter-spacing: -0.02em; margin: 0 12px 0 0; vertical-align: middle; }
#ticker-detail-view #td-ticker .logo { padding: 0; border-radius: 6px; height: 32px; width: 32px; }
#ticker-detail-view #td-company { display: inline; font-size: 14px; font-weight: 500; color: var(--muted); margin: 0; }
#ticker-detail-view .chart-toolbar { margin: 2px 0; padding: 0; gap: 0; font-size: 12px; }
/* Strip all chrome from chips on the profile page — render as plain text
   links so all three toolbars fit on one or two short rows. Active state
   is just colored text (matches the overlay/indicator color for the
   per-line toggles). */
#ticker-detail-view .chart-toolbar .chip,
#ticker-detail-view .chart-toolbar .chart-toggle {
  background: transparent; border: 0; padding: 2px 7px;
  border-radius: 0; color: var(--muted); font-size: 12px;
  cursor: pointer;
}
#ticker-detail-view .chart-toolbar .chart-toggle { gap: 0; }
#ticker-detail-view .chart-toolbar .chart-toggle input { display: none; }
#ticker-detail-view .chart-toolbar .chip:hover,
#ticker-detail-view .chart-toolbar .chart-toggle:hover { color: var(--text); }
#ticker-detail-view .chart-toolbar .chip.active { color: var(--accent); font-weight: 600; }
#ticker-detail-view .chart-toolbar .chart-toggle.active { font-weight: 600; background: transparent; }
#ticker-detail-view .chart-toolbar .chart-toggle[data-overlay-color="sub"].active   { color: #f0883e; border: 0; }
#ticker-detail-view .chart-toolbar .chart-toggle[data-overlay-color="sp500"].active { color: #adbac7; border: 0; }
#ticker-detail-view .chart-toolbar .chart-toggle[data-overlay-color="xlk"].active   { color: #a371f7; border: 0; }
#ticker-detail-view .chart-toolbar .chart-toggle[data-overlay-color="sma20"].active  { color: #ffd33d; border: 0; }
#ticker-detail-view .chart-toolbar .chart-toggle[data-overlay-color="sma50"].active  { color: #ff7b72; border: 0; }
#ticker-detail-view .chart-toolbar .chart-toggle[data-overlay-color="sma200"].active { color: #d2a8ff; border: 0; }
#ticker-detail-view .chart-toolbar .chart-toggle[data-overlay-color="ema9"].active   { color: #56d4dd; border: 0; }
#ticker-detail-view .chart-toolbar .chart-toggle[data-overlay-color="ema21"].active  { color: #7ee787; border: 0; }
#ticker-detail-view .chart-toolbar .chart-toggle[data-overlay-color="rsi"].active    { color: #ffd33d; border: 0; }

/* Compare-ticker input + per-peer chips. The input is inline, narrow, and
   reuses the toolbar font size; peer chips show in their plotted color
   with an × to remove. */
#compare-input {
  margin-left: 10px;
  padding: 2px 8px; width: 90px;
  background: var(--panel); color: var(--text);
  border: 1px solid var(--border); border-radius: 4px;
  font: inherit; font-size: 12px; text-transform: uppercase;
}
#compare-input:focus { outline: none; border-color: var(--accent); }
#compare-peers { display: inline-flex; gap: 6px; align-items: center; margin-left: 6px; }
.compare-chip {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 12px; font-weight: 600;
  padding: 1px 4px 1px 6px;
}
.compare-chip .compare-rm {
  background: transparent; border: 0; color: inherit;
  font-size: 14px; line-height: 1; cursor: pointer; padding: 0 2px;
  opacity: 0.55;
}
.compare-chip .compare-rm:hover { opacity: 1; }
#ticker-detail-view dl { grid-template-columns: 220px 1fr; gap: 12px 24px; max-width: 980px; }
#ticker-detail-view dt { font-size: 14px; }
#ticker-detail-view dd { font-size: 16px; line-height: 1.55; }
#ticker-detail-view dd a { color: var(--accent); }

.returns-strip {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  background: var(--panel); border: 1px solid var(--border); border-radius: 8px;
  padding: 10px 14px; margin-bottom: 16px; font-size: 13px;
}
.returns-strip .rs-label { color: var(--muted); font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.06em; margin-right: 4px; }
.rs-cell { display: flex; flex-direction: column; align-items: center;
  padding: 4px 10px; border-radius: 6px; border: 1px solid var(--border);
  background: var(--panel-2); min-width: 52px; }
.rs-cell .rs-h { font-size: 10px; color: var(--muted); font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.04em; }
.rs-cell .rs-v { font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums; }

.back { display: inline-block; margin-bottom: 4px; font-size: 13px; }

.primary-nav { margin: 0; display: flex; gap: 18px; }
.primary-nav a {
  color: var(--muted); padding: 6px 0; border-bottom: 2px solid transparent;
  font-size: 15px; font-weight: 600; text-decoration: none;
}
.primary-nav a:hover { color: var(--text); }
.primary-nav a.active { color: var(--text); border-bottom-color: var(--accent); }

/* ── Desktop nav: collapse the 15-item primary nav into a single "Menu ▾"
   dropdown so the header isn't cluttered. Scoped to html:not(.mobile-site) so
   the mobile hamburger drawer is completely untouched; uses its own
   .nav-menu-open class (independent of the mobile .nav-open). #primary-nav
   markup + link order are unchanged, so the mobile drawer is identical. */
.desk-nav-toggle { display: none; }                 /* only shown on desktop */
html.mobile-site .nav-wrap { display: contents; }   /* wrapper dissolves on mobile → header layout unchanged */
html:not(.mobile-site) .nav-wrap { position: relative; display: inline-flex; }
html:not(.mobile-site) .desk-nav-toggle {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--panel); color: var(--text); border: 1px solid var(--border);
  border-radius: 8px; padding: 8px 14px; font-size: 14px; font-weight: 600;
  cursor: pointer; line-height: 1; white-space: nowrap;
}
html:not(.mobile-site) .desk-nav-toggle:hover { border-color: var(--accent); }
html:not(.mobile-site) .desk-nav-toggle .caret { font-size: 10px; transition: transform .15s ease; }
html:not(.mobile-site).nav-menu-open .desk-nav-toggle { border-color: var(--accent); }
html:not(.mobile-site).nav-menu-open .desk-nav-toggle .caret { transform: rotate(180deg); }

/* The nav becomes a dropdown panel: hidden by default, shown when open. */
html:not(.mobile-site) .primary-nav {
  position: absolute; top: calc(100% + 8px); left: 0; z-index: 95;
  display: none; flex-direction: column; gap: 2px;
  min-width: 232px; max-height: 76vh; overflow-y: auto;
  background: var(--panel); border: 1px solid var(--border); border-radius: 10px;
  padding: 6px; box-shadow: 0 14px 36px rgba(0, 0, 0, 0.55);
}
html:not(.mobile-site).nav-menu-open .primary-nav { display: flex; }
html:not(.mobile-site) .primary-nav a {
  padding: 9px 12px; border-radius: 6px; border-bottom: 0;
  white-space: nowrap; color: var(--text);
}
html:not(.mobile-site) .primary-nav a:hover { background: var(--panel-2); color: var(--text); }
html:not(.mobile-site) .primary-nav a.active {
  background: rgba(88, 166, 255, 0.12); color: var(--accent); border-bottom: 0;
}

.select-sm {
  background: var(--panel); color: var(--text); border: 1px solid var(--border);
  border-radius: 4px; padding: 3px 6px; font: inherit; font-size: 12px;
}

.expand-btn {
  background: none; border: 1px solid var(--border); border-radius: 3px;
  color: var(--muted); cursor: pointer; font-size: 9px; padding: 1px 5px;
  margin-right: 7px; line-height: 1.4; vertical-align: middle; transition: all 0.12s;
}
.expand-btn:hover { border-color: var(--accent); color: var(--text); }
.expand-btn.open  { border-color: var(--accent); color: var(--accent); }

.expanded-ticker-row td { background: var(--bg); font-size: 12px; border-bottom-color: rgba(48,54,61,0.5); }
.expanded-ticker-row:hover td { background: rgba(14,17,22,0.85); }
.expanded-ticker-row td:first-child { padding-left: 30px; }
.expanded-ticker-row .ticker-sym { font-weight: 600; margin-right: 6px; }
.expanded-ticker-row .co-name    { color: var(--muted); }

tfoot .avg-row td { background: var(--panel-2); border-top: 1px solid var(--border); border-bottom: none; }
tfoot .avg-row .avg-label { color: var(--muted); font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.05em; }

table.sortable th { cursor: pointer; user-select: none; }
table.sortable th:hover { color: var(--text); }
table.sortable th.sort-asc::after  { content: " \25B2"; color: var(--accent); }
table.sortable th.sort-desc::after { content: " \25BC"; color: var(--accent); }

/* Excel-style filter button in column headers. Sits to the right of the
   header text; click opens a fixed-position popover anchored to the column. */
.th-filter-btn {
  background: transparent; border: none; color: var(--muted);
  font: inherit; font-size: 11px; line-height: 1;
  padding: 2px 4px; margin-left: 4px;
  cursor: pointer; vertical-align: middle;
  border-radius: 3px;
}
.th-filter-btn:hover { color: var(--text); background: rgba(255,255,255,0.06); }
.th-filter-btn.active { color: var(--accent); background: rgba(88,166,255,0.12); }

.col-filter-pop {
  position: fixed; z-index: 1000;
  background: var(--panel); color: var(--text);
  border: 1px solid var(--border); border-radius: 8px;
  padding: 12px 14px; min-width: 240px;
  box-shadow: 0 6px 24px rgba(0,0,0,0.5);
  font-size: 13px;
}
.col-filter-pop .cf-title {
  font-size: 11px; font-weight: 600; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.06em;
  margin-bottom: 10px;
}
.col-filter-pop label {
  display: flex; align-items: center; gap: 6px;
  margin: 6px 0; cursor: pointer;
  font-variant-numeric: tabular-nums;
}
.col-filter-pop label input[type="radio"] { margin: 0; }
.col-filter-pop .cf-num {
  width: 64px; padding: 3px 6px;
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 4px;
  font: inherit; font-size: 13px;
  font-variant-numeric: tabular-nums;
}
.col-filter-pop .cf-num:focus { outline: none; border-color: var(--accent); }
.col-filter-pop .cf-actions {
  display: flex; gap: 8px; margin-top: 12px;
  padding-top: 10px; border-top: 1px solid var(--border);
}
.col-filter-pop .cf-actions .btn { font-size: 12px; padding: 4px 10px; }

.monthly-filter-btn { font-size: 12px; padding: 2px 10px; }
.clear-filters-link {
  background: transparent; color: var(--muted); border: 0; padding: 2px 4px;
  font: inherit; cursor: pointer; vertical-align: middle;
  border-radius: 3px;
}
.clear-filters-link:hover { background: rgba(248, 81, 73, 0.12); color: var(--text); }
.clear-filters-link svg { display: block; }

/* All-stocks pagination footer. */
.pager {
  display: flex; gap: 4px; align-items: center; justify-content: center;
  margin: 10px 0 6px; flex-wrap: wrap;
}
.pager .pg-btn {
  background: var(--panel); color: var(--text);
  border: 1px solid var(--border); border-radius: 3px;
  padding: 2px 8px; font: inherit; font-size: 11px; cursor: pointer;
}
.pager .pg-btn:hover:not(:disabled) { border-color: var(--accent); }
.pager .pg-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.pager .pg-btn.active { background: var(--accent); color: var(--bg); border-color: var(--accent); font-weight: 600; }
.pager .pg-gap { color: var(--muted); padding: 0 4px; font-size: 11px; }

/* Selection column on the Stocks table — narrow, centered checkbox. */
th.sel-col, td.sel-col {
  width: 26px; text-align: center; padding-left: 6px; padding-right: 6px;
}
.sel-col input[type="checkbox"] { margin: 0; cursor: pointer; }

/* Selection bar sits above the Stocks table when any row is selected. */
.selection-bar {
  display: flex; align-items: center; gap: 10px;
  margin: 0 0 6px; padding: 6px 10px;
  background: var(--panel-2); border: 1px solid var(--border); border-radius: 4px;
  font-size: 12px;
}
.selection-bar .btn { font-size: 12px; padding: 3px 12px; }
/* "Charts →" call-to-action — the user's primary action after picking rows.
   Bold yellow so it's hard to miss across themes, subthemes, stocks,
   quant, returns, and ticker tables. */
.selection-bar .sel-charts-btn,
.selection-bar a.sel-charts-btn {
  background: #f1c40f; color: #000; font-weight: 700; letter-spacing: 0.02em;
  border: 0; box-shadow: 0 0 0 1px rgba(255, 217, 47, 0.45);
}
.selection-bar .sel-charts-btn:hover { background: #fadb4b; }
/* Twinsies "Chart selected" button + the Picks "Chart selected" button share
   the same bold-yellow chart-action style used by the selection bar. */
.tw-chart-btn, .picks-charts-btn {
  background: #f1c40f; color: #000; font-weight: 700; letter-spacing: 0.02em;
  border: 0; box-shadow: 0 0 0 1px rgba(255, 217, 47, 0.45);
}
.tw-chart-btn:hover, .picks-charts-btn:hover { background: #fadb4b; }

/* ── Déjà Vu (historical pattern analogs) ─────────────────────────────────── */
.dejavu-headline { font-size: 14px; line-height: 1.5; margin: 4px 0 12px; }
.dejavu-tiles { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 14px; }
.dejavu-tile { background: var(--panel); border: 1px solid var(--border); border-radius: 8px;
  padding: 8px 14px; min-width: 118px; }
.dejavu-tile-label { font-size: 10px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); }
.dejavu-tile-value { font-size: 20px; font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1.15; }
.dejavu-tile-sub { font-size: 10px; margin-top: 1px; }
.dejavu-chart-wrap { background: var(--panel); border: 1px solid var(--border); border-radius: 8px;
  padding: 8px; margin-bottom: 4px; }
.dejavu-fan { display: block; }
.dejavu-chart-cap { font-size: 11px; margin: 0 0 14px; }
.dejavu-table { width: 100%; }
.dejavu-mini { margin-left: 6px; text-decoration: none; opacity: 0.65; font-size: 12px; }
.dejavu-mini:hover { opacity: 1; }

/* ── Ripple Effect (lead/lag) ─────────────────────────────────────────────── */
.ripple-cols { display: flex; flex-wrap: wrap; gap: 18px; }
.ripple-col { flex: 1 1 340px; min-width: 0; }
.ripple-col-head { margin: 4px 0 6px; }
.ripple-col-title { font-weight: 700; font-size: 13px; }
.ripple-table { width: 100%; }
.ripple-table td, .ripple-table th { vertical-align: middle; }
.ripple-curve { display: block; max-width: 100%; }
html.mobile-site .ripple-col { flex: 1 1 100%; }
html.mobile-site .dejavu-tile { flex: 1 1 42%; min-width: 0; }
html.mobile-site .dejavu-search input { flex: 1 1 100%; }

/* "Filter to selection" / "Use full universe" toggle. Solid accent when
   active so the user can tell at a glance that the entire pipeline is
   currently scoped to their selection. */
.selection-bar .sel-keep-only-btn {
  background: transparent; color: var(--accent); border: 1px solid var(--accent);
}
.selection-bar .sel-keep-only-btn:hover { background: rgba(99, 179, 237, 0.12); }
.selection-bar .sel-keep-only-btn.sel-keep-only-active {
  background: var(--accent); color: #0b1220; border-color: var(--accent);
  font-weight: 700;
}
/* Highlight the whole selection bar when curated mode is active so the
   user has an unmistakable visual cue that the table below is scoped. */
.selection-bar.curated-active {
  background: rgba(99, 179, 237, 0.10);
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent);
}
.link-btn {
  background: transparent; color: var(--muted); border: 0; padding: 0;
  font: inherit; font-size: 11px; cursor: pointer; text-decoration: underline;
  text-underline-offset: 2px;
}
.link-btn:hover { color: var(--text); }

/* Charts page — Finviz-style responsive grid of mini line charts. */
.charts-toolbar {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  margin: 0 0 10px;
}
.charts-toolbar .muted {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.05em;
  font-weight: 600; margin-right: 4px;
}
.charts-toolbar .chip {
  font-size: 11px; padding: 2px 8px;
}
/* Flex + centered so partial rows stay middle-aligned. Fixed card width
   (~25% bigger than the original 280×140) so they all share the same size
   regardless of how many fit. */
.charts-grid {
  display: flex; flex-wrap: wrap; gap: 10px;
  justify-content: center;
}
.chart-card {
  flex: 0 0 525px;
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 4px; padding: 6px 8px 2px;
  overflow: hidden;
}
.chart-card-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 8px; font-size: 12px; padding: 0 2px;
}
/* + Add form at the start of the /#charts toolbar. Lets the user add
   any ticker (or theme/subsector via the th: / sub: prefix the URL hash
   already understands) to the current grid without leaving the page. */
.charts-add-input {
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 4px;
  padding: 4px 8px; font: inherit; font-size: 12px;
  width: 130px; letter-spacing: 0.03em;
}
.charts-add-input:focus { border-color: var(--accent); outline: none; }
.charts-add-msg { font-size: 11px; margin-left: 4px; }

.chart-card-sym { font-weight: 700; color: #fff; font-size: 13px; flex: 0 0 auto; }
.chart-card-sym:hover { color: var(--accent); text-decoration: none; }
.chart-card-kratio { font-weight: 400; font-size: 11px; margin-left: 4px; }
/* Company name sits between the ticker symbol and the change badge.
   flex:1 so it consumes any extra horizontal room; ellipsis on overflow
   so long company names ("Western Digital Corporation") don't push the
   change/× off the right edge of the card. */
.chart-card-name {
  flex: 1 1 auto; min-width: 0;
  font-size: 11px; font-weight: 400;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chart-card-change { font-variant-numeric: tabular-nums; font-size: 11px; flex: 0 0 auto; }
/* Per-card actions row (stock cards only): add to Picks / add to a watchlist,
   with an inline feedback message. Sits between the head and the chart canvas.
   Reuses .td-add-pick + .td-watchlist-select so it matches the profile page. */
.chart-card-actions {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  padding: 4px 2px 2px; font-size: 11px;
}
.chart-card-actions .chart-card-pick,
.chart-card-actions .chart-card-anti { font-size: 11px; padding: 2px 8px; }
.chart-card-actions .chart-card-wl { padding: 2px 6px; font-size: 11px; max-width: 160px; }
.chart-card-msg { font-size: 11px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chart-card-msg a { color: var(--accent); text-decoration: none; }
.chart-card-msg a:hover { text-decoration: underline; }
/* Per-card × removes this ticker from the multi-chart group. */
.chart-card-remove {
  background: transparent; color: var(--muted); border: 0;
  font-size: 16px; line-height: 1; cursor: pointer; padding: 0 4px;
  margin-left: auto;
}
.chart-card-remove:hover { color: var(--red); }
.chart-card-canvas { width: 100%; height: 263px; }

.card-sel-label { display: inline-flex; align-items: center; cursor: pointer; margin-right: 6px; }
.card-sel { margin: 0; cursor: pointer; }

/* Big overlay-comparison chart that appears above the mini grid when one
   or more cards are checkbox-selected. Spans the full content width. */
.charts-overlay-wrap {
  background: var(--panel); border: 1px solid var(--border); border-radius: 6px;
  padding: 10px 12px; margin: 0 0 14px;
  /* Without overflow: hidden the inner lightweight-charts canvas was free
     to push the wrap wider than the viewport, which made the parent
     section grow horizontally and left the chart truncated at smaller
     browser widths. Clipping the wrap forces the canvas to obey the
     ResizeObserver's measured parent width. */
  overflow: hidden;
}
.charts-overlay-legend {
  display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 6px;
  font-size: 12px; font-variant-numeric: tabular-nums;
}
.ov-swatch { display: inline-flex; align-items: center; gap: 6px; color: var(--text); }
.ov-dot { display: inline-block; width: 10px; height: 10px; border-radius: 2px; }
.charts-overlay-chart { width: 100%; height: 480px; }
.monthly-filter-btn.active { color: var(--accent); border-color: var(--accent); }
.monthly-filter-pop {
  min-width: 460px;
  max-height: calc(100vh - 80px);
  overflow: auto;
}
.monthly-filter-pop .mf-help { font-size: 11px; margin-bottom: 8px; }
.monthly-filter-pop .mf-grid {
  width: 100%; border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}
.monthly-filter-pop .mf-grid th {
  font-size: 11px; font-weight: 600; color: var(--muted);
  text-align: center; padding: 6px 4px;
  border-bottom: 1px solid var(--border);
}
.monthly-filter-pop .mf-grid th:first-child { text-align: left; }
.monthly-filter-pop .mf-grid td { padding: 4px 4px; vertical-align: middle; text-align: center; }
.monthly-filter-pop .mf-grid .mf-month {
  font-size: 12px; color: var(--text); white-space: nowrap;
  padding-right: 10px; text-align: left;
}
.monthly-filter-pop .mf-pick {
  display: inline-flex; border: 1px solid var(--border); border-radius: 4px; overflow: hidden;
}
.monthly-filter-pop .mf-pick button {
  background: transparent; color: var(--muted);
  border: 0; padding: 2px 8px; font-size: 11px; cursor: pointer;
  border-right: 1px solid var(--border);
}
.monthly-filter-pop .mf-pick button:last-child { border-right: 0; }
.monthly-filter-pop .mf-pick button:hover { background: rgba(255,255,255,0.04); color: var(--text); }
.monthly-filter-pop .mf-pick button.on {
  background: var(--accent); color: var(--bg); font-weight: 600;
}

/* Month return columns — tighter than the 1D/1W/.../5Y columns since there
   are 12 of them. Tables that grow past viewport width scroll horizontally
   inside their parent section. */
.month-col, .month-cell {
  font-size: 11px; padding-left: 4px; padding-right: 4px;
  white-space: nowrap;
}
.month-col { color: var(--muted); }
main section { overflow-x: auto; }

/* Charts view opts out — the wide tables don't appear here, and the
   default overflow-x:auto would let the lightweight-charts canvas push
   #charts-view wider than the viewport, defeating the ResizeObserver
   on the overlay chart and leaving it truncated at smaller window
   widths. Clip and force children to fit. */
#charts-view { overflow-x: hidden; min-width: 0; }
#charts-view > *, #charts-view .charts-overlay-wrap,
#charts-view .charts-overlay-chart, #charts-view #charts-grid { min-width: 0; max-width: 100%; }

.ret-pos { color: var(--green); }
.ret-neg { color: #7BAFD4; }

/* ── Finviz-style ticker page grid ───────────────────────────────────────
   Sector chain row + dense 8-column stat grid above the chart. Mirrors
   the visual density of elite.finviz.com/quote: very small font, narrow
   row height, hairline borders, green/red color on positive/negative
   numbers. Each cell is {key, value} laid out horizontally. */

#ticker-detail-view #td-identity {
  font-style: italic;
  font-size: 12px;
  margin: 6px 0 8px;
  color: var(--muted);
}
#ticker-detail-view #td-identity a {
  color: var(--accent);
  text-decoration: none;
}
#ticker-detail-view #td-identity a:hover { text-decoration: underline; }
#ticker-detail-view #td-identity .td-identity-tail {
  display: block;
  margin-top: 2px;
  font-style: normal;
  font-size: 11px;
  color: var(--muted);
}

/* Finviz-flow sections under the chart: Description (filled) plus the
   blank Insider Trading / News / Analyst Ratings parity blocks. */
#ticker-detail-view .td-section {
  margin: 14px 0 0;
}
#ticker-detail-view .td-section-h {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 6px;
  padding-bottom: 4px;
  border-bottom: 1px solid var(--border, #2a2a2a);
}
#ticker-detail-view .td-description {
  font-size: 13px;
  line-height: 1.55;
  color: var(--text, #ddd);
  margin: 0;
  max-width: 1100px;
}
/* Recent-news block on the profile. */
.td-news { margin: 18px 0; max-width: 1100px; }
.td-news-h { margin: 0 0 8px; font-size: 15px; }
.td-news-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 8px; }
.td-news-item { display: flex; flex-direction: column; gap: 1px; }
.td-news-item a { font-size: 13.5px; }
.td-news-meta { font-size: 11px; }
/* Intentionally-empty parity blocks: keep a small footprint so the heading
   reads as a placeholder rather than a broken section. */
#ticker-detail-view .td-blank {
  min-height: 18px;
}

#ticker-detail-view .td-finviz-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
  /* 6 boxes wide, centered — Finviz-style dense block, not edge-to-edge. */
  margin: 8px auto 12px;
  max-width: 1100px;
  border: 1px solid var(--border);
  border-radius: 4px;
  overflow: hidden;
  background: var(--panel);
}
#ticker-detail-view .td-fv-row {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 0;
  border-bottom: 1px solid var(--border);
}
#ticker-detail-view .td-fv-row:last-child { border-bottom: 0; }
#ticker-detail-view .td-fv-cell {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  padding: 4px 8px;
  font-size: 11px;
  line-height: 1.4;
  border-right: 1px solid var(--border);
  min-width: 0;
  overflow: hidden;
}
#ticker-detail-view .td-fv-cell:last-child { border-right: 0; }
#ticker-detail-view .td-fv-cell:hover { background: rgba(255,255,255,0.03); }
#ticker-detail-view .td-fv-k {
  color: var(--muted);
  text-transform: none;
  letter-spacing: 0;
  font-weight: 400;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#ticker-detail-view .td-fv-v {
  color: var(--text);
  font-weight: 600;
  text-align: right;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-variant-numeric: tabular-nums;
}
#ticker-detail-view .td-fv-v.ret-pos { color: var(--green); }
#ticker-detail-view .td-fv-v.ret-neg { color: #7BAFD4; }

/* Narrow screens: step 6 → 3 → 2 columns so cells stay legible. */
@media (max-width: 1000px) {
  #ticker-detail-view .td-fv-row { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 560px) {
  #ticker-detail-view .td-fv-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ── Peers strip (below the chart) ────────────────────────────────────────
   Horizontal-scrolling row of compact peer cards. Each card links to that
   ticker's profile. Designed to be skimmable: ticker, market cap, K-ratio,
   1Y return — same fields the rest of the site uses to compare tickers. */
#ticker-detail-view #td-peers { margin: 14px 0 16px; }
#ticker-detail-view #td-peers:empty { display: none; }
#ticker-detail-view .td-peers-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: 12px;
  margin: 0 0 6px;
}
#ticker-detail-view .td-peers-title {
  font-weight: 700;
  font-size: 13px;
  color: var(--text);
  letter-spacing: 0.01em;
}
#ticker-detail-view .td-peers-head a { color: var(--accent); text-decoration: none; }
#ticker-detail-view .td-peers-head a:hover { text-decoration: underline; }
#ticker-detail-view .td-peers-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 2px 0 6px;
}
#ticker-detail-view .td-peer-card {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--panel);
  font-size: 11px;
  color: var(--text);
  text-decoration: none;
  white-space: nowrap;
  flex: 0 0 auto;
  transition: border-color 90ms ease, background 90ms ease;
}
#ticker-detail-view .td-peer-card:hover {
  border-color: var(--accent);
  background: rgba(255,255,255,0.04);
}
#ticker-detail-view .td-peer-card .logo {
  height: 18px; width: 18px; border-radius: 4px;
}
#ticker-detail-view .td-peer-sym { font-weight: 700; }
#ticker-detail-view .td-peer-mcap,
#ticker-detail-view .td-peer-k { font-variant-numeric: tabular-nums; }
#ticker-detail-view .td-peer-r1y {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  min-width: 50px;
  text-align: right;
}

/* ── Annual revenue chart ─────────────────────────────────────────────── */
#ticker-detail-view #td-revenue-chart { margin: 16px 0 18px; }
#ticker-detail-view #td-revenue-chart:empty { display: none; }
#ticker-detail-view .td-rev-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: 12px;
  margin: 0 0 4px;
}
#ticker-detail-view .td-rev-title {
  font-weight: 700;
  font-size: 13px;
  color: var(--text);
  letter-spacing: 0.01em;
}
#ticker-detail-view .td-rev-svg {
  display: block;
  width: 100%;
  height: auto;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 4px;
}
#ticker-detail-view .td-rev-bar       { fill: #4DD0E1; opacity: 0.75; }
#ticker-detail-view .td-rev-bar.td-rev-up   { fill: var(--green); opacity: 0.80; }
#ticker-detail-view .td-rev-bar.td-rev-down { fill: #7BAFD4;       opacity: 0.85; }
#ticker-detail-view .td-rev-bar-label {
  fill: var(--text);
  font-size: 10px;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}
#ticker-detail-view .td-rev-bar-year {
  fill: var(--muted);
  font-size: 10px;
  font-variant-numeric: tabular-nums;
}
#ticker-detail-view .td-rev-yoy {
  font-size: 10px;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}
#ticker-detail-view .td-rev-yoy-up   { fill: var(--green); }
#ticker-detail-view .td-rev-yoy-down { fill: #7BAFD4; }

/* ── Annual gross-margin chart ────────────────────────────────────────
   Same layout as the revenue chart but neutral bars are a warmer
   amber so the two charts are quickly distinguishable when stacked. */
#ticker-detail-view #td-gm-chart { margin: 16px 0 18px; }
#ticker-detail-view #td-gm-chart:empty { display: none; }
#ticker-detail-view .td-gm-bar         { fill: #e4c98a; opacity: 0.75; }
#ticker-detail-view .td-gm-bar.td-gm-up   { fill: var(--green); opacity: 0.80; }
#ticker-detail-view .td-gm-bar.td-gm-down { fill: #7BAFD4;       opacity: 0.85; }
#ticker-detail-view .td-gm-bar-label {
  fill: var(--text);
  font-size: 10px;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}
#ticker-detail-view .td-gm-bar-year {
  fill: var(--muted);
  font-size: 10px;
  font-variant-numeric: tabular-nums;
}
#ticker-detail-view .td-gm-yoy {
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  letter-spacing: 0.01em;
}
#ticker-detail-view .td-gm-yoy-up   { fill: var(--green); }
#ticker-detail-view .td-gm-yoy-down { fill: #7BAFD4; }

/* ── Annual shares-outstanding chart ──────────────────────────────────
   Sharadar fiscal-year-end sharesbas. Neutral bars a violet so the three
   annual charts are quickly distinguishable. Direction-based colour like the
   other two: shares up = green, shares down (buyback) = blue. */
#ticker-detail-view #td-shares-chart:empty { display: none; }
#ticker-detail-view .td-sh-bar          { fill: #b39ddb; opacity: 0.75; }
#ticker-detail-view .td-sh-bar.td-sh-up   { fill: var(--green); opacity: 0.80; }
#ticker-detail-view .td-sh-bar.td-sh-down { fill: #7BAFD4;       opacity: 0.85; }
#ticker-detail-view .td-sh-yoy {
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  letter-spacing: 0.01em;
}
#ticker-detail-view .td-sh-yoy-up   { fill: var(--green); }
#ticker-detail-view .td-sh-yoy-down { fill: #7BAFD4; }
/* Header net-change summaries: blue (not the global red) for a decrease,
   matching the bars' green-up / blue-down scheme. Scoped to these charts. */
#ticker-detail-view #td-annual-charts .ret-neg { color: #7BAFD4; }

/* ── Annual charts, two per row ───────────────────────────────────────
   Revenue | Gross Margin / Shares Outstanding | Market Cap — a 2-column
   wrapping grid. Each child collapses when empty (an empty cell is removed
   from the flow, so the remaining charts re-flow to fill the rows). */
#ticker-detail-view #td-annual-charts {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: flex-start;
  margin: 16px 0 18px;
}
#ticker-detail-view #td-annual-charts > div {
  flex: 1 1 calc(50% - 6px);
  max-width: calc(50% - 6px);
  min-width: 0; margin: 0;
}
#ticker-detail-view #td-annual-charts > div:empty { display: none; }
/* Each chart renders at ~1/3 width, so shrink all in-SVG text to keep the
   per-bar value / YoY / year labels from running into their neighbours. */
#ticker-detail-view #td-annual-charts .td-rev-bar-label,
#ticker-detail-view #td-annual-charts .td-rev-bar-year,
#ticker-detail-view #td-annual-charts .td-gm-bar-label,
#ticker-detail-view #td-annual-charts .td-gm-bar-year,
#ticker-detail-view #td-annual-charts .td-rev-yoy,
#ticker-detail-view #td-annual-charts .td-gm-yoy,
#ticker-detail-view #td-annual-charts .td-sh-yoy { font-size: 8px; }
/* Mobile replica: stack the three vertically rather than cram them across. */
html.mobile-site #ticker-detail-view #td-annual-charts { flex-direction: column; }

/* ──────────────────────────────────────────────────────────────────────
   MOBILE OVERLAY (mob.770-617-6983.com)
   ──────────────────────────────────────────────────────────────────────
   The .mobile-site class is set on <html> by an inline script in
   index.html when the page is served on mob.* (or with ?mobile=1).
   Same worker, same D1, same JS — these rules just retarget the layout
   for a phone-sized viewport. Desktop visitors at 770-617-6983.com see
   no change.

   Strategy: avoid restructuring components, just collapse the controls,
   bump touch-target sizes, allow tables to scroll horizontally with a
   sticky left column so the ticker/name stays visible while a finger
   pans through monthly returns. */

html.mobile-site { font-size: 14px; }

/* iOS notch / dynamic-island handling. viewport-fit=cover in the meta
   lets content flow under the safe area; env(safe-area-inset-*) pushes
   our chrome back inside it. Only matters for installed PWAs and
   landscape mobile browsers, but no harm on others. */
html.mobile-site body { padding-bottom: max(70px, env(safe-area-inset-bottom)); }
html.mobile-site header {
  padding-top: max(6px, env(safe-area-inset-top));
  padding-left: max(10px, env(safe-area-inset-left));
  padding-right: max(10px, env(safe-area-inset-right));
}
html.mobile-site .mob-nav-toggle {
  top: max(10px, env(safe-area-inset-top));
  right: max(10px, env(safe-area-inset-right));
}
html.mobile-site .mob-top-btn {
  right: max(14px, calc(env(safe-area-inset-right) + 4px));
  bottom: max(80px, calc(env(safe-area-inset-bottom) + 70px));
}
html.mobile-site .site-footer {
  bottom: max(8px, env(safe-area-inset-bottom));
}
html.mobile-site .selection-bar:not([hidden]) {
  padding-bottom: max(10px, env(safe-area-inset-bottom));
  padding-left: max(12px, env(safe-area-inset-left));
  padding-right: max(12px, env(safe-area-inset-right));
}

/* Smoother horizontal panning on tables, peers strip, and charts grid.
   touch-action: pan-x tells the browser "this gesture is horizontal" so
   the vertical scroll on the parent stays responsive — no laggy
   diagonal-pan handoff. overscroll-behavior contains the bounce so a
   sideways pan doesn't trigger pull-to-refresh. */
html.mobile-site main section,
html.mobile-site .td-peers-strip,
html.mobile-site .top-nav {
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
}
html.mobile-site main section { touch-action: pan-x pan-y; }
html.mobile-site .td-peers-strip,
html.mobile-site .top-nav { touch-action: pan-x; }

/* Header: keep the logo + brand, stack the nav below as a horizontally-
   scrollable strip. Search drops to its own line so the touch target is
   the full width. */
html.mobile-site header { padding: 6px 10px 4px; }
html.mobile-site .header-row {
  flex-direction: column;
  align-items: stretch;
  gap: 6px;
}
html.mobile-site .site-brand { font-size: 18px; gap: 6px; }
html.mobile-site .site-logo  { height: 26px; }

/* Hamburger button: three stacked bars that morph to an X when open.
   Desktop hides it via display:none — only .mobile-site shows it.
   Fixed-position so it stays accessible while the user scrolls
   through a long page (and after the header scrolls off-screen). */
.mob-nav-toggle { display: none; }
html.mobile-site .mob-nav-toggle {
  display: inline-flex;
  flex-direction: column;
  justify-content: space-between;
  width: 36px;
  height: 28px;
  padding: 4px 0;
  border: 0;
  background: rgba(13, 17, 22, 0.86);
  border-radius: 6px;
  cursor: pointer;
  position: fixed;
  right: 10px;
  top: 10px;
  z-index: 100;
  backdrop-filter: blur(4px);
}
html.mobile-site .mob-nav-toggle span:nth-child(1),
html.mobile-site .mob-nav-toggle span:nth-child(2),
html.mobile-site .mob-nav-toggle span:nth-child(3) {
  margin: 0 auto;
  width: 22px;
}
html.mobile-site .mob-nav-toggle span {
  display: block;
  height: 2px;
  background: var(--text);
  border-radius: 2px;
  transition: transform 160ms ease, opacity 120ms ease;
}
html.mobile-site .mob-nav-toggle[aria-expanded="true"] span:nth-child(1) {
  transform: translateY(8px) rotate(45deg);
}
html.mobile-site .mob-nav-toggle[aria-expanded="true"] span:nth-child(2) {
  opacity: 0;
}
html.mobile-site .mob-nav-toggle[aria-expanded="true"] span:nth-child(3) {
  transform: translateY(-8px) rotate(-45deg);
}

/* primary-nav becomes a slide-in drawer on mobile. It's pre-rendered
   off-canvas (right: -100%) and animated in via right: 0 when the
   hamburger gets aria-expanded="true". Background dim handled by a
   ::before pseudo-element on <body> when the drawer is open. */
html.mobile-site .primary-nav {
  position: fixed;
  top: 0;
  right: -80%;
  width: 78%;
  max-width: 320px;
  height: 100vh;
  background: var(--panel);
  border-left: 1px solid var(--border);
  flex-direction: column;
  align-items: stretch;
  gap: 0;
  padding: 60px 0 20px;
  overflow-y: auto;
  transition: right 220ms ease;
  z-index: 90;
  box-shadow: -8px 0 24px rgba(0, 0, 0, 0.4);
}
html.mobile-site.nav-open .primary-nav { right: 0; }
html.mobile-site .primary-nav a {
  display: block;
  padding: 12px 18px;
  font-size: 15px;
  border-bottom: 1px solid var(--border);
  text-decoration: none;
  color: var(--text);
}
html.mobile-site .primary-nav a.active {
  background: rgba(88, 166, 255, 0.08);
  color: var(--accent);
  border-left: 3px solid var(--accent);
  padding-left: 15px;
}

/* Scrim behind the open drawer. */
html.mobile-site.nav-open::after {
  content: "";
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.45);
  z-index: 80;
  animation: mob-scrim-in 180ms ease;
}
@keyframes mob-scrim-in { from { opacity: 0; } to { opacity: 1; } }
html.mobile-site #search {
  width: 100%;
  font-size: 16px;          /* iOS won't zoom on focus when ≥16px */
  padding: 8px 10px;
  border-radius: 6px;
}
html.mobile-site .meta-strip {
  font-size: 11px;
  padding: 2px 10px;
  color: var(--muted);
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
}

/* Breadcrumb row stays at the top of the viewport while you scroll — it
   doubles as the always-visible site-map indicator now that the page
   h2s aren't reliably present everywhere. */
html.mobile-site .breadcrumb-bar {
  position: sticky;
  top: 0;
  z-index: 6;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  padding: 6px 10px 4px;
  font-size: 13px;
  flex-wrap: wrap;
}
html.mobile-site .breadcrumb-bar .back { font-size: 14px; padding: 4px 0; }
html.mobile-site .breadcrumb {
  font-size: 12px;
  flex: 1 1 auto;
  min-width: 0;
  /* Cap to 2 lines so a really long subsector name doesn't push the
     content way down. -webkit-line-clamp degrades gracefully in
     browsers that don't support it (just shows full text). */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  line-height: 1.35;
}

/* Magnifying glass button on the mobile breadcrumb. Desktop hides it. */
.mob-search-btn { display: none; }
html.mobile-site .mob-search-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border);
  background: var(--panel);
  border-radius: 6px;
  width: 32px;
  height: 32px;
  font-size: 14px;
  cursor: pointer;
  margin-left: auto;
}
html.mobile-site .mob-search-btn:hover { border-color: var(--accent); }

/* Column filter dropdowns (sortable-table header arrows): bump the
   target size and widen the pop to be tappable on phone. */
html.mobile-site .th-filter-btn { font-size: 14px; padding: 4px 6px; }
html.mobile-site .col-filter-pop {
  min-width: 200px;
  max-width: calc(100vw - 24px);
  font-size: 13px;
  padding: 12px;
}
html.mobile-site .col-filter-pop label {
  padding: 8px 0;
  font-size: 13px;
}
html.mobile-site .col-filter-pop .cf-num {
  font-size: 14px;
  padding: 8px 10px;
}
html.mobile-site .col-filter-pop .cf-actions button {
  min-height: 36px;
  padding: 8px 14px;
}

/* Header isn't sticky on mobile — once you scroll past it, the
   sticky breadcrumb takes over as the persistent navigation cue.
   The hamburger lives in the header so it'll be off-screen when
   the user is deep in a long table — they can swipe up or scroll
   to top to reach it. */

/* Main content: tighter side padding so tables and charts use the
   maximum available width. */
html.mobile-site main { padding: 4px 10px 60px; }

/* Page-heading h2 styling on mobile — non-sticky. The sticky
   breadcrumb-bar above main already handles "where am I" persistence
   on scroll; making the h2 ALSO sticky at top:0 caused it to fight the
   breadcrumb for the same viewport pixels. Keep the size + dividing
   border but let it scroll with the content. */
html.mobile-site main section h2 {
  margin: 0 -10px 8px;
  padding: 8px 10px;
  border-bottom: 1px solid var(--border);
  font-size: 16px;
}
html.mobile-site #ticker-detail-view h2#td-ticker {
  margin: 0 -10px;
  padding: 6px 10px;
  border-bottom: 1px solid var(--border);
}

/* Tables: allow horizontal scroll inside each section (already the
   default), make the header row sticky, bump padding so taps land on
   the right row, and pin the ticker/name column to the left so the
   row label stays visible while scrolling sideways through monthly
   columns. Top-left corner cell (sticky in both axes) gets a higher
   z-index so it sits above the rest. */
html.mobile-site table {
  font-size: 12px;
  border-collapse: separate;
  border-spacing: 0;
}
html.mobile-site thead th {
  position: sticky;
  top: 0;
  background: var(--panel);
  z-index: 2;
}
html.mobile-site tbody td,
html.mobile-site thead th {
  padding: 6px 8px;
  white-space: nowrap;
}
html.mobile-site tbody tr { min-height: 38px; }

/* Sticky-left first content column on the main data tables. The
   leftmost columns are usually a select checkbox (.sel-col) and a
   ticker / name cell. We pin both so they form a fixed left "rail"
   while the user pans horizontally. */
html.mobile-site #stocks-table tbody td:nth-child(1),
html.mobile-site #stocks-table thead th:nth-child(1),
html.mobile-site #quant-table tbody td:nth-child(1),
html.mobile-site #quant-table thead th:nth-child(1),
html.mobile-site #screener-table tbody td:nth-child(1),
html.mobile-site #screener-table thead th:nth-child(1),
html.mobile-site #themes-table tbody td:nth-child(1),
html.mobile-site #themes-table thead th:nth-child(1) {
  position: sticky;
  left: 0;
  background: var(--bg);
  z-index: 1;
}
html.mobile-site #stocks-table tbody td:nth-child(2),
html.mobile-site #stocks-table thead th:nth-child(2),
html.mobile-site #quant-table tbody td:nth-child(2),
html.mobile-site #quant-table thead th:nth-child(2) {
  position: sticky;
  left: 32px;          /* width of the select-checkbox column */
  background: var(--bg);
  z-index: 1;
  box-shadow: 4px 0 6px -4px rgba(0, 0, 0, 0.6);
}
html.mobile-site thead th:nth-child(1),
html.mobile-site thead th:nth-child(2) {
  background: var(--panel);
  z-index: 3;          /* above both column-sticky and row-sticky bodies */
}

/* Buttons / chips: enforce a 36px+ touch target. */
html.mobile-site .chip,
html.mobile-site .btn,
html.mobile-site button {
  min-height: 36px;
  padding: 6px 10px;
  font-size: 13px;
}

/* Quant filter cards stack to a single column and expand. */
html.mobile-site .quant-controls {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
html.mobile-site .quant-factor {
  width: 100%;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px 10px;
  padding: 8px 10px;
}
html.mobile-site .quant-factor-head { grid-column: 1 / -1; }
html.mobile-site .quant-w-input { font-size: 16px; padding: 6px 8px; }

/* Recent-tickers strip on the home (themes) view. Compact pill-row
   linking to the user's last 8 ticker pages. Same look as the peers
   strip on the ticker page. Hidden when empty. */
.recent-tickers { margin: 6px 0 14px; }
.recent-tickers:empty { display: none; }
.recent-tickers-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin: 0 0 4px;
  font-size: 12px;
}
.recent-tickers-title {
  font-weight: 700;
  font-size: 13px;
  color: var(--text);
}
.recent-tickers-strip {
  display: flex;
  flex-wrap: nowrap;
  gap: 6px;
  overflow-x: auto;
  padding: 2px 0 4px;
}
.recent-ticker-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--panel);
  color: var(--text);
  text-decoration: none;
  font-size: 12px;
  white-space: nowrap;
  flex: 0 0 auto;
}
.recent-ticker-chip:hover { border-color: var(--accent); }
.recent-ticker-chip .logo { height: 16px; width: 16px; border-radius: 3px; }
.recent-ticker-sym { font-weight: 700; }

/* Quant action buttons row: the Reset / Share pair gets consistent
   spacing without inline styles. */
#quant-reset + .btn,
#quant-reset ~ #quant-share { margin-left: 8px; }

/* Top-of-viewport progress bar. Hidden by default. .loading on body
   makes the bar visible and animates a sweeping indeterminate
   gradient — set whenever any /api/* fetch is in flight. */
.global-progress {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: transparent;
  pointer-events: none;
  z-index: 200;
  overflow: hidden;
  visibility: hidden;
}
body.loading .global-progress {
  visibility: visible;
}
body.loading .global-progress::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to right, transparent 0%, var(--accent) 50%, transparent 100%);
  animation: gp-sweep 1.1s ease-in-out infinite;
}
@keyframes gp-sweep {
  from { transform: translateX(-100%); }
  to   { transform: translateX(100%); }
}

/* iOS-safe: any number/text input gets ≥16px on mobile so focus
   doesn't trigger the auto-zoom-in browser hack. */
html.mobile-site input[type="number"],
html.mobile-site input[type="text"],
html.mobile-site input[type="search"],
html.mobile-site input[type="email"],
html.mobile-site input[type="url"] {
  font-size: 16px;
}

/* Sub-industry / ticker page rows that pair a title with an action
   button (e.g. CSV export) need to wrap on phone instead of squishing. */
html.mobile-site .row {
  flex-wrap: wrap;
  gap: 8px;
}
html.mobile-site #csv-export {
  font-size: 12px;
  padding: 8px 12px;
  min-height: 36px;
}

/* Stocks / screener / quant tables: cap their visible height so the
   filter UI doesn't push the data off-screen. */
html.mobile-site #stocks-table,
html.mobile-site #screener-table,
html.mobile-site #quant-table { font-size: 11.5px; }

/* Ticker page Finviz grid: drop straight to 2 columns and collapse all
   but the first row by default. A "Show all stats" toggle (rendered by
   renderFinvizGrid) expands the rest. */
html.mobile-site #ticker-detail-view .td-fv-row {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
html.mobile-site #ticker-detail-view .td-fv-cell {
  padding: 5px 8px;
  font-size: 12px;
}
html.mobile-site #ticker-detail-view .td-finviz-grid:not(.td-finviz-expanded) .td-fv-row:nth-child(n+2) {
  display: none;
}
html.mobile-site #ticker-detail-view .td-fv-expand {
  display: block;
  width: 100%;
  margin: 8px 0;
  padding: 8px 12px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--accent);
  font-size: 13px;
  font-weight: 600;
  text-align: center;
  cursor: pointer;
}
/* Desktop: hide the expand button entirely. */
.td-fv-expand { display: none; }

/* TradingView lightweight-charts container: keep full width but
   shorter height so the toolbar + chart fit on a phone screen. */
html.mobile-site #tv-chart-wrap { margin-top: 6px; }
html.mobile-site #tv-chart { height: 260px !important; }
html.mobile-site .chart-card-canvas { height: 180px !important; }

/* Ticker page: the price-chart toolbars use very tight padding on
   desktop. On mobile, wrap them generously and give each chip a real
   touch target. Compare overlays (Subtheme / S&P / XLK / peer input)
   also wrap onto multiple lines so they don't truncate. */
html.mobile-site #ticker-detail-view .chart-toolbar {
  flex-wrap: wrap;
  gap: 4px 6px;
  margin: 4px 0;
  padding: 4px 0;
  font-size: 13px;
}
html.mobile-site #ticker-detail-view .chart-toolbar .chip,
html.mobile-site #ticker-detail-view .chart-toolbar .chart-toggle {
  min-height: 32px;
  padding: 6px 9px;
  font-size: 12px;
}
html.mobile-site #compare-input {
  width: 110px;
  min-height: 32px;
  font-size: 13px;
}
html.mobile-site #compare-peers .compare-peer {
  font-size: 12px;
  padding: 4px 8px;
}

/* Charts grid mini-card toolbars (the Range / SMA / Sort row above
   the small charts). Same wrap + chip bump as the ticker page. */
html.mobile-site .charts-toolbar {
  flex-wrap: wrap;
  gap: 4px 6px;
  padding: 6px 0;
}
html.mobile-site .charts-toolbar .chip {
  min-height: 32px;
  padding: 6px 9px;
  font-size: 12px;
}

/* Charts grid: single column on phone. */
html.mobile-site #charts-grid { grid-template-columns: 1fr; }

/* Multi-stock overlay chart: cap height so it doesn't dominate the
   viewport, and shrink the legend swatches. */
html.mobile-site .charts-overlay-chart { height: 280px !important; }
html.mobile-site .charts-overlay-legend {
  font-size: 11px;
  gap: 4px 10px;
  flex-wrap: wrap;
}
html.mobile-site .charts-overlay-wrap { margin: 8px 0 14px; }

/* ── Mobile: Charts cards full-width ─────────────────────────────────────
   Desktop cards are a fixed 525px (≈140% of a 375px phone), so they
   overflow. Make each card fill the viewport and stack vertically; the
   #charts-grid grid-template-columns rule above is a no-op on the flex
   container, so the width override is what actually fixes it. */
html.mobile-site .charts-grid { justify-content: flex-start; gap: 14px 0; }
html.mobile-site .chart-card { flex: 0 0 100%; max-width: 100%; }
/* Header + actions wrap instead of overflowing the narrow card. */
html.mobile-site .chart-card-head { flex-wrap: wrap; row-gap: 2px; }
html.mobile-site .chart-card-name { flex-basis: 100%; order: 5; }
html.mobile-site .chart-card-actions { flex-wrap: wrap; row-gap: 4px; }
html.mobile-site .charts-add-input { font-size: 16px; }

/* ── Mobile: Quant filter panel + table ──────────────────────────────────
   The filter catalog is a 2-col grid (≥290px per col) on desktop — force a
   single column so it fits a phone. Cover both the grid and column-major
   variants. */
html.mobile-site .quant-filter-grid,
html.mobile-site .quant-filter-col {
  grid-template-columns: 1fr !important;
  grid-auto-flow: row !important;
  grid-template-rows: auto !important;
  max-width: 100% !important;
  gap: 2px 0 !important;
}
/* Number inputs / selects in the panel: 16px so iOS doesn't zoom on focus,
   and a touch-comfortable height. */
html.mobile-site .quant-filter-input,
html.mobile-site .quant-filter-dir,
html.mobile-site .quant-preset,
html.mobile-site .quant-filter-gap-input,
html.mobile-site .quant-filter-gap-dir,
html.mobile-site .quant-rg-pct, html.mobile-site .quant-rg-years,
html.mobile-site .quant-eg-pct, html.mobile-site .quant-eg-years,
html.mobile-site .quant-gm-pp, html.mobile-site .quant-gm-years,
html.mobile-site .quant-sg-pct, html.mobile-site .quant-sg-years,
html.mobile-site .quant-mcg-pct, html.mobile-site .quant-mcg-years,
html.mobile-site .quant-ma-pct, html.mobile-site .quant-ma-dir,
html.mobile-site .quant-gmstreak-min { font-size: 16px; min-height: 30px; }
/* Filter rows: the desktop 5-col grid (96/80/42/52px) crams a phone and
   truncates the preset. Reflow each row to two lines — label on top, then the
   controls (preset grows, dir + number input + unit) on a comfortable line —
   so every control is readable and tappable. Covers the custom row variants
   (revgrowth/eg/gm/sg/mcg, gap, gmstreak) too since they share the row class. */
html.mobile-site .quant-filter-row {
  display: flex !important; flex-wrap: wrap; align-items: center;
  gap: 6px 8px; padding: 9px 26px 9px 8px; min-height: 0; font-size: 13px;
  border-bottom: 1px solid rgba(255,255,255,0.05);
}
html.mobile-site .quant-filter-row > .quant-filter-label {
  flex: 1 0 100%; text-align: left; font-size: 12.5px; font-weight: 600; color: var(--text);
}
html.mobile-site .quant-filter-row > select,
html.mobile-site .quant-filter-row > input { flex: 0 1 auto; min-width: 0; }
html.mobile-site .quant-filter-row > .quant-preset { flex: 1 1 120px; }
html.mobile-site .quant-filter-row > .quant-filter-input,
html.mobile-site .quant-filter-row > .quant-filter-gap-input { flex: 0 0 88px; text-align: right; }
html.mobile-site .quant-filter-row > .quant-filter-unit { flex: 0 0 auto; color: var(--muted); }
html.mobile-site .quant-filter-clear { top: 14px; transform: none; font-size: 18px; padding: 4px 6px; }
/* Tabs: a touch taller, wrap freely. */
html.mobile-site .quant-tab { min-height: 34px; padding: 7px 12px; }
/* Funnel strip pans horizontally rather than stacking into a tall wall of
   chips on a phone. */
html.mobile-site .quant-funnel {
  flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch;
  padding-bottom: 4px;
}
html.mobile-site .quant-funnel-step { flex: 0 0 auto; }
/* The wide (24-col) results table scrolls inside its own wrapper so the
   filter panel above stays put instead of sliding off-screen with it. */
html.mobile-site .quant-table-wrap {
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  max-width: 100%;
}

/* ── Mobile Quant: card list replaces the 24-col table ───────────────────────
   On a phone the wide table forces ~1500px of horizontal scrolling and the
   metric you sorted by is off-screen. Instead we hide the table and show a
   card per row (built by renderQuant from the SAME paginated rows), each with
   the sorted metric front-and-centre + a sort selector. Desktop is untouched. */
#quant-cards { display: none; }                 /* hidden on desktop */
html.mobile-site .quant-table-wrap { display: none; }
html.mobile-site #quant-cards { display: block; margin-top: 4px; }
/* Show the "N stocks that made the cut" count right above the card list (it
   sits in the DOM just before #quant-cards, so it lands exactly there). */
html.mobile-site #quant-table-count {
  display: block; margin: 10px 0 2px; padding: 8px 12px;
  background: var(--panel); border: 1px solid var(--border); border-radius: 8px;
  font-size: 15px; font-weight: 700; color: var(--text);
}
html.mobile-site .quant-table-count-num { color: var(--accent); }
html.mobile-site .quant-table-count-sub { font-size: 12px; font-weight: 400; color: var(--muted); }

/* Sort bar — stands in for the (absent) tappable column headers. */
.qc-sortbar { display: flex; align-items: center; gap: 8px; margin: 2px 0 10px; }
.qc-sortbar label { font-size: 12px; color: var(--muted); white-space: nowrap; }
.qc-sort-select {
  flex: 1 1 auto; min-width: 0;
  font-size: 16px;                                /* ≥16px so iOS doesn't zoom on focus */
  padding: 8px 10px; min-height: 42px; border-radius: 8px;
  background: var(--panel); color: var(--text); border: 1px solid var(--border);
}
.qc-sort-dir {
  flex: 0 0 auto; min-height: 42px; padding: 6px 12px; border-radius: 8px;
  background: var(--panel); color: var(--text); border: 1px solid var(--border);
  font-size: 13px; font-weight: 600; white-space: nowrap;
}
.qc-sort-dir:active { background: var(--panel-2); }

/* Card list. */
.qc-list { display: flex; flex-direction: column; gap: 8px; }
.qc-card {
  background: var(--panel); border: 1px solid rgba(255,255,255,0.08);
  border-radius: 10px; padding: 10px 12px;
}
.qc-child { margin-left: 16px; }                  /* expanded group members indent */
.qc-child .qc-card { background: rgba(255,255,255,0.025); }
.qc-head { display: flex; align-items: center; gap: 9px; }
.qc-chk { width: 20px; height: 20px; flex: 0 0 auto; accent-color: var(--accent); }
.qc-chk-spacer { width: 20px; flex: 0 0 auto; }
.qc-id { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; gap: 1px; }
.qc-idrow { display: flex; align-items: center; gap: 6px; min-width: 0; }
.qc-idrow img { width: 20px; height: 20px; border-radius: 4px; flex: 0 0 auto; }
.qc-ticker { font-size: 16px; font-weight: 700; color: var(--accent); text-decoration: none; white-space: nowrap; }
a.qc-ticker:active { opacity: 0.6; }
.qc-name { font-size: 11.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.qc-metric { display: flex; flex-direction: column; align-items: flex-end; flex: 0 0 auto; text-align: right; padding-left: 8px; }
.qc-metric-val { font-size: 18px; font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1.1; }
.qc-metric-lbl { font-size: 9.5px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); }
.qc-stats {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px 8px;
  margin-top: 9px; padding-top: 8px; border-top: 1px solid rgba(255,255,255,0.06);
}
.qc-stat { display: flex; flex-direction: column; min-width: 0; }
.qc-stat-lbl { font-size: 9.5px; text-transform: uppercase; letter-spacing: 0.03em; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.qc-stat-val { font-size: 13px; font-variant-numeric: tabular-nums; }
.qc-expand { background: none; border: none; color: var(--accent); font-size: 13px; padding: 0 4px 0 0; cursor: pointer; line-height: 1; }
.qc-empty { padding: 20px 12px; text-align: center; }

/* ── Mobile Quant: newer additions (AI screener, interpreted-filter editor,
   Twinsies page + profile strip). Desktop untouched. ─────────────────────── */
/* AI screener prompt: textarea full-width, Run + Clear wrap below it. */
html.mobile-site .ai-screen { padding: 10px; }
html.mobile-site .ai-screen-row { flex-wrap: wrap; }
html.mobile-site .ai-screen-row textarea { flex: 1 1 100%; width: 100%; font-size: 16px; }
html.mobile-site .ai-screen-run { flex: 1 1 auto; min-height: 42px; }
html.mobile-site .ai-screen-clear { flex: 0 0 auto; min-height: 42px; }
html.mobile-site .ai-screen-eg { min-height: 32px; font-size: 12px; }
/* Interpreted-filter editor rows: label on its own line, controls wrap. */
html.mobile-site .ai-filter { flex-wrap: wrap; row-gap: 5px; align-items: center; }
html.mobile-site .ai-filter .ai-f-label { flex: 1 1 100%; }
html.mobile-site .ai-filter input { font-size: 16px; }
html.mobile-site #ai-rerun-btn { min-height: 40px; }

/* Twinsies page: full-width search, stacked chart bar, trimmed table. */
html.mobile-site .twinsies-search input { flex: 1 1 100%; min-width: 0; font-size: 16px; }
html.mobile-site #twinsies-go { flex: 1 1 auto; min-height: 42px; }
html.mobile-site .tw-chart-bar { flex-direction: column; align-items: stretch !important; }
html.mobile-site .tw-chart-btn { min-height: 42px; }
html.mobile-site #twinsies-result { overflow-x: auto; -webkit-overflow-scrolling: touch; }
html.mobile-site .twinsies-table { width: 100%; font-size: 12px; }
/* Drop Company + Sector columns on a phone so the scores fit without scroll. */
html.mobile-site .twinsies-table th:nth-child(4), html.mobile-site .twinsies-table td:nth-child(4),
html.mobile-site .twinsies-table th:nth-child(5), html.mobile-site .twinsies-table td:nth-child(5) { display: none; }
html.mobile-site .twinsies-table .tw-pick,
html.mobile-site .twinsies-table .tw-pick-all { width: 20px; height: 20px; accent-color: var(--accent); }

/* Profile Twinsies strip: the peer-card mobile rule hides .td-peer-k/.td-peer-mcap,
   but those carry the twin score + SPY score here — re-show them (they ARE the point). */
html.mobile-site #td-twinsies .td-peer-card .td-peer-k,
html.mobile-site #td-twinsies .td-peer-card .td-peer-mcap { display: inline; }

/* Peers strip stays horizontal-scroll, but cards are restructured so
   the most-informative pieces (ticker + 1Y return) stack vertically and
   the strip pans faster. Logo + mcap + K are hidden to keep the strip
   thumb-skimmable; the user can tap into the profile for the rest. */
html.mobile-site .td-peer-card {
  font-size: 12px;
  padding: 7px 10px;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  min-width: 80px;
}
html.mobile-site .td-peer-card .logo { display: none; }
html.mobile-site .td-peer-card .td-peer-mcap,
html.mobile-site .td-peer-card .td-peer-k { display: none; }
html.mobile-site .td-peer-card .td-peer-sym { font-size: 13px; }
html.mobile-site .td-peer-card .td-peer-r1y { min-width: 0; text-align: left; }

/* Annual revenue chart on mobile: text labels grow so they're
   readable at thumb distance. The chart aspect ratio shifts a bit
   taller so individual bars are easier to tap. */
html.mobile-site #ticker-detail-view .td-rev-svg { background: var(--panel); aspect-ratio: 16 / 9; }
html.mobile-site #ticker-detail-view .td-rev-bar-label { font-size: 11px; font-weight: 700; }
html.mobile-site #ticker-detail-view .td-rev-bar-year  { font-size: 10px; }
html.mobile-site #ticker-detail-view .td-rev-yoy        { font-size: 9px; }

/* Semi pages on mobile: convert the grid to a single column list. */
html.mobile-site .semi-grid { grid-template-columns: 1fr 1fr; gap: 6px; }
html.mobile-site .semi-card { padding: 8px; }

/* Semi Relationship Graph on mobile: smaller default node + edge sizes
   so the ~540-node graph reads as a structured cloud, not a hairball.
   The graph still pan/zooms (D3 zoom is enabled), so the user can dig
   in. Edge labels (the chip swatches) wrap as needed. */
html.mobile-site .graph-wrap {
  height: calc(100vh - 220px);
  min-height: 360px;
  max-height: 600px;
}
html.mobile-site #semi-graph-svg { height: 100% !important; }
html.mobile-site .graph-toolbar { flex-wrap: wrap; gap: 4px; }
html.mobile-site .graph-toolbar .chip { min-height: 30px; font-size: 11px; padding: 5px 8px; }
html.mobile-site .graph-layer-row { font-size: 10px; }
html.mobile-site .graph-tooltip { font-size: 12px; max-width: 260px; }
html.mobile-site .graph-panel  { width: 95vw; padding: 12px; font-size: 13px; }

/* Selection bar (sel-charts-btn, etc.) becomes a fixed-bottom toolbar
   on phone so it's always reachable. Hidden when no rows are
   selected (the [hidden] attribute already does that). The body gets
   extra bottom padding so the table's last row doesn't slide under. */
html.mobile-site .selection-bar:not([hidden]) {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 50;
  background: var(--panel);
  border-top: 1px solid var(--border);
  padding: 10px 12px;
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.4);
}
html.mobile-site .selection-bar:not([hidden]) .btn,
html.mobile-site .selection-bar:not([hidden]) button,
html.mobile-site .selection-bar:not([hidden]) .sel-charts-btn,
html.mobile-site .selection-bar:not([hidden]) .sel-clear-btn {
  min-height: 38px;
  padding: 8px 14px;
  font-size: 13px;
}
/* Pad the page bottom so the selection bar doesn't hide the last row. */
html.mobile-site body { padding-bottom: 70px; }

/* Hide the "monthly columns" cluster by default on mobile — re-shown
   when the user toggles to monthly mode. The trailing columns alone
   fit comfortably. */
html.mobile-site .month-col,
html.mobile-site .month-cell { font-size: 11px; padding: 6px 6px; }

/* Pager controls (Prev / 1 2 … N / Next) get bigger touch targets on
   mobile, with the numbered buttons compacting so only Prev/Next +
   the current page indicator stay. */
html.mobile-site #stocks-pager .pg-btn,
html.mobile-site .pg-btn {
  min-height: 38px;
  padding: 8px 12px;
  font-size: 13px;
}
html.mobile-site #stocks-pager .pg-btn:not(.active):not([data-pg="prev"]):not([data-pg="next"]),
html.mobile-site #stocks-pager .pg-gap {
  display: none;
}
html.mobile-site #stocks-pager .pg-btn.active {
  background: var(--accent);
  color: var(--bg);
  font-weight: 700;
  cursor: default;
}
html.mobile-site #stocks-pager {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 6px;
  padding: 8px 0 14px;
}

/* Monthly-vs-benchmark filter pop is desktop-sized by default
   (min-width 460px overflows a phone). Drop the min-width and let it
   fill the viewport with a small inset on mobile. */
html.mobile-site .monthly-filter-pop {
  min-width: 0;
  width: calc(100vw - 24px);
  max-width: 100%;
  left: 12px !important;
  right: 12px !important;
  max-height: calc(100vh - 120px);
}
html.mobile-site .monthly-filter-pop .mf-grid th,
html.mobile-site .monthly-filter-pop .mf-grid td { font-size: 11px; padding: 5px 3px; }
html.mobile-site .monthly-filter-pop .mf-pick button { min-height: 30px; }

/* Site-mode toggle in the footer — links desktop / mobile variants.
   Desktop: a subtle inline link at the bottom of the page. Mobile:
   a sticky pill in the lower-right corner. */
.site-footer {
  padding: 24px 20px 40px;
  text-align: center;
  border-top: 1px solid var(--border);
  margin-top: 32px;
  font-size: 11px;
}
.site-footer a {
  color: var(--muted);
  text-decoration: none;
  border: 1px solid var(--border);
  padding: 4px 10px;
  border-radius: 4px;
}
.site-footer a:hover { color: var(--accent); border-color: var(--accent); }
html.mobile-site .site-footer {
  position: sticky;
  bottom: 8px;
  margin: 28px 12px 12px;
  padding: 0;
  border: 0;
  text-align: right;
  background: transparent;
}
html.mobile-site .site-footer a {
  background: var(--panel);
  font-size: 12px;
  padding: 6px 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
}

/* Floating "back to top" button on mobile. Hidden until JS scrolls
   past 600px. Sits above the sticky selection bar (which is z:50). */
.mob-top-btn { display: none; }
html.mobile-site .mob-top-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  position: fixed;
  right: 14px;
  bottom: 80px;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--panel);
  color: var(--text);
  font-size: 16px;
  font-weight: 700;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
  z-index: 51;
  cursor: pointer;
}
html.mobile-site .mob-top-btn[hidden] { display: none; }
html.mobile-site .mob-top-btn:hover { color: var(--accent); border-color: var(--accent); }

/* Ticker-page #td-fields description-list: desktop is two columns
   (label / value); on mobile, stack so long descriptions ("Why it
   fits", "Primary business") use the full width. */
html.mobile-site #ticker-detail-view dl,
html.mobile-site dl {
  grid-template-columns: 1fr;
  gap: 4px 0;
}
html.mobile-site #ticker-detail-view dl dt,
html.mobile-site dl dt {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
  margin-top: 8px;
}
html.mobile-site #ticker-detail-view dl dd,
html.mobile-site dl dd {
  margin: 0 0 4px;
  font-size: 13px;
  line-height: 1.45;
}

/* Outdoor / sunlight contrast: bump the muted-grey tone a hair on
   mobile so secondary text stays legible in bright light. */
html.mobile-site {
  --muted: #aab1bb;
}

/* Taxonomy tree on mobile: full-width rows with a fat-finger toggle
   target, name wraps instead of truncating. Tap a row (even outside
   the ▶/▼ glyph) to toggle. */
html.mobile-site .tax-row {
  padding: 8px 0;
  gap: 10px;
  flex-wrap: wrap;
}
html.mobile-site .tax-toggle {
  font-size: 16px;
  width: 28px;
  height: 28px;
  min-width: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
html.mobile-site .tax-kind-sector   > .tax-row .tax-name { font-size: 16px; }
html.mobile-site .tax-kind-industry > .tax-row .tax-name { font-size: 14px; }
html.mobile-site .tax-kind-theme    > .tax-row .tax-name { font-size: 13px; }
html.mobile-site .tax-name { white-space: normal; word-break: break-word; }
html.mobile-site .tax-meta { font-size: 10px; margin-left: 0; }

/* Ticker page: hide the Indicators + Compare toolbars on mobile by
   default behind a "Indicators & Compare ▾" toggle so the chart
   itself can sit higher on the screen. Desktop hides the toggle and
   shows both toolbars inline as before. */
.td-toolbar-more { display: none; }
html.mobile-site .td-toolbar-more {
  display: block;
  width: 100%;
  margin: 6px 0;
  padding: 8px 12px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--accent);
  font-size: 13px;
  font-weight: 600;
  text-align: center;
  cursor: pointer;
}
html.mobile-site .td-toolbar-extra { display: none; }
html.mobile-site .td-toolbar-more[aria-expanded="true"] + .td-toolbar-extra {
  display: block;
}

/* Empty-state polish: when a table has zero rows after filters, give
   the user a friendly hint above the empty body. */
html.mobile-site #stocks-table tbody:empty::after,
html.mobile-site #quant-table tbody:empty::after,
html.mobile-site #screener-table tbody:empty::after {
  content: "No tickers match the current filters. Loosen a Top % or clear a filter to see more.";
  display: block;
  color: var(--muted);
  font-size: 12px;
  padding: 24px 12px;
  text-align: center;
}

/* Horizontal-scroll hint dropped — gradient-over-scrolling-container is
   visually noisy and the sticky-left ticker column already implies
   "swipe right for more". Users figure it out fast. */

/* Screener filter rows on mobile: stack the label above the chips so
   the chips themselves get full width. Smaller gap so more fit per
   row. */
html.mobile-site .screener-row {
  flex-direction: column;
  align-items: stretch;
  gap: 6px;
  padding: 6px 0;
  border-bottom: 1px solid var(--border);
}
html.mobile-site .screener-row:last-child { border-bottom: 0; }
html.mobile-site .screener-row .screener-label {
  font-size: 11px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  margin-bottom: 2px;
}
html.mobile-site .screener-row > .chip,
html.mobile-site .screener-row > button {
  flex: 1 1 auto;
}
html.mobile-site .screener-filters { margin: 8px 0 16px; }
html.mobile-site .screener-months {
  flex-wrap: wrap;
  gap: 4px;
}

/* ── Retirement planner ──────────────────────────────────────────────── */
#retirement-view { padding: 0 4px; }
#retirement-view h2 { margin: 6px 0 2px; }
/* Cap the input-card grid at 5 columns wide. minmax keeps individual
   cards readable; max-width caps total width so the row never exceeds
   5 columns even on ultra-wide screens. 232px × 5 + 4×8 gap ≈ 1192px. */
.ret-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(232px, 1fr));
  gap: 8px; margin: 8px 0 12px;
  max-width: 1192px;
}
.ret-card {
  background: var(--panel); border: 1px solid var(--border); border-radius: 5px;
  padding: 4px 9px 7px;
  display: flex; flex-direction: column; gap: 3px;
  min-width: 0;
}
.ret-card legend {
  padding: 0 5px; font-size: 10px; color: var(--accent);
  text-transform: uppercase; letter-spacing: 0.05em; font-weight: 700;
}
.ret-card label {
  display: grid; grid-template-columns: 1fr 96px;
  align-items: center; gap: 6px; font-size: 11px; color: var(--muted);
  line-height: 1.25;
}
.ret-card input, .ret-card select {
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 3px;
  padding: 2px 6px; font: inherit; font-size: 11px;
  font-variant-numeric: tabular-nums;
}
.ret-card input[readonly] { color: var(--muted); background: var(--panel-2); cursor: default; }
.ret-card input:focus, .ret-card select:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.ret-actions { display: flex; gap: 8px; margin-top: 6px; }

/* Big stat cards. 5 across on wide screens, wraps gracefully. */
.ret-results {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 8px; margin: 0 0 16px;
}
.ret-stat {
  background: var(--panel); border: 1px solid var(--border); border-radius: 6px;
  padding: 10px 14px;
  display: flex; flex-direction: column; gap: 2px;
}
.ret-stat-label {
  font-size: 10px; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.05em; font-weight: 700;
}
.ret-stat-value {
  font-size: 22px; font-weight: 700; color: var(--text);
  font-variant-numeric: tabular-nums; line-height: 1.1; margin-top: 2px;
}
.ret-stat-sub { font-size: 11px; }
.ret-good { color: #3fb950; }
.ret-mid  { color: #f1c40f; }
.ret-bad  { color: #f85149; }

.ret-charts {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(420px, 1fr));
  gap: 12px; margin-bottom: 16px;
}
.ret-chart-card {
  background: var(--panel); border: 1px solid var(--border); border-radius: 6px;
  padding: 10px 12px;
}
.ret-chart-title {
  font-size: 12px; font-weight: 600; color: var(--text); margin-bottom: 6px;
}
.ret-chart-canvas { width: 100%; min-height: 240px; }
.ret-chart-legend {
  display: flex; flex-wrap: wrap; gap: 12px;
  font-size: 11px; color: var(--muted); margin-top: 6px;
}
.ret-legend-swatch {
  display: inline-block; width: 10px; height: 10px;
  border-radius: 2px; margin-right: 4px; vertical-align: middle;
}

.ret-detail { margin-top: 8px; }
.ret-detail summary {
  cursor: pointer; font-size: 12px; color: var(--accent); padding: 4px 0;
  user-select: none;
}
.ret-table-wrap { overflow-x: auto; margin-top: 8px; }
#ret-table { font-size: 11px; }
#ret-table th { font-size: 10px; }
#ret-table tr.ret-row-retired td { background: rgba(99, 179, 237, 0.04); }

/* Wider cards used for expenses — same intrinsic width as Accounts
   (~808px from its 10-column grid) so both panels line up flush. */
.ret-card-wide {
  grid-column: 1 / -1;
  justify-self: start;
  width: fit-content;
  min-width: 808px;
  max-width: 100%;
}

/* Display + saved-plans card. About half the Accounts width — enough
   for the Saved Plans dropdown + Load + × but not so wide that the
   tiny "Show dollars in" select looks lost. Also widen the per-row
   label grid so the select shows the full option text. */
.ret-display-card {
  grid-column: 1 / -1;
  justify-self: start;
  width: fit-content;
  min-width: 400px;
  max-width: 100%;
}
.ret-display-card label {
  grid-template-columns: 1fr 200px;
}
/* Accounts card still occupies its own row but shrinks to fit the
   column-grid inside (last field = the 24px delete-button column). */
.ret-accounts-card {
  grid-column: 1 / -1;
  justify-self: start;
  width: fit-content;
  max-width: 100%;
}
.ret-account-table-head {
  display: grid;
  grid-template-columns: 150px 130px 110px 52px 52px 64px 60px 54px 58px 24px;
  gap: 6px; font-size: 10px; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.04em; font-weight: 600;
  padding: 2px 0 4px; border-bottom: 1px solid var(--border); margin-bottom: 2px;
}
.ret-account-row {
  display: grid;
  grid-template-columns: 150px 130px 110px 52px 52px 64px 60px 54px 58px 24px;
  align-items: center; gap: 6px; margin: 3px 0;
}
.ret-account-row input[type="text"],
.ret-account-row input[type="number"],
.ret-account-row select {
  width: 100%; background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 3px;
  padding: 3px 6px; font: inherit; font-size: 11px;
  font-variant-numeric: tabular-nums;
}
.ret-account-row select { padding: 2px 4px; }
/* Three-col rows — kept for any legacy usage. */
.ret-card label.ret-three-col {
  display: grid; grid-template-columns: 1fr 64px 64px;
  align-items: center; gap: 6px;
}
.ret-sub-head {
  font-size: 10px; color: var(--muted); margin-top: 2px;
}
.ret-toggle { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }
.ret-toggle input { width: auto; }
.ret-expense-row {
  display: grid; grid-template-columns: 1fr 100px 100px 130px 24px;
  align-items: center; gap: 6px; margin: 4px 0;
}
.ret-expense-row label {
  display: inline-flex; align-items: center; gap: 4px;
  grid-template-columns: none; font-size: 11px;
}
.ret-expense-row input[type="text"] {
  width: 100%; background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 3px;
  padding: 3px 6px; font: inherit; font-size: 12px;
}
.ret-expense-row input[type="number"] {
  width: 56px;
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 3px;
  padding: 3px 6px; font: inherit; font-size: 12px;
  font-variant-numeric: tabular-nums;
}
.ret-exp-x {
  background: transparent; color: var(--muted); border: 0;
  font-size: 16px; line-height: 1; cursor: pointer; padding: 0 4px;
}
.ret-exp-x:hover { color: var(--red); }

/* ── Retirement cross-site links ────────────────────────────────────── */
.ret-site-link {
  font-size: 12px; color: var(--accent); white-space: nowrap;
  text-decoration: none; opacity: 0.8;
}
.ret-site-link:hover { opacity: 1; text-decoration: underline; }
/* Desktop: show mobile link, hide desktop link */
.ret-to-mobile  { display: inline; }
.ret-to-desktop { display: none; }
/* Mobile: flip */
html.mobile-site .ret-to-mobile  { display: none; }
html.mobile-site .ret-to-desktop { display: inline; }

/* Accounts scroll wrapper — allows horizontal scroll on narrow screens */
.ret-accounts-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* ── Mobile retirement overrides ────────────────────────────────────── */
html.mobile-site #retirement-view { padding: 0 2px; }

/* Single-column card grid on mobile */
html.mobile-site .ret-grid {
  /* minmax(0,1fr) — NOT plain 1fr. Plain 1fr = minmax(auto,1fr); inside the
     section's overflow-x:auto the `auto` min lets the track grow to the
     fieldset cards' min-content (~810px), shoving every input off-screen to
     the right. Capping the min at 0 holds the column to the viewport. */
  grid-template-columns: minmax(0, 1fr);
  gap: 6px;
}
/* Fieldsets keep a stubborn min-inline-size:min-content even with min-width:0;
   reset it so the .ret-card cards can shrink to the single grid column. */
html.mobile-site .ret-card { min-inline-size: 0; }
/* The label's own 1fr text column gets the same cap so a long label can't
   re-expand the row past the viewport. */
html.mobile-site .ret-card label { grid-template-columns: minmax(0, 1fr) 92px; }
/* Reset any span-2 children so they don't force a 2nd implicit column */
html.mobile-site .ret-accounts-card,
html.mobile-site .ret-card-wide { grid-column: auto; }

/* 16px font on inputs prevents iOS Safari auto-zoom on focus */
html.mobile-site .ret-card input,
html.mobile-site .ret-card select {
  padding: 5px 8px; font-size: 16px;
}
html.mobile-site .ret-card label {
  font-size: 13px; gap: 8px;
}
html.mobile-site .ret-account-row input[type="text"],
html.mobile-site .ret-account-row input[type="number"],
html.mobile-site .ret-account-row select {
  font-size: 16px;
}

/* Charts: single column, shorter height */
html.mobile-site .ret-charts {
  grid-template-columns: 1fr;
}
html.mobile-site .ret-chart-canvas { min-height: 180px; }

/* Stat cards: 2-wide on mobile */
html.mobile-site .ret-results {
  grid-template-columns: repeat(2, 1fr);
}
html.mobile-site .ret-stat-value { font-size: 18px; }

/* Expense rows: tighten on mobile */
html.mobile-site .ret-expense-row {
  grid-template-columns: 1fr 80px 110px 24px;
}

/* Account rows: readable minimum width inside scroll */
html.mobile-site .ret-account-table-head,
html.mobile-site .ret-account-row {
  min-width: 820px;
}
html.mobile-site .ret-account-row input[type="text"],
html.mobile-site .ret-account-row input[type="number"],
html.mobile-site .ret-account-row select {
  font-size: 13px; padding: 5px 6px;
}

/* ── Saves UI ──────────────────────────────────────────────────────────── */
.ret-saves { margin-top: 10px; border-top: 1px solid var(--border); padding-top: 8px; }
.ret-saves-label { font-size: 10px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; font-weight: 600; margin-bottom: 5px; }
.ret-saves-row { display: flex; gap: 5px; align-items: center; margin-bottom: 4px; }
.ret-save-name { flex: 1; background: var(--bg); color: var(--text); border: 1px solid var(--border); border-radius: 3px; padding: 3px 6px; font: inherit; font-size: 11px; }
.ret-saves-row select { flex: 1; background: var(--bg); color: var(--text); border: 1px solid var(--border); border-radius: 3px; padding: 3px 4px; font: inherit; font-size: 11px; }
.ret-delete-save-btn { padding: 3px 7px; font-size: 11px; }

/* ── Historical reference card ─────────────────────────────────────────── */
/* Historical reference now lives inside a modal popped from a link
   under the Accounts card — see #ret-hist-modal in the markup. */
.ret-hist-link {
  display: inline-block; margin-top: 6px;
  font-size: 11px; color: var(--accent);
  text-decoration: none;
}
.ret-hist-link:hover { text-decoration: underline; }

.ret-hist-modal {
  position: fixed; inset: 0; z-index: 1000;
  display: flex; align-items: center; justify-content: center;
  padding: 16px;
}
.ret-hist-modal[hidden] { display: none; }
.ret-hist-modal-backdrop {
  position: absolute; inset: 0; background: rgba(0,0,0,0.6);
}
.ret-hist-modal-panel {
  position: relative;
  background: var(--card-bg, #161b22);
  border: 1px solid var(--border, #2a2f37);
  border-radius: 8px;
  padding: 14px 16px 12px;
  max-width: 560px; width: 100%;
  max-height: 90vh; overflow-y: auto;
}
.ret-hist-modal-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 6px;
}
.ret-hist-modal-x {
  background: transparent; border: 0; color: var(--muted);
  font-size: 22px; line-height: 1; cursor: pointer; padding: 2px 6px;
}
.ret-hist-modal-x:hover { color: var(--text, #e7e9ea); }

.ret-hist-table { display: flex; flex-direction: column; }
.ret-hist-head {
  display: grid; grid-template-columns: 1.8fr 1fr 1fr; gap: 8px;
  font-size: 10px; color: var(--muted); text-transform: uppercase;
  letter-spacing: 0.04em; font-weight: 600;
  padding: 2px 0 4px; border-bottom: 1px solid var(--border); margin-bottom: 1px;
}
.ret-hist-row {
  display: grid; grid-template-columns: 1.8fr 1fr 1fr; gap: 8px;
  align-items: center; padding: 4px 0; font-size: 11px;
  border-bottom: 1px solid var(--border);
}
.ret-hist-row:last-child { border-bottom: none; }
.ret-hist-row span:not(:first-child) { display: flex; align-items: center; gap: 5px; }
.ret-hist-bar {
  display: inline-block; height: 7px; border-radius: 2px;
  flex-shrink: 0; max-width: 60px; min-width: 4px;
}
.ret-hist-ret { background: var(--accent); opacity: 0.75; }
.ret-hist-vol { background: #e07b39; opacity: 0.75; }

/* Hide desktop-only retirement features on mobile */
html.mobile-site .ret-saves,
html.mobile-site .ret-hist-link,
html.mobile-site .ret-hist-modal { display: none; }

/* ─── Data Center Supply Chain page ─────────────────────────────────── */

.dc-header { margin: 8px 0 12px; }
.dc-header h2 { margin: 0 0 6px; }
.dc-intro { font-size: 12px; max-width: 920px; line-height: 1.45; }
.dc-tabs { display: flex; gap: 6px; margin-top: 10px; }
.dc-tab {
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 3px;
  padding: 5px 14px; font: inherit; font-size: 12px; cursor: pointer;
}
.dc-tab:hover { border-color: var(--accent); }
.dc-tab.active { background: var(--accent); color: #000; border-color: var(--accent); font-weight: 600; }

/* Flow chart — top arrow strip + 4-column grid + parallel chains */
.dc-arrow-strip {
  display: flex; align-items: center; gap: 14px;
  font-size: 11px; color: var(--muted);
  padding: 8px 12px; margin-bottom: 14px;
  background: rgba(196, 168, 110, 0.05); border-radius: 4px;
  border: 1px solid rgba(196, 168, 110, 0.2);
}
.dc-arrow-label { font-weight: 600; color: var(--text); letter-spacing: 0.04em; text-transform: uppercase; font-size: 10px; }
.dc-arrow { color: var(--accent); font-size: 14px; }

.dc-orders-grid {
  display: grid; gap: 12px;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  margin-bottom: 24px;
}
.dc-order-col {
  background: var(--panel-bg);
  border: 1px solid var(--border); border-radius: 5px;
  padding: 12px;
}
.dc-order-head {
  display: flex; align-items: center; gap: 8px;
  padding-bottom: 8px; margin-bottom: 8px;
  border-bottom: 2px solid var(--accent);
}
.dc-order-num {
  display: inline-block; width: 26px; height: 26px;
  background: var(--accent); color: #000; border-radius: 50%;
  font-weight: 700; font-size: 14px; text-align: center; line-height: 26px;
}
.dc-order-icon { font-size: 20px; }
.dc-order-title { margin: 0; font-size: 13px; font-weight: 600; flex: 1; }
.dc-order-blurb { font-size: 11px; margin: 0 0 12px; line-height: 1.4; }

.dc-group { margin-bottom: 14px; }
.dc-group-head {
  font-size: 11px; font-weight: 600;
  color: var(--accent); text-transform: uppercase; letter-spacing: 0.04em;
  margin-bottom: 5px;
}
.dc-group-icon { margin-right: 4px; }
/* Commentary below each group head — small, italic, leading explanation */
.dc-group-desc {
  font-size: 10.5px; line-height: 1.4;
  color: var(--muted); font-style: italic;
  margin: 0 0 6px; padding-left: 4px;
  border-left: 2px solid rgba(196, 168, 110, 0.3);
}
/* Bigger, non-italic version for the By Layer deep-dive view */
.dc-layer-group-desc {
  font-size: 12px; line-height: 1.55;
  color: var(--text); margin: 4px 0 10px;
  padding: 8px 10px;
  background: rgba(196, 168, 110, 0.06);
  border-left: 3px solid var(--accent);
  border-radius: 2px;
}
.dc-group-tiles { display: flex; flex-wrap: wrap; gap: 5px; }

.dc-tile {
  display: inline-flex; align-items: center; gap: 4px;
  background: var(--bg);
  border: 1px solid var(--border); border-radius: 3px;
  padding: 3px 8px 3px 4px; font-size: 11px;
  color: var(--text); text-decoration: none;
  transition: border-color 0.15s, transform 0.1s;
}
.dc-tile:hover { border-color: var(--accent); transform: translateY(-1px); }
.dc-tile img { border-radius: 2px; flex-shrink: 0; }
.dc-tile-ticker { font-weight: 700; color: var(--accent); }
.dc-tile-name { color: var(--muted); font-size: 10px; }

/* Market-cap visual tiers — left-border accent only so tiles still pack
   tightly. Mega = >$500B (MSFT/GOOGL/NVDA), Large = $100-500B (TSM, AVGO,
   BLK), Mid = $10-100B, Small = <$10B. */
.dc-tile-mega  { border-left: 3px solid #ffd700; }
.dc-tile-large { border-left: 3px solid #c0c0c0; }
.dc-tile-mid   { border-left: 3px solid var(--accent); opacity: 0.95; }
.dc-tile-small { opacity: 0.75; }

/* Parallel chains row — full-width cards below the main 4-order grid */
.dc-parallels-h { margin: 18px 0 4px; font-size: 14px; }
.dc-parallels-intro { font-size: 11px; max-width: 900px; margin: 0 0 10px; }
.dc-parallels-grid {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(360px, 1fr));
}
.dc-parallel {
  background: var(--panel-bg); border: 1px solid var(--border); border-radius: 5px;
  padding: 12px;
}
.dc-parallel-head { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
.dc-parallel-icon { font-size: 18px; }
.dc-parallel-title { margin: 0; font-size: 13px; font-weight: 600; }
.dc-parallel-blurb { font-size: 11px; margin: 0 0 10px; line-height: 1.4; }
.dc-parallel-groups { display: flex; flex-direction: column; gap: 10px; }

/* Spider / hub-spoke view */
.dc-spider-wrap { padding: 8px 0; }
.dc-hub-picker {
  display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
  padding: 8px 0 4px;
}
.dc-hub-btn {
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 3px;
  padding: 4px 10px; font: inherit; font-size: 11px; cursor: pointer;
}
.dc-hub-btn:hover { border-color: var(--accent); }
.dc-hub-btn.active { background: var(--accent); color: #000; font-weight: 600; }
.dc-spider-blurb { font-size: 11px; margin: 8px 0; }
.dc-spider-svg {
  width: 100%; max-width: 1100px; height: auto;
  background: var(--panel-bg); border: 1px solid var(--border); border-radius: 5px;
  display: block; margin: 0 auto;
}
.dc-spoke {
  stroke-width: 1.4; fill: none;
  opacity: 0.55;
}
.dc-spoke-supplier { stroke: #5a89b5; color: #5a89b5; }
.dc-spoke-customer { stroke: #89b55a; color: #89b55a; }
.dc-spoke:hover { opacity: 1; stroke-width: 2; }
.dc-node { stroke-width: 2; transition: filter 0.2s; }
.dc-node-supplier { fill: #2a4d6e; stroke: #5a89b5; }
.dc-node-customer { fill: #4d6e2a; stroke: #89b55a; }
.dc-node-hub { fill: var(--accent); stroke: #fff; stroke-width: 3; }
.dc-node-link:hover .dc-node { filter: brightness(1.4); cursor: pointer; }
.dc-node-label {
  fill: #fff; font-size: 11px; font-weight: 700; pointer-events: none;
  font-family: var(--font-mono, monospace);
}
.dc-node-hub-label {
  fill: #000; font-size: 16px; font-weight: 800; pointer-events: none;
  font-family: var(--font-mono, monospace);
}
.dc-legend {
  display: flex; flex-wrap: wrap; gap: 18px;
  padding: 10px; margin-top: 10px;
  background: var(--panel-bg); border-radius: 4px;
  font-size: 11px; color: var(--muted);
}
.dc-legend-swatch {
  display: inline-block; width: 14px; height: 14px;
  border-radius: 50%; vertical-align: middle; margin-right: 4px;
}

/* By Layer view — accordion-style cards stacked vertically */
.dc-layer-view { padding: 8px 0; }
.dc-layer-section-h {
  font-size: 14px; margin: 18px 0 8px;
  padding-bottom: 4px; border-bottom: 1px solid var(--border);
}
.dc-layer-card {
  background: var(--panel-bg); border: 1px solid var(--border); border-radius: 5px;
  padding: 14px; margin-bottom: 12px;
}
.dc-layer-head {
  display: flex; align-items: center; gap: 10px;
  padding-bottom: 8px; margin-bottom: 8px;
  border-bottom: 2px solid var(--accent);
}
.dc-layer-head h3 { margin: 0; font-size: 14px; }
.dc-layer-icon { font-size: 22px; }
.dc-layer-groups {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
.dc-layer-group h4 {
  margin: 0 0 6px; font-size: 12px; color: var(--accent);
  text-transform: uppercase; letter-spacing: 0.04em;
}

/* Responsive: stack the 4-column grid on smaller screens */
@media (max-width: 1100px) {
  .dc-orders-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 700px) {
  .dc-orders-grid { grid-template-columns: 1fr; }
  .dc-parallels-grid { grid-template-columns: 1fr; }
}

/* Market Cap page — top-10 largest companies (mirrors companiesmarketcap.com). */
.mcap-head { margin: 4px 0 14px; }
.mcap-title { margin: 0 0 2px; font-size: 20px; }
.mcap-sub { font-size: 12px; margin: 0; }
.mcap-filter { display: flex; align-items: center; gap: 8px; margin-top: 10px; }
.mcap-filter label { font-size: 12px; color: var(--muted, #8b949e); }
.mcap-select {
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 4px;
  padding: 5px 10px; font: inherit; font-size: 13px;
  cursor: pointer; min-width: 200px;
}
.mcap-select:hover { border-color: var(--accent); }
.mcap-num {
  width: 76px;
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 4px;
  padding: 5px 8px; font: inherit; font-size: 13px;
}
.mcap-num:hover, .mcap-num:focus { border-color: var(--accent); outline: none; }
.mcap-dash { color: var(--muted, #8b949e); }
.mcap-clear { padding: 5px 10px; font-size: 12px; }
.mcap-filter label { white-space: nowrap; }
.mcap-empty { text-align: center; padding: 24px 12px; }

/* Light/white table background (Market Cap page only). Dark text for
   readability; the 24h down-move is a dark amber instead of the dark-theme
   yellow (bright yellow is invisible on white); logos get a light frame. */
.mcap-table { background: #ffffff; color: #1c2128; border-radius: 8px; overflow: hidden; }
.mcap-table thead th {
  background: #eef1f4; color: #57606a;
  border-bottom: 1px solid #d0d7de;
}
.mcap-table tbody td { border-bottom: 1px solid #e6e8eb; }
.mcap-table tbody tr:hover { background: #f3f6f9; }
.mcap-table .mcap-rank { color: #6e7781; }
.mcap-table .mcap-rank-num { color: #1c2128; }
.mcap-table .mcap-name-text { color: #1c2128; }
.mcap-table .mcap-ticker { color: #6e7781; }
.mcap-table .mcap-value { color: #0969da; }
.mcap-table .mcap-sector { color: #57606a; }
.mcap-table .mcap-up   { color: #1f6feb; }
.mcap-table .mcap-down { color: #9a6700; }
.mcap-table .mcap-flat { color: #6e7781; }
.mcap-table .mcap-logo { border: 1px solid #d0d7de; }
.mcap-table .mcap-empty { color: #6e7781; }
/* White "knockout" logos get a dark chip so they stay visible (detected in JS). */
.mcap-logo.mcap-logo--dark { background: #1c2128; border-color: #30363d; }
.mcap-stale { color: #e4c98a; }
.mcap-table {
  width: 100%;
  max-width: 760px;
  border-collapse: collapse;
  font-size: 14px;
}
.mcap-table thead th {
  text-align: left;
  font-weight: 600;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted, #8b949e);
  border-bottom: 1px solid var(--border, #30363d);
  padding: 6px 12px;
}
.mcap-table th.num, .mcap-table td.num { text-align: right; }
.mcap-table tbody td {
  padding: 10px 12px;
  border-bottom: 1px solid var(--border, #30363d);
  vertical-align: middle;
}
.mcap-table tbody tr:hover { background: var(--panel-2, #1c2128); }
.mcap-rank {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: var(--muted, #8b949e);
  width: 70px;
  white-space: nowrap;
}
.mcap-rank-num { font-size: 15px; }
/* Up = blue, down = yellow (colorblind-safe), reinforced by ▲/▼ glyphs. */
.mcap-up   { color: #2F7DD7; }
.mcap-down { color: #F8C23C; }
.mcap-flat { color: var(--muted, #8b949e); }
.mcap-move {
  font-size: 11px;
  font-weight: 700;
  margin-left: 6px;
  font-variant-numeric: tabular-nums;
}
.mcap-chg {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.mcap-chg-cell { white-space: nowrap; }
.mcap-name-cell { display: inline-flex; align-items: center; gap: 11px; }
.mcap-logo {
  width: 40px; height: 40px;
  border-radius: 8px;
  object-fit: contain;
  background: #fff;
  padding: 2px;
  flex: 0 0 auto;
}
.mcap-name-text { font-weight: 600; }
.mcap-ticker {
  font-size: 11px;
  color: var(--muted, #8b949e);
  font-variant-numeric: tabular-nums;
}
.mcap-value {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: var(--accent);
  white-space: nowrap;
}
.mcap-sector { color: var(--muted, #8b949e); font-size: 13px; }
.mcap-country { white-space: nowrap; font-size: 13px; }
.mcap-flag { font-size: 16px; margin-right: 6px; vertical-align: middle; }
.mcap-country-name { color: var(--muted, #8b949e); }
.mcap-select--sm { min-width: 110px; }
/* Clickable Market Cap header (sort) */
.mcap-table th.mcap-sortable { cursor: pointer; user-select: none; }
.mcap-table th.mcap-sortable:hover { color: var(--accent); }
.mcap-sort-ind { font-size: 10px; color: var(--accent); }
.mcap-table .mcap-country-name { color: #57606a; }

/* ── Natural-language AI screener (Quant page) ───────────────────────────── */
.ai-screen {
  background: var(--panel); border: 1px solid var(--border); border-radius: 8px;
  padding: 12px 14px; margin-bottom: 12px;
}
.ai-screen-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 6px; }
.ai-screen-head label { font-size: 13px; font-weight: 700; color: var(--text); }
.ai-screen-hint { font-size: 11px; }
.ai-screen-row { display: flex; gap: 8px; align-items: stretch; }
.ai-screen-row textarea {
  flex: 1 1 auto; resize: vertical; min-height: 38px; font: inherit; font-size: 13px;
  background: var(--bg); color: var(--text); border: 1px solid var(--border);
  border-radius: 6px; padding: 8px 10px; line-height: 1.4;
}
.ai-screen-row textarea:focus { outline: none; border-color: var(--accent); }
.ai-screen-run {
  flex: 0 0 auto; align-self: stretch; white-space: nowrap; cursor: pointer;
  background: var(--accent); color: var(--bg); border: 1px solid var(--accent);
  border-radius: 6px; padding: 0 16px; font: inherit; font-weight: 700; font-size: 13px;
}
.ai-screen-run:hover:not(:disabled) { filter: brightness(1.08); }
.ai-screen-run:disabled { opacity: 0.6; cursor: progress; }
.ai-screen-examples { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.ai-screen-eg {
  cursor: pointer; background: var(--panel-2); color: var(--muted);
  border: 1px solid var(--border); border-radius: 999px; padding: 3px 10px;
  font: inherit; font-size: 11px;
}
.ai-screen-eg:hover { color: var(--accent); border-color: var(--accent); }
.ai-screen-status { margin-top: 8px; font-size: 12px; }
.ai-status-loading { color: var(--muted); }
.ai-status-info { color: var(--muted); }
.ai-status-warn,
.ai-status-error { color: var(--orange); }   /* amber, not red — colorblind-safe */

.ai-screen-result { margin-top: 10px; border-top: 1px solid var(--border); padding-top: 10px; }
.ai-result-head { font-size: 12px; font-weight: 700; color: var(--text); margin-bottom: 4px; }
.ai-result-head .muted { font-weight: 400; }
.ai-result-fail { color: var(--orange); }
.ai-result-why, .ai-result-explain { font-size: 11px; margin-bottom: 6px; }
.ai-result-chips { list-style: none; margin: 4px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.ai-result-chips li {
  background: var(--panel-2); border: 1px solid var(--border); border-radius: 6px;
  padding: 2px 9px; font-size: 11px; color: var(--text); font-variant-numeric: tabular-nums;
}
.ai-result-unmapped { margin-top: 8px; font-size: 11px; color: var(--muted); }
.ai-result-unmapped span {
  display: inline-block; background: rgba(219, 139, 31, 0.12); color: var(--orange);
  border: 1px solid rgba(219, 139, 31, 0.3); border-radius: 6px; padding: 1px 7px; margin-left: 4px;
}
.ai-result-json { margin-top: 8px; font-size: 11px; }
.ai-result-json summary { cursor: pointer; color: var(--muted); }
.ai-result-json summary:hover { color: var(--accent); }
.ai-result-json pre {
  margin: 6px 0 0; padding: 8px 10px; background: var(--bg); border: 1px solid var(--border);
  border-radius: 6px; overflow: auto; max-height: 220px; font-size: 11px; line-height: 1.4;
}

/* Inline-editable interpreted filters */
.ai-filters { display: flex; flex-direction: column; gap: 6px; margin: 6px 0 2px; }
.ai-filter {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  background: var(--panel-2); border: 1px solid var(--border); border-radius: 6px; padding: 5px 8px;
}
.ai-f-label { font-size: 12px; font-weight: 600; color: var(--text); min-width: 140px; }
.ai-f-op { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; min-width: 18px; text-align: center; }
.ai-f-and { font-size: 11px; color: var(--muted); }
.ai-f-unit { font-size: 11px; color: var(--muted); }
.ai-filter input.ai-fval, .ai-filter input.ai-fval-min, .ai-filter input.ai-fval-max {
  width: 96px; background: var(--bg); color: var(--text); border: 1px solid var(--border);
  border-radius: 5px; padding: 3px 6px; font: inherit; font-size: 12px;
}
.ai-filter input.ai-fval-text { flex: 1 1 180px; min-width: 140px; background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 5px; padding: 3px 6px; font: inherit; font-size: 12px; }
.ai-filter input:focus { outline: none; border-color: var(--accent); }
.ai-filter-drop {
  margin-left: auto; cursor: pointer; background: transparent; color: var(--muted);
  border: 1px solid var(--border); border-radius: 5px; width: 22px; height: 22px; line-height: 1;
  font-size: 14px; padding: 0;
}
.ai-filter-drop:hover { color: var(--orange); border-color: var(--orange); }
.ai-controls-row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-top: 10px; font-size: 12px; }
.ai-limit-lbl { color: var(--muted); }
.ai-limit { width: 64px; background: var(--bg); color: var(--text); border: 1px solid var(--border);
  border-radius: 5px; padding: 3px 6px; font: inherit; font-size: 12px; }
.ai-rerun {
  cursor: pointer; background: var(--accent); color: var(--bg); border: 1px solid var(--accent);
  border-radius: 6px; padding: 4px 14px; font: inherit; font-weight: 700; font-size: 12px;
}
.ai-rerun:hover:not(:disabled) { filter: brightness(1.08); }
.ai-rerun:disabled { opacity: 0.6; cursor: progress; }

/* ================================================================
   WIZARD — spectral portfolio experiment (#wizard)
   ================================================================ */
#wizard-chart-wrap { margin: 4px 0 10px; }
#wizard-chart-host { width: 100%; min-height: 300px; }
.wizard-chart-legend { display: flex; gap: 16px; align-items: center; font-size: 12px; margin-top: 6px; }
.wiz-swatch { display: inline-block; width: 12px; height: 12px; border-radius: 3px; margin-right: 5px; vertical-align: -1px; }
.wiz-swatch--wizard { background: #2ecc71; }
.wiz-swatch--random { background: #7BAFD4; }
.wiz-swatch--spy    { background: #bdbdbd; }

.wizard-portfolios { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin: 14px 0 4px; }
.wizard-card { border: 1px solid var(--border); border-radius: 10px; padding: 12px 14px; background: rgba(255,255,255,0.015); }
.wizard-card-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.wizard-card-head h3 { margin: 0; font-size: 15px; }
.wizard-card-tot { display: flex; gap: 10px; align-items: baseline; font-size: 14px; font-weight: 600; }
.wizard-holdings-table { width: 100%; border-collapse: collapse; font-size: 12.5px; margin-top: 4px; }
.wizard-holdings-table th { text-align: left; font-weight: 600; color: var(--muted); border-bottom: 1px solid var(--border); padding: 4px 6px; }
.wizard-holdings-table td { padding: 4px 6px; border-bottom: 1px solid rgba(255,255,255,0.04); }
.wizard-holdings-table td.num, .wizard-holdings-table th.num { text-align: right; }
.wizard-holdings-table .wiz-co { max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* "Today's picks" — full-width spectral-start list above the live books. */
.wizard-daily { margin: 14px 0 4px; }
.wizard-daily-card { background: rgba(124,175,212,0.05); border-color: rgba(124,175,212,0.28); }
.wizard-daily-card .wizard-card-head { flex-wrap: wrap; }
.wizard-daily-table .wiz-co { max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Suggested-allocation cell: a subtle proportional bar behind the % so the
   sizing reads at a glance. --w is the bar width (the weight as a %). */
.wizard-daily-table td.wiz-alloc { position: relative; font-weight: 600; z-index: 1; }
.wiz-alloc-bar { position: absolute; left: 0; top: 3px; bottom: 3px; width: var(--w, 0%);
  background: rgba(46,204,113,0.16); border-radius: 3px; z-index: -1; pointer-events: none; }
.wizard-daily-table tfoot td { border-top: 1px solid var(--border); padding-top: 5px; font-size: 12px; }
.wiz-alloc-total { font-weight: 600; }
html.mobile-site .wizard-daily-table .wiz-co { max-width: 90px; }
html.mobile-site .wizard-daily-table { font-size: 11.5px; }
.wiz-tk { font-weight: 600; }
.ret-up { color: #2ecc71; }
.ret-down { color: #7BAFD4; }

.wizard-method-list { font-size: 12.5px; line-height: 1.55; max-width: 80ch; padding-left: 20px; }
.wizard-method-list li { margin-bottom: 8px; }

.wizard-trades-wrap { margin-top: 16px; }
.wizard-trades-wrap > summary { cursor: pointer; font-weight: 600; font-size: 13px; padding: 6px 0; }
.wizard-trades-table { width: 100%; border-collapse: collapse; font-size: 12px; margin-top: 6px; }
.wizard-trades-table th { text-align: left; color: var(--muted); border-bottom: 1px solid var(--border); padding: 4px 8px; }
.wizard-trades-table td { padding: 4px 8px; border-bottom: 1px solid rgba(255,255,255,0.04); }
.wizard-trades-table td.num, .wizard-trades-table th.num { text-align: right; }
.wizard-trades-table .wiz-reason { max-width: 260px; }
.wiz-pill { display: inline-block; padding: 1px 7px; border-radius: 10px; font-size: 11px; }
.wiz-pill--wizard { background: rgba(46,204,113,0.18); color: #2ecc71; }
.wiz-pill--random { background: rgba(123,175,212,0.18); color: #7BAFD4; }
.wiz-act { font-weight: 600; }
.wiz-act--buy  { color: #2ecc71; }
.wiz-act--sell { color: #7BAFD4; }

/* ================================================================
   PASSWORDS — true-random generator (#passwords)
   ================================================================ */
.pw-form { display: flex; flex-wrap: wrap; gap: 16px; align-items: center; margin: 10px 0 4px; }
.pw-form label { display: flex; align-items: center; gap: 6px; font-size: 13px; }
.pw-form input[type="number"] { width: 72px; padding: 5px 7px; }
.pw-form .pw-disabled { opacity: 0.4; }
.pw-form input:disabled { cursor: not-allowed; background: rgba(255,255,255,0.02); }
/* Option groups (char-only / word-only) flow their labels as flex items. */
.pw-optgroup { display: contents; }
.pw-optgroup[hidden] { display: none; }
.pw-form select { padding: 5px 8px; background: var(--bg); color: inherit; border: 1px solid var(--border); border-radius: 6px; }
.pw-source-label { flex-direction: column; align-items: flex-start; gap: 3px; font-weight: 600; }
.pw-list { list-style: none; padding: 0; margin: 12px 0; display: flex; flex-direction: column; gap: 7px; }
.pw-list li { display: flex; align-items: center; gap: 10px; }
.pw-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 15px; letter-spacing: 0.5px; user-select: all;
  background: rgba(255,255,255,0.05); border: 1px solid var(--border);
  padding: 6px 11px; border-radius: 7px; word-break: break-all;
}
.pw-copy { font-size: 12px; padding: 4px 12px; }
.pw-copy.pw-copied { color: #2ecc71; }
html.mobile-site .pw-list li { flex-wrap: wrap; }
html.mobile-site .pw-code { font-size: 14px; }

/* ================================================================
   SHOCKWAVE — market contagion simulator (#shockwave)
   ================================================================ */
.shock-controls { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; margin: 6px 0 14px; }
.shock-controls #shock-input { font-size: 15px; padding: 8px 12px; min-width: 220px; }
.shock-controls select { padding: 8px 10px; font-size: 14px; background: var(--bg); color: inherit; border: 1px solid var(--border); border-radius: 6px; }
.shock-chain-label { display: flex; align-items: center; gap: 6px; font-size: 13px; }
.shock-names-label { display: flex; align-items: center; gap: 6px; font-size: 13px; }
.shock-blast-wrap { position: relative; }
.shock-day { position: absolute; top: 6px; left: 10px; font-size: 13px; font-weight: 700; color: #f1c40f; letter-spacing: 0.4px; pointer-events: none; }
.shock-mag-label { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.shock-mag-label input[type="range"] { width: 180px; accent-color: #7BAFD4; }
.shock-mag-val { font-weight: 700; min-width: 46px; }
#shock-go { font-size: 15px; }

.shock-headline { display: flex; flex-wrap: wrap; gap: 14px; margin: 10px 0 16px; }
.shock-stat { border: 1px solid var(--border); border-radius: 10px; padding: 10px 16px; min-width: 130px; background: rgba(255,255,255,0.015); }
.shock-stat--hero { flex: 1 1 260px; background: rgba(123,175,212,0.06); }
.shock-stat-val { font-size: 24px; font-weight: 800; line-height: 1.1; }
.shock-stat--hero .shock-stat-val { font-size: 34px; }
.shock-stat-lbl { font-size: 11px; color: var(--muted); margin-top: 4px; text-transform: uppercase; letter-spacing: 0.3px; }

.shock-blast-wrap { margin: 8px 0 18px; }
#shock-blast { width: 100%; }
#shock-blast .shock-node { cursor: pointer; }
.shock-legend { font-size: 11px; text-align: center; margin-top: 6px; }
.shock-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; vertical-align: -1px; margin: 0 2px; }
.shock-dot--down { background: #7BAFD4; }
.shock-dot--up { background: #2ecc71; }

.shock-sectors { margin: 8px 0 18px; }
.shock-sectors h3, .shock-list h3 { margin: 0 0 8px; font-size: 15px; }
.shock-secrow { display: grid; grid-template-columns: 150px 1fr 64px 72px; align-items: center; gap: 10px; padding: 3px 0; font-size: 12.5px; }
.shock-secname { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.shock-secbar { background: rgba(255,255,255,0.05); border-radius: 4px; height: 12px; overflow: hidden; }
.shock-secfill { display: block; height: 100%; border-radius: 4px; }
.shock-secfill.down { background: #7BAFD4; }
.shock-secfill.up { background: #2ecc71; }
.shock-secval { text-align: right; font-weight: 600; }
.shock-secdollar { text-align: right; font-size: 11px; }

.shock-lists { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.shock-list { border: 1px solid var(--border); border-radius: 10px; padding: 12px 14px; background: rgba(255,255,255,0.015); }

html.mobile-site .shock-headline { gap: 10px; }
html.mobile-site .shock-stat { flex: 1 1 calc(50% - 10px); min-width: 0; }
html.mobile-site .shock-lists { grid-template-columns: 1fr; }
html.mobile-site .shock-secrow { grid-template-columns: 96px 1fr 52px; }
html.mobile-site .shock-secdollar { display: none; }
html.mobile-site .shock-mag-label input[type="range"] { width: 130px; }

/* ================================================================
   ORACLE — daily stock-prediction game (#oracle)
   ================================================================ */
.oracle-stats { display: flex; flex-wrap: wrap; gap: 12px; margin: 8px 0 16px; }
.oracle-stat { border: 1px solid var(--border); border-radius: 10px; padding: 10px 16px; min-width: 96px; background: rgba(255,255,255,0.015); }
.oracle-stat--streak { background: rgba(241,196,64,0.08); }
.oracle-stat-val { font-size: 22px; font-weight: 800; line-height: 1.1; }
.oracle-stat-lbl { font-size: 11px; color: var(--muted); margin-top: 3px; text-transform: uppercase; letter-spacing: 0.3px; }

.oracle-today { margin-bottom: 18px; }
.oracle-today-head h3 { margin: 0 0 10px; font-size: 16px; }
.oracle-match { display: flex; align-items: stretch; gap: 10px; margin-bottom: 10px; }
.oracle-vs { align-self: center; font-weight: 800; color: var(--muted); font-size: 13px; flex: 0 0 auto; }
.oracle-side {
  flex: 1 1 0; display: flex; flex-direction: column; gap: 2px; align-items: flex-start;
  border: 1.5px solid var(--border); border-radius: 10px; padding: 11px 14px; cursor: pointer;
  background: rgba(255,255,255,0.02); color: inherit; text-align: left; font: inherit; transition: border-color .12s, background .12s;
}
.oracle-side:hover:not(:disabled) { border-color: #2ecc71; }
.oracle-side.sel { border-color: #2ecc71; background: rgba(46,204,113,0.1); }
.oracle-side:disabled { cursor: default; }
.oracle-side.won { border-color: #2ecc71; }
.oracle-side.lost { opacity: 0.7; }
.oracle-side.right { box-shadow: inset 0 0 0 1.5px #2ecc71; }
.oracle-side.wrong { box-shadow: inset 0 0 0 1.5px #7BAFD4; }
.oracle-tk { font-weight: 700; font-size: 15px; }
.oracle-co { font-size: 11px; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.oracle-ret { font-weight: 700; font-size: 14px; margin-top: 2px; }
.oracle-yourtag { font-size: 10px; text-transform: uppercase; letter-spacing: 0.4px; color: #2ecc71; margin-top: 2px; }
.oracle-action { margin-top: 12px; display: flex; gap: 12px; align-items: center; flex-wrap: wrap; font-size: 13px; }

.oracle-hist-wrap > summary { cursor: pointer; font-weight: 600; font-size: 13px; padding: 6px 0; }
.oracle-hist { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; }
.oracle-histrow { display: grid; grid-template-columns: 96px 1fr 44px 80px; align-items: center; gap: 10px; font-size: 12.5px; }
.oracle-histdots { letter-spacing: 2px; }
.oracle-dot.ok { color: #2ecc71; }
.oracle-dot.no { color: #7BAFD4; }
.oracle-histscore { font-weight: 700; text-align: right; }
.oracle-histhouse { text-align: right; font-size: 11px; }

html.mobile-site .oracle-stat { flex: 1 1 calc(33% - 12px); min-width: 0; }
html.mobile-site .oracle-co { font-size: 10px; }
html.mobile-site .oracle-histrow { grid-template-columns: 78px 1fr 38px; }
html.mobile-site .oracle-histhouse { display: none; }

/* ================================================================
   VERY-MOBILE-FRIENDLY PASS — 2026-06-05
   Site-wide phone polish. Every rule is scoped to html.mobile-site
   so the desktop site is byte-for-byte untouched. Grouped here at
   the end of the file (so it wins on equal specificity) for easy
   review/extension. See HANDOFF "mobile pass".

   Strategy for dense data tables: the page's own headline data
   should be visible WITHOUT sideways scrolling. We (a) hide truly
   secondary columns, (b) pin the row's identifying column as a
   sticky left rail, (c) clamp long text cells, and (d) keep the
   primary metric columns horizontally scrollable with a visible
   thin scrollbar as the swipe cue.
   ================================================================ */

/* Never let iOS auto-inflate font sizes (breaks our tuned layout). */
html.mobile-site { -webkit-text-size-adjust: 100%; }

/* A discoverable scroll cue: show a slim, always-visible scrollbar on
   the horizontally-scrolling content sections + table wraps so users
   know the dense tables pan sideways. (Desktop keeps native bars.) */
html.mobile-site main section,
html.mobile-site .quant-table-wrap,
html.mobile-site #twinsies-result {
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}
html.mobile-site main section::-webkit-scrollbar,
html.mobile-site .quant-table-wrap::-webkit-scrollbar,
html.mobile-site #twinsies-result::-webkit-scrollbar {
  height: 5px;
  -webkit-appearance: none;
}
html.mobile-site main section::-webkit-scrollbar-thumb,
html.mobile-site .quant-table-wrap::-webkit-scrollbar-thumb,
html.mobile-site #twinsies-result::-webkit-scrollbar-thumb {
  background: var(--border);
  border-radius: 3px;
}

/* Bigger touch area for links inside data-table cells without changing
   the visual row height: pad the anchor and pull the padding back with
   a matching negative margin so neighbouring cells don't shift. */
html.mobile-site main section td a {
  display: inline-block;
  padding-block: 8px;
  margin-block: -8px;
}

/* ---- Wizard: stack the two portfolio cards, trim the company column,
   and let the NAV chart + trade log scroll rather than overflow. */
html.mobile-site .wizard-portfolios { grid-template-columns: 1fr; gap: 12px; }
html.mobile-site .wizard-holdings-table .wiz-co { max-width: 96px; }
html.mobile-site #wizard-trades { overflow-x: auto; -webkit-overflow-scrolling: touch; }
html.mobile-site .wizard-trades-table { min-width: 560px; }
html.mobile-site .wizard-trades-table .wiz-reason { max-width: 180px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ---- Market Cap: fit Rank · Company · Market Cap · 24h on a phone,
        so the page's headline number (market cap) is visible with no
        sideways scroll. Sector + Country drop; the company name and
        logo shrink/clamp. ---- */
html.mobile-site .mcap-table { width: 100%; font-size: 12px; }
html.mobile-site .mcap-table thead th,
html.mobile-site .mcap-table tbody td { padding: 7px 5px; white-space: nowrap; }
html.mobile-site .mcap-table th:nth-child(5),
html.mobile-site .mcap-table td:nth-child(5),   /* Sector  */
html.mobile-site .mcap-table th:nth-child(6),
html.mobile-site .mcap-table td:nth-child(6) {  /* Country */
  display: none;
}
html.mobile-site .mcap-table .mcap-rank { width: 30px; }
html.mobile-site .mcap-table .mcap-logo { width: 18px; height: 18px; }
html.mobile-site .mcap-table .mcap-name-text {
  display: inline-block;
  max-width: 30vw;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: middle;
}
/* The Sector + "Rank Δ over N days" filter bar is nowrap by default and
   runs off the right edge; let it wrap and cap the select width. */
html.mobile-site .mcap-filter { flex-wrap: wrap; gap: 6px 10px; }
html.mobile-site .mcap-filter .mcap-select { max-width: 56vw; }

/* ---- Themes (home): drop the count + K-Ratio metadata columns and
        pin the Theme name (checkbox + name form the left rail) so the
        trailing-return columns are what you swipe through. ---- */
html.mobile-site #themes-table th:nth-child(3),
html.mobile-site #themes-table td:nth-child(3),   /* Subthemes count */
html.mobile-site #themes-table th:nth-child(4),
html.mobile-site #themes-table td:nth-child(4),   /* Tickers count   */
html.mobile-site #themes-table th:nth-child(5),
html.mobile-site #themes-table td:nth-child(5) {  /* K-Ratio         */
  display: none;
}
html.mobile-site #themes-table tbody td:nth-child(2),
html.mobile-site #themes-table thead th:nth-child(2) {
  position: sticky;
  left: 30px;            /* width of the sel-col checkbox rail */
  background: var(--bg);
  z-index: 1;
  box-shadow: 4px 0 6px -4px rgba(0, 0, 0, 0.6);
}
html.mobile-site #themes-table thead th:nth-child(2) { background: var(--panel); z-index: 3; }
html.mobile-site #themes-table td:nth-child(2) a {
  display: inline-block;
  max-width: 40vw;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: middle;
}

/* ---- Stocks / sub-industry ticker tables: hide the long free-text
        columns (Company / Theme / Subtheme) so the pinned Ticker rail
        sits right next to Mkt Cap + the return columns. ---- */
html.mobile-site #stocks-table th:nth-child(3),
html.mobile-site #stocks-table td:nth-child(3),   /* Company  */
html.mobile-site #stocks-table th:nth-child(4),
html.mobile-site #stocks-table td:nth-child(4),   /* Theme    */
html.mobile-site #stocks-table th:nth-child(5),
html.mobile-site #stocks-table td:nth-child(5) {  /* Subtheme */
  display: none;
}

/* ---- Picks: pin the ticker so position rows stay labelled while the
        return/vs-SPY columns scroll. Target #picks-table specifically —
        the chart widget also renders a <table>, which must NOT get pinned
        columns. ---- */
html.mobile-site #picks-table tbody td:nth-child(2),
html.mobile-site #picks-table thead th:nth-child(2) {
  position: sticky;
  left: 0;
  background: var(--bg);
  z-index: 1;
}
html.mobile-site #picks-table thead th:nth-child(2) { background: var(--panel); z-index: 3; }

/* ---- Theme→stocks (#theme-stocks-table) and sub-industry→tickers
        (#tickers-table) share the stocks layout. Pin checkbox + Ticker
        and drop the long free-text columns, same as #stocks-table. ---- */
html.mobile-site #theme-stocks-table tbody td:nth-child(1),
html.mobile-site #theme-stocks-table thead th:nth-child(1),
html.mobile-site #tickers-table tbody td:nth-child(1),
html.mobile-site #tickers-table thead th:nth-child(1) {
  position: sticky; left: 0; background: var(--bg); z-index: 1;
}
html.mobile-site #theme-stocks-table tbody td:nth-child(2),
html.mobile-site #theme-stocks-table thead th:nth-child(2),
html.mobile-site #tickers-table tbody td:nth-child(2),
html.mobile-site #tickers-table thead th:nth-child(2) {
  position: sticky; left: 30px; background: var(--bg); z-index: 1;
  box-shadow: 4px 0 6px -4px rgba(0, 0, 0, 0.6);
}
html.mobile-site #theme-stocks-table thead th:nth-child(1),
html.mobile-site #theme-stocks-table thead th:nth-child(2),
html.mobile-site #tickers-table thead th:nth-child(1),
html.mobile-site #tickers-table thead th:nth-child(2) { background: var(--panel); z-index: 3; }
/* Company (3) + Subtheme (4) on theme-stocks; Company (3) on tickers. */
html.mobile-site #theme-stocks-table th:nth-child(3),
html.mobile-site #theme-stocks-table td:nth-child(3),
html.mobile-site #theme-stocks-table th:nth-child(4),
html.mobile-site #theme-stocks-table td:nth-child(4),
html.mobile-site #tickers-table th:nth-child(3),
html.mobile-site #tickers-table td:nth-child(3) { display: none; }

/* Pinned-rail cells need an opaque background so scrolled content
   doesn't bleed through; reinforce it for the name columns. */
html.mobile-site #themes-table tbody td:nth-child(1),
html.mobile-site #themes-table tbody td:nth-child(2),
html.mobile-site #stocks-table tbody td:nth-child(1),
html.mobile-site #stocks-table tbody td:nth-child(2),
html.mobile-site #theme-stocks-table tbody td:nth-child(1),
html.mobile-site #theme-stocks-table tbody td:nth-child(2),
html.mobile-site #tickers-table tbody td:nth-child(1),
html.mobile-site #tickers-table tbody td:nth-child(2) { background: var(--bg); }
