/* Tachyon Flux — premium dark theme, Ross-style multi-panel grid. */

/* Vendored fonts (served from /vendor/fonts — zero external network).
   font-display:swap → text paints instantly in a fallback, then swaps when the
   woff2 finishes; never blocks render, never touches the live-update path. */
@font-face {
  font-family: 'Archivo'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('/vendor/fonts/archivo-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Archivo'; font-style: normal; font-weight: 600; font-display: swap;
  src: url('/vendor/fonts/archivo-600.woff2') format('woff2');
}
@font-face {
  font-family: 'Archivo'; font-style: normal; font-weight: 700; font-display: swap;
  src: url('/vendor/fonts/archivo-700.woff2') format('woff2');
}
@font-face {
  font-family: 'Cousine'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('/vendor/fonts/cousine-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Cousine'; font-style: normal; font-weight: 700; font-display: swap;
  src: url('/vendor/fonts/cousine-700.woff2') format('woff2');
}

:root {
  /* Two families: a grotesque sans (Archivo) for chrome/headings, and a crisp
     mono (Cousine) for the scanner data grid so number columns stay aligned. */
  --ui: 'Archivo', -apple-system, 'Segoe UI Variable', 'Segoe UI', system-ui, sans-serif;
  /* Deep indigo/aurora base — no neutral grays anywhere; every "gray" is a
     tinted periwinkle/indigo so the whole deck reads as one cohesive piece. */
  --bg-0: #020410;   /* app backdrop — EXACT logo background field (#020410) */
  --bg-1: #06090f;   /* panel body  — near-black, matches the logo field   */
  --bg-2: #0b0f1e;   /* header / thead — faint lift off black              */
  --bg-3: #141a33;   /* inputs / chips — visible interactive controls      */
  --bg-row-alt: #080b15;    /* zebra striping — barely there on black      */
  --border: #243066;        /* indigo-tinted border   */
  --border-strong: #3c4d9c; /* brighter indigo border */
  --txt-0: #eaf1ff;  /* primary text  (soft white-blue) */
  --txt-1: #abb7ec;  /* secondary     (lavender, NOT gray) */
  --txt-2: #7682c8;  /* tertiary      (periwinkle, NOT gray) */
  --accent:   #36e2ff;  /* cyan   — logo light-stream */
  --accent-2: #6a76ff;  /* blue   — logo light-stream */
  --accent-3: #b06bff;  /* violet — logo light-stream */
  --accent-dim: #1a8aa3;
  --green: #2ce58f;
  --green-soft: #0c2c20;
  --red:   #ff5c7a;
  --red-soft: #2e1020;
  --amber: #ffc24d;
  --violet: #b48cff;
  --mono: 'Cousine', 'Cascadia Mono', 'Consolas', monospace;
  /* Signature flux gradient (cyan → blue → violet) — the logo's light-streams.
     Reused for brand, focus accents, hairlines. Static; painted where used. */
  --grad:   linear-gradient(90deg, #36e2ff 0%, #6a76ff 50%, #b06bff 100%);
  --grad-v: linear-gradient(180deg, #36e2ff 0%, #6a76ff 50%, #b06bff 100%);
}

* { box-sizing: border-box; }
html, body { margin:0; padding:0; height:100%; color:var(--txt-0);
  font-family: var(--ui); font-size: 12.5px; overflow: hidden;
  /* tabular figures → number columns stay aligned in the proportional chrome
     font; the data grid itself uses mono (Cousine), so this backs up labels. */
  font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1;
  /* Static radial wash — painted once, gives the deck depth at zero runtime cost. */
  /* Entire backdrop = the logo's EXACT pitch-black field (#020410), FLAT — so
     the logo's square is indistinguishable from the deck (no lightening). */
  background: var(--bg-0);
}

/* Tinted scrollbars (pure chrome, zero runtime cost) */
*::-webkit-scrollbar { width: 9px; height: 9px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: linear-gradient(180deg, #2c3a78, #20285a);
  border-radius: 6px; border: 2px solid transparent; background-clip: padding-box;
}
*::-webkit-scrollbar-thumb:hover { background: #3a4a9a; background-clip: padding-box; }

/* ---------------- Top bar ---------------- */
.topbar {
  display: grid;
  /* Equal side columns → the brand (center, auto) sits at TRUE viewport center,
     independent of how wide the left controls vs right clock are. */
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  height: 44px;
  padding: 0 12px;
  background: linear-gradient(180deg, #1a2350, #0e1330);
  border-bottom: 1px solid transparent;
  /* Aurora accent underline (static) */
  border-image: linear-gradient(90deg, #38e6ff, #b48cff 50%, #ff7a3c) 1;
  gap: 12px;
}
.brand { display: flex; align-items: center; gap: 10px; justify-self: center; }
/* Topbar zones: controls on the left, TACHYON FLUX centered, clock far right. */
.topbar-left  { display: flex; align-items: center; gap: 10px; color: var(--txt-1); font-size: 12.5px; }
.topbar-right { display: flex; align-items: center; gap: 8px; justify-self: end; font-size: 12.5px; }
/* PAPER + market-hours badges sit just before the clock — 6px but kept legible
   (tighter letter-spacing + a touch more padding at this size). */
#mode-badge, #session-badge { font-size: 11px; font-weight: 700; letter-spacing: 0.05em; padding: 3px 7px; }
.brand-mark { font-size: 22px; filter: drop-shadow(0 0 6px rgba(56,230,255,0.7)); }
.brand-name {
  font-weight: 700; letter-spacing: 0.22em; font-size: 24px;
  background: linear-gradient(90deg, #38e6ff, #8ad0ff 40%, #b48cff);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  /* Aurora glow — layered drop-shadows (works on gradient-clipped text where
     text-shadow can't) for an intense cyan→violet halo. */
  filter:
    drop-shadow(0 0 4px rgba(120,210,255,0.9))
    drop-shadow(0 0 10px rgba(80,180,255,0.75))
    drop-shadow(0 0 22px rgba(120,160,255,0.6))
    drop-shadow(0 0 40px rgba(180,140,255,0.5));
}
/* Glossy 3D pill badges (PAPER/LIVE, session) — a translucent top-sheen gradient
   (background-IMAGE, so the per-badge background-COLOR shows through) + inset bevel
   highlights + a soft drop shadow give them a raised, lit look. */
.badge { padding: 2px 9px; border-radius: 999px; font-size: 9px; font-weight: 700; letter-spacing: 0.15em;
  background-image: linear-gradient(180deg, rgba(255,255,255,0.16) 0%, rgba(255,255,255,0.03) 48%, rgba(0,0,0,0.16) 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.22), inset 0 -1px 0 rgba(0,0,0,0.30), 0 1px 2px rgba(0,0,0,0.38); }
.badge-paper   { background-color: var(--green-soft); color: var(--green); border:1px solid #2c4327; }
.badge-live    { background-color: var(--red-soft);   color: var(--red);   border:1px solid #4a262e; }
.badge-session { background-color: var(--bg-3);       color: var(--txt-1); border:1px solid var(--border); }

.connection { display: flex; justify-content: center; align-items: center; gap: 8px; color: var(--txt-1); font-size: 11px; }
.dot { width:8px; height:8px; border-radius:50%; }
.dot-red    { background: var(--red);   box-shadow: 0 0 6px var(--red); }
.dot-green  { background: var(--green); box-shadow: 0 0 6px var(--green); }
.dot-amber  { background: var(--amber); box-shadow: 0 0 6px var(--amber); }
.sep { color: var(--txt-2); }
#focus-ticker { color: var(--accent); font-weight: 700; }

.actions { display: flex; align-items: center; gap: 6px; }
.actions input,
.actions button {
  background: var(--bg-3); color: var(--txt-0); border: 1px solid var(--border);
  padding: 5px 10px; border-radius: 3px; font-family: var(--ui); font-size: 12px;
}
.actions input { padding: 4px 8px; width: 200px; }
.actions input:focus, .actions button:hover { border-color: var(--accent); color: var(--accent); outline: none; }

/* ---------------- Workspace ---------------- */
.workspace {
  display: grid;
  /* Default: NO center column — the Ticker Detail (quote + charts) is hidden
     until a ticker is clicked, mirroring StockDashboard's slide-out detail. */
  grid-template-columns: 1fr 1fr;
  gap: 6px;
  padding: 6px;
  height: calc(100vh - 38px);
}
.workspace .col-center, .workspace .col-charts { display: none; }
/* A ticker is selected → reveal the TICKER DETAIL column then a dedicated CHARTS
   column (right-most). Four columns total: scanners-left, scanners-right, detail,
   charts. Charts get the most width. */
.workspace.detail-open { grid-template-columns: 0.85fr 0.85fr 1fr 1.45fr; }
.workspace.detail-open .col-center,
.workspace.detail-open .col-charts { display: flex; }
.col { display: flex; flex-direction: column; gap: 6px; min-height: 0; min-width: 0; }
.col-left   { order: 1; }   /* scanners */
.col-right  { order: 2; }   /* scanners + news */
.col-center { order: 3; }   /* ticker detail — appears on ticker click */
.col-charts { order: 4; }   /* charts only — right-most when open */
/* Column 2 (col-right) has NO visible panels → collapse it so the remaining
   columns expand into the freed width. Adding any col-right panel drops the class
   and restores the normal grid. Toggled by updateEmptyColumns() in app.js. */
.workspace.col2-empty .col-right { display: none; }
.workspace.col2-empty:not(.detail-open) { grid-template-columns: 1fr; }
.workspace.detail-open.col2-empty { grid-template-columns: 0.85fr 1fr 1.45fr; }
/* Spotlight: the focused-ticker analysis (Vantage View) reads as the HERO of the
   deck — a soft cyan flux glow + brighter border lift it above the scanner grid.
   Static (no animation) → zero runtime cost. */
.workspace.detail-open .col-center > .panel {
  border-color: color-mix(in srgb, var(--accent) 42%, var(--border));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 20%, transparent),
              0 12px 36px -16px color-mix(in srgb, var(--accent) 50%, transparent),
              0 6px 18px -10px rgba(0,0,0,0.7);
}

.panel {
  /* Default accent (overridden per-panel below via --pa). */
  --pa: #38e6ff;
  background: linear-gradient(180deg, #0f1530, var(--bg-1) 40%);
  border: 1px solid var(--border);
  border-radius: 6px;
  display: flex;
  flex-direction: column;
  min-height: 0;
  flex: 1 1 0;
  overflow: hidden;                 /* clip header accent to rounded corners */
  box-shadow: 0 6px 18px -10px rgba(0,0,0,0.7);  /* static depth, painted once */
}
.panel.minimized { flex: 0 0 28px; overflow: hidden; }
/* Increment 2 (perf): isolate each data panel's layout + paint so a row update
   repaints ONLY that panel, never the whole deck — keeps fps steady when many
   panels tick at the open. Chart panes are excluded (KLineChart canvas + its
   ResizeObserver). Pure containment: zero per-tick cost, no offscreen risk
   (panels are flex-fit + internally scrolled, so nothing is clipped away). */
.panel:not(.chart-pane) { contain: layout paint; }

.panel-h {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  padding: 4px 8px;
  /* Per-panel colored glow fading into the header base — the "pleasant color
     per window". color-mix tints from the single --pa; the solid layer below
     is the graceful fallback. Static — zero runtime cost. */
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--pa) 26%, transparent),
      color-mix(in srgb, var(--pa) 4%, transparent) 85%),
    linear-gradient(180deg, var(--bg-2), var(--bg-1));
  border-top: 2px solid var(--pa);
  border-bottom: 1px solid var(--border);
  height: 28px;
}
.panel-title {
  font-weight: 700; letter-spacing: 0.12em; font-size: 12px;
  color: var(--pa);
  /* Per-panel glow in the panel's own accent color (--pa). */
  text-shadow:
    0 0 6px color-mix(in srgb, var(--pa) 65%, transparent),
    0 0 13px color-mix(in srgb, var(--pa) 40%, transparent);
}
/* Per-panel emblem — inherits the panel accent (currentColor), with a soft glow
   in the same hue so each panel reads as its own little branded mark. */
.panel-logo { display: inline-flex; align-items: center; vertical-align: -3px; margin-right: 6px; }
.panel-logo svg { width: 15px; height: 15px; display: block;
  filter: drop-shadow(0 0 3px color-mix(in srgb, var(--pa) 55%, transparent)); }
/* Session status pill on the PM / AH gainer panel headers (LIVE vs ENDED). */
.sess-badge {
  margin-left: 7px; font-size: 9px; font-weight: 800; letter-spacing: 0.08em;
  padding: 1px 6px; border-radius: 9px; vertical-align: middle;
  text-shadow: none; white-space: nowrap;
}
.sess-badge.sess-live {
  color: #051; background: #23e07a;
  box-shadow: 0 0 8px color-mix(in srgb, #23e07a 70%, transparent);
  animation: sessPulse 1.6s ease-in-out infinite;
}
.sess-badge.sess-over {
  color: #9fb0cc; background: color-mix(in srgb, #9fb0cc 14%, transparent);
  border: 1px solid color-mix(in srgb, #9fb0cc 32%, transparent);
}
@keyframes sessPulse { 0%,100% { opacity: 1; } 50% { opacity: 0.55; } }

.panel-meta  { color: #8ea2c4; font-size: 11px; padding-right: 6px; }
.panel-meta.count {
  color: var(--pa); font-weight: 700;
  background: color-mix(in srgb, var(--pa) 14%, transparent);
  padding: 1px 7px; border-radius: 10px;
  border: 1px solid color-mix(in srgb, var(--pa) 35%, transparent);
}

/* ---- Signature color per window (drives header + title + count badge) ---- */
.panel[data-pkey="ignition"]      { --pa: #ff7a3c; }  /* fire — buy window   */
.panel[data-pkey="flame"]         { --pa: #ff4d57; }  /* catalyst flame red  */
.panel[data-pkey="pm_gainers"]    { --pa: #2fd6c4; }  /* teal               */
.panel[data-pkey="top_gainers"]   { --pa: #2ce58f; }  /* green              */
.panel[data-pkey="top_losers"]    { --pa: #ff5c7a; }  /* rose               */
.panel[data-pkey="top_relvol"]    { --pa: #38e6ff; }  /* cyan               */
.panel[data-pkey="top_vol_5m"]    { --pa: #4aa8ff; }  /* sky                */
.panel[data-pkey="reversal"]      { --pa: #b48cff; }  /* violet             */
.panel[data-pkey="ross_gappers"]  { --pa: #9ee84a; }  /* lime               */
.panel[data-pkey="smallcap_hodm"] { --pa: #34e0c0; }  /* aqua               */
.panel[data-pkey="top_rsi"]       { --pa: #ffc24d; }  /* gold               */
.panel[data-pkey="halt"]          { --pa: #ff4d4d; }  /* stop red           */
.panel[data-pkey="recent_ipo"]    { --pa: #e86cff; }  /* magenta            */
.panel[data-pkey="ah_gainers"]    { --pa: #8a8cff; }  /* indigo-violet      */
.panel[data-pkey="penny_gappers"] { --pa: #e0a050; }  /* bronze             */
.panel[data-pkey="A"]             { --pa: #5fc9a0; }  /* mint  ($1-20)      */
.panel[data-pkey="B"]             { --pa: #5f9fd9; }  /* steel ($20-80)     */
.panel[data-pkey="C"]             { --pa: #9b8cf2; }  /* periwinkle (>$80)  */
.panel[data-pkey="largecap_eg"]   { --pa: #b8c2d8; }  /* steel-grey (large) */
.panel[data-pkey="continuation"]  { --pa: #ff9e6a; }  /* coral              */
.panel.quote-panel                { --pa: #38e6ff; }  /* cyan               */
/* News + Order Status are the two .feed-panel windows (no data-pkey). */
.feed-panel:has(#news-list)  { --pa: #5aa0ff; } /* news   — blue  */
.feed-panel:has(#alert-list) { --pa: #ffb43c; } /* alerts — amber */

/* Ignition gets an extra static glow — it's THE panel you watch. */
.panel[data-pkey="ignition"] .panel-h {
  box-shadow: inset 0 0 22px -6px rgba(255,122,60,0.5);
}
.panel-h .x {
  background: none; border: none; color: var(--txt-1);
  font-size: 14px; line-height: 1; padding: 0 4px; cursor: pointer;
}
.panel-h .x:hover { color: var(--red); }
.panel-h input {
  background: var(--bg-3); border: 1px solid var(--border); color: var(--txt-0);
  padding: 2px 6px; font-family: var(--ui); font-size: 10px; width: 110px;
}

/* ---------------- Scanner tables ---------------- */
.scan-wrap { flex: 1; min-height: 0; overflow: auto; }
.scan-table { width: 100%; border-collapse: collapse; }
.scan-table thead { position: sticky; top: 0; background: var(--bg-2); z-index: 3; }
.scan-table th, .scan-table td {
  padding: 3px 6px;
  text-align: right;
  font-size: 12px;
  border-bottom: 1px solid var(--bg-2);
  white-space: nowrap;
}
/* Column names — StockDashboard label tone (#8ea2c4), brighter than the old dim periwinkle. */
.scan-table th { color: #8ea2c4; font-weight: 600; letter-spacing: 0.06em; }
/* Sticky ticker column. z-index 2 keeps it ABOVE the columns that scroll under it
   (thead is 3, so the header still wins on vertical scroll). Backgrounds in every
   row state MUST stay opaque or the scrolling columns bleed through under the name. */
.scan-table th:first-child, .scan-table td:first-child { text-align: left; position: sticky; left: 0; background-color: var(--bg-1); z-index: 2; }
.scan-table tbody tr { cursor: pointer; }
/* New scanner rows fade in; reorder glide is driven by the JS FLIP (translateY). */
@keyframes tk-fadein { from { opacity: 0; } to { opacity: 1; } }
/* New scanner row enters with a brief per-panel flux tint that settles to the row
   colour — a tasteful one-shot "something just landed" cue (uses the panel's --pa). */
@keyframes tk-enter {
  from { opacity: 0; background-color: color-mix(in srgb, var(--pa) 32%, transparent); }
  to   { opacity: 1; }
}
.scan-table tbody tr:nth-child(even) { background-color: var(--bg-row-alt); }
.scan-table tbody tr:nth-child(even) td:first-child { background-color: var(--bg-row-alt); }
.scan-table tbody tr:hover { background-color: var(--bg-3); }
.scan-table tbody tr:hover td:first-child { background-color: var(--bg-3); }
.scan-table tbody tr.focused { background-color: color-mix(in srgb, var(--pa) 16%, transparent) !important; box-shadow: inset 2px 0 0 var(--pa); }
.scan-table tbody tr.focused td:first-child { background-color: color-mix(in srgb, var(--pa) 16%, var(--bg-1)); }
/* Glossy, lightly embossed scanner rows — a top sheen + bottom shadow give each
   row a subtle raised 3D bar look. The gradient is a translucent OVERLAY (set via
   background-image) so it composites over whatever row colour is set above (zebra,
   hover, focused) without clobbering it. Static (no transitions) → dense tables
   stay fast; sticky first cell keeps its opaque background-color underneath. */
.scan-table tbody td {
  background-image: linear-gradient(180deg, rgba(255,255,255,0.06) 0%, rgba(255,255,255,0.015) 38%, rgba(0,0,0,0.11) 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.055), inset 0 -1px 0 rgba(0,0,0,0.20);
  /* Embossed-glossy numbers: a crisp dark drop-shadow lifts the text off the row. */
  text-shadow: 0 1px 1px rgba(0,0,0,0.5);
}
/* Only the numeric data cells render in the mono face (Cousine) so number
   columns lock to a fixed advance width; text columns (ticker, strategy,
   signals, flags) stay in the Archivo chrome font. Tagged per-column in
   renderPanel via MONO_COLS. */
.scan-table tbody td.mono { font-family: var(--mono); }

.pos { color: var(--green); }
.neg { color: var(--red); }
.dim { color: var(--txt-2); }

/* Glossy, fully-rounded (smoothed) flag pills — translucent sheen + bevel over the
   per-flag background-COLOR, pill radius for soft curves. */
.flag-pill {
  display: inline-block; font-size: 9px; padding: 1px 6px; margin-right: 2px;
  border-radius: 999px; letter-spacing: 0.04em;
  background-image: linear-gradient(180deg, rgba(255,255,255,0.15) 0%, rgba(255,255,255,0.03) 48%, rgba(0,0,0,0.15) 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.20), inset 0 -1px 0 rgba(0,0,0,0.26), 0 1px 2px rgba(0,0,0,0.30);
}
/* HIGH-confidence IGNITION fire (backtest 4× precision) — the ones that ping. */
.flag-pill.conf-high {
  background-color: #14331f; color: #38e06a; border: 1px solid #1f7a3d; font-weight: 800;
  box-shadow: 0 0 7px color-mix(in srgb, #38e06a 55%, transparent), inset 0 1px 0 rgba(255,255,255,0.18);
}
.flag-red    { background-color: var(--red-soft);   color: var(--red);   border:1px solid #4a262e; }
.flag-green  { background-color: var(--green-soft); color: var(--green); border:1px solid #2c4327; }
.flag-amber  { background-color: #2c2517; color: var(--amber);  border:1px solid #4a3d22; }

/* Float % (turnover) as an ACTION cue: color = "should I act?", arrow = velocity.
   GO (green) rotating up & still early · WATCH (amber) turnover but not accelerating
   · GONE (red) already rotated ~3x+, likely chasing · dim = nothing yet. */
.fp        { font-weight: 700; }
.fp-go     { color: #2ee6a0; }
.fp-watch  { color: #f5c542; }
.fp-gone   { color: #ff5c5c; }
.fp-dim    { color: #6b7688; font-weight: 500; }
.fp-arrow  { margin-left: 3px; font-size: 0.82em; letter-spacing: -1px; vertical-align: 1px; }
.fp-rise   { color: #38e06a; }
.fp-surge  { color: #5cff8f; text-shadow: 0 0 6px rgba(92,255,143,0.55); }

/* Reverse-split badge — crushed float = squeeze fuel AND a distressed/dilution
   risk flag. Amber-gold = "primed but handle with care". */
.rs-badge {
  display: inline-block; margin-left: 4px; padding: 0 4px; font-size: 9px;
  font-weight: 700; line-height: 14px; border-radius: 3px; vertical-align: middle;
  color: #1a1205; background: linear-gradient(180deg, #ffcf5c, #f5a623);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.35), 0 1px 2px rgba(0,0,0,0.35);
}
.flag-violet { background-color: #251c33; color: var(--violet); border:1px solid #3a2c54; }
/* PRE-IGNITION early-warning badge — amber, faintly glowing, weight + uppercase
   so a ⚡ PRE heads-up reads as "watch," distinct from a real pop's count pill. */
.flag-pre {
  background-color: #33270d; color: #ffc24d; border: 1px solid #6b521f;
  font-weight: 700; text-transform: uppercase;
  box-shadow: 0 0 4px rgba(255,194,77,0.35);
}
/* Catalyst flame — fresh POSITIVE-news marker before the ticker. Colour encodes
   freshness: red <15m, orange <60m, yellow <4h. Inline SVG fills with currentColor. */
.flame { display: inline-flex; vertical-align: -7px; margin-left: 5px; line-height: 0; cursor: pointer; }
.flame svg { width: 23px; height: 23px; }   /* CSS overrides the SVG's intrinsic size */
.flame-red    { color: #ff3b30; }
.flame-orange { color: #ff8c1a; }
.flame-yellow { color: #ffd23d; }
/* Overnight/after-hours catalyst still driving the session (>4h old but published
   after the last regular close) — cooler blue distinguishes it from fresh red/orange. */
.flame-overnight { color: #5b9bff; }
/* Colored glow per freshness tier — drop-shadow follows the flame shape and tints
   to match. Only the few rows with a fresh catalyst carry it → negligible paint. */
.flame-red svg    { filter: drop-shadow(0 0 5px #ff3b30); }
.flame-orange svg { filter: drop-shadow(0 0 5px #ff8c1a); }
.flame-yellow svg { filter: drop-shadow(0 0 4px #ffd23d); }
.flame-overnight svg { filter: drop-shadow(0 0 4px #5b9bff); }
/* Pulse ONLY the just-broke (red) flame. opacity-only = GPU-composited, no layout
   or paint on the data path → no measurable latency. */
@keyframes flamePulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }
.flame-red { animation: flamePulse 1.15s ease-in-out infinite; will-change: opacity; }
@media (prefers-reduced-motion: reduce) { .flame-red { animation: none; } }
/* Pretty catalyst tooltip — ONE body-level element (escapes panel contain:paint
   clipping), shown on hover only → zero cost on the render/data path. Accent bar
   is tinted to the flame's freshness colour by the hover handler. */
#flame-tip {
  position: fixed; z-index: 100000; pointer-events: none; max-width: 330px;
  padding: 8px 11px; border-radius: 7px;
  /* Background subtly tinted by the metric's accent colour so each tooltip feels
     like it belongs to its badge, not generic gray-on-black. */
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--tip-accent, #38e6ff) 10%, rgba(20,25,48,.98)), rgba(11,15,31,.98));
  border: 1px solid color-mix(in srgb, var(--tip-accent, #2a356a) 35%, #2a356a);
  border-left: 4px solid var(--tip-accent, var(--accent, #38e6ff));
  box-shadow: 0 8px 26px rgba(0,0,0,.55), 0 0 18px -5px var(--tip-accent, transparent);
  color: #eef2ff; font: italic 11px/1.45 'Archivo', system-ui, sans-serif;
  opacity: 0; transform: translateY(3px);
  transition: opacity .12s ease, transform .12s ease;
}
#flame-tip.show { opacity: 1; transform: translateY(0); }
#flame-tip .tip-head { display: block; font-weight: 400; }
/* Metric badges (Rank/Fuel/Pops/RS) get an accent-coloured heading (not bold). */
/* Lightened accent so the heading stays colour-coded but readable on the dark
   tooltip (raw magenta/indigo etc. was hard to read). Glow keeps the accent identity. */
#flame-tip.tip-metric .tip-head { color: color-mix(in srgb, var(--tip-accent, #eef2ff) 40%, #ffffff); font-weight: 400; text-shadow: 0 0 7px color-mix(in srgb, var(--tip-accent, transparent) 40%, transparent); }
#flame-tip .tip-age  { display: block; margin-top: 3px; color: #8fa0c8; font-size: 11px;
                       text-transform: uppercase; letter-spacing: .05em; }

/* ---------------- Stock Quote pane ---------------- */
/* Fill the (now dedicated) detail column and cap height to it, so a long detail
   SCROLLS inside the panel instead of overflowing the page (which forced a zoom-out). */
.quote-panel { flex: 1 1 0; min-height: 0; }
.quote-body { padding: 0 8px 8px; overflow-y: auto; flex: 1 1 0; min-height: 0; }
/* Frozen identity block — ticker / price / change / name stay pinned at the top
   while the scores, fundamentals and technicals below scroll under it. */
.q-frozen {
  position: sticky; top: 0; z-index: 3;
  background: var(--bg-1); padding-top: 6px;
}
.quote-hero {
  display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap;
  padding-bottom: 2px;
}
#q-ticker { font-size: 18px; font-weight: 700; letter-spacing: 0.1em; color: var(--accent); }
.q-price  { font-size: 22px; font-weight: 700; }
.q-change { font-size: 12px; font-weight: 600; }
/* Company name — its OWN typographic tier so it never reads as just another stat:
   UI sans, heavier (600), letter-spaced, brighter cyan-tinted white, larger than the
   11px gray rows. The divider under it groups ticker/price/name as the identity block,
   separated from the stat table below. Static styling → zero render cost. */
#q-name {
  font-family: var(--ui);
  font-size: 12.5px; font-weight: 600; letter-spacing: 0.02em; line-height: 1.3;
  color: color-mix(in srgb, var(--accent) 26%, #eef4ff);
  margin: 1px 0 7px; padding-bottom: 6px;
  border-bottom: 1px solid var(--border);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#q-name:empty { display: none; }

/* Exchange badge (Stock Quote pane + popout) */
.exch-badge {
  align-self: center; font-size: 9px; font-weight: 700; letter-spacing: 0.06em;
  padding: 2px 6px; border-radius: 3px; text-transform: uppercase;
  border: 1px solid transparent; white-space: nowrap;
}
.exch-badge[hidden] { display: none; }
.exch-nasdaq { background: rgba(0,160,255,0.15);  color: #4ab8ff; border-color: rgba(0,160,255,0.45); }
.exch-nyse   { background: rgba(120,200,120,0.15); color: #7fd47f; border-color: rgba(120,200,120,0.45); }
.exch-otc    { background: rgba(230,170,60,0.15);  color: #e6aa3c; border-color: rgba(230,170,60,0.45); }
.exch-other  { background: var(--bg-3); color: var(--txt-1); border-color: var(--border); }
.quote-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.quote-table td { padding: 4px 8px; border-bottom: 1px dotted var(--bg-3); }
.quote-table td:nth-child(odd) { color: #8ea2c4; }
.quote-table td:nth-child(even) { color: var(--txt-0); text-align: right; }
/* Vantage numeric fields render in the mono face (Cousine) so figures align,
   matching the scanner grid. Label cells (odd / .ql) stay in Archivo chrome. */
.q-price, .q-change, .q-tech-score,
.quote-table td:nth-child(even),
.q-tech-tbl td:not(.ql) { font-family: var(--mono); }

/* Ticker autocomplete dropdown — attached to #quick-search + #quote-search. */
.ticker-ac {
  position: fixed; z-index: 100001; margin: 0; padding: 4px; list-style: none;
  pointer-events: auto;
  background: var(--bg-2); border: 1px solid var(--border-strong); border-radius: 6px;
  box-shadow: 0 10px 28px rgba(0,0,0,0.55); max-height: 340px; overflow-y: auto; min-width: 200px;
}
.ticker-ac .ac-item { pointer-events: auto; }
.ticker-ac.hidden { display: none; }
.ticker-ac .ac-item {
  display: flex; align-items: baseline; gap: 8px; padding: 5px 9px; border-radius: 4px;
  cursor: pointer; font-size: 12.5px; white-space: nowrap;
}
.ticker-ac .ac-item.sel, .ticker-ac .ac-item:hover { background: var(--bg-3); }
.ticker-ac .ac-sym  { font-family: var(--mono); font-weight: 700; color: var(--txt-0); letter-spacing: 0.02em; }
.ticker-ac .ac-name { color: var(--txt-2); font-size: 11px; overflow: hidden; text-overflow: ellipsis; }

/* ---------------- Technical-analysis detail (StockDashboard parity) ------- */
.q-tech { margin-top: 8px; }
.q-tech-empty { color: var(--txt-2); font-size: 11px; padding: 8px; font-style: italic; }
.q-tech-hd { display: flex; align-items: center; gap: 10px; padding: 6px 8px; margin-bottom: 4px;
  border: 1px solid; border-radius: 6px; background: rgba(255,255,255,0.02); }
/* Which score this is — OVERALL / FUNDAMENTAL / TECHNICAL. */
.q-tech-name { font-size: 9.5px; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--txt-2); writing-mode: horizontal-tb; }
.q-tech-score { font-size: 26px; font-weight: 800; line-height: 1; }
.q-tech-of { font-size: 11px; color: var(--txt-2); margin-left: 2px; }
.q-tech-sig { margin-left: auto; padding: 3px 9px; border-radius: 4px; font-size: 11px; font-weight: 800;
  color: #05121a; letter-spacing: 0.03em; }
.q-tech-conf { font-size: 10px; color: var(--txt-2); }
.t-tags { display: flex; flex-wrap: wrap; gap: 4px; margin: 2px 0 6px; }
.t-tag { font-size: 9.5px; font-weight: 700; padding: 1px 6px; border-radius: 3px;
  background: var(--bg-3); color: var(--txt-1); letter-spacing: 0.02em; }
.q-tech-tbl { width: 100%; border-collapse: collapse; font-size: 12px; }
.q-tech-tbl td { padding: 4px 8px; border-bottom: 1px dotted var(--bg-3); }
.q-tech-tbl td.ql { color: #8ea2c4; white-space: nowrap; }
.q-tech-tbl td:not(.ql) { color: var(--txt-0); text-align: right; }
.q-tech-tbl td i { font-style: normal; font-size: 10px; margin-left: 4px; }
.q-tech-tbl tr.q-sec td { background: rgba(255,255,255,0.03); color: var(--accent);
  font-weight: 700; font-size: 10px; letter-spacing: 0.05em; text-transform: uppercase;
  text-align: left; padding: 5px 8px; border-bottom: 1px solid var(--bg-3); }
.fd-banner { display: flex; align-items: baseline; gap: 8px; padding: 5px 9px; margin: 4px 0 6px; border-radius: 4px; }
.fd-label { font-size: 13px; font-weight: 800; letter-spacing: 0.04em; }
.fd-reason { font-size: 10px; color: var(--txt-2); }
.wk52 { display: flex; align-items: center; gap: 8px; font-size: 10px; color: var(--txt-2); padding: 4px 0; }
.wk52-track { position: relative; flex: 1; height: 6px; border-radius: 3px;
  background: linear-gradient(90deg, #f43f5e, #fbbf24, #00ff94); }
.wk52-needle { position: absolute; top: -2px; width: 3px; height: 10px; background: #fff;
  border-radius: 2px; transform: translateX(-50%); box-shadow: 0 0 3px #000; }

/* ---------------- Charts ---------------- */
.chart-panel { min-height: 0; }
.chart-canvas { flex: 1; min-height: 0; }

.indicator-config {
  background: var(--bg-1); border: 1px solid var(--border); border-radius: 3px;
  padding: 4px 8px; max-height: 110px; overflow: auto;
}
.cfg-label { color: var(--txt-1); letter-spacing: 0.1em; font-size: 10px; margin-right: 6px; }
.ind-tab {
  background: var(--bg-3); border: 1px solid var(--border); color: var(--txt-1);
  padding: 2px 8px; margin-right: 4px; cursor: pointer; font-family: var(--ui); font-size: 10px;
}
.ind-tab.active { color: var(--accent); border-color: var(--accent); }
.ind-list {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 2px 10px; margin-top: 6px;
}
.ind-list label { display: flex; align-items: center; gap: 4px; font-size: 10.5px; }
.ind-list input { accent-color: var(--accent); }

/* ---------------- News + alerts ---------------- */
.feed-panel { max-height: 200px; }
.news-list, .alert-list {
  list-style: none; margin: 0; padding: 0; overflow-y: auto; flex: 1;
}
.news-list li, .alert-list li {
  padding: 5px 8px; border-bottom: 1px solid var(--bg-2);
  font-size: 10.5px; animation: fade-in 0.2s ease-out;
}
.news-list li.flash-green { background: rgba(33, 208, 122, 0.10); }
.news-list li.flash-red   { background: rgba(255, 78, 91, 0.10); }
.news-meta { color: var(--txt-2); font-size: 9.5px; margin-right: 4px; }
.news-sym  { color: var(--accent); font-weight: 700; margin-right: 4px; }
.news-score { float: right; font-weight: 700; }
.alert-list li { border-left: 3px solid var(--accent); }
.alert-list li.alert-red    { border-left-color: var(--red); }
.alert-list li.alert-green  { border-left-color: var(--green); }
.alert-list li.alert-amber  { border-left-color: var(--amber); }

@keyframes fade-in {
  from { opacity: 0; transform: translateY(-2px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ---------------- Modals ---------------- */
.modal {
  position: fixed; inset: 0; background: rgba(0,0,0,0.78);
  display: flex; align-items: center; justify-content: center; z-index: 100;
}
.modal.hidden { display: none; }
.modal-card {
  background: var(--bg-1); border: 1px solid var(--border-strong);
  border-radius: 4px; width: 760px; max-height: 80vh;
  overflow: auto; padding: 16px 20px;
}
.modal-card header {
  display: flex; justify-content: space-between; align-items: center; margin-bottom: 14px;
}
.modal-card h2 { margin: 0; font-size: 13px; letter-spacing: 0.15em; }
.modal-card .x { background: none; border: none; color: var(--txt-1); font-size: 20px; cursor: pointer; }
.modal-card .x:hover { color: var(--red); }
.hotkey-table { width: 100%; border-collapse: collapse; font-size: 11px; }
.hotkey-table th, .hotkey-table td { padding: 4px 6px; border-bottom: 1px solid var(--border); }
.hotkey-table th { color: var(--txt-1); text-align: left; }
.hotkey-table input, .hotkey-table select {
  background: var(--bg-2); color: var(--txt-0); border: 1px solid var(--border);
  padding: 2px 4px; font-family: var(--ui); font-size: 11px; width: 100%;
}
.hint { color: var(--txt-2); font-size: 10px; margin: 10px 0 0; }
.modal-foot { margin-top: 12px; display: flex; gap: 8px; justify-content: flex-end; }
.modal-foot button {
  background: var(--bg-3); color: var(--txt-0); border: 1px solid var(--border);
  padding: 6px 12px; font-family: var(--ui); cursor: pointer;
}
.modal-foot button:hover { border-color: var(--accent); color: var(--accent); }

.layout-toggles {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 6px;
}
.layout-toggles label { display: flex; align-items: center; gap: 6px; padding: 4px; font-size: 11px; }

/* ---------------- Popout buttons in panel headers ---------------- */
.panel-h { grid-template-columns: 1fr auto auto auto auto; }
.popout {
  background: none; border: none; color: var(--txt-1);
  font-size: 12px; line-height: 1; padding: 0 5px; cursor: pointer;
}
.popout:hover { color: var(--accent); }
.chart-action {
  background: var(--bg-3); border: 1px solid var(--border); color: var(--txt-0);
  padding: 3px 8px; font-family: var(--ui); font-size: 10px; cursor: pointer;
  border-radius: 2px;
}
.chart-action:hover { border-color: var(--accent); color: var(--accent); }

/* ---------------- Chart top bar (TradingView-ish) ---------------- */
.chart-topbar {
  display: flex; align-items: center; gap: 8px;
  padding: 3px 8px; min-height: 30px;   /* grows to fit the two-row timeframe bar */
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--pa, var(--accent)) 20%, transparent), transparent 85%),
    linear-gradient(180deg, var(--bg-2), var(--bg-1));
  border-top: 2px solid var(--pa, var(--accent));
  border-bottom: 1px solid var(--border);
}
.chart-sym { color: var(--txt-1); font-size: 11px; margin-right: auto; }
.chart-tf { display: flex; gap: 2px; }
.tf-btn {
  background: var(--bg-3); border: 1px solid var(--border); color: var(--txt-1);
  padding: 2px 6px; font-family: var(--ui); font-size: 10px; cursor: pointer;
}
.tf-btn.active { color: var(--accent); border-color: var(--accent); }
.tf-btn:hover  { color: var(--accent); }
/* Chart-type picker (Candle / Hollow / Bar / Line) — matches the tf buttons. */
.pane-ctype {
  background: var(--bg-3); border: 1px solid var(--border); color: var(--txt-1);
  padding: 2px 4px; font-family: var(--ui); font-size: 10px; cursor: pointer;
  border-radius: 3px; margin-left: 4px;
}
.pane-ctype:hover, .pane-ctype:focus { color: var(--accent); border-color: var(--accent); outline: none; }

.wall-clock { font-family: var(--ui); color: var(--accent); font-weight: 700; }

/* ---------------- Dynamic chart grid ---------------- */
#chart-grid {
  flex: 2 1 0;
  min-height: 0;
  display: grid;
  grid-auto-rows: minmax(0, 1fr);
  gap: 6px;
}
#chart-grid .chart-pane { flex: none; min-height: 0; }
.pane-ticker {
  width: 64px;
  background: var(--bg-3); border: 1px solid var(--border); color: var(--txt-0);
  border-radius: 3px; padding: 2px 6px;
  font-family: var(--ui); font-size: 11px; text-transform: uppercase;
}
.pane-ticker::placeholder { color: var(--txt-2); }
.pane-ticker:focus { border-color: var(--accent); color: var(--accent); outline: none; }
.pane-legend { margin-right: auto; }
.pane-tf {
  background: var(--bg-3); border: 1px solid var(--border); color: var(--txt-0);
  border-radius: 3px; font-family: var(--ui); font-size: 11px; padding: 2px 4px;
  cursor: pointer;
}
.pane-tf:hover, .pane-tf:focus { border-color: var(--accent); color: var(--accent); outline: none; }

/* Single-line indicator legend overlaid on the candle pane — replaces
   KLineChart's vertically-stacked native indicator legends with ONE horizontal
   row (crosshair-tracked). pointer-events:none so it never blocks chart drag. */
.kline-legend {
  display: none;   /* shown only while the crosshair is on the chart (JS toggles) */
  position: absolute; top: 22px; left: 8px; z-index: 5;
  pointer-events: none;
  max-width: calc(100% - 14px);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  /* Match the chart's CHART_FONT (Archivo) so every legend shares one font. */
  font-family: 'Archivo', -apple-system, 'Segoe UI', system-ui, sans-serif;
  font-size: 11px; font-weight: 600; line-height: 1.4; letter-spacing: 0.2px;
  color: var(--txt-0);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.85);
}
.kline-legend-sep { color: #4a5488; margin: 0 7px; font-weight: 400; }

/* Hide the OS crosshair ("+") cursor over the chart — the glowing reticle is the
   pointer. !important beats KLineChart's inline cursor:crosshair/default/pointer.
   Scoped to CANVAS only so KLineChart's pane-separator widgets keep their native
   ns-resize cursor — the user can tell a drag-border from inside the chart. */
.tachyon-no-cursor canvas { cursor: none !important; }

/* Live price + % in each chart pane's top bar (beside the timeframe buttons). */
.chart-pane { position: relative; }
/* Y-axis "+" — appears at the cursor height over the price axis; click to drop a
   horizontal S/R line at that price. */
.hline-add {
  position: absolute; right: 4px; transform: translateY(-50%);
  width: 17px; height: 17px; padding: 0; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--accent) 22%, #0b0f1e);
  color: var(--accent); border: 1px solid var(--accent);
  font: 600 13px/1 'Archivo', system-ui, sans-serif; cursor: pointer; z-index: 14;
  box-shadow: 0 0 9px -2px var(--accent);
}
.hline-add[hidden] { display: none; }
.hline-add:hover { background: var(--accent); color: #06121a; }
.pane-quote { font-family: var(--ui); font-size: 11px; font-weight: 600; margin-left: 6px; white-space: nowrap; }
.pane-quote .pq-price { color: var(--txt-0); }
.pane-quote .pq-pct.pos { color: #21d07a; }
.pane-quote .pq-pct.neg { color: #ff4e5b; }

/* HALTED banner overlaid on the chart when the focused ticker is halted. */
.pane-halt {
  position: absolute; top: 36px; left: 50%; transform: translateX(-50%);
  z-index: 20; pointer-events: none;
  background: rgba(220, 30, 50, 0.92); color: #fff;
  font-family: var(--ui); font-size: 11px; font-weight: 700; letter-spacing: 0.04em;
  padding: 3px 11px; border-radius: 4px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.45);
}
/* Halt badge in the VANTAGE VIEW hero. */
.q-halt {
  background: rgba(220, 30, 50, 0.92); color: #fff;
  font-size: 10px; font-weight: 700; letter-spacing: 0.03em;
  padding: 2px 7px; border-radius: 4px; margin-left: 6px; white-space: nowrap;
}

/* ---------- Glossy "Plasma" crosshair overlay (cyan beams + rings reticle) ---------- */
.tachyon-xhair { position: absolute; pointer-events: none; display: none; z-index: 6; }
.tachyon-xhair-v {
  top: 0; bottom: 0; width: 1px; margin-left: -0.5px;
  background: linear-gradient(180deg, rgba(56,230,255,0), rgba(56,230,255,.85) 35%, #fff 50%, rgba(56,230,255,.85) 65%, rgba(56,230,255,0));
  box-shadow: 0 0 2px #38e6ff, 0 0 4px rgba(56,230,255,.16);
}
.tachyon-xhair-h {
  left: 0; right: 0; height: 1px; margin-top: -0.5px;
  background: linear-gradient(90deg, rgba(56,230,255,0), rgba(56,230,255,.85) 35%, #fff 50%, rgba(56,230,255,.85) 65%, rgba(56,230,255,0));
  box-shadow: 0 0 2px #38e6ff, 0 0 4px rgba(56,230,255,.16);
}
.tachyon-xhair-ret {
  z-index: 7; width: 18px; height: 18px; margin: -9px 0 0 -9px;
  filter: drop-shadow(0 0 3px #38e6ff) drop-shadow(0 0 6px rgba(56,230,255,.5));
}
/* counter-rotating rings */
@keyframes tachyon-xh-cw  { to { transform: rotate(360deg); } }
@keyframes tachyon-xh-ccw { to { transform: rotate(-360deg); } }
.tachyon-xhair-ret .cw,
.tachyon-xhair-ret .ccw { transform-box: fill-box; transform-origin: center; }
.tachyon-xhair-ret .cw  { animation: tachyon-xh-cw  4s linear infinite; }
.tachyon-xhair-ret .ccw { animation: tachyon-xh-ccw 3s linear infinite; }

/* ---------------- TradingView-style indicator modal ---------------- */
.modal-card.tv-modal {
  /* Fixed size — the list scrolls inside, so the window never resizes when you
     switch categories/tabs (few vs many items). */
  width: 920px; max-width: 95vw;
  height: 720px; max-height: 88vh;
  padding: 0; display: flex; flex-direction: column;
}
.tv-modal > header { padding: 14px 20px; margin: 0; border-bottom: 1px solid var(--border); }
.tv-modal > header h2 { font-size: 13px; }
.tv-search {
  margin: 12px 20px; padding: 8px 12px;
  background: var(--bg-2); border: 1px solid var(--border-strong); color: var(--txt-0);
  font-family: var(--ui); font-size: 12px; border-radius: 3px;
}
.tv-search:focus { outline: none; border-color: var(--accent); }
.tv-body {
  display: grid; grid-template-columns: 180px 1fr 280px;
  gap: 14px; padding: 0 20px; flex: 1; min-height: 0;
}

/* Detail / definition panel (right column of the indicators modal). */
.tv-detail { border-left: 1px solid var(--border); padding-left: 14px; overflow-y: auto; }
.tv-detail-empty { color: var(--txt-2); font-size: 11.5px; padding-top: 8px; }
.tv-detail-head { font-size: 14px; font-weight: 700; color: var(--accent); margin-top: 2px; }
.tv-detail-meta { font-size: 10px; color: var(--txt-2); letter-spacing: 0.08em;
  text-transform: uppercase; margin: 4px 0 10px; }
.tv-detail-desc { font-size: 12px; line-height: 1.55; color: var(--txt-0); margin: 0 0 14px; }
.tv-detail-toggle {
  display: block; width: 100%; padding: 7px 10px; margin-bottom: 10px; cursor: pointer;
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: var(--accent); border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  border-radius: 4px; font-family: var(--ui); font-size: 11.5px; font-weight: 600;
}
.tv-detail-toggle:hover { background: color-mix(in srgb, var(--accent) 26%, transparent); }
.tv-detail-ref { display: inline-block; font-size: 11.5px; color: var(--accent); text-decoration: none; }
.tv-detail-ref:hover { text-decoration: underline; }
.tv-star-none { color: var(--txt-2); cursor: default; }

/* Indicator row: favorite star (independent of chart) + inline Add button. */
.tv-star { cursor: pointer; }
.tv-star.fav-on { color: var(--amber); }
.tv-ind-item.active .tv-star { color: inherit; }   /* star = favorite, not "added" */
.tv-add {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent); border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
  border-radius: 4px; font-family: var(--ui); font-size: 10px; font-weight: 600;
  padding: 2px 8px; cursor: pointer; white-space: nowrap;
}
.tv-add:hover { background: color-mix(in srgb, var(--accent) 26%, transparent); }
.tv-add.added {
  background: color-mix(in srgb, var(--green) 16%, transparent); color: var(--green);
  border-color: color-mix(in srgb, var(--green) 45%, transparent);
}
.tv-add-na { font-size: 9px; color: var(--txt-2); letter-spacing: 0.06em; }
.tv-detail-note { font-size: 11px; color: var(--txt-2); font-style: italic; margin-bottom: 10px; }
.tv-detail-fav {
  display: block; width: 100%; padding: 6px 10px; margin-bottom: 10px; cursor: pointer;
  background: transparent; color: var(--amber);
  border: 1px solid color-mix(in srgb, var(--amber) 40%, transparent); border-radius: 4px;
  font-family: var(--ui); font-size: 11px;
}
.tv-detail-fav:hover { background: color-mix(in srgb, var(--amber) 14%, transparent); }

/* Popout chart indicator menu. */
.po-ind-wrap { position: relative; }
.po-ind-menu {
  position: absolute; right: 0; top: 26px; z-index: 20;
  width: 220px; max-height: 320px; overflow-y: auto;
  background: var(--bg-1); border: 1px solid var(--border-strong); border-radius: 6px;
  padding: 6px; box-shadow: 0 10px 30px -8px rgba(0,0,0,0.8);
}
.po-ind-menu.hidden { display: none; }
.po-ind-menu label {
  display: flex; align-items: center; gap: 7px; padding: 4px 6px; font-size: 11px;
  border-radius: 4px; cursor: pointer; color: var(--txt-0);
}
.po-ind-menu label:hover { background: var(--bg-2); }
.po-ind-menu input { accent-color: var(--accent); }
.tv-side { border-right: 1px solid var(--border); padding-right: 12px; overflow-y: auto; }
.tv-side-head {
  color: var(--txt-2); font-size: 9px; letter-spacing: 0.18em;
  margin: 12px 0 6px; padding-left: 6px;
}
.tv-side-head:first-child { margin-top: 0; }
.tv-side-btn {
  display: block; width: 100%; text-align: left;
  background: none; border: none; color: var(--txt-0);
  padding: 6px 8px; font-family: var(--ui); font-size: 11.5px; cursor: pointer;
  border-radius: 3px;
}
.tv-side-btn:hover  { background: var(--bg-2); }
.tv-side-btn.active { background: var(--bg-3); color: var(--accent); }
/* One-click day-trade preset bundles — accented action buttons in the sidebar. */
.tv-preset-btn {
  display: block; width: 100%; text-align: left; margin: 3px 0;
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 32%, transparent);
  color: var(--txt-0); padding: 6px 8px; border-radius: 4px;
  font-family: var(--ui); font-size: 11.5px; font-weight: 600; cursor: pointer;
}
.tv-preset-btn:hover { background: color-mix(in srgb, var(--accent) 22%, transparent); border-color: var(--accent); }
/* Active workspace category — edits to panels save as THIS layout's default. */
.tv-preset-btn.active {
  background: color-mix(in srgb, var(--accent) 30%, transparent);
  border-color: var(--accent); font-weight: 800;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 45%, transparent);
}
/* Reset layouts to built-in defaults — muted red, like the clear button. */
.tv-preset-btn.ws-reset { background: color-mix(in srgb, var(--red) 8%, transparent); border-color: color-mix(in srgb, var(--red) 28%, transparent); color: var(--txt-1); font-weight: 600; }
.tv-preset-btn.ws-reset:hover { background: color-mix(in srgb, var(--red) 16%, transparent); border-color: var(--red); }
.tv-preset-clear { background: color-mix(in srgb, var(--red) 8%, transparent); border-color: color-mix(in srgb, var(--red) 28%, transparent); color: var(--txt-1); font-weight: 500; }
.tv-preset-clear:hover { background: color-mix(in srgb, var(--red) 16%, transparent); border-color: var(--red); }

/* ---------- Command palette (Ctrl-K) ---------- */
.cmd-overlay { position: fixed; inset: 0; z-index: 200; background: rgba(2,4,16,0.55);
  display: flex; align-items: flex-start; justify-content: center; padding-top: 12vh; }
.cmd-overlay.hidden { display: none; }
.cmd-box { width: min(560px, 92vw);
  background: linear-gradient(180deg, #0f1530, var(--bg-1));
  border: 1px solid var(--border-strong); border-radius: 10px; overflow: hidden;
  box-shadow: 0 24px 70px -20px rgba(0,0,0,0.85), 0 0 0 1px color-mix(in srgb, var(--accent) 18%, transparent); }
.cmd-input { width: 100%; border: none; outline: none; background: transparent; color: var(--txt-0);
  font-family: var(--ui); font-size: 16px; padding: 14px 16px; border-bottom: 1px solid var(--border); }
.cmd-input::placeholder { color: var(--txt-2); }
.cmd-list { list-style: none; margin: 0; padding: 6px; max-height: 52vh; overflow-y: auto; }
.cmd-item { display: flex; align-items: center; justify-content: space-between;
  padding: 9px 12px; border-radius: 6px; cursor: pointer; }
.cmd-item.sel { background: color-mix(in srgb, var(--accent) 16%, transparent); }
.cmd-label { color: var(--txt-0); font-family: var(--ui); font-size: 13px; }
.cmd-hint  { color: var(--txt-2); font-size: 11px; margin-left: 12px; white-space: nowrap; }
.cmd-empty { padding: 14px; color: var(--txt-2); text-align: center; }

/* Workspace preset buttons in the Layout modal — a wrapping row, auto width. */
.layout-presets { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.layout-presets .tv-preset-btn { width: auto; margin: 0; }

.tv-list-wrap { display: flex; flex-direction: column; min-height: 0; overflow: hidden; }
.tv-tabs { display: flex; gap: 4px; margin-bottom: 8px; border-bottom: 1px solid var(--border); }
.tv-tab {
  background: none; border: none; color: var(--txt-1);
  padding: 6px 14px; font-family: var(--ui); font-size: 11px; cursor: pointer;
  border-bottom: 2px solid transparent;
}
.tv-tab.active { color: var(--accent); border-bottom-color: var(--accent); }

.tv-list {
  list-style: none; margin: 0; padding: 0; overflow-y: auto; flex: 1;
}
.tv-ind-item {
  display: grid; grid-template-columns: 24px 1fr auto;
  align-items: center; padding: 6px 10px; cursor: pointer;
  font-size: 11.5px; border-bottom: 1px solid var(--bg-2);
}
.tv-ind-item:hover  { background: var(--bg-2); }
.tv-ind-item.active { background: rgba(54, 226, 255, 0.08); color: var(--accent); }
.tv-star  { color: var(--txt-2); font-size: 13px; }
/* (star colour is driven solely by .fav-on now — see favorites block below) */
.tv-pane-tag {
  font-size: 9px; color: var(--txt-2); background: var(--bg-3);
  padding: 1px 5px; border-radius: 2px; letter-spacing: 0.08em;
}
.tv-empty { padding: 14px; color: var(--txt-2); text-align: center; font-size: 11px; }
.tv-foot {
  padding: 10px 20px; border-top: 1px solid var(--border);
  display: flex; justify-content: space-between; align-items: center;
}
.tv-foot button {
  background: var(--bg-3); color: var(--txt-0); border: 1px solid var(--border);
  padding: 6px 16px; font-family: var(--ui); cursor: pointer;
}
.tv-foot button:hover { border-color: var(--accent); color: var(--accent); }
#ind-active-count { color: var(--txt-1); font-size: 11px; }

/* ---------------- Popout window layout ---------------- */
.popout-body { height: 100vh; overflow: hidden; }
.popout-topbar {
  /* Override .topbar grid layout — popout has 7 inline children, not 3 columns. */
  display: flex;
  align-items: center;
  gap: 12px;
  height: 60px;
  padding: 0 16px;
  overflow: hidden;       /* never leak header text into the table area below */
}
.popout-topbar .brand-name { font-size: 22px;
  /* Glossy 3D lift: a crisp dark drop-shadow for depth + a soft cyan glow. */
  filter: drop-shadow(0 1px 1px rgba(0,0,0,0.55)) drop-shadow(0 0 7px rgba(120,180,255,0.42)); }
.popout-topbar .popout-logo { height: 44px; }   /* doubled to match the 60px header */
.popout-main { height: calc(100vh - 60px); padding: 4px; overflow: hidden; background: var(--bg-0); position: relative; z-index: 1; }
.popout-main .scan-wrap { height: 100%; overflow: auto; background: var(--bg-1); border: 1px solid var(--border); }
.popout-main .news-list, .popout-main .alert-list {
  list-style: none; margin: 0; padding: 0; height: 100%; overflow-y: auto;
  background: var(--bg-1); border: 1px solid var(--border);
}
.popout-quote {
  background: var(--bg-1); border: 1px solid var(--border); padding: 0 10px 10px;
  height: 100%; overflow: auto;
}
/* Freeze the ticker/price hero (+ search) while the detail below scrolls. */
.popout-quote .quote-hero {
  gap: 10px;
  position: sticky; top: 0; z-index: 3;
  background: var(--bg-1); padding-top: 10px;
}
.popout-quote #po-search {
  background: var(--bg-2); border: 1px solid var(--border); color: var(--txt-0);
  padding: 4px 8px; font-family: var(--ui); font-size: 11px; margin-right: 10px;
}

/* =====================================================================
   Interaction polish — transitions ONLY on chrome the user clicks.
   Deliberately excludes .scan-table rows/cells and price elements, which
   repaint up to 1×/sec; keeping them transition-free preserves the
   "zero performance impact" guarantee.
   ===================================================================== */
.actions button, .actions input, .chart-action, .tf-btn, .ind-tab,
.tv-side-btn, .tv-tab, .pane-tf, .pane-ticker, .popout, .panel-h .x,
.modal-foot button, .tv-foot button, .quote-table, .badge, .exch-badge {
  transition: border-color .13s ease, color .13s ease,
              background-color .13s ease, box-shadow .13s ease;
}
.actions button:hover, .chart-action:hover, .tf-btn:hover {
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 60%, transparent);
}

/* Stock Quote hero — give the headline number presence (static glow). */
#q-ticker, #po-ticker { text-shadow: 0 0 12px color-mix(in srgb, var(--accent) 45%, transparent); }
.q-price { letter-spacing: 0.02em; }

/* Quote detail rows: StockDashboard label tone on the field-name side. */
.quote-table td:nth-child(odd)  { color: #8ea2c4; }
.quote-table td:nth-child(even) { color: var(--txt-0); }

/* Brand badges get a touch more lift. */
.badge-session { background-color: color-mix(in srgb, var(--violet) 14%, transparent);
  color: var(--violet); border: 1px solid color-mix(in srgb, var(--violet) 40%, transparent); }

/* Icon-only topbar buttons (Layout, Hotkeys) — compact, centered glyph. */
.icon-btn { padding: 4px 8px; font-size: 15px; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center; }

/* =====================================================================
   Typography — Inter for chrome/headings (refined sans), JetBrains Mono
   stays on all numeric/data surfaces so columns keep aligning. Pure font
   swaps; vendored + display:swap → no network wait, no live-update cost.
   ===================================================================== */
.brand-name, .panel-title, .modal-card h2, .tv-modal header h2,
.tv-side-head, .tv-side-btn, .tv-tab, .ind-tab,
.news-list li, .alert-list li, .hint, #conn-text,
.actions button, .modal-foot button, .tv-foot button, .layout-toggles label {
  font-family: var(--ui);
}
.brand-name { letter-spacing: 0.18em; font-weight: 700; }
.panel-title { letter-spacing: 0.06em; font-weight: 600; }
.news-list li, .alert-list li { letter-spacing: 0.01em; }
/* News symbol + scores stay mono (tickers/numbers read better aligned). */
.news-sym, .news-score, .news-meta { font-family: var(--ui); }

/* =====================================================================
   Timeframe bar — TradingView-style row of buttons (replaces the dropdown).
   Compact so all tfs sit side-by-side; scrolls horizontally only if a pane
   is unusually narrow, never breaking the topbar layout.
   ===================================================================== */
/* Two stacked rows: intraday on top, daily/weekly/monthly/yearly below. */
.chart-tf {
  display: flex; flex-direction: column; gap: 2px; flex: 0 1 auto; min-width: 0;
}
.tf-row { display: flex; gap: 2px; flex-wrap: wrap; }
.tf-btn {
  flex: 0 0 auto;
  background: linear-gradient(180deg, rgba(255,255,255,0.05), rgba(255,255,255,0.015));
  border: 1px solid var(--border); color: var(--txt-1);
  padding: 2px 6px; font-family: var(--ui); font-size: 9.5px; font-weight: 600; line-height: 15px;
  letter-spacing: 0.01em; cursor: pointer; border-radius: 999px;   /* pill */
  transition: color .12s ease, border-color .12s ease, background-color .12s ease, box-shadow .12s ease;
}
.tf-btn:hover {
  color: var(--accent); border-color: color-mix(in srgb, var(--accent) 55%, transparent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 28%, transparent);
}
.tf-btn.active {
  color: #04060f; font-weight: 700; border-color: transparent;
  background: var(--grad);                                   /* cyan→violet flux gradient */
  box-shadow: 0 0 10px -2px color-mix(in srgb, var(--accent) 70%, transparent);
}
/* Main-deck chart header: TWO stacked rows — a row of identity (ticker · company
   name · price · %) + control buttons, over a full-width row of ALL timeframes, so
   every timeframe is visible even in the narrow 4-column layout. Popout chart bar
   (.po-chart-bar) is excluded — its wide window lays out fine as a single row. */
.chart-topbar:not(.po-chart-bar) { flex-direction: column; align-items: stretch; gap: 3px; }
.ct-id { display: flex; align-items: center; gap: 8px; width: 100%; min-width: 0; }
/* Control buttons pushed to the far right; ✕ is last in the markup, ↗ just before it. */
.ct-actions { margin-left: auto; display: flex; align-items: center; gap: 4px; flex: 0 0 auto; }
/* Timeframes get their own full-width wrapping row — all of them always reachable. */
.chart-topbar:not(.po-chart-bar) .chart-tf { width: 100%; display: flex; flex-flow: row wrap; gap: 2px; flex: 0 0 auto; }
.chart-topbar:not(.po-chart-bar) .tf-row   { display: contents; }
/* Ticker + company name shrinks/ellipsizes so the actions always fit on the row. */
.chart-sym { color: var(--txt-1); font-size: 10.5px; margin: 0 6px;
  flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Empty-state "Add chart" tile shown when the last chart is closed. */
.chart-empty {
  width: 100%; height: 100%; min-height: 80px;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(180deg, #0f1530, var(--bg-1) 60%);
  border: 1px dashed var(--border-strong); border-radius: 6px;
  color: var(--txt-1); font-family: var(--ui); font-size: 13px; letter-spacing: 0.06em;
  cursor: pointer; transition: border-color .13s ease, color .13s ease;
}
.chart-empty:hover { color: var(--accent); border-color: var(--accent); }

/* Popout chart: same controls as a main-deck chart pane. */
.po-chart-wrap { --pa: #38e6ff; display: flex; flex-direction: column; height: 100%;
  background: var(--bg-1); border: 1px solid var(--border); border-radius: 6px; overflow: hidden; }
/* Chart-popout top bar: 60px to match the other popout headers; Tachyon icon +
   ticker/flame/name/price/% + current TF on the LEFT, all timeframe buttons +
   chart-type on the RIGHT. */
.po-chart-bar  { flex: 0 0 auto; height: 60px; padding: 0 16px; gap: 12px; justify-content: space-between; flex-wrap: nowrap; }
.po-bar-left   { display: flex; align-items: center; gap: 8px; min-width: 0; }
.po-bar-right  { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
.po-chart-bar .popout-logo { height: 44px; }
.po-chart-name  { color: var(--txt-1); font-size: 12px; max-width: 200px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.po-chart-curtf { color: var(--accent); font-size: 12px; font-weight: 700; letter-spacing: 0.05em; }
.po-chart-flame { display: inline-flex; align-items: center; }
.po-chart-area { flex: 1 1 auto; min-height: 0; }

/* =====================================================================
   ░░  TACHYON FLUX — v2 REDESIGN LAYER  (2026-06-24)  ░░
   Elevated "wow" theme + brand integration. ZERO added latency by
   construction:
     • NO backdrop-filter anywhere (the one expensive GPU op on scroll).
     • NO transitions/animation on .scan-table rows/cells or price els
       (they repaint up to 1×/sec — kept transition-free, per the
       guarantee at the "Interaction polish" block above).
     • Panels keep `contain: layout paint` (defined earlier) so a row
       tick repaints ONLY its panel.
     • All gradients/shadows are STATIC — painted once, not per frame.
     • The ONLY motion is a slow gradient drift on the brand wordmark:
       a single tiny topbar element, isolated from the data path, and
       disabled under prefers-reduced-motion.
   ===================================================================== */

/* ---- Top bar: taller, glassy, flux-gradient edge ---- */
.topbar {
  height: 84px;
  /* EXACT logo field colour, flat + opaque → the full logo melts into the bar
     with no visible square. */
  background: var(--bg-0);
  border-image: var(--grad) 1;
  box-shadow: 0 6px 22px -12px rgba(0,0,0,0.85);
}
.workspace { height: calc(100vh - 84px); }   /* match the taller bar — no overflow */

/* ---- Brand lockup: real logo emblem + flux wordmark ---- */
.brand { gap: 12px; align-items: flex-end; }   /* bottom-align icon ↔ tagline */
/* Logo = the flux MARK only (text removed), glow baked in, transparent.
   Height synced to the full text lockup (name + gap + tagline ≈ 72px). */
.brand-logo {
  height: 67px; aspect-ratio: 401 / 179; width: auto; flex: 0 0 auto;
  /* Transparent padding trimmed off the PNG, so the box = the glowing art.
     Height equals the text lockup (name 45 + gap 4 + tagline 18 ≈ 67px)
     and the row is bottom-aligned → icon TOP lines up with TACHYON, icon BOTTOM
     with the tagline. */
  background: url('/assets/tachyon-mark.png?v=2') no-repeat 50% / contain;
}
/* Brand name + tagline sliced straight from the logo (EXACT font + colours),
   tagline stacked directly UNDER the name. Both set to the SAME width so the
   name spans the tagline's width and they form an aligned block. */
.brand-lockup  { display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 4px; }
.brand-wordmark { width: 240px; height: auto; display: block;
  /* Brighter + a touch more saturation (so FLUX's colours pop) + a soft glow
     that traces the letters (transparent PNG → drop-shadow follows the text).
     Glow ONLY on the name. Static — zero latency. Width matched to the tagline. */
  filter: brightness(1.24) saturate(1.12) drop-shadow(0 0 7px rgba(150,200,255,0.55)); }
.brand-tagline  { width: 264px; height: auto; display: block; opacity: 1;
  image-rendering: -webkit-optimize-contrast;   /* crisper downscale */
  /* Original PNG design/colour kept — just SHARPER + more visible: brightness +
     contrast up, glow blur tightened to 2px so the edges stay crisp (no halo). */
  filter: brightness(1.7) contrast(1.3) saturate(1.1) drop-shadow(0 0 2px rgba(150,200,255,0.5)); }
.brand-name {
  font-size: 34px; letter-spacing: 0.24em; font-weight: 700;
  background: var(--grad); background-size: 220% auto;
  -webkit-background-clip: text; background-clip: text; color: transparent;
  filter:
    drop-shadow(0 0 5px rgba(120,210,255,0.55))
    drop-shadow(0 0 16px rgba(150,150,255,0.40));
  animation: brandFlux 7s linear infinite;     /* the lone, isolated motion accent */
}
@keyframes brandFlux { 0% { background-position: 0% 50%; } 100% { background-position: 220% 50%; } }
@media (prefers-reduced-motion: reduce) { .brand-name { animation: none; } }

/* ---- Panels: glassy, rounder, layered depth (all static) ---- */
.panel {
  border-radius: 12px;
  border: 1px solid var(--border);
  /* Near-black card (matches the logo field) with the faintest top lift — the
     border + colored accent header provide the structure, not a lighter fill. */
  background: linear-gradient(180deg, #090c16 0%, #04060e 55%);
  box-shadow:
    0 12px 30px -18px rgba(0,0,0,0.9),
    inset 0 1px 0 rgba(255,255,255,0.035);
}
/* The header's --pa accent reads as a glowing top hairline against the glass. */
.panel-h { box-shadow: inset 0 -1px 0 rgba(255,255,255,0.02); }

/* ---- Per-panel flux emblem: a touch larger + accent glow ---- */
.panel-logo svg {
  width: 16px; height: 16px;
  filter: drop-shadow(0 0 4px color-mix(in srgb, var(--pa) 70%, transparent));
}

/* ---- Count pill: subtle inner lift ---- */
.panel-meta.count { box-shadow: inset 0 0 8px -3px color-mix(in srgb, var(--pa) 60%, transparent); }

/* ---- Inputs / buttons: rounder, with a focus glow (chrome only, not data) ---- */
.actions input, .actions button, .chart-action, .tf-btn,
.pane-ticker, .pane-tf, .pane-ctype, .modal-foot button, .tv-foot button { border-radius: 7px; }
.actions input:focus, .quote-table:focus-within,
.pane-ticker:focus, .pane-tf:focus, .pane-ctype:focus,
.panel-h input:focus, .tv-search:focus, #quote-search:focus {
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 42%, transparent);
}

/* ---- Scanner header: faint gradient so the sticky thead reads as a ledge ---- */
.scan-table thead { background: linear-gradient(180deg, var(--bg-2), var(--bg-1)); }
/* Focused row: a crisper flux edge (static; bg already handled above). */
.scan-table tbody tr.focused { box-shadow: inset 3px 0 0 var(--pa), inset 0 0 22px -14px var(--pa); }

/* ---- Stock Quote hero: flux-gradient ticker for presence ---- */
#q-ticker {
  background: var(--grad); -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 0 10px rgba(54,226,255,0.35));
}
.q-price { font-weight: 800; }

/* ---- Modals: cleaner card framing (rare path — safe) ---- */
.modal-card { border-radius: 12px; box-shadow: 0 30px 80px -30px rgba(0,0,0,0.85); }

/* ---- Popout header: keep it COMPACT. The v2 `.topbar { height: 84px }` above
   leaks into popout windows (they share the .topbar class), ballooning the bar
   to 84px of empty space AND pushing the chart's x-axis off the bottom (popout
   chart area is sized calc(100vh - 30px)). Two-class selector wins regardless
   of order → restores the 30px bar and the x-axis crosshair time label. ---- */
.topbar.popout-topbar { height: 60px; }
/* Flux mark in the popout header — the trimmed glowing mark. Base size suits the
   compact chart-popout toolbar; the standalone (news/alerts/Vantage) header bar
   below scales it up to match its 60px height + larger panel name. */
.popout-logo {
  height: 22px; aspect-ratio: 401 / 179; width: auto; flex: 0 0 auto; margin-right: 2px;
  background: url('/assets/tachyon-mark.png?v=2') no-repeat 50% / contain;
}
/* Popouts: drop the "live · N msg/s" connection clutter in EVERY toggled-out window. */
.popout-topbar .dot,
.popout-topbar #conn-text,
.popout-topbar #msg-rate,
.popout-topbar .sep { display: none; }
/* Chart popout → ONE band: hide the separate header entirely; the chart toolbar
   (flux mark + ticker + timeframes + candle + indicators) becomes the only bar. */
.popout-body.chart-popout .popout-topbar { display: none; }
.popout-body.chart-popout .popout-main  { height: 100vh; }
/* Popout is wide → single-row timeframe bar: D/W/M/Y flow right after 4h instead
   of wrapping to a second line. (Main-deck panes are narrower, so they keep the
   stacked two-row layout.) */
.popout-body .chart-tf { flex-direction: row; flex-wrap: wrap; align-items: center; }
/* Positioning context for the popout chart's HALTED banner (.pane-halt). */
.po-chart-wrap { position: relative; }
/* Subtle Tachyon emblem watermark on toggled-out (data) panels — faint enough not
   to interfere with content; pointer-events:none so it never blocks clicks. Excludes
   the chart popout so candles stay perfectly clear. */
.popout-body:not(.chart-popout) .popout-main::after {
  content: ''; position: absolute; inset: 0; z-index: 6; pointer-events: none;
  background: url('/assets/tachyon-mark.png?v=2') no-repeat center / min(100%, 1080px) 90%;
  opacity: 0.04;
}

