/* ============================================================================
   Ticker Lab — redesign component layer (brief 00 foundation)
   Lifted from the canonical chrome mockups (docs/mockups/tl_market_pulse_cards
   .html, tl_eod_data_compact.html, tl_apexqquant_redesign.html). Consumes the
   §2 redesign tokens in tokens.css (--bg/--surface/--text/--accent/...). NO
   hardcoded hex — every colour resolves to a token.

   Two layers:
     1. GLOBAL sidebar chrome (.side/.nav/...) — wired into base.html now, so it
        renders on every page. Footer bits (.whats-new/.user-chip/.popover-menu/
        .theme-toggle) keep their existing base.css styles; only Phosphor-icon
        sizing is added here.
     2. The `.tlx` page surface — every page-content class is scoped under .tlx
        so it cannot restyle a live page. Pages restyled by briefs 01+ opt in by
        wrapping their content in <div class="tlx">…</div>; the shared partials
        (_market_pulse_card, _status_strip, page_header, sort_button) assume that
        ancestor. Scoping also lets `.tlx .btn`/`.tlx .chip` carry the dense
        mockup look without touching the global `.btn`/`.chip`.
   ============================================================================ */

/* ===========================================================================
   1. SIDEBAR CHROME (global)
   =========================================================================== */
.side {
  flex: 0 0 var(--sidebar-width);
  width: var(--sidebar-width);
  position: sticky; top: 0; align-self: flex-start; height: 100vh;
  display: flex; flex-direction: column;
  /* Sidebar v3: top padding trimmed 16px → 4px to raise the brand + nav to eye
     level (sides/bottom unchanged at 12px/16px). Combined with the .nav-h trim
     below this lifts the SOLUTIONS label + nav links ~20px and the logo ~12px. */
  padding: 4px 12px 16px;
  background: var(--surface);
  border-right: 1px solid var(--border);
  z-index: var(--z-sidebar);
  overflow-y: auto;
}

.nav-h {
  font-family: var(--mono);
  font-size: 9px; letter-spacing: .16em; font-weight: 600;
  text-transform: uppercase;
  color: var(--text-3);
  /* Sidebar v3: top padding trimmed 10px → 2px (raise to eye level). The logo's
     own bottom padding (var(--space-2) = 8px, base.css) still spaces it off. */
  padding: 2px 10px 6px;
}
.nav { display: flex; flex-direction: column; gap: 2px; }
.nav a {
  position: relative;
  display: flex; align-items: center; gap: 11px;
  padding: 9px 10px; border-radius: 8px;
  /* Visual hierarchy: nav links sit at full --text brightness + weight-medium so
     they read as the most prominent tier, above the recessed data zone below.
     (was --text-2; size 13px == --text-sm and weight 500 == --weight-medium are
     unchanged. Active .on + hover already carry semibold/accent/surface-2.) */
  color: var(--text); font-weight: 500; font-size: 13px;
}
.nav a i.ph { font-size: 18px; line-height: 1; }
/* Sidebar v4: nav icons are blue-family, never warm — muted blue-grey when
   inactive, full accent on the active item (the label/pill keep their own
   colours from .nav a / .nav a.on above). */
.side .nav a i { color: var(--text-2); }
.side .nav a.on i { color: var(--accent); }
.nav a:hover { background: var(--surface-2); color: var(--text); text-decoration: none; }
.nav a.on { background: var(--accent-soft); color: var(--accent-text); font-weight: 600; }
.nav a.on::before {
  content: ""; position: absolute; left: 0; top: 7px; bottom: 7px;
  width: 2.5px; border-radius: 2px; background: var(--accent);
}
.nav a .adm {
  /* Sidebar v4b (Fix 1): a whisper-small ADMIN indicator beside the "ApexQQuant"
     label — visually secondary, not a primary badge (9px / tight 1px 4px padding /
     3px radius / .05em). v4 kept the solid blue accent pill + small left gap;
     white-on-accent reads in both themes. */
  margin-left: 5px;
  font-family: var(--mono); font-size: 9px; font-weight: 600;
  letter-spacing: .05em; text-transform: uppercase;
  color: var(--on-accent); background: var(--accent);
  border: 1px solid var(--accent); border-radius: 3px; padding: 1px 4px;
}
/* Ideas nav unvoted-count badge (feedback_voting_v1) — a small accent pill pushed
   to the right of the "Ideas" nav label, mirroring the lock-icon's margin-left:auto
   placement so the row alignment matches the other nav items. */
.nav a .nav-badge {
  margin-left: auto; min-width: 16px; height: 16px; padding: 0 5px;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--mono); font-size: 10px; font-weight: 600; line-height: 1;
  border-radius: var(--radius-pill); background: var(--accent); color: var(--on-accent);
}

/* Phosphor-icon sizing for the reused footer controls (their layout/colours
   come from base.css; only the icon glyph needs a font-size). */
.side .theme-toggle i.ph { font-size: 18px; line-height: 1; color: var(--text-2); }
.side .whats-new i.ph { font-size: 16px; line-height: 1; color: var(--accent-text); }
.side .user-avatar i.ph { font-size: 14px; line-height: 1; }

/* Sidebar v5: the theme toggle now lives INSIDE the account chip's frame, not on a
   standalone row above it. .account-bar is the bordered frame base.css used to draw
   on .user-chip; the chip (popover trigger) and the moon/sun toggle are siblings
   inside it, so the toggle is visually within the chip yet the popover handler
   (closest('.user-chip')) still ignores it. overflow:hidden clips each child's hover
   fill to the rounded frame, so the trigger zone and the moon zone read as two
   flush segments split by the divider below. */
.side .account-bar {
  display: flex;
  align-items: stretch;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
}

/* Chip = the popover trigger: borderless and flex-filling inside the frame (the
   frame now owns the border). min-width:0 keeps the user-name ellipsis working in
   the flex row; its base.css hover background highlights just this left zone. */
.side .user-chip { flex: 1 1 auto; width: auto; min-width: 0; border: 0; border-radius: 0; }

/* Theme toggle = the right segment: full-height, glyph centred, split from the
   trigger by a hairline divider. (Sidebar v4's flex-start/10px rail alignment was
   for the old standalone-row position and no longer applies.) */
.side .account-bar .theme-toggle {
  align-self: stretch; height: auto;
  justify-content: center; padding-left: 0;
  border-left: 1px solid var(--border); border-radius: 0;
}

/* Account-chip caret muted to the redesign --text-3 (was the legacy faint token). */
.side .user-chip::after { border-right-color: var(--text-3); border-bottom-color: var(--text-3); }

/* Sidebar v4b (Fix 5): land the account avatar on the 22px nav rail. base.css gives
   .user-chip a 12px (--space-3) inner pad + a 1px border, so the avatar sat at 25px
   (3px right of the rail); 9px left pad → 12px(chip edge) + 1px border + 9px = 22px,
   matching the nav icons and the theme-toggle glyph above. Right pad kept for the
   caret. */
.side .user-chip { padding-left: 9px; }

/* Sidebar v4b (Fix 3): widen the account popover toward the sidebar edges. base.css
   pins it left:0/right:0 of the footer content box (a 12px inset each side, so it
   read as over-margined vs the band above). -space-2 bleeds it to a ~4px side gap —
   nearly the full sidebar inner width while staying a card off the edge. Geometry
   only: position / z-index / background / border / radius untouched. */
.side .popover-menu { left: calc(-1 * var(--space-2)); right: calc(-1 * var(--space-2)); }

/* ---------------------------------------------------------------------------
   Collapsible sidebar (ui_polish_batch_1) — an icon-only ~48px rail toggled by
   html.sidebar-collapsed (set no-FOUC in <head>, flipped by the delegated handler
   in base.html, persisted in localStorage 'tl-sidebar'). The shell (.app-shell)
   is flexbox, so shrinking .side lets .content reclaim the freed width with no
   grid swap. The chevron lives top-right of the brand expanded, centred below the
   logo collapsed.
   --------------------------------------------------------------------------- */
.side-head { display: flex; align-items: center; gap: 6px; }
.side-head .brand-lockup { flex: 1 1 auto; min-width: 0; }
.side-toggle {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; padding: 0;
  border: 1px solid var(--border); border-radius: 7px;
  background: transparent; color: var(--text-2); cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.side-toggle:hover { background: var(--surface-2); color: var(--text); }
.side-toggle i.ph { font-size: 15px; line-height: 1; }
.side-toggle .ico-expand { display: none; }   /* '>' shows only when collapsed */

/* Collapsed rail. The label text in each nav <a> is a bare text node, so it can't
   be display:none'd directly — font-size:0 collapses it while the icon keeps its
   own size; the same trick hides the user-name without touching the avatar. */
.sidebar-collapsed .side {
  flex-basis: 48px; width: 48px;
  padding-left: 6px; padding-right: 6px;
}
.sidebar-collapsed .side-head { flex-direction: column; gap: 8px; }
.sidebar-collapsed .side .brand-text { display: none; }
.sidebar-collapsed .side .brand-lockup { flex: 0 0 auto; justify-content: center; padding: 0; gap: 0; }
.sidebar-collapsed .side .brand-mark { flex-basis: 28px; width: 28px; height: 28px; }
.sidebar-collapsed .side-toggle .ico-collapse { display: none; }
.sidebar-collapsed .side-toggle .ico-expand { display: inline-flex; }

.sidebar-collapsed .side .nav-h,
.sidebar-collapsed .side .sidebar-lower,
.sidebar-collapsed .side .user-meta,
.sidebar-collapsed .side .nav a .adm { display: none; }

.sidebar-collapsed .side .nav a { justify-content: center; gap: 0; padding: 9px 0; font-size: 0; }
.sidebar-collapsed .side .nav a i.ph { font-size: 18px; }

.sidebar-collapsed .side .account-bar { flex-direction: column; border: 0; }
.sidebar-collapsed .side .user-chip { padding: 6px 0; justify-content: center; }
.sidebar-collapsed .side .user-chip::after { display: none; }
.sidebar-collapsed .side .account-bar .theme-toggle {
  align-self: stretch; width: 100%;
  border-left: 0; border-top: 1px solid var(--border);
}
/* The account popover would be a cramped 48px otherwise — pin it to the rail's
   left edge with a readable fixed width, overflowing over the content. */
.sidebar-collapsed .side .popover-menu { left: 0; right: auto; min-width: 200px; }

/* Market-levels strip (sidebar market-levels build) — NIFTY/VIX last + day-change%.
   Global sidebar layer (NOT under .tlx). Numbers use Inter tabular-nums; colour is
   by sign of the change (green up / red down / muted flat). Every colour is a token. */
.sidebar-levels {
  margin-top: 12px;
  padding: 10px 10px 8px;
  border-top: 1px solid var(--border);
}
.sidebar-levels .sl-head {
  display: flex; align-items: baseline; justify-content: space-between;
  margin-bottom: 7px;
}
.sidebar-levels .sl-title {
  font-family: var(--mono);
  font-size: 9px; letter-spacing: .16em; font-weight: 600;
  text-transform: uppercase; color: var(--text-3);
}
.sidebar-levels .sl-asof {
  font-size: 9.5px; color: var(--text-3);
  font-variant-numeric: tabular-nums;
}
.sidebar-levels .sl-asof.is-stale { opacity: .8; }
.sidebar-levels .sl-row {
  display: grid; grid-template-columns: auto 1fr auto;
  align-items: baseline; gap: 8px; padding: 3px 0;
}
.sidebar-levels .sl-name {
  font-size: 11px; font-weight: 600; color: var(--text-2); letter-spacing: .02em;
}
.sidebar-levels .sl-last {
  font-size: 12px; color: var(--text);
  text-align: right; font-variant-numeric: tabular-nums;
}
.sidebar-levels .sl-chg {
  font-size: 11px; text-align: right; min-width: 52px;
  font-variant-numeric: tabular-nums;
}
.sidebar-levels .sl-chg.up   { color: var(--green); }
.sidebar-levels .sl-chg.down { color: var(--red); }
.sidebar-levels .sl-chg.flat { color: var(--text-3); }
.sidebar-levels .sl-chg.is-stale { opacity: .55; }

/* Policy & Macro news strip (sidebar_market_news_build) — up to 5 recent
   regulatory market-event headline citations. Global sidebar layer (NOT under
   .tlx). Same section-label treatment as .sidebar-levels; SEBI-safe citation
   block, so NO directional/bias colour. Every colour is a token. */
.sidebar-news {
  margin-top: 12px;
  padding: 10px 10px 8px;
  border-top: 1px solid var(--border);
}
.sidebar-news .sn-head,
.sidebar-shipped .sn-head {
  display: flex; align-items: baseline; justify-content: space-between;
  margin-bottom: 7px;
}
.sidebar-news .sn-title,
.sidebar-shipped .sn-title {
  font-family: var(--mono);
  font-size: 9px; letter-spacing: .16em; font-weight: 600;
  text-transform: uppercase; color: var(--text-3);
}
/* Each item: a citation link. Dashed divider between items (not above the first). */
.sidebar-news .sn-item {
  display: block; text-decoration: none;
  padding: 6px 0; border-top: 1px dashed var(--border);
}
.sidebar-news .sn-item:first-of-type { border-top: 0; padding-top: 0; }
.sidebar-news .sn-item.is-nolink { cursor: default; }
/* Headlines read as INFORMATION, not UI controls (sidebar visual hierarchy):
   off-white --text-2 + weight-normal, brightening to --text on hover. Size 11px
   and the snug 1.35 line-height are unchanged (--leading-snug is not a token). */
.sidebar-news .sn-headline,
.sidebar-shipped .sn-headline {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden;
  font-size: 11px; line-height: 1.35;
  font-weight: var(--weight-normal); color: var(--text-2);
}
.sidebar-news a.sn-item:hover { cursor: pointer; }
.sidebar-news a.sn-item:hover .sn-headline { color: var(--text); text-decoration: underline; }
.sidebar-news .sn-meta,
.sidebar-shipped .sn-meta {
  display: block; margin-top: 3px;
  font-size: 10px; color: var(--text-3);
}
.sidebar-news .sn-empty {
  margin: 0; font-size: 10px; font-style: italic; color: var(--text-3);
}

/* Lower band wrapper (sidebar layout v2) — groups the levels / breadth / news /
   promo strips and drops them as ONE block to the bottom of the sidebar, directly
   above the account footer. The single margin-top:auto lives here (the footer's
   own auto is neutralised below) so the group + footer stay contiguous at the
   bottom. .side is a flex column, so this is a flex child. */
.side .sidebar-lower {
  margin-top: auto;
  display: flex; flex-direction: column;
}
.side .sidebar-footer { margin-top: 0; }

/* Last Shipped strip (sidebar v3) — the bottom-band release nudge, restyled from
   the old bordered ".whats-new" promo CARD into a plain section that mirrors the
   POLICY & MACRO strip: a mono section label + headline + date, NO card border /
   background / icon. Sits BELOW the data zone (not inside it), so it keeps its own
   10px horizontal padding to align with the nav like a top-level section. The
   section/label/headline/meta typography is shared with .sidebar-news via the
   grouped .sn-* selectors above, so the two read as identical citation rows. */
.sidebar-shipped {
  margin-top: 12px;
  padding: 10px 10px 8px;
  border-top: 1px solid var(--border);
}
.sidebar-shipped-item { display: block; }

/* Illuminatis — the Ideas surface. Sidebar v6 retired the standalone boxed GREEN
   lamp and relocated it INTO the account bar, as a quiet segment beside the
   theme-toggle (half-moon): the same 34px stretch-to-frame square, the same centred
   18px glyph, the same hairline divider and hover — but coloured the LOGO BLUE
   (--accent) rather than the moon's muted grey, so the lamp reads as on-brand (no
   green, no box, no fill, no glow). Hover brightens to --accent-text; active (/ideas)
   keeps the accent. The only other loud element is the unvoted-count pip, accent-blue.
   The name "Illuminatis" lives in title/aria-label (icon-only). */
.side .account-bar .sidebar-illuminatis {
  position: relative;
  flex: 0 0 auto; width: 34px;
  align-self: stretch; height: auto;
  display: inline-flex; align-items: center; justify-content: center;
  text-decoration: none; cursor: pointer;
  background: transparent; color: var(--accent);
  border-left: 1px solid var(--border); border-radius: 0;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.side .account-bar .sidebar-illuminatis:hover { background: var(--color-surface-raised); color: var(--accent-text); }
.side .account-bar .sidebar-illuminatis.on { color: var(--accent); }
/* Glyph matches the half-moon exactly: 18px, inherits the segment colour. */
.illuminatis-glyph { font-size: 18px; line-height: 1; color: inherit; }
/* Unvoted-count pip — accent-blue, overlaid on the segment's top-right. */
.illuminatis-badge {
  position: absolute; top: 3px; right: 3px;
  min-width: 15px; height: 15px; padding: 0 4px;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--mono); font-size: 9px; font-weight: 700; line-height: 1;
  border-radius: var(--radius-pill);
  background: var(--accent); color: var(--on-accent);
}
/* Locked (non-subscriber) overlay. */
.illuminatis-lock {
  position: absolute; top: 4px; right: 5px;
  font-size: 11px; opacity: .6; color: var(--text-3);
}
/* Collapsed rail — the account bar stacks (flex column, no frame border), so the
   lamp becomes a full-width row like the theme-toggle: swap the left divider for a
   top one and re-centre (mirrors the .theme-toggle collapsed rule below). */
.sidebar-collapsed .side .account-bar .sidebar-illuminatis {
  width: 100%; padding: 7px 0;
  border-left: 0; border-top: 1px solid var(--border);
}

/* Visual-hierarchy tiers (sidebar_visual_hierarchy_build). The lower band splits
   into a hairline divider that caps it, a recessed DATA zone holding the three
   market strips, and the promo below — so the NAV / DATA / FOOTER tiers read at
   distinct weights. */
/* Divider — bleeds to the sidebar edges. The bleed is 12px (== .side's horizontal
   padding), NOT 16px: .side is overflow-y:auto, so overflow-x computes to auto and
   a wider bleed would trip a horizontal scrollbar. */
.side-divider {
  border: none;
  border-top: 1px solid var(--border);
  margin: var(--space-3) calc(-1 * var(--space-3));
  opacity: 0.6;
}
/* Data zone — a subtly recessed, bordered panel. Tint is var(--bg), NOT the
   brief's var(--surface-2): in light mode --surface-2 == --surface (#FFFFFF), so a
   surface-2 fill would be invisible against the white sidebar. --bg is one step
   darker than the sidebar's --surface in BOTH themes (#0b0d12 vs #12141c dark;
   #F3F5F9 vs #FFFFFF light), and the hairline border guarantees separation either
   way. Slight negative horizontal margin (within .side's 12px padding) feels inset. */
.side-data-zone {
  background: var(--bg);
  /* Sidebar v4b (Fix 2): soften the panel border to --border-2 (fainter than
     --border in BOTH themes: #1E1E2E vs #232838 dark, #E8EBF0 vs #E3E6EC light) so
     the recess reads as a tier, not a heavy box-within-the-sidebar. */
  border: 1px solid var(--border-2);
  border-radius: var(--radius-lg);
  padding: var(--space-3);
  /* Sidebar v4b (Fix 4): bleed the band to the sidebar edges (was -space-2 → a 4px
     side gap that read as a cramped inset box). -space-3 matches the safe full-bleed
     of .side-divider above (a wider bleed trips overflow-x in the scrollable .side).
     The strips below regain the 22px rail via +10px padding. */
  margin: 0 calc(-1 * var(--space-3));
  display: flex; flex-direction: column;
}
/* Strips nest flush inside the zone's padding: drop their own horizontal padding,
   and reset the first strip's top margin/border/padding so it sits against the
   zone's top padding (the inter-strip border-top hairlines stay as section rules). */
/* Sidebar v4b: a 10px inset lands the strip CONTENT on the 22px nav rail. The zone
   now full-bleeds (-space-3 margin → border-box at the sidebar edge) + 12px padding,
   so its content box sits at 12px; +10px puts the content at 22px — exactly the nav
   <a> content column (icon rail). Symmetric on the right. */
.side-data-zone .sidebar-levels,
.side-data-zone .sidebar-ad,
.side-data-zone .sidebar-news { padding-left: 10px; padding-right: 10px; }
.side-data-zone > :first-child { margin-top: 0; border-top: 0; padding-top: 0; }

/* Breadth strip (sidebar layout v2) — today's advance/decline split bar + a 5-day
   A/D% sparkline. Global sidebar layer (NOT under .tlx). Same section-label
   treatment as .sidebar-levels; colour is by sign only (green adv / red dec).
   Every colour is a token. */
.sidebar-ad {
  margin-top: 12px;
  padding: 10px 10px 8px;
  border-top: 1px solid var(--border);
}
.sidebar-ad .sa-head {
  display: flex; align-items: baseline; justify-content: space-between;
  margin-bottom: 7px;
}
.sidebar-ad .sa-title {
  font-family: var(--mono);
  font-size: 9px; letter-spacing: .16em; font-weight: 600;
  text-transform: uppercase; color: var(--text-3);
}
.sidebar-ad .sa-asof {
  font-size: 9.5px; color: var(--text-3); font-variant-numeric: tabular-nums;
}
.sidebar-ad .sa-asof.is-stale { opacity: .8; }
/* Split bar: pill, 8px tall, two inner spans (green adv% / red dec%). */
.sidebar-ad .sa-bar {
  display: flex; height: 8px; border-radius: 999px; overflow: hidden;
  background: var(--border);
}
.sidebar-ad .sa-bar > span {
  display: inline-block; height: 100%; transition: width .3s ease;
}
.sidebar-ad .sa-bar-adv { background: var(--green); }
.sidebar-ad .sa-bar-dec { background: var(--red); }
/* Count row: adv green / dec red, tabular Inter. */
.sidebar-ad .sa-counts {
  display: flex; justify-content: space-between; margin-top: 5px;
  font-size: 10px; font-variant-numeric: tabular-nums;
}
.sidebar-ad .sa-adv { color: var(--green); }
.sidebar-ad .sa-dec { color: var(--red); }
.sidebar-ad i.ph { font-size: 9px; line-height: 1; vertical-align: middle; }
/* 5-day sparkline: thin polyline (segment-by-segment colour) + tiny mono ticks. */
.sidebar-ad .sa-spark { margin-top: 8px; overflow: hidden; }
.sidebar-ad .sa-spark svg { display: block; width: 100%; }
.sidebar-ad .sa-spark line {
  stroke-width: 1.25; fill: none; stroke-linecap: round; stroke-linejoin: round;
}
.sidebar-ad .sa-spark .spk-up { stroke: var(--green); }
.sidebar-ad .sa-spark .spk-down { stroke: var(--red); }
.sidebar-ad .sa-ticks {
  display: flex; justify-content: space-between; margin-top: 3px;
  font-family: var(--mono); font-size: 9px; color: var(--text-3);
}
.sidebar-ad .sa-empty {
  margin: 4px 0 0; font-size: 10px; font-style: italic; color: var(--text-3);
}
/* Stale / awaiting: dim the bar + counts (brief §4). */
.sidebar-ad.is-stale .sa-bar,
.sidebar-ad.is-stale .sa-counts { opacity: .5; }

/* ===========================================================================
   2. PAGE SURFACE — scoped to `.tlx` (opt-in per redesigned page)
   =========================================================================== */
.tlx { color: var(--text); }
.tlx .mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.tlx .t3 { color: var(--text-3); }
.tlx .pos { color: var(--green); }
.tlx .neg { color: var(--red); }

/* --- Identity line (page_header macro) ------------------------------------ */
.tlx .idline { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
.tlx .idline .name { margin: 0; /* element-proof: h1 or span (SEO Phase A) */
  font-family: var(--mono); font-size: 11px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--text); font-weight: 600;
}
.tlx .idline .tag { font-size: 12.5px; color: var(--text-3); }
.tlx .idline .right { margin-left: auto; display: flex; align-items: center; gap: 14px; }
.tlx .idline .stats { font-family: var(--mono); font-size: 11px; color: var(--text-3); }
.tlx .idline .stats b { color: var(--text-2); font-weight: 500; }

/* --- Sub-tabs (Cards/Table/Changes) --------------------------------------- */
.tlx .vtabs { display: flex; align-items: center; gap: 2px; border-bottom: 1px solid var(--border); margin-bottom: 14px; }
.tlx .vtabs button, .tlx .vtabs a {
  border: 0; background: transparent; color: var(--text-2);
  font-weight: 600; font-size: 13.5px; padding: 9px 4px; margin-right: 16px;
  border-bottom: 2px solid transparent; cursor: pointer;
  font-family: var(--body); text-decoration: none; line-height: 1.5;
}
.tlx .vtabs button.on, .tlx .vtabs a.on { color: var(--text); border-bottom-color: var(--accent); }

/* --- Product pill tabs (EOD Data/Screener/Dashboard) ---------------------- */
.tlx .ptabs {
  display: inline-flex; gap: 2px; background: var(--surface-2);
  border: 1px solid var(--border); border-radius: 9px; padding: 3px; margin-bottom: 14px;
}
.tlx .ptabs button, .tlx .ptabs a {
  border: 0; background: transparent; color: var(--text-2);
  padding: 7px 16px; border-radius: 6px; font-weight: 600; font-size: 13px;
  cursor: pointer; font-family: var(--body); text-decoration: none;
}
.tlx .ptabs button.on, .tlx .ptabs a.on { background: var(--accent); color: var(--on-accent); }

/* --- Compact control bar (EOD) -------------------------------------------- */
.tlx .ctrl { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; border-bottom: 1px solid var(--border); }
.tlx .ctrl .right { margin-left: auto; display: flex; align-items: center; gap: 8px; padding-bottom: 7px; }
.tlx .subtabs { display: flex; gap: 2px; }
.tlx .subtabs button, .tlx .subtabs a {
  border: 0; background: transparent; color: var(--text-2); font-weight: 600;
  font-size: 13.5px; padding: 9px 4px; margin-right: 14px;
  border-bottom: 2px solid transparent; cursor: pointer; font-family: var(--body); text-decoration: none;
}
.tlx .subtabs button.on, .tlx .subtabs a.on { color: var(--text); border-bottom-color: var(--accent); }

/* --- Filter bar: dropdowns / search / buttons ----------------------------- */
.tlx .filters { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; }
.tlx .ddl {
  display: inline-flex; align-items: center; gap: 8px;
  border: 1px solid var(--border); background: var(--surface-2); color: var(--text);
  border-radius: 8px; padding: 8px 12px; font-size: 12.5px; font-weight: 500;
}
.tlx .ddl i { color: var(--text-3); font-size: 12px; }
.tlx .ddl.date { font-family: var(--mono); }

/* --- Date inputs: unified across all pages -------------------------------
   Two intentional patterns share the native date control:
   (1) admin form fields (class="input", e.g. EOD Refresh, the reference),
   (2) filter-bar pickers nested in a `.ddl` pill, deliberately borderless
       since the pill supplies the border, background and caret.
   The base look below mirrors `.input` so any standalone or future unclassed
   date input matches the reference; `:not(.ddl input)` leaves the pill
   pickers untouched (no box-in-box, no padding or width shift). The
   calendar-icon tint applies to ALL date inputs: the native glyph renders
   near-invisible dark-on-dark, so tint it on the dark theme and fall back to
   the default glyph under `html.light`. */
input[type="date"]:not(.ddl input) {
  width: 100%;
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-sm);
  background: var(--color-bg);
  color: var(--color-text);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  transition: border-color var(--transition-fast);
}
input[type="date"]:not(.ddl input):focus { border-color: var(--color-accent); }

input[type="date"]::-webkit-calendar-picker-indicator {
  filter: invert(0.6);
  cursor: pointer;
}
html.light input[type="date"]::-webkit-calendar-picker-indicator { filter: none; }
.tlx .search {
  flex: 1; min-width: 220px; display: flex; align-items: center; gap: 8px;
  border: 1px solid var(--border); background: var(--surface-2);
  border-radius: 8px; padding: 8px 12px; color: var(--text-3);
}
.tlx .search i { font-size: 15px; }
.tlx .search input {
  border: 0; background: transparent; color: var(--text);
  font-size: 13px; outline: none; width: 100%; font-family: var(--body);
}
/* Dense control button (sort_button macro, CSV, Columns). Scoped — does NOT
   touch the global .btn used by existing pages. */
.tlx .btn {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; color: var(--text-2);
  border: 1px solid var(--border); background: var(--surface-2);
  border-radius: 8px; padding: 8px 12px; font-weight: 600; cursor: pointer;
  font-family: var(--body); text-decoration: none;
}
.tlx .btn:hover { color: var(--text); background: var(--surface); }
.tlx .btn i { font-size: 14px; }
.tlx .refresh {
  display: inline-flex; align-items: center; gap: 6px; font-size: 12px;
  color: var(--text-2); border: 1px solid var(--border); background: var(--surface-2);
  border-radius: 8px; padding: 6px 11px; font-weight: 600; cursor: pointer;
}
.tlx .refresh i { font-size: 14px; }

/* --- View-mode toggle (Market Lean: Table ⇄ Cards) ------------------------ */
/* Icon-only segmented control (no text). Lives at the left of the filter row;
   collapses with the row on the Changes tab. */
.tlx .viewmode {
  display: inline-flex; align-items: center; gap: 2px;
  border: 1px solid var(--border); background: var(--surface-2);
  border-radius: 8px; padding: 3px;
}
.tlx .viewmode .vm {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 28px; border: 0; background: transparent;
  color: var(--text-3); border-radius: 6px; cursor: pointer;
}
.tlx .viewmode .vm i { font-size: 15px; }
.tlx .viewmode .vm:hover:not(.on) { color: var(--text); }
.tlx .viewmode .vm.on { background: var(--accent); color: var(--on-accent); }

/* Market Pulse top-gap trim — tighten the tab + filter rows so the table / digest
   sit closer to the tabs. Scoped to `.scanner` so other `.tlx` pages keep their
   spacing; the higher specificity (.tlx.scanner) wins over the base `.tlx` rule. */
.tlx.scanner .vtabs { margin-bottom: 10px; }
.tlx.scanner .filters { margin-bottom: 10px; }

/* --- Meta line ------------------------------------------------------------ */
.tlx .meta {
  font-family: var(--mono); font-size: 11px; color: var(--text-3);
  padding: 10px 2px; display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
}
.tlx .meta b { color: var(--text-2); font-weight: 500; }
.tlx .meta .dot { color: var(--border); }
.tlx .meta .disc { margin-left: auto; font-style: italic; }

/* --- Consensus marks (signature device, §7) ------------------------------- */
.tlx .marks { display: inline-flex; align-items: center; font-family: var(--mono); font-size: 16px; line-height: 1; }
.tlx .marks .g { display: inline-flex; gap: 3px; font-weight: 400; }
.tlx .marks .g + .g { margin-left: 9px; }
.tlx .marks .bull, .tlx .bull { color: var(--green); }
.tlx .marks .neu, .tlx .neu { color: var(--text-3); }
.tlx .marks .bear, .tlx .bear { color: var(--red); }

/* --- Regime label (EOD screener / apex) ----------------------------------- */
.tlx .reg { font-family: var(--mono); font-size: 11px; font-weight: 600; }
.tlx .reg.bull { color: var(--green); }
.tlx .reg.bear { color: var(--red); }
.tlx .reg.neu { color: var(--text-3); }

/* --- Tables --------------------------------------------------------------- */
/* L1: wide tables (e.g. F&O = 18 cols) overflow the content area; `overflow:hidden`
   clipped the right-hand columns with NO horizontal scroll, so they were
   delivered-but-unreachable (narrow Cash/Key-Strikes fit, so only F&O bit). Match
   the base system's `.table-wrap { overflow-x:auto }` (base.css) — wide tables now
   scroll horizontally; narrow ones get no scrollbar; rounded corners still clip. */
.tlx .tablewrap { border: 1px solid var(--border); border-radius: 11px; overflow-x: auto; background: var(--surface); }
.tlx .tbl { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.tlx .tbl thead th {
  position: sticky; top: 0; background: var(--surface); text-align: right;
  font-family: var(--mono); font-size: 10px; letter-spacing: .05em;
  text-transform: uppercase; color: var(--text-3); font-weight: 600;
  padding: 11px 16px; border-bottom: 1px solid var(--border);
}
.tlx .tbl thead th:first-child { text-align: left; }
/* L2: `white-space: nowrap` keeps every data cell single-line. The base system's
   `table.data tbody td` (base.css) had this; the `.tlx` restyle dropped it (same
   class of regression as L1's overflow). Without it, F&O's free-text columns
   `gap` (comma-joined diffs) and `ranking` (concatenated "rank=> [expiry]" parts,
   up to ~255 chars) WRAP across many lines → rows hundreds of px tall, while the
   narrow Cash / Key-Strikes tables (no long free-text column) stay tight. With
   L1's `overflow-x:auto` on `.tablewrap`, the now-single-line wide row scrolls
   horizontally instead of wrapping vertically. Long cells elsewhere (scanner
   headline) already clip via `.clip`, so this is a no-op for them. */
.tlx .tbl tbody td {
  padding: 11px 16px; border-bottom: 1px solid var(--border-2);
  font-family: var(--mono); font-variant-numeric: tabular-nums; text-align: right;
  white-space: nowrap;
}
.tlx .tbl tbody td:first-child { text-align: left; }
.tlx .tbl tbody tr:last-child td { border-bottom: 0; }
.tlx .tbl tbody tr:hover { background: var(--surface-2); }
.tlx .tbl .sym { font-weight: 600; color: var(--text); }
.tlx .tbl .dash, .tlx .dash { color: var(--text-3); }

/* Strategies descriptor table — a vertical scroll box (~30 rows) with the
   already-sticky `.tbl thead th` pinned. `.tablewrap` is already a scroll box
   (the overflow-x:auto above clips both axes); giving it a max-height makes the
   body scroll while the header stays put. The z-index lifts the sticky header
   above scrolling rows. Scoped to `.strat-scroll` so no other table is touched. */
.tlx .tablewrap.strat-scroll { max-height: 960px; overflow-y: auto; }
.tlx .tablewrap.strat-scroll thead th { z-index: 2; }

/* --- Market Pulse cards (anatomy locked, §6) ------------------------------ */
.tlx .grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.tlx .card {
  border: 1px solid var(--border); border-radius: 12px; background: var(--surface);
  padding: 16px 16px 15px; display: flex; flex-direction: column; gap: 13px;
}
.tlx .c-meta { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.tlx .c-meta .type {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--text-3); font-weight: 600;
}
.tlx .c-meta .sep { color: var(--border); font-size: 11px; }
.tlx .tag {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .03em;
  border-radius: 5px; padding: 3px 8px; font-weight: 600; text-transform: uppercase;
}
.tlx .tag.earn { background: var(--amber-soft); color: var(--amber); }
.tlx .tag.corp { background: var(--accent-soft); color: var(--accent-text); }
.tlx .c-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.tlx .c-head .sym {
  font-family: var(--mono); font-weight: 700; font-size: 17px; letter-spacing: -.01em;
  display: inline-flex; align-items: center; gap: 8px; color: var(--text);
}
.tlx .c-head .sym i { font-size: 16px; }
.tlx .prov { font-size: 12px; color: var(--text-3); line-height: 1.55; }
.tlx .prov .cnt { font-family: var(--mono); font-variant-numeric: tabular-nums; color: var(--text-2); font-weight: 600; }
.tlx .prov .more2 { color: var(--accent-text); font-weight: 600; cursor: pointer; }
.tlx .divider { height: 1px; background: var(--border-2); margin-top: 1px; }
.tlx .news { display: flex; flex-direction: column; gap: 11px; }
.tlx .ni { display: flex; gap: 10px; }
.tlx .ni .d { font-family: var(--mono); font-size: 10px; color: var(--text-3); flex: 0 0 42px; padding-top: 1px; }
.tlx .ni .body .h { font-size: 12.5px; color: var(--text); line-height: 1.4; }
.tlx .ni .body .s { font-size: 10.5px; color: var(--text-3); margin-top: 3px; }
.tlx .morelink { font-family: var(--mono); font-size: 11px; color: var(--accent-text); font-weight: 600; }

/* --- Market Pulse: "+N more" expands IN PLACE (sources / news) ------------- */
/* A native <details>: the <summary> IS the "+N more" control (styled like the
   .more2 / .morelink it replaces); clicking it reveals the hidden items in a
   capped-height scroll region (no navigation, no JS). The cap keeps the card
   footprint bounded so the grid stays stable; the user scrolls within the
   region to read the rest. Clicking the summary again collapses it. */
.tlx details.more { display: inline; }
.tlx details.more.more-news { display: block; margin-top: 2px; }
.tlx details.more > summary {
  display: inline-flex; align-items: center; gap: 4px; cursor: pointer;
  list-style: none; -webkit-user-select: none; user-select: none;
}
.tlx details.more > summary::-webkit-details-marker { display: none; }
/* Caret affordance that flips on open (the collapse signal). */
.tlx details.more > summary::after {
  content: ""; width: 5px; height: 5px; opacity: .75; margin-left: 1px;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg); transition: transform .15s ease;
}
.tlx details.more[open] > summary::after { transform: rotate(-135deg); }
.tlx details.more .more-list {
  max-height: 132px; overflow-y: auto; margin-top: 8px;
  font-size: 12px; color: var(--text-3); line-height: 1.55;
}
.tlx details.more .more-list.news { display: flex; flex-direction: column; gap: 11px; }

/* --- Market Pulse: "List all N calls" — every call as direction · firm ------ */
/* One call = a small bias arrow + the calling firm. Inline for a single call
   (sits after "Total 1 call ·"); a flex column inside the expanded list so each
   call reads on its own line, in the same bull→neutral→bear order as the marks. */
.tlx .prov .call { display: inline-flex; align-items: baseline; gap: 5px; }
.tlx .prov .call i { font-size: 12px; transform: translateY(1px); }
.tlx .prov .call .nm { color: var(--text-2); }
.tlx details.more .more-list.calls { display: flex; flex-direction: column; gap: 7px; }

/* --- Market Pulse: article headline links out (new tab + external glyph) --- */
.tlx .hl { color: inherit; text-decoration: none; }
.tlx .hl:hover { text-decoration: underline; text-underline-offset: 2px; }
.tlx .hl .hl-ico { font-size: 11px; margin-left: 4px; color: var(--text-3); vertical-align: baseline; }
.tlx .hl:hover .hl-ico { color: var(--accent-text); }

/* --- Bias arrow legend (first appearance, §4) ----------------------------- */
.tlx .bias-legend { display: inline-flex; align-items: center; gap: 12px; font-size: 11px; color: var(--text-3); }
.tlx .bias-legend i { font-size: 13px; vertical-align: middle; }
.tlx .bias-up { color: var(--green); }
.tlx .bias-down { color: var(--red); }
.tlx .bias-flat { color: var(--text-2); }
/* Consensus half of the legend: the §7 mark glyphs (+ • −), mono and coloured to
   match the live cells via the shared `.bull/.neu/.bear` colour classes. A muted
   hairline divides the two legend groups (Bias | Consensus). */
.tlx .cons-legend .mk { font-family: var(--mono); font-weight: 400; font-size: 13px; }
.tlx .legend-sep { width: 1px; height: 12px; background: var(--border); margin: 0 14px; align-self: center; }

/* --- ApexQQuant status strip (§6) ----------------------------------------- */
.tlx .status {
  display: flex; align-items: center; gap: 14px;
  border: 1px solid var(--border); border-left: 2.5px solid var(--accent);
  border-radius: 11px; background: var(--surface);
  padding: 14px 18px; margin-bottom: 22px; flex-wrap: wrap;
}
.tlx .status .id { font-family: var(--display); font-weight: 600; font-size: 14px; color: var(--text); }
.tlx .status .desc { font-size: 12px; color: var(--text-2); margin-left: 6px; }
.tlx .status .desc b { color: var(--text); font-weight: 500; }
.tlx .chips { display: flex; gap: 6px; flex-wrap: wrap; }
.tlx .chip {
  font-family: var(--mono); font-size: 9px; letter-spacing: .06em; font-weight: 600;
  border-radius: 5px; padding: 3px 8px; text-transform: uppercase;
}
.tlx .chip.paper { background: var(--amber-soft); color: var(--amber); }
.tlx .chip.ro { border: 1px solid var(--border); background: var(--surface-2); color: var(--text-2); }
.tlx .chip.cash { background: var(--accent-soft); color: var(--accent-text); }

/* --- Responsive: collapse the 3-up card grid on narrow viewports ---------- */
@media (max-width: 900px) {
  .tlx .grid { grid-template-columns: 1fr; }
}

/* ===========================================================================
   Brief 01 — Market Pulse page specifics. Scoped under .tlx, token-only.
   The foundation `.ddl` was authored as a static mock span; the live page needs
   functional <select>s, a control-row actions group beside the sub-tabs, and a
   mixed numeric/text table (the foundation `.tbl` is right-aligned by default).
   =========================================================================== */

/* Control row: coverage stats + Refresh sit to the right of the view sub-tabs. */
.tlx .vtabs .right { margin-left: auto; display: inline-flex; align-items: center; gap: 14px; }
.tlx .hstats { font-family: var(--mono); font-size: 11px; color: var(--text-3); }
.tlx .hstats b { color: var(--text-2); font-weight: 500; }

/* A real <select> wrapped in `.ddl`: strip the native chrome so the box styling
   and the Phosphor caret read as one control (the wrapper supplies border/bg). */
.tlx .ddl > select {
  appearance: none; -webkit-appearance: none; -moz-appearance: none;
  border: 0; background: transparent; color: var(--text); cursor: pointer;
  font-family: var(--body); font-size: 12.5px; font-weight: 500; outline: none; padding: 0;
}
/* Native <option> popup (F1 Issue A): the OS-drawn option list ignores the
   `.ddl` wrapper bg, so the rows render text-on-same-colour and read as
   INVISIBLE until the cursor highlights one. Set BOTH background + text colour
   EXPLICITLY (token-based) so they're readable in BOTH dark and light themes;
   flag the selected/hovered row with the accent tint. Fixing this also makes
   the date control visibly open (F1 Issue B — same root cause). */
.tlx .ddl > select option {
  background-color: var(--surface);
  color: var(--text);
}
.tlx .ddl > select option:checked,
.tlx .ddl > select option:hover {
  background-color: var(--accent-soft);
  color: var(--text);
}

/* Mixed numeric/text table: per-column alignment + a body-font text cell + a
   single-line clip (the default `.tbl` cell is mono + right-aligned). */
.tlx .tbl th.l, .tlx .tbl td.l { text-align: left; }
.tlx .tbl th.c, .tlx .tbl td.c { text-align: center; }
/* Fully left-aligned variant (`class="tbl tbl-left"`) — overrides the default
   right-alignment for every header + cell, including `.num` ones; numbers keep
   their mono + tabular-nums for clean digit columns, just flush-left. Used by the
   IA / EOD option-strategies descriptor table, and the F&O OI chain (the
   `table.data` variant below — same flush-left treatment for a `.data` table). */
.tlx .tbl.tbl-left thead th,
.tlx .tbl.tbl-left tbody td,
.tlx table.data.tbl-left thead th,
.tlx table.data.tbl-left tbody td { text-align: left; }
/* IA Cash also drops the mono-semibold symbol weight — the left-aligned variant
   renders a plain, uniform-weight body (the strategies table has no `.sym` cells,
   so it is unaffected). */
.tlx .tbl.tbl-left .sym { font-weight: var(--weight-normal); }
.tlx .tbl td.txt { font-family: var(--body); font-variant-numeric: normal; color: var(--text-2); }
.tlx .tbl .clip { display: inline-block; max-width: 280px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; }

/* Right-aligned bias legend sitting just above a table. */
.tlx .legend-row { display: flex; justify-content: flex-end; margin-bottom: 8px; }

/* ===========================================================================
   Brief 06 / E1 — Zero Point (authed home, GET /) page surface. Scoped under
   .tlx, token-only (master §2). Relocated here from the page's inline
   <style> (brief E1): a per-page <style> in head_extra is dropped on hx-boost
   in-app navigation (body-only swap discards the incoming <head>), leaving the
   page naked; rules in components.css load via the persistent <head> <link>
   and survive boosted swaps — the same pattern the ON pages already use.
   Collision-renamed vs the Market Pulse card classes: .news -> .whatsnew,
   .ni -> .wn-item, .tg -> .wn-tag. .pos/.neg reuse the green/red direction
   colours already defined under .tlx.
   =========================================================================== */

/* greeting identity (bespoke — not the mono-uppercase page_header) */
.tlx .hello { display:flex; align-items:baseline; gap:12px; flex-wrap:wrap; margin-bottom:4px; }
.tlx .hello h1 { font-size:22px; font-weight:700; letter-spacing:-.02em; margin:0; color:var(--text); }
.tlx .hello .gmeta { font-family:var(--mono); font-size:11px; color:var(--text-3); }
.tlx .hello .dot { color:var(--border); }
.tlx .sub { font-size:12.5px; color:var(--text-3); margin-bottom:20px; }

.tlx .zp-eyebrow { font-family:var(--mono); font-size:10px; letter-spacing:.1em; text-transform:uppercase; color:var(--text-3); font-weight:600; margin:0 0 11px; }

/* market hero — two live panels: index strip · street-lean dial. (Sector breadth ·
   advance % was relocated into the Intraday dashboard row beside the intraday lines.)
   The column ratio + gap MATCH .zp-charts below so the two stacked rows form one
   aligned 2x2 grid (the four Market-read / Intraday boxes share L/R edges). Each
   panel wears the same .card-head header as the .dash-panel charts, so all four
   read as one component family. align-items:stretch (matching .zp-charts below,
   which defaults to it) makes the shorter Indices box grow to the taller Street
   lean box, so their bottom edges line up and the 2x2 grid reads square. */
.tlx .hero { display:grid; grid-template-columns:1.6fr 1fr; gap:16px; margin-bottom:26px; align-items:stretch; }
.tlx .panel { border:1px solid var(--border); border-radius:11px; background:var(--surface); }
.tlx .panel .panel-body { padding:16px; }
.tlx .idxgrid { display:grid; grid-template-columns:1fr 1fr; gap:12px; }
/* Indices card: the 2x2 tile grid fills the panel so its tiles meet the card edges
   (the panel is stretched to the Street-lean height by the .hero align-items:stretch).
   Scoped to .idx-panel so the Street-lean panel keeps its natural block flow. */
.tlx .idx-panel { display:flex; flex-direction:column; }
.tlx .idx-panel .panel-body { flex:1 1 auto; min-height:0; display:flex; flex-direction:column; }
.tlx .idx-panel .idxgrid { flex:1 1 auto; grid-template-rows:1fr 1fr; }
.tlx .idx { border:1px solid var(--border-2); border-radius:10px; background:var(--surface-2); padding:12px 13px; display:flex; flex-direction:column; min-height:0; }
.tlx .idx .nm { font-family:var(--mono); font-size:9.5px; letter-spacing:.06em; color:var(--text-3); font-weight:600; }
.tlx .idx .val { font-family:var(--mono); font-size:19px; font-weight:600; letter-spacing:-.01em; margin-top:6px; line-height:1; color:var(--text); }
.tlx .idx .chg { font-family:var(--mono); font-size:11.5px; font-weight:600; margin-top:5px; display:inline-flex; align-items:center; gap:4px; color:var(--text-2); }
.tlx .idx .chg i { font-size:12px; }
/* Intraday sparkline: grows to fill the tile's remaining height; the SVG viewBox is
   stretched horizontally (preserveAspectRatio="none") with a non-scaling stroke so the
   line stays crisp. Coloured by the tile's day direction (green up / red down). */
.tlx .idx .idx-spark { flex:1 1 auto; min-height:30px; margin-top:11px; }
.tlx .idx .idx-spark svg { display:block; width:100%; height:100%; }
.tlx .idx .idx-spark .line { fill:none; stroke:var(--text-3); stroke-width:1.5; stroke-linejoin:round; stroke-linecap:round; }
.tlx .idx .idx-spark .area { fill:var(--text-3); opacity:.10; stroke:none; }
.tlx .idx .idx-spark.up .line { stroke:var(--green); }
.tlx .idx .idx-spark.up .area { fill:var(--green); }
.tlx .idx .idx-spark.down .line { stroke:var(--red); }
.tlx .idx .idx-spark.down .area { fill:var(--red); }
.tlx .closetag { font-family:var(--mono); font-size:10px; color:var(--text-3); margin-top:13px; text-align:right; }
/* Indices empty state reuses the shared .dash-empty shell (the same look the
   "Sector breadth · intraday" panel shows when empty) — see markup in dashboard.html. */

/* sector breadth · advance % (Intraday dashboard row) — reuses the .apex-sec-* bar
   list; cap the height so the tall sector list doesn't unbalance the row beside the
   intraday chart (scrolls past the cap). */
.tlx .zp-secbars { max-height:316px; overflow-y:auto; padding-right:3px; }
/* GREYSCALE bars (breadth polish) — SCOPED to .zp-secbars so the ApexQQuant
   dashboard's green/red .apex-sec-* bars are untouched. The fill is the theme --text
   base (flips light/dark); per-bar `opacity` (inline, from the shared sector shade)
   is its identity, matching the intraday line + legend swatch. No adv/dec hue here —
   the % value + bar length carry direction (design-system pull-to-neutral). */
.tlx .zp-secbars .apex-sec-fill { background:var(--text); }
/* Member-count label: widen the name column and split it into an ellipsised name +
   an always-visible (N) count, so two equal-% rows read apart and sector size shows. */
.tlx .zp-secbars .apex-sec-row { grid-template-columns:152px 1fr 38px; }
.tlx .zp-secbars .apex-sec-label { display:flex; align-items:baseline; gap:4px; min-width:0; }
.tlx .zp-secbars .apex-sec-name { min-width:0; }
.tlx .zp-secbars .zp-secn { flex:0 0 auto; font-family:var(--mono); font-size:10px; color:var(--text-3); }
/* Bars-only variant (the narrow advance-% panel in the 3-up breadth row): drop the
   name label + % text so only the bars show; the sector name / count / % live in the
   row's hover title (native tooltip). The track then spans the full row width. */
.tlx .zp-secbars-bare .apex-sec-row { grid-template-columns:1fr; }
.tlx .zp-secbars-bare .apex-sec-label,
.tlx .zp-secbars-bare .apex-sec-pct { display:none; }

/* street lean — needle dial with three coloured zone arcs (bearish red · neutral
   grey · bullish green). The arc strokes use literal hex, not theme tokens: an SVG
   stroke does not inherit CSS custom properties reliably, and the zones must read
   identically in both themes (the same precedent the OI/PCR chart lines follow).
   The amber needle is rotated server-side by the net (bull − bear) tilt; the hub
   stays theme-grey so it flips. Zone labels are colour-keyed to their arc. */
.tlx .zp-dial { padding:2px 0 0; }
/* Street-lean dial + read + keys sit a touch lower in the panel (small vertical nudge). */
.tlx .lean .zp-dial { margin-top:16px; }
.tlx .zp-dial-svg { width:100%; max-width:236px; height:auto; display:block; margin:0 auto; }
.tlx .zp-dial-zone { fill:none; stroke-width:13; stroke-linecap:butt; }
.tlx .zp-dial-zone.bear { stroke:#EF4444; }
.tlx .zp-dial-zone.neut { stroke:#6B7280; }
.tlx .zp-dial-zone.bull { stroke:#22C55E; }
.tlx .zp-dial-needle { fill:#F59E0B; }
.tlx .zp-dial-hub { fill:var(--text); stroke:var(--surface); stroke-width:2.5; }
.tlx .zp-dial-scale { display:flex; justify-content:space-between; max-width:236px; margin:5px auto 0; font-family:var(--mono); font-size:10px; font-weight:600; letter-spacing:.04em; text-transform:uppercase; }
.tlx .zp-dial-scale .bear { color:#EF4444; }
.tlx .zp-dial-scale .neut { color:var(--text-3); }
.tlx .zp-dial-scale .bull { color:#22C55E; }
.tlx .zp-dial-read { text-align:center; margin:9px 0 14px; }
.tlx .zp-dial-read strong { font-family:var(--mono); font-size:23px; font-weight:700; color:var(--text); letter-spacing:-.01em; }
.tlx .zp-dial-read span { display:block; font-family:var(--mono); font-size:9.5px; letter-spacing:.04em; text-transform:uppercase; color:var(--text-3); margin-top:3px; }

.tlx .leankeys { display:flex; flex-direction:column; gap:8px; }
.tlx .leankey { display:flex; align-items:center; gap:9px; font-size:12.5px; }
.tlx .leankey .sw { width:9px; height:9px; border-radius:3px; flex:0 0 9px; }
.tlx .leankey .lab { color:var(--text-2); }
.tlx .leankey .n { font-family:var(--mono); font-weight:600; margin-left:auto; color:var(--text-2); }
.tlx .leanfoot { margin-top:13px; padding-top:12px; border-top:1px solid var(--border-2); display:flex; align-items:center; }
.tlx .leanfoot a { font-family:var(--mono); font-size:11.5px; color:var(--accent-text); font-weight:600; display:inline-flex; align-items:center; gap:5px; }
.tlx .leanfoot a i { font-size:13px; }
.tlx .leanfoot .cover { font-family:var(--mono); font-size:11px; color:var(--text-3); margin-left:auto; }
.tlx .lean-empty { font-size:12px; color:var(--text-3); padding:18px 4px; line-height:1.5; }

/* what's new */
.tlx .whatsnew { border:1px solid var(--border); border-radius:12px; background:var(--surface); overflow:hidden; }
.tlx .wn-item { display:flex; align-items:center; gap:12px; padding:12px 16px; border-bottom:1px solid var(--border-2); }
.tlx .wn-item:last-child { border-bottom:0; }
.tlx .wn-tag { font-family:var(--mono); font-size:9px; letter-spacing:.04em; text-transform:uppercase; font-weight:600; border-radius:5px; padding:3px 8px; flex:0 0 auto; }
.tlx .wn-tag.new { background:var(--green-soft); color:var(--green); }
.tlx .wn-tag.upd { background:var(--accent-soft); color:var(--accent-text); }
.tlx .wn-text { font-size:12.5px; color:var(--text-2); }
.tlx .wn-date { margin-left:auto; font-family:var(--mono); font-size:10.5px; color:var(--text-3); }

/* responsive: hero stacks at the SAME 980px breakpoint as .zp-charts below, so the
   two rows collapse together and never sit half-aligned (one 2-col, one stacked). */
@media (max-width:980px) {
  .tlx .hero { grid-template-columns:1fr; }
  .tlx .zp-secbars { max-height:none; }
}

/* ---------------------------------------------------------------------------
   Zero Point dashboards — stacked sections share the .zp-card grid:
   INTRADAY DASHBOARD (.zp-cards.zp-today, the live market-clock card), then
   CASH MARKET (5 DAYS) (.zp-cards summary tiles + group/sector charts) and
   F&O MARKET (5 DAYS) (.zp-cards, four OI/PCR average cards) + the 5-day
   OI/breadth bars + PCR trend. Additive to
   the brief-06 home surface; token-only, scoped under .tlx. The four OI/PCR cards
   show the retained 5-day EOD average as honest context (live "today" capture is
   pending and is never fabricated). The OI bars use a theme-token grey ramp (so the
   greys stay legible in both themes); the overlaid % advancing / PCR lines keep
   literal hex (the established chart precedent for a vivid single accent).
   Theme-driven strokes/text use .zp-gl / .zp-axt / .zp-barval so they flip.
   The DAILY AVERAGE grid is 4-up; .zp-today is 2-up so the two live cards line up
   above the two half-width .zp-bubbles panels. */
.tlx .zp-cards { display:grid; grid-template-columns:repeat(4,1fr); gap:12px; margin-bottom:18px; }
.tlx .zp-cards.zp-today { grid-template-columns:repeat(2,1fr); }
.tlx .zp-card { border:1px solid var(--border); border-radius:12px; background:var(--surface); padding:13px 14px; display:flex; flex-direction:column; gap:6px; min-width:0; }
.tlx .zp-card .k { font-family:var(--mono); font-size:9.5px; letter-spacing:.05em; text-transform:uppercase; color:var(--text-3); font-weight:600; display:flex; align-items:center; gap:6px; }
.tlx .zp-card .v { font-family:var(--mono); font-size:20px; font-weight:600; letter-spacing:-.01em; line-height:1.05; color:var(--text); }
.tlx .zp-card .v.zp-na { color:var(--text-3); }
.tlx .zp-card .s { font-family:var(--mono); font-size:10.5px; color:var(--text-3); line-height:1.4; }
.tlx .zp-tag { font-family:var(--mono); font-size:8px; letter-spacing:.04em; text-transform:uppercase; font-weight:600; color:var(--text-3); border:1px solid var(--border-2); border-radius:5px; padding:1px 5px; }
.tlx .zp-prog { height:5px; border-radius:3px; background:var(--surface-2); overflow:hidden; }
.tlx .zp-prog > i { display:block; height:100%; background:linear-gradient(90deg,var(--accent),var(--accent-text)); border-radius:3px; }
.tlx .zp-ad { display:flex; align-items:center; gap:7px; font-size:17px; }
.tlx .zp-ad .up { color:var(--green); display:inline-flex; align-items:center; gap:3px; }
.tlx .zp-ad .down { color:var(--red); display:inline-flex; align-items:center; gap:3px; }
.tlx .zp-ad .up i, .tlx .zp-ad .down i { font-size:13px; }
.tlx .zp-ad .sl { color:var(--border); }

/* Sector-breadth row — the three breadth panels side by side on one baseline:
   5-day average · intraday · advance-% bars. The two outer panels are narrow and the
   middle intraday chart (a full-session time series) gets the extra width. align-items
   defaults to stretch, so all three panels grow to the tallest and their tops/middles
   line up. (This row no longer mirrors the .hero 1.6fr/1fr split above it — that L/R
   alignment was traded for the three-up breadth layout.) */
.tlx .zp-charts { display:grid; grid-template-columns:1fr 1.6fr 1fr; gap:16px; margin-bottom:16px; }
/* .zp-pair: a two-panel .zp-charts row (5-day OI bars + PCR trend) — equal halves,
   not the 3-up 1fr/1.6fr/1fr breadth split, so neither chart is starved and no
   empty third column trails on the right. */
.tlx .zp-charts.zp-pair { grid-template-columns:1fr 1fr; }
.tlx .zp-chart-wrap { padding:12px 14px 4px; }
.tlx .zp-chart-wrap svg { width:100%; height:200px; display:block; }
.tlx .zp-gl { stroke:var(--border-2); stroke-width:1; }
.tlx .zp-axt { fill:var(--text-3); font-family:var(--mono); font-size:9px; }
/* 5-day OI bars — grey ramp via theme tokens (dark-on-light / light-on-dark, so
   the greys stay legible in both themes). The value prints inside each bar,
   rotated 90deg anticlockwise; .out floats it just above a too-short bar. */
.tlx .zp-bar-fut { fill:var(--text); }
.tlx .zp-bar-pe  { fill:var(--text-2); }
.tlx .zp-bar-ce  { fill:var(--text-3); }
.tlx .zp-barval { fill:var(--surface); font-family:var(--mono); font-size:8.5px; font-weight:600; letter-spacing:.02em; dominant-baseline:central; }
.tlx .zp-barval.out { fill:var(--text-2); }
.tlx .zp-advlab { fill:var(--text-2); font-weight:600; }
.tlx .zp-legend { display:flex; flex-wrap:wrap; gap:8px 16px; padding:4px 16px 14px; font-family:var(--mono); font-size:10.5px; color:var(--text-2); }
.tlx .zp-legend .lg { display:inline-flex; align-items:center; gap:6px; }
.tlx .zp-legend .lg i { width:11px; height:11px; border-radius:3px; display:inline-block; }
.tlx .zp-legend .lg i.ln { height:3px; border-radius:2px; }

/* Cash-market charts — the two group panels (delivery vs turnover, win:loss) sit
   side-by-side; the date-wise sector mini-trends span full width below them
   (.zp-gspan). BARS stay a greyscale ramp (A darkest -> C lightest, like the 5-day
   OI bars); the per-group % LINES get a literal-hex colour (set in JS) so the three
   read apart. Gridlines, axis text and the parity reference flip with the theme via
   .zp-gl / .zp-axt / .zp-parity. */
.tlx .zp-gcharts { display:grid; grid-template-columns:1fr 1fr; gap:16px; margin-bottom:26px; }
.tlx .zp-gcharts .zp-chart-wrap svg { height:230px; }
.tlx .zp-gspan { grid-column:1 / -1; }
.tlx .zp-parity { stroke:var(--text-3); stroke-width:1; stroke-dasharray:3 3; opacity:.6; }
/* Intraday sector-breadth lines — greyscale over the theme --text base (flips
   light/dark). TWO per-line channels, both set in JS: stroke-WIDTH = member-stock
   count (bigger = bolder) and stroke-OPACITY = the sector's shared identity shade
   (see zero_point._sector_shade), which matches its advance-% bar (Chart B) and its
   hover-tooltip swatch. */
/* Fill the panel's (grid-stretched) height so the x-axis sits near the box's bottom
   edge rather than floating above dead space; min-height keeps the prior floor when
   the panel isn't stretched. The TOP gap is unchanged — padT is fixed in JS, so only
   plotH grows downward. (Panel flex + wrap flex:1 give the SVG a definite height.) */
/* Both line charts flex-fill their panel so, side by side in the breadth row, their
   plot areas share the same height and baseline. */
.tlx #zp-sec-intraday, .tlx #zp-sec-daily { height:100%; min-height:264px; }
/* Axis titles ("%", "Time ->") read a shade stronger than the grey tick numbers. */
.tlx #zp-sec-intraday .zp-axttl, .tlx #zp-sec-daily .zp-axttl { fill:var(--text-2); font-weight:600; }
/* 15-minute x-axis interval dots — faint markers on the baseline, no labels. */
.tlx #zp-sec-intraday .zp-xtick { fill:var(--text-3); opacity:.5; }
.tlx .zp-secline { stroke:var(--text); fill:none; stroke-linejoin:round; stroke-linecap:round; transition:stroke-opacity .08s linear; }
/* Per-day node dot on the 5-day lines (fill-opacity = the sector's shade, set inline)
   so a sector present on a single session still shows a mark, not an invisible path. */
.tlx .zp-secdot { fill:var(--text); }
/* Fat transparent hit-path laid over each thin line so hover is easy to land;
   pointer-events:stroke captures the perimeter regardless of the transparent paint. */
.tlx .zp-secline-hit { fill:none; stroke:transparent; pointer-events:stroke; cursor:pointer; }
/* Floating hover tooltip (sector name + member count) — a lightweight positioned div
   in the chart wrap (not a library component); theme tokens so it flips light/dark. */
.tlx #zp-sec-intraday-panel, .tlx #zp-sec-daily-panel { display:flex; flex-direction:column; }
.tlx #zp-sec-intraday-panel .zp-chart-wrap,
.tlx #zp-sec-daily-panel .zp-chart-wrap { position:relative; flex:1 1 auto; }
.tlx .zp-secline-tip { position:absolute; z-index:6; pointer-events:none; display:none;
  background:var(--surface); border:1px solid var(--border); border-radius:6px;
  padding:4px 9px; font-family:var(--mono); font-size:10.5px; line-height:1.3;
  color:var(--text); white-space:nowrap; box-shadow:0 3px 10px rgba(0,0,0,.22); }
.tlx .zp-secline-tip i.ln { display:inline-block; width:12px; height:3px; border-radius:2px;
  margin-right:7px; vertical-align:middle; }
/* Group A/B/C greyscale BAR ramp (darkest -> lightest = A -> C). The % lines are
   coloured inline in JS, not here. */
.tlx .zp-gbar-a { fill:var(--text); }
.tlx .zp-gbar-b { fill:var(--text-2); }
.tlx .zp-gbar-c { fill:var(--text-3); }
/* Delivery-vs-turnover bars carry an edge in their GROUP colour — the same hex as
   that group's % line (A blue · B amber · C green, matching ZP_GROUPS in JS) — so
   each grey bar is tied to its line. The faded turnover bar (fill-opacity 0.3) reads
   as a crisp coloured outline around the solid delivery bar inside it (the stroke
   stays full-opacity — fill-opacity dims only the fill). Scoped to that chart so the
   win:loss bars are unaffected. */
.tlx #zp-grp-deliv .zp-gbar-a { stroke:#3B82F6; stroke-width:1; }
.tlx #zp-grp-deliv .zp-gbar-b { stroke:#F59E0B; stroke-width:1; }
.tlx #zp-grp-deliv .zp-gbar-c { stroke:#10B981; stroke-width:1; }

/* Date-wise sector mini-trends (small multiples) — one auto-scaled panel per
   NIFTY-500 sector: greyscale delivery-inside-turnover bars over the 5 days
   (turnover via .zp-bar-ce, delivery via .zp-bar-fut) + a coloured win:loss line.
   The grid flows the ~10 panels into rows; each panel is scaled to its own turnover. */
.tlx .zp-trend-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(150px,1fr)); gap:12px 14px; padding:8px 16px 12px; }
.tlx .zp-trend-cell { border:1px solid var(--border); border-radius:9px; background:var(--surface); padding:8px 9px 5px; min-width:0; }
.tlx .zp-trend-nm { font-family:var(--mono); font-size:10px; font-weight:600; color:var(--text-2); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; margin:0 0 3px; }
.tlx .zp-trend-svg { width:100%; height:64px; display:block; }
.tlx .zp-trend-tick { font-size:7px; }

@media (max-width:980px) {
  .tlx .zp-cards { grid-template-columns:repeat(2,1fr); }
  .tlx .zp-charts, .tlx .zp-charts.zp-pair, .tlx .zp-gcharts { grid-template-columns:1fr; }
}
@media (max-width:560px) {
  .tlx .zp-cards, .tlx .zp-cards.zp-today { grid-template-columns:1fr; }
}

/* ===========================================================================
   Brief 05 / E2 — EOD Dashboard (workspace/dashboard.html) page surface.
   Scoped under .tlx, token-only (master §2). Relocated here from the page's
   inline <style> (brief E2): a per-page <style> in head_extra is dropped on
   hx-boost in-app navigation (body-only swap discards the incoming <head>),
   leaving the page naked when navigated INTO from another page; rules in
   components.css load via the persistent <head> <link> and survive boosted
   swaps — the same pattern the ON pages already use.
   Collision resolved: the page's .panel clashed with the Zero Point .panel
   above (different radius/padding) — renamed here to .dash-panel (markup too).
   .ddl and .meta REUSE the shared filter/meta components above; the page's
   .cmp-head .ddl and .card-head .meta are scoped overrides that win by
   specificity (compatible — no rename).
   =========================================================================== */

/* OI / level data tokens (derived from the §2 direction tokens so they flip
   with the theme; color-mix gives the translucent OI fills with a --*-soft
   fallback for browsers without color-mix). */
.tlx {
  --ce: var(--red-soft);
  --ce: color-mix(in srgb, var(--red) 42%, transparent);
  --pe: var(--green-soft);
  --pe: color-mix(in srgb, var(--green) 42%, transparent);
  --lvl-r: var(--red);
  --lvl-s: var(--green);
  --lvl-mp: var(--amber);
}

.tlx .num { font-family: var(--mono); font-variant-numeric: tabular-nums; text-align: right; }

/* --- Control row: ptabs + symbol jump + interval seg ---------------------- */
.tlx .dash-ctrl { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 14px; }
.tlx .dash-ctrl .ptabs { margin-bottom: 0; }
.tlx .dash-ctrl-right { margin-left: auto; display: inline-flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.tlx .dash-jump { flex: 0 0 auto; min-width: 200px; }
.tlx .seg { display: inline-flex; gap: 2px; background: var(--surface-2); border: 1px solid var(--border); border-radius: 9px; padding: 3px; }
.tlx .seg button {
  border: 0; background: transparent; color: var(--text-2);
  padding: 6px 14px; border-radius: 6px; font-weight: 600; font-size: 12px;
  font-family: var(--mono); letter-spacing: .02em; cursor: pointer;
}
.tlx .seg button.on { background: var(--accent-soft); color: var(--accent-text); box-shadow: inset 0 0 0 1px var(--accent-soft); }

/* --- Symbol identity strip + preview note --------------------------------- */
.tlx .sym-head { display: flex; align-items: center; gap: 16px; margin-bottom: 6px; flex-wrap: wrap; }
.tlx .sym-id { display: flex; align-items: baseline; gap: 12px; }
.tlx .sym-id .t { font-family: var(--mono); font-weight: 700; font-size: 24px; letter-spacing: -.01em; color: var(--text); }
.tlx .sym-id .n { color: var(--text-2); font-size: 13.5px; }
.tlx .sym-px { display: flex; align-items: baseline; gap: 10px; }
.tlx .sym-px .p { font-family: var(--mono); font-size: 20px; font-weight: 600; color: var(--text); }
.tlx .sym-px .c { font-family: var(--mono); font-size: 13px; font-weight: 600; display: inline-flex; align-items: center; gap: 4px; }
.tlx .kind { font-family: var(--mono); font-size: 10px; font-weight: 600; letter-spacing: .06em; padding: 3px 8px; border-radius: 6px; background: var(--accent-soft); color: var(--accent-text); }
.tlx .asof { font-family: var(--mono); font-size: 11px; color: var(--text-3); }
.tlx .preview-note { font-family: var(--mono); font-size: 11px; color: var(--text-3); margin: 0 0 16px; display: inline-flex; align-items: center; gap: 6px; }
.tlx .preview-note i { font-size: 13px; color: var(--amber); }

/* --- Signal row ----------------------------------------------------------- */
.tlx .signal { display: grid; grid-template-columns: repeat(5, 1fr) 1.6fr; gap: 1px; background: var(--border-2); border: 1px solid var(--border); border-radius: 11px; overflow: hidden; margin-bottom: 18px; }
.tlx .sig { background: var(--surface); padding: 13px 15px; display: flex; flex-direction: column; gap: 7px; }
.tlx .sig .k { font-size: 10px; letter-spacing: .06em; text-transform: uppercase; color: var(--text-3); font-weight: 600; }
.tlx .sig .v { font-size: 14px; font-weight: 600; font-family: var(--display); display: inline-flex; align-items: center; gap: 6px; }
.tlx .sig.hero { background: linear-gradient(180deg, var(--accent-soft), transparent); }
/* 4-tile strip (F&O Options summary): override the 6-col Dashboard layout. */
.tlx .signal.signal-4 { grid-template-columns: repeat(4, 1fr); }
.tlx .score { display: flex; align-items: baseline; gap: 8px; }
.tlx .score .big { font-family: var(--mono); font-size: 24px; font-weight: 700; color: var(--accent-text); }
.tlx .score .of { font-size: 11px; color: var(--text-3); }
.tlx .bar { height: 5px; border-radius: 3px; background: var(--surface-2); overflow: hidden; }
.tlx .bar > i { display: block; height: 100%; background: linear-gradient(90deg, var(--accent), var(--accent-text)); }
.tlx .stratchips { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.tlx .sc { font-family: var(--mono); font-size: 11px; font-weight: 600; border-radius: 6px; padding: 3px 9px; background: var(--accent-soft); color: var(--accent-text); display: inline-flex; align-items: center; gap: 4px; }

/* --- Signal badges -------------------------------------------------------- */
.tlx .badge { display: inline-flex; align-items: center; gap: 5px; font-family: var(--mono); font-size: 11px; font-weight: 600; letter-spacing: .04em; padding: 3px 9px; border-radius: 6px; }
.tlx .badge i { font-size: 12px; }
.tlx .b-bull { background: var(--green-soft); color: var(--green); }
.tlx .b-bear { background: var(--red-soft); color: var(--red); }
.tlx .b-up { background: var(--accent-soft); color: var(--accent-text); }
.tlx .b-neu { background: var(--surface-2); color: var(--text-2); }

/* --- Tab panels ----------------------------------------------------------- */
.tlx .tab { display: none; }
.tlx .tab.on { display: block; }

/* --- Section labels + panels ---------------------------------------------- */
.tlx .section-label { display: flex; align-items: center; gap: 10px; margin: 4px 0 12px; }
.tlx .section-label span { font-family: var(--mono); font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--text-3); font-weight: 600; }
.tlx .section-label .nm { color: var(--accent-text); letter-spacing: .1em; }
.tlx .section-label .ln { flex: 1; height: 1px; background: var(--border-2); }
.tlx .dash-panel { background: var(--surface); border: 1px solid var(--border); border-radius: 11px; }
.tlx .dash-panel h3, .tlx .panel .card-head h3 { font-family: var(--display); font-weight: 600; font-size: 13px; margin: 0; color: var(--text); }
.tlx .card-head { display: flex; align-items: center; justify-content: space-between; padding: 12px 16px; border-bottom: 1px solid var(--border); flex-wrap: wrap; gap: 8px; }
.tlx .card-head .meta { font-family: var(--mono); font-size: 11px; color: var(--text-3); padding: 0; display: inline; }

/* --- Candle / line chart -------------------------------------------------- */
.tlx .chart { padding: 10px 14px; }
.tlx .chart .gl { stroke: var(--border-2); stroke-width: 1; }
.tlx .ema21 { stroke: var(--accent-text); fill: none; stroke-width: 1.5; }
.tlx .ema50 { stroke: var(--amber); fill: none; stroke-width: 1.3; opacity: .85; }
.tlx .chart-legend { display: flex; gap: 14px; padding: 0 16px 12px; font-family: var(--mono); font-size: 10.5px; color: var(--text-3); flex-wrap: wrap; }
.tlx .chart-legend i { display: inline-block; width: 14px; height: 2px; vertical-align: middle; margin-right: 5px; }

/* --- Chart-Duo ------------------------------------------------------------ */
.tlx .charts-2col { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 16px; }
.tlx .cmp-head { display: flex; align-items: center; gap: 10px; padding: 12px 16px; border-bottom: 1px solid var(--border); flex-wrap: wrap; }
.tlx .cmp-head .name { font-family: var(--display); font-weight: 600; font-size: 13px; }
.tlx .cmp-head .tagn { font-family: var(--mono); font-size: 9px; letter-spacing: .08em; color: var(--text-3); border: 1px solid var(--border-2); border-radius: 5px; padding: 2px 6px; text-transform: uppercase; }
.tlx .cmp-head .ddl { padding: 6px 11px; }
.tlx .cmp-head .ddl .dot { width: 8px; height: 8px; border-radius: 2px; display: inline-block; }
.tlx .series { display: flex; gap: 6px; flex-wrap: wrap; padding: 10px 16px; border-bottom: 1px solid var(--border-2); align-items: center; }
.tlx .series .dim { color: var(--text-3); font-family: var(--mono); font-size: 10px; }
.tlx .series .sp { display: inline-flex; align-items: center; gap: 6px; font-family: var(--mono); font-size: 11px; border: 1px solid var(--border); background: var(--surface-2); border-radius: 999px; padding: 4px 10px; color: var(--text); }
.tlx .series .sp .dot { width: 8px; height: 8px; border-radius: 2px; display: inline-block; }
.tlx .series .sp .x { color: var(--text-3); font-size: 10px; display: inline-flex; }
.tlx .series .addser { font-family: var(--mono); font-size: 11px; color: var(--accent-text); display: inline-flex; align-items: center; gap: 4px; }
.tlx .series .cnt { margin-left: auto; font-family: var(--mono); font-size: 10px; color: var(--text-3); }
.tlx .cmp-body { padding: 14px 14px 8px; }
.tlx .bars { display: flex; align-items: flex-end; gap: 4px; height: 165px; border-bottom: 1px solid var(--border-2); position: relative; }
.tlx .bars .b { flex: 1; border-radius: 3px 3px 0 0; min-width: 5px; }
.tlx .ovl { position: absolute; inset: 0; pointer-events: none; }
.tlx .bx-axis { display: flex; justify-content: space-between; font-family: var(--mono); font-size: 9px; color: var(--text-3); margin-top: 7px; }

/* --- Chart-OI ------------------------------------------------------------- */
.tlx .mig { display: flex; gap: 18px; flex-wrap: wrap; padding: 11px 16px; border-bottom: 1px solid var(--border-2); background: var(--surface-2); }
.tlx .mig .m { display: flex; flex-direction: column; gap: 2px; }
.tlx .mig .mk { font-size: 9px; letter-spacing: .05em; text-transform: uppercase; color: var(--text-3); font-weight: 600; }
.tlx .mig .mv { font-family: var(--mono); font-size: 12px; font-weight: 600; color: var(--text-2); display: inline-flex; align-items: center; gap: 4px; }
.tlx .mig .mv .cur { color: var(--text); }
.tlx .mig .ar { color: var(--text-3); font-size: 11px; display: inline-flex; }
.tlx .legend-top { display: flex; gap: 18px; justify-content: center; font-family: var(--mono); font-size: 11px; color: var(--text-2); margin: 13px 0 9px; }
.tlx .legend-top i { display: inline-block; width: 11px; height: 11px; border-radius: 2px; vertical-align: middle; margin-right: 6px; }
.tlx .oi-rows { display: flex; flex-direction: column; gap: 5px; padding: 0 16px; position: relative; max-width: 760px; margin: 0 auto; width: 100%; }
.tlx .axis-line { position: absolute; left: 50%; top: 0; bottom: 0; width: 1px; background: var(--border-2); transform: translateX(-50%); }
.tlx .oi-row { display: grid; grid-template-columns: 1fr 112px 1fr; align-items: center; gap: 8px; position: relative; }
.tlx .oi-bar-l { display: flex; justify-content: flex-end; }
.tlx .oi-bar-r { display: flex; justify-content: flex-start; }
.tlx .oi-bar-l i { height: 13px; background: var(--ce); border-radius: 3px 0 0 3px; display: block; }
.tlx .oi-bar-r i { height: 13px; background: var(--pe); border-radius: 0 3px 3px 0; display: block; }

/* Max Pain chart (F&O · Max Pain sub-tab) — server-rendered SVG pain curve.
   Muted bars, the max-pain (minimum-pain) strike highlighted in accent, a dashed
   amber current-price marker. Theme-aware via tokens (light + dark). */
.tlx .mp-chart-wrap { overflow-x: auto; margin-bottom: var(--space-3); }
.tlx .mp-chart { display: block; width: 100%; min-width: 480px; }
.tlx .mp-chart .mp-bar { fill: var(--text-3); opacity: .38; }
.tlx .mp-chart .mp-bar-min { fill: var(--accent); opacity: 1; }
.tlx .mp-chart .mp-axis { stroke: var(--border); stroke-width: 1; }
.tlx .mp-chart .mp-spot { stroke: var(--amber); stroke-width: 1.5; stroke-dasharray: 4 3; }
.tlx .mp-chart .mp-tick { fill: var(--text-3); font-family: var(--mono); font-size: 11px; }
.tlx .mp-legend { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4);
  align-items: center; font-size: var(--text-xs); color: var(--text-2); }
.tlx .mp-legend .mp-swatch { display: inline-block; width: 10px; height: 10px;
  border-radius: 2px; vertical-align: middle; margin-right: 4px; }
.tlx .mp-legend .mp-sw-min { background: var(--accent); }
.tlx .mp-legend .mp-sw-spot { background: var(--amber); }
.tlx .ctr { position: relative; display: flex; align-items: center; justify-content: center; }
.tlx .strike { font-family: var(--mono); font-size: 11px; color: var(--text-2); }
.tlx .oi-row.atm .strike { color: var(--accent-text); font-weight: 700; }
.tlx .lvl { position: absolute; left: 3px; display: flex; align-items: center; justify-content: center; width: 18px; height: 14px; }
.tlx .lvl.r, .tlx .ln.r, .tlx .legend-bot .r { color: var(--lvl-r); }
.tlx .lvl.s, .tlx .ln.s, .tlx .legend-bot .s { color: var(--lvl-s); }
.tlx .ln { width: 16px; display: inline-block; }
.tlx .ln.dbl { height: 4px; border-top: 1px solid currentColor; border-bottom: 1px solid currentColor; }
.tlx .ln.sgl { height: 0; border-top: 2px solid currentColor; }
.tlx .diamond { width: 9px; height: 9px; background: var(--lvl-mp); transform: rotate(45deg); border-radius: 1px; display: inline-block; }
.tlx .oi-axis { display: grid; grid-template-columns: 1fr 112px 1fr; font-family: var(--mono); font-size: 9.5px; color: var(--text-3); margin: 9px auto 4px; max-width: 760px; width: 100%; }
.tlx .oi-axis .oil { text-align: left; }
.tlx .oi-axis .oic { text-align: center; }
.tlx .oi-axis .oir { text-align: right; }
.tlx .legend-bot { display: flex; gap: 16px; flex-wrap: wrap; justify-content: center; padding: 13px 16px; border-top: 1px solid var(--border-2); font-family: var(--mono); font-size: 10.5px; color: var(--text-2); }
.tlx .legend-bot .lm { display: inline-flex; align-items: center; gap: 7px; }
.tlx .scrub { padding: 14px 16px; border-top: 1px solid var(--border-2); }
.tlx .scrub-top { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; flex-wrap: wrap; }
.tlx .replay-btn { display: inline-flex; align-items: center; gap: 6px; border: 1px solid var(--border); background: var(--surface-2); color: var(--text); border-radius: 7px; padding: 6px 11px; font-size: 11px; font-weight: 600; font-family: var(--mono); cursor: pointer; }
.tlx .replay-btn i { font-size: 13px; }
.tlx .scrub-date { font-family: var(--mono); font-size: 12px; color: var(--accent-text); font-weight: 600; }
.tlx .scrub-note { margin-left: auto; font-family: var(--mono); font-size: 10px; color: var(--text-3); }
.tlx .rail { position: relative; height: 30px; }
.tlx .rail .line { position: absolute; top: 13px; left: 2%; right: 2%; height: 3px; background: var(--border); border-radius: 2px; }
.tlx .rail .fill { position: absolute; top: 13px; left: 2%; width: 90%; height: 3px; background: var(--accent-soft); border-radius: 2px; }
.tlx .rail .tick { position: absolute; top: 9px; width: 9px; height: 9px; border-radius: 50%; background: var(--surface); border: 2px solid var(--border-2); transform: translateX(-50%); }
.tlx .rail .tick.on { background: var(--accent); border-color: var(--accent); width: 13px; height: 13px; top: 7px; }
.tlx .rail .lab { position: absolute; top: 24px; font-family: var(--mono); font-size: 9px; color: var(--text-3); transform: translateX(-50%); }
.tlx .rail .lab.on { color: var(--accent-text); font-weight: 600; }

/* --- Galaxy (radial spoke chart) ----------------------------------------- */
/* Column flow: a single-row legend bar on top (Ring 1 · Ring 2 · hover hint ·
   spoke-length hint), then the radial stage beside its strategies, then the day
   slider full-width BELOW the chart (matching the Chart-Duo slider placement). */
.tlx .galaxy-wrap { display: flex; flex-direction: column; gap: 14px; padding: 18px; }
.tlx .gx-main { display: flex; gap: 22px; align-items: stretch; flex-wrap: wrap; }
.tlx .gx-stage { position: relative; flex: 0 0 460px; max-width: 100%; }
.tlx .gx-stage svg { width: 100%; height: auto; display: block; }
.tlx .gx-tip { position: absolute; pointer-events: none; z-index: 20; background: var(--surface); border: 1px solid var(--border); border-radius: 7px; padding: 5px 9px; font-family: var(--mono); font-size: 11px; color: var(--text-2); box-shadow: 0 6px 18px rgba(0,0,0,.3); white-space: nowrap; }
.tlx .gx-tip b { color: var(--text); }
.tlx .gx-side { flex: 1 1 240px; min-width: 220px; display: flex; flex-direction: column; gap: 16px; }
.tlx .gx-foot { margin-top: 2px; }
.tlx .gx-block { display: flex; flex-direction: column; gap: 8px; }
.tlx .gx-h { font-family: var(--mono); font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--text-3); font-weight: 600; }
.tlx .gx-strats { display: flex; flex-wrap: wrap; gap: 6px; }
.tlx .gx-strat { display: inline-flex; align-items: center; gap: 5px; font-family: var(--mono); font-size: 10.5px; border-radius: 6px; padding: 3px 8px; border: 1px solid var(--border-2); background: var(--surface-2); color: var(--text-2); }
.tlx .gx-strat b { font-weight: 600; }
.tlx .gx-strat.tone-up { background: var(--green-soft); color: var(--green); border-color: transparent; }
.tlx .gx-strat.tone-down { background: var(--red-soft); color: var(--red); border-color: transparent; }
.tlx .gx-strat.tone-acc { background: var(--accent-soft); color: var(--accent-text); border-color: transparent; }
.tlx .gx-strat.tone-neu { color: var(--text-2); }
.tlx .gx-empty { font-size: 11.5px; color: var(--text-3); }
.tlx .gx-legend { display: flex; flex-direction: column; gap: 8px; }
.tlx .gx-legend .row { display: flex; gap: 8px; align-items: center; font-size: 11.5px; color: var(--text-2); }
.tlx .gx-legend .ring { width: 12px; height: 12px; border-radius: 50%; flex: 0 0 12px; }
.tlx .gx-legend .hint { font-size: 10.5px; color: var(--text-3); }
/* Single-row legend bar: all four ring/hint items on one line, wrapping only
   when the card is too narrow; a hairline divides it from the chart below. */
.tlx .gx-legend-bar { flex-direction: row; flex-wrap: wrap; align-items: center; gap: 7px 18px; padding: 0 2px 12px; border-bottom: 1px solid var(--border-2); }
.tlx .gx-legend-bar .hint { display: inline-flex; align-items: center; gap: 6px; }
.tlx .gx-legend-bar .hint i { font-size: 13px; color: var(--text-3); }

/* --- Summary -------------------------------------------------------------- */
.tlx .data-2col { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.tlx .subhead { padding: 10px 16px; font-size: 10px; letter-spacing: .07em; text-transform: uppercase; color: var(--text-3); font-weight: 600; background: var(--surface-2); border-bottom: 1px solid var(--border-2); }
.tlx .readout { display: flex; flex-direction: column; }
.tlx .ind-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 16px; border-bottom: 1px solid var(--border-2); }
.tlx .ind-row:last-child { border-bottom: 0; }
.tlx .ind-row .k { color: var(--text-2); font-size: 12px; }
.tlx .ind-row .v { font-family: var(--mono); font-weight: 600; font-size: 13px; text-align: right; }
.tlx .mini { height: 4px; width: 64px; border-radius: 2px; background: var(--surface-2); overflow: hidden; display: inline-block; margin-left: 8px; vertical-align: middle; }
.tlx .mini > i { display: block; height: 100%; }
.tlx .fstat-row { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1px; background: var(--border-2); }
.tlx .fstat { background: var(--surface); padding: 13px 16px; }
.tlx .fstat .k { font-size: 10px; letter-spacing: .05em; text-transform: uppercase; color: var(--text-3); font-weight: 600; margin-bottom: 5px; }
.tlx .fstat .v { font-family: var(--mono); font-size: 17px; font-weight: 600; color: var(--text); }
.tlx .fstat .s { font-family: var(--mono); font-size: 11px; color: var(--text-2); margin-top: 2px; }
.tlx .gtbl { width: 100%; border-collapse: collapse; font-size: 12px; }
.tlx .gtbl th { font-family: var(--mono); font-size: 10px; letter-spacing: .05em; text-transform: uppercase; color: var(--text-3); text-align: right; padding: 8px 12px; border-bottom: 1px solid var(--border); font-weight: 600; }
.tlx .gtbl th:first-child { text-align: left; }
.tlx .gtbl td { padding: 8px 12px; border-bottom: 1px solid var(--border-2); font-family: var(--mono); font-variant-numeric: tabular-nums; text-align: right; color: var(--text); }
.tlx .gtbl td:first-child { text-align: left; font-weight: 600; }
.tlx .gtbl tr:last-child td { border-bottom: 0; }
.tlx .ce-t { color: var(--lvl-r); }
.tlx .pe-t { color: var(--lvl-s); }
.tlx .planned { font-family: var(--mono); font-size: 9px; letter-spacing: .06em; color: var(--amber); background: var(--amber-soft); border-radius: 5px; padding: 2px 7px; font-weight: 600; }
.tlx .na-note { font-size: 11.5px; color: var(--text-3); font-style: italic; margin: -2px 0 12px; }
.tlx .band { position: relative; height: 40px; margin: 8px 4px 2px; }
.tlx .band .track { position: absolute; top: 18px; left: 0; right: 0; height: 4px; background: linear-gradient(90deg, var(--green-soft), var(--surface-2), var(--red-soft)); border-radius: 2px; }
.tlx .band .bdot { position: absolute; top: 12px; width: 13px; height: 13px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 4px var(--accent-soft); transform: translateX(-50%); }
.tlx .band .lbl { position: absolute; font-family: var(--mono); font-size: 9px; color: var(--text-2); top: -1px; transform: translateX(-50%); white-space: nowrap; }
.tlx .band .lbl.spot { top: 26px; color: var(--accent-text); }

.tlx .gap16 { margin-bottom: 16px; }

/* ===========================================================================
   Brief 05 — EOD Dashboard DATA BUILD (live per-symbol wiring). Additive,
   scoped under .tlx, token-only. Empty/locked states, the derived-signal tags,
   the interactive Chart-Duo dropdown/menu/legend/hover tooltip, and the
   Chart-OI date "replay" strip.
   =========================================================================== */

/* Empty / locked / not-found shell + the cash-only F&O note. */
.tlx .dash-empty, .tlx .na-panel {
  display: flex; align-items: center; gap: 12px; padding: 22px 20px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 11px;
  color: var(--text-2); font-size: 13px; margin-bottom: 16px;
}
.tlx .dash-empty i, .tlx .na-panel i { font-size: 22px; color: var(--text-3); flex: 0 0 auto; }
.tlx .dash-empty p, .tlx .na-panel p { margin: 0; }
.tlx .na-panel { align-items: flex-start; }
.tlx .na-panel i { color: var(--amber); }

/* Derived-signal hint + RSI tag in the signal row. */
.tlx .sig .k .der { font-family: var(--mono); font-size: 8px; letter-spacing: .04em; color: var(--accent-text); background: var(--accent-soft); border-radius: 4px; padding: 1px 4px; margin-left: 4px; }
.tlx .sig .rtag { font-family: var(--mono); font-size: 10px; font-weight: 600; color: var(--text-3); }

/* Chart-Duo reading-hints bar — mirrors .gx-legend-bar: a wrapping row of
   icon-led hints divided from the charts by a hairline, one idea per item. */
.tlx .duo-note { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 18px; margin: 0 0 14px; padding: 0 2px 12px; border-bottom: 1px solid var(--border-2); font-size: 11.5px; color: var(--text-2); }
.tlx .duo-note .hint { display: inline-flex; align-items: center; gap: 7px; }
.tlx .duo-note .hint i { color: var(--accent-text); font-size: 14px; flex: 0 0 auto; }
.tlx .duo-note em { color: var(--text); font-style: italic; }

/* Add-series dropdown (button + grouped menu). */
.tlx .duo-add { position: relative; }
.tlx .duo-add-btn { display: inline-flex; align-items: center; gap: 5px; border: 1px solid var(--border); background: var(--surface-2); color: var(--accent-text); border-radius: 7px; padding: 5px 11px; font-family: var(--mono); font-size: 11px; font-weight: 600; cursor: pointer; }
.tlx .duo-add-btn i { font-size: 12px; }
.tlx .duo-menu { display: none; position: absolute; right: 0; top: calc(100% + 6px); z-index: 30; width: 248px; max-height: 340px; overflow-y: auto; background: var(--surface); border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 10px 30px rgba(0,0,0,.28); padding: 6px; }
.tlx .duo-menu.open { display: block; }
.tlx .duo-menu-h { font-family: var(--mono); font-size: 9px; letter-spacing: .08em; text-transform: uppercase; color: var(--text-3); font-weight: 600; padding: 8px 8px 4px; }
.tlx .duo-menu-item { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left; border: 0; background: transparent; color: var(--text); font-size: 12px; font-family: var(--display); padding: 6px 8px; border-radius: 6px; cursor: pointer; }
.tlx .duo-menu-item:hover { background: var(--surface-2); }
.tlx .duo-menu-item .dot { width: 9px; height: 9px; border-radius: 2px; flex: 0 0 auto; }
.tlx .duo-menu-item .ty { font-family: var(--mono); font-size: 8px; letter-spacing: .04em; color: var(--text-3); border: 1px solid var(--border-2); border-radius: 4px; padding: 0 4px; text-transform: uppercase; }
.tlx .duo-menu-item .ph-check { margin-left: auto; color: var(--accent-text); font-size: 13px; }
.tlx .duo-menu-item.is-on { color: var(--accent-text); }
.tlx .duo-menu-item.is-disabled { opacity: .4; cursor: not-allowed; }

/* Series chip remove control (mirrors .series .sp .x). */
.tlx .series .sp .duo-chip-x { color: var(--text-3); font-size: 10px; display: inline-flex; cursor: pointer; margin-left: 2px; }
.tlx .series .sp .duo-chip-x:hover { color: var(--red); }

/* Chart-Duo plot area + per-series legend + hover tooltip. */
.tlx .cmp-body { position: relative; }
.tlx .duo-chart { width: 100%; height: 200px; }
.tlx .duo-legend { display: flex; flex-wrap: wrap; gap: 6px 14px; padding: 8px 16px 4px; font-family: var(--mono); font-size: 10.5px; color: var(--text-2); }
.tlx .duo-legend .lg { display: inline-flex; align-items: center; gap: 5px; }
.tlx .duo-legend .lg i { width: 12px; height: 3px; border-radius: 2px; display: inline-block; }
.tlx .duo-legend .lg b { color: var(--text); font-weight: 600; }
.tlx .duo-tip { position: absolute; top: 6px; transform: translateX(-50%); pointer-events: none; background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 7px 9px; font-family: var(--mono); font-size: 10.5px; color: var(--text-2); box-shadow: 0 6px 18px rgba(0,0,0,.3); z-index: 20; white-space: nowrap; }
.tlx .duo-tip .d { color: var(--accent-text); font-weight: 600; margin-bottom: 4px; }
.tlx .duo-tip .r { display: flex; align-items: center; gap: 6px; }
.tlx .duo-tip .r i { width: 9px; height: 3px; border-radius: 2px; display: inline-block; }
.tlx .duo-tip .r b { color: var(--text); }

/* Chart-OI date replay strip (replaces the intraday scrub rail). */
.tlx .oi-dates { display: flex; gap: 6px; flex-wrap: wrap; }
.tlx .oi-date { font-family: var(--mono); font-size: 11px; font-weight: 600; color: var(--text-2); border: 1px solid var(--border); background: var(--surface-2); border-radius: 7px; padding: 5px 11px; cursor: pointer; }
.tlx .oi-date.on { background: var(--accent-soft); color: var(--accent-text); border-color: var(--accent-soft); }

/* Shared date slider — Chart-Duo dual-handle range + Galaxy single-handle day.
   Two transparent native range inputs ride over a custom track/fill (the only
   reliable way to get a two-thumb range + a filled segment cross-browser). The
   inputs themselves are click-through (pointer-events:none) except their thumbs. */
/* Chart-Duo date-range slider now sits BELOW the two charts (charts-2col already
   carries the 16px gap above it), so it only needs a small bottom margin. */
.tlx .duo-range { margin: 2px 0 8px; }
.tlx .dslider { display: flex; flex-direction: column; gap: 9px; }
.tlx .dslider-head { display: flex; align-items: center; gap: 8px; }
.tlx .dslider-title { display: inline-flex; align-items: center; gap: 6px; font-family: var(--mono); font-size: 10px; letter-spacing: .07em; text-transform: uppercase; color: var(--text-3); font-weight: 600; }
.tlx .dslider-title i { font-size: 13px; }
.tlx .dslider-val { margin-left: auto; display: inline-flex; align-items: center; gap: 6px; font-family: var(--mono); font-size: 11px; font-weight: 600; color: var(--accent-text); }
.tlx .dslider-val i { color: var(--text-3); font-size: 11px; }
.tlx .dslider-rail { position: relative; height: 22px; }
.tlx .dslider-track { position: absolute; top: 9px; left: 8px; right: 8px; height: 4px; background: var(--border); border-radius: 2px; }
.tlx .dslider-fill { position: absolute; top: 9px; height: 4px; background: var(--accent); border-radius: 2px; }
.tlx .dslider-input { -webkit-appearance: none; appearance: none; position: absolute; top: 0; left: 0; width: 100%; height: 22px; margin: 0; background: transparent; pointer-events: none; }
.tlx .dslider-input::-webkit-slider-runnable-track { height: 4px; background: transparent; }
.tlx .dslider-input::-moz-range-track { height: 4px; background: transparent; }
.tlx .dslider-input::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; pointer-events: auto; width: 15px; height: 15px; margin-top: -5.5px; border-radius: 50%; background: var(--accent); border: 2px solid var(--surface); box-shadow: 0 1px 3px rgba(0,0,0,.35); cursor: pointer; }
.tlx .dslider-input::-moz-range-thumb { pointer-events: auto; width: 15px; height: 15px; border-radius: 50%; background: var(--accent); border: 2px solid var(--surface); box-shadow: 0 1px 3px rgba(0,0,0,.35); cursor: pointer; }
.tlx .dslider-input:focus-visible::-webkit-slider-thumb { outline: 2px solid var(--accent-text); outline-offset: 2px; }
.tlx .dslider-input:focus-visible::-moz-range-thumb { outline: 2px solid var(--accent-text); outline-offset: 2px; }

/* --- Columns popover (shared: EOD Data + Screener) ------------------------ */
/* The <details> "Columns" dropdown from components/_cols.html. Toolbar: Select
   all / Reset / Save (Save persists per-account); the list scrolls. Replaces the
   previous inline-styled popover so both tables read identically. */
.tlx .col-pop { position: relative; }
.tlx .col-pop > summary { list-style: none; cursor: pointer; }
.tlx .col-pop > summary::-webkit-details-marker { display: none; }
.tlx .col-pop-menu { position: absolute; right: 0; z-index: 30; margin-top: 6px; min-width: 246px; max-height: 360px; overflow: auto; display: flex; flex-direction: column; gap: 6px; padding: 12px; background: var(--surface); border: 1px solid var(--border); border-radius: 10px; box-shadow: var(--shadow-md); }
.tlx .col-pop-actions { display: flex; gap: 6px; padding-bottom: 8px; border-bottom: 1px solid var(--border); }
.tlx .col-pop-btn { flex: 1; padding: 4px 8px; font-size: 11px; display: inline-flex; align-items: center; justify-content: center; gap: 4px; white-space: nowrap; }
.tlx .col-pop-save { color: var(--accent-text); }
.tlx .col-pop-save i { font-size: 12px; }
.tlx .col-pop-status { min-height: 0; font-family: var(--mono); font-size: 10px; font-weight: 600; color: var(--green); opacity: 0; max-height: 0; overflow: hidden; transition: opacity .15s ease; }
.tlx .col-pop-status.on { opacity: 1; min-height: 14px; max-height: 14px; }
.tlx .col-pop-status.err { color: var(--red); }
.tlx .col-pop-list { display: flex; flex-direction: column; gap: 6px; }
.tlx .col-pop-row { display: flex; gap: 8px; align-items: center; font-size: 12px; cursor: pointer; }

/* ===========================================================================
   IA Summary visual polish (ui_polish_batch_1) — scoped to .tlx.ia-dash so the
   SHARED EOD dashboard render is untouched (the wrapper only gains `ia-dash` in
   ia_mode). Adds a per-state 3px left-border + value colour to the signal cells,
   zebra/tabular readout rows, and a 3-up ATM-Greeks grid that removes the empty
   cell the 2-col grid left beside the lone IV-skew stat.
   =========================================================================== */
.tlx.ia-dash .sig { border-left: 3px solid var(--border); }
.tlx.ia-dash .sig.sig--bull   { border-left-color: var(--green); }
.tlx.ia-dash .sig.sig--bear   { border-left-color: var(--red); }
.tlx.ia-dash .sig.sig--accent { border-left-color: var(--accent); }
.tlx.ia-dash .sig.sig--amber  { border-left-color: var(--amber); }
.tlx.ia-dash .sig.sig--bull .v   { color: var(--green); }
.tlx.ia-dash .sig.sig--bear .v   { color: var(--red); }
.tlx.ia-dash .sig.sig--accent .v { color: var(--accent-text); }
.tlx.ia-dash .sig.sig--amber .v  { color: var(--amber); }

/* Readout rows — subtle zebra, steady row height, tabular figures. */
.tlx.ia-dash .readout .ind-row { min-height: 32px; }
.tlx.ia-dash .readout .ind-row:nth-child(even) { background: var(--zebra); }
.tlx.ia-dash .ind-row .v { font-variant-numeric: tabular-nums; }

/* ATM option Greeks card: three stats in one row (no empty 2-col cell). Applies
   in BOTH the EOD (`.tlx`) and IA (`.tlx.ia-dash`) dashboard renders — the base
   `.fstat-row` stays 2-up for the wider F&O-summary blocks. */
.tlx .fstat-row.fstat-3 { grid-template-columns: repeat(3, 1fr); }

/* ---------------------------------------------------------------------------
   IA Stats tab table (ui_polish_batch_1) — dense table with a client-toggled
   column set (persisted in localStorage 'tl-ia-stats-cols'). Hidden columns drop
   out per cell (display:none on the matching th+td); long cells (e.g. URLs) clip
   with an ellipsis instead of bleeding past the container.
   --------------------------------------------------------------------------- */
.tlx .stats-tbl th, .tlx .stats-tbl td {
  max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tlx .stats-tbl .hidden-col { display: none; }

/* --- Responsive ----------------------------------------------------------- */
@media (max-width: 900px) {
  .tlx .signal, .tlx .signal.signal-4 { grid-template-columns: 1fr 1fr; }
  .tlx .charts-2col, .tlx .data-2col { grid-template-columns: 1fr; }
}

/* ===========================================================================
   Brief A1 / E2 — IA Screener (ia/screener.html) page surface. Scoped under
   .tlx, token-only. Relocated from the page's inline <style> (brief E2,
   hx-boost-safe — same rationale as the EOD Dashboard note above). The original
   inline rules were NOT .tlx-scoped; prefixed with .tlx here to match the
   page's .tlx wrapper and avoid leaking global class names. No collisions.
   =========================================================================== */
.tlx .screener-grid { display: grid; grid-template-columns: 280px 1fr; gap: var(--space-6); align-items: start; }
.tlx .filter-panel { position: sticky; top: var(--space-4); }
.tlx .filter-group { margin-bottom: var(--space-5); }
.tlx .filter-group h4 { font-size: var(--text-sm); margin-bottom: var(--space-2); }
.tlx .range-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); }
.tlx .range-row label { font-size: var(--text-xs); color: var(--text-2); }
@media (max-width: 820px) { .tlx .screener-grid { grid-template-columns: 1fr; } }

/* ===========================================================================
   Contextual-help tooltips (.tlx-tip) — brief dashboard_tooltips_build.
   A "?" affordance next to non-obvious metrics; reveals a short explainer on
   hover / keyboard focus. PURE CSS: the bubble is a ::after rendered from the
   data-tip attribute (so the text is shown as plain text, never parsed as HTML
   — XSS-safe) with a ::before caret. Scoped under .tlx like the rest of the
   redesign surface; token-only. No JS.
   =========================================================================== */
.tlx .tlx-tip { position: relative; display: inline-flex; align-items: center;
  vertical-align: middle; margin-left: 4px; color: var(--text-3); line-height: 1;
  cursor: help; }
.tlx .tlx-tip > i { font-size: 11px; }
.tlx .tlx-tip:hover, .tlx .tlx-tip:focus-within { color: var(--text-2); outline: none; }

/* Bubble + caret: hidden by default, revealed on hover / focus. */
.tlx .tlx-tip::after, .tlx .tlx-tip::before {
  position: absolute; opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .12s ease; z-index: 50; }
.tlx .tlx-tip::after {
  content: attr(data-tip);
  width: max-content; max-width: 240px;
  white-space: normal; text-align: left;
  background: var(--surface); color: var(--text-2);
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  padding: 8px 10px; font-family: var(--font-body);
  font-size: 11px; font-weight: 400; line-height: 1.4; letter-spacing: 0;
  text-transform: none; box-shadow: var(--shadow-md); }
.tlx .tlx-tip::before {
  content: ""; width: 8px; height: 8px; background: var(--surface);
  border-left: 1px solid var(--border); border-top: 1px solid var(--border); }
.tlx .tlx-tip:hover::after, .tlx .tlx-tip:focus-within::after,
.tlx .tlx-tip:hover::before, .tlx .tlx-tip:focus-within::before {
  opacity: 1; visibility: visible; }

/* Position: top (default) — bubble centered above the icon. */
.tlx .tlx-tip[data-pos="top"]::after, .tlx .tlx-tip:not([data-pos])::after {
  left: 50%; bottom: 100%; transform: translateX(-50%) translateY(-8px); }
.tlx .tlx-tip[data-pos="top"]::before, .tlx .tlx-tip:not([data-pos])::before {
  left: 50%; bottom: 100%; transform: translateX(-50%) translateY(-4px) rotate(45deg); }

/* Position: bottom — bubble centered below the icon. */
.tlx .tlx-tip[data-pos="bottom"]::after {
  left: 50%; top: 100%; transform: translateX(-50%) translateY(8px); }
.tlx .tlx-tip[data-pos="bottom"]::before {
  left: 50%; top: 100%; transform: translateX(-50%) translateY(4px) rotate(225deg); }

/* Position: right — opens down-and-right of the icon. Used for dense table
   column headers: anchoring the bubble top near the icon keeps it inside the
   .tablewrap scroll box (which clips vertically via overflow-x:auto), so the
   header tip is never cut off above the table. */
.tlx .tlx-tip[data-pos="right"]::after {
  left: 100%; top: -4px; transform: translateX(8px); }
.tlx .tlx-tip[data-pos="right"]::before {
  left: 100%; top: 5px; transform: translateX(4px) rotate(-45deg); }

/* The signal row clips its rounded corners (overflow:hidden); lift that only
   while a tooltip inside it is shown so the bubble can escape the row box. */
.tlx .signal:has(.tlx-tip:hover), .tlx .signal:has(.tlx-tip:focus-within) {
  overflow: visible; }

/* ===========================================================================
   ApexQQuant admin Dashboard + Screener (apex_dashboard_redesign).
   Relocated here from the page head_extra <style> (hx-boost drops a per-page
   <head> <style> on in-app navigation, rendering the page naked). Token-only,
   scoped under .tlx; the .apex-* names are shared by snapshot_dashboard.html and
   screener.html. monitor.html keeps its own inline styles (out of scope here).
   =========================================================================== */

/* --- freshness pill + heartbeat dot (shared chrome) ----------------------- */
/* apex_dashboard_v6: the freshness indicator is now a filled PILL (shared chrome
   across all four tabs). The market pill (.apex-mkt) mirrors it. */
.tlx .apex-fresh { display: inline-flex; align-items: center; gap: 5px; font-family: var(--mono);
  font-size: 11px; font-weight: 500; letter-spacing: .04em; padding: 3px 9px; border-radius: 999px; }
.tlx .apex-dot { display: inline-block; width: .5em; height: .5em; border-radius: 50%;
  background: currentColor; vertical-align: middle; flex: 0 0 auto; }
.tlx .apex-fresh-live  { color: var(--green); background: var(--green-soft); }
/* Last-refresh chip (operator ask 10-Jul): the module's truest data time.
   Greys via .is-stale in lockstep with the badge threshold - the two never disagree. */
.tlx .apex-asof { display: inline-flex; align-items: center; font-family: var(--mono);
  font-size: 10.5px; letter-spacing: .02em; color: var(--text-3);
  padding: 3px 8px; border-radius: 999px; background: var(--bg-3); white-space: nowrap; }
.tlx .apex-asof.is-stale { color: var(--amber); background: var(--amber-soft); }
.tlx .apex-fresh-stale { color: var(--amber); background: var(--amber-soft); }
.tlx .apex-fresh-wait  { color: var(--text-3); background: var(--surface-2); border: 1px solid var(--border); }
.tlx .apex-heart { display: inline-flex; align-items: center; gap: 4px; font-family: var(--mono);
  font-size: 10px; color: var(--text-3); }
.tlx .apex-heart-dot { display: inline-block; width: .5em; height: .5em; border-radius: 50%;
  background: currentColor; vertical-align: middle; flex: 0 0 auto; }
.tlx .apex-heart-ok   { color: var(--green); }
.tlx .apex-heart-warn { color: var(--amber); }
.tlx .apex-heart-off  { color: var(--text-3); }

/* --- compact header band (brand + chips + freshness, ONE row) ------------- */
.tlx .apex-headerbar { display: flex; align-items: center; justify-content: space-between;
  gap: 14px; flex-wrap: wrap; border: 1px solid var(--border); border-left: 2.5px solid var(--accent);
  border-radius: 11px; background: var(--surface); padding: 11px 16px; margin-bottom: 18px; }
.tlx .apex-hb-id { display: inline-flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.tlx .apex-hb-name { font-family: var(--display); font-weight: 700; font-size: 15px; color: var(--text);
  letter-spacing: -.01em; }
.tlx .apex-hb-tag { color: var(--text-3); font-size: 12px; font-weight: 500; }
.tlx .apex-hb-chips { display: inline-flex; gap: 6px; flex-wrap: wrap; }
.tlx .apex-hb-badge { font-family: var(--mono); font-size: 10px; color: var(--text-3);
  border: 1px solid var(--border-2); border-radius: 5px; padding: 2px 7px; letter-spacing: .03em; }
.tlx .apex-hb-meta { display: inline-flex; align-items: center; gap: 7px; flex-wrap: wrap;
  font-family: var(--mono); font-size: 11px; color: var(--text-3); }
.tlx .apex-hb-sep { color: var(--border-2); }
.tlx .apex-hb-date { color: var(--text-2); font-weight: 600; }
.tlx .apex-hb-asof { color: var(--text-3); }

/* --- eyebrow (mono-uppercase label + hairline rule + optional right meta) -- */
.tlx .apex-eyebrow { display: flex; align-items: center; gap: 12px; font-family: var(--mono);
  font-size: 11px; letter-spacing: var(--tracking-mono); text-transform: uppercase;
  font-weight: var(--weight-medium); color: var(--text-3); margin: 22px 0 11px; }
.tlx .apex-eyebrow .ln { flex: 1 1 auto; height: 1px; background: var(--border); }
.tlx .apex-eyebrow .meta { flex: 0 1 auto; letter-spacing: 0; text-transform: none;
  color: var(--text-3); font-size: 11px; }
.tlx .apex-eyebrow .apex-viewall { flex: 0 0 auto; letter-spacing: 0; text-transform: none;
  font-size: 11px; font-weight: 600; color: var(--accent-text); display: inline-flex; align-items: center; gap: 4px; }
.tlx .apex-eyebrow .apex-viewall:hover { text-decoration: underline; }

/* --- consistent panel chrome (matches the .tlx redesign cards) ------------ */
.tlx .apex-panel { border: 1px solid var(--border); border-radius: 12px; background: var(--surface);
  padding: 14px 16px; margin-bottom: 18px; }
.tlx .apex-empty-state { text-align: center; padding: 40px 20px; }
.tlx .apex-empty-k { font-family: var(--mono); font-size: 11px; text-transform: uppercase;
  letter-spacing: .06em; color: var(--text-2); font-weight: 600; margin-bottom: 8px; }
.tlx .apex-empty-p { font-size: 13px; color: var(--text-3); max-width: 460px; margin: 0 auto; line-height: 1.5; }

/* --- KPI strip (4-across, compact; 2x2 under 720px) ----------------------- */
.tlx .apex-kpi { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 18px; }
.tlx .apex-kpi-card { border: 1px solid var(--border); border-radius: 12px; background: var(--surface);
  padding: 12px 14px; display: flex; flex-direction: column; gap: 5px; min-width: 0; max-height: 120px; }
.tlx .apex-kpi-k { font-family: var(--mono); font-size: 9.5px; letter-spacing: .05em; text-transform: uppercase;
  color: var(--text-3); font-weight: 600; }
.tlx .apex-kpi-v { font-family: var(--mono); font-size: 22px; font-weight: 600; letter-spacing: -.01em;
  line-height: 1.05; color: var(--text); }
.tlx .apex-kpi-s { font-family: var(--mono); font-size: 10.5px; color: var(--text-3); }
.tlx .apex-mkt { display: inline-flex; align-items: center; gap: 5px; font-family: var(--mono);
  font-size: 11px; font-weight: 500; letter-spacing: .04em; padding: 3px 9px; border-radius: 999px; }
.tlx .apex-mkt-open { color: var(--green); background: var(--green-soft); }
.tlx .apex-mkt-closed { color: var(--text-3); background: var(--surface-2); border: 1px solid var(--border); }

/* --- top row: 3 KPI tiles + Regime panel (Market tile removed; Regime hoisted) --- */
.tlx .apex-topgrid { display: grid; grid-template-columns: repeat(3, 1fr) 1.9fr; gap: 12px;
  align-items: stretch; margin-bottom: 18px; }
.tlx .apex-regime-panel { margin-bottom: 0; }
.tlx .apex-regime-panel .apex-eyebrow { margin: 0 0 10px; }

/* --- market-context 2-col row (Regime | Sector bars) ---------------------- */
.tlx .apex-ctx { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; align-items: start; }
.tlx .apex-ctx .apex-panel { margin-bottom: 18px; }
.tlx .apex-regime { display: flex; flex-wrap: wrap; align-items: center; gap: 16px; font-size: 13px; }
.tlx .apex-regime-bl { margin-top: 11px; }
.tlx .apex-regime .regime-cell { display: inline-flex; align-items: center; gap: 8px; }
.tlx .apex-regime .regime-k { color: var(--text-2); font-size: 12px; }
.tlx .apex-spark { display: inline-flex; align-items: center; }
.tlx .apex-spark svg { display: block; }
.tlx .apex-banned { display: inline-flex; flex-wrap: wrap; gap: 4px; }

/* sector breadth — sorted horizontal bar list (the readability win) */
.tlx .apex-sec-bars { display: flex; flex-direction: column; gap: 7px; }
.tlx .apex-sec-row { display: grid; grid-template-columns: 116px 1fr 38px; align-items: center; gap: 10px; }
.tlx .apex-sec-name { font-size: 12px; color: var(--text-2); overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.tlx .apex-sec-track { position: relative; height: 9px; border-radius: 5px; background: var(--surface-2);
  border: 1px solid var(--border-2); overflow: hidden; }
.tlx .apex-sec-fill { display: block; height: 100%; border-radius: 5px 0 0 5px; }
.tlx .apex-sec-fill.adv { background: var(--green); }
.tlx .apex-sec-fill.dec { background: var(--red); }
.tlx .apex-sec-pct { font-size: 11.5px; font-weight: 600; color: var(--text-2); text-align: right; }

/* risk limits — compact, consistent chrome */
.tlx .apex-risk-panel { max-width: 520px; }
.tlx .apex-risk { display: flex; flex-direction: column; gap: 5px; font-family: var(--mono); font-size: 12px; }
.tlx .apex-risk-row { display: flex; justify-content: space-between; gap: 16px; }
.tlx .apex-risk-row .rk { color: var(--text-2); }
.tlx .apex-risk-row .rv { color: var(--text); }
.tlx .apex-risk-mult { margin-top: 8px; font-family: var(--mono); font-size: 10.5px; color: var(--text-3); }

/* --- radar bubble map (inline SVG; sanctioned gold border accent) ---------- */
.tlx .apex-radar-card { position: relative; border-top: 2px solid var(--color-gold); }
.tlx .apex-radar-wrap { position: relative; width: 100%; }
.tlx .apex-radar-svg { display: block; width: 100%; height: auto; }
.tlx .apex-radar-svg circle { transition: stroke-width var(--transition-fast); cursor: default; }
.tlx .apex-radar-svg circle:hover { stroke-width: 3; }
.tlx .apex-radar-empty { display: none; padding: 60px 20px; text-align: center; color: var(--text-3);
  font-size: 13px; }
.tlx .apex-legend { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 11px; font-size: 11px;
  color: var(--text-3); }
.tlx .apex-legend-item { display: inline-flex; align-items: center; gap: 6px; }
.tlx .apex-legend-swatch { width: 12px; height: 12px; border-radius: 999px; border: 2px solid var(--neutral);
  display: inline-block; }
.tlx .apex-legend-swatch.bull { background: var(--green-soft); border-color: var(--green); }
.tlx .apex-legend-swatch.bear { background: var(--red-soft); border-color: var(--red); }
.tlx .apex-cyan { color: #22D3EE; }

/* --- top signals teaser (Symbol · Score · Macro · Alpha · Δ% · Pressure) --- */
.tlx .apex-movers-panel { padding: 6px 16px; }
.tlx .apex-movers { display: flex; flex-direction: column; }
.tlx .apex-mover { display: grid; grid-template-columns: 1.3fr 58px 1fr 60px 66px 1.1fr; align-items: center;
  gap: 12px; padding: 9px 0; border-bottom: 1px solid var(--border-2); }
.tlx .apex-mover:last-child { border-bottom: 0; }
.tlx .apex-mover-head { font-family: var(--mono); font-size: 9.5px; letter-spacing: .05em; text-transform: uppercase;
  color: var(--text-3); font-weight: 600; padding: 4px 0 7px; }
.tlx .apex-mover-head .num { text-align: right; }
.tlx .apex-mover-sym { font-weight: 600; color: var(--text); display: inline-flex; align-items: center; gap: 6px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tlx .apex-mover-score { font-size: 13px; font-weight: 600; text-align: right; }
.tlx .apex-mover-macro { font-size: 12px; color: var(--text-2); overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.tlx .apex-mover-alpha { font-size: 12px; text-align: right; color: var(--text-2); }
.tlx .apex-mover-chg { font-size: 12px; text-align: right; }
.tlx .apex-mover-pr { text-align: right; }
.tlx .apex-movers-empty { font-size: 12px; padding: 14px 0; }

/* --- positions table cells ------------------------------------------------ */
.tlx .apex-tablewrap { margin-bottom: 8px; }
.tlx .apex-instr { display: flex; flex-direction: column; gap: 1px; }
.tlx .apex-instr-sub { color: var(--text-3); font-size: 10px; font-family: var(--mono); }
.tlx .apex-pos-empty, .tlx .apex-scr-empty { font-size: 12px; padding: 8px 2px; }

/* --- dense signal cells (Screener: whale / patterns / trail / signal) ----- */
.tlx .apex-whale { font-family: var(--mono); font-size: 12px; white-space: nowrap; }
.tlx .apex-whale-split { color: var(--text-3); font-size: 10px; margin-left: 2px; }
.tlx .apex-whale-split i.ph { font-size: 1em; vertical-align: -.05em; }
.tlx .apex-pat { font-family: var(--mono); font-size: 10px; white-space: nowrap; letter-spacing: .02em; }
.tlx .apex-pat .pk { color: var(--text-3); }
.tlx .apex-alpha-w { font-size: 10px; }
.tlx .apex-trail { display: inline-flex; gap: 2px; align-items: center; }
.tlx .apex-trail-chip { display: inline-block; min-width: 16px; text-align: center; font-family: var(--mono);
  font-size: 10px; line-height: 1.5; padding: 0 2px; border-radius: 3px; border: 1px solid var(--border);
  color: var(--text-2); cursor: default; }
.tlx .apex-trail-chip.pos { color: var(--green); border-color: var(--green-soft); }
.tlx .apex-trail-chip.neg { color: var(--red); border-color: var(--red-soft); }
.tlx .apex-trail-empty { color: var(--text-3); font-size: 10px; }
.tlx .apex-sig { max-width: 260px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--text-3); font-size: 11px; }

/* --- screener controls (search + filter chips) ---------------------------- */
.tlx .apex-scr-controls { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 14px; }
.tlx .apex-scr-search { display: inline-flex; align-items: center; gap: 7px; border: 1px solid var(--border);
  border-radius: 8px; background: var(--surface); padding: 6px 11px; }
.tlx .apex-scr-search i { color: var(--text-3); font-size: 14px; }
.tlx .apex-scr-search input { border: 0; background: transparent; color: var(--text); outline: none;
  font-family: var(--body); font-size: 12.5px; width: 150px; }
.tlx .apex-scr-search input::placeholder { color: var(--text-3); }
.tlx .apex-scr-chips { display: inline-flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.tlx .apex-scr-grouplabel { font-family: var(--mono); font-size: 9.5px; text-transform: uppercase;
  letter-spacing: .05em; color: var(--text-3); font-weight: 600; margin-right: 2px; }
.tlx .apex-scr-chip { font-family: var(--mono); font-size: 11px; font-weight: 500; color: var(--text-2);
  background: var(--surface); border: 1px solid var(--border); border-radius: 999px; padding: 4px 11px;
  cursor: pointer; display: inline-flex; align-items: center; gap: 5px; transition: all var(--transition-fast); }
.tlx .apex-scr-chip:hover { color: var(--text); border-color: var(--border-strong); }
.tlx .apex-scr-chip.is-active { color: var(--accent-text); background: var(--accent-soft); border-color: var(--accent); }
.tlx .apex-scr-chip i { font-size: 12px; }
.tlx .apex-scr-count { margin-left: auto; font-size: 11px; }
.tlx .apex-scr-disc { font-size: 11px; font-style: italic; margin-top: 10px; }

/* sortable column headers — caret + active accent */
.tlx table.data th.apex-sortable { cursor: pointer; user-select: none; white-space: nowrap; }
.tlx table.data th.apex-sortable:hover { color: var(--text); }
.tlx table.data th.apex-sort-active { color: var(--accent-text); }
.tlx table.data th.apex-sort-asc::after { content: " \2191"; font-size: 10px; }
.tlx table.data th.apex-sort-desc::after { content: " \2193"; font-size: 10px; }

/* --- 2-col context row eyebrows (Regime | Sector) sit flush to the panel top - */
.tlx .apex-ctx .apex-eyebrow { margin: 0 0 10px; }
.tlx .apex-sectors-panel { margin-bottom: 0; }

/* --- IA F&O Greeks per-strike ladder — ATM centerline row ------------------
   Replaces the old "ATM" text badge: the at-the-money strike reads as the chain's
   centerline via a bracketed accent band rather than a word. Used by both ladders —
   the `.tlx` F&O Greeks tab (table.data, _fo_greeks.html) and the workspace
   dashboard's "Option Greeks by strike" panel (table.tbl, workspace/dashboard.html).
   Both are border-collapse: collapse, so the top/bottom border rules show. */
table.data tr.atm-row > td,
table.tbl tr.atm-row > td {
  background: var(--accent-soft);
  border-top: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
}
table.data tr.atm-row:hover > td,
table.tbl tr.atm-row:hover > td { background: var(--accent-soft); }
table.data tr.atm-row > td.atm-strike,
table.tbl tr.atm-row > td.atm-strike { color: var(--accent-text); }
.tlx .apex-sec-empty { font-size: 12px; padding: 8px 2px; }

/* --- risk limits — collapsed/subtle fold (apex_dashboard_5tab) ------------- */
.tlx .apex-riskfold { margin: -4px 0 18px; }
.tlx .apex-riskfold > summary { cursor: pointer; font-family: var(--mono); font-size: 10.5px;
  letter-spacing: .05em; text-transform: uppercase; color: var(--text-3); font-weight: 600;
  list-style: none; display: inline-flex; align-items: center; gap: 6px; }
.tlx .apex-riskfold > summary::-webkit-details-marker { display: none; }
.tlx .apex-riskfold > summary::before { content: "\25B8"; font-size: 9px; color: var(--text-3); }
.tlx .apex-riskfold[open] > summary::before { content: "\25BE"; }
.tlx .apex-riskfold .apex-risk { margin-top: 9px; max-width: 420px; }

/* --- radar full-canvas (its OWN tab now): floor the height so it never blobs - */
.tlx .apex-radar-full .apex-radar-wrap { min-height: 400px; }

/* ===========================================================================
   apex_dashboard_v6 — Dashboard rebuild (header pills + bias legend + 2-tile
   KPI strip + 2-col body) and the Activity tab (open positions + trade log).
   Hardcoded signal hex (#22C55E / #E24B4A / #6B7280) is used ONLY for inline-SVG
   strokes + the cohesive A/D % colour the brief pins; all chrome stays on tokens
   so the page flips with the theme toggle.
   =========================================================================== */

/* --- signal direction colours (match the inline-SVG arrows/sparkline) ------ */
.tlx .apex-up   { color: #22C55E; }
.tlx .apex-down { color: #E24B4A; }
.tlx .apex-flat { color: #6B7280; }

/* --- bias legend — right-aligned, between the tabs and the KPI strip --------
   Matches the Market Pulse bias legend: muted label text, colour ONLY in the
   icons (their hardcoded-hex SVG strokes). */
.tlx .apex-adleg { display: flex; justify-content: flex-end; align-items: center; gap: 12px;
  margin: 2px 0 8px; font-size: 11px; color: var(--text-3); }
.tlx .apex-adleg-item { display: inline-flex; align-items: center; gap: 4px; }
.tlx .apex-adleg-item svg { display: block; }

/* --- KPI strip — Session stats (2fr) | A/D Regime (1fr) -------------------- */
.tlx .apex-kstrip { display: grid; grid-template-columns: 2fr 1fr; gap: 8px; margin-bottom: 14px; }
.tlx .apex-ktile { border: 1px solid var(--border); border-radius: 12px; background: var(--surface);
  padding: 11px 14px; min-width: 0; }
.tlx .apex-ktile-label { font-family: var(--mono); font-size: 9.5px; letter-spacing: .05em;
  text-transform: uppercase; color: var(--text-3); font-weight: 600; margin-bottom: 8px; }
.tlx .apex-kstats { display: flex; align-items: flex-end; gap: 24px; flex-wrap: wrap; }
.tlx .apex-kstat { display: flex; flex-direction: column; gap: 2px; }
.tlx .apex-kstat .v { font-family: var(--mono); font-size: 16px; font-weight: 500; line-height: 1.1; color: var(--text); }
.tlx .apex-kstat .s { font-size: 10px; color: var(--text-3); }
/* A/D tile: sparkline (fills) -> % -> arrow */
.tlx .apex-adtile-body { display: flex; align-items: center; gap: 10px; min-height: 24px; }
.tlx .apex-adspark { flex: 1 1 auto; display: flex; align-items: center; min-width: 0; }
.tlx .apex-adspark svg { display: block; width: 100%; height: 22px; }
.tlx .apex-adpct { font-size: 16px; font-weight: 500; flex: 0 0 auto; }
.tlx .apex-adarrow { flex: 0 0 auto; display: inline-flex; align-items: center; }
.tlx .apex-adarrow svg { display: block; }

/* --- 2-col body — Top signals | Sector breadth ---------------------------- */
.tlx .apex-body2 { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 16px;
  align-items: stretch; }
.tlx .apex-body2 .apex-panel { margin-bottom: 0; }
.tlx .apex-body2 .apex-eyebrow { margin: 0 0 8px; }

/* top-signals compact table (Symbol · Score · Δ% · Pressure) */
.tlx .apex-sigtable { width: 100%; border-collapse: collapse; font-size: 12px; }
.tlx .apex-sigtable th { font-family: var(--mono); font-size: 9.5px; letter-spacing: .05em;
  text-transform: uppercase; color: var(--text-3); font-weight: 600; padding: 4px 5px;
  text-align: left; border-bottom: 1px solid var(--border); }
.tlx .apex-sigtable td { padding: 6px 5px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.tlx .apex-sigtable tr:last-child td { border-bottom: 0; }
.tlx .apex-sigsym { display: inline-flex; align-items: center; gap: 5px; font-weight: 600; color: var(--text); }
.tlx .apex-sigsym svg { display: block; flex: 0 0 auto; }
.tlx .apex-stag { display: inline-block; padding: 1px 7px; border-radius: 10px; font-size: 10px;
  font-weight: 600; white-space: nowrap; }
.tlx .apex-stag.sb { background: var(--red-soft); color: var(--red); }
.tlx .apex-stag.sg { background: var(--green-soft); color: var(--green); }
.tlx .apex-stag.n  { background: var(--surface-2); color: var(--text-3); }
.tlx .apex-sig-empty { font-size: 12px; padding: 8px 2px; }
.tlx .apex-viewlink { display: inline-flex; align-items: center; gap: 4px; margin-top: 8px;
  font-size: 11px; font-weight: 600; color: var(--accent-text); }
.tlx .apex-viewlink:hover { text-decoration: underline; }
.tlx .apex-viewlink i { font-size: 12px; }

/* --- Activity tab — divider, stale banner, empty cards -------------------- */
.tlx .apex-divider { height: 1px; background: var(--border); margin: 18px 0; }
.tlx .apex-warn { display: flex; align-items: flex-start; gap: 8px; background: var(--amber-soft);
  border: 1px solid var(--amber); border-radius: 8px; padding: 10px 14px; font-size: 12px;
  color: var(--amber); margin-bottom: 10px; }
.tlx .apex-empty-card { background: var(--surface); border: 1px solid var(--border); border-radius: 8px;
  padding: 24px; text-align: center; color: var(--text-3); font-size: 12px; }

/* --- responsive: collapse KPI to 2x2, context to 1-col under 720px -------- */
@media (max-width: 720px) {
  .tlx .apex-kpi { grid-template-columns: repeat(2, 1fr); }
  .tlx .apex-topgrid { grid-template-columns: repeat(2, 1fr); }
  .tlx .apex-topgrid .apex-regime-panel { grid-column: 1 / -1; }
  .tlx .apex-ctx { grid-template-columns: 1fr; }
  .tlx .apex-sectors-panel { margin-bottom: 18px; }
  .tlx .apex-sec-row { grid-template-columns: 96px 1fr 34px; }
  .tlx .apex-mover { grid-template-columns: 1.2fr 52px 64px 1fr; }
  .tlx .apex-mover .apex-mover-macro, .tlx .apex-mover-head :nth-child(3),
  .tlx .apex-mover .apex-mover-alpha, .tlx .apex-mover-head :nth-child(4) { display: none; }
  /* v6: stack the KPI tiles + body columns */
  .tlx .apex-kstrip { grid-template-columns: 1fr; }
  .tlx .apex-body2 { grid-template-columns: 1fr; }
  .tlx .apex-body2 .apex-panel:first-child { margin-bottom: 8px; }
}

/* ===========================================================================
   apex_screener_redesign — Screener filter bar + dense signal table (mockup v5,
   operator-approved). Template + CSS only; the header band reuses the v6 chrome
   (.apex-headerbar / .apex-fresh / .apex-mkt) so it is byte-identical across the
   Dashboard / Radar / Screener tabs.

   THEME NOTE: the mockup pinned dark-only hex — pale weak-level greens/reds
   (#86EFAC / #FCA5A5) and dark tag backgrounds (#052E16 …) — that are illegible
   on the light theme. To honour the brief's "light + dark both correct" gate the
   colour STRUCTURE is preserved but mapped onto the theme-aware tokens
   (var(--green) / --red / --amber / --accent); only the bright STRONG-level hex
   (#22C55E / #EF4444) — already this page family's sanctioned signal hex — stay
   hardcoded, because they read on both themes.
   =========================================================================== */

/* --- filter bar: pressure chips (icon + abbrev, colour-coded per level) ----- */
.tlx .apex-scr-chip.p-sbu { color: #22C55E; border-color: rgba(34,197,94,.45); }
.tlx .apex-scr-chip.p-bu  { color: var(--green); border-color: var(--green-soft); }
.tlx .apex-scr-chip.p-wb  { color: var(--red); border-color: var(--red-soft); }
.tlx .apex-scr-chip.p-sb  { color: #EF4444; border-color: rgba(239,68,68,.45); }
.tlx .apex-scr-chip.p-sbu.is-active { color: #22C55E; background: rgba(34,197,94,.14); border-color: #22C55E; }
.tlx .apex-scr-chip.p-bu.is-active  { color: var(--green); background: var(--green-soft); border-color: var(--green); }
.tlx .apex-scr-chip.p-wb.is-active  { color: var(--red); background: var(--red-soft); border-color: var(--red); }
.tlx .apex-scr-chip.p-sb.is-active  { color: #EF4444; background: rgba(239,68,68,.14); border-color: #EF4444; }
/* the Neutral chip keeps the default chip styling; its active state uses the
   generic .apex-scr-chip.is-active accent (brief: "N … on = accent blue"). */

/* --- filter bar: Market-Pulse-style sort buttons (Δ% · Pressure) ----------- */
.tlx .apex-scr-sort { font-family: var(--mono); font-size: 11.5px; font-weight: 500; color: var(--text-2);
  background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 5px 11px;
  cursor: pointer; display: inline-flex; align-items: center; gap: 6px; transition: all var(--transition-fast); }
.tlx .apex-scr-sort:hover { color: var(--text); border-color: var(--border-strong); }
.tlx .apex-scr-sort.is-active { color: var(--text); border-color: var(--border-strong); }
.tlx .apex-scr-sort i { font-size: 13px; color: var(--text-3); }

/* --- pattern legend strip (one line between the filter bar and the table) --- */
.tlx .apex-plegend { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin: 0 0 12px; font-size: 11px; }
.tlx .apex-plegend-label { font-family: var(--mono); font-size: 9.5px; text-transform: uppercase;
  letter-spacing: .05em; color: var(--text-3); font-weight: 600; margin-right: 2px; }
.tlx .apex-plegend-desc { color: var(--text-3); font-size: 11px; margin-right: 10px; }

/* --- pattern tags (shared: legend + the W/D/H columns). Tinted bg + colour
   text via the -soft tokens, so they flip with the theme (mirrors .apex-stag). - */
.tlx .apex-ptag { display: inline-flex; align-items: center; font-family: var(--mono); font-size: 10.5px;
  line-height: 1.45; padding: 1px 6px; border-radius: 4px; white-space: nowrap; }
.tlx .apex-ptag.asc  { color: var(--green); background: var(--green-soft); }
.tlx .apex-ptag.desc { color: var(--red); background: var(--red-soft); }
.tlx .apex-ptag.rng  { color: var(--amber); background: var(--amber-soft); }
.tlx .apex-ptag.tri  { color: var(--accent-text); background: var(--accent-soft); }
.tlx .apex-ptag.np   { color: var(--text-3); background: transparent; padding-left: 0; padding-right: 0; }

/* --- pressure cell: icon + text, NO box, colour only (5 levels) ------------ */
.tlx .apex-prs { display: inline-flex; align-items: center; gap: 4px; font-size: 11px; font-weight: 500; white-space: nowrap; }
.tlx .apex-prs i { font-size: 12px; }
.tlx .apex-prs.lvl-sbu { color: #22C55E; }
.tlx .apex-prs.lvl-bu  { color: var(--green); }
.tlx .apex-prs.lvl-n   { color: var(--text-3); }
.tlx .apex-prs.lvl-wb  { color: var(--red); }
.tlx .apex-prs.lvl-sb  { color: #EF4444; }

/* --- signal cell: muted "No Setup" / accent + medium for an active signal --- */
.tlx .apex-scr-table .apex-sig { display: block; max-width: 100%; }
.tlx .apex-sig.on { color: var(--accent-text); font-weight: 500; }

/* --- whale ₹Cr cells: Buy green / Sell red / Net signed, tabular, no bold ----
   The mockup pinned #22C55E / #E24B4A; mapped to theme tokens so they read on
   the light theme too, and Net reuses the shared .pos/.neg colour. ---------- */
.tlx .apex-scr-table .apex-whale-buy   { color: var(--green); }
.tlx .apex-scr-table .apex-whale-sell  { color: var(--red); }
.tlx .apex-scr-table td.apex-whale-net { font-variant-numeric: tabular-nums; }

/* --- engine-scores: a row of 12 mini score boxes (replaces the old Trail) ----
   20×18 boxes, 3px radius; coloured by score sign with the pattern-tag -soft
   token pair so they flip with the theme; an idle/empty cycle is a faint dot. - */
.tlx .apex-es-wrap { display: inline-flex; flex-wrap: nowrap; gap: 2px; align-items: center; }
.tlx .apex-es { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 18px;
  border-radius: 3px; font-family: var(--mono); font-size: 10px; font-weight: 500; line-height: 1;
  font-variant-numeric: tabular-nums; flex: 0 0 auto; }
.tlx .apex-es.p     { color: var(--green); background: var(--green-soft); }
.tlx .apex-es.n     { color: var(--red); background: var(--red-soft); }
.tlx .apex-es.z     { color: var(--text-3); background: var(--surface-2); }
.tlx .apex-es.blank { color: var(--text-3); background: transparent; opacity: .25; }

/* --- stacked ▲▼ sort indicator (Δ% · Pressure · Whale headers) ------------- */
.tlx .apex-sortpair { display: inline-flex; flex-direction: column; margin-left: 4px; line-height: .7; vertical-align: middle; }
.tlx .apex-sortpair span { font-size: 7px; color: var(--text-3); opacity: .45; }
.tlx .apex-sortpair span.on { opacity: 1; color: var(--accent-text); }

/* --- the dense table: fixed layout (colgroup widths), hairline rows, no bold -
   11 leaf columns now (Whale split into Buy/Sell/Net + the 12-box Engine scores)
   under a 2-row header, so widths come from <colgroup> — th:nth-child would mis-
   index across the grouped header. min-width is sized so the 12 score boxes never
   clip; the base .table-wrap scrolls horizontally below it. -------------------- */
.tlx .apex-scr-table { table-layout: fixed; min-width: 1040px; }
.tlx .apex-scr-table th { padding: 6px 7px; font-size: 9.5px; vertical-align: bottom; }
.tlx .apex-scr-table th.num { text-align: right; }
/* `display: table-cell` re-asserts the cell box. The generic `.tlx .ctr` flex
   utility (the OI ladder's centered <div>, line ~1059) shares this class name and
   would otherwise clobber these W/D/H/Whale cells' default table-cell display —
   ejecting them from the grid so they stack vertically. Specificity here (0,3,1)
   beats `.tlx .ctr` (0,2,0); the shared flex utility stays intact for the ladder. */
.tlx .apex-scr-table th.ctr, .tlx .apex-scr-table td.ctr { text-align: center; display: table-cell; }
.tlx .apex-scr-table td { padding: 7px 7px; border-bottom: 1px solid var(--border); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; font-weight: 400; }
.tlx .apex-scr-table tbody tr:hover td { background: var(--surface-2); }
.tlx .apex-scr-table .apex-scr-sym { font-weight: 500; color: var(--text); }
/* column-group separators — a hairline on the first column of each group
   (W starts the pattern group · Buy the whale group · Engine scores). */
.tlx .apex-scr-table th.apex-grp, .tlx .apex-scr-table td.apex-grp {
  border-left: 1px solid var(--border); padding-left: 12px; }
/* colgroup widths (sum 100%); Engine scores gets the most room so its 12 fixed-
   width boxes sit without clipping. */
.tlx .apex-scr-table .c-sym   { width: 9%; }
.tlx .apex-scr-table .c-pct   { width: 7%; }
.tlx .apex-scr-table .c-prs   { width: 12%; }
.tlx .apex-scr-table .c-sig   { width: 13%; }
.tlx .apex-scr-table .c-wdh   { width: 5%; }    /* W · D · H (×3) */
.tlx .apex-scr-table .c-whale { width: 6%; }    /* Buy · Sell · Net (×3) */
.tlx .apex-scr-table .c-es    { width: 26%; }   /* Engine scores (12 boxes) */

/* ============================================================================
   Subscribe page (subscribe_page_v2) — feature-comparison table + billing-period
   / order panels (replaces the old inline sub-card grid). Tokens are this repo's
   real names: the v3 mockup's generic vocabulary (--text-primary, --fill-accent,
   --surface-1, --bg-accent, --border-strong, --radius, --text-success …) is
   translated here to --text/--text-2/--text-3, --accent/--accent-soft/--on-accent,
   --surface, --color-border-strong, --radius-*, --green/--green-soft. Scoped under
   .tlx like every other page surface.
   ============================================================================ */
.tlx .sub-layout { display: grid; grid-template-columns: 1fr 210px; gap: var(--space-5); align-items: start; }

/* --- Left: feature comparison table ------------------------------------- */
.tlx .sub-table { width: 100%; border-collapse: collapse; }
.tlx .sub-table th { padding: 10px 12px; text-align: center; vertical-align: bottom;
  font-size: var(--text-sm); font-weight: 500; border-bottom: 0.5px solid var(--border); }
.tlx .sub-table th.feat-col { text-align: left; font-size: var(--text-2xs); font-weight: 500;
  letter-spacing: .08em; text-transform: uppercase; color: var(--text-3); }
.tlx .sub-table th .sub-price { display: block; margin-top: 2px; font-size: var(--text-2xs);
  font-weight: 400; color: var(--text-3); }
.tlx .sub-cb-wrap { margin-bottom: 8px; }
/* `.sub-cb` is the plan selector — a single-select RADIO (round), not a checkbox. */
.tlx .sub-cb { display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 50%;
  border: 1.5px solid var(--color-border-strong); background: none; cursor: pointer;
  vertical-align: middle; transition: background .12s, border-color .12s; }
.tlx .sub-cb.on { background: var(--accent); border-color: var(--accent); }
.tlx .sub-cb.on::after { content: ''; display: block; width: 6px; height: 6px;
  border-radius: 50%; background: var(--on-accent); }
.tlx .sub-table td { padding: 9px 12px; text-align: center; font-size: var(--text-sm);
  border-bottom: 0.5px solid var(--border); }
.tlx .sub-table td.feat { text-align: left; color: var(--text-2); }
.tlx .sub-table tr:last-child td { border-bottom: none; }
.tlx .sub-table tbody tr:hover td { background: var(--surface); }
.tlx .sub-chk { color: var(--green); font-size: var(--text-base); }
.tlx .sub-dsh { color: var(--text-3); font-size: var(--text-xs); }
.tlx .sub-free { margin-left: 2px; font-size: var(--text-2xs); background: var(--green-soft);
  color: var(--green); padding: 1px 6px; border-radius: var(--radius-pill); vertical-align: middle; }
.tlx .sub-note { font-size: var(--text-2xs); color: var(--text-3); margin-top: 8px; }
/* Per-plan launch gate (§F): a column whose bundle isn't all-launched dims and
   carries a "Launching soon" tag; Pay stays disabled for it (JS + server). */
.tlx .sub-table th.sub-col-soon .sub-cb { opacity: .5; }
.tlx .sub-soon-tag { display: block; margin-top: 3px; font-size: var(--text-2xs);
  font-weight: 600; color: var(--amber); background: var(--amber-soft);
  padding: 1px 6px; border-radius: var(--radius-pill); }

/* --- Right: stacked panels ---------------------------------------------- */
.tlx .sub-right { display: flex; flex-direction: column; gap: var(--space-3); }
.tlx .sub-panel { background: var(--surface); border: 0.5px solid var(--border);
  border-radius: var(--radius-lg); padding: var(--space-4); }
.tlx .sub-panel-title { font-size: var(--text-2xs); font-weight: 500; letter-spacing: .08em;
  text-transform: uppercase; color: var(--text-3); margin-bottom: 10px; }

/* Billing period options */
.tlx .sub-period-opt { display: flex; align-items: center; gap: 10px; padding: 8px 10px;
  border: 0.5px solid transparent; border-radius: var(--radius-md); cursor: pointer; margin-bottom: 4px; }
.tlx .sub-period-opt:last-child { margin-bottom: 0; }
.tlx .sub-period-opt.on { background: var(--accent-soft); border-color: var(--accent); }
.tlx .sub-radio { width: 14px; height: 14px; flex-shrink: 0; border-radius: 50%;
  border: 1.5px solid var(--color-border-strong); }
.tlx .sub-radio.on { border-color: var(--accent); background: var(--accent);
  box-shadow: inset 0 0 0 3px var(--surface); }
.tlx .sub-pinfo { flex: 1; }
.tlx .sub-pname { font-size: var(--text-xs); font-weight: 500; }
.tlx .sub-psave { font-size: var(--text-2xs); color: var(--green); }
.tlx .sub-pprice { font-size: var(--text-xs); font-weight: 500; text-align: right; }
.tlx .sub-pnote { font-size: var(--text-2xs); color: var(--text-3); text-align: right; }

/* Order summary */
.tlx .sub-order-rows { display: flex; flex-direction: column; gap: 5px; margin-bottom: 8px; }
.tlx .sub-order-row { display: flex; justify-content: space-between; font-size: var(--text-xs);
  color: var(--text-2); }
.tlx .sub-empty { font-size: var(--text-xs); color: var(--text-3); }
.tlx .sub-order-total { display: flex; justify-content: space-between; font-size: var(--text-xs);
  font-weight: 500; color: var(--text); padding-top: 7px; border-top: 1px solid var(--color-border-strong); }
.tlx .sub-expiry { font-size: var(--text-2xs); color: var(--text-3); margin: 6px 0 12px; text-align: right; }
.tlx .sub-pay { display: block; width: 100%; padding: 9px; border: none; border-radius: var(--radius-md);
  font: inherit; font-size: var(--text-sm); font-weight: 500; text-align: center;
  background: var(--accent); color: var(--on-accent); cursor: pointer; }
.tlx a.sub-pay { text-decoration: none; }
.tlx .sub-pay:disabled { opacity: .5; cursor: not-allowed; }
.tlx .sub-msg { font-size: var(--text-xs); text-align: center; margin-top: 8px; }
.tlx .sub-msg.err { color: var(--red); }
.tlx .sub-paynote { font-size: var(--text-2xs); color: var(--text-3); line-height: 1.5;
  text-align: center; margin-top: 8px; }

/* Narrow screens: stack the order panel under the table. */
@media (max-width: 720px) {
  .tlx .sub-layout { grid-template-columns: 1fr; }
}

/* ===========================================================================
   IDEAS — product-ideas board (feedback_voting_v1). Approved mockup
   docs/ideas_page_b_kanban.html, retokenised to the brief-00 palette and
   namespaced under `.tlx.ideas` so the bespoke chips/badges/cards never collide
   with the shared .tlx .chip/.badge/.card components. List + board share one
   server render; the view toggle, category/status filters, and sort are
   client-side (ideas/list.html script).
   =========================================================================== */

/* page header */
.tlx.ideas .ihead { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.tlx.ideas .ihead .htitle { font-size: 16px; font-weight: 500; color: var(--text); }
.tlx.ideas .ihead .hsub { font-size: 12px; color: var(--text-3); margin-top: 2px; }
.tlx.ideas .btn-new {
  display: inline-flex; align-items: center; gap: 5px; padding: 7px 14px;
  border-radius: var(--radius-md); font-size: 12px; font-weight: 600;
  background: var(--accent); color: var(--on-accent); border: none; cursor: pointer;
  text-decoration: none; white-space: nowrap;
}
.tlx.ideas .btn-new:hover { background: var(--accent-hover, var(--accent)); }

/* filter bar */
.tlx.ideas .ifilters { display: flex; align-items: center; gap: 6px; margin-bottom: 16px; flex-wrap: wrap; }
.tlx.ideas .fchip {
  display: inline-flex; align-items: center; gap: 4px; padding: 4px 11px;
  border-radius: var(--radius-pill); font-size: 11px; border: 1px solid var(--border);
  color: var(--text-2); cursor: pointer; white-space: nowrap; background: transparent;
  font-family: var(--body);
}
.tlx.ideas .fchip:hover { color: var(--text); }
.tlx.ideas .fchip.on { background: var(--accent-soft); color: var(--accent-text); border-color: var(--accent); }
.tlx.ideas .fchip.view-on { background: var(--surface); color: var(--text); border-color: var(--border); }
.tlx.ideas .fsep { width: 1px; height: 16px; background: var(--border); margin: 0 3px; }
.tlx.ideas .isort {
  display: inline-flex; align-items: center; gap: 4px; padding: 5px 11px;
  border-radius: var(--radius-md); font-size: 11px; border: 1px solid var(--border);
  color: var(--text-2); cursor: pointer; margin-left: auto; background: var(--surface-2);
  text-decoration: none; font-family: var(--body);
}
.tlx.ideas .isort:hover { color: var(--text); }

/* status badge + category tag */
.tlx.ideas .sbadge { display: inline-block; padding: 2px 8px; border-radius: var(--radius-pill); font-size: 10px; font-weight: 600; }
.tlx.ideas .sbadge.open { background: var(--surface-2); color: var(--text-3); border: 1px solid var(--border); }
.tlx.ideas .sbadge.planned { background: var(--amber-soft); color: var(--amber); }
.tlx.ideas .sbadge.shipped { background: var(--green-soft); color: var(--green); }
.tlx.ideas .sbadge.rejected { background: var(--red-soft); color: var(--red); }
.tlx.ideas .ctag { display: inline-block; padding: 1px 7px; border-radius: var(--radius-xs); font-size: 10px; font-weight: 600; }
.tlx.ideas .ctag.improve { background: var(--accent-soft); color: var(--accent-text); }
.tlx.ideas .ctag.add { background: var(--green-soft); color: var(--green); }
.tlx.ideas .ctag.remove { background: var(--red-soft); color: var(--red); }

/* view visibility (toggled via data-view on the page root) + JS filter hiding */
.tlx.ideas .iboard { display: none; }
.tlx.ideas[data-view="board"] .ilist { display: none; }
.tlx.ideas[data-view="board"] .iboard { display: grid; }
.tlx.ideas[data-view="board"] .only-list { display: none; }
.tlx.ideas .is-hidden { display: none !important; }

/* ── LIST VIEW ── */
.tlx.ideas .ilist { display: flex; flex-direction: column; }
.tlx.ideas .irow { display: flex; align-items: center; gap: 14px; padding: 12px 0; border-bottom: 1px solid var(--border-2); }
.tlx.ideas .irow:last-child { border-bottom: none; }
.tlx.ideas .irank { display: flex; flex-direction: column; align-items: center; width: 44px; flex-shrink: 0; gap: 1px; }
.tlx.ideas .irank .num { font-size: 16px; font-weight: 600; line-height: 1; color: var(--text); font-variant-numeric: tabular-nums; }
.tlx.ideas .irank .lbl { font-size: 9px; color: var(--text-3); text-transform: uppercase; letter-spacing: .05em; }
.tlx.ideas .ibar { flex: 1; min-width: 0; }
.tlx.ideas .ititle { font-size: 13px; font-weight: 500; margin-bottom: 4px; line-height: 1.3; color: var(--text); text-decoration: none; display: inline-block; }
.tlx.ideas a.ititle:hover { color: var(--accent-text); }
.tlx.ideas .imeta { display: flex; align-items: center; gap: 6px; margin-bottom: 6px; flex-wrap: wrap; }
.tlx.ideas .iauthor { font-size: 10px; color: var(--text-3); }
.tlx.ideas .iprog { height: 3px; background: var(--border); border-radius: 2px; overflow: hidden; }
.tlx.ideas .iprog .fill { height: 100%; border-radius: 2px; background: var(--accent); }
.tlx.ideas .iprog .fill.shipped { background: var(--green); }
.tlx.ideas .ireward { font-size: 10px; color: var(--green); margin-top: 5px; display: flex; align-items: center; gap: 4px; }
.tlx.ideas .iact { display: flex; flex-direction: column; align-items: flex-end; gap: 5px; flex-shrink: 0; }
.tlx.ideas .ivote {
  display: inline-flex; align-items: center; gap: 4px; padding: 5px 12px;
  border-radius: var(--radius-md); font-size: 11px; font-weight: 600;
  border: 1px solid var(--border); cursor: pointer; background: transparent;
  color: var(--text-2); white-space: nowrap; font-family: var(--body);
}
.tlx.ideas .ivote:hover { color: var(--text); border-color: var(--border); }
.tlx.ideas .ivote.voted { background: var(--accent-soft); color: var(--accent-text); border-color: var(--accent); }

/* ── BOARD (KANBAN) VIEW ── */
.tlx.ideas .iboard { grid-template-columns: repeat(4, 1fr); gap: 10px; }
.tlx.ideas .icol { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 10px; min-width: 0; }
.tlx.ideas .icol-head { font-size: 10px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase; color: var(--text-3); margin-bottom: 9px; display: flex; align-items: center; justify-content: space-between; }
.tlx.ideas .icol-count { background: var(--surface-2); color: var(--text-3); padding: 1px 7px; border-radius: var(--radius-pill); font-size: 10px; }
.tlx.ideas .icard { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 9px 10px; margin-bottom: 6px; text-decoration: none; display: block; }
.tlx.ideas .icard:last-child { margin-bottom: 0; }
.tlx.ideas .icard:hover { border-color: var(--accent); }
.tlx.ideas .icard.planned { border-left: 2px solid var(--amber); }
.tlx.ideas .icard.shipped { border-left: 2px solid var(--green); }
.tlx.ideas .icard.rejected { border-left: 2px solid var(--red); opacity: .7; }
.tlx.ideas .icard-title { font-size: 12px; font-weight: 500; margin-bottom: 6px; line-height: 1.3; color: var(--text); }
.tlx.ideas .icard-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.tlx.ideas .icard-votes { font-size: 11px; color: var(--text-3); display: inline-flex; align-items: center; gap: 3px; font-variant-numeric: tabular-nums; }
.tlx.ideas .icard-votes.has-vote { color: var(--accent-text); }
.tlx.ideas .icard-votes.shipped { color: var(--green); }
.tlx.ideas .icard-reward { font-size: 10px; color: var(--green); margin-top: 5px; }
.tlx.ideas .icol-empty { font-size: 11px; color: var(--text-3); padding: 6px 2px; }

/* ── DETAIL PAGE ── */
.tlx.ideas .idetail { max-width: 720px; }
.tlx.ideas .idetail .dmeta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 4px 0 14px; }
.tlx.ideas .idetail .dtitle { font-size: 19px; font-weight: 600; color: var(--text); line-height: 1.3; }
.tlx.ideas .idetail .dbody { font-size: 13.5px; line-height: 1.7; color: var(--text-2); white-space: pre-wrap; margin-bottom: 18px; }
.tlx.ideas .vote-panel { display: flex; align-items: center; gap: 12px; margin-bottom: 18px; }
.tlx.ideas .vote-panel .vcount { font-size: 12px; color: var(--text-3); }
.tlx.ideas .vote-panel .vcount b { color: var(--text); font-weight: 600; }
.tlx.ideas .dnote { border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface); padding: 12px 14px; margin-bottom: 14px; }
.tlx.ideas .dnote .lbl { font-size: 10px; text-transform: uppercase; letter-spacing: .06em; color: var(--text-3); margin-bottom: 5px; }
.tlx.ideas .dnote .txt { font-size: 12.5px; color: var(--text-2); line-height: 1.6; }
.tlx.ideas .reward-banner {
  border: 1px solid var(--green); background: var(--green-soft); border-radius: var(--radius-md);
  padding: 13px 15px; margin-bottom: 16px; font-size: 13px; color: var(--text); line-height: 1.6;
}
.tlx.ideas .reward-banner b { color: var(--green); }
.tlx.ideas .dback { font-size: 12px; color: var(--text-3); text-decoration: none; display: inline-flex; align-items: center; gap: 5px; margin-bottom: 14px; }
.tlx.ideas .dback:hover { color: var(--text); }

/* ── SUBMIT FORM ── */
.tlx.ideas .iform { max-width: 620px; display: flex; flex-direction: column; gap: 18px; }
.tlx.ideas .ifield label { display: block; font-size: 12px; font-weight: 500; color: var(--text-2); margin-bottom: 6px; }
.tlx.ideas .ifield input[type="text"], .tlx.ideas .ifield textarea {
  width: 100%; background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius-md); padding: 9px 11px; font-size: 13px; color: var(--text);
  font-family: var(--body);
}
.tlx.ideas .ifield textarea { min-height: 120px; resize: vertical; line-height: 1.6; }
.tlx.ideas .ifield input:focus, .tlx.ideas .ifield textarea:focus { outline: none; border-color: var(--accent); }
.tlx.ideas .ifield .counter { font-size: 10px; color: var(--text-3); text-align: right; margin-top: 4px; }
.tlx.ideas .iradios { display: flex; flex-direction: column; gap: 8px; }
.tlx.ideas .iradio { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--text-2); cursor: pointer; }
.tlx.ideas .iradio input { accent-color: var(--accent); }
.tlx.ideas .iwarn {
  border: 1px solid var(--amber); background: var(--amber-soft); border-radius: var(--radius-md);
  padding: 11px 13px; font-size: 12.5px; color: var(--text-2); line-height: 1.6;
}
.tlx.ideas .iwarn a { color: var(--accent-text); }
.tlx.ideas .ierr { color: var(--red); font-size: 12.5px; }
.tlx.ideas .iform-actions { display: flex; align-items: center; gap: 10px; }

/* narrow screens: collapse the board to 2 then 1 columns */
@media (max-width: 980px) { .tlx.ideas[data-view="board"] .iboard { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .tlx.ideas[data-view="board"] .iboard { grid-template-columns: 1fr; } }

/* ============================================================================
   Admin Console v2 (admin_console_v2 brief) — the dense, flat redesign of the
   /admin/* surface. Lives in the .adm-* namespace, OUTSIDE .tlx (the admin body
   renders un-wrapped). Tokens only: the brief mockup's placeholder names map to
   the real brief-00 palette here once — text-primary -> --text, text-muted ->
   --text-3, fill-accent -> --accent, surface-1 -> --surface-2, radius -> radius-md,
   border-warning/bg-warning/text-warning -> --amber / --amber-soft / --amber.
   Typography rule (brief): nothing heavier than 500; labels/names 500, body 400.
   ============================================================================ */

/* --- Header eyebrow ----------------------------------------------------- */
.adm-head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  padding: 10px 0 8px; border-bottom: .5px solid var(--border); margin-bottom: 0; }
.adm-eyebrow { font-size: 11px; font-weight: 500; letter-spacing: .07em;
  text-transform: uppercase; color: var(--text-3); }
.adm-sub { font-size: 11px; color: var(--text-3); }

/* --- Tab strip (underline) ---------------------------------------------- */
.adm-tabs { display: flex; gap: 0; border-bottom: .5px solid var(--border);
  margin-bottom: 16px; overflow-x: auto; }
.adm-tab { padding: 7px 14px; font-size: 12px; color: var(--text-3);
  border: none; background: none; border-bottom: 2px solid transparent;
  margin-bottom: -1px; cursor: pointer; white-space: nowrap; text-decoration: none; }
.adm-tab:hover { color: var(--text-2); text-decoration: none; }
.adm-tab.on { color: var(--text); border-bottom-color: var(--accent); }

/* --- Switch strip ------------------------------------------------------- */
.adm-switch-strip { display: flex; gap: 0; border: .5px solid var(--border);
  border-radius: var(--radius-md); overflow: hidden; margin-bottom: 16px; }
.adm-sw-cell { display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding: 8px 14px; flex: 1; margin: 0;
  border-right: .5px solid var(--border); }
.adm-sw-cell:last-child { border-right: none; }
.adm-sw-info { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.adm-sw-name { font-size: 12px; color: var(--text); }
.adm-sw-desc { font-size: 10px; color: var(--text-3); }
.adm-sw-toggle { display: flex; align-items: center; gap: 6px; flex-shrink: 0;
  cursor: pointer; background: none; border: none; padding: 0; }
.adm-sw-toggle:disabled { cursor: not-allowed; opacity: .55; }
.adm-sw-pill { width: 34px; height: 18px; border-radius: 9px; position: relative;
  flex-shrink: 0; transition: background .15s; }
.adm-sw-pill.on { background: var(--accent); }
.adm-sw-pill.off { background: var(--surface-2); border: .5px solid var(--border); }
.adm-sw-pill::after { content: ''; position: absolute; top: 2px; width: 12px;
  height: 12px; border-radius: 50%; background: #fff; transition: left .15s; }
.adm-sw-pill.on::after { left: 18px; }
.adm-sw-pill.off::after { left: 2px; }
.adm-sw-label { font-size: 10px; font-weight: 500; width: 22px; text-align: left; }
.adm-sw-label.on { color: var(--accent-text); }
.adm-sw-label.off { color: var(--text-3); }
.adm-sw-meta { color: var(--text-3); white-space: nowrap; }
.adm-sw-actions { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.adm-sw-actions form { margin: 0; }
.adm-run-btn { padding: 4px 10px; border-radius: var(--radius-sm);
  border: 1px solid var(--color-border-strong); background: var(--surface-2); color: var(--text-2);
  font-size: 11px; line-height: 1; cursor: pointer; white-space: nowrap; }
.adm-run-btn:hover { color: var(--text); border-color: var(--text-3); background: var(--surface); }
.adm-run-form { display: flex; align-items: center; gap: 6px; }
.adm-run-days { width: 44px; padding: 3px 6px; border-radius: var(--radius-sm);
  border: 1px solid var(--color-border-strong); background: var(--surface-2); color: var(--text);
  font-size: 11px; line-height: 1; text-align: center; }
.adm-run-days:focus { outline: none; border-color: var(--accent); }
.adm-run-days-lbl { font-size: 10px; color: var(--text-3); margin-right: 2px; }

/* --- Section block + label ---------------------------------------------- */
.adm-block { margin-bottom: 16px; }
.adm-sec { display: flex; align-items: center; gap: 6px;
  font-size: 10px; font-weight: 500; letter-spacing: .07em; text-transform: uppercase;
  color: var(--text-3); margin-bottom: 8px; }
.adm-hint { font-size: 11px; color: var(--text-3); margin: 0; padding: 2px 0 0; }
.adm-two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 720px) { .adm-two-col { grid-template-columns: 1fr; } }

/* --- Search row --------------------------------------------------------- */
.adm-search { margin-bottom: 6px; }
.adm-search .input { width: 100%; font-size: 12px; padding: 5px 10px;
  background: var(--surface-2); }

/* --- Dense list-box ----------------------------------------------------- */
.adm-list { border: .5px solid var(--border); border-radius: var(--radius-md);
  overflow: hidden; }
.adm-list-row { display: flex; align-items: center; gap: 8px; padding: 6px 12px;
  border-bottom: .5px solid var(--border); font-size: 12px; margin: 0; }
.adm-list-row:last-child { border-bottom: none; }
.adm-list-row:hover { background: var(--surface-2); }
.adm-row-main { flex: 1; min-width: 0; color: var(--text-2);
  overflow: hidden; text-overflow: ellipsis; }
.adm-row-meta { font-size: 11px; color: var(--text-3); }
.adm-list-foot { padding: 5px 12px; font-size: 11px; color: var(--text-3);
  border-top: .5px solid var(--border); background: var(--surface-2); }
.adm-list-row form { margin: 0; }

/* --- Badges (no bold) --------------------------------------------------- */
.adm-badges { display: flex; gap: 4px; flex-shrink: 0; }
.adm-badge { display: inline-block; padding: 1px 6px; border-radius: 3px;
  font-size: 10px; font-weight: 500; line-height: 1.5; }
.adm-badge.admin   { background: var(--accent-soft); color: var(--accent-text); }
.adm-badge.comp    { background: var(--green-soft);  color: var(--green); }
.adm-badge.warn    { background: var(--amber-soft);  color: var(--amber); }
.adm-badge.neutral { background: var(--surface-2);   color: var(--text-3); }

/* --- Edit / small list buttons ------------------------------------------ */
.adm-edit-btn { font-size: 11px; padding: 2px 7px; border-radius: 3px;
  border: .5px solid var(--border); background: none; color: var(--text-3);
  cursor: pointer; text-decoration: none; line-height: 1.5; }
.adm-edit-btn:hover { color: var(--text); border-color: var(--color-border-strong);
  text-decoration: none; }
.adm-edit-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.adm-list-row .btn { padding: 3px 9px; font-size: 11px; }

/* --- Inline-editable exception row (Edit -> Apply, checkboxes in place) ------
   Current-exceptions rows edit IN PLACE instead of loading the top editor: the
   Edit label flips a pure-CSS toggle (.adm-exc-toggle — nameless + visually
   hidden, so it never posts) that swaps the collapsed badges+Edit cluster for an
   inline Active/Admin/Comp-path checkbox group + Apply. Robust to any HTMX swap
   (no JS); Apply is the same native PRG POST the top editor uses. */
.adm-exc-row { position: relative; flex-wrap: wrap; row-gap: 6px; }
.adm-exc-toggle { position: absolute; width: 0; height: 0; opacity: 0; pointer-events: none; }
.adm-exc-view { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.adm-exc-edit { display: none; flex: 1; align-items: center;
  justify-content: flex-end; flex-wrap: wrap; gap: 6px 12px; }
/* Toggled-open: hide the badges/Edit, reveal the checkbox group, and let the email
   shrink so the controls own the row (wrapping right-aligned on narrow widths). */
.adm-exc-toggle:checked ~ .adm-exc-view { display: none; }
.adm-exc-toggle:checked ~ .adm-exc-edit { display: flex; }
.adm-exc-toggle:checked ~ .adm-row-main { flex: 0 0 auto; }

.adm-chips { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 12px; }
.adm-chk { display: inline-flex; align-items: center; gap: 5px; line-height: 1.5;
  font-size: 11px; color: var(--text-2); cursor: pointer; white-space: nowrap; }
.adm-chk input { flex-shrink: 0; width: 13px; height: 13px; margin: 0;
  accent-color: var(--accent); cursor: pointer; }
.adm-chk.is-disabled { opacity: .45; cursor: not-allowed; }
.adm-chk.is-disabled input { cursor: not-allowed; }
/* Hairline divider between the access (Active/Admin) and comp-path groups. */
.adm-chk-sep { align-self: stretch; width: 0; margin: 1px 0;
  border-left: .5px solid var(--border); }
.adm-exc-cancel { color: var(--text-3); }

/* --- Inline status (empty states) --------------------------------------- */
.adm-status-row { display: flex; align-items: center; gap: 8px; padding: 6px 12px;
  border: .5px solid var(--border); border-radius: var(--radius-md);
  font-size: 11px; color: var(--text-3); }

/* --- Panels (form containers) ------------------------------------------- */
.adm-panel { padding: 10px 12px; border: .5px solid var(--border);
  border-radius: var(--radius-md); }
.adm-panel-label { font-size: 10px; font-weight: 500; letter-spacing: .07em;
  text-transform: uppercase; color: var(--text-3); margin-bottom: 8px; }
.adm-field { margin-bottom: 8px; }
.adm-field label { display: block; font-size: 11px; color: var(--text-3);
  margin-bottom: 3px; }
.adm-panel .input, .adm-panel select.input { width: 100%; font-size: 12px;
  padding: 5px 9px; background: var(--surface-2); }
.adm-panel select.input { appearance: auto; }
.adm-form-note { font-size: 10px; color: var(--text-3); margin: 6px 0 0;
  line-height: 1.4; }

/* --- Product & pricing panel (admin_product_pricing) -------------------- */
/* Launch strip wraps (6 products, unlike the 2-3-cell job strips). */
.adm-launch-strip { flex-wrap: wrap; }
.adm-launch-strip .adm-sw-cell { flex: 1 1 240px;
  border-bottom: .5px solid var(--border); }
/* Per-plan monthly editors: name · ₹input/mo · derived q/a · Save. */
.adm-price-row { display: flex; align-items: center; gap: 10px; margin: 0;
  padding: 6px 0; border-bottom: .5px solid var(--border); }
.adm-price-row:last-child { border-bottom: none; }
.adm-price-name { flex: 0 0 96px; font-size: 12px; color: var(--text); font-weight: 500; }
.adm-price-in { display: inline-flex; align-items: center; gap: 3px; font-size: 12px;
  color: var(--text-3); }
.adm-price-in .input { width: 84px; text-align: right; }
.adm-price-per { color: var(--text-3); }
.adm-price-derived { flex: 1 1 auto; font-size: 11px; color: var(--text-3);
  font-family: var(--mono); }
.adm-price-save { padding: 3px 12px; font-size: 11px; flex-shrink: 0; }

/* --- Export row (top-right) --------------------------------------------- */
.adm-export { display: flex; gap: 8px; justify-content: flex-end; margin-bottom: 12px; }
.adm-export .btn { padding: 3px 9px; font-size: 11px; }

/* --- Dense table (subscriptions / grants / ingest) ---------------------- */
.adm-tbl { width: 100%; border-collapse: collapse; font-size: 12px; }
.adm-tbl th { font-size: 10px; color: var(--text-3); padding: 4px 8px;
  text-align: left; border-bottom: .5px solid var(--border); font-weight: 500;
  text-transform: uppercase; letter-spacing: .04em; white-space: nowrap; }
.adm-tbl td { padding: 5px 8px; border-bottom: .5px solid var(--border);
  color: var(--text-2); white-space: nowrap; }
.adm-tbl tr:last-child td { border-bottom: none; }
.adm-tbl .num { text-align: right; }
.adm-tbl-wrap { overflow-x: auto; border: .5px solid var(--border);
  border-radius: var(--radius-md); }
.adm-y { color: var(--green); }
.adm-pill-done { display: inline-block; padding: 1px 6px; border-radius: 3px;
  font-size: 10px; font-weight: 500; background: var(--green-soft); color: var(--green); }
.adm-pill-run  { background: var(--amber-soft); color: var(--amber); }
.adm-pill-err  { background: var(--red-soft);   color: var(--red); }

/* --- Kite token (Configuration) ----------------------------------------- */
.adm-token { display: flex; align-items: center; gap: 10px; padding: 7px 12px;
  background: var(--surface-2); border: .5px solid var(--border);
  border-radius: var(--radius-md); margin-bottom: 10px; font-size: 12px; }
.adm-token-dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0;
  background: var(--green); }
.adm-token-dot.off { background: var(--red); }
.adm-token-main { flex: 1; min-width: 0; }
.adm-token-when { font-size: 10px; color: var(--text-3); }
.adm-token-path { font-size: 10px; color: var(--text-3); font-family: var(--code);
  margin-top: 1px; word-break: break-all; }
.adm-step-desc { font-size: 12px; color: var(--text-2); margin: 0 0 7px; }
.adm-step .input { width: 100%; font-size: 12px; padding: 5px 9px;
  background: var(--surface-2); margin-bottom: 6px; }

/* --- Maintenance (Configuration, bottom, amber) ------------------------- */
.adm-maintenance { border: .5px solid var(--amber); background: var(--amber-soft);
  border-radius: var(--radius-md); padding: 10px 12px; margin-top: 16px; }
.adm-maint-label { display: flex; align-items: center; gap: 8px; font-size: 10px;
  font-weight: 500; letter-spacing: .06em; text-transform: uppercase;
  color: var(--amber); margin-bottom: 6px; }
.adm-maint-state { font-weight: 500; }
.adm-maint-state.on  { color: var(--amber); }
.adm-maint-state.off { color: var(--text-3); }
.adm-maint-row { display: flex; align-items: center; gap: 10px; margin: 0; }
.adm-maint-input { flex: 1; padding: 5px 9px; border-radius: var(--radius-md);
  border: .5px solid var(--amber); background: var(--surface-2); color: var(--text);
  font-size: 12px; }
.adm-maint-input::placeholder { color: var(--text-3); }
.adm-btn-warn { padding: 5px 12px; border-radius: var(--radius-md); font-size: 12px;
  cursor: pointer; border: .5px solid var(--amber); background: none;
  color: var(--amber); white-space: nowrap; }
.adm-btn-warn:hover { background: var(--amber-soft); }
.adm-maint-msg { font-size: 11px; color: var(--text-2); margin: 8px 0 0; }

/* ============================================================================
   Public landing v3 (GET /) -- .lp-* namespace ONLY. Rebuild of the guest
   landing against the Figr "Landing Page" design (project 6d75327f). base.css /
   tokens.css are NOT touched: the landing carries its OWN dark palette in local
   `--lp-*` vars scoped to `.lp-page`, so it renders identically regardless of the
   global light/dark theme (the marketing surface is dark-only by design). The
   brand mark stays the Firefly logo via the shared brand() macro (operator ruling
   -- do NOT swap in the Figr Sigma glyph). Display type = Sora, mono = JetBrains
   Mono (loaded from Google Fonts in the page's head_extra), body = Inter.
   The shell rule `.app-shell.is-landing .content` (base.css) makes content
   full-bleed so each full-width band (trust strip, spotlight, CTA) can span edge
   to edge while `.lp-wrap` centres the inner column at 1200px.
   ============================================================================ */
.lp-page {
  --lp-bg: #0A0E17;
  --lp-s1: #0F1420;
  --lp-s2: #131A28;
  --lp-s3: #1A2333;
  --lp-line: #1E2636;
  --lp-line2: #2B3547;
  --lp-fg: #F1F5F9;
  --lp-muted: #94A3B8;
  --lp-subtle: #647084;
  --lp-primary: #2563EB;
  --lp-primary-h: #1D4ED8;
  --lp-primary-l: #3B82F6;
  --lp-green: #34E0A1;
  --lp-green-dim: #12241E;
  --lp-red: #F76B6B;
  --lp-red-dim: #2A1618;
  --lp-magenta: #E879C9;
  --lp-orange: #FB923C;
  --lp-purple: #A78BFA;
  --lp-cyan: #22D3EE;
  --lp-glow: 0 0 0 1px rgba(37,99,235,.18), 0 24px 60px -20px rgba(37,99,235,.35);
  --lp-card: 0 20px 50px -24px rgba(0,0,0,.7);
  --lp-display: 'Sora', system-ui, sans-serif;
  --lp-mono: 'JetBrains Mono', ui-monospace, monospace;
  --lp-max: 1200px;

  width: 100%;
  min-height: 100vh;
  background: var(--lp-bg);
  color: var(--lp-fg);
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
.app-shell.is-landing { background: #0A0E17; }
.app-shell.is-landing .content { padding: 0; max-width: none; }
.lp-page a { text-decoration: none; color: inherit; }
.lp-page ::selection { background: rgba(37,99,235,.30); }
.lp-mono { font-family: var(--lp-mono); }
.lp-disp { font-family: var(--lp-display); }
/* .lp-band (NOT .lp-wrap): base.css owns an orphaned `.is-landing .lp-wrap` rule
   (0,2,0) that would override this one and strip the bands' padding -> section
   overlap. Renamed off that collision; base.css stays untouched (off-limits). */
.lp-band { max-width: var(--lp-max); margin: 0 auto; padding: 0 24px; width: 100%; }

/* --- reveal-on-scroll (IntersectionObserver toggles .is-in) --- */
.lp-reveal { opacity: 0; transform: translateY(14px);
  transition: opacity .7s cubic-bezier(.22,1,.36,1), transform .7s cubic-bezier(.22,1,.36,1); }
.lp-reveal.is-in { opacity: 1; transform: none; }
.lp-fade { opacity: 0; transition: opacity .9s ease; }
.lp-fade.is-in { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .lp-reveal, .lp-fade { opacity: 1 !important; transform: none !important; transition: none; }
  .lp-spoke { opacity: 1 !important; animation: none !important; }
  .lp-fbub { animation: none !important; }
}

/* --- shared buttons --- */
.lp-btn { display: inline-flex; align-items: center; gap: 8px; border-radius: 10px;
  padding: 14px 22px; font-size: 15px; font-weight: 500; line-height: 1;
  border: 1px solid transparent; cursor: pointer; transition: background .18s, border-color .18s; }
.lp-btn svg { width: 17px; height: 17px; }
.lp-btn-primary { background: var(--lp-primary); color: #fff; }
.lp-btn-primary:hover { background: var(--lp-primary-h); }
.lp-btn-ghost { border-color: var(--lp-line2); color: var(--lp-fg); }
.lp-btn-ghost:hover { background: var(--lp-s2); }
.lp-btn-sm { padding: 9px 16px; font-size: 14px; border-radius: 9px; }

/* Phosphor icons on the landing (font loaded globally via fonts.css) */
.lp-page .ph { line-height: 1; display: inline-block; }
.lp-btn .ph { font-size: 17px; }
.lp-nav .ph { font-size: 15px; }
.lp-pillar-ic .ph { font-size: 20px; }
.lp-torpedo-ic .ph { font-size: 22px; }
.lp-module-ic .ph { font-size: 24px; }
.lp-module-link .ph, .lp-torpedo-link .ph { font-size: 15px; }

/* --- top nav (fixed) --- */
.lp-nav { position: fixed; top: 0; left: 0; right: 0; z-index: 50;
  border-bottom: 1px solid transparent; transition: background .3s, border-color .3s; }
.lp-nav.is-scrolled { background: rgba(10,14,23,.85); backdrop-filter: blur(10px);
  border-bottom-color: var(--lp-line); }
.lp-nav-in { height: 64px; display: flex; align-items: center; justify-content: space-between; }
.lp-nav-left { display: flex; align-items: center; gap: 40px; }
.lp-nav-links { display: flex; align-items: center; gap: 28px; font-size: 14px; color: var(--lp-muted); }
.lp-nav-links a:hover { color: var(--lp-fg); }
.lp-nav-right { display: flex; align-items: center; gap: 16px; }
.lp-beta { display: inline-flex; align-items: center; gap: 6px; border-radius: 999px;
  border: 1px solid #1E3A2F; background: var(--lp-green-dim); padding: 4px 10px;
  font-size: 12px; font-weight: 500; color: var(--lp-green); }
.lp-beta .lp-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--lp-green); }
.lp-nav-signin { font-size: 14px; color: var(--lp-muted); }
.lp-nav-signin:hover { color: var(--lp-fg); }
/* keep the shared brand lockup on the dark landing legible */
.lp-page .brand-word { color: var(--lp-fg); }
.lp-page .brand-word .accent { color: var(--lp-primary-l); }
.lp-page .brand-tagline { color: var(--lp-subtle); }
@media (max-width: 820px) { .lp-nav-links, .lp-nav-signin, .lp-beta { display: none; } }

/* --- hero --- */
.lp-hero { position: relative; overflow: hidden; padding: 132px 0 96px; }
.lp-hero-glow { pointer-events: none; position: absolute; top: -96px; right: 0;
  width: 720px; height: 720px; border-radius: 50%; opacity: .14; filter: blur(64px);
  background: radial-gradient(circle, var(--lp-primary) 0%, transparent 60%); }
.lp-hero-grid { position: relative; display: grid; grid-template-columns: 1.05fr .95fr;
  gap: 56px; align-items: center; }
.lp-eyebrow { display: inline-flex; align-items: center; gap: 8px; border-radius: 999px;
  border: 1px solid #1E2F52; background: #0F1830; padding: 6px 12px; font-size: 12px;
  font-weight: 500; color: var(--lp-primary-l); }
.lp-eyebrow .lp-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--lp-green); }
.lp-h1 { font-family: var(--lp-display); font-weight: 600; font-size: 60px; line-height: 1.04;
  letter-spacing: -.02em; margin: 24px 0 0; }
.lp-h1 .lp-accent { color: var(--lp-green); text-shadow: 0 0 18px rgba(52,224,161,.45); }
.lp-hero-sub { max-width: 520px; margin: 24px 0 0; font-size: 18px; line-height: 1.6; color: var(--lp-subtle);
  font-weight: 400; /* element-proof: this class now styles the semantic H1 (SEO Phase A) */ }
.lp-hero-sub strong { color: var(--lp-fg); font-weight: 500; }
.lp-hero-ctas { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 32px; }
.lp-hero-note { margin-top: 16px; font-size: 14px; color: var(--lp-subtle); }

/* hero montage card */
.lp-montage { border-radius: 18px; border: 1px solid var(--lp-line);
  background: rgba(19,26,40,.8); padding: 20px; box-shadow: var(--lp-card); }
.lp-montage-head { display: flex; align-items: center; justify-content: space-between;
  font-family: var(--lp-mono); }
.lp-montage-head .lp-l { font-size: 11px; letter-spacing: .06em; color: var(--lp-muted); }
.lp-montage-head .lp-r { font-size: 10px; color: var(--lp-subtle); }
.lp-galaxy { margin: 4px auto 0; max-width: 360px; aspect-ratio: 1; }
.lp-galaxy svg { width: 100%; height: 100%; display: block; }
.lp-spoke { opacity: 0; animation: lp-spoke .9s ease forwards; }
@keyframes lp-spoke { to { opacity: 1; } }
.lp-galaxy-legend { display: flex; align-items: center; justify-content: center; gap: 16px;
  margin-top: 4px; font-size: 11px; color: var(--lp-muted); }
.lp-galaxy-legend span { display: inline-flex; align-items: center; gap: 6px; }
.lp-galaxy-legend i { width: 8px; height: 8px; border-radius: 50%; }

.lp-lean { margin-top: 16px; border-radius: 12px; border: 1px solid var(--lp-line);
  background: var(--lp-s1); padding: 12px; }
.lp-lean-head { display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 8px; font-family: var(--lp-mono); }
.lp-lean-head .lp-l { font-size: 10px; letter-spacing: .06em; color: var(--lp-muted); }
.lp-lean-head .lp-r { font-size: 10px; color: var(--lp-subtle); }
.lp-lean-bar { display: flex; height: 10px; border-radius: 999px; overflow: hidden; }
.lp-lean-bar i { display: block; height: 100%; }
.lp-lean-legend { display: flex; justify-content: space-between; margin-top: 6px;
  font-family: var(--lp-mono); font-size: 11px; }
.lp-tiles { display: grid; grid-template-columns: repeat(3,1fr); gap: 10px; margin-top: 12px; }
.lp-tile { border-radius: 12px; border: 1px solid var(--lp-line); background: var(--lp-s1); padding: 8px 12px; }
.lp-tile .lp-tl { font-family: var(--lp-mono); font-size: 10px; letter-spacing: .04em; color: var(--lp-subtle); }
.lp-tile .lp-tv { font-family: var(--lp-mono); font-size: 16px; font-weight: 600; }
.lp-c-green { color: var(--lp-green); }
.lp-c-red { color: var(--lp-red); }
.lp-c-fg { color: var(--lp-fg); }
.lp-c-primary { color: var(--lp-primary-l); }
.lp-c-muted { color: var(--lp-muted); }
.lp-montage-foot { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--lp-line);
  text-align: center; font-family: var(--lp-mono); font-size: 10.5px; letter-spacing: .02em; color: var(--lp-subtle); }

/* --- trust strip --- */
.lp-strip { border-top: 1px solid var(--lp-line); border-bottom: 1px solid var(--lp-line);
  background: var(--lp-s1); }
.lp-strip-in { display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 8px 20px; padding: 14px 24px; font-family: var(--lp-mono); font-size: 12.5px; color: var(--lp-subtle); }
.lp-strip-in .lp-sep { color: var(--lp-line2); }

/* --- section header --- */
.lp-sec { padding: 96px 0; border-top: 1px solid var(--lp-line); }
.lp-sec-kicker { font-family: var(--lp-mono); font-size: 12px; letter-spacing: .2em; color: var(--lp-primary-l); }
.lp-sec-h { font-family: var(--lp-display); font-weight: 600; font-size: 42px; line-height: 1.1;
  letter-spacing: -.02em; margin: 12px 0 0; }
.lp-sec-lead { max-width: 640px; margin: 16px 0 0; font-size: 18px; line-height: 1.6; color: var(--lp-muted); }

/* --- modules --- */
.lp-modules { margin-top: 80px; display: flex; flex-direction: column; gap: 112px; }
.lp-module { display: grid; grid-template-columns: 1fr 1fr; gap: 56px; align-items: center; }
.lp-module.lp-flip .lp-module-copy { order: 2; }
.lp-module.lp-flip .lp-module-viz { order: 1; }
.lp-module-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.lp-module-ic { display: grid; place-items: center; width: 44px; height: 44px; border-radius: 12px;
  border: 1px solid var(--lp-line); background: var(--lp-s2); color: var(--lp-primary-l); flex-shrink: 0; }
.lp-status { border-radius: 999px; border: 1px solid; padding: 2px 10px;
  font-family: var(--lp-mono); font-size: 10px; letter-spacing: .03em; }
.lp-status.free, .lp-status.live { color: var(--lp-green); border-color: #1E3A2F; background: var(--lp-green-dim); }
.lp-status.paid { color: var(--lp-primary-l); border-color: #1E2F52; background: #0F1830; }
.lp-module-name { font-family: var(--lp-display); font-weight: 600; font-size: 30px;
  letter-spacing: -.02em; margin: 0; }
.lp-module-body { max-width: 460px; margin: 16px 0 0; font-size: 15px; line-height: 1.6; color: var(--lp-muted); }
.lp-module-body.lp-dim { color: var(--lp-subtle); }
.lp-points { list-style: none; margin: 20px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.lp-points li { display: flex; align-items: flex-start; gap: 10px; font-size: 14px; color: rgba(241,245,249,.9); }
.lp-points .lp-bullet { flex-shrink: 0; width: 6px; height: 6px; margin-top: 7px; border-radius: 50%; background: var(--lp-subtle); }
.lp-module-link { display: inline-flex; align-items: center; gap: 6px; margin-top: 22px;
  font-family: var(--lp-mono); font-size: 13px; color: var(--lp-primary-l); }
.lp-module-link:hover { color: var(--lp-primary); }

/* torpedo teaser */
.lp-torpedo { margin-top: 96px; border-radius: 18px; border: 1px dashed var(--lp-line2);
  background: rgba(15,20,32,.6); padding: 36px 32px; display: flex; flex-wrap: wrap;
  align-items: center; justify-content: space-between; gap: 20px; }
.lp-torpedo-l { display: flex; align-items: flex-start; gap: 16px; }
.lp-torpedo-ic { display: grid; place-items: center; width: 44px; height: 44px; border-radius: 12px;
  border: 1px solid var(--lp-line); background: var(--lp-s2); color: var(--lp-subtle); flex-shrink: 0; }
.lp-torpedo-row { display: flex; align-items: center; gap: 12px; }
.lp-torpedo-name { font-family: var(--lp-display); font-weight: 600; font-size: 20px; color: var(--lp-muted); }
.lp-chip { border-radius: 999px; border: 1px solid var(--lp-line2); background: var(--lp-s3);
  padding: 2px 10px; font-family: var(--lp-mono); font-size: 10px; color: var(--lp-subtle); }
.lp-torpedo-sub { max-width: 560px; margin: 6px 0 0; font-size: 14px; color: var(--lp-subtle); }
.lp-torpedo-link { font-family: var(--lp-mono); font-size: 13px; color: var(--lp-primary-l); flex-shrink: 0; }

/* --- generic viz card --- */
.lp-viz { border-radius: 18px; border: 1px solid var(--lp-line); background: var(--lp-s2);
  padding: 20px; box-shadow: var(--lp-card); }
.lp-viz-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px;
  font-family: var(--lp-mono); }
.lp-viz-head .lp-l { font-size: 10px; letter-spacing: .06em; color: var(--lp-muted); }
.lp-viz-head .lp-r { font-size: 10px; color: var(--lp-subtle); }

/* ZeroPoint viz */
.lp-ix { display: grid; grid-template-columns: repeat(3,1fr); gap: 10px; }
.lp-ix-cell { border-radius: 10px; border: 1px solid var(--lp-line); background: var(--lp-s1); padding: 10px 12px; font-family: var(--lp-mono); }
.lp-ix-cell .lp-n { font-size: 10px; color: var(--lp-subtle); }
.lp-ix-cell .lp-v { font-size: 14px; font-weight: 600; color: var(--lp-fg); }
.lp-ix-cell .lp-c { font-size: 11px; }
.lp-breadth { margin-top: 16px; border-radius: 10px; border: 1px solid var(--lp-line); background: var(--lp-s1); padding: 14px; }
.lp-breadth-row { display: flex; align-items: center; gap: 12px; margin-top: 8px; }
.lp-breadth-row .lp-name { width: 128px; flex-shrink: 0; font-size: 12px; color: var(--lp-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lp-breadth-track { flex: 1; height: 8px; border-radius: 999px; background: var(--lp-s3); overflow: hidden; }
.lp-breadth-track i { display: block; height: 100%; border-radius: 999px; }
.lp-breadth-row .lp-pct { width: 36px; text-align: right; font-family: var(--lp-mono); font-size: 11px; color: var(--lp-fg); }

/* MarketPulse viz */
.lp-mp { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.lp-mp-card { border-radius: 12px; border: 1px solid var(--lp-line); background: var(--lp-s1); padding: 14px; }
.lp-mp-top { display: flex; align-items: center; justify-content: space-between; }
.lp-mp-sym { display: flex; align-items: center; gap: 8px; font-family: var(--lp-mono); font-size: 14px; font-weight: 600; color: var(--lp-fg); }
.lp-mp-calls { font-family: var(--lp-mono); font-size: 11px; color: var(--lp-subtle); }
.lp-mp-strip { display: flex; gap: 3px; margin-top: 10px; }
.lp-mp-strip i { width: 6px; height: 12px; border-radius: 1px; }
.lp-mp-head { margin-top: 10px; font-size: 12px; line-height: 1.35; color: var(--lp-muted);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.lp-mp-src { display: flex; align-items: center; justify-content: space-between; margin-top: 10px;
  font-family: var(--lp-mono); font-size: 10px; color: var(--lp-subtle); }
.lp-mp-src .lp-pub { color: var(--lp-primary-l); }

/* EOD viz */
.lp-oi-row { display: flex; align-items: center; gap: 8px; margin-top: 6px; }
.lp-oi-side { flex: 1; display: flex; }
.lp-oi-side.lp-call { justify-content: flex-end; }
.lp-oi-side i { display: block; height: 14px; border-radius: 2px; }
.lp-oi-call i { background: rgba(247,107,107,.8); }
.lp-oi-put i { background: rgba(52,224,161,.8); }
.lp-oi-strike { width: 56px; flex-shrink: 0; text-align: center; font-family: var(--lp-mono); font-size: 11px; color: var(--lp-muted); }
.lp-oi-strike.lp-pin { color: var(--lp-orange); font-weight: 600; }
.lp-oi-tiles { display: grid; grid-template-columns: repeat(4,1fr); gap: 8px; margin-top: 16px; }

/* ChartDuo viz */
.lp-duo { display: flex; flex-wrap: wrap; gap: 12px; }
.lp-duo-panel { flex: 1; min-width: 220px; border-radius: 12px; border: 1px solid var(--lp-line); background: var(--lp-s1); padding: 14px; }
.lp-duo-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.lp-duo-title { display: flex; align-items: center; gap: 8px; }
.lp-duo-title .lp-nm { font-family: var(--lp-mono); font-size: 11px; font-weight: 600; color: var(--lp-fg); }
.lp-duo-title .lp-tag { font-family: var(--lp-mono); font-size: 9px; letter-spacing: .06em; color: var(--lp-subtle);
  border-radius: 4px; background: var(--lp-s3); padding: 2px 6px; }
.lp-duo-legend { display: flex; align-items: center; gap: 10px; font-family: var(--lp-mono); font-size: 10px; color: var(--lp-muted); }
.lp-duo-legend span { display: inline-flex; align-items: center; gap: 5px; }
.lp-duo-legend i { width: 8px; height: 8px; border-radius: 1px; }
.lp-duo-chart { height: 128px; }
.lp-duo-chart svg { width: 100%; height: 100%; display: block; }
.lp-duo-foot { margin-top: 12px; font-family: var(--lp-mono); font-size: 10px; color: var(--lp-subtle); }

/* RadarMap viz */
.lp-radar { position: relative; height: 280px; border-radius: 12px; border: 1px solid var(--lp-line);
  background: #0B0F1A; overflow: hidden;
  background-image: linear-gradient(rgba(255,255,255,.025) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.025) 1px, transparent 1px);
  background-size: 44px 44px; }
.lp-radar-axis { position: absolute; left: 0; right: 0; top: 50%; border-top: 1px dashed var(--lp-line2); }
.lp-radar-lx { position: absolute; top: 8px; left: 12px; font-family: var(--lp-mono); font-size: 9px; color: var(--lp-subtle); }
.lp-radar-lc { position: absolute; bottom: 8px; right: 12px; font-family: var(--lp-mono); font-size: 9px; color: var(--lp-subtle); }
.lp-bub { position: absolute; border-radius: 50%; }
.lp-radar-legend { display: flex; align-items: center; gap: 16px; margin-top: 12px; font-family: var(--lp-mono); font-size: 10px; color: var(--lp-muted); }
.lp-radar-legend span { display: inline-flex; align-items: center; gap: 6px; }
.lp-radar-legend i { width: 10px; height: 10px; border-radius: 50%; }

/* Torpedo Fulcrum viz — animated deviation-bubble field. Green drifts above the
   dashed own-SMA baseline, red below, neutral hugs it; each bubble breathes on a
   slow vertical drift (staggered via inline animation-delay). Reduced-motion
   users get the static field (see the media block below). */
.lp-fulcrum { position: relative; height: 300px; border-radius: 12px; border: 1px solid var(--lp-line);
  overflow: hidden;
  background: linear-gradient(180deg, rgba(52,224,161,.07) 0%, #0B0F1A 46%, #0B0F1A 54%, rgba(247,107,107,.08) 100%), #0B0F1A; }
.lp-fulcrum-axis { position: absolute; left: 0; right: 0; top: 50%; border-top: 1px dashed rgba(34,211,238,.55); }
.lp-fulcrum-tag { position: absolute; top: 50%; right: 8px; transform: translateY(-50%); padding: 2px 7px;
  border-radius: 5px; background: rgba(34,211,238,.14); border: 1px solid rgba(34,211,238,.4);
  font-family: var(--lp-mono); font-size: 9px; color: var(--lp-primary-l); }
.lp-fbub { position: absolute; border-radius: 50%; animation: lp-fdrift 5.5s ease-in-out infinite alternate; }
.lp-fbub-up { background: rgba(52,224,161,.22); border: 1.5px solid var(--lp-green); }
.lp-fbub-dn { background: rgba(247,107,107,.22); border: 1.5px solid var(--lp-red); }
.lp-fbub-nt { background: rgba(148,163,184,.14); border: 1.5px solid rgba(148,163,184,.55); }
.lp-fbub-lbl { position: absolute; left: 50%; bottom: 100%; transform: translate(-50%, -4px);
  display: flex; flex-direction: column; align-items: center; gap: 1px; white-space: nowrap;
  font-family: var(--lp-mono); font-size: 9px; color: var(--lp-muted); }
.lp-fbub-lbl b { font-size: 10px; color: var(--lp-fg); letter-spacing: .04em; }
@keyframes lp-fdrift { from { transform: translateY(-7px); } to { transform: translateY(7px); } }

/* ScreenerGrid viz */
.lp-sg { border-radius: 12px; border: 1px solid var(--lp-line); overflow: hidden; }
.lp-sg-row { display: grid; grid-template-columns: 1.1fr .8fr 1fr 1.1fr 1.4fr; gap: 8px;
  align-items: center; padding: 9px 12px; font-family: var(--lp-mono); }
.lp-sg-head { background: var(--lp-s1); font-size: 9px; letter-spacing: .06em; color: var(--lp-subtle); }
.lp-sg-body { border-top: 1px solid var(--lp-line); background: rgba(15,20,32,.4); font-size: 12px; }
.lp-sg-sym { color: var(--lp-fg); font-weight: 500; }
.lp-sg-chg { color: var(--lp-green); }
.lp-sg-press { justify-self: start; border-radius: 6px; border: 1px solid; padding: 2px 8px; font-size: 10px; }
.lp-press-sbull { color: var(--lp-green); border-color: rgba(52,224,161,.4); background: rgba(52,224,161,.1); }
.lp-press-bull { color: var(--lp-green); border-color: rgba(52,224,161,.25); background: rgba(52,224,161,.05); }
.lp-press-sbear { color: var(--lp-red); border-color: rgba(247,107,107,.4); background: rgba(247,107,107,.1); }
.lp-press-bear { color: var(--lp-red); border-color: rgba(247,107,107,.25); background: rgba(247,107,107,.05); }
.lp-sg-sig { font-size: 10.5px; }
.lp-sg-sig.lp-none { color: var(--lp-subtle); }
.lp-sg-sig.lp-setup { color: var(--lp-primary-l); }
.lp-sg-scores { display: flex; justify-content: flex-end; gap: 3px; }
.lp-sg-scores i { display: grid; place-items: center; width: 20px; height: 20px; border-radius: 3px;
  font-size: 9px; font-weight: 600; color: #0A0E17; }
.lp-tr-l { text-align: right; }

/* --- feature spotlight (cash + f&o) --- */
.lp-spot { padding: 96px 0; border-top: 1px solid var(--lp-line); background: var(--lp-s1); }
.lp-spot-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 56px; align-items: center; }
.lp-spot-h { font-family: var(--lp-display); font-weight: 600; font-size: 42px; line-height: 1.1;
  letter-spacing: -.02em; margin: 12px 0 0; }
.lp-spot-lead { max-width: 460px; margin: 20px 0 0; font-size: 18px; line-height: 1.6; color: var(--lp-muted); }
.lp-spot-chips { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 28px; }
.lp-spot-chip { border-radius: 10px; border: 1px solid var(--lp-line); background: var(--lp-s2);
  padding: 6px 12px; font-size: 13px; color: rgba(241,245,249,.9); }
.lp-panel-duo { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.lp-panel { border-radius: 12px; border: 1px solid var(--lp-line); background: var(--lp-s1); padding: 16px; }
.lp-panel-t { font-family: var(--lp-mono); font-size: 10px; letter-spacing: .06em; color: var(--lp-subtle); margin-bottom: 12px; }
.lp-kv { display: flex; align-items: center; justify-content: space-between; margin-top: 10px; }
.lp-kv:first-of-type { margin-top: 0; }
.lp-kv .lp-k { font-size: 13px; color: var(--lp-muted); }
.lp-kv .lp-vv { font-family: var(--lp-mono); font-size: 13px; font-weight: 500; }
.lp-levels { margin-top: 12px; border-radius: 12px; border: 1px solid var(--lp-line); background: var(--lp-s1); padding: 16px; }

/* --- trust pillars --- */
.lp-pillars { margin-top: 56px; display: grid; grid-template-columns: repeat(3,1fr); gap: 16px; }
.lp-pillar { height: 100%; border-radius: 18px; border: 1px solid var(--lp-line); background: var(--lp-s2); padding: 24px; }
.lp-pillar.lp-accent { border-color: #1E2F52; background: #0F1830; }
.lp-pillar-ic { display: grid; place-items: center; width: 40px; height: 40px; border-radius: 12px;
  margin-bottom: 16px; background: var(--lp-s3); color: var(--lp-green); }
.lp-pillar.lp-accent .lp-pillar-ic { background: rgba(37,99,235,.2); color: var(--lp-primary-l); }
.lp-pillar-h { font-family: var(--lp-display); font-weight: 600; font-size: 17px; }
.lp-pillar-b { margin-top: 8px; font-size: 14px; line-height: 1.6; color: var(--lp-muted); }

/* --- CTA band + footer --- */
.lp-cta { position: relative; overflow: hidden; border-top: 1px solid var(--lp-line); }
.lp-cta-glow { pointer-events: none; position: absolute; inset: 0; opacity: .16; filter: blur(64px);
  background: radial-gradient(600px 300px at 50% 0%, var(--lp-primary) 0%, transparent 70%); }
.lp-cta-in { position: relative; padding: 96px 24px; text-align: center; }
.lp-cta-h { font-family: var(--lp-display); font-weight: 600; font-size: 48px; letter-spacing: -.02em; margin: 0; }
.lp-cta-h .lp-accent { color: var(--lp-green); }
.lp-cta-sub { margin: 16px 0 0; font-size: 18px; color: var(--lp-muted); }
.lp-cta-btns { display: flex; align-items: center; justify-content: center; gap: 12px; margin-top: 32px; }

/* --- landing footer (bespoke: Products/Company/Legal columns + disclaimer bar) --- */
.lp-foot { border-top: 1px solid var(--lp-line); background: var(--lp-s1); }
.lp-foot-grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: 40px; padding: 56px 24px; }
.lp-foot-tagline { max-width: 280px; margin: 16px 0 0; font-size: 14px; line-height: 1.6; color: var(--lp-subtle); }
.lp-foot-col-h { font-family: var(--lp-mono); font-size: 11px; letter-spacing: .04em; color: rgba(241,245,249,.9); }
.lp-foot-links { list-style: none; margin: 16px 0 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.lp-foot-links a { font-size: 14px; color: var(--lp-muted); }
.lp-foot-links a:hover { color: var(--lp-fg); }
.lp-foot-bottom { border-top: 1px solid var(--lp-line); }
/* full-width bar (not the 1200 band) so the fine-print disclaimer sits on ONE row at a
   small size on desktop; natural wrap on narrow screens (no nowrap -> no horizontal scroll). */
.lp-foot-bottom-in { max-width: 1500px; margin: 0 auto; padding: 20px 32px;
  display: flex; flex-direction: column; align-items: center; gap: 10px; }
.lp-foot-legal { max-width: none; margin: 0; text-align: center;
  font-size: 9px; line-height: 1.6; color: var(--lp-subtle); }
.lp-foot-copy { font-family: var(--lp-mono); font-size: 11px; color: var(--lp-subtle); text-align: center; }
.lp-foot-copy a { color: var(--lp-muted); }
.lp-foot-copy a:hover { color: var(--lp-fg); }

/* SHARED app footer (Zero Point + every chrome page), harmonized with the landing
   footer's bottom bar (.lp-foot-bottom-in): the same centered fine-print stack —
   the 9px SEBI sentence, a links row, and the mono 11px copyright/contact line —
   so the two footers read as one system. Colours stay on the theme tokens (NOT the
   --lp-* dark palette) so the app footer follows light/dark.
   Overrides base.css `.muted-footer*` (components.css loads after base.css). */
.muted-footer { display: flex; flex-direction: column; align-items: center; gap: var(--space-2); text-align: center; }
.muted-footer-disclaimer { max-width: none; margin: 0; font-size: 9px; }
.muted-footer-links { font-size: var(--text-xs); }
.muted-footer-copy { margin: 0; font-family: var(--font-mono); font-size: 11px; color: var(--color-text-faint); }
.muted-footer-copy a { color: var(--color-text-secondary); }
.muted-footer-copy a:hover { color: var(--color-text); }

/* --- responsive --- */
@media (max-width: 960px) {
  .lp-hero-grid, .lp-module, .lp-spot-grid { grid-template-columns: 1fr; gap: 40px; }
  .lp-module.lp-flip .lp-module-copy { order: 0; }
  .lp-module.lp-flip .lp-module-viz { order: 0; }
  .lp-h1 { font-size: 46px; }
  .lp-sec-h, .lp-spot-h { font-size: 34px; }
  .lp-cta-h { font-size: 36px; }
  .lp-pillars { grid-template-columns: 1fr 1fr; }
  .lp-foot-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 560px) {
  .lp-hero { padding-top: 108px; }
  .lp-h1 { font-size: 38px; }
  .lp-mp, .lp-panel-duo { grid-template-columns: 1fr; }
  .lp-pillars, .lp-foot-grid { grid-template-columns: 1fr; }
  .lp-sg-row { grid-template-columns: 1fr .7fr 1fr; }
  .lp-sg-sig, .lp-sg-scores { display: none; }
  .lp-cta-btns, .lp-hero-ctas { flex-direction: column; align-items: stretch; }
}

/* === Active sessions (session_cap_sharing) ============================== */
/* Account page "Active sessions" card. Lives here (components.css) per the
   account-CSS rule; uses the base --color- / --space- token sets to sit flush
   with the surrounding .account-* cards (defined in base.css). (Do not write
   a star-glob after a token name in comments: "star slash" ends the comment
   early and silently drops the next rule — it ate .account-sessions once.) */
.account-sessions { list-style: none; margin: var(--space-3) 0 0; padding: 0;
  display: flex; flex-direction: column; gap: 0; }
.account-session { padding: var(--space-3) 0; border-bottom: .5px solid var(--color-border); }
.account-session:last-child { border-bottom: 0; }
.account-session-main { display: flex; align-items: center; gap: var(--space-2); }
.account-session-device { font-size: var(--text-sm); color: var(--color-text); }
.account-session-badge { font-size: 10px; line-height: 1.5; padding: 1px 7px;
  border-radius: 3px; background: var(--color-accent-soft); color: var(--color-accent-text); }
.account-session-meta { margin-top: 2px; font-size: var(--text-xs);
  color: var(--color-text-faint); display: flex; flex-wrap: wrap; gap: 6px;
  align-items: baseline; }
.account-session-sep { color: var(--color-text-faint); opacity: .6; }
.account-sessions-actions { margin-top: var(--space-3); }
.account-sessions-actions form { margin: 0; }

/* === Admin concurrency review (session_cap_sharing) ===================== */
/* Review-only — never an auto-action. Flags accounts whose sessions span many
   IPs (login-sharing/resale leads). Uses the dense .adm-* token set. */
.adm-conc-signals { display: flex; gap: 4px; flex-shrink: 0; }
.adm-badge.flag { background: var(--amber-soft); color: var(--amber); }

/* === Torpedo v1.0 (torpedo_v1_foundation) — namespaced .tor-* ============ */
/* Product chrome only: premium/nav badges, the data-freshness pill, the
   landing cards, and the warming state. All Torpedo-specific styling lives
   under .tor-* per the standing rule (base.css off-limits). */

/* Premium / version badges (landing header). */
.tor-badge { display: inline-flex; align-items: center; padding: 1px 8px;
  border-radius: 999px; border: 1px solid var(--color-accent-text);
  color: var(--color-accent-text); font-family: var(--mono);
  font-size: 10px; letter-spacing: .08em; line-height: 1.6; }
.tor-badge-ver { border-color: var(--color-border); color: var(--color-text-faint); }

/* Sidebar nav badge — sits beside the "Torpedo" label. */
.tor-nav-badge { margin-left: 6px; padding: 0 5px; border-radius: 3px;
  background: var(--color-accent-soft); color: var(--color-accent-text);
  font-family: var(--mono); font-size: 9px; letter-spacing: .06em; line-height: 1.7; }

/* Data-freshness pill — live / idle / warming (torpedo/_fresh_pill.html). */
.tor-fresh { display: inline-flex; align-items: center; gap: 6px;
  padding: 2px 10px; border-radius: 999px; border: 1px solid var(--color-border);
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .04em;
  color: var(--color-text-secondary); white-space: nowrap; }
.tor-fresh-dot { width: 6px; height: 6px; border-radius: 50%;
  background: var(--color-text-faint); flex-shrink: 0; }
.tor-fresh.is-live { border-color: var(--green, #3fa66a); color: var(--green, #3fa66a); }
.tor-fresh.is-live .tor-fresh-dot { background: var(--green, #3fa66a); }
.tor-fresh.is-warming { border-color: var(--amber, #c9962e); color: var(--amber, #c9962e); }
.tor-fresh.is-warming .tor-fresh-dot { background: var(--amber, #c9962e); }

/* Landing cards — three links into Cash / F&O / Screener. */
.tor-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-3); max-width: 860px; }
.tor-card { display: flex; flex-direction: column; gap: 6px;
  padding: var(--space-4); border: 1px solid var(--color-border);
  border-radius: var(--radius-md); background: var(--color-surface);
  text-decoration: none; transition: border-color .15s ease; }
.tor-card:hover { border-color: var(--color-accent-text); }
.tor-card-ic { font-size: 20px; color: var(--color-accent-text); }
.tor-card-name { font-family: var(--mono); font-size: var(--text-sm);
  letter-spacing: .06em; text-transform: uppercase; color: var(--color-text); }
.tor-card-sub { font-size: var(--text-xs); color: var(--color-text-secondary);
  line-height: 1.5; }

/* Warming state — reuses .empty-state geometry; tint only. */
.tor-warming .empty-icon { color: var(--amber, #c9962e); }

/* === Torpedo v2 — S/R Confluence chart (.tor-sr-*) ======================= */
/* Reconciled to docs/sr_confluence_chart_mockup.html: axis ticks + dashed
   gridlines left; level rails in the LEFT band; VOLUME PROFILE rail middle;
   OI rail right with a centre split (call bars left / put bars right, strike
   labels centred); accent SPOT line + badge; method colour chips (OI purple,
   PIV sky, VP teal) and three confluence dots per surfaced level. */
.tor-sr-hd { display: flex; align-items: center; gap: 12px; margin-bottom: 8px; }
.tor-sr-sym { font-size: var(--text-lg); font-weight: 600; letter-spacing: .3px; }
.tor-sr-seg { font-size: 10px; font-weight: 600; color: var(--color-accent-text);
  border: 1px solid var(--color-accent-text); border-radius: 5px; padding: 1px 7px;
  letter-spacing: .5px; }
.tor-sr-spotv { margin-left: auto; text-align: right; display: flex;
  flex-direction: column; line-height: 1.2; }
.tor-sr-spotv b { font-size: 18px; font-weight: 600; }
.tor-sr-spotv i { font-style: normal; font-size: 9.5px; color: var(--color-text-faint);
  letter-spacing: .6px; }
.tor-sr-help { margin: 2px 0 10px; }
.tor-sr-help > summary { cursor: pointer; font-size: 12px; opacity: .65; width: fit-content;
  padding: 3px 10px; border: 1px solid var(--line, #2a2f3a); border-radius: 9px; list-style: none; }
.tor-sr-help > summary::-webkit-details-marker { display: none; }
.tor-sr-help > summary:hover { opacity: 1; }
.tor-sr-help[open] > summary { opacity: 1; border-color: var(--accent, #5b9dd9); }
.tor-sr-help[open] { padding-bottom: 6px; }
.tor-sr-help .tor-sr-legend { margin-top: 8px; }
.tor-sr-legend { display: flex; gap: 16px; align-items: center; flex-wrap: wrap;
  padding: 8px 0 10px; border-bottom: 1px solid var(--color-border);
  margin-bottom: 12px; font-size: var(--text-xs); color: var(--color-text-secondary); }
.tor-sr-legend .chip { display: inline-flex; align-items: center; gap: 6px; }
.tor-sr-legend .dot { width: 8px; height: 8px; border-radius: 2px; display: inline-block; }
.dot.m-oi { background: #a855f7; }
.dot.m-piv { background: #38bdf8; }
.dot.m-vp { background: #2dd4bf; }
.tor-sr-chart { position: relative; height: 560px; overflow: hidden;
  border: 1px solid var(--color-border); border-radius: var(--radius-md);
  background: var(--color-surface); }
.tor-sr-tick { position: absolute; left: 0; width: 52px; text-align: right;
  padding-right: 8px; transform: translateY(-50%); font-family: var(--mono);
  font-size: 10px; color: var(--color-text-faint); }
.tor-sr-grid { position: absolute; left: 52px; right: 0;
  border-top: 1px dashed var(--color-border); opacity: .5; }
/* level rails live in the LEFT band between the axis and the VP rail */
.tor-sr-rail { position: absolute; left: 52px; right: 54%;
  transform: translateY(-50%); border-top: 2px solid; border-radius: 2px; }
.tor-sr-rail.r { border-color: var(--red, #c0504d); }
.tor-sr-rail.s { border-color: var(--green, #3fa66a); }
.tor-sr-rail.is-faint { opacity: .07; transition: opacity .15s; }
.tor-sr-rail.is-faint:hover { opacity: .65; }
.tor-sr-tag { position: absolute; left: 6px; top: -10px; display: inline-flex;
  align-items: center; gap: 7px; background: var(--color-surface); padding: 0 6px;
  white-space: nowrap; }
.tor-sr-tag .rank { font-size: 11px; font-weight: 700; letter-spacing: .5px; }
.tor-sr-rail.r .rank { color: var(--red, #c0504d); }
.tor-sr-rail.s .rank { color: var(--green, #3fa66a); }
.tor-sr-tag .price { font-size: 12px; font-weight: 600; color: var(--color-text);
  font-family: var(--mono); }
.tor-sr-tag .mchips { display: inline-flex; gap: 4px; }
.tor-sr-tag .mtag { font-style: normal; font-size: 9px; font-weight: 700;
  letter-spacing: .4px; border-radius: 4px; padding: 0 5px; border: 1px solid; }
.tor-sr-tag .mtag.m-oi { color: #a855f7; border-color: #a855f766; }
.tor-sr-tag .mtag.m-piv { color: #38bdf8; border-color: #38bdf866; }
.tor-sr-tag .mtag.m-vp { color: #2dd4bf; border-color: #2dd4bf66; }
.tor-sr-tag .cdots { display: inline-flex; gap: 3px; align-items: center; }
.cdot { width: 6px; height: 6px; border-radius: 50%;
  background: var(--color-text-faint); display: inline-block; margin-left: 2px; }
.cdot.on { background: var(--color-accent-text); }
.tor-sr-spot { position: absolute; left: 52px; right: 0; z-index: 5;
  transform: translateY(-50%); border-top: 2px solid var(--color-accent-text); }
.tor-sr-spot span { position: absolute; right: 8px; top: -11px;
  background: var(--color-accent-text); color: var(--color-bg, #fff);
  font-size: 10px; font-weight: 700; padding: 2px 8px; border-radius: 5px;
  letter-spacing: .5px; font-family: var(--mono); }
/* VP rail — middle band, bars grow rightward from its left border */
.tor-sr-vprail { position: absolute; top: 0; bottom: 0; left: 46%; width: 24%;
  border-left: 1px solid var(--color-border); }
.tor-sr-rail-h { position: absolute; top: 4px; left: 8px; font-family: var(--mono);
  font-size: 9px; letter-spacing: .6px; color: var(--color-text-faint);
  white-space: nowrap; z-index: 2; }
.tor-sr-vpbar { position: absolute; left: 0; height: 8px; max-width: 96%;
  transform: translateY(-50%); background: #2dd4bf47; border-radius: 0 3px 3px 0; }
.tor-sr-vpbar.poc { background: #2dd4bf; }
.tor-sr-poclbl { position: absolute; transform: translateY(-50%); font-size: 9px;
  font-weight: 700; color: #2dd4bf; font-family: var(--mono); }
/* OI rail — right band with a centre split: call to the left, put right */
.tor-sr-oirail { position: absolute; top: 0; bottom: 0; right: 0; width: 30%;
  border-left: 1px solid var(--color-border); }
.tor-sr-oirail .tor-sr-rail-h { left: 50%; transform: translateX(-50%); }
.tor-sr-oimid { position: absolute; top: 0; bottom: 0; left: 50%;
  border-left: 1px dashed var(--color-border); opacity: .6; }
.tor-sr-oibar { position: absolute; height: 8px; transform: translateY(-50%);
  max-width: 48%; }
.tor-sr-oibar.call { right: 50%; background: var(--red, #c0504d);
  opacity: .55; border-radius: 3px 0 0 3px; }
.tor-sr-oibar.put { left: 50%; background: var(--green, #3fa66a);
  opacity: .55; border-radius: 0 3px 3px 0; }
.tor-sr-oistrike { position: absolute; left: 50%; transform: translate(-50%, -50%);
  font-size: 8.5px; color: var(--color-text-faint); background: var(--color-surface);
  padding: 0 3px; font-family: var(--mono); z-index: 2; }
/* cash symbols: no OI rail — the VP band slides right to fill */
.tor-sr-chart.tor-sr-no-oi .tor-sr-rail { right: 34%; }
.tor-sr-chart.tor-sr-no-oi .tor-sr-vprail { left: 66%; width: 34%; }
/* Warming state — reuses .empty-state geometry; tint only. */
.tor-warming .empty-icon { color: var(--amber, #c9962e); }

/* === Torpedo v2 — normalized-deviation bubble scanner (.tor-bub-*) ====== */
/* Reconciled to docs/normalized_sma_bubble_mockup.html: soft above/below
   zones, plus-minus axis ticks + dashed gridlines, the dashed accent 0
   baseline with its badge, three-state bubbles (up / dn / flat), the accent
   emphasis ring, and outside labels for emphasised names. */
.tor-bub-chart { position: relative; height: 540px; overflow: hidden;
  border: 1px solid var(--color-border); border-radius: var(--radius-md);
  background: var(--color-surface); }
/* Inner plot region (item 9, UI unification): matches the axis inset (the
   46px tick gutter / 8px right margin the zones+grid+zero already use) so the
   bubbles' 0–100% positions map onto the PLOT AREA, and the template's
   clamp()ed coordinates keep every bubble/label fully inside it. */
.tor-bub-plot { position: absolute; top: 0; bottom: 0; left: 46px; right: 8px; }
.tor-bub-zone-up { position: absolute; left: 46px; right: 8px; top: 0; height: 50%;
  background: linear-gradient(180deg, rgba(63, 166, 106, .07), transparent);
  pointer-events: none; }
.tor-bub-zone-dn { position: absolute; left: 46px; right: 8px; bottom: 0; height: 50%;
  background: linear-gradient(0deg, rgba(192, 80, 77, .07), transparent);
  pointer-events: none; }
.tor-bub-grid { position: absolute; left: 46px; right: 8px;
  border-top: 1px dashed var(--color-border); opacity: .45; }
.tor-bub-tick { position: absolute; left: 0; width: 40px; text-align: right;
  padding-right: 6px; transform: translateY(-50%); font-family: var(--mono);
  font-size: 10px; color: var(--color-text-faint); }
.tor-bub-zero { position: absolute; left: 46px; right: 8px; z-index: 3;
  border-top: 2px dashed var(--color-accent-text); }
.tor-bub-zero-badge { position: absolute; right: 10px; top: -9px;
  background: var(--color-accent-text); color: var(--color-bg, #fff);
  font-size: 10px; font-weight: 700; padding: 2px 8px; border-radius: 5px;
  letter-spacing: .4px; font-family: var(--mono); }
.tor-bub { position: absolute; transform: translate(-50%, -50%);
  border-radius: 50%; border: 1.5px solid transparent; transition: transform .12s; }
.tor-bub:hover { transform: translate(-50%, -50%) scale(1.06); z-index: 9; }
.tor-bub.st-up { background: rgba(63, 166, 106, .26);
  border-color: var(--green, #3fa66a); }
.tor-bub.st-dn { background: rgba(192, 80, 77, .26);
  border-color: var(--red, #c0504d); }
.tor-bub.st-flat { background: rgba(138, 151, 168, .22);
  border-color: var(--color-text-faint); }
.tor-bub.emph { box-shadow: 0 0 0 2px var(--color-accent-text),
  0 0 0 4px var(--color-surface); z-index: 4; }
.tor-bub-lab { position: absolute; transform: translate(-50%, -50%);
  text-align: center; white-space: nowrap; pointer-events: none; z-index: 5;
  line-height: 1.15; }
.tor-bub-lab b { font-size: 10.5px; font-weight: 700; color: var(--color-text);
  display: block; }
.tor-bub-lab i { font-style: normal; font-size: 9px; font-weight: 600;
  font-family: var(--mono); }
.tor-bub-lab i.st-up { color: var(--green, #3fa66a); }
.tor-bub-lab i.st-dn { color: var(--red, #c0504d); }
.tor-bub-lab i.st-flat { color: var(--color-text-secondary); }
.tor-bub-legend { display: inline-flex; align-items: center; gap: 6px;
  font-size: var(--text-xs); color: var(--color-text-secondary); }
.tor-bub-key { width: 10px; height: 10px; border-radius: 50%;
  display: inline-block; margin-left: 10px; }
.tor-bub-key.above { background: var(--green, #3fa66a); }
.tor-bub-key.below { background: var(--red, #c0504d); }
.tor-bub-key.emph { background: var(--color-surface);
  border: 1px solid var(--color-text); box-shadow: 0 0 0 2px var(--color-accent-soft); }

/* === Torpedo v2 — radar universe map (.tor-radar-*) ====================== */
.tor-radar-chart { position: relative; height: 540px; overflow: hidden;
  border: 1px solid var(--color-border); border-radius: var(--radius-md);
  background: var(--color-surface); }
.tor-radar-mid-v { position: absolute; top: 0; bottom: 0; left: 50%;
  border-left: 1px dashed var(--color-border); }
.tor-radar-mid-h { position: absolute; left: 0; right: 0; top: 50%;
  border-top: 1px dashed var(--color-border); }
.tor-radar-axis-x { position: absolute; bottom: 4px; left: 0; right: 0;
  text-align: center; font-family: var(--mono); font-size: 9.5px;
  letter-spacing: .06em; color: var(--color-text-faint); pointer-events: none; }
.tor-radar-axis-y { position: absolute; top: 8px; left: 8px;
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .06em;
  color: var(--color-text-faint); pointer-events: none; }
.tor-radar-slider { display: inline-flex; align-items: center; gap: 6px;
  color: var(--color-text-secondary); }
.tor-radar-slider input[type="range"] { width: 120px; accent-color: var(--color-accent-text); }

/* === Fulcrum declutter — label collision-hide + search/highlight (usability brief) === */
.tor-bub-search { height: 30px; width: 150px; padding: 0 10px;
  border: 1px solid var(--color-border); border-radius: var(--radius-sm);
  background: var(--color-surface); color: var(--color-text);
  font-family: var(--mono); font-size: var(--text-sm); }
.tor-bub-search:focus { outline: none; border-color: var(--color-accent-text); }
/* a label dropped by the collision pass — the name stays readable on hover (title) */
.tor-bub-lab.is-hidden { display: none; }
.tor-bub-lab-temp { z-index: 12; }
/* search mode: dim everything except the matched bubbles + their forced labels */
.tor-bub-plot.is-searching .tor-bub:not(.is-match) { opacity: .1; }
.tor-bub-plot.is-searching .tor-bub-lab:not(.tor-bub-lab-temp) { display: none; }
.tor-bub.is-match { z-index: 10;
  box-shadow: 0 0 0 2px var(--color-accent-text), 0 0 0 5px var(--color-accent-soft); }

/* Y-axis zoom (Fulcrum usability) — a live vertical-scale slider to spread the
   ±% cluster; outliers beyond the zoomed range dim (.off-scale). */
.tor-bub-zoombar { display: flex; align-items: center; justify-content: flex-end;
  gap: 9px; margin-bottom: 10px; font-size: var(--text-xs);
  color: var(--color-text-secondary); }
.tor-bub-zoombar > i.ph { font-size: 15px; color: var(--color-text-secondary); }
.tor-bub-zoombar label { font-weight: 600; }
.tor-bub-zoombar input[type="range"] { width: 168px; max-width: 40vw;
  accent-color: var(--color-accent-text); cursor: pointer; }
.tor-bub-zoombar #tor-bub-zoom-val { min-width: 36px; text-align: right;
  color: var(--color-text); }
.tor-bub-zoom-reset { height: 28px; padding: 0 11px; }
.tor-bub.off-scale { opacity: .28; }

/* === Torpedo v2 — S/R Method 4: demand/supply zone bands ================ */
/* Shaded price RANGES under the level rails (torpedo_v2_sr_demand_supply
   §6): demand bands tint support-side green, supply bands resistance-side
   red; a band holding line-method confluence draws bolder. Same horizontal
   extent as the rails (left band; widens on the cash no-OI variant). */
.tor-sr-band { position: absolute; left: 52px; right: 54%; z-index: 0;
  border-top: 1px solid; border-bottom: 1px solid; pointer-events: auto; }
.tor-sr-band.s { background: rgba(63, 166, 106, .10);
  border-color: rgba(63, 166, 106, .35); }
.tor-sr-band.r { background: rgba(192, 80, 77, .10);
  border-color: rgba(192, 80, 77, .35); }
.tor-sr-band.is-conf.s { background: rgba(63, 166, 106, .20);
  border-color: var(--green, #3fa66a); }
.tor-sr-band.is-conf.r { background: rgba(192, 80, 77, .20);
  border-color: var(--red, #c0504d); }
.tor-sr-band.is-faint { opacity: .10; transition: opacity .15s; }
.tor-sr-band.is-faint:hover { opacity: .45; }
.tor-sr-chart.tor-sr-no-oi .tor-sr-band { right: 34%; }
.tor-sr-rail.in-zone { z-index: 1; }
.dot.m-ds { background: var(--amber, #c9962e); }
.dot.m-mp { background: #f59e0b; }
.tor-sr-tag .mtag.m-mp { color: #f59e0b; border-color: #f59e0b66; }
.tor-sr-tag .mtag.m-ds { color: var(--amber, #c9962e);
  border-color: rgba(201, 150, 46, .45); }

/* === Torpedo — close-vs-S/R positioning strip (value-audit Part 3) ====== */
/* Compact "where is price now" read above the S/R chart: location state
   badge + nearest structure distances (% · ATR) + room + POC side. Purely
   descriptive vocabulary (RA-safe). */
.tor-sr-pos { display: flex; flex-wrap: wrap; align-items: center;
  column-gap: 28px; row-gap: 10px;
  padding: 10px 14px; margin-bottom: 10px;
  border: 1px solid var(--color-border); border-radius: var(--radius-md, 8px);
  background: var(--color-bg-secondary); }
.tor-sr-pos-state { font-family: var(--mono); font-size: var(--text-xs);
  font-weight: 700; letter-spacing: .04em; padding: 3px 9px;
  border-radius: 999px; border: 1px solid var(--color-border);
  color: var(--color-text-secondary); white-space: nowrap; }
.tor-sr-pos-state.is-sup { color: var(--green, #3fa66a);
  border-color: rgba(63, 166, 106, .45); background: rgba(63, 166, 106, .10); }
.tor-sr-pos-state.is-res { color: var(--red, #c0504d);
  border-color: rgba(192, 80, 77, .45); background: rgba(192, 80, 77, .10); }
/* Declutter (operator, 10-Jul): each metric is a small vertical stat cell —
   LABEL / value / meta — instead of one run-on line of inline pairs. */
.tor-sr-pos-item { display: inline-flex; flex-direction: column;
  align-items: flex-start; gap: 1px;
  font-size: var(--text-xs); white-space: nowrap; }
.tor-sr-pos-item i { font-style: normal; color: var(--color-text-faint);
  text-transform: uppercase; letter-spacing: .07em; font-size: 9.5px; }
.tor-sr-pos-item b { font-family: var(--mono); font-weight: 600;
  font-size: 13.5px; color: var(--color-text-primary); }
.tor-sr-pos-item em { font-style: normal; font-family: var(--mono);
  font-size: 10.5px; color: var(--color-text-secondary); }
.tor-sr-pos-item.is-wall b { color: var(--purple, #8a6fd1); }
/* DI verdict strip + occupancy bars (row 23) */
.di-verdicts { display: flex; flex-wrap: wrap; gap: 10px; padding: 10px 12px; }
.di-chip { display: inline-flex; align-items: center; gap: 7px;
  padding: 6px 12px; border-radius: 999px; text-decoration: none;
  border: 1px solid var(--color-border); background: var(--color-bg-secondary);
  font-size: 11px; color: var(--color-text-secondary); }
.di-chip .di-dot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; }
.di-chip-lbl { font-weight: 700; letter-spacing: .03em;
  color: var(--color-text-primary); white-space: nowrap; }
.di-chip-line { white-space: nowrap; }
.di-ok .di-dot { background: var(--green); }
.di-ok { border-color: rgba(63,166,106,.35); }
.di-warn .di-dot { background: var(--amber, #c9852b); }
.di-warn { border-color: rgba(201,133,43,.4); }
.di-bad .di-dot { background: var(--red); }
.di-bad { border-color: rgba(192,80,77,.45); }
.di-na .di-dot { background: var(--color-text-faint); }
.di-occ { display: inline-block; width: 52px; height: 7px; margin-right: 6px;
  vertical-align: baseline; border-radius: 2px; background: var(--bg-3);
  overflow: hidden; }
.di-occ i { display: block; height: 100%; border-radius: 2px; opacity: .8; }

/* IA tracker payoff family (row 20 §2b) */
.iat-payoff { margin: 8px 0 10px; }
.iat-payoff-svg { width: 100%; max-width: 480px; height: auto;
  background: var(--bg-3); border: 1px solid var(--color-border);
  border-radius: 6px; }
.iat-po-zero { stroke: var(--color-text-faint); stroke-width: .7; stroke-dasharray: 2 3; }
.iat-po-be { stroke: var(--color-text-faint); stroke-width: .7; stroke-dasharray: 4 3; }
.iat-po-fwd { stroke: var(--amber, #c9852b); stroke-width: .8; }
.iat-po-expiry { stroke: var(--color-text-secondary); stroke-width: 1.1; }
.iat-po-t0 { stroke: var(--accent, #34e0a1); stroke-width: 1.6; }
.iat-payoff-meta { display: flex; flex-direction: column; gap: 2px;
  font-size: 10.5px; color: var(--color-text-secondary); margin-top: 4px; }
.iat-po-key { display: inline-block; width: 14px; height: 3px;
  vertical-align: middle; border-radius: 2px; }
.iat-po-key-t0 { background: var(--accent, #34e0a1); }
.iat-po-key-exp { background: var(--color-text-secondary); }

/* Liquid Strikes gamma-wall micro-bar (row 20) */
.lqs-gw { display: inline-block; width: 44px; height: 7px; margin-right: 6px;
  vertical-align: baseline; border-radius: 2px; background: var(--bg-3);
  overflow: hidden; }
.lqs-gw i { display: block; height: 100%; border-radius: 2px;
  background: var(--purple, #8a6fd1); opacity: .75; }

/* Torpedo - Profile tab (session volume profile; brief torpedo_volume_profile_tab) */
.tlx .tvp-controls{display:flex;align-items:center;gap:10px;margin:6px 0 10px}
.tlx .tvp-controls input[type=range]{flex:1 1 auto;max-width:520px}
.tlx .tvp-arrow{border:1px solid var(--line,#2a2f3a);background:transparent;color:inherit;border-radius:6px;padding:2px 10px;font-size:15px;cursor:pointer;line-height:1.4}
.tlx .tvp-arrow:hover{border-color:var(--accent,#5b9dd9)}
.tlx .tvp-range-lbl{font-size:12px;opacity:.65;white-space:nowrap}
.tlx .tvp-stale{font-size:12px;opacity:.6;margin:0 0 8px}
.tlx .tvp-head{display:flex;align-items:center;gap:10px;margin:4px 0 8px}
.tlx .tvp-date{font-weight:600;font-size:14px}
.tlx .tvp-badge{font-size:11px;padding:1px 8px;border-radius:9px;border:1px solid var(--line,#2a2f3a)}
.tlx .tvp-final{color:var(--green,#3fb68b);border-color:var(--green,#3fb68b)}
.tlx .tvp-live{color:var(--accent,#5b9dd9);border-color:var(--accent,#5b9dd9);animation:tvp-pulse 2s ease-in-out infinite}
.tlx .tvp-gap{color:var(--amber,#c9852b);border-color:var(--amber,#c9852b)}
@keyframes tvp-pulse{0%,100%{opacity:1}50%{opacity:.55}}
.tlx .tvp-svg{width:100%;height:auto;display:block;background:var(--panel,transparent);border:1px solid var(--line,#2a2f3a);border-radius:8px}
.tlx .tvp-grid{stroke:var(--line,#2a2f3a);stroke-width:.5;stroke-dasharray:3 5;opacity:.6}
.tlx .tvp-tick{fill:currentColor;opacity:.55;font-size:13px}
.tlx .tvp-va-band{fill:var(--accent,#5b9dd9);opacity:.08}
.tlx .tvp-bar{fill:currentColor;opacity:.28}
.tlx .tvp-bar-va{fill:var(--accent,#5b9dd9);opacity:.55}
.tlx .tvp-poc{stroke:var(--amber,#c9852b);stroke-width:1.5}
.tlx .tvp-poc-lbl{fill:var(--amber,#c9852b);font-size:13px;font-weight:600}
.tlx .tvp-close{stroke:currentColor;stroke-width:1;stroke-dasharray:6 4;opacity:.6}
.tlx .tvp-close-lbl{fill:currentColor;opacity:.6;font-size:12px}
.tlx .tvp-node{stroke-width:3}
.tlx .tvp-node-hvn{stroke:var(--green,#3fb68b)}
.tlx .tvp-node-lvn{stroke:var(--red,#d9534f)}
.tlx .tvp-caption{font-size:12px;opacity:.65;margin-top:8px}

/* Torpedo - Structure tab (universe S/R screener) */
.tlx .tstr-meta{font-size:12px;opacity:.65;margin:2px 0 10px}
.tlx .tstr-row{cursor:pointer}
.tlx .tstr-row:hover td{background:rgba(91,157,217,.06)}
.tlx .tstr-sorted{color:var(--accent,#5b9dd9)}
.tlx .tstr-loc{font-size:11px;opacity:.75;margin-right:6px}
.tlx .tstr-badge{font-size:10px;padding:0 6px;border-radius:8px;border:1px solid var(--line,#2a2f3a);margin-right:4px}
.tlx .tstr-badge.s{color:var(--green,#3fb68b);border-color:var(--green,#3fb68b)}
.tlx .tstr-badge.r{color:var(--red,#d9534f);border-color:var(--red,#d9534f)}
.tlx .tstr-badge.w{color:var(--amber,#c9852b);border-color:var(--amber,#c9852b)}

/* Torpedo - S/R max-pain drift strip (E7 consumer) */
.tlx .tsr-drift{display:flex;align-items:center;column-gap:28px;row-gap:6px;margin:4px 0 12px;flex-wrap:wrap;
  padding:10px 14px;border:1px solid var(--color-border);border-radius:var(--radius-md,8px);
  background:var(--color-bg-secondary)}
.tlx .tsr-drift-lbl{font-size:9.5px;letter-spacing:.07em;color:var(--color-text-faint);white-space:nowrap;
  max-width:120px;white-space:normal;line-height:1.5}
.tlx .tsr-drift-meta{font-family:var(--mono);font-size:10.5px;color:var(--color-text-secondary);
  display:inline-flex;flex-direction:column;gap:1px}
.tlx .tsr-drift-svg{width:320px;height:46px;flex:0 0 auto;background:var(--panel,transparent);border:1px solid var(--line,#2a2f3a);border-radius:6px}
.tlx .tsr-drift-mp{stroke:var(--amber,#c9852b);stroke-width:1.4}
.tlx .tsr-drift-cw{fill:var(--red,#d9534f);opacity:.7}
.tlx .tsr-drift-pw{fill:var(--green,#3fb68b);opacity:.7}
.tlx .tsr-drift-spot{fill:var(--accent,#5b9dd9)}
.tlx .tsr-drift-meta{font-size:12px;opacity:.7}

/* IA - strategy tracker premium sparkline (E7 history member) */
.tlx .iat-spark{display:flex;align-items:center;gap:10px;margin-top:8px;flex-wrap:wrap}
.tlx .iat-spark-lbl{font-size:11px;opacity:.6;white-space:nowrap}
.tlx .iat-spark-svg{width:240px;height:36px;border:1px solid var(--line,#2a2f3a);border-radius:6px;background:var(--panel,transparent)}
.tlx .iat-spark-line{stroke:var(--accent,#5b9dd9);stroke-width:1.4}
.tlx .iat-spark-meta{font-size:12px;opacity:.75}

/* IA screener - data-source pill (which path served the render) */
.tlx .src-pill{font-size:10px;padding:0 7px;border-radius:8px;border:1px solid var(--line,#2a2f3a);letter-spacing:.05em}
.tlx .src-pill.src-ws{color:var(--accent,#5b9dd9);border-color:var(--accent,#5b9dd9)}
.tlx .src-pill.src-api{color:inherit;opacity:.7}
