/* ===========================================================================
   VIVEK 5.0 — terminal theme
   Dark-only, dense, pro-desk look: hairline borders instead of drop shadows,
   JetBrains Mono for every number/ticker/label, sharp corners, fast
   transform/opacity-only transitions. Same layout + class names as before —
   only the skin changed, so all pages and JS keep working untouched.
   ===========================================================================

   ── BREAKPOINT SCALE (backlog #39) ──────────────────────────────────────
   The canonical responsive scale for Vivek 5.0 — new work uses THESE, not a
   fresh ad-hoc value tuned to one element:

     320px  — narrowest supported phone. Nothing may overflow here (the e2e
              suite asserts it on every page). Design floor.
     480px  — small phone → large phone / spark-drop boundary.
     680px  — THE phone⇄desktop line. Below it: bottom tab bar + MORE sheet,
              hidden pill nav, 16px inputs, card reflows, h-scroll strips.
     880px  — tablet / narrow-desktop: multi-column grids collapse to one.
     1200px — full desktop content width ceiling.

   Grandfathered: a handful of older, content-specific queries (e.g. 560/720/
   1440) predate this scale and are left as-is where rewriting them would risk
   a layout the owner already signed off on. Migrate opportunistically when
   touching the surrounding rules — never in a blind sweep.
   =========================================================================== */
:root {
  /* ═══ iOS REVAMP (owner request 2026-07-05: "complete revamp — more BOLD,
     more brighter, more iOS/Apple-like"). The whole skin moves from the dark
     terminal to an Apple-dark look: iOS system accent colours, big rounded
     corners, soft layered shadows instead of hairline rings, SF-style bold
     sans labels (Inter ≈ SF Pro on non-Apple hardware), frosted top bar,
     segmented controls, pill buttons, tinted rounded badges.
     Terminal-pass values (for a revert): panel #171d27/#1d2431/#242e3e ·
     text #f8fafe/#e6edf6/#bcc6d6/#9aa4b6 · borders #2d3646/#3c4761/#222a38 ·
     accents #4da3ff/#2fd07f/#ff5b5b/#ffb224 · radius 10/8/6 ·
     shadow = 0 0 0 1px var(--border). ═══ */
  --bg: #10141b;
  --bg-grad: #10141b;
  --panel: #1c222d;
  --panel-2: #232a38;
  --panel-3: #2c3546;
  --elevated: #232a38;

  --text: #ffffff;
  --text-2: #ecf1f9;
  /* UI Wave 1 (2026-07-22): lifted from #c3cddd / #9fabbf — both already met
     WCAG AA, but muted-2 sat at 5.3:1 on --panel-3; now ≥6.2:1 everywhere
     (muted ≥8.4:1), so secondary text reads cleanly on every surface. */
  --muted: #cdd6e4;
  --muted-2: #adb9cd;

  --separator: #313b4c;
  --border: #313b4c;
  --border-2: #445373;
  --border-soft: #273040;
  --fill: rgba(255,255,255,0.07);
  --fill-2: rgba(255,255,255,0.05);

  /* iOS system palette (dark), soft tints at iOS "tinted button" strength */
  --blue: #0a84ff;   --blue-soft: rgba(10,132,255,0.16);
  --green: #30d158;  --green-soft: rgba(48,209,88,0.16);
  --red: #ff453a;    --red-soft: rgba(255,69,58,0.16);
  --orange: #ff9f0a; --orange-soft: rgba(255,159,10,0.16);
  --teal: #64d2ff;
  --purple: #bf5af2;

  --ema-8: #ff5c8a;  --ema-13: #ff9f43; --ema-21: #ffd23f; --ema-34: #30d158;
  --ema-55: #64d2ff; --ema-89: #0a84ff; --ema-144: #bf5af2;

  --grade-aplus: #30d158; --grade-a: #0a84ff; --grade-b: #ff9f0a; --grade-c: #8e97a8;

  --accent: var(--green);
  --radius: 18px; --radius-md: 14px; --radius-sm: 10px;
  /* iOS elevation: soft layered drop shadows + a faint white key-line */
  --shadow: 0 1px 1px rgba(0,0,0,0.20), 0 8px 22px rgba(0,0,0,0.30),
            0 0 0 1px rgba(255,255,255,0.055);
  --shadow-hover: 0 2px 3px rgba(0,0,0,0.22), 0 14px 34px rgba(0,0,0,0.38),
                  0 0 0 1px rgba(255,255,255,0.10);
  --shadow-open: 0 2px 3px rgba(0,0,0,0.22), 0 14px 34px rgba(0,0,0,0.38),
                 0 0 0 1px rgba(255,255,255,0.10);
  --shadow-pill: 0 2px 8px rgba(0,0,0,0.32);
  --nav: #141922;
  /* CLS #1: "Inter-fallback"/"JBMono-fallback" are metric-matched local
     fallbacks (fonts.css) — they paint with (near-)Inter geometry while the
     real files load, so the swap doesn't re-flow the page. */
  --sans: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text",
          "Inter", "Inter-fallback", "Segoe UI", system-ui, sans-serif;
  --mono: "JetBrains Mono", "JBMono-fallback", ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html { color-scheme: dark; }
body {
  font-family: var(--sans);
  background: var(--bg);
  color: var(--text);
  min-height: 100vh;
  min-height: 100dvh;   /* #36: iOS URL-bar collapse must not jitter sticky UI */
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  letter-spacing: -0.01em;
}
::selection { background: rgba(47,208,127,0.25); }
/* #92: one visible keyboard-focus ring for EVERY interactive element — a green
   outline plus a soft halo so it reads on busy/dark cards too. Applies to
   links, buttons, inputs, custom [role]/[tabindex] widgets, summary folds and
   the clickable result rows alike (the universal :focus-visible selector). */
:focus-visible {
  outline: 2px solid var(--green); outline-offset: 2px; border-radius: 4px;
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--green) 22%, transparent);
}
/* Keep the ring on form controls that drop the default outline for mouse use:
   restore it specifically for keyboard focus. */
input:focus-visible, textarea:focus-visible, select:focus-visible {
  outline: 2px solid var(--green); outline-offset: 1px;
}

/* ================================================================= nav bar */
.topbar {
  display: flex; align-items: center; gap: 14px;
  padding: 11px 20px; border-bottom: 1px solid var(--border);
  background: var(--nav);
  position: sticky; top: 0; z-index: 30;
}
/* signature accent hairline across the very top */
.topbar::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 2px;
  background: linear-gradient(90deg, var(--green), var(--teal) 40%, transparent 80%);
  pointer-events: none;
}
/* two-row variant (index.html) */
.topbar:has(.topbar-row1) { flex-direction: column; gap: 0; padding: 0; }
.topbar-row1 {
  display: flex; align-items: center; gap: 14px; position: relative;
  padding: 9px 20px; width: 100%;
}
.topbar-row2 {
  display: flex; align-items: center; gap: 10px;
  padding: 5px 20px 6px; width: 100%;
  border-top: 0.5px solid var(--separator);
}
/* "SET UPS" label — sits cleanly to the left of the scan-type tabs, not inside
   the tab group. A quiet, premium section title with a hairline divider. */
.setups-title {
  font: 800 12px/1 var(--sans);
  letter-spacing: 0.16em;
  color: var(--text-2);
  text-transform: uppercase;
  padding-right: 12px;
  margin-right: 2px;
  border-right: 1.5px solid var(--separator);
  flex-shrink: 0;
  white-space: nowrap;
}
@media (max-width: 560px) {
  .setups-title { display: none; }   /* reclaim space for tabs on small screens */
}
/* city clocks — all four now sit on the LEFT of row 1 (owner 2026-07-05),
   stacked in a single column: MELBOURNE · NEW YORK · CHINA · LONDON. Narrow
   (~280px) so the row fits clocks + quote + nav + brand down to ~1760px. */
.topbar-clocks { display: flex; flex-direction: column; gap: 5px; flex-shrink: 0; }
.topbar-clocks-left { gap: 3px; }
.topbar-clocks-right { text-align: right; }
.topbar-clocks-right .clock-city { justify-content: flex-end; }
.clock-city { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.clock-city-name {
  font: 700 11px/1 var(--sans); letter-spacing: 0.1em; color: var(--muted); min-width: 72px;
}
.clock-time { font: 600 17px/1 var(--mono); color: var(--text); font-variant-numeric: tabular-nums; }
.clock-date { font: 500 12px/1 var(--sans); color: var(--muted); }
/* per-city colours */
.clock-city.clk-mel    { --clk: #f5c518; }   /* Melbourne — yellow */
.clock-city.clk-ny     { --clk: #b98bff; }   /* New York  — purple */
.clock-city.clk-china  { --clk: var(--muted-2); } /* China — faint grey */
.clock-city.clk-london { --clk: #35c5d8; }   /* London — teal */
.clock-city[class*="clk-"] .clock-city-name { color: var(--clk); opacity: 0.85; }
.clock-city[class*="clk-"] .clock-time      { color: var(--clk); }
/* brand — inline in row 1 (clocks · brand · quote · nav · clocks) */
.topbar-brand {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  flex-shrink: 0;
}
/* The quote sits in the MIDDLE of row 1 — between the clocks (left) and the
   nav (owner 2026-07-05). It flex-grows to fill the gap and centres its text,
   free to wrap to two lines. Room is made by shrinking the trailing nav pills
   (.nav-minor) rather than dropping the quote to another row. */
.topbar-quote {
  flex: 1 1 auto; min-width: 0; text-align: center; padding: 0 16px;
  font: 400 italic 11.5px/1.45 var(--sans); color: var(--text-2);
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden;
}
/* market-switch + nav-link pills — right of the quote, left of the brand. */
.topbar-nav {
  display: flex; align-items: center; gap: 12px; flex-shrink: 0;
}
/* VIVEK 5.0 wordmark now sits at the far RIGHT of row 1 (owner 2026-07-05). */
.topbar-brand { align-items: flex-end; }
/* push search/reload to the right in row 2 */
.topbar-row2 .search-trigger { margin-left: auto; }
.brand { display: flex; align-items: center; gap: 10px; }
.brand-mark {
  display: grid; place-items: center; width: 32px; height: 32px; border-radius: var(--radius-sm);
  color: var(--green); background: var(--green-soft);
  border: 1px solid rgba(47,208,127,0.35); flex-shrink: 0;
}
.brand-text { display: flex; flex-direction: column; align-items: flex-start; gap: 1px; line-height: 1; }
.brand h1 { margin: 0; font: 700 14px/1 var(--mono); letter-spacing: 0.05em; color: var(--text); }
.brand-sub { font: 600 8.5px/1 var(--mono); letter-spacing: 0.26em; text-transform: uppercase; color: var(--green); }

/* Dashboard header brand — bigger + bolder, with the BETA SCANNER subtitle. */
.topbar-brand .brand { gap: 13px; }
.topbar-brand .brand-mark { width: 44px; height: 44px; border-radius: 8px; }
.topbar-brand .brand-mark svg { width: 26px; height: 26px; }
.topbar-brand .brand h1 { font-size: 23px; letter-spacing: 0.03em; }
.topbar-brand .brand-sub { font-size: 10px; letter-spacing: 0.34em; margin-top: 3px; }

.market-switch { display: inline-flex; gap: 2px; padding: 2px; background: var(--fill-2); border: 1px solid var(--border); border-radius: var(--radius-sm); }
.market-btn {
  appearance: none; border: 0; cursor: pointer; background: transparent;
  color: var(--muted); font: 600 11.5px/1 var(--mono); letter-spacing: 0.05em;
  padding: 6px 14px; border-radius: 4px; transition: all .15s;
}
.market-btn.is-active {
  background: var(--green-soft); color: var(--green);
  box-shadow: inset 0 0 0 1px rgba(47,208,127,0.4);
}
.market-btn:not(.is-active):hover { color: var(--text-2); }

.scan-switch { display: inline-flex; gap: 2px; padding: 2px; background: var(--fill-2); border: 1px solid var(--border); border-radius: var(--radius-sm); }
.scan-btn {
  appearance: none; border: 0; cursor: pointer; background: transparent;
  color: var(--muted); font: 600 11.5px/1 var(--mono); letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 6px 12px; border-radius: 4px; transition: all .15s;
}
.scan-btn.is-active {
  background: var(--orange-soft); color: var(--orange);
  box-shadow: inset 0 0 0 1px rgba(255,178,36,0.4);
}
.scan-btn:not(.is-active):hover { color: var(--text-2); }
.scan-btn-short.is-active { background: var(--red); }
.scan-btn-short:not(.is-active) { color: var(--red); }
.scan-btn-googy.is-active { background: #5856d6; }
.scan-btn-googy:not(.is-active) { color: #9d9dff; }
.scan-btn-vivek.is-active { background: var(--green); }
.scan-btn-vivek:not(.is-active) { color: var(--green); }

/* ── VIVEK (5.0) detail — prominent trade-levels ladder ── */
.vk-detail { padding: 4px 26px 40px; }
.vk-hero {
  display: grid; grid-template-columns: 108px 1fr; gap: 0;
  border-radius: var(--radius); overflow: hidden; margin: 22px 0 18px;
  background: var(--panel); box-shadow: var(--shadow); border: 0.5px solid var(--border-soft);
}
.vk-grade-block {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 8px; padding: 22px 12px;
  background: color-mix(in srgb, var(--gc) 10%, var(--panel));
  border-right: 1px solid color-mix(in srgb, var(--gc) 35%, transparent);
}
.vk-grade-lbl { font: 700 9px/1 var(--mono); letter-spacing: 0.16em; color: var(--muted); }
.vk-grade-val { font: 700 40px/0.9 var(--mono); letter-spacing: -0.02em; color: var(--gc); }
.vk-grade-score { font: 600 11px/1 var(--mono); color: var(--gc); background: color-mix(in srgb, var(--gc) 14%, transparent); border: 1px solid color-mix(in srgb, var(--gc) 40%, transparent); padding: 4px 8px; border-radius: 3px; font-variant-numeric: tabular-nums; }
.vk-hero-body { padding: 16px 20px; display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.vk-hero-top { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.vk-dir { font: 800 11px/1 var(--sans); letter-spacing: 0.05em; padding: 5px 9px; border-radius: 7px; }
.vk-dir.dir-long  { background: var(--green-soft); color: var(--green); }
.vk-dir.dir-short { background: var(--red-soft); color: var(--red); }
.vk-tf-chip { font: 600 10px/1 var(--mono); letter-spacing: 0.05em; color: var(--text-2); background: var(--fill-2); border: 1px solid var(--border); padding: 5px 9px; border-radius: 3px; }
.vk-rr { margin-left: auto; font: 700 16px/1 var(--mono); color: var(--blue); font-variant-numeric: tabular-nums; }
.vk-rr-sub { font: 600 10px/1 var(--sans); color: var(--muted); letter-spacing: 0.02em; }
.vk-chart-btn { font: 700 11px/1 var(--sans); color: var(--blue); text-decoration: none; padding: 6px 10px; border-radius: 8px; background: var(--blue-soft); }
.vk-chart-btn:hover { filter: brightness(0.96); }
.vk-why { margin: 0; font: 400 14.5px/1.65 var(--sans); color: var(--text-2); }

/* the level ladder — SL · Entry · TP1/2/3, each a clear row */
.vk-ladder { display: flex; flex-direction: column; gap: 1px; border-radius: var(--radius-md); overflow: hidden; background: var(--separator); margin-bottom: 18px; }
.vk-lvl {
  display: grid; grid-template-columns: 52px 1fr auto auto; align-items: baseline; gap: 14px;
  padding: 16px 18px; background: var(--panel);
}
.vk-lvl-key { font: 700 10px/1 var(--mono); letter-spacing: 0.06em; padding: 4px 7px; border-radius: 3px; text-align: center; }
.vk-lvl-label { font: 500 12px/1 var(--mono); color: var(--text-2); }
.vk-lvl-price { font: 700 19px/1 var(--mono); color: var(--text); font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
.vk-lvl-sub { font: 500 11px/1.3 var(--mono); color: var(--muted); text-align: right; font-variant-numeric: tabular-nums; }
.vk-lvl.vk-sl    { background: color-mix(in srgb, var(--red) 5%, var(--panel)); }
.vk-lvl.vk-sl    .vk-lvl-key { background: var(--red-soft); color: var(--red); }
.vk-lvl.vk-sl    .vk-lvl-price { color: var(--red); }
.vk-lvl.vk-entry { background: color-mix(in srgb, var(--blue) 5%, var(--panel)); }
.vk-lvl.vk-entry .vk-lvl-key { background: var(--blue-soft); color: var(--blue); }
.vk-lvl.vk-tp    .vk-lvl-key { background: var(--green-soft); color: var(--green); }
.vk-lvl.vk-tp    .vk-lvl-price { color: var(--green); }
.vk-chips { display: flex; flex-wrap: wrap; gap: 7px; }

/* freshness chip in the hero */
.vk-fresh { font: 600 10px/1 var(--mono); letter-spacing: 0.04em; color: var(--muted); background: var(--fill-2); border: 1px solid var(--border); padding: 5px 8px; border-radius: 3px; }
.vk-fresh.stale { color: var(--red); background: var(--red-soft); }

/* 5.0 trade checklist — mechanical criteria, pass/fail at a glance */
.vk-checklist-wrap { margin-bottom: 18px; }
.vk-section-lbl { font: 700 10.5px/1 var(--sans); letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); margin-bottom: 10px; }
.vk-checklist { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--separator); border-radius: var(--radius-md); overflow: hidden; }
.vk-check { display: flex; align-items: center; gap: 9px; padding: 12px 14px; background: var(--panel); }
.vk-check-ic { flex: 0 0 18px; width: 18px; height: 18px; border-radius: 50%; display: grid; place-items: center; font: 800 11px/1 var(--sans); }
.vk-check.ok .vk-check-ic { background: var(--green-soft); color: var(--green); }
.vk-check.no .vk-check-ic { background: var(--red-soft); color: var(--red); }
.vk-check-lbl { font: 700 13px/1.2 var(--sans); color: var(--text); }
.vk-check-note { margin-left: auto; font: 500 11.5px/1.2 var(--sans); color: var(--muted); text-align: right; }
.vk-plan-note { margin-top: 10px; font: 500 12px/1.5 var(--sans); color: var(--text-2); padding: 11px 13px; background: var(--fill); border-radius: var(--radius-sm); }

@media (max-width: 560px) {
  .vk-detail { padding: 4px 14px 32px; }
  .vk-hero { grid-template-columns: 88px 1fr; }
  .vk-lvl { grid-template-columns: 44px 1fr auto; }
  .vk-checklist { grid-template-columns: 1fr; }
  .vk-lvl-sub { grid-column: 2 / -1; text-align: left; }
}

/* Asset type badges */
.badge.asset-commodity { background: rgba(255,193,7,.15); color: #ffc107; }
.badge.asset-asx       { background: rgba(45,208,127,.12); color: #2fd07f; }
.badge.asset-nasdaq    { background: rgba(77,159,255,.12); color: #4d9fff; }
.badge.asset-index     { background: rgba(178,128,255,.15); color: #b280ff; }
.badge.asset-crypto    { background: rgba(255,149,0,.14); color: var(--orange); }

.howto-link {
  display: inline-flex; align-items: center;
  color: var(--muted); text-decoration: none;
  font: 600 11px/1 var(--mono); letter-spacing: 0.06em; text-transform: uppercase;
  padding: 5px 2px; white-space: nowrap;
  transition: color .15s;
}
.howto-link:hover { color: var(--green); }
.howto-link.bot-nav-link { color: var(--blue); }
.howto-link.bot-nav-link:hover { color: var(--blue); opacity: 0.8; }

/* Dashboard nav links as quiet mono tags, set apart from the market switch
   by a gap + hairline divider so the two groups read as distinct. */
.nav-pills {
  display: inline-flex; align-items: center; gap: 6px;
  position: relative; padding-left: 14px;
}
.nav-pills::before {
  content: ""; position: absolute; left: 0; top: 50%; transform: translateY(-50%);
  width: 1px; height: 20px; background: var(--border-2);
}
.nav-pills .howto-link {
  padding: 6px 11px; border-radius: 4px;
  background: var(--fill-2); border: 1px solid var(--border);
  color: var(--muted); font: 600 10px/1 var(--mono); letter-spacing: 0.08em; transition: all .15s;
}
.nav-pills .howto-link:hover { color: var(--green); border-color: rgba(47,208,127,0.4); background: var(--green-soft); }
.nav-pills .howto-link.bot-nav-link {
  background: var(--blue-soft); border-color: rgba(77,163,255,0.35); color: var(--blue);
}
.bot-nav-dot {
  display: inline-block; width: 6px; height: 6px; border-radius: 50%;
  background: var(--blue); vertical-align: middle; margin-right: 4px; flex-shrink: 0;
  animation: pulse-bot-dot 2.4s infinite;
}
@keyframes pulse-bot-dot {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.3; }
}

.reload-btn {
  appearance: none; cursor: pointer;
  display: inline-flex; align-items: center; gap: 7px; height: 33px; padding: 0 15px;
  border: 1px solid rgba(47,208,127,0.5); border-radius: var(--radius-sm);
  background: var(--green-soft); color: var(--green); transition: background .15s, opacity .15s;
}
.reload-btn:hover { background: rgba(47,208,127,0.22); }
.reload-btn:disabled { opacity: .55; cursor: default; }
.reload-label { font: 700 11.5px/1 var(--mono); letter-spacing: 0.1em; }
.reload-btn.spinning svg { animation: spin .8s linear infinite; transform-origin: 50% 50%; }
@keyframes spin { to { transform: rotate(360deg); } }

/* scan toast */
.scan-toast {
  position: fixed; left: 50%; bottom: 24px; transform: translate(-50%, 14px);
  z-index: 999; max-width: min(92vw, 460px);
  background: var(--panel-2); color: var(--text);
  border: 1px solid rgba(47,208,127,0.5); border-left: 3px solid var(--green);
  font: 500 12.5px/1.5 var(--mono); padding: 12px 16px; border-radius: var(--radius-sm);
  box-shadow: 0 12px 36px rgba(0,0,0,.4);
  opacity: 0; pointer-events: none; transition: opacity .2s, transform .2s;
}
.scan-toast.show { opacity: 1; transform: translate(-50%, 0); }
.scan-toast.warn { border-color: rgba(255,178,36,0.5); border-left-color: var(--orange); }
.scan-toast.info { border-color: rgba(77,163,255,0.5); border-left-color: var(--blue); }

.wrap { max-width: 1500px; margin: 0 auto; padding: 18px 20px 64px; }

/* ================================================================ scan banner */
.scan-banner {
  background: transparent; border-radius: 0; box-shadow: none; border: 0;
  padding: 2px 0 16px; margin-bottom: 0;
}
.scan-banner-title { font: 500 14px/1.3 var(--sans); color: var(--muted); }
.scan-banner-sub { font-size: 13px; color: var(--muted-2); margin-top: 3px; }
/* data freshness + schema badge: green when fresh, amber when stale/low coverage/old build */
.scan-fresh {
  display: inline-flex; align-items: center; margin-top: 8px;
  font: 600 11px/1 var(--mono); letter-spacing: 0.02em;
  color: var(--green); background: var(--green-soft);
  padding: 5px 10px; border-radius: 7px;
  border: 1px solid color-mix(in srgb, var(--green) 26%, transparent);
}
.scan-fresh.warn {
  color: var(--orange); background: var(--orange-soft);
  border-color: color-mix(in srgb, var(--orange) 30%, transparent);
}
/* Pipeline funnel disclosure (2026-07-29) — why names were excluded, on tap. */
.scan-funnel { margin-top: 6px; }
.scan-funnel > summary {
  cursor: pointer; list-style: none; display: inline-flex; align-items: center;
  font: 600 11px/1 var(--mono); letter-spacing: 0.02em; color: var(--muted-2);
  padding: 4px 0; -webkit-tap-highlight-color: transparent;
}
.scan-funnel > summary::-webkit-details-marker { display: none; }
.scan-funnel > summary::before { content: "▸ "; color: var(--muted-2); }
.scan-funnel[open] > summary::before { content: "▾ "; }
.scan-funnel .sf-body {
  margin: 6px 0 2px; font: 500 12px/1.6 var(--sans); color: var(--muted);
}
.scan-funnel .sf-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.scan-funnel .sf-chip {
  display: inline-flex; align-items: center; gap: 5px; text-decoration: none;
  font: 600 11px/1 var(--mono); color: var(--text);
  background: var(--panel-2); border: 1px solid var(--border);
  padding: 5px 9px; border-radius: 7px;
}
.scan-funnel .sf-chip .sf-rvol { color: var(--orange); }
/* Funnel-history trend (Task 2) — quiet by design: it lives inside the
   disclosure and reads as evidence, not alarm. Existing tokens only. */
.scan-funnel .sf-hist { margin-top: 10px; display: grid; gap: 4px; }
.scan-funnel .sf-hist:empty { display: none; }
.scan-funnel .sf-hist-head { color: var(--muted-2); font: 500 11px/1.4 var(--sans); }
.scan-funnel .sf-hist-row { display: flex; align-items: center; gap: 8px; }
.scan-funnel .sf-hist-label {
  color: var(--muted); font: 600 11px/1 var(--mono);
  min-width: 86px; letter-spacing: 0.03em;
}
.scan-funnel .sf-spark { color: var(--blue); flex: none; opacity: 0.9; }
.scan-funnel .sf-hist-vals { color: var(--muted-2); font: 500 11px/1 var(--mono); }
/* v5 payload split — the expanded panel's own loading / retry states.
   Quiet, panel-scoped: a detail fetch failure must read as "this panel",
   never as "the page broke". */
.detail-inner .dp-loading { color: var(--muted-2); font: 500 12px/1.6 var(--sans); padding: 8px 0; }
.detail-inner .dp-retry { color: var(--muted); font: 500 12px/1.6 var(--sans); padding: 8px 0; }
.detail-inner .dp-retry-btn {
  margin-left: 8px; cursor: pointer;
  font: 600 11px/1 var(--sans); color: var(--blue);
  background: var(--blue-soft); border: 1px solid var(--border);
  padding: 6px 12px; border-radius: 8px;
}
.vkf-note { font: 600 11.5px/1 var(--sans); color: var(--muted-2); }

/* ================================================== VIVEK paper track record */
.track {
  margin: 4px 0 18px; padding: 14px 16px; border-radius: 14px;
  background: var(--panel); border: 1px solid var(--border);
}
.trk-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.trk-label { font: 700 10px/1 var(--sans); letter-spacing: 1.2px; text-transform: uppercase; color: var(--muted); }
.trk-headline { font: 800 14px/1.2 var(--mono); color: var(--text); }
.trk-headline.pos { color: var(--green); } .trk-headline.neg { color: var(--red); }
.trk-open { margin-left: auto; font: 600 11px/1 var(--mono); color: var(--muted-2); }
.trk-more { font: 700 11px/1 var(--sans); color: var(--blue); text-decoration: none; }
.trk-more:hover { text-decoration: underline; }
.trk-groups { display: flex; gap: 22px; flex-wrap: wrap; margin-top: 12px; }
.trk-group { display: flex; flex-direction: column; gap: 6px; }
.trk-title { font: 700 9.5px/1 var(--sans); letter-spacing: 1px; text-transform: uppercase; color: var(--muted-2); }
.trk-pill { display: flex; align-items: baseline; gap: 7px; }
.trk-k { min-width: 56px; font: 600 12px/1.3 var(--sans); color: var(--text-2); }
.trk-r { font: 800 12.5px/1 var(--mono); color: var(--text); font-variant-numeric: tabular-nums; }
.trk-r.pos { color: var(--green); } .trk-r.neg { color: var(--red); }
.trk-sub { font: 600 10.5px/1 var(--mono); color: var(--muted-2); }
.trk-note { margin-top: 12px; font: 500 11px/1.5 var(--sans); color: var(--muted-2); max-width: 760px; }

/* ======================================================================= PULSE */
.pulse {
  display: flex; align-items: stretch; border-radius: var(--radius);
  background: var(--panel); margin-bottom: 16px; overflow: hidden; box-shadow: var(--shadow);
}
.pulse-label {
  display: grid; place-items: center; gap: 5px; padding: 0 12px;
  font: 700 10px/1 var(--mono); letter-spacing: 0.14em; color: var(--green);
  border-right: 1px solid var(--border); background: var(--fill-2);
}
.pulse-delayed {
  font: 600 8.5px/1 var(--mono); letter-spacing: 0.02em; color: var(--muted-2);
  background: var(--fill); padding: 3px 5px; border-radius: 3px; white-space: nowrap;
}
.pulse-track { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(140px,1fr); overflow-x: auto; flex: 1; scrollbar-width: thin; scrollbar-color: var(--border-2) transparent; }
.pulse-track::-webkit-scrollbar { height: 4px; }
.pulse-track::-webkit-scrollbar-thumb { background: var(--border-2); border-radius: 2px; }
.pulse-track::-webkit-scrollbar-track { background: transparent; }
.pulse-item { padding: 11px 14px; border-right: 1px solid var(--border-soft); min-width: 0; }
.pulse-item:last-child { border-right: 0; }
.pi-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.pi-key { font: 600 9.5px/1 var(--mono); letter-spacing: 0.08em; color: var(--muted); }
.pi-val { font: 600 12px/1 var(--mono); color: var(--text); }
.pi-change { font: 600 11.5px/1 var(--mono); margin-top: 6px; display: flex; align-items: baseline; gap: 7px; }
.pi-change.up { color: var(--green); } .pi-change.down { color: var(--red); }
.pi-5d { font-size: 10px; color: var(--muted); font-weight: 500; }
.pi-spark { margin-top: 6px; display: block; width: 100%; height: 22px; }

/* ===================================================================== stats */
.stats {
  display: grid; grid-template-columns: repeat(4,1fr); gap: 0;
  background: var(--panel); border-radius: var(--radius);
  box-shadow: var(--shadow); margin-bottom: 18px; overflow: hidden;
}
.stat-card {
  background: transparent; border-radius: 0; box-shadow: none;
  padding: 20px 22px;
  border-right: 0.5px solid var(--separator);
}
.stat-card:last-child { border-right: 0; }
.stat-label { font: 600 10px/1 var(--mono); color: var(--muted); letter-spacing: 0.1em; text-transform: uppercase; }
.stat-value { font: 700 26px/1.15 var(--mono); letter-spacing: -0.02em; margin-top: 11px; color: var(--text); }
.accent-green { color: var(--green); } .accent-orange { color: var(--orange); }

/* ================================================================= view tabs */
.view-tabs { display: flex; gap: 22px; border-bottom: 1px solid var(--border); margin-bottom: 14px; }
.view-tab {
  appearance: none; border: 0; background: transparent; cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px; color: var(--muted);
  font: 600 12px/1 var(--mono); letter-spacing: 0.06em; text-transform: uppercase;
  padding: 4px 0 12px; margin-bottom: -1px;
  border-bottom: 2px solid transparent; transition: color .15s;
}
.view-tab:hover { color: var(--text-2); }
.view-tab.is-active { color: var(--green); border-bottom-color: var(--green); }
.watch-count { font: 600 10px/1 var(--mono); background: var(--fill); border: 1px solid var(--border); color: var(--muted); padding: 2px 6px; border-radius: 3px; }

/* ================================================================== controls */
.controls { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
.control-group { display: inline-flex; align-items: center; }
.control-label { display: none; }
.seg { display: inline-flex; gap: 2px; padding: 2px; background: var(--fill-2); border: 1px solid var(--border); border-radius: var(--radius-sm); }
.seg-btn {
  appearance: none; border: 0; cursor: pointer; background: transparent;
  color: var(--muted); font: 600 11.5px/1 var(--mono); letter-spacing: 0.03em;
  padding: 7px 12px; border-radius: 4px; display: inline-flex; align-items: center; gap: 6px; transition: all .15s;
}
/* Active segment (grade tabs AND sorts) — raised panel with an inset ring. */
.seg-btn.is-active { background: var(--panel-3); color: var(--text); box-shadow: inset 0 0 0 1px var(--border-2); }
.seg-btn:not(.is-active):hover { color: var(--text-2); }
.seg-count { font: 600 9.5px/1 var(--mono); background: var(--fill-2); border: 1px solid var(--border); color: var(--muted); padding: 2px 5px; border-radius: 3px; }
.seg-btn.is-active .seg-count { background: var(--green-soft); border-color: rgba(47,208,127,0.35); color: var(--green); }

/* Sort direction arrow on the active sort button. */
.sort-arrow { font-size: 0.92em; font-weight: 700; opacity: 0.95; }

/* ================================================================ EMA legend */
.ema-legend { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; background: transparent; border-radius: 0; padding: 0 0 12px; margin-bottom: 12px; box-shadow: none; border-bottom: 1px solid var(--border); min-height: 24px; /* CLS #1: reserved pre-data */ }
.legend-tag { font: 700 10px/1 var(--mono); letter-spacing: 0.12em; color: var(--muted); }
.ema-dot { display: inline-flex; align-items: center; gap: 6px; font: 600 11px/1 var(--mono); color: var(--text-2); }
.ema-dot i { width: 8px; height: 8px; border-radius: 2px; display: inline-block; }

/* VIVEK entry-type filter chips — "200 SMA interaction" */
.vk-filters { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; }
.vkf-label { font: 700 10px/1 var(--mono); letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); margin-right: 2px; }
.vkf-chip {
  appearance: none; cursor: pointer; border: 1px solid var(--border-2); background: var(--panel);
  color: var(--text-2); font: 600 11.5px/1 var(--mono); letter-spacing: 0.02em; padding: 7px 11px; border-radius: var(--radius-sm);
  display: inline-flex; align-items: center; gap: 7px; transition: all .15s;
}
.vkf-chip:hover { border-color: var(--blue); color: var(--text); }
.vkf-chip { touch-action: manipulation; }   /* remove tap delay / scroll-eats-tap on mobile */
.vkf-chip b { font-weight: 800; font-variant-numeric: tabular-nums; color: var(--muted); }
.vkf-chip.is-active { background: var(--blue); border-color: var(--blue); color: #fff; box-shadow: var(--shadow-pill); }
.vkf-chip.is-active b { color: rgba(255,255,255,0.85); }
/* Backtest quality tint on the entry-type chips: a left dot + tinted border.
   Active (blue) state still overrides these. */
.vkf-chip.q-green::before, .vkf-chip.q-amber::before, .vkf-chip.q-red::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0;
}
.vkf-chip.q-green { border-color: rgba(45,208,127,.55); }
.vkf-chip.q-green::before { background: var(--green); }
.vkf-chip.q-amber { border-color: rgba(255,176,32,.55); }
.vkf-chip.q-amber::before { background: #ffb020; }
.vkf-chip.q-red { border-color: rgba(255,91,91,.5); }
.vkf-chip.q-red::before { background: var(--red); }
.vkf-chip.is-active::before { background: #fff; }
.vkf-legend { font: 600 11px/1 var(--sans); color: var(--muted); margin: 0 2px; white-space: nowrap; }
/* thin divider between the entry-type chips and the toggles */
.vkf-sep { width: 1px; align-self: stretch; background: var(--border); margin: 2px 4px; }
.vkf-recent.is-active { background: var(--green); border-color: var(--green); }
.vkf-highconv { border-color: rgba(255,196,77,.6); color: #ffc44d; }
.vkf-highconv.is-active { background: #ffb020; border-color: #ffb020; color: #1a1205; }
.vkf-highconv.is-active b { color: rgba(0,0,0,0.6); }
@media (max-width: 560px) { .vkf-legend { display: none; } }
@media (max-width: 560px) {
  /* Wrap the chips onto multiple rows so every filter — including the High
     conviction / Triggered recently toggles on the right — is fully visible and
     tappable. (Previously this was a horizontal scroll strip, which pushed those
     toggles off-screen and ate taps as scroll gestures on phones.) */
  .vk-filters { gap: 6px; flex-wrap: wrap; }
  .vkf-label { display: none; }
  .vkf-sep { display: none; }
}

/* ======================================================================= rows */
.rows { display: flex; flex-direction: column; gap: 14px;
  /* CLS #1: the list holds most-of-a-viewport from the first frame, so the
     footer paints in (roughly) its final place instead of being shoved down
     when the rows arrive — this was ~0.38 of the measured shift. */
  min-height: 72vh; }

/* staggered entrance — replays on every list render (tab / sort / market
   switch and on fresh data load) so content settles in rather than snapping. */
@keyframes rowIn {
  from { opacity: 0; transform: translateY(9px) scale(0.992); }
  to   { opacity: 1; transform: none; }
}

.row-wrap {
  background: var(--panel);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow);
  transition: box-shadow .22s ease, transform .22s ease;
  will-change: transform;
  /* backwards fill holds the start frame during the stagger delay, then
     releases so :hover transforms keep working once the entrance finishes. */
  animation: rowIn .2s cubic-bezier(0.22, 1, 0.36, 1) backwards;
  animation-delay: calc(var(--row-i, 0) * 26ms);
}
.row-wrap:hover {
  box-shadow: var(--shadow-hover);
  transform: translateY(-1px);
}
.row-wrap.open {
  box-shadow: var(--shadow-open);
  transform: none;
}

/* 3-column grid: grade strip | main content | right actions */
.row {
  display: grid;
  grid-template-columns: 68px 1fr auto;
  align-items: stretch;
  cursor: pointer;
  min-height: 90px;
  user-select: none;
}

/* Left colored grade strip */
.row-grade {
  display: flex;
  align-items: center;
  justify-content: center;
  background: color-mix(in srgb, var(--grade-color, var(--grade-c)) 9%, transparent);
  border-right: 1px solid color-mix(in srgb, var(--grade-color, var(--grade-c)) 30%, transparent);
  font: 700 14px/1 var(--mono);
  letter-spacing: 0.02em;
  color: var(--grade-color, var(--grade-c));
  flex-shrink: 0;
  transition: background .15s;
}
.row-wrap:hover .row-grade {
  background: color-mix(in srgb, var(--grade-color, var(--grade-c)) 15%, transparent);
}

/* Center: ticker + chips */
.row-main {
  padding: 20px 20px 18px;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 9px;
}
.row-line1 {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: nowrap;
  overflow: hidden;
}
.tkr {
  font: 700 17px/1 var(--mono);
  letter-spacing: 0.01em;
  color: var(--text);
  text-decoration: none;
  transition: color .15s;
}
.tkr:hover { color: var(--green); }

.badge { font: 600 9px/1 var(--mono); letter-spacing: 0.06em; text-transform: uppercase; padding: 4px 7px; border-radius: 3px; white-space: nowrap; border: 1px solid transparent; }
/* Direction tag — prominent and explicitly colour-coded: LONG green, SHORT red */
.badge.dir { font: 700 10px/1 var(--mono); letter-spacing: 0.08em; padding: 5px 9px; }
.badge.dir.long  { border-color: rgba(47,208,127,0.3); }
.badge.dir.short { border-color: rgba(255,91,91,0.3); }
.badge.dir.long  { color: var(--green); background: var(--green-soft); }
.badge.dir.short { color: var(--red);   background: var(--red-soft); }
.badge.sector { color: var(--text-2); background: var(--fill); }
.badge.liq-liquid { color: var(--green); background: var(--green-soft); }
.badge.liq-ok { color: var(--muted); background: var(--fill); }
.badge.seccount { color: var(--orange); background: var(--orange-soft); }
.badge.mcap       { color: var(--text-2); background: var(--fill); font-weight: 700; }
.badge.mcap-small { color: var(--orange); background: var(--orange-soft); font-weight: 700; }
.badge.mcap-hot   { color: var(--red);    background: var(--red-soft);    font-weight: 700; }
.cname { font-size: 14px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 1; min-width: 0; }
.rprice { font: 600 17px/1 var(--mono); letter-spacing: -0.01em; color: var(--text); flex-shrink: 0; }

.row-chips { display: flex; flex-wrap: wrap; gap: 5px; }
.row-chips:empty { display: none; }
/* VIVEK screening badges on the row */
.rbadge { font: 600 9.5px/1 var(--mono); letter-spacing: 0.05em; padding: 4px 7px; border-radius: 3px;
  white-space: nowrap; border: 1px solid transparent; }
.rbadge.fresh  { color: var(--green);  background: var(--green-soft);
  border-color: color-mix(in srgb, var(--green) 32%, transparent); }
.rbadge.trig   { color: var(--blue);   background: var(--blue-soft); }
.rbadge.wk     { color: var(--orange); background: var(--orange-soft); }
.rbadge.struct { color: var(--text-2); background: var(--fill); }
.rbadge.hiconv { color: #1a1205; background: #ffb020; font-weight: 800;
  border-color: color-mix(in srgb, #ffb020 60%, transparent); }
.rbadge.fundwarn { color: var(--red); background: var(--red-soft); font-weight: 800;
  border-color: color-mix(in srgb, var(--red) 40%, transparent); }
/* Longs / Shorts direction filter chips */
.vkf-long  { color: var(--green); border-color: color-mix(in srgb, var(--green) 40%, transparent); }
.vkf-short { color: var(--red);   border-color: color-mix(in srgb, var(--red) 40%, transparent); }
.vkf-long.is-active  { background: var(--green); border-color: var(--green); color: #fff; }
.vkf-short.is-active { background: var(--red);   border-color: var(--red);   color: #fff; }
.vkf-long.is-active b, .vkf-short.is-active b { color: rgba(255,255,255,0.85); }
/* a direction with nothing to show in the current view — dimmed + not clickable */
.vkf-chip.vkf-off, .vkf-chip:disabled { opacity: 0.38; cursor: default; }
.vkf-chip.vkf-off:hover { border-color: currentColor; }
.chip { font: 500 9.5px/1 var(--mono); letter-spacing: 0.05em; color: var(--blue); background: var(--blue-soft); border: 1px solid rgba(77,163,255,0.25); padding: 4px 7px; border-radius: 3px; white-space: nowrap; }
.chip.weekly { color: var(--green); background: var(--green-soft); border-color: rgba(47,208,127,0.25); }
.chip.warn { color: var(--red); background: var(--red-soft); border-color: rgba(255,91,91,0.3); }
.chip.info { color: var(--orange); background: var(--orange-soft); border-color: rgba(255,178,36,0.3); }

/* Right: sparkline + score/rr + actions */
.row-right {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 14px 12px 8px;
  flex-shrink: 0;
}

.row-spark {
  display: block;
  width: 64px;
  height: 28px;
  flex-shrink: 0;
  text-decoration: none;
  opacity: 0.82;
  transition: opacity .16s;
}
.row-spark:hover { opacity: 1; }
.row-spark svg { width: 100%; height: 100%; display: block; }

.row-kpis {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 5px;
}
.rk-score {
  font: 700 16px/1 var(--mono);
  color: var(--text);
  letter-spacing: -0.01em;
}
.rk-max { font-size: 10.5px; font-weight: 500; color: var(--muted); }
.rk-rr {
  font: 600 10.5px/1 var(--mono);
  padding: 4px 8px;
  border-radius: 3px;
  background: var(--green-soft);
  border: 1px solid rgba(47,208,127,0.3);
  color: var(--green);
  white-space: nowrap;
}
.rk-rr.low { border-color: rgba(255,91,91,0.3); }
.rk-rr.low { background: var(--red-soft); color: var(--red); }

.t-star {
  appearance: none; border: 0; background: transparent; cursor: pointer;
  color: var(--muted-2); padding: 7px; line-height: 0;
  transition: color .15s, transform .12s;
  border-radius: 8px;
  flex-shrink: 0;
}
.t-star:hover { color: var(--orange); transform: scale(1.18); }
.t-star.starred { color: var(--orange); }

.row-copy-debug {
  appearance: none; border: 0; background: transparent; cursor: pointer;
  color: var(--muted-2); padding: 4px; line-height: 0;
  transition: color .15s; display: none; border-radius: 6px;
}
body.debug-mode .row-copy-debug { display: inline-flex; }
.row-copy-debug:hover { color: var(--blue); }

.row-expand {
  appearance: none; border: 0; background: transparent; cursor: pointer;
  color: var(--muted-2); padding: 7px; line-height: 0; border-radius: 8px;
  transition: color .18s, transform .3s cubic-bezier(0.4,0,0.2,1), background .15s;
  flex-shrink: 0;
}
.row-expand:hover { color: var(--text); background: var(--fill); }
.row-wrap.open .row-expand { transform: rotate(180deg); color: var(--text); }

/* ======================================================= detail animation */
.detail-anim {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.2s cubic-bezier(0.22, 1, 0.36, 1);   /* #56: <=200ms */
}
.row-wrap.open .detail-anim { grid-template-rows: 1fr; }
.detail-inner { overflow: hidden; min-height: 0; }

/* ease the content in — a gentle lift + fade, timed to land just after the
   panel has finished opening so it feels deliberate rather than abrupt. */
.detail-inner > .row-detail,
.detail-inner > .debug-panel {
  opacity: 0;
  transform: translateY(-6px);
  transition: opacity 0.18s ease 0.04s, transform 0.2s cubic-bezier(0.22, 1, 0.36, 1) 0.04s;   /* #56 */
}
.row-wrap.open .detail-inner > .row-detail,
.row-wrap.open .detail-inner > .debug-panel { opacity: 1; transform: none; }

/* ====================================================== detail panel
   Calmer, more premium layout: a dominant hero (Grade · Score · Entry · Stop ·
   Target · R:R), then quiet, well-spaced secondary sections. Colour lives on the
   numbers — surfaces stay neutral — so the key metrics read instantly without
   visual noise. All class names are unchanged so the markup is untouched. */
.row-detail { padding: 4px 26px 40px; }
.row-detail > * + * { margin-top: 24px; }   /* one consistent vertical rhythm */

/* ── hero trade card — the focal point ── */
.detail-hero {
  display: grid;
  grid-template-columns: 116px 1fr;
  border-radius: var(--radius);
  overflow: hidden;
  margin: 22px 0 0;
  background: var(--panel);
  box-shadow: var(--shadow);
  border: 0.5px solid var(--border-soft);
}
/* Left: Grade + Score — a calm colour panel (soft gradient, not a flat slab) */
.dh-grade-block {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 26px 14px;
  gap: 10px;
  background: color-mix(in srgb, var(--gc, var(--grade-c)) 10%, var(--panel));
  border-right: 1px solid color-mix(in srgb, var(--gc, var(--grade-c)) 35%, transparent);
}
.dh-grade-lbl {
  font: 700 9px/1 var(--mono);
  letter-spacing: 0.16em;
  color: var(--muted);
  text-transform: uppercase;
}
.dh-grade-val {
  font: 700 46px/0.9 var(--mono);
  letter-spacing: -0.02em;
  color: var(--gc, var(--grade-c));
}
.dh-score-val {
  font: 600 11px/1 var(--mono);
  letter-spacing: 0.02em;
  color: var(--gc, var(--grade-c));
  background: color-mix(in srgb, var(--gc, var(--grade-c)) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--gc, var(--grade-c)) 40%, transparent);
  padding: 4px 8px;
  border-radius: 3px;
  font-variant-numeric: tabular-nums;
}
/* Right: Entry · Stop · Target · R:R — neutral cells, colour on the value only */
.dh-metrics {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  background: var(--separator);
}
.dh-metric {
  background: var(--panel);
  padding: 24px 20px;
  display: flex;
  flex-direction: column;
  gap: 11px;
  min-width: 0;
}
.dh-lbl {
  font: 600 9.5px/1 var(--mono);
  letter-spacing: 0.12em;
  color: var(--muted);
  text-transform: uppercase;
}
.dh-val {
  font: 700 22px/1 var(--mono);
  letter-spacing: -0.02em;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.dh-val.low { color: var(--red); }
.dh-unit { font-size: 13px; font-weight: 600; color: var(--muted); margin-left: 1px; }
.dh-sub { font: 600 12px/1 var(--sans); font-variant-numeric: tabular-nums; }
.dh-sub.pos { color: var(--green); }
.dh-sub.neg { color: var(--red); }
/* Meaning is carried by the coloured value + sub-%, not a tinted background. */
.dh-stop   .dh-val { color: var(--red); }
.dh-target .dh-val { color: var(--green); }
.dh-rr     .dh-val { color: var(--blue); }

/* Signal chips — quiet, roomy */
.detail-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
}

/* metadata bar — sector · mcap · count, very quiet just under the hero */
.detail-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.meta-item {
  font: 500 10.5px/1 var(--mono);
  letter-spacing: 0.03em;
  color: var(--muted);
  padding: 5px 9px;
  background: var(--fill-2);
  border: 1px solid var(--border);
  border-radius: 3px;
}
.meta-item.accent-orange { color: var(--orange); background: var(--orange-soft); }

/* analysis — clean, readable callout with a grade-coloured edge */
.rd-analysis {
  padding: 18px 22px;
  background: var(--fill-2);
  border-radius: var(--radius-md);
  border-left: 3px solid var(--grade-color, var(--blue));
}
.rd-tag { font: 700 11.5px/1 var(--sans); letter-spacing: 0.08em; color: var(--muted); margin-bottom: 8px; }
.rd-analysis p { margin: 0; font: 400 16px/1.7 var(--sans); color: var(--text-2); }
.rd-k { font: 700 12px/1 var(--sans); letter-spacing: 0.06em; color: var(--muted); }

/* price strip — secondary market context, deliberately understated */
.detail-prices {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  background: var(--separator);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.dp-cell {
  background: var(--panel);
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.dp-lbl {
  font: 600 10px/1 var(--sans);
  letter-spacing: 0.07em;
  color: var(--muted);
  text-transform: uppercase;
}
.dp-val {
  font: 500 13px/1.1 var(--mono);
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.dp-val .pcell-pct { font-size: 11px; font-weight: 600; margin-left: 3px; }
.dp-val.pct-up { color: var(--green); }
.dp-val.pct-down { color: var(--red); }

/* ── secondary clusters: each a calm, generously-padded card ── */
.rd-group {
  background: var(--fill-2);
  border: 0.5px solid var(--border-soft);
  border-radius: var(--radius-md);
  padding: 4px 22px 22px;
}
.rd-group > .rd-volume-bare:last-child,
.rd-group > .rd-fast:last-child,
.rd-group > .rd-structure:last-child { border-bottom: 0; }
.rd-section {
  display: flex;
  align-items: center;
  gap: 10px;
  font: 700 11px/1 var(--sans);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 22px 0 15px;
  border-bottom: 0.5px solid var(--separator);
  margin-bottom: 4px;
}
.rd-section-note {
  font: 600 11px/1 var(--sans);
  letter-spacing: 0;
  text-transform: none;
  color: var(--muted);
}
.rd-section-note.green { color: var(--green); }
.rd-section-note.muted { color: var(--muted); }
.rd-section-note.accent-orange { color: var(--orange); }
.rd-section-note.pct-down { color: var(--red); }
.rd-section-note:first-of-type { margin-left: auto; }

/* key-level rows */
.rd-levels { padding: 0; }
.dl-row {
  display: grid;
  grid-template-columns: 140px 1fr auto;
  align-items: center;
  gap: 12px;
  padding: 16px 0;
  border-bottom: 0.5px solid var(--border-soft);
}
.rd-levels .dl-row:last-child { border-bottom: 0; }
.dl-label { font: 500 13px/1 var(--mono); color: var(--text-2); }
.dl-label.red { color: var(--red); }
.dl-label.green { color: var(--green); }
.dl-val { font: 600 16px/1 var(--mono); color: var(--text); font-variant-numeric: tabular-nums; }
.dl-pct { font: 600 12px/1 var(--mono); text-align: right; font-variant-numeric: tabular-nums; }

/* trailing stop — quiet accent row */
.rd-trail {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  padding: 15px 0 4px;
  margin-top: 8px;
  border-top: 0.5px solid var(--separator);
}
.rd-trail-label { font: 600 13px/1 var(--sans); color: var(--orange); flex-shrink: 0; }
.rd-trail-val { font: 700 17px/1 var(--sans); color: var(--orange); font-variant-numeric: tabular-nums; }
.rd-trail-note { font: 500 12px/1 var(--sans); color: var(--muted); margin-left: auto; }

/* volume / rsi info rows */
.rd-volume {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px 16px;
  margin-bottom: 10px;
  background: var(--fill-2);
  border-radius: var(--radius-md);
}
.rd-volume-bare {
  padding: 16px 0;
  margin-bottom: 0;
  background: transparent;
  border-radius: 0;
  border-bottom: 0.5px solid var(--border-soft);
}
.rd-vol { font: 700 15px/1.2 var(--sans); color: var(--text); }
.rd-vol.green { color: var(--green); }
.rd-vol-note { font: 500 12px/1 var(--sans); color: var(--muted); margin-left: auto; }

/* EMA section */
.rd-ema { padding: 14px 16px; margin-bottom: 10px; background: var(--fill-2); border-radius: var(--radius-md); }
.rd-ema-head { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
.rd-ema-head .rd-spread { margin-left: auto; font: 500 12px/1 var(--sans); color: var(--muted); }
.rd-ladder { display: flex; align-items: center; gap: 8px; padding: 16px 0 12px; }
.el-ema { font: 700 15px/1 var(--sans); }
.el-gt { color: var(--muted-2); }
.rd-fast { display: grid; gap: 14px; padding: 6px 0 16px; border-bottom: 0.5px solid var(--border-soft); }
.fl-row { display: grid; grid-template-columns: 1fr auto auto; align-items: center; gap: 16px; }
.fl-label { font: 500 13px/1 var(--sans); color: var(--text-2); }
.fl-ema { font: 700 11px/1 var(--sans); }
.fl-val { font: 600 15px/1 var(--sans); color: var(--text); font-variant-numeric: tabular-nums; }
.fl-pct { font: 600 13px/1 var(--sans); font-variant-numeric: tabular-nums; }

/* structure */
.rd-structure { padding: 16px 0 4px; }
.rd-swings { margin-top: 10px; font: 400 13px/1.75 var(--sans); color: var(--text-2); }

/* utility colours */
.green { color: var(--green); }
.muted { color: var(--muted); }
.pct-up { color: var(--green); }
.pct-down { color: var(--red); }

/* ================================================================ placeholders */
.placeholder {
  text-align: center; padding: 56px 24px; color: var(--muted);
  background: var(--panel); border-radius: var(--radius); box-shadow: var(--shadow);
}
.placeholder h3 { margin: 0 0 8px; color: var(--text); font-weight: 700; }
.placeholder p { margin: 0; font-size: 15px; }
.skeleton {
  height: 72px; background: var(--panel); border-radius: var(--radius);
  box-shadow: var(--shadow); position: relative; overflow: hidden;
}
.skeleton::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent 0%, var(--fill) 50%, transparent 100%);
  animation: shimmer 1.4s ease-in-out infinite;
}
@keyframes shimmer { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } }

/* ========================================================= search trigger */
.search-trigger {
  appearance: none; border: 0; cursor: pointer; background: transparent;
  color: var(--muted); padding: 7px; border-radius: 8px; line-height: 0;
  transition: color .15s, background .15s;
}
.search-trigger:hover { color: var(--text); background: var(--fill); }

.refresh-timer {
  font: 600 11px/1 var(--mono); letter-spacing: 0.04em;
  color: var(--muted); background: var(--fill-2); border: 1px solid var(--border);
  padding: 5px 9px; border-radius: 3px; white-space: nowrap;
  min-width: 44px; text-align: center;
}

/* ========================================================== search overlay */
.search-overlay {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(0,0,0,0.45);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  display: flex; flex-direction: column; align-items: center;
  padding-top: 80px;
}
.search-overlay[hidden] { display: none; }
.search-box {
  display: flex; align-items: center; gap: 10px;
  background: var(--panel); border-radius: var(--radius-md);
  padding: 12px 16px; width: min(94vw, 560px);
  box-shadow: 0 24px 64px rgba(0,0,0,.38);
  border: 1px solid var(--separator);
}
.search-icon { color: var(--muted); flex-shrink: 0; }
.search-input {
  flex: 1; appearance: none; border: 0; background: transparent;
  font: 500 16px/1 var(--sans); color: var(--text); outline: none;
}
.search-input::placeholder { color: var(--muted); }
.search-esc {
  font: 600 10.5px/1 var(--sans); color: var(--muted); background: var(--fill);
  border: 1px solid var(--border); padding: 4px 7px; border-radius: 6px;
}
.search-results {
  width: min(94vw, 560px); background: var(--panel); border-radius: var(--radius-md);
  margin-top: 8px; overflow: hidden; box-shadow: 0 24px 64px rgba(0,0,0,.28);
  border: 1px solid var(--separator);
}
.sr-row {
  display: grid; grid-template-columns: 32px 80px 1fr auto;
  align-items: center; gap: 10px; padding: 11px 16px;
  text-decoration: none; color: var(--text);
  border-bottom: 0.5px solid var(--separator); transition: background .1s;
}
.sr-row:last-child { border-bottom: 0; }
.sr-row:hover { background: var(--panel-2); }
/* #32: cancel button (desktop uses Esc; this shows on mobile), recent chips, hint */
.search-cancel { display: none; appearance: none; border: 0; background: transparent;
  color: var(--blue); font: 700 16px/1 var(--sans); padding: 10px 4px; cursor: pointer; }
.sr-hint { padding: 16px; font: 500 13px/1.5 var(--sans); color: var(--muted); }
.sr-recent { padding: 14px 16px 16px; }
.sr-recent-hd { font: 700 10.5px/1 var(--sans); letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted-2); margin-bottom: 10px; }
.sr-recent-row { display: flex; flex-wrap: wrap; gap: 8px; }
.sr-recent-chip { display: inline-flex; align-items: center; gap: 6px; text-decoration: none;
  font: 800 13px/1 var(--sans); color: var(--text); background: var(--fill-2);
  border: 1px solid var(--border); border-radius: 999px; padding: 9px 13px; }
.sr-recent-chip:hover { border-color: var(--blue); }
.sr-recent-mkt { font: 700 9px/1 var(--mono); color: var(--muted-2); letter-spacing: 0.05em; }
@media (max-width: 680px) {
  /* Full-screen search sheet — no dim-behind, the input + results own the
     viewport, and a big Cancel sits beside the field. */
  .search-overlay { padding-top: 0; background: var(--bg); backdrop-filter: none; -webkit-backdrop-filter: none; }
  .search-box { width: 100%; border-radius: 0; border: 0; border-bottom: 1px solid var(--separator);
    box-shadow: none; padding: 14px 14px calc(14px + env(safe-area-inset-top, 0)); padding-top: max(14px, env(safe-area-inset-top, 0px)); gap: 8px; }
  .search-esc { display: none; }
  .search-cancel { display: inline-block; flex: 0 0 auto; }
  .search-results { width: 100%; border-radius: 0; border: 0; box-shadow: none; margin-top: 0;
    flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch; }
  .sr-recent-chip { padding: 11px 15px; }   /* ≥44px-ish tap target */
}
.sr-grade { font: 800 11.5px/1 var(--sans); }
.sr-sym { font: 700 14px/1 var(--sans); letter-spacing: -0.01em; }
.sr-name { font: 500 13px/1 var(--sans); color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sr-price { font: 600 13px/1 var(--sans); color: var(--text-2); text-align: right; }
.sr-empty { padding: 16px; text-align: center; color: var(--muted); font-size: 14px; }

/* ============================================================ debug panel */
.row-copy-debug { display: none; }
body.debug-mode .row-copy-debug { display: inline-flex; }

.debug-panel { display: none; }
body.debug-mode .debug-panel {
  display: block; margin: 0 18px 14px; padding: 12px 14px;
  background: rgba(255,255,255,0.03); border: 1px dashed var(--border-2);
  border-radius: var(--radius-sm);
  font-family: var(--mono);
}
.dbg-title {
  font: 700 10px/1 monospace; letter-spacing: 0.1em; color: var(--orange);
  margin-bottom: 8px; text-transform: uppercase;
}
.dbg-row { display: flex; gap: 12px; padding: 3px 0; border-bottom: 0.5px solid var(--border-soft); }
.dbg-row:last-child { border-bottom: 0; }
.dbg-k { font: 500 11.5px/1.4 monospace; color: var(--muted); min-width: 110px; flex-shrink: 0; }
.dbg-v { font: 600 11.5px/1.4 monospace; color: var(--text-2); word-break: break-all; }

/* ================================================================== footer */
.site-footer { text-align: center; padding: 28px 20px 44px; }
.disclaimer { color: var(--muted); font-size: 13.5px; margin: 0 0 6px; }
.credit { color: var(--muted-2); font-size: 12.5px; margin: 0; }

/* ===================================================== micro-interactions */
/* tactile press feedback — controls dip slightly when tapped */
.seg-btn, .scan-btn, .market-btn, .view-tab {
  transition: all .18s, transform .08s ease;
}
.seg-btn:active, .scan-btn:active, .market-btn:active,
.view-tab:active, .reload-btn:active, .search-trigger:active,
.t-star:active, .row-expand:active { transform: scale(0.94); }
.reload-btn { transition: filter .15s, opacity .15s, transform .08s ease; }
.search-trigger { transition: color .15s, background .15s, transform .08s ease; }

/* row tap settles inward a touch before the detail opens */
.row:active { transform: scale(0.995); }
.row { transition: transform .12s ease; }

/* segmented-control active pill eases in rather than snapping */
.seg-btn.is-active, .market-btn.is-active, .scan-btn.is-active {
  transition: background .22s cubic-bezier(0.22,1,0.36,1), color .18s, box-shadow .22s, transform .08s ease;
}

/* soft entrance for the empty / no-data placeholder */
@keyframes fadeUp {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}
.placeholder { animation: fadeUp .2s cubic-bezier(0.22,1,0.36,1) backwards; }

/* search overlay: backdrop fades, panel rises into place */
@keyframes overlayIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes searchBoxIn {
  from { opacity: 0; transform: translateY(-14px) scale(0.97); }
  to   { opacity: 1; transform: none; }
}
.search-overlay:not([hidden]) { animation: overlayIn .2s ease; }
.search-overlay:not([hidden]) .search-box {
  animation: searchBoxIn .2s cubic-bezier(0.22,1,0.36,1);
}
.sr-row { transition: background .14s ease, transform .12s ease; }
.sr-row:active { transform: scale(0.99); }

/* honour reduced-motion: keep things instant for users who ask for it */
/* #94: kill ALL motion for users who ask for it — shimmer, entrance slides,
   chevron spins, pulses, hover lifts — across every component, not just the
   handful listed below. The near-zero durations neutralise animations and
   transitions everywhere; the targeted rules below additionally cancel the
   static transforms that :active/entrance states apply. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .row-wrap, .placeholder, .search-overlay:not([hidden]),
  .search-overlay:not([hidden]) .search-box { animation: none; }
  .detail-anim { transition: grid-template-rows .01ms; }
  .detail-inner > .row-detail, .detail-inner > .debug-panel { transition: none; transform: none; }
  .row:active, .seg-btn:active, .scan-btn:active, .market-btn:active,
  .view-tab:active, .reload-btn:active, .mn-row:hover { transform: none; }
}

/* ============================================================== responsive */
@media (max-width: 1200px) {
  .stats { grid-template-columns: repeat(2,1fr); }
  .stat-card:nth-child(2) { border-right: 0; }
  .stat-card:nth-child(1), .stat-card:nth-child(2) { border-bottom: 0.5px solid var(--separator); }
}
@media (max-width: 880px) {
  .topbar { flex-wrap: wrap; gap: 10px; padding: 11px 16px; }
  /* Market switch is the primary control — keep it FIRST in the nav so ASX /
     NASDAQ / CRYPTO stay visible (order:3 buried it off-screen right once the
     nav became a horizontal scroll strip on phones). */
  .market-switch { order: -1; flex-shrink: 0; }
  .cname { max-width: 130px; }
}
@media (max-width: 1760px) {
  /* Row 1 holds clocks + quote + nav + brand. The single-column clock stack
     is ~280px, so it fits down to ~1760px; below this it's dropped first and
     the quote keeps its room; brand · quote · nav stay. */
  .topbar-clocks { display: none; }
}
@media (max-width: 1600px) {
  /* below here the full-size nav + brand need the width — retire the quote
     (it returns above 1600px where there's room for it to be legible) */
  .topbar-quote { display: none; }
}
@media (max-width: 560px) {
  /* keep the bigger brand prominent but sized to fit a phone next to the tabs */
  .topbar-brand .brand-mark { width: 38px; height: 38px; border-radius: 10px; }
  .topbar-brand .brand-mark svg { width: 23px; height: 23px; }
  .topbar-brand .brand h1 { font-size: 21px; }
  .topbar-brand .brand-sub { font-size: 9.5px; letter-spacing: 0.28em; }
}
@media (max-width: 768px) {
  .topbar-row1 { padding: 9px 12px; gap: 10px; }
  .topbar-row2 { padding: 6px 12px 7px; }
  .topbar { padding: 10px 14px; gap: 8px; } /* legacy single-row pages */
  .brand h1 { font-size: 14px; }
  .refresh-timer { display: none; }
  /* Keep every nav link reachable on mobile: scroll the row horizontally
     instead of hiding all but the last link (which buried Journal / News). */
  .topbar-nav {
    overflow-x: auto; -webkit-overflow-scrolling: touch;
    scrollbar-width: none; -ms-overflow-style: none;
    margin-left: 0; flex: 1; justify-content: flex-start;
  }
  .topbar-nav::-webkit-scrollbar { display: none; }
  .howto-link { padding: 8px 6px; }            /* taller tap target */
  .market-btn { padding: 8px 14px; }           /* taller tap target */
  /* Scan-type row scrolls as one strip; buttons keep their size + tap area. */
  .topbar-row2 { overflow-x: auto; scrollbar-width: none; }
  .topbar-row2::-webkit-scrollbar { display: none; }
  .scan-switch { flex: 0 0 auto; }
  .scan-btn { padding: 8px 13px; }
  .stats { grid-template-columns: repeat(2,1fr); }
  .stat-card:nth-child(2) { border-right: 0; }
  .stat-card:nth-child(1), .stat-card:nth-child(2) { border-bottom: 0.5px solid var(--separator); }
  .stat-value { font-size: 24px; }
  .row-spark { width: 52px; }
  /* roomier tap targets on the filter segments */
  .seg-btn { padding: 9px 13px; }
  .view-tab { padding: 6px 0 13px; }
}
@media (max-width: 600px) {
  .wrap { padding: 14px 12px 56px; }
  .row { grid-template-columns: 52px 1fr auto; min-height: 80px; }
  .row-main { padding: 15px 15px 13px; gap: 8px; }
  .row-right { padding: 12px 10px 12px 6px; gap: 6px; }
  .row-spark { width: 46px; height: 24px; }
  .tkr { font-size: 18px; }
  .rprice { font-size: 18px; }
  /* .cname display:none removed (v2 #27) — names now wrap to their own line on phones; see the Wave-4 block at the end of this file. */
  /* tighter, quieter secondary badges so the ticker + price stay the focus */
  .badge { font-size: 9.5px; padding: 3px 7px; }
  .row-chips { gap: 4px; }
  .chip { font-size: 10px; padding: 3px 7px; }
  /* filter + sort segments scroll as one strip instead of wrapping messily */
  .controls { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; gap: 8px; }
  .controls::-webkit-scrollbar { display: none; }
  .control-group { flex: 0 0 auto; }
  .ema-legend { gap: 10px; overflow-x: auto; scrollbar-width: none; }
  .ema-legend::-webkit-scrollbar { display: none; }
  .row-detail { padding: 4px 16px 24px; }
  /* hero: keep grade block, stack metrics 2×2 */
  .detail-hero { grid-template-columns: 84px 1fr; }
  .dh-grade-val { font-size: 46px; }
  .dh-grade-block { padding: 20px 10px; }
  .dh-metrics { grid-template-columns: repeat(2, 1fr); }
  .dh-metric { padding: 16px 16px; gap: 8px; }
  .dh-val { font-size: 20px; }
  .detail-prices { grid-template-columns: repeat(2, 1fr); }
  .rd-group { padding: 0 14px 16px; }
  .rd-section { padding: 16px 0 11px; font-size: 11px; }
  .dl-row { padding: 14px 0; }
  .dl-val { font-size: 16px; }
  .rd-levels .dl-row { grid-template-columns: 110px 1fr auto; }
  .fl-row { grid-template-columns: 1fr auto; }
  .fl-pct { display: none; }
  .rd-trail { padding: 12px 0 2px; }
  .rd-trail-val { font-size: 15px; }
  .rd-vol { font-size: 14px; }
  .rd-analysis { padding: 14px 16px; }
  .detail-meta { margin: -2px 0 16px; }
}
@media (max-width: 480px) {
  .topbar-row1 { flex-wrap: wrap; padding: 8px 12px; }
  .topbar-row2 { padding: 4px 12px 5px; overflow-x: auto; }
  .topbar { flex-wrap: wrap; } /* legacy single-row pages */
  .reload-btn .reload-label { display: none; }
  .reload-btn { padding: 0 10px; }
  .stats { grid-template-columns: 1fr 1fr; }
  .stat-card { padding: 16px 16px; }
  .stat-value { font-size: 22px; }
  .brand-mark { width: 28px; height: 28px; }
  .brand h1 { font-size: 13px; }
  .row-spark { display: none; }
  .row-right { gap: 5px; padding: 12px 10px 12px 4px; }
  .search-overlay { padding-top: 60px; }
  /* narrow grade block on very small screens */
  .detail-hero { grid-template-columns: 70px 1fr; }
  .dh-grade-val { font-size: 34px; }
  .dh-grade-block { padding: 16px 8px; }
}

/* ===================================================== VIVEK track-record page */
.trkp-head { margin: 6px 0 18px; }
.trkp-title { font: 800 22px/1.1 var(--sans); color: var(--text); display: flex; align-items: center; gap: 10px; }
.trkp-tag { font: 700 10px/1 var(--sans); letter-spacing: 1px; text-transform: uppercase;
  color: var(--muted); background: var(--fill); padding: 5px 8px; border-radius: 6px; }
.trkp-sub { font: 500 13px/1.6 var(--sans); color: var(--text-2); max-width: 820px; margin: 8px 0 0; }
.trkp-stats { margin-bottom: 22px; }
.trkp-section { margin: 0 0 26px; }
.trkp-h3 { font: 700 12px/1 var(--sans); letter-spacing: 0.6px; text-transform: uppercase;
  color: var(--muted); margin: 0 0 12px; display: flex; align-items: baseline; gap: 10px; }
.trkp-h3-sub { font-weight: 600; letter-spacing: 0; text-transform: none; color: var(--muted-2); font-size: 11px; }
.trkp-count { font: 700 11px/1 var(--mono); color: var(--text-2); background: var(--fill); padding: 4px 8px; border-radius: 20px; }

.trkp-breakdown { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 16px; }
.trkp-grp { background: var(--panel); border: 1px solid var(--border); border-radius: 14px; padding: 14px; }
.trkp-grp-title { font: 700 10px/1 var(--sans); letter-spacing: 1px; text-transform: uppercase; color: var(--muted-2); margin-bottom: 10px; }

.trkp-tablewrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.trkp-table { width: 100%; border-collapse: collapse; font: 600 12.5px/1.3 var(--sans); white-space: nowrap; }
.trkp-table th { font: 700 10px/1 var(--sans); letter-spacing: 0.5px; text-transform: uppercase;
  color: var(--muted-2); text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--border); }
.trkp-table td { padding: 9px 10px; border-bottom: 1px solid var(--separator); color: var(--text-2); }
.trkp-table tbody tr:hover { background: rgba(120,120,128,.06); }
.trkp-table .mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.trkp-table .pos { color: var(--green); }
.trkp-table .neg { color: var(--red); }
.trkp-table .trkp-k { font-weight: 700; color: var(--text); }
.trkp-table .trkp-r { font-family: var(--mono); font-weight: 800; }
.trkp-bd td, .trkp-bd th { padding: 7px 8px; }
.trkp-empty td { color: var(--muted-2); font-weight: 500; }
.trkp-type { font: 700 10.5px/1 var(--sans); color: var(--blue); background: var(--blue-soft); padding: 4px 7px; border-radius: 5px; }
.grade-Ap { color: var(--grade-aplus); } .grade-A { color: var(--grade-a); }

.trkp-equity { background: var(--panel); border: 1px solid var(--border); border-radius: 14px; padding: 14px; }
.trkp-svg { width: 100%; height: 180px; display: block; }
.trkp-zero { stroke: var(--separator); stroke-width: 1; stroke-dasharray: 4 4; }
.trkp-line { fill: none; stroke-width: 2; }
.trkp-line.pos { stroke: var(--green); } .trkp-line.neg { stroke: var(--red); }
.trkp-eqfoot { display: flex; justify-content: space-between; margin-top: 8px;
  font: 700 11.5px/1 var(--mono); color: var(--muted-2); }
.trkp-eqfoot .pos { color: var(--green); } .trkp-eqfoot .neg { color: var(--red); }
.trkp-emptybox { background: var(--panel); border: 1px dashed var(--border); border-radius: 12px;
  padding: 22px; text-align: center; color: var(--muted-2); font: 500 13px/1.6 var(--sans); }

/* ═══ Multi-lens confluence — when VIVEK + PhaseMap + Specs line up, it must
   stick out. 2-lens = loud chip; 3-lens = pulsing beacon. (2026-07-02) ═══ */
.pm-conf {
  font-family: var(--mono); font-size: 10.5px; font-weight: 700; letter-spacing: 0.05em;
  color: var(--orange); background: var(--orange-soft);
  border: 1px solid rgba(255,178,36,0.5); padding: 2px 8px; border-radius: 4px;
  white-space: nowrap;
}
.pm-conf-3 {
  color: #140c00; background: var(--orange); border-color: var(--orange);
  animation: pm-conf-pulse 1.6s ease-in-out infinite;
}
@keyframes pm-conf-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255,178,36,0.65); }
  50%      { box-shadow: 0 0 0 7px rgba(255,178,36,0); }
}
.pm-card-triple { box-shadow: 0 0 0 1px var(--orange), 0 0 18px rgba(255,178,36,0.18) !important; }

.conf-banner {
  display: flex; flex-wrap: wrap; gap: 8px 14px; align-items: center;
  margin: 12px 0; padding: 11px 14px; border-radius: 10px;
  border: 1px solid rgba(255,178,36,0.55); background: var(--orange-soft);
  font-family: var(--mono); font-size: 12px; color: var(--text);
}
.conf-banner-label { color: var(--orange); font-weight: 700; letter-spacing: 0.08em; }
.conf-banner a { color: var(--text); text-decoration: none; border-bottom: 1px dotted var(--muted); }
.conf-banner a:hover { color: var(--orange); }

/* ═══ Legibility pass 2 (owner 2026-07-02): bigger + BOLDER interface text,
   especially the top pills (market switch + page nav). Appended overrides —
   the originals above stay documented; delete this block to revert. ═══ */
.market-btn { font: 700 14px/1 var(--mono); padding: 8px 17px; }
.howto-link { font: 700 13px/1 var(--mono); color: var(--text-2); }
.howto-link:hover { color: var(--green); }
.brand-text h1 { font-size: 19px; }
.brand-sub { font-size: 11px; font-weight: 700; }
.view-tab { font: 700 13.5px/1 var(--mono); }
.seg-btn { font-weight: 700; font-size: 13px; }
.stat-label { font: 700 11px/1 var(--mono); color: var(--muted); letter-spacing: 0.1em; text-transform: uppercase; }
.chip { font: 600 11px/1 var(--mono); letter-spacing: 0.05em; padding: 4px 8px; }
.clock-time { font-weight: 700; }
.scan-banner-title { font-weight: 700; }
/* the nav pills have their own more-specific rule — override at same depth */
.nav-pills .howto-link { font-size: 12.5px; font-weight: 700; color: var(--text-2); }
.nav-pills .howto-link:hover { color: var(--green); }
.pm-topnav .howto-link { font-size: 12.5px; font-weight: 700; }
/* secondary pills (DEBUG · HOW IT WORKS · AI BOT) shrunk to buy the header
   quote room in row 1 (owner 2026-07-05). Higher specificity so it wins over
   both the base rule above and the 1440px compaction below. */
.nav-pills .howto-link.nav-minor {
  font-size: 10px; font-weight: 600; padding: 5px 7px; letter-spacing: 0.05em;
}
/* mid-width safety: keep the bold pills but compact them where the row gets
   tight (clocks are already hidden below 1560px) */
@media (max-width: 1440px) {
  .nav-pills .howto-link { font-size: 11px; padding: 5px 8px; }
  .market-btn { font-size: 12.5px; padding: 7px 12px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   iOS REVAMP — component pass (owner 2026-07-05: "complete revamp — more
   BOLD, more brighter, more iOS/Apple-like"). Appended overrides, same class
   names and layout as before; the :root tokens above carry the palette.
   Delete this block + restore the terminal :root values to revert.
   ═══════════════════════════════════════════════════════════════════════ */

/* ---- frosted, floating top bar (iOS navigation-bar material) ---- */
.topbar {
  background: rgba(18,22,30,0.78);
  -webkit-backdrop-filter: blur(22px) saturate(1.8);
  backdrop-filter: blur(22px) saturate(1.8);
  border-bottom: 1px solid rgba(255,255,255,0.07);
}
.topbar-row2 { border-top: 1px solid rgba(255,255,255,0.06); }

/* app-icon style brand tile: gradient superellipse, white glyph */
.brand-mark, .topbar-brand .brand-mark {
  background: linear-gradient(140deg, #34d15e 0%, #0aa9b8 55%, #0a84ff 120%);
  color: #fff; border: 0; border-radius: 27%;
  box-shadow: 0 3px 10px rgba(10,132,255,0.30), 0 1px 2px rgba(0,0,0,0.4);
}
.brand h1 { font-family: var(--sans); font-weight: 800; letter-spacing: -0.02em; }
.topbar-brand .brand h1 { letter-spacing: -0.02em; }
.brand-sub { font-family: var(--sans); }

/* ---- iOS segmented controls (market switch · scan types · sorts) ---- */
.market-switch, .scan-switch, .seg {
  background: rgba(255,255,255,0.07); border: 0; border-radius: 12px; padding: 3px;
}
.market-btn, .scan-btn, .seg-btn {
  font-family: var(--sans); font-weight: 700; letter-spacing: 0;
  border-radius: 9px;
}
.market-btn { font-size: 13.5px; padding: 8px 17px; }
.market-btn.is-active {
  background: var(--green); color: #04140a;
  box-shadow: 0 2px 8px rgba(48,209,88,0.35);
}
.scan-btn { font-size: 12.5px; }
.scan-btn.is-active {
  background: var(--orange); color: #191001;
  box-shadow: 0 2px 8px rgba(255,159,10,0.30);
}
.seg-btn { font-size: 13px; }
.seg-btn.is-active {
  background: var(--panel-3); color: var(--text);
  box-shadow: 0 2px 8px rgba(0,0,0,0.38), 0 0 0 1px rgba(255,255,255,0.08);
}
.seg-count { border-radius: 999px; font-family: var(--sans); }
.watch-count { border-radius: 999px; }

/* ---- nav pills: rounded-full, bold SF-style ---- */
.nav-pills .howto-link {
  border-radius: 999px; padding: 8px 14px;
  background: rgba(255,255,255,0.07); border: 1px solid rgba(255,255,255,0.09);
  font-family: var(--sans); font-weight: 700; font-size: 12.5px; letter-spacing: 0.02em;
  color: var(--text-2);
}
.nav-pills .howto-link:hover {
  color: var(--green); border-color: rgba(48,209,88,0.45); background: var(--green-soft);
}
.nav-pills .howto-link.nav-minor { font-size: 10.5px; font-weight: 600; padding: 6px 10px; }
.nav-pills .howto-link.bot-nav-link {
  background: var(--blue-soft); border-color: rgba(10,132,255,0.4); color: #6cb5ff;
}
.pm-topnav .howto-link { font-family: var(--sans); }
.howto-link { font-family: var(--sans); letter-spacing: 0.02em; }

/* ---- row-2 controls: filled pill buttons (iOS prominent / tinted) ---- */
.reload-btn {
  border: 0; border-radius: 999px; height: 36px; padding: 0 18px;
  background: var(--green); color: #04140a;
  box-shadow: 0 2px 10px rgba(48,209,88,0.35);
}
.reload-btn:hover { background: #3ddb64; }
.reload-label { font-family: var(--sans); font-weight: 800; letter-spacing: 0.06em; }
.search-trigger {
  background: rgba(255,255,255,0.08); border-radius: 999px; padding: 9px;
  color: var(--text-2);
}
.search-trigger:hover { background: rgba(255,255,255,0.14); color: var(--text); }
.refresh-timer {
  border-radius: 999px; border: 0; background: rgba(255,255,255,0.07);
  padding: 7px 12px; font-family: var(--sans); font-weight: 700;
}

/* ---- stat cards: separate rounded widgets (iOS home-screen grid) ---- */
.stats { gap: 12px; background: transparent; box-shadow: none; overflow: visible; }
.stat-card {
  background: var(--panel); border-radius: var(--radius);
  box-shadow: var(--shadow); border-right: 0; padding: 20px 22px;
}
.stat-label { font-family: var(--sans); font-weight: 700; letter-spacing: 0.07em; font-size: 11px; }
.stat-value { font-family: var(--sans); font-weight: 800; font-size: 30px; letter-spacing: -0.03em; }

/* ---- scan banner ---- */
.scan-banner-title { font-size: 15px; }
.scan-fresh { border-radius: 999px; font-family: var(--sans); font-weight: 700; }

/* ---- view tabs -> iOS segmented control (was underline tabs) ---- */
.view-tabs {
  display: inline-flex; gap: 3px; border-bottom: 0; margin-bottom: 16px;
  background: rgba(255,255,255,0.07); border-radius: 13px; padding: 3px;
}
.view-tab {
  font-family: var(--sans); font-weight: 700; font-size: 13.5px; letter-spacing: 0.02em;
  padding: 9px 18px; margin-bottom: 0; border-bottom: 0; border-radius: 10px;
}
.view-tab.is-active {
  color: var(--text); border-bottom: 0; background: var(--panel-3);
  box-shadow: 0 2px 8px rgba(0,0,0,0.38), 0 0 0 1px rgba(255,255,255,0.08);
}

/* ---- filter chips: rounded-full, SF-style ---- */
.vkf-chip { border-radius: 999px; font-family: var(--sans); font-weight: 600; font-size: 12.5px; }
.vkf-label, .legend-tag { font-family: var(--sans); }

/* ---- result rows: bolder Apple-Stocks-style type ---- */
.tkr { font-family: var(--sans); font-weight: 800; font-size: 18px; letter-spacing: -0.02em; }
.rprice { font-family: var(--sans); font-weight: 700; font-size: 18px; letter-spacing: -0.01em; }
.cname { font-family: var(--sans); font-weight: 500; }
.row-grade { font-family: var(--sans); font-weight: 800; font-size: 15px; }
.row-wrap:hover { transform: translateY(-2px); }

/* ---- badges & chips: tinted rounded-full capsules ---- */
.badge, .rbadge, .chip, .vk-tf-chip, .vk-fresh, .vk-lvl-key, .vk-grade-score {
  border-radius: 999px; font-family: var(--sans); letter-spacing: 0.03em;
}
.badge { font-size: 10px; font-weight: 700; padding: 4px 9px; }
.badge.dir { font-size: 10.5px; font-weight: 800; padding: 5px 11px; }
.rbadge { font-size: 10px; font-weight: 700; padding: 4px 9px; }
.chip { font-size: 10.5px; font-weight: 600; padding: 4px 9px; }

/* ---- overlays / toasts ---- */
.search-box { border-radius: 18px; background: var(--panel-2); }
.search-input { font-weight: 600; }
.scan-toast { border-radius: 14px; font-family: var(--sans); font-weight: 600; }
.conf-banner { border-radius: var(--radius-md); }

/* iOS type is never letter-spaced wide at body sizes */
body { letter-spacing: -0.012em; }

/* keep the compact mid-width overrides in the new voice */
@media (max-width: 1440px) {
  .nav-pills .howto-link { font-size: 11.5px; padding: 6px 10px; }
  .market-btn { font-size: 12.5px; padding: 7px 13px; }
}

/* ═══════════════════════ shared site navigation (nav.js) ══════════════════ */
/* Active-page pill — clearly "you are here" in the pill row. */
.nav-pills .howto-link.is-here,
.howto-link.is-here {
  background: var(--blue); border-color: var(--blue); color: #fff;
}
.nav-pills .howto-link.bot-nav-link.is-here { color: #fff; }
.nav-pills .howto-link.bot-nav-link.is-here .bot-nav-dot { background: #fff; }

/* MORE ▾ dropdown */
.nav-more { position: relative; display: inline-flex; }
.nav-more-btn { cursor: pointer; }
.nav-more-menu {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 60;
  display: flex; flex-direction: column; min-width: 160px;
  background: var(--elevated); border: 1px solid var(--border);
  border-radius: 12px; box-shadow: var(--shadow-open); padding: 6px; gap: 2px;
}
.nav-more-menu[hidden] { display: none; }
.nav-more-item {
  padding: 9px 12px; border-radius: 8px; text-decoration: none;
  font: 600 12.5px/1 var(--sans); color: var(--text-2); white-space: nowrap;
}
.nav-more-item:hover { background: var(--fill); color: var(--text); }
.nav-more-item.is-here { color: var(--blue); }

/* Bottom tab bar — the one-thumb mobile nav. Hidden on desktop. */
.site-tabs { display: none; }
@media (max-width: 680px) {
  .site-tabs {
    display: grid; grid-template-columns: repeat(6, 1fr);
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 80;
    background: var(--nav);
    -webkit-backdrop-filter: saturate(180%) blur(22px); backdrop-filter: saturate(180%) blur(22px);
    border-top: 0.5px solid var(--separator);
    padding-bottom: env(safe-area-inset-bottom, 0);
  }
  .site-tab {
    display: flex; flex-direction: column; align-items: center; gap: 3px;
    padding: 8px 2px 7px; text-decoration: none; color: var(--muted);
  }
  /* #30: the MORE tab is a <button> — reset its native chrome to match tabs. */
  .site-tab-more { appearance: none; background: transparent; border: 0; cursor: pointer; font: inherit; }
  .site-tab-ico { font-size: 18px; line-height: 1; position: relative; }
  .site-tab-lbl { font: 700 9px/1 var(--sans); letter-spacing: 0.04em; }
  .site-tab.is-here { color: var(--blue); }
  /* #29: active tab gets a filled pill + a top accent so "where am I" reads
     instantly; badge counts ride the icon. */
  .site-tab.is-here .site-tab-lbl { font-weight: 800; }
  .site-tab.is-here::before {
    content: ""; position: absolute; top: 0; left: 50%; transform: translateX(-50%);
    width: 26px; height: 3px; border-radius: 0 0 3px 3px; background: var(--blue);
  }
  .site-tab-badge {
    position: absolute; top: -6px; left: 60%;
    min-width: 15px; height: 15px; padding: 0 4px; box-sizing: border-box;
    display: inline-flex; align-items: center; justify-content: center;
    font: 800 9px/1 var(--mono); color: #fff; background: var(--red);
    border-radius: 999px; border: 1.5px solid var(--nav);
  }
  /* A CSS `display` overrides the HTML `hidden` attribute — restore it so the
     count-less tabs (RECS/PHASEMAP/MY NAMES) don't show an empty dot. */
  .site-tab-badge[hidden] { display: none; }
  .site-tab[data-tabkey="index"] .site-tab-badge { background: var(--green); }
  body.has-site-tabs { padding-bottom: calc(64px + env(safe-area-inset-bottom, 0)); }
  /* the top pill nav is redundant on phones once the tab bar exists */
  .nav-pills { display: none; }

  /* ── #30: MORE bottom sheet ──────────────────────────────────────────── */
  .more-sheet-scrim {
    position: fixed; inset: 0; z-index: 90;
    background: rgba(0,0,0,0); transition: background .22s ease;
    display: flex; align-items: flex-end;
  }
  /* Restore the hidden attribute (CSS display overrides it) — else the scrim
     covers the screen and eats the MORE tap even while "closed". */
  .more-sheet-scrim[hidden] { display: none; }
  .more-sheet-scrim.is-open { background: rgba(0,0,0,0.55); }
  .more-sheet {
    width: 100%; background: var(--elevated, var(--panel));
    border-radius: 20px 20px 0 0; border-top: 0.5px solid var(--separator);
    padding: 8px 14px calc(16px + env(safe-area-inset-bottom, 0));
    transform: translateY(100%); transition: transform .24s cubic-bezier(.2,.8,.2,1);
    max-height: 82vh; max-height: 82dvh; overflow-y: auto;
  }
  .more-sheet-scrim.is-open .more-sheet { transform: translateY(0); }
  .more-sheet-grip { width: 38px; height: 4px; border-radius: 999px; background: var(--border-2); margin: 6px auto 10px; }
  .more-sheet-hd {
    display: flex; align-items: center; justify-content: space-between;
    font: 800 17px/1 var(--sans); color: var(--text); padding: 2px 4px 12px;
  }
  .more-sheet-x {
    appearance: none; border: 0; background: var(--fill-2); color: var(--text-2);
    width: 34px; height: 34px; border-radius: 999px; font-size: 15px; cursor: pointer;
  }
  .more-sheet-row {
    display: flex; align-items: center; gap: 14px; text-decoration: none;
    padding: 15px 8px; border-radius: 12px; color: var(--text);
    min-height: 44px; border-bottom: 0.5px solid var(--border-soft);
  }
  .more-sheet-row:last-child { border-bottom: 0; }
  .more-sheet-row:active { background: var(--fill); }
  .more-sheet-row.is-here { color: var(--blue); }
  .more-sheet-ico { font-size: 20px; width: 26px; text-align: center; flex: 0 0 auto; }
  .more-sheet-lbl { font: 700 15px/1 var(--sans); flex: 1; }
  .more-sheet-go { color: var(--muted-2); font-size: 20px; }
  /* comfortable thumb targets for the filter chips */
  .vkf-chip { min-height: 34px; padding: 8px 12px; }
}

/* ═══════════════ dashboard bot-activity strip (what happened) ═════════════ */
.bot-activity {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  background: var(--panel); border: 1px solid var(--border-soft);
  border-radius: var(--radius-md); padding: 9px 14px; margin: 0 0 14px;
}
.ba-label { font: 800 10px/1 var(--sans); letter-spacing: 0.1em; color: var(--muted); }
.ba-item {
  display: inline-flex; align-items: center; gap: 6px;
  font: 600 12px/1 var(--sans); color: var(--text-2);
  background: var(--fill-2); border-radius: 999px; padding: 5px 11px;
  text-decoration: none;
}
.ba-item:hover { background: var(--fill); color: var(--text); }
.ba-kind-open  { color: var(--blue); }
.ba-kind-close.pos { color: var(--green); }
.ba-kind-close.neg { color: var(--red); }
.ba-ago { font: 500 10.5px/1 var(--sans); color: var(--muted-2); }
.ba-more { margin-left: auto; font: 700 11px/1 var(--sans); color: var(--blue); text-decoration: none; white-space: nowrap; }
/* Stall-probe line (2026-07-30): its own full-width row inside the strip so it
   cannot be skimmed past — the probe's flags, the owner's call. */
.ba-stall {
  flex-basis: 100%; display: block; text-decoration: none;
  font: 600 11px/1.5 var(--mono); color: var(--orange);
  background: var(--orange-soft); border-radius: 7px; padding: 5px 9px;
  border: 1px solid color-mix(in srgb, var(--orange) 26%, transparent);
}
.ba-stall:hover { color: var(--text); }

/* Journal — compact account summary living in the (sticky) topbar. */
.jr-topsum {
  display: inline-flex; align-items: center; gap: 12px; margin-left: auto;
  font: 700 12px/1 var(--mono); color: var(--text-2); white-space: nowrap;
}
.jr-topsum .pos { color: var(--green); } .jr-topsum .neg { color: var(--red); }
.jr-topsum .ts-who { font: 700 10px/1 var(--sans); color: var(--muted); letter-spacing: .04em; }
@media (max-width: 720px) { .jr-topsum { gap: 8px; font-size: 11px; } }

/* Phase Map cross-badge on scanner rows — the same name is live over there. */
.rbadge.pmx { color: var(--teal); background: rgba(48,176,199,0.13);
  border-color: color-mix(in srgb, var(--teal) 32%, transparent); }

/* ═══════════════════ UI WAVE 1 (2026-07-22) — speed + readability ═════════
   Appended overrides, same pattern as the iOS pass above. */

/* Skeleton placeholders sized like real row cards (min-height 90 / 80 mobile)
   so the swap to live rows doesn't jump the layout; shimmer keyframe reused. */
.skeleton { height: 90px; }
@media (max-width: 600px) { .skeleton { height: 80px; } }

/* Tabular figures on every numeric cell. The `font:` shorthand in the base
   rules resets the body-level tabular-nums, so re-assert it where numbers
   must not wiggle as they change: prices, scores, R multiples, stat values. */
.rprice, .rk-score, .rk-rr, .dp-val, .dh-val, .stat-value {
  font-variant-numeric: tabular-nums;
}

/* Rows hold 2 visual lines max: line 1 (ticker · price) already clips; the
   chip strip now never wraps — overflow collapses into the "+N" chip. */
.row-chips { flex-wrap: nowrap; overflow: hidden; }
.rbadge.chip-more {
  color: var(--muted); background: var(--fill-2);
  border-color: var(--border); flex-shrink: 0;
}

/* Bot strip: one summary line; the event list expands below on click. */
.ba-sum {
  appearance: none; border: 0; background: transparent; cursor: pointer;
  display: inline-flex; align-items: center; gap: 7px; padding: 4px 2px;
  font: 700 12.5px/1 var(--sans); color: var(--text-2); text-align: left;
}
.ba-sum:hover { color: var(--text); }
.ba-chev { font-size: 10px; color: var(--muted-2); transition: transform .15s; }
.ba-open .ba-chev { transform: rotate(180deg); }
.ba-events {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  width: 100%; padding-top: 4px;
}
.ba-events[hidden] { display: none; }

/* ╔═══════════════════════════════════════════════════════════════════════╗
   ║  SHARED DECK COMPONENT — ONE SOURCE OF TRUTH (backlog #23)             ║
   ║                                                                       ║
   ║  These classes are the shared command-deck vocabulary used by the     ║
   ║  dashboard AND specs.html AND phasemap.html (Wave P parity). Change    ║
   ║  a deck look HERE and it updates every page — never fork these into    ║
   ║  a page-specific rule. The component is three layers:                 ║
   ║                                                                       ║
   ║    • TOPBAR   .deck-top / .deck-top-right / .microclock — the single   ║
   ║               row: brand · market switch · #site-nav pills · actions.  ║
   ║    • DECK     .deck / .deck-status / .deck-title / .deck-sub /         ║
   ║               .deck-dot / .deck-pills / .fpill (+g/o/t/top/is-active)  ║
   ║               — the status line + click-to-filter pill strip.         ║
   ║    • TOOLBAR  .toolbar / .tb-line / .seg / .seg-btn / .vkf-chip /      ║
   ║               .tb-sort* — the sticky merged filter/sort line (see the  ║
   ║               "ONE sticky toolbar" block below, near the row cards).   ║
   ║                                                                       ║
   ║  Responsive rules for all three live in the mobile @media blocks       ║
   ║  (h-scroll strips, 40px thumb targets, sticky offsets). Per-page       ║
   ║  scripts (app.js / specs.js / phasemap.js) render into these IDs:      ║
   ║  #deck-pills / #sp-pills / #pm-* — same markup, same skin.             ║
   ╚═══════════════════════════════════════════════════════════════════════╝
   WAVE 3a (2026-07-22) — Command Deck, tranche A:
   One command bar replaces the scan banner, 4 stat cards, bot strip and the
   at-level/confluence banner strips; the topbar collapses to a single row. */

/* ---- single-row topbar ---- */
.deck-top { display: flex; align-items: center; gap: 14px; padding: 9px 20px; }
.deck-top .brand { flex-shrink: 0; }
.deck-top .nav-pills { display: flex; gap: 6px; flex-wrap: nowrap; overflow-x: auto;
  scrollbar-width: none; min-width: 0;
  /* CLS #1: nav.js injects the pills AFTER first paint. flex-basis 0 (not
     auto!) means the strip's size comes ONLY from the free space — injected
     content can never expand its basis and re-wrap the header (at ~800px a
     basis of auto made the loaded pills push the strip to a second row,
     shoving the whole page down 44px — the dominant 0.51 shift). Pills scroll
     inside whatever space the row grants. min-height reserves the row. */
  flex: 1 1 0; min-height: 30px; }
.deck-top .nav-pills::-webkit-scrollbar { display: none; }
.deck-top-right { margin-left: auto; display: flex; align-items: center; gap: 9px; flex-shrink: 0; }
.microclock {
  /* Owner 2026-07-22: bolder, larger, each city its OWN colour.
     2×2 grid: MEL/NY (with seconds) left, CN/LDN right. Dates in tooltip. */
  font: 800 14px/1.5 var(--mono); cursor: default;
  display: grid; grid-template-columns: auto auto; gap: 1px 16px;
  white-space: nowrap; font-variant-numeric: tabular-nums; text-align: left;
  letter-spacing: 0.01em;
}
/* CLS #1: the cells boot as "—" then become "18:51:09 MEL" — reserve widths
   so the tick-over doesn't nudge the header's right group. */
.microclock .mc-major { display: inline-block; min-width: 118px; }
.microclock .mc-minor { display: inline-block; min-width: 92px; }
#clk-mel-time    { color: var(--blue); }     /* Melbourne — blue */
#clk-ny-time     { color: #ff5c8a; }         /* New York — pink */
#clk-china-time  { color: var(--orange); }   /* China — orange */
#clk-london-time { color: var(--teal); }     /* London — teal */

/* BACK pill (owner 2026-07-22) — subtle outline so it never fights SCAN */
.nav-pills .nav-back { color: var(--muted); background: transparent; cursor: pointer; }
.nav-pills .nav-back:hover { color: var(--text); background: var(--fill); border-color: var(--border-2); }

/* ---- command deck bar ---- */
/* CLS pass (UX top-10 #1, 2026-07-26): the deck used to paint as a thin
   "Loading…" bar, then GROW as pills + the bot strip arrived — shoving the
   toolbar, rows and footer down (Lighthouse blamed main.wrap for ~0.50 of the
   ~0.89 CLS). Space is now RESERVED before data arrives: the deck, its pills
   row, the bot strip and the EMA legend all hold their loaded height from the
   first frame (values measured slightly UNDER real loaded heights so an
   under-shoot never leaves a permanent gap). #results holds 72vh so the
   footer never sits high then jumps (its share was ~0.38). */
.deck {
  background: var(--panel); border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 14px 18px; margin: 0 0 14px;
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  min-height: 118px;
}
.deck-status { min-width: 0; }
.deck-title { font: 800 19px/1.25 var(--sans); letter-spacing: -0.02em; color: var(--text); }
.deck-sub {
  display: flex; align-items: center; gap: 8px; margin-top: 3px;
  font: 500 12px/1.5 var(--sans); color: var(--muted-2); flex-wrap: wrap;
  min-height: 23px;   /* CLS #1: the freshness pill is taller than the text line */
}
.deck-dot {
  width: 8px; height: 8px; border-radius: 99px; flex-shrink: 0;
  background: var(--green); box-shadow: 0 0 7px var(--green);
}
.deck-dot.sync { background: var(--blue); box-shadow: 0 0 7px var(--blue);
  animation: deckpulse 1s ease-in-out infinite; }
.deck-dot.warn { background: var(--orange); box-shadow: 0 0 7px var(--orange); }
@keyframes deckpulse { 50% { opacity: 0.35; } }
.deck-sub .scan-fresh { margin: 0; }

.deck-pills { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; min-height: 32px; }
/* Reserve the bot strip's slot while it loads — [hidden] usually means
   display:none, but that would collapse the deck and re-shift everything when
   the strip arrives. visibility:hidden keeps it out of the a11y tree while
   holding the space. */
.deck .deck-bot[hidden] { display: flex; visibility: hidden; min-height: 32px; }
/* Mid widths (tablet / small laptop): the deck stacks progressively — pills
   wrap under the status column, the bot strip takes its own line, the sub-text
   wraps to two lines — so the loaded height climbs as the viewport narrows.
   Reservations are tiered from MEASURED loaded heights (always a few px UNDER
   actual, so an over-reserve can never leave a permanent gap). */
@media (max-width: 1150px) { .deck { min-height: 170px; align-items: flex-start; } }
@media (max-width: 1024px) { .deck { min-height: 188px; } }
@media (max-width: 860px)  { .deck { min-height: 198px; } .deck-status { min-height: 74px; } }
/* In the reserved band the deck is top-aligned (above) so the empty state
   paints children at their loaded positions — centering redistributed them
   when the content arrived, which was itself a shift. */
/* Mobile: the deck stacks fully (title / pills wrap / full-width bot strip) so
   its loaded height is taller again — reserve the measured mobile heights. */
@media (max-width: 600px) {
  .deck { min-height: 230px; }
  .deck-pills { min-height: 38px; }
  .deck .deck-bot[hidden] { min-height: 60px; }
}
.fpill {
  appearance: none; cursor: pointer; text-decoration: none;
  display: inline-flex; align-items: center; gap: 7px;
  font: 700 12.5px/1 var(--sans); padding: 9px 13px; border-radius: 999px;
  background: var(--fill-2); border: 1px solid var(--border-soft); color: var(--text-2);
  transition: background .15s, border-color .15s;
}
.fpill b { font: 800 13px/1 var(--mono); }
.fpill:hover { background: var(--fill); }
.fpill.g { color: var(--green); background: var(--green-soft); border-color: rgba(48,209,88,0.3); }
.fpill.o { color: var(--orange); background: var(--orange-soft); border-color: rgba(255,159,10,0.3); }
.fpill.t { color: var(--teal); background: rgba(100,210,255,0.12); border-color: rgba(100,210,255,0.3); }
.fpill.top { color: var(--orange); }
.fpill.is-active { outline: 2px solid currentColor; outline-offset: -1px; font-weight: 800; }
.deck-npick { font: 600 11.5px/1 var(--sans); color: var(--muted-2); white-space: nowrap; }
/* Products set aside from the A+/A counts (2026-08-13). Quieter than
   .deck-npick on purpose: it explains a subtraction, it is not a target. */
.deck-products {
  font: 600 11.5px/1 var(--sans); color: var(--muted-2); white-space: nowrap;
  opacity: .82; cursor: help;
}

/* bot chip lives inside the deck now */
.deck-bot { margin-left: auto; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.deck-bot .ba-sum {
  background: var(--fill-2); border: 1px solid var(--border-soft);
  border-radius: 999px; padding: 9px 14px;
}
.deck-bot .ba-events { padding-top: 8px; }

/* ---- RECOMMENDATIONS page (owner 2026-07-22) — deck-language cards ---- */
.rec-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin: 0 0 14px; }
.rec-card {
  background: var(--panel); border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 16px 18px; margin: 0 0 2px; min-width: 0;
}
.rec-card-hd { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.rec-card-hd h3 { margin: 0; font: 800 15px/1 var(--sans); letter-spacing: -0.01em; }
.rec-verdict {
  margin-left: auto; font: 800 11.5px/1 var(--sans); letter-spacing: 0.04em;
  padding: 7px 11px; border-radius: 999px; white-space: nowrap;
}
.rec-verdict.up    { color: var(--green);  background: var(--green-soft); }
.rec-verdict.down  { color: var(--red);    background: var(--red-soft); }
.rec-verdict.mixed { color: var(--orange); background: var(--orange-soft); }
.rec-breadth {
  position: relative; height: 10px; border-radius: 999px; background: var(--red-soft);
  overflow: hidden; margin: 4px 0 18px;
}
.rec-breadth i { position: absolute; inset: 0 auto 0 0; background: var(--green); opacity: 0.75; border-radius: 999px 0 0 999px; }
.rec-breadth-lbl {
  position: absolute; inset: 0; display: grid; place-items: center;
  font: 700 8.5px/1 var(--mono); letter-spacing: 0.05em; color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,.6);
}
.rec-line { margin: 0 0 12px; font: 400 13.5px/1.55 var(--sans); color: var(--text-2); }
.rec-nums { display: flex; gap: 8px; flex-wrap: wrap; }
.rec-nums span {
  font: 600 11.5px/1 var(--sans); color: var(--muted); background: var(--fill-2);
  border: 1px solid var(--border-soft); border-radius: 999px; padding: 7px 11px;
}
.rec-nums b { font: 800 12px/1 var(--mono); color: var(--text); }
.rec-nums b.pos { color: var(--green); } .rec-nums b.neg { color: var(--red); }
.rec-age { margin-top: 10px; font: 500 10.5px/1.4 var(--sans); color: var(--muted-2); }
.rec-note { border-left: 3px solid var(--blue); margin-bottom: 14px; }
.rec-note-body { margin: 0; font: 400 14.5px/1.65 var(--sans); color: var(--text-2); }
.rec-movers .rec-mv-list { display: flex; gap: 8px; flex-wrap: wrap; }
.rec-mv {
  display: inline-flex; align-items: center; gap: 8px; text-decoration: none;
  font: 700 12.5px/1 var(--sans); color: var(--text);
  background: var(--fill-2); border: 1px solid var(--border-soft);
  border-radius: 999px; padding: 9px 13px;
}
.rec-mv:hover { background: var(--fill); }
.rec-mv-mkt { font: 700 9px/1 var(--mono); color: var(--muted-2); letter-spacing: 0.06em; }
.rec-mv-r { font: 800 12px/1 var(--mono); }
.rec-mv-r.pos { color: var(--green); } .rec-mv-r.neg { color: var(--red); }
.rec-link { margin-left: auto; font: 700 12px/1 var(--sans); color: var(--blue); text-decoration: none; }
.rec-disclaimer { font: 500 11.5px/1.6 var(--sans); color: var(--muted-2); max-width: 760px; margin: 18px 0 0; }
@media (max-width: 880px) { .rec-grid { grid-template-columns: 1fr; } }

/* ── Wave R #18: degraded / stale states ────────────────────────────────── */
.rec-degraded { opacity: 0.92; border-style: dashed; }
.rec-stale-card { box-shadow: inset 0 2px 0 var(--orange); }
.rec-stale {
  font: 800 10.5px/1 var(--mono); color: var(--orange);
  background: var(--orange-soft); border: 1px solid rgba(255,159,10,0.30);
  border-radius: 999px; padding: 3px 8px;
}

/* ── Wave R #17: recs mobile pass — movers h-scroll + thumb targets ──────── */
@media (max-width: 680px) {
  .rec-grid { gap: 10px; }
  /* Movers become a swipeable horizontal strip instead of a wrapping block. */
  .rec-movers .rec-mv-list {
    flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch;
    scrollbar-width: none; padding-bottom: 4px; scroll-snap-type: x proximity;
  }
  .rec-movers .rec-mv-list::-webkit-scrollbar { display: none; }
  .rec-mv { flex: 0 0 auto; min-height: 44px; scroll-snap-align: start; }
  .rec-open { min-height: 44px; display: inline-flex; align-items: center; }
  .rec-archive > summary { padding: 13px 0; }   /* ≥44px tap target */
  .rec-sec { min-height: 32px; }
}

/* ── Wave R #10: day-over-day breadth delta chip ────────────────────────── */
.rec-delta-row { margin: 0 0 10px; }
.rec-delta {
  display: inline-flex; align-items: center; gap: 4px;
  font: 700 11px/1 var(--mono); letter-spacing: 0.01em;
  padding: 4px 9px; border-radius: 999px; border: 1px solid var(--border-2);
}
.rec-delta.up   { color: var(--green);  background: var(--green-soft);  border-color: rgba(47,208,127,0.30); }
.rec-delta.down { color: var(--red);    background: var(--red-soft);    border-color: rgba(255,92,92,0.28); }
.rec-delta.flat { color: var(--muted);  background: var(--fill-2); }

/* ── Wave R #11: N-day breadth history strip ────────────────────────────── */
.rec-hist { margin: 0 0 12px; }
.rec-hist-bars {
  display: flex; align-items: flex-end; gap: 3px; height: 34px;
  padding: 4px 6px; background: var(--fill-2); border-radius: var(--radius-sm);
}
.rec-hbar { flex: 1 1 0; min-width: 3px; border-radius: 2px 2px 0 0; opacity: 0.85; }
.rec-hbar.up   { background: var(--green); }
.rec-hbar.down { background: var(--red); }
.rec-hbar.flat { background: var(--muted-2); }
.rec-hist-lbl { display: block; margin-top: 4px; font: 600 9.5px/1 var(--sans); letter-spacing: 0.04em; color: var(--muted-2); text-transform: uppercase; }

/* ── Wave R #13+#14: lazy card enrichment (at-level / multi-lens / sectors) ── */
.rec-enrich:empty { display: none; }
.rec-enrich-nums { display: flex; gap: 8px; flex-wrap: wrap; margin: 10px 0 0; }
.rec-enrich-nums span {
  font: 600 11px/1 var(--sans); color: var(--text-2);
  background: var(--fill-2); border: 1px solid var(--border); border-radius: 999px; padding: 5px 10px;
}
.rec-enrich-nums b { font: 800 12px/1 var(--mono); color: var(--text); }
.rec-sec-list { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border); }
.rec-sec-hd { font: 700 9.5px/1 var(--sans); letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted-2); margin-bottom: 7px; }
.rec-sec { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 3px 0; }
.rec-sec-nm { font: 600 12px/1.2 var(--sans); color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rec-sec-lean { font: 700 11px/1 var(--mono); white-space: nowrap; flex: 0 0 auto; }
.rec-sec-lean.up { color: var(--green); } .rec-sec-lean.down { color: var(--red); } .rec-sec-lean.flat { color: var(--muted); }

/* ── Wave R #15+#16: watchlist badges + deep links ──────────────────────── */
.rec-watch-badge {
  font: 800 11px/1 var(--mono); color: var(--orange);
  background: var(--orange-soft); border: 1px solid rgba(255,159,10,0.30);
  border-radius: 999px; padding: 3px 8px;
}
.rec-card-hd .rec-verdict { margin-left: auto; }   /* verdict stays right when a ★ badge is present */
.rec-card-ft { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 10px; }
.rec-card-ft .rec-age { margin-top: 0; }
.rec-open { font: 700 12px/1 var(--sans); color: var(--blue); text-decoration: none; white-space: nowrap; }
.rec-open:hover { text-decoration: underline; }
.rec-mv.watched { border-color: rgba(255,159,10,0.45); background: var(--orange-soft); }
.rec-mv-star { color: var(--orange); font-size: 11px; margin-right: 2px; }

/* ── Wave R #12: note archive fold ──────────────────────────────────────── */
.rec-archive {
  margin: 0 0 14px; background: var(--panel-2); border: 1px solid var(--border);
  border-radius: var(--radius-md); padding: 4px 14px;
}
.rec-archive > summary {
  cursor: pointer; list-style: none; padding: 10px 0; user-select: none;
  font: 700 12.5px/1 var(--sans); color: var(--text-2);
}
.rec-archive > summary::-webkit-details-marker { display: none; }
.rec-archive > summary::before { content: "▸ "; color: var(--muted); }
.rec-archive[open] > summary::before { content: "▾ "; }
.rec-arch-item { padding: 10px 0; border-top: 1px solid var(--border); }
.rec-arch-date { font: 700 10.5px/1 var(--mono); letter-spacing: 0.03em; color: var(--muted-2); }
.rec-arch-item p { margin: 5px 0 0; font: 400 13px/1.55 var(--sans); color: var(--text-2); }

/* snappy re-renders (backlog #48): the entrance cascade plays on FIRST paint
   only — filter/sort/pill re-renders swap instantly instead of re-animating. */
.rows[data-painted] .row-wrap { animation: none; }

/* responsive: the deck is the same app at thumb scale (backlog #19 seed) */
@media (max-width: 880px) {
  .deck-top { flex-wrap: wrap; }
  .deck-top .market-switch { order: 0; }
  .microclock { display: none; }
}
@media (max-width: 680px) {
  .deck { padding: 12px 14px; gap: 10px; }
  .deck-title { font-size: 16.5px; }
  .deck-pills { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
    width: 100%; padding-bottom: 2px; }
  .deck-pills::-webkit-scrollbar { display: none; }
  .fpill { flex-shrink: 0; min-height: 38px; }
  .deck-bot { margin-left: 0; width: 100%; }
}

/* ── Wave 3R (#1-3): ONE sticky filter toolbar ──────────────────────────────
   Grades + ★ watch + VIVEK chips + cycling sort in a single line that pins
   under the topbar (height measured into --topbar-h by app.js) and slims
   once the deck scrolls away. Replaces .view-tabs + .controls on the
   dashboard (both classes remain for specs.html). */
.toolbar {
  position: sticky; top: var(--topbar-h, 53px); z-index: 20;
  background: var(--nav);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--border);
  padding: 8px 0 9px; margin-bottom: 14px;
}
/* Desktop: the line WRAPS — every chip and the sort control stay visible
   (owner 2026-07-24: the grown chip set was silently clipping "Shorts" and
   SCORE past the container edge; a hidden-scrollbar strip gives no hint that
   anything is cut off). Mobile (≤680px) keeps the deliberate one-line
   horizontal scroll with the sort pinned right — see the block below. */
.tb-line { display: flex; align-items: center; gap: 6px; row-gap: 6px;
  flex-wrap: wrap;
  scrollbar-width: none; -webkit-overflow-scrolling: touch; }
.tb-line::-webkit-scrollbar { display: none; }
.tb-line > * { flex: 0 0 auto; }
.tb-watch { border: 1px solid var(--border); border-radius: 999px;
  background: var(--fill-2); padding: 7px 13px; }
#toolbar #vk-filters { display: inline-flex; align-items: center; gap: 6px;
  flex-wrap: wrap; row-gap: 6px; margin: 0;
  /* Shrinkable (overrides the .tb-line > * flex:0 0 auto): at its natural
     max-content width the chip strip would refuse to compress and overflow
     mid-width screens — allowing shrink lets its internal wrap engage. */
  flex: 1 1 auto; min-width: 0; }
#toolbar #vk-filters[hidden] { display: none; }
#toolbar .vkf-label, #toolbar .vkf-legend { display: none; } /* tooltips carry these */
#toolbar .vkf-sep { width: 1px; height: 18px; background: var(--border); flex: 0 0 auto; }
.tb-sort { display: inline-flex; margin-left: auto; border: 1px solid var(--border);
  border-radius: var(--radius-sm); overflow: hidden; background: var(--fill-2); }
.tb-sort-label, .tb-sort-dir { appearance: none; border: 0; background: transparent;
  color: var(--text-2); font: inherit; font-weight: 700; font-size: 13px;
  padding: 7px 10px; cursor: pointer; font-variant-numeric: tabular-nums; }
.tb-sort-label { border-right: 1px solid var(--border); min-width: 60px; text-align: center; }
.tb-sort-dir { font-size: 14px; padding: 7px 11px; color: var(--text); }
.tb-sort-label:hover, .tb-sort-dir:hover { color: var(--text); background: var(--panel-3); }
/* Slim variant on scroll (#3): tighter paddings + smaller type, counts stay. */
.toolbar.is-slim { padding: 4px 0 5px; }
.toolbar.is-slim .seg-btn, .toolbar.is-slim .vkf-chip { font-size: 11px; padding: 4px 8px; }
.toolbar.is-slim .tb-watch { padding: 4px 10px; }
.toolbar.is-slim .tb-sort-label, .toolbar.is-slim .tb-sort-dir { font-size: 11px; padding: 4px 9px; }
@media (max-width: 680px) {
  /* Mobile keeps the ONE-LINE horizontally-scrolling strip (thumb design):
     nowrap + natural width so the strip scrolls instead of squashing. */
  .tb-line { gap: 6px; padding-bottom: 2px; flex-wrap: nowrap; overflow-x: auto; }
  #toolbar #vk-filters { flex-wrap: nowrap; flex: 0 0 auto; min-width: auto; }
  .tb-sort-label { min-width: 58px; }
  /* #42: pin the sort control to the right edge so it's always reachable even
     as the filter chips scroll horizontally under it. */
  .tb-sort {
    position: sticky; right: 0; margin-left: 6px; z-index: 2;
    background: var(--nav); box-shadow: -10px 0 10px -6px var(--nav);
  }
}
/* Keep the merged line dense enough that the sort control never clips on a
   standard desktop (1366-1500px): slightly tighter chips inside the toolbar. */
#toolbar .vkf-chip { padding: 6px 10px; }
#toolbar .seg-btn { padding: 6px 11px; }

/* ── Wave 3R (#4+#7): row card v2 ───────────────────────────────────────────
   76px cards: ticker + dir arrow + mcap + name on line 1, chips beneath;
   price with day-% stacked in its own column; spark + score/R:R + actions
   right. Direction is an arrow (▲/▼) instead of a pill — the colour carries
   the meaning, the title carries the word. */
.row { grid-template-columns: 68px 1fr auto auto; min-height: 76px; }
.rdir { font: 800 14px/1 var(--mono); flex: 0 0 auto; transform: translateY(1px); }
.rdir.long { color: var(--green); }
.rdir.short { color: var(--red); }
.row-price {
  display: flex; flex-direction: column; align-items: flex-end;
  justify-content: center; gap: 3px; min-width: 84px; padding: 0 4px;
}
.rday { font: 600 11.5px/1 var(--mono); font-variant-numeric: tabular-nums; letter-spacing: 0.01em; }
.rday.up { color: var(--green); }
.rday.down { color: var(--red); }
.rday.est { opacity: 0.8; }
.skeleton { height: 76px; }
@media (max-width: 680px) {
  .row-price { min-width: 68px; padding: 0 2px; }
  .rday { font-size: 10.5px; }
}
/* v2 height trim: 76px standard card on desktop too (was ~87 from padding). */
.row-main { padding: 10px 14px 10px 16px; gap: 6px; }
@media (min-width: 681px) { .row-main { padding: 10px 15px 10px 16px; } }

/* ── Wave 3R (#5+#6+#31): expanded panel v2 ─────────────────────────────────
   Horizontal trade ladder (SL → IN → TP1 → TP2 → TP3 reading in trade order,
   arrows between cells), checklist as inline pass/fail chips, and View
   chart → promoted to the panel's primary action. On phones the ladder
   reflows to a 2-row grid (#31) — never five squished columns. */
.vk-ladder-h {
  display: grid; grid-template-columns: repeat(5, 1fr); gap: 1px;
  background: var(--separator); border-radius: var(--radius-md); overflow: hidden;
}
.vk-cell {
  display: flex; flex-direction: column; gap: 4px; padding: 11px 12px 10px;
  background: var(--panel); min-width: 0; position: relative;
}
.vk-cell-key { font: 700 10.5px/1 var(--mono); letter-spacing: 0.08em; color: var(--muted-2); }
.vk-cell-key::after { content: " →"; opacity: 0.45; }
.vk-cell:last-child .vk-cell-key::after { content: ""; }
.vk-cell-price { font: 700 15px/1 var(--mono); font-variant-numeric: tabular-nums; color: var(--text); white-space: nowrap; }
.vk-cell-sub { font: 500 10.5px/1.35 var(--sans); color: var(--muted-2); }
.vk-sl .vk-cell-key, .vk-sl .vk-cell-price { color: var(--red); }
.vk-sl { box-shadow: inset 0 2px 0 var(--red); }
.vk-entry .vk-cell-key, .vk-entry .vk-cell-price { color: var(--blue); }
.vk-entry { box-shadow: inset 0 2px 0 var(--blue); }
.vk-tp .vk-cell-key, .vk-tp .vk-cell-price { color: var(--green); }
.vk-tp { box-shadow: inset 0 2px 0 var(--green); }
@media (max-width: 680px) {
  /* #31: 2-row reflow — SL + IN across the top, the three TPs beneath. */
  .vk-ladder-h { grid-template-columns: repeat(6, 1fr); }
  .vk-cell { padding: 10px 10px 9px; }
  .vk-sl, .vk-entry { grid-column: span 3; }
  .vk-tp { grid-column: span 2; }
}
/* #6: checklist chips */
.vk-checks { display: flex; flex-wrap: wrap; gap: 6px; }
.vk-chk {
  display: inline-flex; align-items: center; gap: 6px; padding: 6px 11px;
  border-radius: 999px; font: 600 11.5px/1 var(--sans); cursor: default;
  border: 1px solid var(--border-2); color: var(--text-2); background: var(--panel);
}
.vk-chk b { font-weight: 800; }
.vk-chk.ok { color: var(--green); border-color: rgba(47, 208, 127, 0.35); background: var(--green-soft); }
.vk-chk.no { color: var(--red); border-color: rgba(255, 92, 92, 0.3); background: rgba(255, 92, 92, 0.08); }
/* #6: View chart → is the panel's primary CTA */
.vk-chart-btn {
  background: var(--blue); border-color: var(--blue); color: #fff !important;
  font-weight: 700; padding: 8px 14px; border-radius: 10px;
}
.vk-chart-btn:hover { filter: brightness(1.12); }

/* ── Wave 5 #47: FUND/REIT dimming (default on, ⚠ FUNDS chip toggles) ───── */
.row-wrap.row-dim { opacity: 0.45; }
.row-wrap.row-dim:hover, .row-wrap.row-dim.open { opacity: 1; }
.tb-dim.is-active { color: var(--orange); }

/* ── Wave 4 core (#27+#28+#33): phone rows + touch targets ──────────────────
   ≤680px: 44px grade rail; company name gets its OWN line under the ticker
   (was display:none); price + day-%% stay right-aligned; ≤480px drops the
   spark but keeps the day-%%. Tap targets: 44px boxes on star/expand/copy,
   invisible ±5px hit-area extensions on chips/pills/segs (iOS HIG). */
@media (max-width: 680px) {
  .row { grid-template-columns: 44px 1fr auto auto; }
  .row-grade { font-size: 12.5px; }
  .row-main { padding: 9px 10px 9px 12px; gap: 5px; }
  .row-line1 { flex-wrap: wrap; row-gap: 2px; }
  .cname {
    display: block; flex-basis: 100%; order: 5; max-width: none;
    font-size: 12px; line-height: 1.25;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  /* Debug-copy is a desktop tool — its 44px box starved the ticker line. */
  .row-copy-debug { display: none; }
  .t-star, .row-expand {
    min-width: 38px; min-height: 44px; position: relative;
    display: inline-flex; align-items: center; justify-content: center;
  }
  .t-star::after, .row-expand::after { content: ""; position: absolute; inset: -3px; }
  .row-right { gap: 0; }
  .row-price { min-width: 62px; }
  .row-kpis { min-width: 44px; }
  .seg-btn, .vkf-chip, .fpill, .tb-sort-label, .tb-sort-dir { position: relative; }
  .seg-btn::after, .vkf-chip::after, .fpill::after,
  .tb-sort-label::after, .tb-sort-dir::after {
    content: ""; position: absolute; inset: -5px;
  }
}
@media (max-width: 480px) {
  .row-spark { display: none; }   /* #28: spark goes, day-%% stays */
}

/* ═══ Wave 4 mobile foundations (#35 safe-area · #37 16px inputs) ═══════════
   Appended last so these win on order. Scoped to phones — desktop untouched. */
@media (max-width: 680px) {
  /* #37: a 16px floor on every keyboard-invoking input kills iOS's
     zoom-on-focus (which then never zooms back out). Beats the per-class
     13-15px sizes (.pm-search / .mj-input / .jr-modal-input) via !important —
     the one place it's the accepted fix. Range/checkbox/radio excluded. */
  input[type="text"], input[type="search"], input[type="number"],
  input[type="email"], input[type="tel"], input[type="password"],
  input:not([type]), textarea, select { font-size: 16px !important; }

  /* #35: safe-area insets — content clears the notch (portrait status bar +
     landscape side cutout) and the home indicator. viewport-fit=cover is
     already set in every page's <meta viewport>. */
  .topbar {
    padding-top: max(11px, env(safe-area-inset-top, 0px));
    padding-left: max(14px, env(safe-area-inset-left, 0px));
    padding-right: max(14px, env(safe-area-inset-right, 0px));
  }
  .wrap {
    padding-left: max(14px, env(safe-area-inset-left, 0px));
    padding-right: max(14px, env(safe-area-inset-right, 0px));
  }
  .site-tabs {
    padding-left: env(safe-area-inset-left, 0px);
    padding-right: env(safe-area-inset-right, 0px);
  }
  /* Full-screen overlays must clear the notch too. */
  .search-overlay { padding-top: env(safe-area-inset-top, 0px); }
}

/* ── Wave 4 #44: star tap micro-animation ───────────────────────────────── */
@keyframes star-pop { 0% { transform: scale(1); } 40% { transform: scale(1.4); } 70% { transform: scale(0.9); } 100% { transform: scale(1); } }
.t-star.pop { animation: star-pop .32s cubic-bezier(.2,.8,.3,1.4); }
@media (prefers-reduced-motion: reduce) { .t-star.pop { animation: none; } }

/* ── Wave 4 #45: long-press quick-action sheet ──────────────────────────── */
.qa-scrim {
  position: fixed; inset: 0; z-index: 95; display: flex; align-items: flex-end;
  background: rgba(0,0,0,0); transition: background .2s ease;
}
.qa-scrim[hidden] { display: none; }        /* CSS display overrides hidden — restore it */
.qa-scrim.is-open { background: rgba(0,0,0,0.55); }
.qa-sheet {
  width: 100%; background: var(--elevated, var(--panel));
  border-radius: 20px 20px 0 0; border-top: 0.5px solid var(--separator);
  padding: 8px 14px calc(14px + env(safe-area-inset-bottom, 0)); box-sizing: border-box;
  transform: translateY(100%); transition: transform .22s cubic-bezier(.2,.8,.2,1);
}
.qa-scrim.is-open .qa-sheet { transform: translateY(0); }
.qa-hd { display: flex; flex-direction: column; gap: 2px; padding: 4px 6px 12px; }
.qa-hd b { font: 800 18px/1.1 var(--sans); color: var(--text); letter-spacing: -0.01em; }
.qa-hd span { font: 500 12.5px/1.3 var(--sans); color: var(--muted); }
.qa-act {
  display: flex; align-items: center; gap: 13px; width: 100%; box-sizing: border-box;
  appearance: none; border: 0; background: var(--fill-2); color: var(--text);
  font: 700 15px/1 var(--sans); text-align: left; text-decoration: none;
  padding: 15px 16px; border-radius: 12px; margin-bottom: 8px; min-height: 52px; cursor: pointer;
}
.qa-act:active { background: var(--fill); }
.qa-ico { font-size: 19px; width: 24px; text-align: center; }
.qa-cancel { justify-content: center; background: transparent; color: var(--muted); font-weight: 600; margin-bottom: 0; }

/* ── Wave 4 #43: one-time Add-to-Home-Screen nudge (phones) ─────────────── */
.a2hs {
  position: fixed; left: 10px; right: 10px; z-index: 85;
  bottom: calc(66px + env(safe-area-inset-bottom, 0));   /* just above the tab bar */
  display: flex; align-items: center; gap: 10px;
  background: var(--elevated, var(--panel)); border: 1px solid var(--border-2);
  border-radius: 14px; padding: 11px 12px; box-shadow: 0 12px 30px rgba(0,0,0,.4);
  transform: translateY(140%); opacity: 0; transition: transform .28s cubic-bezier(.2,.8,.2,1), opacity .28s;
}
.a2hs.in { transform: translateY(0); opacity: 1; }
.a2hs-ico { font-size: 20px; flex: 0 0 auto; }
.a2hs-msg { flex: 1; font: 600 12.5px/1.35 var(--sans); color: var(--text-2); }
.a2hs-msg b { color: var(--text); }
.a2hs-add { appearance: none; border: 0; background: var(--blue); color: #fff; font: 800 12.5px/1 var(--sans); padding: 9px 14px; border-radius: 999px; flex: 0 0 auto; cursor: pointer; }
.a2hs-x { appearance: none; border: 0; background: var(--fill-2); color: var(--muted); width: 30px; height: 30px; border-radius: 999px; font-size: 13px; flex: 0 0 auto; cursor: pointer; }

/* ── Wave 4 #25+#26: thumb-height controls in the mobile strips ──────────────
   The command-bar pills and the sticky filter toolbar carry the SAME content
   as desktop and h-scroll (done earlier); this gives their controls proper
   >=40px touch height on phones per the iOS HIG. */
@media (max-width: 680px) {
  #toolbar .seg-btn, #toolbar .vkf-chip, #toolbar .tb-watch,
  #toolbar .tb-sort-label, #toolbar .tb-sort-dir {
    min-height: 40px; display: inline-flex; align-items: center; justify-content: center;
  }
  #toolbar .seg { align-items: stretch; }
  #deck-pills .fpill { min-height: 38px; display: inline-flex; align-items: center; }
  /* the strips already scroll; make the momentum feel native + hide the bar */
  #deck-pills { -webkit-overflow-scrolling: touch; }
}

/* ── Wave 5 #48/#49/#50/#51: group headers, +N affordance, panel tools ────── */
/* #48: sticky grade-group headers (shown only when sorted by SCORE). */
.row-group {
  position: sticky; top: calc(var(--topbar-h, 53px) + 46px); z-index: 5;
  display: flex; align-items: center; justify-content: space-between;
  padding: 7px 16px; margin: 0; background: var(--nav);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border); box-shadow: inset 3px 0 0 var(--grade-color, var(--grade-c));
  font: 800 11px/1 var(--sans); letter-spacing: 0.06em; color: var(--grade-color, var(--text-2));
}
.row-group-n { font: 800 11px/1 var(--mono); color: var(--muted-2); background: var(--fill-2); border-radius: 999px; padding: 3px 8px; }
/* #49: the +N overflow chip is an explicit, tappable expand affordance. */
.chip-more { cursor: pointer; }
.chip-more:hover { border-color: var(--blue); color: var(--text); }
/* #50: focused row gets a clear ring (also helps mouse users tab through). */
.row-wrap:focus-visible { outline: 2px solid var(--blue); outline-offset: -2px; border-radius: 12px; }
/* #51: copy-debug in the expanded panel. */
.dp-tools { display: flex; justify-content: flex-end; padding: 10px 2px 2px; }
.dp-copy {
  display: inline-flex; align-items: center; gap: 7px; appearance: none; cursor: pointer;
  border: 1px solid var(--border); background: var(--fill-2); color: var(--muted);
  font: 600 11px/1 var(--sans); padding: 8px 12px; border-radius: 999px;
}
.dp-copy:hover { color: var(--text-2); border-color: var(--border-2); }

/* ── Wave 5 #55: cross-lens watch badges + other-lens strip ─────────────── */
.lens-badge {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; border-radius: 5px; flex: 0 0 auto;
  font: 800 9px/1 var(--mono); color: #fff;
}
.lens-badge.lens-V { background: var(--blue); }
.lens-badge.lens-P { background: var(--purple, #bf5af2); }
.lens-badge.lens-S { background: var(--orange); }
.olw { margin: 14px 2px 4px; padding-top: 14px; border-top: 1px dashed var(--border); }
.olw-hd { font: 700 10.5px/1.3 var(--sans); letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted-2); margin-bottom: 10px; }
.olw-row { display: flex; flex-wrap: wrap; gap: 8px; }
.olw-chip {
  display: inline-flex; align-items: center; gap: 6px; text-decoration: none;
  background: var(--fill-2); border: 1px solid var(--border); border-radius: 999px;
  padding: 7px 12px; color: var(--text); font: 800 13px/1 var(--sans);
}
.olw-chip:hover { border-color: var(--blue); }

/* ── Wave 6 #58: skip render work for off-screen rows ───────────────────────
   content-visibility:auto lets the browser skip layout+paint for rows outside
   the viewport (big win on 200-400 row NASDAQ lists); the intrinsic-size
   placeholder keeps the scrollbar honest. On-screen + expanded rows render
   fully as normal. */
.row-wrap { content-visibility: auto; contain-intrinsic-size: auto 76px; }
.row-wrap.open { content-visibility: visible; }   /* never virtualize an open panel */

/* ── Wave 6 #68: windowed-list "show all" notice ────────────────────────── */
.row-cap { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: center;
  padding: 16px; margin-top: 8px; font: 500 12.5px/1.5 var(--sans); color: var(--muted); text-align: center; }
.row-cap-all { appearance: none; border: 1px solid var(--blue); background: transparent; color: var(--blue);
  font: 700 12.5px/1 var(--sans); padding: 8px 14px; border-radius: 999px; cursor: pointer; }
.row-cap-all:hover { background: var(--blue); color: #fff; }

/* ── Wave 6 #65: sprite icon fills (star fill toggles via .starred) ──────── */
.t-star svg { fill: none; stroke: currentColor; stroke-width: 2; }
.t-star.starred svg { fill: currentColor; }
.row-expand svg { fill: none; stroke: currentColor; stroke-width: 2.2; }

/* ── UX top-10 #2: system-status pill + popover ──────────────────────────── */
.sys-pill {
  appearance: none; cursor: pointer; border-radius: 999px; padding: 3px 10px;
  font: 700 10.5px/1.4 var(--sans); letter-spacing: .03em; white-space: nowrap;
  border: 1px solid var(--border); background: var(--fill); color: var(--muted);
  transition: border-color .15s, background .15s;
}
.sys-pill.ok   { color: var(--green); background: var(--green-soft); border-color: color-mix(in srgb, var(--green) 30%, transparent); }
.sys-pill.warn { color: var(--orange); background: color-mix(in srgb, var(--orange) 13%, transparent); border-color: color-mix(in srgb, var(--orange) 38%, transparent); }
.sys-pill:hover { border-color: var(--blue); }
.sys-pill[hidden] { display: none; }
.sys-popover {
  position: absolute; z-index: 999; width: 264px;
  background: var(--panel-2); border: 1px solid var(--border-2); border-radius: 12px;
  padding: 12px 14px; box-shadow: 0 14px 40px rgba(0,0,0,.5);
  font: 500 12px/1.5 var(--sans); color: var(--text-2);
}
.sysp-row { display: flex; justify-content: space-between; gap: 10px; padding: 3px 0; }
.sysp-k { color: var(--muted); font-weight: 600; }
.sysp-row b { color: var(--text); font-weight: 700; }
.sysp-row b.r-ok { color: var(--green); }
.sysp-row b.r-warn { color: var(--orange); }
.sysp-sub { color: var(--muted-2); font-weight: 500; font-size: 10.5px; }
.sysp-note { margin: 8px 0; padding-top: 8px; border-top: 1px solid var(--border); color: var(--muted); font-size: 11px; }
.sysp-link { display: inline-block; color: var(--blue); text-decoration: none; font-weight: 700; font-size: 11.5px; }
.sysp-link:hover { text-decoration: underline; }

/* ── UX top-10 #3: first-visit onboarding ────────────────────────────────── */
.ob-scrim {
  position: fixed; inset: 0; z-index: 1000; display: grid; place-items: center;
  background: rgba(6, 9, 14, 0.72); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  padding: 20px;
}
.ob-card {
  width: min(92vw, 400px); background: var(--panel); border: 1px solid var(--border-2);
  border-radius: var(--radius); box-shadow: 0 24px 70px rgba(0,0,0,.55);
  padding: 26px 24px 20px; text-align: center;
}
.ob-ico { font-size: 34px; margin-bottom: 10px; }
.ob-title { margin: 0 0 8px; font: 800 19px/1.25 var(--sans); letter-spacing: -0.01em; color: var(--text); }
.ob-body { margin: 0 0 16px; font: 500 13.5px/1.6 var(--sans); color: var(--text-2); }
.ob-dots { display: flex; justify-content: center; gap: 6px; margin-bottom: 16px; }
.ob-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--fill); border: 1px solid var(--border); }
.ob-dot.on { background: var(--green); border-color: var(--green); }
.ob-actions { display: flex; justify-content: space-between; gap: 10px; }
.ob-skip {
  appearance: none; border: none; background: none; cursor: pointer;
  color: var(--muted); font: 600 12.5px/1 var(--sans); padding: 10px 8px;
}
.ob-skip:hover { color: var(--text); }
.ob-next {
  appearance: none; cursor: pointer; border: none; border-radius: 999px;
  background: var(--green); color: #06240f; font: 800 13px/1 var(--sans);
  padding: 11px 22px; letter-spacing: .01em;
}
.ob-next:hover { filter: brightness(1.08); }

/* ── UX top-10 #9: recs morning-read strip ───────────────────────────────── */
.mr-strip {
  background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius-md);
  box-shadow: var(--shadow); padding: 13px 16px; margin: 0 0 14px;
}
.mr-strip[hidden] { display: none; }
.mr-hd { font: 800 14px/1.3 var(--sans); color: var(--text); margin-bottom: 9px; }
.mr-sub { font: 500 11px/1.3 var(--sans); color: var(--muted-2); margin-left: 6px; }
.mr-stats { display: flex; flex-wrap: wrap; gap: 8px 18px; margin-bottom: 10px; }
.mr-stat { font: 600 12.5px/1.5 var(--sans); color: var(--muted); display: inline-flex; align-items: center; gap: 7px; }
.mr-stat b { color: var(--text); font: 800 14px/1 var(--mono); font-variant-numeric: tabular-nums; }
.mr-delta { font: 700 10.5px/1 var(--mono); padding: 3px 7px; border-radius: 6px; white-space: nowrap; }
.mr-delta.up   { color: var(--green); background: var(--green-soft); }
.mr-delta.down { color: var(--red); background: var(--red-soft); }
.mr-delta.flat { color: var(--muted); background: var(--fill); }
.mr-watch { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding-top: 10px; border-top: 1px solid var(--border); }
.mr-watch-lbl { font: 600 11px/1 var(--sans); letter-spacing: .05em; text-transform: uppercase; color: var(--muted); }
.mr-pick {
  display: inline-flex; align-items: center; gap: 6px; text-decoration: none;
  font: 800 12.5px/1 var(--mono); color: var(--text);
  background: var(--fill); border: 1px solid var(--border); border-radius: 999px; padding: 7px 12px;
  transition: border-color .15s;
}
.mr-pick:hover { border-color: var(--green); color: var(--green); }
.mr-pick-mkt { font: 700 9px/1 var(--sans); letter-spacing: .07em; color: var(--muted-2); }

/* ── UX top-10 #4: proportional plan axis + R:R meter (row detail) ───────── */
.vk-axis { margin: 2px 0 12px; }
.vk-axis-track {
  position: relative; height: 40px; border-radius: 8px;
  background: var(--fill-2); border: 1px solid var(--border);
}
.vk-axis-seg { position: absolute; top: 6px; height: 8px; border-radius: 4px; }
.vk-axis-seg.risk   { background: color-mix(in srgb, var(--red) 45%, transparent); }
.vk-axis-seg.reward { background: color-mix(in srgb, var(--green) 45%, transparent); }
.vk-axis-tick {
  position: absolute; top: 3px; transform: translateX(-50%);
  font: 700 8.5px/1 var(--mono); letter-spacing: .04em; color: var(--muted);
  text-align: center; padding-top: 15px; cursor: help;
}
.vk-axis-tick i { position: absolute; left: 50%; top: 0; width: 2px; height: 14px; background: currentColor; border-radius: 1px; transform: translateX(-50%); }
.vk-axis-tick.sl { color: var(--red); }
.vk-axis-tick.in { color: var(--text); font-weight: 800; }
.vk-axis-tick.tp { color: var(--green); }
.vk-axis-now {
  position: absolute; top: 1px; width: 12px; height: 12px; border-radius: 50%;
  background: var(--blue); border: 2px solid var(--bg); transform: translateX(-50%);
  box-shadow: 0 0 8px var(--blue); z-index: 2;
}
.vk-axis-meta { display: flex; align-items: center; gap: 10px; margin-top: 7px; }
.vk-rrmeter { display: inline-flex; width: 130px; height: 7px; border-radius: 4px; overflow: hidden; background: var(--fill); }
.vk-rrmeter .rm-risk { background: var(--red); opacity: .75; }
.vk-rrmeter .rm-rw { background: var(--green); opacity: .8; }
.vk-axis-note { font: 600 11px/1.2 var(--mono); color: var(--muted); font-variant-numeric: tabular-nums; }

/* ── UX top-10 #5: toolbar density on wide screens — one line at ≥1500px ── */
@media (min-width: 1200px) {
  #toolbar .vkf-chip { padding: 6px 8px; font-size: 12px; }
  #toolbar .seg-btn { padding: 6px 9px; }
  .tb-line { gap: 5px; }
  #toolbar #vk-filters { gap: 5px; }
  .tb-watch { padding: 7px 10px; }
  .tb-sort-label { min-width: 54px; }
}

/* ── UX top-10 #10: cross-document view transitions (progressive) ────────── */
@view-transition { navigation: auto; }
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; }
}

/* ── UX-20 #1: what-changed markers ──────────────────────────────────────── */
.chg { font: 800 8.5px/1 var(--sans); letter-spacing: .05em; padding: 3px 5px; border-radius: 5px; vertical-align: 2px; }
.chg-new  { color: var(--blue); background: var(--blue-soft); }
.chg-up   { color: var(--green); background: var(--green-soft); font-size: 10px; }
.chg-down { color: var(--red); background: var(--red-soft); font-size: 10px; }

/* ── UX-20 #6: per-row W/3D/D dots ───────────────────────────────────────── */
.tfdots { display: inline-flex; gap: 3px; align-items: center; margin: 0 2px; cursor: help; }
.tfd { width: 6px; height: 6px; border-radius: 50%; background: var(--fill); border: 1px solid var(--border); }
.tfd.on   { background: var(--green); border-color: var(--green); box-shadow: 0 0 4px var(--green); }
.tfd.near { background: transparent; border-color: var(--orange); }
.tfd.off  { opacity: .55; }

/* ── UX-20 #3: ★ MY NAMES strip ─────────────────────────────────────────── */
.watch-strip {
  display: flex; align-items: center; flex-wrap: wrap; gap: 7px;
  margin: 0 0 12px; padding: 9px 12px; border-radius: 12px;
  background: var(--panel); border: 1px solid var(--border);
}
.watch-strip[hidden] { display: none; }
.ws-lbl { appearance: none; border: none; background: none; cursor: pointer;
  font: 800 10px/1 var(--sans); letter-spacing: .08em; color: var(--muted); padding: 4px 2px; }
.ws-lbl:hover { color: var(--text); }
.ws-chip {
  display: inline-flex; align-items: center; gap: 5px; text-decoration: none; cursor: pointer;
  font: 700 11.5px/1 var(--mono); color: var(--text);
  background: var(--fill); border: 1px solid var(--border); border-radius: 999px; padding: 6px 10px;
  transition: border-color .15s;
}
.ws-chip:hover { border-color: var(--green); }
.ws-chip.quiet { color: var(--muted); }
.ws-g { font: 800 9px/1 var(--sans); color: var(--grade-aplus); }
.ws-d.l { color: var(--green); } .ws-d.s { color: var(--red); }
.ws-al { color: var(--teal); }
.ws-all { margin-left: auto; font: 700 10.5px/1 var(--sans); color: var(--blue); text-decoration: none; }
.ws-all:hover { text-decoration: underline; }

/* ── UX-20 #2: views menu ────────────────────────────────────────────────── */
.tb-views { min-width: 34px; }
.views-menu {
  position: absolute; z-index: 999; min-width: 220px;
  background: var(--panel-2); border: 1px solid var(--border-2); border-radius: 12px;
  padding: 8px; box-shadow: 0 14px 40px rgba(0,0,0,.5);
}
.vm-row { display: flex; align-items: center; gap: 6px; }
.vm-apply { flex: 1; appearance: none; border: none; background: none; cursor: pointer; text-align: left;
  color: var(--text); font: 600 12.5px/1.3 var(--sans); padding: 8px 9px; border-radius: 8px; }
.vm-apply:hover { background: var(--fill); }
.vm-del { appearance: none; border: none; background: none; cursor: pointer; color: var(--muted); font-size: 11px; padding: 6px; }
.vm-del:hover { color: var(--red); }
.vm-empty { color: var(--muted); font: 500 12px/1.4 var(--sans); padding: 8px 9px; }
.vm-save { width: 100%; appearance: none; border: none; cursor: pointer; margin-top: 4px;
  background: var(--fill); color: var(--blue); font: 700 12px/1 var(--sans); padding: 9px; border-radius: 8px; }
.vm-save:hover { background: var(--blue-soft); }

/* ── UX-20 #12: per-setup sizing line in the row detail ──────────────────── */
.vk-size {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  margin: 2px 0 10px; padding: 8px 12px; border-radius: 10px;
  border: 1px dashed var(--border-2); background: rgba(120,120,128,.07);
  font: 600 12px/1.5 var(--sans); color: var(--muted);
}
.vk-size-out { color: var(--text); }
.vk-size-out b { font-family: var(--mono); font-size: 13px; }
.vk-size-src { color: var(--muted); font-weight: 500; }
.vk-size label { display: inline-flex; align-items: center; gap: 4px; color: var(--muted); }
.vk-size input {
  width: 76px; padding: 4px 7px; border-radius: 8px; border: 1px solid var(--border-2);
  background: rgba(0,0,0,.25); color: var(--text); font: 600 12px/1 var(--mono);
}
.vk-size input:focus { outline: none; border-color: var(--blue); }
.vk-size input[data-k="risk"] { width: 52px; }

/* ── UX-20 #14: recs week-in-review strip ────────────────────────────────── */
.rec-week {
  margin: 0 0 14px; padding: 11px 16px; border-radius: var(--r-mid, 14px);
  border: 1px solid var(--border); background: var(--panel);
}
.rw-hd { font: 700 12.5px/1 var(--sans); letter-spacing: .02em; margin-bottom: 8px; }
.rw-sub { color: var(--muted); font-weight: 600; font-size: 11px; margin-left: 6px; }
.rw-body { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 14px; font: 600 12px/1.5 var(--sans); color: var(--muted); }
.rw-lbl { text-transform: uppercase; font-size: 10px; letter-spacing: .07em; }
.rw-arc b { color: var(--text); font-family: var(--mono); font-weight: 700; }
.rw-arc i, .rw-bot b { font-style: normal; font-family: var(--mono); }
.rw-arc .up, .rw-bot .up { color: var(--green); }
.rw-arc .down, .rw-bot .down { color: var(--red); }
.rw-arc .flat { color: var(--muted); }
.rw-bot { color: var(--text); }

/* ── UX-20 #15+#16: ⌘K command palette (nav.js, every page) ──────────────── */
.cp-overlay {
  position: fixed; inset: 0; z-index: 120; background: rgba(4,7,12,.6);
  backdrop-filter: blur(3px); display: flex; justify-content: center;
  align-items: flex-start; padding: max(9vh, 46px) 14px 20px;
}
.cp-overlay[hidden] { display: none; }
.cp-box {
  width: min(560px, 100%); border-radius: 16px; overflow: hidden;
  border: 1px solid var(--border-2); background: var(--panel, #131a26);
  box-shadow: 0 24px 70px rgba(0,0,0,.6);
}
.cp-input-row { display: flex; align-items: center; gap: 9px; padding: 12px 14px; border-bottom: 1px solid var(--border); }
.cp-glyph { color: var(--muted); font: 700 13px/1 var(--mono); }
.cp-input {
  flex: 1 1 auto; min-width: 0; border: none; background: none; color: var(--text);
  font: 600 15px/1.4 var(--sans); outline: none;
}
.cp-esc { font: 600 10px/1 var(--mono); color: var(--muted); border: 1px solid var(--border-2); border-radius: 5px; padding: 3px 5px; }
.cp-list { max-height: min(52vh, 430px); overflow-y: auto; padding: 6px; }
.cp-hd { font: 700 9.5px/1 var(--sans); letter-spacing: .09em; text-transform: uppercase; color: var(--muted); padding: 8px 10px 5px; }
.cp-item {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  padding: 9px 10px; border: none; border-radius: 10px; background: none;
  color: var(--text); font: 600 13px/1.3 var(--sans); cursor: pointer;
}
.cp-item:hover, .cp-item.is-sel { background: rgba(120,120,128,.16); }
.cp-item.is-sel { outline: 1px solid var(--border-2); }
.cp-ico { flex: 0 0 22px; text-align: center; font-size: 13px; }
.cp-ico.cp-long { color: var(--green); }
.cp-ico.cp-short { color: var(--red); }
.cp-lbl { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cp-item .cp-lbl { font-family: var(--sans); }
.cp-meta { flex: 0 0 auto; color: var(--muted); font: 600 11px/1 var(--mono); }
.cp-grade { color: var(--grade-aplus, #2fd07f); }
.cp-note { padding: 12px 10px; color: var(--muted); font: 500 12px/1.5 var(--sans); }

/* the MORE sheet's search row is a <button> among <a> rows */
button.more-sheet-row { width: 100%; background: none; border: none; font: inherit; color: inherit; cursor: pointer; text-align: left; }

/* ── UX-20 #17: compact row density ──────────────────────────────────────── */
body.density-compact .rows { gap: 7px; }
body.density-compact .row { min-height: 54px; grid-template-columns: 50px 1fr auto; }
body.density-compact .row-main { padding: 9px 14px 8px; gap: 4px; }
body.density-compact .row-grade { font-size: 12px; }
body.density-compact .cname { font-size: 12.5px; }
body.density-compact .rprice { font-size: 15px; }
body.density-compact .row-spark svg { height: 20px; width: 52px; }
body.density-compact .row-chips:empty { display: none; }
body.density-compact .badge { padding: 2.5px 5px; }

/* ── UX-20 #18: sector group headers ─────────────────────────────────────── */
.row-group-sector span:first-child { letter-spacing: .07em; }

/* degraded-universe tripwire (2026-07-26) */
.scan-degraded {
  color: var(--orange, #ffb020); font: 700 11px/1 var(--sans);
  padding: 3px 8px; border-radius: 999px; border: 1px solid rgba(255,176,32,.4);
  background: rgba(255,176,32,.1); white-space: nowrap; cursor: help;
}

/* ── Fix-10 batch A ──────────────────────────────────────────────────────── */
/* #5: shared bottom toast (trade-card copy etc.) */
.gbs-toast {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(24px + env(safe-area-inset-bottom, 0)); z-index: 130;
  max-width: min(92vw, 520px); padding: 11px 18px; border-radius: 12px;
  border: 1px solid var(--border-2); background: var(--panel, #131a26);
  color: var(--text); font: 600 12.5px/1.5 var(--sans); text-align: center;
  box-shadow: 0 14px 44px rgba(0,0,0,.55); animation: pa-in .22s ease;
}
.gbs-toast.tappable { cursor: pointer; }
.gbs-toast.tappable:hover { border-color: var(--blue); }
.gbs-toast.out { opacity: 0; transition: opacity .4s ease; }
body.has-site-tabs .gbs-toast { bottom: calc(76px + env(safe-area-inset-bottom, 0)); }
@keyframes pa-in { from { opacity: 0; transform: translate(-50%, 6px); } }

/* #2: price-alert manager card (alerts page) */
.pa-manager {
  margin: 0 0 16px; padding: 13px 16px; border-radius: var(--r-mid, 14px);
  border: 1px solid var(--border); background: var(--panel);
}
.pa-mg-hd { font: 700 13px/1.4 var(--sans); display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.pa-mg-hd b { font-family: var(--mono); color: #00d2ff; }
.pa-mg-sub { font: 500 11px/1.5 var(--sans); color: var(--muted); }
.pa-mg-rows { margin-top: 10px; display: flex; flex-direction: column; gap: 2px; }
.pa-mg-row {
  display: flex; align-items: center; gap: 10px; padding: 7px 8px;
  border-radius: 9px; font: 600 12.5px/1.4 var(--sans);
}
.pa-mg-row:hover { background: rgba(120,120,128,.1); }
.pa-mg-sym { font: 700 13px/1 var(--mono); color: var(--text); text-decoration: none; min-width: 52px; }
.pa-mg-sym:hover { color: var(--blue); }
.pa-mg-mkt { font: 600 9.5px/1 var(--mono); letter-spacing: .06em; color: var(--muted);
  border: 1px solid var(--border-2); border-radius: 4px; padding: 3px 5px; }
.pa-mg-px { color: var(--muted); flex: 1 1 auto; }
.pa-mg-px b { font-family: var(--mono); color: #00d2ff; }
.pa-mg-ago { font: 500 11px/1 var(--sans); color: var(--muted); }
.pa-mg-del {
  border: none; background: none; color: var(--muted); cursor: pointer;
  font: 700 13px/1 var(--mono); padding: 5px 8px; border-radius: 7px;
}
.pa-mg-del:hover { color: var(--red); background: rgba(255,91,91,.14); }

/* #6: alert count on the ALERTS nav pill / sheet row + row ⏰ chip */
.nav-count {
  display: inline-block; min-width: 15px; text-align: center; margin-left: 2px;
  padding: 2px 5px; border-radius: 999px; font: 700 9.5px/1 var(--mono);
  background: rgba(0,210,255,.18); color: #00d2ff;
}
.row-alert { font-size: 11px; line-height: 1; opacity: .85; flex-shrink: 0; }

/* #3: palette personal rows */
.cp-ico.cp-mine { color: var(--amber, #ffb020); }

/* #4: copy-plan button in the row detail */
.vk-copy-btn { cursor: pointer; background: none; }
