/* KPI grid */
.kpi-grid {
  display: grid;
  gap: 16px;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  margin-bottom: 16px;
}
.kpi-card {
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: 12px;
  padding: 16px 20px;
  box-shadow: var(--shadow);
}
.kpi-label {
  color: var(--text-secondary);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .5px;
}
/* Card header row — label on the left, eye toggle on the right (sensitive
   money cards only; non-sensitive cards keep a bare .kpi-label). */
.kpi-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.kpi-toggle {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border: none;
  border-radius: 6px;
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
  line-height: 1;
  transition: color .15s ease, background-color .15s ease;
}
.kpi-toggle:hover,
.kpi-toggle:focus-visible {
  color: var(--text-primary);
  background: var(--bg-primary);
}
.kpi-toggle:focus-visible {
  outline: 2px solid var(--accent-color, var(--text-secondary));
  outline-offset: 1px;
}
/* Masked value — muted dots, never colored, so the P/L direction is private
   too. Slight letter-spacing so the dots read as a deliberate mask. */
.kpi-value.kpi-masked {
  color: var(--text-secondary);
  letter-spacing: 2px;
}
.kpi-sub.kpi-sub-masked {
  letter-spacing: 2px;
}
.kpi-value {
  font-size: 28px;
  font-weight: 600;
  margin-top: 4px;
  font-variant-numeric: tabular-nums;
}
.kpi-positive { color: var(--success-color); }
.kpi-negative { color: var(--danger-color); }

/* Tighter KPI cards on phones — fit two per row, smaller type. */
@media (max-width: 768px) {
  .kpi-grid {
    gap: 8px;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    margin-bottom: 12px;
  }
  .kpi-card { padding: 10px 12px; border-radius: 10px; }
  .kpi-value { font-size: 20px; }
  .kpi-label { font-size: 11px; }
  .kpi-sub { font-size: 11px !important; }
}
@media (max-width: 380px) {
  .kpi-grid { grid-template-columns: 1fr; }
}

/* Sidebar nav */
.sidebar-nav { display: flex; flex-direction: column; gap: 4px; padding: 8px; }
.sidebar-nav .nav-item {
  display: flex; align-items: center; gap: 12px;
  background: transparent; border: 0; color: var(--text-primary);
  padding: 10px 12px; border-radius: 8px; text-align: left;
  font-size: 14px; cursor: pointer; text-decoration: none;
}
.sidebar-nav .nav-item:hover { background: var(--bg-hover, rgba(255,255,255,.08)); }
.sidebar-nav .nav-item.active { background: var(--accent-color); color: #fff; }

/* Working orders table — sticky columns + headers.
 * Use dvh so the visible region is correct on mobile (browser chrome aware).
 * Use clamp() to keep a usable minimum even on short viewports. */
.working-orders {
  max-height: clamp(280px, calc(100dvh - 360px), 100dvh);
  overflow: auto;
}
.working-orders table { margin-bottom: 0; }
.working-orders th, .working-orders td { white-space: nowrap; }
.working-orders thead th {
  position: sticky; top: 0; background: var(--bg-secondary); z-index: 3;
}
.working-orders th[data-sticky="left"],
.working-orders td[data-sticky="left"] {
  position: sticky; left: 0; min-width: 120px;
  background: var(--bg-secondary); z-index: 2;
  box-shadow: 1px 0 0 var(--border-color);
}
.working-orders th[data-sticky="right"],
.working-orders td[data-sticky="right"] {
  position: sticky; right: 0; min-width: 90px;
  background: var(--bg-secondary); z-index: 2;
  box-shadow: -1px 0 0 var(--border-color);
}
.working-orders th[data-sticky="right-1"],
.working-orders td[data-sticky="right-1"] {
  position: sticky; right: 90px; min-width: 100px;
  background: var(--bg-secondary); z-index: 2;
}
.working-orders thead th[data-sticky] { z-index: 4; }

/* Sortable working-orders headers: click to sort; a trailing arrow shows the
 * current sort state (idle ↕, ascending ↑, descending ↓). */
.working-orders th.sortable { cursor: pointer; user-select: none; }
.working-orders th.sortable::after {
  content: '\2195';
  margin-left: 0.3em;
  font-size: 0.8em;
  opacity: 0.25;
}
.working-orders th.sortable:hover::after { opacity: 0.55; }
.working-orders th.sort-asc::after  { content: '\2191'; opacity: 0.9; }
.working-orders th.sort-desc::after { content: '\2193'; opacity: 0.9; }

/* Collapsible "Short Deltas" column group. The delta columns (.delta-col:
 * execution delta + 10:00 AM–3:00 PM buckets) are hidden while the table
 * carries .deltas-collapsed (the default). The .delta-toggle group header is
 * always visible and clickable; a trailing chevron shows the state. */
.working-orders table.deltas-collapsed .delta-col { display: none; }
.working-orders th.delta-toggle { cursor: pointer; user-select: none; white-space: nowrap; }
.working-orders th.delta-toggle::after {
  content: '\25B8';            /* ▸ collapsed */
  margin-left: 0.3em;
  font-size: 0.8em;
  opacity: 0.7;
}
.working-orders table:not(.deltas-collapsed) th.delta-toggle::after {
  content: '\25BE';            /* ▾ expanded */
}
.working-orders th.delta-toggle:hover::after { opacity: 1; }

/* Hold-time (Trade Time) filter inputs — compact fixed width. */
.wo-hold-filter .wo-hold-input { max-width: 6rem; }

/* On mobile, drop right-side sticky columns — they steal too much horizontal
 * space on a narrow viewport. Headers/left sticky still help orientation.
 * Also drop the fixed max-height: the parent [data-view-root="dashboard"]
 * scrolls vertically, so a bounded inner scroller would create nested
 * scrollbars and trap touch gestures. Letting the table grow naturally
 * gives one clean page-level scroll. */
@media (max-width: 768px) {
  .working-orders {
    max-height: none;
    /* Allow horizontal scroll for wide tables, but let vertical content
     * flow up to the page-level scroll on the dashboard view root. */
    overflow-x: auto;
    overflow-y: visible;
    font-size: 0.82rem;
  }
  .working-orders thead th {
    /* Sticky header stays anchored to the *page* scroll on mobile. */
    position: sticky;
    top: 0;
  }
  .working-orders th[data-sticky="right"],
  .working-orders td[data-sticky="right"],
  .working-orders th[data-sticky="right-1"],
  .working-orders td[data-sticky="right-1"] {
    position: static;
    box-shadow: none;
    min-width: 0;
  }
  .working-orders th[data-sticky="left"],
  .working-orders td[data-sticky="left"] {
    min-width: 90px;
  }
  .working-orders .table-sm th,
  .working-orders .table-sm td { padding: 0.3rem 0.4rem; }
}

/* Dashboard controls bar — already uses flex-wrap; ensure wrap children
 * don’t overflow on narrow viewports. */
@media (max-width: 576px) {
  .dash-controls { gap: 0.4rem; }
  .dash-controls .btn-group { flex-wrap: wrap; }
  .dash-controls .ms-auto { margin-left: 0 !important; }
  .dash-controls > label { font-size: 0.78rem; }
}

/* Cell flash on diff */
.cell-flash { animation: cell-flash 1.2s ease; }
@keyframes cell-flash {
  0% { background: rgba(255, 215, 0, .35); }
  100% { background: transparent; }
}
@media (prefers-reduced-motion: reduce) {
  .cell-flash { animation: none; }
}

/* Ensure dashboard text is readable across themes (overrides Bootstrap defaults
   that hard-code dark text on .table, .text-muted, headings, etc.). */
.dashboard-content,
.dashboard-content h1,
.dashboard-content h2,
.dashboard-content h3,
.dashboard-content h4,
.dashboard-content h5,
.dashboard-content h6,
.dashboard-content label,
.dashboard-content p,
.dashboard-content span,
.dashboard-content small {
  color: var(--text-primary);
}

.dashboard-content .text-muted,
.dashboard-content .small.text-muted,
.dashboard-content .kpi-sub {
  color: var(--text-secondary) !important;
}

/* Bootstrap table overrides — make table cells, headers, hover, and striping
   pick up the active theme variables instead of the default light-mode colors. */
.dashboard-content .table {
  --bs-table-color: var(--text-primary);
  --bs-table-bg: transparent;
  --bs-table-border-color: var(--border-color);
  --bs-table-striped-color: var(--text-primary);
  --bs-table-striped-bg: var(--bg-tertiary);
  --bs-table-hover-color: var(--text-primary);
  --bs-table-hover-bg: var(--bg-hover);
  color: var(--text-primary);
  border-color: var(--border-color);
}

.dashboard-content .table > :not(caption) > * > * {
  color: var(--text-primary);
  background-color: transparent;
  border-color: var(--border-color);
}

.dashboard-content .table thead th {
  color: var(--text-primary);
  background-color: var(--bg-secondary);
  border-color: var(--border-color);
}

/* Preserve P/L color cues even with the broad text-primary rule above. */
.dashboard-content .kpi-positive,
.dashboard-content .table .kpi-positive,
.dashboard-content .text-success { color: var(--success-color) !important; }
.dashboard-content .kpi-negative,
.dashboard-content .table .kpi-negative,
.dashboard-content .text-danger { color: var(--danger-color) !important; }
.dashboard-content .text-warning { color: var(--warning-color) !important; }

/* Working-orders totals footer: highlighted row with bold uppercase label. */
.dashboard-content .table tfoot .totals-row > td {
  background-color: var(--bg-secondary);
  border-top: 2px solid var(--border-color);
  font-weight: 700;
}
.dashboard-content .table tfoot .totals-row .totals-label {
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* ── Print stylesheet ──────────────────────────────────────────────────────
 * When the user prints from the dashboard view, drop the app chrome
 * (sidebar, header, chat input) and force a light palette so KPI cards
 * and tables render legibly on paper. The ``[data-view="dashboard"]``
 * gate keeps these rules from leaking into other view-specific prints.
 */
@media print {
  /* Hide the SPA chrome unconditionally; only the active view content prints. */
  .sidebar,
  .sidebar-backdrop,
  .chat-header,
  .chat-container,
  .modal-overlay,
  #welcomeScreen,
  #loginScreen {
    display: none !important;
  }
  /* Reset the app-container layout (it's a flex row by default) so the
   * dashboard content can occupy the entire page width.
   */
  .app-container,
  .main-content {
    display: block !important;
    width: 100% !important;
    max-width: 100% !important;
    padding: 0 !important;
    margin: 0 !important;
  }
  .dashboard-content {
    color: #000 !important;
    background: #fff !important;
    padding: 0 !important;
    margin: 0 !important;
    width: 100% !important;
    max-width: 100% !important;
  }
  .dashboard-content,
  .dashboard-content * {
    color: #000 !important;
    background: transparent !important;
    box-shadow: none !important;
  }
  .dashboard-content .kpi-grid {
    /* Two columns prints cleaner on letter-size landscape than auto-fit. */
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    gap: 8px !important;
  }
  .dashboard-content .kpi-card {
    border: 1px solid #999 !important;
    page-break-inside: avoid;
  }
  .dashboard-content .kpi-positive,
  .dashboard-content .text-success { color: #006400 !important; }
  .dashboard-content .kpi-negative,
  .dashboard-content .text-danger { color: #8b0000 !important; }
  .dashboard-content .table {
    border-collapse: collapse;
  }
  .dashboard-content .table th,
  .dashboard-content .table td {
    border: 1px solid #ccc !important;
    padding: 4px 6px !important;
  }
  .dashboard-content .table thead {
    /* Repeat headers across page breaks. */
    display: table-header-group;
  }
  @page {
    size: letter landscape;
    margin: 0.5in;
  }
}


/* ===== Charts panel (Phase A) =================================================
 * Grid layout for the dashboard analytics charts. Two responsive columns on
 * desktop with a chart-wide modifier that spans both. ApexCharts supplies
 * its own SVG; we only style the wrapping card.
 */
.charts-panel {
  margin-top: 16px;
}
.charts-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}
.chart-card {
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: 12px;
  padding: 12px 14px;
  /* Anchor for the absolutely-positioned .chart-locked-hint badge
     and .chart-overlay-blocker overlay rendered by the click-to-
     activate wiring in lightweight-spx-chart.js and tradingview-
     widget.js. Without this, those elements would escape to the
     nearest ancestor with positioning and land in the wrong spot. */
  position: relative;
}
.chart-card.chart-wide {
  grid-column: span 2;
}
.chart-header {
  display: flex;
  flex-direction: column;
  margin-bottom: 4px;
}
.chart-title {
  font-weight: 600;
  color: var(--text-primary);
}
.chart-sub {
  color: var(--text-secondary);
}

/* Per-chart live/connecting/error status dot, injected by chart-status.js into
   the start of each `.chart-title`. Colours reuse the global status palette. */
.chart-status-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-right: 7px;
  vertical-align: middle;
  background: var(--warning-color);
  flex: 0 0 auto;
}
.chart-status-dot[data-status="live"] {
  background: var(--success-color);
}
.chart-status-dot[data-status="connecting"] {
  background: var(--warning-color);
  animation: chartStatusPulse 1.4s ease-in-out infinite;
}
.chart-status-dot[data-status="error"] {
  background: var(--danger-color);
}
@keyframes chartStatusPulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}
@media (prefers-reduced-motion: reduce) {
  .chart-status-dot { animation: none !important; }
}

/* ============================================================
   SPX chart variant toggle — segmented control in the LC card
   header that lets the user pick between the in-app
   Lightweight Charts engine, the TradingView iframe embed, or
   both side-by-side. Rendered as a row of pill buttons; the
   active button gets the `is-active` class which inverts the
   color scheme so the selected variant reads as the current
   choice. Wired in lightweight-spx-chart.js::_buildEngineToggle.
   ============================================================ */
.chart-variant-toggle {
  display: inline-flex;
  align-self: flex-start;
  margin-top: 8px;
  padding: 2px;
  gap: 2px;
  border: 1px solid var(--border-color);
  border-radius: 999px;
  background: var(--bg-secondary, transparent);
}
.chart-variant-btn {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--text-secondary);
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1;
  padding: 6px 12px;
  border-radius: 999px;
  cursor: pointer;
  transition: background-color 120ms ease, color 120ms ease;
}
.chart-variant-btn:hover {
  color: var(--text-primary);
}
.chart-variant-btn.is-active {
  background: var(--accent-color, #2962ff);
  color: #ffffff;
  cursor: default;
}
.chart-variant-btn:focus-visible {
  outline: 2px solid var(--accent-color, #2962ff);
  outline-offset: 2px;
}
.chart-body {
  /* ApexCharts inherits the height from its options; keep min-height
     so the card doesn't collapse before the first render completes. */
  min-height: 220px;
}

/* SPX View Chart (Lightweight Charts engine) — taller than the generic
   chart-body so the main price pane, the dedicated volume pane, and the
   three indicator sub-panes (RSI / MACD / ATR) all stay readable. The
   chart engine runs with autoSize:true, so it adopts this container
   height. Raised from 960px when volume moved into its own pane. */
.chart-spx-view {
  height: 1080px;
}

/* Today-view hint shown in place of the hidden aggregate analytics charts.
   A slim, full-width informational note (not a real chart card surface). */
.dash-today-charts-hint {
  min-height: 0;
}
.dash-today-charts-hint-body {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  color: var(--text-muted, #94a3b8);
  font-size: 0.9rem;
  line-height: 1.4;
}
.dash-today-charts-hint-body i {
  font-size: 1.1rem;
  flex: 0 0 auto;
  opacity: 0.85;
}

/* === Chart click-to-activate (focus-to-interact) =====================
   Both the Lightweight Charts and TradingView embed cards default to
   a "locked" state — their internal wheel + drag handlers are
   suppressed (LC via handleScroll/handleScale = false; TV via the
   overlay below) so vertical scrolling the dashboard doesn't get
   pirated by the chart. A single click on the chart card flips it
   into "interactive" mode (toggled via the .chart-interactive class
   on the card). Clicking outside the card or pressing Escape re-locks
   it. The lock badge is the user-visible affordance. */
.chart-locked-hint {
  position: absolute;
  bottom: 8px;
  right: 8px;
  padding: 4px 10px;
  background: rgba(0, 0, 0, 0.6);
  color: #ffffff;
  font-size: 11px;
  line-height: 1.2;
  border-radius: 4px;
  pointer-events: none;
  opacity: 0.85;
  z-index: 9;
  user-select: none;
  transition: opacity 0.6s ease;
}
/* Auto-fade the hint after a few seconds so it doesn't permanently sit
   over the price action (the morning candles hug the left edge). Added
   by JS on a timer. */
.chart-locked-hint.chart-locked-hint-faded {
  opacity: 0;
}
.chart-card.chart-interactive .chart-locked-hint {
  display: none;
}
.chart-card.chart-interactive {
  /* Subtle blue ring confirms the chart is live; the offset is
     negative so it draws *inside* the card without changing layout. */
  outline: 2px solid var(--accent-color, #2962ff);
  outline-offset: -2px;
}
/* The TV iframe is cross-origin so we can't disable its scroll
   capture from outside — instead, a transparent <div> overlays the
   iframe and absorbs wheel + click events while the chart is locked.
   `pointer-events: auto` makes the overlay block events; the JS
   click handler flips it to `none` after the activating click so
   subsequent events reach the iframe. */
.chart-overlay-blocker {
  position: absolute;
  inset: 0;
  z-index: 8;
  cursor: pointer;
  background: transparent;
}
.chart-card.chart-interactive .chart-overlay-blocker {
  /* Belt-and-suspenders: even if JS forgot to flip pointer-events,
     the class on the card itself disables the overlay. */
  pointer-events: none;
}

/* === Always-on vertical price scrollbar ================================
   Injected by `_wirePriceScrollbar()` in lightweight-spx-chart.js onto
   the right edge of `#chartLightweightSpx`. Dragging it pans the price
   window up/down (via `_pricePanOffset` folded into the candle
   autoscaleInfoProvider) WITHOUT enabling the hand-button drag/edit
   mode — so a trader can scan strikes vertically on a locked chart.
   `writing-mode: vertical-lr; direction: rtl` orients the native range
   input vertically with the max value at the TOP (drag up = higher
   strikes). It stays interactive regardless of the .chart-interactive
   state, so it lives above the overlay blocker (z-index 10 > 8). */
.spx-price-scroll {
  position: absolute;
  top: 14%;
  right: 4px;
  height: 58%;
  width: 14px;
  margin: 0;
  padding: 0;
  z-index: 10;
  writing-mode: vertical-lr;
  direction: rtl;
  cursor: ns-resize;
  pointer-events: auto;
  accent-color: var(--accent-color, #2962ff);
  opacity: 0.5;
  transition: opacity 120ms ease;
}
.spx-price-scroll:hover,
.spx-price-scroll:focus {
  opacity: 1;
}

/* Floating readout that appears next to the price scrollbar thumb while
   the user drags it (toggled via the `.is-visible` class from
   `_updatePriceScrollLabel`). Reports the active pan offset and the
   price now at the pane center, then fades out after the drag ends.
   Sits left of the scrollbar (right:4px width:14px) and above the
   overlay blocker so it stays readable on a locked chart. */
.spx-price-scroll-label {
  position: absolute;
  right: 24px;
  transform: translateY(-50%);
  z-index: 11;
  padding: 2px 6px;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 600;
  line-height: 1.3;
  white-space: nowrap;
  color: #fff;
  background: rgba(20, 24, 34, 0.88);
  border: 1px solid var(--accent-color, #2962ff);
  pointer-events: none;
  opacity: 0;
  transition: opacity 120ms ease;
}
.spx-price-scroll-label.is-visible {
  opacity: 1;
}

/* === Style preset drag-to-reorder list =================================
   Expandable list under the "▾ Reorder by drag" toggle in the
   TradingView gear popover. Only user-saved presets appear here —
   built-ins are pinned to the top of the dropdown and don't make
   sense to drag. Each `<li>` is draggable via the HTML5 drag API. */
.lc-preset-reorder-list {
  list-style: none;
  padding: 0;
  margin: 4px 0 8px 0;
  max-height: 200px;
  overflow-y: auto;
  border: 1px solid var(--border-color, #2a2e39);
  border-radius: 4px;
  background: var(--bg-secondary, #131722);
}
.lc-preset-reorder-list[hidden] {
  display: none;
}
.lc-preset-reorder-list li {
  padding: 6px 10px;
  cursor: grab;
  border-bottom: 1px solid var(--border-color, #2a2e39);
  user-select: none;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
}
.lc-preset-reorder-list li:last-child {
  border-bottom: none;
}
.lc-preset-reorder-list li:hover {
  background: var(--bg-hover, #1e222d);
}
.lc-preset-reorder-list li.dragging {
  opacity: 0.4;
  cursor: grabbing;
}
.lc-preset-reorder-list li.lc-preset-reorder-empty {
  cursor: default;
  color: var(--text-muted, #6c7080);
  font-style: italic;
}
.lc-preset-reorder-list li.lc-preset-reorder-empty:hover {
  background: transparent;
}
.lc-preset-grip {
  color: var(--text-muted, #6c7080);
  font-weight: bold;
  letter-spacing: -2px;
}

/* TradingView Advanced Chart embed. The widget uses `autosize: true`,
   which means it reads its host element's pixel height at mount time.
   Without an explicit height the iframe collapses to zero and the
   user sees an empty card. 620px keeps the card visually balanced
   with the SPX Indicators stack above it. */
.chart-tradingview {
  height: 620px;
  /* The iframe paints its own background; suppress the card's
     padding-induced gap so the chart sits flush inside the card. */
  padding: 0;
  overflow: hidden;
  /* Match the card's rounded corners so the iframe doesn't bleed
     over the bottom-left/right radii on small viewports. */
  border-radius: 8px;
}

/* Provider / latency status row below the TradingView embed. Driven by
   a static symbol->provider lookup in tradingview-widget.js (we can't
   read the cross-origin iframe), so the badge reflects the *requested*
   symbol's data tier, not a live confirmation of the chart frame.
   Latency tiers map to color via the .tv-status-latency-{tier} suffix:
   realtime (green), delayed (amber), gated (red), unknown (grey). */
.chart-tradingview-status {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  padding: 6px 10px 4px;
  font-size: 0.78rem;
  color: var(--bs-secondary-color, #6c757d);
}
.chart-tradingview-status .tv-status-symbol {
  font-family: var(--bs-font-monospace, monospace);
  color: var(--bs-body-color, #212529);
  font-weight: 600;
}
.chart-tradingview-status .tv-status-sep {
  opacity: 0.5;
}
.chart-tradingview-status .tv-status-latency {
  font-weight: 600;
  padding: 1px 8px;
  border-radius: 999px;
  font-size: 0.72rem;
  letter-spacing: 0.01em;
  border: 1px solid transparent;
}
/* Green: free real-time feeds (CFD providers, major crypto venues). */
.chart-tradingview-status .tv-status-latency-realtime {
  color: #198754;
  background: rgba(25, 135, 84, 0.10);
  border-color: rgba(25, 135, 84, 0.30);
}
/* Amber: standard delayed feeds (CBOE indices, US equities/ETFs,
   futures). Free in the embed, just not real-time. */
.chart-tradingview-status .tv-status-latency-delayed {
  color: #b54708;
  background: rgba(245, 158, 11, 0.12);
  border-color: rgba(245, 158, 11, 0.35);
}
/* Red: gated feeds that need a logged-in TradingView session and
   therefore will not render in the anonymous embed (SP:SPX et al). */
.chart-tradingview-status .tv-status-latency-gated {
  color: #b91c1c;
  background: rgba(220, 38, 38, 0.10);
  border-color: rgba(220, 38, 38, 0.30);
}
/* Grey: unknown symbol — exchange prefix isn't in our table. */
.chart-tradingview-status .tv-status-latency-unknown {
  color: var(--bs-secondary-color, #6c757d);
  background: rgba(108, 117, 125, 0.10);
  border-color: rgba(108, 117, 125, 0.25);
}
/* Dark theme: lift the badge colors a notch so they read against the
   darker card background. */
[data-theme="dark"] .chart-tradingview-status .tv-status-latency-realtime {
  color: #34d399;
  background: rgba(52, 211, 153, 0.12);
  border-color: rgba(52, 211, 153, 0.35);
}
[data-theme="dark"] .chart-tradingview-status .tv-status-latency-delayed {
  color: #fbbf24;
  background: rgba(251, 191, 36, 0.12);
  border-color: rgba(251, 191, 36, 0.35);
}
[data-theme="dark"] .chart-tradingview-status .tv-status-latency-gated {
  color: #f87171;
  background: rgba(248, 113, 113, 0.12);
  border-color: rgba(248, 113, 113, 0.35);
}

/* Today's open-trade strike chips rendered immediately below the
   TradingView embed. The iframe is cross-origin so we cannot paint
   strike lines on the chart canvas; the chip strip is the closest
   honest substitute. Each row groups a trade's chips together; each
   chip is a side badge (SC/SP/BC/BP) + strike price, color-coded
   by side so calls (red family) and puts (green family) read at a
   glance. Hidden via the `[hidden]` attribute when there are no
   open trades today. */
.chart-tradingview-strikes {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 4px 10px 8px;
  font-size: 0.78rem;
}
.chart-tradingview-strikes[hidden] { display: none; }
.chart-tradingview-strikes .tv-strikes-header {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--bs-secondary-color, #6c757d);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  cursor: help;
}
.chart-tradingview-strikes .tv-strikes-body {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.chart-tradingview-strikes .tv-strike-trade {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}
.chart-tradingview-strikes .tv-strike-strategy {
  font-family: var(--bs-font-monospace, monospace);
  color: var(--bs-body-color, #212529);
  font-weight: 600;
  padding: 1px 6px;
  border-radius: 4px;
  background: rgba(108, 117, 125, 0.08);
  border: 1px solid rgba(108, 117, 125, 0.20);
  cursor: help;
}
.chart-tradingview-strikes .tv-strike-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 1px 6px;
  border-radius: 999px;
  border: 1px solid transparent;
  font-family: var(--bs-font-monospace, monospace);
  font-size: 0.72rem;
  line-height: 1.4;
}
.chart-tradingview-strikes .tv-strike-side {
  font-weight: 700;
  letter-spacing: 0.02em;
}
.chart-tradingview-strikes .tv-strike-price { font-weight: 500; }
/* Short Call: bearish for the trade (resistance) — red family. */
.chart-tradingview-strikes .tv-strike-chip.tv-strike-sc {
  color: #b91c1c;
  background: rgba(220, 38, 38, 0.10);
  border-color: rgba(220, 38, 38, 0.30);
}
/* Bought Call (long leg above the short call) — lighter red. */
.chart-tradingview-strikes .tv-strike-chip.tv-strike-bc {
  color: #b91c1c;
  background: rgba(220, 38, 38, 0.05);
  border-color: rgba(220, 38, 38, 0.18);
}
/* Short Put: bearish for the trade (support) — green family. */
.chart-tradingview-strikes .tv-strike-chip.tv-strike-sp {
  color: #198754;
  background: rgba(25, 135, 84, 0.10);
  border-color: rgba(25, 135, 84, 0.30);
}
/* Bought Put (long leg below the short put) — lighter green. */
.chart-tradingview-strikes .tv-strike-chip.tv-strike-bp {
  color: #198754;
  background: rgba(25, 135, 84, 0.05);
  border-color: rgba(25, 135, 84, 0.18);
}
[data-theme="dark"] .chart-tradingview-strikes .tv-strike-chip.tv-strike-sc,
[data-theme="dark"] .chart-tradingview-strikes .tv-strike-chip.tv-strike-bc {
  color: #f87171;
  background: rgba(248, 113, 113, 0.10);
  border-color: rgba(248, 113, 113, 0.30);
}
[data-theme="dark"] .chart-tradingview-strikes .tv-strike-chip.tv-strike-sp,
[data-theme="dark"] .chart-tradingview-strikes .tv-strike-chip.tv-strike-bp {
  color: #34d399;
  background: rgba(52, 211, 153, 0.10);
  border-color: rgba(52, 211, 153, 0.30);
}
[data-theme="dark"] .chart-tradingview-strikes .tv-strike-strategy {
  background: rgba(139, 148, 158, 0.10);
  border-color: rgba(139, 148, 158, 0.25);
}

/* SPX-Indicators chart toolbar styling — make the active tool icon
   clearly distinct from inactive ones. ApexCharts adds class
   ``apexcharts-selected`` to the active toolbar tool's wrapper.
   We bump its opacity to 1 (default 0.6) and tint it with the
   accent color so the user can see whether pan or zoom is on.
   Inactive tools get a deliberate grey to make the difference
   obvious. */
.chart-card .apexcharts-toolbar .apexcharts-zoom-icon,
.chart-card .apexcharts-toolbar .apexcharts-pan-icon,
.chart-card .apexcharts-toolbar .apexcharts-zoomin-icon,
.chart-card .apexcharts-toolbar .apexcharts-zoomout-icon,
.chart-card .apexcharts-toolbar .apexcharts-reset-icon,
.chart-card .apexcharts-toolbar .apex-yzoom-in,
.chart-card .apexcharts-toolbar .apex-yzoom-out,
.chart-card .apexcharts-toolbar .apex-yzoom-reset {
  opacity: 0.45;
  transition: opacity 120ms, color 120ms;
  color: var(--text-secondary, #8b949e);
}
.chart-card .apexcharts-toolbar .apexcharts-zoom-icon:hover,
.chart-card .apexcharts-toolbar .apexcharts-pan-icon:hover,
.chart-card .apexcharts-toolbar .apexcharts-zoomin-icon:hover,
.chart-card .apexcharts-toolbar .apexcharts-zoomout-icon:hover,
.chart-card .apexcharts-toolbar .apexcharts-reset-icon:hover,
.chart-card .apexcharts-toolbar .apex-yzoom-in:hover,
.chart-card .apexcharts-toolbar .apex-yzoom-out:hover,
.chart-card .apexcharts-toolbar .apex-yzoom-reset:hover {
  opacity: 0.9;
  color: var(--text-primary, #c9d1d9);
}
.chart-card .apexcharts-toolbar .apexcharts-selected {
  opacity: 1 !important;
  color: var(--accent-secondary, #1f6feb) !important;
}
/* Tighten the inline SVG icon color follow-through (Apex sets stroke
   on the inner SVG, which otherwise ignores `color`). */
.chart-card .apexcharts-toolbar .apexcharts-pan-icon svg,
.chart-card .apexcharts-toolbar .apexcharts-zoom-icon svg,
.chart-card .apexcharts-toolbar .apexcharts-zoomin-icon svg,
.chart-card .apexcharts-toolbar .apexcharts-zoomout-icon svg,
.chart-card .apexcharts-toolbar .apexcharts-reset-icon svg {
  stroke: currentColor;
}

/* Popover for the SPX Indicators color settings — anchored to the
   gear button in the chart-card header. Hidden by the [hidden]
   attribute until the user clicks the gear, then a small panel of
   color pickers slides in. Persists overrides to localStorage. */
.indicator-settings-popover {
  position: absolute;
  top: 32px;
  right: 0;
  z-index: 50;
  min-width: 260px;
  max-width: 320px;
  max-height: 70vh;
  overflow-y: auto;
  padding: 12px 14px;
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
  font-size: 0.85rem;
}
.indicator-settings-popover[hidden] {
  display: none;
}
.indicator-settings-popover h6 {
  margin: 0 0 8px 0;
  font-size: 0.9rem;
  color: var(--text-primary);
}
.indicator-settings-popover .ind-color-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 4px 0;
  border-top: 1px solid var(--border-color);
}
.indicator-settings-popover .ind-color-row:first-of-type {
  border-top: none;
}
.indicator-settings-popover .ind-color-label {
  flex: 1;
  color: var(--text-primary);
  font-size: 0.8rem;
}
.indicator-settings-popover input[type="color"] {
  width: 32px;
  height: 22px;
  padding: 0;
  border: 1px solid var(--border-color);
  background: transparent;
  cursor: pointer;
}
/* Opacity sliders sit next to the color swatches in the chart-style
   rows. Cap the width so they don't blow out the popover width and
   keep them visually compact alongside the readout span. */
.indicator-settings-popover .ind-color-row input[type="range"] {
  width: 90px;
  flex: 0 0 auto;
}
.indicator-settings-popover .ind-actions {
  display: flex;
  gap: 8px;
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px solid var(--border-color);
}
.indicator-settings-popover .ind-actions button {
  flex: 1;
  padding: 4px 8px;
  font-size: 0.78rem;
  border-radius: 4px;
  border: 1px solid var(--border-color);
  background: var(--bg-primary);
  color: var(--text-primary);
  cursor: pointer;
}
.indicator-settings-popover .ind-actions button:hover {
  background: var(--bg-tertiary);
}

/* ============================================================
   Lightweight Charts on-chart indicator panels
   ------------------------------------------------------------
   Small floating pills overlaid in the upper-left of the SPX
   Lightweight Charts canvas. Each panel exposes a label, an
   eye toggle (hide/show), and a gear (settings popover).
   Lives directly inside `#chartLightweightSpx` which has
   position:relative applied by lightweight-spx-chart.js so the
   panels anchor to the chart, not the page.
   ============================================================ */
.lc-indicator-panel {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 6;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 8px;
  background: var(--bg-secondary, rgba(255, 255, 255, 0.85));
  border: 1px solid var(--border-color, rgba(0, 0, 0, 0.15));
  border-radius: 14px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.18);
  font-size: 0.78rem;
  user-select: none;
  pointer-events: auto;
}
/* Horizontal, wrapping row of the on-chart indicator pills pinned to the
   top of the chart (below the overlay legend). Replaces the full-height
   left-column stack that obscured the morning candles. The container is
   click-through (gaps pass to the chart); each pill re-enables pointer
   events on itself. */
.lc-indicator-panels {
  position: absolute;
  top: 34px;
  left: 8px;
  right: 8px;
  z-index: 6;
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  pointer-events: none;
}
.lc-indicator-panels .lc-indicator-panel {
  position: static;
  top: auto;
  left: auto;
  padding: 2px 7px;
  font-size: 0.72rem;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.16);
  pointer-events: auto;
}
[data-theme="dark"] .lc-indicator-panel {
  background: rgba(22, 27, 34, 0.9);
}
.lc-indicator-panel-label {
  color: var(--text-primary);
  font-weight: 600;
  letter-spacing: 0.02em;
}
.lc-indicator-panel.lc-indicator-panel-hidden .lc-indicator-panel-label {
  /* Strike-through label when the indicator is hidden so the user has
     an at-a-glance state cue beyond the eye-icon swap. */
  opacity: 0.55;
  text-decoration: line-through;
}
.lc-indicator-panel-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  padding: 0;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 4px;
  color: var(--text-primary);
  cursor: pointer;
  font-size: 0.85rem;
  line-height: 1;
  transition: background-color 120ms ease;
}
.lc-indicator-panel-btn:hover {
  background: var(--bg-tertiary, rgba(0, 0, 0, 0.06));
  border-color: var(--border-color, rgba(0, 0, 0, 0.15));
}
.lc-indicator-panel-btn:focus-visible {
  outline: 2px solid var(--accent-color, #2962FF);
  outline-offset: 1px;
}
/* On-chart popovers — position is set inline by JS to anchor under
   their panel. We just override the static popover positioning so the
   panel-popover doesn't fight with the .indicator-settings-popover
   `top: 32px; right: 0` defaults from the previous TV-card popover. */
.indicator-settings-popover.lc-indicator-popover {
  position: absolute;
  top: auto;
  right: auto;
  z-index: 7;
}

@media (max-width: 768px) {
  .charts-grid { grid-template-columns: 1fr; }
  .chart-card.chart-wide { grid-column: span 1; }
}


/* Chart action buttons (e.g. CSV download in the simulator card header). */
.chart-card .chart-header {
  position: relative;
}
.chart-card .chart-action-btn {
  position: absolute;
  top: 0;
  right: 0;
  padding: 2px 8px;
  font-size: 0.75rem;
  line-height: 1.4;
}
/* Header action-button group (full-window + drag toggle). Pins the
   buttons to the header's right edge as a flex row so they no longer
   collide at the same absolute origin. Buttons inside become static so
   the flex layout controls their placement. */
.chart-card .chart-header-actions {
  position: absolute;
  top: 0;
  right: 0;
  display: flex;
  gap: 4px;
}
.chart-card .chart-header-actions .chart-action-btn {
  position: static;
}
/* Historical rewind date navigator (date picker + prev/next + Live).
   Sits at the left of the header-actions group. */
.chart-card .chart-date-nav {
  display: flex;
  align-items: center;
  gap: 2px;
  margin-right: 4px;
}
.chart-card .chart-date-input {
  font-size: 0.72rem;
  padding: 1px 4px;
  line-height: 1.3;
  border: 1px solid var(--border-color, #d0d7de);
  border-radius: 4px;
  background: var(--input-bg, #ffffff);
  color: var(--text-primary, #24292f);
  max-width: 132px;
}
.chart-card .chart-date-live {
  font-size: 0.72rem;
  font-weight: 600;
}
/* Freshness indicator turns amber while replaying a past session. */
.chart-card .chart-updated.is-historical {
  color: #b45309;
  font-weight: 600;
}
/* Amber when the live candle age exceeds the ~1-minute freshness budget
   (server intraday TTL + one poll interval) so a lagging/stalled feed is
   visually obvious instead of silently frozen. */
.chart-card .chart-updated.is-stale {
  color: #b45309;
  font-weight: 600;
}
/* Last-updated freshness indicator (#3). Small, muted, tabular so the
   HH:MM:SS doesn't reflow every second. Sits between the title and the
   variant toggle in the header. */
.chart-card .chart-updated {
  margin-left: 10px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.chart-card .chart-action-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
/* Active state for the drag-mode hand toggle in the LC chart card
   header. Mirrors the segmented-control "is-active" treatment used by
   .chart-variant-btn so the affordance reads as a sibling control:
   filled accent background, white icon, no border. */
.chart-card .chart-action-btn.is-active,
.chart-card .chart-action-btn[aria-pressed="true"] {
  background: var(--accent-color, #2962ff);
  color: #ffffff;
  border-color: var(--accent-color, #2962ff);
}
.chart-card .chart-action-btn.is-active:hover,
.chart-card .chart-action-btn[aria-pressed="true"]:hover {
  background: var(--accent-hover, #1d4fd7);
  color: #ffffff;
}
.chart-card .chart-action-btn:focus-visible {
  outline: 2px solid var(--accent-color, #2962ff);
  outline-offset: 2px;
}

/* ============================================================
   SPX Indicators (Lightweight Charts) — readout strips
   ------------------------------------------------------------
   `.chart-lightweight-targets` and `.chart-lightweight-atr` are
   the two thin info strips rendered below the LC canvas by
   lightweight-spx-chart.js. They share the chart-card padding
   so the readout aligns with the chart body above. The
   `.cross-target-near` modifier (#2) gives the targets strip a
   pulsing highlight when SPX price is within CROSS_ALERT_BPS
   of either EMA cross-target — a passive visual nudge that does
   not steal focus from the rest of the dashboard.
   ============================================================ */
.chart-card .chart-lightweight-targets,
.chart-card .chart-lightweight-atr {
  margin: 6px 12px 0;
  font-variant-numeric: tabular-nums;
}
.chart-card .chart-lightweight-targets.cross-target-near {
  color: var(--text-primary);
  background: rgba(34, 197, 94, 0.18);
  border-left: 3px solid #22c55e;
  padding: 4px 8px;
  border-radius: 4px;
  animation: dash-spx-cross-alert 1.2s ease-in-out infinite;
}
@keyframes dash-spx-cross-alert {
  0%, 100% { background-color: rgba(34, 197, 94, 0.18); }
  50%      { background-color: rgba(34, 197, 94, 0.32); }
}

/* ============================================================
   SPX Flow Panel (GY Capital)
   Strike-distributed sub-charts in one card:
     .spx-flow-quad-grid           — 2x2 grid wrapping the 4 Quad cells
     #chartSpxFlowGexClassic       — horizontal GEX Classic bar chart
   See web-app/static/js/spx-flow-panel.js and
   docs/SPX_FLOW_PANEL_DESIGN.md.
   ============================================================ */
.spx-flow-quad-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  margin-top: 12px;
}
.spx-flow-quad-cell {
  /* Each cell is a sub-card inside the parent chart-card. We use
     the same border + bg vars as .chart-card so the sub-cells read
     as siblings of the outer card and stay theme-consistent. */
  background: var(--bg-primary, transparent);
  border: 1px solid var(--border-color);
  border-radius: 8px;
  padding: 6px 8px;
  min-height: 200px;
}
.spx-flow-sonar-body {
  margin-top: 12px;
  min-height: 200px;
}
/* Full-width horizontal GEX Classic chart (strikes on Y-axis).
   Sized to give the 21 horizontal bars enough vertical room for the
   strike labels to render without overlap. */
.spx-flow-sonar-full {
  margin-top: 12px;
  min-height: 380px;
}
/* Prediction report (legacy, inert) — monospace text block under
   the GEX Classic chart. The `.spx-flow-report-*` selectors stay
   defined so older smoke tests + any future re-render of the
   report keep working. Live UI now renders the predicted close
   inline via the header badge (`_renderPredictedClose`).

   The block uses `<pre white-space: pre>` so the literal spaces in
   the label padding spans survive, which keeps the two-column
   monospace alignment working alongside per-token coloring. The
   `.spx-flow-report-*` selectors below provide the contrast story:
   dim labels, bright values, accent for the title / timestamp /
   section heading / trade names, and regime-tinted values
   (green / red / amber) so the eye is pulled to the active signal. */
.spx-flow-report {
  margin-top: 12px;
  padding: 14px 18px;
  font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;
  font-size: 0.85rem;
  line-height: 1.55;
  /* Default (light theme) — high-contrast slate text on a near-white
     panel. Dark theme overrides further down lift the values to pure
     white against a near-black panel. */
  color: #0f172a;
  background: #f8fafc;
  border: 1px solid rgba(15, 23, 42, 0.25);
  border-radius: 8px;
  white-space: pre;
  overflow-x: auto;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.65);
}
[data-theme="dark"] .spx-flow-report {
  color: #f8fafc;
  /* Push the panel darker than the card so the report visually pops
     out instead of blending into the chart body's background. */
  background: #0b1220;
  border-color: rgba(148, 163, 184, 0.45);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
}
/* "Prediction for SPX" header line. */
.spx-flow-report-title {
  color: #0ea5e9;
  font-weight: 700;
  letter-spacing: 0.02em;
}
[data-theme="dark"] .spx-flow-report-title { color: #38bdf8; }
.spx-flow-report-sep { color: rgba(15, 23, 42, 0.45); }
[data-theme="dark"] .spx-flow-report-sep { color: rgba(148, 163, 184, 0.55); }
/* Timestamp on the header line — amber so it's clearly the "when"
   marker without competing with the regime/strength tints below. */
.spx-flow-report-ts {
  color: #b45309;
  font-weight: 600;
}
[data-theme="dark"] .spx-flow-report-ts { color: #fbbf24; }
/* Narrative paragraph — body text inherits the report color but the
   emphasized tokens inside (`spx-flow-report-emph`) bump weight + tone
   so the key facts read first. */
.spx-flow-report-narrative {
  color: inherit;
}
.spx-flow-report-emph {
  font-weight: 700;
  color: #0f172a;
}
[data-theme="dark"] .spx-flow-report-emph { color: #ffffff; }
/* Two-column metric rows. Label is dimmed, value is bright + bold so
   the eye lands on the number. The trailing spaces inside the label
   span are preserved by the parent's `white-space: pre`. */
.spx-flow-report-label {
  color: rgba(15, 23, 42, 0.62);
  font-weight: 500;
}
[data-theme="dark"] .spx-flow-report-label { color: rgba(226, 232, 240, 0.65); }
.spx-flow-report-value {
  color: #0f172a;
  font-weight: 700;
}
[data-theme="dark"] .spx-flow-report-value { color: #ffffff; }
/* Regime-tinted values (used in narrative + Short/Long term bias rows). */
.spx-flow-report-value-bull {
  color: #15803d;
}
[data-theme="dark"] .spx-flow-report-value-bull { color: #4ade80; }
.spx-flow-report-value-bear {
  color: #b91c1c;
}
[data-theme="dark"] .spx-flow-report-value-bear { color: #f87171; }
.spx-flow-report-value-neutral {
  color: rgba(15, 23, 42, 0.7);
}
[data-theme="dark"] .spx-flow-report-value-neutral { color: rgba(226, 232, 240, 0.85); }
/* Strength readings ≥ 0.7 — amber to flag the trade-worthy band. */
.spx-flow-report-value-strong {
  color: #b45309;
}
[data-theme="dark"] .spx-flow-report-value-strong { color: #fbbf24; }
/* "Example Trades:" section heading — accent + underline so the
   reader scanning the report knows the actionable block starts. */
.spx-flow-report-section {
  display: inline-block;
  margin-top: 2px;
  color: #0ea5e9;
  font-weight: 700;
  border-bottom: 1px solid rgba(14, 165, 233, 0.35);
}
[data-theme="dark"] .spx-flow-report-section {
  color: #38bdf8;
  border-bottom-color: rgba(56, 189, 248, 0.45);
}
/* Trade rows: name is the accent color (matches the section heading
   so it visually groups), strikes are the high-contrast value tone. */
.spx-flow-report-trade-name {
  color: #0e7490;
  font-weight: 600;
}
[data-theme="dark"] .spx-flow-report-trade-name { color: #67e8f9; }
.spx-flow-report-trade-strikes {
  color: #0f172a;
  font-weight: 700;
}
[data-theme="dark"] .spx-flow-report-trade-strikes { color: #ffffff; }
/* Per-user hide-toggle for the entire SPX Flow Panel. Mirrors
   the dashSpxEngine pattern from lightweight-spx-chart.js — header
   stays visible so the user can re-show with a single click, body
   collapses (display: none) so the synthetic-data panels don't
   bias users who don't trust the spike. The toggle is wired by
   spx-flow-panel.js (state stored in DEFAULT_SETTINGS['dashSpxFlowHidden']
   and mirrored into localStorage.dashSpxFlowHidden). */
.spx-flow-hide-btn {
  margin-left: auto;
  padding: 2px 6px;
  font-size: 0.9rem;
  background: transparent;
  border: 1px solid var(--border-color);
  color: var(--text-secondary, #94a3b8);
  border-radius: 6px;
  cursor: pointer;
}
.spx-flow-hide-btn:hover {
  color: var(--text-primary, #f8fafc);
  border-color: var(--text-secondary, #94a3b8);
}
#chartSpxFlowPanelCard.spx-flow-hidden .spx-flow-collapsible {
  display: none;
}
/* Regime badge in the chart header — colored chip that reads as
   Long Gamma / Short Gamma / Neutral plus the dollar Net GEX. Stays
   inline with the chart-title so it's the first thing the trader
   sees scanning the card. */
.spx-flow-badge {
  display: inline-block;
  padding: 2px 8px;
  margin-left: 8px;
  font-size: 0.7rem;
  font-weight: 600;
  border-radius: 999px;
  vertical-align: middle;
}
.spx-flow-badge-bull {
  background: rgba(34, 197, 94, 0.22);
  color: #22c55e;
  border: 1px solid rgba(34, 197, 94, 0.45);
}
.spx-flow-badge-bear {
  background: rgba(239, 68, 68, 0.22);
  color: #ef4444;
  border: 1px solid rgba(239, 68, 68, 0.45);
}
.spx-flow-badge-neutral {
  background: rgba(148, 163, 184, 0.22);
  color: var(--text-secondary, #94a3b8);
  border: 1px solid rgba(148, 163, 184, 0.45);
}
/* Stepper miss / warning state — used when the user has scrubbed
   backwards to a minute that the snapshot capture function did NOT
   cover (weekend, off-hours, before deploy). The chart still paints
   with the synthetic fallback, but this warning chip makes the
   "you're looking at interpolated data" state unmissable. */
.spx-flow-badge-warn {
  background: rgba(245, 158, 11, 0.22);
  color: #f59e0b;
  border: 1px solid rgba(245, 158, 11, 0.45);
}
/* Sonar weight presets — sit above the four weight inputs in the
   Settings modal. Wrap freely so they reflow on narrow viewports
   without overlapping the inputs. The buttons reuse the global
   `btn btn-secondary` skin so light/dark mode tracks for free. */
.spx-flow-weight-presets {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 8px;
  margin-bottom: 8px;
}
.spx-flow-preset-btn {
  padding: 4px 10px;
  font-size: 0.85rem;
  border-radius: 6px;
}
/* Narrow viewports collapse the quad grid to a single column so
   each Quad cell stays readable on phones / split-screen tablets. */
@media (max-width: 720px) {
  .spx-flow-quad-grid {
    grid-template-columns: 1fr;
  }
}
/* Phone-narrow viewports: the report block is still legible at
   narrow widths thanks to overflow-x, but the report's monospace
   font can push the card past viewport width. Shrink the font a
   touch and let it scroll horizontally instead of breaking the
   layout. */
@media (max-width: 520px) {
  .spx-flow-report {
    font-size: 0.72rem;
    padding: 8px 10px;
  }
}

/* ── SPX GEX + Sonar View ─────────────────────────────────────────────
   Replaces the legacy SPX Distribution Panels. Single card with
   regime banner + GEX/Sonar grids + Trading Advisor action card.
   Pattern: dense data grid with subtle separators, regime-coloured
   banner, Foundry result card at the bottom. */
#chartSpxGexSonarViewCard .spx-gex-sonar-body {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 12px 14px 14px;
}
.spx-gex-sonar-regime-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.spx-gex-sonar-regime-banner {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 12px;
  border-radius: 8px;
  font-size: 0.95rem;
  border: 1px solid rgba(148, 163, 184, 0.25);
  background: rgba(148, 163, 184, 0.08);
}
.spx-gex-sonar-regime-banner.regime-long-gamma {
  border-color: rgba(34, 197, 94, 0.45);
  background: rgba(34, 197, 94, 0.10);
  color: #16a34a;
}
.spx-gex-sonar-regime-banner.regime-short-gamma {
  border-color: rgba(239, 68, 68, 0.45);
  background: rgba(239, 68, 68, 0.10);
  color: #dc2626;
}
.spx-gex-sonar-regime-banner .regime-flip-hint {
  font-style: italic;
  opacity: 0.85;
  cursor: help;
  border-bottom: 1px dotted currentColor;
}
.spx-gex-sonar-regime-banner .regime-window-badge {
  margin-left: auto;
  padding: 2px 8px;
  border-radius: 6px;
  font-size: 0.75rem;
  font-weight: 600;
  cursor: help;
  border: 1px solid rgba(148, 163, 184, 0.45);
  background: rgba(148, 163, 184, 0.12);
  color: inherit;
}
.spx-gex-sonar-vix-badge {
  padding: 6px 10px;
  border-radius: 8px;
  font-size: 0.85rem;
  border: 1px solid rgba(148, 163, 184, 0.35);
  background: rgba(148, 163, 184, 0.08);
}
.spx-gex-sonar-vix-badge.vix-low {
  color: #0284c7;
  border-color: rgba(2, 132, 199, 0.45);
  background: rgba(2, 132, 199, 0.10);
}
.spx-gex-sonar-vix-badge.vix-normal {
  color: #475569;
}
.spx-gex-sonar-vix-badge.vix-high {
  color: #b45309;
  border-color: rgba(180, 83, 9, 0.45);
  background: rgba(180, 83, 9, 0.10);
}
.spx-gex-sonar-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px;
}
.spx-gex-sonar-grid-6 {
  grid-template-columns: repeat(6, minmax(0, 1fr));
}
.spx-gex-sonar-cell {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px 10px;
  border-radius: 6px;
  background: rgba(148, 163, 184, 0.06);
  border: 1px solid rgba(148, 163, 184, 0.18);
  min-width: 0;
}
.spx-gex-sonar-cell .cell-label {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--bs-secondary-color, #64748b);
}
.spx-gex-sonar-cell .cell-value {
  font-size: 1.05rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.spx-gex-sonar-cell .cell-value.direction-bullish { color: #16a34a; }
.spx-gex-sonar-cell .cell-value.direction-bearish { color: #dc2626; }
.spx-gex-sonar-cell .cell-value.direction-neutral { color: #64748b; }
.spx-gex-sonar-cell .cell-sub {
  font-size: 0.72rem;
  line-height: 1.1;
}
/* 0DTE-fallback wall source hint — amber so a cold structural cache is
   visible (the walls are the collapse-toward-spot intraday fallback, not the
   SpotGamma-style multi-expiration structural levels). */
.spx-gex-sonar-cell .cell-sub.spx-walls-fallback {
  color: #d97706;
  font-weight: 600;
}
.spx-gex-sonar-implication-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}
.spx-gex-sonar-implication,
.spx-gex-sonar-structure {
  flex: 1 1 240px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 6px 10px;
  border-radius: 6px;
  background: rgba(148, 163, 184, 0.05);
  border: 1px dashed rgba(148, 163, 184, 0.30);
}
/* Self-describing Trading Rules v3.0 trade structure: bold structure name
   ("Structure B") on the first line, muted width / take-profit detail
   ("$60 wings · take profit at 10% of max") on the second so the label is
   meaningful without the rulebook doc open. */
.spx-gex-sonar-structure .structure-name {
  font-weight: 600;
}
.spx-gex-sonar-structure .structure-detail {
  display: block;
  line-height: 1.2;
}
.spx-gex-sonar-action-card {
  margin-top: 4px;
  padding: 10px 12px;
  border-radius: 8px;
  border: 1px solid rgba(148, 163, 184, 0.30);
  background: rgba(148, 163, 184, 0.05);
  display: flex;
  flex-direction: column;
  gap: 6px;
}
/* Advisor / rule-engine structure disagreement warning. */
.spx-gex-sonar-action-card .action-structure-warning {
  font-size: 0.8rem;
  font-weight: 600;
  color: #b45309;
  background: rgba(217, 119, 6, 0.08);
  border: 1px solid rgba(217, 119, 6, 0.35);
  border-radius: 6px;
  padding: 4px 8px;
}
.spx-gex-sonar-action-card.state-loading { opacity: 0.75; }
.spx-gex-sonar-action-card.state-error {
  border-color: rgba(239, 68, 68, 0.4);
  background: rgba(239, 68, 68, 0.06);
}
.spx-gex-sonar-action-card.action-iron_condor,
.spx-gex-sonar-action-card.action-sell_call_spread,
.spx-gex-sonar-action-card.action-sell_put_spread {
  border-color: rgba(34, 197, 94, 0.45);
  background: rgba(34, 197, 94, 0.06);
}
.spx-gex-sonar-action-card.action-buy_protective {
  border-color: rgba(59, 130, 246, 0.45);
  background: rgba(59, 130, 246, 0.06);
}
.spx-gex-sonar-action-card.action-stand_aside {
  border-color: rgba(245, 158, 11, 0.45);
  background: rgba(245, 158, 11, 0.06);
}
.spx-gex-sonar-action-card .action-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}
.spx-gex-sonar-action-card .action-rationale {
  font-size: 0.92rem;
  line-height: 1.35;
}
.spx-gex-sonar-action-card .action-meta {
  font-size: 0.78rem;
}
.spx-gex-sonar-action-card .action-guardrails ul {
  margin: 4px 0 0 1.1rem;
  padding: 0;
  font-size: 0.82rem;
}
.spx-gex-sonar-action-card .action-retry {
  margin-top: 8px;
}
.spx-gex-sonar-trade-impact {
  margin-top: 8px;
  padding: 10px 12px;
  border-radius: 8px;
  border: 1px solid rgba(99, 102, 241, 0.30);
  background: rgba(99, 102, 241, 0.05);
  display: flex;
  flex-direction: column;
  gap: 6px;
}
/* Stale-data badge: shown when the live option-flow feed is down and the
   server is serving the most recent captured snapshot (source=snapshot_fallback). */
.spx-gex-sonar-stale-badge {
  color: #f59e0b;
  font-weight: 600;
  padding: 1px 8px;
  border-radius: 999px;
  border: 1px solid rgba(245, 158, 11, 0.45);
  background: rgba(245, 158, 11, 0.10);
  white-space: nowrap;
}
.spx-gex-sonar-trade-impact.state-loading { opacity: 0.75; }
.spx-gex-sonar-trade-impact.state-streaming { opacity: 0.95; }
.spx-gex-sonar-trade-impact .impact-cursor {
  display: inline-block;
  margin-left: 1px;
  color: rgba(99, 102, 241, 0.9);
  animation: impact-cursor-blink 1s steps(1) infinite;
}
@keyframes impact-cursor-blink {
  50% { opacity: 0; }
}
.spx-gex-sonar-trade-impact.state-error {
  border-color: rgba(239, 68, 68, 0.4);
  background: rgba(239, 68, 68, 0.06);
}
.spx-gex-sonar-trade-impact .trade-impact-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}
.spx-gex-sonar-trade-impact .trade-impact-question {
  font-style: italic;
}
.spx-gex-sonar-trade-impact .trade-impact-answer {
  font-size: 0.92rem;
  line-height: 1.55;
  color: var(--text-primary);
  white-space: pre-wrap;
}
/* Rendered-markdown variant: when the agent answer is parsed into real block
   elements we drop pre-wrap (otherwise block margins double up) and add a
   scannable, well-spaced layout so the major points pop at a glance. All
   colours resolve from the theme tokens so the card stays legible in both
   the dark and light themes (the old --text-strong / --accent fallbacks did
   not exist, so bold lead-ins rendered near-white and vanished on light). */
.spx-gex-sonar-trade-impact .trade-impact-answer.impact-rich {
  white-space: normal;
  display: grid;
  gap: 10px;
}
.spx-gex-sonar-trade-impact .impact-rich > :first-child { margin-top: 0; }
.spx-gex-sonar-trade-impact .impact-rich > :last-child { margin-bottom: 0; }
.spx-gex-sonar-trade-impact .impact-rich p { margin: 0; }
/* Section headings: theme-aware accent, lifted off the preceding block with a
   hairline divider so PRESSURE / MAGNETS / HIRO / ACTION NOW read as distinct
   sections rather than running together. */
.spx-gex-sonar-trade-impact .impact-rich h1,
.spx-gex-sonar-trade-impact .impact-rich h2,
.spx-gex-sonar-trade-impact .impact-rich h3,
.spx-gex-sonar-trade-impact .impact-rich h4 {
  margin: 6px 0 0;
  padding-top: 8px;
  border-top: 1px solid var(--border-color);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--accent-secondary);
}
/* The first heading sits flush against the question line — no divider/top
   padding needed there. */
.spx-gex-sonar-trade-impact .impact-rich > h1:first-child,
.spx-gex-sonar-trade-impact .impact-rich > h2:first-child,
.spx-gex-sonar-trade-impact .impact-rich > h3:first-child,
.spx-gex-sonar-trade-impact .impact-rich > h4:first-child {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}
.spx-gex-sonar-trade-impact .impact-rich strong {
  font-weight: 700;
  color: var(--text-primary);
}
.spx-gex-sonar-trade-impact .impact-rich ul,
.spx-gex-sonar-trade-impact .impact-rich ol {
  margin: 0;
  padding-left: 1.25rem;
  display: grid;
  gap: 6px;
}
.spx-gex-sonar-trade-impact .impact-rich li {
  padding-left: 4px;
  line-height: 1.5;
}
.spx-gex-sonar-trade-impact .impact-rich li::marker { color: var(--accent-secondary); }
.spx-gex-sonar-trade-impact .impact-rich code {
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 0.85em;
  padding: 1px 5px;
  border-radius: 4px;
  color: var(--text-primary);
  background: var(--bg-hover);
  border: 1px solid var(--border-color);
}
.spx-gex-sonar-trade-impact .impact-rich hr {
  border: 0;
  border-top: 1px solid var(--border-color);
  margin: 2px 0;
}
.spx-gex-sonar-trade-impact .action-retry {
  margin-top: 8px;
}
/* Ask-Kassia launcher — floating avatar button pinned to the TRACE chart's
   top-right corner. Clicking opens the chat assistant with a context-rich
   prompt about the current surface. The chart card is position:relative
   (set below) so this anchors to it. */
.spx-trace-ask-kassia {
  position: absolute;
  top: 12px;
  right: 14px;
  z-index: 5;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px 12px 5px 5px;
  border-radius: 999px;
  border: 1px solid rgba(99, 102, 241, 0.45);
  background: linear-gradient(135deg, rgba(99, 102, 241, 0.18), rgba(139, 92, 246, 0.14));
  color: var(--text-primary);
  cursor: pointer;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.25);
  transition: transform 0.12s ease, box-shadow 0.12s ease, border-color 0.12s ease;
  backdrop-filter: blur(4px);
}
.spx-trace-ask-kassia:hover {
  transform: translateY(-1px);
  border-color: rgba(139, 92, 246, 0.8);
  box-shadow: 0 4px 16px rgba(99, 102, 241, 0.35);
}
.spx-trace-ask-kassia:focus-visible {
  outline: 2px solid var(--accent-secondary);
  outline-offset: 2px;
}
.spx-trace-ask-kassia-img {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  object-fit: cover;
  background: rgba(10, 11, 18, 0.4);
  flex: 0 0 auto;
}
.spx-trace-ask-kassia-label {
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  white-space: nowrap;
}
/* Graceful fallback when the avatar image is missing: a sparkle glyph badge
   replaces the broken <img> (set by the inline onerror handler). */
.spx-trace-ask-kassia.no-img {
  padding-left: 12px;
}
.spx-trace-ask-kassia.no-img::before {
  content: "\2728"; /* ✨ */
  font-size: 1rem;
  line-height: 1;
}
@media (max-width: 640px) {
  .spx-trace-ask-kassia-label { display: none; }
  .spx-trace-ask-kassia { padding: 5px; }
}

/* Kassia's Read — AI interpretation panel under the SPX TRACE heatmap.
   Mirrors the GEX+Sonar trade-impact card but renders sanitized markdown
   prose (paragraphs / lists / emphasis) rather than pre-wrapped text. */
.spx-trace-kassia {
  margin-top: 12px;
  padding: 12px 14px;
  border-radius: 10px;
  border: 1px solid rgba(99, 102, 241, 0.30);
  background: rgba(99, 102, 241, 0.05);
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.spx-trace-kassia.state-loading { opacity: 0.75; }
.spx-trace-kassia.state-empty,
.spx-trace-kassia.state-idle { opacity: 0.7; }
.spx-trace-kassia.state-error {
  border-color: rgba(239, 68, 68, 0.4);
  background: rgba(239, 68, 68, 0.06);
}
.spx-trace-kassia .spx-trace-kassia-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}
.spx-trace-kassia .spx-trace-kassia-header i {
  color: rgba(99, 102, 241, 0.9);
  margin-right: 4px;
}
.spx-trace-kassia .spx-trace-kassia-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}
.spx-trace-kassia .spx-trace-kassia-toggle {
  border: 0;
  background: transparent;
  color: inherit;
  opacity: 0.7;
  padding: 0 2px;
  line-height: 1;
  cursor: pointer;
}
.spx-trace-kassia .spx-trace-kassia-toggle:hover { opacity: 1; }
.spx-trace-kassia .spx-trace-kassia-toggle i { margin-right: 0; }
.spx-trace-kassia .spx-trace-kassia-action {
  border: 0;
  background: transparent;
  color: inherit;
  opacity: 0.7;
  padding: 0 2px;
  line-height: 1;
  cursor: pointer;
}
.spx-trace-kassia .spx-trace-kassia-action:hover { opacity: 1; }
.spx-trace-kassia .spx-trace-kassia-action i { margin-right: 0; }
.spx-trace-kassia.state-loading .spx-trace-kassia-action[id$="Refresh"] i {
  animation: spx-kassia-spin 0.8s linear infinite;
}
@keyframes spx-kassia-spin { to { transform: rotate(360deg); } }
.spx-trace-kassia.is-collapsed .spx-trace-kassia-body { display: none; }
.spx-trace-kassia .spx-trace-kassia-body {
  font-size: 0.92rem;
  line-height: 1.45;
}
.spx-trace-kassia .spx-trace-kassia-body p:first-child { margin-top: 0; }
.spx-trace-kassia .spx-trace-kassia-body p:last-child { margin-bottom: 0; }
.spx-trace-kassia .spx-trace-kassia-body ul,
.spx-trace-kassia .spx-trace-kassia-body ol {
  margin: 4px 0;
  padding-left: 18px;
}
.spx-trace-kassia .action-retry {
  margin-top: 8px;
}
/* Kassia's Morning Game Plan — once-per-trading-day pre-market read pinned
   under the KPI grid. Mirrors Kassia's Read but with a warm "sunrise" accent
   so it reads as the morning anchor for the dashboard. Renders sanitized
   markdown prose (sections / lists / emphasis). */
.morning-plan {
  margin: 4px 0 16px;
  padding: 14px 16px;
  border-radius: 10px;
  border: 1px solid rgba(245, 158, 11, 0.32);
  background: rgba(245, 158, 11, 0.06);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.morning-plan.state-loading { opacity: 0.8; }
.morning-plan.state-empty,
.morning-plan.state-idle { opacity: 0.85; }
.morning-plan.state-error {
  border-color: rgba(239, 68, 68, 0.4);
  background: rgba(239, 68, 68, 0.06);
}
.morning-plan .morning-plan-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}
.morning-plan .morning-plan-header i {
  color: rgba(245, 158, 11, 0.95);
  margin-right: 4px;
}
.morning-plan .morning-plan-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}
.morning-plan .morning-plan-action {
  border: 0;
  background: transparent;
  color: inherit;
  opacity: 0.7;
  padding: 0 2px;
  line-height: 1;
  cursor: pointer;
}
.morning-plan .morning-plan-action:hover { opacity: 1; }
.morning-plan .morning-plan-action i { margin-right: 0; }
.morning-plan.state-loading .morning-plan-action[id$="Refresh"] i {
  animation: spx-kassia-spin 0.8s linear infinite;
}
.morning-plan.is-collapsed .morning-plan-body { display: none; }
.morning-plan .morning-plan-body {
  font-size: 0.92rem;
  line-height: 1.5;
}
.morning-plan .morning-plan-body p:first-child { margin-top: 0; }
.morning-plan .morning-plan-body p:last-child { margin-bottom: 0; }
.morning-plan .morning-plan-body ul,
.morning-plan .morning-plan-body ol {
  margin: 4px 0;
  padding-left: 18px;
}
.morning-plan .action-retry {
  margin-top: 8px;
}
/* Morning plan accuracy badge + past-mornings history list. */
.morning-plan .morning-plan-stat {
  font-weight: 600;
  font-size: 0.72rem;
}
/* At-a-glance chips: macro-catalyst posture (ACTIVE/PENDING/CLEAR), releases
   already fired today, the next scheduled event, and the COR1M spasm gauge.
   Shared by the morning plan and the retrospective card, so the selectors are
   standalone (not nested under .morning-plan). */
.morning-plan-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 2px 0 2px;
}
.morning-plan.is-collapsed .morning-plan-chips { display: none; }
.mp-chip {
  display: inline-flex;
  align-items: center;
  font-size: 0.72rem;
  font-weight: 600;
  line-height: 1;
  padding: 4px 8px;
  border-radius: 999px;
  border: 1px solid rgba(148, 163, 184, 0.35);
  background: rgba(148, 163, 184, 0.12);
  color: inherit;
  white-space: nowrap;
}
.mp-chip-ok {
  border-color: rgba(34, 197, 94, 0.5);
  background: rgba(34, 197, 94, 0.14);
}
.mp-chip-warn {
  border-color: rgba(245, 158, 11, 0.55);
  background: rgba(245, 158, 11, 0.16);
}
.mp-chip-danger {
  border-color: rgba(239, 68, 68, 0.55);
  background: rgba(239, 68, 68, 0.16);
}
.mp-chip-event {
  border-color: rgba(59, 130, 246, 0.5);
  background: rgba(59, 130, 246, 0.14);
}
.mp-chip-next {
  border-style: dashed;
  border-color: rgba(148, 163, 184, 0.5);
}
.mp-chip-muted { opacity: 0.85; }
.morning-plan .morning-plan-viewing {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 0.85rem;
  padding: 4px 8px;
  border-radius: 6px;
  background: rgba(245, 158, 11, 0.1);
  border: 1px dashed rgba(245, 158, 11, 0.35);
}
.morning-plan .morning-plan-viewing i { color: rgba(245, 158, 11, 0.95); }
.morning-plan .morning-plan-history {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-height: 220px;
  overflow-y: auto;
  padding: 4px;
  border-radius: 8px;
  background: rgba(0, 0, 0, 0.12);
}
.morning-plan .morning-plan-hist-row {
  display: flex;
  align-items: center;
  gap: 10px;
  border: 0;
  background: transparent;
  color: inherit;
  text-align: left;
  padding: 6px 8px;
  border-radius: 6px;
  cursor: pointer;
}
.morning-plan .morning-plan-hist-row:hover { background: rgba(255, 255, 255, 0.06); }
.morning-plan .morning-plan-hist-date { font-variant-numeric: tabular-nums; font-weight: 600; }
.morning-plan .morning-plan-hist-verdict { font-size: 0.7rem; }
/* Kassia's Sample Trades — the LIVE companion to the morning plan. Recomputed
   client-side every refresh from the same implied move that paints the SPX
   chart's "1d Move Low/High" rails. Uses a cool emerald accent so it reads as
   the actionable, ever-updating sibling of the amber morning plan. */
.sample-trades {
  margin: 0 0 16px;
  padding: 14px 16px;
  border-radius: 10px;
  border: 1px solid rgba(16, 185, 129, 0.34);
  background: rgba(16, 185, 129, 0.06);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.sample-trades.state-loading { opacity: 0.8; }
.sample-trades.state-empty,
.sample-trades.state-idle { opacity: 0.85; }
.sample-trades.state-error {
  border-color: rgba(239, 68, 68, 0.4);
  background: rgba(239, 68, 68, 0.06);
}
.sample-trades .sample-trades-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}
.sample-trades .sample-trades-header i {
  color: rgba(16, 185, 129, 0.95);
  margin-right: 4px;
}
.sample-trades .sample-trades-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}
.sample-trades .sample-trades-action {
  border: 0;
  background: transparent;
  color: inherit;
  opacity: 0.7;
  padding: 0 2px;
  line-height: 1;
  cursor: pointer;
}
.sample-trades .sample-trades-action:hover { opacity: 1; }
.sample-trades .sample-trades-action i { margin-right: 0; }
.sample-trades.state-loading .sample-trades-action[id$="Refresh"] i {
  animation: spx-kassia-spin 0.8s linear infinite;
}
.sample-trades.is-collapsed .sample-trades-body { display: none; }
.sample-trades .sample-trades-body {
  font-size: 0.92rem;
  line-height: 1.5;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.sample-trades .st-reference {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 12px;
}
.sample-trades .st-rails {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: rgba(203, 213, 225, 0.95);
}
/* Long-gamma anchor note: the positive gamma-pressure ("purple spike") band
   the short strikes were derived from. Tinted to the same purple the Options
   Flow pressure overlay paints so the two surfaces read as one story. */
.sample-trades .st-gamma-band {
  flex-basis: 100%;
  font-weight: 500;
  color: rgba(176, 116, 255, 0.95);
}
.sample-trades .st-structure-badge {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  font-size: 0.72rem;
  font-weight: 600;
  line-height: 1;
  padding: 4px 8px;
  border-radius: 999px;
  border: 1px solid rgba(148, 163, 184, 0.35);
  background: rgba(148, 163, 184, 0.12);
  white-space: nowrap;
}
.sample-trades .st-structure-a {
  border-color: rgba(34, 197, 94, 0.5);
  background: rgba(34, 197, 94, 0.14);
}
.sample-trades .st-structure-b {
  border-color: rgba(245, 158, 11, 0.55);
  background: rgba(245, 158, 11, 0.16);
}
.sample-trades .st-structure-standdown {
  border-color: rgba(239, 68, 68, 0.55);
  background: rgba(239, 68, 68, 0.16);
}
.sample-trades .st-condor {
  width: 100%;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}
.sample-trades .st-condor td {
  padding: 6px 8px;
  border-top: 1px solid rgba(148, 163, 184, 0.18);
}
.sample-trades .st-condor tr:first-child td { border-top: 0; }
.sample-trades .st-leg-side {
  font-weight: 600;
  opacity: 0.9;
}
.sample-trades .st-leg-sell { color: rgba(248, 113, 113, 0.95); font-weight: 600; }
.sample-trades .st-leg-buy { color: rgba(148, 163, 184, 0.95); }
.sample-trades .st-leg-credit {
  text-align: right;
  color: rgba(34, 197, 94, 0.95);
  font-weight: 600;
}
.sample-trades .st-condor thead th {
  font-size: 0.68rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  opacity: 0.6;
  padding: 0 8px 2px;
  border: 0;
  text-align: left;
}
.sample-trades .st-condor thead th:last-child { text-align: right; }
.sample-trades .st-pl {
  font-variant-numeric: tabular-nums;
  padding-top: 2px;
  color: rgba(203, 213, 225, 0.95);
}
.sample-trades .st-pl strong { color: rgba(34, 197, 94, 0.95); }
.sample-trades .st-risk {
  font-variant-numeric: tabular-nums;
  color: rgba(148, 163, 184, 0.9);
}
.sample-trades .st-risk strong { color: rgba(248, 113, 113, 0.95); }
.sample-trades .st-standdown {
  font-weight: 600;
  color: rgba(248, 113, 113, 0.95);
}
.sample-trades .st-note { opacity: 0.85; }
.sample-trades .st-drift {
  font-variant-numeric: tabular-nums;
  opacity: 0.9;
  padding-top: 2px;
  border-top: 1px dashed rgba(148, 163, 184, 0.22);
}
/* Signal Check — confirm/caution chips grading the condor's short strikes
   against the walls / gamma flip the spx-flow payload carries. */
.sample-trades .st-signals {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding-top: 6px;
  border-top: 1px dashed rgba(148, 163, 184, 0.22);
}
.sample-trades .st-signals-head {
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  opacity: 0.75;
}
.sample-trades .st-signal {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 0.86rem;
  line-height: 1.35;
}
.sample-trades .st-signal-mark {
  flex: 0 0 auto;
  width: 1em;
  text-align: center;
  font-weight: 700;
}
.sample-trades .st-signal-label {
  flex: 0 0 auto;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.sample-trades .st-signal-detail { opacity: 0.85; }
.sample-trades .st-signal-ok .st-signal-mark { color: rgba(34, 197, 94, 0.95); }
.sample-trades .st-signal-warn .st-signal-mark { color: rgba(248, 191, 96, 0.98); }
.sample-trades .st-signal-warn .st-signal-label { color: rgba(248, 191, 96, 0.98); }
.sample-trades .st-signal-muted .st-signal-mark { color: rgba(148, 163, 184, 0.85); }
.sample-trades .st-signal-momentum {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.sample-trades .st-signals-foot { opacity: 0.7; padding-top: 2px; }
.sample-trades .st-log-wrap { margin-top: 2px; }
.sample-trades .st-log-btn { font-weight: 600; }
.sample-trades .st-log-btn i { margin-right: 4px; }
.sample-trades .action-retry { margin-top: 8px; }
/* Today's Retrospective — Kassia's plan-vs-outcome review, revealed after the
   close. Mirrors the morning plan card with a cool "review" accent. */
.morning-retro {
  margin: 0 0 16px;
  padding: 14px 16px;
  border-radius: 10px;
  border: 1px solid rgba(20, 184, 166, 0.32);
  background: rgba(20, 184, 166, 0.06);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.morning-retro.state-loading { opacity: 0.8; }
.morning-retro .morning-retro-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}
.morning-retro .morning-retro-header i {
  color: rgba(20, 184, 166, 0.95);
  margin-right: 4px;
}
.morning-retro .morning-retro-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}
.morning-retro .morning-retro-action {
  border: 0;
  background: transparent;
  color: inherit;
  opacity: 0.7;
  padding: 0 2px;
  line-height: 1;
  cursor: pointer;
}
.morning-retro .morning-retro-action:hover { opacity: 1; }
.morning-retro .morning-retro-action i { margin-right: 0; }
.morning-retro.state-loading .morning-retro-action[id$="Refresh"] i {
  animation: spx-kassia-spin 0.8s linear infinite;
}
.morning-retro .morning-retro-body {
  font-size: 0.92rem;
  line-height: 1.5;
}
.morning-retro .morning-retro-body p:first-child { margin-top: 0; }
.morning-retro .morning-retro-body p:last-child { margin-bottom: 0; }
.morning-retro .morning-retro-body ul,
.morning-retro .morning-retro-body ol {
  margin: 4px 0;
  padding-left: 18px;
}
/* SPX TRACE heatmap header controls */
.spx-trace-badge {
  margin-left: 8px;
  font-size: 0.7rem;
  letter-spacing: 0.04em;
  vertical-align: middle;
}
/* Projected 5-min HIRO move freshness readout + manual "Update" button. Sits
   between the 0DTE badge and the view controls, showing the current next-5-min
   projection and how long since it last updated. Goes amber (.is-stale) when
   the projection has gone stale past the snapshot cadence. */
.spx-trace-proj {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: 10px;
}
.spx-trace-proj-meta {
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  color: #9fb4d4;
}
.spx-trace-proj-meta.is-stale {
  color: #f5cd78;
}
.spx-trace-proj-refresh {
  white-space: nowrap;
  padding: 1px 8px;
  font-size: 0.72rem;
}
.spx-trace-proj-refresh.is-busy {
  opacity: 0.6;
  pointer-events: none;
}
.spx-trace-controls {
  margin-left: auto;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
}
.spx-trace-controls .spx-trace-lens {
  width: auto;
  min-width: 160px;
}
.spx-trace-controls .spx-trace-date {
  width: auto;
  min-width: 130px;
}
.spx-trace-controls .spx-trace-time {
  width: auto;
  min-width: 104px;
}
.spx-trace-controls .spx-trace-time-sep {
  margin: 0 -2px;
}
.spx-trace-controls .spx-trace-hours-clear {
  white-space: nowrap;
}
.spx-trace-controls .spx-trace-presets {
  display: inline-flex;
  gap: 4px;
}
.spx-trace-controls .spx-trace-preset {
  white-space: nowrap;
}
.spx-trace-controls .spx-trace-reset {
  white-space: nowrap;
}

/* Time scrubber — a full-width playhead slider under the TRACE heatmap that
   rewinds/advances the surface to a chosen point in the session (sets the
   as-of end of the visible window). Reads as a timeline beneath the chart. */
.spx-trace-scrubber {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 12px 10px 56px; /* left pad ~matches the Plotly y-axis margin */
}
.spx-trace-scrubber .spx-trace-time-slider {
  flex: 1 1 auto;
  height: 4px;
  cursor: pointer;
  accent-color: #5a96ff;
}
.spx-trace-scrubber .spx-trace-scrubber-label {
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.spx-trace-scrubber .spx-trace-scrubber-readout {
  min-width: 84px;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  color: #5a96ff;
}
.spx-trace-scrubber .spx-trace-scrubber-live {
  white-space: nowrap;
}

/* HIRO-by-price hover readout — a compact price ladder that floats over the
   top-right of the TRACE surface and updates as the cursor scrubs across time,
   showing the net puts + calls Δ-flow at each price for the hovered minute. */
#chartSpxTraceCard { position: relative; }
.spx-trace-hiro-slice {
  position: absolute;
  top: 58px;
  right: 104px;
  z-index: 6;
  width: 184px;
  display: flex;
  flex-direction: column;
  max-height: 62vh;
  background: rgba(10, 11, 18, 0.92);
  border: 1px solid rgba(120, 130, 150, 0.35);
  border-radius: 6px;
  padding: 7px 9px;
  pointer-events: none; /* never block hovering the surface beneath */
  font-size: 11px;
  color: #c7cfdb;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.45);
}
.spx-trace-hiro-slice .hiro-header { flex: 0 0 auto; }
.spx-trace-hiro-slice .hiro-ladder {
  position: relative;
  flex: 1 1 auto;
  overflow-y: auto;        /* scrolled programmatically to follow the cursor */
  scrollbar-width: none;   /* the ladder tracks the mouse Y, not a drag-bar */
}
.spx-trace-hiro-slice .hiro-ladder::-webkit-scrollbar { display: none; }
.spx-trace-hiro-slice .hiro-title {
  font-weight: 600;
  color: #e6ebf2;
  margin-bottom: 1px;
}
.spx-trace-hiro-slice .hiro-sub {
  font-size: 9px;
  color: #8a93a6;
  margin-bottom: 5px;
}
.spx-trace-hiro-slice .hiro-cursor {
  font-size: 10px;
  color: #c6cedd;
  font-variant-numeric: tabular-nums;
  margin-bottom: 5px;
  min-height: 13px;
}
.spx-trace-hiro-slice .hiro-cursor strong { color: #e6ebf2; }
.spx-trace-hiro-slice .hiro-net {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 10px;
  color: #aab3c5;
  padding-bottom: 5px;
  margin-bottom: 4px;
  border-bottom: 1px solid rgba(120, 130, 150, 0.22);
}
.spx-trace-hiro-slice .hiro-row {
  display: flex;
  align-items: center;
  gap: 6px;
  line-height: 1.45;
}
.spx-trace-hiro-slice .hiro-row.is-spot {
  background: rgba(120, 130, 150, 0.16);
  border-radius: 3px;
}
.spx-trace-hiro-slice .hiro-row.is-cursor {
  background: rgba(120, 180, 255, 0.26);
  border-radius: 3px;
  box-shadow: inset 0 0 0 1px rgba(150, 200, 255, 0.55);
}
.spx-trace-hiro-slice .hiro-px {
  width: 38px;
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: #aab3c5;
}
.spx-trace-hiro-slice .hiro-bar-wrap {
  flex: 1 1 auto;
  height: 7px;
  background: rgba(255, 255, 255, 0.05);
  border-radius: 2px;
  overflow: hidden;
}
.spx-trace-hiro-slice .hiro-bar {
  display: block;
  height: 100%;
  border-radius: 2px;
}
.spx-trace-hiro-slice .hiro-bar.pos { background: rgba(90, 150, 255, 0.85); }
.spx-trace-hiro-slice .hiro-bar.neg { background: rgba(255, 99, 110, 0.85); }
.spx-trace-hiro-slice .hiro-val {
  width: 46px;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.spx-trace-hiro-slice .hiro-val.pos { color: #8fb8ff; }
.spx-trace-hiro-slice .hiro-val.neg { color: #ff9aa0; }

/* ============================================================
   Full-window SPX View Chart (#5). The header full-window button
   toggles `.is-spx-fullpage` on #chartLightweightSpxCard, which
   pins the card to the viewport so the trader can study the chart
   without the surrounding dashboard chrome. The chart body grows
   to fill the space below the header; LWC's autoSize observer
   repaints at the new dimensions. Escape or the button exits.
   ============================================================ */
.chart-card.is-spx-fullpage {
  position: fixed;
  inset: 0;
  z-index: 1050;
  margin: 0;
  border-radius: 0;
  display: flex;
  flex-direction: column;
  background: var(--card-bg, #ffffff);
  padding: 12px 16px 16px;
  overflow: auto;
}
.chart-card.is-spx-fullpage .chart-body.chart-spx-view {
  flex: 1 1 auto;
  min-height: 0;
  height: auto;
}

/* ============================================================
   Dedicated full-page TRACE view (#/trace) — the SPX TRACE
   heatmap card gets the entire page real estate here instead of
   a 2-column dashboard grid cell. The wrapper fills the main
   content area; the card stretches to fill it as a flex column
   so the Plotly body (#chartSpxTraceHeatmap) consumes the
   remaining height below the header. The JS (_fullpageHeight in
   spx-trace-heatmap.js) sizes the Plotly surface to the viewport
   when the card carries the .is-fullpage class.
   ============================================================ */
.trace-fullpage {
  display: flex;
  flex-direction: column;
  /* Natural height (content-driven) so the view-root can scroll when the chart
     + Kassia's Read exceed the viewport. Was ``flex: 1 1 auto`` (stretch-fill),
     which collapsed the Plotly host to 0 once the view-root became scrollable —
     letting the surface overflow onto Kassia's Read. */
  flex: 0 0 auto;
  min-height: 0;
  width: 100%;
}
/* The TRACE view-root claims the remaining height inside .main-content and
   scrolls its own content vertically (mirrors the dashboard/reports view-roots)
   so a tall heatmap — or a short window — never hides the time axis, the
   scrubber, or Kassia's Read off-screen with no way to reach them. */
[data-view-root="trace"] {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}
/* Compact header bar for the dedicated full-page TRACE view: a
   back-to-dashboard affordance plus a page title. */
.trace-page-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
  flex: 0 0 auto;
}
.trace-back-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}
.trace-page-title {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
}
.trace-fullpage .chart-card.is-fullpage {
  display: flex;
  flex-direction: column;
  /* Natural height so the card wraps the chart's explicit (Plotly layout)
     height instead of stretch-collapsing in the scrollable view-root. */
  flex: 0 0 auto;
  min-height: 0;
  width: 100%;
  /* Outside the dashboard grid the span-2 rule is meaningless. */
  grid-column: auto;
}
.trace-fullpage .chart-card.is-fullpage .chart-body {
  /* Wrap the Plotly surface's explicit height (set from _fullpageHeight in
     spx-trace-heatmap.js). ``flex: 1 1 auto`` here collapsed the host to 0 in
     the scroll container, so the SVG overflowed onto the sibling Kassia's Read. */
  flex: 0 0 auto;
  min-height: 0;
}
@media (max-width: 640px) {
  .trace-fullpage .chart-card.is-fullpage .chart-header {
    flex-wrap: wrap;
  }
  .trace-fullpage .chart-card.is-fullpage .spx-trace-controls {
    margin-left: 0;
    flex-wrap: wrap;
  }
}
.spx-gex-sonar-analogs {
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px solid rgba(148, 163, 184, 0.25);
}
.spx-gex-sonar-analogs-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 4px;
}
/* "Match structure" toggle in the analog header + the empty-after-filter note. */
.spx-gex-sonar-analogs-header .spx-analogs-match-toggle {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  cursor: pointer;
  user-select: none;
}
.spx-gex-sonar-analog-empty {
  padding: 2px 0;
}
.spx-gex-sonar-analogs-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.spx-gex-sonar-analog-row {
  display: grid;
  grid-template-columns: 3.2rem 1fr 4.5rem 4rem 5rem 2.4rem;
  align-items: baseline;
  gap: 8px;
  padding: 2px 0;
  font-size: 0.82rem;
}
.spx-gex-sonar-analog-row .analog-sim {
  font-weight: 600;
  color: #2563eb;
}
.spx-gex-sonar-analog-row .analog-bias.direction-bullish { color: #16a34a; }
.spx-gex-sonar-analog-row .analog-bias.direction-bearish { color: #dc2626; }
.spx-gex-sonar-analog-row .analog-bias.direction-neutral { color: #64748b; }
/* Persisted Trading Rules v3.0 structure badge on each analog row: a compact
   A / B / SD pill so users see which entry structure that day resolved to. */
.spx-gex-sonar-analog-row .analog-structure {
  justify-self: end;
  font-weight: 600;
  font-size: 0.72rem;
  padding: 0 6px;
  border-radius: 999px;
  border: 1px solid rgba(148, 163, 184, 0.35);
  color: #64748b;
}
.spx-gex-sonar-analog-row .analog-structure.structure-structure_b {
  color: #b45309;
  border-color: rgba(217, 119, 6, 0.45);
}
.spx-gex-sonar-analog-row .analog-structure.structure-stand_down {
  color: #dc2626;
  border-color: rgba(220, 38, 38, 0.45);
}
@media (max-width: 720px) {
  .spx-gex-sonar-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .spx-gex-sonar-grid-6 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .spx-gex-sonar-analog-row {
    grid-template-columns: 3rem 1fr 3.5rem 2.4rem;
  }
  .spx-gex-sonar-analog-row .analog-strength,
  .spx-gex-sonar-analog-row .analog-spot { display: none; }
}

/* Rich analog cards: a clickable summary head + an expandable detail body
   showing structure, the trades Triton placed, outcome metrics, and Kassia's
   lessons. The analogs list stacks these cards with the same 2px gap used by
   the former one-line rows. */
.spx-gex-sonar-analog-card {
  border: 1px solid rgba(148, 163, 184, 0.25);
  border-radius: 8px;
  overflow: hidden;
  background: rgba(148, 163, 184, 0.04);
}
.spx-gex-sonar-analog-card.is-expanded {
  border-color: rgba(37, 99, 235, 0.35);
}
.analog-card-head {
  display: grid;
  grid-template-columns: 1rem 3.2rem 1fr 4.5rem 2.4rem auto;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 6px 8px;
  background: transparent;
  border: 0;
  cursor: pointer;
  text-align: left;
  font-size: 0.82rem;
  color: inherit;
}
.analog-card-head:hover { background: rgba(148, 163, 184, 0.08); }
.analog-card-head .analog-sim { font-weight: 600; color: #2563eb; }
.analog-card-head .analog-bias.direction-bullish { color: #16a34a; }
.analog-card-head .analog-bias.direction-bearish { color: #dc2626; }
.analog-card-head .analog-bias.direction-neutral { color: #64748b; }
.analog-card-head .analog-structure {
  justify-self: end;
  font-weight: 600;
  font-size: 0.72rem;
  padding: 0 6px;
  border-radius: 999px;
  border: 1px solid rgba(148, 163, 184, 0.35);
  color: #64748b;
}
.analog-card-head .analog-structure.structure-structure_b {
  color: #b45309;
  border-color: rgba(217, 119, 6, 0.45);
}
.analog-card-head .analog-structure.structure-stand_down {
  color: #dc2626;
  border-color: rgba(220, 38, 38, 0.45);
}
.analog-caret { color: #64748b; font-size: 0.75rem; }
.analog-outcome-chip {
  justify-self: end;
  font-weight: 600;
  font-size: 0.72rem;
  padding: 0 6px;
  border-radius: 999px;
  border: 1px solid rgba(148, 163, 184, 0.35);
  color: #64748b;
}
.analog-outcome-chip.win { color: #16a34a; border-color: rgba(22, 163, 74, 0.4); }
.analog-outcome-chip.loss { color: #dc2626; border-color: rgba(220, 38, 38, 0.4); }
.analog-card-body {
  padding: 6px 10px 10px 10px;
  border-top: 1px solid rgba(148, 163, 184, 0.2);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.analog-detail-title {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #64748b;
  margin-bottom: 3px;
}
.analog-detail-row {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  font-size: 0.8rem;
  padding: 1px 0;
}
.analog-detail-k { color: #64748b; }
.analog-detail-v { font-weight: 500; }
.analog-trade-list { display: flex; flex-direction: column; gap: 4px; }
.analog-trade-chip {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.8rem;
  padding: 3px 6px;
  border-radius: 6px;
  background: rgba(148, 163, 184, 0.08);
}
.analog-trade-strat { font-weight: 700; }
.analog-trade-strikes { font-variant-numeric: tabular-nums; }
.analog-trade-outcome { text-transform: capitalize; font-weight: 600; }
.analog-trade-outcome.win { color: #16a34a; }
.analog-trade-outcome.loss { color: #dc2626; }
.analog-trade-outcome.flat { color: #64748b; }
.analog-trade-outcome.pending { color: #94a3b8; }
.analog-trade-pnl {
  margin-left: auto;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.analog-trade-pnl.win { color: #16a34a; }
.analog-trade-pnl.loss { color: #dc2626; }
.analog-trade-pnl.flat { color: #64748b; }

/* =====================================================================
   Reports view — multi-day browser for Kassia's daily reports
   =====================================================================
   A dedicated review surface (distinct from the live "today" Dashboard).
   Header carries the rolling accuracy summary; a date picker + recent-days
   rail drive three stacked report panels (Morning Game Plan, Post-Trade
   Analysis, "How are your trades doing?"). */
/* The Reports view-root claims the remaining height inside .main-content and
   scrolls its own content vertically (mirrors the dashboard view-root), so long
   reports get a scrollbar instead of overflowing the fixed-height shell. */
[data-view-root="reports"] {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}
.reports-view {
  width: 100%;
  padding: 12px 24px 40px;
}
.reports-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 12px;
}
.reports-title h2 {
  margin: 0 0 2px;
  font-size: 1.35rem;
  display: flex;
  align-items: center;
  gap: 8px;
}
.reports-accuracy {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 2px;
  padding-top: 4px;
}
.reports-controls {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 16px;
}
.reports-datepick { display: inline-flex; align-items: center; }
.reports-viewing { margin-left: auto; }
.reports-layout {
  display: grid;
  grid-template-columns: 220px minmax(0, 1fr);
  gap: 18px;
  align-items: start;
}
.reports-rail {
  position: sticky;
  top: 8px;
  border: 1px solid rgba(148, 163, 184, 0.24);
  border-radius: 10px;
  overflow: hidden;
  background: var(--card-bg, rgba(148, 163, 184, 0.04));
}
.reports-rail-head {
  padding: 8px 10px;
  border-bottom: 1px solid rgba(148, 163, 184, 0.2);
  font-weight: 600;
}
.reports-rail-list { display: flex; flex-direction: column; max-height: 70vh; overflow-y: auto; }
.reports-rail-row {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-bottom: 1px solid rgba(148, 163, 184, 0.14);
  background: transparent;
  color: inherit;
  cursor: pointer;
  text-align: left;
  font-size: 0.85rem;
}
.reports-rail-row:hover { background: rgba(148, 163, 184, 0.1); }
.reports-rail-row.active { background: rgba(59, 130, 246, 0.14); }
.reports-rail-date { font-variant-numeric: tabular-nums; font-weight: 600; }
.reports-panels { display: flex; flex-direction: column; gap: 26px; min-width: 0; }
.reports-panel {
  border: 1px solid rgba(148, 163, 184, 0.45);
  border-top-width: 4px;
  border-radius: 10px;
  padding: 14px 16px;
  background: var(--card-bg, rgba(148, 163, 184, 0.04));
  box-shadow: 0 2px 10px rgba(15, 23, 42, 0.10);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
/* Color-code each section's top accent so the three reports read as clearly
   distinct blocks (sunrise = plan, blue = market, teal = post-trade). */
#reportsPlanCard { border-top-color: #f59e0b; }
#reportsEodCard { border-top-color: #3b82f6; }
#reportsRetroCard { border-top-color: #14b8a6; }
/* A firm divider under each panel header separates the title from the body. */
.reports-panel-head {
  padding-bottom: 8px;
  border-bottom: 2px solid rgba(148, 163, 184, 0.35);
}
.reports-panel.state-loading { opacity: 0.8; }
.reports-panel.state-empty,
.reports-panel.state-idle { opacity: 0.85; }
.reports-panel-head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
}
.reports-panel-head > strong { display: inline-flex; align-items: center; gap: 6px; font-size: 1.02rem; }
.reports-panel-head .text-muted { margin-left: auto; }
.reports-panel-verdict,
.reports-panel-chips { display: inline-flex; align-items: center; gap: 6px; }
.reports-panel-body { line-height: 1.5; padding-top: 2px; }
.reports-panel-body p:first-child { margin-top: 0; }
.reports-panel-body p:last-child { margin-bottom: 0; }
.reports-panel-body ul,
.reports-panel-body ol { margin: 4px 0; padding-left: 18px; }
/* Full-view empty state — shown before any daily report is persisted. */
.reports-empty {
  text-align: center;
  padding: 56px 20px;
  border: 1px dashed rgba(148, 163, 184, 0.35);
  border-radius: 12px;
  background: var(--card-bg, rgba(148, 163, 184, 0.04));
}
.reports-empty > i {
  font-size: 2.4rem;
  color: var(--text-muted, #94a3b8);
  display: block;
  margin-bottom: 10px;
}
.reports-empty h3 { margin: 0 0 6px; font-size: 1.1rem; }
.reports-empty p { max-width: 520px; margin: 0 auto; }
/* Right column of the grid: the export-capture root (summary + panels). */
.reports-main {
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-width: 0;
}
/* Power BI-style day summary: KPI cards + performance charts. */
.reports-summary {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 0;
  border: 1px solid rgba(148, 163, 184, 0.28);
  border-radius: 14px;
  background:
    linear-gradient(180deg, rgba(59, 130, 246, 0.06), rgba(59, 130, 246, 0) 120px),
    var(--card-bg, rgba(148, 163, 184, 0.04));
  box-shadow: 0 10px 30px -18px rgba(15, 23, 42, 0.55), 0 2px 6px -3px rgba(15, 23, 42, 0.3);
  overflow: hidden;
}
/* ── Adaptive-card header bar ─────────────────────────────────────────────── */
.reports-summary-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 14px 18px;
  background: linear-gradient(120deg, #4f46e5 0%, #3b82f6 55%, #0ea5e9 100%);
  color: #f8fafc;
}
.reports-summary-titlewrap {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}
.reports-summary-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  flex: 0 0 auto;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.16);
  font-size: 1.15rem;
  color: #fff;
}
.reports-summary-title {
  font-size: 1.02rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  line-height: 1.15;
}
.reports-summary-date {
  font-size: 0.82rem;
  opacity: 0.9;
  margin-top: 1px;
}
.reports-summary-verdict {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.reports-summary-meta {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  justify-content: flex-end;
}
.reports-summary-structure {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0.32em 0.7em;
  border-radius: 999px;
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: #f8fafc;
  background: rgba(255, 255, 255, 0.16);
  border: 1px solid rgba(255, 255, 255, 0.28);
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.2);
}
.reports-summary-structure::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.9;
}
.reports-summary-structure.is-a { color: #bbf7d0; }
.reports-summary-structure.is-b { color: #fed7aa; }
.reports-summary-structure.is-mixed { color: #e2e8f0; }
/* Session gamma-regime chip — the regime the market was ACTUALLY in across the
   day (open→close / dominant), distinct from the structure the trades used. A
   diamond marker + amber accent flags an intraday regime change. */
.reports-summary-regime {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0.32em 0.7em;
  border-radius: 999px;
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: #f8fafc;
  background: rgba(255, 255, 255, 0.12);
  border: 1px solid rgba(255, 255, 255, 0.24);
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.2);
}
.reports-summary-regime::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 2px;
  transform: rotate(45deg);
  background: currentColor;
  opacity: 0.9;
}
.reports-summary-regime.is-long { color: #bbf7d0; }
.reports-summary-regime.is-short { color: #fecaca; }
.reports-summary-regime.is-changed {
  color: #fde68a;
  border-color: rgba(253, 230, 138, 0.45);
  background: rgba(253, 230, 138, 0.12);
}
.reports-summary-verdict-label {
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  opacity: 0.85;
}
.reports-summary-verdict .badge {
  font-size: 0.82rem;
  padding: 0.4em 0.7em;
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.25);
}
.reports-kpis {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 10px;
  padding: 0 16px;
}
.reports-kpi {
  padding: 12px 12px;
  border-radius: 10px;
  background: rgba(148, 163, 184, 0.1);
  border: 1px solid rgba(148, 163, 184, 0.18);
  text-align: center;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.reports-kpi:hover {
  transform: translateY(-1px);
  box-shadow: 0 6px 16px -10px rgba(15, 23, 42, 0.5);
}
.reports-kpi-value {
  font-size: 1.4rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.reports-kpi-label {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted, #94a3b8);
  margin-top: 2px;
}
.reports-kpi.kpi-good { border-color: rgba(22, 163, 74, 0.4); background: rgba(22, 163, 74, 0.08); }
.reports-kpi.kpi-bad { border-color: rgba(220, 38, 38, 0.4); background: rgba(220, 38, 38, 0.08); }
.reports-kpi.kpi-warn { border-color: rgba(217, 119, 6, 0.4); background: rgba(217, 119, 6, 0.08); }
.reports-kpi.kpi-good .reports-kpi-value { color: #16a34a; }
.reports-kpi.kpi-bad .reports-kpi-value { color: #dc2626; }
.reports-kpi.kpi-warn .reports-kpi-value { color: #d97706; }
.reports-kpi-hint { padding: 6px 2px; }
/* ── Followed-plan interactive tile + breakdown popover ───────────────────── */
.reports-kpi-interactive {
  position: relative;
  cursor: pointer;
  user-select: none;
}
.reports-kpi-interactive:hover,
.reports-kpi-interactive:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.45);
}
.reports-kpi-caret {
  position: absolute;
  top: 6px;
  right: 8px;
  font-size: 0.7rem;
  color: var(--text-muted, #94a3b8);
  transition: transform 0.15s ease;
}
.reports-kpi-interactive.is-open .reports-kpi-caret { transform: rotate(180deg); }
.reports-followed-pop {
  position: absolute;
  z-index: 30;
  top: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  width: max-content;
  max-width: 280px;
  padding: 8px;
  text-align: left;
  border-radius: 10px;
  border: 1px solid var(--border-color, #26324a);
  background: var(--bg-secondary, #111a2e);
  box-shadow: 0 12px 32px -12px rgba(15, 23, 42, 0.65);
}
.reports-followed-pop-head {
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted, #94a3b8);
  padding: 2px 4px 6px;
}
.reports-followed-row {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 5px 6px;
  border-radius: 7px;
  font-size: 0.82rem;
}
.reports-followed-row > i { margin-top: 1px; }
.reports-followed-row > .reports-followed-tag { margin-top: 1px; }
.reports-followed-row + .reports-followed-row { margin-top: 2px; }
.reports-followed-row.is-followed { background: rgba(22, 163, 74, 0.1); }
.reports-followed-row.is-followed > i { color: #16a34a; }
.reports-followed-row.is-skipped { background: rgba(220, 38, 38, 0.08); }
.reports-followed-row.is-skipped > i { color: #dc2626; }
.reports-followed-label {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}
.reports-followed-body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.reports-followed-body .reports-followed-label { flex: 0 0 auto; }
.reports-followed-detail {
  font-size: 0.72rem;
  color: var(--text-muted, #94a3b8);
  font-variant-numeric: tabular-nums;
}
.reports-followed-tag {
  flex: 0 0 auto;
  font-size: 0.66rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted, #94a3b8);
}
.reports-followed-row.is-followed .reports-followed-tag { color: #16a34a; }
.reports-followed-row.is-skipped .reports-followed-tag { color: #dc2626; }
/* Sensitive Net P/L card — hosts an eye toggle in the top-right corner and a
   muted-dots masked value (no color, so the P/L direction stays private too). */
.reports-kpi-sensitive { position: relative; }
.reports-kpi-toggle {
  position: absolute;
  top: 4px;
  right: 4px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  padding: 0;
  border: none;
  border-radius: 5px;
  background: transparent;
  color: var(--text-muted, #94a3b8);
  cursor: pointer;
  line-height: 1;
  font-size: 0.8rem;
}
.reports-kpi-toggle:hover,
.reports-kpi-toggle:focus-visible {
  color: var(--text-primary);
  background: rgba(148, 163, 184, 0.18);
}
.reports-kpi-value.kpi-masked {
  color: var(--text-muted, #94a3b8);
  letter-spacing: 2px;
}
.reports-charts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px;
  padding: 0 16px;
}
.reports-chart-card {
  border: 1px solid rgba(148, 163, 184, 0.2);
  border-radius: 10px;
  padding: 8px 10px 4px;
  background: rgba(148, 163, 184, 0.04);
  min-width: 0;
}
.reports-chart-title {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--text-muted, #94a3b8);
  margin-bottom: 2px;
}
.reports-chart { min-height: 190px; }
.reports-chart-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 190px;
}
/* ── Takeaways & lessons footer ───────────────────────────────────────────── */
.reports-summary-takeaways {
  margin: 0 16px 16px;
  padding: 12px 14px;
  border-radius: 10px;
  border: 1px solid rgba(234, 179, 8, 0.3);
  border-left: 4px solid #eab308;
  background: rgba(234, 179, 8, 0.07);
}
.reports-summary-takeaways.is-pending {
  border-color: rgba(148, 163, 184, 0.25);
  border-left-color: rgba(148, 163, 184, 0.5);
  background: rgba(148, 163, 184, 0.06);
}
.reports-takeaways-head {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 0.8rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #a16207;
  margin-bottom: 6px;
}
.reports-summary-takeaways.is-pending .reports-takeaways-head { color: var(--text-muted, #94a3b8); }
.reports-takeaways-head i { color: #eab308; }
.reports-takeaways-body {
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--text-primary);
}
.reports-summary-takeaways.is-pending .reports-takeaways-body {
  color: var(--text-muted, #94a3b8);
  font-style: italic;
}
.reports-takeaways-body p { margin: 0 0 6px; }
.reports-takeaways-body p:last-child { margin-bottom: 0; }
.reports-takeaways-body ul,
.reports-takeaways-body ol { margin: 0; padding-left: 20px; }
.reports-takeaways-body li { margin-bottom: 4px; }
/* Dark-theme readability: lift the amber accents for contrast. */
[data-theme="dark"] .reports-takeaways-head { color: #fbbf24; }
[data-theme="dark"] .reports-summary-takeaways { background: rgba(234, 179, 8, 0.1); }
/* ── Export light palette ─────────────────────────────────────────────────────
 * Applied transiently during PNG / client-PDF capture so the shared image reads
 * on a white page regardless of the live theme. Overrides the palette tokens on
 * the captured root; charts are separately re-rendered in ApexCharts light mode.
 */
.reports-export-light,
.reports-export-light * {
  --text-primary: #1e293b;
  --text-secondary: #475569;
  --text-muted: #64748b;
  --border-color: #cbd5e1;
  --bg-secondary: #ffffff;
}
.reports-export-light {
  background: #ffffff !important;
  color: #1e293b;
}
.reports-export-light .reports-kpi { background: #f1f5f9; border-color: #e2e8f0; }
.reports-export-light .reports-kpi-value { color: #1e293b; }
.reports-export-light .reports-kpi.kpi-good .reports-kpi-value { color: #15803d; }
.reports-export-light .reports-kpi.kpi-bad .reports-kpi-value { color: #b91c1c; }
.reports-export-light .reports-kpi.kpi-warn .reports-kpi-value { color: #b45309; }
.reports-export-light .reports-chart-card { background: #f8fafc; border-color: #e2e8f0; }
.reports-export-light .reports-summary-takeaways { background: rgba(234, 179, 8, 0.12); }
.reports-export-light .reports-takeaways-head { color: #a16207; }
.reports-export-light .reports-takeaways-body { color: #1e293b; }
.reports-export-light .reports-panel { background: #ffffff; border-color: #e2e8f0; }
.reports-export-light .reports-panel-body { color: #1e293b; }
/* Hide the interactive-only affordances in the exported snapshot. */
.reports-export-light .reports-kpi-caret,
.reports-export-light .reports-followed-pop { display: none !important; }
/* Export-only branding footer — hidden live, revealed in the capture. */
.reports-export-brand { display: none; }
.reports-export-light .reports-export-brand {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin: 0 16px 14px;
  padding-top: 10px;
  border-top: 1px solid #e2e8f0;
  font-size: 0.72rem;
  color: #64748b;
}
.reports-export-light .reports-export-brand-name {
  font-weight: 700;
  letter-spacing: 0.02em;
  color: #334155;
}
.reports-export-light .reports-export-brand-name i { color: #3b82f6; margin-right: 4px; }
.reports-export-light .reports-export-brand-url { font-variant-numeric: tabular-nums; }
.reports-export .dropdown-menu { font-size: 0.85rem; }
.reports-export .dropdown-item i { margin-right: 6px; }
@media (max-width: 768px) {
  .reports-layout { grid-template-columns: 1fr; }
  .reports-rail { position: static; max-height: none; }
  .reports-rail-list { max-height: 240px; }
}
/* =====================================================================
   Documentation view (#/docs)
   =====================================================================
   Static help center: a sticky table-of-contents rail beside scrollable
   content sections. Mirrors the reports-view layout language (cards,
   accent borders, muted rails) so the page feels native to the shell. */
.docs-view {
  width: 100%;
  padding: 12px 24px 48px;
}
.docs-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 16px;
}
.docs-title h2 {
  margin: 0 0 2px;
  font-size: 1.35rem;
  display: flex;
  align-items: center;
  gap: 8px;
}
.docs-search { min-width: 220px; max-width: 320px; flex: 1 1 220px; }
.docs-layout {
  display: grid;
  grid-template-columns: 220px minmax(0, 1fr);
  gap: 24px;
  align-items: start;
}
/* Sticky table of contents. */
.docs-toc {
  position: sticky;
  top: 8px;
  border: 1px solid rgba(148, 163, 184, 0.24);
  border-radius: 10px;
  overflow: hidden;
  background: var(--card-bg, rgba(148, 163, 184, 0.04));
}
.docs-toc-head {
  padding: 8px 12px;
  border-bottom: 1px solid rgba(148, 163, 184, 0.2);
  font-weight: 600;
}
.docs-toc-list {
  display: flex;
  flex-direction: column;
  max-height: 78vh;
  overflow-y: auto;
}
.docs-toc-link {
  display: block;
  width: 100%;
  padding: 8px 12px;
  border: 0;
  border-left: 3px solid transparent;
  background: transparent;
  color: var(--text-secondary, inherit);
  cursor: pointer;
  text-align: left;
  font-size: 0.86rem;
}
.docs-toc-link:hover { background: rgba(148, 163, 184, 0.1); }
.docs-toc-link.active {
  background: rgba(59, 130, 246, 0.12);
  border-left-color: var(--accent-secondary, #3b82f6);
  color: var(--text-primary, inherit);
  font-weight: 600;
}
/* Content column. */
.docs-content {
  display: flex;
  flex-direction: column;
  gap: 22px;
  min-width: 0;
}
.docs-section {
  border: 1px solid rgba(148, 163, 184, 0.45);
  border-top-width: 4px;
  border-top-color: var(--accent-secondary, #3b82f6);
  border-radius: 10px;
  padding: 18px 20px;
  background: var(--card-bg, rgba(148, 163, 184, 0.04));
  box-shadow: 0 2px 10px rgba(15, 23, 42, 0.10);
  scroll-margin-top: 12px;
}
.docs-section h3 {
  margin: 0 0 12px;
  font-size: 1.12rem;
  display: flex;
  align-items: center;
  gap: 8px;
  padding-bottom: 8px;
  border-bottom: 2px solid rgba(148, 163, 184, 0.3);
}
.docs-section h4 {
  font-size: 0.98rem;
  margin: 16px 0 8px;
}
.docs-section p { line-height: 1.55; }
.docs-section > p:last-child { margin-bottom: 0; }
/* Feature/summary cards grid. */
.docs-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 12px;
  margin: 12px 0;
}
.docs-card {
  padding: 14px;
  border-radius: 10px;
  border: 1px solid rgba(148, 163, 184, 0.24);
  background: rgba(148, 163, 184, 0.06);
}
.docs-card > i {
  font-size: 1.4rem;
  color: var(--accent-secondary, #3b82f6);
  display: block;
  margin-bottom: 6px;
}
.docs-card h4 { margin: 0 0 4px; font-size: 0.94rem; }
.docs-card p { margin: 0; font-size: 0.86rem; color: var(--text-secondary, inherit); }
/* Numbered walkthrough. */
.docs-steps { padding-left: 20px; margin: 8px 0 0; }
.docs-steps li { margin-bottom: 10px; line-height: 1.5; }
.docs-steps li:last-child { margin-bottom: 0; }
/* Bulleted lists. */
.docs-list { margin: 8px 0 0; padding-left: 20px; }
.docs-list li { margin-bottom: 8px; line-height: 1.5; }
.docs-list li:last-child { margin-bottom: 0; }
.docs-list-mono code {
  font-size: 0.82rem;
  padding: 1px 5px;
  border-radius: 4px;
  background: rgba(148, 163, 184, 0.16);
}
/* Accordions (How-To / FAQ). */
.docs-accordion {
  border: 1px solid rgba(148, 163, 184, 0.24);
  border-radius: 8px;
  margin-bottom: 8px;
  background: rgba(148, 163, 184, 0.04);
  overflow: hidden;
}
.docs-accordion:last-child { margin-bottom: 0; }
.docs-accordion > summary {
  cursor: pointer;
  padding: 10px 14px;
  font-weight: 600;
  font-size: 0.9rem;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.docs-accordion > summary::-webkit-details-marker { display: none; }
.docs-accordion > summary::after {
  content: '\F282';
  font-family: 'bootstrap-icons';
  font-weight: normal;
  color: var(--text-muted, #94a3b8);
  transition: transform 0.15s ease;
}
.docs-accordion[open] > summary::after { transform: rotate(180deg); }
.docs-accordion > summary:hover { background: rgba(148, 163, 184, 0.08); }
.docs-accordion-body {
  padding: 0 14px 12px;
  font-size: 0.88rem;
  line-height: 1.5;
  color: var(--text-secondary, inherit);
}
.docs-accordion-body p { margin: 0; }
/* Reference tables. */
.docs-table-wrap { overflow-x: auto; margin: 8px 0; }
.docs-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.86rem;
}
.docs-table th,
.docs-table td {
  text-align: left;
  padding: 8px 10px;
  border-bottom: 1px solid rgba(148, 163, 184, 0.2);
  vertical-align: top;
}
.docs-table th {
  font-weight: 600;
  color: var(--text-secondary, inherit);
  border-bottom-width: 2px;
}
.docs-table td:first-child { white-space: nowrap; font-weight: 500; }
.docs-table i { color: var(--accent-secondary, #3b82f6); margin-right: 6px; }
/* Glossary definition list. */
.docs-glossary { margin: 8px 0 0; }
.docs-glossary dt {
  font-weight: 700;
  margin-top: 10px;
}
.docs-glossary dt:first-child { margin-top: 0; }
.docs-glossary dd {
  margin: 2px 0 0;
  padding-left: 0;
  color: var(--text-secondary, inherit);
  font-size: 0.9rem;
}
/* What's-new timeline. */
.docs-timeline { list-style: none; padding: 0; margin: 8px 0 0; }
.docs-timeline li {
  display: flex;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid rgba(148, 163, 184, 0.16);
}
.docs-timeline li:last-child { border-bottom: 0; }
.docs-timeline-tag {
  flex: 0 0 auto;
  height: fit-content;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  background: rgba(59, 130, 246, 0.16);
  color: var(--accent-secondary, #3b82f6);
}
.docs-timeline strong { font-size: 0.92rem; }
/* Callouts. */
.docs-callout {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 14px 0 0;
  padding: 10px 14px;
  border-radius: 8px;
  font-size: 0.88rem;
  line-height: 1.5;
}
.docs-callout > i { margin-top: 2px; }
.docs-callout-info {
  background: rgba(59, 130, 246, 0.1);
  border: 1px solid rgba(59, 130, 246, 0.25);
}
.docs-callout-info > i { color: var(--accent-secondary, #3b82f6); }
.docs-callout-warn {
  background: rgba(217, 119, 6, 0.1);
  border: 1px solid rgba(217, 119, 6, 0.28);
}
.docs-callout-warn > i { color: #d97706; }
/* Inline "jump to section" link rendered as a button. */
.docs-inline-link {
  border: 0;
  background: transparent;
  padding: 0;
  color: var(--accent-secondary, #3b82f6);
  font: inherit;
  cursor: pointer;
  text-decoration: underline;
}
.docs-inline-link:hover { text-decoration: none; }
/* Filter empty state. */
.docs-no-results {
  text-align: center;
  padding: 40px 20px;
  border: 1px dashed rgba(148, 163, 184, 0.35);
  border-radius: 12px;
  background: var(--card-bg, rgba(148, 163, 184, 0.04));
}
.docs-no-results > i {
  font-size: 2rem;
  color: var(--text-muted, #94a3b8);
  display: block;
  margin-bottom: 8px;
}
@media (max-width: 768px) {
  .docs-layout { grid-template-columns: 1fr; }
  .docs-toc { position: static; max-height: none; }
  .docs-toc-list { max-height: 220px; }
}

.analog-stat-row { display: flex; flex-wrap: wrap; gap: 12px; }
.analog-stat { display: flex; flex-direction: column; }
.analog-stat-k { font-size: 0.7rem; color: #64748b; }
.analog-stat-v { font-weight: 600; font-size: 0.85rem; }
.analog-lesson-body { font-size: 0.82rem; line-height: 1.4; }
.analog-lesson-body > :first-child { margin-top: 0; }
.analog-lesson-body > :last-child { margin-bottom: 0; }
.analog-lesson-retry { margin-left: 6px; }
/* Reconcile affordance (Outcome block) shown when an analog day still has
   open, unresolved trades. */
.analog-reconcile {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 6px;
}
/* Similar-trades vector-search results: one compact row per comparable trade. */
.analog-similar-list {
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.analog-similar-row {
  display: grid;
  grid-template-columns: 3rem 3rem 1fr 4rem 4rem;
  align-items: baseline;
  gap: 8px;
  font-size: 0.8rem;
  padding: 1px 0;
}
.analog-similar-row .analog-sim { font-weight: 600; color: #2563eb; }
.analog-similar-row .analog-trade-pnl { justify-self: end; }
/* Drill-through: clickable similar-trade rows + inline full-trade detail. */
.analog-similar-row.is-clickable { cursor: pointer; border-radius: 4px; }
.analog-similar-row.is-clickable:hover { background: rgba(148, 163, 184, 0.1); }
.analog-trade-detail {
  margin: 2px 0 6px 0;
  padding: 6px 8px;
  border-left: 2px solid rgba(37, 99, 235, 0.4);
  background: rgba(148, 163, 184, 0.06);
  border-radius: 0 6px 6px 0;
}



