/* 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: 14px;
}
.quant-pagination button {
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 4px;
  padding: 4px 10px; font: inherit; font-size: 14px;
  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: 13px;
  margin-left: 2px;
}

/* Stock count shown directly above the Quant table header. */
.quant-table-count {
  font-size: 14px;
  color: var(--muted, #8b949e);
  margin: 6px 0 4px;
}
/* Results-count line + "Export to Excel" button on one row (count left, button right). */
.quant-results-bar { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.quant-results-bar .quant-table-count { margin: 6px 0; }
.quant-export-btn { white-space: nowrap; flex: 0 0 auto; }
.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: 13px;
  margin-left: 2px;
}

:root {
  --bg: #0e1116;
  --panel: #161b22;
  --panel-2: #1c2128;
  --border: #30363d;
  --text: #e6edf3;
  --muted: #aab4c0;
  --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: 16px/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: 14px; padding: 2px 20px 6px; }
/* Search box + its live autocomplete dropdown. The wrap holds the flex sizing
   and is position:relative so the dropdown anchors directly under the input. */
.search-wrap { flex: 1; max-width: 520px; margin-left: auto; position: relative; }
#search {
  width: 100%; box-sizing: border-box;
  padding: 6px 12px; background: var(--panel);
  color: var(--text); border: 1px solid var(--border); border-radius: 7px;
  font: inherit; font-size: 14.5px;
}
.search-dropdown {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 200;
  background: var(--panel); border: 1px solid var(--border); border-radius: 8px;
  max-height: min(60vh, 440px); overflow-y: auto; padding: 4px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
}
.search-dropdown[hidden] { display: none; }
.search-dd-item {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 9px; border-radius: 6px; cursor: pointer;
  font-size: 14.5px; white-space: nowrap;
}
.search-dd-item.active { background: rgba(88, 166, 255, 0.18); }
.search-dd-logo { flex: 0 0 auto; display: inline-flex; }
.search-dd-sym  { font-weight: 700; color: #f8fafc; flex: 0 0 auto; }
.search-dd-name { color: #c5cedd; flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.search-dd-sub  { color: var(--muted); font-size: 13px; flex: 0 0 auto; }
.search-dd-empty { padding: 10px 12px; font-size: 14px; color: var(--muted); }
.search-dd-group {
  padding: 6px 9px 2px; font-size: 12px; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted);
}
.search-dd-subrow .search-dd-sym { color: var(--muted); font-weight: 400; }
.search-dd-hint {
  padding: 7px 10px; font-size: 13px; color: var(--muted);
  border-top: 1px solid var(--border); margin-top: 4px;
}
html.mobile-site .search-wrap { flex: 1 1 100%; max-width: none; }

/* 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: 14px;
  color: var(--muted);
}
.breadcrumb-bar .back {
  color: var(--accent);
  text-decoration: none;
  font-weight: 600;
  font-size: 14px;
}
.breadcrumb-bar .back:hover { text-decoration: underline; }
.breadcrumb-bar .bc-sep-back { color: var(--border); }
.breadcrumb { color: var(--muted); font-size: 14px; 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; }

/* AVGO vs S&P 500 tracker (#avgo). Desktop height matches the old inline 360px
   (byte-for-byte unchanged at desktop widths). The chart height now comes from
   CSS so it can flex; the page is made usable on a phone even on the DESKTOP
   domain (which never gets html.mobile-site) via a viewport @media query —
   tightly scoped to #avgo-view, and only firing at phone widths, so wide
   desktop screens are unaffected. */
#avgo-chart { height: 360px; }
@media (max-width: 640px) {
  #avgo-view h2 { font-size: 17px; }
  #avgo-view #avgo-status { font-size: 13.5px; line-height: 1.45; }
  #avgo-view #avgo-readout { gap: 14px 16px; font-size: 14.5px; }
  #avgo-view #avgo-chart { height: clamp(300px, 58vh, 440px); }
}

/* Account performance pages (#ira, #roth401k) — shared styles via classes so
   the mobile overrides below actually win (inline styles used to block them).
   Chart height comes from CSS so it flexes; phones get a shorter, viewport-
   relative height. */
#roth401k-chart, #ira-chart { height: clamp(360px, 60vh, 520px); }
.acct-status { font-size: 14px; margin-bottom: 8px; }
.acct-readout { display: flex; gap: 18px; flex-wrap: wrap; align-items: center; margin-bottom: 10px; font-size: 14px; }
.acct-readout > span { white-space: nowrap; }
.acct-readout b { font-size: 15px; }
.acct-stats-table { font-size: 14.5px; }
@media (max-width: 640px) {
  #roth401k-view h2, #ira-view h2 { font-size: 17px; line-height: 1.25; }
  #roth401k-chart, #ira-chart { height: clamp(300px, 52vh, 420px); }
  .acct-status { font-size: 13.5px; line-height: 1.45; }
  /* Readout: stack one legend item per line — clean to scan, no awkward wrap. */
  .acct-readout { flex-direction: column; align-items: flex-start; gap: 8px; font-size: 14.5px; margin-bottom: 14px; }
  .acct-readout > span { white-space: normal; }
  .acct-readout b { font-size: 14.5px; }
  /* Stats table: use the full width and a touch smaller so it never scrolls. */
  .acct-stats-table { font-size: 14.5px; width: 100%; }
}

h2 { font-size: 18px; font-weight: 700; letter-spacing: -0.01em; margin: 8px 0 4px; }
h3 { font-size: 14.5px; 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: 12px; 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: 14.5px; font-weight: 500; line-height: 1.3; flex: 0 0 auto; }
.card-stats { color: var(--muted); font-size: 14px; margin-bottom: 0; display: inline-flex; gap: 6px; align-items: center; }
.card-desc {
  color: var(--muted); font-size: 14px; 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: 14px; 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: 13px; 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: 13px; 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: 12px; 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: 14px; 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. */
[data-returns-level],
.chart-toolbar {}

.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: 13px;
  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. */
#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: 12px;
     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: 13px; margin-left: 12px;
}
.table-mode-toggle .muted {
  font-size: 12px; 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: 13px;
  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: 13px; margin-left: 12px;
}
.quant-order-toggle .muted {
  font-size: 12px; 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: 13px;
  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: 13px; 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: 14px; }
dd { margin: 0; font-size: 14.5px; }



.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; }
/* (The standalone .td-kratio-grid was removed — the K-Ratio family now lives in
   the Signals panel inside Market Context. See .signal-row.) */
/* 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: 14px; 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: 12px; }
.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: 13px; 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; }

/* ── US Manufacturing Locations (profile bottom: table + albersUSA pin map) ── */
.td-mfg { display: block; margin: 26px 0 8px; padding-top: 18px; border-top: 1px solid var(--border); }
.td-mfg-head { font-size: 16px; font-weight: 700; margin: 0 0 12px; }
.td-mfg-head .muted { font-weight: 400; font-size: 14.5px; }
.td-mfg-map { position: relative; width: 100%; max-width: 820px; margin: 0 auto 14px; background: #0e1116; border: 1px solid var(--border); border-radius: 10px; overflow: hidden; }
.td-mfg-svg { display: block; }
.td-pin .td-pin-dot { fill: #3fb950; stroke: #ffffff; stroke-width: 1.4; transition: r .1s ease; }
.td-pin .td-pin-num { fill: #04220e; font-size: 10px; font-weight: 700; pointer-events: none; }
.td-pin:hover .td-pin-dot, .td-pin.td-pin-hi .td-pin-dot { fill: #7BAFD4; r: 9; }
.td-mfg-tip { position: absolute; z-index: 5; pointer-events: none; max-width: 240px; padding: 7px 10px;
  background: rgba(13,17,23,0.96); border: 1px solid var(--border); border-radius: 8px; font-size: 14px;
  color: var(--text); box-shadow: 0 4px 16px rgba(0,0,0,0.5); line-height: 1.35; }
.td-mfg-tablewrap { overflow-x: auto; }
.td-mfg-table { width: 100%; border-collapse: collapse; font-size: 14.5px; }
.td-mfg-table thead th { text-align: left; font-size: 13px; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--muted); border-bottom: 1px solid var(--border); padding: 6px 10px; }
.td-mfg-table th.num, .td-mfg-table td.num { text-align: center; width: 34px; }
.td-mfg-table tbody td { padding: 8px 10px; border-bottom: 1px solid var(--border); vertical-align: top; }
.td-mfg-table tbody tr.td-fac-hi { background: rgba(123,175,212,0.14); }
.td-mfg-num { color: var(--accent); font-weight: 700; font-variant-numeric: tabular-nums; }
.td-mfg-loc { white-space: nowrap; color: var(--muted); }
.td-mfg-addr { font-size: 13px; margin-top: 2px; }
.td-mfg-src { text-decoration: none; opacity: 0.7; }
.td-mfg-src:hover { opacity: 1; }
/* Google-satellite deep-links: address (accent), location (stays subtle), 🛰 icon. */
.td-mfg-sat { color: var(--accent); text-decoration: none; }
.td-mfg-sat:hover { text-decoration: underline; }
.td-mfg-loc a.td-mfg-sat { color: var(--muted); }
.td-mfg-loc a.td-mfg-sat:hover { color: var(--accent); }
.td-mfg-satico { text-decoration: none; opacity: 0.85; white-space: nowrap; }
.td-mfg-satico:hover { opacity: 1; }
.td-mfg-tip-sat { color: var(--accent); font-size: 13px; }
.td-mfg-note { font-size: 13px; margin: 10px 0 0; }
html.mobile-site .td-mfg-table { font-size: 14px; }
html.mobile-site .td-mfg-table tbody td { padding: 7px 6px; }
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: 14px;
  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: 13px; }
.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: 14.5px; }
.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: 14px; }
.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: 14px; 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: 14px;
}
.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: 14px; }
/* Universe toggles (No OTC / US only / S&P 500 / Nasdaq 100) next to "Show by". */
.quant-universe-cbs { display: inline-flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding-left: 10px; margin-left: 2px; border-left: 1px solid var(--border); }
.quant-uni-cb { display: inline-flex; align-items: center; gap: 4px; font-size: 13px;
  cursor: pointer; color: var(--text); white-space: nowrap; user-select: none; }
.quant-uni-cb input { margin: 0; cursor: pointer; }
/* "Profile contains…" post-filter row (below the Show-by toolbar). */
.quant-profile-row { display: flex; align-items: center; gap: 8px; margin: 0 0 6px; font-size: 14px; flex-wrap: wrap; }
.quant-profile-row input { width: 260px; max-width: 60vw; }
/* "Add ticker" row (temporary stocks dropped into the results). */
.quant-added-row { display: flex; align-items: center; gap: 8px; margin: 0 0 6px; font-size: 14px; flex-wrap: wrap; }
.quant-added-row input { width: 180px; max-width: 50vw; }
.quant-added-chips { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.quant-added-chip { display: inline-flex; align-items: center; gap: 4px; padding: 1px 4px 1px 7px;
  border: 1px solid var(--border); border-radius: 10px; font-size: 13px; font-weight: 600; color: var(--text); background: var(--bg); }
.quant-added-chip button { border: 0; background: none; color: var(--muted); cursor: pointer; font-size: 14.5px; line-height: 1; padding: 0 2px; }
.quant-added-chip button:hover { color: var(--text); }
.quant-added-badge { font-size: 12px; font-weight: 700; color: #0b69d4; border: 1px solid #0b69d4;
  border-radius: 3px; padding: 0 3px; margin-left: 5px; vertical-align: middle; letter-spacing: .02em; }
/* Per-row ✕ to remove a stock from the list (hover-revealed on desktop). */
.quant-remove-x { opacity: 0; border: 0; background: none; color: var(--muted); cursor: pointer;
  font-size: 15px; line-height: 1; padding: 0 3px; margin-left: 4px; vertical-align: middle; transition: opacity .1s, color .1s; }
#quant-table tbody tr:hover .quant-remove-x { opacity: .55; }
.quant-remove-x:hover { opacity: 1 !important; color: var(--down, #7BAFD4); }
html.mobile-site .quant-remove-x { opacity: .55; }   /* no hover on touch — always visible */
.quant-removed-row { display: flex; align-items: center; gap: 8px; margin: -2px 0 6px; font-size: 14px; flex-wrap: wrap; }
.quant-link-btn { border: 0; background: none; color: #0b69d4; cursor: pointer; font-size: 13px; padding: 0; text-decoration: underline; }
/* 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: 14.5px; }
#quant-table th { font-size: 13px; }
/* Theme + Sub-theme: smaller "category" text — long names that shouldn't shout. */
#quant-table td.quant-cat { font-size: 12px; color: var(--muted); }
#quant-table td.quant-cat.quant-hov-cell { color: var(--accent); cursor: pointer; }
#quant-table td.quant-cat.quant-hov-cell:hover { text-decoration: underline; }
.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: 12px; 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: 14px; 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: 14px; }
.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: 13px; 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: 14px;
  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: 14px; 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: 14px; 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: 14px; 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: 13px; 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: 14.5px; font-weight: 600; color: #e6edf3; }
.semi-sub-count { font-size: 13px; 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: 14px; 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: 13px; }
.semi-sub-ticker:hover { text-decoration: underline; }
.semi-sub-priv { color: var(--muted);
  font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 13px; }
/* 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: 12px; text-transform: uppercase;
  letter-spacing: 0.08em; margin-bottom: 3px; }
.semi-sub-labs-list li { font-size: 14px; 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: 13px; padding: 2px 0 2px 4px; font-style: italic; }
.semi-sub-link { color: var(--accent); font-size: 14.5px; 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: 14.5px; 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: 13px; 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: 13px; }

/* 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: 13px; 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: 13px; 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: 14.5px; font-weight: 500; }
.tax-kind-subsector > .tax-row .tax-name { font-size: 14.5px; 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: 14px; 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: 12px; }

/* 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: 13px; 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: 12px; 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: 14.5px; 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; }
/* Backtest tab — factor form against the local Sharadar service. */
.bt-presets { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin: 0 0 12px; }
.bt-preset {
  background: var(--bg); border: 1px solid var(--border); color: var(--text);
  border-radius: 14px; padding: 4px 11px; font-size: 14px; cursor: pointer;
}
.bt-preset:hover { border-color: var(--accent); color: var(--accent); }
.bt-group-h {
  font-size: 13px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--muted); margin: 12px 0 6px; display: flex; gap: 8px; align-items: center;
}
.bt-group-h select, .bt-runrow select {
  padding: 4px 6px; background: var(--bg); border: 1px solid var(--border);
  border-radius: 4px; color: var(--text); font-size: 14px;
}
.bt-grid { display: flex; flex-wrap: wrap; gap: 10px 14px; margin-bottom: 4px; }
.bt-field { display: flex; flex-direction: column; gap: 3px; }
.bt-field label { font-size: 13px; color: var(--muted); }
.bt-field input {
  width: 124px; padding: 7px 9px; font-size: 16px;
  background: var(--bg); border: 1px solid var(--border); border-radius: 4px; color: var(--text);
}
.bt-runrow { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; margin: 12px 0 10px; }
.bt-submode { display: flex; gap: 6px; margin: 0 0 12px; }
.bt-submode-btn {
  flex: 1; padding: 9px 12px; font-size: 14.5px; cursor: pointer; border-radius: 6px;
  background: var(--bg); border: 1px solid var(--border); color: var(--muted);
}
.bt-submode-btn:hover { color: var(--text); border-color: var(--accent); }
.bt-submode-btn.active { background: var(--accent); color: #0b1220; border-color: var(--accent); font-weight: 600; }
/* Walk-forward backtest: stat cards + equity-curve chart + caveats. */
.btw-stats { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0; }
.btw-stat { background: var(--panel-2); border: 1px solid var(--border); border-radius: 6px; padding: 7px 11px; min-width: 96px; }
.btw-stat .lbl { font-size: 12px; text-transform: uppercase; letter-spacing: .03em; color: var(--muted); }
.btw-stat .val { font-size: 17px; font-weight: 700; font-variant-numeric: tabular-nums; }
.btw-chart-legend { display: flex; gap: 16px; font-size: 14px; margin: 4px 0 6px; }
.btw-chart-legend span::before { content: "—"; font-weight: 900; margin-right: 5px; }
#btw-chart { width: 100%; height: 340px; }
.btw-caveats { font-size: 13px; color: var(--muted); margin: 10px 0; line-height: 1.5; }
.btw-caveats li { margin: 2px 0; }
.btw-warn { color: #E69F00; }
/* Service-side prescreen walk (D5): the recipe echo line + the greyed factor
   controls while a prescreen (whose recipe replaces them) is selected. */
.btw-recipe { color: var(--fg); background: rgba(122, 175, 212, 0.08); border: 1px solid var(--border); border-radius: 6px; padding: 6px 10px; margin-bottom: 8px; }
.bt-field-off { opacity: 0.45; }
/* 🧺 Prescreen basket sub-pane (cont. 200) — the basket being backtested is
   shown as chips BEFORE the numbers so a curve is always traceable to its picks. */
#btb-chart { width: 100%; height: 340px; }
.btb-picks { margin: 8px 0 4px; }
.btb-picks-head { font-size: 14px; color: var(--muted); margin-bottom: 6px; }
.btb-picks-head b { color: var(--text); }
.btb-picks-list { display: flex; flex-wrap: wrap; gap: 5px; }
.btb-chip {
  font-size: 12.5px; font-weight: 600; padding: 2px 7px; border-radius: 4px;
  background: var(--panel-2); border: 1px solid var(--border); color: var(--text);
  font-variant-numeric: tabular-nums;
}
.btb-warn { color: #E69F00; }
.btb-ok { color: #3fb950; }
/* 🧺 hold-today's-picks ⇄ ⏩ walk-forward (cont. 202) — a second-level toggle
   inside the Backtest tab's sub-mode, so it reads as subordinate to it. */
.btb-mode { display: flex; gap: 6px; margin: 0 0 10px; flex-wrap: wrap; }
.btb-mode-btn {
  background: var(--panel-2); color: var(--muted); border: 1px solid var(--border);
  border-radius: 5px; padding: 5px 11px; font-size: 13.5px; cursor: pointer;
}
.btb-mode-btn:hover { color: var(--text); border-color: var(--accent); }
.btb-mode-btn.active { background: var(--panel); color: var(--text); border-color: var(--accent); font-weight: 600; }
#btb-prescreen option:disabled { color: var(--muted); }
.btb-excluded { font-size: 13px; line-height: 1.5; margin: 10px 0 2px; }
.bt-nl { display: flex; gap: 8px; align-items: stretch; margin: 0 0 12px; }
.bt-nl textarea {
  flex: 1; min-width: 0; resize: vertical; padding: 8px 10px; font-size: 16px;
  background: var(--bg); border: 1px solid var(--border); border-radius: 4px;
  color: var(--text); font-family: inherit; line-height: 1.35;
}
/* Best-of-best (hierarchical AI screen) summary — one block per surviving
   category, its aggregate stats vs the S&P, then the top-N stocks. */
.ai-bob { margin: 10px 0 6px; border: 1px solid var(--border); border-radius: 6px; background: var(--panel-2); padding: 10px 12px; }
.ai-bob-head { font-size: 14.5px; margin-bottom: 6px; }
.ai-bob-notes { font-size: 13px; margin-bottom: 8px; }
.ai-bob-cat { padding: 7px 0; border-top: 1px solid rgba(48, 54, 61, .45); }
.ai-bob-cat-h { font-size: 14.5px; margin-bottom: 3px; display: flex; flex-wrap: wrap; gap: 4px 12px; align-items: baseline; }
.ai-bob-stat { font-size: 13.5px; white-space: nowrap; }
.ai-bob-stock { font-size: 14.5px; padding: 2px 0 2px 6px; }
.ai-bob-rank { color: var(--muted); font-variant-numeric: tabular-nums; }
.ai-bob-stock a { color: var(--accent); font-weight: 600; text-decoration: none; }
.ai-bob-co { color: var(--text); }
/* 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; }
html.mobile-site .bt-nl { flex-direction: column; }
html.mobile-site .bt-nl .btn { min-height: 44px; }
/* 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: 13px;
}
.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-colfilter {
  border-color: #63b3ed; border-left-width: 3px;   /* column ▾ filters, distinct from the factor stages */
}
.quant-funnel-step.quant-funnel-input {
  background: transparent; border-style: dashed; border-color: var(--border);
}
.quant-funnel-label { font-size: 12px; 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: 14.5px; 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: 14px; line-height: 1; cursor: pointer; padding: 0;
}
.quant-funnel-x:hover { color: var(--text); border-color: var(--text); }
/* 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: 12px; 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: 12px; 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: 12px; 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: 13px; 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: 13px; }
.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: 13px; 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; }
/* "each yr" toggle wraps to its own indented line under the row's controls. */
.quant-filter-row--revgrowth > .quant-each-cb { grid-column: 1 / -1; justify-self: start; margin-left: 100px; }
.quant-each-cb { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; color: var(--muted); cursor: pointer; }
.quant-each-cb input { margin: 0; cursor: pointer; }
.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: 13px;
}
/* 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: 13px;
}
.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: 13px;
}
.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: 12px; 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: 13px; 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: 13px; }
.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: 13px; }
.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: 13px;
  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: 13px;
}
.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: 13px;
}
.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: 13px;
  max-width: 1100px;
  line-height: 1.5;
}
/* Prescreens-tab "Run on" level picker (Stocks / Industries / Themes / Subthemes). */
.quant-prescreen-level-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  padding: 2px 12px 6px;
  font-size: 14px;
}
.quant-prescreen-level {
  border: 1px solid var(--border);
  background: var(--card, rgba(255, 255, 255, 0.03));
  color: var(--text, #e6e6e6);
  border-radius: 999px;
  padding: 4px 12px;
  font-size: 14px;
  cursor: pointer;
  line-height: 1.2;
  transition: background 0.12s, border-color 0.12s;
}
.quant-prescreen-level:hover { border-color: var(--accent); }
.quant-prescreen-level.active {
  border-color: var(--accent);
  background: var(--accent);
  color: #fff;
  font-weight: 600;
}
.quant-prescreen-level-hint { margin-left: 4px; font-size: 13px; }

/* Quant table hover-preview chart popup (Task B). */
.quant-hovchart {
  position: fixed;
  z-index: 9999;
  width: 256px;
  background: #121212;
  border: 1px solid var(--border, #2a2a2a);
  border-radius: 8px;
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.55);
  padding: 8px 10px 10px;
  pointer-events: none;
}
.quant-hovchart-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  font-size: 14px;
  font-weight: 600;
  color: var(--text, #e6e6e6);
  margin-bottom: 6px;
}
.quant-hovchart-chg { font-size: 14px; font-weight: 700; }
.quant-hovchart-body { line-height: 0; }
.quant-hovchart-body svg { display: block; width: 100%; height: 116px; }
.quant-hovchart-loading,
.quant-hovchart-empty {
  line-height: 1.4;
  font-size: 13px;
  color: var(--muted, #8a8f98);
  padding: 18px 4px;
  text-align: center;
}
/* Subtle "previewable on hover" cue on the company / theme text cells (the
   ticker cell already styles its link). */
#quant-table td.quant-hov-cell { cursor: default; }
#quant-table td.quant-hov-cell:hover { background: rgba(255, 255, 255, 0.035); }
.quant-prescreen-scope {
  margin: 4px 10px 10px;
  padding: 8px 12px;
  font-size: 14px;
  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: 14.5px;
  font-weight: 700;
  color: #e4c98a;
  letter-spacing: 0.01em;
}
.quant-prescreen-badge {
  font-size: 12px;
  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: 13px;
  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: 13px;
  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: 13px;
  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: 14px; 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: 12px;
  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: 12px;
  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: 14.5px;
  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: 13px; }
#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: 13px;
}
.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: 14px;
}
#picks-table th, #picks-table td {
  padding: 6px 10px;
  border-bottom: 1px solid var(--border);
  text-align: left;
}
#picks-table th {
  font-size: 13px;
  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: 12px; 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: 13px; 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: 13px; 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: 13px; }
#td-add-pick-msg a { color: var(--accent); text-decoration: none; }
#td-add-pick-msg a:hover { text-decoration: underline; }

/* ── Portfolio v2 — transaction-driven living portfolio ─────────────────
   Multi-portfolio selector, summary cards, Buy/Sell/Cash entry, holdings
   table→cards, value-vs-SPY chart, sector+theme SVG donuts, editable txn
   ledger. ZERO red: gains/day/realized use the shared .ret-pos / .ret-neg
   classes (green / #7BAFD4); Sell + Delete buttons use muted/blue, never red.
   Donut colors come from OVERLAY_COLORS (Okabe-Ito) + gray for Cash. */

/* Selector bar. */
.pf-bar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 0 0 14px;
}
.pf-select {
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 4px;
  padding: 6px 10px; font: inherit; font-size: 14.5px; min-width: 180px;
}
.pf-select:focus { border-color: var(--accent); outline: none; }
.pf-btn { font-size: 14px; padding: 5px 12px; }
.pf-asof { font-size: 13px; margin-left: auto; }

/* Summary cards. */
.pf-summary { display: flex; flex-wrap: wrap; gap: 10px; margin: 4px 0 14px; }
.pf-summary-empty { font-size: 14px; padding: 6px 0; }
.pf-tile {
  flex: 0 0 auto; min-width: 140px;
  padding: 8px 12px;
  background: var(--panel); border: 1px solid var(--border); border-radius: 6px;
}
.pf-tile-label {
  font-size: 12px; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 2px;
}
.pf-tile-value { font-size: 18px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
.pf-tile-sub { font-size: 13px; margin-top: 1px; font-variant-numeric: tabular-nums; }

/* Transaction entry. */
.pf-entry {
  background: var(--panel); border: 1px solid var(--border); border-radius: 8px;
  padding: 12px 14px; margin: 0 0 16px;
}
.pf-entry-tabs { display: flex; gap: 6px; margin-bottom: 12px; }
.pf-tab {
  background: transparent; color: var(--muted);
  border: 1px solid var(--border); border-radius: 6px;
  padding: 5px 16px; font: inherit; font-size: 14.5px; cursor: pointer;
}
.pf-tab:hover { color: var(--text); }
.pf-tab.active { background: var(--accent); color: #0e1116; border-color: var(--accent); font-weight: 600; }
.pf-form { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; }
/* The [hidden] attr alone loses to `.pf-form{display:flex}` (higher specificity),
   so the inactive form rendered ON TOP of the active one. Re-assert the hide. */
.pf-form[hidden] { display: none; }
.pf-field { display: flex; flex-direction: column; gap: 4px; }
.pf-field label {
  font-size: 12px; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.04em;
  display: flex; align-items: center; gap: 6px;
}
.pf-field input, .pf-field select {
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 4px;
  padding: 6px 10px; font: inherit; font-size: 14.5px;
}
.pf-field input:focus, .pf-field select:focus { border-color: var(--accent); outline: none; }
.pf-field input:disabled { opacity: 0.5; cursor: not-allowed; }
#pf-ticker { width: 120px; letter-spacing: 0.04em; text-transform: uppercase; }
#pf-qty, #pf-price, #pf-cash-amount { width: 120px; }
#pf-note { width: 180px; }
.pf-field-note { flex: 1 1 160px; }
.pf-field-note #pf-note { width: 100%; }
.pf-mini-toggle {
  background: transparent; border: 1px solid var(--border); border-radius: 4px;
  color: var(--accent); font-size: 12px; padding: 1px 6px; cursor: pointer;
  text-transform: none; letter-spacing: 0;
}
.pf-mini-toggle:hover { border-color: var(--accent); }
/* Allocate-by segmented control: Shares · $ Amount · % Alloc. Sits where the
   field label normally goes, so it doubles as the field's heading. */
.pf-field-amt { position: relative; }
.pf-amt-modes {
  display: inline-flex; width: fit-content; margin-bottom: 2px;
  border: 1px solid var(--border); border-radius: 5px; overflow: hidden;
}
.pf-amt-mode {
  appearance: none; background: var(--panel-2); color: var(--muted);
  border: 0; border-right: 1px solid var(--border);
  padding: 5px 11px; font: inherit; font-size: 13px; font-weight: 600;
  line-height: 1.1; cursor: pointer; transition: background .08s, color .08s;
}
.pf-amt-mode:last-child { border-right: 0; }
.pf-amt-mode:hover { color: var(--text); }
.pf-amt-mode.active { background: var(--accent); color: #0e1116; }
/* Floats just under the qty input so it never shoves the input out of baseline
   alignment with the other fields. */
.pf-amt-hint {
  position: absolute; top: 100%; left: 0; margin-top: 3px;
  font-size: 13px; line-height: 1.2; white-space: nowrap;
}
.pf-check {
  font-size: 12px; color: var(--muted); margin-top: 4px;
  text-transform: none; letter-spacing: 0; display: flex; align-items: center; gap: 5px;
}
.pf-check input { width: auto; }
#pf-mkt-quote { font-variant-numeric: tabular-nums; }
.pf-submit { font-size: 14.5px; padding: 6px 18px; }
/* Sell variant — muted blue, explicitly NOT red. */
.pf-submit-sell { background: #7BAFD4; border-color: #7BAFD4; color: #0e1116; }
.pf-entry-msg { font-size: 13px; margin-top: 10px; min-height: 14px; }
.pf-entry-msg.pf-msg-error { color: #7BAFD4; }

/* Section heads. */
.pf-section-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin: 14px 0 6px; }

/* Read-only IRA view (#ira / #roth401k): a clean, shareable long-term-account
   page — hide the portfolio-management controls, the buy/sell/cash entry form,
   the transaction ledger, and the per-share price columns (prices stay hidden). */
.pf-readonly #pf-select,
.pf-readonly #pf-new-btn,
.pf-readonly #pf-rename-btn,
.pf-readonly #pf-delete-btn,
.pf-readonly #pf-entry,
.pf-readonly #pf-ledger-block { display: none !important; }
/* (The read-only holdings table is now built column-by-column in JS — taxonomy +
   1M/3M returns, all sortable — so no nth-child column hiding here.) */
#pf-table th.pf-sortable { cursor: pointer; user-select: none; white-space: nowrap; }
#pf-table th.pf-sortable:hover { color: var(--accent); }
/* Excel-style per-column filter (▾) on the holdings header. */
.pf-hold-filter-btn { background: none; border: 0; color: var(--muted); cursor: pointer; font-size: 12px; padding: 0 2px; margin-left: 3px; line-height: 1; }
.pf-hold-filter-btn:hover { color: var(--accent); }
.pf-hold-filter-btn.pf-hf-on { color: var(--accent); font-weight: 700; }
.pf-hold-pop { position: fixed; z-index: 10000; background: #161616; border: 1px solid var(--border); border-radius: 8px; box-shadow: 0 8px 28px rgba(0,0,0,0.55); padding: 8px 10px; font-size: 14px; min-width: 200px; max-width: 280px; }
.pf-hold-pop .cf-title { font-weight: 700; margin-bottom: 6px; }
.pf-hold-pop label { display: block; margin: 3px 0; }
.pf-hold-pop input[type="number"] { width: 64px; }
.pf-hold-pop .pfhf-search { width: 100%; margin: 2px 0 6px; box-sizing: border-box; }
.pf-hold-pop .pfhf-selrow { display: flex; gap: 8px; margin-bottom: 4px; }
.pf-hold-pop .pfhf-list { max-height: 240px; overflow-y: auto; border: 1px solid var(--border); border-radius: 4px; padding: 4px 6px; }
.pf-hold-pop .pfhf-chk { display: block; margin: 2px 0; white-space: nowrap; }
.pf-hold-pop .cf-actions { display: flex; gap: 8px; margin-top: 8px; }
.pf-hold-pop .cf-actions button, .pf-hold-pop .pfhf-all, .pf-hold-pop .pfhf-none { cursor: pointer; border: 1px solid var(--border); background: var(--card, rgba(255,255,255,0.04)); color: var(--text); border-radius: 4px; padding: 2px 10px; font-size: 14px; }
.pf-hold-pop .pfhf-apply { border-color: var(--accent); }

/* Performance: trailing-returns table, stat tiles, monthly-returns grid. */
.pf-stats-table { border-collapse: collapse; font-size: 14px; font-variant-numeric: tabular-nums; }
.pf-stats-table th, .pf-stats-table td { padding: 5px 10px; text-align: right; border-bottom: 1px solid var(--border); white-space: nowrap; }
.pf-stats-table thead th { color: var(--muted); font-weight: 600; }
.pf-stats-table .pf-stats-rowlbl { text-align: left; color: var(--text); font-weight: 600; }
.pf-stats-table .pf-stats-excess td { border-top: 1px solid var(--border); color: var(--muted); }
.pf-stat-tiles { display: flex; flex-wrap: wrap; gap: 10px; margin: 12px 0 4px; }
.pf-stat-tile { border: 1px solid var(--border); border-radius: 8px; padding: 8px 14px; min-width: 120px; }
.pf-stat-lbl { font-size: 13px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.03em; }
.pf-stat-val { font-size: 18px; font-weight: 700; font-variant-numeric: tabular-nums; }
.pf-stat-sub { font-size: 13px; margin-top: 1px; }
/* Risk & performance metrics — two side-by-side label/value tables that stack on narrow screens. */
.pf-metrics-grid { display: flex; flex-wrap: wrap; gap: 2px 34px; margin: 12px 0 4px; }
.pf-metrics-table { border-collapse: collapse; flex: 1 1 300px; min-width: 280px; font-size: 14.5px; font-variant-numeric: tabular-nums; }
.pf-metrics-table td { padding: 5px 0; border-bottom: 1px solid var(--border); }
.pf-metrics-table .pf-m-lbl { color: var(--muted); padding-right: 14px; }
.pf-metrics-table .pf-m-val { text-align: right; font-weight: 700; color: var(--text); white-space: nowrap; }
.pf-stats-monthly-wrap { overflow-x: auto; }
.pf-stats-monthly th, .pf-stats-monthly td { padding: 4px 8px; }
.pf-stats-monthly .pf-stats-year { font-weight: 700; border-left: 1px solid var(--border); }
/* Performance matrix (Portfolio · stocks · S&P 500 TR · Excess) × windows.
   Many columns → the wrap scrolls; the row-label column stays pinned. */
.pf-stats-matrix .pf-stats-rowlbl { position: sticky; left: 0; background: var(--bg); z-index: 1; }
.pf-stats-matrix .pf-stats-total td { font-weight: 700; }
.pf-stats-matrix .pf-stats-bench td { border-top: 1px solid var(--border); color: var(--muted); }
.pf-stats-wt { font-size: 12px; color: var(--muted); font-weight: 400; margin-left: 5px; }
/* Locked portfolio (e.g. "3 Year Portfolio"): no entry/manage/edit controls on
   the site — modifiable only by hand. Holdings/performance/ledger stay visible. */
.pf-locked #pf-select,
.pf-locked #pf-new-btn,
.pf-locked #pf-rename-btn,
.pf-locked #pf-delete-btn,
.pf-locked #pf-entry,
.pf-locked .pf-ledger-tools,
.pf-locked #pf-csv-panel,
.pf-locked .pf-txn-actions { display: none !important; }
.pf-lock { font-size: 0.8em; opacity: 0.85; }
.pf-logo { margin: 2px 0 10px; }
.pf-logo[hidden] { display: none; }
.pf-logo-svg { width: 100%; max-width: 424px; height: auto; display: block; }
.pf-countdown {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 14px;
  margin: 4px 0 10px; padding: 10px 14px;
  border: 1px solid var(--border); border-left: 3px solid var(--accent);
  border-radius: 8px; background: var(--panel);
}
.pf-countdown[hidden] { display: none; }
.pf-cd-lbl { font-weight: 700; font-size: 14.5px; }
.pf-cd-val { font-size: 15px; font-variant-numeric: tabular-nums; }
.pf-cd-val b { font-size: 17px; }
.pf-cd-sub { font-size: 13px; }

/* Holdings + ledger tables. */
.pf-table-wrap { overflow-x: auto; }
#pf-table, #pf-txns-table { width: 100%; border-collapse: collapse; font-size: 14px; }
#pf-table th, #pf-table td,
#pf-txns-table th, #pf-txns-table td {
  padding: 6px 10px; border-bottom: 1px solid var(--border); text-align: left;
}
#pf-table th, #pf-txns-table th {
  font-size: 13px; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--muted); font-weight: 600;
}
#pf-table td.num, #pf-table th.num,
#pf-txns-table td.num, #pf-txns-table th.num { text-align: right; font-variant-numeric: tabular-nums; }
.pf-ticker {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--accent); text-decoration: none; font-weight: 700;
}
.pf-ticker:hover { text-decoration: underline; }
.pf-co { color: var(--muted); max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pf-stale { color: var(--muted); margin-left: 2px; font-weight: 700; }
.pf-cash-row td { color: var(--text); }
.pf-cash-tk { color: var(--muted); cursor: default; }
.pf-note-cell { max-width: 200px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Type badges (no red). */
.pf-badge {
  display: inline-block; font-size: 12px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.04em;
  padding: 1px 7px; border-radius: 4px; border: 1px solid var(--border);
}
.pf-badge-buy      { color: #3fb950; border-color: rgba(63,185,80,0.5); }
.pf-badge-sell     { color: #7BAFD4; border-color: rgba(123,175,212,0.5); }
.pf-badge-deposit  { color: #56B4E9; border-color: rgba(86,180,233,0.5); }
.pf-badge-withdraw { color: #E69F00; border-color: rgba(230,159,0,0.5); }
/* Dividend = income. Gold, the same identity colour the /7Y portfolio line
   uses — distinct from the green/#7BAFD4 direction pair by design. */
.pf-badge-dividend { color: #f5d547; border-color: rgba(245,213,71,0.5); }

/* ── Ticker autocomplete (trade form + dividend ticker) ────────────────────── */
.pf-field-ticker, .pf-field-divtk { position: relative; }
.pf-ac {
  position: absolute; z-index: 30; top: 100%; left: 0; min-width: 260px;
  margin-top: 3px; background: var(--panel); border: 1px solid var(--border);
  border-radius: 6px; box-shadow: 0 8px 22px rgba(0,0,0,0.45); overflow: hidden;
}
.pf-ac[hidden] { display: none; }
.pf-ac-row {
  display: flex; align-items: baseline; gap: 8px; padding: 5px 10px;
  font-size: 14px; cursor: pointer; white-space: nowrap;
}
.pf-ac-row:hover, .pf-ac-row.active { background: var(--panel-2); }
.pf-ac-tk { font-weight: 700; letter-spacing: 0.03em; min-width: 58px; }
.pf-ac-co { overflow: hidden; text-overflow: ellipsis; max-width: 240px; }

/* ── Ledger tools (dividend sync + CSV import) ─────────────────────────────── */
.pf-ledger-tools { margin-left: auto; display: flex; gap: 8px; flex-wrap: wrap; }
.pf-csv-panel {
  border: 1px solid var(--border); border-radius: 8px; background: var(--panel);
  padding: 12px; margin: 10px 0 4px;
}
.pf-csv-panel[hidden] { display: none; }
.pf-csv-head { display: flex; flex-direction: column; gap: 3px; margin-bottom: 8px; font-size: 13.5px; }
.pf-csv-head code { font-size: 12.5px; }
.pf-csv-text {
  width: 100%; box-sizing: border-box; background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 4px; padding: 8px 10px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; line-height: 1.5;
}
.pf-csv-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 8px; }
.pf-csv-actions input[type=file] { font-size: 13px; color: var(--muted); max-width: 100%; }
.pf-csv-commit:disabled { opacity: 0.45; cursor: not-allowed; }
.pf-csv-report { margin-top: 10px; font-size: 13.5px; }
.pf-csv-sum { margin-bottom: 6px; }
.pf-csv-row { display: grid; grid-template-columns: 100px 84px 84px 1fr; gap: 8px; padding: 1px 0; color: var(--muted); }
.pf-csv-more { margin-top: 4px; }
/* Rejected lines are called out, never hidden — a silent skip in an import is
   how a ledger quietly goes wrong. Amber, never red (colorblind palette). */
.pf-csv-bad { color: #E69F00; }
.pf-csv-errs { margin-top: 8px; color: #E69F00; line-height: 1.6; }

/* Ledger action buttons — link-style, never red. */
.pf-txn-actions { white-space: nowrap; }
.pf-link-btn {
  background: transparent; border: none; color: var(--accent);
  font: inherit; font-size: 14px; cursor: pointer; padding: 2px 6px;
}
.pf-link-btn:hover { text-decoration: underline; }
.pf-del-btn { color: #7BAFD4; }
.pf-edit-in {
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 4px;
  padding: 4px 6px; font: inherit; font-size: 14px; width: 100%; box-sizing: border-box;
}
.pf-edit-in.num { text-align: right; }
.pf-edit-tk { text-transform: uppercase; }
#pf-txns-table .pf-txn-edit td { background: rgba(255,255,255,0.02); }
/* Inline ledger editor: a single full-width labelled flex form (the display
   table is percent-only / 6 cols, but editing still needs shares + amount). */
.pf-txn-edit-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 8px 10px; padding: 4px 2px; }
.pf-txn-edit-form .pf-ef { display: flex; flex-direction: column; gap: 2px; font-size: 12px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.03em; }
.pf-txn-edit-form .pf-ef input, .pf-txn-edit-form .pf-ef select { width: 100px; }
.pf-txn-edit-form .pf-ef.pf-ef-grow { flex: 1 1 160px; }
.pf-txn-edit-form .pf-ef.pf-ef-grow input { width: 100%; }
.pf-txn-edit-form .pf-txn-actions { display: flex; gap: 10px; align-items: center; padding-bottom: 4px; }

/* Mobile cards hidden on desktop; shown under html.mobile-site. */
.pf-cards { display: none; }

/* Value-vs-SPY chart. */
.pf-chart-legend { display: flex; gap: 18px; flex-wrap: wrap; margin: 2px 0 6px; font-size: 14px; }
.pf-leg { display: inline-flex; align-items: center; gap: 6px; color: var(--muted); }
.pf-leg-dot { width: 12px; height: 3px; border-radius: 2px; display: inline-block; }
.pf-history-chart {
  width: 100%; min-height: 120px;
  border: 1px solid var(--border); border-radius: 6px;
  background: var(--panel); overflow: hidden;
}

/* Allocation donuts — two side by side. */
.pf-donuts { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.pf-donut-card {
  background: var(--panel); border: 1px solid var(--border); border-radius: 8px;
  padding: 12px 14px;
}
.pf-donut-title { font-size: 14.5px; font-weight: 600; margin-bottom: 8px; }
.pf-donut-body { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.pf-donut-svg-wrap { flex: 0 0 auto; }
.pf-donut-svg { display: block; }
.pf-donut-center { fill: var(--text); font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums; }
.pf-donut-center-sub { fill: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; }
.pf-donut-legend { flex: 1 1 140px; min-width: 120px; display: flex; flex-direction: column; gap: 3px; }
.pf-leg-row { display: flex; align-items: center; gap: 7px; font-size: 14px; }
.pf-leg-sw { width: 11px; height: 11px; border-radius: 2px; flex: 0 0 auto; }
.pf-leg-name { flex: 1 1 auto; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pf-leg-pct { color: var(--muted); font-variant-numeric: tabular-nums; }

/* ── 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: 14px;
}
.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: 13px; 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: 14px;
  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: 13px; font-variant-numeric: tabular-nums; }
.watchlists-main { min-width: 0; }
.wl-detail-empty { padding: 40px 12px; text-align: center; font-size: 14.5px; }
.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: 14px;
  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: 13px; }
#wl-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}
#wl-table th, #wl-table td {
  padding: 6px 10px;
  border-bottom: 1px solid var(--border);
  text-align: left;
}
#wl-table th {
  font-size: 13px; 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: 13px;
  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: 13px; 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: 13px; 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: 13px; 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: 13px; 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: 14px; 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: 14.5px; 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: 13px;
}
.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: 12px;
}
/* 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: 13px;
}
.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: 13px; 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: 13px; 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: 14px;
}
.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: 14px;
}
/* 📱 On a phone this becomes a FIXED, top-anchored, full-width sheet. The old
   absolute drop-under could open with most of its body below the fold, and the
   near-full-width popup swallowed every touch — so the page couldn't be
   scrolled to reach the rest of the list or the Done button (Wade, 2026-07-08).
   Fixed + fully on-screen + the grid scrolling INSIDE the sheet fixes that.
   !important beats the JS-set inline position/top/left. Top-anchored (not a
   bottom sheet) so the search box stays visible above the iOS keyboard; dvh
   shrinks the sheet when the keyboard opens (vh fallback for older Safari). */
html.mobile-site .quant-tax-pop {
  position: fixed !important;
  top: 10px !important; bottom: auto !important;
  left: 12px !important; right: 12px !important;
  width: calc(100vw - 24px) !important; max-width: 100% !important;
  max-height: calc(100vh - 20px) !important;
  max-height: calc(100dvh - 20px) !important;
}
.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: 14px; }
.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: 13px;
}
.quant-tax-actions {
  display: flex; align-items: center; gap: 12px;
  padding: 6px 12px; border-bottom: 1px solid var(--border);
  font-size: 13px;
}
.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: 13px; 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: 12px; min-width: 14px; }
.quant-factor-head { display: inline-flex; align-items: center; gap: 6px;
  font-size: 13px; color: var(--text); cursor: pointer; }
.quant-factor-head .muted { font-size: 12px; }
.quant-weight { display: inline-flex; align-items: center; gap: 4px;
  font-size: 13px; 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: 13px; }
/* 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: 13px; color: var(--muted); font-weight: 400; letter-spacing: .02em; }
.cvd-block-h {
  font-size: 13px; 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: 14.5px; 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: 14.5px; 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: 12px 18px; flex-wrap: wrap; margin: 6px 0 16px; }
#hm-meta { font-size: 16px; font-weight: 500; color: var(--text); opacity: .95; line-height: 1.5; }
/* Heat-map dropdowns + labels — roomier + readable (replaces the 60px quant inputs). */
.hm-ctl-label { font-size: 14.5px; font-weight: 600; color: var(--text); }
.hm-select { width: auto; min-width: 130px; padding: 7px 12px; background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 6px; font: inherit; font-size: 14.5px; font-weight: 600; cursor: pointer; }
.hm-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(186px, 1fr));
  grid-auto-rows: 124px;           /* every box the same height — roomy so names don't overrun */
  gap: 8px;
}
.hm-box {
  position: relative; cursor: pointer;
  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.selected { box-shadow: inset 0 0 0 2px var(--accent); }
/* Deep-Dive select checkbox, upper-right of each Traditional box. A styled span
   (not an <input>) so the delegated handler fully controls toggling. */
.hm-box-chk {
  position: absolute; top: 5px; right: 5px; width: 20px; height: 20px;
  border-radius: 4px; border: 2px solid rgba(255,255,255,0.65);
  background: rgba(0,0,0,0.35); cursor: pointer; z-index: 3;
  display: flex; align-items: center; justify-content: center;
  font-size: 14px; font-weight: 800; line-height: 1; color: #fff;
}
/* Invisible enlarged hit target so the box is easy to click without precise aim
   (biased toward the tile interior so it doesn't spill onto the neighbour). */
.hm-box-chk::before { content: ""; position: absolute; top: -6px; right: -6px; bottom: -10px; left: -10px; }
.hm-box-chk:hover { border-color: #fff; background: rgba(0,0,0,0.45); }
.hm-box-chk.checked { background: var(--accent); border-color: var(--accent); color: #0b0e14; }
.hm-box-chk.checked::after { content: "✓"; }
/* Traditional drill breadcrumb (in #hm-meta): All › Sector › Theme › … */
.hm-crumb { color: var(--accent); text-decoration: none; cursor: pointer; font-weight: 600; }
.hm-crumb:hover { text-decoration: underline; }
.hm-crumb-sep { opacity: 0.5; margin: 0 3px; }
.hm-box-name {
  font-size: 13px; line-height: 1.2; font-weight: 600; opacity: 0.92; padding-right: 24px;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
html.mobile-site .hm-box-name { padding-right: 28px; }   /* clear the larger 24px mobile checkbox */
.hm-box-sub { font-size: 13px; 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: 10px 13px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.55);
  font-size: 14.5px; min-width: 184px; max-width: 320px;
}
.hm-tip[hidden] { display: none; }
.hm-tip-name { font-weight: 700; font-size: 14.5px; margin-bottom: 3px; 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: 16px; justify-content: flex-start; font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; margin: 7px 0 2px; }
.hm-tip-spark-row .muted { font-size: 13px; font-weight: 600; margin-right: 3px; }
.hm-tip-ex { font-size: 14px; color: var(--muted); line-height: 1.35; margin-bottom: 2px; }
.hm-tip-foot { font-size: 13px; color: var(--muted); opacity: 0.85; margin-top: 3px; }

/* ── 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: 7px 16px; font-size: 14.5px; font-weight: 700; 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; }
/* Mobile keeps the toggle so the Traditional view (Group-by + drill +
   checkbox Deep Dive) is reachable; only the dense sector market-map is
   desktop-only, so hide just that option (and drop the now-leading border). */
html.mobile-site .hm-mode-toggle a[data-mode="sector"] { display: none; }
html.mobile-site .hm-mode-toggle a[data-mode="theme"] { border-left: none; }

/* ── 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: 13px; 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: 11px; 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; }
/* Per-tile "live quote" dot (H3) — sector map, 1-Day window only. Deliberately
   tiny + monochrome: it marks WHICH names the live colour is coming from
   without competing with the red/green the map is read by. */
.hm-treemap .hm-sm-live {
  position: absolute; top: 2px; right: 2px; width: 4px; height: 4px;
  border-radius: 50%; background: rgba(255,255,255,0.9); box-shadow: 0 0 2px rgba(0,0,0,0.6);
  pointer-events: none;
}
.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: 14.5px;
  cursor: pointer; min-width: 160px;
}
.quant-screen-select:hover { border-color: var(--accent); }

.chart-toolbar { display: flex; align-items: center; gap: 8px; margin: 4px 0 6px;
  font-size: 14.5px; flex-wrap: wrap; }
.chart-toolbar .muted { font-size: 13px; 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: 14px;
}
.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: 14px;
}
.chart-colors-row {
  display: flex; align-items: center; gap: 8px; margin: 4px 0;
}
.chart-colors-row label {
  flex: 1; color: var(--muted); font-size: 13px;
}
.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: 13px;
  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: 14.5px; 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);
  /* Centered, capped at the wide content width so it aligns with the snapshot /
     metrics / market-context columns and stays the main visual object. */
  max-width: min(78%, var(--profile-wide, 1120px));
  margin-left: auto;
  margin-right: auto;
}
/* Viewport-relative height, clamped up to 500px — the main visual object,
   bigger than the financial bar cards but not overpowering the page. */
#tv-chart { height: clamp(360px, calc((100vh - 210px) * 0.66), 500px); }
@media (max-width: 1100px) { #tv-chart { height: 440px; } }
#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: 14px; 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: #0433FF; }
#tv-chart-legend .lg-down  { color: #FFFB00; }
#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 #td-company .td-wiki { text-decoration: none; margin-left: 8px; vertical-align: baseline; }
#ticker-detail-view #td-company .td-wiki-mark {
  font-family: Georgia, "Linux Libertine", "Times New Roman", serif;
  font-size: 18px; font-weight: 400; line-height: 1; color: var(--muted);
}
#ticker-detail-view #td-company .td-wiki:hover .td-wiki-mark { color: var(--accent); }
/* ── Chart controls card (H4a) ───────────────────────────────────────────────
   The Range/TF/Style/Scale row + Indicators + Compare used to float in the page
   as three bare rows of inline text controls — the last "scattered text" spot
   on the profile. They now sit in a panel the same width as the chart, joined
   to its top edge, with each cluster a .tb-group separated by a hairline. */
#ticker-detail-view .td-chart-card {
  max-width: min(78%, var(--profile-wide, 1120px));
  margin: 10px auto 0;
  background: var(--panel);
  border: 1px solid var(--border);
  border-bottom: 0;
  border-radius: 8px 8px 0 0;
  padding: 8px 12px 7px;
}
/* Joined to the card above: square off the shared edge. */
#ticker-detail-view #tv-chart-wrap { border-radius: 0 0 8px 8px; margin-top: 0; }
#ticker-detail-view .tb-group {
  display: inline-flex; align-items: center; flex-wrap: wrap;
  padding-right: 12px; margin-right: 12px;
  border-right: 1px solid var(--border);
}
#ticker-detail-view .chart-toolbar > .tb-group:last-of-type { border-right: 0; margin-right: 0; padding-right: 0; }
/* K-Ratio is a readout, not a control — park it at the right end of the row. */
#ticker-detail-view .chart-toolbar > .td-chart-kratio { margin-left: auto; padding-left: 12px; }
#ticker-detail-view .chart-toolbar { margin: 2px 0; padding: 0; gap: 0; font-size: 14px; }
/* 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: 14px;
  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: 14px; 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: 14px; 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: 14.5px;
}
.returns-strip .rs-label { color: var(--muted); font-size: 13px; 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: 12px; color: var(--muted); font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.04em; }
.rs-cell .rs-v { font-size: 14.5px; font-weight: 600; font-variant-numeric: tabular-nums; }

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

.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); }
/* Preference switch living in the nav (Reading comfort, H4d) — reads as a nav
   item, not a form control. */
.nav-pref-toggle {
  appearance: none; background: none; border: 0; border-bottom: 2px solid transparent;
  color: var(--muted); padding: 6px 0; font: inherit; font-size: 15px; font-weight: 600;
  cursor: pointer; text-align: left; display: inline-flex; align-items: center; gap: 7px;
}
.nav-pref-toggle:hover { color: var(--text); }
.nav-pref-toggle.active { color: var(--text); border-bottom-color: var(--accent); }
.nav-pref-mark {
  font-family: Georgia, "Times New Roman", serif; font-size: 16px; line-height: 1;
  border: 1px solid var(--border); border-radius: 4px; padding: 1px 4px;
}
.nav-pref-toggle.active .nav-pref-mark { border-color: var(--accent); 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: 12px; 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;
}

/* Nav submenu groups (Portfolios / Random Stuff / Categorizations WIP) — a
   collapsible section header + indented child links, inside both the desktop
   "Menu ▾" dropdown and the mobile drawer (both vertical lists), so it's a
   click-to-expand group, not a hover flyout. Section-title headers get a subtle
   non-white tint (--nav-section) to read as headers; the indicator is a rotating
   arrowhead (▸ collapsed → ▾ expanded). */
.nav-group { display: flex; flex-direction: column; }
.nav-group-toggle {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  width: 100%; background: none; border: 0; cursor: pointer; text-align: left;
  color: var(--nav-section, #9fb0c9); font-family: inherit; font-size: 15px;
  font-weight: 600; letter-spacing: 0.02em;
}
.nav-group-toggle:hover { color: var(--text); }
.nav-group-toggle .caret { font-size: 13px; opacity: .85; transition: transform .15s ease; }
.nav-group.open > .nav-group-toggle .caret { transform: rotate(90deg); }
.nav-sub { display: none; flex-direction: column; }
.nav-group.open > .nav-sub { display: flex; }
/* Desktop "Menu ▾" dropdown context — keep the section tint (no white override) */
html:not(.mobile-site) .nav-group-toggle { padding: 9px 12px; border-radius: 6px; }
html:not(.mobile-site) .nav-group-toggle:hover { background: var(--panel-2); }
html:not(.mobile-site) .nav-group.has-active > .nav-group-toggle { color: var(--accent); }
html:not(.mobile-site) .nav-sub a { padding-left: 24px; }
/* Mobile drawer context */
html.mobile-site .nav-group-toggle { padding: 12px 18px; font-size: 15px; border-bottom: 1px solid var(--border); }
html.mobile-site .nav-group.has-active > .nav-group-toggle { color: var(--accent); }
html.mobile-site .nav-sub a { padding-left: 32px; background: rgba(255, 255, 255, 0.02); }

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

.expand-btn {
  background: none; border: 1px solid var(--border); border-radius: 3px;
  color: var(--muted); cursor: pointer; font-size: 11px; 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: 14px; 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: 13px; 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: 13px; 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: 14.5px;
}
.col-filter-pop .cf-title {
  font-size: 13px; 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"],
.col-filter-pop label input[type="checkbox"] { margin: 0; flex: 0 0 auto; }
.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: 14.5px;
  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: 14px; padding: 4px 10px; }
/* Categorical (Class / Pass / Data) popup: explicit multi-select → Apply. */
.col-filter-pop .cf-hint { font-size: 12.5px; margin: -6px 0 8px; }
.col-filter-pop .cf-actions .cf-apply { border-color: var(--accent); font-weight: 600; }

.monthly-filter-btn { font-size: 14px; 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(123, 175, 212, 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: 13px; 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: 13px; }

/* 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: 14px;
}
.selection-bar .btn { font-size: 14px; 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; }
/* Deep Dive button — drill from selected categories into their constituent
   stocks. Burnt-orange (#BF5700) per spec, white text. */
.selection-bar .sel-deepdive-btn {
  background: #BF5700; color: #fff; font-weight: 700; letter-spacing: 0.02em;
  border: 0; box-shadow: 0 0 0 1px rgba(191, 87, 0, 0.5);
}
.selection-bar .sel-deepdive-btn:hover { background: #d96a12; }
/* "Mini Profiles →" — Quant-Screen-only action on selected stocks. Violet so
   it reads as distinct from the yellow Charts and burnt-orange Deep Dive. */
.selection-bar .sel-miniprofiles-btn {
  background: #8957e5; color: #fff; font-weight: 700; letter-spacing: 0.02em;
  border: 0; box-shadow: 0 0 0 1px rgba(137, 87, 229, 0.5);
}
.selection-bar .sel-miniprofiles-btn:hover { background: #9d72ee; }

/* ── Mini Profiles page (#miniprofiles) — readability-first typography ─────
   Investor-research feel, not a compressed dashboard: larger/heavier body copy,
   stronger contrast, constrained line length. Scoped to #miniprofiles-view so
   the rest of the site stays byte-for-byte unchanged. */
#miniprofiles-view {
  -webkit-font-smoothing: auto;          /* never thin the text on macOS/Safari */
  -moz-osx-font-smoothing: auto;
  text-rendering: optimizeLegibility;
}
.miniprofiles-list { display: flex; flex-direction: column; gap: 0; }
/* Each company section gets real breathing room before its divider. */
.mp-entry { padding: 8px 0 28px; }
/* Wide chart on the left, returns list to its right. */
.mp-top { display: flex; flex-wrap: wrap; gap: 22px; align-items: flex-start; }
.mp-chart-col {
  flex: 1 1 560px; max-width: 740px;
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 8px; padding: 8px 10px 4px; overflow: hidden;
}
/* Vertical returns + K-Ratio readout to the right of the chart. */
.mp-returns {
  flex: 0 0 190px; min-width: 170px;
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 8px; padding: 10px 14px;
  font-variant-numeric: tabular-nums;
}
/* Ticker + company name in the chart head — legible, not tiny (id-scoped so
   they beat the shared .chart-card-sym / .chart-card-name base rules). */
#miniprofiles-view .mp-sym  { font-size: 14px; font-weight: 700; color: #f8fafc; }
#miniprofiles-view .mp-name { font-size: 14.5px; font-weight: 600; color: #aeb8c7; }
.mp-ret-title {
  font-size: 14px; font-weight: 700; color: #8d99aa;
  text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 6px;
}
.mp-ret-row { display: flex; justify-content: space-between; gap: 12px; padding: 4px 0; font-size: 14.5px; }
.mp-ret-lab { color: #aeb8c7; font-weight: 600; }
.mp-ret-val { font-size: 14.5px; font-weight: 700; }
.mp-ret-divider { border-top: 1px solid var(--border); margin: 7px 0; }
/* Company description → a real, readable profile-summary block (clean reading
   surface, not a loud card). 15px / 1.65 / 500-weight / high-contrast copy,
   line length capped at ~82ch so it reads like an article. */
.mp-writeup {
  max-width: 82ch; margin: 16px 0 0; padding: 16px 18px;
  border: 1px solid rgba(148, 163, 184, 0.18); border-radius: 12px;
  background: rgba(15, 23, 42, 0.38);
}
.mp-writeup p {
  margin: 0 0 14px; font-size: 15px; line-height: 1.65; font-weight: 500; color: #e6edf5;
}
.mp-writeup p:last-child { margin-bottom: 0; }
.mp-writeup ul { margin: 4px 0 14px; padding-left: 20px; }
.mp-writeup li { font-size: 15px; line-height: 1.6; font-weight: 500; color: #e6edf5; margin: 2px 0; }
/* Section subheads emitted by structuredCopyHtml() — same yellow-accent look as
   the profile page's, sized for this smaller reading block. */
.mp-writeup .profile-copy-subhead {
  margin: 16px 0 6px; font-size: 13px; font-weight: 800; letter-spacing: 0.08em;
  text-transform: uppercase; color: #FACC15;
}
.mp-writeup .profile-copy-subhead:first-child { margin-top: 0; }
/* Loading state only: dim the placeholder line until the copy arrives. */
.mp-writeup.muted, .mp-writeup.muted p { color: #8d99aa; }
/* Divider between consecutive stocks. */
.mp-sep { border: 0; border-top: 1px solid rgba(148, 163, 184, 0.18); margin: 0 0 28px; }
/* Phones: stack the returns under the chart; both full width; NEVER shrink the
   reading copy — keep the description at a comfortable 15px / 1.65. */
html.mobile-site .mp-chart-col { flex: 0 0 100%; max-width: 100%; }
html.mobile-site .mp-returns { flex: 1 1 100%; min-width: 0; }
html.mobile-site .mp-writeup { max-width: 100%; padding: 15px 16px; }
html.mobile-site .mp-writeup p { font-size: 15px; line-height: 1.65; }
/* Deep Dive active-indicator chip on #quant-desc, with an exit ✕. */
#quant-desc .quant-dd-chip {
  display: inline-flex; align-items: center; gap: 6px;
  background: rgba(191, 87, 0, 0.15); color: #BF5700; font-weight: 600;
  border: 1px solid rgba(191, 87, 0, 0.5); border-radius: 10px;
  padding: 1px 8px; margin-right: 6px;
}
#quant-desc .quant-dd-chip .quant-dd-exit {
  background: none; border: 0; color: #BF5700; cursor: pointer;
  font-size: 14.5px; line-height: 1; padding: 0 2px;
}
#quant-desc .quant-dd-chip .quant-dd-exit:hover { color: #d96a12; }
/* 📌 Pinned-universe chip + Pin button (a pre-screen of a pre-screen). */
#quant-desc .quant-pin-chip {
  display: inline-flex; align-items: center; gap: 6px;
  background: rgba(47, 125, 215, 0.16); color: #2F7DD7; font-weight: 600;
  border: 1px solid rgba(47, 125, 215, 0.55); border-radius: 10px;
  padding: 1px 8px; margin-right: 6px;
}
#quant-desc .quant-pin-chip .quant-pin-clear {
  background: none; border: 0; color: #2F7DD7; cursor: pointer;
  font-size: 14.5px; line-height: 1; padding: 0 2px;
}
#quant-desc .quant-pin-chip .quant-pin-clear:hover { color: #5a9fe6; }
.quant-pin-btn { white-space: nowrap; flex: 0 0 auto; }
.quant-pin-btn.pinned { border-color: #2F7DD7; color: #2F7DD7; }
.quant-pin-btn:disabled { opacity: 0.5; cursor: not-allowed; }
/* 🔗 Share-these-stocks — same bold yellow as the chart-action buttons. */
.quant-sharelist-btn {
  white-space: nowrap; flex: 0 0 auto;
  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);
}
.quant-sharelist-btn:hover { background: #fadb4b; }
.quant-sharelist-btn:disabled { opacity: 0.5; cursor: not-allowed; }
/* 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: 12px; 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: 12px; 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: 13px; margin: 0 0 14px; }
.dejavu-table { width: 100%; }
.dejavu-mini { margin-left: 6px; text-decoration: none; opacity: 0.65; font-size: 14px; }
.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: 14.5px; }
.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: 13px; 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: 12px; text-transform: uppercase; letter-spacing: 0.05em;
  font-weight: 600; margin-right: 4px;
}
.charts-toolbar .chip {
  font-size: 13px; padding: 2px 8px;
}
/* "Mini Profiles →" on the Charts toolbar — violet to match the Quant
   selection-bar action; dimmed + non-interactive when no stock is checked. */
.charts-toolbar .chip.charts-mp-btn {
  background: #8957e5; color: #fff; font-weight: 700; border: 0;
  box-shadow: 0 0 0 1px rgba(137, 87, 229, 0.5);
}
.charts-toolbar .chip.charts-mp-btn:hover { color: #fff; background: #9d72ee; }
.charts-toolbar .chip.charts-mp-btn[disabled] {
  background: transparent; color: var(--muted); font-weight: 600;
  box-shadow: 0 0 0 1px var(--border); cursor: default;
}
/* "Quant →" on the Charts toolbar — blue (CVD-safe, distinct from the violet
   Mini Profiles button) action that opens the screener filtered to these charts. */
.charts-toolbar .chip.charts-quant-btn {
  background: #2f6df6; color: #fff; font-weight: 700; border: 0;
  box-shadow: 0 0 0 1px rgba(47, 109, 246, 0.5);
}
.charts-toolbar .chip.charts-quant-btn:hover { color: #fff; background: #4d85ff; }
/* 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: 14px; 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: 14px;
  width: 130px; letter-spacing: 0.03em;
}
.charts-add-input:focus { border-color: var(--accent); outline: none; }
.charts-add-msg { font-size: 13px; margin-left: 4px; }

.chart-card-sym { font-weight: 700; color: #fff; font-size: 14.5px; flex: 0 0 auto; }
.chart-card-sym:hover { color: var(--accent); text-decoration: none; }
.chart-card-kratio { font-weight: 400; font-size: 13px; 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: 13px; font-weight: 400;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chart-card-change { font-variant-numeric: tabular-nums; font-size: 13px; font-weight: 700; flex: 0 0 auto; }
/* Range % change (e.g. "6M +20.5%") — secondary to today's move, so smaller. */
.chart-card-range { font-variant-numeric: tabular-nums; font-size: 12px; opacity: 0.92; 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: 13px;
}
.chart-card-actions .chart-card-pick,
.chart-card-actions .chart-card-anti { font-size: 13px; padding: 2px 8px; }
.chart-card-actions .chart-card-wl { padding: 2px 6px; font-size: 13px; max-width: 160px; }
.chart-card-msg { font-size: 13px; 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(--text); }
.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: 14px; 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: 13px; 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: 13px; 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: 14px; 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: 13px; 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: 13px; 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: 14px;
  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: 13px;
  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: 14px;
  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: 14.5px;
  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: 14.5px; }
.td-news-meta { font-size: 13px; }
/* 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;
}

/* ── Profile page readable long-text cards ───────────────────────────────────
   The company DESCRIPTION + classification narrative (primary business / why it
   fits / why not pure / curated summary) used to render as tiny 13px walls of
   text spanning the full page width. These cards constrain the line length,
   enlarge + brighten the copy, and break walls into paragraphs. Dark theme +
   colorblind-safe yellow/blue accents are preserved (NO red/green — the user has
   protanomaly); everything is scoped to #ticker-detail-view so other pages are
   untouched. */
#ticker-detail-view #td-description-wrap { margin: 22px 0 6px; }
/* Wide card, centered to align with the (centered) price chart + finviz grid —
   so it never strands as a small box on the left of a wide page — but the
   readable copy inside stays at a 72ch column so lines never run too long. */
#ticker-detail-view .profile-text-card {
  width: min(100%, 920px);
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 20px 24px;
  margin: 0 auto 16px;
}
#ticker-detail-view .profile-text-card:last-child { margin-bottom: 0; }
#ticker-detail-view .profile-text-label {
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: #FACC15;            /* colorblind-safe yellow accent */
  margin-bottom: 10px;
}
#ticker-detail-view .profile-readable-copy {
  max-width: 74ch;           /* stop the reader's eyes travelling full-width */
  font-size: 15px;
  line-height: 1.65;
  color: #D6DEE8;            /* soft off-white — not pure white, not dim gray */
  text-align: left;          /* long copy is never centered */
}
#ticker-detail-view .profile-readable-copy--dense { max-width: 72ch; }
#ticker-detail-view .profile-readable-copy p { margin: 0 0 14px; }
#ticker-detail-view .profile-readable-copy p:last-child { margin-bottom: 0; }
#ticker-detail-view .profile-readable-copy ul { margin: 8px 0 14px 20px; padding: 0; }
#ticker-detail-view .profile-readable-copy li { margin-bottom: 6px; line-height: 1.55; }
#ticker-detail-view .profile-copy-subhead {
  margin: 18px 0 6px;
  font-size: 14px; font-weight: 800; letter-spacing: 0.08em;
  text-transform: uppercase; color: #FACC15;
}
/* Collapsible long copy: clip to ~7 lines, subtle fade to the card bg, toggle. */
#ticker-detail-view .expandable-copy {
  position: relative;
  /* ~8.5 lines at 15px / 1.65. Was 11.4em (~7 lines), raised with H4c: a
     structured description spends ~2.5em of the clip on its first subhead, so
     the old height showed barely four lines of prose before the fade. */
  max-height: 13.6em;
  overflow: hidden;
}
#ticker-detail-view .expandable-copy.is-expanded { max-height: none; }
#ticker-detail-view .expandable-copy:not(.is-expanded)::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: 0; height: 3em;
  background: linear-gradient(to bottom, rgba(22, 27, 34, 0), var(--panel));
  pointer-events: none;
}
#ticker-detail-view .expand-copy-button {
  margin-top: 12px;
  appearance: none;
  border: 1px solid rgba(250, 204, 21, 0.38);
  background: rgba(250, 204, 21, 0.08);
  color: #FACC15;
  border-radius: 999px;
  padding: 7px 14px;
  font-size: 14px; font-weight: 700;
  cursor: pointer;
}
#ticker-detail-view .expand-copy-button:hover { background: rgba(250, 204, 21, 0.16); }

/* Shared width rhythm so every profile module lines up (item 12). */
#ticker-detail-view {
  --profile-wide: 1120px;            /* data-heavy modules: snapshot/metrics/chart/context/financials */
  --profile-readable-max: 960px;     /* section headers + peers/twinsies/news ancestor width */
  --profile-news-max: 860px;
  --profile-section-gap-sm: 16px; --profile-section-gap-md: 24px; --profile-section-gap-lg: 34px;
}

/* Consistent section header — uppercase title + a thin rule that fills the row,
   so DESCRIPTION / RECENT NEWS / CLASSIFICATION read as clear scannable bands. */
#ticker-detail-view .profile-section-header {
  display: flex; align-items: center; gap: 12px;
  width: min(100%, var(--profile-readable-max));
  margin: 30px auto 12px;
}
#ticker-detail-view .profile-section-header.profile-subsection-header { margin-top: 22px; }
#ticker-detail-view .profile-section-title {
  font-size: 13px; font-weight: 800; letter-spacing: 0.11em;
  text-transform: uppercase; color: #E2E8F0; white-space: nowrap; margin: 0;
}
#ticker-detail-view .profile-section-rule { height: 1px; flex: 1; background: rgba(148, 163, 184, 0.16); }

/* At-a-glance summary pills under the header — what the company IS, before the
   metrics wall. */
#ticker-detail-view .profile-summary-strip {
  display: flex; flex-wrap: wrap; gap: 8px;
  margin: 12px auto 16px; max-width: 1100px;
}
#ticker-detail-view .summary-pill {
  display: flex; flex-direction: column; gap: 3px;
  min-width: 150px; max-width: 360px; padding: 9px 12px;
  background: var(--panel); border: 1px solid var(--border); border-radius: 10px;
}
#ticker-detail-view .summary-label {
  font-size: 12px; font-weight: 800; letter-spacing: 0.08em;
  text-transform: uppercase; color: #94A3B8;
}
#ticker-detail-view .summary-value { font-size: 14.5px; font-weight: 650; line-height: 1.3; color: #E2E8F0; }
#ticker-detail-view .summary-value a { color: var(--accent); }
#ticker-detail-view .summary-value a:hover { text-decoration: underline; }

/* Key metrics row — the ~12 important numbers, always visible above the
   (collapsed) full grid. Returns keep the site's CVD palette (green-up /
   #7BAFD4-down), not red/green. */
/* Key-metrics wrap holds the grid + the collapsed full grid + the toggle, so
   the "Show all metrics" button aligns under the grid instead of stranding on
   the far left of the page. */
#ticker-detail-view .key-metrics-wrap { width: min(100%, var(--profile-wide)); margin: 0 auto 14px; }
#ticker-detail-view .overview-metrics-grid {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px; margin: 0; width: 100%;
}
#ticker-detail-view .key-metric-card {
  min-width: 0; padding: 8px 10px;
  background: rgba(15, 23, 42, 0.38); border: 1px solid rgba(148, 163, 184, 0.10); border-radius: 8px;
}
#ticker-detail-view .key-metric-card .metric-label {
  font-size: 12px; color: #94A3B8; margin-bottom: 3px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#ticker-detail-view .key-metric-card .metric-value {
  font-size: 14.5px; font-weight: 800; color: #E5E7EB;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-variant-numeric: tabular-nums;
}
#ticker-detail-view .key-metric-card .metric-value.ret-pos { color: var(--green); }
#ticker-detail-view .key-metric-card .metric-value.ret-neg { color: #7BAFD4; }
@media (max-width: 1100px) { #ticker-detail-view .overview-metrics-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* Full Finviz grid collapsed by default behind "Show all metrics" (desktop +
   mobile) — the key-metrics row already covers the at-a-glance read. */
#ticker-detail-view .td-finviz-grid.td-finviz-collapsible:not(.td-finviz-expanded) { display: none; }
#ticker-detail-view .td-finviz-grid { margin-top: 8px; }
/* Toggle sits inside .key-metrics-wrap, left-aligned under the grid. */
#ticker-detail-view .td-fv-expand {
  display: inline-block; margin: 8px 0 0; cursor: pointer;
  font-size: 14px; font-weight: 700; color: #FACC15;
  background: rgba(250, 204, 21, 0.08);
  border: 1px solid rgba(250, 204, 21, 0.38); border-radius: 999px; padding: 6px 14px;
}
#ticker-detail-view .td-fv-expand:hover { background: rgba(250, 204, 21, 0.16); }

/* Classification module (#td-fields): summary card → mini cards → details.
   Mini cards are 3-up only when short; renderTickerNotes adds --2 (2 columns)
   when any card text is long, so the copy isn't cramped. */
#ticker-detail-view #td-fields { margin: 0 auto; max-width: 1000px; }
#ticker-detail-view .classification-card-grid {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin-top: 12px;
}
#ticker-detail-view .classification-card-grid.classification-card-grid--2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
#ticker-detail-view .classification-mini-card {
  background: var(--panel); border: 1px solid var(--border); border-radius: 12px;
  padding: 16px 18px; min-height: 132px;
}
#ticker-detail-view .classification-mini-card .profile-text-label { margin-bottom: 8px; }
#ticker-detail-view .classification-mini-card .profile-readable-copy { font-size: 14.5px; line-height: 1.55; max-width: none; }
#ticker-detail-view .classification-mini-card .profile-readable-copy p { margin: 0 0 10px; }
#ticker-detail-view .classification-mini-card .profile-readable-copy p:last-child { margin-bottom: 0; }
#ticker-detail-view .profile-definition-grid {
  display: grid; grid-template-columns: 180px minmax(0, 1fr);
  gap: 10px 18px; align-items: start; max-width: 760px;
}
#ticker-detail-view .profile-definition-label { color: #94A3B8; font-size: 14px; font-weight: 600; }
#ticker-detail-view .profile-definition-value {
  color: #D6DEE8; font-size: 14px; line-height: 1.5; min-width: 0; overflow-wrap: anywhere;
}
#ticker-detail-view .profile-definition-value a { color: var(--accent); }
#ticker-detail-view .profile-definition-value a:hover { text-decoration: underline; }

/* News as compact cards (5 visible + "Show more news"). */
#ticker-detail-view #td-news { width: min(100%, var(--profile-news-max)); margin: 0 auto; }
#ticker-detail-view .news-list { display: grid; gap: 7px; }
#ticker-detail-view .news-item {
  display: block; padding: 9px 12px; text-decoration: none;
  background: var(--panel); border: 1px solid var(--border); border-radius: 8px;
}
#ticker-detail-view .news-item:hover { border-color: var(--accent); }
#ticker-detail-view .news-title { display: block; font-size: 14.5px; font-weight: 600; line-height: 1.35; color: var(--accent); }
#ticker-detail-view .news-meta { display: block; margin-top: 3px; font-size: 13.5px; color: #94A3B8; }
#ticker-detail-view .news-more-wrap { display: contents; }
#ticker-detail-view .news-more-wrap[data-collapsed="1"] { display: none; }
#ticker-detail-view .news-more-btn {
  margin-top: 10px; cursor: pointer;
  font-size: 14px; font-weight: 700; color: #FACC15;
  background: rgba(250, 204, 21, 0.08);
  border: 1px solid rgba(250, 204, 21, 0.38); border-radius: 999px; padding: 6px 14px;
}
#ticker-detail-view .news-more-btn:hover { background: rgba(250, 204, 21, 0.16); }

/* ── OVERVIEW PANEL — ONE unified top module (standard financial-research
   layout): a business-summary row on top, then a balanced two-column data row
   (Return Snapshot table | Key Metrics grid), then a footer with the "Show all
   metrics" toggle. No asymmetric rails, no empty boxes. Return palette: positive
   #FACC15 / negative #FB923C / neutral slate, ALWAYS signed (protanomaly-safe),
   distinct from the key-metrics green/#7BAFD4. */
#ticker-detail-view .overview-panel {
  width: min(100%, var(--profile-wide)); margin: 12px auto 12px; padding: 12px 14px;
  background: rgba(15, 23, 42, 0.78);
  border: 1px solid rgba(148, 163, 184, 0.14); border-radius: 12px;
}
#ticker-detail-view .overview-summary-row {
  padding-bottom: 10px; margin-bottom: 10px;
  border-bottom: 1px solid rgba(148, 163, 184, 0.12);
}
#ticker-detail-view .overview-summary-row[hidden] { display: none; }
#ticker-detail-view .overview-summary-copy {
  font-size: 14.5px; line-height: 1.42; color: #D6DEE8; margin-bottom: 8px;
}
#ticker-detail-view .overview-summary-tags { display: flex; flex-wrap: wrap; gap: 6px; }
#ticker-detail-view .overview-summary-tags span {
  display: inline-flex; align-items: center; padding: 4px 8px; border-radius: 999px;
  background: rgba(2, 6, 23, 0.28); border: 1px solid rgba(148, 163, 184, 0.12);
  font-size: 13px; color: #AAB4C2;
}
#ticker-detail-view .overview-summary-tags a { color: var(--accent); text-decoration: none; }
#ticker-detail-view .overview-summary-tags a:hover { text-decoration: underline; }

/* Balanced two-column data row: Return Snapshot (320px) | Key Metrics (1fr). */
#ticker-detail-view .overview-data-row {
  display: grid; grid-template-columns: 320px minmax(0, 1fr); gap: 14px; align-items: start;
}
@media (max-width: 900px) {
  #ticker-detail-view .overview-data-row { grid-template-columns: 1fr; }
}
#ticker-detail-view .overview-return-card,
#ticker-detail-view .overview-metrics-card {
  min-width: 0;
  background: rgba(2, 6, 23, 0.24);
  border: 1px solid rgba(148, 163, 184, 0.12); border-radius: 10px;
  padding: 10px 12px;
}
#ticker-detail-view .overview-return-card[hidden] { display: none; }
/* Both sub-cards are headed by the same yellow .card-label. */
#ticker-detail-view .overview-panel .card-label {
  font-size: 13px; font-weight: 850; letter-spacing: 0.1em;
  text-transform: uppercase; color: #FACC15; margin-bottom: 8px;
}
#ticker-detail-view .overview-footer { margin-top: 10px; }
#ticker-detail-view .overview-footer .td-fv-expand { margin: 0; }

#ticker-detail-view .return-table { width: 100%; border-collapse: collapse; }
#ticker-detail-view .return-table tr { border-bottom: 1px solid rgba(148, 163, 184, 0.16); }
#ticker-detail-view .return-table tr:last-child { border-bottom: none; }
#ticker-detail-view .return-table th {
  width: 62%; padding: 5px 0; text-align: left;
  font-size: 14.5px; font-weight: 600; color: #AAB4C2; line-height: 1.25;
}
#ticker-detail-view .return-table td {
  width: 38%; padding: 5px 0; text-align: right;
  font-size: 14.5px; font-weight: 850; line-height: 1.25; font-variant-numeric: tabular-nums;
}
#ticker-detail-view .return-table.return-table--compact th,
#ticker-detail-view .return-table.return-table--compact td { padding: 4px 0; font-size: 14.5px; }
#ticker-detail-view .return-table td.positive { color: #FACC15; }
#ticker-detail-view .return-table td.negative { color: #FB923C; }
#ticker-detail-view .return-table td.neutral  { color: #CBD5E1; }
#ticker-detail-view .return-table-subhead {
  margin: 10px 0 4px; font-size: 12px; font-weight: 800; letter-spacing: 0.08em;
  text-transform: uppercase; color: #94A3B8;
}
/* Performance strip below the chart — selected-range return vs SPY/subtheme. */
#ticker-detail-view .chart-performance-strip {
  width: min(100%, var(--profile-wide)); margin: 8px auto 10px;
  display: flex; flex-wrap: wrap; gap: 8px;
}
#ticker-detail-view .performance-item {
  display: inline-flex; align-items: center; gap: 6px; padding: 5px 10px;
  background: var(--panel); border: 1px solid var(--border); border-radius: 999px;
}
#ticker-detail-view .performance-item span { font-size: 12.5px; color: #94A3B8; }
#ticker-detail-view .performance-item strong { font-size: 14px; color: #FACC15; font-variant-numeric: tabular-nums; }
#ticker-detail-view .performance-item strong.positive { color: #FACC15; }
#ticker-detail-view .performance-item strong.negative { color: #FB923C; }
#ticker-detail-view .performance-item strong.neutral  { color: #CBD5E1; }
#ticker-detail-view .performance-item.perf-range-label { background: rgba(250, 204, 21, 0.10); border-color: rgba(250, 204, 21, 0.30); }
#ticker-detail-view .performance-item.perf-range-label strong { color: #FACC15; }

/* ── Market Context section (Signals · peers/twinsies · news) ─────────────── */
#ticker-detail-view .market-context-section { width: min(100%, var(--profile-wide)); margin: 30px auto 36px; }
#ticker-detail-view .market-context-section .profile-section-header { width: 100%; margin: 0 0 12px; }
#ticker-detail-view .market-context-grid {
  display: grid; grid-template-columns: 280px minmax(0, 1fr); gap: 14px; align-items: start;
}
/* When the Signals panel is empty, peers fill the row (no narrow orphan col). */
#ticker-detail-view .market-context-grid.mc-no-signals { grid-template-columns: minmax(0, 1fr); }
#ticker-detail-view .market-context-panel {
  background: var(--panel); border: 1px solid var(--border); border-radius: 12px; padding: 13px 15px; min-width: 0;
}
#ticker-detail-view .market-context-panel[hidden] { display: none; }
#ticker-detail-view .news-panel { grid-column: 1 / -1; }
#ticker-detail-view .market-context-panel-title {
  font-size: 12px; font-weight: 800; letter-spacing: 0.09em;
  text-transform: uppercase; color: #FACC15; margin-bottom: 10px;
}
/* SIGNALS panel rows (analyst consensus + K-Ratios) — compact label/value. */
#ticker-detail-view .signal-row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  padding: 5px 0; border-bottom: 1px solid rgba(148, 163, 184, 0.10); font-size: 14.5px;
}
#ticker-detail-view .signal-row:last-child { border-bottom: 0; }
#ticker-detail-view .signal-label { color: #94A3B8; font-size: 13px; }
#ticker-detail-view .signal-value { color: #FACC15; font-weight: 750; font-variant-numeric: tabular-nums; }
#ticker-detail-view .signal-value .ret-pos { color: var(--green); }
#ticker-detail-view .signal-value .ret-neg { color: #7BAFD4; }
/* Inside the panels, drop the per-block margins the strips/news add on their own. */
#ticker-detail-view .peers-panel #td-peers,
#ticker-detail-view .peers-panel #td-twinsies,
#ticker-detail-view .news-panel #td-news { width: auto; margin: 0; }
#ticker-detail-view .peers-panel #td-twinsies { margin-top: 12px; }

/* Financial History header subtitle (item 7). */
#ticker-detail-view #td-financials-header { width: min(100%, var(--profile-wide)); }
#ticker-detail-view .profile-section-subtitle {
  margin-top: 3px; font-size: 14px; color: #94A3B8;
  letter-spacing: 0; text-transform: none; font-weight: 500;
}

/* Collapsible classification details (item 9). */
#ticker-detail-view .classification-details-toggle {
  margin: 16px 0 0; cursor: pointer;
  font-size: 14px; font-weight: 700; color: #FACC15;
  background: rgba(250, 204, 21, 0.08);
  border: 1px solid rgba(250, 204, 21, 0.38); border-radius: 999px; padding: 6px 14px;
}
#ticker-detail-view .classification-details-toggle:hover { background: rgba(250, 204, 21, 0.16); }
#ticker-detail-view .classification-details-wrap { margin-top: 14px; }
#ticker-detail-view .classification-details-wrap[data-collapsed="1"] { display: none; }
@media (max-width: 900px) {
  #ticker-detail-view .market-context-grid { grid-template-columns: 1fr; }
  #ticker-detail-view .news-panel { grid-column: auto; }
}

/* Mobile replica (mob.* / ?mobile=1) — full-width cards, 16px copy, stacked
   metadata. Scoped to html.mobile-site so desktop stays byte-for-byte. */
html.mobile-site #ticker-detail-view .profile-text-card {
  padding: 18px 16px;
  border-radius: 12px;
  width: 100%;
}
html.mobile-site #ticker-detail-view .profile-readable-copy,
html.mobile-site #ticker-detail-view .profile-readable-copy--dense {
  max-width: none;
  font-size: 16px;
  line-height: 1.65;
}
html.mobile-site #ticker-detail-view .expandable-copy { max-height: 13em; }
html.mobile-site #ticker-detail-view #td-fields { max-width: none; }
html.mobile-site #ticker-detail-view .profile-definition-grid {
  grid-template-columns: 1fr;
  gap: 4px;
  max-width: none;
}
html.mobile-site #ticker-detail-view .profile-definition-label { margin-top: 14px; }
html.mobile-site #ticker-detail-view .profile-definition-label:first-child { margin-top: 0; }

/* Mobile replica — new profile modules go full-width / fewer columns. */
html.mobile-site #ticker-detail-view .overview-metrics-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: none; }
html.mobile-site #ticker-detail-view .classification-card-grid { grid-template-columns: 1fr; }
html.mobile-site #ticker-detail-view .profile-section-header { width: 100%; margin-top: 24px; }
html.mobile-site #ticker-detail-view .profile-summary-strip { max-width: none; }
html.mobile-site #ticker-detail-view #td-news,
html.mobile-site #ticker-detail-view #td-peers,
html.mobile-site #ticker-detail-view #td-twinsies { width: 100%; }

/* Narrow desktop windows — stack the 3-up classification cards. */
@media (max-width: 860px) {
  #ticker-detail-view .classification-card-grid { grid-template-columns: 1fr; }
}

#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: 13px;
  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; }
/* Center the peers / twinsies blocks + cap their width so the chip strip wraps
   cleanly instead of running edge-to-edge across a wide page. */
#ticker-detail-view #td-peers,
#ticker-detail-view #td-twinsies { width: min(100%, var(--profile-readable-max)); margin: 18px auto 0; }
#ticker-detail-view .td-peers-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: 14px;
  margin: 0 0 8px;
}
#ticker-detail-view .td-peers-title {
  font-weight: 700;
  font-size: 14.5px;
  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: 7px;
  padding: 2px 0 6px;
}
#ticker-detail-view .td-peer-card {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 28px;
  padding: 5px 12px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--panel);
  font-size: 13.5px;
  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; }
/* Two-line header: title on line 1, subtitle (fiscal years · CAGR) on line 2 —
   easier to read than one compressed line. */
#ticker-detail-view .td-rev-head {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: 14px;
  margin: 0 0 6px;
}
#ticker-detail-view .td-rev-title {
  font-weight: 850;
  font-size: 14px;
  color: #E5E7EB;
  line-height: 1.15;
  letter-spacing: 0.01em;
}
#ticker-detail-view .td-rev-head .muted {
  font-size: 12.5px;
  font-weight: 600;
  color: #AAB4C2;
  line-height: 1.15;
}
#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: #0433FF; opacity: 0.80; }
#ticker-detail-view .td-rev-bar.td-rev-down { fill: #FFFB00;       opacity: 0.85; }
#ticker-detail-view .td-rev-bar-label {
  fill: #E5E7EB;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}
#ticker-detail-view .td-rev-bar-year {
  fill: #9CA3AF;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}
#ticker-detail-view .td-rev-yoy {
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}
#ticker-detail-view .td-rev-yoy-up   { fill: #FACC15; }
#ticker-detail-view .td-rev-yoy-down { fill: #FB923C; }

/* ── 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: #0433FF; opacity: 0.80; }
#ticker-detail-view .td-gm-bar.td-gm-down { fill: #FFFB00;       opacity: 0.85; }
#ticker-detail-view .td-gm-bar-label {
  fill: #E5E7EB;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}
#ticker-detail-view .td-gm-bar-year {
  fill: #9CA3AF;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}
#ticker-detail-view .td-gm-yoy {
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  letter-spacing: 0.01em;
}
#ticker-detail-view .td-gm-yoy-up   { fill: #FACC15; }
#ticker-detail-view .td-gm-yoy-down { fill: #FB923C; }

/* ── 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: #0433FF; opacity: 0.80; }
#ticker-detail-view .td-sh-bar.td-sh-down { fill: #FFFB00;       opacity: 0.85; }
#ticker-detail-view .td-sh-yoy {
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  letter-spacing: 0.01em;
}
#ticker-detail-view .td-sh-yoy-up   { fill: #FACC15; }
#ticker-detail-view .td-sh-yoy-down { fill: #FB923C; }
/* Header net-change + in-chart change labels: yellow #FACC15 for positive,
   orange #FB923C for negative (NOT blue-on-dark, which was hard to read). */
#ticker-detail-view #td-annual-charts .ret-pos { color: #FACC15; }
#ticker-detail-view #td-annual-charts .ret-neg { color: #FB923C; }

/* ── 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). */
/* Financial-history bar charts — SECONDARY supporting modules, NOT giant
   dashboard panels. A centered, width-capped 2-column grid; each chart in a
   compact card with a height-capped plot so the main price chart stays the
   dominant visual. (The SVGs use viewBox 380x210 + preserveAspectRatio meet and
   otherwise scaled with width — ~500px tall on a wide monitor.) */
/* 2-column grid by DEFAULT so each chart is ~540px wide — enough room for 8
   fiscal years of bars + value labels (3-col made them too narrow / collide).
   1 column on phones; 3 columns only on an ultra-wide (≥1700px) monitor. */
#ticker-detail-view #td-annual-charts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  align-items: start;
  margin: 14px auto 18px;
  width: min(100%, var(--profile-wide));
}
@media (max-width: 760px) {
  #ticker-detail-view #td-annual-charts { grid-template-columns: 1fr; }
}
#ticker-detail-view #td-annual-charts > div {
  min-width: 0; margin: 0;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 12px 14px;
}
#ticker-detail-view #td-annual-charts > div:empty { display: none; }
/* ── Chart / Table / Both (H4b) ──────────────────────────────────────────────
   Each annual card renders BOTH an svg and a table; the view class on the
   container picks which are shown. Default (and the class-less state, e.g. a
   card rendered before the toggle is wired) is chart-only — exactly how the
   section has always looked. */
#ticker-detail-view #td-annual-charts .td-annual-table { display: none; }
#ticker-detail-view #td-annual-charts.fin-view-table .td-rev-svg { display: none; }
#ticker-detail-view #td-annual-charts.fin-view-table .td-annual-table,
#ticker-detail-view #td-annual-charts.fin-view-both  .td-annual-table { display: table; }
#ticker-detail-view .td-annual-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 10px;
  font-size: 13.5px;
  font-variant-numeric: tabular-nums;
  /* Sits INSIDE an annual card, so drop the global table chrome (panel fill,
     border, radius) — otherwise it reads as a box inside a box. */
  background: transparent; border: 0; border-radius: 0;
}
#ticker-detail-view .td-annual-table th { background: transparent; }
#ticker-detail-view #td-annual-charts.fin-view-table .td-annual-table { margin-top: 4px; }
#ticker-detail-view .td-annual-table th,
#ticker-detail-view .td-annual-table td {
  padding: 5px 8px;
  text-align: right;
  border-bottom: 1px solid rgba(148, 163, 184, 0.14);
}
#ticker-detail-view .td-annual-table thead th {
  color: #9CA3AF; font-size: 12px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.05em;
  border-bottom-color: rgba(148, 163, 184, 0.28);
}
#ticker-detail-view .td-annual-table th:first-child,
#ticker-detail-view .td-annual-table tbody th { text-align: left; }
#ticker-detail-view .td-annual-table tbody th { color: #9CA3AF; font-weight: 600; }
#ticker-detail-view .td-annual-table tbody td { color: #E5E7EB; font-weight: 600; }
#ticker-detail-view .td-annual-table tbody tr:last-child th,
#ticker-detail-view .td-annual-table tbody tr:last-child td { border-bottom: 0; }
#ticker-detail-view .td-annual-table .td-annual-flat { color: #9CA3AF; font-weight: 500; }
/* Chart/Table/Both toggle in the section header. */
#ticker-detail-view .td-fin-view { display: inline-flex; align-items: center; gap: 2px; flex: 0 0 auto; }
#ticker-detail-view .td-fin-view .chip {
  background: transparent; border: 0; border-radius: 0;
  padding: 2px 8px; color: var(--muted); font-size: 13px; cursor: pointer;
}
#ticker-detail-view .td-fin-view .chip:hover { color: var(--text); }
#ticker-detail-view .td-fin-view .chip.active { color: var(--accent); font-weight: 700; }
/* ~200px plot → each card lands ~255px tall (well under the main price chart).
   The charts are WIDE (2-col within the 1120px content cap ≈ 552px each), which
   is what gives the labels room. max-height clamps the aspect-driven SVG; on
   narrower cards the natural aspect height is smaller, so it never letterboxes. */
#ticker-detail-view #td-annual-charts .td-rev-svg {
  display: block;
  width: 100%;
  height: auto;
  max-height: 208px;
}
/* In-SVG label sizing (viewBox units). Now that label DENSITY is thinned in JS
   (first/last/min/max on the 8-bar charts), each value label has room to be
   BIGGER. A subtle dark text-halo (paint-order: stroke, below) lets every label
   read cleanly over the bars + dark background. Text is off-white, never blue. */
#ticker-detail-view #td-annual-charts .td-rev-bar-label,
#ticker-detail-view #td-annual-charts .td-gm-bar-label { font-size: 14.5px; }
#ticker-detail-view #td-annual-charts .td-rev-bar-year,
#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: 14px; }
#ticker-detail-view #td-annual-charts text {
  paint-order: stroke;
  stroke: #080D14;
  stroke-width: 0.8px;
  stroke-linejoin: round;
}
/* Mobile replica: stack the three vertically rather than cram them across. */
html.mobile-site #ticker-detail-view #td-annual-charts { grid-template-columns: 1fr; width: 100%; margin: 14px 0 18px; }
/* The overview panel + below-panel modules go full-width / single-column on the
   mobile replica (the data row stacks Return Snapshot over Key Metrics). */
html.mobile-site #ticker-detail-view .overview-panel,
html.mobile-site #ticker-detail-view .market-context-section,
html.mobile-site #ticker-detail-view .chart-performance-strip,
html.mobile-site #ticker-detail-view #td-financials-header { width: 100%; }
html.mobile-site #ticker-detail-view .market-context-grid,
html.mobile-site #ticker-detail-view .overview-data-row { grid-template-columns: 1fr; }
html.mobile-site #ticker-detail-view .news-panel { grid-column: auto; }

/* ──────────────────────────────────────────────────────────────────────
   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; }
/* Peers + Twinsies strip: horizontal-scroll on mobile (not multi-row wrap). The
   desktop base rule sets flex-wrap:wrap via an ID selector, so this override must
   also use the ID to win specificity — this activates the pan-x scroll above. */
html.mobile-site #ticker-detail-view .td-peers-strip { flex-wrap: nowrap; overflow-x: auto; }

/* 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: 13px;
  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: 14.5px;
  flex-wrap: wrap;
}
html.mobile-site .breadcrumb-bar .back { font-size: 14px; padding: 4px 0; }
html.mobile-site .breadcrumb {
  font-size: 14px;
  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: 14.5px;
  padding: 12px;
}
html.mobile-site .col-filter-pop label {
  padding: 8px 0;
  font-size: 14.5px;
}
html.mobile-site .col-filter-pop .cf-num {
  font-size: 16px;   /* >=16px so iOS doesn't focus-zoom (matches the file's anti-zoom rule) */
  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: 14px;
  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 #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: 14.5px;
}

/* 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: 14px;
}
.recent-tickers-title {
  font-weight: 700;
  font-size: 14.5px;
  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: 14px;
  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: 14px;
  padding: 8px 12px;
  min-height: 36px;
}

/* Stocks / 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 #quant-table { font-size: 13.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: 14px;
}
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: 14.5px;
  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; display: flex; flex-direction: column; overflow: visible; }
html.mobile-site #tv-chart { height: 340px !important; }
html.mobile-site .chart-card-canvas { height: 180px !important; }
/* Profile chart legend: on mobile the absolute overlay sat ON TOP of the price
   line and made the chart unreadable. Lift it out of the overlay and render it
   as a tidy header bar ABOVE the chart instead, so it never covers the data. */
html.mobile-site #tv-chart-legend {
  position: static; order: -1; max-width: none; width: auto;
  white-space: normal; line-height: 1.45; font-size: 13px;
  background: var(--panel); border: none; border-bottom: 1px solid var(--border);
  border-radius: 0; padding: 6px 10px;
}
html.mobile-site #tv-chart-legend:empty { display: none; }

/* 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: 14.5px;
}
/* Chart controls card (H4a) on phones: full width, tighter, and the group
   separators become bottom rules — a vertical hairline between clusters that
   have each wrapped onto their own line just reads as noise. */
html.mobile-site #ticker-detail-view .td-chart-card {
  max-width: 100%;
  margin: 6px 0 0;
  padding: 6px 10px 8px;
}
html.mobile-site #ticker-detail-view .tb-group {
  padding: 0 0 4px; margin: 0 0 4px;
  border-right: 0; border-bottom: 1px solid var(--border);
  width: 100%; gap: 4px 6px;
}
html.mobile-site #ticker-detail-view .chart-toolbar > .tb-group:last-of-type { border-bottom: 0; margin-bottom: 0; padding-bottom: 0; }
html.mobile-site #ticker-detail-view .chart-toolbar > .td-chart-kratio { margin-left: 0; padding-left: 0; }
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: 14px;
}
html.mobile-site #compare-input {
  width: 110px;
  min-height: 32px;
  font-size: 14.5px;
}
html.mobile-site #compare-peers .compare-peer {
  font-size: 14px;
  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: 14px;
}

/* 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: 13px;
  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: 14.5px;
  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: 14.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 results table scrolls inside its own wrapper so the filter panel
   above stays put instead of sliding off-screen with it. DESKTOP TOO (Wade,
   2026-07-11): the Ⓐ Anthropic stage adds 21 columns (~3,500px total) and the
   old section-level scroll put the only horizontal scrollbar at the very
   bottom of the page — the right-hand columns were effectively unreachable.
   Now the table pans in place (drag / shift+wheel / trackpad), with an
   always-visible thin scrollbar as the cue. */
.quant-table-wrap {
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  max-width: 100%;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}
.quant-table-wrap::-webkit-scrollbar { height: 8px; }
.quant-table-wrap::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; }

/* ── 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: 14px; 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; flex-wrap: wrap; }
.qc-sortbar label { font-size: 14px; color: var(--muted); white-space: nowrap; }
.qc-select-all {
  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: 14.5px; font-weight: 600; white-space: nowrap;
}
.qc-select-all.active { background: rgba(46,204,113,0.16); border-color: rgba(46,204,113,0.5); color: #2ecc71; }
.qc-select-all:active { background: var(--panel-2); }
.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: 14.5px; 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: 13.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: 11.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: 11.5px; text-transform: uppercase; letter-spacing: 0.03em; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.qc-stat-val { font-size: 14.5px; font-variant-numeric: tabular-nums; }
.qc-expand { background: none; border: none; color: var(--accent); font-size: 14.5px; 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: 14px; }
/* 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: 14px; }
/* 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: 14px;
  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: 14.5px; }
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; }
/* The wide 520-unit viewBox renders smaller on a narrow phone, so bump the
   in-SVG label fonts (viewBox units) to keep them ~10px rendered. */
html.mobile-site #ticker-detail-view #td-annual-charts .td-rev-bar-label,
html.mobile-site #ticker-detail-view #td-annual-charts .td-gm-bar-label { font-size: 15px; font-weight: 700; }
html.mobile-site #ticker-detail-view #td-annual-charts .td-rev-bar-year,
html.mobile-site #ticker-detail-view #td-annual-charts .td-gm-bar-year,
html.mobile-site #ticker-detail-view #td-annual-charts .td-rev-yoy { font-size: 14px; }

/* 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: 13px; padding: 5px 8px; }
html.mobile-site .graph-layer-row { font-size: 12px; }
html.mobile-site .graph-tooltip { font-size: 14px; max-width: 260px; }
html.mobile-site .graph-panel  { width: 95vw; padding: 12px; font-size: 14.5px; }

/* 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: 14.5px;
}
/* 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: 13px; 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: 14.5px;
}
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: 13px; 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: 13px;
}
.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: 14px;
  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: 13px;
  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: 14.5px;
  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: 14.5px; }
html.mobile-site .tax-name { white-space: normal; word-break: break-word; }
html.mobile-site .tax-meta { font-size: 12px; 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: 14.5px;
  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 {
  content: "No tickers match the current filters. Loosen a Top % or clear a filter to see more.";
  display: block;
  color: var(--muted);
  font-size: 14px;
  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. */

/* ── 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: 12px; 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: 13px; 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: 13px;
  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: 12px; 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: 13px; }
.ret-good { color: #3fb950; }
.ret-mid  { color: #f1c40f; }
.ret-bad  { color: #7BAFD4; }   /* colorblind down/alert (was red #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: 14px; 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: 13px; 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: 14px; color: var(--accent); padding: 4px 0;
  user-select: none;
}
.ret-table-wrap { overflow-x: auto; margin-top: 8px; }
#ret-table { font-size: 13px; }
#ret-table th { font-size: 12px; }
#ret-table tr.ret-row-retired td { background: rgba(99, 179, 237, 0.04); }

/* Planned expenses is a NORMAL grid cell (2026-07-19, Wade: "same width
   as IN RETIREMENT") — the old full-row 808px band matching Accounts is
   gone; .ret-card-wide keeps no special sizing. The expense rows below
   wrap to fit the narrow card. */

/* 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: 12px; 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: 13px;
  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: 12px; color: var(--muted); margin-top: 2px;
}
.ret-toggle { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }
.ret-toggle input { width: auto; }
/* Each expense wraps inside the normal-width card: name input on its own
   line, then the age / years / amount / × cluster flowing beneath. */
.ret-expense-row {
  display: flex; flex-wrap: wrap;
  align-items: center; gap: 4px 6px; margin: 4px 0 8px;
}
.ret-expense-row label {
  display: inline-flex; align-items: center; gap: 4px;
  grid-template-columns: none; font-size: 13px;
}
.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: 14px;
}
.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: 14px;
  font-variant-numeric: tabular-nums;
}
.ret-expense-row .ret-exp-label { flex: 1 1 100%; }
.ret-expense-row .ret-exp-amt { width: 96px; }
.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(--text); }

/* ── Retirement cross-site links ────────────────────────────────────── */
.ret-site-link {
  font-size: 14px; 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; }

/* ── Retirement quick calculator (compound growth) ──────────────────── */
/* Section headings splitting the page into Quick calculator / Full planner */
.ret-section-head {
  margin: 16px 0 8px; font-size: 15px; color: var(--text);
  text-transform: uppercase; letter-spacing: 0.05em;
}
/* Inputs live in one wrapping row (desktop) — labels get inline sizing
   instead of the planner card's stacked 1fr/96px grid. */
.retc-card { max-width: 1192px; margin-bottom: 10px; }
.retc-inputs { display: flex; flex-wrap: wrap; gap: 8px 18px; align-items: center; padding: 4px 0 2px; }
.retc-inputs label {
  display: flex; align-items: center; gap: 6px;
  font-size: 13px; color: var(--muted); white-space: nowrap;
}
.retc-inputs input { width: 110px; }
.retc-inputs #retc-years, .retc-inputs #retc-return { width: 72px; }
.retc-inputs #retc-freq { width: auto; }
/* Desktop: the amount+frequency wrapper dissolves — its two labels stay
   direct flex items of .retc-inputs, so the one-row layout is unchanged. */
.retc-regular { display: contents; }
#retc-reset { padding: 3px 10px; font-size: 13px; }
.retc-results, .retc-chart-card { max-width: 1192px; }
.retc-chart-card { margin-bottom: 4px; }
#retc-table { font-size: 13px; }
#retc-table th { font-size: 12px; }
/* Mobile: each input on its own row, value boxes right-aligned (mirrors
   the planner cards). Input font sizes come from the .ret-card rules
   (16px = no iOS focus-zoom); the extra padding here gives ~40px touch
   targets. */
html.mobile-site .ret-section-head { font-size: 13.5px; margin: 14px 0 6px; }
html.mobile-site .retc-card { padding: 6px 10px 10px; }
html.mobile-site .retc-inputs { gap: 8px; }
html.mobile-site .retc-inputs label {
  width: 100%; justify-content: space-between; white-space: normal;
}
html.mobile-site .retc-inputs input { width: 110px; flex: 0 0 auto; }
/* Extra class in the selector out-specifies the later shared
   `html.mobile-site .ret-card input` (5px 8px) rule. */
html.mobile-site .retc-card .retc-inputs input,
html.mobile-site .retc-card .retc-inputs select { padding: 8px 10px; }
/* Amount + frequency fuse into ONE row — "Regular investment [500] / [Month]".
   The word "every" hides; a slash stands in. min-width:0 lets the label text
   wrap instead of overflowing on the narrowest phones. */
html.mobile-site .retc-regular { display: flex; width: 100%; align-items: center; gap: 8px; }
html.mobile-site .retc-regular > label:first-child { flex: 1 1 auto; width: auto; min-width: 0; }
html.mobile-site .retc-regular .retc-every { flex: 0 0 auto; width: auto; gap: 6px; }
html.mobile-site .retc-every-word { display: none; }
html.mobile-site .retc-every::before { content: "/"; color: var(--muted); }
html.mobile-site #retc-reset {
  margin-left: auto; min-height: 40px; padding: 8px 16px; font-size: 14.5px;
}
/* Stat tiles: uniform 2×2 (a wrapping label can't stagger row heights any
   more) and the headline numbers a notch up from the planner's shared 18px. */
html.mobile-site .retc-results { grid-auto-rows: 1fr; gap: 6px; margin-bottom: 10px; }
html.mobile-site .retc-results .ret-stat { padding: 8px 11px; }
html.mobile-site .retc-results .ret-stat-label { font-size: 11px; }
html.mobile-site .retc-results .ret-stat-value { font-size: 21px; }
html.mobile-site .retc-results .ret-stat-sub { font-size: 12px; }
html.mobile-site .retc-chart-card { padding: 8px 9px; }
/* Year-by-year table: the per-year Invested/Growth columns hide (a constant
   deposit repeated 30× is noise on a phone — cumulative + balance tell the
   story), the "(yr N)" tag hides, and Year pins left (site rail pattern)
   for the SE-width phones where the remaining 4 columns still overflow. */
html.mobile-site #retc-table th:nth-child(2), html.mobile-site #retc-table td:nth-child(2),
html.mobile-site #retc-table th:nth-child(3), html.mobile-site #retc-table td:nth-child(3) { display: none; }
html.mobile-site #retc-table .retc-yrn { display: none; }
html.mobile-site #retc-table tbody td:nth-child(1),
html.mobile-site #retc-table thead th:nth-child(1) { position: sticky; left: 0; background: var(--bg); z-index: 1; box-shadow: 4px 0 6px -4px rgba(0,0,0,.6); }
html.mobile-site #retc-table thead th:nth-child(1) { background: var(--panel); z-index: 3; }
html.mobile-site #retc-table td, html.mobile-site #retc-table th { padding: 4px 6px; }

/* 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: 14.5px; 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; }

/* 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: 14.5px; padding: 5px 6px;
}

/* ── Saves UI ──────────────────────────────────────────────────────────── */
.ret-saves { margin-top: 10px; border-top: 1px solid var(--border); padding-top: 8px; }
.ret-saves-label { font-size: 12px; 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: 13px; }
.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: 13px; }
.ret-delete-save-btn { padding: 3px 7px; font-size: 13px; }

/* ── 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: 13px; 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: 12px; 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: 13px;
  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: 14px; 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: 14px; 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: 13px; 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: 12px; }
.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: 14.5px; font-weight: 600; flex: 1; }
.dc-order-blurb { font-size: 13px; margin: 0 0 12px; line-height: 1.4; }

.dc-group { margin-bottom: 14px; }
.dc-group-head {
  font-size: 13px; 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: 12.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: 14px; 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: 13px;
  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: 12px; }

/* 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: 13px; 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: 14.5px; font-weight: 600; }
.dc-parallel-blurb { font-size: 13px; 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: 13px; 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: 13px; 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: 13px; 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: 13px; 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: 14px; 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: 14px; margin: 0; }
.mcap-filter { display: flex; align-items: center; gap: 8px; margin-top: 10px; }
.mcap-filter label { font-size: 14px; 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: 14.5px;
  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: 14.5px;
}
.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: 14px; }
.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, .mcap-table tbody tr:hover td { background: transparent; }   /* no row/cell hover-tint — must target td to beat the global `tr:hover td` rule (per request) */
.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: #2f9e44; }   /* green up (was blue) — palette */
.mcap-table .mcap-down { color: #7BAFD4; }   /* blue down (was amber) — palette */
.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%;
  border-collapse: collapse;
  font-size: 14px;
}
.mcap-table thead th {
  text-align: left;
  font-weight: 600;
  font-size: 13px;
  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, .mcap-table tbody tr:hover td { background: transparent; }   /* no row/cell hover-tint — must target td to beat the global `tr:hover td` rule (per request) */
/* Company name + logo link to the profile, with NO hover color change. */
.mcap-name-link { color: inherit; text-decoration: none; cursor: pointer; display: inline-block; }
.mcap-name-link:hover, .mcap-name-link:hover .mcap-name-text, .mcap-name-link:hover .mcap-ticker { color: inherit; }
/* Flag + country name are a click target (isolate that country). */
.mcap-country-click { cursor: pointer; display: inline-flex; align-items: center; }
.mcap-country-click:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
.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 = green, down = #7BAFD4 blue (site colorblind palette), reinforced by ▲/▼. */
.mcap-up   { color: var(--green, #2f9e44); }
.mcap-down { color: #7BAFD4; }
.mcap-flat { color: var(--muted, #8b949e); }
.mcap-move {
  font-size: 13px;
  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; }

/* ── Market Cap screener: toolbar, sortable headers, ▾ filter popover ── */
.mcap-toolbar { display: flex; align-items: center; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.mcap-toolbar label { font-size: 14px; color: var(--muted, #8b949e); white-space: nowrap; }
.mcap-search {
  padding: 6px 10px; font-size: 14.5px; min-width: 230px;
  border: 1px solid var(--border, #30363d); border-radius: 7px;
  background: var(--panel, #161b22); color: var(--text, #e6edf3);
}
.mcap-search:focus { outline: none; border-color: var(--accent, #58a6ff); }
.mcap-table-wrap { overflow-x: auto; }
.mcap-th { white-space: nowrap; }
.mcap-th.mcap-sortable { cursor: pointer; user-select: none; }
.mcap-th.mcap-sortable:hover .mcap-th-lbl { color: #0969da; }
.mcap-fbtn {
  margin-left: 5px; padding: 0 4px; font-size: 13px; line-height: 1.4;
  border: 1px solid transparent; border-radius: 4px; background: transparent;
  color: #8b949e; cursor: pointer; vertical-align: middle;
}
.mcap-fbtn:hover { color: #1c2128; background: #eef1f4; }
.mcap-fbtn.active { color: #0969da; background: #ddf4ff; border-color: #54aeff; font-weight: 700; }
.mcap-table .mcap-subtheme { color: #57606a; font-size: 14.5px; }
.mcap-filter-pop {
  position: fixed; z-index: 60; background: #fff; color: #1c2128;
  border: 1px solid #d0d7de; border-radius: 10px; box-shadow: 0 8px 28px rgba(0,0,0,0.30);
  padding: 11px; min-width: 250px; max-width: 380px; font-size: 14.5px;
}
/* 📱 Same treatment as the Quant taxonomy picker: the popup is position:fixed,
   so if the ▾ button sits low on a phone screen the body of the popup opened
   BELOW the fold and page-scroll could never bring it into view ("stuck in
   place" — Wade, 2026-07-08). Fixed top-anchored full-width sheet, scrolls
   internally, always entirely on-screen. !important beats the JS inline top/left. */
html.mobile-site .mcap-filter-pop {
  top: 10px !important; bottom: auto;
  left: 10px !important; right: 10px;
  width: auto; max-width: none !important; min-width: 0;
  max-height: calc(100vh - 20px) !important;
  max-height: calc(100dvh - 20px) !important;
  overflow-y: auto;
  z-index: 300;
}
.mcap-fp-title { font-weight: 700; font-size: 14px; margin-bottom: 8px; }
.mcap-fp-row { display: flex; align-items: center; gap: 6px; margin: 6px 0; }
.mcap-fp-in { width: 66px; padding: 3px 6px; border: 1px solid #d0d7de; border-radius: 6px; font-size: 14.5px; }
.mcap-fp-search { width: 100%; padding: 4px 8px; border: 1px solid #d0d7de; border-radius: 6px; margin-bottom: 6px; font-size: 14.5px; box-sizing: border-box; }
.mcap-fp-allnone { display: flex; gap: 6px; margin-bottom: 6px; }
.mcap-fp-allnone button { font-size: 13px; padding: 2px 8px; border: 1px solid #d0d7de; border-radius: 6px; background: #f6f8fa; color: #24292f; cursor: pointer; }
.mcap-fp-list { max-height: 230px; overflow-y: auto; border: 1px solid #eaeef2; border-radius: 6px; padding: 4px; }
.mcap-fp-chk { display: flex; align-items: center; gap: 7px; padding: 3px 4px; cursor: pointer; border-radius: 4px; }
.mcap-fp-chk:hover { background: #f6f8fa; }
.mcap-fp-chk span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mcap-fp-btns { display: flex; gap: 8px; margin-top: 10px; }
.mcap-fp-btns .btn { padding: 4px 12px; font-size: 14px; border-radius: 6px; cursor: pointer; }
.mcap-fp-apply { background: #1f883d; color: #fff; border: 0; }
.mcap-fp-clear { background: #f6f8fa; color: #24292f; border: 1px solid #d0d7de; }
/* One-click preset chips (Top 10% etc.) — mouse-first, no typing. */
.mcap-fp-presets { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 4px; }
.mcap-fp-preset { font-size: 13.5px; padding: 4px 10px; border: 1px solid #d0d7de; border-radius: 14px; background: #f6f8fa; color: #24292f; cursor: pointer; white-space: nowrap; }
.mcap-fp-preset:hover { background: #eef1f4; border-color: #54aeff; }
.mcap-fp-preset.active { background: #ddf4ff; border-color: #54aeff; color: #0969da; font-weight: 700; }
.mcap-fp-or { font-size: 12px; color: #8b949e; text-transform: uppercase; letter-spacing: .04em; margin: 8px 0 2px; }
.mcap-table .mcap-rankd-cell { white-space: nowrap; font-variant-numeric: tabular-nums; }
.mcap-table .mcap-rankd-cell .mcap-move { margin-left: 0; }
/* Compact the left-side columns (Wade 2026-07-08: "move the Rank Δ column
   farther left — stack heading text if needed — so all should shift left").
   The 100%-width auto-layout table was spreading slack into the #/Rank Δ/Chg
   columns (~124px each), pushing Company + everything after it far right.
   width:1% + nowrap cells shrinks each to its content, and the two-word
   headers (RANK Δ / CHG 1D) are allowed to stack onto two lines. */
.mcap-table .mcap-rank { width: 1%; }
.mcap-th[data-sort="rank_change"], .mcap-th[data-sort="chg"] { width: 1%; }
.mcap-th[data-sort="rank_change"] .mcap-th-lbl, .mcap-th[data-sort="chg"] .mcap-th-lbl {
  white-space: normal; display: inline-block; max-width: 3.6em;
  line-height: 1.15; vertical-align: middle;
}
.mcap-ticker {
  font-size: 13px;
  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: 14.5px; }
.mcap-country { white-space: nowrap; font-size: 14.5px; }
.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: 12px; 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: 14.5px; font-weight: 700; color: var(--text); }
.ai-screen-hint { font-size: 13px; }
.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: 14.5px;
  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: 14.5px;
}
.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: 13px;
}
.ai-screen-eg:hover { color: var(--accent); border-color: var(--accent); }
.ai-screen-status { margin-top: 8px; font-size: 14px; }
.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: 14px; 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: 13px; 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: 13px; color: var(--text); font-variant-numeric: tabular-nums;
}
.ai-result-unmapped { margin-top: 8px; font-size: 13px; 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: 13px; }
.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: 13px; 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: 14px; font-weight: 600; color: var(--text); min-width: 140px; }
.ai-f-op { font-size: 14px; color: var(--muted); font-variant-numeric: tabular-nums; min-width: 18px; text-align: center; }
.ai-f-and { font-size: 13px; color: var(--muted); }
.ai-f-unit { font-size: 13px; 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: 14px;
}
.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: 14px; }
.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: 14px; }
.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: 14px; }
.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: 14px;
}
.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: 14px; 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: #0433FF; }
.wiz-swatch--random { background: #FFFB00; }
.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: 14.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: 14px; }
.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: 13.5px; }
.wiz-tk { font-weight: 600; }
.ret-up { color: #2ecc71; }
.ret-down { color: #7BAFD4; }

.wizard-method-list { font-size: 14.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: 14.5px; padding: 6px 0; }
.wizard-trades-table { width: 100%; border-collapse: collapse; font-size: 14px; 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: 13px; }
.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: 14.5px; }
.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: 14px; 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: 14.5px; }
.shock-names-label { display: flex; align-items: center; gap: 6px; font-size: 14.5px; }
.shock-blast-wrap { position: relative; }
.shock-day { position: absolute; top: 6px; left: 10px; font-size: 14.5px; font-weight: 700; color: #f1c40f; letter-spacing: 0.4px; pointer-events: none; }
.shock-mag-label { display: flex; align-items: center; gap: 8px; font-size: 14.5px; }
.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: 13px; 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: 13px; 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: #FFFB00; }
.shock-dot--up { background: #0433FF; }

.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: 14.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: #FFFB00; }
.shock-secfill.up { background: #0433FF; }
.shock-secval { text-align: right; font-weight: 600; }
.shock-secdollar { text-align: right; font-size: 13px; }

.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: 13px; 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: 14.5px; 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: 13px; 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: 12px; 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: 14.5px; }

.oracle-hist-wrap > summary { cursor: pointer; font-weight: 600; font-size: 14.5px; 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: 14.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: 13px; }

html.mobile-site .oracle-stat { flex: 1 1 calc(33% - 12px); min-width: 0; }
html.mobile-site .oracle-co { font-size: 12px; }
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 on a phone: compact paddings, clamp the company name.
   ⚠ The old rule here hid columns by nth-child(5)/(6) with "Sector/Country"
   comments — but the Rank Δ + Sub-theme columns were inserted later, so those
   indices silently became MARKET CAP and SECTOR (Wade caught the missing
   sector filter, 2026-07-08). Target the per-column CLASSES/data-sort instead
   (insert-proof), and drop ONLY Country — Sector + Sub-theme stay, with their
   ▾ filters; .mcap-table-wrap already scrolls horizontally for the rest. ---- */
html.mobile-site .mcap-table { width: 100%; font-size: 14px; }
html.mobile-site .mcap-table thead th,
html.mobile-site .mcap-table tbody td { padding: 7px 5px; white-space: nowrap; }
html.mobile-site .mcap-th[data-sort="country"],
html.mobile-site .mcap-table td.mcap-country {
  display: none;
}
/* Keep the category text columns from eating the whole width. */
html.mobile-site .mcap-table td.mcap-sector,
html.mobile-site .mcap-table td.mcap-subtheme {
  max-width: 34vw; overflow: hidden; text-overflow: ellipsis;
}
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 checkbox (1) + ticker (2) so the row-select box AND the
        label both stay put while the return/vs-SPY columns scroll — mirrors the
        #tickers rail. 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(1),
html.mobile-site #picks-table thead th:nth-child(1) {
  position: sticky; left: 0; background: var(--bg); z-index: 1;
}
html.mobile-site #picks-table tbody td:nth-child(2),
html.mobile-site #picks-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 #picks-table thead th:nth-child(1),
html.mobile-site #picks-table thead th:nth-child(2) { background: var(--panel); z-index: 3; }

/* ---- Sub-industry→tickers (#tickers-table) shares the stocks layout.
        Pin checkbox + Ticker and drop the long free-text columns, same
        as #stocks-table. ---- */
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 #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 #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) on tickers. */
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 #tickers-table tbody td:nth-child(1),
html.mobile-site #tickers-table tbody td:nth-child(2) { background: var(--bg); }

/* New Listings page */
.nl-table { width: 100%; }
.nl-table .nl-co { max-width: 260px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nl-badge { display: inline-block; font-size: 11px; font-weight: 700; padding: 1px 4px; margin-left: 4px;
  border-radius: 3px; background: rgba(124,175,212,0.18); color: #9ec7e6; vertical-align: middle; }
.nl-sort:hover { color: var(--text); }
html.mobile-site .nl-table .nl-co { max-width: 90px; }

/* Traditional heat map on mobile — the morning's desktop drill/Deep-Dive view
   ported to phones. Bigger touch target for the per-box select checkbox, and a
   touch-friendly breadcrumb (no hover transform on touch). Scoped so desktop is
   byte-for-byte unchanged. */
html.mobile-site .hm-box-chk {
  top: 5px; right: 5px; width: 24px; height: 24px; font-size: 15px;
  border-color: rgba(255,255,255,0.8);
}
html.mobile-site .hm-box-name { padding-right: 26px; }   /* clear the checkbox */
html.mobile-site .hm-box:hover { transform: none; }      /* no lift on touch */
html.mobile-site #hm-meta { line-height: 1.7; }          /* breathable breadcrumb wrap */
html.mobile-site .hm-crumb { padding: 1px 2px; }

/* ── Portfolio v2 — mobile. Selector + entry forms stack full-width, inputs
   ≥16px (no iOS zoom), the desktop holdings + ledger tables hide in favor of
   the card lists, summary tiles drop to a 2-up grid, donuts stack vertically,
   and the history chart stays responsive. All selectors scoped to
   html.mobile-site so desktop stays byte-for-byte unchanged. */
html.mobile-site .pf-bar { gap: 8px; }
html.mobile-site .pf-bar h2 { flex: 1 1 100%; }
html.mobile-site .pf-select { flex: 1 1 100%; min-width: 0; font-size: 16px; }
html.mobile-site .pf-btn { flex: 1 1 auto; min-height: 40px; }
html.mobile-site .pf-asof { flex: 1 1 100%; margin-left: 0; }

html.mobile-site .pf-summary { gap: 6px; }
html.mobile-site .pf-tile { min-width: 0; flex: 1 1 calc(50% - 6px); }

html.mobile-site .pf-form { flex-direction: column; align-items: stretch; gap: 10px; }
html.mobile-site .pf-field { width: 100%; }
html.mobile-site .pf-field input,
html.mobile-site .pf-field select,
html.mobile-site #pf-ticker,
html.mobile-site #pf-qty,
html.mobile-site #pf-price,
html.mobile-site #pf-cash-amount,
html.mobile-site #pf-note,
html.mobile-site #pf-cash-ticker { width: 100%; font-size: 16px; box-sizing: border-box; }
html.mobile-site .pf-field .pf-check input { width: auto; }
html.mobile-site .pf-submit { width: 100%; min-height: 44px; }
html.mobile-site .pf-tab { flex: 1 1 auto; min-height: 40px; }
/* Autocomplete: full field width and taller rows for a thumb; a 260px min-width
   would push the panel off a 390px screen. */
html.mobile-site .pf-ac { left: 0; right: 0; min-width: 0; width: 100%; max-height: 44vh; overflow-y: auto; }
html.mobile-site .pf-ac-row { padding: 9px 10px; font-size: 15px; }
html.mobile-site .pf-ac-co { max-width: 55vw; }
/* Ledger tools stack full-width; the CSV preview grid drops the price column. */
html.mobile-site .pf-ledger-tools { margin-left: 0; width: 100%; }
html.mobile-site .pf-ledger-tools .pf-btn { flex: 1 1 auto; min-height: 40px; }
html.mobile-site .pf-csv-text { font-size: 16px; }
html.mobile-site .pf-csv-row { grid-template-columns: 92px 70px 1fr; }
html.mobile-site .pf-csv-row > :nth-child(4) { display: none; }
html.mobile-site .pf-csv-actions .pf-btn { flex: 1 1 auto; min-height: 40px; }

html.mobile-site #pf-table-wrap, html.mobile-site #pf-txns-wrap { display: none; }
html.mobile-site .pf-cards { display: flex; flex-direction: column; gap: 8px; }
html.mobile-site .pfc-card {
  background: var(--panel); border: 1px solid rgba(255,255,255,0.08);
  border-radius: 10px; padding: 10px 12px;
}
html.mobile-site .pfc-head { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; flex-wrap: wrap; }
html.mobile-site .pfc-head .pf-ticker { font-size: 16px; }
html.mobile-site .pfc-co { flex: 1 1 auto; min-width: 0; font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
html.mobile-site .pfc-row { display: flex; justify-content: space-between; gap: 10px; padding: 2px 0; font-size: 14.5px; }
html.mobile-site .pfc-row.pf-txn-actions { justify-content: flex-end; gap: 14px; margin-top: 4px; }
html.mobile-site .pfc-lbl { font-size: 13.5px; }
html.mobile-site .pfc-val { font-variant-numeric: tabular-nums; }
html.mobile-site .pf-txn-card .pf-edit-in { font-size: 16px; }
html.mobile-site .pf-link-btn { font-size: 14px; min-height: 32px; }

html.mobile-site .pf-donuts { grid-template-columns: 1fr; gap: 12px; }
html.mobile-site .pf-donut-body { justify-content: center; }
html.mobile-site .pf-history-chart { min-height: 220px; }

/* ─────────────────────────────────────────────────────────────────────────
   Mobile Quant usability pass (2026-06-14) — all scoped to html.mobile-site
   so desktop stays byte-for-byte unchanged.
   ───────────────────────────────────────────────────────────────────────── */

/* Taxonomy pickers: 4 stacked full-width rows → a compact 2×2 grid. */
html.mobile-site .quant-top-filters {
  display: grid; grid-template-columns: 1fr 1fr; gap: 6px 8px;
  padding: 6px 8px; margin-bottom: 6px;
}
html.mobile-site .quant-top-tax {
  flex: initial; min-width: 0; display: flex; flex-direction: column;
  align-items: stretch; gap: 2px;
}
html.mobile-site .quant-top-tax-label { min-width: 0; font-size: 12px; text-transform: uppercase; letter-spacing: 0.03em; }
html.mobile-site .quant-top-tax .quant-tax-btn { min-width: 0; width: 100%; min-height: 38px; font-size: 14px; }

/* Pin the result sort bar so Sort / dir / Select-all stay reachable while
   scrolling a long list. (#quant-cards is display:none on desktop.) */
html.mobile-site .qc-sortbar {
  position: sticky; top: 0; z-index: 30; margin: 0 0 8px; padding: 8px 0;
  background: var(--bg); border-bottom: 1px solid var(--border);
  box-shadow: 0 4px 8px -6px rgba(0,0,0,.5);
}

/* Stat row is now sort/filter-aware (variable count) → reflow cleanly. */
html.mobile-site .qc-stats { grid-template-columns: repeat(auto-fit, minmax(80px, 1fr)); gap: 8px 10px; }

/* Ask-AI example prompts: a tall wrapping wall → one horizontal-scroll strip. */
html.mobile-site .ai-screen-examples {
  flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; padding-bottom: 4px;
}
html.mobile-site .ai-screen-examples::-webkit-scrollbar { height: 3px; }
html.mobile-site .ai-screen-eg { flex: 0 0 auto; white-space: nowrap; }

/* Reclaim first-screen height: single-line meta strip + tighter breadcrumb. */
html.mobile-site .meta-strip {
  white-space: nowrap; overflow-x: auto; font-size: 14px; padding: 1px 12px 3px; opacity: .95;
}
html.mobile-site .breadcrumb-bar { padding: 4px 12px 3px; }
html.mobile-site .breadcrumb-bar .back { font-size: 14.5px; padding: 8px 6px 8px 0; }

/* Bottom jump bar — instant Filters↔Results hop + live match count (mobile,
   Quant view, Factor/Ask-AI result surface only). Desktop never shows it. */
.quant-jumpbar { display: none; }
html.mobile-site #quant-view:not([hidden]) .quant-jumpbar:not([hidden]) {
  display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 49;
  gap: 8px; padding: 8px 12px calc(8px + env(safe-area-inset-bottom, 0px));
  background: var(--panel); border-top: 1px solid var(--border);
}
html.mobile-site .quant-jumpbar button {
  flex: 1 1 0; min-height: 44px; border-radius: 8px; background: var(--panel-2);
  color: var(--text); border: 1px solid var(--border); font-size: 14px; font-weight: 600;
}
html.mobile-site .quant-jumpbar button:active { background: var(--panel); }
html.mobile-site .quant-jumpbar button b { color: var(--green); }
/* Stack above the selection bar when it's showing; keep the last card clear. */
html.mobile-site #quant-selection:not([hidden]) ~ .quant-jumpbar:not([hidden]) { bottom: calc(56px + env(safe-area-inset-bottom, 0px)); }
html.mobile-site #quant-view:not([hidden]) #quant-cards { padding-bottom: 64px; }
/* Lift the back-to-top button above the jump bar on the Quant view. */
html.mobile-site body.view-quant .mob-top-btn { bottom: 70px; }

/* ─────────────────────────────────────────────────────────────────────────
   Mobile Quant pass #3 (2026-06-20) — card legibility, Backtest reflow,
   iOS-zoom-safe controls, pagination + first-screen polish. All html.mobile-site.
   ───────────────────────────────────────────────────────────────────────── */
/* Result cards: bigger headline, roomier body, larger checkbox tap target. */
html.mobile-site .qc-card { padding: 12px 14px; }
html.mobile-site .qc-head { gap: 11px; }
html.mobile-site .qc-chk, html.mobile-site .qc-chk-spacer { width: 24px; }
html.mobile-site .qc-chk { height: 24px; }
html.mobile-site .qc-metric-val { font-size: 22px; }
html.mobile-site .qc-name { font-size: 14px; }
html.mobile-site .qc-stat-lbl { font-size: 12px; }
html.mobile-site .qc-stat-val { font-size: 14.5px; }
/* Count line (#quant-desc): readable now that the funnel prose is dropped. */
html.mobile-site #quant-desc { font-size: 14.5px !important; line-height: 1.45; }
/* Pagination renders OUTSIDE the hidden table on mobile → make it a comfortable
   tappable row, with the row-count on its own centered line above the buttons. */
html.mobile-site #quant-pagination { flex-wrap: wrap; gap: 6px; padding: 6px 0 10px; }
html.mobile-site #quant-pagination button { min-height: 40px; }
html.mobile-site .quant-page-info { flex: 1 1 100%; order: -1; text-align: center; }
/* Backtest form: one readable column; iOS-zoom-safe selects (≥16px); clear
   group headings with a separator; 44px submode buttons; presets scroll. */
html.mobile-site .bt-group-h select, html.mobile-site .bt-runrow select { font-size: 16px; min-height: 44px; }
html.mobile-site .bt-grid { flex-direction: column; gap: 9px; }
html.mobile-site .bt-field { width: 100%; }
html.mobile-site .bt-field input { width: 100%; }
html.mobile-site .bt-field label { font-size: 14.5px; font-weight: 600; color: var(--text); }
html.mobile-site .bt-group-h { font-size: 14.5px; color: var(--text); margin: 16px 0 8px; padding-top: 10px; border-top: 1px solid var(--border); }
html.mobile-site .bt-submode-btn { min-height: 44px; }
html.mobile-site .bt-presets { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; padding-bottom: 4px; }
html.mobile-site .bt-presets::-webkit-scrollbar { height: 3px; }
html.mobile-site .bt-preset { flex: 0 0 auto; min-height: 36px; }
/* Prescreen basket on a phone: the sub-mode row now holds 3 buttons, so let it
   scroll sideways rather than squeeze the labels; picks chips + the holdings
   table follow the page's existing scroll-sideways-in-a-container convention. */
html.mobile-site .bt-submode { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; padding-bottom: 4px; }
html.mobile-site .bt-submode-btn { flex: 0 0 auto; }
html.mobile-site #btb-prescreen, html.mobile-site #btb-years { font-size: 16px; min-height: 44px; width: 100%; }
html.mobile-site #btb-holdings { overflow-x: auto; }
html.mobile-site #btb-holdings table { min-width: 520px; }
html.mobile-site .btb-mode { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; padding-bottom: 4px; }
html.mobile-site .btb-mode-btn { flex: 0 0 auto; min-height: 40px; }

/* ─────────────────────────────────────────────────────────────────────────
   Mobile site-wide usability pass #2 (2026-06-14) — the non-Quant pages.
   From the mobile audit; all scoped to html.mobile-site (desktop unchanged).
   ───────────────────────────────────────────────────────────────────────── */

/* P1 (highest leverage): every <select> ≥16px so iOS never zooms on focus
   (the global input rule covers inputs but not selects). */
html.mobile-site select { font-size: 16px; }

/* P1: per-ticker price chart kept desktop's max-width:75% on mobile too. */
html.mobile-site #tv-chart-wrap { max-width: 100%; }

/* P0: #returns 14-col table — pin checkbox + Name, hide Theme so rows keep
   their identity when you swipe to the return columns. */
html.mobile-site #returns-table tbody td:nth-child(1),
html.mobile-site #returns-table thead th:nth-child(1) { position: sticky; left: 0; background: var(--bg); z-index: 1; }
html.mobile-site #returns-table tbody td:nth-child(2),
html.mobile-site #returns-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,.6); }
html.mobile-site #returns-table thead th:nth-child(1),
html.mobile-site #returns-table thead th:nth-child(2) { background: var(--panel); z-index: 3; }
html.mobile-site #returns-table th:nth-child(3),
html.mobile-site #returns-table td:nth-child(3) { display: none; }
html.mobile-site #returns-table td:nth-child(2) { max-width: 42vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* P0: #wl-table (watchlists, never got a mobile pass) — pin Ticker, hide
   Company + Theme. */
html.mobile-site #wl-table tbody td:nth-child(1),
html.mobile-site #wl-table thead th:nth-child(1) { position: sticky; left: 0; background: var(--bg); z-index: 1; box-shadow: 4px 0 6px -4px rgba(0,0,0,.6); }
html.mobile-site #wl-table thead th:nth-child(1) { background: var(--panel); z-index: 3; }
html.mobile-site #wl-table th:nth-child(2), html.mobile-site #wl-table td:nth-child(2),
html.mobile-site #wl-table th:nth-child(3), html.mobile-site #wl-table td:nth-child(3) { display: none; }
html.mobile-site #wl-table [data-wl-rm] { min-width: 40px; min-height: 40px; font-size: 16px; padding: 6px 10px; }

/* P0: .nl-table (new listings) — pin Ticker, hide Company + Sector. */
html.mobile-site .nl-table tbody td:nth-child(1),
html.mobile-site .nl-table thead th:nth-child(1) { position: sticky; left: 0; background: var(--bg); z-index: 1; box-shadow: 4px 0 6px -4px rgba(0,0,0,.6); }
html.mobile-site .nl-table thead th:nth-child(1) { background: var(--panel); z-index: 3; }
html.mobile-site .nl-table th:nth-child(2), html.mobile-site .nl-table td:nth-child(2),
html.mobile-site .nl-table th:nth-child(3), html.mobile-site .nl-table td:nth-child(3) { display: none; }

/* P1: ticker-detail primary action touch targets. */
html.mobile-site #ticker-detail-view .td-name-row .td-add-pick,
html.mobile-site #ticker-detail-view .td-name-row .td-add-anti { min-height: 40px; padding: 8px 14px; font-size: 14.5px; }
html.mobile-site .td-watchlist-select { font-size: 16px; padding: 8px 10px; min-height: 40px; }
html.mobile-site #ticker-detail-view .td-name-row { gap: 8px 10px; }
html.mobile-site #compare-input { font-size: 16px; }

/* P1: ripple sparkline — preserve aspect ratio (was width=260/height=78
   fixed → non-uniform squish on a narrow column). */
html.mobile-site .ripple-curve { width: 100%; height: auto; max-width: 160px; }
html.mobile-site .ripple-col { overflow-x: auto; -webkit-overflow-scrolling: touch; }
html.mobile-site .ripple-table { font-size: 14px; }

/* P1: search inputs with inline font-size:15px iOS-zoom — beat the inline. */
html.mobile-site #twinsies-input,
html.mobile-site #dejavu-input,
html.mobile-site #ripple-input { font-size: 16px !important; }

/* P1: Data Centers Hub&Spoke SVG — scroll at a readable scale instead of
   squishing 1100px into 375 (labels become ~3.7px). */
html.mobile-site .dc-spider-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
html.mobile-site .dc-spider-svg { min-width: 640px; }
html.mobile-site .dc-node-label { font-size: 18px; }
html.mobile-site .dc-node-hub-label { font-size: 24px; }
html.mobile-site .dc-hub-btn, html.mobile-site .dc-tab { min-height: 40px; padding: 8px 12px; font-size: 14.5px; }
html.mobile-site .dc-hub-picker { gap: 8px; }

/* P1: Passwords generator form — stack the controls on a phone. */
html.mobile-site .pw-form { flex-direction: column; align-items: stretch; gap: 12px; }
html.mobile-site .pw-form label { justify-content: space-between; }
html.mobile-site .pw-form select { width: 100%; }
html.mobile-site .pw-optgroup { display: flex; flex-direction: column; gap: 10px; }
html.mobile-site #pw-generate { width: 100%; min-height: 44px; }

/* P1: Returns toolbar select + Shockwave epicenter input + Market Cap select. */
html.mobile-site #returns-metric.select-sm { min-height: 40px; padding: 6px 10px; }
html.mobile-site #returns-view .sort-controls { gap: 6px 8px; }
html.mobile-site .shock-controls #shock-input { font-size: 16px; min-width: 0; flex: 1 1 100%; }
html.mobile-site .shock-mag-label input[type=range] { height: 36px; padding: 8px 0; }
html.mobile-site .mcap-filter .mcap-select { min-height: 40px; }

/* P2: Picks add form, Taxonomy indent/toggle, Heat-map grid, Oracle, Charts. */
html.mobile-site .picks-form { flex-wrap: wrap; gap: 10px; }
html.mobile-site .picks-form input[type=text] { width: 100%; box-sizing: border-box; }
html.mobile-site #picks-submit, html.mobile-site #picks-submit-anti { flex: 1 1 auto; min-height: 40px; }
html.mobile-site .tax-children { padding-left: 12px; margin-left: 4px; }
html.mobile-site .tax-toggle { width: 40px; height: 40px; min-width: 40px; }
html.mobile-site .hm-grid { grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); grid-auto-rows: 76px; gap: 6px; }
html.mobile-site .oracle-side { padding: 10px; }
html.mobile-site .oracle-match { gap: 6px; }
html.mobile-site .oracle-vs { font-size: 13px; }
html.mobile-site .charts-toolbar .chip { min-height: 36px; }

/* ─────────────────────────────────────────────────────────────────────────
   Pinned S&P 500 benchmark — always-on comparison basis (2026-06-15).
   In the Quant results (desktop row + mobile card) and the Traditional heat
   map tile. Values come live from the benchmark cache, never hardcoded.
   ───────────────────────────────────────────────────────────────────────── */

/* Quant desktop table — benchmark row, visually set apart. Always rendered FIRST
   (outside the sorted/filtered set) so it survives every filter/screen. NOT
   position:sticky — the desktop quant header isn't sticky, so a sticky row had
   nothing to anchor under and floated over the header + first data row. */
#quant-table tbody tr.quant-bench-row td {
  background: var(--panel-2); font-weight: 600;
  border-top: 2px solid var(--accent); border-bottom: 2px solid var(--accent);
}
#quant-table tbody tr.quant-bench-row .quant-bench-name { color: var(--accent); font-weight: 700; letter-spacing: 0.01em; }

/* Quant mobile card — benchmark variant. */
.qc-card.qc-bench { border: 1px solid var(--accent); background: rgba(88, 166, 255, 0.06); }
.qc-card.qc-bench .qc-bench-ticker { color: var(--accent); }

/* Traditional heat-map S&P 500 reference tile — BLACK box, YELLOW writing. */
.hm-box.hm-box-sp500 { background: #000; border: 1px solid #FFFB00; cursor: default; }
.hm-box.hm-box-sp500 .hm-box-name,
.hm-box.hm-box-sp500 .hm-box-val { color: #FFFB00; }

/* Universe-scope steps in the funnel flow chart (sub-theme gate / Deep Dive /
   excludes) — fixed, structural, non-draggable: dashed violet accent, no grip,
   no ×. Added 2026-07-02 so the Tucson gate (and any gate) is VISIBLE. */
.quant-funnel-step.quant-funnel-fixed {
  border-style: dashed;
  border-color: #7c5cff;
  cursor: default;
}
.quant-funnel-step.quant-funnel-fixed .quant-funnel-label { color: #b9a7ff; font-weight: 600; }

/* ── 📈 EPS Revisions (Quant page, 2026-07-16) ────────────────────────────
   Too many controls for the 5/7-col grid templates — flex-flow the row like
   a toolbar (mobile already forces flex on every filter row). Injected
   columns get a green family tint (vs the Ⓐ set's blue) so the two families
   read apart at a glance; cell direction colors are the standard
   green/#7BAFD4 pair via ret-pos/ret-neg — never red. */
.quant-filter-row--epsrev { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; }
.quant-filter-row--epsrev > .quant-filter-label { flex: 0 0 96px; }
th.estrev-col { background: rgba(63, 185, 80, 0.10); white-space: nowrap; }
td.estrev-cell { white-space: nowrap; }

/* ── Anthropic prescreen (Quant page, 2026-07-10) ─────────────────────────
   Colorblind-safe: green = business ahead, #7BAFD4 blue = valuation ahead
   (site standard "down" color — never red); every state also carries a text
   label + symbol so color is never the only signal. */
.quant-filter-row--anthropic { flex-wrap: wrap; }
.quant-anth-gap { margin-left: 6px; font-size: 12px; }
.quant-anth-filters {
  display: flex; flex-wrap: wrap; gap: 6px 14px;
  padding: 4px 8px 8px; margin: -2px 0 6px;
  border-left: 2px solid rgba(88, 166, 255, 0.45);
}
.quant-anth-filters-lbl { flex-basis: 100%; font-size: 12px; }
.quant-anth-flt { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; opacity: 0.55; white-space: nowrap; }
.quant-anth-flt.on { opacity: 1; }
.quant-anth-flt input[type="number"] { width: 56px; }
th.anth-col { background: rgba(88, 166, 255, 0.10); white-space: nowrap; }
td.anth-cell { white-space: nowrap; }
td.anth-cell.anth-score { font-weight: 700; }
.anth-badge {
  display: inline-block; padding: 1px 6px; border-radius: 9px;
  font-size: 11px; white-space: nowrap; border: 1px solid transparent;
}
.anth-badge--ahead     { background: rgba(63, 185, 80, 0.15);  border-color: var(--green); }
.anth-badge--aligned   { background: rgba(170, 180, 192, 0.15); border-color: var(--muted); }
.anth-badge--justified { background: rgba(88, 166, 255, 0.18);  border-color: var(--accent); }
.anth-badge--lagging   { background: rgba(123, 175, 212, 0.18); border-color: #7BAFD4; }
.anth-badge--severe    { background: rgba(123, 175, 212, 0.32); border-color: #5588aa; font-weight: 700; }
.anth-badge--invalid   { background: rgba(219, 139, 31, 0.15);  border-color: var(--orange); }
.anth-pass { color: var(--green); font-weight: 600; white-space: nowrap; }
.anth-fail { color: #7BAFD4; font-weight: 600; white-space: nowrap; }
.anth-detail-btn {
  background: none; border: 1px solid var(--border); border-radius: 6px;
  color: inherit; cursor: pointer; font-size: 11px; padding: 1px 6px; white-space: nowrap;
}
.anth-detail-btn:hover { background: rgba(88, 166, 255, 0.15); border-color: var(--accent); }
.anth-detail-wrap {
  position: fixed; inset: 0; background: rgba(0, 0, 0, 0.45); z-index: 1000;
  display: flex; align-items: center; justify-content: center;
}
.anth-detail-pop {
  position: relative; background: var(--panel); color: var(--text);
  border: 1px solid var(--accent); border-radius: 10px;
  max-width: min(640px, calc(100vw - 24px));
  max-height: calc(100dvh - 40px); overflow-y: auto;
  padding: 14px 16px; box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
  font-size: 13px; line-height: 1.5;
}
.anth-detail-pop h4 { margin: 0 18px 6px 0; font-size: 15px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.anth-detail-close { position: absolute; top: 8px; right: 10px; background: none; border: none; color: var(--muted); font-size: 20px; cursor: pointer; line-height: 1; }
.anth-detail-close:hover { color: var(--text); }
.anth-detail-table { border-collapse: collapse; margin: 8px 0; width: 100%; }
.anth-detail-table th, .anth-detail-table td { padding: 2px 8px; border-bottom: 1px solid var(--border); font-size: 12px; text-align: left; }
.anth-detail-table td.num, .anth-detail-table th.num { text-align: right; }
.anth-detail-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 3px 18px; font-size: 12px; margin: 8px 0; }
.anth-detail-grid .muted { margin-right: 4px; }
.anth-detail-decomp { font-size: 12px; background: rgba(88, 166, 255, 0.08); border-radius: 8px; padding: 8px 10px; margin: 8px 0; }
.anth-detail-sec { font-size: 12px; margin: 6px 0; }
.anth-detail-sec ul { margin: 2px 0 0 18px; padding: 0; }
.anth-score-chip { display: inline-block; background: rgba(63, 185, 80, 0.15); border: 1px solid var(--green); border-radius: 9px; padding: 1px 6px; font-size: 11px; }
html.mobile-site .anth-detail-pop { max-width: calc(100vw - 16px); }
html.mobile-site .anth-detail-grid { grid-template-columns: 1fr; }
html.mobile-site .quant-anth-filters { border-left: none; padding-left: 0; }

/* ─────────────────────────────────────────────────────────────────────────
   D11 Mobile-Quant polish (2026-08-05) — the cont. 27 / cont. 6 deferred
   audit items: skeleton loader, sticky bench card, funnel chip cloud,
   factor search + Active-only, jump-bar pagination, pinnable card stats,
   whole-card tap feedback, collapsible filter panel.
   EVERY rule here is either scoped to html.mobile-site or a base
   display:none guard for elements only the mobile JS renders — desktop
   stays byte-for-byte unchanged.
   ───────────────────────────────────────────────────────────────────────── */

/* Base guards (the jumpbar precedent): these elements are only ever created
   by mobile-guarded JS, but hide them unconditionally as belt-and-braces. */
.qf-collapse, .qf-tools { display: none; }

/* Skeleton cards — shimmer placeholders while the first /api/quant loads. */
html.mobile-site .qc-skel { pointer-events: none; }
html.mobile-site .qc-skel-line, html.mobile-site .qc-skel-bar {
  border-radius: 6px;
  background: linear-gradient(90deg, rgba(255,255,255,0.05) 25%, rgba(255,255,255,0.13) 50%, rgba(255,255,255,0.05) 75%);
  background-size: 200% 100%;
  animation: qc-shimmer 1.2s linear infinite;
}
html.mobile-site .qc-skel-line { height: 14px; margin: 5px 0; }
html.mobile-site .qc-skel-w40 { width: 40%; }
html.mobile-site .qc-skel-w70 { width: 70%; }
html.mobile-site .qc-skel-bar { height: 34px; margin-top: 10px; }
@keyframes qc-shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }

/* Sticky S&P 500 bench card — pinned just under the sticky sort bar (top set
   from the bar's measured height via --qc-sticky-top). Needs an OPAQUE
   background or the cards scrolling beneath show through the rgba tint. */
html.mobile-site .qc-list > .qc-card.qc-bench {
  position: sticky; top: var(--qc-sticky-top, 59px); z-index: 25;
  background-color: var(--panel);
  background-image: linear-gradient(rgba(88,166,255,0.08), rgba(88,166,255,0.08));
}

/* Funnel chip cloud — wrap the active-step chips instead of a sideways pan
   (order still reads top-left → bottom-right; the ‹ › reorder arrows stay on
   each chip). The → connectors go — they were the width problem. */
html.mobile-site .quant-funnel { flex-wrap: wrap; overflow-x: visible; }
html.mobile-site .quant-funnel > .quant-funnel-arrow { display: none; }

/* Collapse-filters toggle — folds the whole control stack down to the funnel
   chip cloud (the chip summary IS the screen); one tap brings it back. */
html.mobile-site #quant-view:not([hidden]) .qf-collapse {
  display: block; width: 100%; min-height: 40px; margin: 8px 0 4px;
  background: var(--panel); color: var(--muted); border: 1px solid var(--border);
  border-radius: 8px; font-size: 14px; font-weight: 600;
}
html.mobile-site #quant-pipeline.qf-collapsed > :not(.quant-funnel):not(.qf-collapse) { display: none; }

/* Factor tools — search box + "Active only" above the filter grid. */
html.mobile-site #quant-view:not([hidden]) .qf-tools { display: flex; gap: 8px; margin: 10px 0 6px; }
html.mobile-site .qf-search {
  flex: 1 1 auto; min-width: 0; font-size: 16px; min-height: 42px;   /* ≥16px: no iOS zoom */
  padding: 8px 10px; border-radius: 8px;
  background: var(--panel); color: var(--text); border: 1px solid var(--border);
}
html.mobile-site .qf-active-only {
  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: 14px; font-weight: 600; white-space: nowrap;
}
html.mobile-site .qf-active-only.active { background: rgba(46,204,113,0.16); border-color: rgba(46,204,113,0.5); color: #2ecc71; }
html.mobile-site .quant-filter-row.qf-hidden { display: none !important; }

/* Jump-bar pagination cluster (‹ Page x/y ›). */
html.mobile-site .quant-jumpbar .qjb-page-btn { flex: 0 0 44px; font-size: 19px; font-weight: 700; }
html.mobile-site .quant-jumpbar .qjb-page-btn:disabled { opacity: 0.35; }
html.mobile-site .quant-jumpbar .qjb-page {
  flex: 0 0 auto; align-self: center; font-size: 13.5px; font-weight: 600;
  color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap;
}

/* Pinned card stats (📌) + whole-card tap feedback. */
html.mobile-site .qc-stat.qc-pinned .qc-stat-lbl { color: var(--accent); }
html.mobile-site .qc-card[data-ticker]:active { background: var(--panel-2); }

/* ═══ READING COMFORT — opt-in, site-wide (H4d) ═══════════════════════════════
   The 2026-06-15 profile-readability pass deliberately left the SECONDARY,
   SITE-WIDE asks (bigger base copy, looser line-height, roomier table rows,
   brighter dim text) unbuilt: done globally they repaint every page, which is
   Wade's call and not a session's. This is that substance behind a switch —
   the "Reading comfort" item at the bottom of the nav menu.

   ⚠ Every rule below is scoped under `html.reading-comfort`, so with the switch
   OFF (the default) every page renders exactly as it did before this block
   existed. Flipping the DEFAULT to on is a one-line change in PREFS_DEFAULTS.

   Deliberately NOT touched: SVG/canvas-laid-out surfaces (heat-map tiles, the
   d3 graph pages, lightweight-charts) — their text is positioned by geometry,
   so scaling it overlaps rather than helps; and any element whose size is a
   hard px value stays put unless it is a reading surface named below. */
html.reading-comfort body { font-size: 17.5px; line-height: 1.62; }
html.reading-comfort { --muted: #c2cbd6; }          /* dim gray → readable gray */
html.reading-comfort p,
html.reading-comfort li { line-height: 1.72; }
/* Data tables: the site default is a very tight 1px/6px, 1.2 line-height. */
html.reading-comfort table { font-size: 14px; }
html.reading-comfort th,
html.reading-comfort td { padding: 4px 8px; line-height: 1.38; }
html.reading-comfort th { padding: 5px 8px; font-size: 12.5px; }
/* Long-form reading surfaces carry explicit px sizes, so they need naming. */
html.reading-comfort #ticker-detail-view .profile-readable-copy,
html.reading-comfort #ticker-detail-view .profile-readable-copy--dense { font-size: 16.5px; line-height: 1.8; }
html.reading-comfort #ticker-detail-view .td-description { font-size: 16.5px; line-height: 1.8; }
html.reading-comfort .mp-writeup p,
html.reading-comfort .mp-writeup li { font-size: 16.5px; line-height: 1.8; }
html.reading-comfort #ticker-detail-view .td-annual-table { font-size: 14.5px; }
html.reading-comfort .news-title { font-size: 15.5px; line-height: 1.5; }
/* Clipped copy has to grow with the type or it clips mid-word. */
html.reading-comfort #ticker-detail-view .expandable-copy { max-height: 15.8em; }
