/* StrikeIQ - Options Intelligence Portal
   Deliberately restrained: no gradients, no glow, no animation, no chart
   clutter (Phase 5 instructions section 20). A dense, legible operations
   console, not a retail trading app. */

:root {
  color-scheme: dark;
  --bg: #0d1117;
  --bg-panel: #161b22;
  --bg-raised: #21262d;
  /* Table header surfaces - dark keeps its existing flat look exactly
     (Phase 8 Part 11: do not redesign Dark mode), so both resolve to the
     same panel color already used everywhere else. */
  --bg-header: var(--bg-panel);
  --bg-group-header: var(--bg-panel);
  --border: #30363d;
  --text: #c9d1d9;
  --text-dim: #8b949e;
  --text-faint: #484f58;
  --accent: #58a6ff;
  --accent-contrast: #0b1015;
  --positive: #3fb950;
  --negative: #f85149;
  --amber: #d29922;
  --tier-top-pick: #ffb454;
  --rank1: #58a6ff;
  --rank2: #8957e5;
  --radius: 4px;
  --date-picker-icon-filter: invert(0.75);
}

/* LIGHT THEME - a genuine professional light terminal, not an inverted dark
   theme or a generic SaaS palette. Every rule above resolves through these
   same custom properties, so switching the attribute is the entire theme
   change - no separate light-mode rules are needed elsewhere.
   Phase 8 Part 7/8 pass: table headers/group-headers now step down in
   tone from the white panel underneath them (rather than matching it
   exactly) so the table reads as a structured instrument, not one flat
   white rectangle - borders/text/accent deepened to match, no gradients,
   no shadows, no per-row color. */
[data-theme='light'] {
  color-scheme: light;
  --bg: #eef0f3;
  --bg-panel: #ffffff;
  --bg-raised: #f3f5f8;
  --bg-header: #eef2f7;
  --bg-group-header: #e2e8f1;
  --border: #c3cad6;
  --text: #14181f;
  --text-dim: #4b5563;
  --text-faint: #7c8698;
  --accent: #0b5fae;
  --accent-contrast: #ffffff;
  --positive: #15803d;
  --negative: #b91c1c;
  --amber: #9a6700;
  --tier-top-pick: #953800;
  --rank1: #0b5fae;
  --rank2: #8250df;
  --date-picker-icon-filter: none;
}

* {
  box-sizing: border-box;
}

[hidden] {
  display: none !important;
}

html,
body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  font-size: 13px;
  line-height: 1.4;
  /* Mobile safety net: every intentionally-scrollable region in this app
     (`.table-wrap`, `.overview-intel-strip`, `.primary-nav`, ...) already
     scrolls internally via its own `overflow: auto/scroll` - this only
     stops something that slips past one of those from opening a second,
     page-level horizontal scrollbar/gutter on narrow viewports. Vertical
     scrolling is untouched. */
  overflow-x: hidden;
}

/* Top header (row 1): BRAND | compact centered SEARCH | MARKET CONTEXT +
   USER CONTROLS. Three zones; the side columns share the remaining width
   equally (minmax(0,1fr)) so the search stays centered, and the search is
   capped at 320px so it never dominates the row. */
.app-header {
  display: grid;
  grid-template-columns: minmax(max-content, 1fr) minmax(140px, 320px) minmax(max-content, 1fr);
  align-items: center;
  padding: 0 20px;
  height: 56px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-panel);
  gap: 24px;
}

.brand-cluster {
  display: flex;
  flex-direction: column;
  justify-content: center;
  flex-shrink: 0;
}

.brand {
  font-size: 16px;
  line-height: 1;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--text);
}

.brand-iq {
  color: var(--accent);
}

.brand-tag {
  color: var(--text-faint);
  font-size: 9px;
  font-weight: 500;
  text-transform: uppercase;
  margin-top: 4px;
  letter-spacing: 0.1em;
  white-space: nowrap;
}

.header-controls {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 16px;
  min-width: 0;
}

/* Market context block (date, time, market status, data status) and the user
   controls (theme, bell, profile) - two quiet groups divided by one hairline. */
.header-context {
  display: flex;
  align-items: center;
  gap: 14px;
  min-width: 0;
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-left: 16px;
  border-left: 1px solid var(--border);
  height: 28px;
}

/* Global search - primary navigation control: flat dark input, 1px border,
   4px radius (no pill), accent border on focus. */
.header-search {
  position: relative;
  display: flex;
  align-items: center;
  width: 100%;
  margin: 0;
}

.header-search-icon {
  position: absolute;
  left: 9px;
  color: var(--text-faint);
  pointer-events: none;
}

.header-search-input {
  width: 100%;
  height: 28px;
  padding: 0 40px 0 28px;
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font: inherit;
  font-size: 12px;
  outline: none;
  -webkit-appearance: none;
  appearance: none;
}

.header-search-input::placeholder {
  color: var(--text-faint);
}

.header-search-input::-webkit-search-cancel-button {
  display: none;
}

.header-search-input:hover {
  border-color: var(--text-faint);
}

.header-search-input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent);
}

.header-search:focus-within .header-search-icon {
  color: var(--accent);
}

.header-search-kbd {
  position: absolute;
  right: 6px;
  padding: 1px 5px;
  font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
  font-size: 10px;
  line-height: 14px;
  color: var(--text-faint);
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 3px;
  pointer-events: none;
}

/* Date / time readouts: micro-label over a tabular-figure value - distinct
   but compact, same monospace family as the existing toolbar badges. */
.header-readout {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 3px;
  white-space: nowrap;
}

.header-readout-label {
  font-size: 8px;
  line-height: 1;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--text-faint);
}

.header-readout-value {
  font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
  font-size: 12px;
  line-height: 1.2;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}

/* Market status pill - text + dot are written by app.js from the server's
   calendar-aware market summary; colors reuse the session-active/-closed tokens. */
.market-status-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 24px;
  padding: 0 10px;
  border: 1px solid var(--border);
  border-radius: 12px;
  font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  white-space: nowrap;
}

.market-status-pill:empty {
  display: none;
}

.market-status-pill::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}

.market-status-pill.session-active {
  border-color: var(--positive);
}

/* Data freshness: secondary to market status - plain dim text with a small
   status dot, no border/pill. ID-scoped because app.js rewrites this element's
   className (dropping toolbar-badge/header-data-badge) on every refresh. */
#data-status-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 0;
  border: 0;
  border-radius: 0;
  font-size: 9px;
  letter-spacing: 0.06em;
  color: var(--text-faint);
  white-space: nowrap;
}

#data-status-badge:empty {
  display: none;
}

#data-status-badge::before {
  content: '';
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--text-faint);
}

#data-status-badge.status-ok::before {
  background: var(--positive);
}

#data-status-badge.status-warn::before {
  background: var(--amber);
}

#data-status-badge.status-error::before {
  background: var(--negative);
}

#data-status-badge.status-running::before {
  background: var(--accent);
}

.header-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  margin: 0;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text-dim);
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
}

.header-icon-btn:hover {
  color: var(--text);
  background: var(--bg-raised);
}

.header-icon-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Notification bell + panel (in-app notifications). Compact, tokens only - same surface language as the account menu. */
.header-notifications {
  position: relative;
  display: flex;
  align-items: center;
}

#notifications-btn {
  position: relative;
}

#notifications-btn[aria-expanded="true"] {
  color: var(--text);
  background: var(--bg-raised);
}

.notif-badge {
  position: absolute;
  top: -5px;
  right: -5px;
  min-width: 15px;
  height: 15px;
  padding: 0 4px;
  box-sizing: border-box;
  border-radius: 8px;
  background: var(--accent);
  color: var(--accent-contrast);
  font-size: 9px;
  font-weight: 700;
  line-height: 15px;
  text-align: center;
  pointer-events: none;
}

.notif-badge[hidden] {
  display: none;
}

.notif-panel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: 340px;
  max-width: calc(100vw - 24px);
  max-height: min(70vh, 460px);
  display: flex;
  flex-direction: column;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
  z-index: 1000;
}

.notif-panel[hidden] {
  display: none;
}

.notif-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-bottom: 1px solid var(--border);
}

.notif-title {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--text-dim);
}

.notif-unread-count {
  flex: 1;
  font-size: 10px;
  color: var(--text-faint);
}

.notif-mark-all,
.notif-mark-read {
  font: inherit;
  font-size: 10px;
  color: var(--accent);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius);
  padding: 2px 6px;
  cursor: pointer;
}

.notif-mark-all:hover:not(:disabled),
.notif-mark-read:hover {
  background: var(--bg-raised);
  border-color: var(--border);
}

.notif-mark-all:focus-visible,
.notif-mark-read:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.notif-mark-all:disabled {
  color: var(--text-faint);
  cursor: default;
}

.notif-list {
  list-style: none;
  margin: 0;
  padding: 0;
  overflow-y: auto;
}

.notif-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 10px;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 55%, transparent);
}

.notif-item:last-child {
  border-bottom: 0;
}

.notif-item:hover {
  background: color-mix(in srgb, var(--accent) 8%, transparent);
}

.notif-unread {
  background: color-mix(in srgb, var(--accent) 6%, transparent);
}

.notif-marker {
  flex: none;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: transparent;
}

.notif-unread .notif-marker {
  background: var(--accent);
}

.notif-body {
  flex: 1;
  min-width: 0;
}

.notif-meta {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  font-size: 10px;
}

.notif-category {
  letter-spacing: 0.06em;
  color: var(--text-dim);
}

.notif-time {
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}

.notif-line {
  display: flex;
  align-items: baseline;
  gap: 6px;
  margin-top: 2px;
  font-size: 12px;
}

.notif-unread .notif-line {
  font-weight: 600;
}

.notif-read .notif-line {
  color: var(--text-dim);
}

.notif-sep {
  color: var(--text-faint);
}

.notif-long {
  color: var(--positive);
}

.notif-short {
  color: var(--negative);
}

.notif-empty {
  padding: 22px 14px;
  text-align: center;
}

.notif-empty-title {
  font-size: 12px;
  color: var(--text-dim);
}

.notif-empty-hint {
  margin-top: 4px;
  font-size: 10px;
  color: var(--text-faint);
}

/*
 * Account menu (StrikeIQ header user account dropdown fix): click/toggle,
 * never hover-driven. The previous `.header-account:hover .account-menu`
 * rule was the actual bug - the trigger's own hoverable box ends at its
 * text/icon, so any pointer path from the trigger down into the menu
 * (through the `margin-top` gap, or off-axis toward "Settings") left that
 * hoverable box and instantly closed the menu before the item could be
 * reached. State now lives entirely in the menu's `hidden` attribute,
 * toggled by app.js's click/outside-click/Escape handlers - CSS here is
 * presentation only.
 */
.header-account {
  position: relative;
  display: flex;
  align-items: center;
}

.account-trigger {
  display: flex;
  align-items: center;
  gap: 4px;
  background: transparent;
  margin: 0;
  padding: 0 8px;
  height: 28px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  cursor: pointer;
  color: var(--text-dim);
  font: inherit;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.05em;
}

.account-trigger:hover {
  color: var(--text);
  background: var(--bg-raised);
}

.account-trigger:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Open state (aria-expanded is the single source of truth app.js writes) reuses the same hover treatment, so the trigger reads as "active" the whole time the menu is open. */
.account-trigger[aria-expanded='true'] {
  color: var(--text);
  background: var(--bg-raised);
}

.account-dropdown-icon {
  font-size: 10px;
  transition: transform 0.15s ease;
}

.account-trigger[aria-expanded='true'] .account-dropdown-icon {
  transform: rotate(180deg);
}

.account-menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 6px;
  min-width: 180px;
  max-width: calc(100vw - 24px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
  z-index: 1000;
}

.account-menu[hidden] {
  display: none;
}

.account-menu-role {
  padding: 6px 10px 10px;
  font-size: 10px;
  color: var(--text-faint);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  border-bottom: 1px solid var(--border);
  margin-bottom: 4px;
}

/* Settings (<a>) and Logout (<button>) share one look - same box, padding,
   typography and hover/focus treatment - so the two menu items read as a
   single consistent set, not a styled button next to a bare browser link. */
.account-menu-link,
.btn-logout {
  display: block;
  width: 100%;
  box-sizing: border-box;
  text-align: left;
  background: transparent;
  border: none;
  border-radius: var(--radius);
  color: var(--text);
  padding: 8px 10px;
  font: inherit;
  font-size: 12px;
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
}

.account-menu-link:hover,
.btn-logout:hover {
  background: var(--bg-raised);
}

.account-menu-link:focus-visible,
.btn-logout:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.theme-toggle {
  color: var(--text-dim);
  font-size: 14px;
  cursor: pointer;
}

#session-status.session-active,
.session-active {
  color: var(--positive);
}

#session-status.session-closed,
.session-closed {
  color: var(--text-faint);
}

/* Primary workspace navigation - dense terminal style, own row below the
   brand/status header row. Tightened (Dashboard Phase 1 density pass) so
   all groups fit within a normal viewport without horizontal scrolling;
   overflow-x stays as a narrow-viewport fallback, not the primary fit
   strategy. */
.primary-nav {
  display: flex;
  align-items: center;
  gap: 20px;
  height: 44px;
  padding: 0 20px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-panel);
  overflow-x: auto;
  flex-wrap: nowrap;
  width: 100%;
  scrollbar-width: none; /* Hide scrollbar for clean layout */
}
.primary-nav::-webkit-scrollbar {
  display: none;
}

/* Nav links are only ~27px tall within the 44px row (padding, not the row
   height, is the actual tap target) - fine for a pointer, short for a
   thumb. The row grows to match so taller links never overflow it; the
   horizontal-scroll fallback above is unchanged, still the same nav on a
   narrow phone, just a touch-sized row. Desktop/tablet untouched.
   `.primary-nav .nav-link` (not the bare class) so this reliably beats the
   unconditional `.nav-link { padding: 6px 10px }` rule declared later in
   this file, regardless of source order. */
@media (max-width: 640px) {
  .primary-nav {
    height: 48px;
  }

  .primary-nav .nav-link {
    padding: 10px 12px;
  }
}

.nav-group {
  display: flex;
  align-items: center;
  gap: 2px;
  padding-left: 20px;
  border-left: 1px solid var(--border);
  white-space: nowrap;
  flex-shrink: 0;
}

.nav-group:first-child {
  padding-left: 0;
  border-left: none;
}

.nav-group-label {
  font-size: 9px;
  font-weight: 500;
  color: var(--text-faint);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-right: 8px;
  opacity: 0.85;
}

.nav-link {
  display: inline-block;
  padding: 6px 10px;
  color: var(--text-dim);
  text-decoration: none;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.15;
  border-radius: var(--radius);
  transition: background-color 0.15s, color 0.15s;
}

.nav-link:hover {
  color: var(--text);
  background: var(--bg-raised);
}

.nav-link.is-active {
  color: var(--accent);
  background: var(--bg-raised);
  box-shadow: inset 0 -2px 0 var(--accent);
}

.workspace-shell {
  padding: 0 0 40px;
}

.workspace {
  padding: 16px 20px 0;
}

.workspace-header {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 12px;
}

.workspace-header h1 {
  margin: 0;
  font-size: 14px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.workspace-subtitle {
  color: var(--text-dim);
  font-size: 11px;
}

/* `.workspace-header` is shared by every workspace (BASE/Snapshots/BBRS/
   Confluence/Metrics/Futures/Watchlist/Paper Trading/Settings, not just
   Overview - Overview has its own always-on wrapping override elsewhere in
   this file, which this doesn't touch). On desktop it fits on one row;
   several of those workspaces add a long subtitle plus a badge/select/
   filter group (`.date-refresh-group`, `.underlying-label`, `.paper-filter`,
   ...) to the SAME row with no wrap, which overflows the viewport once it's
   a phone rather than a narrow desktop window. Scoped to this one
   breakpoint so every desktop/tablet layout is unchanged. */
@media (max-width: 640px) {
  .workspace-header {
    flex-wrap: wrap;
    row-gap: 6px;
  }

  .workspace-header > .date-refresh-group {
    margin-left: 0;
    flex-basis: 100%;
  }
}

/* Overview - Section 2: concise command-center */
.overview-wrap {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: 1400px;
}

.overview-meta {
  display: none; /* Moved to toolbar natively */
}



.market-snapshot-header {
  margin-top: 8px;
  margin-bottom: 4px;
}

.market-snapshot-header.futures-market-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
}

.futures-market-header-left {
  display: flex;
  flex-direction: column;
}

.view-futures-link {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  color: var(--accent);
  text-decoration: none;
  letter-spacing: 0.05em;
}

.view-futures-link:hover {
  text-decoration: underline;
}

.market-snapshot-title {
  font-size: 11px;
  font-weight: 700;
  color: var(--text-dim);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.market-snapshot-subtitle {
  display: none;
}

.market-snapshot-table {
  width: 100%;
  max-width: 800px;
  border-collapse: collapse;
  font-size: 12px;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  background: var(--bg-panel);
  border: 1px solid var(--border);
}

.market-snapshot-table th {
  text-align: right;
  padding: 6px 10px;
  color: var(--text-dim);
  font-weight: 600;
  font-size: 10px;
  text-transform: uppercase;
  border-bottom: 1px solid var(--border);
  background: var(--bg-header);
}

.market-snapshot-table td {
  padding: 6px 10px;
  text-align: right;
  border-bottom: 1px solid var(--border);
}

.market-snapshot-table tr:hover,
.futures-market-table tr:hover {
  background: var(--bg-raised);
}

/* The authoritative `.futures-market-table`/`th`/`td` rules (including the
   default text-align this table relies on) live in one place further down
   this file (Dashboard Futures panel density pass) - see that block's own
   comment. `.text-left` (the SYMBOL column's override) stays here since
   it's the only thing this table still needs from this spot. */
.futures-market-table .text-left {
  text-align: left;
}

.toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 20px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-raised);
  font-size: 11px;
}

.command-bar-left,
.command-bar-right {
  display: flex;
  align-items: center;
  gap: 10px;
}

.header-status {
  display: flex;
  align-items: center;
  gap: 12px;
}

.date-label {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--text-dim);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

#trading-date-input {
  background: var(--bg-panel);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 6px 10px;
  font-size: 13px;
  font-weight: 700;
  height: 30px;
}

#trading-date-input::-webkit-calendar-picker-indicator {
  filter: var(--date-picker-icon-filter, none);
  cursor: pointer;
  opacity: 0.75;
}

#trading-date-input::-webkit-calendar-picker-indicator:hover {
  opacity: 1;
}

/* BASE/Snapshots underlying + slot selectors - same visual language as the trading-date input. */
.underlying-label {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--text-dim);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.underlying-label select {
  background: var(--bg-raised);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 4px 8px;
  font-size: 13px;
}

#refresh-btn {
  background: var(--bg-panel);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 6px 16px;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  height: 30px;
  cursor: pointer;
}

#refresh-btn:hover {
  border-color: var(--accent);
  color: var(--accent);
}

#refresh-btn:disabled {
  opacity: 0.55;
  cursor: default;
  border-color: var(--border);
  color: var(--text);
}

.date-label-compact {
  display: inline-flex;
  align-items: center;
}

.date-label-compact input {
  background: transparent;
  color: var(--text);
  font-size: 13px;
  font-weight: 700;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  font-variant-numeric: tabular-nums;
  outline: none;
}

.btn-toolbar {
  background: var(--bg-panel);
  color: var(--text-dim);
  border: 1px solid var(--border);
  border-radius: 2px;
  padding: 2px 8px;
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  cursor: pointer;
}

.btn-toolbar:hover {
  border-color: var(--accent);
  color: var(--text);
}

.toolbar-badge,
.data-status-badge {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  font-weight: 600;
  font-size: 10px;
  color: var(--text-faint);
  border: 1px solid var(--border);
  padding: 2px 6px;
  border-radius: 2px;
}

.toolbar-badge.status-ok, .data-status-badge.status-ok { color: var(--positive); border-color: var(--positive); }
.toolbar-badge.status-warn, .data-status-badge.status-warn { color: var(--amber); border-color: var(--amber); }
.toolbar-badge.status-error, .data-status-badge.status-error { color: var(--negative); border-color: var(--negative); }
.toolbar-badge.status-running, .data-status-badge.status-running { color: var(--accent); border-color: var(--accent); }

/* Right-side control bar readout - shows the persisted snapshot's own
   date+time (never a fabricated/client-computed timestamp), styled as a
   compact status readout rather than a generic badge/button. */
.snapshot-readout {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 30px;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0 10px;
}

.snapshot-readout-label {
  font-size: 9px;
  font-weight: 700;
  color: var(--text-faint);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  white-space: nowrap;
}

.snapshot-readout-value {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  font-size: 12px;
  font-weight: 600;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.auto-refresh-compact {
  display: flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 10px;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font-size: 10px;
  font-weight: 700;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  cursor: pointer;
}

/* Custom checkbox rendered as a compact toggle switch - same functional
   input/id/listener as before, visual only. */
.auto-refresh-compact input {
  appearance: none;
  margin: 0;
  width: 26px;
  height: 15px;
  border-radius: 999px;
  background: var(--border);
  border: 1px solid var(--border);
  position: relative;
  cursor: pointer;
  flex-shrink: 0;
  transition: background-color 0.15s, border-color 0.15s;
}

.auto-refresh-compact input::before {
  content: '';
  position: absolute;
  top: 1px;
  left: 1px;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--bg-panel);
  transition: transform 0.15s;
}

.auto-refresh-compact input:checked {
  background: var(--positive);
  border-color: var(--positive);
}

.auto-refresh-compact input:checked::before {
  transform: translateX(11px);
  background: #ffffff;
}

.threepm-notice {
  padding: 8px 16px;
  font-size: 12px;
  color: var(--amber);
  border-bottom: 1px solid var(--border);
}

/* States */
.state {
  padding: 28px 16px;
  text-align: center;
}

.state-title {
  font-weight: 600;
  font-size: 14px;
}

.state-message {
  color: var(--text-dim);
  font-size: 13px;
  margin-top: 4px;
}

.state-loading {
  color: var(--text-dim);
  font-size: 13px;
}

.state-action-link {
  display: inline-block;
  margin-top: 10px;
  font-size: 12px;
  font-weight: 700;
  color: var(--accent);
  text-decoration: none;
  letter-spacing: 0.03em;
}

.state-action-link:hover {
  text-decoration: underline;
}

.state-error .state-title {
  color: var(--negative);
}

/* Tables */
.signal-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
}

.signal-table th {
  text-align: right;
  padding: 6px 10px;
  color: var(--text-dim);
  font-weight: 600;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
  position: sticky;
  top: 0;
  background: var(--bg-header);
  z-index: 10;
  vertical-align: middle;
}

.group-header-row th {
  top: 0;
  z-index: 11;
  padding: 4px 10px;
  font-size: 10px;
  color: var(--text-faint);
  border-bottom: 1px solid var(--border);
  background: var(--bg-group-header);
}

.signal-table thead tr:nth-child(2) th {
  top: 24px;
}

.text-center {
  text-align: center !important;
}

.signal-table td {
  padding: 6px 10px;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
  text-align: right;
  vertical-align: middle;
}

.signal-table tbody tr:hover {
  background: var(--bg-raised);
}

.signal-table th.text-left,
.signal-table td.text-left {
  text-align: left;
}

/* SORTABLE COLUMN HEADERS - shared across every table type (signal-table,
   market-data-table, futures-table, metrics-table, live-preview-table).
   Deliberately a muted text-only affordance (Section 13): no icon glyphs,
   no oversized controls - a small ↕ hint on hover, a ▲/▼ once a column is
   actively sorted. Driven entirely by ::after pseudo-content and classes so
   header textContent never changes (nothing else in the app reads the
   arrow, and it keeps existing header-label lookups exact). */
.sortable-col {
  cursor: pointer;
  user-select: none;
}

.sortable-col:hover,
.sortable-col:focus-visible {
  color: var(--text);
}

.sortable-col:focus-visible {
  outline: 1px solid var(--accent);
  outline-offset: -2px;
}

/*
 * Fixed-width reserved slot for the indicator glyph (Phase 10 instructions
 * Part 13): ↕/▲/▼ swap on click, but the box they sit in never changes
 * size, so clicking a header cannot shift that header's own width/geometry
 * - independent of the explicit column widths below, which already fix
 * the table's overall column geometry regardless of header content.
 */
.sortable-col::after {
  content: '\2195';
  display: inline-block;
  width: 10px;
  margin-left: 4px;
  font-size: 9px;
  text-align: center;
  opacity: 0.32;
}

.sortable-col:hover::after,
.sortable-col:focus-visible::after {
  opacity: 0.75;
}

.sortable-col.sort-asc,
.sortable-col.sort-desc {
  color: var(--accent);
}

.sortable-col.sort-asc::after {
  content: '\25B2';
  opacity: 1;
}

.sortable-col.sort-desc::after {
  content: '\25BC';
  opacity: 1;
}

/* Provide a scrolling container for tables so sticky headers work */
.table-wrap {
  overflow: auto;
  max-height: calc(100vh - 190px);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.identity {
  display: flex;
  gap: 8px;
  align-items: baseline;
  text-align: left;
}

.identity-underlying {
  font-weight: 700;
}

.identity-strike {
  font-weight: 700;
  color: var(--accent);
}

.identity-offset {
  color: var(--text-faint);
  font-size: 11px;
}

/* Dashboard Overview Radar panel only (`buildOverviewRadarIdentityCell` in
   render.js) - tighter gap than the base `.identity` (8px) now that the
   offset shows as a bare `+2`/`0`/`-2` instead of `identityCell`'s
   `offset +2` text, so the identity block needs less horizontal room.
   Watchlist/3PM/the full Radar workspace keep the base `.identity` gap
   unchanged. `identity-compact` now sits on the outer `<td>` (a plain
   table-cell, alongside `identity-cell` - shared row-divider fix, same as
   `identityCell()`/`watchlistIdentityCell()`), with the actual `.identity`
   flex box one level in on an inner `<span>`, so the gap override targets
   that inner span rather than the (no longer flex) `<td>` itself. */
.identity-compact .identity {
  gap: 4px;
}

/* Watchlist's combined Underlying/Strike/Offset identity cell (Phase 9
   instructions Parts 1/6) - explicit nowrap on top of `.identity`'s flex
   row so the three spans always render as one compact line, never stacked. */
.watchlist-identity {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* The truncation above used to sit directly on `.watchlist-identity`'s
   `<td>` back when it was also the `.identity` flex container itself; that
   flex box now lives one level in (see `watchlistIdentityCell()` in
   render.js - shared row-divider fix), so the same nowrap/overflow/ellipsis
   needs repeating on the inner flex box for a genuinely overlong combined
   value to still truncate the same way. `min-width: 0` is required for a
   flex item to shrink below its content size at all. */
.watchlist-identity .identity {
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.positive {
  color: var(--positive);
}

.negative {
  color: var(--negative);
}

.pe-oi.positive {
  font-weight: 700;
}

.signal-time {
  color: var(--text-dim);
}

/* Watchlist evidence row (Phase 8 Part 4): pure reference values (contract
   expiry, raw spot) sit muted so identity stays the strongest element and
   directional CE/PE evidence (colored via .positive/.negative) reads as
   the actionable signal - never the whole row tinted. */
.reference-value {
  color: var(--text-dim);
}

.tier-badge,
.action-badge,
.paper-badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  border: 1px solid transparent;
  white-space: nowrap;
}

.tier-TOP_PICK {
  color: var(--tier-top-pick);
  border-color: var(--tier-top-pick);
}

.tier-STRONG {
  color: var(--amber);
  border-color: var(--amber);
}

.tier-GOOD {
  color: var(--text-dim);
  border-color: var(--border);
}

.action-BUY_NOW {
  color: var(--positive);
  border-color: var(--positive);
}

.action-WATCH {
  color: var(--amber);
  border-color: var(--amber);
}

.action-IGNORE {
  color: var(--text-faint);
  border-color: var(--border);
}

/* BBRS-3 signal badges - same tier-badge/action-badge shape, one color rule
   per canonical BBRS-2 signal value (never a rainbow of invented colors).
   GREEN_LONG/RED_SHORT reuse the existing positive/negative pair, BLUE_LONG
   reuses --accent (already a blue tone), YELLOW_SHORT reuses --amber
   (closest existing "secondary/caution" token) - no new custom properties. */
.bbrs-badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  border: 1px solid transparent;
  white-space: nowrap;
}
.bbrs-GREEN_LONG {
  color: var(--positive);
  border-color: var(--positive);
}
.bbrs-BLUE_LONG {
  color: var(--accent);
  border-color: var(--accent);
}
.bbrs-RED_SHORT {
  color: var(--negative);
  border-color: var(--negative);
}
.bbrs-YELLOW_SHORT {
  color: var(--amber);
  border-color: var(--amber);
}
.bbrs-NONE {
  color: var(--text-faint);
  border-color: var(--border);
}

/* BBRS-4 Confluence state badge - deliberately minimal color decoration
   (instructions section 20): only the two CONFIRMED states and CONFLICT get
   a semantic color, every other exhaustive state (BBRS_ONLY_* and STRIKEIQ_ONLY_* variants,
   NO_DIRECTIONAL_SIGNAL/DATA_UNAVAILABLE) reuses the same neutral treatment. */
.confluence-badge {
  display: inline-block;
  padding: 4px 12px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 700;
  border: 1px solid var(--border);
  color: var(--text-faint);
  white-space: nowrap;
}
.confluence-CONFIRMED_LONG {
  color: var(--positive);
  border-color: var(--positive);
}
.confluence-CONFIRMED_SHORT {
  color: var(--negative);
  border-color: var(--negative);
}
.confluence-CONFLICT {
  color: var(--amber);
  border-color: var(--amber);
}

.paper-badge {
  border-radius: var(--radius);
}

.paper-open {
  color: var(--accent);
  border-color: var(--accent);
}

.paper-closed {
  color: var(--text-dim);
  border-color: var(--border);
}

.paper-none {
  color: var(--text-faint);
  border-color: transparent;
}

.paper-row-closed {
  opacity: 0.5;
}

.paper-row-closed:hover {
  opacity: 1;
}

/* Paper-trade action buttons - deliberately styled distinctly from
   intelligence badges (BUY NOW / WATCH / TOP PICK) so a paper action never
   reads as a real order (Phase 6 instructions section 25). */
.paper-action {
  white-space: nowrap;
  /* !important to beat .signal-table td's own text-align: right - same
     pattern as .text-center above. */
  text-align: center !important;
}

/* Fixed geometry (Phase 10 instructions Part 14) - the label text never
   changes the button's own box, and the button sits centered in its
   column via .paper-action{text-align:center} above. */
.btn-paper-trade,
.btn-close-position {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 104px;
  height: 28px;
  background: var(--bg-raised);
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  padding: 0 10px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}

.btn-paper-trade:hover,
.btn-close-position:hover {
  background: var(--accent);
  color: var(--bg);
}

.btn-paper-trade:disabled,
.btn-close-position:disabled {
  opacity: 0.6;
  cursor: default;
}

.outcome-value {
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}

/* Paper Positions status filter */
.paper-filter {
  margin-left: auto;
  display: flex;
  gap: 6px;
}

.filter-btn {
  background: transparent;
  color: var(--text-dim);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 4px 10px;
  font-size: 12px;
  cursor: pointer;
}

/* `.filter-btn` (Paper Trading's All/Open/Closed filter, and the shared
   BBRS/Confluence scanner filter bar) is a real tap target, not just a
   label - 4px/10px desktop padding is mouse-comfortable but small for a
   thumb. Desktop/tablet sizing is unchanged. */
@media (max-width: 640px) {
  .filter-btn {
    padding: 8px 12px;
    font-size: 13px;
  }
}

.filter-btn.is-active {
  color: var(--accent);
  border-color: var(--accent);
}

/* Confirmation modal (Paper Trade / Close) */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(4, 6, 9, 0.7);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  z-index: 100;
}

.modal-card {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  width: 100%;
  max-width: 420px;
  max-height: 90vh;
  overflow-y: auto;
  padding: 18px 20px;
}

.modal-title {
  margin: 0 0 12px;
  font-size: 15px;
  font-weight: 700;
}

.modal-body {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.modal-field {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 13px;
  padding: 4px 0;
  border-bottom: 1px solid var(--border);
}

.modal-field-label {
  color: var(--text-dim);
}

.modal-field-value {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  text-align: right;
}

.modal-warning {
  margin-top: 12px;
  padding: 8px 10px;
  border: 1px solid var(--amber);
  border-radius: var(--radius);
  color: var(--amber);
  font-size: 12px;
  font-weight: 600;
  text-align: center;
}

.modal-error {
  margin-top: 12px;
  padding: 8px 10px;
  border: 1px solid var(--negative);
  border-radius: var(--radius);
  color: var(--negative);
  font-size: 12px;
}

.modal-actions {
  margin-top: 16px;
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

.btn-modal-cancel,
.btn-modal-confirm {
  border-radius: var(--radius);
  padding: 7px 16px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}

.btn-modal-cancel {
  background: transparent;
  color: var(--text-dim);
  border: 1px solid var(--border);
}

.btn-modal-confirm {
  background: var(--accent);
  color: var(--accent-contrast);
  border: 1px solid var(--accent);
}

.btn-modal-confirm:disabled,
.btn-modal-cancel:disabled {
  opacity: 0.6;
  cursor: default;
}

/* Delete User confirmation - existing red/danger theme token, same shape as the default confirm button. */
.btn-modal-confirm-danger {
  background: var(--negative);
  color: var(--accent-contrast);
  border: 1px solid var(--negative);
}

/* LIVE MARKET PREVIEW - deliberately distinct from the persisted
   data-status badge above (different color, different verb - "Fetched at",
   never "Last snapshot") so it can never read as a persisted snapshot. */
.btn-live-preview {
  margin-left: auto;
  background: var(--bg-raised);
  color: var(--amber);
  border: 1px solid var(--amber);
  border-radius: var(--radius);
  padding: 6px 14px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}

.btn-live-preview:hover {
  background: var(--amber);
  color: var(--bg);
}

.btn-live-preview:disabled {
  opacity: 0.6;
  cursor: default;
}

/* LIVE MARKET symbol picker - bounded, searchable selector over the full
   canonical F&O universe (200+ symbols), so opening the workspace never by
   itself fetches everything at once. */
.live-market-picker {
  margin: 4px 16px 16px;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised);
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.live-market-picker-controls {
  display: flex;
  align-items: flex-end;
  gap: 10px;
  flex-wrap: wrap;
}

.live-market-search-label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 12px;
  color: var(--text-dim);
}

.live-market-search-label input {
  padding: 6px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--text);
  font-size: 13px;
  min-width: 220px;
}

.btn-secondary {
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 6px 12px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}

.btn-secondary:hover {
  border-color: var(--amber);
  color: var(--amber);
}

/* Destructive actions (Delete User) - existing red/danger theme token
   (var(--negative)), same outline-then-fill hover pattern as .btn-live-preview. */
.btn-danger {
  background: var(--bg);
  color: var(--negative);
  border: 1px solid var(--negative);
  border-radius: var(--radius);
  padding: 6px 12px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}

.btn-danger:hover {
  background: var(--negative);
  color: var(--accent-contrast);
}

.btn-danger:disabled {
  opacity: 0.5;
  cursor: default;
  background: var(--bg);
  color: var(--negative);
}

.live-market-symbol-select {
  width: 100%;
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 4px;
  font-size: 13px;
}

.live-market-symbol-select option[hidden] {
  display: none;
}

.live-market-picker-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.live-market-selection-count {
  font-size: 12px;
  color: var(--text-dim);
}

.live-preview-truncated-notice {
  padding: 8px 12px;
  border: 1px solid var(--amber);
  border-radius: var(--radius);
  color: var(--amber);
  font-size: 12px;
}

.live-preview-wrap {
  padding: 4px 16px 16px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.live-preview-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.live-preview-badge {
  display: inline-block;
  padding: 3px 9px;
  border-radius: var(--radius);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--amber);
  border: 1px solid var(--amber);
}

.live-preview-fetched {
  color: var(--text-faint);
  font-size: 12px;
}

.live-preview-error {
  color: var(--negative);
  font-size: 12px;
  padding: 6px 10px;
  border: 1px solid var(--negative);
  border-radius: var(--radius);
}

.live-preview-underlying {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}

.live-preview-underlying-header {
  display: flex;
  align-items: baseline;
  gap: 14px;
  flex-wrap: wrap;
  padding: 10px 14px;
  background: var(--bg-raised);
  border-bottom: 1px solid var(--border);
}

.live-preview-spot {
  font-size: 16px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.live-preview-detail {
  color: var(--text-dim);
  font-size: 12px;
}

/* Real <table> + table-layout: fixed so its <colgroup> (render.js) takes
   effect - see the .market-data-table comment above for why the old
   split-thead/tbody-into-block hack is gone. Scrolling/sticky-header
   behavior comes from the .table-wrap ancestor. */
.live-preview-table {
  table-layout: fixed;
}

.live-preview-leg {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

.live-preview-leg-empty {
  color: var(--text-faint);
}

.live-preview-leg-label {
  color: var(--text-faint);
  font-size: 11px;
  width: 20px;
}

.live-preview-leg-price {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.live-preview-leg-oi {
  color: var(--text-dim);
  font-size: 11px;
}

.live-preview-partial {
  padding: 6px 14px;
  color: var(--amber);
  font-size: 12px;
  border-top: 1px solid var(--border);
}

/* BASE / Snapshots MARKET DATA WORKSPACE - dense, spreadsheet-parity
   tables. Legacy column names shown verbatim (StrikeLabel/PRICE/...) -
   never renamed, this is an audit view of the persisted data. */
.market-data-wrap {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.market-data-meta {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  padding-bottom: 12px;
  margin-bottom: 12px;
  border-bottom: 1px solid var(--border);
}

.market-data-badge {
  display: inline-block;
  padding: 3px 9px;
  border-radius: var(--radius);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  border: 1px solid transparent;
}

/* BASE is frozen/immutable - deliberately a cooler, static color, never the amber "live" tone Live Market Preview uses. */
.base-badge {
  color: var(--rank2);
  border-color: var(--rank2);
}

.snapshot-badge {
  color: var(--accent);
  border-color: var(--accent);
}

.market-data-note {
  color: var(--text-faint);
  font-size: 12px;
  font-style: italic;
}

/*
 * Fixed, disciplined column geometry (Phase 10 instructions - geometry
 * pass): `table-layout: fixed` + no `width: 100%` means the table sizes
 * itself to the sum of its <colgroup> widths (declared per-table in
 * render.js) instead of stretching every column to fill whatever space
 * happens to be available - this is what keeps the identity column
 * compact instead of consuming half the table. The bounding/scrolling
 * behavior comes from the shared `.table-wrap` ancestor every caller
 * already wraps the table in (overflow: auto; max-height), so `<th>
 * position: sticky` pins correctly without splitting thead/tbody into
 * separate table boxes (that split silently ignores <colgroup>).
 */
.market-data-table {
  table-layout: fixed;
}

.market-data-table thead th {
  position: sticky;
  top: 0;
  background: var(--bg-header);
  z-index: 1;
}

.market-data-table thead .group-header-row th {
  background: var(--bg-group-header);
}

/* ATM row - visibly highlighted per the MARKET DATA WORKSPACE spec, distinct from but consistent with the identity-strike accent color used elsewhere. */
.atm-row {
  background: rgba(79, 140, 255, 0.08);
}

.atm-row:hover {
  background: rgba(79, 140, 255, 0.14);
}

.atm-row td.identity {
  color: var(--accent);
  font-weight: 700;
}

/* FUTURES workspace (STRIKEIQ Futures correction) - dense, spreadsheet-style,
   deliberately no BASE-style "frozen reference" badge language. */
.futures-status {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-left: auto;
  font-size: 12px;
}

.futures-meta-item {
  color: var(--text-faint);
}

.futures-meta-item.status-ok {
  color: var(--positive);
}

.futures-meta-item.status-warn {
  color: var(--amber);
}

.futures-meta-item.status-error {
  color: var(--negative);
}

.futures-table {
  table-layout: fixed;
}

.futures-table thead th {
  position: sticky;
  top: 0;
  background: var(--bg-header);
  z-index: 1;
}

.futures-partial-notice {
  padding: 10px 14px;
  color: var(--amber);
  font-size: 12px;
  border-top: 1px solid var(--border);
}

/* Monthly Metrics only (Daily Metrics passes no `cmpNote`, so it never
   renders this): one line stating CMP's meaning once, instead of relabeling
   every per-date CMP sub-header. */
.metrics-cmp-note {
  padding: 0 0 8px;
  color: var(--text-dim);
  font-size: 12px;
}

/* DAILY METRICS / MONTHLY METRICS - dense spreadsheet matrix (legacy
   Daily/EOD_Master_DB sheets): frozen StrikeLabel column, frozen 2-row
   grouped header (timestamp/date group + CMP/CE_OI/PE_OI sub-header),
   horizontally AND vertically scrollable. Deliberately no positive/negative
   coloring - this workspace has no delta/growth column to color. */
.metrics-matrix-wrap {
  overflow: auto;
  max-height: 720px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.metrics-table {
  border-collapse: separate;
  border-spacing: 0;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}

.metrics-table th,
.metrics-table td {
  padding: 6px 10px;
  border-bottom: 1px solid var(--border);
  border-right: 1px solid var(--border);
  white-space: nowrap;
  text-align: right;
  vertical-align: middle;
}

/* CMP/CE_OI/PE_OI sub-headers align with their right-aligned numeric
   columns beneath them (Phase 10 instructions Part 1/4/11) - only the
   StrikeLabel corner (.metrics-frozen-col, left) and the merged date/time
   group row above (centered, spans 3 columns) differ from this. */
.metrics-table thead th.metrics-sub-header {
  text-align: right;
}

.metrics-table thead th {
  position: sticky;
  background: var(--bg-panel);
  color: var(--text-dim);
  font-weight: 600;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  text-align: center;
  z-index: 2;
}

.metrics-table thead tr:first-child th {
  top: 0;
  z-index: 3;
}

/* Height of the first (group) header row - keeps the second (CMP/CE_OI/PE_OI) row pinned directly beneath it rather than overlapping. */
.metrics-table thead tr:nth-child(2) th {
  top: 29px;
}

.metrics-group-header {
  background: var(--bg-raised);
}

.metrics-pe-header {
  color: var(--text-faint);
}

.metrics-frozen-col {
  position: sticky;
  left: 0;
  background: var(--bg-panel);
  z-index: 1;
  text-align: left;
}

.metrics-table thead th.metrics-frozen-col,
.metrics-table thead th.metrics-corner {
  z-index: 4;
  /* StrikeLabel stays left-aligned like its body column beneath it (Phase
     10 instructions Part 1/11), overriding the generic centered-header rule. */
  text-align: left;
}

.metrics-table tbody tr:hover td {
  background: var(--bg-raised);
}

.metrics-table tbody tr:hover td.metrics-frozen-col {
  background: var(--bg-raised);
}

/* Responsive: desktop-first, keep tables usable down to tablet width. */
@media (max-width: 900px) {
  .toolbar {
    flex-wrap: wrap;
    row-gap: 8px;
  }

  .last-snapshot {
    margin-left: 0;
    width: 100%;
  }

  /* `.toolbar` wrapping alone only lets `.command-bar-left`/`.command-bar-right`
     (its two direct children) drop onto their own line each - within
     `.command-bar-right` itself, the Trading Date group, Last Snapshot
     readout and Auto-refresh toggle stayed one un-wrapping row, wide enough
     to overflow the viewport on a phone. They wrap as whole units here
     instead (never split apart), and the 14px gap that only made sense
     between them on one long desktop row collapses so wrapped rows don't
     look lopsided. */
  .command-bar-left,
  .command-bar-right {
    flex-wrap: wrap;
    row-gap: 8px;
  }

  /* Extra specificity (`.command-bar-right .command-bar-snapshot`, not the
     bare class) so this reliably beats the unconditional `margin-left: 14px`
     base rule declared later in this file, regardless of source order -
     same technique the existing `:has(#overview-header-status[hidden])`
     override below already relies on for this same element. */
  .command-bar-right .command-bar-snapshot {
    margin-left: 0;
  }

  .signal-table {
    display: block;
    overflow-x: auto;
  }
}

/* ATM highlight for Live Market & BASE */
.atm-row {
  background: var(--bg-raised);
}
.atm-row td {
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  font-weight: 600;
}

/* Instrument Headers for BASE / Snapshots */
.instrument-header {
  margin-bottom: 16px;
  padding: 12px 16px;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.instrument-header-top {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 12px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border);
}
.instrument-title {
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 0.02em;
}
.instrument-subtitle {
  font-size: 12px;
  color: var(--text-dim);
}
.instrument-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
}
.stat-block {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.stat-label {
  font-size: 10px;
  font-weight: 600;
  color: var(--text-faint);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.stat-value {
  font-size: 14px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.stat-primary {
  color: var(--accent);
}
.stat-highlight {
  background: var(--bg-raised);
  padding: 4px 8px;
  border-radius: var(--radius);
  margin: -4px -8px;
}
.stat-highlight .stat-value {
  color: var(--amber);
}

/* BBRS-3 workspace panels (Signal History / Bar History / Condition
   Inspection) - same panel language as .instrument-header, stacked with
   explicit spacing since .market-data-wrap itself uses gap: 0. */
.bbrs-panel {
  margin-bottom: 16px;
  padding: 12px 16px;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.bbrs-panel-title {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--text-dim);
  margin-bottom: 12px;
}
.bbrs-panel .table-wrap {
  border: none;
  max-height: none;
}

/* BBRS 1H + 1D PARALLEL VIEW - two equal-width panels (LEFT 1h / RIGHT 1d)
   in the same panel language as .bbrs-panel/.instrument-header; existing
   tokens only. Stacks to one column at the design system's 900px break, and
   `minmax(0, 1fr)` + `min-width: 0` keep either panel from ever forcing
   page-level horizontal overflow. */
.bbrs-timeframe-context-value {
  color: var(--text);
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 4px 8px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
}
.bbrs-dual-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  align-items: start;
  margin-bottom: 16px;
}
.bbrs-dual-panel {
  min-width: 0;
  padding: 12px 16px;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.bbrs-dual-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--border);
}
.bbrs-dual-title {
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.04em;
}
.bbrs-dual-sub {
  font-size: 11px;
  color: var(--text-dim);
  white-space: nowrap;
}
.bbrs-dual-section-title {
  margin-bottom: 8px;
  font-size: 10px;
  font-weight: 700;
  color: var(--text-faint);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.bbrs-dual-stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px 16px;
}
/* A joined multi-signal badge (e.g. GREEN + BLUE) may be wider than one of the three columns - let it wrap inside its cell instead of overflowing into the next. */
.bbrs-dual-stats .bbrs-badge {
  white-space: normal;
  text-align: center;
}
.bbrs-dual-panel .state {
  padding: 20px 8px;
}
.bbrs-dual-option {
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
}
.bbrs-option-table {
  width: 100%;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}
.bbrs-option-table th {
  padding: 0 0 4px;
  font-size: 10px;
  font-weight: 600;
  color: var(--text-faint);
  text-align: right;
  letter-spacing: 0.05em;
}
.bbrs-option-table td {
  padding: 3px 0;
  font-size: 14px;
  font-weight: 600;
  text-align: right;
}
.bbrs-option-table th:first-child,
.bbrs-option-table td:first-child {
  width: 64px;
  text-align: left;
}
.bbrs-option-table td.bbrs-option-side {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.05em;
  color: var(--text-dim);
}
.bbrs-asof {
  margin-top: 8px;
  font-size: 11px;
  font-weight: 600;
  color: var(--text);
  letter-spacing: 0.03em;
}
.bbrs-option-note {
  margin-top: 2px;
  font-size: 11px;
  color: var(--text-faint);
}
@media (max-width: 900px) {
  .bbrs-dual-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* BBRS-4 Confluence workspace - STRIKEIQ INTELLIGENCE and BBRS side by side
   (each an existing .bbrs-panel), stacking to one column on narrow
   viewports rather than ever overflowing. */
.confluence-evidence-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 16px;
}
.confluence-evidence-row .bbrs-panel {
  margin-bottom: 0;
}
.confluence-source-note {
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
  font-size: 11px;
  color: var(--text-faint);
}
.confluence-result-panel {
  display: flex;
  align-items: center;
  gap: 12px;
}

/* CONDITION INSPECTION - compact diagnostic grid, one column per group
   (INDECISION/SETUP/STOCHASTIC/SIGNALS), never a decorative dashboard. */
.bbrs-condition-groups {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 20px;
}
.bbrs-condition-group-title {
  font-size: 10px;
  font-weight: 700;
  color: var(--text-faint);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 8px;
  padding-bottom: 4px;
  border-bottom: 1px solid var(--border);
}
.bbrs-condition-row {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  padding: 3px 0;
  font-size: 12px;
}
.bbrs-condition-label {
  color: var(--text-dim);
}
.bbrs-condition-value {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.bbrs-condition-value.bbrs-true {
  color: var(--positive);
}
.bbrs-condition-value.bbrs-false {
  color: var(--text-faint);
}

/* Radar Conditions Legend */
.radar-legend {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  width: fit-content;
  max-width: 100%;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin-bottom: 16px;
  padding: 8px 14px;
  overflow-x: auto;
  white-space: nowrap;
}
.radar-legend-label {
  font-weight: 700;
  font-size: 11px;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding-right: 4px;
  border-right: 1px solid var(--border);
  white-space: nowrap;
}
.radar-legend-item {
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
  padding-left: 14px;
  border-left: 1px solid var(--border);
  white-space: nowrap;
}
.radar-legend-item:first-of-type {
  padding-left: 0;
  border-left: none;
}
.radar-legend-tier {
  font-weight: 700;
  font-size: 12px;
  white-space: nowrap;
}
.radar-legend-tier.tier-TOP_PICK {
  color: var(--tier-top-pick);
}
.radar-legend-tier.tier-STRONG {
  color: var(--amber);
}
.radar-legend-tier.tier-GOOD {
  color: var(--text-dim);
}
.radar-legend-desc {
  font-size: 11px;
  color: var(--text-faint);
  white-space: nowrap;
}

/* PHASE 1 AUTHENTICATION - header account controls + User Management workspace.
   Reuses the existing dark-terminal tokens/table conventions throughout -
   no new visual language. */
.header-account {
  display: flex;
  align-items: center;
  gap: 10px;
}

.current-user-badge {
  font-size: 12px;
  color: var(--text-dim);
}

.create-user-form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px;
  padding: 12px 14px;
  margin-bottom: 14px;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.create-user-form label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-dim);
}

.create-user-form input,
.create-user-form select {
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 5px 8px;
  font-size: 13px;
}

.create-user-error {
  color: var(--negative);
  font-size: 12px;
}

.user-role-select {
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 3px 6px;
  font-size: 12px;
}

.user-status-active {
  color: var(--positive);
  font-weight: 600;
}

.user-status-disabled {
  color: var(--negative);
  font-weight: 600;
}

.user-actions-cell {
  display: flex;
  gap: 6px;
  justify-content: center;
}

/* SYSTEM ACTIVITY LOG (Settings, bottom panel) - compact/dense per spec:
   a tighter max-height than the default .table-wrap (which is sized for a
   full workspace table), same border/overflow-auto scroll behavior so the
   page itself never scrolls horizontally, only this panel does. */
.activity-log-wrap {
  max-height: 360px;
}

.activity-log-table {
  table-layout: fixed;
}

.activity-log-time {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Column-geometry fix: `.activity-log-table` now sizes its columns from an
   explicit colgroup (see ACTIVITY_LOG_COLUMN_WIDTHS in render.js), so every
   cell needs its own overflow handling - a fixed-width table cell doesn't
   clip nowrap content on its own, it lets it visually paint past the cell
   box into whatever sits next in the row (the original DETAIL-into-STATUS
   collision this fixes). Same nowrap/overflow/ellipsis convention as
   `.watchlist-identity` elsewhere in this file. */
.activity-log-event,
.activity-log-detail {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.activity-log-detail {
  color: var(--text-dim);
}

/* STATUS badge cell: fixed-width column (ACTIVITY_LOG_COLUMN_WIDTHS) sized
   for the longest status word (WARNING/RUNNING/SUCCESS) - this rule just
   guarantees the badge itself never wraps and stays vertically centered
   even if a future status label runs long. */
.activity-log-status-cell {
  white-space: nowrap;
  vertical-align: middle;
}

.activity-log-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 4px 0 12px;
}

.activity-log-filter-btn {
  background: var(--bg);
  color: var(--text-dim);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 4px 12px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
}

.activity-log-filter-btn:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.activity-log-filter-btn.is-active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-contrast);
}

/* LOGIN SCREEN - institutional trading-terminal look, deliberately minimal
   (Phase 1 instructions section 5), in the same dark visual family as the
   public landing page. Every color is a landing.css --lp-* token (login.html
   links landing.css for them) - no palette of its own. The page is always
   dark and never follows the app's saved theme. Only a restrained mint wash
   sits behind the card; the landing hero art (grid, curve, candles) is
   deliberately not reused - this is an auth screen, not a marketing page. */
html:has(> .login-body) {
  background: var(--lp-bg); /* keeps overscroll / short viewports on the same near-black as the body */
}

.login-body {
  min-height: 100vh;
  /* Same mint wash as the landing hero (landing.css writes it as rgba(0, 248, 168, x) = --lp-mint), toned down and centered behind the card. */
  background:
    radial-gradient(52% 44% at 50% 40%, rgba(0, 248, 168, 0.07), transparent 70%),
    radial-gradient(38% 40% at 4% 0%, rgba(0, 248, 168, 0.04), transparent 70%),
    var(--lp-bg);
  color: var(--lp-text);
}

.login-shell {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

.login-card {
  width: 100%;
  max-width: 340px;
  /* Charcoal, a step lighter than the page so the card reads as raised; subtle border + shadow, no glow. */
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.018)),
    var(--lp-bg-raised);
  border: 1px solid var(--lp-line);
  border-radius: var(--radius);
  padding: 32px 28px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.05),
    0 24px 48px -24px rgba(0, 0, 0, 0.8);
}

.login-brand {
  font-size: 24px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-align: center;
  color: var(--lp-text);
}

.login-tagline {
  margin-top: 4px;
  margin-bottom: 28px;
  text-align: center;
  font-size: 11px;
  color: var(--lp-text-dim);
  text-transform: uppercase;
  letter-spacing: 0.12em;
}

.login-form {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.login-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--lp-text-dim);
}

.login-field input {
  background: var(--lp-bg); /* inset: darker than the card */
  color: var(--lp-text);
  border: 1px solid var(--lp-line-strong); /* the landing page's outline-control edge - keeps the field boundary above 3:1 on the dark card */
  border-radius: var(--radius);
  padding: 9px 10px;
  font-size: 14px;
}

.login-field input:focus-visible {
  outline: 2px solid var(--lp-mint);
  outline-offset: 1px;
}

/* Browser autofill (password managers) would otherwise paint its own light fill behind light text. */
.login-field input:-webkit-autofill {
  -webkit-text-fill-color: var(--lp-text);
  caret-color: var(--lp-text);
  box-shadow: 0 0 0 1000px var(--lp-bg) inset;
}

.login-error {
  color: var(--negative);
  font-size: 12px;
}

/* .login-submit still carries .btn-live-preview (unchanged, shared with the app); these later rules re-skin it for the login screen only - a solid mint action, dark text (same pairing as landing.css's primary CTA), no glow. */
.login-submit {
  width: 100%;
  text-align: center;
  letter-spacing: 0.08em;
  background: var(--lp-mint-deep);
  color: #03120c;
  border: 1px solid var(--lp-mint-deep);
}

.login-submit:hover {
  background: var(--lp-mint);
  border-color: var(--lp-mint);
  color: #03120c;
}

.login-submit:focus-visible {
  outline: 2px solid var(--lp-mint);
  outline-offset: 2px;
}

/* ==========================================================================
   LANDING PAGE (PUBLIC)
   ========================================================================== */

.landing-body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  min-height: 100vh;
  overflow: hidden; /* Prevent all scrolling */
}

.landing-hero {
  width: 100vw;
  height: 100vh;
  display: block;
}

.hero-canvas {
  width: 100%;
  height: 100%;
  display: block;
}

/* Index Row Ranking */
.index-row.rank-1 td:first-child { border-left: 3px solid var(--rank1); }
.index-row.rank-2 td:first-child { border-left: 3px solid var(--rank2); }

/* SETTINGS WORKSPACE RESTRUCTURING */
.settings-grid {
  display: flex;
  flex-direction: column;
  gap: 32px;
  max-width: 1440px;
  width: 95%;
  margin: 0 auto;
}

.settings-panel {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 24px;
}

.settings-panel-title-block {
  display: flex;
  align-items: flex-start;
  gap: 16px;
}

.panel-icon-box {
  width: 48px;
  height: 48px;
  border-radius: 8px;
  background: rgba(37, 99, 235, 0.1);
  color: var(--accent);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.settings-panel-eyebrow {
  font-size: 11px;
  font-weight: 700;
  color: var(--accent);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-bottom: 4px;
}

.settings-panel-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 24px;
}

.settings-panel-titles h2 {
  margin: 0 0 4px 0;
  font-size: 20px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--text);
}

.settings-panel-desc {
  font-size: 13px;
  color: var(--text-dim);
}

.broker-content-grid {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 32px;
  margin-top: 24px;
  padding-top: 24px;
  border-top: 1px solid var(--border);
}

@media (max-width: 1024px) {
  .broker-content-grid {
    grid-template-columns: 1fr;
  }
}

.broker-fields-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  margin-bottom: 24px;
}

@media (max-width: 768px) {
  .broker-fields-grid {
    grid-template-columns: 1fr;
  }
}

.form-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.form-field .field-label {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-dim);
}

.form-field input {
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 8px 12px;
  font-size: 14px;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
}

.form-field input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -1px;
}

.broker-form-actions {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 12px;
  padding-top: 20px;
  border-top: 1px solid var(--border);
}

.btn-primary {
  background: var(--accent);
  color: var(--accent-contrast);
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  padding: 7px 16px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}

.btn-primary:hover {
  opacity: 0.9;
}

.btn-primary:disabled {
  opacity: 0.6;
  cursor: default;
}

.input-with-icon {
  position: relative;
  display: flex;
  align-items: center;
}

.input-with-icon input {
  width: 100%;
  padding-right: 36px;
  background: var(--bg-hover) !important;
  border-color: transparent !important;
}

.input-with-icon .eye-icon {
  position: absolute;
  right: 12px;
  color: var(--text-dim);
  pointer-events: none;
}

.broker-status-card {
  background: rgba(34, 197, 94, 0.1);
  border: 1px solid rgba(34, 197, 94, 0.2);
  border-radius: 6px;
  padding: 12px 16px;
  min-width: 200px;
}

.broker-status-card-header {
  display: flex;
  align-items: center;
  gap: 8px;
  color: #22c55e;
  font-size: 14px;
  margin-bottom: 4px;
}

.broker-status-card-desc {
  font-size: 11px;
  color: var(--text-dim);
}

.security-panel {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 20px;
}

.security-header {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.05em;
  color: var(--text);
  margin-bottom: 16px;
}

.security-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.security-list li {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-size: 12px;
  color: var(--text-dim);
  line-height: 1.4;
}

.security-list li svg {
  width: 14px;
  height: 14px;
  color: #22c55e;
  margin-top: 2px;
  flex-shrink: 0;
}

.btn-icon-left {
  display: flex;
  align-items: center;
  gap: 8px;
}

.settings-table-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px;
  border-top: 1px solid var(--border);
  font-size: 12px;
  color: var(--text-dim);
}

.pagination-controls {
  display: flex;
  align-items: center;
  gap: 16px;
}

.pagination-btn {
  background: transparent;
  border: none;
  color: var(--text-dim);
  cursor: pointer;
  padding: 4px;
}

.pagination-current {
  background: rgba(37, 99, 235, 0.1);
  color: var(--accent);
  padding: 4px 12px;
  border-radius: 4px;
  font-weight: 600;
}

/* OVERVIEW DASHBOARD RESTRUCTURING - this is the selector that actually
   wins the cascade (identical specificity to the `.overview-wrap` rule
   above, declared later) - it is the ONE authoritative rule governing the
   real block-to-block rhythm; the earlier declaration is intentionally
   left in sync rather than removed outright, to avoid an unrelated
   restructure of this file under this task's minimal-diff constraint. */
.overview-wrap {
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: 95%;
  max-width: 1440px;
  margin: 0 auto;
  padding: 4px 0 8px;
}

/* Overview's title (h1 + workspace-subtitle) and this status line share the
   same .workspace-header row (see index.html) - margin-left: auto pushes
   the status to the right on that shared row, and the divider that used to
   sit below the (now-removed) duplicate hero header lives here instead,
   scoped to Overview only so other workspaces' headers are unaffected. */
.workspace[data-workspace="overview"] .workspace-header {
  padding-bottom: 6px;
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
  row-gap: 4px;
}

/* Dashboard-only heading normalization (Typography pass) - OVERVIEW's own
   h1 steps down from the shared `.workspace-header h1` size (14px) to match
   the FUTURES/MARKET STATUS headings below (13px) so all three section
   headings on this page share one compact hierarchy, per Section 2 of the
   typography pass. Scoped to Overview only - every other workspace keeps
   the original `.workspace-header h1` rule untouched. */
.workspace[data-workspace="overview"] .workspace-header h1 {
  font-size: 13px;
  line-height: 1.15;
  letter-spacing: 0.04em;
}

.overview-meta-info {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-left: auto;
  font-size: 11px;
  font-weight: 600;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

/* MARKET STATUS + NIFTY/BANKNIFTY/FINNIFTY render together into the
   OVERVIEW header (see index.html's #overview-header-status) - single-line
   header row (no separate ticker row below), same compact terminal-style
   monospace the old ticker row used. Wraps onto its own line(s) under the
   title/subtitle on narrow screens (via .overview-meta-info's flex-wrap)
   rather than forcing horizontal page overflow. */
#overview-header-status {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
  flex-wrap: wrap;
  row-gap: 4px;
}

/* The index readouts sit on the left of the shared control bar (not the
   OVERVIEW title row): no auto-margin, and [hidden] must beat display:flex. */
#overview-header-status {
  margin-left: 0;
}
#overview-header-status[hidden] {
  display: none;
}

/* Trading Date + Refresh travel as one group: right side of the OVERVIEW
   title row on Overview, start of the control bar elsewhere. */
.date-refresh-group {
  display: flex;
  align-items: center;
  gap: 10px;
}
.workspace-header > .date-refresh-group {
  margin-left: auto;
}

/* Gap separating the Trading Date/Refresh group from Last Snapshot/Auto. */
.command-bar-snapshot {
  margin-left: 14px;
}

/* Non-Overview workspaces (the index readouts are hidden there): flatten the
   right group into the bar so Trading Date + Refresh sit on the LEFT and
   Last Snapshot + Auto stay on the RIGHT. Overview is unaffected. */
.command-bar:has(#overview-header-status[hidden]) {
  justify-content: flex-start;
  gap: 10px;
}
.command-bar:has(#overview-header-status[hidden]) .command-bar-left {
  display: none;
}
.command-bar:has(#overview-header-status[hidden]) .command-bar-right {
  display: contents;
}
.command-bar:has(#overview-header-status[hidden]) .command-bar-snapshot {
  margin-left: auto;
}

.meta-divider {
  color: var(--border);
}

.overview-kpi-section {
  display: flex;
  flex-direction: column;
  gap: 0;
}

/* Hidden by design: the KPI strip is its own section surface, with no
   separate heading above it (matches the reference Dashboard - no
   generic/admin-panel label). Kept as a class on the existing element
   rather than removed from renderOverview's markup, so this stays a
   pure CSS decision. */
.overview-kpi-title {
  display: none;
}

/* KPI STRIP: four equal, equal-height, hairline-bordered surface cards on one
   shared grid (same panel surface/border/radius tokens as every other
   Overview panel; no shadows, gradients or decoration). Desktop 4 across ->
   2 x 2 -> stacked. Hierarchy: VALUE > LABEL > DETAIL. */
.overview-kpi-strip {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
  align-items: stretch;
}

@media (max-width: 1100px) {
  .overview-kpi-strip {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 560px) {
  .overview-kpi-strip {
    grid-template-columns: minmax(0, 1fr);
  }
}

.overview-kpi-strip .kpi-item {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px 16px;
  min-height: 88px;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 6px;
  text-decoration: none;
  color: inherit;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}

.overview-kpi-strip .kpi-item:hover {
  background: var(--bg-raised);
  border-color: var(--text-faint);
}

.overview-kpi-strip .kpi-item:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
  background: var(--bg-raised);
}

.overview-kpi-strip .kpi-label {
  font-size: 10px;
  line-height: 1.2;
  font-weight: 600;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* The primary figure: terminal-mono, tabular, the largest thing on the card. */
.overview-kpi-strip .kpi-value {
  font-size: 28px;
  font-weight: 700;
  letter-spacing: -0.02em;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  line-height: 1.05;
}

.overview-kpi-strip .kpi-context {
  min-height: 15px;
  font-size: 12px;
  line-height: 1.25;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}

/* Semantic tone only where it carries meaning: LONG / SHORT. */
.overview-kpi-strip .kpi-seg-long { color: var(--positive); font-weight: 600; }
.overview-kpi-strip .kpi-seg-short { color: var(--negative); font-weight: 600; }
.overview-kpi-strip .kpi-sep { color: var(--text-faint); margin: 0 3px; }

/* Watchlist tier micro-stats: plain inline text (no pills). The count leads in the tier's existing semantic colour; the label is smaller and muted. */
.overview-kpi-strip .kpi-seg-tier-TOP_PICK .kpi-seg-count { color: var(--tier-top-pick); }
.overview-kpi-strip .kpi-seg-tier-STRONG .kpi-seg-count { color: var(--amber); }
.overview-kpi-strip .kpi-seg-tier-GOOD .kpi-seg-count { color: var(--text); }
.overview-kpi-strip .kpi-seg-tier .kpi-seg-count { font-weight: 700; }
.overview-kpi-strip .kpi-seg-tier .kpi-seg-label {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.05em;
  color: var(--text-dim);
}

/* No-number states (loading / unavailable / nothing to count for the date): the dash is de-emphasised so it can never read as a real 0. */
.overview-kpi-strip .kpi-state-loading .kpi-value,
.overview-kpi-strip .kpi-state-unavailable .kpi-value,
.overview-kpi-strip .kpi-state-na .kpi-value {
  color: var(--text-faint);
}
.overview-kpi-strip .kpi-state-loading .kpi-context,
.overview-kpi-strip .kpi-state-unavailable .kpi-context,
.overview-kpi-strip .kpi-state-na .kpi-context {
  color: var(--text-faint);
}

/* PRIMARY DATA WORKSPACE: true 2-column grid - FUTURES (left, larger) |
   RADAR (right) - replaces the old 3-column Futures/middle/sidebar
   composition. `align-items: stretch` gives both panels the same row
   height (bounded by `.overview-futures-panel`'s own max-height below),
   with each panel scrolling internally rather than growing the page.
   Futures is the primary market-data workspace, so it gets the larger
   share (~70%/30%) rather than the old, more even 60/40 split. */
.overview-primary-grid {
  display: grid;
  grid-template-columns: 7fr 3fr; /* Futures ~70% / Radar ~30% */
  gap: 16px;
  align-items: stretch;
}

/* LOWER ROW: TOP MOVERS | RECENT ALERTS | SYSTEM HEALTH as
   one full-width row of three equal, compact blocks underneath the primary
   Futures/Radar workspace (previously stacked vertically in a right-side
   sidebar column). */
.overview-utility-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  align-items: stretch;
  margin-top: 16px;
}

@media (max-width: 1024px) {
  .overview-primary-grid,
  .overview-utility-grid {
    grid-template-columns: 1fr;
  }

  .overview-right-column {
    grid-column: 1;
    grid-row: 2;
  }
}

/* `max-height` is a fixed, non-viewport pixel value that lives on both
   `.overview-futures-panel` and `.overview-right-column` so the primary
   row shares one coherent, bounded height - the Futures panel scrolls
   internally (`.overview-futures-strip`), and the right column's own
   children (RADAR/BBRS, see below) split that same bounded height between
   themselves via flex-grow rather than either growing the page. */
.overview-futures-panel {
  grid-column: 1;
  grid-row: 1;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  max-height: 640px;
  overflow: hidden;
}

/* RIGHT COLUMN: single vertical workspace stacking RADAR above ACTIVE
   SIGNALS (BBRS) (Dashboard BBRS-height rebalance pass - previously RADAR
   and BBRS were independent grid items with BBRS capped at a short fixed
   height, leaving dead space below it whenever Futures ran taller). Bounded
   to the same `max-height` as `.overview-futures-panel` so `align-items:
   stretch` on `.overview-primary-grid` stretches this column to exactly the
   Futures panel's rendered height; RADAR and BBRS then divide that one
   shared height by `flex-grow` (below) instead of BBRS being a short,
   independently-capped strip. */
.overview-right-column {
  grid-column: 2;
  grid-row: 1;
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-width: 0;
  min-height: 0;
  max-height: 640px;
}

/* RADAR primary intelligence panel - the larger of the two right-column
   panels: `flex: 7` here vs BBRS's `flex: 3` below (a ~70/30 split,
   echoing `.overview-primary-grid`'s own Futures/Radar ratio), scrolling
   internally via `.overview-radar-strip` if its content exceeds its share
   of the column's height. No longer an independent grid item/max-height -
   `.overview-right-column` above now owns the shared height bound. */
.overview-radar-panel {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  display: flex;
  flex-direction: column;
  flex: 7 1 0;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
}

/* Radar empty state (0 candidates) - reuses the shared `.state-empty`/
   `.state-title`/`.state-message` pattern (same classes the Futures/BBRS
   panel empty states use, see below) rather than a new component, just
   scoped here so it fills the panel body (`flex: 1`, same as
   `.overview-radar-strip` when rows are present) and centers on both axes
   within that existing space - no change to the panel's own height/width.
   Fixes the empty state previously sitting top-aligned with dead space
   left below it. */
.overview-radar-panel .state-empty {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
}

/* MIDDLE INTELLIGENCE ROW: ACTIVE SIGNALS (BBRS) | CONFLUENCE SUMMARY (15M)
   | TOP MOVERS (OPTION PREMIUM) - three equal panels with one shared,
   fixed height (each scrolls internally via `.overview-intel-strip`, so a
   long/short table never makes one panel taller than its neighbours) and
   the same border/radius as every other Overview panel. Stacks to one
   column at the same breakpoint as `.overview-primary-grid`. */
.overview-intel-row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
  align-items: stretch;
  margin-top: 16px;
}

@media (max-width: 1024px) {
  .overview-intel-row {
    grid-template-columns: 1fr;
  }
}

.overview-intel-panel {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  display: flex;
  flex-direction: column;
  height: 340px;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
}

/* LOWER ROW (TOP MOVERS | RECENT ALERTS | SYSTEM HEALTH): the Top Movers
   panel sizes with its neighbours' natural height instead of the fixed
   primary-row height. */
.overview-utility-grid .overview-intel-panel {
  height: auto;
}

/* Scroll region shared by the three middle-row panels (same rule as
   `.overview-futures-strip`). The BBRS panel keeps its own class too. */
.overview-intel-strip,
.overview-bbrs-strip {
  flex: 0 1 auto;
  min-height: 0;
  overflow-x: auto;
  overflow-y: auto;
}

/* Empty/loading/unavailable states fill the remaining body and centre. */
.overview-intel-panel .state-empty {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
}

/* Compact cell padding so five columns stay readable in a one-third-width panel. */
.overview-intel-panel .futures-market-table th,
.overview-intel-panel .futures-market-table td {
  padding-left: 8px;
  padding-right: 8px;
  white-space: nowrap;
}

/* Row accent bar + LONG/SHORT text + Confluence RESULT badge (middle row).
   Colours reuse the existing tokens: positive/negative for LONG/SHORT,
   --amber for CONFLICT, --accent for BBRS ONLY, --rank2 (purple) for
   STRIKEIQ ONLY. */
.intel-row td:first-child {
  box-shadow: inset 3px 0 0 var(--intel-accent, transparent);
}
.intel-row-LONG, .intel-row-long { --intel-accent: var(--positive); }
.intel-row-SHORT, .intel-row-short { --intel-accent: var(--negative); }
.intel-row-conflict { --intel-accent: var(--amber); }
.intel-row-bbrs { --intel-accent: var(--accent); }
.intel-row-strikeiq { --intel-accent: var(--rank2); }
.intel-dir { font-weight: 700; letter-spacing: 0.02em; }
.intel-dir-LONG { color: var(--positive); }
.intel-dir-SHORT { color: var(--negative); }
.intel-dir-none { color: var(--text-faint); }
.overview-intel-panel .confluence-badge {
  padding: 2px 8px;
  font-size: 11px;
  border-radius: var(--radius);
  border-color: transparent;
  background: var(--bg-raised);
}
.overview-intel-panel .confluence-CONFIRMED_LONG { background: color-mix(in srgb, var(--positive) 18%, transparent); }
.overview-intel-panel .confluence-CONFIRMED_SHORT { background: color-mix(in srgb, var(--negative) 18%, transparent); }
.overview-intel-panel .confluence-CONFLICT { background: color-mix(in srgb, var(--amber) 18%, transparent); }
.overview-intel-panel .confluence-BBRS_ONLY_LONG,
.overview-intel-panel .confluence-BBRS_ONLY_SHORT {
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 18%, transparent);
}
.overview-intel-panel .confluence-STRIKEIQ_ONLY_LONG,
.overview-intel-panel .confluence-STRIKEIQ_ONLY_SHORT {
  color: var(--rank2);
  background: color-mix(in srgb, var(--rank2) 18%, transparent);
}

/* "View All →" in the middle row: mixed case, accent colour. */
.overview-intel-panel .view-full-link {
  color: var(--accent);
  letter-spacing: 0;
}
.overview-intel-panel .view-full-link:hover {
  text-decoration: underline;
}
.overview-panel-title-suffix {
  font-size: 10px;
  font-weight: 600;
  color: var(--text-dim);
}

/* CALLS / PUTS segmented toggle (TOP MOVERS header) - same look as the chart timeframe segment control, at panel-header scale. */
.movers-toggle {
  display: flex;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1px;
}
.movers-toggle-btn {
  background: transparent;
  border: none;
  color: var(--text-dim);
  font-size: 10px;
  font-weight: 700;
  padding: 3px 10px;
  cursor: pointer;
  border-radius: 2px;
  letter-spacing: 0.05em;
}
.movers-toggle-btn:hover {
  color: var(--text);
}
.movers-toggle-btn.is-active {
  background: var(--accent);
  color: var(--accent-contrast);
}

/* TOP MOVERS' CALLS/PUTS toggle is the one interactive control inside that
   panel - at the 3px/10px desktop padding it's a ~18px-tall tap target,
   too small for a thumb. Widened at phone width only; the segmented-toggle
   look itself (and every desktop measurement) is unchanged. */
@media (max-width: 640px) {
  .movers-toggle-btn {
    padding: 8px 12px;
    font-size: 11px;
  }
}

/* Scroll region for the Dashboard Futures panel - fills whatever height
   `.overview-futures-panel`'s own `max-height` (see above) gives it, minus
   the panel header, with no cap of its own so there is no leftover blank
   gap under the rows. `min-height: 0` is required for a flex child to
   shrink below its content size instead of forcing the panel taller; this
   is also what makes `.futures-market-table th`'s `position: sticky`
   actually take effect (sticky needs a scrolling ancestor with a bounded
   height to stick within). `overflow-y: auto` keeps every row reachable
   by scrolling inside the panel regardless of row count; `overflow-x:
   auto` is scoped to this element only, so it never causes page-level
   horizontal overflow. */
.overview-futures-strip {
  flex: 1;
  min-height: 0;
  overflow-x: auto;
  overflow-y: auto;
}

/* Same scroll-region rule as `.overview-futures-strip`, for the Radar panel. */
.overview-radar-strip {
  flex: 1;
  min-height: 0;
  overflow-x: auto;
  overflow-y: auto;
}

.overview-panel-header {
  padding: 8px 14px;
  border-bottom: 1px solid var(--border);
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.overview-panel-header h2 {
  font-size: 13px;
  line-height: 1.15;
  font-weight: 700;
  margin: 0;
  color: var(--text);
  letter-spacing: 0.04em;
}

.overview-panel-header h2 .overview-panel-title-qualifier {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--text-faint);
}

/* Scanner-backed panels (ACTIVE SIGNALS (BBRS) / CONFLUENCE SUMMARY (15M)): the title plus a small refresh indicator on one
   line. The indicator sits inline after the title (nothing to its right moves) and is shorter than the h2, so it never changes the header height. */
.overview-panel-heading {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.overview-refresh-indicator {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  flex: none;
  white-space: nowrap;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.03em;
  color: var(--text-faint);
}

.overview-refresh-indicator[hidden] {
  display: none;
}

.overview-refresh-indicator[data-state='error'] {
  color: var(--amber);
  cursor: help;
}

.overview-refresh-spinner {
  width: 9px;
  height: 9px;
  border: 1.5px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: overview-refresh-spin 0.9s linear infinite;
}

@keyframes overview-refresh-spin {
  to {
    transform: rotate(360deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .overview-refresh-spinner {
    animation: none;
  }
}

/* KPI card whose latest refresh failed: the last successful value stays; a small amber dot after the label marks it as stale (reason in the tooltip). */
.overview-kpi-strip .kpi-refresh-error .kpi-label::after {
  content: '';
  display: inline-block;
  width: 5px;
  height: 5px;
  margin-left: 6px;
  border-radius: 50%;
  background: var(--amber);
  vertical-align: middle;
}

.overview-panel-subtitle {
  font-size: 11px;
  color: var(--text-faint);
  margin-top: 2px;
}

.overview-panel-subtitle-sep {
  opacity: 0.6;
}

.overview-panel-last-refresh {
  font-variant-numeric: tabular-nums;
}

@media (max-width: 768px) {
  .overview-panel-subtitle-sep,
  .overview-panel-last-refresh {
    display: none;
  }
}

.view-full-link {
  font-size: 11px;
  font-weight: 700;
  color: var(--text-dim);
  text-decoration: none;
  letter-spacing: 0.05em;
  transition: color 0.15s;
}

.view-full-link:hover {
  color: var(--accent);
}

/* Each utility-row block (Market Status / System Health / Quick Actions) is
   a direct `.overview-utility-grid` column now (previously stacked in
   `.overview-sidebar`) - `display: flex` lets `align-items: stretch` on the
   grid give all three equal height, aligning their bottoms. */
.sidebar-block {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px;
  display: flex;
  flex-direction: column;
}

.sidebar-title {
  font-size: 13px;
  line-height: 1.15;
  font-weight: 700;
  color: var(--text);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0 0 12px 0;
}

.market-status-box {
  border-radius: 6px;
  padding: 10px 12px;
  margin-bottom: 12px;
}

.market-status-box.status-ok {
  background: rgba(34, 197, 94, 0.1);
  border: 1px solid rgba(34, 197, 94, 0.2);
}

.market-status-box.status-closed {
  background: rgba(100, 116, 139, 0.1);
  border: 1px solid rgba(100, 116, 139, 0.2);
}

.market-status-badge {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: nowrap;
  white-space: nowrap;
  font-size: 13px;
  color: var(--text);
}

.status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  align-self: center;
}

.status-ok .status-dot {
  background: #22c55e;
  box-shadow: 0 0 8px #22c55e;
}

.status-closed .status-dot {
  background: #64748b;
}

.market-status-sep {
  color: var(--text-faint);
}

.market-status-sub {
  font-size: 11px;
  color: var(--text-dim);
}

.status-rows {
  display: flex;
  flex-direction: column;
  gap: 12px;
  font-size: 12px;
}

.status-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  color: var(--text-dim);
}

.health-item {
  display: flex;
  align-items: center;
  gap: 8px;
}

.health-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
}

.health-dot.ok { background: #22c55e; }
.health-dot.warn { background: #f59e0b; }
.health-dot.err { background: #ef4444; }

.health-value.ok { color: #22c55e; }
.health-value.warn { color: #f59e0b; }
.health-value.err { color: #ef4444; }

.quick-actions-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.quick-action-btn {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 10px 12px;
  color: var(--text);
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.15s;
}

.quick-action-btn:hover {
  background: var(--bg-hover);
}

.overview-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 32px 0;
  border-top: 1px solid var(--border);
  margin-top: 24px;
}

.footer-links {
  display: flex;
  align-items: center;
  gap: 16px;
  font-size: 11px;
  color: var(--text-faint);
  letter-spacing: 0.08em;
}

.footer-version {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 11px;
  color: var(--text-faint);
}

.version-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #10b981;
}

/* Dashboard Futures panel table (institutional density pass) - the ONE
   authoritative `.futures-market-table` rule set (the near-duplicate that
   used to sit near line 393 has been folded in here: default text-align,
   table font-size and panel background all came from there). Dense,
   spreadsheet-like: compact row padding, tabular-nums for clean numeric
   column alignment, subtle row-separator borders only (no boxed cells),
   a sticky header (see `.overview-futures-strip`'s scroll container just
   above this table's markup for where that actually takes effect), and
   the symbol column's only extra weight is `font-bold` (the class the
   markup already applies - this table is its only consumer, so scoping
   the rule here is safe). */
.futures-market-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
  background: var(--bg-panel);
}

.futures-market-table th {
  text-align: right;
  font-size: 10px;
  font-weight: 600;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 5px 10px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-panel);
  position: sticky;
  top: 0;
  z-index: 10;
}

.futures-market-table td {
  text-align: right;
  padding: 4px 10px;
  font-size: 12px;
  border-bottom: 1px solid var(--border);
  color: var(--text);
  white-space: nowrap;
}

.futures-market-table td.font-bold {
  font-weight: 700;
}

/* CHG / CHG % / OI CHG / OI CHG % cells (see changeClass() in render.js) -
   restore the semantic positive/negative color, which the flat
   `.futures-market-table td { color: var(--text) }` rule above otherwise
   wins on specificity. */
.futures-market-table td.positive {
  color: var(--positive);
}

.futures-market-table td.negative {
  color: var(--negative);
}

.futures-market-table tbody tr {
  transition: background-color 0.15s ease;
}

.futures-market-table tbody tr:hover {
  background: var(--bg-hover);
}

.futures-market-table tbody tr:last-child td {
  border-bottom: none;
}

/* Dashboard Futures panel only (rebalance pass): the panel's own extra
   width from `.overview-primary-grid`'s wider Futures column is spent as
   horizontal cell breathing room, not a larger font - vertical padding
   (row density) is untouched. Scoped to `.overview-futures-panel` so the
   Radar and BBRS panels below, which share the same `.futures-market-table`
   base rule, are unaffected. */
.overview-futures-panel .futures-market-table th,
.overview-futures-panel .futures-market-table td {
  padding-left: 16px;
  padding-right: 16px;
}

/* Dashboard Radar panel only (rebalance pass): the narrower Radar column
   needs tighter horizontal cell padding to stay compact and fully
   readable without clipping or an unwanted horizontal scrollbar. Scoped to
   `.overview-radar-panel` so the Futures and BBRS panels, which share the
   same `.futures-market-table` base rule, are unaffected. */
.overview-radar-panel .futures-market-table th,
.overview-radar-panel .futures-market-table td {
  padding-left: 6px;
  padding-right: 6px;
}

/* ==========================================================================
   INDEX INTELLIGENCE BLOCK (NIFTY/BANKNIFTY)
   ========================================================================== */

.overview-index-intel-panel {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.index-intel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid var(--border-light);
  padding-bottom: 12px;
}

.index-intel-title {
  font-size: 24px;
  font-weight: 700;
  color: var(--text-primary);
  margin: 0;
  letter-spacing: 0.5px;
}

.index-intel-subtitle {
  font-size: 13px;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 1px;
}

.index-intel-primary {
  display: flex;
  align-items: baseline;
  gap: 24px;
  padding: 12px 0;
}

.index-intel-ltp {
  font-size: 32px;
  font-weight: 700;
  color: var(--text-primary);
  line-height: 1;
}

.index-intel-chg, .index-intel-chg-pct {
  font-size: 20px;
  font-weight: 600;
}

.index-intel-section {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.index-intel-section-title {
  font-size: 11px;
  color: var(--text-secondary);
  margin: 0;
  letter-spacing: 1.5px;
  text-transform: uppercase;
}

.index-intel-metrics-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 16px;
}

.index-intel-metric {
  display: flex;
  flex-direction: column;
  gap: 4px;
  background: var(--bg-body);
  padding: 12px;
  border-radius: 4px;
  border: 1px solid var(--border-light);
}

.index-intel-metric .metric-label {
  font-size: 11px;
  color: var(--text-secondary);
  text-transform: uppercase;
}

.index-intel-metric .metric-value {
  font-size: 15px;
  font-weight: 600;
  color: var(--text-primary);
}

.index-intel-divider {
  height: 1px;
  background: var(--border-light);
  margin: 4px 0;
}

/* NIFTY/BANKNIFTY/FINNIFTY + MARKET STATUS/clock (single-line OVERVIEW
   header) - these classes are applied to spans inside
   `#overview-header-status` (see `.overview-meta-info` and
   `renderOverviewHeaderStatus`); there is no separate ticker row/container
   anymore. */
.ticker-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.ticker-status.session-active { color: var(--positive); }
.ticker-status.session-closed { color: var(--text-faint); }

.ticker-clock {
  color: var(--text-dim);
  font-weight: 600;
}

.ticker-sep {
  color: var(--border);
}

.ticker-item {
  display: flex;
  align-items: center;
  gap: 8px;
}

.ticker-item-muted {
  color: var(--text-faint);
}

.ticker-sym {
  font-weight: 700;
  color: var(--text-dim);
}

.ticker-px {
  font-weight: 600;
}

.ticker-chg {
  font-weight: 700;
}
.ticker-chg.positive { color: var(--positive); }
.ticker-chg.negative { color: var(--negative); }

/* ==================================================
   CHART WORKSPACE
   ================================================== */
.chart-visual {
  position: relative;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}

.chart-scroll-wrap {
  overflow-x: auto;
  overflow-y: hidden;
  /* hide scrollbar */
  scrollbar-width: none;
}
.chart-scroll-wrap::-webkit-scrollbar {
  display: none;
}

.chart-scroll-inner {
  position: relative;
  display: flex;
  flex-direction: column;
}

.chart-svg,
.chart-volume-svg,
.chart-stoch-svg,
.chart-time-axis-svg {
  display: block;
}

.chart-svg {
  height: 420px;
  flex-shrink: 0;
}
.chart-volume-svg {
  height: 60px;
  flex-shrink: 0;
}
.chart-stoch-svg {
  height: 80px;
  flex-shrink: 0;
}
.chart-time-axis-svg {
  height: 22px;
  flex-shrink: 0;
}


.chart-gridline,
.chart-stoch-reference {
  stroke: var(--border);
  stroke-width: 1px;
}

.chart-axis-label {
  fill: var(--text-dim);
  font-size: 10px;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
}

.chart-pane-label {
  fill: var(--text-faint);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.05em;
}

.chart-wick {
  stroke-width: 1px;
}
.chart-wick.positive { stroke: var(--positive); }
.chart-wick.negative { stroke: var(--negative); }

.chart-candle-body {
  stroke: none;
}
.chart-candle-body.positive { fill: var(--positive); }
.chart-candle-body.negative { fill: var(--negative); }

.chart-volume-bar {
  opacity: 0.6;
}
.chart-volume-bar.positive { fill: var(--positive); }
.chart-volume-bar.negative { fill: var(--negative); }

.chart-bb-channel {
  fill: var(--text-dim);
  opacity: 0.05;
}

.chart-bb-basis {
  fill: none;
  stroke: var(--amber);
  stroke-width: 1px;
  opacity: 0.8;
  stroke-dasharray: 4 2;
}

.chart-bb-band {
  fill: none;
  stroke: var(--text-dim);
  stroke-width: 1px;
  opacity: 0.4;
}

.chart-stoch-k {
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.5px;
}

.chart-stoch-d {
  fill: none;
  stroke: var(--text-dim);
  stroke-width: 1.5px;
  stroke-dasharray: 4 2;
}

.chart-signal-marker {
  stroke: none;
}
.chart-signal-marker.bbrs-GREEN_LONG { fill: var(--positive); }
.chart-signal-marker.bbrs-BLUE_LONG { fill: var(--accent); }
.chart-signal-marker.bbrs-RED_SHORT { fill: var(--negative); }
.chart-signal-marker.bbrs-YELLOW_SHORT { fill: var(--amber); }

.chart-latest-price-line {
  stroke-width: 1px;
  stroke-dasharray: 2 2;
}
.chart-latest-price-line.positive { stroke: var(--positive); }
.chart-latest-price-line.negative { stroke: var(--negative); }

.chart-latest-price-label {
  font-size: 10px;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  font-weight: 700;
}
.chart-latest-price-label.positive { fill: var(--positive); }
.chart-latest-price-label.negative { fill: var(--negative); }

.chart-crosshair {
  stroke: var(--text-dim);
  stroke-width: 1px;
  stroke-dasharray: 2 2;
  opacity: 0.5;
  pointer-events: none;
}

/* Hover Readout */
.chart-hover-readout {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  padding: 4px 12px;
  display: flex;
  gap: 8px;
  font-size: 10px;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  background: rgba(22, 27, 34, 0.85);
  backdrop-filter: blur(4px);
  border-bottom: 1px solid var(--border);
  z-index: 10;
  pointer-events: none;
}

[data-theme='light'] .chart-hover-readout {
  background: rgba(255, 255, 255, 0.85);
}

.chart-readout-time {
  color: var(--text);
  font-weight: 600;
}

.chart-readout-sep {
  color: var(--text-faint);
}

.chart-readout-signal {
  font-weight: 700;
}
.chart-readout-signal.bbrs-signal-GREEN_LONG { color: var(--positive); }
.chart-readout-signal.bbrs-signal-BLUE_LONG { color: var(--accent); }
.chart-readout-signal.bbrs-signal-RED_SHORT { color: var(--negative); }
.chart-readout-signal.bbrs-signal-YELLOW_SHORT { color: var(--amber); }


/* ==================================================
   CHART WORKSPACE V2 - PROFESSIONAL POLISH
   ================================================== */
.chart-instrument-header {
  margin-bottom: 16px;
  padding: 16px;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.chart-header-grid {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* 1. Identity Block */
.chart-header-identity {
  display: flex;
  flex-direction: column;
  gap: 4px;
  border-bottom: 1px solid var(--border);
  padding-bottom: 12px;
}
.chart-header-symbol {
  font-size: 16px;
  font-weight: 700;
  color: var(--text);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.chart-header-timeframe {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.chart-header-datetime {
  font-size: 11px;
  color: var(--text-faint);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* 2. OHLC Readout */
.chart-ohlc-block {
  display: flex;
  flex-direction: column;
  gap: 8px;
  border-bottom: 1px solid var(--border);
  padding-bottom: 12px;
}
.chart-ohlc-row {
  display: flex;
  gap: 24px;
  align-items: baseline;
}
.chart-ohlc-item {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  font-size: 13px;
}
.chart-ohlc-label {
  color: var(--text-faint);
  font-weight: 600;
}
.chart-ohlc-value {
  color: var(--text);
  font-weight: 500;
}
.chart-ohlc-change {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  font-size: 13px;
  font-weight: 500;
}

/* 3. Controls Row */
.chart-controls-row {
  display: flex;
  align-items: center;
  gap: 16px;
  border-bottom: 1px solid var(--border);
  padding-bottom: 12px;
}
.chart-timeframe-segment-control {
  display: flex;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 2px;
}
.chart-timeframe-segment {
  background: transparent;
  border: none;
  color: var(--text-dim);
  font-size: 11px;
  font-weight: 600;
  padding: 6px 16px;
  cursor: pointer;
  border-radius: 2px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.chart-timeframe-segment:hover {
  color: var(--text);
}
.chart-timeframe-segment.is-active {
  background: var(--bg-panel);
  color: var(--accent);
  box-shadow: 0 1px 3px rgba(0,0,0,0.2);
}
.chart-reset-view-btn {
  background: transparent;
  border: none;
  color: var(--text-dim);
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
  text-decoration: underline;
  padding: 6px 8px;
}
.chart-reset-view-btn:hover {
  color: var(--text);
}

/* 4. Analytic Stats Block */
.chart-header-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
}
.chart-analytic-block {
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 10px 16px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 140px;
}
.chart-analytic-label {
  font-size: 10px;
  font-weight: 700;
  color: var(--text-faint);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.chart-analytic-value {
  font-size: 12px;
  font-weight: 600;
  color: var(--text);
}
.confluence-none {
  color: var(--text-dim);
}

/* Remove old conflicting padding if it exists */
.instrument-header.chart-instrument-header {
  padding: 0;
  border: none;
  background: transparent;
}

/* ==================================================
   CHART WORKSPACE V3 - COMPACT TERMINAL POLISH
   ================================================== */
.chart-instrument-header-compact {
  margin-bottom: 4px;
  padding: 6px 12px;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.chart-header-compact-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 12px;
}

/* 1. Identity Block */
.chart-header-identity {
  display: flex;
  align-items: center;
  gap: 8px;
  border: none;
  padding: 0;
}
.chart-header-symbol {
  font-size: 14px;
  font-weight: 700;
  color: var(--text);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.chart-header-timeframe {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.chart-header-datetime {
  font-size: 11px;
  color: var(--text-faint);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.chart-header-sep {
  color: var(--text-faint);
  font-size: 12px;
  opacity: 0.5;
}

/* 2. OHLC Readout (Inline) */
.chart-ohlc-compact-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
  border: none;
  padding: 0;
}
.chart-ohlc-item {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  font-size: 13px;
}
.chart-ohlc-label {
  color: var(--text-faint);
  font-weight: 600;
}
.chart-ohlc-value {
  color: var(--text);
  font-weight: 500;
}
.chart-ohlc-change {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  font-size: 13px;
  font-weight: 500;
}

/* 3. Controls Row (Inline) */
.chart-controls-row {
  display: flex;
  align-items: center;
  gap: 12px;
  border: none;
  padding: 0;
}
.chart-timeframe-segment-control {
  display: flex;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 2px;
}
.chart-timeframe-segment {
  background: transparent;
  border: none;
  color: var(--text-dim);
  font-size: 11px;
  font-weight: 600;
  padding: 4px 12px;
  cursor: pointer;
  border-radius: 2px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.chart-timeframe-segment:hover {
  color: var(--text);
}
.chart-timeframe-segment.is-active {
  background: var(--bg-panel);
  color: var(--accent);
  box-shadow: 0 1px 3px rgba(0,0,0,0.2);
}
.chart-reset-view-btn {
  background: transparent;
  border: none;
  color: var(--text-dim);
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
  text-decoration: underline;
  padding: 4px;
}
.chart-reset-view-btn:hover {
  color: var(--text);
}

/* 4. Analytic Stats Block (Inline) */
.chart-header-stats-compact {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
}
.chart-analytic-block {
  display: flex;
  align-items: center;
  gap: 6px;
  background: transparent;
  border: none;
  padding: 0;
  min-width: auto;
}
.chart-analytic-label {
  font-size: 10px;
  font-weight: 700;
  color: var(--text-faint);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.chart-analytic-label::after {
  content: ':';
}
.chart-analytic-value {
  font-size: 11px;
  font-weight: 600;
  color: var(--text);
}
.confluence-none {
  color: var(--text-dim);
}

/* Hide the old stats padding */
.instrument-header.chart-instrument-header {
  display: none;
}

/* ==================================================
   CHART BODY V3 - INSTITUTIONAL TRADING TERMINAL
   ================================================== */
.chart-gridline {
  stroke: var(--border);
  stroke-width: 1px;
  stroke-opacity: 0.4;
}
.chart-gridline.horizontal {
  /* solid or subtle dash */
}
.chart-gridline.vertical {
  stroke-dasharray: 2 4;
}

.chart-axis-label {
  fill: var(--text-faint);
  font-size: 10px;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  font-weight: 500;
}

.chart-pane-label {
  fill: var(--text-dim);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.05em;
  opacity: 0.8;
}

.chart-bb-channel {
  fill: var(--accent);
  fill-opacity: 0.03;
}
.chart-bb-basis {
  stroke: var(--accent);
  stroke-width: 1px;
  stroke-opacity: 0.5;
}
.chart-bb-band {
  stroke: var(--text-faint);
  stroke-width: 1px;
  stroke-dasharray: 2 4;
  stroke-opacity: 0.4;
}

.chart-candle-body {
  stroke-width: 1px;
}
.chart-candle-body.positive {
  fill: var(--positive);
  stroke: var(--positive);
}
.chart-candle-body.negative {
  fill: var(--negative);
  stroke: var(--negative);
}

.chart-wick {
  stroke-width: 1px;
}
.chart-wick.positive {
  stroke: var(--positive);
}
.chart-wick.negative {
  stroke: var(--negative);
}

.chart-volume-bar {
  opacity: 0.8;
}

.chart-stoch-k {
  stroke: var(--accent);
  stroke-width: 1.5px;
  fill: none;
}
.chart-stoch-d {
  stroke: var(--amber);
  stroke-width: 1.5px;
  stroke-dasharray: 3 3;
  fill: none;
}
.chart-stoch-reference {
  stroke: var(--border);
  stroke-width: 1px;
  stroke-dasharray: 2 4;
  stroke-opacity: 0.5;
}

.chart-crosshair {
  stroke: var(--text-faint);
  stroke-width: 1px;
  stroke-dasharray: 4 4;
  pointer-events: none;
}

.chart-latest-price-line {
  stroke-width: 1px;
  stroke-dasharray: 4 4;
  stroke-opacity: 0.7;
}
.chart-latest-price-line.positive { stroke: var(--positive); }
.chart-latest-price-line.negative { stroke: var(--negative); }

.chart-latest-price-label {
  font-size: 10px;
  font-weight: 700;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
}
.chart-latest-price-label.positive { fill: var(--positive); }
.chart-latest-price-label.negative { fill: var(--negative); }

.chart-signal-marker {
  stroke-width: 1px;
  stroke: var(--bg-panel);
}

.chart-scroll-wrap {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-panel);
  overflow-x: auto;
  overflow-y: hidden;
  margin-top: 4px;
}

/* DISCOVERY SCANNERS (BBRS signal scanner / Confluence scanner) - a compact
   panel above the per-symbol workspace view. The table scrolls inside a
   bounded height so a long universe never pushes the symbol view off screen;
   the sticky header comes from `.futures-market-table th`. */
.scanner-panel {
  margin-bottom: 16px;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  min-width: 0;
}
.scanner-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 16px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
}
.scanner-head-titles {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 12px;
  min-width: 0;
}
.scanner-title {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.04em;
}
.scanner-subtitle {
  font-size: 12px;
  color: var(--text-dim);
}
.scanner-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.scanner-scroll {
  max-height: 320px;
  overflow: auto;
}
.scanner-table .confluence-badge {
  padding: 2px 8px;
  font-size: 11px;
}
.scanner-empty {
  padding: 20px 8px;
}
.scanner-note,
.scanner-muted {
  font-size: 12px;
  color: var(--text-dim);
}
.scanner-note {
  padding: 8px 14px;
  border-top: 1px solid var(--border);
}
.overview-intel-panel .scanner-note {
  padding: 6px 14px;
  margin-top: auto;
}

/* Top header - responsive. Search shrinks first, then secondary text drops
   (brand tag, data status, ⌘K hint); market context and controls stay usable.
   The nav row scrolls internally, never the page. */
@media (max-width: 1240px) {
  .app-header {
    gap: 16px;
  }

  .brand-tag {
    display: none;
  }

  .header-controls {
    gap: 12px;
  }

  .header-context {
    gap: 12px;
  }
}

@media (max-width: 1040px) {
  #data-status-badge {
    display: none;
  }
}

@media (max-width: 820px) {
  .app-header {
    padding: 0 10px;
    gap: 8px;
  }

  .header-controls,
  .header-context {
    gap: 8px;
  }

  .header-actions {
    padding-left: 8px;
    gap: 6px;
  }

  .header-search-kbd {
    display: none;
  }

  .header-search-input {
    padding-right: 8px;
  }

  .primary-nav {
    padding: 0 10px;
  }
}

/* The account trigger's text label is dropped here (the icon+chevron
   button stays, still reachable, Settings/Logout unaffected) - but the
   notification bell is NOT hidden: it is Recent Alerts' only entry point,
   and every phone in normal use falls under this breakpoint, so hiding it
   would make notifications unreachable on mobile rather than just denser.
   The "very narrow" header collapse below is widened to this same 640px
   breakpoint (from 560px) specifically so `.header-controls` has room
   (via its own wrap) to keep the bell visible without overflowing. */
@media (max-width: 640px) {
  .current-user-badge {
    display: none;
  }
}

/* Very narrow: search drops to its own full-width row under brand + status. */
@media (max-width: 640px) {
  .app-header {
    grid-template-columns: max-content minmax(0, 1fr);
    height: auto;
    padding: 6px 10px;
    row-gap: 6px;
  }

  .header-search {
    grid-column: 1 / -1;
    grid-row: 2;
  }

  .header-readout-label {
    display: none;
  }

  .header-controls {
    flex-wrap: wrap;
    row-gap: 4px;
  }

  /* Touch targets: the icon-only header buttons (theme/notifications) and
     the account trigger are the same 28px square used on desktop, where a
     mouse pointer makes that fine - bumped up for a thumb on the narrow
     header this block already applies to. Desktop/tablet widths above this
     breakpoint keep the original 28px sizing untouched. */
  .header-icon-btn {
    width: 36px;
    height: 36px;
    font-size: 15px;
  }

  .account-trigger {
    height: 36px;
    padding: 0 10px;
  }

  /* `.header-actions`' own fixed height (28px on desktop) must grow to
     match, or the taller buttons above just overflow its box instead of
     the divider/row sizing to them. */
  .header-actions {
    height: 36px;
  }
}

/* ==========================================================================
   OVERVIEW TERMINAL SURFACE PASS (presentation only)
   One coherent surface system for every Overview card - KPI strip, the two
   intelligence rows and SYSTEM HEALTH. Scoped to `.overview-wrap` so no other
   workspace changes, appended last and matched on specificity so it refines
   the earlier per-panel rules instead of editing them. Composition, markup,
   data and panel order are untouched. Tokens are derived from the existing
   theme variables (color-mix) - no new palette. Surface ladder:
     page (--bg)  <  card (--bg-panel)  <  panel header  <  table header
   Dark steps UP from the card toward --bg-raised; light steps DOWN toward
   --bg-header, so both themes read as the same product.
   ========================================================================== */
.overview-wrap {
  --ov-panel: var(--bg-panel);
  --ov-panel-head: color-mix(in srgb, var(--bg-panel) 66%, var(--bg-raised));
  --ov-th: color-mix(in srgb, var(--bg-panel) 44%, var(--bg-raised));
  --ov-border: var(--border);
  --ov-row-line: color-mix(in srgb, var(--border) 55%, transparent);
  --ov-row-hover: color-mix(in srgb, var(--accent) 10%, transparent);
  --ov-active: color-mix(in srgb, var(--accent) 16%, transparent);
  --ov-shadow: none;
  --ov-ease: 0.12s ease;
  gap: 12px;
}

[data-theme='light'] .overview-wrap {
  --ov-panel-head: color-mix(in srgb, var(--bg-panel) 55%, var(--bg-header));
  --ov-th: var(--bg-header);
  --ov-row-line: color-mix(in srgb, var(--border) 60%, transparent);
  --ov-row-hover: color-mix(in srgb, var(--accent) 8%, transparent);
  --ov-active: color-mix(in srgb, var(--accent) 12%, transparent);
  --ov-shadow: 0 1px 2px rgba(20, 24, 31, 0.06);
}

/* Section rhythm: one 12px gap between KPI strip / intelligence row / lower row (the rows' old 16px margins are folded into the wrap gap). */
.overview-wrap .overview-kpi-strip,
.overview-wrap .overview-intel-row,
.overview-wrap .overview-utility-grid {
  gap: 12px;
}
.overview-wrap .overview-intel-row,
.overview-wrap .overview-utility-grid {
  margin-top: 0;
}

/* --- Card surface: identical fill, hairline border, radius and depth on every card. --- */
.overview-wrap .kpi-item,
.overview-wrap .overview-intel-panel,
.overview-wrap .sidebar-block {
  background: var(--ov-panel);
  border: 1px solid var(--ov-border);
  border-radius: var(--radius);
  box-shadow: var(--ov-shadow);
}

/* --- Panel headers: TITLE (qualifier) ........ ACTION, one aligned 34px bar. --- */
.overview-wrap .overview-panel-header,
.overview-wrap .sidebar-block .sidebar-title {
  box-sizing: border-box;
  min-height: 34px;
  padding: 0 12px 0 14px;
  gap: 12px;
  background: var(--ov-panel-head);
  border-bottom: 1px solid var(--ov-border);
}
.overview-wrap .overview-panel-header > :first-child {
  min-width: 0;
}
.overview-wrap .overview-panel-header h2,
.overview-wrap .sidebar-block .sidebar-title {
  margin: 0;
  font-size: 12px;
  line-height: 1.2;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.overview-wrap .sidebar-block .sidebar-title {
  display: flex;
  align-items: center;
}
/* Qualifier: same baseline, smaller, lighter weight, muted - never a badge. */
.overview-wrap .overview-panel-header h2 .overview-panel-title-qualifier,
.overview-wrap .overview-panel-header h2 .overview-panel-title-suffix {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--text-dim);
}

/* Header action: smaller than the title but plainly interactive. Uppercase via CSS so every panel matches (markup text unchanged). */
.overview-wrap .overview-panel-header .view-full-link {
  flex-shrink: 0;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
  padding: 2px 0;
  border-bottom: 1px solid transparent;
  transition: color var(--ov-ease), border-color var(--ov-ease);
}
.overview-wrap .overview-panel-header .view-full-link:hover {
  color: var(--accent);
  text-decoration: none;
  border-bottom-color: currentColor;
}
.overview-wrap .overview-panel-header .view-full-link:focus-visible {
  outline: 1px solid var(--accent);
  outline-offset: 2px;
  border-radius: 2px;
}

/* CALLS / PUTS toggle: compact segmented control, tinted active state. */
.overview-wrap .movers-toggle {
  flex-shrink: 0;
  background: var(--ov-panel);
  border-color: var(--ov-border);
  padding: 1px;
}
.overview-wrap .movers-toggle-btn {
  padding: 2px 9px;
  font-size: 10px;
  letter-spacing: 0.06em;
  transition: color var(--ov-ease), background-color var(--ov-ease);
}
.overview-wrap .movers-toggle-btn:hover {
  background: var(--ov-row-hover);
  color: var(--text);
}
.overview-wrap .movers-toggle-btn.is-active {
  background: var(--ov-active);
  color: var(--accent);
}
.overview-wrap .movers-toggle-btn:focus-visible {
  outline: 1px solid var(--accent);
  outline-offset: 1px;
}

/* --- KPI strip: muted label / dominant figure / quiet metadata. --- */
.overview-wrap .overview-kpi-strip .kpi-item {
  padding: 10px 14px 11px;
  min-height: 84px;
  gap: 4px;
  transition: background-color var(--ov-ease), border-color var(--ov-ease);
}
.overview-wrap .overview-kpi-strip .kpi-item:hover {
  background: color-mix(in srgb, var(--ov-panel) 88%, var(--accent));
  border-color: color-mix(in srgb, var(--accent) 45%, var(--ov-border));
}
.overview-wrap .overview-kpi-strip .kpi-item:focus-visible {
  outline: 1px solid var(--accent);
  outline-offset: -1px;
  border-color: var(--accent);
}
.overview-wrap .overview-kpi-strip .kpi-label {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.09em;
  color: var(--text-dim);
}
.overview-wrap .overview-kpi-strip .kpi-value {
  font-size: 30px;
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1;
}
.overview-wrap .overview-kpi-strip .kpi-context {
  min-height: 14px;
  font-size: 11px;
  letter-spacing: 0.02em;
  color: var(--text-dim);
}

/* --- Tables: compact tonal header, aligned numerics, soft row lines, clear hover. --- */
.overview-wrap .futures-market-table {
  background: transparent;
}
.overview-wrap .futures-market-table th {
  padding-top: 6px;
  padding-bottom: 6px;
  background: var(--ov-th);
  border-bottom: 1px solid var(--ov-border);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.07em;
  color: var(--text-dim);
}
.overview-wrap .futures-market-table td {
  padding-top: 5px;
  padding-bottom: 5px;
  border-bottom: 1px solid var(--ov-row-line);
}
/* Table edges line up with the panel header's text inset. */
.overview-wrap .futures-market-table th:first-child,
.overview-wrap .futures-market-table td:first-child {
  padding-left: 14px;
}
.overview-wrap .futures-market-table th:last-child,
.overview-wrap .futures-market-table td:last-child {
  padding-right: 14px;
}
.overview-wrap .futures-market-table tbody tr {
  transition: background-color var(--ov-ease);
}
.overview-wrap .futures-market-table tbody tr:hover {
  background: var(--ov-row-hover);
}
.overview-wrap .futures-market-table .sortable-col:hover,
.overview-wrap .futures-market-table .sortable-col:focus-visible {
  color: var(--text);
}
.overview-wrap .futures-market-table .sortable-col.sort-asc,
.overview-wrap .futures-market-table .sortable-col.sort-desc {
  color: var(--accent);
}

/* Symbols stay the primary element; hover is a quiet accent + underline. */
.overview-wrap a.identity-underlying {
  color: var(--text);
  text-decoration: none;
  transition: color var(--ov-ease);
}
.overview-wrap a.identity-underlying:hover {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.overview-wrap a.identity-underlying:focus-visible {
  outline: 1px solid var(--accent);
  outline-offset: 2px;
  border-radius: 2px;
}

/* BBRS / Confluence row accent bar: thinner and softer. */
.overview-wrap .intel-row td:first-child {
  box-shadow: inset 2px 0 0 color-mix(in srgb, var(--intel-accent, transparent) 85%, transparent);
}

/* --- State badges: compact, square-cornered indicators with a tinted fill and a hairline of their own colour. --- */
.overview-wrap .tier-badge,
.overview-wrap .confluence-badge {
  padding: 1px 6px;
  border-radius: 2px;
  font-size: 10px;
  font-weight: 700;
  line-height: 1.5;
  letter-spacing: 0.05em;
}
.overview-wrap .tier-TOP_PICK {
  background: color-mix(in srgb, var(--tier-top-pick) 14%, transparent);
  border-color: color-mix(in srgb, var(--tier-top-pick) 45%, transparent);
}
.overview-wrap .tier-STRONG {
  background: color-mix(in srgb, var(--amber) 14%, transparent);
  border-color: color-mix(in srgb, var(--amber) 45%, transparent);
}
.overview-wrap .tier-GOOD {
  background: transparent;
  border-color: var(--ov-border);
}
.overview-wrap .confluence-badge {
  border-color: color-mix(in srgb, currentColor 35%, transparent);
  background: color-mix(in srgb, currentColor 12%, transparent);
}

/* --- Empty / unavailable states: centred, restrained, understated. --- */
.overview-wrap .overview-intel-panel .state-empty {
  gap: 3px;
}
.overview-wrap .overview-intel-panel .state-title {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--text);
}
.overview-wrap .overview-intel-panel .state-message {
  max-width: 34ch;
  margin-top: 0;
  font-size: 11px;
  line-height: 1.5;
  color: var(--text-dim);
}
.overview-wrap .overview-intel-panel .state-loading,
.overview-wrap .overview-intel-panel .state-empty.state-loading {
  font-size: 11px;
  color: var(--text-dim);
}
/* Note strip under a table ("N symbols warming up", "x of y evaluated"): a quiet footer band. */
.overview-wrap .overview-intel-panel .scanner-note {
  padding: 5px 14px;
  font-size: 11px;
  background: var(--ov-panel-head);
  border-top: 1px solid var(--ov-border);
  color: var(--text-dim);
}

/* --- SYSTEM HEALTH: same header bar as the other panels, ruled status rows, tokenised status colours. --- */
.overview-wrap .sidebar-block {
  padding: 0;
  overflow: hidden;
}
.overview-wrap .sidebar-block .sidebar-title {
  flex-shrink: 0;
}
.overview-wrap .sidebar-block .status-rows {
  gap: 0;
}
.overview-wrap .sidebar-block .status-row {
  padding: 9px 14px;
  border-bottom: 1px solid var(--ov-row-line);
  font-size: 12px;
  color: var(--text);
}
.overview-wrap .sidebar-block .status-row:last-child {
  border-bottom: none;
}
.overview-wrap .sidebar-block .health-dot.ok { background: var(--positive); }
.overview-wrap .sidebar-block .health-dot.warn { background: var(--amber); }
.overview-wrap .sidebar-block .health-dot.err { background: var(--negative); }
.overview-wrap .sidebar-block .health-value {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.03em;
}
.overview-wrap .sidebar-block .health-value.ok { color: var(--positive); }
.overview-wrap .sidebar-block .health-value.warn { color: var(--amber); }
.overview-wrap .sidebar-block .health-value.err { color: var(--negative); }
.overview-wrap .sidebar-block .state {
  padding: 22px 14px;
}
.overview-wrap .sidebar-block .state-title {
  font-size: 12px;
}

@media (prefers-reduced-motion: reduce) {
  .overview-wrap * {
    transition: none !important;
  }
}

/* BASE / SNAPSHOT SHEETS - the legacy `BASE_09-15` and `HH-MM` Google Sheet tabs (reference/workbook,
   reference/legacy-code createSnapshot): every symbol stacked in one grid,
   one frozen header row + frozen StrikeLabel column, thin gridlines on
   every cell, centred values, bold left-aligned StrikeLabel. The light
   theme uses the sheet's own colours verbatim; the dark theme uses tints
   of the same hues so the conventions read the same in both. */
.base-sheet-wrap {
  --sheet-header-bg: var(--bg-raised);
  --sheet-grid: var(--border);
  --sheet-offset-below: rgba(88, 166, 255, 0.16);
  --sheet-offset-atm: rgba(248, 81, 73, 0.3);
  --sheet-ce-coi-warm: rgba(255, 153, 51, 0.22);
  --sheet-ce-coi-hot: rgba(248, 81, 73, 0.32);
  --sheet-pe-coi-warm: rgba(63, 185, 80, 0.18);
  --sheet-pe-coi-hot: rgba(63, 185, 80, 0.34);
}

[data-theme='light'] .base-sheet-wrap {
  --sheet-header-bg: #cccccc;
  --sheet-grid: #a9a9a9;
  --sheet-offset-below: #cfe2f3;
  --sheet-offset-atm: #ea9999;
  --sheet-ce-coi-warm: #f9cb9c;
  --sheet-ce-coi-hot: #ea9999;
  --sheet-pe-coi-warm: #d9ead3;
  --sheet-pe-coi-hot: #b6d7a8;
}

.base-sheet-status {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 16px;
  padding: 0 0 8px;
  color: var(--text-dim);
  font-size: 12px;
}

/* Snapshot sheets reuse every .base-sheet-* rule; the caption states the slot and its BASE-relative contract. */
.base-sheet-caption {
  flex-basis: 100%;
  color: var(--text);
  font-weight: 700;
}

.base-sheet-missing {
  color: var(--text-faint);
}

.base-sheet-failed {
  color: var(--negative);
}

.base-sheet-table {
  table-layout: fixed;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}

.base-sheet-table th,
.base-sheet-table td {
  padding: 3px 8px;
  border-right: 1px solid var(--sheet-grid);
  border-bottom: 1px solid var(--sheet-grid);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: center;
  vertical-align: middle;
}

.base-sheet-table thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--sheet-header-bg);
  color: var(--text);
  font-weight: 700;
}

.base-sheet-table .sheet-frozen-col {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--bg-panel);
  text-align: left;
  font-weight: 700;
}

.base-sheet-table thead th.sheet-frozen-col {
  z-index: 3;
  background: var(--sheet-header-bg);
  text-align: center;
}

.base-sheet-table .atm-row td.sheet-frozen-col {
  background: var(--bg-raised);
}

/* Overlay, not a background swap - the legacy StepOffset/COI% fills stay visible on the hovered row. */
.base-sheet-table tbody tr:not(.base-sheet-symbol-row):hover td {
  box-shadow: inset 0 0 0 9999px rgba(127, 127, 127, 0.12);
}

/* One thin label row per symbol group; its content stays pinned left while the sheet scrolls sideways. */
.base-sheet-symbol-row th {
  background: var(--bg-group-header);
  border-top: 2px solid var(--sheet-grid);
  text-align: left;
  font-weight: 400;
}

.base-sheet-symbol {
  position: sticky;
  left: 8px;
  display: inline-flex;
  gap: 14px;
  align-items: baseline;
}

.base-sheet-symbol-name {
  font-weight: 700;
  color: var(--text);
}

.base-sheet-symbol-fact {
  color: var(--text-dim);
}

.base-sheet-fact-label {
  color: var(--text-faint);
  font-size: 11px;
}

.base-sheet-table td.sheet-offset-below { background: var(--sheet-offset-below); }
.base-sheet-table td.sheet-offset-atm { background: var(--sheet-offset-atm); }
.base-sheet-table td.sheet-ce-coi-warm { background: var(--sheet-ce-coi-warm); }
.base-sheet-table td.sheet-ce-coi-hot { background: var(--sheet-ce-coi-hot); }
.base-sheet-table td.sheet-pe-coi-warm { background: var(--sheet-pe-coi-warm); }
.base-sheet-table td.sheet-pe-coi-hot { background: var(--sheet-pe-coi-hot); }

.underlying-label input[type='search'] {
  background: var(--bg-raised);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 4px 8px;
  font-size: 13px;
  width: 150px;
  text-transform: uppercase;
}
