/* ============================================================
   AnalogQuant — public landing
   Light, dense, professional. Livevolpro / institutional feel.
   ============================================================ */

:root {
  /* ============================================================
     CHANGELOG_SERIAL.md #099 — Sticky offset cascade custom props.
     CHANGELOG_SERIAL.md #316 — spotbar-above-tabs: stack is now
     header → hero-pin (spotbar) → tab-nav → section-chips.
     Worst-case heights baked per breakpoint (static, no ResizeObserver).
     Desktop: header=80px, hero-pin=64px, tab-nav=54px.
       hero-pin top = --aq-hdr-h (80px)
       tab-nav  top = --aq-tab-top = calc(--aq-hdr-h + --aq-pin-h) = 144px
       chips    top = --aq-pin-top = calc(--aq-hdr-h + --aq-pin-h + --aq-tab-h) = 198px
     At <=480px hero-pin is un-stuck (position:static) so --aq-pin-h=0 and
     tab-nav sticks directly under header (114px total sticky budget).
     Overridden inside each @media block below.
     Any component that pins itself relative to these layers must use
     the vars rather than hardcoded px so a single edit propagates.
     ============================================================ */
  --aq-hdr-h:  80px;   /* full header height (main-row + status-strip) */
  --aq-tab-h:  54px;   /* tab-nav height */
  --aq-pin-h:  64px;   /* #316 hero-pin-slim (spotbar) height */
  --aq-tab-top: calc(var(--aq-hdr-h) + var(--aq-pin-h));                          /* tab-nav sticky top = hdr + spotbar */
  --aq-pin-top: calc(var(--aq-hdr-h) + var(--aq-pin-h) + var(--aq-tab-h));        /* section-chips sticky top = hdr + spotbar + tabs */

  /* Surfaces */

  --bg:           #f7f8fa;
  --bg-card:      #ffffff;
  --bg-ticker:    #1a1f2e;
  --bg-table-alt: #fafbfc;

  /* Text — CHANGELOG_SERIAL.md #152 palette refresh */
  --text:         #1a1f2e;
  --text-muted:   #4a5468; /* was #5a6478 */
  --text-dim:     #6a7488; /* was #8a93a3 */
  --text-invert:  #f5f7fa;

  /* Lines — CHANGELOG_SERIAL.md #152 palette refresh */
  --line:         #d6dae2; /* was #e3e6ec */
  --line-strong:  #b4bbc6; /* was #c6ccd6 */

  /* CHANGELOG_SERIAL.md #025 — high-contrast button border per theme.
     The default --line / --line-strong are intentionally muted (good
     for card edges) but at 1px they're nearly invisible on action
     buttons, which is why Pete couldn't find the theme toggle. This
     variable gives buttons a near-black border on light backgrounds
     and a near-white border on dark backgrounds. Used by .theme-toggle,
     .oi-zoom-pill, .filter-pill, .capit-btn etc. */
  --btn-border:        rgba(15, 23, 42, 0.55);
  --btn-border-strong: rgba(15, 23, 42, 0.85);

  /* Accents — CHANGELOG_SERIAL.md #152: accent-2/3 added; accent/hover unchanged */
  --accent:       #0052cc;
  --accent-hover: #003e9c;
  --accent-2:     #7c3aed; /* violet-600 — forecast / pin values */
  --accent-3:     #d97706; /* amber-600  — time-pressure values  */

  /* Status */
  --pos:          #137333;
  --neg:          #c5221f;
  --warn:         #b06000;

  /* Chart terrain */
  --buy-strong:   rgba(40, 180, 90, 0.85);
  --buy-light:    rgba(110, 200, 140, 0.55);
  --flat:         rgba(150, 155, 160, 0.5);
  --sell-light:   rgba(220, 120, 130, 0.55);
  --sell-strong:  rgba(230, 60, 80, 0.85);

  /* Typography */
  --mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  --sans: "Inter", "SF Pro Display", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

/* ============================================================
   CHANGELOG_SERIAL.md #099 — Sticky-stack breakpoint overrides.
   CHANGELOG_SERIAL.md #316 — added --aq-pin-h per tier; removed --aq-sfb-h.
   Override --aq-hdr-h, --aq-tab-h, and --aq-pin-h at each viewport tier;
   --aq-tab-top and --aq-pin-top cascade automatically via calc().

   Tier sizing rationale (after #316):
     ≥1025px  header=80px  pin=64px  tab=54px  → tab-top=144px  chips-top=198px
     769-1024 header=80px  pin=64px  tab=54px  → same as desktop
     481-767  header=72px  pin=64px  tab=52px  → tab-top=136px  chips-top=188px
     ≤480px   header=64px  pin=0px   tab=50px  → tab-top=64px   (hero-pin un-stuck)
              total mobile sticky budget = 64+50 = 114px (≤120px target)
   ============================================================ */
@media (max-width: 1024px) {
  :root {
    --aq-hdr-h: 80px;
    --aq-tab-h: 54px;
    --aq-pin-h: 64px; /* #316 spotbar height unchanged at tablet */
  }
}
@media (max-width: 767px) {
  :root {
    --aq-hdr-h: 72px;
    --aq-tab-h: 52px;
    --aq-pin-h: 64px; /* #316 spotbar height unchanged at phablet */
  }
}
@media (max-width: 480px) {
  :root {
    --aq-hdr-h: 64px;
    --aq-tab-h: 50px;
    --aq-pin-h: 0px;  /* #316 hero-pin is un-stuck on mobile; tab sticks under header only */
    /* --aq-tab-top auto-resolves to calc(64px + 0px) = 64px via var() cascade */
  }
}

/* ============================================================
   Dark mode — LiveVol Pro / Bloomberg terminal aesthetic.
   Activated when document root has [data-theme="dark"].
   ============================================================ */
[data-theme="dark"] {
  /* Surfaces — deep navy/black, slightly lighter cards */
  --bg:           #0a131c;
  --bg-card:      #111e2b;
  --bg-ticker:    #050a10;
  --bg-table-alt: #16263a;

  /* Text — CHANGELOG_SERIAL.md #152 palette refresh */
  --text:         #e8e6df;
  --text-muted:   #b8c5d6; /* was #8a99ab — brighter for legibility on dark navy */
  --text-dim:     #8a99ab; /* was #5a6878 — old muted becomes new dim */
  --text-invert:  #0a131c;

  /* Lines — CHANGELOG_SERIAL.md #152 palette refresh */
  --line:         #2a4a66; /* was #1f3a52 */
  --line-strong:  #3a5d80; /* was #2a4a66 */

  /* CHANGELOG_SERIAL.md #025 — dark-theme override of --btn-border.
     Near-white semi-transparent so buttons read as outlined on the
     dark navy background. */
  --btn-border:        rgba(226, 232, 240, 0.45);
  --btn-border-strong: rgba(226, 232, 240, 0.85);

  /* Accents — CHANGELOG_SERIAL.md #152: brighter blue + accent-2/3 added */
  --accent:       #5cb6ff; /* was #4ea1ff */
  --accent-hover: #7ec4ff; /* was #6cb4ff */
  --accent-2:     #c084fc; /* violet-400 — forecast / pin values        */
  --accent-3:     #fbbf24; /* amber-400  — time-pressure values (= --warn in dark) */

  /* Status — saturated for terminal-style readability */
  --pos:          #22c55e;
  --neg:          #ef4444;
  --warn:         #fbbf24;

  /* Chart terrain — same hues, slightly more saturated for dark bg */
  --buy-strong:   rgba(34, 197, 94, 0.85);
  --buy-light:    rgba(34, 197, 94, 0.40);
  --flat:         rgba(140, 150, 170, 0.40);
  --sell-light:   rgba(239, 68, 68, 0.40);
  --sell-strong:  rgba(239, 68, 68, 0.85);
}

/* Dark mode — invert footer brand pill backgrounds */
[data-theme="dark"] .footer-link {
  background: rgba(255, 255, 255, 0.04);
  border-color: rgba(255, 255, 255, 0.10);
  color: var(--text);
}
[data-theme="dark"] .footer-link:hover {
  background: rgba(167, 139, 250, 0.15);
  border-color: rgba(167, 139, 250, 0.40);
  color: #c4b5fd;
}

/* Dark mode — semi-transparent overlays need re-tinting */
[data-theme="dark"] .adi-component { background: rgba(255,255,255,0.03); }
[data-theme="dark"] .adi-pin-analysis { background: rgba(255,255,255,0.03); border-color: rgba(255,255,255,0.08); }
[data-theme="dark"] .adi-pin-factor { background: rgba(255,255,255,0.04); }
[data-theme="dark"] .adi-nuances { background: rgba(255,255,255,0.03); }
[data-theme="dark"] .adi-nuance.info { background: rgba(255,255,255,0.04); color: var(--text); }
[data-theme="dark"] .edge-radar-card,
[data-theme="dark"] .atr-tile,
[data-theme="dark"] .replay-timeline { background: var(--bg-card); }
[data-theme="dark"] .atr-stat { background: rgba(255,255,255,0.04); border-color: rgba(255,255,255,0.08); }
[data-theme="dark"] .atr-stat-current { background: rgba(78, 161, 255, 0.16); border-color: rgba(78, 161, 255, 0.40); }
[data-theme="dark"] .atr-stat-expected { background: rgba(78, 161, 255, 0.08); border-color: rgba(78, 161, 255, 0.22); }
[data-theme="dark"] .atr-stat-similar { background: rgba(167, 139, 250, 0.10); border-color: rgba(167, 139, 250, 0.30); }
[data-theme="dark"] .replay-bar { background: rgba(255,255,255,0.03); border-color: rgba(255,255,255,0.08); }
[data-theme="dark"][data-replay-mode="replay"] .replay-bar { background: rgba(167, 139, 250, 0.12); border-color: rgba(167, 139, 250, 0.35); }

/* Theme toggle button in header */
.theme-toggle {
  appearance: none;
  /* CHANGELOG_SERIAL.md #025 — switched from --line (low contrast,
     made the button basically invisible) to the new --btn-border
     variable. 1.5px so it reads as a clear actionable control. */
  border: 1.5px solid var(--btn-border-strong);
  background: var(--bg-card);
  color: var(--text);
  width: 34px; height: 34px;
  border-radius: 8px;
  cursor: pointer;
  font-size: 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background-color 0.15s, border-color 0.15s;
  margin-left: 12px;
}
.theme-toggle:hover {
  background: var(--bg-table-alt);
  border-color: var(--text);
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }

body {
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.45;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.container {
  max-width: 2300px;
  margin: 0 auto;
  padding: 0 12px;
}

/* ============================================================
   CHANGELOG_SERIAL.md #112 - Recent Positions strip
   Replaces the Live alerts feed at the top of page. 5-row strip
   (3 on mobile) showing open + recently-closed Auto Trader positions.
   Header carries bankroll, today's P&L, and an Export button that
   opens the export modal (rules at the bottom of this block).
   ============================================================ */
/* ============================================================
   CHANGELOG_SERIAL.md #170 — value-prop intro hero (UX Phase 4 #1).
   Above-the-fold WHAT/WHY block for logged-out, non-dismissed visitors
   (intro.js controls visibility). Palette per FRONTEND_CONVENTIONS.md:
   green-500 primary CTA, no neon. Ships `hidden`; intro.js reveals.
   ============================================================ */
.aq-hero {
  position: relative;
  background:
    radial-gradient(120% 140% at 12% 0%, rgba(34, 197, 94, 0.10), transparent 55%),
    var(--bg-card, #0e1420);
  border-bottom: 1px solid var(--line);
}
.aq-hero[hidden] { display: none; }
.aq-hero-inner {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
  gap: 36px;
  align-items: center;
  padding: 30px 0 32px;
}
.aq-hero-eyebrow {
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.14em;
  color: rgb(34, 197, 94);
  margin-bottom: 10px;
}
.aq-hero-title {
  font-size: 30px;
  line-height: 1.16;
  font-weight: 800;
  letter-spacing: -0.01em;
  margin: 0 0 12px;
  color: var(--text);
  max-width: 20ch;
}
.aq-hero-sub {
  font-size: 15px;
  line-height: 1.5;
  color: var(--text-muted);
  margin: 0 0 20px;
  max-width: 60ch;
}
.aq-hero-cta { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.aq-hero-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 700;
  padding: 11px 18px;
  border-radius: 8px;
  text-decoration: none;
  cursor: pointer;
  border: 1px solid transparent;
  font-family: var(--sans);
  transition: transform 0.05s ease, filter 0.15s ease;
}
.aq-hero-btn:active { transform: translateY(1px); }
.aq-hero-btn-primary { background: rgb(34, 197, 94); color: #06210f; }
.aq-hero-btn-primary:hover { filter: brightness(1.08); }
.aq-hero-btn-google { background: #fff; color: #1f2937; border-color: var(--btn-border-strong); }
.aq-hero-btn-google:hover { filter: brightness(0.97); }
.aq-hero-btn-ghost { background: transparent; color: var(--text-muted); border-color: var(--btn-border); }
.aq-hero-btn-ghost:hover { color: var(--text); }
.aq-hero-foot { font-size: 12px; color: var(--text-muted); margin: 14px 0 0; opacity: 0.85; }
.aq-hero-points { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.aq-hero-points li {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 12px 14px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--line);
  border-left: 3px solid rgb(34, 197, 94);
  border-radius: 6px;
}
.aq-hero-pt-k { font-size: 13px; font-weight: 700; color: var(--text); }
.aq-hero-pt-v { font-size: 12.5px; line-height: 1.45; color: var(--text-muted); }
.aq-hero-dismiss {
  position: absolute;
  top: 10px;
  right: 14px;
  width: 30px;
  height: 30px;
  border-radius: 6px;
  background: transparent;
  border: 1px solid var(--btn-border);
  color: var(--text-muted);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}
.aq-hero-dismiss:hover { color: var(--text); border-color: var(--btn-border-strong); }
@media (max-width: 860px) {
  .aq-hero-inner { grid-template-columns: 1fr; gap: 20px; padding: 24px 0 26px; }
  .aq-hero-points { grid-template-columns: 1fr; }
}

/* CHANGELOG_SERIAL.md #215 — top-of-page two-column grid: LEFT = Recent
   Positions strip, RIGHT = live OI-flow feed. Sits directly under the header
   (already a .container, so it inherits the page max-width/gutters). Stacks to
   a single column at <=900px. */
/* CHANGELOG_SERIAL.md #225 — top margin reduced (10px→6px top, 4px→2px bottom)
   to tighten space between header and chart. */
/* CHANGELOG_SERIAL.md #304 — layout: Recent Positions full-width on top, OI Flow
   full-width directly below. Single-column grid replaces the old 2-col side-by-side.
   The visual-order flip (@media 901px order:1/order:2) is removed; DOM order is
   now the display order (positions first, OI flow second). */
.top-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 14px;
  align-items: stretch;
  /* CHANGELOG_SERIAL.md #305 — full-bleed: the Recent Positions blotter spans the
     ENTIRE viewport width, edge to edge, so the row uses all available space (and
     fills an ultrawide instead of being capped by .container's 2300px box). */
  width: 100vw;
  max-width: 100vw;
  margin: 6px 0 2px;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  padding: 0 10px;
  box-sizing: border-box;
}
.top-col-left, .top-col-right { min-width: 0; }

/* CHANGELOG_SERIAL.md #215 — positions-strip placed INSIDE the grid column.
   Drop the full-bleed dark band / bottom border / shadow it had when it spanned
   the page, and let the strip sit as a bordered card in the column. The inner
   .container loses its max-width clamp here (the grid already constrains it). */
.positions-strip.ps-in-grid {
  background: rgba(255, 255, 255, 0.02);
  border: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: none;
  padding: 10px 14px 12px;
}
.positions-strip.ps-in-grid > .container {
  width: 100%;
  max-width: none;
  padding-left: 0;
  padding-right: 0;
  margin: 0;
}

/* CHANGELOG_SERIAL.md #233 — make the positions card use flex-column so its
   list scrolls internally. Originally desktop-only (guarded at >900px to match
   OI Flow card height); #304 de-guarded since the card is now always full-width. */
/* CHANGELOG_SERIAL.md #304 — flex-column structure for positions strip applies at
   all widths now that the card is always full-width (guard was only needed when the
   strip needed to match the OI Flow card height in a 2-col side-by-side layout). */
.top-col-left { display: flex; }
.positions-strip.ps-in-grid {
  flex: 1;
  display: flex;
  flex-direction: column;
}
.positions-strip.ps-in-grid > .container {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
/* The row list (collapsed) and the expanded panel scroll inside the card;
   header + footer stay pinned. */
.positions-strip.ps-in-grid .positions-strip-list {
  flex: 1 1 auto;
  overflow-y: auto;
  min-height: 0;
}
.positions-strip.ps-in-grid .ps-expand-panel {
  flex: 1 1 auto;
  max-height: none;                  /* override the 50vh cap from #210 */
  min-height: 0;
}

/* CHANGELOG_SERIAL.md #215 — "Open only" toggle in the Recent Positions header.
   Sits inline next to the strategy filter; mirrors its muted-label styling. */
.ps-open-only-label {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  margin-left: 0.6em;
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--text-muted);
  cursor: pointer;
  user-select: none;
}
.ps-open-only-check {
  width: 14px; height: 14px;
  accent-color: #22c55e;   /* green-500 — matches the open-row accent */
  cursor: pointer;
}
.ps-open-only-text {
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 0.7rem;
}

/* CHANGELOG_SERIAL.md #276 — removed: #228 Filter popover CSS (.ps-filter-wrap,
   .ps-filter-btn, .ps-filter-pop, .ps-filter-group, .ps-filter-legend,
   .ps-filter-opt, .ps-filter-strategy, .ps-filter-older, .ps-filter-row,
   .ps-filter-row-label, .ps-filter-date, .ps-filter-time, .ps-filter-hint).
   The HTML elements were deleted in #276; the inline .ps-filterbar (#244) is the
   live filter UI. The superseding display:none!important rule below is also removed. */

/* CHANGELOG_SERIAL.md #215 — OI-flow feed (right column). Newest-first scrolling
   list of taker-flow events above the contract threshold. Card matches the
   ps-in-grid styling so the two columns read as a pair. */
.oiflow {
  background: rgba(255, 255, 255, 0.02);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 10px 14px 12px;
  color: var(--text);
}
.oiflow-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 8px;
}
.oiflow-title {
  font-size: 16px;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-weight: 800;
  color: var(--text-muted);
  margin: 0;
  display: flex;
  align-items: center;
  gap: 10px;
}
.oiflow-title .live-dot {
  width: 10px; height: 10px;
  background: #4ade80;
  border-radius: 50%;
  display: inline-block;
}
.oiflow-title-text { color: var(--text); }
.oiflow-thresh-note {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.03em;
  text-transform: none;
  color: var(--text-dim);
}
.oiflow-min-label {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.oiflow-min-input {
  width: 5.5em;
  font-family: var(--mono);
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--text);
  background: rgba(148, 163, 184, 0.12);
  border: 1px solid rgba(148, 163, 184, 0.28);
  border-radius: 6px;
  padding: 0.18em 0.5em;
}
.oiflow-min-input:focus-visible {
  outline: 2px solid #22c55e;
  outline-offset: 1px;
}
/* CHANGELOG_SERIAL.md #215 — 5-minute age-band checkboxes (0-5m / 5-10m /
   10-15m). All checked = full last 15 min; uncheck older bands to narrow. */
.oiflow-bands {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  flex-wrap: wrap;
}
.oiflow-bands-text {
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.oiflow-band-label {
  display: inline-flex;
  align-items: center;
  gap: 0.25em;
  font-size: 0.72rem;
  font-weight: 500;
  color: var(--text-muted);
  cursor: pointer;
  user-select: none;
}
.oiflow-band-check {
  width: 13px; height: 13px;
  accent-color: #22c55e;   /* green-500 — matches the live-dot accent */
  cursor: pointer;
}
.oiflow-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
  max-height: 360px;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  scrollbar-color: rgba(140, 140, 140, 0.4) transparent;
}
.oiflow-list::-webkit-scrollbar { width: 6px; }
.oiflow-list::-webkit-scrollbar-track { background: transparent; }
.oiflow-list::-webkit-scrollbar-thumb {
  background: rgba(140, 140, 140, 0.4);
  border-radius: 3px;
}
.oiflow-empty {
  padding: 12px 10px;
  color: var(--text-dim);
  font-size: 13px;
  font-style: italic;
}
/* Each event row: HH:MM:SS ET | $strike | label | size. Left border + text
   color set inline per bucket (green / red / pink / purple). */
.oiflow-row {
  display: grid;
  /* #218 — fr columns so time/strike/size/OI/spot SPREAD across the full width
     instead of crunching to the left. Cols: time | strike | label | size | OI | spot. */
  grid-template-columns: 0.95fr 0.95fr 1.5fr 0.85fr 1.1fr 1.05fr;
  align-items: baseline;
  gap: 8px;
  padding: 5px 10px;
  border-left: 3px solid transparent;
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.025);
  font-size: 15px;                                   /* #216 larger */
  line-height: 1.3;
}
/* #216 — time is now BOLD + larger. */
.oiflow-time { font-variant-numeric: tabular-nums; opacity: 0.95; font-size: 14px; font-weight: 700; }
.oiflow-strike { font-weight: 700; }
.oiflow-label {
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  font-size: 12.5px;
}
.oiflow-size { font-weight: 800; text-align: right; font-variant-numeric: tabular-nums; }
/* #216 — current OI at that strike; secondary, dimmer than the flow size. */
.oiflow-oi { font-weight: 700; text-align: right; font-variant-numeric: tabular-nums; opacity: 0.72; font-size: 13px; }
/* #218 — BTC spot at the time of print. */
.oiflow-spot { font-weight: 700; text-align: right; font-variant-numeric: tabular-nums; opacity: 0.8; font-size: 13px; }

.positions-strip {
  background: var(--bg-ticker);
  color: var(--text-invert);
  border-bottom: 2px solid #000;
  padding: 10px 0 12px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.18);
}

.positions-strip-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
  gap: 14px;
  flex-wrap: wrap;
}

.positions-strip-title {
  font-size: 16px;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-weight: 800;
  color: #c6cfdb;
  margin: 0;
  display: flex;
  align-items: center;
  gap: 12px;
}
.positions-strip-title .title-text { color: #fff; }
.positions-strip-title .live-dot {
  background: #4ade80;
  width: 10px;
  height: 10px;
}

.positions-strip.ps-live-stale .positions-strip-title .live-dot { background: #facc15; }
.positions-strip.ps-live-down  .positions-strip-title .live-dot { background: #ef4444; animation: none; }

.positions-strip-meta {
  font-weight: 500;
  letter-spacing: 0.04em;
  color: #8a93a3;
  font-size: 13px;
  text-transform: none;
}

.positions-strip-stats {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  font-size: 13px;
  color: #c6cfdb;
}
.ps-stat { display: inline-flex; align-items: baseline; gap: 6px; }
.ps-stat-label { color: #8a93a3; font-size: 11px; text-transform: uppercase; letter-spacing: 0.10em; }
.ps-stat-val   { font-family: var(--mono); font-weight: 700; color: #fff; }
.ps-stat-val.pnl-pos  { color: #4ade80; }
.ps-stat-val.pnl-neg  { color: #ff4d6d; }
.ps-stat-val.pnl-zero { color: #c6cfdb; }
.ps-stat-sep { color: #4a5363; }

.ps-export-btn {
  margin-left: 6px;
  padding: 4px 11px;
  border-radius: 6px;
  border: 1px solid rgba(255, 255, 255, 0.30);
  background: rgba(255, 255, 255, 0.06);
  color: #e8edf3;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  cursor: pointer;
  font-family: var(--sans);
  transition: background 80ms ease, border-color 80ms ease;
}
.ps-export-btn:hover {
  background: rgba(255, 255, 255, 0.14);
  border-color: rgba(255, 255, 255, 0.50);
}
.ps-export-btn:focus {
  outline: 2px solid rgba(96, 165, 250, 0.80);
  outline-offset: 1px;
}

.positions-strip-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  /* CHANGELOG_SERIAL.md #233 — slightly looser gap for the bigger rows. */
  gap: 4px;
}

.ps-row-placeholder {
  padding: 10px 12px;
  color: #8a93a3;
  font-size: 13px;
  background: rgba(255, 255, 255, 0.03);
  border-radius: 4px;
}

/* CHANGELOG_SERIAL.md #229 — professional blotter grid.
   7 columns: id(70px) contract(1.6fr) dir(34px) qty(34px)
              entry(1fr) exit(1fr) pnl(62px).
   Entry/exit are two-line cells: bold fill price (hero) over dim spot·time. */
.ps-row {
  display: grid;
  /* CHANGELOG_SERIAL.md #234 — flat one-row blotter, 11 columns:
     id | contract | side | qty | entry$ | exit$ | entry spot | exit spot |
     entry time | exit time | p&l. */
  /* CHANGELOG_SERIAL.md #236 — full-width card now, so columns breathe + 14px font;
     timestamps get their own ~92px cols so HH:MM:SS is never clipped. */
  grid-template-columns: 66px minmax(150px,1.2fr) 38px 48px 66px 66px 90px 90px 104px 104px 80px;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border-radius: 4px;
  font-size: 15px;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.03);
  border-left: 3px solid transparent;
}

/* CHANGELOG_SERIAL.md #234 — uniform blotter cells: ALL white, same size (13px),
   bold; mono tabular numerics; single line (ellipsis on overflow). ONLY the side
   chip and the P&L carry color (green/red); the strat keeps its green accent.
   NO grey anywhere. */
.ps-row .ps-col {
  font-family: var(--mono);
  font-size: 15px;
  font-weight: 700;
  color: #ffffff;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ps-row .ps-col-id, .ps-row .ps-col-contract { font-family: var(--sans); }
.ps-blot-strat  { color: #22c55e; font-size: 15px; font-weight: 700; }   /* green accent (allowed) */
.ps-blot-kind   { color: #ffffff; font-size: 15px; font-weight: 700; letter-spacing: normal; text-transform: none; }
.ps-blot-dot    { color: #ffffff; }
.ps-blot-strike { color: #ffffff; font-size: 15px; font-weight: 700; }
.ps-blot-qty    { color: #ffffff; font-size: 15px; font-weight: 700; }
.ps-blot-dir    { background: none; padding: 0; border-radius: 0; font-size: 15px; font-weight: 800; }
.ps-row .ps-dir-yes { color: #22c55e; }
.ps-row .ps-dir-no  { color: #ef4444; }
.ps-row .ps-pnl     { font-size: 15px; font-weight: 800; }
.ps-row .ps-pnl-pos { color: #22c55e; }
.ps-row .ps-pnl-neg { color: #ef4444; }
.ps-row .ps-pnl-open{ color: #ffffff; }
/* Header row: white UPPERCASE caps. #237 — enlarged from 10.5px so the column
   labels ("tabs") under the title are clearly legible. */
.ps-row-header .ps-col {
  color: #ffffff;
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}

/* ============================================================
   CHANGELOG_SERIAL.md #239 — TRANSACTION TAPE. Positions read like the OI Flow
   feed: one row per transaction, row text + left-border colored by action
   (inline style), strat dim, P&L green/red. 8 cols:
   strat | time | contract | action | qty | price | spot | p&l.
   ============================================================ */
.ps-tape-row {
  display: grid;
  /* #245 — time | strategy | side+qty | strike | price | spot | p&l | reason */
  grid-template-columns: 0.6fr 0.6fr 1.2fr 1.05fr 0.6fr 0.9fr 0.62fr 1.0fr;
  align-items: baseline;
  gap: 14px;
  padding: 9px 16px;
  border-left: 3px solid transparent;
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.025);
  font-size: 16px;           /* #240 — larger */
  line-height: 1.4;
}
.ps-tape-row + .ps-tape-row { margin-top: 3px; }
.ps-tape-strat {
  font-family: var(--sans); font-weight: 800; font-size: 12px;
  color: #c6cfdb; letter-spacing: 0.02em; text-transform: uppercase;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* #250 — short referenceable trade id next to the strategy name.
   #251 — sized to match the Reason text (13.5px). */
.ps-tape-id { color: #6b7585; font-weight: 600; font-size: 13.5px; font-family: var(--mono); text-transform: none; letter-spacing: 0; }

/* ============================================================
   CHANGELOG_SERIAL.md #252 — ONE ROW PER TRADE (entry+exit, keyed by ID).
   CHANGELOG_SERIAL.md #275 — 9 columns: time | strat | side×qty | contract |
   entry | exit | p&l | reason | id. Time-first / ID-last.
   ============================================================ */
.ps-trade-row {
  display: grid;
  /* CHANGELOG_SERIAL.md #307 — 12 cols: Strat Side Contract | EntryTime Entry BTC@Entry
     | ExitTime Exit BTC@Exit | P&L Reason ID (entry/exit each split into time/price/spot). */
  grid-template-columns: 0.6fr 0.72fr 1.0fr 0.85fr 0.55fr 0.85fr 0.85fr 0.55fr 0.85fr 0.55fr 1.0fr 74px;
  align-items: baseline;
  gap: 10px;
  padding: 9px 14px;
  border-left: 3px solid transparent;
  border-radius: 4px;
  background: rgba(255,255,255,0.025);
  font-size: 14px;
  line-height: 1.4;
}
.ps-trade-row + .ps-trade-row { margin-top: 3px; }
.ps-trade-row.ps-row-open { border-left-color: #4ade80; background: rgba(74,222,128,0.06); }
.ps-trade-row .ps-col {
  color: #e6edf5; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-variant-numeric: tabular-nums;
}
/* CHANGELOG_SERIAL.md #275 — ps-tr-time styled identically to ps-tr-id (same color + mono) */
.ps-tr-id, .ps-tr-time { color: #6b7585; font-family: var(--mono); font-size: 13px; font-weight: 600; }
.ps-tr-strat    { color: #22c55e; font-weight: 800; font-size: 13px; font-family: var(--sans); }
.ps-tr-side     { font-weight: 800; }
.ps-tr-side.ps-tr-yes { color: #22c55e; }
.ps-tr-side.ps-tr-no  { color: #ef4444; }
.ps-tr-contract { font-weight: 700; }
/* CHANGELOG_SERIAL.md #306 — Pete: entry/exit cells all on ONE line, same size +
   color. Price, time, and BTC spot now all inherit the cell's #e6edf5 / base size /
   normal weight (no white-bold price, no muted time, no small block spot). */
.ps-tr-entry b, .ps-tr-exit b { color: inherit; font-weight: inherit; }
.ps-tr-t        { color: inherit; font-size: inherit; font-weight: inherit; }
.ps-tr-spot     { display: inline; color: inherit; font-size: inherit; font-weight: inherit; margin-left: 6px; }
.ps-tr-open     { color: #8a93a3; font-style: italic; }
/* CHANGELOG_SERIAL.md #312 — settled-but-feed-stale open row reads "settling…" (muted, neutral). */
.ps-tr-settling { color: #b9912f; font-style: italic; opacity: 0.9; }
.ps-pnl-muted   { color: #8a93a3 !important; font-style: italic; font-weight: 400; }
.ps-tr-pnl      { font-weight: 800; }
.ps-tr-pnl.ps-pnl-pos { color: #22c55e; }
.ps-tr-pnl.ps-pnl-neg { color: #ef4444; }
.ps-tr-reason   {
  color: #7dd3fc; cursor: pointer; text-decoration: underline;
  text-decoration-style: dotted; text-underline-offset: 2px;
}
.ps-tr-reason:hover { color: #bae6fd; text-decoration-style: solid; }
.ps-trade-header { background: transparent; border-left-color: transparent; padding-bottom: 3px; }
.ps-trade-header .ps-col {
  color: #ffffff; font-family: var(--sans); font-size: 11px; font-weight: 800;
  text-transform: uppercase; letter-spacing: 0.04em; opacity: 0.72;
}
/* CHANGELOG_SERIAL.md #275 — 7-col tablet layout: keep Time + ID visible, hide Strat + Exit.
   DOM order after reorder: Time, Strat, Side, Contract, Entry, P&L, Reason, ID. */
@media (max-width: 767px) {
  .ps-trade-row { grid-template-columns: 64px 0.9fr 1fr 0.6fr 0.5fr 1fr 60px; gap: 8px; font-size: 13px; }
  .ps-trade-row .ps-tr-strat, .ps-trade-row .ps-tr-exit { display: none; }
}

/* ============================================================
   CHANGELOG_SERIAL.md #284 — OPEN-POSITION ROW (10 columns).
   CHANGELOG_SERIAL.md #286 — grid widths tuned for alignment; Reason is now
   a clickable link (ps-tr-reason reused); font-variant-numeric on all cells;
   header inlined by JS so no static DOM element needed.
   Time | Kind | Strike | Side | Qty | Entry | Current | Unreal P&L | Reason | Age.
   Separate from the closed-blotter .ps-trade-row.
   ============================================================ */
.ps-open-row {
  display: grid;
  /* CHANGELOG_SERIAL.md #308 — BTC @ Entry column added to open rows.
     Time  Kind  Strike  Side  Qty  Entry  BTC@Entry  Current  Unreal-P&L  Reason  Age */
  grid-template-columns: 76px 58px 112px 48px 38px 62px 84px 64px 90px 1fr 52px;
  align-items: baseline;
  gap: 10px;
  padding: 8px 14px;
  border-left: 3px solid #4ade80;
  border-radius: 4px;
  background: rgba(74,222,128,0.06);
  font-size: 14px;
  line-height: 1.4;
  list-style: none;
}
.ps-open-row + .ps-open-row { margin-top: 3px; }
/* Header row: transparent background, label styling */
.ps-open-header {
  background: transparent;
  border-left-color: transparent;
  padding-top: 4px;
  padding-bottom: 3px;
}
.ps-open-header .ps-ocol {
  color: #ffffff; font-family: var(--sans); font-size: 11px; font-weight: 800;
  text-transform: uppercase; letter-spacing: 0.04em; opacity: 0.72;
}
/* All open-row data cells share these base styles */
.ps-open-row .ps-ocol {
  color: #e6edf5; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-variant-numeric: tabular-nums;
}
/* Per-column styles */
.ps-or-time    { color: #6b7585; font-family: var(--mono); font-size: 13px; font-weight: 600; }
.ps-or-kind    { color: #94a3b8; font-size: 12px; font-weight: 700; letter-spacing: 0.02em; }
.ps-or-strike  { font-weight: 700; font-family: var(--mono); }
.ps-or-side    { font-weight: 800; }
.ps-or-side.ps-tr-yes { color: #22c55e; }
.ps-or-side.ps-tr-no  { color: #ef4444; }
.ps-or-qty     { color: #cbd5e1; font-weight: 700; font-family: var(--mono); }
.ps-or-entry   { color: #cbd5e1; font-family: var(--mono); }
.ps-or-current { color: #93c5fd; font-weight: 700; font-family: var(--mono); }
.ps-or-upnl    { font-weight: 800; font-family: var(--mono); }
.ps-or-upnl.ps-pnl-pos { color: #22c55e; }
.ps-or-upnl.ps-pnl-neg { color: #ef4444; }
/* Reason: styled as a clickable link (same as ps-tr-reason on closed rows).
   The ps-tr-reason class is also added in renderOpenRow() so the existing
   document-level click handler (openReasonDetail) fires without extra wiring. */
.ps-or-reason  {
  color: #7dd3fc; font-size: 13px;
  cursor: pointer; text-decoration: underline;
  text-decoration-style: dotted; text-underline-offset: 2px;
}
.ps-or-reason:hover { color: #bae6fd; text-decoration-style: solid; }
.ps-or-age     { color: #6b7585; font-size: 13px; font-family: var(--mono); }
/* #290 — today's-ET win-rate badge inside the Reason cell. Green >=67% (keeps
   trading under the gate), amber below. */
.ps-or-twr { font-family: var(--mono); font-size: 11px; font-weight: 700; padding: 0 4px;
             border-radius: 4px; white-space: nowrap; }
.ps-or-twr.ps-twr-good { color: #22c55e; background: rgba(34,197,94,0.12); }
.ps-or-twr.ps-twr-low  { color: #f59e0b; background: rgba(245,158,11,0.12); }
/* "Completed trades" divider above the closed blotter */
.ps-completed-divider {
  color: #94a3b8; font-size: 12px; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; padding: 8px 14px 4px;
  border-top: 1px solid rgba(148,163,184,0.18); margin-top: 6px;
  list-style: none;
}
/* Tablet (≤767px): hide Kind + Reason; re-declare 8-col grid for the 8 visible tracks.
   Visible order: Time | Strike | Side | Qty | Entry | Current | Unreal P&L | Age */
@media (max-width: 767px) {
  .ps-open-row {
    grid-template-columns: 64px 100px 44px 36px 58px 60px 80px 46px;
    gap: 8px; font-size: 13px;
  }
  .ps-open-row .ps-or-kind, .ps-open-row .ps-or-reason { display: none; }
}
/* Mobile (≤480px): also hide Current; 7-col grid for 7 visible tracks.
   Visible order: Time | Strike | Side | Qty | Entry | Unreal P&L | Age */
@media (max-width: 480px) {
  .ps-open-row {
    grid-template-columns: 58px 90px 40px 30px 54px 70px 42px;
    gap: 6px; font-size: 12px;
  }
  .ps-open-row .ps-or-kind,
  .ps-open-row .ps-or-reason,
  .ps-open-row .ps-or-current { display: none; }
}

.ps-tape-time     { font-variant-numeric: tabular-nums; font-weight: 700; }
/* #245 — side+qty (e.g. "Buy NO open ×10") + strike (kind+strike) + reason. */
.ps-tape-action   { font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ps-tape-strike   { font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ps-tape-reason   { color: #8a93a3 !important; font-weight: 600; font-size: 13.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* legacy cells (pre-#245) kept harmless if referenced elsewhere */
.ps-tape-contract { font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ps-tape-label    { font-weight: 700; white-space: nowrap; }
.ps-tape-size     { text-align: right; font-weight: 800; font-variant-numeric: tabular-nums; }
.ps-tape-price    { text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; }
.ps-tape-spot     { text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; opacity: 0.85; }
.ps-tape-pnl      { text-align: right; font-weight: 800; font-variant-numeric: tabular-nums; }
.ps-tape-pnl.ps-pnl-pos { color: #22c55e !important; }
.ps-tape-pnl.ps-pnl-neg { color: #ef4444 !important; }
/* #243 — setup/rule suffix on the action: dim, neutral (not the action color). */
.ps-tape-setup { color: #8a93a3 !important; font-weight: 600; font-size: 13px; }
/* CHANGELOG_SERIAL.md #276 — .ps-setup-select removed: styled #ps-setup-filter which
   was inside the dead #ps-filter-pop popover, deleted in #276. */
.positions-strip-meta .pnl-pos { color: #22c55e; font-weight: 700; }
.positions-strip-meta .pnl-neg { color: #ef4444; font-weight: 700; }

/* ============================================================
   CHANGELOG_SERIAL.md #244 — inline filter bar above the column header.
   Clean dark controls (color-scheme:dark fixes the white-on-white native
   dropdown), dim uppercase labels, green focus accent — house style.
   ============================================================ */
.ps-filterbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 16px;
  padding: 8px 2px 12px;
  margin: 0 0 6px;
  border-bottom: 1px solid var(--line);
}
.ps-fb-field { display: inline-flex; align-items: center; gap: 7px; }
.ps-fb-lbl {
  color: #8a93a3;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: 700;
  font-size: 10.5px;
  font-family: var(--sans);
  white-space: nowrap;
}
.ps-fb-select, .ps-fb-date, .ps-fb-time {
  color-scheme: dark;                       /* native popup/list renders dark */
  background: #161b22;
  color: #e6edf5;
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 5px 10px;
  font-size: 13px;
  font-weight: 600;
  font-family: var(--sans);
  cursor: pointer;
  transition: border-color 0.12s ease, background 0.12s ease;
}
.ps-fb-select:hover, .ps-fb-date:hover, .ps-fb-time:hover {
  background: #1c222c;
  border-color: rgba(255, 255, 255, 0.38);
}
.ps-fb-select:focus, .ps-fb-date:focus, .ps-fb-time:focus {
  outline: none;
  border-color: #22c55e;
  box-shadow: 0 0 0 2px rgba(34, 197, 94, 0.20);
}
.ps-fb-select option { background: #161b22; color: #e6edf5; }
.ps-fb-older { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.ps-fb-to { color: #8a93a3; font-size: 12px; }
/* CHANGELOG_SERIAL.md #276 — dead .ps-filter-wrap rule removed (HTML deleted in #276). */

/* ============================================================
   CHANGELOG_SERIAL.md #300 — two-axis filter bar components.
   Segmented status toggle, sub-pickers, reset button, summary bar + chips.
   ============================================================ */
/* Segmented status toggle container */
.ps-seg {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--line);
  border-radius: 7px;
  overflow: hidden;
}
/* Individual segment button */
.ps-seg-btn {
  background: #161b22;
  color: #8a93a3;
  border: none;
  border-right: 1px solid var(--line);
  padding: 5px 12px;
  font-size: 12px;
  font-weight: 600;
  font-family: var(--sans);
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
  white-space: nowrap;
  line-height: 1.4;
}
.ps-seg-btn:last-child { border-right: none; }
.ps-seg-btn:hover { background: #1c222c; color: #c6cfdb; }
/* Active segment — green accent matching the dashboard palette (green-500) */
.ps-seg-btn.is-active {
  background: rgba(34, 197, 94, 0.15);
  color: #22c55e;
}
/* Sub-picker spans (hour-wrap / day-wrap) — hidden by default via [hidden] attribute */
.ps-fb-sub {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-wrap: nowrap;
}
/* CHANGELOG_SERIAL.md #303 — BUG FIX: the display rules above (and on .ps-fb-field
   / .ps-fb-reset / .ps-fb-summary) override the HTML `hidden` attribute, so the
   hour + day sub-pickers showed even on When=Recent (two stray "12:00 AM ET"
   dropdowns + a date box), and changing them did nothing. Make `hidden` win. */
.ps-fb-sub[hidden],
.ps-fb-field[hidden],
.ps-fb-reset[hidden],
.ps-fb-summary[hidden] { display: none !important; }
/* Reset button */
.ps-fb-reset {
  background: rgba(239, 68, 68, 0.08);
  color: #ef4444;
  border: 1px solid rgba(239, 68, 68, 0.30);
  border-radius: 6px;
  padding: 5px 10px;
  font-size: 12px;
  font-weight: 600;
  font-family: var(--sans);
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
  white-space: nowrap;
}
.ps-fb-reset:hover {
  background: rgba(239, 68, 68, 0.18);
  border-color: rgba(239, 68, 68, 0.60);
}
/* Summary bar — one line below the filter bar */
.ps-fb-summary {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  padding: 6px 2px 8px;
  font-size: 12px;
  color: #8a93a3;
  border-bottom: 1px solid var(--line);
  margin-bottom: 4px;
}
/* Summary total count */
.ps-fb-total {
  font-weight: 600;
  color: #c6cfdb;
  margin-right: 2px;
}
/* Filter chips on the summary bar */
.ps-fb-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: rgba(125, 211, 252, 0.10);
  border: 1px solid rgba(125, 211, 252, 0.25);
  border-radius: 12px;
  padding: 2px 8px 2px 10px;
  font-size: 11.5px;
  font-weight: 600;
  color: #7dd3fc;
  white-space: nowrap;
}
/* Chip remove button */
.ps-chip-x {
  background: none;
  border: none;
  color: #7dd3fc;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  padding: 0 0 0 2px;
  opacity: 0.7;
  transition: opacity 0.12s;
}
.ps-chip-x:hover { opacity: 1; }
/* Inline clear-filters button inside empty placeholder */
.ps-inline-clear {
  background: none;
  border: none;
  color: #7dd3fc;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  text-decoration: underline;
  text-decoration-style: dotted;
  text-underline-offset: 2px;
  padding: 0;
  font-family: var(--sans);
}
.ps-inline-clear:hover { color: #bae6fd; text-decoration-style: solid; }
/* Empty state when filters are active — slightly dimmer than the default placeholder */
.ps-row-filtered-empty { color: #8a93a3 !important; font-style: italic; }

/* ============================================================
   CHANGELOG_SERIAL.md #246 — Reason drill-down modal (setup track record).
   ============================================================ */
/* Reason renders as a hyperlink (#247) — click to open the inline stats section. */
.ps-tape-reason {
  color: #7dd3fc !important;          /* sky-300 link */
  cursor: pointer;
  text-decoration: underline;
  text-decoration-style: dotted;
  text-underline-offset: 2px;
}
.ps-tape-reason:hover { color: #bae6fd !important; text-decoration-style: solid; }
/* #247 — inline track-record section (NOT a popup). Full-width card below the top row. */
.ps-reason-section {
  display: flex;
  flex-direction: column;
  background: rgba(255, 255, 255, 0.02);
  border: 1px solid var(--line);
  border-radius: 10px;
  margin: 8px auto 10px;
  overflow: hidden;
  scroll-margin-top: 120px;            /* clear the sticky header when scrolled to */
}
/* CHANGELOG_SERIAL.md #287 — the display:flex above beats the UA [hidden]{display:none}
   (author rule wins), so the Setup-track-record panel showed its empty "—" shell by
   default AND the × Close (which sets hidden=true) couldn't hide it. Same fix as #268. */
.ps-reason-section[hidden] { display: none !important; }
.ps-reason-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  padding: 16px 18px 12px; border-bottom: 1px solid var(--line);
}
.ps-reason-title { margin: 0; font-size: 19px; font-weight: 800; color: #fff; }
.ps-reason-sub { font-size: 12px; color: #8a93a3; margin-top: 2px; }
.ps-reason-close {
  background: rgba(255,255,255,0.05); border: 1px solid var(--line); color: #c6cfdb;
  font-size: 12px; font-weight: 600; line-height: 1; border-radius: 6px;
  cursor: pointer; padding: 6px 10px; white-space: nowrap; transition: background 0.12s, color 0.12s;
}
.ps-reason-close:hover { color: #fff; background: rgba(255,255,255,0.12); }
.ps-reason-stats {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px;
  padding: 14px 18px; border-bottom: 1px solid var(--line);
}
.ps-reason-stat { display: flex; flex-direction: column; gap: 3px; }
.ps-reason-stat-lbl { font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.05em; color: #8a93a3; font-weight: 700; }
.ps-reason-stat-val { font-size: 17px; font-weight: 800; color: #e6edf5; font-variant-numeric: tabular-nums; }
.ps-reason-stat-val.pnl-pos { color: #22c55e; }
.ps-reason-stat-val.pnl-neg { color: #ef4444; }
.ps-reason-loading { color: #8a93a3; font-size: 13px; }
.ps-reason-list-head, .ps-reason-row {
  display: grid; grid-template-columns: 1.5fr 0.5fr 1.2fr 0.8fr 0.8fr 0.8fr;
  gap: 10px; align-items: baseline; padding: 6px 18px;
}
.ps-reason-list-head {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.04em; color: #8a93a3;
  font-weight: 800; border-bottom: 1px solid var(--line);
}
.ps-reason-list-head span:nth-child(n+4) { text-align: right; }
.ps-reason-list { list-style: none; margin: 0; padding: 4px 0; overflow-y: auto; max-height: 440px; }
.ps-reason-row { font-size: 13.5px; color: #d7deea; border-bottom: 1px solid rgba(255,255,255,0.04); }
.ps-reason-row span:nth-child(n+4) { text-align: right; font-variant-numeric: tabular-nums; }
.ps-reason-row .pnl-pos { color: #22c55e; font-weight: 700; }
.ps-reason-row .pnl-neg { color: #ef4444; font-weight: 700; }
.ps-reason-row .ps-dir-yes { color: #22c55e; font-weight: 800; }
.ps-reason-row .ps-dir-no  { color: #ef4444; font-weight: 800; }
.ps-reason-empty { padding: 18px; color: #8a93a3; font-size: 13px; text-align: center; }
.ps-reason-foot { padding: 9px 18px; border-top: 1px solid var(--line); font-size: 11px; color: #8a93a3; }

/* CHANGELOG_SERIAL.md #254 — per-EMA-regime folder breakdown inside the Reason drill-down. */
.ps-reason-folders { border-top: 1px solid var(--line); }
.ps-folders-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; padding: 11px 18px 6px; flex-wrap: wrap;
}
.ps-folders-title { font-size: 12px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.04em; color: #e6edf5; }
.ps-folders-regime { font-size: 12px; color: #8a93a3; }
.ps-folders-list-head, .ps-folder-row {
  display: grid; grid-template-columns: 1fr 1fr 1.1fr 1fr; gap: 10px;
  padding: 6px 18px; align-items: center;
}
.ps-folders-list-head { font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.04em; color: #8a93a3; border-bottom: 1px solid var(--line); }
.ps-folders-list { list-style: none; margin: 0; padding: 0; }
.ps-folder-row { font-size: 13px; border-bottom: 1px solid rgba(255,255,255,0.04); }
.ps-folder-row.ps-folder-cur { background: rgba(125,211,252,0.08); }
.ps-folder-cur > span:first-child b { color: #7dd3fc; }
.ps-folder-live { color: #cbd5e1; }
.ps-trend-mixed { color: #d4a72c; }

/* CHANGELOG_SERIAL.md #256 — per-trade readout panel. */
.ps-trade-section { margin-top: 14px; border: 1px solid var(--line); border-radius: 10px; background: var(--card, rgba(255,255,255,0.02)); overflow: hidden; }
.ps-trade-badge { font-size: 11px; font-weight: 800; padding: 2px 8px; border-radius: 999px; vertical-align: middle; margin-left: 8px; letter-spacing: 0.04em; }
.ps-badge-open { background: rgba(74,222,128,0.16); color: #4ade80; }
.ps-badge-closed { background: rgba(148,163,184,0.16); color: #cbd5e1; }
.ps-trade-facts {
  display: grid; grid-template-columns: repeat(2, minmax(0,1fr));
  gap: 2px 22px; padding: 12px 18px;
}
.ps-tf-row { display: flex; justify-content: space-between; gap: 12px; padding: 6px 0; border-bottom: 1px solid rgba(255,255,255,0.04); font-size: 13.5px; }
.ps-tf-lbl { color: #8a93a3; }
.ps-tf-val { color: #e6edf5; text-align: right; font-variant-numeric: tabular-nums; }
.ps-tf-val b { color: #fff; }
.ps-tf-sub { color: #8a93a3; font-size: 12px; }
.ps-trade-context { padding: 4px 18px 14px; }
.ps-tc-block { padding: 10px 0; border-top: 1px solid var(--line); }
.ps-tc-head { font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.04em; color: #e6edf5; margin-bottom: 7px; }
.ps-tc-folder { color: #7dd3fc; font-size: 12px; text-transform: none; letter-spacing: 0; }
.ps-tc-chips { display: flex; flex-wrap: wrap; gap: 10px; }
.ps-tc-chip { font-size: 13px; }
.ps-tc-tf { color: #8a93a3; font-size: 11px; }
.ps-tc-sub { margin-top: 6px; font-size: 12px; color: #8a93a3; }
.ps-tc-stats { display: flex; flex-wrap: wrap; gap: 8px 20px; align-items: baseline; font-size: 13px; }
.ps-tc-stat { color: #cbd5e1; }
.ps-tc-stat b { color: #fff; font-weight: 700; }
.ps-tc-na { color: #8a93a3; font-style: italic; font-size: 12.5px; }
.ps-tc-loading { color: #8a93a3; font-size: 12.5px; padding: 8px 0; }
.ps-tr-id-link { cursor: pointer; }
.ps-tr-id-link:hover { color: #7dd3fc; text-decoration: underline; text-decoration-style: dotted; text-underline-offset: 2px; }
@media (max-width: 560px) {
  .ps-trade-facts { grid-template-columns: 1fr; gap: 0 0; }
}
@media (max-width: 560px) {
  .ps-folders-list-head, .ps-folder-row { grid-template-columns: 0.9fr 0.9fr 1fr 0.8fr; gap: 6px; font-size: 12px; }
  .ps-reason-stats { grid-template-columns: repeat(2, 1fr); }
  .ps-reason-list-head, .ps-reason-row { grid-template-columns: 1.3fr 0.4fr 1fr 0.7fr; }
  .ps-reason-list-head span:nth-child(5), .ps-reason-list-head span:nth-child(6),
  .ps-reason-row span:nth-child(5), .ps-reason-row span:nth-child(6) { display: none; }
}
.ps-tape-openflag {
  color: #8a93a3 !important; font-weight: 600; font-size: 12px;
  text-transform: uppercase; letter-spacing: 0.05em;
}
/* Header: white caps, no action color, transparent. */
.ps-tape-header {
  background: transparent;
  border-left-color: transparent;
  padding-bottom: 3px;
}
.ps-tape-header span {
  color: #ffffff;
  font-family: var(--sans);
  font-size: 11.5px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  opacity: 0.72;
}

/* --- blotter id cell (col 1): strat name stacked over serial --- */
.ps-col-id {
  display: flex;
  flex-direction: column;
  line-height: 1.15;
  overflow: hidden;
}
.ps-blot-strat {
  font-family: var(--sans);
  font-size: 12.5px;
  font-weight: 800;
  letter-spacing: 0.01em;
  color: #22c55e;                /* green-500 — matches .ps-strategy */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ps-blot-serial {
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 400;
  color: #5a6478;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* Tuning badge: compact amber "T" chip */
.ps-tuning-tag {
  display: inline-block;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.05em;
  color: #f59e0b;
  border: 1px solid #f59e0b;
  border-radius: 3px;
  padding: 0 3px;
  margin-left: 3px;
  vertical-align: middle;
  line-height: 1.4;
  text-transform: uppercase;
}

/* --- blotter contract cell (col 2): "60m · $62,000" --- */
.ps-col-contract {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.ps-blot-kind {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #64748b;                /* slate-500 — muted label */
  font-variant-numeric: tabular-nums;
}
.ps-blot-dot { color: #3a4255; }
.ps-blot-strike {
  font-family: var(--mono);
  font-size: 16px;               /* #233 — hero strike */
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: #e2e8f0;                /* near-white */
  letter-spacing: 0.01em;
}

/* --- blotter direction chip (col 3) --- */
.ps-col-dir { text-align: center; }
.ps-blot-dir {
  display: inline-block;
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.04em;
  padding: 2px 5px;
  border-radius: 4px;
  line-height: 1.3;
}
/* CHANGELOG_SERIAL.md #229 — direction chips: colored again (YES green / NO red)
   on a very subtle tinted bg. The contract descriptor col carries the neutral
   strike text; the chip is allowed to carry direction color since it's compact. */
.ps-dir-yes {
  color: rgb(34, 197, 94);       /* green-500 */
  background: rgba(34, 197, 94, 0.10);
}
.ps-dir-no {
  color: rgb(239, 68, 68);       /* red-500 */
  background: rgba(239, 68, 68, 0.10);
}

/* --- blotter qty cell (col 4) --- */
.ps-col-qty { text-align: center; }
.ps-blot-qty {
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: #8a93a3;
}

/* --- blotter entry/exit cells (cols 5–6): two-line fill price + sub-line --- */
.ps-col-entry,
.ps-col-exit {
  display: flex;
  flex-direction: column;
  line-height: 1.15;
  overflow: hidden;
  min-width: 0;
}
/* Hero line: contract fill price (bold, sky-blue mono) */
.ps-blot-fill {
  font-family: var(--mono);
  font-size: 16px;               /* #233 — hero fill price */
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: #7dd3fc;                /* sky-300 — matches FRONTEND_CONVENTIONS squeeze tint */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Open position fill line: dimmer (position not yet closed) */
.ps-blot-fill-open {
  color: #4ade80;                /* green-400 — echoes open-row left-border */
  font-weight: 600;
}
/* "mid" badge beside the live mid-market price */
.ps-blot-mid-tag {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: #4ade80;
  vertical-align: middle;
  margin-left: 3px;
}
/* Sub-line: dim "spot · HH:MM" */
.ps-blot-sub {
  font-family: var(--mono);
  font-size: 11.5px;
  font-weight: 400;
  font-variant-numeric: tabular-nums;
  color: #5a6478;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-top: 1px;
}
.ps-blot-sub-open { color: #3a4255; }
/* Timestamp line (entry/exit) — its own row so HH:MM:SS is never clipped;
   slightly brighter than the spot sub so the time reads clearly. #232 */
.ps-blot-time {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: #94a3b8;                /* slate-400 — readable, still secondary */
  white-space: nowrap;
  margin-top: 1px;
}

/* --- blotter p&l cell (col 7) --- */
.ps-col-pnl { text-align: right; }

/* Legacy flat-cell value styles — kept in case other code paths reference them. */
.ps-type-num { font-variant-numeric: tabular-nums; color: #8a93a3; font-weight: 700; }
.ps-spot-val { font-variant-numeric: tabular-nums; color: #d7deea; }
.ps-spot-open { color: #5a6478; }
.ps-time-val { font-variant-numeric: tabular-nums; color: #aeb6c4; font-size: 13.5px; }

/* Legacy two-line time/spot cell styles (kept for fmtTimeSpotHtml callers) */
.ps-col-timespot {
  display: flex;
  flex-direction: column;
  line-height: 1.1;
  white-space: nowrap;
  overflow: hidden;
}
.ps-ts-time {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-size: 13.5px;
  color: #d7deea;
}
.ps-ts-spot {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  color: #8a93a3;
}
/* CHANGELOG_SERIAL.md #224 — contract price next to the timestamp (legacy path). */
.ps-ts-price {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  font-weight: 700;
  color: #93c5fd;
  margin-left: 5px;
}
.ps-row-open  { background: rgba(74, 222, 128, 0.08); border-left-color: #4ade80; }
.ps-row-close { background: rgba(255, 255, 255, 0.04); border-left-color: rgba(255, 255, 255, 0.18); }

/* CHANGELOG_SERIAL.md #145/#146 — column header row. */
.ps-row-header {
  background: transparent;
  border-left-color: transparent;
  border-bottom: 1px solid rgba(255, 255, 255, 0.10);
  margin-bottom: 2px;
  padding-bottom: 5px;
}

/* Header cell label: small uppercase, muted. */
.ps-col-hdr {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: #5a6478;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: default;
}

/* Serial — dim, very small mono. */
.ps-col-serial {
  color: #5a6478;
  font-size: 11px;
  letter-spacing: 0.04em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Date+time — compact two-line-in-one mono. */
.ps-col-datetime {
  color: #c6cfdb;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* CHANGELOG_SERIAL.md #176 — date + time are now separate spans. On desktop
   they sit inline (identical to the old "MM/DD  HH:MM:SS" string); the phone
   breakpoint below stacks them so the time can't be clipped. */
.ps-dt-date { color: inherit; }
.ps-dt-time { font-variant-numeric: tabular-nums; }

/* Strike — includes the kind tag sub-label. */
.ps-col-strike {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: #e8edf4;
  font-family: var(--mono);
}

/* Kind tag (binary / hourly) beside the strike price. */
.ps-kind-tag {
  display: inline;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: #22c55e;            /* #209 binary/hourly in bold green-500 (was grey #5a6478) */
  font-family: var(--sans);
  margin-left: 4px;
}

/* CHANGELOG_SERIAL.md #162 — account badge (Auto Trader / Leo) beside the
   serial. Mirrors .ps-kind-tag sizing; a subtle per-account tint distinguishes
   the two shadow paper books in the merged feed. */
.ps-acct-tag {
  display: inline-block;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-family: var(--sans);
  padding: 1px 5px;
  border-radius: 999px;
  margin-left: 4px;
  vertical-align: middle;
}
.ps-acct-auto {
  color: #8b94a6;
  background: rgba(139, 148, 166, 0.12);
}
.ps-acct-leo {
  color: rgb(96, 165, 250);                 /* blue-400 */
  background: rgba(96, 165, 250, 0.14);
}

/* CHANGELOG_SERIAL.md #164 — Strategy column. First column now names the
   strategy/account that placed each trade ("Leo" | "app") in green bold so the
   two separate paper books are obvious in the merged feed. */
.ps-strategy {
  color: #22c55e;                /* green-500 — pops on both themes */
  font-weight: 800;
  font-family: var(--sans);
  letter-spacing: 0.01em;
}

/* CHANGELOG_SERIAL.md #172 — strategy filter dropdown in the Recent Positions
   header. Lets Pete pick which paper accounts (All / app / LeoDog / Leo)
   populate the feed; choice persists in localStorage. Sits inline with the
   title + meta. */
.ps-strategy-filter-label {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  margin-left: 0.75em;
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--text-muted);
}
.ps-strategy-filter-text {
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 0.7rem;
}
.ps-strategy-filter {
  font-family: var(--sans);
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--text);
  background: rgba(148, 163, 184, 0.12);
  border: 1px solid rgba(148, 163, 184, 0.28);
  border-radius: 6px;
  padding: 0.18em 0.5em;
  cursor: pointer;
  line-height: 1.3;
}
/* CHANGELOG_SERIAL.md #185 — the dropdown <option> items rendered black-on-black:
   the select's translucent bg does NOT apply to the native option list, so options
   fell back to the OS default. Force a SOLID, theme-aware color on the options. */
.ps-strategy-filter option {
  background-color: var(--bg, #0e1320);
  color: var(--text, #e8edf4);
}
.ps-strategy-filter:hover { border-color: rgba(148, 163, 184, 0.5); }
.ps-strategy-filter:focus-visible {
  outline: 2px solid #22c55e;
  outline-offset: 1px;
}
.ps-serial-sub {
  color: var(--text-muted);
  font-size: 9px;
  opacity: 0.7;
}

/* Direction phrase — BUY YES ↑ higher / BUY NO ↓ lower. */
.ps-col-dir {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ps-dir {
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
}
/* CHANGELOG_SERIAL.md #165 — UX polish P1 — direction column softened to
   neutral text so the tape no longer reads "RED RED RED" top-to-bottom; the
   % return (.ps-col-pnl, unchanged) is now the row's loudest signal. The
   up/down glyph (↑/↓) still encodes direction by shape. NOTE: the glyph is
   inline in the same span as the phrase (positions_strip.js), and that file
   is out of scope for this frontend-only pass, so the arrow is neutral too
   rather than a subdued red-400/green-400 — direction stays scannable. The
   .ps-dir-yes/.ps-dir-no classes are kept (still emitted by the JS) but now
   resolve to the default text color. .ps-strategy (the #164 green book name)
   is untouched. */
.ps-dir-yes { color: var(--text); }
.ps-dir-no  { color: var(--text); }

/* CHANGELOG_SERIAL.md #229 — blotter column alignment. Entry/exit/pnl
   right-aligned; dir/qty centered; id/contract left-aligned (default). */
.ps-col-entry,
.ps-col-exit,
.ps-col-pnl { text-align: right; font-size: 16px; }   /* #233 — hero P&L */
.ps-col-dir,
.ps-col-qty { text-align: center; }
/* Legacy flat-col alignment kept for any external references. */
.ps-col-espot,
.ps-col-xspot,
.ps-col-etime,
.ps-col-xtime { text-align: right; }
.ps-col-type  { text-align: center; }

.ps-mono-r {
  font-family: var(--mono);
  color: #c6cfdb;
}

/* Dim "open" placeholder in exit col while position is live. */
.ps-exit-open {
  color: #5a6478;
  font-style: italic;
  font-size: 11.5px;
}

.ps-pnl-pos { color: rgb(34, 197, 94);  font-weight: 800; }   /* green-500 */
.ps-pnl-neg { color: rgb(239, 68, 68);  font-weight: 800; }   /* red-500   */
.ps-pnl-open { color: #c6cfdb; }

/* Keep pills for any other use in the page; header row no longer uses them. */
.ps-pill {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-family: var(--sans);
}
.ps-pill-open  { background: rgba(74, 222, 128, 0.22); color: #6ee7b7; }
.ps-pill-close { background: rgba(255, 255, 255, 0.12); color: #c6cfdb; }
.ps-pill-kind  { background: rgba(96, 165, 250, 0.18); color: #93c5fd; }
.ps-pill-side.ps-side-yes { background: rgba(74, 222, 128, 0.22); color: #6ee7b7; }
.ps-pill-side.ps-side-no  { background: rgba(248, 113, 113, 0.22); color: #fca5a5; }

.positions-strip-footer {
  display: flex;
  justify-content: flex-end;
  margin-top: 6px;
}
.ps-history-link {
  font-size: 12px;
  color: #8a93a3;
  text-decoration: none;
  letter-spacing: 0.04em;
}
.ps-history-link:hover { color: #fff; }

/* CHANGELOG_SERIAL.md #210 — collapsed/expanded strip toggle button. */
.ps-strip-toggle {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 10px;
  border-radius: 6px;
  border: 1px solid rgba(255, 255, 255, 0.22);
  background: rgba(255, 255, 255, 0.05);
  color: #c6cfdb;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  cursor: pointer;
  font-family: var(--sans);
  transition: background 80ms ease, border-color 80ms ease;
  white-space: nowrap;
}
.ps-strip-toggle:hover {
  background: rgba(255, 255, 255, 0.11);
  border-color: rgba(255, 255, 255, 0.42);
}
.ps-strip-toggle:focus {
  outline: 2px solid rgba(96, 165, 250, 0.80);
  outline-offset: 1px;
}

/* CHANGELOG_SERIAL.md #210 — expanded panel: scrollable container. */
.ps-expand-panel {
  max-height: 50vh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;   /* momentum scroll on iOS */
  overscroll-behavior: contain;
  margin-top: 4px;
  border-radius: 4px;
  /* Thin scrollbar on Webkit */
  scrollbar-width: thin;
  scrollbar-color: rgba(255,255,255,0.18) transparent;
}
.ps-expand-panel::-webkit-scrollbar { width: 6px; }
.ps-expand-panel::-webkit-scrollbar-track { background: transparent; }
.ps-expand-panel::-webkit-scrollbar-thumb {
  background: rgba(255,255,255,0.18);
  border-radius: 3px;
}
.ps-expand-panel[hidden] { display: none; }

/* Inner list inside the expanded panel. */
.ps-expanded-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

/* CHANGELOG_SERIAL.md #210 — sticky day/open dividers. */
.ps-day-divider {
  position: sticky;
  top: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 4px 12px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  background: rgba(14, 19, 32, 0.95);   /* matches --bg approx; opaque for sticky */
  border-bottom: 1px solid rgba(255,255,255,0.09);
  color: #8a93a3;
  margin-top: 4px;
}
.ps-open-divider {
  color: #4ade80;   /* green-400 — matches ps-row-open border */
  border-bottom-color: rgba(74, 222, 128, 0.20);
}
.ps-day-label { flex: 1; }
.ps-day-pnl {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
}
.ps-day-pnl-pos { color: #22c55e; }   /* green-500 */
.ps-day-pnl-neg { color: #ef4444; }   /* red-500  */

/* CHANGELOG_SERIAL.md #234 — tablet (<=767px): drop id, qty, the $ price cols.
   7 visible: contract | side | entry spot | exit spot | entry time | exit time | pnl */
@media (max-width: 767px) {
  .ps-row {
    grid-template-columns: minmax(80px,1.2fr) 26px 58px 58px 64px 64px 52px;
    gap: 6px;
    font-size: 12.5px;
  }
  .ps-col-id, .ps-col-qty, .ps-col-eprice, .ps-col-xprice { display: none; }
}

/* CHANGELOG_SERIAL.md #234 — phone (<=480px): keep just the essentials.
   5 visible: contract | side | entry time | exit time | pnl */
@media (max-width: 480px) {
  .positions-strip-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
  }
  .positions-strip-stats { width: 100%; justify-content: space-between; }
  .ps-row {
    grid-template-columns: minmax(72px,1.3fr) 26px 64px 64px 50px;
    font-size: 12px;
    gap: 6px;
    padding: 6px 8px;
  }
  .ps-col-id, .ps-col-qty, .ps-col-eprice, .ps-col-xprice,
  .ps-col-espot, .ps-col-xspot { display: none; }
  .ps-blot-strike { font-size: 12px; }
  .ps-blot-fill { font-size: 12.5px; }
  .ps-blot-sub { font-size: 10.5px; }
  .ps-pill { font-size: 9.5px; padding: 1px 6px; }
  /* #170 — value-prop hero: tighten for phone portrait. */
  .aq-hero-title { font-size: 23px; }
  .aq-hero-sub { font-size: 14px; }
  .aq-hero-cta .aq-hero-btn { flex: 1 1 auto; justify-content: center; }
  /* CHANGELOG_SERIAL.md #210 — mobile: expand panel fills available vertical
     space; momentum scroll already set via -webkit-overflow-scrolling: touch. */
  .ps-expand-panel { max-height: 60vh; }
}

/* ----- Export modal (#112) ----- */
.ps-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(8, 12, 22, 0.62);
  z-index: 9000;
}
.ps-modal {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9010;
  padding: 16px;
}
.ps-modal[hidden], .ps-modal-backdrop[hidden] { display: none; }
.ps-modal-inner {
  background: var(--bg-card, #0f1626);
  color: var(--text, #e8edf3);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 10px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.55);
  width: 100%;
  max-width: 460px;
  padding: 18px 22px 16px;
  font-family: var(--sans);
}
.ps-modal-title {
  margin: 0 0 12px;
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 0.04em;
  border-bottom: 1px solid rgba(255, 255, 255, 0.10);
  padding-bottom: 8px;
}
.ps-modal-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
}
.ps-modal-label {
  font-size: 12px;
  color: #b8c2d0;
  min-width: 78px;
}
.ps-modal-date {
  flex: 1;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 6px;
  color: #fff;
  padding: 6px 8px;
  font-family: var(--mono);
  font-size: 13px;
}
/* CHANGELOG_SERIAL.md #173 — Account selector (App / Leo / LeoDog) in export. */
.ps-export-accts { align-items: flex-start; }
.ps-acct-checks { display: flex; flex-wrap: wrap; gap: 14px; flex: 1; }
.ps-acct-check {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: #d6dde7;
  cursor: pointer;
  user-select: none;
}
.ps-acct-check input { cursor: pointer; accent-color: rgb(34, 197, 94); }
.ps-acct-check input:disabled { cursor: not-allowed; }
.ps-acct-check input:disabled + span { color: #5a6478; text-decoration: line-through; }

.ps-modal-quick {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  align-items: center;
  margin-top: 4px;
  margin-bottom: 12px;
}
.ps-modal-quick-label { font-size: 12px; color: #8a93a3; margin-right: 4px; }
.ps-quick-chip {
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.22);
  background: rgba(255, 255, 255, 0.04);
  color: #c6cfdb;
  font-size: 11.5px;
  font-weight: 600;
  cursor: pointer;
  font-family: var(--sans);
}
.ps-quick-chip:hover {
  background: rgba(255, 255, 255, 0.10);
  border-color: rgba(255, 255, 255, 0.45);
}
.ps-modal-status {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 12px;
  color: #b8c2d0;
  margin-bottom: 14px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  padding-top: 8px;
}
.ps-modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}
.ps-modal-cancel,
.ps-modal-confirm {
  padding: 6px 14px;
  border-radius: 6px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  font-family: var(--sans);
  border: 1px solid transparent;
}
.ps-modal-cancel {
  background: transparent;
  color: #c6cfdb;
  border-color: rgba(255, 255, 255, 0.22);
}
.ps-modal-cancel:hover { background: rgba(255, 255, 255, 0.06); }
.ps-modal-confirm {
  background: rgba(96, 165, 250, 0.30);
  color: #fff;
  border-color: rgba(96, 165, 250, 0.65);
}
.ps-modal-confirm:hover:not(:disabled) {
  background: rgba(96, 165, 250, 0.45);
  border-color: rgba(96, 165, 250, 0.85);
}
.ps-modal-confirm:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}
body.ps-modal-open { overflow: hidden; }

/* ============================================================
   CHANGELOG_SERIAL.md #093 — Site header v2: brand block + search
   trigger + live pill + icon actions + status strip.
   Preserves sticky positioning and z-index=110 from old header.
   ============================================================ */
.site-header {
  background: var(--bg-card);
  border-bottom: 2px solid var(--line-strong);
  position: sticky;
  top: 0;
  z-index: 110;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.18);
}

/* Keep old .header-row class alive in case any JS references it */
.header-row { display: contents; }

/* CHANGELOG_SERIAL.md #230 — compact header: tighten main row + status strip heights */
/* v2 main row */
.hdr-main-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 4px 12px;
  min-height: 44px;
}

/* Brand block: logo + wordmark + tagline */
.hdr-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: var(--text);
  flex-shrink: 0;
}
/* CHANGELOG_SERIAL.md #230 — shrink logo from 38->30px to match tighter row */
.hdr-logo {
  width: 30px;
  height: 30px;
  border-radius: 8px;
  /* currentColor drives SVG fill — inherit from .hdr-brand */
  color: #0052cc;
  flex-shrink: 0;
}
[data-theme="dark"] .hdr-logo { color: #4ea1ff; }
.hdr-wordmark-wrap {
  display: flex;
  flex-direction: column;
  gap: 1px;
  line-height: 1.1;
}
/* CHANGELOG_SERIAL.md #230 — trim wordmark 18->16px; tagline hidden by default to save row */
.hdr-wordmark {
  font-family: var(--sans);
  font-size: 16px;
  font-weight: 800;
  letter-spacing: -0.015em;
  background: linear-gradient(135deg, #4f9bff 0%, #34d399 50%, #a78bfa 100%);
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
          color: transparent;
}
.hdr-tagline {
  font-size: 10px;
  font-weight: 500;
  color: var(--text-muted);
  white-space: nowrap;
  letter-spacing: 0.01em;
  display: none;
}

/* Search trigger — flex-fill between brand and actions */
.hdr-search-trigger {
  flex: 1 1 auto;
  min-width: 0;
  max-width: 480px;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  border: 1px solid var(--btn-border);
  border-radius: 8px;
  background: var(--bg-table-alt);
  color: var(--text-muted);
  font-family: var(--sans);
  font-size: 13px;
  cursor: pointer;
  transition: border-color 0.12s, background 0.12s;
  text-align: left;
  margin: 0 8px;
}
.hdr-search-trigger:hover {
  border-color: var(--btn-border-strong);
  background: var(--bg);
  color: var(--text);
}
.hdr-search-icon { flex-shrink: 0; }
.hdr-search-label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hdr-search-kbd {
  flex-shrink: 0;
  font-family: var(--mono);
  font-size: 11px;
  padding: 2px 5px;
  border: 1px solid var(--btn-border);
  border-radius: 4px;
  background: var(--bg-card);
  color: var(--text-muted);
  line-height: 1.4;
}

/* Action area: live pill + icon buttons */
.hdr-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}

/* CHANGELOG_SERIAL.md #120 - EST clock in header. Tabular numerals so the
   seconds don't jitter the date underneath. Stacks date on top of time at
   narrow widths; collapses to time-only at ≤767px. */
.hdr-clock {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  padding: 0 4px;
  margin-right: 4px;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
  font-feature-settings: "tnum";
}
.hdr-clock-time {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  letter-spacing: 0.02em;
}
.hdr-clock-date {
  font-size: 10px;
  font-weight: 500;
  color: var(--text-muted);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  margin-top: 1px;
}
@media (max-width: 767px) {
  .hdr-clock-date {
    display: none;
  }
  .hdr-clock-time {
    font-size: 12px;
  }
}

/* Live status pill */
.hdr-live-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 9px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  border: 1px solid transparent;
  white-space: nowrap;
  /* Default: live (green) */
  background: rgba(34, 197, 94, 0.14);
  border-color: rgba(34, 197, 94, 0.40);
  color: #15803d;
}
[data-theme="dark"] .hdr-live-pill {
  color: #22c55e;
}
.hdr-live-pill[data-state="reconnecting"] {
  background: rgba(250, 204, 21, 0.14);
  border-color: rgba(250, 204, 21, 0.40);
  color: #b45309;
}
[data-theme="dark"] .hdr-live-pill[data-state="reconnecting"] {
  color: #facc15;
}
.hdr-live-pill[data-state="offline"] {
  background: rgba(239, 68, 68, 0.14);
  border-color: rgba(239, 68, 68, 0.40);
  color: #b91c1c;
}
[data-theme="dark"] .hdr-live-pill[data-state="offline"] {
  color: #ef4444;
}
.hdr-live-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #22c55e;
  flex-shrink: 0;
}
.hdr-live-pill[data-state="reconnecting"] .hdr-live-dot { background: #facc15; }
.hdr-live-pill[data-state="offline"] .hdr-live-dot { background: #ef4444; }

/* CHANGELOG_SERIAL.md #230 — compact icon buttons 34->30px to match tighter row */
/* Shared icon button style for header icons */
.hdr-icon-btn {
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 7px;
  border: 1.5px solid var(--btn-border-strong);
  background: var(--bg-card);
  color: var(--text);
  cursor: pointer;
  text-decoration: none;
  font-size: 14px;
  transition: background 0.12s, border-color 0.12s;
  flex-shrink: 0;
}
.hdr-icon-btn:hover {
  background: var(--bg-table-alt);
  border-color: var(--text);
}
/* theme-toggle already has its own sizing from #025 — keep that but apply hdr-icon-btn border */
.theme-toggle.hdr-icon-btn { margin-left: 0; }

/* CHANGELOG_SERIAL.md #262 — persistent header Sign in / Account control.
   CHANGELOG_SERIAL.md #230 — tighten padding; add [hidden] override so the
   HTML hidden attribute correctly suppresses display:inline-flex elements. */
.hdr-signin,
.hdr-acct-link,
.hdr-signout {
  /* [hidden] attribute sets display:none via the browser default, but
     display:inline-flex on these classes overrides it. Force it back. */
}
#hdr-signin[hidden],
#hdr-acct-link[hidden],
#hdr-signout[hidden] { display: none !important; }
.hdr-signin {
  display: inline-flex; align-items: center; margin-left: 6px;
  padding: 4px 11px; border-radius: 7px; font-size: 12px; font-weight: 700;
  background: #22c55e; color: #06210f; text-decoration: none; white-space: nowrap;
  border: 1px solid #22c55e;
}
.hdr-signin:hover { background: #34d36b; }
.hdr-acct-link {
  display: inline-flex; align-items: center; margin-left: 6px;
  padding: 4px 10px; border-radius: 7px; font-size: 12px; font-weight: 600;
  color: #e6edf5; text-decoration: none; border: 1px solid var(--line);
  max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.hdr-acct-link:hover { border-color: #2f3b52; background: rgba(255,255,255,0.03); }
.hdr-acct-link::before { content: "\1F464"; margin-right: 5px; opacity: 0.7; }
.hdr-signout {
  display: inline-flex; align-items: center; margin-left: 4px;
  padding: 4px 8px; border-radius: 7px; font-size: 11px; font-weight: 600;
  color: #8a93a3; text-decoration: none; border: 1px solid var(--line); white-space: nowrap;
}
.hdr-signout:hover { color: #ef4444; border-color: #ef4444; }
@media (max-width: 560px) {
  .hdr-signin { padding: 4px 8px; font-size: 11px; }
  .hdr-acct-link { max-width: 90px; }
}

/* Status strip — CHANGELOG_SERIAL.md #230: slim single-line strip */
.hdr-status-strip {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 2px 12px 3px;
  font-size: 11px;
  font-weight: 500;
  color: var(--text-muted);
  flex-wrap: nowrap;
  border-top: 1px solid var(--line);
  overflow: hidden;
}
.hdr-strip-item {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  white-space: nowrap;
}
.hdr-strip-label {
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 10px;
  color: var(--text-dim);
}
.hdr-strip-val {
  font-size: 11px;
  font-weight: 600;
  color: var(--text-muted);
}
.hdr-strip-sep { color: var(--text-dim); padding: 0 2px; }

/* Mobile: 920px collapse for header already handled in existing block;
   480px overrides are in the @media (max-width: 480px) block at EOF. */
@media (max-width: 920px) {
  .hdr-main-row { gap: 8px; padding: 6px 8px; }
  .hdr-search-trigger { margin: 0 4px; }
}

/* Also keep old .brand* selectors alive for any JS that queries them */
.brand { display: none; }
.brand-mark, .header-time, .header-date { display: none; }

/* ============================================================
   Main grid layout
   ============================================================ */
.main-grid {
  display: grid;
  grid-template-columns: 1fr 320px;
  /* CHANGELOG_SERIAL.md #228 — kill dead space at top of Live tab: row gap 16->10,
     top pad 16->6 so the spot bar / tiles / EMA / chart stack densely under the
     tab nav. Bottom pad unchanged. */
  gap: 10px;
  padding-top: 6px;
  padding-bottom: 32px;
  align-items: start;
}

/* Hero pin + tab nav always at top, full-width. Tab content cards flow naturally below. */
.hero-pin-card  { grid-column: 1 / -1; }
.tab-nav        { grid-column: 1 / -1; }
.tab-content    { grid-column: 1 / -1; }
/* Within the Terrain tab, terrain + flow15 form a 2-column row, table sits full-width below */
.terrain-card   { grid-column: 1; }
.flow15-card    { grid-column: 2; }
.table-card     { grid-column: 1 / -1; }
/* Reference tab puts calibration + methodology side-by-side */
.cal-card       { grid-column: 1; }
.meth-card      { grid-column: 2; }

@media (max-width: 960px) {
  .main-grid { grid-template-columns: 1fr; }
  .hero-pin-card, .adi-card, .terrain-card, .setup-card, .flow15-card, .table-card, .underwater-card, .flowhist-card, .capit-card, .cal-card, .meth-card {
    grid-column: 1; grid-row: auto;
  }
}

/* ============================================================
   Tab navigation — sticky at top, mobile-friendly
   ============================================================ */
.tab-nav {
  display: flex;
  gap: 6px;
  padding: 8px;
  background: var(--bg-card);
  border: 2px solid var(--text);
  border-radius: 10px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  /* Sticky below header + hero-pin (spotbar). Stack after #316:
     header (z:110, top:0) → hero-pin (z:100, top:hdr) → tabs (z:95, top:hdr+pin).
     --aq-tab-top = calc(--aq-hdr-h + --aq-pin-h) per #316. */
  position: sticky;
  top: var(--aq-tab-top); /* #099/#316 — driven by --aq-tab-top var */
  z-index: 95;
  margin-bottom: 6px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.10);
}
/* CHANGELOG_SERIAL.md #165 — UX polish P1 — wrapper for the tab-nav now that
   it lives directly under the header (above the positions-strip) instead of
   inside <main class="main-grid">. The inner .container matches the header /
   positions-strip width; the small top margin keeps it off the header edge
   and preserves the existing vertical rhythm. */
.tab-nav-shell {
  margin-top: 8px;
}
.tab-btn {
  flex: 1 1 auto;
  min-width: 110px;
  padding: 14px 22px;
  border: none;
  background: transparent;
  color: var(--text-muted);
  font-size: 19px;
  font-weight: 800;
  cursor: pointer;
  border-radius: 6px;
  white-space: nowrap;
  transition: background 100ms ease, color 100ms ease;
  font-family: var(--sans);
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.tab-btn:hover {
  background: var(--bg-table-alt);
  color: var(--text);
}
.tab-btn.active {
  background: var(--accent);
  color: #fff;
  box-shadow: 0 1px 4px rgba(0, 82, 204, 0.35);
}

/* Tab content visibility — only show cards whose data-tab matches the active tab.
   Body data-active-tab attribute is updated by the tab click handler in app.js. */
.tab-content { display: none; }
body[data-active-tab="live"]      .tab-content[data-tab="live"]      { display: block; }
body[data-active-tab="terrain"]   .tab-content[data-tab="terrain"]   { display: block; }
body[data-active-tab="flow"]      .tab-content[data-tab="flow"]      { display: block; }
body[data-active-tab="pressure"]  .tab-content[data-tab="pressure"]  { display: block; }
body[data-active-tab="paper"]     .tab-content[data-tab="paper"]     { display: block; }
body[data-active-tab="reference"] .tab-content[data-tab="reference"] { display: block; }
body[data-active-tab="help"]      .tab-content[data-tab="help"]      { display: block; } /* CHANGELOG_SERIAL.md #180 — Help tab visibility */
body[data-active-tab="lab"]       .tab-content[data-tab="lab"]       { display: block; } /* CHANGELOG_SERIAL.md #330 — Lab tab visibility */

/* ============================================================
   CHANGELOG_SERIAL.md #235 — 1.1: Top-grid on Live tab only.
   On non-Live tabs collapse the full two-column #top-grid to a
   slim one-line ticker strip and show the slim bar instead.
   The full grid + its children are hidden; .top-grid-slim is
   shown. On Live tab: full grid shows, slim bar hides.
   ============================================================ */
/* Full top-grid: show only on Live tab */
body:not([data-active-tab="live"]) .top-grid {
  display: none !important;
}
/* Slim ticker: hidden on Live tab, shown on all other tabs */
.top-grid-slim { display: none; }
body:not([data-active-tab="live"]) .top-grid-slim {
  display: flex;
  align-items: center;
  gap: 0;
  height: 36px;
  padding: 0 14px;
  background: rgba(255, 255, 255, 0.02);
  border: 1px solid var(--line);
  border-radius: 8px;
  margin: 6px auto 2px;
  font-size: 13px;
  font-family: var(--mono);
  color: var(--text-muted);
  cursor: pointer;
  text-decoration: none;
  overflow: hidden;
  white-space: nowrap;
  max-width: 2300px;
  box-sizing: border-box;
  width: calc(100% - 24px);
  transition: background 0.12s;
}
body:not([data-active-tab="live"]) .top-grid-slim:hover {
  background: rgba(34, 197, 94, 0.06);
}
.tgs-item { display: inline-flex; align-items: center; gap: 4px; }
.tgs-label { color: var(--text-dim); font-size: 11px; letter-spacing: 0.04em; text-transform: uppercase; }
.tgs-val { font-weight: 700; color: var(--text); }
.tgs-val.pnl-pos { color: rgb(34, 197, 94); }
.tgs-val.pnl-neg { color: rgb(239, 68, 68); }
.tgs-sep { color: var(--text-dim); padding: 0 10px; user-select: none; }
.tgs-hint { margin-left: auto; font-size: 11px; color: var(--text-dim); opacity: 0.7; }

/* ============================================================
   CHANGELOG_SERIAL.md #235 — 1.2: EMA Stack compression.
   Default collapsed to one-row strip showing chips only.
   Expanded via [data-ema-expanded] on the section element.
   ============================================================ */
.ema-top .ema-top-cols { display: none; } /* hidden when collapsed */
.ema-top[data-ema-expanded] .ema-top-cols { display: grid; } /* show on expand */
.ema-top[data-ema-expanded] .ema-collapsed-strip { display: none; }
/* #235 — when collapsed, hide the big centered title block too so it's truly a
   one-row strip; the centered title/subtitle/ⓘ return on expand. */
.ema-top:not([data-ema-expanded]) .ema-top-header { display: none; }
/* Collapsed strip: one row of chips */
.ema-collapsed-strip {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: nowrap;
  overflow: hidden;
}
.ema-cs-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 8px;
  border-radius: 4px;
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--line);
  font-size: 12px;
  font-family: var(--mono);
  font-weight: 700;
}
.ema-cs-tf { font-size: 11px; font-weight: 700; color: #93c5fd; letter-spacing: 0.04em; text-transform: uppercase; }
.ema-top-toggle {
  margin-left: auto;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--text-dim);
  font-size: 12px;
  padding: 2px 6px;
  border-radius: 4px;
  transition: background 0.12s;
  white-space: nowrap;
}
.ema-top-toggle:hover { background: rgba(255,255,255,0.06); color: var(--text); }
/* Sync the header/sub visibility: hide in collapsed state, keep in expanded */
.ema-top .ema-top-header { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; text-align: left; }
.ema-top[data-ema-expanded] .ema-top-header { margin-bottom: 6px; }

/* ============================================================
   CHANGELOG_SERIAL.md #235 — 1.3: Chart legend sidebars.
   On the Live OI timeline and Pulse 15M cards, add an "info"
   toggle button that shows/hides the full sidebar. When the
   sidebar is hidden the canvas takes full card width.
   The existing sidebar hide is done by removing has-sidebar
   grid layout; we use a class .sidebar-hidden on the card.
   Flag: full popover pattern is partial (sidebar hidden, but
   not a floating popover — that risks z-index/chart-resize
   issues). The canvas gets full width when sidebar is hidden.
   ============================================================ */
.live-oi-card.sidebar-hidden .live-oi-sidebar,
.pulse-15m-card.sidebar-hidden .pulse-15m-sidebar { display: none; }
/* Override the grid layout to single-column when sidebar hidden */
body[data-active-tab="live"] .live-oi-card.has-sidebar.sidebar-hidden {
  grid-template-columns: 1fr;
}
body[data-active-tab="live"] .pulse-15m-card.has-sidebar.sidebar-hidden {
  grid-template-columns: 1fr;
}
/* Info/toggle button for sidebar — sits in card header area */
.sidebar-toggle-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: none;
  border: 1px solid var(--btn-border);
  border-radius: 4px;
  padding: 3px 8px;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-muted);
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
  white-space: nowrap;
}
.sidebar-toggle-btn:hover { background: rgba(255,255,255,0.06); color: var(--text); }

/* ============================================================
   CHANGELOG_SERIAL.md #235 — 1.6: Short-tab void fix.
   Give every tab content panel a minimum height so short tabs
   (Flow, Pressure, Reference) do not leave a black void under
   the footer. Footer is pinned at end of body via flex-column
   on the body layout.
   ============================================================ */
html { height: 100%; }
body { min-height: 100%; display: flex; flex-direction: column; }
body > * { flex-shrink: 0; }
.main-grid { flex: 1 0 auto; }
/* Ensure each tab's content area (main-grid when that tab active) fills */
.tab-content[data-tab="flow"],
.tab-content[data-tab="pressure"],
.tab-content[data-tab="reference"],
.tab-content[data-tab="paper"],
.tab-content[data-tab="help"] {
  min-height: calc(100vh - var(--aq-hdr-h) - var(--aq-tab-h) - 60px);
}

/* CHANGELOG_SERIAL.md #274 — removed: .adi-radar-grid 2-col grid.
   Edge Radar was relocated above the heatmap (.oi-above-chart-row > .oi-radar-col).
   ADI is now a standalone full-width tab-content card (tab-content + data-tab="live"
   moved onto #adi directly). The wrapper div and its grid rules are no longer needed. */

/* ============================================================
   CHANGELOG_SERIAL.md #235 — 1.8: Sticky section chips.
   Slim sticky row under tab nav on Live (and Terrain) tabs.
   Smooth-scrolls to anchors; active section highlights via JS.
   Reuses .help-toc-link color vocab (green-500 palette).
   ============================================================ */
.section-chips-bar {
  display: none; /* shown only when Live or Terrain tab active, see below */
  grid-column: 1 / -1; /* span full main-grid width when displayed */
  position: sticky;
  top: var(--aq-pin-top); /* sticks just below header+spotbar+tabnav (#235; var updated #316) */
  z-index: 85;
  background: var(--bg-card);
  border-bottom: 1px solid var(--line);
  padding: 5px 14px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  white-space: nowrap;
  flex-shrink: 0;
}
.section-chips-bar::-webkit-scrollbar { display: none; }
body[data-active-tab="live"] .section-chips-bar[data-tab-scope="live"],
body[data-active-tab="terrain"] .section-chips-bar[data-tab-scope="terrain"] {
  display: flex;
  align-items: center;
  gap: 5px;
}
.sc-chip {
  display: inline-flex;
  align-items: center;
  padding: 3px 9px;
  font-size: 11px;
  font-weight: 600;
  color: var(--text-muted);
  text-decoration: none;
  border: 1px solid var(--line);
  border-radius: 4px;
  white-space: nowrap;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
  cursor: pointer;
  background: none;
  font-family: var(--sans);
}
.sc-chip:hover {
  background: rgba(34, 197, 94, 0.10);
  color: rgb(74, 222, 128);
  border-color: rgba(34, 197, 94, 0.4);
  text-decoration: none;
}
.sc-chip.sc-active {
  background: rgba(34, 197, 94, 0.15);
  color: rgb(34, 197, 94);
  border-color: rgba(34, 197, 94, 0.5);
}
.sc-chip-cmd {
  margin-left: 8px;
  background: rgba(255,255,255,0.04);
  border-color: rgba(255,255,255,0.12);
  color: var(--text-dim);
  font-family: var(--mono);
  font-size: 11px;
}
.sc-chip-cmd:hover { background: rgba(255,255,255,0.08); color: var(--text-muted); }

/* ============ Paper trading (Phase 1) ============ */

/* Portfolio header strip — 7 stats inline */
.paper-portfolio-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
  gap: 8px;
  padding: 12px 16px 16px;
}
.paper-stat {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 8px 10px;
  background: rgba(76, 139, 255, 0.05);
  border: 1px solid rgba(76, 139, 255, 0.18);
  border-radius: 8px;
}
.paper-stat-label {
  font-size: 11px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--muted, #8aa0b3);
}
.paper-stat-value {
  font-size: 17px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.paper-stat-value.pnl-up   { color: #10b981; }
.paper-stat-value.pnl-down { color: #ef4444; }
.paper-stat-value.pnl-flat { color: var(--text, inherit); }

.paper-actions { display: flex; gap: 8px; align-items: center; }
.paper-btn {
  appearance: none;
  border: 1px solid var(--line, #1c2c3d);
  background: var(--bg-card, transparent);
  color: var(--text, inherit);
  font-size: 13px;
  font-weight: 600;
  padding: 6px 14px;
  border-radius: 6px;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}
.paper-btn:hover:not(:disabled) { background: rgba(76, 139, 255, 0.08); border-color: rgba(76, 139, 255, 0.5); }
.paper-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.paper-btn-danger { color: #ef4444; border-color: rgba(239, 68, 68, 0.4); }
.paper-btn-danger:hover:not(:disabled) { background: rgba(239, 68, 68, 0.08); border-color: rgba(239, 68, 68, 0.65); }
.paper-btn-primary { background: linear-gradient(90deg, #4c8bff, #4ed4b5); color: #07101a; border-color: transparent; }
.paper-btn-primary:hover:not(:disabled) { filter: brightness(1.05); }

/* Trade ladder */
.paper-ladder-info {
  font-size: 13px;
  color: var(--muted, #8aa0b3);
  margin-top: 4px;
}
.paper-ladder-toggle { display: inline-flex; gap: 0; border: 1px solid var(--line, #1c2c3d); border-radius: 8px; overflow: hidden; }
.paper-ladder-pill {
  appearance: none;
  background: transparent;
  color: var(--muted, #8aa0b3);
  border: 0;
  font-size: 13px;
  font-weight: 700;
  padding: 6px 14px;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.paper-ladder-pill.active {
  background: rgba(76, 139, 255, 0.18);
  color: var(--text, inherit);
}
.paper-ladder-pill:hover:not(.active) { background: rgba(76, 139, 255, 0.06); color: var(--text, inherit); }

.paper-ladder-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.paper-ladder-table th,
.paper-ladder-table td { padding: 8px 10px; border-bottom: 1px solid rgba(76, 139, 255, 0.08); text-align: left; vertical-align: middle; }
.paper-ladder-table th { font-size: 11px; letter-spacing: 0.5px; text-transform: uppercase; color: var(--muted, #8aa0b3); font-weight: 600; }
.paper-ladder-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.ladder-strike { font-weight: 700; color: #fcd34d; }
.ladder-mid-yes { color: #34d399; font-weight: 600; }
.ladder-mid-no  { color: #f87171; font-weight: 600; }
.ladder-row-atm { background: rgba(76, 139, 255, 0.05); }
.ladder-row-atm .ladder-strike { color: #4c8bff; }
.ladder-pos { font-size: 12px; line-height: 1.4; }
.ladder-pos-yes { color: #34d399; font-weight: 700; }
.ladder-pos-no  { color: #f87171; font-weight: 700; }
.ladder-actions { display: flex; gap: 6px; }
.ladder-buy {
  appearance: none;
  border: 1px solid;
  padding: 4px 9px;
  font-size: 12px;
  font-weight: 700;
  border-radius: 5px;
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
}
.ladder-buy-yes { color: #34d399; border-color: rgba(52, 211, 153, 0.55); background: rgba(52, 211, 153, 0.08); }
.ladder-buy-yes:hover:not(:disabled) { background: rgba(52, 211, 153, 0.22); }
.ladder-buy-no  { color: #f87171; border-color: rgba(248, 113, 113, 0.55); background: rgba(248, 113, 113, 0.08); }
.ladder-buy-no:hover:not(:disabled)  { background: rgba(248, 113, 113, 0.22); }
.ladder-buy:disabled { opacity: 0.35; cursor: not-allowed; }
.ladder-close { color: var(--muted, #8aa0b3); border-color: var(--line, #1c2c3d); background: transparent; }
.ladder-close:hover { color: var(--text); border-color: rgba(76, 139, 255, 0.5); background: rgba(76, 139, 255, 0.08); }

.paper-ladder-footer {
  padding: 8px 16px 14px;
  font-size: 13px;
  color: var(--muted, #8aa0b3);
}
.paper-ladder-footer label { cursor: pointer; user-select: none; }
.paper-ladder-footer input { margin-right: 6px; vertical-align: middle; }

/* Open positions table */
.paper-positions-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.paper-positions-table th,
.paper-positions-table td { padding: 8px 10px; border-bottom: 1px solid rgba(76, 139, 255, 0.08); text-align: left; vertical-align: middle; }
.paper-positions-table th { font-size: 11px; letter-spacing: 0.5px; text-transform: uppercase; color: var(--muted, #8aa0b3); font-weight: 600; }
.paper-positions-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.pos-yes { color: #34d399; font-weight: 700; }
.pos-no  { color: #f87171; font-weight: 700; }

/* Modals (BUY / CLOSE) */
.paper-modal {
  position: fixed; inset: 0;
  background: rgba(0, 0, 0, 0.55);
  display: flex; align-items: center; justify-content: center;
  z-index: 1000;
  padding: 16px;
  backdrop-filter: blur(2px);
}
.paper-modal[hidden] { display: none; }
.paper-modal-card {
  background: var(--bg-card, #0b1722);
  border: 1px solid var(--line, #1c2c3d);
  border-radius: 12px;
  padding: 22px 24px 20px;
  width: 100%;
  max-width: 420px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.45);
}
.paper-modal-title { font-size: 20px; margin: 0 0 6px; }
.paper-modal-side { padding: 1px 8px; border-radius: 5px; font-size: 14px; }
.paper-modal-side.pos-yes { background: rgba(52, 211, 153, 0.18); color: #34d399; }
.paper-modal-side.pos-no  { background: rgba(248, 113, 113, 0.18); color: #f87171; }
.paper-modal-meta { font-size: 13px; color: var(--muted, #8aa0b3); margin-bottom: 14px; }
.paper-modal-row {
  display: flex; justify-content: space-between; align-items: center;
  padding: 7px 0;
  border-top: 1px solid rgba(76, 139, 255, 0.08);
  font-size: 14px;
}
.paper-modal-row span { color: var(--muted, #8aa0b3); }
.paper-modal-row strong { font-variant-numeric: tabular-nums; }
.paper-modal-row input[type="number"] {
  background: transparent;
  border: 1px solid var(--line, #1c2c3d);
  color: var(--text, inherit);
  padding: 5px 9px;
  border-radius: 6px;
  width: 110px;
  font-size: 14px;
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.paper-modal-cost strong { font-size: 16px; }
.paper-modal-pnl.pnl-up   { color: #10b981; }
.paper-modal-pnl.pnl-down { color: #ef4444; }
.paper-modal-foot { margin-top: 10px; font-size: 12px; }
.paper-modal-foot-ok  { color: var(--muted, #8aa0b3); }
.paper-modal-foot-err { color: #ef4444; }
.paper-modal-actions {
  display: flex; gap: 8px; justify-content: flex-end;
  margin-top: 16px;
}

/* Phase 3: trade journal + performance stats + equity curve */

.paper-journal-pagination {
  display: flex; align-items: center; gap: 10px;
  font-size: 12px;
  color: var(--muted, #8aa0b3);
}
.paper-journal-page { font-variant-numeric: tabular-nums; min-width: 160px; text-align: center; }

.paper-journal-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.paper-journal-table th,
.paper-journal-table td { padding: 7px 10px; border-bottom: 1px solid rgba(76, 139, 255, 0.06); text-align: left; vertical-align: middle; }
.paper-journal-table th { font-size: 10px; letter-spacing: 0.5px; text-transform: uppercase; color: var(--muted, #8aa0b3); font-weight: 600; }
.paper-journal-table .num { text-align: right; font-variant-numeric: tabular-nums; }

/* Stats card: top tile grid + breakdown row + equity curve */
.paper-stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 8px;
  padding: 12px 16px 8px;
}
.paper-stats-breakdown {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 8px;
  padding: 4px 16px 12px;
}
.paper-stat-wide .paper-stat-value { font-size: 13px; font-weight: 600; }
.paper-stats-equity {
  padding: 4px 16px 16px;
  border-top: 1px solid rgba(76, 139, 255, 0.08);
  margin-top: 4px;
}
.paper-stats-equity-title {
  font-size: 13px;
  font-weight: 700;
  margin: 12px 0 8px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--muted, #8aa0b3);
}
.paper-stats-equity-chart {
  position: relative;
  height: 220px;
  width: 100%;
}
.paper-stats-equity .muted.small { font-size: 11px; margin-top: 6px; }

/* Phase 2: stale badge — position past its settle but page missed the transition */
.paper-stale-badge {
  display: inline-block;
  font-size: 10px;
  letter-spacing: 0.6px;
  padding: 1px 6px;
  margin-left: 6px;
  border-radius: 4px;
  background: rgba(245, 158, 11, 0.15);
  border: 1px solid rgba(245, 158, 11, 0.5);
  color: #f59e0b;
  font-weight: 800;
  vertical-align: middle;
}
.paper-row-stale { background: rgba(245, 158, 11, 0.04); }
.paper-stale-cell { color: #f59e0b; font-size: 12px; font-style: italic; }

/* CHANGELOG_SERIAL.md #053 — trade-fill alert toasts (top-right) + mute toggle */
.ap-toast-container {
  position: fixed;
  top: 20px;
  right: 20px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  z-index: 1200;
  pointer-events: none;
  max-width: 360px;
  min-width: 280px;
}
.ap-trade-toast {
  pointer-events: auto;
  background: var(--bg-card, #0b1722);
  border: 1px solid var(--line, #1c2c3d);
  border-left: 4px solid rgb(140, 140, 140);
  border-radius: 8px;
  padding: 10px 14px;
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.35);
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13px;
  opacity: 0;
  transform: translateX(24px);
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.ap-trade-toast.ap-trade-toast-in { opacity: 1; transform: translateX(0); }
.ap-toast-text { flex: 1; font-variant-numeric: tabular-nums; line-height: 1.4; }
.ap-toast-close {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--muted, #8aa0b3);
  cursor: pointer;
  font-size: 18px;
  line-height: 1;
  padding: 0 2px;
  flex-shrink: 0;
}
.ap-toast-close:hover { color: var(--text, inherit); }
/* CHANGELOG_SERIAL.md #065 — header actions row (X share + mute) */
.ap-header-actions {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  flex-shrink: 0;
  margin-left: auto;
}
.ap-x-share-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  appearance: none;
  border: 1px solid var(--line, #1c2c3d);
  background: transparent;
  color: var(--muted, #8aa0b3);
  cursor: pointer;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
  line-height: 1;
  padding: 5px 10px;
  border-radius: 6px;
  flex-shrink: 0;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.ap-x-share-btn:hover {
  color: var(--text, #d0dde8);
  border-color: var(--muted, #8aa0b3);
  background: rgba(255,255,255,0.04);
}
.ap-mute-toggle {
  appearance: none;
  border: 1px solid var(--line, #1c2c3d);
  background: transparent;
  color: var(--muted, #8aa0b3);
  cursor: pointer;
  font-size: 18px;
  line-height: 1;
  padding: 4px 8px;
  border-radius: 6px;
  align-self: flex-start;
  flex-shrink: 0;
}
.ap-mute-toggle:hover { color: var(--text, inherit); border-color: var(--muted, #8aa0b3); }

/* Phase 2: settle toast container — bottom-right of viewport, stacked */
.paper-toast-container {
  position: fixed;
  bottom: 16px;
  right: 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  z-index: 1100;
  pointer-events: none;             /* clicks pass through gaps */
  max-width: 380px;
}
.paper-toast {
  pointer-events: auto;             /* but toasts themselves are clickable */
  background: var(--bg-card, #0b1722);
  border: 1px solid var(--line, #1c2c3d);
  border-left: 4px solid var(--muted, #8aa0b3);
  border-radius: 8px;
  padding: 10px 14px;
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.35);
  opacity: 0;
  transform: translateX(20px);
  transition: opacity 0.25s ease, transform 0.25s ease;
  font-size: 13px;
  min-width: 280px;
}
.paper-toast.paper-toast-in { opacity: 1; transform: translateX(0); }
.paper-toast-win  { border-left-color: #10b981; }
.paper-toast-loss { border-left-color: #ef4444; }
.paper-toast-head {
  display: flex; align-items: center; gap: 8px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--muted, #8aa0b3);
  margin-bottom: 4px;
}
.paper-toast-win .paper-toast-verdict  { color: #10b981; font-weight: 800; }
.paper-toast-loss .paper-toast-verdict { color: #ef4444; font-weight: 800; }
.paper-toast-close {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--muted, #8aa0b3);
  cursor: pointer;
  font-size: 18px;
  line-height: 1;
  padding: 0 2px;
  margin-left: auto;
}
.paper-toast-close:hover { color: var(--text, inherit); }
.paper-toast-body {
  font-variant-numeric: tabular-nums;
  line-height: 1.4;
}

/* On mobile, tab buttons should sit edge-to-edge for thumb reach. */
@media (max-width: 960px) {
  .tab-btn { padding: 14px 16px; font-size: 15px; min-width: 86px; font-weight: 800; }
  /* #099 — top: 500px placeholder removed; tab-nav top driven by --aq-tab-top var */
}

/* ============================================================
   Hero Pin — spot vs forecast EOH, always visible
   STICKY so it stays on screen across all tabs (Live, Terrain, Flow, etc.)
   ============================================================ */
.hero-pin-card {
  background: linear-gradient(180deg, rgba(168, 85, 247, 0.04) 0%, var(--bg-card) 100%);
  border: 2px solid var(--text);
  border-radius: 10px;
  /* CHANGELOG_SERIAL.md #165 — UX polish P1 — hero stat strip no longer sticky.
     The sticky <header> already follows scroll; stacking the hero strip on top
     consumed ~20% of a 900px laptop viewport. It is now a normal top-of-page
     card. The sticky <header> rule (.site-header) is unchanged. */
  position: static;
  z-index: 80;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.10);
  margin-bottom: 6px;
}
[data-theme="dark"] .hero-pin-card {
  background: linear-gradient(180deg, rgba(167, 139, 250, 0.08) 0%, var(--bg-card) 100%);
  border-color: var(--line-strong);
}
/* #099 — 720px hero-pin override superseded by var-based system below; kept as no-op comment */
/* @media (max-width: 720px) { .hero-pin-card { top: 280px; } } */
.hero-pin-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 18px;
  padding: 18px 22px 14px;
}
.hero-pin-cell {
  display: flex; flex-direction: column; gap: 4px; min-width: 0;
}
.hero-pin-label {
  font-size: 12px; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--text-muted); font-weight: 700;
}
.hero-pin-value {
  font-size: 36px; font-weight: 800; color: var(--text);
  letter-spacing: -0.025em; font-variant-numeric: tabular-nums;
  font-family: var(--mono);
  line-height: 1.0;
}
/* CHANGELOG_SERIAL.md #152 - palette refresh */
.hero-pin-value.pin { color: var(--accent-2); }          /* Forecast EOH — violet */
.hero-pin-value.band { font-size: 22px; font-weight: 600; }
.hero-pin-value.tte { font-size: 32px; color: var(--accent-3); } /* Time to settle — amber */
.hero-pin-sub {
  font-size: 13px; color: var(--text-muted);
  font-family: var(--mono); font-weight: 600;
  margin-top: 2px;
}
.hero-pin-sub.bullish { color: var(--pos); }
.hero-pin-sub.bearish { color: var(--neg); }

/* The visualization ribbon — shows spot & pin relative position */
.hero-pin-ribbon {
  padding: 6px 22px 8px;
}
.hero-pin-ribbon-track {
  position: relative; height: 24px;
  background: rgba(150, 155, 160, 0.06);
  border: 1px solid var(--line);
  border-radius: 5px;
}
.hero-pin-ribbon-2s {
  position: absolute; top: 0; bottom: 0;
  background: rgba(150, 155, 160, 0.18);
  border-radius: 3px;
}
.hero-pin-ribbon-1s {
  position: absolute; top: 0; bottom: 0;
  background: rgba(168, 85, 247, 0.14);
  border-radius: 3px;
}
.hero-pin-marker {
  position: absolute; top: -4px; bottom: -4px;
  width: 3px;
  transform: translateX(-50%);
  transition: left 320ms ease-out;
}
.hero-pin-marker.spot-marker {
  background: #1a1f2e;
  border: 1.5px solid #fff;
  border-radius: 2px;
  width: 5px;
  box-shadow: 0 0 4px rgba(0,0,0,0.3);
  z-index: 2;
}
.hero-pin-marker.pin-marker {
  background: rgba(168, 85, 247, 1);
  border-left: 1.5px dashed rgba(168, 85, 247, 1);
  border-right: 1.5px dashed rgba(168, 85, 247, 1);
  box-shadow: 0 0 6px rgba(168, 85, 247, 0.5);
  z-index: 1;
}
.hero-pin-ribbon-labels {
  display: flex; justify-content: space-between;
  margin-top: 8px;
  font-size: 12px; color: var(--text-muted);
  font-family: var(--mono); font-weight: 600;
}
.hero-pin-ribbon-center { color: var(--text); font-weight: 700; }
.hero-pin-footer {
  display: flex; justify-content: space-between; flex-wrap: wrap;
  padding: 8px 22px 14px;
  font-size: 13px; color: var(--text-muted);
  font-family: var(--mono); font-weight: 600;
  border-top: 1px solid var(--line);
}
.hero-pin-history.bullish { color: var(--pos); }
.hero-pin-history.bearish { color: var(--neg); }
.hero-pin-spot-vs-pin.bullish { color: var(--pos); }
.hero-pin-spot-vs-pin.bearish { color: var(--neg); }

/* ============================================================
   AnalogQuant Direction Index — composite barometer card
   ============================================================ */
.adi-body { padding: 18px 22px 22px; }
.adi-hero {
  display: grid;
  grid-template-columns: minmax(220px, 280px) 1fr;
  gap: 28px;
  align-items: center;
  padding-bottom: 22px;
  border-bottom: 1px solid var(--line);
}
.adi-score-wrap { display: flex; flex-direction: column; gap: 4px; }
.adi-score {
  font-size: 64px; font-weight: 800; font-family: var(--mono);
  line-height: 1; letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.adi-label {
  font-size: 18px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--text-muted);
}
.adi-label.bullish-strong  { color: rgba(20, 130, 60, 1); }
.adi-label.bullish         { color: var(--pos); }
.adi-label.neutral         { color: var(--text-muted); }
.adi-label.bearish         { color: var(--neg); }
.adi-label.bearish-strong  { color: rgba(180, 30, 50, 1); }
.adi-agreement {
  font-size: 13px; color: var(--text-muted); margin-top: 4px;
}

/* Regime classification — color-coded badge under the ADI label */
.adi-regime {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px dashed var(--line);
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.adi-regime-badge {
  display: inline-block;
  align-self: flex-start;
  padding: 6px 12px;
  border-radius: 4px;
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  border: 1.5px solid;
}
.adi-regime-badge.stabilizing_pin {
  background: rgba(40, 180, 90, 0.10);
  color: rgba(20, 130, 60, 1);
  border-color: rgba(40, 180, 90, 0.40);
}
.adi-regime-badge.stabilizing_with_drift {
  background: rgba(80, 130, 220, 0.10);
  color: rgba(50, 90, 180, 1);
  border-color: rgba(80, 130, 220, 0.40);
}
.adi-regime-badge.destabilizing_neutral {
  background: rgba(220, 140, 40, 0.12);
  color: rgba(180, 100, 20, 1);
  border-color: rgba(220, 140, 40, 0.45);
}
.adi-regime-badge.destabilizing_cascade {
  background: rgba(230, 60, 80, 0.12);
  color: rgba(180, 30, 50, 1);
  border-color: rgba(230, 60, 80, 0.55);
  animation: regime-pulse 1.6s infinite;
}
@keyframes regime-pulse {
  50% { box-shadow: 0 0 8px rgba(230, 60, 80, 0.4); }
}
.adi-regime-explanation {
  font-size: 13px;
  color: var(--text-muted);
  line-height: 1.45;
  font-style: italic;
}
.adi-barometer-wrap { min-width: 0; }
.adi-barometer {
  position: relative; height: 22px; margin-bottom: 8px;
}
.adi-bar-bg {
  position: absolute; inset: 0; border-radius: 4px;
  background: linear-gradient(to right,
    rgba(230, 60, 80, 0.85) 0%,
    rgba(230, 60, 80, 0.5) 20%,
    rgba(150, 155, 160, 0.25) 50%,
    rgba(40, 180, 90, 0.5) 80%,
    rgba(40, 180, 90, 0.85) 100%);
  border: 1px solid var(--line);
}
.adi-bar-zero {
  position: absolute; top: -4px; bottom: -4px; left: 50%;
  width: 1px; background: rgba(0, 0, 0, 0.18);
}
.adi-bar-marker {
  position: absolute; top: -6px; bottom: -6px; left: 50%;
  width: 5px; background: #1a1f2e;
  border: 2px solid #fff;
  border-radius: 3px;
  transform: translateX(-50%);
  box-shadow: 0 0 6px rgba(0,0,0,0.25);
  transition: left 320ms ease-out;
}
.adi-bar-labels {
  display: flex; justify-content: space-between;
  font-size: 12px; color: var(--text-muted);
  font-family: var(--mono);
  font-weight: 600;
}
.adi-bar-labels small {
  font-size: 10px; font-weight: 600; letter-spacing: 0.06em; display: block;
}

/* Range forecast bar */
.adi-range { padding: 18px 0 16px; border-bottom: 1px solid var(--line); }
.adi-range-title {
  font-size: 13px; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--text-muted); font-weight: 700; margin-bottom: 10px;
}
.adi-range-bar { position: relative; padding: 12px 0; }
.adi-range-track {
  position: relative; height: 18px;
  background: rgba(150, 155, 160, 0.08);
  border: 1px solid var(--line);
  border-radius: 4px;
  overflow: visible;
}
.adi-range-fill-2s {
  position: absolute; top: 0; bottom: 0;
  background: rgba(150, 155, 160, 0.20);
  border-radius: 2px;
}
.adi-range-fill-1s {
  position: absolute; top: 0; bottom: 0;
  background: rgba(40, 180, 90, 0.18);
  border-radius: 2px;
}
.adi-range-spot {
  position: absolute; top: -4px; bottom: -4px;
  width: 2.5px; background: rgba(168, 85, 247, 1);
  transform: translateX(-50%);
  box-shadow: 0 0 4px rgba(168, 85, 247, 0.5);
}
.adi-range-center {
  position: absolute; top: -2px; bottom: -2px;
  width: 1.5px; background: rgba(26, 31, 46, 0.45);
  border-left: 1px dashed rgba(26, 31, 46, 0.55);
  transform: translateX(-50%);
}
.adi-range-labels {
  display: flex; justify-content: space-between;
  margin-top: 10px;
  font-size: 12px; color: var(--text-muted);
  font-family: var(--mono); font-weight: 600;
}
.adi-range-labels span:nth-child(3) {
  color: rgba(168, 85, 247, 1); font-weight: 700;
}

/* Component breakdown */
.adi-components { padding-top: 18px; }
/* CHANGELOG_SERIAL.md #211 — EMA stack (5/8/13/26 on 5-min bars) in the ADI card. */
/* CHANGELOG_SERIAL.md #212 — per-EMA color-coded labels, larger font sizes. */
.adi-ema {
  margin: 14px 0 4px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.02);
}
.adi-ema-tf-block + .adi-ema-tf-block { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line); }
/* #213 — header centered + larger ("EMA STACK 5 MIN"), state pill below it. */
.adi-ema-head {
  display: flex; flex-direction: column; align-items: center; gap: 7px;
  text-align: center; margin-bottom: 12px;
}
.adi-ema-title {
  font-size: 19px; text-transform: uppercase; letter-spacing: 0.06em;
  color: #fff; font-weight: 800;
}
.adi-ema-tf {
  font-family: var(--mono); font-size: 18px; font-weight: 700;
  color: #93c5fd; margin-left: 6px; text-transform: none; letter-spacing: 0;
}
.adi-ema-state {
  font-size: 12px; font-weight: 800; letter-spacing: 0.04em;
  padding: 2px 9px; border-radius: 999px; white-space: nowrap;
}
.adi-ema-bull  { color: #22c55e; background: rgba(34, 197, 94, 0.12);  border: 1px solid rgba(34,197,94,0.35); }
.adi-ema-bear  { color: #ef4444; background: rgba(239, 68, 68, 0.12);  border: 1px solid rgba(239,68,68,0.35); }
.adi-ema-mixed { color: #94a3b8; background: rgba(148, 163, 184, 0.12); border: 1px solid rgba(148,163,184,0.30); }
.adi-ema-rows {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(112px, 1fr));
  gap: 6px;
}
.adi-ema-cell {
  display: flex; flex-direction: column; gap: 3px;
  padding: 7px 9px; border-radius: 4px;
  background: rgba(255, 255, 255, 0.03);
}
/* Base label — overridden per-EMA by color classes below. #213 larger. */
.adi-ema-k {
  font-size: 15px; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--text-dim); font-weight: 800;
}
/* Per-EMA color ramp: amber(fast) -> sky -> violet -> slate(slow).
   Tailwind 400 palette — warm-to-cool mirrors classic EMA chart convention.
   All are clearly distinct from each other and from the green/red state pill. */
.adi-ema-k--5  { color: #f59e0b; } /* Tailwind amber-400  — fastest, warmest */
.adi-ema-k--8  { color: #38bdf8; } /* Tailwind sky-400    — fast-mid, cool */
.adi-ema-k--12 { color: #a78bfa; } /* Tailwind violet-400 — slow-mid, purple */
.adi-ema-k--26 { color: #94a3b8; } /* Tailwind slate-400  — slowest, subdued */
.adi-ema-v {
  font-family: var(--mono); font-size: 15px; font-weight: 700; color: #fff;
}
.adi-ema-price { background: rgba(96, 165, 250, 0.10); }
.adi-ema-price .adi-ema-k { color: #93c5fd; }

/* CHANGELOG_SERIAL.md #214 — EMA stack moved to TOP of page: two columns
   (5 MIN | 15 MIN), each EMA listed top-to-bottom. */
/* CHANGELOG_SERIAL.md #225 — EMA panel compaction: tighter padding/margin/font. */
.ema-top {
  /* #227 — full-width inside main-grid (was rendering as a narrow centered box
     floating in whitespace). Force the grid span + stretch + flush margins. */
  grid-column: 1 / -1;
  justify-self: stretch;
  /* CHANGELOG_SERIAL.md #228 — EMA panel tucks flush above the chart (4/8 -> 0/4). */
  margin: 0 0 4px;
  padding: 8px 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.02);
}
.ema-top[hidden] { display: none; }
/* #226 — now a .tab-content child of main-grid; collapse when empty (cold start)
   so the tab-content display rule can't show an empty bordered box before data. */
.ema-top:empty { display: none !important; }
.ema-top-title {
  text-align: center;
  font-size: 13px; font-weight: 800; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--text-muted);
  margin-bottom: 6px;
}
.ema-top-cols { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
.ema-col {
  border: 1px solid var(--line); border-radius: 6px;
  padding: 5px 10px; background: rgba(255, 255, 255, 0.02);
}
.ema-col-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 5px; padding-bottom: 4px; border-bottom: 1px solid var(--line);
}
.ema-col-tf { font-family: var(--mono); font-size: 14px; font-weight: 800; color: #93c5fd; }
.ema-col-rows { display: flex; flex-direction: column; gap: 2px; }
.ema-row {
  display: flex; align-items: center; justify-content: space-between; padding: 2px 2px;
}
.ema-k {
  font-size: 13px; font-weight: 800; letter-spacing: 0.03em; text-transform: uppercase;
  color: var(--text-dim);
}
.ema-k--5  { color: #f59e0b; } /* amber-400  — fastest */
.ema-k--8  { color: #38bdf8; } /* sky-400 */
.ema-k--12 { color: #a78bfa; } /* violet-400 */
.ema-k--26 { color: #94a3b8; } /* slate-400  — slowest */
.ema-v { font-family: var(--mono); font-size: 14px; font-weight: 700; color: #fff; }
.ema-row-spot { margin-top: 2px; padding-top: 4px; border-top: 1px dashed var(--line); }
.ema-row-spot .ema-k { color: #93c5fd; }
@media (max-width: 560px) { .ema-top-cols { grid-template-columns: 1fr; } }

/* CHANGELOG_SERIAL.md #341 — EMA heatmap strip: now renders the FULL EMA readout
   (same colHtml grid as #ema-top) above the heatmap canvas. Container is block-level
   so the inner .ema-top-cols 2-column grid lays out correctly.
   Replaces the compact flex-row from #337. Palette unchanged. */
.ema-heatmap-strip {
  display: block;
  padding: 6px 10px 8px;
  margin-bottom: 6px;
  background: rgba(255, 255, 255, 0.025);
  border: 1px solid var(--line);
  border-radius: 6px;
  overflow: hidden;
}
.ema-heatmap-strip[hidden] { display: none; }
/* Inner full-cols wrapper: the .ema-top-cols grid is display:grid by default in this
   context (not inside .ema-top which hides it when collapsed). Override to always show. */
.ema-heatmap-strip .ema-heatmap-full-cols { display: grid; }
/* Label: "EMA STACK" heading chip */
.ehs-label {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-dim, #8a93a3);
  white-space: nowrap;
  margin-right: 2px;
}
/* Divider between 5MIN and 15MIN segments */
.ehs-div {
  display: inline-block;
  width: 1px;
  height: 16px;
  background: var(--line);
  align-self: center;
  flex-shrink: 0;
}
/* One timeframe segment (5MIN or 15MIN) */
.ehs-seg {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  white-space: nowrap;
}
.ehs-tf {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.05em;
  color: #93c5fd; /* sky-300 — matches .ema-col-tf */
  text-transform: uppercase;
}
/* State badge inherits .adi-ema-state colours; ehs-badge tightens the size */
.ehs-badge {
  font-size: 10px;
  padding: 1px 6px;
}
/* e5/e26 values cluster */
.ehs-vals {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.ehs-kv {
  display: inline-flex;
  align-items: baseline;
  gap: 2px;
}
.ehs-k {
  font-size: 10px;
  color: var(--text-dim, #8a93a3);
  text-transform: lowercase;
  letter-spacing: 0;
}
.ehs-v {
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 700;
  color: var(--text, #e6edf5);
}

/* CHANGELOG_SERIAL.md #217 — EMA panel: centered header, subtitle, info pop-up */
/* CHANGELOG_SERIAL.md #225 — header/subtitle further tightened to match overall compaction. */
.ema-top-header {
  text-align: center;
  margin-bottom: 6px;
}
/* #217 — title: larger and clearly centered; ema-top-title now inside the header wrapper */
/* #225 — font-size 17px → 13px; margin-bottom 3px → 2px */
.ema-top-title {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  justify-content: center;
  font-size: 13px; font-weight: 800; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--text-muted);
  margin-bottom: 2px;
}
/* #217 — subtitle: muted, smaller, centered directly below title */
/* #225 — font-size 11px → 10px */
.ema-top-sub {
  font-size: 10px; font-weight: 500; letter-spacing: 0.04em;
  color: var(--text-dim); text-transform: none; margin-top: 0;
}
/* #217 — circled-i info button */
.ema-info-btn {
  background: none; border: none; padding: 0 0 0 2px; margin: 0;
  cursor: pointer; font-size: 15px; line-height: 1;
  color: var(--text-dim); opacity: 0.75;
  vertical-align: middle;
  transition: opacity 0.15s;
}
.ema-info-btn:hover,
.ema-info-btn:focus-visible { opacity: 1; outline: 1px dotted var(--text-muted); outline-offset: 2px; }
.ema-info-btn[aria-expanded="true"] { opacity: 1; color: #93c5fd; }
/* #217 — info popover panel */
.ema-info-pop {
  margin: 0 0 10px;
  padding: 10px 14px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: rgba(15, 23, 42, 0.85);
  display: flex; flex-direction: column; gap: 7px;
}
.ema-info-pop[hidden] { display: none; }
.ema-info-row {
  display: flex; align-items: flex-start; gap: 10px;
}
/* #217 — state pills inside the popover: match the existing .adi-ema-bull/bear/mixed colours */
.ema-info-pill {
  flex-shrink: 0;
  font-size: 11px; font-weight: 800; letter-spacing: 0.04em;
  padding: 2px 8px; border-radius: 999px; white-space: nowrap;
}
.ema-info-bull  { color: #22c55e; background: rgba(34, 197, 94, 0.12);  border: 1px solid rgba(34,197,94,0.35); }
.ema-info-bear  { color: #ef4444; background: rgba(239, 68, 68, 0.12);  border: 1px solid rgba(239,68,68,0.35); }
.ema-info-mixed { color: #94a3b8; background: rgba(148, 163, 184, 0.12); border: 1px solid rgba(148,163,184,0.30); }
.ema-info-text {
  font-size: 12.5px; color: var(--text-dim); line-height: 1.45;
}

.adi-components-title {
  font-size: 13px; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--text-muted); font-weight: 700; margin-bottom: 10px;
}
.adi-components-list {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 10px;
}
.adi-component {
  display: flex; flex-direction: column; gap: 4px;
  padding: 10px 12px;
  border: 1px solid var(--line); border-radius: 5px;
  background: rgba(0, 0, 0, 0.015);
}
.adi-component.low-conf { opacity: 0.55; }
.adi-comp-row {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 8px;
}
.adi-comp-name {
  font-size: 13px; font-weight: 700; color: var(--text);
}
.adi-comp-score {
  font-size: 16px; font-weight: 700; font-family: var(--mono);
  font-variant-numeric: tabular-nums;
}
.adi-comp-score.pos { color: var(--pos); }
.adi-comp-score.neg { color: var(--neg); }
.adi-comp-meta {
  font-size: 11px; color: var(--text-muted); font-family: var(--mono);
}
.adi-comp-label {
  font-size: 12px; color: var(--text-muted); margin-top: 2px;
}

/* Nuances strip — context caveats below components */
.adi-nuances {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
}
.adi-nuances-title {
  font-size: 13px; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--text-muted); font-weight: 700; margin-bottom: 8px;
}
.adi-nuances-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.adi-nuance {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 8px 12px;
  border-radius: 5px;
  border-left: 3px solid;
  font-size: 13px;
  line-height: 1.45;
}
.adi-nuance.info {
  background: rgba(150, 155, 160, 0.06);
  border-left-color: rgba(120, 125, 130, 0.6);
  color: var(--text);
}
.adi-nuance.warning {
  background: rgba(220, 140, 40, 0.08);
  border-left-color: rgba(220, 140, 40, 0.8);
  color: rgba(140, 80, 10, 1);
}
.adi-nuance.alert {
  background: rgba(230, 60, 80, 0.10);
  border-left-color: rgba(230, 60, 80, 1);
  color: rgba(160, 30, 50, 1);
  font-weight: 600;
}
.adi-nuance-icon {
  font-size: 14px;
  line-height: 1;
  width: 16px;
  flex-shrink: 0;
}

/* ============================================================
   Cards
   ============================================================ */
.card {
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 6px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--line);
}

.card-title {
  font-size: 18px;
  font-weight: 800;
  margin: 0;
  letter-spacing: -0.005em;
  color: var(--text);
  display: flex;
  align-items: center;
  gap: 8px;
}

.card-sub {
  font-size: 14px;
  margin: 4px 0 0;
  color: var(--text-muted);
  max-width: 720px;
}

.live-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--pos);
  display: inline-block;
  box-shadow: 0 0 0 0 rgba(19, 115, 51, 0.5);
  animation: pulse 2.4s infinite ease-out;
}
@keyframes pulse {
  0%   { box-shadow: 0 0 0 0 rgba(19,115,51,0.55); }
  70%  { box-shadow: 0 0 0 8px rgba(19,115,51,0); }
  100% { box-shadow: 0 0 0 0 rgba(19,115,51,0); }
}

.card-meta {
  font-family: var(--mono);
  font-size: 11px;
  text-align: right;
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 220px;
}
.meta-row { display: block; color: var(--text); }
.meta-row.muted { color: var(--text-dim); }

/* ============================================================
   CHANGELOG_SERIAL.md #305 — Copy affordance button.
   Small inline clipboard icon button sits in card header rows.
   Matches the hdr-icon-btn idiom: 28x28, currentColor, subtle
   border, theme-aware. Reverts to a check-mark on success.
   ============================================================ */
.aq-copy-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  flex-shrink: 0;
  background: transparent;
  border: 1px solid var(--btn-border);
  border-radius: 5px;
  color: var(--text-dim);
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
  vertical-align: middle;
}
.aq-copy-btn:hover {
  color: var(--text);
  border-color: var(--btn-border-strong);
  background: rgba(125, 125, 125, 0.08);
}
.aq-copy-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.aq-copy-btn--copied {
  color: var(--pos);
  border-color: var(--pos);
}
/* Light theme: slightly darker border so it reads on white cards */
[data-theme="light"] .aq-copy-btn {
  border-color: rgba(15, 23, 42, 0.3);
  color: var(--text-dim);
}
[data-theme="light"] .aq-copy-btn:hover {
  border-color: var(--btn-border-strong);
  color: var(--text);
}
/* Mobile rule is in the @media (max-width: 480px) block at EOF per conventions */

/* ============================================================
   Terrain chart card
   ============================================================ */
.zoom-controls {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 9px 18px;
  border-bottom: 1px solid var(--line);
  background: var(--bg-table-alt);
  font-size: 11px;
  flex-wrap: wrap;
}
.zoom-label {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 600;
  color: var(--text-dim);
  margin-right: 4px;
}
.zoom-btn {
  padding: 3px 11px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--bg-card);
  color: var(--text-muted);
  font-size: 11px;
  font-weight: 500;
  cursor: pointer;
  font-family: var(--sans);
  transition: background 80ms ease, color 80ms ease, border-color 80ms ease;
}
.zoom-btn:hover {
  background: #eef2f7;
  color: var(--text);
}
.zoom-btn.active {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
}
.zoom-hint {
  margin-left: auto;
  color: var(--text-dim);
  font-size: 11px;
  font-style: italic;
}
@media (max-width: 720px) {
  .zoom-hint { display: none; }
}

.chart-wrap {
  position: relative;
  height: 380px;
  padding: 12px 8px 4px;
}

.legend {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  align-items: center;
  padding: 10px 18px 14px;
  border-top: 1px solid var(--line);
  font-size: 11px;
  color: var(--text-muted);
}

.leg-label {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 600;
  font-size: 10px;
  color: var(--text-dim);
}

.leg-item { display: inline-flex; align-items: center; gap: 5px; }
.sw {
  display: inline-block;
  width: 18px;
  height: 10px;
  border-radius: 2px;
}
.sw-buy-strong  { background: var(--buy-strong); }
.sw-buy-light   { background: var(--buy-light); }
.sw-flat        { background: var(--flat); }
.sw-sell-light  { background: var(--sell-light); }
.sw-sell-strong { background: var(--sell-strong); }

/* ============================================================
   Setup sidebar
   ============================================================ */
.setup-list {
  margin: 0;
  padding: 8px 0;
}

.setup-row {
  display: flex;
  justify-content: space-between;
  padding: 8px 18px;
  border-bottom: 1px solid var(--line);
  font-size: 12px;
}
.setup-row:last-child { border-bottom: none; }

.setup-row dt {
  color: var(--text-muted);
  font-weight: 500;
}

.setup-row dd {
  margin: 0;
  color: var(--text);
  font-weight: 600;
  text-align: right;
}

.setup-row dd.mono { font-family: var(--mono); }

/* TTE urgency: pulse red when < 60s to settle — actual hedging window */
.tte-urgent {
  color: var(--neg) !important;
  font-weight: 700;
  animation: tte-pulse 1s infinite ease-in-out;
}
@keyframes tte-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.55; }
}

.setup-mech {
  padding: 12px 18px;
  border-top: 1px solid var(--line);
  font-size: 12px;
  color: var(--text-muted);
  line-height: 1.55;
  background: var(--bg-table-alt);
  border-radius: 0 0 6px 6px;
}

/* Status pills */
.pill {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 12px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
}
.pill-up    { background: rgba(19, 115, 51, 0.12); color: var(--pos); }
.pill-down  { background: rgba(197, 34, 31, 0.12); color: var(--neg); }
.pill-mixed { background: rgba(176, 96, 0, 0.12);  color: var(--warn); }
.pill-flat  { background: rgba(90, 100, 120, 0.12); color: var(--text-muted); }

/* ============================================================
   Positioning table
   ============================================================ */
.table-wrap {
  overflow-x: auto;
}

.strikes-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.strikes-controls {
  display: flex;
  align-items: center;
  gap: 8px;
}
.strikes-control-label {
  font-size: 13px;
  color: var(--text-muted);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.strikes-select {
  font-size: 14px;
  padding: 6px 10px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--bg-elev);
  color: var(--text);
  font-family: var(--mono-font, ui-monospace, monospace);
  cursor: pointer;
}

.positioning-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 16px;
}

.positioning-table th,
.positioning-table td {
  padding: 10px 16px;
  text-align: left;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}

.positioning-table th {
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  background: var(--bg-table-alt);
}

.positioning-table td.num,
.positioning-table th.num {
  text-align: right;
  font-family: var(--mono);
}

.positioning-table tbody tr:hover { background: var(--bg-table-alt); }
.positioning-table tr.is-spot      { background: rgba(0, 82, 204, 0.04); }
.positioning-table tr.is-spot td   { font-weight: 600; }
.positioning-table .force-bar {
  display: inline-block;
  height: 9px;
  border-radius: 2px;
  vertical-align: middle;
  margin-right: 6px;
}

/* ============================================================
   Calibration card
   ============================================================ */
.cal-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  padding: 18px;
  gap: 16px;
}

.cal-cell {
  text-align: center;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--bg-table-alt);
}

.cal-label {
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  margin-bottom: 6px;
}

.cal-value {
  font-family: var(--mono);
  font-size: 32px;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 2px;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.cal-sub {
  font-size: 13px;
  color: var(--text-dim);
  font-family: var(--mono);
}

/* ============================================================
   Methodology card
   ============================================================ */
.meth-body { padding: 16px 18px; }
.meth-body p { margin: 0 0 10px; color: var(--text); font-size: 15px; line-height: 1.55; }
.meth-body p.muted { color: var(--text-muted); font-size: 14px; margin-top: 14px; }
.meth-body strong { color: var(--text); font-weight: 600; }
.meth-body em { color: var(--text); font-style: italic; }
.meth-list { margin: 0 0 10px; padding-left: 18px; }
.meth-list li { margin-bottom: 8px; color: var(--text-muted); font-size: 15px; line-height: 1.55; }

/* ============================================================
   CHANGELOG_SERIAL.md #095 — Footer v2: two-row layout with brand,
   nav links, social icons (row 1) and copyright/contact/sources (row 2).
   Old .footer-* selectors preserved as display:none so any JS referencing
   them doesn't throw.
   ============================================================ */
.site-footer {
  border-top: 1px solid var(--line);
  background: var(--bg-card);
  margin-top: 24px;
}

/* v2 inner wrapper */
.ftr-inner {
  max-width: 1200px;
  padding: 24px 16px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* Both rows are flex rows */
.ftr-row {
  display: flex;
  align-items: center;
  gap: 20px;
  flex-wrap: wrap;
}

/* Row 1 layout: brand left, nav center (flex-fill), social right */
.ftr-row-top {
  justify-content: space-between;
}

.ftr-brand {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}
.ftr-logo {
  width: 28px;
  height: 28px;
  border-radius: 8px;
  color: #0052cc;
}
[data-theme="dark"] .ftr-logo { color: #4ea1ff; }
.ftr-wordmark {
  font-size: 15px;
  font-weight: 800;
  color: var(--text);
  letter-spacing: -0.01em;
}

.ftr-nav {
  display: flex;
  align-items: center;
  gap: 20px;
  flex: 1 1 auto;
  justify-content: center;
}
.ftr-nav-link {
  font-size: 13px;
  font-weight: 500;
  color: var(--text-muted);
  text-decoration: none;
  transition: color 0.1s;
}
.ftr-nav-link:hover { color: var(--text); }

.ftr-social {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}
.ftr-social-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 6px;
  border: 1px solid var(--btn-border);
  background: var(--bg-table-alt);
  color: var(--text-muted);
  text-decoration: none;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.ftr-social-btn:hover {
  background: var(--bg);
  color: var(--text);
  border-color: var(--btn-border-strong);
}

/* Row 2: copyright and text links */
.ftr-row-bottom {
  font-size: 12px;
  color: var(--text-muted);
  gap: 8px;
  flex-wrap: wrap;
}
.ftr-copy { color: var(--text-muted); }
.ftr-sep { color: var(--text-dim); }
.ftr-text-link {
  color: var(--text-muted);
  text-decoration: none;
  font-weight: 500;
  transition: color 0.1s;
}
.ftr-text-link:hover { color: var(--text); text-decoration: underline; }
.ftr-sources { color: var(--text-dim); }

/* Mobile stack handled in @media (max-width: 480px) block at EOF */
@media (max-width: 720px) {
  .ftr-row-top { flex-direction: column; align-items: flex-start; gap: 12px; }
  .ftr-nav { justify-content: flex-start; }
  .ftr-row-bottom { flex-direction: column; gap: 4px; align-items: flex-start; }
}

/* Preserve old class names so any JS referencing them is quiet */
.footer-row, .footer-brand, .footer-contact, .footer-disclaim, .footer-title { display: none; }
.footer-link { display: none; }

.muted { color: var(--text-muted); }
.mono { font-family: var(--mono); }

/* ============================================================
   15-min binary flow card (right column, below setup)
   ============================================================ */
.flow15-grid { padding: 10px 14px 14px; }

.flow15-strike-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 6px 0 10px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 8px;
}
.flow15-strike-row .mono { font-size: 20px; font-weight: 700; color: var(--text); }

.flow15-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}
.flow15-table th {
  font-weight: 500;
  text-align: left;
  padding: 7px 6px;
  color: var(--text-muted);
}
.flow15-table thead th {
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-dim);
  font-weight: 600;
  border-bottom: 1px solid var(--line);
}
.flow15-table td.num {
  padding: 7px 6px;
  text-align: right;
  font-size: 16px;
  color: var(--text);
}
.flow15-table tbody tr + tr th,
.flow15-table tbody tr + tr td { border-top: 1px solid var(--line); }

.flow15-bias-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
}
.flow15-bias-cell {
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.flow15-bias-cell .mono {
  font-size: 20px;
  font-weight: 700;
  color: var(--text);
}
.flow15-bias-cell .mono.up { color: var(--pos); }
.flow15-bias-cell .mono.down { color: var(--neg); }

/* Δ vs VWAP row — customer profit/underwater coloring */
.flow15-table td.mono.up   { color: var(--pos); font-weight: 600; }
.flow15-table td.mono.down { color: var(--neg); font-weight: 600; }
.flow15-delta-row th       { font-weight: 600; }
.flow15-delta-row td.mono.up::after   { content: " ▲"; font-size: 0.85em; opacity: 0.7; }
.flow15-delta-row td.mono.down::after { content: " ▼"; font-size: 0.85em; opacity: 0.7; }

/* ============================================================
   Customer flow underwater map (per-strike VWAP vs mid)
   ============================================================ */
.underwater-card .card-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.underwater-toggle {
  display: inline-flex;
  gap: 0;
  border: 1px solid var(--line);
  border-radius: 6px;
  overflow: hidden;
}
.underwater-btn {
  background: transparent;
  border: none;
  color: var(--text-muted);
  padding: 6px 14px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: background 120ms, color 120ms;
}
.underwater-btn:hover { background: var(--bg-elev); color: var(--text); }
.underwater-btn.active {
  background: var(--accent);
  color: white;
}
.underwater-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 16px;
}
.underwater-table thead th {
  text-align: right;
  font-weight: 600;
  color: var(--text-muted);
  padding: 9px 12px;
  font-size: 14px;
  border-bottom: 1px solid var(--line);
}
.underwater-table thead tr:first-child th {
  text-align: center;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  border-bottom: 1px solid var(--line-faint, var(--line));
}
.underwater-table thead th:first-child { text-align: left; }
.underwater-table tbody td {
  padding: 9px 12px;
  border-bottom: 1px solid var(--line-faint, var(--line));
  font-family: var(--mono-font, ui-monospace, monospace);
  text-align: right;
}
.underwater-table tbody td:first-child { text-align: left; font-weight: 600; }
.underwater-table tbody tr.is-spot { background: rgba(255, 255, 255, 0.02); }
.underwater-table tbody tr.is-spot td:first-child { color: var(--accent); }
.underwater-table td.delta.up   { color: var(--pos); font-weight: 600; }
.underwater-table td.delta.down { color: var(--neg); font-weight: 600; }
.underwater-table td.delta.up::after   { content: " ▲"; font-size: 0.85em; opacity: 0.7; }
.underwater-table td.delta.down::after { content: " ▼"; font-size: 0.85em; opacity: 0.7; }
.underwater-table td.zero { color: var(--text-muted); }
/* Visually separate YES and NO column groups */
.underwater-table th:nth-child(5), .underwater-table td:nth-child(5) {
  border-right: 1px solid var(--line);
  padding-right: 16px;
}
.underwater-table th:nth-child(6), .underwater-table td:nth-child(6) {
  padding-left: 16px;
}

/* ============================================================
   Flow history card (full width, two stacked charts)
   ============================================================ */
.flowhist-controls {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  align-items: center;
}
.flowhist-tabs {
  display: inline-flex;
  gap: 4px;
  flex-wrap: wrap;
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 3px;
  background: var(--bg-card);
}
.flowhist-tab {
  padding: 5px 12px;
  border: none;
  background: transparent;
  color: var(--text-muted);
  font-size: 13px;
  font-weight: 600;
  font-family: var(--mono);
  cursor: pointer;
  border-radius: 4px;
  transition: background 80ms ease, color 80ms ease;
  white-space: nowrap;
}
.flowhist-tab:hover { background: var(--bg-table-alt); color: var(--text); }
.flowhist-tab.active {
  background: var(--accent);
  color: #fff;
}
.flowhist-tab.live::before {
  content: "● ";
  color: var(--pos);
  margin-right: 2px;
}
.flowhist-tab.live.active::before { color: #fff; }
.flowhist-toggle {
  display: inline-flex;
  gap: 0;
  border: 1px solid var(--line);
  border-radius: 6px;
  overflow: hidden;
  font-family: var(--sans);
}
.flowhist-btn {
  padding: 6px 16px;
  border: none;
  background: var(--bg-card);
  color: var(--text-muted);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  font-family: inherit;
  transition: background 80ms ease, color 80ms ease;
}
.flowhist-btn + .flowhist-btn { border-left: 1px solid var(--line); }
.flowhist-btn:hover { background: var(--bg-table-alt); color: var(--text); }
.flowhist-btn.active {
  background: var(--accent);
  color: #fff;
}

.flowhist-status {
  padding: 16px 18px;
  font-size: 14px;
  color: var(--text-muted);
  font-style: italic;
  border-bottom: 1px solid var(--line);
}
.flowhist-status.hidden { display: none; }
.flowhist-status.error { color: var(--neg); font-style: normal; }

.flowhist-charts {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
}

.flowhist-chart-wrap {
  padding: 10px 14px 14px;
}
.flowhist-chart-wrap + .flowhist-chart-wrap { border-top: 1px solid var(--line); }

/* CHANGELOG_SERIAL.md #165 — UX polish P1 — dropped text-transform:uppercase
   so these titles render in their authored sentence case (e.g. "Customer
   taker volume — YES vs NO (cumulative)", "Pain meter — mid minus VWAP")
   instead of YELLING in all caps. Acronyms (YES/NO/VWAP) stay capitalized in
   the source. Letter-spacing relaxed to suit normal-case text. */
.flowhist-chart-title {
  font-size: 18px;
  letter-spacing: 0.01em;
  color: var(--text-muted);
  font-weight: 800;
  margin-bottom: 8px;
}

/* CHANGELOG_SERIAL.md #148 — Pain Meter history select row.
   Flex row so the title and dropdown sit on one line; title takes the slack. */
.flowhist-chart-title-row {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 8px;
  flex-wrap: wrap;
}
.flowhist-chart-title-row .flowhist-chart-title {
  margin-bottom: 0;
  flex: 1 1 auto;
}
.pain-hist-select {
  flex: 0 0 auto;
  font-size: 13px;
  font-weight: 600;
  font-family: var(--sans);
  color: var(--text);
  background: var(--bg-card);
  border: 1px solid var(--line-strong);
  border-radius: 4px;
  padding: 4px 10px;
  cursor: pointer;
  max-width: 210px;
}
.pain-hist-select:focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.flowhist-chart-area {
  position: relative;
  height: 260px;
}

/* ============================================================
   Ralph chat: floating widget bottom-right
   ============================================================ */
#ralph-root {
  position: fixed;
  bottom: 24px;
  right: 24px;
  z-index: 9999;
  font-family: var(--sans);
}

.ralph-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: var(--bg-ticker);
  color: #fff;
  border: none;
  padding: 11px 18px 11px 14px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.01em;
  cursor: pointer;
  box-shadow: 0 4px 18px rgba(26, 31, 46, 0.22), 0 1px 4px rgba(26, 31, 46, 0.12);
  transition: transform 100ms ease, box-shadow 100ms ease;
}
.ralph-toggle:hover {
  transform: translateY(-1px);
  box-shadow: 0 6px 22px rgba(26, 31, 46, 0.28), 0 2px 6px rgba(26, 31, 46, 0.16);
}
.ralph-toggle-icon { font-size: 15px; }
.ralph-toggle-label { letter-spacing: 0.02em; }
.ralph-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #4ade80;
  margin-left: 2px;
  box-shadow: 0 0 0 0 rgba(74, 222, 128, 0.5);
  animation: ralph-pulse 2.4s infinite ease-out;
}
@keyframes ralph-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(74, 222, 128, 0.5); }
  70%  { box-shadow: 0 0 0 7px rgba(74, 222, 128, 0); }
  100% { box-shadow: 0 0 0 0 rgba(74, 222, 128, 0); }
}

.ralph-panel {
  display: none;
  position: absolute;
  bottom: 56px;
  right: 0;
  width: 380px;
  max-width: calc(100vw - 32px);
  height: 540px;
  max-height: calc(100vh - 120px);
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 12px 38px rgba(26, 31, 46, 0.18), 0 4px 12px rgba(26, 31, 46, 0.10);
  flex-direction: column;
  overflow: hidden;
}
#ralph-root.ralph-open .ralph-panel { display: flex; }
#ralph-root.ralph-open .ralph-toggle { display: none; }

.ralph-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 14px;
  border-bottom: 1px solid var(--line);
  background: var(--bg-table-alt);
}
.ralph-header-left { display: flex; align-items: center; gap: 10px; }
.ralph-avatar {
  width: 32px; height: 32px;
  border-radius: 50%;
  background: linear-gradient(135deg, #0052cc, #28b45a);
  color: #fff;
  font-size: 14px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.ralph-name { font-size: 14px; font-weight: 700; color: var(--text); }
.ralph-sub  { font-size: 11px; color: var(--text-muted); margin-top: 1px; }

.ralph-close {
  background: transparent;
  border: none;
  font-size: 22px;
  line-height: 1;
  color: var(--text-muted);
  cursor: pointer;
  padding: 4px 8px;
  border-radius: 4px;
}
.ralph-close:hover { background: rgba(0,0,0,0.05); color: var(--text); }

.ralph-messages {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  background: var(--bg-card);
}

.ralph-greeting {
  font-size: 13px;
  color: var(--text);
  line-height: 1.5;
}
.ralph-greeting p { margin: 0 0 6px; }
.ralph-greeting-sub { color: var(--text-muted); font-size: 12px; }

.ralph-chips {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 6px;
}
.ralph-chip {
  text-align: left;
  background: var(--bg-table-alt);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 8px 12px;
  font-size: 12.5px;
  color: var(--text);
  cursor: pointer;
  font-family: var(--sans);
  line-height: 1.4;
  transition: background 80ms ease, border-color 80ms ease;
}
.ralph-chip:hover { background: #eef2f7; border-color: var(--accent); color: var(--accent); }
.ralph-chip:disabled { opacity: 0.5; cursor: not-allowed; }

.ralph-msg {
  max-width: 88%;
  padding: 9px 12px;
  border-radius: 12px;
  font-size: 13px;
  line-height: 1.45;
  word-wrap: break-word;
}
.ralph-msg.user {
  align-self: flex-end;
  background: var(--accent);
  color: #fff;
  border-bottom-right-radius: 4px;
}
.ralph-msg.assistant {
  align-self: flex-start;
  background: var(--bg-table-alt);
  border: 1px solid var(--line);
  color: var(--text);
  border-bottom-left-radius: 4px;
}
.ralph-msg.assistant strong { color: var(--text); font-weight: 600; }
.ralph-msg.thinking {
  color: var(--text-muted);
  font-style: italic;
}
.ralph-msg.error {
  background: rgba(197, 34, 31, 0.06);
  border: 1px solid rgba(197, 34, 31, 0.2);
  color: var(--neg);
}
.ralph-msg.notice {
  background: rgba(0, 82, 204, 0.06);
  border: 1px solid rgba(0, 82, 204, 0.2);
  color: var(--accent);
  font-size: 12px;
  text-align: center;
  align-self: center;
}

.ralph-form {
  display: flex;
  gap: 8px;
  padding: 10px;
  border-top: 1px solid var(--line);
  background: var(--bg-card);
}
.ralph-input {
  flex: 1;
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 8px 12px;
  font-size: 13px;
  font-family: var(--sans);
  color: var(--text);
  background: var(--bg-card);
  outline: none;
}
.ralph-input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(0, 82, 204, 0.12); }
.ralph-input:disabled { background: var(--bg-table-alt); color: var(--text-dim); }

.ralph-send {
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: 6px;
  width: 36px;
  height: 36px;
  font-size: 16px;
  font-weight: 700;
  cursor: pointer;
  transition: background 80ms ease;
}
.ralph-send:hover { background: var(--accent-hover); }
.ralph-send:disabled { background: var(--text-dim); cursor: not-allowed; }

.ralph-footer {
  padding: 6px 12px 8px;
  border-top: 1px solid var(--line);
  background: var(--bg-table-alt);
}
.ralph-footer-note {
  font-size: 10.5px;
  color: var(--text-dim);
  font-style: italic;
}

/* ============================================================
   CHANGELOG_SERIAL.md #094 — Cmd+K search palette modal
   ============================================================ */
.aq-palette-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.45);
  z-index: 900;
}
.aq-palette-backdrop.is-open { display: block; }

.aq-palette {
  position: fixed;
  top: 80px;
  left: 50%;
  transform: translateX(-50%);
  width: min(640px, calc(100vw - 32px));
  z-index: 901;
  border-radius: 14px;
  border: 1px solid var(--line-strong);
  background: var(--bg-card);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35), 0 4px 12px rgba(0, 0, 0, 0.18);
  overflow: hidden;
}
.aq-palette[hidden] { display: none; }

.aq-palette-inner { display: flex; flex-direction: column; }

.aq-palette-search-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--line);
}
.aq-palette-search-icon { flex-shrink: 0; color: var(--text-muted); }
.aq-palette-input {
  flex: 1 1 auto;
  background: transparent;
  border: none;
  outline: none;
  font-family: var(--sans);
  font-size: 15px;
  font-weight: 500;
  color: var(--text);
  caret-color: var(--accent);
  min-width: 0;
}
.aq-palette-input::placeholder { color: var(--text-dim); }
.aq-palette-esc-hint {
  flex-shrink: 0;
  font-family: var(--mono);
  font-size: 10px;
  padding: 2px 6px;
  border: 1px solid var(--btn-border);
  border-radius: 4px;
  background: var(--bg-table-alt);
  color: var(--text-muted);
  line-height: 1.5;
}

.aq-palette-list {
  list-style: none;
  margin: 0;
  padding: 6px 0;
  max-height: 380px;
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* Group label separator */
.aq-palette-group {
  padding: 6px 16px 2px;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--text-dim);
}

.aq-palette-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 16px;
  cursor: pointer;
  font-size: 14px;
  color: var(--text);
  transition: background 80ms ease;
  outline: none;
}
.aq-palette-item:hover,
.aq-palette-item[aria-selected="true"] {
  background: var(--bg-table-alt);
}
.aq-palette-item[aria-selected="true"] {
  background: rgba(78, 161, 255, 0.12);
}
[data-theme="dark"] .aq-palette-item[aria-selected="true"] {
  background: rgba(78, 161, 255, 0.18);
}

.aq-palette-item-icon {
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  border-radius: 7px;
  background: var(--bg-table-alt);
  border: 1px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  color: var(--text-muted);
}
.aq-palette-item-body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.aq-palette-item-title {
  font-size: 14px;
  font-weight: 500;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.aq-palette-item-subtitle {
  font-size: 11px;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.aq-palette-item-title mark,
.aq-palette-item-subtitle mark {
  background: rgba(250, 204, 21, 0.35);
  color: inherit;
  border-radius: 2px;
  padding: 0 1px;
}
.aq-palette-item-kbd {
  flex-shrink: 0;
  font-family: var(--mono);
  font-size: 10px;
  padding: 2px 6px;
  border: 1px solid var(--btn-border);
  border-radius: 4px;
  background: var(--bg-table-alt);
  color: var(--text-dim);
}
.aq-palette-item-badge {
  flex-shrink: 0;
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  padding: 1px 5px;
  border-radius: 3px;
  letter-spacing: 0.06em;
}
.aq-palette-badge-recent {
  background: rgba(167, 139, 250, 0.18);
  color: #a78bfa;
}

.aq-palette-footer {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 8px 16px;
  border-top: 1px solid var(--line);
  font-size: 11px;
  color: var(--text-dim);
  background: var(--bg-table-alt);
  flex-wrap: wrap;
}
.aq-palette-footer kbd {
  font-family: var(--mono);
  font-size: 10px;
  padding: 1px 5px;
  border: 1px solid var(--btn-border);
  border-radius: 3px;
  background: var(--bg-card);
  color: var(--text-muted);
  margin-right: 3px;
}

/* ============================================================
   CHANGELOG_SERIAL.md #093 — mobile header overrides (480px)
   kept here near the palette block for discoverability; the main
   480px block at EOF also touches .site-header.
   ============================================================ */

@media (max-width: 480px) {
  #ralph-root { bottom: 16px; right: 16px; left: 16px; }
  .ralph-panel {
    width: auto;
    right: 0;
    left: 0;
    bottom: 56px;
    height: 70vh;
  }
}

/* ============================================================
   Capitulation pressure card
   ============================================================ */
.capit-card .card-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.capit-toggle {
  display: inline-flex;
  gap: 0;
  /* CHANGELOG_SERIAL.md #025 — upgrade outer segmented-control border
     to high-contrast --btn-border so the control reads as actionable
     in both themes. */
  border: 1px solid var(--btn-border);
  border-radius: 6px;
  overflow: hidden;
}
.capit-btn {
  background: transparent;
  border: none;
  color: var(--text-muted);
  padding: 4px 12px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: background 120ms, color 120ms;
}
.capit-btn:hover { background: var(--bg-elev); color: var(--text); }
.capit-btn.active { background: var(--accent); color: white; }

.capit-live-row {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
  gap: 18px;
  padding: 12px 16px;
  margin: 8px 0 12px;
  background: rgba(180, 80, 30, 0.04);
  border: 1px solid rgba(180, 80, 30, 0.10);
  border-radius: 6px;
}
.capit-live-cell {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.capit-live-label {
  font-size: 14px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  font-weight: 600;
}
.capit-live-value {
  font-size: 48px;
  font-weight: 500;
  font-family: var(--mono);
  color: var(--text);
  line-height: 1.1;
  letter-spacing: -0.025em;
  font-variant-numeric: tabular-nums;
}
.capit-live-bar {
  display: inline-block;
  height: 6px;
  width: 100%;
  background: var(--line);
  border-radius: 3px;
  overflow: hidden;
  margin-top: 4px;
}
.capit-live-fill {
  display: block;
  height: 100%;
  width: 0%;
  background: var(--pos);
  transition: width 250ms ease-out, background 250ms ease-out;
}
.capit-live-tier {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--pos);
  margin-top: 2px;
}
.capit-live-tier.tier-low    { color: var(--pos); }
.capit-live-tier.tier-mid    { color: var(--warn, #c67); }
.capit-live-tier.tier-high   { color: var(--neg); }
.capit-live-tier.tier-extreme{ color: var(--neg); text-shadow: 0 0 6px rgba(230,60,80,0.4); animation: capit-pulse 1s infinite; }
.capit-percentile {
  display: block;
  font-size: 12px;
  font-family: var(--mono-font, ui-monospace, monospace);
  color: var(--text-muted);
  margin-top: 4px;
  letter-spacing: 0.02em;
}
@keyframes capit-pulse { 50% { opacity: 0.5; } }
.capit-slider {
  width: 100%;
  margin-top: 6px;
  accent-color: var(--accent);
}

/* Secondary indicators row (acceleration, urgency, cascade flag) */
.capit-secondary-row {
  display: grid;
  grid-template-columns: 1fr 1fr 1.5fr;
  gap: 14px;
  padding: 10px 16px;
  margin-bottom: 12px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--bg-card);
}
.capit-sec-cell { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.capit-sec-label {
  font-size: 14px; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--text-muted); font-weight: 600;
}
.capit-sec-value {
  font-size: 32px; font-weight: 500; color: var(--text); line-height: 1.15;
  font-family: var(--mono);
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.capit-sec-sub { font-size: 13px; color: var(--text-muted); }
.capit-cascade-armed {
  color: var(--neg);
  text-shadow: 0 0 6px rgba(230,60,80,0.3);
  animation: capit-pulse 1.4s infinite;
}
.capit-cascade-safe { color: var(--pos); }

/* Sensitivity grid */
.capit-sensitivity {
  padding: 10px 16px;
  margin-bottom: 12px;
  border: 1px solid var(--line);
  border-radius: 6px;
}
.capit-sens-header {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; margin-bottom: 10px; flex-wrap: wrap;
}
.capit-sens-title {
  font-size: 14px; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--text-muted); font-weight: 600;
}
.capit-sens-controls { display: flex; gap: 12px; align-items: center; }
.capit-sens-control-label { font-size: 12px; color: var(--text-muted); font-weight: 600; }
.capit-sens-select {
  font-size: 13px; padding: 4px 8px; margin-left: 6px;
  border: 1px solid var(--line); border-radius: 4px;
  background: var(--bg-elev); color: var(--text);
  font-family: var(--mono-font, ui-monospace, monospace); cursor: pointer;
}
.capit-sens-chart-area {
  width: 100%; height: 360px; position: relative;
}
/* ============================================================
   Live signals card — pattern badges (anti-consensus, smart money, capit)
   ============================================================ */
.signals-body {
  padding: 14px 18px 18px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.signal-badge {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 16px;
  border-radius: 6px;
  border-left: 4px solid;
  background: rgba(0,0,0,0.02);
}
.signal-badge.fade  { border-left-color: var(--neg);            background: rgba(230,60,80,0.06); }
.signal-badge.smart { border-left-color: var(--pos);            background: rgba(40,180,90,0.06); }
.signal-badge.migration { border-left-color: var(--warn, #c67); background: rgba(220,140,40,0.06); }
.signal-badge.capit { border-left-color: var(--neg);            background: rgba(230,60,80,0.06); }
.signal-icon {
  font-size: 26px;
  line-height: 1;
  width: 36px;
  text-align: center;
}
.signal-content { flex: 1; min-width: 0; }
.signal-title {
  font-size: 18px;
  font-weight: 800;
  color: var(--text);
  letter-spacing: 0.01em;
}
.signal-detail {
  font-size: 14px;
  color: var(--text-muted);
  margin-top: 4px;
  font-family: var(--mono-font, ui-monospace, monospace);
}
.signal-empty {
  padding: 18px;
  text-align: center;
  color: var(--text-muted);
  font-style: italic;
  font-size: 14px;
}
.signal-x-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: rgba(0,0,0,0.04);
  color: var(--text-muted);
  text-decoration: none;
  flex-shrink: 0;
  transition: background 120ms, color 120ms, transform 120ms;
}
.signal-x-btn:hover {
  background: #000;
  color: #fff;
  transform: scale(1.05);
}
.signal-x-btn svg { display: block; }

/* ============================================================
   Max pain card — total customer $ loss by hypothetical settle
   ============================================================ */
.maxpain-meta {
  padding: 10px 18px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 14px;
  font-size: 14px;
  border-bottom: 1px solid var(--line);
}
.maxpain-meta-cell {
  display: flex; flex-direction: column; gap: 4px;
}
.maxpain-meta-label {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--text-muted); font-weight: 600;
}
.maxpain-meta-value {
  font-size: 22px; font-weight: 500; color: var(--text);
  font-family: var(--mono-font, ui-monospace, monospace);
  line-height: 1.1;
}
.maxpain-meta-sub {
  font-size: 12px; color: var(--text-muted);
}

.capit-sens-pressure.tier-low,    .capit-sens-tier.tier-low    { color: var(--pos); }
.capit-sens-pressure.tier-mid,    .capit-sens-tier.tier-mid    { color: var(--warn, #c67); }
.capit-sens-pressure.tier-high,   .capit-sens-tier.tier-high   { color: var(--neg); }
.capit-sens-pressure.tier-extreme,.capit-sens-tier.tier-extreme{ color: var(--neg); }

/* ============ Edge Radar panel ============ */
/* CHANGELOG_SERIAL.md #274 — margin-top removed; now inside .oi-radar-col which handles spacing */
.edge-radar-card {
  margin-top: 0;
}
.edge-radar-regime {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 14px;
  border-radius: 8px;
  font-size: 14px; font-weight: 600;
  background: rgba(220, 140, 40, 0.10);
  color: rgba(180, 100, 20, 1);
  border: 1px solid rgba(220, 140, 40, 0.40);
  margin: 12px 0;
}
.edge-radar-regime.cascade {
  background: rgba(230, 60, 80, 0.12);
  color: rgba(180, 30, 50, 1);
  border-color: rgba(230, 60, 80, 0.55);
}
.edge-radar-regime.pin {
  background: rgba(40, 180, 90, 0.10);
  color: rgba(20, 130, 60, 1);
  border-color: rgba(40, 180, 90, 0.40);
}
.edge-radar-regime-icon { font-size: 16px; }

.edge-radar-walls {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 10px;
  margin: 16px 0;
}
.edge-radar-wall, .edge-radar-spot {
  text-align: center;
  padding: 14px 10px;
  border-radius: 10px;
  background: rgba(0,0,0,0.025);
  border: 1px solid rgba(0,0,0,0.08);
}
.edge-radar-spot {
  background: rgba(80, 130, 220, 0.10);
  border-color: rgba(80, 130, 220, 0.35);
}
.wall-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 4px;
}
.wall-strike {
  font-size: 24px;
  font-weight: 800;
  margin: 2px 0;
}
.wall-meta {
  font-size: 12px;
  color: var(--text-muted);
}

.edge-radar-table-wrap {
  overflow-x: auto;
  margin-top: 8px;
}
.edge-radar-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}
.edge-radar-table th {
  text-align: left;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  padding: 8px 10px;
  border-bottom: 2px solid rgba(0,0,0,0.10);
}
.edge-radar-table td {
  padding: 12px 10px;
  border-bottom: 1px solid rgba(0,0,0,0.06);
  font-weight: 600;
}
.edge-radar-table tr.row-high { background: rgba(40, 180, 90, 0.06); }
.edge-radar-table tr.row-medium { background: rgba(80, 130, 220, 0.05); }
.edge-radar-table tr.row-low { background: rgba(160, 160, 160, 0.04); }
.edge-radar-table tr.row-avoid { background: rgba(230, 60, 80, 0.05); opacity: 0.75; }
.edge-radar-table tr.row-best {
  outline: 2px solid rgba(40, 180, 90, 0.55);
  outline-offset: -2px;
  position: relative;
}
.edge-radar-table tr.row-best td:first-child::before {
  content: "★ ";
  color: rgba(40, 180, 90, 1);
  font-weight: 900;
}
.edge-radar-conviction {
  display: inline-block;
  padding: 4px 10px;
  border-radius: 6px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.edge-radar-conviction.high {
  background: rgba(40, 180, 90, 0.15);
  color: rgba(20, 130, 60, 1);
}
.edge-radar-conviction.medium {
  background: rgba(80, 130, 220, 0.12);
  color: rgba(50, 90, 180, 1);
}
.edge-radar-conviction.low {
  background: rgba(160, 160, 160, 0.15);
  color: var(--text-muted);
}
.edge-radar-conviction.avoid {
  background: rgba(230, 60, 80, 0.15);
  color: rgba(180, 30, 50, 1);
}
.edge-radar-edge-pos { color: rgba(20, 130, 60, 1); font-weight: 700; }
.edge-radar-edge-neg { color: rgba(180, 30, 50, 1); font-weight: 700; }

.edge-radar-rationale {
  margin-top: 14px;
  padding: 12px 14px;
  border-radius: 8px;
  background: rgba(40, 180, 90, 0.06);
  border: 1px solid rgba(40, 180, 90, 0.25);
}
.rationale-title {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(20, 130, 60, 1);
  margin-bottom: 4px;
}
.rationale-text {
  font-size: 14px;
  line-height: 1.5;
}

.edge-radar-note {
  margin-top: 12px;
  padding: 10px 14px;
  border-radius: 8px;
  background: rgba(160, 160, 160, 0.08);
  color: var(--text-muted);
  font-size: 13px;
  font-style: italic;
}

.edge-radar-empty {
  text-align: center;
  color: var(--text-muted);
  font-style: italic;
  padding: 24px;
}

@media (max-width: 720px) {
  .edge-radar-walls { grid-template-columns: 1fr; }
  .wall-strike { font-size: 20px; }
  .edge-radar-table { font-size: 12px; }
  .edge-radar-table th, .edge-radar-table td { padding: 6px 6px; }
}

/* ============ Edge Map card (#281) ============
   CHANGELOG_SERIAL.md #281 — per-strike fair value vs market price screen.
   Colors use locked Tailwind green-500 (34,197,94) / red-500 (239,68,68) palette.
   Row background intensity is proportional to |yes_edge|, capped at 8¢ (0.08). */
.edge-map-card {
  margin-top: 12px;
}
.edge-map-body {
  padding: 0 0 4px;
}
.edge-map-table-wrap {
  overflow-x: auto;
}
.edge-map-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.edge-map-table th {
  text-align: left;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  padding: 8px 10px 6px;
  border-bottom: 2px solid var(--line);
  white-space: nowrap;
}
.edge-map-table td {
  padding: 7px 10px;
  border-bottom: 1px solid var(--line);
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
}
/* ATM row: subtle left border accent to orient Pete */
.edge-map-table tr.em-atm td:first-child {
  border-left: 3px solid rgba(125, 211, 252, 0.85);
  padding-left: 7px;
}
/* Row tint: green when YES cheap (edge>0), red when YES rich (edge<0).
   Intensity applied via inline --em-alpha CSS var set by JS. */
.edge-map-table tr.em-cheap {
  background: rgba(34, 197, 94, var(--em-alpha, 0.05));
}
.edge-map-table tr.em-rich {
  background: rgba(239, 68, 68, var(--em-alpha, 0.05));
}
/* Edge column: signed color */
.em-edge-pos { color: rgb(34, 197, 94); font-weight: 700; }  /* green-500 */
.em-edge-neg { color: rgb(239, 68, 68);  font-weight: 700; }  /* red-500 */
.em-edge-zero { color: var(--text-muted); }
/* Verdict badge: pill shown for CHEAP_YES / CHEAP_NO */
.em-badge {
  display: inline-block;
  padding: 2px 7px;
  border-radius: 4px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-family: var(--sans);
  white-space: nowrap;
}
.em-badge.cheap-yes {
  background: rgba(34, 197, 94, 0.15);
  color: rgb(21, 128, 61);   /* green-700 */
  border: 1px solid rgba(34, 197, 94, 0.35);
}
.em-badge.cheap-no {
  background: rgba(239, 68, 68, 0.14);
  color: rgb(185, 28, 28);   /* red-700 */
  border: 1px solid rgba(239, 68, 68, 0.35);
}
[data-theme="dark"] .em-badge.cheap-yes { color: rgb(74, 222, 128); }  /* green-400 on dark */
[data-theme="dark"] .em-badge.cheap-no  { color: rgb(248, 113, 113); } /* red-400 on dark */
.edge-map-empty {
  text-align: center;
  color: var(--text-muted);
  font-style: italic;
  padding: 20px;
  font-family: var(--sans);
  font-size: 13px;
}
.edge-map-efficient {
  padding: 8px 14px 10px;
  font-size: 12px;
  color: var(--text-muted);
  font-style: italic;
}
/* CHANGELOG_SERIAL.md #293 — Confluence Map: OI confirmation chip + no-wall note + recenter flags */
/* "OI v" chip: small green pill that confirms OI wall agrees with fair-value direction */
.em-oi-chip {
  display: inline-block;
  padding: 1px 5px;
  border-radius: 3px;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-family: var(--sans);
  white-space: nowrap;
  background: rgba(34, 197, 94, 0.18);   /* green-500 at low opacity */
  color: rgb(21, 128, 61);               /* green-700 */
  border: 1px solid rgba(34, 197, 94, 0.35);
  vertical-align: middle;
  margin-left: 4px;
}
[data-theme="dark"] .em-oi-chip { color: rgb(74, 222, 128); }  /* green-400 on dark */
/* Dim "edge Nc · no wall" note: value-edge present but OI wall absent */
.em-no-wall {
  font-size: 10px;
  color: var(--text-muted);
  font-style: italic;
  font-family: var(--sans);
  white-space: nowrap;
}
/* Recenter note in sub-line (feeds detected recentering) */
.em-recenter {
  display: inline-block;
  font-style: normal;
  font-weight: 600;
  font-size: 11px;
  color: rgb(125, 211, 252);   /* sky-300 — informational, not alarming */
  margin-left: 4px;
}
/* Model resyncing amber flag: abs(offset) > 30 — signals are stale/misaligned */
.em-resyncing {
  display: inline-block;
  font-style: normal;
  font-weight: 700;
  font-size: 11px;
  color: rgb(250, 204, 21);   /* yellow-400 — amber warning */
  margin-left: 4px;
}
/* Muted version used inside signal cells when resyncing suppresses BUY signals */
.em-resyncing-muted {
  color: rgb(250, 204, 21);
  font-style: italic;
  font-weight: 400;
}
/* CHANGELOG_SERIAL.md #293 — plain-English action row styles */
/* Action cell: wide column holding the full sentence */
.em-action-cell { width: 100%; }
.em-wall-cell   { width: 1%; white-space: nowrap; padding-left: 4px; }
/* BUY YES: green action label */
.em-action-yes {
  font-weight: 700;
  color: rgb(21, 128, 61);   /* green-700 */
  font-family: var(--sans);
}
[data-theme="dark"] .em-action-yes { color: rgb(74, 222, 128); }  /* green-400 on dark */
/* BUY NO: red action label */
.em-action-no {
  font-weight: 700;
  color: rgb(185, 28, 28);   /* red-700 */
  font-family: var(--sans);
}
[data-theme="dark"] .em-action-no { color: rgb(248, 113, 113); }  /* red-400 on dark */
/* Price detail: "pay Nc · worth Nc" in muted mono */
.em-price-detail {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--text-secondary);
}
/* Edge delta: "(+Nc)" highlighted slightly */
.em-edge-delta {
  font-weight: 700;
  color: rgb(34, 197, 94);   /* green-500 */
}
.em-action-no .em-edge-delta,
.em-price-detail + .em-edge-delta { /* keep same green for edge delta regardless of side */ }
/* Wall chip: brick emoji pill */
.em-wall-chip {
  font-size: 14px;
  line-height: 1;
  display: inline-block;
  vertical-align: middle;
  cursor: default;
}
/* Fair-priced strike label */
.em-fair-strike {
  font-family: var(--mono);
  font-weight: 600;
  color: var(--text-secondary);
}
/* "— fairly priced —" text */
.em-fairly-priced {
  font-size: 11px;
  color: var(--text-muted);
  font-style: italic;
  font-family: var(--sans);
}

/* ============ Freshness banner UNDER live feed ============ */
.feed-freshness {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 10px 0 0;
  padding: 10px 16px;
  border-radius: 6px;
  background: rgba(74, 222, 128, 0.10);
  color: #4ade80;
  border: 1.5px solid rgba(74, 222, 128, 0.30);
  font-variant-numeric: tabular-nums;
  transition: background-color 0.3s, border-color 0.3s, color 0.3s;
}
.feed-freshness.stale-warn {
  background: rgba(251, 191, 36, 0.10);
  color: #fbbf24;
  border-color: rgba(251, 191, 36, 0.40);
}
.feed-freshness.stale-alert {
  background: rgba(239, 68, 68, 0.14);
  color: #ef4444;
  border-color: rgba(239, 68, 68, 0.50);
  animation: freshness-pulse 1.4s infinite;
}
.feed-freshness-dot {
  width: 12px; height: 12px; border-radius: 50%;
  background: currentColor;
  animation: freshness-blink 2s infinite;
  flex-shrink: 0;
}
.feed-freshness-label {
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.10em;
  opacity: 0.75;
  text-transform: uppercase;
}
.feed-freshness-time {
  font-family: var(--mono);
  font-size: 22px;
  font-weight: 800;
  letter-spacing: 0.02em;
}
.feed-freshness-age {
  font-family: var(--mono);
  font-size: 15px;
  font-weight: 600;
  opacity: 0.85;
  margin-left: auto;
}
@media (max-width: 720px) {
  .feed-freshness-time { font-size: 18px; }
  .feed-freshness-label { font-size: 11px; }
  .feed-freshness-age { font-size: 13px; }
}

/* ============ Legacy freshness pill (kept for tab-nav badge that still uses it) ============ */
.freshness-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  border-radius: 18px;
  font-size: 13px;
  font-weight: 700;
  background: rgba(40, 180, 90, 0.10);
  color: rgba(20, 130, 60, 1);
  border: 1px solid rgba(40, 180, 90, 0.35);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  transition: background-color 0.3s, border-color 0.3s, color 0.3s;
}
.freshness-pill.stale-warn {
  background: rgba(220, 140, 40, 0.10);
  color: rgba(170, 100, 20, 1);
  border-color: rgba(220, 140, 40, 0.40);
}
.freshness-pill.stale-alert {
  background: rgba(230, 60, 80, 0.12);
  color: rgba(180, 30, 50, 1);
  border-color: rgba(230, 60, 80, 0.50);
  animation: freshness-pulse 1.4s infinite;
}
@keyframes freshness-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.6; }
}
.freshness-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: currentColor;
  display: inline-block;
  animation: freshness-blink 2s infinite;
}
@keyframes freshness-blink {
  0%, 60% { opacity: 1; }
  80% { opacity: 0.35; }
}
.freshness-time {
  font-weight: 800;
}
.freshness-age {
  font-weight: 500;
  opacity: 0.8;
  font-size: 12px;
}

/* Tab-nav freshness badge (always visible when sticky) */
.tab-freshness {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 14px;
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  background: rgba(40, 180, 90, 0.12);
  color: rgba(20, 130, 60, 1);
  border: 1px solid rgba(40, 180, 90, 0.35);
  white-space: nowrap;
  transition: background-color 0.3s, border-color 0.3s, color 0.3s;
}
.tab-freshness.stale-warn {
  background: rgba(220, 140, 40, 0.12);
  color: rgba(170, 100, 20, 1);
  border-color: rgba(220, 140, 40, 0.40);
}
.tab-freshness.stale-alert {
  background: rgba(230, 60, 80, 0.14);
  color: rgba(180, 30, 50, 1);
  border-color: rgba(230, 60, 80, 0.50);
}
@media (max-width: 720px) {
  .freshness-age { display: none; }
  .tab-freshness { font-size: 11px; padding: 3px 8px; }
}

/* ============ Hourly ATR stat tile ============ */
.atr-tile {
  margin-bottom: 16px;
  padding: 16px 18px;
}
.atr-tile-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 12px;
}
.atr-tile-title {
  font-size: 14px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text);
  margin: 0;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.atr-tile-asof {
  font-size: 11px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.atr-tile-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 12px;
}
.atr-stat {
  padding: 10px 12px;
  border-radius: 8px;
  background: rgba(0, 0, 0, 0.025);
  border: 1px solid rgba(0, 0, 0, 0.06);
}
.atr-stat-current {
  background: rgba(80, 130, 220, 0.12);
  border-color: rgba(80, 130, 220, 0.35);
}
.atr-stat-expected {
  background: rgba(80, 130, 220, 0.06);
  border-color: rgba(80, 130, 220, 0.20);
}
.atr-stat-similar {
  background: rgba(100, 50, 170, 0.06);
  border-color: rgba(100, 50, 170, 0.20);
}
.atr-stat-label {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 4px;
}
.atr-stat-value {
  font-size: 22px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.atr-stat-sub {
  font-size: 12px;
  color: var(--text-muted);
  margin-top: 2px;
}
.atr-stat-rank.rank-low .atr-stat-value { color: rgba(20, 130, 60, 1); }
.atr-stat-rank.rank-mid .atr-stat-value { color: rgba(180, 110, 20, 1); }
.atr-stat-rank.rank-high .atr-stat-value { color: rgba(180, 30, 50, 1); }
.atr-stat-rank.rank-extreme .atr-stat-value {
  color: rgba(180, 30, 50, 1);
  animation: regime-pulse 1.4s infinite;
}
.atr-tile-note {
  margin-top: 12px;
  padding: 8px 12px;
  border-radius: 6px;
  background: rgba(220, 140, 40, 0.08);
  color: rgba(170, 100, 20, 1);
  font-size: 12px;
  font-style: italic;
}
@media (max-width: 720px) {
  .atr-tile-grid { grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); }
  .atr-stat-value { font-size: 18px; }
}

/* ============ Pin analysis (T-30 to T-0) ============ */
.adi-pin-analysis {
  margin-top: 16px;
  padding: 14px;
  border-radius: 10px;
  background: rgba(0, 0, 0, 0.025);
  border: 1px solid rgba(0, 0, 0, 0.08);
}
.adi-pin-header {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
  margin-bottom: 6px;
}
.adi-pin-verdict {
  font-size: 16px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 4px 12px;
  border-radius: 6px;
  border: 2px solid transparent;
}
.adi-pin-verdict.pin-likely {
  background: rgba(40, 180, 90, 0.15);
  color: rgba(20, 130, 60, 1);
  border-color: rgba(40, 180, 90, 0.40);
}
.adi-pin-verdict.pin-mildly-likely {
  background: rgba(40, 180, 90, 0.08);
  color: rgba(20, 130, 60, 0.95);
  border-color: rgba(40, 180, 90, 0.25);
}
.adi-pin-verdict.mixed {
  background: rgba(160, 160, 160, 0.12);
  color: var(--text-muted);
  border-color: rgba(160, 160, 160, 0.30);
}
.adi-pin-verdict.pin-mildly-unlikely {
  background: rgba(230, 60, 80, 0.08);
  color: rgba(180, 30, 50, 0.95);
  border-color: rgba(230, 60, 80, 0.25);
}
.adi-pin-verdict.pin-unlikely {
  background: rgba(230, 60, 80, 0.15);
  color: rgba(180, 30, 50, 1);
  border-color: rgba(230, 60, 80, 0.45);
}
.adi-pin-prob {
  font-size: 14px;
  font-weight: 700;
  color: var(--text-muted);
}
.adi-pin-prob .prob-num {
  font-size: 20px;
  font-weight: 900;
  color: var(--text);
}
.adi-pin-strike {
  font-size: 13px;
  color: var(--text-muted);
  margin-bottom: 10px;
}
.adi-pin-factors {
  display: grid; gap: 6px;
}
.adi-pin-factor {
  display: grid;
  grid-template-columns: 32px 1fr;
  gap: 10px;
  padding: 6px 10px;
  border-radius: 6px;
  background: rgba(0,0,0,0.02);
  font-size: 13px;
  line-height: 1.4;
}
.adi-pin-factor-score {
  font-weight: 900;
  text-align: center;
  font-size: 14px;
}
.adi-pin-factor-score.pos { color: rgba(20, 130, 60, 1); }
.adi-pin-factor-score.neg { color: rgba(180, 30, 50, 1); }
.adi-pin-factor-score.zero { color: var(--text-muted); }
.adi-pin-factor-text { color: var(--text); }
.adi-pin-factor-name {
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-right: 6px;
}

/* ============ Replay bar ============ */
.replay-bar {
  margin: 4px 0; /* CHANGELOG_SERIAL.md #228 — tightened 12->4 to cut top dead space */
  padding: 10px 14px;
  background: rgba(0, 0, 0, 0.03);
  border: 1px solid rgba(0, 0, 0, 0.08);
  border-radius: 10px;
}
body[data-replay-mode="replay"] .replay-bar {
  background: rgba(140, 80, 200, 0.07);
  border-color: rgba(140, 80, 200, 0.30);
}
.replay-toggle-row {
  display: flex; align-items: center; gap: 14px;
  flex-wrap: wrap;
}
.replay-mode-switch {
  display: inline-flex;
  border: 2px solid rgba(0,0,0,0.15);
  border-radius: 8px;
  overflow: hidden;
}
.replay-mode-btn {
  appearance: none;
  border: 0;
  background: transparent;
  padding: 8px 16px;
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.06em;
  cursor: pointer;
  color: var(--text-muted);
  transition: all 0.15s;
}
.replay-mode-btn:hover {
  background: rgba(0,0,0,0.04);
  color: var(--text);
}
.replay-mode-btn.active {
  background: rgba(40, 180, 90, 0.15);
  color: rgba(20, 130, 60, 1);
}
.replay-mode-btn[data-mode="replay"].active {
  background: rgba(140, 80, 200, 0.15);
  color: rgba(100, 50, 170, 1);
}
.replay-status {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-muted);
}
body[data-replay-mode="replay"] .replay-status {
  color: rgba(100, 50, 170, 1);
}

.replay-controls {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid rgba(0,0,0,0.08);
}
.replay-row {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
  flex-wrap: wrap;
}
.replay-row:last-child { margin-bottom: 0; }
.replay-label {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.replay-select {
  flex: 1;
  min-width: 260px;
  padding: 8px 10px;
  font-size: 14px;
  font-weight: 600;
  border-radius: 6px;
  border: 1px solid rgba(0,0,0,0.15);
  background: white;
  cursor: pointer;
}

.replay-type-toggle {
  display: inline-flex;
  border: 1px solid rgba(0,0,0,0.15);
  border-radius: 6px;
  overflow: hidden;
}
.replay-type-btn {
  appearance: none;
  border: 0;
  background: transparent;
  padding: 6px 12px;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  color: var(--text-muted);
}
.replay-type-btn.active {
  background: rgba(80, 130, 220, 0.12);
  color: rgba(50, 90, 180, 1);
}

.replay-row-slider {
  display: block;
}
.replay-slider-labels {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: 12px;
  font-weight: 700;
  color: var(--text-muted);
  margin-bottom: 4px;
}
.replay-slider-current {
  font-size: 14px;
  font-weight: 800;
  color: rgba(100, 50, 170, 1);
}
.replay-slider {
  width: 100%;
  height: 8px;
  border-radius: 4px;
  appearance: none;
  background: linear-gradient(to right,
    rgba(230, 60, 80, 0.30) 0%,
    rgba(220, 140, 40, 0.30) 50%,
    rgba(40, 180, 90, 0.30) 100%);
  outline: none;
  cursor: pointer;
}
.replay-slider::-webkit-slider-thumb {
  appearance: none;
  width: 22px; height: 22px;
  border-radius: 50%;
  background: rgba(100, 50, 170, 1);
  border: 3px solid white;
  box-shadow: 0 2px 6px rgba(0,0,0,0.20);
  cursor: pointer;
}
.replay-slider::-moz-range-thumb {
  width: 22px; height: 22px;
  border-radius: 50%;
  background: rgba(100, 50, 170, 1);
  border: 3px solid white;
  box-shadow: 0 2px 6px rgba(0,0,0,0.20);
  cursor: pointer;
}
.replay-slider-keyhint {
  font-size: 11px;
  color: var(--text-muted);
  margin-top: 6px;
  text-align: center;
}

.replay-timeline {
  margin-top: 16px;
  padding: 14px;
  border-radius: 10px;
  background: white;
  border: 1px solid rgba(0,0,0,0.10);
}
.replay-timeline-controls {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
  flex-wrap: wrap;
}
.replay-play-btn {
  appearance: none;
  border: 0;
  background: rgba(100, 50, 170, 1);
  color: white;
  padding: 8px 16px;
  font-size: 13px;
  font-weight: 800;
  border-radius: 6px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  letter-spacing: 0.04em;
}
.replay-play-btn:hover { background: rgba(80, 40, 140, 1); }
.replay-play-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.replay-restart-btn {
  appearance: none;
  border: 1px solid rgba(0,0,0,0.15);
  background: white;
  padding: 8px 12px;
  font-size: 14px;
  border-radius: 6px;
  cursor: pointer;
}
.replay-speed-label {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-left: 8px;
}
.replay-speed-select {
  padding: 6px 10px;
  font-size: 13px;
  font-weight: 600;
  border-radius: 6px;
  border: 1px solid rgba(0,0,0,0.15);
  background: white;
  cursor: pointer;
}
.replay-timeline-status {
  font-size: 12px;
  color: var(--text-muted);
  margin-left: auto;
  font-style: italic;
}
/* CHANGELOG_SERIAL.md #135 — raised from 340px to 460px.
   CHANGELOG_SERIAL.md #136 — raised to 580px for full strike ladder. */
.replay-timeline-chart-wrap {
  position: relative;
  width: 100%;
  height: 580px;
}
.replay-timeline-chart-wrap canvas { width: 100% !important; height: 100% !important; }
.replay-timeline-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin-top: 10px;
  font-size: 12px;
  color: var(--text-muted);
}
.tl-legend-item { display: inline-flex; align-items: center; gap: 5px; }
.tl-swatch { display: inline-block; }
/* CHANGELOG_SERIAL.md #135 — spot swatch updated to white (matches chart line);
   yes/no swatches locked to canonical green-500 / red-500. */
.tl-swatch.tl-spot {
  width: 16px; height: 3px;
  background: rgba(245, 245, 245, 0.95);
}
.tl-swatch.tl-yes {
  width: 11px; height: 11px;
  border-radius: 50%;
  background: rgba(34, 197, 94, 0.80);
  border: 1px solid rgba(21, 128, 61, 1);
}
.tl-swatch.tl-no {
  width: 11px; height: 11px;
  border-radius: 50%;
  background: rgba(239, 68, 68, 0.80);
  border: 1px solid rgba(185, 28, 28, 1);
}
.replay-timeline-caption {
  margin-top: 10px;
  padding: 8px 12px;
  background: rgba(100, 50, 170, 0.06);
  border-radius: 6px;
  font-size: 13px;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  min-height: 20px;
}

.replay-reveal {
  margin-top: 14px;
  padding: 14px;
  border-radius: 10px;
  background: rgba(40, 180, 90, 0.08);
  border: 1px solid rgba(40, 180, 90, 0.30);
  display: grid;
  grid-template-columns: 1fr auto 1fr 1fr;
  gap: 14px;
  align-items: center;
}
.reveal-block {
  text-align: center;
}
.reveal-arrow {
  font-size: 22px;
  font-weight: 900;
  color: rgba(40, 180, 90, 0.55);
}
.reveal-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 2px;
}
.reveal-value {
  font-size: 20px;
  font-weight: 800;
}
.reveal-value.error-large { color: rgba(180, 30, 50, 1); }
.reveal-value.error-small { color: rgba(20, 130, 60, 1); }

@media (max-width: 720px) {
  .replay-select { min-width: 100%; }
  .replay-reveal { grid-template-columns: 1fr; }
  .reveal-arrow { display: none; }
}

/* ============ Skeleton loading state ============
   Cards in their initial pre-fetch state add the `.is-loading` modifier.
   JS render functions strip it once real data lands. Pulses the headline
   values so users see motion instead of a wall of `$—`. */
@keyframes skeleton-pulse {
  0%, 100% { opacity: 0.40; }
  50%      { opacity: 0.78; }
}
.is-loading .adi-score,
.is-loading .adi-label,
.is-loading .adi-agreement,
.is-loading .atr-stat-value,
.is-loading .atr-stat-sub,
.is-loading .wall-strike,
.is-loading .edge-radar-empty td {
  animation: skeleton-pulse 1.4s ease-in-out infinite;
}

/* Hover-tooltip cue: labels with a `title=` attribute show a dotted
   underline + help cursor so users know they're explorable. Native
   browser tooltip handles the actual popup on hover (~700ms delay). */
.has-tip {
  cursor: help;
  border-bottom: 1px dotted var(--text-muted);
  display: inline-block;
}

/* ============ Sortable tables (UX_POLISH_SPEC #2 + #3) ============
   Headers marked .aq-sortable take a pointer cursor + hover tint, and a
   small ▲/▼ arrow span appended to indicate the active sort column. */
th.aq-sortable {
  cursor: pointer;
  user-select: none;
  position: relative;
}
th.aq-sortable:hover {
  background: var(--row-hover, rgba(255,255,255,0.04));
}
.aq-sort-arrow {
  display: inline-block;
  margin-left: 4px;
  font-size: 0.85em;
  opacity: 0.7;
  min-width: 0.85em;
}

/* Row pulse-highlight for click-to-filter bubble → strikes-table (UX_POLISH_SPEC #4) */
@keyframes aq-row-pulse {
  0%   { background-color: rgba(250, 204, 21, 0.45); }
  100% { background-color: transparent; }
}
tr.aq-row-pulse > td {
  animation: aq-row-pulse 1.2s ease-out;
}

/* ============ Tabler icons inline utility (UX_POLISH_SPEC #5) ============
   Used wherever a Tabler `ti-*` glyph sits inline with text (legends, card
   titles, meters). Inherits color + size from the parent; a small right
   margin so it doesn't crowd the adjacent label. */
.aq-icon-inline {
  display: inline-block;
  font-size: 1em;
  vertical-align: -0.1em;
  margin-right: 4px;
  color: inherit;
}

/* ============ MM net-delta banner (top of Live OI timeline card) ============ */
.mm-delta-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 14px;
  margin: 10px 0 4px;
  border-radius: 8px;
  background: rgba(150, 150, 150, 0.08);
  border: 1px solid rgba(150, 150, 150, 0.20);
  font-weight: 700;
  font-size: 14px;
  font-variant-numeric: tabular-nums;
}
.mm-delta-banner .mm-delta-arrow { font-size: 18px; line-height: 1; }
.mm-delta-banner .mm-delta-label {
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-size: 11px;
  color: var(--text-muted);
}
.mm-delta-banner .mm-delta-value { font-size: 16px; }
.mm-delta-banner .mm-delta-detail {
  margin-left: auto;
  font-weight: 500;
  font-size: 12px;
  color: var(--text-muted);
}
.mm-delta-banner.is-long {
  background: rgba(40, 180, 60, 0.10);
  border-color: rgba(40, 180, 60, 0.45);
  color: rgba(20, 130, 40, 1);
}
.mm-delta-banner.is-short {
  background: rgba(220, 50, 70, 0.10);
  border-color: rgba(220, 50, 70, 0.45);
  color: rgba(170, 30, 50, 1);
}
[data-theme="dark"] .mm-delta-banner.is-long {
  background: rgba(70, 200, 90, 0.14);
  border-color: rgba(70, 200, 90, 0.55);
  color: rgba(130, 240, 160, 1);
}
[data-theme="dark"] .mm-delta-banner.is-short {
  background: rgba(240, 80, 100, 0.14);
  border-color: rgba(240, 80, 100, 0.55);
  color: rgba(255, 140, 160, 1);
}
[data-theme="dark"] .mm-delta-banner.is-neutral { color: rgba(220, 225, 235, 1); }

.mm-delta-trend {
  font-size: 12px;
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 999px;
  background: rgba(150, 150, 150, 0.18);
  color: inherit;
  font-variant-numeric: tabular-nums;
}
.mm-delta-trend.is-up   { background: rgba(40, 180, 60, 0.22);  color: rgba(20, 130, 40, 1); }
.mm-delta-trend.is-down { background: rgba(220, 50, 70, 0.22); color: rgba(170, 30, 50, 1); }
[data-theme="dark"] .mm-delta-trend.is-up   { background: rgba(70, 200, 90, 0.25);  color: rgba(140, 245, 170, 1); }
[data-theme="dark"] .mm-delta-trend.is-down { background: rgba(240, 80, 100, 0.25); color: rgba(255, 150, 170, 1); }

/* ============ OI timeline legend grid (2×2) ============ */
.oi-legend-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px 14px;
  margin-top: 8px;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-muted);
}
.oi-legend-item { display: inline-flex; align-items: center; gap: 6px; }
.oi-swatch {
  width: 14px; height: 14px;
  border-radius: 50%;
  flex-shrink: 0;
  display: inline-block;
  box-sizing: border-box;
}
/* CHANGELOG_SERIAL.md #133 — canonical green-500 / red-500 everywhere. */
.oi-swatch-yes-open  { background: rgba(34, 197, 94, 0.85);   border: 1.5px solid rgba(21, 128, 61, 1); }
.oi-swatch-yes-close { background: transparent;                border: 2.5px solid rgba(34, 197, 94, 1); }
.oi-swatch-no-open   { background: rgba(239, 68, 68, 0.85);   border: 1.5px solid rgba(185, 28, 28, 1); }
.oi-swatch-no-close  { background: transparent;                border: 2.5px solid rgba(239, 68, 68, 1); }
.oi-swatch-cone      { background: rgba(167, 139, 250, 0.30); border: 1px solid rgba(167, 139, 250, 0.7); border-radius: 2px; }
/* Directional OI heatmap swatches — 5-zone classifier post-#133:
   green-500 buy / red-500 sell / amber pin / sky-blue squeeze / gray low. */
.oi-swatch-heat-green   { background: rgba(34, 197, 94, 0.85);   border: 1px solid rgba(34, 197, 94, 1);   border-radius: 2px; }
.oi-swatch-heat-red     { background: rgba(239, 68, 68, 0.85);   border: 1px solid rgba(239, 68, 68, 1);   border-radius: 2px; }
.oi-swatch-heat-pin     { background: rgba(245, 158, 11, 0.85);  border: 1px solid rgba(245, 158, 11, 1);  border-radius: 2px; }
.oi-swatch-heat-gray    { background: rgba(150, 150, 150, 0.70); border: 1px solid rgba(150, 150, 150, 1); border-radius: 2px; }
.oi-swatch-heat-squeeze { background: rgba(125, 211, 252, 0.85); border: 1px solid rgba(125, 211, 252, 1); border-radius: 2px; }
/* CHANGELOG_SERIAL.md #133 — terrain swatch: sell(red) → pin(amber) → buy(green). */
.oi-swatch-terrain   {
  background: linear-gradient(90deg,
    rgba(239, 68, 68, 0.55)   0%,
    rgba(245, 158, 11, 0.55) 50%,
    rgba(34, 197, 94, 0.55)  100%);
  border: 1px solid rgba(150, 150, 150, 0.5);
  border-radius: 2px;
}
/* CHANGELOG_SERIAL.md #133 — rings now green-500 / red-500. */
.oi-swatch-ring-cyan { background: transparent; border: 2.5px solid rgba(34, 197, 94, 0.95); }   /* green-500 MM buys */
.oi-swatch-ring-amber{ background: transparent; border: 2.5px solid rgba(239, 68, 68, 0.95); }   /* red-500 MM sells */
/* Direction-stripe swatches — narrow vertical bars to match the in-chart stripe */
.oi-swatch-stripe-cyan,
.oi-swatch-stripe-amber,
.oi-swatch-stripe-gray {
  width: 5px;
  border-radius: 1px;
  border: none;
}
/* CHANGELOG_SERIAL.md #133 — green-500 / red-500 stripes. */
.oi-swatch-stripe-cyan  { background: rgba(34, 197, 94, 0.85); }   /* green-500 buy */
.oi-swatch-stripe-amber { background: rgba(239, 68, 68, 0.85); }   /* red-500 sell */
.oi-swatch-stripe-gray  { background: rgba(107, 114, 128, 0.55); }

/* ============ Close-flow markers (CHANGELOG_SERIAL.md #219) ============ */
/* Diamond swatches — 45deg-rotated squares matching the in-chart diamonds.
   Tailwind 500 green/red; hollow gray for silent; faded vs bold for the
   confidence extremes. */
.oi-swatch-cf-yes,
.oi-swatch-cf-no,
.oi-swatch-cf-silent,
.oi-swatch-cf-faded,
.oi-swatch-cf-bold {
  width: 11px; height: 11px;
  border-radius: 1px;
  transform: rotate(45deg);
  box-sizing: border-box;
}
.oi-swatch-cf-yes    { background: rgba(34, 197, 94, 0.85); border: none; }   /* green-500 */
.oi-swatch-cf-no     { background: rgba(239, 68, 68, 0.85); border: none; }   /* red-500 */
.oi-swatch-cf-silent { background: transparent; border: 1.5px solid rgba(150, 150, 150, 0.9); }
.oi-swatch-cf-faded  { background: rgba(34, 197, 94, 0.32); border: none; }
.oi-swatch-cf-bold   { background: rgba(34, 197, 94, 0.95); border: none; }

/* Hover tooltip for individual close-flow markers (CHANGELOG_SERIAL.md #220).
   Appended to document.body by close_flow.js; positioned at the cursor. */
.aq-cf-tooltip {
  position: fixed;
  z-index: 9999;
  pointer-events: none;
  max-width: 280px;
  padding: 8px 10px;
  border-radius: 6px;
  background: rgba(10, 19, 28, 0.96);
  border: 1px solid rgba(120, 187, 255, 0.45);
  color: #e0e6ee;
  font: 12px/1.4 ui-sans-serif, system-ui, sans-serif;
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.45);
}
.aq-cf-tt-line { font-variant-numeric: tabular-nums; }
.aq-cf-tt-line strong { color: #ffffff; }
.aq-cf-tt-sub {
  margin-top: 4px;
  padding-top: 4px;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  color: #aab4c2;
  font-size: 11px;
}

/* ============ Y-axis zoom pills (Live OI timeline) ============ */
.oi-zoom-pills {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 4px;
  margin-top: 8px;
  font-size: 12px;
}
.oi-zoom-label {
  color: var(--text-muted);
  margin-right: 6px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  font-size: 10px;
}
.oi-zoom-pill {
  appearance: none;
  background: transparent;
  /* CHANGELOG_SERIAL.md #025 — full 1px border replaces border:0 so
     each pill reads as a discrete button. Bottom-border still goes
     accent-blue on active state, but the full perimeter is now
     visible at rest too. */
  border: 1px solid var(--btn-border);
  padding: 4px 10px;
  font: inherit;
  cursor: pointer;
  color: var(--text-muted);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  border-radius: 5px;
  transition: color 0.15s ease, border-color 0.15s ease, background-color 0.15s ease;
}
.oi-zoom-pill:hover {
  color: var(--text);
  border-color: var(--btn-border-strong);
}
.oi-zoom-pill.is-active {
  color: #4f9bff;
  border-color: #4f9bff;
  background: rgba(79, 155, 255, 0.10);
}
[data-theme="dark"] .oi-zoom-pill.is-active {
  color: #78bbff;
  border-color: #78bbff;
  background: rgba(120, 187, 255, 0.14);
}

/* ============ "Biggest flow this minute" callout below the chart ============ */
.biggest-flow-callout {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 12px;
  padding: 10px 14px;
  border-radius: 8px;
  background: rgba(150, 150, 150, 0.08);
  border: 1px solid rgba(150, 150, 150, 0.20);
  font-size: 13px;
}
.biggest-flow-tag {
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-size: 11px;
  color: var(--text-muted);
  white-space: nowrap;
}
.biggest-flow-detail {
  flex: 1;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.biggest-flow-callout.is-bullish {
  background: rgba(40, 180, 60, 0.10);
  border-color: rgba(40, 180, 60, 0.35);
}
.biggest-flow-callout.is-bearish {
  background: rgba(220, 50, 70, 0.10);
  border-color: rgba(220, 50, 70, 0.35);
}
[data-theme="dark"] .biggest-flow-callout.is-bullish {
  background: rgba(70, 200, 90, 0.14);
  border-color: rgba(70, 200, 90, 0.40);
}
[data-theme="dark"] .biggest-flow-callout.is-bearish {
  background: rgba(240, 80, 100, 0.14);
  border-color: rgba(240, 80, 100, 0.40);
}

/* ============ Live OI timeline (Live tab — bubble-over-time per strike, mirror of replay timeline format) ============ */
.live-oi-card { padding: 10px 18px 18px; } /* CHANGELOG_SERIAL.md #228 — top pad 14->10 so the chart sits higher */
.live-oi-chart-area {
  position: relative;
  height: 360px;
  margin-top: 8px;
}
.live-oi-chart-area canvas { width: 100% !important; height: 100% !important; }
.live-oi-status {
  margin-top: 8px;
  font-size: 12px;
  color: var(--text-muted);
  font-style: italic;
}
@media (max-width: 720px) {
  .live-oi-chart-area { height: 280px; }
}

/* ============ Live OI two-column layout — sidebar (left) + main (right) ============
   NOTE on specificity: the global tab system uses
     body[data-active-tab="live"] .tab-content[data-tab="live"] { display: block; }
   which has specificity (0,3,1) and beats a plain `.live-oi-card.has-sidebar`
   (0,2,0) rule. To make the grid layout actually win on the Live tab we tie our
   selector to the same body[data-active-tab="live"] prefix so the two rules
   tie on specificity and our `display: grid` (defined later in the cascade)
   wins. Same trick applied inside the @media collapse below. */
body[data-active-tab="live"] .live-oi-card.has-sidebar {
  display: grid;
  grid-template-columns: 264px 1fr;
  gap: 24px;
  align-items: stretch;
}
.live-oi-sidebar {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 4px 4px 4px 0;
  border-right: 1px solid var(--line);
  padding-right: 18px;
  min-width: 0;
}
.live-oi-sidebar .card-title { font-size: 18px; }
.live-oi-sidebar .card-sub.live-oi-sidebar-sub {
  font-size: 13px;
  line-height: 1.55;
  margin: 2px 0 0;
  max-width: none;
  color: var(--text-muted);
}
.live-oi-sidebar .oi-legend-grid {
  grid-template-columns: 1fr;
  gap: 14px 0;
  margin-top: 12px;
  font-size: 15px;
}
.live-oi-sidebar .oi-legend-item {
  line-height: 1.35;
  align-items: flex-start;
  gap: 10px;
}
/* Bigger swatches inside the sidebars so the encoding reads clearly at
   a glance (was 14×14 — too small to distinguish stripe / ring / fill
   at the default sidebar font). */
.live-oi-sidebar .oi-swatch,
.pulse-15m-sidebar .oi-swatch {
  width: 20px;
  height: 20px;
  margin-top: 2px;
}
.live-oi-sidebar .oi-swatch-stripe-cyan,
.live-oi-sidebar .oi-swatch-stripe-amber,
.live-oi-sidebar .oi-swatch-stripe-gray {
  width: 7px;
}
/* Two-line legend layout: title on top, plain-English gloss below in
   muted small. Applied scoped to the two sidebars only so other places
   that use .oi-legend-item (single-line) are untouched. */
.live-oi-sidebar .legend-label,
.pulse-15m-sidebar .legend-label {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.live-oi-sidebar .legend-title,
.pulse-15m-sidebar .legend-title {
  font-weight: 600;
  color: var(--text);
}
.live-oi-sidebar .legend-gloss,
.pulse-15m-sidebar .legend-gloss {
  font-size: 12.5px;
  font-weight: 400;
  color: var(--text-muted);
  line-height: 1.4;
  opacity: 0.88;
}
.live-oi-main { display: flex; flex-direction: column; min-width: 0; }
.live-oi-main > .card-header.live-oi-main-header {
  padding: 0 0 10px 0;
  border-bottom: none;
  gap: 8px;
}
.live-oi-main > .card-header.live-oi-main-header > div:first-child { flex: 1; }
.live-oi-main > .live-oi-chart-area { flex: 1; min-height: 460px; }

@media (max-width: 1100px) {
  body[data-active-tab="live"] .live-oi-card.has-sidebar {
    grid-template-columns: 1fr;
    gap: 14px;
  }
  .live-oi-sidebar {
    border-right: none;
    border-bottom: 1px solid var(--line);
    padding: 0 0 12px 0;
  }
  .live-oi-sidebar .oi-legend-grid { grid-template-columns: 1fr 1fr; }
}

/* ============ Recent 15-min outcomes status text ============ */
.live-15m-outcomes-status {
  margin-top: 8px;
  font-size: 12px;
  color: var(--text-muted);
  font-style: italic;
}

/* ============ 15-Minute Pulse (FIFTEEN_MIN_PULSE_SPEC.md Phases 2-4) ============
   Layout mirrors .live-oi-card.has-sidebar — same 264px sidebar + 24px gap +
   1fr chart-area grid. That gives both cards an identical left offset before
   the chart area, so the data pixels line up second-for-second when the
   y-axis widths are also matched (we pin them in pulse_15m.js afterFit). */
.pulse-15m-card { padding: 14px 18px 18px; margin-top: 0; }
.pulse-15m-card.has-sidebar { padding-top: 18px; }

body[data-active-tab="live"] .pulse-15m-card.has-sidebar {
  display: grid;
  grid-template-columns: 264px 1fr;
  gap: 24px;
  align-items: stretch;
}
.pulse-15m-sidebar {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 4px 4px 4px 0;
  border-right: 1px solid var(--line);
  padding-right: 18px;
  min-width: 0;
}
.pulse-15m-sidebar .card-title { font-size: 18px; }
.pulse-15m-sidebar .card-sub.pulse-15m-sidebar-sub {
  font-size: 13px;
  line-height: 1.55;
  margin: 2px 0 0;
  max-width: none;
  color: var(--text-muted);
}
.pulse-15m-sidebar .oi-legend-grid {
  grid-template-columns: 1fr;
  gap: 14px 0;
  margin-top: 12px;
  font-size: 15px;
}
.pulse-15m-sidebar .oi-legend-item {
  line-height: 1.35;
  align-items: flex-start;
  gap: 10px;
}
.pulse-15m-meta-row { margin-top: auto; font-size: 12px; color: var(--text-muted); }

/* ============ Sidebar section grouping (CHANGELOG #011) ============
   Both OI and Pulse sidebars are grouped into named sections (Customer
   prints, Per-strike bands, Layers, etc.). Section titles are small,
   uppercase, muted; sections after the first get a thin divider above. */
.legend-section-title {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.7px;
  text-transform: uppercase;
  color: rgba(207, 213, 226, 0.55);
  margin: 14px 0 6px;
  padding: 0;
  line-height: 1.2;
}
.legend-section-title:first-child {
  margin-top: 4px;
}
.legend-section {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 4px 0 8px;
}
.legend-section + .legend-section-title {
  border-top: 0.5px solid rgba(120, 130, 155, 0.18);
  padding-top: 12px;
}

/* Legend swatch colors mirror the runtime palette in pulse_15m.js so the
   sidebar legend matches what the chart actually paints. Synced to
   Tailwind green-500 / red-500 / yellow-400 via CHANGELOG_SERIAL.md #010. */
.pulse-swatch-yes        { background: rgba( 34, 197,  94, 1); }
.pulse-swatch-no         { background: rgba(239,  68,  68, 1); }
.pulse-swatch-balanced   { background: rgba(250, 204,  21, 1); }
.pulse-swatch-thin       { background: rgba(160, 160, 160, 1); }
/* CHANGELOG_SERIAL.md #133 — canonical green-500 / red-500. */
.pulse-swatch-heatmap-yes { background: rgba( 34, 197,  94, 0.85); border-radius: 50%; }
.pulse-swatch-heatmap-no  { background: rgba(239,  68,  68, 0.85); border-radius: 50%; }
.pulse-swatch-heatmap-bal { background: rgba(180, 180, 180, 0.35); border-radius: 50%; }
.pulse-swatch-settled-yes { background: rgba( 34, 197,  94, 1);    border-radius: 50%; }
.pulse-swatch-settled-no  { background: rgba(239,  68,  68, 1);    border-radius: 50%; }

.pulse-15m-main { display: flex; flex-direction: column; min-width: 0; }
.pulse-15m-chart-area {
  position: relative;
  height: 460px; /* match .live-oi-main > .live-oi-chart-area min-height */
}
.pulse-15m-chart-area canvas { width: 100% !important; height: 100% !important; }
.pulse-15m-marginal-area {
  position: relative;
  height: 70px;
  margin-top: 4px;
}
.pulse-15m-marginal-area canvas { width: 100% !important; height: 100% !important; }
.pulse-15m-status {
  margin-top: 8px;
  font-size: 12px;
  color: var(--text-muted);
  font-style: italic;
}

@media (max-width: 1100px) {
  body[data-active-tab="live"] .pulse-15m-card.has-sidebar {
    grid-template-columns: 1fr;
    gap: 14px;
  }
  .pulse-15m-sidebar {
    border-right: none;
    border-bottom: 1px solid var(--line);
    padding: 0 0 12px 0;
  }
  .pulse-15m-sidebar .oi-legend-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 720px) {
  .pulse-15m-chart-area { height: 300px; }
  .pulse-15m-marginal-area { height: 56px; }
}

/* ============ Recent 15-min outcomes (bar chart of last N settled contracts) ============ */
.live-15m-outcomes-card { padding: 14px 18px 18px; }
.live-15m-outcomes-chart-area {
  position: relative;
  height: 260px;
  margin-top: 8px;
}
.live-15m-outcomes-chart-area canvas { width: 100% !important; height: 100% !important; }
@media (max-width: 720px) {
  .live-15m-outcomes-chart-area { height: 200px; }
}

  50%      { opacity: 0.78; }
}

/* ============================================================
   ===== LAYOUT v2 — appended palette/sticky/tab/edge/spark =====
   These rules override earlier definitions via cascade order.
   Goal: disciplined palette, compressed sticky stack, louder
   tab nav, edge-hero card + sparkline pin, graceful empties.
   ============================================================ */

/* --- Disciplined palette tokens (dark mode is what visitors see) --- */
[data-theme="dark"], :root {
  --brand-1:   #4f9bff;
  --brand-2:   #34d399;
  --brand-3:   #a78bfa;
  --highlight: #fcd34d;
  --bg-elev:   #15212f;
}

/* --- Pulsing "● LIVE" cue, applied everywhere .live-dot is used --- */
@keyframes aq-live-pulse {
  0%, 100% { opacity: 1;    transform: scale(1); }
  50%      { opacity: 0.55; transform: scale(0.78); }
}
.live-dot {
  display: inline-block;
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--brand-2);
  box-shadow: 0 0 8px rgba(52, 211, 153, 0.55);
  animation: aq-live-pulse 2s ease-in-out infinite;
  vertical-align: middle;
}

/* --- Site header: compress to ~46px, no min-height bloat --- */
.site-header {
  padding: 6px 0;
  min-height: 0;
}
.header-row {
  grid-template-columns: auto 1fr auto auto;
  gap: 24px;
  padding: 4px 0;
}
.header-time, .header-date {
  font-size: 20px;
  line-height: 1;
}
.brand {
  flex-direction: column;
  align-items: center;
  gap: 1px;
  justify-self: center;
}
.brand-mark { display: none; }   /* the gradient text is the brand mark */
.brand-text {
  font-size: 22px;
  letter-spacing: -0.015em;
}
.brand-tagline {
  font-family: var(--sans);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--text-dim);
  line-height: 1;
}
.site-nav { gap: 18px; font-size: 12.5px; }

/* --- Alerts strip: pull freshness inline, drop the big banner --- */
.alerts-section {
  /* #099 — alerts-section is no longer sticky (it scrolls away as read-once
     content per prior decision); top: removed to avoid confusion. */
  padding: 8px 0 6px;
}
.feed-freshness {
  display: inline-flex !important;
  align-items: center;
  gap: 8px;
  margin: 4px 0 0;
  padding: 4px 12px;
  background: transparent;
  border-radius: 999px;
  font-size: 11px;
  color: var(--text-muted);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  width: auto !important;
  border: none !important;
}
.feed-freshness-label { font-weight: 700; }
.feed-freshness-time, .feed-freshness-age {
  font-family: var(--mono);
  font-weight: 700;
  color: var(--brand-2);
  text-transform: none;
  letter-spacing: 0;
}

/* --- Tab nav: louder primary navigation, replay folded in --- */
.tab-nav {
  top: var(--aq-tab-top); /* #099 — driven by --aq-tab-top var */
  padding: 6px 6px;
  gap: 4px;
  border: none;
  border-bottom: 2px solid var(--brand-1);
  border-radius: 0;
  background: var(--bg-card);
  box-shadow: none;
}
.tab-btn {
  padding: 12px 18px;
  font-size: 19px;
  font-weight: 800;
  letter-spacing: 0.05em;
  color: var(--text-dim);
  border-radius: 6px 6px 0 0;
  position: relative;
  background: transparent;
}
.tab-btn:hover { color: var(--text); background: transparent; }
.tab-btn.active {
  background: transparent;
  color: var(--brand-1);
  box-shadow: none;
}
.tab-btn.active::after {
  content: '';
  position: absolute;
  left: 14%; right: 14%; bottom: -2px;
  height: 3px;
  background: var(--brand-1);
  border-radius: 2px 2px 0 0;
}
.tab-freshness {
  padding: 0 14px;
  margin-left: auto;
  background: transparent;
  border-left: 1px solid var(--line);
  font-size: 11px;
  color: var(--text-muted);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* --- Edge-hero row: NEW container holding the edge card + slim spot pin --- */
.edge-hero-row {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: 14px;
  margin: 10px 0 8px;
}
@media (max-width: 960px) {
  .edge-hero-row { grid-template-columns: 1fr; }
}

.edge-hero-card {
  background: linear-gradient(135deg, rgba(79,155,255,0.10), rgba(167,139,250,0.10));
  border: 1px solid var(--brand-1);
  border-radius: 10px;
  padding: 14px 18px 16px;
  position: relative;
  overflow: hidden;
  min-height: 140px;
}
.edge-hero-card::before {
  content: '';
  position: absolute; inset: 0;
  background: radial-gradient(circle at 0% 0%, rgba(79,155,255,0.10), transparent 55%);
  pointer-events: none;
}
.edge-hero-label {
  font-size: 11px; font-weight: 800;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--brand-1);
  display: flex; align-items: center; gap: 6px;
}
.edge-hero-headline {
  font-family: var(--mono);
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--text);
  margin: 6px 0 6px;
  line-height: 1.25;
}
.edge-hero-headline strong { color: var(--highlight); font-weight: 800; }
.edge-hero-strapline {
  font-size: 13px;
  color: var(--text-muted);
  line-height: 1.5;
  margin: 0 0 10px;
}
.edge-hero-detail {
  display: flex; gap: 18px; flex-wrap: wrap;
  font-size: 12px;
}
.edge-hero-detail .cell { display: flex; flex-direction: column; gap: 1px; }
.edge-hero-detail .label {
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 10px;
  font-weight: 700;
}
.edge-hero-detail .val {
  font-family: var(--mono);
  font-weight: 800;
  font-size: 15px;
  color: var(--text);
}
.edge-hero-detail .val.pos { color: var(--pos); }
.edge-hero-detail .val.neg { color: var(--neg); }
.edge-hero-empty {
  display: flex; align-items: center; gap: 10px;
  font-size: 13px; color: var(--text-muted);
  padding: 16px 0;
}

/* --- Slim hero-pin: hide sigma ribbon, show sparkline. --- */
.edge-hero-row #hero-pin {
  margin: 0;
  padding: 14px 18px 12px;
  border-radius: 10px;
}
.edge-hero-row .hero-pin-grid {
  grid-template-columns: 1fr 1fr;
  gap: 10px 22px;
  padding: 0;
}
.edge-hero-row .hero-pin-value      { font-size: 24px; line-height: 1.05; }
.edge-hero-row .hero-pin-value.band { font-size: 16px; }
.edge-hero-row .hero-pin-value.tte  { font-size: 22px; }
.edge-hero-row .hero-pin-ribbon,
.edge-hero-row .hero-pin-footer { display: none; }

.hero-pin-spark {
  position: relative;
  margin-top: 10px;
  padding-top: 8px;
  height: 56px;
  border-top: 1px solid var(--line);
}
.hero-pin-spark canvas { width: 100%; height: 100%; display: block; }
.hero-pin-spark-cap {
  position: absolute; right: 0; top: 8px;
  font-size: 10px;
  color: var(--text-dim);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* Outside edge-hero-row (legacy hero-pin spots), behave as before */

/* --- ATR live differentiation: glow border + pulse on the live tiles --- */
.atr-stat-current,
.atr-stat-expected {
  position: relative;
  border-color: rgba(52, 211, 153, 0.35);
}
.atr-stat-current::after,
.atr-stat-expected::after {
  content: '';
  position: absolute;
  top: 10px; right: 10px;
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--pos);
  box-shadow: 0 0 6px var(--pos);
  animation: aq-live-pulse 2s ease-in-out infinite;
}

/* --- Empty-state strip for live OI / taker flow when no data --- */
.empty-state {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  background: var(--bg-table-alt);
  border: 1px dashed var(--line-strong);
  border-radius: 8px;
  margin-top: 8px;
}
.empty-state-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--text-dim);
  flex-shrink: 0;
}
.empty-state-text {
  font-size: 13px; color: var(--text-muted); line-height: 1.5; flex: 1;
}
.empty-state-text strong { color: var(--text); font-weight: 700; }
.empty-state-meta {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--text-dim);
  white-space: nowrap;
  letter-spacing: 0.04em;
}
/* (Legacy .has-data toggle removed — superseded by .no-data scheme below.) */

/* --- Updated sticky offsets — superseded by #099 var-based system --- */
/* (was: alerts-section/hero-pin-card/tab-nav top overrides at 720px — removed) */
.edge-hero-row .hero-pin-footer { display: none; }

.hero-pin-spark {
  position: relative;
  margin-top: 10px;
  padding-top: 8px;
  height: 56px;
  border-top: 1px solid var(--line);
}
.hero-pin-spark canvas { width: 100%; height: 100%; display: block; }
.hero-pin-spark-cap {
  position: absolute; right: 0; top: 8px;
  font-size: 10px;
  color: var(--text-dim);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* --- ATR live differentiation --- */
.atr-stat-current,
.atr-stat-expected {
  position: relative;
  border-color: rgba(52, 211, 153, 0.35);
}
.atr-stat-current::after,
.atr-stat-expected::after {
  content: '';
  position: absolute;
  top: 10px; right: 10px;
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--pos);
  box-shadow: 0 0 6px var(--pos);
  animation: aq-live-pulse 2s ease-in-out infinite;
}

/* --- Empty-state strip --- */
.empty-state {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  background: var(--bg-table-alt);
  border: 1px dashed var(--line-strong);
  border-radius: 8px;
  margin-top: 8px;
}
.empty-state-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--text-dim);
  flex-shrink: 0;
}
.empty-state-text {
  font-size: 13px; color: var(--text-muted); line-height: 1.5; flex: 1;
}
.empty-state-text strong { color: var(--text); font-weight: 700; }
.empty-state-meta {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--text-dim);
  white-space: nowrap;
  letter-spacing: 0.04em;
}
/* (Second legacy .has-data block also removed — only .no-data scheme below is active.) */

/* Mobile sticky offsets — superseded by #099 var-based system */
/* Orphan fragment cleaned: */ font-weight: 700; }
.empty-state-meta {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--text-dim);
  white-space: nowrap;
  letter-spacing: 0.04em;
}
/* Default: chart visible, empty-state hidden. JS adds .no-data to flip. */
.empty-state { display: none; }
.live-oi-card.no-data .empty-state { display: flex; }
.live-oi-card.no-data .live-oi-chart-area { display: none; }

/* Mobile sticky offsets — superseded by #099 var-based system */

/* ============ iOS Add-to-Home-Screen install banner ============
   Only shown by ios-install-prompt.js when running in iOS Safari + not in
   standalone mode + not previously dismissed. Hidden by [hidden] until JS
   un-hides it. Sticks to the bottom of the viewport above iOS safe-area. */
.ios-install-banner {
  position: fixed;
  left: 12px; right: 12px;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 12px);
  z-index: 9999;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border-radius: 14px;
  background: rgba(20, 25, 38, 0.96);
  color: #f7f8fa;
  box-shadow: 0 12px 36px rgba(0, 0, 0, 0.40), 0 0 0 1px rgba(255,255,255,0.08);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  font-size: 14px;
  line-height: 1.35;
  animation: ios-install-slide-up 0.35s ease-out;
}
.ios-install-banner[hidden] { display: none !important; }
.ios-install-icon img {
  display: block;
  width: 40px; height: 40px;
  border-radius: 9px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.3);
}
.ios-install-text { flex: 1; display: flex; flex-direction: column; gap: 2px; }
.ios-install-text strong { font-size: 15px; font-weight: 700; }
.ios-install-text span { font-size: 12px; color: rgba(247, 248, 250, 0.78); }
.ios-share-icon {
  display: inline-block;
  width: 14px; height: 14px;
  vertical-align: -2px;
  margin: 0 2px;
  color: #4ea1ff;
}
.ios-install-close {
  flex: 0 0 auto;
  width: 30px; height: 30px;
  display: flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,0.08);
  border: 0;
  border-radius: 50%;
  color: #f7f8fa;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  padding: 0;
}
.ios-install-close:active { background: rgba(255,255,255,0.18); }
@keyframes ios-install-slide-up {
  from { transform: translateY(calc(100% + 32px)); opacity: 0; }
  to   { transform: translateY(0); opacity: 1; }
}

/* ============ Share button in header ============ */
.share-toggle {
  appearance: none;
  border: 1px solid var(--line);
  background: var(--bg-card);
  color: var(--text);
  padding: 6px 10px;
  border-radius: 8px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.share-toggle:hover { background: rgba(78, 161, 255, 0.10); border-color: rgba(78, 161, 255, 0.40); }
.share-toggle:active { transform: translateY(1px); }
[data-theme="dark"] .share-toggle:hover { background: rgba(78, 161, 255, 0.18); }

/* ============ Copy-link toast (after Web Share fallback) ============ */
.share-toast {
  position: fixed;
  left: 50%;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 24px);
  transform: translateX(-50%) translateY(20px);
  z-index: 10000;
  padding: 10px 18px;
  border-radius: 22px;
  background: rgba(20, 25, 38, 0.95);
  color: #f7f8fa;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.30);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.share-toast.is-visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* ============ Mobile fit polish ============
   Touch-friendly tap targets, safe-area insets, tighter card padding,
   collapsible brand tagline on tiny screens. */
@supports (padding: env(safe-area-inset-top)) {
  .site-header { padding-top: env(safe-area-inset-top, 0px); }
}
@media (max-width: 540px) {
  /* Tiny phones: kill the tagline, tighten everything. */
  .brand-tagline { display: none; }
  .header-time, .header-date { font-size: 11px; }
  .brand-text { font-size: 15px; }
  .site-nav { gap: 6px; }
  .site-nav a { font-size: 12px; padding: 4px 6px; }
  /* Cards: reclaim horizontal space */
  .card, .live-oi-card, .pulse-15m-card,
  .live-15m-outcomes-card, .atr-tile { padding: 12px 14px; }
  .card-title { font-size: 16px; }
  .card-sub { font-size: 12px; }
  /* MM hedge banner: stack tighter, hide right-side meta */
  .mm-delta-banner { flex-wrap: wrap; gap: 6px; padding: 8px 10px; font-size: 13px; }
  .mm-delta-banner .mm-delta-value { font-size: 15px; }
  .mm-delta-banner .mm-delta-detail { font-size: 11px; flex-basis: 100%; margin-left: 0; }
  /* Tap targets at least 36px touchable */
  .share-toggle, .theme-toggle { min-width: 36px; min-height: 36px; }
}

/* ============================================================
   Slim hero-pin (.hero-pin-card.hero-pin-slim) — CHANGELOG_SERIAL.md #316:
   moved ABOVE the tab nav (now lives in the DOM between </header> and
   .tab-nav-shell). Sticky at top:var(--aq-hdr-h) so it freezes just under
   the header. z-index 100 keeps it above the tab nav (95). Goal: single
   horizontal row of 4 stats, drop
   sparkbar / ribbon / footer so vertical real estate goes to
   the chart below. We override the rules from .hero-pin-card
   without touching the original so the card form still works
   if anything else needs it.
   ============================================================ */
.hero-pin-card.hero-pin-slim {
  /* CHANGELOG_SERIAL.md #316 — spotbar-above-tabs: sticky just below the header,
     above the tab nav. top = var(--aq-hdr-h) so it freezes right under the header.
     z-index 100 keeps it above the tab nav (z-index 95) in the sticky stack.
     width:100% because this element lives outside <main class="container main-grid">
     and must span the full viewport width like the header and tab-nav do.
     At <=480px position is overridden to static (mobile budget rule). */
  position: sticky;
  top: var(--aq-hdr-h);
  z-index: 100;
  width: 100%;
  /* CHANGELOG_SERIAL.md #228 — tightened margins (6/10 -> 0/6). Margin-bottom
     0 here since .tab-nav-shell has margin-top:8px for the gap. */
  margin: 0;
  padding: 0;
  border-width: 1px;
  border-radius: 0; /* full-width bar — no radius on left/right edges */
  border-left: none;
  border-right: none;
  /* Opaque card background so content doesn't show through when sticky. */
  background: var(--bg-card);
  box-sizing: border-box;
}
[data-theme="dark"] .hero-pin-card.hero-pin-slim {
  background: var(--bg-card);
}
/* #099 — hero-pin-slim 720px override superseded by var-based system; no-op comment */
/* @media (max-width: 720px) { .hero-pin-card.hero-pin-slim { top: 104px; } } */
.hero-pin-card.hero-pin-slim .hero-pin-grid {
  padding: 10px 18px;
  gap: 14px;
  grid-template-columns: repeat(4, 1fr);
}
.hero-pin-card.hero-pin-slim .hero-pin-cell { gap: 2px; }
.hero-pin-card.hero-pin-slim .hero-pin-label { font-size: 10.5px; }
.hero-pin-card.hero-pin-slim .hero-pin-value { font-size: 22px; line-height: 1.05; }
.hero-pin-card.hero-pin-slim .hero-pin-value.band { font-size: 15px; }
.hero-pin-card.hero-pin-slim .hero-pin-value.tte  { font-size: 20px; }
.hero-pin-card.hero-pin-slim .hero-pin-sub { font-size: 11.5px; margin-top: 1px; }
/* Hide the auxiliary visuals — they pushed the card to ~150px tall. */
.hero-pin-card.hero-pin-slim .hero-pin-spark,
.hero-pin-card.hero-pin-slim .hero-pin-ribbon,
.hero-pin-card.hero-pin-slim .hero-pin-footer {
  display: none;
}
@media (max-width: 720px) {
  .hero-pin-card.hero-pin-slim .hero-pin-grid { grid-template-columns: repeat(2, 1fr); }
}

/* CHANGELOG_SERIAL.md #316 — spotbar-above-tabs: .spot-freeze-bar (#225) removed.
   The slim BTC/EOH/TTE strip is superseded by #hero-pin now frozen above the
   tab nav. All .sfb-* rules removed with it. app.js sfb-* calls are null-safe. */

/* ============================================================
   Slim ATR tile (.atr-tile-slim) — applied when the tile sits
   below the chart on the Live tab. Same idea: collapse to a
   single horizontal row of compact stats so the chart owns
   the vertical real estate.
   ============================================================ */
.atr-tile-slim {
  padding: 8px 14px;
  margin-bottom: 12px;
}
.atr-tile-slim .atr-tile-header {
  padding: 0 0 6px 0;
  border-bottom: 1px solid var(--line);
  margin-bottom: 8px;
}
.atr-tile-slim .atr-tile-title { font-size: 13px; }
.atr-tile-slim .atr-tile-grid {
  grid-template-columns: repeat(5, 1fr);
  gap: 10px;
}
.atr-tile-slim .atr-stat {
  padding: 6px 8px;
  min-width: 0;
}
.atr-tile-slim .atr-stat-label { font-size: 10.5px; }
.atr-tile-slim .atr-stat-value { font-size: 15px; }
.atr-tile-slim .atr-stat-sub   { font-size: 10.5px; }
@media (max-width: 1100px) {
  .atr-tile-slim .atr-tile-grid { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
}

/* ============================================================
   Chart fills the viewport on the Live tab.
   Above the chart on first open we have: header (~80) + alerts
   (~250) + tabs (~50) + slim hero pin (~70) + replay bar slim
   (~50) = ~500px. Reserve another ~20 of breathing room and
   give the chart everything else: calc(100vh - 520px). Floor
   at 460px so on very short windows the chart stays usable.
   ============================================================ */
.live-oi-main > .live-oi-chart-area {
  min-height: max(460px, calc(100vh - 520px));
}

/* ============================================================
   Replay bar slimmed for in-tab use. The control row in LIVE
   mode is just two pills + a status line; we don't need card-
   like vertical padding for it. Keeps the chart pushed up.
   ============================================================ */
.replay-bar.tab-content {
  padding: 8px 14px;
  margin-bottom: 10px;
}

/* ============ What-if Simulator (Phase 0) ============
   CHANGELOG_SERIAL.md #200 — Controls relocated into the left sidebar box
   (.aq-sim-sidebar-box). The old .aq-sim-controls flex row in .live-oi-main
   is removed from the DOM; the class rule below is kept as dead-code stub
   in case any JS references it as a selector (none do currently).
   When .aq-sim-active is on the live-oi card, a purple border tints the
   whole card so the user knows they're looking at a projection, not live data. */
.aq-sim-controls {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 6px 0 8px;
}

/* CHANGELOG_SERIAL.md #200 — Sidebar container for all SIM controls.
   Violet border (rgba(167,139,250,...) = violet-400 accent consistent with
   existing SIM accent throughout this file) separates the Simulator section
   from the legend rows above and below it. */
.aq-sim-sidebar-box {
  border: 1px solid rgba(167, 139, 250, 0.40);
  border-radius: 8px;
  background: rgba(167, 139, 250, 0.04);
  padding: 10px 12px 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 4px 0;
}
.aq-sim-sidebar-title {
  /* Uses .legend-section-title base; override margin so it sits flush at top
     of the box without the default top margin that separates section titles. */
  margin-top: 0 !important;
  color: rgba(167, 139, 250, 0.85);
}
/* Ensure the toggle sits flush left inside the box */
.aq-sim-sidebar-box .aq-sim-toggle { align-self: flex-start; }
.aq-sim-toggle {
  display: inline-flex;
  border: 1px solid var(--line, #1c2c3d);
  border-radius: 8px;
  overflow: hidden;
}
.aq-sim-toggle-pill {
  appearance: none;
  background: transparent;
  color: var(--muted, #8aa0b3);
  border: 0;
  font-size: 13px;
  font-weight: 700;
  padding: 6px 14px;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.aq-sim-toggle-pill.active {
  color: var(--text, inherit);
}
.aq-sim-toggle-pill[data-mode="live"].active { background: rgba(52, 211, 153, 0.18); }
.aq-sim-toggle-pill[data-mode="sim"].active  { background: rgba(167, 139, 250, 0.22); }
.aq-sim-toggle-pill:hover:not(.active) { background: rgba(76, 139, 255, 0.06); color: var(--text, inherit); }

/* CHANGELOG_SERIAL.md #133 — terrain-style-toggle removed from DOM.
   CSS block kept as dead code stub so older localStorage states + any
   cached HTML don't surface visible broken elements. The selector matches
   nothing after the index.html change. */
.terrain-style-toggle { display: none; }

.aq-sim-banner {
  flex: 1 1 240px;
  font-size: 13px;
  line-height: 1.4;
  color: var(--text, inherit);
  background: rgba(167, 139, 250, 0.10);
  border: 1px solid rgba(167, 139, 250, 0.45);
  border-radius: 8px;
  padding: 6px 12px;
}

/* Phase 1: TTE slider. Only visible when sim mode is active.
   CHANGELOG_SERIAL.md #200 — Now lives inside .aq-sim-sidebar-box (vertical
   column), not the old horizontal inline row or the #194 floating overlay.
   No background/border on the tte element itself — the sidebar box provides
   the container treatment. Slider uses width:100% to fill sidebar width. */
.aq-sim-tte {
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.aq-sim-tte[hidden] { display: none; }
.aq-sim-tte-label {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--muted, #8aa0b3);
  white-space: nowrap;
}
.aq-sim-tte input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;   /* CHANGELOG_SERIAL.md #200 — was 180px; now fills sidebar column */
  height: 4px;
  background: rgba(167, 139, 250, 0.25);
  border-radius: 4px;
  outline: none;
  cursor: pointer;
}
.aq-sim-tte input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 16px; height: 16px;
  background: #a78bfa;
  border: 2px solid var(--bg-card, #0b1722);
  border-radius: 50%;
  cursor: pointer;
  box-shadow: 0 0 0 1px rgba(167, 139, 250, 0.6);
}
.aq-sim-tte input[type="range"]::-moz-range-thumb {
  width: 16px; height: 16px;
  background: #a78bfa;
  border: 2px solid var(--bg-card, #0b1722);
  border-radius: 50%;
  cursor: pointer;
}
.aq-sim-tte-readout {
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  color: var(--text, inherit);
  white-space: nowrap;
}
.aq-sim-banner[hidden] { display: none; }
.aq-sim-banner-hint { color: var(--muted, #8aa0b3); font-size: 12px; }

/* CHANGELOG_SERIAL.md #194 — .aq-sim-tte-docked was the floating overlay class.
   CHANGELOG_SERIAL.md #200 — Superseded: #aq-sim-tte moved to the sidebar box;
   the .aq-sim-tte-docked class is no longer applied to any element. Rules kept
   as dead-code stub so no stale class reference in any partial render breaks
   layout if the class surfaces unexpectedly. */
.aq-sim-tte-docked {
  /* no longer active — see #200 sidebar relocation */
}

/* CHANGELOG_SERIAL.md #192 — "Back to live" button. Always visible while
   SIM is on so the escape hatch is unmissable. Uses the same pill border
   system as other action buttons (--btn-border). */
.aq-sim-back-btn {
  appearance: none;
  background: rgba(52, 211, 153, 0.14);    /* teal tint = "live" */
  color: var(--text, inherit);
  border: 1px solid rgba(52, 211, 153, 0.55);
  border-radius: 8px;
  font-size: 13px;
  font-weight: 700;
  padding: 6px 14px;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.15s, border-color 0.15s;
}
.aq-sim-back-btn:hover {
  background: rgba(52, 211, 153, 0.26);
  border-color: rgba(52, 211, 153, 0.80);
}
.aq-sim-back-btn[hidden] { display: none; }

/* Purple-tint border on the OI card when sim is active. Cue applies to
   the WHOLE card so even a quick glance signals "this is a projection." */
.live-oi-card.aq-sim-active {
  border-color: rgba(167, 139, 250, 0.55);
  box-shadow: 0 0 0 1px rgba(167, 139, 250, 0.30);
}
/* CHANGELOG_SERIAL.md #192 — cursor: crosshair (click-to-place primary) +
   retain ns-resize cue from legacy drag. Both interactions are active. */
.live-oi-card.aq-sim-active .live-oi-chart-area {
  cursor: crosshair;
}

/* Phase 3: sim-only columns. Hidden everywhere by default; revealed when
   body.aq-sim-on is set by sim.js setBorderClass on activate. */
.sim-only { display: none; }
body.aq-sim-on .sim-only { display: table-cell; }
/* Sim-mid + Sim P&L cells get a faint purple tint so they read as a
   different "world" than the live columns next to them. */
body.aq-sim-on .paper-ladder-table .sim-only,
body.aq-sim-on .paper-positions-table .sim-only {
  background: rgba(167, 139, 250, 0.06);
  border-left: 1px solid rgba(167, 139, 250, 0.18);
}
body.aq-sim-on .paper-ladder-table th.sim-only,
body.aq-sim-on .paper-positions-table th.sim-only {
  color: #a78bfa;
}
.sim-mid-yes { color: #34d399; font-weight: 600; }
.sim-mid-no  { color: #f87171; font-weight: 600; }

/* Phase 4: hover-explain tooltip. Fixed-positioned card; sim.js sets
   left/top from cursor coords on each mousemove. Only visible while
   .aq-sim-tooltip-visible is on. */
.aq-sim-tooltip {
  position: fixed;
  left: 0; top: 0;
  max-width: 340px;
  background: rgba(7, 16, 26, 0.96);
  color: #e8f0f7;
  border: 1px solid rgba(167, 139, 250, 0.55);
  border-radius: 10px;
  padding: 10px 14px;
  font-size: 13px;
  line-height: 1.45;
  box-shadow: 0 14px 32px rgba(0, 0, 0, 0.45);
  pointer-events: none;     /* don't intercept the very drag we're using */
  z-index: 1200;
  opacity: 0;
  transform: translateY(-3px);
  transition: opacity 0.15s ease, transform 0.15s ease;
}
.aq-sim-tooltip-visible {
  opacity: 1;
  transform: translateY(0);
}
.aq-sim-tooltip-strike {
  font-size: 14px;
  font-weight: 700;
  color: #fcd34d;
  margin-bottom: 2px;
}
.aq-sim-tooltip-headline {
  font-size: 12px;
  letter-spacing: 0.3px;
  font-weight: 700;
  margin: 2px 0 6px;
  font-variant-numeric: tabular-nums;
}
.aq-sim-tooltip-verdict-brightened { color: #10b981; }
.aq-sim-tooltip-verdict-dimmed     { color: #ef4444; }
.aq-sim-tooltip-verdict-unchanged  { color: #8aa0b3; }
.aq-sim-tooltip-reason {
  font-size: 12px;
  color: #cad7e5;
  line-height: 1.5;
}

/* ============ Refresh-now button in header ============
   Sits between share-toggle and theme-toggle. Click forces every poller
   to re-fetch with a cache-busting query param. Three transient visual
   states layered as 3 SVGs (only one visible per state). */
.refresh-toggle {
  appearance: none;
  border: 1px solid var(--line);
  background: var(--bg-card);
  color: var(--text);
  width: 34px; height: 34px;
  border-radius: 8px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background-color 0.15s, border-color 0.15s, color 0.15s;
  margin-left: 8px;
  position: relative;
  overflow: hidden;
}
.refresh-toggle:hover { background: rgba(76, 139, 255, 0.08); border-color: rgba(76, 139, 255, 0.45); }
.refresh-toggle:disabled { opacity: 0.85; cursor: wait; }

/* All three SVGs stacked at the same spot; we show one at a time */
.refresh-toggle .refresh-icon {
  position: absolute;
  inset: 0;
  margin: auto;
  display: none;
}
.refresh-toggle .refresh-icon-arrow { display: block; }
.refresh-toggle.spinning .refresh-icon-arrow { display: block; animation: refresh-spin 0.9s linear infinite; }
.refresh-toggle.success .refresh-icon-arrow { display: none; }
.refresh-toggle.success .refresh-icon-check { display: block; color: #10b981; }
.refresh-toggle.success { border-color: rgba(16, 185, 129, 0.55); background: rgba(16, 185, 129, 0.08); }
.refresh-toggle.error .refresh-icon-arrow { display: none; }
.refresh-toggle.error .refresh-icon-error { display: block; color: #ef4444; }
.refresh-toggle.error { border-color: rgba(239, 68, 68, 0.55); background: rgba(239, 68, 68, 0.08); }

@keyframes refresh-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* ============ Terrain color scale legend (CHANGELOG #008) ============
   Slim horizontal bar below the OI chart canvas. Gradient swaps
   between Signed (red↔white↔blue) and Magnitude (blue→cyan→green→
   yellow→orange→red) based on data-terrain-style attribute. End
   labels swap too: "MM sells/buys" vs "quiet/peak". */
.terrain-scale-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 14px 8px;
  font-size: 11px;
  color: rgba(207, 213, 226, 0.7);
  user-select: none;
}
.terrain-scale-label-text {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: rgba(207, 213, 226, 0.85);
}
.terrain-scale-label-left,
.terrain-scale-label-right {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  min-width: 0;
}
.terrain-scale-gradient {
  flex: 1;
  height: 10px;
  border-radius: 3px;
  border: 1px solid rgba(60, 70, 95, 0.45);
}
/* CHANGELOG_SERIAL.md #133 — single unified terrain mode.
   sell(red-500) → pin(amber) → buy(green-500).
   Applies for both the new data-terrain-style="unified" and any legacy
   cached value ("signed"/"magnitude") so old localStorage states degrade
   gracefully. */
.terrain-scale-bar .terrain-scale-gradient,
.terrain-scale-bar[data-terrain-style="unified"] .terrain-scale-gradient,
.terrain-scale-bar[data-terrain-style="signed"] .terrain-scale-gradient,
.terrain-scale-bar[data-terrain-style="magnitude"] .terrain-scale-gradient {
  background: linear-gradient(to right,
    rgb(239,  68,  68)  0%,
    rgb(239,  68,  68) 28%,
    rgb(245, 158,  11) 42%,
    rgb(245, 158,  11) 58%,
    rgb( 34, 197,  94) 72%,
    rgb( 34, 197,  94) 100%);
}

/* ============ Pulse direction-tier legend (CHANGELOG #009) ============
   Static gradient bar below the Pulse main chart showing the 7-tier
   color mapping for binary line direction. Mirrors the OI .terrain-
   scale-bar pattern but doesn't toggle modes (only one palette). */
.pulse-scale-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 14px 8px;
  font-size: 11px;
  color: rgba(207, 213, 226, 0.7);
  user-select: none;
}
.pulse-scale-label-text {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: rgba(207, 213, 226, 0.85);
}
.pulse-scale-label-left,
.pulse-scale-label-right {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.pulse-scale-gradient {
  flex: 1;
  height: 10px;
  border-radius: 3px;
  border: 1px solid rgba(60, 70, 95, 0.45);
  /* CHANGELOG_SERIAL.md #010 — sharp 7-tier blocks replace the smooth
     gradient. Each tier gets ~14.28% of the bar; hard color stops at
     each boundary so adjacent tiers don't blend into muddy in-between
     values. Tailwind 400/500/700 colors. */
  background: linear-gradient(to right,
    rgb(185,  28,  28)   0%, rgb(185,  28,  28)  14.28%,
    rgb(239,  68,  68)  14.28%, rgb(239,  68,  68)  28.57%,
    rgb(248, 113, 113)  28.57%, rgb(248, 113, 113)  42.85%,
    rgb(250, 204,  21)  42.85%, rgb(250, 204,  21)  57.14%,
    rgb( 74, 222, 128)  57.14%, rgb( 74, 222, 128)  71.42%,
    rgb( 34, 197,  94)  71.42%, rgb( 34, 197,  94)  85.71%,
    rgb( 21, 128,  61)  85.71%, rgb( 21, 128,  61) 100%);
}

/* ============ Top brightest strikes panel (CHANGELOG #014) ============
   Compact row of the top-3 highest-intensity per-strike bands rendered
   under the OI chart. The heatmap bands carry intensity visually, but
   without a numeric readout the user can't tell 0.62 from 0.74 — both
   look "kinda bright." This panel surfaces the exact value + direction
   for the strikes that matter most right now. Direction dot color
   mirrors the 4-zone band classifier (green=cyan-dir, red=amber-dir,
   gray=balanced, light-blue=squeeze override ≥ 0.85). */
.oi-top-strikes-panel {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 6px 14px 8px;
  font-size: 11px;
  color: rgba(207, 213, 226, 0.85);
  user-select: none;
  flex-wrap: wrap;
}
.oi-top-strikes-label {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: rgba(207, 213, 226, 0.85);
  white-space: nowrap;
}
.oi-top-strikes-list {
  display: flex;
  gap: 14px;
  list-style: none;
  margin: 0;
  padding: 0;
  flex-wrap: wrap;
}
.oi-top-strike-row {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  padding: 2px 8px;
  border-radius: 4px;
  background: rgba(40, 48, 68, 0.45);
  border: 1px solid rgba(60, 70, 95, 0.45);
}
.oi-top-strike-row.oi-top-strike-empty {
  opacity: 0.45;
}
.oi-top-strike-rank {
  font-size: 10px;
  color: rgba(207, 213, 226, 0.55);
  font-weight: 600;
}
.oi-top-strike-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  border: 1px solid rgba(0, 0, 0, 0.35);
}
/* CHANGELOG_SERIAL.md #133 — green-500/red-500 canonical + amber-pin + sky squeeze. */
.oi-top-strike-dot.dir-cyan    { background: rgb( 34, 197,  94); }  /* green-500 buy */
.oi-top-strike-dot.dir-amber   { background: rgb(239,  68,  68); }  /* red-500 sell */
.oi-top-strike-dot.dir-pin     { background: rgb(245, 158,  11); }  /* amber heavy-pin wall */
.oi-top-strike-dot.dir-gray    { background: rgb(140, 140, 140); }
.oi-top-strike-dot.dir-squeeze { background: rgb(125, 211, 252); border-color: rgba(125, 211, 252, 0.85); }
.oi-top-strike-strike {
  font-weight: 600;
  color: rgba(231, 237, 248, 0.95);
}
.oi-top-strike-intensity {
  color: rgba(231, 237, 248, 0.85);
}
.oi-top-strike-distance {
  color: rgba(207, 213, 226, 0.55);
  font-size: 10px;
}
.oi-top-strike-badge {
  margin-left: 2px;
  padding: 1px 5px;
  border-radius: 3px;
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: rgb(8, 47, 73);
  background: rgb(125, 211, 252);  /* squeeze — sky-blue default */
}
/* CHANGELOG_SERIAL.md #133 — amber badge for heavy-pin wall strikes. */
.oi-top-strike-badge.oi-top-strike-badge-pin {
  color: rgb(28, 14, 0);
  background: rgb(245, 158, 11);
}
.oi-top-strike-pending {
  color: rgba(207, 213, 226, 0.45);
  font-style: italic;
}

/* ============ Read panel + layers row — above-chart flex layout (#026 + #027 + #274) ========
   CHANGELOG_SERIAL.md #274 — restructured into two columns:
   .oi-read-col (left): READ panel stacked above layers pills + GEX row.
   .oi-radar-col (right): Edge Radar card.
   flex-wrap:wrap ensures Edge Radar stacks under the left column at narrow widths.
   align-items:flex-start prevents the shorter READ column from stretching to Edge Radar height. */
.oi-above-chart-row {
  display: flex;
  gap: 16px;
  align-items: flex-start;
  margin: 8px 0 10px;
  flex-wrap: wrap;
}
/* Left column: READ panel + layer pills + GEX expiry */
.oi-read-col {
  flex: 1 1 340px;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
/* Right column: Edge Radar card. 520px floor keeps the 8-col EV table readable;
   below ~900px total the column wraps under the READ column. */
.oi-radar-col {
  flex: 1 1 520px;
  min-width: 0;
}
.oi-radar-col > .edge-radar-card {
  margin: 0;
}
/* Layer pills: was flex:0 0 auto in old direct-child rule; now inside .oi-read-col */
.oi-read-col > .oi-layer-pills {
  flex: 0 0 auto;
  align-self: flex-start;
}

.read-panel {
  padding: 12px 16px 14px;
  border-radius: 6px;
  background: rgba(40, 48, 68, 0.30);
  border: 1px solid rgba(60, 70, 95, 0.45);
  /* CHANGELOG_SERIAL.md #027 — font bumped 12 → 14px per Pete's
     "decent size font" request. Tabular numerals so the dollar
     columns line up cleanly. */
  font-size: 14px;
  color: rgba(231, 237, 248, 0.95);
  font-variant-numeric: tabular-nums;
}
[data-theme="light"] .read-panel {
  background: rgba(241, 245, 249, 0.65);
  border-color: rgba(148, 163, 184, 0.40);
  color: rgba(15, 23, 42, 0.95);
}
.read-panel-header {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 10px;
}
.read-panel-title {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: rgba(125, 211, 252, 0.95);
}
/* CHANGELOG_SERIAL.md #027 — timestamp shows when the panel was last
   refreshed by _updateReadPanel. HH:MM:SS ET. Sits between the title
   and the "auto-updates" hint. Monospaced for stable width. */
.read-panel-ts {
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 600;
  color: rgba(207, 213, 226, 0.85);
  font-variant-numeric: tabular-nums;
}
[data-theme="light"] .read-panel-ts { color: rgba(15, 23, 42, 0.85); }
.read-panel-sub {
  font-size: 11px;
  color: rgba(207, 213, 226, 0.55);
  font-style: italic;
  margin-left: auto;  /* push to the right edge of the header */
}
[data-theme="light"] .read-panel-sub { color: rgba(71, 85, 105, 0.65); }
.read-panel-body {
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.read-row {
  display: flex;
  gap: 12px;
  align-items: baseline;
  line-height: 1.5;
  white-space: normal;
}
.read-row-label {
  flex: 0 0 96px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: rgba(207, 213, 226, 0.65);
  white-space: nowrap;
}
[data-theme="light"] .read-row-label { color: rgba(71, 85, 105, 0.75); }
.read-row-text { flex: 1; }
.read-row-pending {
  color: rgba(207, 213, 226, 0.55);
  font-style: italic;
}
/* CHANGELOG_SERIAL.md #133 — canonical colors. Added read-token-pin. */
.read-token-bullish { color: rgb( 34, 197,  94); font-weight: 600; }  /* green-500 */
.read-token-bearish { color: rgb(239,  68,  68); font-weight: 600; }  /* red-500 */
.read-token-pin     { color: rgb(245, 158,  11); font-weight: 600; }  /* amber pin wall */
.read-token-neutral { color: rgba(207, 213, 226, 0.85); font-weight: 600; }
.read-token-squeeze { color: rgb(125, 211, 252); font-weight: 600; }
.read-token-strike  { font-weight: 600; color: rgba(231, 237, 248, 1); }
[data-theme="light"] .read-token-strike  { color: rgba(15, 23, 42, 1); }
.read-token-dim     { color: rgba(207, 213, 226, 0.55); }
[data-theme="light"] .read-token-dim     { color: rgba(71, 85, 105, 0.65); }
.read-zone-dot {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  margin-right: 6px;
  vertical-align: 1px;
  border: 1px solid rgba(0, 0, 0, 0.35);
}
/* CHANGELOG_SERIAL.md #133 — added dir-pin amber. */
.read-zone-dot.dir-cyan    { background: rgb( 34, 197,  94); }  /* green-500 buy */
.read-zone-dot.dir-amber   { background: rgb(239,  68,  68); }  /* red-500 sell */
.read-zone-dot.dir-pin     { background: rgb(245, 158,  11); }  /* amber heavy-pin wall */
.read-zone-dot.dir-gray    { background: rgb(140, 140, 140); }
.read-zone-dot.dir-squeeze { background: rgb(125, 211, 252); border-color: rgba(125, 211, 252, 0.85); }

/* ============================================================
   CHANGELOG_SERIAL.md #311 — Zone-click explainer panel (Part B + C).
   Docked below the live OI timeline card. Overlays, does not reflow.
   Theme-aware (dark default, light override). Mobile-friendly.
   ============================================================ */
.aq-zone-panel {
  /* Anchored inline below the OI timeline card — inserts via JS */
  margin: 10px 0 0 0;
  padding: 16px 20px 18px;
  border-radius: 8px;
  border: 1px solid rgba(60, 80, 110, 0.55);
  background: rgba(30, 42, 60, 0.92);
  color: rgba(231, 237, 248, 0.95);
  font-size: 13.5px;
  line-height: 1.6;
  font-family: var(--sans);
  /* Don't shift the chart above it */
  position: relative;
  z-index: 10;
  /* Scroll into view on open */
  scroll-margin-top: 16px;
}
[data-theme="light"] .aq-zone-panel {
  background: rgba(241, 245, 249, 0.96);
  border-color: rgba(148, 163, 184, 0.50);
  color: rgba(15, 23, 42, 0.95);
}
.aqzp-header {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
  flex-wrap: wrap;
}
.aqzp-zone-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
  border: 1px solid rgba(0,0,0,0.30);
}
/* Zone dot colors — match 4-zone classifier */
.aqzp-zone-dot-yes-loaded   { background: rgb(34, 197, 94); }   /* green-500 */
.aqzp-zone-dot-no-loaded    { background: rgb(239, 68, 68); }   /* red-500 */
.aqzp-zone-dot-balanced-pin { background: rgb(245, 158, 11); }  /* amber */
.aqzp-zone-dot-thin         { background: rgb(140, 140, 140); } /* gray */
.aqzp-zone-dot-squeeze      { background: rgb(125, 211, 252); border-color: rgba(125, 211, 252, 0.70); }
.aqzp-title {
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.3px;
  flex: 1 1 auto;
}
.aqzp-sub {
  font-size: 12px;
  color: rgba(180, 195, 220, 0.70);
  font-family: var(--mono);
  white-space: nowrap;
}
[data-theme="light"] .aqzp-sub { color: rgba(71, 85, 105, 0.75); }
.aqzp-close {
  background: transparent;
  border: none;
  cursor: pointer;
  font-size: 14px;
  color: rgba(180, 195, 220, 0.70);
  padding: 2px 6px;
  border-radius: 4px;
  line-height: 1;
  flex-shrink: 0;
  transition: color 0.15s;
}
.aqzp-close:hover { color: rgba(231, 237, 248, 0.95); }
[data-theme="light"] .aqzp-close { color: rgba(71, 85, 105, 0.70); }
[data-theme="light"] .aqzp-close:hover { color: rgba(15, 23, 42, 0.95); }
.aqzp-divider {
  height: 1px;
  background: rgba(80, 100, 130, 0.35);
  margin: 0 0 10px;
}
[data-theme="light"] .aqzp-divider { background: rgba(148, 163, 184, 0.40); }
.aqzp-hedge-line {
  font-size: 13.5px;
  font-weight: 600;
  margin-bottom: 12px;
  color: rgba(231, 237, 248, 0.92);
}
[data-theme="light"] .aqzp-hedge-line { color: rgba(15, 23, 42, 0.92); }
.aqzp-blocks {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 14px;
}
.aqzp-block {
  display: flex;
  gap: 10px;
  align-items: flex-start;
}
.aqzp-block-label {
  flex: 0 0 130px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: rgba(180, 195, 220, 0.60);
  padding-top: 2px;
  white-space: nowrap;
}
[data-theme="light"] .aqzp-block-label { color: rgba(71, 85, 105, 0.75); }
.aqzp-block-text {
  flex: 1;
  font-size: 13px;
  line-height: 1.55;
  color: rgba(210, 220, 238, 0.90);
}
[data-theme="light"] .aqzp-block-text { color: rgba(30, 42, 60, 0.92); }
.aqzp-footer {
  display: flex;
  justify-content: flex-end;
  padding-top: 4px;
  border-top: 1px solid rgba(80, 100, 130, 0.25);
}
[data-theme="light"] .aqzp-footer { border-top-color: rgba(148, 163, 184, 0.30); }
.aqzp-ralph-btn {
  background: rgba(92, 182, 255, 0.10);
  border: 1px solid rgba(92, 182, 255, 0.35);
  border-radius: 5px;
  color: rgb(92, 182, 255);
  font-size: 12.5px;
  font-weight: 600;
  padding: 6px 14px;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
  font-family: var(--sans);
}
.aqzp-ralph-btn:hover {
  background: rgba(92, 182, 255, 0.20);
  border-color: rgba(92, 182, 255, 0.65);
}
[data-theme="light"] .aqzp-ralph-btn {
  background: rgba(0, 82, 204, 0.07);
  border-color: rgba(0, 82, 204, 0.40);
  color: rgb(0, 82, 204);
}
[data-theme="light"] .aqzp-ralph-btn:hover {
  background: rgba(0, 82, 204, 0.13);
  border-color: rgba(0, 82, 204, 0.70);
}

/* CHANGELOG_SERIAL.md #319 — Track record block inside zone-click panel */
.aqzp-trackrecord-wrap {
  /* shown once stats load; hidden if fetch fails (set via JS display:none) */
}
.aqzp-trackrecord {
  margin: 6px 0 4px;
  padding: 9px 12px 9px;
  border-radius: 5px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(80, 100, 130, 0.25);
  font-size: 12.5px;
  line-height: 1.55;
}
[data-theme="light"] .aqzp-trackrecord {
  background: rgba(15, 23, 42, 0.04);
  border-color: rgba(100, 116, 139, 0.25);
}
.aqzp-tr-header {
  font-size: 12px;
  font-weight: 600;
  color: rgba(180, 195, 220, 0.80);
  margin-bottom: 4px;
  letter-spacing: 0.2px;
}
[data-theme="light"] .aqzp-tr-header {
  color: rgba(71, 85, 105, 0.80);
}
.aqzp-tr-row {
  color: rgba(200, 215, 235, 0.90);
  margin-bottom: 2px;
}
[data-theme="light"] .aqzp-tr-row {
  color: rgba(30, 42, 60, 0.88);
}
.aqzp-tr-notyet {
  font-size: 12px;
  color: rgba(140, 140, 140, 0.85);
  font-style: italic;
}
[data-theme="light"] .aqzp-tr-notyet {
  color: rgba(100, 116, 139, 0.80);
}
.aqzp-tr-footnote {
  margin-top: 4px;
  font-size: 11px;
  color: rgba(140, 155, 175, 0.60);
}
[data-theme="light"] .aqzp-tr-footnote {
  color: rgba(100, 116, 139, 0.60);
}

/* ===========================================================================
   CHANGELOG_SERIAL.md #330 — Strategy Lab tab styles.
   Palette: Tailwind 400/500/700 only (FRONTEND_CONVENTIONS.md).
   Mobile-first: single-column stacked cards, >=40px tap targets, no hover-only
   affordances. Mobile overrides inside @media (max-width: 480px) at EOF.
   =========================================================================== */

/* Lab page card wrapper (tab-content container) */
.lab-card {
  padding: 0;
  background: transparent;
  border: none;
  box-shadow: none;
}

/* ---- Scanner status strip ---- */
.lab-scanner-strip {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px 10px;
  padding: 8px 16px;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 8px;
  margin-bottom: 14px;
  font-size: 12px;
  font-family: var(--sans);
}
.lab-scanner-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-dim);
  flex-shrink: 0;
}
.lab-scanner-sep {
  color: var(--line-strong);
  flex-shrink: 0;
}
.lab-scanner-item {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
}
.lab-scanner-k {
  font-size: 11px;
  font-weight: 600;
  color: var(--text-dim);
}
.lab-scanner-v {
  font-size: 12px;
  font-weight: 500;
  color: var(--text);
}
.lab-scanner-strip.lab-scanner-stale .lab-scanner-label {
  color: rgb(239, 68, 68); /* red-500 — stale scanner */
}

/* ---- Cards grid ---- */
.lab-grid {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.lab-placeholder {
  padding: 24px 0;
  text-align: center;
  color: var(--text-dim);
  font-size: 13px;
  font-family: var(--sans);
}

/* ---- Individual strategy card ---- */
.lab-strat-card {
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 14px 16px;
  font-family: var(--sans);
  transition: border-color 0.15s;
}
/* Fired = accent green left border */
.lab-strat-card.lab-state-fired {
  border-left: 4px solid rgb(34, 197, 94); /* green-500 */
}
/* Armed = amber left border */
.lab-strat-card.lab-state-armed {
  border-left: 4px solid rgb(250, 204, 21); /* yellow-400 */
}
/* Idle = muted left border */
.lab-strat-card.lab-state-idle {
  border-left: 4px solid var(--line-strong);
}
/* Rejected = red left border + dimmed text */
.lab-strat-card.lab-state-rejected {
  border-left: 4px solid rgb(239, 68, 68); /* red-500 */
  opacity: 0.65;
}

/* ---- Card header row ---- */
.lab-card-header {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 8px;
}
.lab-card-id {
  font-size: 11px;
  font-weight: 700;
  font-family: var(--mono);
  color: var(--text-dim);
  flex-shrink: 0;
  margin-top: 1px;
}
.lab-card-name {
  font-size: 14px;
  font-weight: 700;
  color: var(--text);
  flex: 1 1 auto;
  min-width: 0;
}
/* Author badge */
.lab-badge {
  display: inline-flex;
  align-items: center;
  height: 20px;
  padding: 0 6px;
  border-radius: 4px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  flex-shrink: 0;
}
.lab-badge-author {
  background: rgba(92, 182, 255, 0.15);
  color: var(--accent);
  border: 1px solid rgba(92, 182, 255, 0.30);
}
/* Live state pill */
.lab-state-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 22px;
  padding: 0 8px;
  border-radius: 5px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  flex-shrink: 0;
}
.lab-state-pill.lab-pill-fired {
  background: rgba(34, 197, 94, 0.18);  /* green-500 */
  color: rgb(34, 197, 94);
  border: 1px solid rgba(34, 197, 94, 0.40);
}
.lab-state-pill.lab-pill-armed {
  background: rgba(250, 204, 21, 0.15);  /* yellow-400 */
  color: rgb(161, 131, 0);
  border: 1px solid rgba(250, 204, 21, 0.40);
}
[data-theme="dark"] .lab-state-pill.lab-pill-armed {
  color: rgb(250, 204, 21);
}
.lab-state-pill.lab-pill-idle {
  background: rgba(140, 140, 140, 0.12);
  color: var(--text-dim);
  border: 1px solid var(--line);
}
.lab-state-pill.lab-pill-rejected {
  background: rgba(239, 68, 68, 0.12); /* red-500 */
  color: rgb(239, 68, 68);
  border: 1px solid rgba(239, 68, 68, 0.30);
  text-decoration: line-through;
}
.lab-fire-count {
  font-size: 10px;
  font-weight: 700;
  background: rgb(34, 197, 94); /* green-500 */
  color: #fff;
  border-radius: 8px;
  padding: 0 5px;
  height: 16px;
  display: inline-flex;
  align-items: center;
}

/* ---- Thesis line ---- */
.lab-card-thesis {
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-muted);
  margin-bottom: 10px;
}
.lab-strat-card.lab-state-rejected .lab-card-thesis {
  text-decoration: line-through;
  opacity: 0.8;
}

/* ---- Chips row (structure + tenor + status) ---- */
.lab-chips {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-bottom: 10px;
}
.lab-chip {
  display: inline-flex;
  align-items: center;
  height: 20px;
  padding: 0 7px;
  border-radius: 4px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  background: var(--bg-table-alt);
  color: var(--text-dim);
  border: 1px solid var(--line);
}
/* Status chip colours keyed on status value */
.lab-chip-status-validated   { background: rgba(34, 197, 94, 0.12); color: rgb(21, 128, 61); border-color: rgba(34, 197, 94, 0.30); } /* green-700 text, green-500 bg */
.lab-chip-status-paper-live  { background: rgba(34, 197, 94, 0.20); color: rgb(21, 128, 61); border-color: rgba(34, 197, 94, 0.45); }
.lab-chip-status-idea        { background: rgba(92, 182, 255, 0.10); color: var(--accent); border-color: rgba(92, 182, 255, 0.25); }
.lab-chip-status-backtesting { background: rgba(250, 204, 21, 0.10); color: rgb(161, 131, 0); border-color: rgba(250, 204, 21, 0.30); }
.lab-chip-status-needs-data  { background: rgba(250, 204, 21, 0.10); color: rgb(161, 131, 0); border-color: rgba(250, 204, 21, 0.30); }
.lab-chip-status-rejected    { background: rgba(239, 68, 68, 0.10); color: rgb(239, 68, 68); border-color: rgba(239, 68, 68, 0.25); }
[data-theme="dark"] .lab-chip-status-validated,
[data-theme="dark"] .lab-chip-status-paper-live { color: rgb(34, 197, 94); }
[data-theme="dark"] .lab-chip-status-backtesting,
[data-theme="dark"] .lab-chip-status-needs-data { color: rgb(250, 204, 21); }

/* ---- Entry/exit collapsible ---- */
.lab-entry-exit {
  margin-bottom: 10px;
}
.lab-ee-toggle {
  background: transparent;
  border: none;
  cursor: pointer;
  font-size: 11px;
  font-weight: 600;
  color: var(--accent);
  font-family: var(--sans);
  padding: 4px 0;
  min-height: 40px; /* >=40px tap target */
  display: inline-flex;
  align-items: center;
  gap: 4px;
  -webkit-tap-highlight-color: transparent;
}
.lab-ee-toggle:hover { color: var(--accent-hover); }
.lab-ee-body {
  margin-top: 4px;
  padding: 8px 12px;
  background: var(--bg-table-alt);
  border: 1px solid var(--line);
  border-radius: 6px;
  font-size: 12px;
  line-height: 1.55;
  color: var(--text-muted);
}
.lab-ee-body[hidden] { display: none; }
.lab-ee-row {
  display: flex;
  gap: 6px;
  margin-bottom: 4px;
}
.lab-ee-row:last-child { margin-bottom: 0; }
.lab-ee-label {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-dim);
  flex-shrink: 0;
  min-width: 36px;
  padding-top: 1px;
}

/* ---- Stats row ---- */
.lab-stats {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-bottom: 10px;
  padding: 8px 10px;
  background: var(--bg-table-alt);
  border: 1px solid var(--line);
  border-radius: 6px;
}
.lab-stat {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 60px;
}
.lab-stat-k {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-dim);
}
.lab-stat-v {
  font-size: 13px;
  font-weight: 700;
  font-family: var(--mono);
  color: var(--text);
}
.lab-stat-v.lab-stat-pos { color: rgb(34, 197, 94);  } /* green-500 */
.lab-stat-v.lab-stat-neg { color: rgb(239, 68, 68);  } /* red-500  */
.lab-stat-v.lab-stat-null { color: var(--text-dim); }
/* Small-sample warning */
.lab-small-sample {
  display: inline-flex;
  align-items: center;
  font-size: 10px;
  font-weight: 700;
  color: rgb(250, 204, 21); /* yellow-400 */
  margin-left: 3px;
  cursor: help;
}

/* ---- Card footer ---- */
.lab-card-footer {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  border-top: 1px solid var(--line);
  padding-top: 8px;
  margin-top: 4px;
}
.lab-footer-item {
  font-size: 11px;
  color: var(--text-dim);
}
.lab-footer-item .lab-footer-k {
  font-weight: 600;
}

/* ---- Live detail line (shown only when state != idle) ---- */
.lab-live-detail {
  font-size: 11px;
  font-weight: 500;
  color: var(--text-muted);
  margin-bottom: 8px;
  padding: 4px 8px;
  background: var(--bg-table-alt);
  border-left: 2px solid rgb(34, 197, 94); /* green-500 */
  border-radius: 0 4px 4px 0;
}
.lab-strat-card.lab-state-armed .lab-live-detail {
  border-left-color: rgb(250, 204, 21); /* yellow-400 */
}
.lab-strat-card.lab-state-rejected .lab-live-detail,
.lab-strat-card.lab-state-idle    .lab-live-detail {
  display: none;
}

/* ---- Error / unavailable state ---- */
.lab-error {
  padding: 24px 0;
  text-align: center;
  color: rgb(239, 68, 68); /* red-500 */
  font-size: 13px;
  font-family: var(--sans);
}

/* ---- CHANGELOG_SERIAL.md #336 — Headline stats block (EV/ROI) ---- */
.lab-stats-headline {
  margin-bottom: 6px;
  border-color: rgba(34, 197, 94, 0.20); /* green-500 accent tint */
}
/* Larger value font for headline metrics */
.lab-stat-v-lg {
  font-size: 16px;
}

/* ---- Stats legend line ---- */
.lab-stats-legend {
  font-size: 10px;
  color: var(--text-dim);
  font-family: var(--sans);
  margin-bottom: 10px;
  line-height: 1.4;
}

/* ==========================================================================
   CHANGELOG_SERIAL.md #336 — TEST STRATS (Paper/Test) portfolio section
   Palette: Tailwind 400/500/700 only. Mobile-first single column.
   Unmistakably PAPER / TEST — amber header band, dashed border.
   ========================================================================== */

/* Outer section wrapper */
.tp-section {
  margin-top: 28px;
  border: 2px dashed rgba(250, 204, 21, 0.45); /* yellow-400 dashed = test/paper signal */
  border-radius: 10px;
  font-family: var(--sans);
  overflow: hidden;
}

/* Section header band */
.tp-section-header {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 8px 14px;
  background: rgba(250, 204, 21, 0.10); /* yellow-400 very light */
  border-bottom: 1px solid rgba(250, 204, 21, 0.30);
}
.tp-section-badge {
  display: inline-flex;
  align-items: center;
  height: 20px;
  padding: 0 7px;
  border-radius: 4px;
  background: rgba(250, 204, 21, 0.20);
  color: rgb(161, 131, 0);
  border: 1px solid rgba(250, 204, 21, 0.50);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  flex-shrink: 0;
}
[data-theme="dark"] .tp-section-badge {
  color: rgb(250, 204, 21); /* yellow-400 */
}
.tp-section-title {
  font-size: 13px;
  font-weight: 700;
  color: var(--text);
}
.tp-section-sub {
  font-size: 11px;
  color: var(--text-dim);
  font-style: italic;
}

/* Body padding */
.tp-body {
  padding: 12px 14px;
}

/* Generated-at timestamp */
.tp-generated {
  font-size: 10px;
  color: var(--text-dim);
  margin-bottom: 10px;
  text-align: right;
}

/* Placeholder / empty state */
.tp-placeholder {
  padding: 20px 0;
  text-align: center;
  color: var(--text-dim);
  font-size: 13px;
}

/* Strategy group */
.tp-group {
  margin-bottom: 18px;
}
.tp-group:last-child {
  margin-bottom: 0;
}
.tp-group-header {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
  padding: 6px 10px;
  background: var(--bg-table-alt);
  border: 1px solid var(--line);
  border-radius: 6px 6px 0 0;
  border-bottom: none;
}
.tp-group-id {
  font-size: 12px;
  font-weight: 700;
  font-family: var(--mono);
  color: var(--accent);
  flex-shrink: 0;
}
.tp-group-counts {
  font-size: 11px;
  color: var(--text-dim);
  flex-shrink: 0;
}
/* Headline P&L / ROI for the group */
.tp-group-headline {
  display: flex;
  gap: 8px;
  align-items: baseline;
  flex-wrap: wrap;
  margin-left: auto; /* push to right on desktop */
}
.tp-group-roi {
  font-size: 15px;
  font-weight: 700;
  font-family: var(--mono);
}
.tp-group-pnl {
  font-size: 12px;
  font-weight: 600;
  font-family: var(--mono);
}

/* Trade rows list */
.tp-group-trades {
  border: 1px solid var(--line);
  border-top: none;
  border-radius: 0 0 6px 6px;
  overflow: hidden;
}
.tp-trade-row {
  padding: 8px 10px;
  border-bottom: 1px solid var(--line);
}
.tp-trade-row:last-child {
  border-bottom: none;
}

/* Trade top row: ID · meta · badge */
.tp-trade-top {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 4px;
}
.tp-trade-id {
  font-size: 10px;
  font-weight: 700;
  font-family: var(--mono);
  color: var(--text-dim);
  flex-shrink: 0;
}
.tp-trade-meta {
  font-size: 11px;
  color: var(--text-muted);
  flex: 1 1 auto;
}

/* Status badges */
.tp-badge {
  display: inline-flex;
  align-items: center;
  height: 18px;
  padding: 0 6px;
  border-radius: 4px;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  flex-shrink: 0;
}
.tp-badge-open {
  background: rgba(250, 204, 21, 0.15); /* yellow-400 */
  color: rgb(161, 131, 0);
  border: 1px solid rgba(250, 204, 21, 0.40);
}
[data-theme="dark"] .tp-badge-open {
  color: rgb(250, 204, 21);
}
.tp-badge-win {
  background: rgba(34, 197, 94, 0.15); /* green-500 */
  color: rgb(21, 128, 61);             /* green-700 */
  border: 1px solid rgba(34, 197, 94, 0.35);
}
[data-theme="dark"] .tp-badge-win {
  color: rgb(34, 197, 94);
}
.tp-badge-loss {
  background: rgba(239, 68, 68, 0.12); /* red-500 */
  color: rgb(239, 68, 68);
  border: 1px solid rgba(239, 68, 68, 0.30);
}

/* Leg display */
.tp-legs {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-bottom: 3px;
}
.tp-leg {
  font-size: 11px;
  font-family: var(--mono);
  color: var(--text);
}
.tp-leg-sep {
  color: var(--text-dim);
  font-size: 11px;
}

/* Trigger / description line */
.tp-trigger {
  font-size: 11px;
  color: var(--text-dim);
  margin-bottom: 3px;
}

/* Approximate entry marker */
.tp-approx {
  display: inline;
  font-size: 10px;
  font-weight: 600;
  color: rgb(250, 204, 21); /* yellow-400 */
  margin-left: 4px;
  cursor: help;
}

/* Settled result (P&L + ROI%) */
.tp-result {
  font-size: 13px;
  font-weight: 700;
  font-family: var(--mono);
}
.tp-pnl-pos { color: rgb(34, 197, 94);  } /* green-500 */
.tp-pnl-neg { color: rgb(239, 68, 68);  } /* red-500  */

@media (max-width: 480px) {
  /* CHANGELOG_SERIAL.md #330 — Lab mobile overrides (inside EOF 480px block
     is preferred per FRONTEND_CONVENTIONS.md but we add a standalone
     @media here before it to avoid re-opening that large block). */
  .lab-scanner-strip {
    padding: 6px 10px;
    font-size: 11px;
    gap: 4px 8px;
  }
  .lab-strat-card {
    padding: 12px 12px;
  }
  .lab-card-name {
    font-size: 13px;
  }
  .lab-card-thesis {
    font-size: 12px;
  }
  .lab-stats {
    gap: 8px 10px;
  }
  .lab-stat-v {
    font-size: 12px;
  }
  /* CHANGELOG_SERIAL.md #336 — portfolio mobile */
  .tp-section {
    margin-top: 18px;
  }
  .tp-group-headline {
    margin-left: 0;
    width: 100%;
  }
  .tp-group-roi {
    font-size: 14px;
  }
  .tp-stat-v-lg {
    font-size: 14px;
  }
}

@media (max-width: 480px) {
  /* CHANGELOG_SERIAL.md #274 — tighten the 2-col above-chart layout on phone;
     .oi-radar-col's flex-basis wraps it under .oi-read-col automatically. */
  .oi-above-chart-row { gap: 10px; }
     .oi-radar-col's flex-basis wraps it under .oi-read-col automatically. */
  .oi-above-chart-row { gap: 10px; }
  .oi-read-col { gap: 8px; }
  .read-panel {
    padding: 9px 11px 11px;
    font-size: 12px;
  }
  .read-row-label { flex-basis: 72px; font-size: 10px; }
  .read-panel-title { font-size: 11px; }
  .read-panel-ts { font-size: 11px; }
}

/* ============ iPhone Safari portrait polish (CHANGELOG #023) ============
   The page already has @media (max-width:720px) breakpoints handling
   tablet-ish viewports, but iPhone portrait (~375-430px) needs
   tighter rules: 4-column stat strips → 2x2, sidebars stacked above
   charts (the existing 1100px sidebar-collapse fires but legends
   stay 2-column at iPhone widths), tighter chart heights, and the
   layer-pill row allowed to wrap onto two lines. ALL FIXES OPT-IN
   via media query so desktop is untouched. */
@media (max-width: 480px) {
  /* Hero stat strip: 4 columns → 2x2 so each tile keeps a readable
     value font without being squashed. Slim variant hardcoded 4cols. */
  .hero-pin-card.hero-pin-slim .hero-pin-grid {
    grid-template-columns: 1fr 1fr;
    gap: 10px 14px;
    padding: 10px 12px;
  }
  .hero-pin-value {
    font-size: 18px;
    line-height: 1.05;
  }
  .hero-pin-label { font-size: 10px; letter-spacing: 0.6px; }
  .hero-pin-sub   { font-size: 10px; }

  /* Sidebars: legends were 2-column at the 1100px breakpoint. On
     iPhone there isn't horizontal room for that — drop to single
     column so each legend item gets full width and reads clean. */
  .live-oi-sidebar .oi-legend-grid,
  .pulse-15m-sidebar .oi-legend-grid {
    grid-template-columns: 1fr;
  }
  .live-oi-sidebar,
  .pulse-15m-sidebar {
    padding-right: 0;
    padding-bottom: 10px;
    font-size: 13px;
  }
  .live-oi-sidebar .card-title,
  .pulse-15m-sidebar .card-title { font-size: 16px; }

  /* Chart heights — phones get less vertical screen, so shrink the
     canvas areas so the page isn't 3000px tall to scroll. */
  body[data-active-tab="live"] .live-oi-main > .live-oi-chart-area,
  .live-oi-chart-area { min-height: 280px; height: 280px; }
  .pulse-15m-chart-area { height: 240px; }
  .pulse-15m-marginal-area { height: 44px; }

  /* Card padding tighter on phone — every horizontal px counts. */
  .card,
  .live-oi-card,
  .pulse-15m-card,
  .live-15m-outcomes-card,
  .hero-pin-card {
    padding-left: 12px;
    padding-right: 12px;
  }

  /* Layer pills + zoom pills: allow wrapping to a second row instead
     of horizontal scroll. Right-justify still works because flex
     wrap inherits parent justify-content: flex-end. */
  .oi-zoom-pills {
    flex-wrap: wrap;
    justify-content: flex-start;
    gap: 6px 8px;
  }
  .oi-zoom-pill {
    font-size: 11px;
    padding: 4px 8px;
  }
  .oi-zoom-label { font-size: 10px; }

  /* Brightest strikes panel: rows stack vertically when they would
     overflow horizontally; tighten font and padding so each row fits
     on one phone-width line. */
  .oi-top-strikes-panel {
    gap: 6px;
    font-size: 10px;
    padding: 6px 8px;
  }
  .oi-top-strikes-list { gap: 6px 10px; }
  .oi-top-strike-row { padding: 2px 6px; }

  /* Terrain + Pulse scale legends — keep visible but tighten. */
  .terrain-scale-bar,
  .pulse-scale-bar {
    gap: 6px;
    padding: 4px 10px 6px;
    font-size: 10px;
  }

  /* CHANGELOG_SERIAL.md #093 — header v2 mobile overrides.
     Hides tagline, shrinks search to icon-only, collapses status
     strip to data freshness only. */
  .hdr-tagline { display: none; }
  .hdr-wordmark { font-size: 15px; }
  .hdr-search-label { display: none; }
  .hdr-search-kbd { display: none; }
  .hdr-search-trigger { max-width: 40px; flex: 0 0 40px; justify-content: center; padding: 6px; margin: 0 4px; }
  /* Status strip: show only data freshness on mobile */
  .hdr-strip-item:not(.hdr-strip-freshness),
  .hdr-strip-sep { display: none; }
  .hdr-strip-freshness { display: inline-flex; }
  /* CHANGELOG_SERIAL.md #230 — keep mobile min-height in line with condensed desktop row */
  .hdr-main-row { min-height: 44px; }

  /* Theme toggle: make the moon/sun more tappable on mobile —
     this is the #1 fix-it-yourself escape hatch if the page lands
     in the wrong theme for any reason. Apple HIG hit target = 44px. */
  #theme-toggle {
    width: 44px;
    height: 44px;
    min-width: 44px;
  }

  /* Tab buttons row — at 970px collapse exists, but at 480px
     allow horizontal scroll on the tab bar rather than wrapping
     (tabs are meant to be a single row visually). */
  .tab-nav,
  .tab-bar {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }

  /* Biggest-flow callout: long money strings can overflow on phone;
     allow wrap. */
  .biggest-flow-callout {
    flex-wrap: wrap;
    font-size: 11px;
  }

  /* Forecast EOH numbers in the hero pin need to stay legible. */
  .hero-pin-value.tte  { font-size: 18px; }
  .hero-pin-value.band { font-size: 12px; }

  /* Lessons panel: tighten font on phone */
  .ap-lesson { padding: 6px 10px; }
  .ap-lesson-headline { font-size: 12px; }

  /* CHANGELOG_SERIAL.md #053 — trade alert toasts: full-width on phone */
  .ap-toast-container {
    top: 10px;
    right: 10px;
    left: 10px;
    max-width: none;
    min-width: 0;
  }

  /* CHANGELOG_SERIAL.md #059 — hide GEX expiry selector on mobile */
  .gex-expiry-row { display: none; }

  /* CHANGELOG_SERIAL.md #064 — tighten trades table on phone */
  .ap-trades-table th, .ap-trades-table td { padding: 5px 6px; font-size: 12px; }

  /* CHANGELOG_SERIAL.md #067 — stack pagination on phone */
  .ap-trades-pagination { flex-wrap: wrap; gap: 8px; }
  .ap-page-indicator { width: 100%; text-align: center; }

  /* CHANGELOG_SERIAL.md #135/#136 — replay chart: tighten on phone.
     320px gives more strike rows than the previous 280px without overflowing. */
  .replay-timeline-chart-wrap { height: 320px; }

  /* CHANGELOG_SERIAL.md #341 — EMA heatmap strip: full readout on phone.
     .ema-top-cols already switches to 1-column grid at max-width:560px so
     the two EMA cols stack vertically — padding just tightens on phone. */
  .ema-heatmap-strip {
    padding: 4px 8px 6px;
  }
}


/* ============================================================
 * CHANGELOG_SERIAL.md #059 — GEX expiry selector
 * ============================================================ */
.gex-expiry-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 0 2px;
  flex-wrap: wrap;
}
.gex-expiry-selector {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.gex-expiry-btn {
  appearance: none;
  border: 1px solid var(--line, #1c2c3d);
  background: transparent;
  color: var(--muted, #8aa0b3);
  cursor: pointer;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.5px;
  padding: 3px 10px;
  border-radius: 6px;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.gex-expiry-btn:hover {
  color: var(--text, #d0dde8);
  border-color: var(--muted, #8aa0b3);
}
.gex-expiry-btn.is-active {
  background: rgba(34, 197, 94, 0.15);
  border-color: rgb(34, 197, 94);
  color: rgb(34, 197, 94);
}

/* ============================================================
 * Auto Paper Trader card (CHANGELOG #032 Phase 2)
 * Terrain-driven auto-trader tile on the Paper tab.
 * ============================================================ */

.auto-paper-card .ap-portfolio-strip {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 10px;
  margin: 12px 0 18px;
}

.ap-halt-badge {
  display: inline-block;
  padding: 2px 8px;
  background: rgba(220, 38, 38, 0.18);
  color: #dc2626;
  border: 1px solid rgba(220, 38, 38, 0.45);
  border-radius: 10px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  margin-left: 8px;
  vertical-align: middle;
}
.ap-halt-badge.hidden { display: none; }

.ap-section-title {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 22px 0 10px;
}

/* Active contracts strip — each contract gets a row with its bands. */
.ap-contracts {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.ap-contract {
  padding: 8px 12px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: 6px;
}
.ap-contract-head {
  display: flex;
  gap: 12px;
  align-items: baseline;
  flex-wrap: wrap;
  font-size: 12px;
  margin-bottom: 6px;
}
.ap-contract-kind {
  font-weight: 600;
  letter-spacing: 0.05em;
  font-size: 11px;
  padding: 1px 6px;
  background: rgba(59, 130, 246, 0.16);
  color: #3b82f6;
  border-radius: 4px;
}
.ap-contract-settle { color: var(--muted); }
.ap-contract-spot { font-weight: 600; color: var(--text); }

.ap-band-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.ap-band-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 10px;
  font-weight: 500;
  border: 1px solid transparent;
}
.ap-band-int {
  font-size: 10px;
  opacity: 0.75;
}
.ap-band-green {
  background: rgba(34, 197, 94, 0.18);
  color: #15803d;
  border-color: rgba(34, 197, 94, 0.35);
}
.ap-band-red {
  background: rgba(239, 68, 68, 0.18);
  color: #dc2626;
  border-color: rgba(239, 68, 68, 0.35);
}
.ap-band-blue {
  background: rgba(125, 211, 252, 0.22);
  color: #0284c7;
  border-color: rgba(125, 211, 252, 0.45);
}
.ap-band-gray {
  background: rgba(160, 160, 160, 0.18);
  color: var(--muted);
  border-color: rgba(160, 160, 160, 0.35);
}

/* Positions table — like paper-positions-table but its own selector
 * so we can adjust without touching manual paper. */
.ap-table-wrap {
  overflow-x: auto;
  margin-bottom: 8px;
}
.ap-positions-table,
.ap-rules-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
}
.ap-positions-table th,
.ap-rules-table th {
  text-align: left;
  font-weight: 600;
  color: var(--muted);
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 8px 8px;
  border-bottom: 1px solid var(--line);
}
.ap-positions-table td,
.ap-rules-table td {
  padding: 7px 8px;
  border-bottom: 1px solid var(--line);
}
.ap-positions-table tr:last-child td,
.ap-rules-table tr:last-child td { border-bottom: 0; }

.ap-positions-table td.pos,
.ap-rules-table td.pos { color: #15803d; font-weight: 600; }
.ap-positions-table td.neg,
.ap-rules-table td.neg { color: #dc2626; font-weight: 600; }

.ap-side-chip {
  display: inline-block;
  padding: 1px 7px;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
}
.ap-side-yes {
  background: rgba(34, 197, 94, 0.22);
  color: #15803d;
}
.ap-side-no {
  background: rgba(239, 68, 68, 0.22);
  color: #dc2626;
}

.ap-reason-chip {
  display: inline-block;
  padding: 1px 7px;
  border-radius: 4px;
  font-size: 10px;
  letter-spacing: 0.04em;
}

/* CHANGELOG_SERIAL.md #064 — completed trades table */
.ap-trades-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.ap-trades-table th {
  text-align: left;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 4px 8px 6px;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
.ap-trades-table td {
  padding: 6px 8px;
  border-bottom: 1px solid var(--line, rgba(255,255,255,0.06));
  vertical-align: middle;
  font-variant-numeric: tabular-nums;
}
.ap-trades-table tr:last-child td { border-bottom: 0; }
.ap-trades-table tr:hover td { background: rgba(255,255,255,0.03); }
.pos { color: rgb(34, 197, 94); }
.neg { color: rgb(239, 68, 68); }

/* CHANGELOG_SERIAL.md #067 — trades pagination controls */
.ap-trades-pagination {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 2px 4px;
}
.ap-page-btn {
  appearance: none;
  border: 1px solid var(--line, #1c2c3d);
  background: transparent;
  color: var(--muted, #8aa0b3);
  cursor: pointer;
  font-size: 12px;
  font-weight: 600;
  padding: 4px 12px;
  border-radius: 6px;
  transition: color 0.15s, border-color 0.15s;
}
.ap-page-btn:hover:not(:disabled) {
  color: var(--text, #d0dde8);
  border-color: var(--muted, #8aa0b3);
}
.ap-page-btn:disabled { opacity: 0.35; cursor: default; }
.ap-page-indicator {
  font-size: 12px;
  color: var(--muted, #8aa0b3);
  font-variant-numeric: tabular-nums;
}

/* ============================================================
 * CHANGELOG_SERIAL.md #070 — GEX-by-strike tile
 * ============================================================ */
.gex-tile-subheader {
  font-size: 11px;
  color: var(--text-muted, #5a6478);
  margin: 4px 0 12px;
  letter-spacing: 0.02em;
}
.gex-tile-header-strip {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 10px;
  margin-bottom: 14px;
}
.gex-stat {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.gex-stat-label {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted, #5a6478);
}
.gex-stat-value {
  font-size: 16px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--text, #1a1f2e);
}
.gex-stat-value.pos { color: rgb(34, 197, 94); }
.gex-stat-value.neg { color: rgb(239, 68, 68); }
.gex-tile-selector {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
.gex-tile-body {
  display: flex;
  flex-direction: column;
  gap: 3px;
  max-height: 520px;
  overflow-y: auto;
}
.gex-strike-row {
  display: grid;
  grid-template-columns: 80px 1fr 72px;
  align-items: center;
  gap: 8px;
  padding: 3px 4px;
  border-radius: 4px;
  transition: background 0.1s;
}
.gex-strike-row:hover { background: rgba(0,0,0,0.04); }
.gex-strike-atm {
  background: rgba(125, 211, 252, 0.10);
  border-left: 2px solid rgba(125, 211, 252, 0.6);
  padding-left: 6px;
}
.gex-strike-label {
  font-size: 12px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--text, #1a1f2e);
  white-space: nowrap;
}
.gex-bar-track {
  position: relative;
  height: 10px;
  background: rgba(0,0,0,0.06);
  border-radius: 4px;
  overflow: hidden;
}
.gex-bar-fill {
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  border-radius: 4px;
  transition: width 0.25s;
}
.gex-strike-value {
  font-size: 11px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}
.gex-strike-value.pos { color: rgb(34, 197, 94); }
.gex-strike-value.neg { color: rgb(239, 68, 68); }
.gex-tile-formula {
  margin-top: 14px;
  font-size: 10px;
  color: var(--text-dim, #8a93a3);
  letter-spacing: 0.02em;
}
.gex-tile-empty {
  padding: 18px 0;
  text-align: center;
}

@media (max-width: 480px) {
  /* CHANGELOG_SERIAL.md #070 — GEX tile: collapse stat strip to 2×2 */
  .gex-tile-header-strip {
    grid-template-columns: 1fr 1fr;
  }
  .gex-strike-row {
    grid-template-columns: 68px 1fr 60px;
  }
  .gex-strike-label { font-size: 11px; }
  .gex-stat-value   { font-size: 14px; }
}

/* CHANGELOG_SERIAL.md #064 — collapsible accordion panels */
.ap-accordion {
  border: 1px solid var(--line, #1c2c3d);
  border-radius: 8px;
  margin-top: 12px;
  overflow: hidden;
}
.ap-accordion[open] { margin-bottom: 4px; }
.ap-accordion-summary {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  cursor: pointer;
  user-select: none;
  list-style: none;
  background: var(--bg-card2, rgba(255,255,255,0.03));
}
.ap-accordion-summary::-webkit-details-marker { display: none; }
.ap-accordion-summary::before {
  content: "\25B6";
  font-size: 9px;
  color: var(--muted);
  transition: transform 0.18s ease;
  flex-shrink: 0;
}
.ap-accordion[open] > .ap-accordion-summary::before { transform: rotate(90deg); }
.ap-accordion-summary:hover { background: rgba(255,255,255,0.05); }
.ap-accordion-hint {
  font-size: 11px;
  font-weight: 400;
  color: var(--muted);
  margin-left: 4px;
}
.ap-accordion > *:not(summary) {
  padding: 12px 14px;
}

/* Two-column layout — kept for any legacy references */
.ap-two-col {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
  margin-top: 12px;
}
.ap-col {
  min-width: 0;
}

.ap-decision-list {
  list-style: none;
  padding: 0;
  margin: 0;
  max-height: 360px;
  overflow-y: auto;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--bg-soft);
}
.ap-decision {
  display: grid;
  grid-template-columns: 64px 60px 1fr;
  gap: 8px;
  align-items: baseline;
  font-size: 11px;
  padding: 6px 10px;
  border-bottom: 1px solid var(--line);
}
.ap-decision:last-child { border-bottom: 0; }
.ap-dec-time { color: var(--muted); font-variant-numeric: tabular-nums; }
.ap-dec-action {
  font-weight: 600;
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 1px 5px;
  border-radius: 3px;
  text-align: center;
}
.ap-action-open    { background: rgba(34, 197, 94, 0.18); color: #15803d; }
.ap-action-add     { background: rgba(34, 197, 94, 0.10); color: #15803d; }
.ap-action-exit    { background: rgba(239, 68, 68, 0.18); color: #dc2626; }
.ap-action-settle  { background: rgba(125, 211, 252, 0.22); color: #0284c7; }
.ap-action-skiphalted, .ap-action-skipnocash, .ap-action-skipcapped {
  background: rgba(160, 160, 160, 0.20); color: var(--muted);
}
.ap-dec-detail { color: var(--text); }
.ap-dec-detail .pos { color: #15803d; font-weight: 600; }
.ap-dec-detail .neg { color: #dc2626; font-weight: 600; }

/* Phone breakpoint — single-column the two-col block */
@media (max-width: 720px) {
  .auto-paper-card .ap-portfolio-strip { grid-template-columns: repeat(2, 1fr); }
  .ap-two-col { grid-template-columns: 1fr; }
}

/* ============================================================
 * Auto Paper Trader — Phase 3 rule-status badges
 * ============================================================ */
.ap-status-chip {
  display: inline-block;
  padding: 1px 6px;
  border-radius: 3px;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}
.ap-status-active {
  background: rgba(34, 197, 94, 0.16);
  color: #15803d;
  border: 1px solid rgba(34, 197, 94, 0.30);
}
.ap-status-probing {
  background: rgba(160, 160, 160, 0.18);
  color: var(--muted);
  border: 1px solid rgba(160, 160, 160, 0.30);
}
.ap-status-suspended {
  background: rgba(220, 38, 38, 0.20);
  color: #dc2626;
  border: 1px solid rgba(220, 38, 38, 0.45);
}
.ap-rules-table tr.ap-row-suspended {
  opacity: 0.7;
}
.ap-rules-table tr.ap-row-suspended td:first-child {
  text-decoration: line-through;
  text-decoration-color: rgba(220, 38, 38, 0.5);
}

/* Skip-suspended decision action chip */
.ap-action-skipsuspended {
  background: rgba(220, 38, 38, 0.18);
  color: #dc2626;
}

/* CHANGELOG_SERIAL.md #052 — Recent lessons panel */
#ap-lessons-body {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 4px;
}
.ap-lesson {
  padding: 8px 12px;
  border-radius: 0 6px 6px 0;
  background: var(--bg-card2, rgba(255,255,255,0.03));
  cursor: default;
}
.ap-lesson-row1 {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 3px;
}
.ap-lesson-ts {
  font-size: 11px;
  color: var(--muted);
  flex: 1;
}
.ap-lesson-badge {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  padding: 1px 5px;
  border-radius: 3px;
}
.ap-lesson-badge-win  { background: rgba(34, 197, 94, 0.16);  color: #15803d; border: 1px solid rgba(34, 197, 94, 0.30); }
.ap-lesson-badge-loss { background: rgba(239, 68, 68, 0.16);  color: #dc2626; border: 1px solid rgba(239, 68, 68, 0.30); }
.ap-lesson-badge-flat { background: rgba(140, 140, 140, 0.16); color: var(--muted); border: 1px solid rgba(140, 140, 140, 0.30); }
.ap-lesson-pnl {
  font-size: 12px;
  font-weight: 600;
  min-width: 60px;
  text-align: right;
}
.ap-lesson-headline {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 2px;
}
.ap-lesson-detail {
  font-size: 11px;
  color: var(--muted);
}

/* ============================================================
 * CHANGELOG_SERIAL.md #071 — Unified X-share modal
 * ============================================================ */

/* Nav bar "𝕏 Share" button (desktop sticky header) */
.aq-share-nav-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  appearance: none;
  border: 1px solid rgba(140, 150, 170, 0.30);
  background: transparent;
  color: var(--text-muted, #5a6478);
  cursor: pointer;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 5px 10px;
  border-radius: 7px;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.aq-share-nav-btn:hover {
  color: var(--text, #1a1f2e);
  border-color: rgba(59, 130, 246, 0.5);
  background: rgba(59, 130, 246, 0.07);
}
.aq-share-nav-label { line-height: 1; }

/* Mobile FAB — fixed bottom-right, hidden on desktop */
.aq-share-fab {
  display: none;
  position: fixed;
  bottom: 16px;
  right: 16px;
  z-index: 900;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: rgb(59, 130, 246);
  color: #fff;
  border: none;
  cursor: pointer;
  box-shadow: 0 4px 16px rgba(0,0,0,0.30);
  align-items: center;
  justify-content: center;
  transition: background 0.15s, transform 0.15s;
}
.aq-share-fab:hover { background: rgb(37, 99, 235); transform: scale(1.07); }

/* Modal backdrop */
.aq-share-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.65);
  backdrop-filter: blur(4px);
  z-index: 9800;
  display: flex;
  align-items: center;
  justify-content: center;
}
/* Modal card */
.aq-share-modal {
  background: var(--bg-card, #ffffff);
  border: 1px solid var(--line, #e3e6ec);
  border-radius: 16px;
  padding: 24px;
  max-width: 560px;
  width: 92%;
  max-height: 92vh;
  overflow-y: auto;
  color: var(--text, #1a1f2e);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.22);
  outline: none;
}
.aq-share-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 18px;
}
.aq-share-modal-title {
  font-size: 17px;
  font-weight: 700;
  display: flex;
  align-items: center;
  gap: 7px;
}
.aq-share-close {
  appearance: none;
  background: transparent;
  border: none;
  color: var(--text-muted, #5a6478);
  cursor: pointer;
  font-size: 22px;
  line-height: 1;
  padding: 2px 6px;
  border-radius: 4px;
  transition: color 0.12s, background 0.12s;
}
.aq-share-close:hover { color: var(--text); background: rgba(0,0,0,0.06); }

/* Section label */
.aq-share-section-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted, #5a6478);
  margin-bottom: 8px;
}

/* Category pills */
.aq-share-cat-pills {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.aq-share-cat-pill {
  appearance: none;
  border: 1px solid var(--line, #e3e6ec);
  background: transparent;
  color: var(--text-muted, #5a6478);
  cursor: pointer;
  font-size: 12px;
  font-weight: 600;
  padding: 5px 12px;
  border-radius: 20px;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.aq-share-cat-pill:hover {
  border-color: rgba(59, 130, 246, 0.5);
  color: var(--text);
}
.aq-share-cat-pill.is-active {
  background: rgba(59, 130, 246, 0.12);
  border-color: rgb(59, 130, 246);
  color: rgb(59, 130, 246);
}

/* Template radio list */
.aq-share-tpl-list {
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.aq-share-tpl-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--line, #e3e6ec);
  border-radius: 8px;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
}
.aq-share-tpl-row:hover { background: rgba(59, 130, 246, 0.06); border-color: rgba(59, 130, 246, 0.35); }
.aq-share-tpl-row.is-active { background: rgba(59, 130, 246, 0.09); border-color: rgb(59, 130, 246); }
.aq-share-tpl-radio { margin-top: 2px; flex-shrink: 0; accent-color: rgb(59, 130, 246); }
.aq-share-tpl-text { flex: 1; min-width: 0; }
.aq-share-tpl-label { font-size: 13px; font-weight: 600; color: var(--text); margin-bottom: 2px; }
.aq-share-tpl-desc  { font-size: 11px; color: var(--text-muted, #5a6478); line-height: 1.4; }

/* Preview area */
.aq-share-preview-wrap {
  position: relative;
}
.aq-share-preview {
  width: 100%;
  box-sizing: border-box;
  font-family: "JetBrains Mono", "Courier New", monospace;
  font-size: 12px;
  line-height: 1.55;
  background: var(--bg-table-alt, #fafbfc);
  border: 1px solid var(--line, #e3e6ec);
  border-radius: 8px;
  padding: 10px 12px;
  color: var(--text);
  resize: none;
  outline: none;
}
.aq-share-charcount {
  position: absolute;
  bottom: 8px;
  right: 10px;
  font-size: 10px;
  color: var(--text-dim, #8a93a3);
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}
.aq-share-charcount.warn { color: rgb(234, 179, 8); }
.aq-share-charcount.over { color: rgb(239, 68, 68); font-weight: 700; }

/* Footer buttons */
.aq-share-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 18px;
}
.aq-share-btn-cancel {
  appearance: none;
  background: transparent;
  border: 1px solid var(--line, #e3e6ec);
  color: var(--text-muted, #5a6478);
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  padding: 8px 16px;
  border-radius: 8px;
  transition: color 0.12s, border-color 0.12s;
}
.aq-share-btn-cancel:hover { color: var(--text); border-color: var(--text-muted); }
.aq-share-btn-post {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  appearance: none;
  background: rgb(59, 130, 246);
  border: none;
  color: #fff;
  cursor: pointer;
  font-size: 13px;
  font-weight: 700;
  padding: 8px 18px;
  border-radius: 8px;
  transition: background 0.15s;
}
.aq-share-btn-post:hover { background: rgb(37, 99, 235); }
/* CHANGELOG_SERIAL.md #161 — "Email a friend" button. Mirrors the cancel
   button's outline style with a teal accent so it reads as a secondary action
   next to the primary Post-to-X button. */
.aq-share-btn-email {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  appearance: none;
  background: transparent;
  border: 1px solid rgba(45, 212, 191, 0.55);
  color: var(--text, #cfd6e3);
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  padding: 8px 16px;
  border-radius: 8px;
  transition: background 0.12s, border-color 0.12s;
}
.aq-share-btn-email:hover { background: rgba(45, 212, 191, 0.12); border-color: rgba(45, 212, 191, 0.9); }
.aq-share-btn-email:disabled { opacity: 0.6; cursor: progress; }

@media (max-width: 480px) {
  /* CHANGELOG_SERIAL.md #071 — hide nav Share button, show FAB on mobile */
  .aq-share-nav-btn { display: none; }
  .aq-share-fab { display: flex; }
  /* Modal goes full-screen on phone */
  .aq-share-modal {
    max-width: 100%;
    width: 100%;
    max-height: 100dvh;
    border-radius: 0;
    padding: 16px;
  }
  .aq-share-backdrop {
    align-items: flex-end;
  }
  .aq-share-cat-pills { gap: 6px; }
  .aq-share-cat-pill  { font-size: 11px; padding: 4px 10px; }
}

/* ============================================================
   CHANGELOG_SERIAL.md #100 — Touch target minimum 44×44px (Apple HIG).
   Scoped to ≤767px only — desktop stays compact (no row-height bloat
   on the paper ladder, no oversized header buttons on desktop).

   Strategy per element:
     .hdr-icon-btn   — fixed box: bump width+height to 44px (was 34px)
     .filter-pill    — pill row: add min-height 44px + flex centering
     .oi-zoom-pill   — pill row: add min-height 44px + flex centering;
                       overrides the existing ≤480px padding reduction
                       (min-height still applies after padding changes)
     .ladder-buy     — table cell button: min-height 44px, pad 10px 9px
                       .ladder-close inherits from .ladder-buy base so
                       is also covered without a separate rule
     .ap-page-btn    — pagination: min-height 44px, pad 10px 12px

   Visual impact: header icons grow 34→44px (10px wider — slight but
   necessary); pill rows gain internal whitespace but don't grow
   wider; ladder rows in the paper tab gain ~20px height on mobile
   (~8 rows visible instead of ~15 — acceptable per brief).
   ============================================================ */
@media (max-width: 767px) {

  /* Header icon buttons: X follow, email, refresh, theme-toggle */
  .hdr-icon-btn {
    width: 44px;
    height: 44px;
    border-radius: 10px; /* scale radius with larger box */
  }
  /* theme-toggle shares .hdr-icon-btn — override its own fixed sizing too */
  .theme-toggle {
    width: 44px;
    height: 44px;
    min-width: 44px;
  }

  /* Filter pills in the alerts feed header */
  .filter-pill {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0 11px; /* collapse vertical pad — min-height owns the height */
  }

  /* Zoom pills (Y-axis, X-axis) and Layer pills above the OI chart */
  .oi-zoom-pill {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    padding: 0 10px; /* min-height owns the height; horizontal pad unchanged */
  }

  /* Paper ladder BUY YES / BUY NO / Close buttons */
  .ladder-buy,
  .ladder-close {
    min-height: 44px;
    padding: 10px 9px; /* 10px top/bottom vs original 4px — reaches 44px */
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

  /* Pagination Prev / Next buttons (auto-trader + paper journal) */
  .ap-page-btn {
    min-height: 44px;
    padding: 10px 12px; /* 10px top/bottom vs original 4px */
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

}

/* ============================================================
   CHANGELOG_SERIAL.md #101 — Mid-range collapse block (≤767px).
   No JS changes. No palette changes.

   Components addressed:
     .adi-hero           — 2-col grid → single column, barometer below score
     .capit-live-row     — 3-col grid → single column; live-value 48px→32px
     .capit-secondary-row — 3-col grid → single column; sec-value 32px→24px
     .paper-portfolio-strip — auto-fit minmax(110px) → 2-col fixed grid
     .hdr-status-strip   — hide Session + Next Settle, keep freshness only
                           (mirrors existing ≤480px rule, now fires at ≤767px)
   ============================================================ */
@media (max-width: 767px) {

  /* ── ADI hero: stack score above barometer ────────────────── */
  .adi-hero {
    grid-template-columns: 1fr;  /* single column */
    gap: 18px;
  }
  /* Score wrap stays first in DOM so it leads; barometer follows naturally */
  .adi-barometer-wrap {
    min-width: 0;
    width: 100%;
  }

  /* ── Capitulation live row: collapse to single column ─────── */
  .capit-live-row {
    grid-template-columns: 1fr;
    gap: 12px;
  }
  .capit-live-value {
    font-size: 32px;  /* was 48px — fits single-col on 360px phone */
  }

  /* ── Capitulation secondary row: collapse to single column ── */
  .capit-secondary-row {
    grid-template-columns: 1fr;
    gap: 10px;
  }
  .capit-sec-value {
    font-size: 24px;  /* was 32px */
  }

  /* ── Paper portfolio stat strip: 2-col grid ──────────────── */
  .paper-portfolio-strip {
    grid-template-columns: repeat(2, 1fr);
  }

  /* ── Status strip: show freshness only (same as ≤480px rule) */
  .hdr-strip-item:not(.hdr-strip-freshness),
  .hdr-strip-sep { display: none; }
  .hdr-strip-freshness { display: inline-flex; }

}

/* ============================================================
   CHANGELOG_SERIAL.md #102 — Table column hiding at ≤767px.
   Pure CSS display:none on specific nth-child positions.
   No JS, no HTML changes, no palette changes.

   Column maps (1-indexed per visible cell in each row):

   .underwater-table (dual-header):
     Row 1 (group labels): Strike(1, rowspan=2) · YES-side(2, colspan=4) · NO-side(3, colspan=4)
       → hide entire row 1 on mobile to avoid colspan/data misalignment
     Row 2 (col names, nth-child within that tr): Bought(1)·VWAP(2)·Mid(3)·Δ(4)·Bought(5)·VWAP(6)·Mid(7)·Δ(8)
       → hide col 2,3,6,7 (VWAP YES, Mid YES, VWAP NO, Mid NO)
     tbody rows: Strike(1)·Bought(2)·VWAP(3)·Mid(4)·Δ(5)·Bought(6)·VWAP(7)·Mid(8)·Δ(9)
       → hide col 3,4,7,8

   .edge-radar-table (single header, 8 cols):
     Play(1)·Action(2)·Cost(3)·Mkt%(4)·Our%(5)·Edge(6)·EV/$(7)·Conviction(8)
       → hide col 5 (Our%), col 7 (EV/$)

   .paper-positions-table (10 cols incl sim-only cols):
     Contract(1)·Strike(2)·Side(3)·Qty(4)·Entry(5)·Mid(6)·Unrealized P&L(7)·Sim mid(8)·Sim P&L(9)·Action(10)
       → hide col 6 (Mid), col 7 (Unrealized P&L)
       → sim-only cols 8+9 already gated by body.aq-sim-on — not touched here

   .paper-journal-table (9 cols):
     Date(1)·Contract(2)·Strike(3)·Side(4)·Qty(5)·Entry(6)·Exit(7)·P&L(8)·Reason(9)
       → hide col 9 (Reason — free-text strategy string, noise on mobile)

   .ap-trades-table (8 cols):
     Time(1)·Action(2)·Kind(3)·Strike(4)·Side(5)·Mid(6)·P&L(7)·Reason(8)
       → hide col 6 (Mid — not actionable on closed trades), col 8 (Reason)

   .ap-positions-table (9 cols, not in brief but same judgment):
     Kind(1)·Strike(2)·Side(3)·Qty(4)·Entry(5)·Current(6)·Unreal P&L(7)·Reason(8)·Age(9)
       → hide col 8 (Reason only — all other cols actionable for open positions)
   ============================================================ */
@media (max-width: 767px) {

  /* ── Underwater map ─────────────────────────────────────────
     Hide the dual-header group row (colspan mismatch) and
     hide VWAP + Mid columns in the data header + body rows.   */
  .underwater-table thead tr:nth-child(1) { display: none; }

  /* Second header row: nth-child within that <tr> */
  .underwater-table thead tr:nth-child(2) th:nth-child(2),
  .underwater-table thead tr:nth-child(2) th:nth-child(3),
  .underwater-table thead tr:nth-child(2) th:nth-child(6),
  .underwater-table thead tr:nth-child(2) th:nth-child(7) { display: none; }

  /* Body rows: Strike is col 1; VWAP YES=3, Mid YES=4, VWAP NO=7, Mid NO=8 */
  .underwater-table tbody td:nth-child(3),
  .underwater-table tbody td:nth-child(4),
  .underwater-table tbody td:nth-child(7),
  .underwater-table tbody td:nth-child(8) { display: none; }

  /* ── Edge Radar ─────────────────────────────────────────────
     Hide Our% (col 5) and EV/$ (col 7).                       */
  .edge-radar-table th:nth-child(5),
  .edge-radar-table td:nth-child(5),
  .edge-radar-table th:nth-child(7),
  .edge-radar-table td:nth-child(7) { display: none; }

  /* ── Paper open positions ───────────────────────────────────
     Hide Mid (col 6) and Unrealized P&L (col 7).
     Sim cols 8+9 remain gated by body.aq-sim-on as-is.        */
  .paper-positions-table th:nth-child(6),
  .paper-positions-table td:nth-child(6),
  .paper-positions-table th:nth-child(7),
  .paper-positions-table td:nth-child(7) { display: none; }

  /* ── Paper trade journal ────────────────────────────────────
     Hide Reason (col 9).                                       */
  .paper-journal-table th:nth-child(9),
  .paper-journal-table td:nth-child(9) { display: none; }

  /* ── Auto-trader completed trades ──────────────────────────
     Hide Mid (col 6, not useful post-close) and Reason (col 8). */
  .ap-trades-table th:nth-child(6),
  .ap-trades-table td:nth-child(6),
  .ap-trades-table th:nth-child(8),
  .ap-trades-table td:nth-child(8) { display: none; }

  /* ── Auto-trader open positions ─────────────────────────────
     Hide Reason (col 8) only — all other cols actionable.      */
  .ap-positions-table th:nth-child(8),
  .ap-positions-table td:nth-child(8) { display: none; }

}

/* ============================================================
   CHANGELOG_SERIAL.md #103 — Mobile polish: tab scroll fade,
   flowhist chart height reduction, palette kbd hints hidden.
   No JS, no HTML changes, no palette changes.

   1. Tab nav right-edge scroll fade (≤767px):
      .tab-nav already has overflow-x: auto so a position:absolute
      ::after would be clipped. Instead, mask-image is applied to
      the element itself — the gradient mask is viewport-fixed (moves
      with the sticky element, not with scroll position), giving a
      static right-edge fade that signals more tabs exist off-screen.
      padding-right bumped to 30px so the last visible tab's text
      doesn't disappear under the fade zone.

   2. Flow history chart height (≤767px):
      Four stacked .flowhist-chart-area divs at 260px each = ~1040px
      of chart-only scroll on the Flow tab. Reduced to 180px each.
      Chart.js respects container height via responsive:true — no JS
      change needed.

   3. Palette keyboard hints (touch devices):
      @media (hover: none) and (pointer: coarse) targets touch screens
      without over-scoping to any arbitrary px width. Hides only the
      <kbd> elements inside .aq-palette-footer (the hint text spans
      remain — e.g. "navigate", "jump", "new tab" — just without the
      key-cap badges). The footer itself stays visible.
   ============================================================ */

/* ── 1. Tab nav right-edge scroll fade (≤767px) ──────────────── */
@media (max-width: 767px) {
  .tab-nav {
    padding-right: 30px;
    -webkit-mask-image: linear-gradient(
      to right,
      black calc(100% - 40px),
      transparent 100%
    );
    mask-image: linear-gradient(
      to right,
      black calc(100% - 40px),
      transparent 100%
    );
  }
}

/* ── 2. Flow history chart height reduction (≤767px) ─────────── */
@media (max-width: 767px) {
  .flowhist-chart-area {
    height: 180px; /* was 260px — saves ~320px of scroll across 4 charts */
  }
}

/* ── 3. Palette kbd hints hidden on touch devices ────────────── */
@media (hover: none) and (pointer: coarse) {
  .aq-palette-footer kbd { display: none; }
}

/* ============================================================
   CHANGELOG_SERIAL.md #178 -- Phase 4 frontend: Ralph widget
   Floating "Ask Ralph" button + slide-up chat panel +
   waitlist modal + hero preview card.
   Palette: uses existing --accent (#0052cc on light) and brand
   teal/green. Dark-theme overrides inside [data-theme="dark"].
   Mobile block at EOF per FRONTEND_CONVENTIONS.md.
   ============================================================ */

/* ---- Floating pill button ---------------------------------- */
.aq-ralph-btn {
  position: fixed;
  bottom: 24px;
  right: 24px;
  z-index: 9800;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 0 20px;
  height: 64px;
  min-width: 160px;
  border-radius: 999px;
  border: none;
  cursor: pointer;
  background: #0f6e3c;  /* brand teal-green, close to green-700 */
  color: #fff;
  font-family: var(--sans);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.01em;
  box-shadow: 0 4px 12px rgba(0,0,0,0.18);
  transition: background 0.15s, box-shadow 0.15s;
  animation: ralph-pulse 8s ease-in-out infinite;
  -webkit-animation: ralph-pulse 8s ease-in-out infinite;
}
.aq-ralph-btn:hover {
  background: #137a45;
  box-shadow: 0 6px 18px rgba(0,0,0,0.22);
  animation-play-state: paused;
}
.aq-ralph-btn:focus-visible {
  outline: 2px solid #22c55e;
  outline-offset: 3px;
}
.aq-ralph-btn-icon {
  flex: 0 0 16px;
}
.aq-ralph-btn-label {
  white-space: nowrap;
}
@keyframes ralph-pulse {
  0%, 85%, 100% { transform: scale(1.0); }
  90% { transform: scale(1.04); }
  95% { transform: scale(1.0); }
}

/* ---- Chat panel -------------------------------------------- */
.aq-ralph-panel {
  position: fixed;
  bottom: 104px;
  right: 24px;
  z-index: 9850;
  width: 380px;
  height: 560px;
  display: flex;
  flex-direction: column;
  background: var(--bg-card, #ffffff);
  border: 1px solid var(--line, #d6dae2);
  border-radius: 16px;
  box-shadow: 0 8px 32px rgba(0,0,0,0.14);
  overflow: hidden;
  transform: translateY(20px);
  opacity: 0;
  pointer-events: none;
  transition: transform 0.22s cubic-bezier(0.34,1.56,0.64,1), opacity 0.18s ease;
}
.aq-ralph-panel.aq-ralph-panel-open {
  transform: translateY(0);
  opacity: 1;
  pointer-events: auto;
}
[data-theme="dark"] .aq-ralph-panel {
  background: #13171f;
  border-color: #262d3b;
}

/* Panel header */
.aq-ralph-panel-header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--line, #d6dae2);
  flex-shrink: 0;
}
[data-theme="dark"] .aq-ralph-panel-header {
  border-bottom-color: #262d3b;
}
.aq-ralph-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: #0f6e3c;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 800;
  font-size: 14px;
  flex-shrink: 0;
}
.aq-ralph-title-wrap {
  display: flex;
  flex-direction: column;
  line-height: 1.2;
}
.aq-ralph-title {
  font-weight: 700;
  font-size: 14px;
  color: var(--text, #1a1f2e);
}
.aq-ralph-subtitle {
  font-size: 11px;
  color: var(--text-muted, #4a5468);
}
.aq-ralph-quota {
  margin-left: auto;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-muted, #4a5468);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.aq-ralph-quota.aq-ralph-quota-amber { color: #b45309; }
.aq-ralph-quota.aq-ralph-quota-red   { color: #b91c1c; }
.aq-ralph-close {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: none;
  background: transparent;
  cursor: pointer;
  color: var(--text-muted, #4a5468);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  flex-shrink: 0;
  transition: background 0.12s;
}
.aq-ralph-close:hover { background: rgba(0,0,0,0.06); }

/* Message list */
.aq-ralph-msgs {
  flex: 1;
  overflow-y: auto;
  padding: 14px 14px 8px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  scroll-behavior: smooth;
}
.aq-ralph-msgs::-webkit-scrollbar { width: 6px; }
.aq-ralph-msgs::-webkit-scrollbar-thumb { background: var(--line, #d6dae2); border-radius: 3px; }
.aq-ralph-empty {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 12px;
  color: var(--text-muted, #4a5468);
  font-size: 13.5px;
  line-height: 1.55;
}
.aq-ralph-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.aq-ralph-chip {
  background: rgba(0,82,204,0.07);
  border: 1px solid rgba(0,82,204,0.22);
  border-radius: 999px;
  padding: 5px 12px;
  cursor: pointer;
  font-size: 12px;
  color: var(--accent, #0052cc);
  font-family: var(--sans);
  transition: background 0.12s;
}
.aq-ralph-chip:hover { background: rgba(0,82,204,0.14); }
.aq-ralph-msg {
  padding: 9px 12px;
  border-radius: 10px;
  max-width: 88%;
  font-size: 14px;
  line-height: 1.5;
  word-break: break-word;
}
.aq-ralph-msg-user {
  background: rgba(0,82,204,0.10);
  border: 1px solid rgba(0,82,204,0.20);
  color: var(--text, #1a1f2e);
  align-self: flex-end;
}
.aq-ralph-msg-ralph {
  background: rgba(0,0,0,0.04);
  border: 1px solid var(--line, #d6dae2);
  color: var(--text, #1a1f2e);
  align-self: flex-start;
}
[data-theme="dark"] .aq-ralph-msg-user {
  background: rgba(88,166,255,0.12);
  border-color: rgba(88,166,255,0.25);
  color: #e8eef5;
}
[data-theme="dark"] .aq-ralph-msg-ralph {
  background: rgba(125,133,144,0.10);
  border-color: #262d3b;
  color: #e8eef5;
}
.aq-ralph-msg-thinking {
  color: var(--text-muted, #4a5468);
  font-style: italic;
  background: transparent !important;
  border-style: dashed !important;
}

/* Footer input area */
.aq-ralph-footer {
  border-top: 1px solid var(--line, #d6dae2);
  padding: 10px 12px;
  display: flex;
  gap: 8px;
  align-items: flex-end;
  flex-shrink: 0;
  background: var(--bg-card, #ffffff);
}
[data-theme="dark"] .aq-ralph-footer {
  background: #13171f;
  border-top-color: #262d3b;
}
.aq-ralph-input {
  flex: 1;
  background: var(--bg, #f7f8fa);
  border: 1px solid var(--line, #d6dae2);
  border-radius: 8px;
  padding: 8px 11px;
  color: var(--text, #1a1f2e);
  font-size: 13.5px;
  font-family: var(--sans);
  resize: none;
  outline: none;
  line-height: 1.45;
  min-height: 38px;
  max-height: 96px;
  overflow-y: auto;
  transition: border-color 0.12s;
}
.aq-ralph-input:focus { border-color: var(--accent, #0052cc); }
.aq-ralph-input:disabled { opacity: 0.5; cursor: not-allowed; }
[data-theme="dark"] .aq-ralph-input {
  background: #0a0c10;
  border-color: #262d3b;
  color: #e8eef5;
}
.aq-ralph-send {
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  border-radius: 8px;
  border: none;
  background: #0f6e3c;
  color: #fff;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.12s;
}
.aq-ralph-send:hover { background: #137a45; }
.aq-ralph-send:disabled { background: var(--text-dim, #6a7488); cursor: wait; }
.aq-ralph-limit-msg {
  font-size: 13px;
  color: var(--text-muted, #4a5468);
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  padding: 4px 0;
}
.aq-ralph-link-btn {
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  color: var(--accent, #0052cc);
  font-size: 13px;
  font-family: var(--sans);
  text-decoration: underline;
}

/* ---- Waitlist modal ---------------------------------------- */
.aq-ralph-modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 10000;
  background: rgba(0,0,0,0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
/* CHANGELOG_SERIAL.md #268 — the display:flex above overrides the [hidden]
   attribute (author rule beats the UA [hidden]{display:none}), so the waitlist
   X couldn't close it. Make hidden actually hide. */
.aq-ralph-modal-overlay[hidden] { display: none !important; }
.aq-ralph-modal {
  background: var(--bg-card, #ffffff);
  border: 1px solid var(--line, #d6dae2);
  border-radius: 16px;
  padding: 28px 28px 24px;
  max-width: 400px;
  width: 100%;
  position: relative;
  box-shadow: 0 12px 40px rgba(0,0,0,0.18);
}
[data-theme="dark"] .aq-ralph-modal {
  background: #13171f;
  border-color: #262d3b;
}
.aq-ralph-modal-close {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: none;
  background: transparent;
  cursor: pointer;
  color: var(--text-muted, #4a5468);
  font-size: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.12s;
}
.aq-ralph-modal-close:hover { background: rgba(0,0,0,0.07); }
.aq-ralph-modal-title {
  font-size: 20px;
  font-weight: 800;
  color: var(--text, #1a1f2e);
  margin: 0 0 10px;
}
.aq-ralph-modal-body {
  font-size: 14px;
  color: var(--text-muted, #4a5468);
  line-height: 1.6;
  margin: 0 0 18px;
}
.aq-ralph-wl-email {
  width: 100%;
  box-sizing: border-box;
  padding: 10px 13px;
  font-size: 14px;
  background: var(--bg, #f7f8fa);
  border: 1px solid var(--line, #d6dae2);
  border-radius: 8px;
  color: var(--text, #1a1f2e);
  font-family: var(--sans);
  outline: none;
  margin-bottom: 12px;
  transition: border-color 0.12s;
}
.aq-ralph-wl-email:focus { border-color: var(--accent, #0052cc); }
[data-theme="dark"] .aq-ralph-wl-email {
  background: #0a0c10;
  border-color: #262d3b;
  color: #e8eef5;
}
.aq-ralph-wl-submit {
  width: 100%;
  padding: 11px;
  font-size: 15px;
  font-weight: 700;
  background: #0f6e3c;
  color: #fff;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  font-family: var(--sans);
  transition: background 0.12s;
}
.aq-ralph-wl-submit:hover { background: #137a45; }
.aq-ralph-wl-submit:disabled { background: var(--text-dim, #6a7488); cursor: wait; }
.aq-ralph-wl-msg {
  margin-top: 14px;
  font-size: 13px;
  color: #137333;
  font-weight: 600;
}

/* ---- Hero preview card (signed-out) ------------------------ */
.aq-ralph-preview {
  max-width: 600px;
  margin: 24px auto;
  background: var(--bg-card, #ffffff);
  border: 1px solid var(--line, #d6dae2);
  border-radius: 14px;
  padding: 20px 22px 16px;
  box-shadow: 0 2px 10px rgba(0,0,0,0.06);
}
[data-theme="dark"] .aq-ralph-preview {
  background: #13171f;
  border-color: #262d3b;
}
.aq-ralph-preview-header {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-muted, #4a5468);
  margin-bottom: 14px;
}
.aq-ralph-preview-qa {
  transition: opacity 0.3s ease;
  min-height: 80px;
}
.aq-ralph-preview-fade { opacity: 0; }
.aq-ralph-preview-q {
  font-size: 15px;
  font-weight: 600;
  color: var(--text, #1a1f2e);
  margin-bottom: 8px;
  font-style: italic;
}
.aq-ralph-preview-a {
  font-size: 14px;
  color: var(--text-muted, #4a5468);
  line-height: 1.6;
}
.aq-ralph-preview-cta {
  margin-top: 16px;
  text-align: center;
}
.aq-ralph-preview-btn {
  background: #0f6e3c;
  color: #fff;
  border: none;
  border-radius: 8px;
  padding: 10px 20px;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  font-family: var(--sans);
  transition: background 0.12s;
}
.aq-ralph-preview-btn:hover { background: #137a45; }

/* ============================================================
   CHANGELOG_SERIAL.md #180 — Help tab page styles.
   Reuses .card, .card-title, .card-sub from the existing system.
   Palette: green-500 accents, no new colors outside the locked
   palette (FRONTEND_CONVENTIONS.md).
   ============================================================ */

/* Jump-nav table of contents */
.help-toc {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 10px;
  padding: 12px 18px 16px;
  border-bottom: 1px solid var(--line, rgba(255,255,255,0.08));
}
.help-toc-link {
  font-size: 12px;
  font-weight: 600;
  color: rgb(34, 197, 94); /* green-500 — locked palette accent */
  text-decoration: none;
  padding: 3px 8px;
  border: 1px solid rgba(34, 197, 94, 0.3);
  border-radius: 4px;
  transition: background 0.12s, color 0.12s;
  white-space: nowrap;
}
.help-toc-link:hover {
  background: rgba(34, 197, 94, 0.12);
  color: rgb(74, 222, 128); /* green-400 */
  text-decoration: none;
}

/* Help body container */
.help-body {
  padding: 0 18px 24px;
}

/* Individual feature sections */
.help-section {
  padding: 22px 0 20px;
  border-bottom: 1px solid var(--line, rgba(255,255,255,0.06));
}
.help-section:last-child {
  border-bottom: none;
}
.help-section-title {
  font-size: 16px;
  font-weight: 700;
  color: var(--text, #e6e6e6);
  margin: 0 0 10px;
  line-height: 1.35;
}

/* Body paragraphs */
.help-p {
  font-size: 14px;
  line-height: 1.7;
  color: var(--text, #e6e6e6);
  margin: 0 0 10px;
}

/* Bulleted lists */
.help-list {
  margin: 0 0 10px 0;
  padding-left: 20px;
  font-size: 14px;
  line-height: 1.7;
  color: var(--text, #e6e6e6);
}
.help-list li {
  margin-bottom: 6px;
}
.help-list li strong {
  color: var(--text, #e6e6e6);
}

/* Definition list for layer-by-layer / row-by-row breakdowns */
.help-dl {
  margin: 0 0 10px;
  display: grid;
  grid-template-columns: minmax(110px, max-content) 1fr;
  gap: 0;
  font-size: 14px;
  line-height: 1.65;
}
.help-dl dt {
  font-weight: 700;
  color: rgb(34, 197, 94); /* green-500 — locked accent */
  padding: 5px 14px 5px 0;
  vertical-align: top;
}
.help-dl dd {
  margin: 0;
  padding: 5px 0;
  color: var(--text, #e6e6e6);
  border-bottom: 1px solid var(--line, rgba(255,255,255,0.04));
}
.help-dl dt:last-of-type,
.help-dl dd:last-of-type {
  border-bottom: none;
}

/* "What to look for" tip callout */
.help-tip {
  font-size: 13px;
  line-height: 1.6;
  color: var(--text-muted, rgba(230,230,230,0.65));
  background: rgba(34, 197, 94, 0.05);
  border-left: 3px solid rgb(34, 197, 94); /* green-500 accent */
  padding: 8px 12px;
  border-radius: 0 4px 4px 0;
  margin: 10px 0 0;
}
.help-tip strong {
  color: rgb(74, 222, 128); /* green-400 */
}

/* Light theme overrides */
[data-theme="light"] .help-toc-link {
  color: rgb(21, 128, 61); /* green-700 — better contrast on light bg */
  border-color: rgba(21, 128, 61, 0.35);
}
[data-theme="light"] .help-toc-link:hover {
  background: rgba(21, 128, 61, 0.09);
  color: rgb(21, 128, 61);
}
[data-theme="light"] .help-dl dt {
  color: rgb(21, 128, 61);
}
[data-theme="light"] .help-tip {
  border-left-color: rgb(21, 128, 61);
  background: rgba(21, 128, 61, 0.05);
}
[data-theme="light"] .help-tip strong {
  color: rgb(21, 128, 61);
}

/* ============================================================
   CHANGELOG_SERIAL.md #314 — Help tab: per-entry location labels
   + "Show me" jump buttons. Theme-aware, mobile-friendly.
   .help-location = the "Found in: Tab → Card" line.
   .help-jump-btn = the keyboard-accessible "Show me →" button.
   .aq-jump-highlight = 1.5s sky-blue ring pulse on the target card.
   Palette: amber-500 for the location badge, sky-400 for the ring.
   Both are locked Tailwind values already used elsewhere on the dash.
   ============================================================ */
.help-location {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 6px 0 10px;
  font-size: 12px;
  line-height: 1.4;
  flex-wrap: wrap;
}
.help-location-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: rgb(245, 158, 11); /* amber-500 — locked Tailwind value */
  font-weight: 600;
  letter-spacing: 0.01em;
  white-space: nowrap;
}
.help-location-badge svg {
  flex-shrink: 0;
}
.help-jump-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 9px;
  font-size: 11px;
  font-weight: 600;
  font-family: var(--sans);
  color: rgb(56, 189, 248); /* sky-400 — locked Tailwind value */
  background: rgba(56, 189, 248, 0.09);
  border: 1px solid rgba(56, 189, 248, 0.35);
  border-radius: 4px;
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
  text-decoration: none;
  white-space: nowrap;
  /* Keyboard-accessible */
  outline-offset: 2px;
}
.help-jump-btn:hover,
.help-jump-btn:focus-visible {
  background: rgba(56, 189, 248, 0.18);
  color: rgb(125, 211, 252); /* sky-300 */
  text-decoration: none;
}
/* Light-theme overrides for amber / sky on light backgrounds */
[data-theme="light"] .help-location-badge {
  color: rgb(180, 83, 9); /* amber-700 — better contrast on light bg */
}
[data-theme="light"] .help-jump-btn {
  color: rgb(2, 132, 199);  /* sky-700 */
  background: rgba(2, 132, 199, 0.07);
  border-color: rgba(2, 132, 199, 0.30);
}
[data-theme="light"] .help-jump-btn:hover,
[data-theme="light"] .help-jump-btn:focus-visible {
  background: rgba(2, 132, 199, 0.14);
  color: rgb(7, 89, 133);   /* sky-800 */
}
/* 1.5 s ring-pulse highlight on jump target */
@keyframes aq-jump-pulse {
  0%   { box-shadow: 0 0 0 0   rgba(56,189,248,0.80); outline: 2px solid rgba(56,189,248,0.80); }
  55%  { box-shadow: 0 0 0 6px rgba(56,189,248,0.25); outline: 2px solid rgba(56,189,248,0.40); }
  100% { box-shadow: 0 0 0 0   rgba(56,189,248,0.00); outline: 2px solid rgba(56,189,248,0.00); }
}
.aq-jump-highlight {
  animation: aq-jump-pulse 1.5s ease-out forwards;
  border-radius: 6px;
  position: relative;
  z-index: 1;
}

/* ============================================================
   CHANGELOG_SERIAL.md #178 -- Ralph widget mobile (<=480px).
   Per FRONTEND_CONVENTIONS.md all mobile rules are inside a
   single @media block at EOF.
   ============================================================ */
@media (max-width: 480px) {
  .aq-ralph-btn {
    bottom: 18px;
    right: 18px;
    height: 56px;
    min-width: 140px;
    font-size: 14px;
    padding: 0 16px;
  }
  .aq-ralph-panel {
    bottom: 0;
    right: 0;
    left: 0;
    width: 100%;
    height: 100%;
    border-radius: 0;
    border: none;
    max-height: 100dvh;
  }
  .aq-ralph-modal-overlay {
    align-items: flex-end;
    padding: 0;
  }
  .aq-ralph-modal {
    border-radius: 16px 16px 0 0;
    max-width: 100%;
    width: 100%;
  }
  /* CHANGELOG_SERIAL.md #180 — Help tab mobile rules (<=480px) */
  .help-toc { padding: 10px 12px 12px; gap: 5px 8px; }
  .help-toc-link { font-size: 11px; padding: 3px 7px; }
  .help-body { padding: 0 12px 18px; }
  .help-section { padding: 16px 0 14px; }
  .help-section-title { font-size: 14px; }
  .help-p, .help-list, .help-dl { font-size: 13px; }
  .help-dl { grid-template-columns: 1fr; }
  .help-dl dt { padding: 5px 0 2px; border-bottom: none; }
  .help-dl dd { padding: 0 0 6px; }
  /* CHANGELOG_SERIAL.md #192 — SIM Back-to-live button: smaller on mobile */
  .aq-sim-back-btn { font-size: 12px; padding: 5px 10px; }
  /* CHANGELOG_SERIAL.md #200 — sidebar sim box: tighter padding on mobile;
     inherits the sidebar's single-column collapse so no extra width rules needed. */
  .aq-sim-sidebar-box { padding: 8px 10px 10px; }

  /* #201 — SIM mobile bottom bar.
     When body.aq-sim-on is active on <=480px, promote .aq-sim-sidebar-box
     to a fixed bottom bar so the Forward slider is always reachable while
     the heatmap fills the screen above it. CSS-only repositioning — no IDs
     are duplicated; sim.js continues to wire the same elements by id.

     Glass treatment: translucent dark bg + backdrop-blur + violet top border
     matching the existing SIM accent color rgba(167,139,250).

     When SIM is OFF the box renders normally in the stacked sidebar.
     Desktop (>480px) is UNTOUCHED — all rules below are scoped to this
     single <=480px block AND to the body.aq-sim-on gate.               */

  /* --- Fixed bottom bar when SIM is active ----------------------------- */
  body.aq-sim-on .aq-sim-sidebar-box {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 200;
    /* Glass: dark translucent so the chart shows through the seam */
    background: rgba(15, 20, 35, 0.88);
    -webkit-backdrop-filter: blur(12px) saturate(1.2);
    backdrop-filter: blur(12px) saturate(1.2);
    /* Violet top border — unmistakably SIM */
    border: none;
    border-top: 2px solid rgba(167, 139, 250, 0.70);
    border-radius: 0;
    /* Layout: row of controls, wrapping for narrow screens */
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 12px;
    padding: 10px 14px;
    padding-bottom: max(10px, env(safe-area-inset-bottom));
    margin: 0;
    /* Prevent the long banner from stretching the bar */
    box-sizing: border-box;
  }

  /* Hide the "Simulator" h3 title — redundant in the fixed bar */
  body.aq-sim-on .aq-sim-sidebar-box .aq-sim-sidebar-title {
    display: none;
  }

  /* Hide the verbose banner text in the fixed bar on mobile — it's multi-line
     and not thumb-operable; the readout below the slider carries the key info */
  body.aq-sim-on #aq-sim-banner {
    display: none !important;
  }

  /* LIVE/SIM toggle pills: keep compact, sit in the left of the bar */
  body.aq-sim-on .aq-sim-sidebar-box .aq-sim-toggle {
    flex: 0 0 auto;
    align-self: center;
  }

  /* Back-to-live button: full tap target */
  body.aq-sim-on .aq-sim-sidebar-box .aq-sim-back-btn {
    flex: 0 0 auto;
    min-height: 40px;
    font-size: 13px;
    padding: 8px 14px;
    /* Invert from the normal small-font override above */
  }

  /* Forward-in-time slider block: expand to fill remaining width */
  body.aq-sim-on .aq-sim-sidebar-box .aq-sim-tte {
    flex: 1 1 180px;
    min-width: 0;
    gap: 4px;
  }

  /* Full-width slider — fills the available bar width */
  body.aq-sim-on .aq-sim-sidebar-box .aq-sim-tte input[type="range"] {
    width: 100%;
  }

  /* Larger thumb — touch-friendly (~28px) */
  body.aq-sim-on .aq-sim-sidebar-box .aq-sim-tte input[type="range"]::-webkit-slider-thumb {
    width: 28px;
    height: 28px;
  }
  body.aq-sim-on .aq-sim-sidebar-box .aq-sim-tte input[type="range"]::-moz-range-thumb {
    width: 28px;
    height: 28px;
  }

  /* Readout: slightly larger so it's legible at arm's length */
  body.aq-sim-on .aq-sim-sidebar-box .aq-sim-tte-readout {
    font-size: 13px;
  }

  /* Label: uppercase micro-label style */
  body.aq-sim-on .aq-sim-sidebar-box .aq-sim-tte-label {
    font-size: 10px;
    letter-spacing: 0.5px;
    text-transform: uppercase;
    color: rgba(167, 139, 250, 0.85);
  }

  /* Push the bottom of the live-oi-card down so the fixed bar
     does not permanently obscure the chart bottom edge.
     ~80px covers the bar height plus safe-area headroom. */
  body.aq-sim-on .live-oi-card {
    padding-bottom: 80px;
  }

  /* CHANGELOG_SERIAL.md #220 — close-flow tooltip: tap-to-open on mobile,
     slightly narrower so it fits the portrait viewport. Marker shrink (8->6px)
     and history-sparkline hide are handled in close_flow.js via matchMedia. */
  .aq-cf-tooltip {
    max-width: 220px;
    font-size: 11px;
  }

  /* CHANGELOG_SERIAL.md #316 — #spot-freeze-bar removed; its mobile rules removed here too. */
  /* CHANGELOG_SERIAL.md #235 — 1.8 mobile: section chips bar hidden on mobile
     (too many chips for narrow viewport; Cmd+K palette still accessible) */
  .section-chips-bar { display: none !important; }
  /* CHANGELOG_SERIAL.md #235 — 1.1 mobile: slim ticker still shows at <=480px */
  .top-grid-slim { font-size: 12px; height: 32px; padding: 0 10px; }
  /* CHANGELOG_SERIAL.md #235 — 1.2 EMA collapsed strip wraps on mobile */
  .ema-collapsed-strip { flex-wrap: wrap; }
  /* CHANGELOG_SERIAL.md #281 — Edge Map: tighter table on mobile */
  .edge-map-table { font-size: 11px; }
  .edge-map-table th, .edge-map-table td { padding: 5px 6px; }
  .em-badge { font-size: 9px; padding: 2px 5px; }
  /* CHANGELOG_SERIAL.md #314 — Help location lines: slightly more compact on mobile */
  .help-location { gap: 6px; margin: 4px 0 8px; }
  .help-jump-btn { font-size: 10px; padding: 2px 7px; }
}

/* ============================================================
   CHANGELOG_SERIAL.md #235 — 1.5: Flow tab — remove duplicate
   bottom axis labels from the 3 non-bottom charts in the flowhist
   stack. The bottom chart (flowhist-delta-chart) keeps its axis.
   Implemented via .flowhist-suppress-x-axis on the chart-wrap
   divs that should lose their bottom axis label row. Since Chart.js
   renders axes onto the canvas we cannot CSS-hide them without
   hiding canvas content — FLAG: full axis sharing (single Chart.js
   x-axis at the bottom) requires chart config changes that risk
   breaking the charts. Safe part done: document the intent here.
   The chart wrappers already have equal widths and the canvases
   align naturally. A follow-on serial should set display: false
   on the x-axis of the top 3 charts in renderFlowHistory() to
   remove the redundant axis label rows.
   ============================================================ */
/* CHANGELOG_SERIAL.md #235 — 1.5 PARTIAL: flag for follow-on */
/* flowhist charts share x-axis visually via equal widths (already true).
   Full axis suppression is FLAGGED — safe to do in JS in a follow-on serial. */

/* ============================================================
   CHANGELOG_SERIAL.md #249 — OI Lab (interactive positioning sandbox).
   ============================================================ */
.card-sub-inline { font-weight: 400; color: #8a93a3; font-size: 14px; }
.oilab-ctrls { display: flex; gap: 8px; flex-wrap: wrap; }
.oilab-btn {
  background: rgba(255,255,255,0.06); color: #c6cfdb; border: 1px solid var(--line);
  border-radius: 6px; padding: 5px 11px; font-size: 12px; font-weight: 600;
  cursor: pointer; font-family: var(--sans); transition: background .12s, color .12s;
}
.oilab-btn:hover { background: rgba(255,255,255,0.13); color: #fff; }
.oi-lab-body { display: grid; grid-template-columns: 1fr 280px; gap: 16px; padding-top: 10px; }
.oi-lab-canvas-wrap { min-width: 0; }
#oilab-canvas { width: 100%; height: 520px; display: block; border: 1px solid var(--line); border-radius: 8px; }
.oi-lab-side { display: flex; flex-direction: column; gap: 12px; }
.oi-lab-readout { display: flex; flex-direction: column; gap: 6px; }
.oilab-stat { display: flex; justify-content: space-between; align-items: baseline; font-size: 13px; color: #9aa4b2; border-bottom: 1px solid rgba(255,255,255,0.05); padding-bottom: 5px; }
.oilab-stat b { color: #e6edf5; font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 13px; }
.oilab-stat b.g { color: #22c55e; } .oilab-stat b.r { color: #ef4444; }
.oilab-stat b em { color: #8a93a3; font-style: normal; font-size: 11px; margin-left: 4px; }
.oilab-warn { color: #f59e0b; font-size: 12.5px; padding: 4px 0; }
.oi-lab-form { display: flex; flex-direction: column; gap: 8px; border-top: 1px solid var(--line); padding-top: 10px; }
.oilab-row { display: flex; gap: 8px; }
.oilab-input {
  color-scheme: dark; background: #161b22; color: #e6edf5; border: 1px solid var(--line);
  border-radius: 6px; padding: 6px 8px; font-size: 13px; font-family: var(--sans); width: 100%; min-width: 0;
}
.oilab-input:focus { outline: none; border-color: #22c55e; box-shadow: 0 0 0 2px rgba(34,197,94,0.18); }
.oilab-add { background: #22c55e; color: #06210f; border: none; border-radius: 6px; padding: 8px; font-size: 13px; font-weight: 800; cursor: pointer; }
.oilab-add:hover { filter: brightness(1.1); }
.oilab-spot-field { display: flex; align-items: center; gap: 8px; font-size: 11px; color: #8a93a3; text-transform: uppercase; letter-spacing: 0.04em; font-weight: 700; }
.oilab-spot-field .oilab-input { width: auto; flex: 1; }
.oi-lab-trades { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; max-height: 170px; overflow-y: auto; }
.oilab-trade { display: flex; align-items: center; gap: 6px; font-size: 12.5px; color: #d7deea; background: rgba(255,255,255,0.03); border-radius: 5px; padding: 4px 8px; font-family: var(--mono); }
.oilab-trade .g { color: #22c55e; font-weight: 700; } .oilab-trade .r { color: #ef4444; font-weight: 700; }
.oilab-trade button { margin-left: auto; background: none; border: none; color: #8a93a3; cursor: pointer; font-size: 16px; line-height: 1; padding: 0 2px; }
.oilab-trade button:hover { color: #fff; }
.oilab-empty { font-size: 12px; color: #5a6478; padding: 6px; }
@media (max-width: 900px) {
  .oi-lab-body { grid-template-columns: 1fr; }
  #oilab-canvas { height: 420px; }
}

/* ============================================================
   CHANGELOG_SERIAL.md #294 — Universal color-convention pill strip.
   Placed in OI Timeline sidebar above the customer-prints legend.
   GREEN = YES / RED = NO across every surface.
   ============================================================ */
.oi-color-convention {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 14px;
  padding: 6px 10px;
  margin-bottom: 10px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 6px;
  font-size: 12px;
  color: #9aa4b2;
}
.oicc-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-weight: 600;
  color: #c6cfdb;
}
.oicc-swatch {
  display: inline-block;
  width: 28px;
  height: 10px;
  border-radius: 3px;
  flex-shrink: 0;
}
/* Tailwind green-500 / red-500 — matches all chart constants */
.oicc-yes { background: rgba(34, 197, 94, 0.85); border: 1.5px solid rgb(21, 128, 61); }
.oicc-no  { background: rgba(239, 68, 68, 0.85);  border: 1.5px solid rgb(185, 28, 28); }
.oicc-note {
  width: 100%;
  font-size: 10.5px;
  color: #5a6478;
  font-style: italic;
}

/* ============================================================
   CHANGELOG_SERIAL.md #292 — Order-Flow Ladder card.
   Diverging horizontal bar chart: green right = yes_taker_cum,
   red left = no_taker_cum. Center axis at 50% width.
   Tailwind green-500 (34,197,94) / red-500 (239,68,68).
   ============================================================ */
.flow-ladder-card {
  /* Full-width below OI timeline, above Pulse 15M */
}
.flow-ladder-card .card-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
  margin-bottom: 8px;
}
.flow-ladder-legend {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 5px 0 10px;
  font-size: 12px;
  color: #9aa4b2;
  border-bottom: 1px solid var(--line);
  margin-bottom: 10px;
}
.fll-item {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-weight: 600;
  color: #c6cfdb;
}
.fll-swatch {
  display: inline-block;
  width: 20px;
  height: 8px;
  border-radius: 2px;
}
.fll-yes { background: rgb(34, 197, 94); }
.fll-no  { background: rgb(239, 68, 68); }
.fll-atm {
  margin-left: auto;
  font-size: 11px;
  color: #5a6478;
}
.flow-ladder-body {
  position: relative;
  min-height: 60px;
}
.flow-ladder-empty {
  color: #5a6478;
  font-size: 13px;
  padding: 12px 0;
  text-align: center;
}
.flow-ladder-chart {
  display: flex;
  flex-direction: column;
  gap: 3px;
}
/* One row per strike */
.fl-row {
  display: grid;
  /* label(left) | NO bar(expands left) | center mark | YES bar(expands right) | label(right) */
  grid-template-columns: 70px 1fr 2px 1fr 56px;
  align-items: center;
  gap: 0 4px;
  min-height: 22px;
  padding: 0 4px;
  border-radius: 3px;
}
.fl-row.fl-atm {
  background: rgba(34, 197, 94, 0.07);
  border: 1px solid rgba(34, 197, 94, 0.25);
}
.fl-strike-label {
  font-size: 11.5px;
  font-family: var(--mono);
  color: #9aa4b2;
  text-align: right;
  padding-right: 6px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.fl-row.fl-atm .fl-strike-label {
  color: rgb(74, 222, 128);  /* green-400 — ATM highlight */
  font-weight: 700;
}
.fl-atm-marker {
  display: inline;
  font-size: 9px;
  margin-left: 2px;
}
/* NO bar cell — bar grows from RIGHT edge toward center */
.fl-no-cell {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  overflow: hidden;
  min-width: 0;
  position: relative;
  height: 16px;
}
.fl-no-bar {
  height: 16px;
  background: rgb(239, 68, 68);   /* red-500 */
  border-radius: 2px 0 0 2px;
  min-width: 0;
  transition: width 0.25s ease;
  position: relative;
}
/* YES bar cell — bar grows from LEFT edge away from center */
.fl-yes-cell {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  overflow: hidden;
  min-width: 0;
  position: relative;
  height: 16px;
}
.fl-yes-bar {
  height: 16px;
  background: rgb(34, 197, 94);   /* green-500 */
  border-radius: 0 2px 2px 0;
  min-width: 0;
  transition: width 0.25s ease;
}
/* Center divider line */
.fl-center {
  width: 2px;
  background: rgba(255, 255, 255, 0.18);
  align-self: stretch;
  border-radius: 1px;
}
/* Dollar label on the right of the YES bar */
.fl-label {
  font-size: 10.5px;
  font-family: var(--mono);
  color: #9aa4b2;
  white-space: nowrap;
  padding-left: 4px;
  text-align: left;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Dominant side label highlight */
.fl-label.fl-label-yes { color: rgb(74, 222, 128); font-weight: 700; }
.fl-label.fl-label-no  { color: rgb(248, 113, 113); font-weight: 700; }

/* Light theme overrides */
[data-theme="light"] .fl-strike-label { color: #4b5563; }
[data-theme="light"] .fl-row.fl-atm .fl-strike-label { color: rgb(21, 128, 61); }
[data-theme="light"] .fl-center { background: rgba(0,0,0,0.18); }
[data-theme="light"] .fl-label { color: #6b7280; }
[data-theme="light"] .fl-label.fl-label-yes { color: rgb(21, 128, 61); }
[data-theme="light"] .fl-label.fl-label-no  { color: rgb(185, 28, 28); }

/* Mobile — collapse the NO side label column, keep YES-side only */
@media (max-width: 480px) {
  .fl-row { grid-template-columns: 62px 1fr 2px 1fr 48px; }
  .fl-strike-label { font-size: 10.5px; }
  .fl-label { font-size: 9.5px; }
  /* CHANGELOG_SERIAL.md #300 — filter bar mobile: tighter segment buttons,
     summary bar wraps naturally, chips stay readable. */
  .ps-seg-btn { padding: 4px 9px; font-size: 11.5px; }
  .ps-fb-summary { font-size: 11px; padding: 5px 2px 7px; }
  .ps-fb-chip { font-size: 11px; padding: 2px 7px 2px 9px; }
  .ps-fb-reset { padding: 4px 8px; font-size: 11.5px; }
  /* CHANGELOG_SERIAL.md #305 — copy button: slightly larger tap target on phone */
  .aq-copy-btn { width: 30px; height: 30px; }
  /* CHANGELOG_SERIAL.md #311 — zone panel: tighter on mobile */
  .aq-zone-panel { padding: 12px 14px 14px; font-size: 12.5px; }
  .aqzp-block { flex-direction: column; gap: 3px; }
  .aqzp-block-label { flex-basis: auto; }
  .aqzp-sub { white-space: normal; }
  .aqzp-ralph-btn { width: 100%; text-align: center; }
  .aqzp-footer { justify-content: stretch; }
  /* CHANGELOG_SERIAL.md #319 — track record: slightly tighter on mobile */
  .aqzp-trackrecord { padding: 7px 10px 8px; font-size: 12px; }

  /* ===========================================================================
     CHANGELOG_SERIAL.md #315 — mobile-usability-p1
     7-fix measured overflow + touch audit pass at 390px.
     ALL rules below are scoped to this <=480px block — desktop untouched.
     =========================================================================== */

  /* ----- Fix #1: .hdr-actions collapse ----------------------------------------
     Hide clock, X follow link, and email link at <=480px.
     Keep: brand, LIVE dot (.hdr-live-pill), search trigger, refresh,
     theme toggle, and sign-in/sign-out controls.
     Fixes the 754px baseline scrollWidth on 5 of 7 tabs. */
  .hdr-clock { display: none; }
  /* X follow link and email link are .hdr-icon-btn <a> elements in .hdr-actions.
     Target by their aria-label to avoid hiding the refresh button or theme toggle. */
  .hdr-actions a.hdr-icon-btn[aria-label*="Follow"],
  .hdr-actions a.hdr-icon-btn[aria-label*="Email"] {
    display: none;
  }

  /* ----- Fix #2: Terrain hero + chart container constraints -------------------
     Force .chart-wrap and its canvas to stay within the viewport.
     The terrain canvas can render at desktop-computed width without these.
     Also add overflow guard on hero-pin-card itself. */
  .chart-wrap {
    max-width: 100%;
    min-width: 0;
    box-sizing: border-box;
    overflow: hidden;
  }
  .chart-wrap canvas {
    max-width: 100%;
    min-width: 0;
  }
  .hero-pin-card.hero-pin-slim {
    max-width: 100%;
    min-width: 0;
    box-sizing: border-box;
  }

  /* CHANGELOG_SERIAL.md #316 — spotbar-above-tabs mobile: un-stick #hero-pin at
     <=480px so it is in-flow (scrolls away). Keeps total sticky budget = 64px
     header + 50px tab-nav = 114px, under the 120px cap. --aq-pin-h=0px in :root
     for this breakpoint means --aq-tab-top auto-resolves to var(--aq-hdr-h)=64px. */
  #hero-pin { position: static !important; width: 100% !important; }

  /* ----- Fix #3: Live tab structural collapse ---------------------------------
     .main-grid is already 1-column at <=960px via the desktop rule above.
     Target the remaining overflow sources: ema-top-cols, replay-bar,
     hero-pin-card, and the 6-column OI flow rows.
     (#spot-freeze-bar removed in #316 — was the old thin BTC/EOH/TTE strip.) */

  /* EMA stack columns: force single column instead of 2-column grid */
  .ema-top-cols {
    grid-template-columns: 1fr !important;
  }

  /* Replay bar: ensure it doesn't push out of bounds */
  .replay-bar,
  .hero-pin-card {
    max-width: 100%;
    min-width: 0;
    box-sizing: border-box;
  }

  /* Replay controls: allow wrapping */
  .replay-controls,
  .replay-toggle-row,
  .replay-row {
    flex-wrap: wrap;
  }

  /* OI FLOW rows: reflow 6-col grid to two visual lines.
     Line 1 (auto): time | action label | strike | size (the "trade" facts).
     Line 2 (muted): OI total | @spot.
     Implementation: collapse to flex-wrap with the OI and spot cells
     going to a second line via their own 100%-width sub-row. */
  .oiflow-row {
    display: flex;
    flex-wrap: wrap;
    gap: 2px 6px;
    align-items: baseline;
    padding: 6px 10px;
    font-size: 13px;
  }
  /* Primary line: time, strike, label, size — flex-shrink 0, natural wrap order */
  .oiflow-time   { order: 1; font-size: 12px; flex-shrink: 0; }
  .oiflow-strike { order: 2; font-size: 13px; flex-shrink: 0; }
  .oiflow-label  { order: 3; font-size: 11px; flex: 1 1 auto; min-width: 0; }
  .oiflow-size   { order: 4; font-size: 13px; flex-shrink: 0; }
  /* Secondary line: OI and spot — pushed to new line by full-width gap */
  .oiflow-oi,
  .oiflow-spot {
    order: 5;
    font-size: 11px;
    opacity: 0.60;
    flex-shrink: 0;
  }
  /* Force a line break between size (order 4) and OI/spot (order 5)
     by inserting an invisible 100%-width element via ::after */
  .oiflow-size::after {
    content: "";
    display: block;
    width: 100vw;
    height: 0;
  }

  /* ----- Fix #4: Single Ralph launcher ----------------------------------------
     On mobile, when ralph_widget.js has mounted the public button
     (body.aq-ralph-public-active), hide the private #ralph-root toggle
     so only one launcher is visible. The open panel (#ralph-root.ralph-open)
     is still usable if opened programmatically.
     When the public button is NOT mounted (body without .aq-ralph-public-active),
     both buttons could show; we also reset #ralph-root width so it docks
     cleanly bottom-right (not full-spanning). */
  body.aq-ralph-public-active #ralph-root .ralph-toggle { display: none; }
  /* Also prevent #ralph-root from spanning the full width when toggle is hidden */
  body.aq-ralph-public-active #ralph-root {
    left: auto;
    right: 16px;
    bottom: 16px;
    width: auto;
  }

  /* ----- Fix #5: Tap targets ≥44px -------------------------------------------
     Bump AGE checkbox labels and filter chips via padding (not font-size).
     Tab buttons and theme toggle are already handled above (line 8244+). */

  /* AGE band checkboxes: taller hit area */
  .oiflow-band-label {
    min-height: 44px;
    padding: 6px 8px;
  }
  .oiflow-band-check {
    width: 18px;
    height: 18px;
  }

  /* help-toc-link chips: taller hit area */
  .help-toc-link {
    min-height: 36px;
    padding: 8px 10px;
    display: inline-flex;
    align-items: center;
  }

  /* Tab buttons: ensure ≥44px height */
  .tab-btn {
    padding-top: 15px;
    padding-bottom: 15px;
  }

  /* ----- Fix #6: Help tab accordion sections (closed by default at <=480px) ---
     The <details class="help-accordion"> wrappers around each .help-section
     are added in index.html. On mobile (<=480px) they use native <details>
     toggle behavior (closed by default since no [open] attribute).
     Extra tightening for the summary row. */
  .help-accordion {
    border-top: 1px solid var(--line);
    border-bottom: none;
    border-left: none;
    border-right: none;
    border-radius: 0;
    margin-top: 0;
    overflow: visible;
  }
  .help-accordion:first-of-type { border-top: none; }
  .help-accordion > .ap-accordion-summary {
    padding: 12px 2px;
    font-size: 13.5px;
    font-weight: 700;
  }
  /* When closed on mobile, keep the help-section hidden (native <details> behavior
     already handles this — no extra CSS needed). */
  /* When open, give the section its normal padding */
  .help-accordion[open] > .help-section {
    padding-bottom: 12px;
  }

  /* ----- Fix #7: Search palette polish ----------------------------------------
     .hdr-search-kbd is already hidden by the existing rule at line ~8232.
     Hide the Esc hint inside the palette input row, and the full hint footer. */
  .aq-palette-esc-hint { display: none; }
  .aq-palette-footer { display: none; }

  /* ===========================================================================
     CHANGELOG_SERIAL.md #317 — mobile-usability-p2
     Bottom tab bar, summary-row accordions, legend bottom-sheets.
     ALL rules below are scoped to this <=480px block.
     Desktop (>=481px) stays pixel-identical — see the companion min-width:481px
     block below this media query.
     =========================================================================== */

  /* ----- #317 Piece 1: Hide top tab-nav, show bottom bar ----------------------
     The .tab-nav-shell (top nav) is hidden on mobile — its tab-switching
     function is replaced by #mob-bottom-bar injected by mobile_nav.js.
     Free ~50px of top sticky budget. */
  .tab-nav-shell { display: none; }

  /* Body padding so content never hides behind the fixed bottom bar.
     56px bar + safe-area-inset-bottom (iPhone home bar gesture zone). */
  body {
    padding-bottom: calc(56px + env(safe-area-inset-bottom, 0px));
  }

  /* Bottom tab bar shell */
  .mob-bottom-bar {
    display: flex;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 200;
    background: var(--bg-card);
    border-top: 1px solid var(--line);
    height: calc(56px + env(safe-area-inset-bottom, 0px));
    padding-bottom: env(safe-area-inset-bottom, 0px);
    align-items: stretch;
    box-shadow: 0 -2px 12px rgba(0,0,0,0.18);
  }

  /* Individual tab buttons */
  .mob-tab-btn {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    border: none;
    background: transparent;
    color: var(--text-muted);
    font-size: 10px;
    font-weight: 500;
    font-family: var(--sans);
    padding: 6px 2px;
    min-height: 44px;
    cursor: pointer;
    transition: color 0.15s;
    -webkit-tap-highlight-color: transparent;
  }
  .mob-tab-btn:active { opacity: 0.7; }
  /* Active state: sky-300 per spec */
  .mob-tab-btn.mob-tab-active {
    color: rgb(125, 211, 252); /* sky-300 */
  }
  .mob-tab-icon { flex-shrink: 0; }
  .mob-tab-label { line-height: 1; }

  /* Ralph launcher docks ABOVE the bottom bar, bottom-right.
     Offset by bar height so it sits flush above it.
     Applies to both the public .aq-ralph-btn and the private #ralph-root. */
  .aq-ralph-btn,
  #ralph-root {
    bottom: calc(60px + env(safe-area-inset-bottom, 0px)) !important;
  }

  /* ----- #317 Piece 1b: "More" sheet -----------------------------------------
     A small fixed panel that slides up from the bottom bar. */
  .mob-more-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 190;
    background: rgba(0,0,0,0.45);
  }
  .mob-more-backdrop.mob-backdrop-open { display: block; }

  .mob-more-sheet {
    position: fixed;
    bottom: calc(56px + env(safe-area-inset-bottom, 0px));
    left: 0;
    right: 0;
    z-index: 195;
    background: var(--bg-card);
    border: 1px solid var(--line);
    border-radius: 12px 12px 0 0;
    padding: 12px 16px calc(8px + env(safe-area-inset-bottom, 0px));
    display: flex;
    flex-direction: column;
    gap: 6px;
    transform: translateY(110%);
    transition: transform 0.22s ease;
    box-shadow: 0 -4px 20px rgba(0,0,0,0.25);
  }
  .mob-more-sheet.mob-sheet-open { transform: translateY(0); }

  .mob-more-btn {
    display: flex;
    align-items: center;
    gap: 12px;
    background: transparent;
    border: none;
    color: var(--text);
    font-size: 15px;
    font-weight: 500;
    font-family: var(--sans);
    padding: 12px 8px;
    min-height: 44px;
    cursor: pointer;
    border-radius: 8px;
    -webkit-tap-highlight-color: transparent;
  }
  .mob-more-btn:active { background: rgba(255,255,255,0.06); }

  .mob-more-close {
    margin-top: 4px;
    background: rgba(255,255,255,0.06);
    border: 1px solid var(--line);
    border-radius: 8px;
    color: var(--text-muted);
    font-size: 14px;
    padding: 10px;
    min-height: 44px;
    cursor: pointer;
    font-family: var(--sans);
  }

  /* ----- #317 Piece 2: Summary-row accordions on Live -------------------------
     .mob-section-details wraps body content; summary is the toggle.
     At <=480px these are styled like ap-accordion but slimmer. */
  .mob-section-details {
    margin: 0;
    padding: 0;
    border: none;
  }

  .mob-section-summary {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 14px;
    font-size: 12px;
    font-weight: 600;
    color: var(--text-muted);
    cursor: pointer;
    list-style: none;
    border-top: 1px solid var(--line);
    background: var(--bg-card);
    position: relative;
    -webkit-tap-highlight-color: transparent;
  }
  .mob-section-summary::-webkit-details-marker { display: none; }
  .mob-section-title {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--text-dim);
    white-space: nowrap;
  }
  .mob-acc-hint {
    flex: 1;
    font-size: 12px;
    font-weight: 500;
    color: var(--text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  /* Palette-locked greens/reds for collapsed-header numbers */
  .mob-hint-pos     { color: rgb(34, 197, 94); }  /* green-500 */
  .mob-hint-neg     { color: rgb(239, 68, 68);  }  /* red-500 */
  .mob-hint-neutral { color: var(--text-muted); }
  .mob-hint-muted   { color: var(--text-dim);   }

  /* Caret indicator */
  .mob-section-caret {
    margin-left: auto;
    width: 0;
    height: 0;
    border-left: 4px solid transparent;
    border-right: 4px solid transparent;
    border-top: 5px solid var(--text-dim);
    flex-shrink: 0;
    transition: transform 0.15s;
  }
  .mob-section-details[open] > .mob-section-summary .mob-section-caret {
    transform: rotate(180deg);
  }
  /* When closed: hide the section body content */
  .mob-section-details:not([open]) > :not(summary) {
    display: none !important;
  }
  /* When open: restore normal display */
  .mob-section-details[open] > :not(summary) {
    display: block;
  }

  /* ----- #317 Piece 3: Legend / help bottom sheets ----------------------------
     Fixed bottom panel, max-height 70vh, scrollable. Dismiss on backdrop tap. */
  .mob-sheet-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 210;
    background: rgba(0,0,0,0.50);
  }
  .mob-sheet-backdrop.mob-backdrop-open { display: block; }

  .mob-legend-sheet {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 215;
    background: var(--bg-card);
    border: 1px solid var(--line);
    border-radius: 16px 16px 0 0;
    max-height: 70vh;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding: 0 0 calc(16px + env(safe-area-inset-bottom, 0px));
    transform: translateY(110%);
    transition: transform 0.25s ease;
    box-shadow: 0 -6px 24px rgba(0,0,0,0.30);
  }
  .mob-legend-sheet.mob-sheet-visible { transform: translateY(0); }

  .mob-sheet-close-row {
    display: flex;
    justify-content: flex-end;
    padding: 10px 14px 4px;
    position: sticky;
    top: 0;
    background: var(--bg-card);
    z-index: 1;
  }
  .mob-sheet-close-btn {
    background: rgba(255,255,255,0.07);
    border: 1px solid var(--line);
    border-radius: 8px;
    color: var(--text-muted);
    font-size: 13px;
    padding: 6px 14px;
    min-height: 36px;
    cursor: pointer;
    font-family: var(--sans);
  }
  .mob-sheet-title {
    font-size: 14px;
    font-weight: 700;
    color: var(--text);
    padding: 4px 16px 8px;
    border-bottom: 1px solid var(--line);
    margin-bottom: 8px;
  }
  .mob-sheet-content {
    padding: 0 16px;
  }
  .mob-sheet-p {
    font-size: 13px;
    line-height: 1.55;
    color: var(--text-muted);
    margin: 0 0 10px;
  }

  /* ⓘ info button added to card headers on mobile */
  .mob-info-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: none;
    color: var(--text-dim);
    width: 36px;
    height: 36px;
    border-radius: 50%;
    cursor: pointer;
    flex-shrink: 0;
    -webkit-tap-highlight-color: transparent;
  }
  .mob-info-btn:active { background: rgba(255,255,255,0.08); }

  /* When the OI legend sidebar is inside a sheet, reset its positioning */
  .live-oi-sidebar.mob-in-sheet {
    position: static !important;
    width: 100% !important;
    max-width: 100% !important;
    border-right: none !important;
    border-bottom: none !important;
    height: auto !important;
    max-height: none !important;
    overflow: visible !important;
    padding: 8px 0 0 !important;
  }

  /* On mobile: hide the desktop legend sidebar toggle button and sidebar
     (it's now accessible via the ⓘ button → sheet). */
  #live-oi-sidebar-toggle { display: none; }
  /* The sidebar itself is also hidden in the normal card layout on mobile
     — it's only visible inside the sheet. */
  .live-oi-sidebar:not(.mob-in-sheet) { display: none; }

  /* CHANGELOG_SERIAL.md #340 — OI flow filter tabs: wrap on mobile,
     ensure >=40px tap targets via min-height. .oi-zoom-pill covers both old pills
     and new .oi-flow-filter-tab buttons (which carry the same base class). */
  .oi-flow-filter-bar { gap: 4px; }
  .oi-flow-filter-bar .oi-zoom-pill { min-height: 40px; padding: 6px 10px; font-size: 11.5px; }

  /* CHANGELOG_SERIAL.md #339 — Exact OI grid: full-width on mobile,
     label on its own line above value for narrow screens. */
  .aqzp-exact-row { flex-direction: column; gap: 0; }
  .aqzp-exact-label { min-width: auto; }
  .aqzp-exact-val { font-size: 11.5px; word-break: break-all; }
}

/* ===========================================================================
   CHANGELOG_SERIAL.md #315 — Help tab: desktop-open override.
   The <details class="help-accordion"> elements default to closed (no [open]).
   On desktop (≥481px) force all content visible and neutralize the accordion
   chrome so the Help tab looks identical to before on wide screens.
   This is a DESKTOP rule — not mobile — intentionally outside the EOF 480px block.
   =========================================================================== */

/* ===========================================================================
   CHANGELOG_SERIAL.md #340 — OI timeline flow-category filter: 4 independent
   multi-select tabs. Replaces #338 single-select pills.
   Each tab has a category-specific active colour matching its bubble colour:
     Buy YES to Open  — green-500 (#22c55e) filled bubble
     Buy NO to Open   — red-500  (#ef4444) filled bubble
     Sell YES to Close — green-500 hollow outline
     Sell NO to Close  — red-500  hollow outline
   When OFF: muted (inherits base .oi-zoom-pill inactive style).
   When ON (.is-active): border tinted to category colour.
   =========================================================================== */
.oi-flow-filter-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 6px;
  padding: 4px 0 4px 2px;
  margin-bottom: 2px;
}
/* Buy YES to Open — green-500 tint when active */
.oi-flow-tab--yes-open.is-active  {
  border-color: rgba(34, 197, 94, 0.80);
  color: rgba(34, 197, 94, 1);
  background: rgba(34, 197, 94, 0.12);
}
/* Buy NO to Open — red-500 tint when active */
.oi-flow-tab--no-open.is-active   {
  border-color: rgba(239, 68, 68, 0.80);
  color: rgba(239, 68, 68, 1);
  background: rgba(239, 68, 68, 0.12);
}
/* Sell YES to Close — green-500 hollow tint when active */
.oi-flow-tab--yes-close.is-active {
  border-color: rgba(34, 197, 94, 0.60);
  color: rgba(34, 197, 94, 0.85);
  background: rgba(34, 197, 94, 0.07);
}
/* Sell NO to Close — red-500 hollow tint when active */
.oi-flow-tab--no-close.is-active  {
  border-color: rgba(239, 68, 68, 0.60);
  color: rgba(239, 68, 68, 0.85);
  background: rgba(239, 68, 68, 0.07);
}

/* ===========================================================================
   CHANGELOG_SERIAL.md #339 — Zone panel exact OI data grid.
   Sits inside .aqzp-block above the narrative mechLine text.
   Compact two-column (label : value) rows; monospace values for alignment.
   Palette: label = var(--text-dim), value = var(--text). No neon.
   =========================================================================== */
.aqzp-exact-grid {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 4px 0 8px;
  padding: 7px 10px;
  background: rgba(15, 23, 42, 0.30);
  border-left: 2px solid rgba(125, 211, 252, 0.45); /* sky-300, matches squeeze accent */
  border-radius: 0 4px 4px 0;
  font-size: 12.5px;
  line-height: 1.45;
}
[data-theme="light"] .aqzp-exact-grid {
  background: rgba(241, 245, 249, 0.60);
  border-left-color: rgba(14, 165, 233, 0.50);
}
.aqzp-exact-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0 6px;
  align-items: baseline;
}
.aqzp-exact-label {
  color: var(--text-dim);
  font-size: 11.5px;
  font-weight: 600;
  white-space: nowrap;
  flex-shrink: 0;
  min-width: 78px;
}
.aqzp-exact-val {
  color: var(--text);
  font-family: var(--mono);
  font-size: 12px;
  word-break: break-all;
}

@media (min-width: 481px) {
  details.help-accordion > *:not(summary) {
    display: block !important;
  }
  details.help-accordion > summary.ap-accordion-summary {
    display: none;
  }
}

/* ===========================================================================
   CHANGELOG_SERIAL.md #317 — mobile-usability-p2: desktop-open overrides.
   All .mob-* elements are injected by mobile_nav.js only at <=480px (it
   checks matchMedia before building anything). These rules are a safety net:
   if the page is ever viewed at >480px after the JS has run (e.g., DevTools
   resize), the bottom bar, sheets, and accordions are invisible/inert.
   =========================================================================== */
@media (min-width: 481px) {
  /* Bottom bar: hidden above mobile */
  .mob-bottom-bar     { display: none !important; }
  .mob-more-sheet     { display: none !important; }
  .mob-more-backdrop  { display: none !important; }
  /* Bottom-sheet infrastructure: hidden above mobile */
  .mob-legend-sheet   { display: none !important; }
  .mob-sheet-backdrop { display: none !important; }
  /* ⓘ info buttons: hidden above mobile */
  .mob-info-btn       { display: none !important; }
  /* Summary accordion wrappers: force content visible, hide summary handle */
  .mob-section-details > :not(summary) {
    display: block !important;
  }
  .mob-section-summary { display: none !important; }
  /* The OI sidebar must be visible in its normal position on desktop */
  .live-oi-sidebar { display: block !important; }
  /* Tab nav shell: must be visible on desktop */
  .tab-nav-shell { display: block !important; }
  /* Body padding-bottom reset (was set inside <=480px block) */
  body { padding-bottom: 0; }
}
