/* FrontRunner — app stylesheet.
 *
 * Light-mode design system. Geist for UI, Geist Mono for tabular figures.
 * WCAG/Apple-HIG-aware contrast: deep accent, contrast-safe gain/loss tones,
 * borders-first surfaces (minimal shadow). 16px base for a mixed audience.
 * All colour, spacing and radius values flow from the :root tokens below.
 */

:root {
  --font-ui:  'Geist', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --font-num: 'Geist Mono', ui-monospace, 'SF Mono', 'JetBrains Mono', monospace;

  --bg:             #F3F4F6;
  --surface:        #FFFFFF;
  --surface-elev:   #F5F6F8;
  --surface-hover:  #ECEEF1;
  --border:         #DEE0E5;
  --border-strong:  #C7CAD2;
  --divider:        #EBEDF0;
  --text:           #1C1F23;
  --text-secondary: #4A5159;
  --text-tertiary:  #5F6671;
  --accent:         #3457B2;
  --accent-hover:   #2C4A9B;
  --profit:         #2F7D54;          /* text-safe gain — 4.6:1 on white */
  --loss:           #BC3B30;          /* text-safe loss — 4.7:1 on white */
  --profit-graphic: #3E9A68;          /* brighter gain — chart fills / strips */
  --loss-graphic:   #D24B3E;          /* brighter loss — chart fills / strips */
  --warning:        #A66515;
  --live:           #2F7D54;
  --paper:          #A66515;
  --backtest:       #6B7280;
  --danger:         #BC3B30;
  --radius-sm:      6px;
  --radius:         8px;
  --radius-lg:      12px;

  /* Spacing scale — one source of truth. Bump these to rescale the app. */
  --space-1:        5px;
  --space-2:        9px;
  --space-3:        13px;
  --space-4:        18px;
  --space-5:        24px;
  --space-6:        34px;
  --shadow-sm:      0 1px 2px rgba(16, 24, 40, 0.04);
  --shadow-md:      0 4px 16px rgba(16, 24, 40, 0.10);
  --topbar-h:       56px;
  /* Vertical space taken by the year-strip + spacing above the chart
     card. Used by .chart-card-fill and .chart-side so they fill exactly
     to the viewport bottom. Kept as a single source of truth to avoid
     drift between the card and the sidebar. */
  --chart-fold-offset: 112px;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-ui);
  font-size: 18px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.num, .ticker {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1, 'ss01' 1;
}

a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--accent-hover); }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

.skip-link { position: absolute; left: -999px; }
.skip-link:focus {
  left: 8px; top: 8px;
  background: var(--surface);
  padding: 8px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  z-index: 100;
}

/* --- App shell — a slim sticky icon rail + the main content --- */
.shell { display: flex; align-items: flex-start; min-height: 100vh; }

/* Floating rail — a rounded card with the page background visible on all
   four sides; sticks in frame as the content scrolls. */
.appbar {
  position: sticky;
  top: var(--space-3);
  flex-shrink: 0;
  width: 62px;
  height: calc(100vh - var(--space-3) - var(--space-3));
  margin: var(--space-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-3) 0 var(--space-4);
  background: #2A2E35;
  border: 1px solid #23262C;
  border-radius: var(--radius-lg);
  z-index: 40;
}

/* Mode + utility icon buttons — stacked, centred in the rail. */
.appbar-modes,
.appbar-util {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
}
.appbar-util {
  align-self: center;
  width: 42px;
  padding-top: var(--space-3);
  border-top: 1px solid rgba(255, 255, 255, 0.12);
}
.appbar-icon {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: none;
  border-radius: var(--radius);
  background: transparent;
  color: rgba(255, 255, 255, 0.62);
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}
.appbar-icon svg { width: 23px; height: 23px; }
.appbar-icon:hover { background: rgba(255, 255, 255, 0.10); color: #fff; }
.appbar-icon.is-active { background: rgba(255, 255, 255, 0.14); color: #fff; }
.appbar-icon.mode-live.is-active { background: rgba(62, 154, 104, 0.38); color: #fff; }
.appbar-icon.mode-paper.is-active { background: rgba(210, 140, 60, 0.34); color: #fff; }
/* Hover tooltip — sits to the right of the rail. Matches the icon's
   own square hit-area in height with the appbar's dark theme, and uses
   the same uppercase / bold treatment as the chart card's vertical tab
   labels so the rail-and-tooltip pair read as one piece of chrome. */
.appbar-icon::after {
  content: attr(aria-label);
  position: absolute;
  left: calc(100% + 8px);
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  height: 44px;
  padding: 0 14px;
  border-radius: var(--radius);
  background: #2A2E35;
  border: 1px solid #23262C;
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 110ms ease;
  z-index: 60;
}
.appbar-icon:hover::after { opacity: 1; }

/* Brand — the horse above the large vertical wordmark, pinned bottom-left. */
.appbar-brand {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
}
.appbar-brand:hover { color: inherit; }
.appbar-horse {
  display: block;
  width: 46px;
  height: auto;
}
.appbar-wordmark {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  font-size: 38px;
  font-weight: 700;
  letter-spacing: 0.05em;
  color: #fff;
}

/* --- Content — fills the space to the right of the rail --- */
.shell-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}
/* No left padding — the appbar's own right margin is the only gap, so the
   grey strip left of the rail equals the strip right of it. */
.content {
  flex: 1;
  width: 100%;
  padding: var(--space-3) var(--space-5) var(--space-4) 0;
}

.bottomtabs { display: none; }

/* --- Cards --- */
.page-title { font-size: 26px; font-weight: 700; margin: 0 0 4px; }
.page-sub { color: var(--text-secondary); font-size: 15px; margin: 0 0 20px; }
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 14px;
  margin-bottom: 14px;
}
.card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
}
.card-head h2 { font-size: 15px; font-weight: 600; margin: 0; }
.card-link { font-size: 15px; font-weight: 500; }
.card-flush { padding: 0; overflow: hidden; }
.card-flush .card-head { padding: 16px 18px 0; margin-bottom: 12px; }

.dash-split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
}
.dash-aside {
  display: grid;
  grid-template-columns: 1.6fr 1fr;
  gap: 20px;
  align-items: start;
}

/* --- Status bar --- */
.status-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 24px;
  padding: 14px 18px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  margin-bottom: 20px;
  box-shadow: var(--shadow-sm);
}
.status-mode {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-weight: 600;
  font-size: 15px;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--surface-elev);
  border: 1px solid var(--border);
}
.status-item {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  color: var(--text-secondary);
  font-size: 14px;
}
.status-item .num { color: var(--text); font-size: 19px; font-weight: 600; }
.pnl-pos { color: var(--profit); }
.pnl-neg { color: var(--loss); }

/* --- Chart --- the readout panel + the chart card sit side by side --- */
.perf-row {
  display: flex;
  align-items: stretch;
  /* No automatic gap — the rail and chart card must touch with no seam.
     The sidebar gets an explicit margin-left so it still breathes. */
  gap: 0;
  margin-bottom: var(--space-4);
}
.perf-row > .chart-side { margin-left: var(--space-3); }
/* Three-column pivot (perf-row-3col) — left annual, centre chart+tabs,
   right daily. Left sidebar gets a right-margin instead of relying on
   the existing left-margin rule. */
.perf-row-3col > .chart-side-left { margin-left: 0; margin-right: var(--space-3); }
.perf-row-3col > .chart-side-right { margin-left: var(--space-3); }
/* Left readout column — a standalone bordered panel (outside the chart
   card, so the card's padding doesn't squeeze its content). */
.chart-side {
  width: 272px;
  flex-shrink: 0;
  /* Match the chart card's fixed first-fold height exactly so a long
     readout (Trades, Baseline, etc.) scrolls inside its own column
     rather than stretching the chart card and the tab rail below the
     fold. Falls back to min-height on very short viewports. */
  height: calc(100vh - var(--chart-fold-offset));
  min-height: 420px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-3);
}
/* Slim, unobtrusive scrollbar inside the readout column. */
.chart-side::-webkit-scrollbar { width: 8px; }
.chart-side::-webkit-scrollbar-thumb {
  background: rgba(0, 0, 0, 0.18);
  border-radius: 999px;
}
.chart-side::-webkit-scrollbar-track { background: transparent; }
.chart-card { flex: 1; min-width: 0; margin-bottom: 0; }
/* Vertical stack: tab rail on top, chart card below. Sits as a single
   flex item inside .perf-row, alongside the right-hand sidebar. */
.chart-stack { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.chart-stack-fill {
  height: calc(100vh - var(--chart-fold-offset));
  min-height: 420px;
}
.chart-stack-fill > .chart-card-fill { flex: 1; height: auto; min-height: 0; }
.chart-wrap { display: flex; flex: 1; min-height: 0; }
.chart-main { flex: 1; min-width: 0; display: flex; flex-direction: column; position: relative; }
.chart-area { height: 360px; position: relative; }
/* Reset control — sits beside the Linear/Log scale toggle in the chart's
   control row, styled to match the toggle pills (dark, rounded). */
/* Reset chart overlays — light pill that matches the Trade Log's
   "Reset filters" chip. Keeps the ↻ icon + "Reset" label. */
.chart-reset {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 14px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text-secondary);
  font: 600 13px var(--font-ui);
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
}
.chart-reset:hover {
  background: var(--surface-elev);
  color: var(--text);
  border-color: #C7CAD3;
}
.chart-reset-icon { flex-shrink: 0; color: var(--text-tertiary); }
.chart-reset:hover .chart-reset-icon { color: var(--text); }
/* Icon-only variant — square, just the rotating-arrow glyph. */
.chart-reset.chart-reset-icon-only {
  padding: 0;
  width: 32px;
  height: 32px;
  justify-content: center;
}

/* Fill-the-fold chart card — the equity chart leads the page and the card
   stretches so its curve fills the first viewport. With tabs on, the card
   becomes a 2-column grid: a 48px tab strip + the tab-panel container. */
.chart-card-fill {
  display: flex;
  flex-direction: column;
  height: calc(100vh - var(--chart-fold-offset));
  min-height: 420px;
}
.chart-card-fill .chart-area { height: auto; flex: 1; min-height: 0; }
/* Horizontal view selector — a 4-option toggle on top of the chart
   card. Light theme, white background to match the card, joined to the
   card with no visible seam. A sliding "thumb" indicates the active
   option; its --pos custom-property is driven from JS (0 / 1 / 2 / 3). */
.ctab-rail {
  --pos: 0;
  position: relative;
  flex-shrink: 0;
  width: 100%;
  display: flex;
  flex-direction: row;
  padding: 4px;
  /* Inactive surface is the page tint so the white thumb reads clearly
     as "raised / selected" against it. */
  background: var(--bg);
  border: 1px solid var(--border);
  /* Bottom edge flat + 1px negative margin so the rail and the chart card
     read as a single joined surface, not two stacked cards. */
  border-bottom: none;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  margin-bottom: -1px;
  z-index: 1;
}
/* Sliding thumb — the active highlight. White pill, lifted with a soft
   shadow so it reads as the foreground/selected option against the
   tinted rail background. */
.ctab-thumb {
  position: absolute;
  z-index: 0;
  top: 4px;
  bottom: 4px;
  left: 4px;
  width: calc((100% - 8px) / 4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04),
              0 2px 6px rgba(0, 0, 0, 0.06);
  transform: translateX(calc(var(--pos, 0) * 100%));
  transition: transform 240ms cubic-bezier(.4, 0, .2, 1);
  pointer-events: none;
}
.ctab {
  /* flex:1 1 0 + min-width:0 → strict equal partitioning of rail width
     across all tabs regardless of label length or viewport. */
  flex: 1 1 0;
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
  border: none;
  background: transparent;
  color: var(--text-tertiary);
  cursor: pointer;
  padding: 10px 14px;
  transition: color 160ms ease;
}
.ctab-label {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  white-space: nowrap;
  user-select: none;
}
.ctab:hover { color: var(--text); }
.ctab:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
  border-radius: var(--radius-sm);
}
.ctab.is-active { color: var(--accent); }
/* The chart card abuts the rail — flatten its top corners so the two
   shapes form a single rounded slab. */
.chart-stack > .card.chart-card {
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}

/* Tab-panel container inside the card — fills the card's body. Only the
   active panel is rendered (display:flex column so the chart can grow). */
.ctab-panels {
  flex: 1;
  min-height: 0;
  position: relative;
  display: flex;
  flex-direction: column;
}
.ctab-panel {
  flex: 1;
  min-height: 0;
  display: none;
  overflow: hidden;
}
.ctab-panel.is-active {
  display: flex;
  flex-direction: column;
}
.ctab-panel .chart-wrap { flex: 1; min-height: 0; }
/* Tab panel body is itself a flex column so any internal scroll
   container (e.g. the rankings table) can flex:1 + min-height:0 and
   fill the remaining viewport. */
.ctab-panel-body {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  padding: var(--space-3);
}

/* Search + count toolbar above the Trade Log table (and the Rankings
   panel uses the same layout via `.rankings-tools`). */
.trade-log-tools,
.rankings-tools {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-2);
  flex-wrap: wrap;
}
.trade-log-search {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex: 1;
  max-width: 360px;
  height: 36px;
  padding: 0 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text-tertiary);
  transition: border-color 140ms ease, box-shadow 140ms ease;
}
.trade-log-search:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(52, 87, 178, 0.14);
  color: var(--text);
}
.trade-log-search-icon { flex-shrink: 0; }
.trade-log-search input {
  flex: 1;
  min-width: 0;
  border: none;
  outline: none;
  background: transparent;
  font: 500 14px var(--font-ui);
  color: var(--text);
}
.trade-log-search input::placeholder {
  color: var(--text-tertiary);
  font-weight: 500;
}
.trade-log-count {
  font-size: 13px;
  color: var(--text-tertiary);
  font-variant-numeric: tabular-nums;
}
/* Inline "x" inside the search input — appears only when the field
   has content, dismisses just the search query. */
.trade-log-clear {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: var(--surface-elev);
  color: var(--text-tertiary);
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}
.trade-log-clear[hidden] { display: none; }
.trade-log-clear:hover { background: var(--border); color: var(--text); }
/* Standalone reset chip — appears whenever either filter is active;
   wipes the search AND pops the chart's range back to "All years". */
.trade-log-reset {
  flex-shrink: 0;
  padding: 6px 12px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text-secondary);
  font: 600 12px var(--font-ui);
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
}
.trade-log-reset[hidden] { display: none; }
.trade-log-reset:hover {
  background: var(--surface-elev);
  color: var(--text);
  border-color: #C7CAD3;
}

/* Sidebar is shown on every tab — the period-summary context is useful
   regardless of which view (Chart / Holdings / Rankings / Trade Log /
   Strategy) is active. */

/* Floating trade-event tooltip on the chart — appears near the crosshair
   when hovering a day on which a buy/sell/swap fired. Replaces the chip
   that used to live in the sidebar. */
.trade-tip {
  position: absolute;
  /* top is set dynamically by showTradeTip() so the tip rides the
     crosshair's y. */
  transform: translateX(-50%);
  pointer-events: none;
  background: #1F2329;
  color: #F3F4F6;
  border-radius: var(--radius-sm);
  padding: 8px 12px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.22);
  font-family: var(--font-ui);
  font-size: 13px;
  line-height: 1.3;
  z-index: 12;
  opacity: 0;
  transition: opacity 120ms ease;
  white-space: nowrap;
}
.trade-tip.is-visible { opacity: 1; }
.trade-tip-act { font-weight: 700; }
.trade-tip-sub {
  font-size: 12px;
  color: rgba(243, 244, 246, 0.78);
  margin-top: 2px;
}
/* Compact control strip under the chart — layer + compare toggles share a row. */
.chart-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 14px;
  margin-top: 8px;
}
.chart-foot .chart-layers,
.chart-foot .symbol-toggles { margin-top: 0; }
/* Control row below the bull/bear strip — layer toggles left, Linear/Log
   pushed to the right. */
.chart-controls {
  display: flex;
  align-items: center;
  /* Single-row layout — the toggle pills shrink to fit; the right
     cluster (Reset · $/% · Linear/Log) stays put. */
  flex-wrap: nowrap;
  gap: 6px 10px;
  margin-top: 6px;
  min-width: 0;
}
.chart-controls .chart-layers {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
}
.chart-controls-right { flex-shrink: 0; }
/* Right-side cluster: Reset · $/% · Linear/Log. Pushed flush right so
   the toggles always sit against the chart's right edge regardless of
   the chart-layers row's width. */
.chart-controls-right {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-left: auto;
}
.chart-controls .scale-btn { min-height: 26px; }
.chart-controls .chart-layers { margin-top: 0; }
.scale-toggle {
  display: flex;
  gap: 2px;
  background: var(--surface-elev);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 2px;
}
.scale-btn, .universe-btn {
  min-height: 32px;
  padding: 0 12px;
  border: none;
  background: transparent;
  color: var(--text-secondary);
  border-radius: 6px;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
}
.scale-btn:hover, .universe-btn:hover { color: var(--text); }
.scale-btn[disabled] {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}
.scale-btn.is-active, .universe-btn.is-active {
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-sm);
}
/* Crosshair readout — the upper, flexible part of the left panel. */
.chart-legend {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-size: 13px;
}
.legend-title { color: var(--text-secondary); }
.legend-value { font-size: 20px; font-weight: 700; color: var(--text); }
.legend-change { font-size: 13px; font-weight: 600; }

/* Rich crosshair tooltip */
.tt-date { color: var(--text-secondary); font-size: 12px; }
.tt-hold {
  align-self: flex-start;
  font-size: 12px;
  font-weight: 700;
  padding: 1px 7px;
  margin: 2px 0;
  border-radius: 999px;
  background: rgba(27, 79, 216, 0.12);
  color: var(--accent);
}
.tt-hold.tt-cash { background: var(--surface-elev); color: var(--text-secondary); }
.tt-value { font-size: 21px; font-weight: 700; color: var(--text); }
.tt-row { font-size: 12px; color: var(--text-secondary); }

/* Market-regime block strip — solid green/red segments aligned with the
   chart's time scale. Painted by chart.js (DOM spans, not SVG) so the
   block can be any pixel height (LWC's pane API floors sub-panes at
   ~135px, which is why this lives outside the chart). */
.regime-strip {
  position: relative;
  height: 22px;
  margin-top: 4px;
  border-radius: 4px;
  overflow: hidden;
  border: 1px solid var(--border);
}
.regime-strip[hidden], .regime-strip:empty { display: none; }
.regime-seg {
  position: absolute;
  top: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  font-size: 11px;
  font-weight: 700;
  color: #fff;
  white-space: nowrap;
  cursor: default;
}

/* Floating positions tooltip — pinned to the chart's bottom-left, lists
   each held ticker as a tiny colored chip. Replaces the previously
   below-chart holding ribbon: a 70+-symbol universe over 17 years made
   the ribbon labels unreadable, so the position list lives "on" the
   chart at hover-time instead. */
/* .hold-tip retired — the bottom-left floating ticker chip is gone now
   that the sidebar Holdings stack carries the same info per-day. */

/* Chart key / legend strip */
.chart-key {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 16px;
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
  font-size: 13px;
  color: var(--text-secondary);
}
.key-item { display: inline-flex; align-items: center; gap: 6px; }
.key-swatch { width: 11px; height: 11px; border-radius: 3px; display: inline-block; }
.key-cash { background: #5C5F6B; }
.key-line { width: 16px; height: 0; display: inline-block; }
.key-stop { border-top: 2px dashed #F7A6AE; }
.key-qqq { border-top: 2px solid #B0B4C0; }
.key-base { border-top: 2px dashed #C7CAD3; }
.key-bull { background: #3E9A68; }
.key-bear { background: #D24B3E; }
.key-mk { font-size: 12px; line-height: 1; }
.key-buy { color: var(--profit); }
.key-sell { color: #EA580C; }
.key-swap { color: var(--accent); }
.key-stopout { color: var(--loss); }

/* Chart layer panel — FrontRunner-relevant overlays the operator can toggle. */
.chart-layers {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 5px;
  margin-top: 10px;
}
.chart-layers:empty { display: none; }
.layer-toggle {
  flex-shrink: 0;
  min-height: 28px;
  padding: 0 9px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text-secondary);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  transition: background 120ms ease, border-color 120ms ease, color 120ms ease;
}
.layer-toggle:hover { background: var(--surface-hover); }
.layer-toggle.is-on {
  color: var(--text);
  border-color: var(--border-strong);
  background: var(--surface-hover);
}
.layer-toggle::before {
  content: '';
  display: inline-block;
  width: 8px; height: 8px;
  margin-right: 6px;
  border-radius: 2px;
  background: var(--border-strong);
  vertical-align: middle;
  opacity: 0.35;
}
.layer-toggle.is-on::before { opacity: 1; background: var(--accent); }

/* Crosshair-tooltip market-regime row */
.tt-regime { font-weight: 700; }
.tt-regime-bull { color: var(--profit); }
.tt-regime-bear { color: var(--loss); }

/* Period summary — the readout panel's resting state: stats for the
   selected year / era / All. Crosshair hover swaps in the .tt-* day view. */
.ps-mode {
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-tertiary);
}
/* Sidebar footer — pinned to the bottom by an auto top margin so the
   RETURN/RISK/ACTIVITY groups above it stay locked in place regardless
   of what the footer is showing. The footer carries either the era /
   period label (resting state) or the colored ticker pills (hover). */
.ps-footer {
  margin-top: auto;
  padding-top: 14px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  min-height: 96px;
}
/* Title slot for the footer — stacked column of ticker pills under
   hover, or plain period label otherwise. Slot reserves enough space
   for N=3 pills so hover/rest transitions never reflow rows above. */
.ps-head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  font-size: 18px;
  font-weight: 600;
  color: var(--text);
}
/* Era container — name + info "i" pip on a single baseline-aligned row.
   The i icon stays vertically centred with the era name regardless of
   font weight or line-height differences. */
.ps-era {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 18px;
  font-weight: 600;
  color: var(--text);
}
.ps-era .ps-info { margin-left: 0; }
.ps-era-name { line-height: 1.2; }
.ps-tk {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--c);
  color: #fff;
  font-family: var(--font-num);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.02em;
  line-height: 1.15;
}
.ps-tk-sym { font-size: 14px; }
.ps-tk-sub {
  font-size: 11px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.78);
}
.ps-tk-cash {
  background: var(--surface-elev);
  color: var(--text-secondary);
  font-style: italic;
  font-weight: 600;
  font-family: var(--font-ui);
}
/* Trade-chip slot — always present, reserved height. On days with no
   trade the slot is empty but still occupies the same vertical space, so
   the RETURN/RISK/ACTIVITY groups below never shift up or down. */
.sb-trade {
  min-height: 56px;
  display: flex;
  align-items: flex-start;
}
.sb-trade .ps-trade { width: 100%; }
/* Em-dash placeholder for missing values — muted so users can tell it's
   "no data" rather than a real zero. */
.ps-num.is-empty {
  color: var(--text-tertiary);
  font-weight: 500;
}
.ps-range { font-size: 13px; color: var(--text-secondary); }
.ps-big {
  margin-top: 4px;
  font-size: 24px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}
.ps-big-label { font-size: 12px; color: var(--text-secondary); }
.ps-rows {
  display: flex;
  flex-direction: column;
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid var(--divider);
}
/* Group sub-heading — "Risk", "Activity". */
.ps-grp {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-tertiary);
  margin: 6px 0 2px;
}
.ps-grp:first-child { margin-top: 0; }
.ps-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
  padding: 2px 0;
}
.period-rows .ps-row { min-height: 0; }
.ps-label {
  font-size: 13px;
  color: var(--text-secondary);
  flex: 0 0 auto;
  min-width: 72px;
  white-space: nowrap;
}
.ps-val {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  line-height: 1.2;
  min-width: 0;
}
.ps-val .ps-sub { white-space: nowrap; }
.ps-num {
  font-size: 15px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}
/* Regime pill — green for bull, red for bear. Sits inside the sidebar's
   .ps-num value slot in place of plain text. */
.ps-regime-pill {
  display: inline-flex;
  align-items: center;
  padding: 2px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.ps-regime-bull {
  background: rgba(47, 125, 84, 0.14);
  color: var(--profit);
}
.ps-regime-bear {
  background: rgba(188, 59, 48, 0.14);
  color: var(--loss);
}
.ps-sub {
  font-size: 12px;
  color: var(--text-tertiary);
  margin-top: 1px;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}
/* Compare-row swatch — ties the row to its overlay line. */
.ps-dot {
  display: inline-block;
  width: 9px; height: 9px;
  border-radius: 3px;
  margin-right: 6px;
  vertical-align: middle;
}
/* Trade-event chip in the hover readout. */
.ps-trade {
  display: flex;
  flex-direction: column;
  gap: 1px;
  margin: 8px 0 2px;
  padding: 7px 9px;
  background: var(--surface-elev);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.ps-trade-act { font-size: 13px; font-weight: 700; color: var(--text); }
.ps-trade-sub { font-size: 12px; color: var(--text-secondary); }
/* Info icon next to the subtitle (e.g. "Quantitative-Easing Bull Market") —
   reveals the full era description as a hover tooltip so the description
   no longer needs a separate accordion row at the bottom of the sidebar. */
.ps-info {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 13px;
  height: 13px;
  margin-left: 4px;
  padding: 0;
  border: 1px solid #1F2329;
  border-radius: 50%;
  /* Inverse styling — matches the dark tooltip the icon reveals, so the
     pairing reads as a single piece of UI. */
  background: #1F2329;
  color: #F3F4F6;
  font-family: var(--font-num, ui-monospace, monospace);
  font-size: 8.5px;
  font-style: italic;
  font-weight: 700;
  line-height: 1;
  cursor: help;
  vertical-align: middle;
  position: relative;
  transition: background 120ms ease, border-color 120ms ease;
}
.ps-info:hover, .ps-info:focus-visible {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
  outline: none;
}
/* Info tooltip — a single floating element appended to <body> so it
   escapes the sidebar's clipping scroll container and the chart-card's
   overflow:hidden. Positioned dynamically in JS (see chart.js) and
   clamped to the viewport. */
.info-tip {
  position: fixed;
  z-index: 1000;
  max-width: 300px;
  padding: 10px 12px;
  background: #1F2329;
  color: #F3F4F6;
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 500;
  line-height: 1.45;
  text-align: left;
  border-radius: var(--radius-sm);
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.28);
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity 140ms ease;
  white-space: normal;
}
.info-tip.is-visible {
  opacity: 1;
  visibility: visible;
}
/* Title line — the era's expanded name (e.g. "Global Financial Crisis
   Recovery"). Larger and bolder than the body. */
.info-tip-h {
  font-size: 13px;
  font-weight: 700;
  color: #fff;
  margin-bottom: 6px;
}
/* One-line synopsis under the title — italicised, slightly muted. */
.info-tip-sum {
  font-size: 12px;
  font-style: italic;
  color: rgba(243, 244, 246, 0.78);
  margin-bottom: 6px;
}
/* Body paragraph — the full description. */
.info-tip-p {
  font-size: 12px;
  color: rgba(243, 244, 246, 0.88);
}

/* Per-symbol comparison toggles — a single-row trigger + a year-grouped
   dropdown picker. The trigger button opens the picker; selected chips
   appear inline next to it. Held tickers can number 70+ across a 17-year
   backtest, so the full list lives inside the dropdown rather than
   wrapping across the chart card. */
.symbol-toggles {
  position: relative;
  margin-bottom: var(--space-2);
}
.symbol-toggles:empty { display: none; }
.cmp-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: nowrap;
  overflow: hidden;
}
.cmp-trigger {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 12px;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text);
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  flex-shrink: 0;
  white-space: nowrap;
}
.cmp-trigger:hover { background: var(--surface-elev); }
.cmp-trigger[aria-expanded="true"] {
  border-color: var(--accent);
  color: var(--accent);
}
.cmp-caret {
  font-size: 10px;
  line-height: 1;
  opacity: 0.7;
}
.cmp-chips {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: thin;
}
.cmp-chips::-webkit-scrollbar { height: 4px; }
.cmp-chips::-webkit-scrollbar-thumb { background: var(--border-strong); }
.cmp-x {
  font-size: 14px;
  line-height: 1;
  opacity: 0.6;
  margin-left: 2px;
}
.cmp-row:hover .cmp-x { opacity: 1; }
/* Year-grouped picker — popover dropdown anchored under the trigger.
   One column per year so a ticker held across multiple eras appears
   under each year, but toggling any occurrence flips the same overlay. */
/* One year per row — header sits left, tickers flow horizontally across
   the full picker width. Wraps to the next line only when the tickers
   exceed the available width. */
.cmp-picker {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 40;
  max-height: 360px;
  overflow-y: auto;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  box-shadow: 0 12px 32px rgba(15, 23, 42, 0.18);
}
.cmp-picker[hidden] { display: none; }
.cmp-yr {
  display: grid;
  grid-template-columns: 56px 1fr;
  align-items: center;
  gap: 12px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--border);
}
.cmp-yr:last-child {
  padding-bottom: 0;
  border-bottom: 0;
}
.cmp-yr-hd {
  font-family: var(--font-num);
  font-size: 12px;
  font-weight: 700;
  color: var(--text-secondary);
}
.cmp-yr-list {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.cmp-opt {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 8px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text-secondary);
  font-family: inherit;
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
}
.cmp-opt:hover { color: var(--text); border-color: var(--border-strong); }
.cmp-opt.is-on { color: var(--text); border-color: var(--c); }
.cmp-opt.is-on .cmp-swatch { background: var(--c); }
.cmp-row {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text-secondary);
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: color 120ms ease, border-color 120ms ease;
}
.cmp-row:hover { color: var(--text); border-color: var(--border-strong); }
.cmp-row.is-on { color: var(--text); border-color: var(--c); }
.cmp-swatch {
  width: 10px;
  height: 10px;
  flex-shrink: 0;
  border-radius: 3px;
  border: 1.5px solid var(--c);
  background: transparent;
}
.cmp-row.is-on .cmp-swatch { background: var(--c); }
.cmp-tk { font-family: var(--font-num); }
.range-tabs, .filter-tabs, .date-nav { display: flex; gap: 2px; }
.range-btn, .filter-btn {
  min-height: 32px;
  min-width: 44px;
  padding: 0 12px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--text-secondary);
  border-radius: 6px;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}
.range-btn:hover, .filter-btn:hover { background: var(--surface-hover); color: var(--text); }
.range-btn.is-active, .filter-btn.is-active {
  background: rgba(27, 79, 216, 0.10);
  color: var(--accent);
  font-weight: 600;
}
.date-nav {
  align-items: center;
  background: var(--surface-elev);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 2px;
}
.date-btn {
  min-height: 44px;
  min-width: 44px;
  border: none;
  background: transparent;
  color: var(--text-secondary);
  border-radius: 6px;
  font-size: 18px;
  cursor: pointer;
}
.date-btn:hover { background: var(--surface-hover); color: var(--text); }
.date-btn:disabled { opacity: 0.35; cursor: not-allowed; }
.date-btn:disabled:hover { background: transparent; color: var(--text-secondary); }
.date-label {
  padding: 0 12px;
  align-self: center;
  color: var(--text);
  font-size: 15px;
  font-weight: 500;
}

/* --- Tables --- */
.table-scroll { overflow-x: auto; }
.data-table { width: 100%; border-collapse: collapse; font-size: 13px; }
/* Trade log — fixed column widths so the table doesn't reflow when the
   date filter changes the visible rows. Reason column gets the
   remainder of the table width. */
.trade-log { table-layout: fixed; }
.trade-log th:nth-child(1) { width: 112px; }    /* Date */
.trade-log th:nth-child(2) { width: 84px; }     /* Action */
.trade-log th:nth-child(3) { width: 84px; }     /* Ticker */
.trade-log th:nth-child(4) { width: 96px; }     /* Shares */
.trade-log th:nth-child(5) { width: 108px; }    /* Price */
.trade-log th:nth-child(6) { width: 132px; }    /* Value */
.trade-log th:nth-child(7) { width: 96px; }     /* Event */
.data-table th, .data-table td { white-space: nowrap; }
/* Reason row — secondary line under each trade, spans all columns. The
   top border is suppressed so it visually pairs with the row above; the
   trade row's bottom border still separates pairs. */
.trade-log tr.trade-log-reason-row td {
  white-space: normal;
  padding-top: 0;
  padding-left: 24px;
  border-top: none;
  color: var(--text-secondary);
  font-size: 13px;
  line-height: 1.4;
}
.trade-log tr:not(.trade-log-reason-row) td { border-bottom: none; }
.trade-log tr.trade-log-reason-row td .reason-label {
  display: inline-block;
  margin-right: 8px;
  color: var(--text-secondary);
  font-weight: 600;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  opacity: 0.7;
}
.trade-log tbody tr:hover { background: transparent; }
.trade-log tbody tr:not(.trade-log-reason-row):hover,
.trade-log tbody tr:not(.trade-log-reason-row):hover + tr.trade-log-reason-row {
  background: var(--surface-elev);
}
.data-table th, .data-table td {
  text-align: left;
  padding: 8px 6px;
  border-bottom: 1px solid var(--border);
}
.data-table th:first-child, .data-table td:first-child { padding-left: 10px; }
.data-table th:last-child,  .data-table td:last-child  { padding-right: 10px; }
.data-table th { font-size: 11px; }
.data-table thead th { border-bottom: 1px solid var(--border-strong); }
.data-table tbody tr:last-child td { border-bottom: none; }
.data-table tbody tr:hover { background: var(--surface-elev); }
.data-table th {
  color: var(--text-secondary);
  font-weight: 600;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.data-table .num { text-align: right; font-family: 'JetBrains Mono', monospace; }
.col-rank { width: 36px; text-align: center; }
th.col-rank, td.col-rank { text-align: center; }
/* GICS bucket column — kept tight so the table doesn't grow to fit the
   longest bucket label. The pill inside truncates if needed. */
.data-table th:nth-child(5),
.data-table td:nth-child(5) {
  max-width: 150px;
}
.data-table td:nth-child(5) .pill-bucket {
  display: inline-block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: middle;
}
.ticker { font-family: 'JetBrains Mono', monospace; font-weight: 600; }
.side-buy, .side-sell, .side-closed { font-weight: 700; }
.side-buy { color: var(--profit); }
.side-sell { color: var(--loss); }
.side-closed { color: #B5642A; }   /* gate-block "closed" — warm amber */
.pill {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 600;
}
.pill-ok { background: rgba(47, 125, 84, 0.12); color: var(--profit); }
.pill-muted { background: var(--surface-elev); color: var(--text-secondary); }
.pill-nas100 { background: rgba(27, 79, 216, 0.12); color: var(--accent); }
.pill-outlier {
  background: var(--surface-elev);
  color: var(--text-secondary);
  border: 1px solid var(--border);
}
/* GICS bucket pills — one tinted background per bucket so the rankings
   table reads as three visually distinct sub-universes at a glance. */
.pill-bucket { font-weight: 500; }
.pill-bucket-tech-software-services { background: rgba(27, 79, 216, 0.10); color: var(--accent); }
.pill-bucket-semis-and-hardware { background: rgba(124, 58, 237, 0.10); color: #7C3AED; }
.pill-bucket-consumer-health-other { background: rgba(47, 125, 84, 0.10); color: var(--profit); }
/* Bucket-leader marker — #1 within a GICS bucket is what the engine
   would actually pick from that sub-universe. */
.bucket-leader { color: var(--profit); font-weight: 600; }
/* Trade-log event pills */
.pill-event { letter-spacing: 0.03em; }
.pill-ev-entry { background: rgba(47, 125, 84, 0.12); color: var(--profit); }
.pill-ev-swap { background: rgba(124, 58, 237, 0.12); color: #7C3AED; }
.pill-ev-stop { background: rgba(188, 59, 48, 0.12); color: var(--loss); }
.pill-ev-gate { background: rgba(245, 158, 11, 0.14); color: #92600C; }
.pill-ev-earnings, .pill-ev-trade {
  background: var(--surface-elev); color: var(--text-secondary);
}

/* Backtest daily-ranking card */
.bt-rank-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}
/* Rankings table fills the rest of the tab panel — internal scroll
   only kicks in when the row count exceeds the viewport. No fixed
   max-height (which otherwise clipped the table and left top rows
   stranded above the viewport on tall windows). */
.bt-rank-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}
.bt-rank-scroll thead th {
  position: sticky;
  top: 0;
  background: var(--surface);
  z-index: 1;
}

/* Held-row highlight — the operator's live positions sit somewhere in
   the universe ranking; a soft green wash makes them findable at a
   glance without breaking the table's row rhythm. Border-left adds a
   second cue independent of background colour for accessibility. */
.data-table tbody tr.is-held {
  background: rgba(62, 154, 104, 0.10);
  box-shadow: inset 3px 0 0 var(--profit);
}

/* Ticker link to Public.com — keeps the monospace look of the ticker
   cell, gains an underline-on-hover affordance to signal it is clickable.
   External-link semantics are carried in the attrs (target, rel). */
.ticker-link {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px dashed transparent;
}
.ticker-link:hover {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

/* --- Empty states --- */
.empty-state {
  padding: 32px 16px;
  text-align: center;
  color: var(--text-secondary);
  font-size: 15px;
}

.chart-empty-loading {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 0;
  pointer-events: none;
  z-index: 2;
}
.chart-empty-loading .loading-horse {
  width: min(560px, 70%);
  height: auto;
  display: block;
}
.chart-empty-loading .empty-state-text {
  margin: 0;
}

/* --- Widgets --- */
.widget-card { padding: 0; overflow: hidden; }
.widget-card .card-head { padding: 16px 18px 8px; margin-bottom: 0; }
.tradingview-widget-copyright {
  font-size: 13px;
  padding: 6px 12px;
  color: var(--text-secondary);
}
.tradingview-widget-copyright a, .tradingview-widget-copyright .blue-text {
  color: var(--text-secondary);
}

/* --- Misc --- */
.muted { color: var(--text-secondary); }
.profile-section { padding: 16px 0; border-top: 1px solid var(--border); }
.profile-section:first-of-type { border-top: none; padding-top: 4px; }
.profile-section h3 {
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-secondary);
  margin: 0 0 8px;
}
.role-badge {
  background: rgba(27, 79, 216, 0.10);
  color: var(--accent);
  font-size: 13px;
  font-weight: 600;
  padding: 4px 10px;
  border-radius: 999px;
}
.select {
  min-height: 36px;
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0 10px;
  font-size: 15px;
}
.control-label { font-size: 14px; color: var(--text-secondary); margin-right: 8px; }
.trade-controls { display: flex; align-items: center; }

/* --- Login --- */
.login-body {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  background: var(--bg);
}
/* Pure Clerk widget container — no FrontRunner card chrome. */
.login-shell {
  width: 100%;
  max-width: 440px;
  padding: 16px;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.login-shell #clerk-signin-mount { width: 100%; }
.login-card {
  width: 100%;
  max-width: 440px;
  padding: 36px 32px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  text-align: center;
}
/* Container for the embedded Clerk SignIn widget. Clerk's own card
   chrome is stripped via its `appearance` API (see login.html), so this
   block just gives the form fields breathing room inside our card. */
.login-clerk {
  margin: 22px 0 6px;
  text-align: left;
}
.login-clerk .cl-rootBox,
.login-clerk > div { width: 100%; }
.login-brand { font-size: 26px; margin: 0; }
.login-rule {
  width: 56px; height: 3px;
  background: var(--accent);
  border-radius: 2px;
  margin: 14px auto 22px;
}
.login-lead { color: var(--text-secondary); }
.login-foot { font-size: 14px; color: var(--text-secondary); margin: 14px 0 0; }
.login-foot-muted { font-size: 13px; }
.login-notice {
  font-size: 15px;
  color: var(--text);
  background: rgba(245, 158, 11, 0.08);
  padding: 14px;
  border: 1px solid rgba(245, 158, 11, 0.30);
  border-radius: var(--radius);
}

/* --- Toast --- */
.fr-toast {
  position: fixed;
  top: calc(var(--topbar-h) + 16px);
  right: 20px;
  z-index: 60;
  max-width: 320px;
  padding: 12px 16px;
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
  font-size: 15px;
  opacity: 0;
  transform: translateY(-8px);
  transition: opacity 200ms ease, transform 200ms ease;
}
.fr-toast.is-shown { opacity: 1; transform: translateY(0); }

/* --- Buttons --- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 40px;
  padding: 0 16px;
  border-radius: var(--radius);
  border: 1px solid transparent;
  font-size: 15px;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  transition: background 120ms ease, filter 120ms ease;
}
.btn:disabled { opacity: 0.4; cursor: not-allowed; }
.btn-primary { background: var(--accent); color: #fff; }
.btn-primary:hover:not(:disabled) { background: var(--accent-hover); }
.btn-secondary {
  background: var(--surface);
  color: var(--text);
  border-color: var(--border-strong);
}
.btn-secondary:hover:not(:disabled) { background: var(--surface-hover); }
.btn-danger { background: var(--danger); color: #fff; }
.btn-danger:hover:not(:disabled) { filter: brightness(0.94); }

/* --- Live trading-action panel --- */
.live-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  margin-bottom: 20px;
}
.live-position, .live-autotrade { margin-bottom: 0; }
.live-position-line {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 19px;
  font-weight: 600;
  margin: 0 0 12px;
}
.live-state-dot {
  width: 10px; height: 10px;
  border-radius: 50%;
  display: inline-block;
}
.live-state-dot.dot-cash { background: var(--border-strong); }
.live-figures { display: flex; flex-wrap: wrap; gap: 8px 24px; }
.live-fig {
  display: inline-flex;
  flex-direction: column;
  gap: 2px;
  font-size: 13px;
  color: var(--text-secondary);
}
.live-fig .num { font-size: 20px; font-weight: 700; color: var(--text); }
.live-pending {
  margin: 14px 0 0;
  padding-top: 12px;
  border-top: 1px solid var(--border);
  font-size: 15px;
  color: var(--text-secondary);
}
.live-autotrade { display: flex; flex-direction: column; }
.live-arm-state {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 15px;
  margin: 0 0 14px;
}
.live-arm-state.armed { color: var(--live); font-weight: 600; }
.live-autotrade .btn { width: 100%; }
.live-estop { margin-top: 10px; }
.live-notice {
  padding: 12px 16px;
  margin-bottom: 16px;
  background: rgba(27, 79, 216, 0.08);
  border: 1px solid rgba(27, 79, 216, 0.25);
  border-radius: var(--radius);
  font-size: 15px;
}

/* --- Backtest report --- */
.card-sub { font-size: 14px; color: var(--text-secondary); }

/* Slim hypothetical-results disclaimer */
/* Hero summary card */
.bt-hero {
  background:
    radial-gradient(120% 160% at 100% 0%, rgba(27, 79, 216, 0.06), transparent 62%),
    var(--surface);
}
.bt-hero-figure {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 14px;
}
.bt-hero-label {
  width: 100%;
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-secondary);
  margin-bottom: 4px;
}
.bt-hero-value {
  font-size: 46px;
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.02em;
  color: var(--text);
}
.bt-hero-delta {
  font-size: 21px;
  font-weight: 700;
  padding: 4px 10px;
  border-radius: 999px;
}
.bt-hero-delta.pnl-pos { background: rgba(47, 125, 84, 0.12); }
.bt-hero-delta.pnl-neg { background: rgba(188, 59, 48, 0.12); }
.bt-hero-sub {
  margin: 12px 0 0;
  font-size: 15px;
  color: var(--text-secondary);
}
.bt-hero-sub strong { font-weight: 700; }

/* Regime band — macro market eras above the year strip. Shares the year
   strip's grid (N year columns + a trailing "All" column) so each era tile
   spans exactly the year tiles it covers. */
/* Year-strip wrapper — the regime band + per-year heatmap stacked
   vertically, with the square "ALL" reset-to-full-period tile pinned
   to the right of both rows. */
.year-strip {
  display: flex;
  align-items: stretch;
  gap: 8px;
  margin-bottom: 10px;
}
.year-strip-grid {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.year-strip-grid .regime-row,
.year-strip-grid .year-row { margin: 0; }
.regime-row {
  display: grid;
  grid-template-columns: repeat(var(--ycols), 1fr);
  gap: 4px;
  margin-bottom: 4px;
}
.regime-tile {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  min-width: 0;
  overflow: hidden;
  height: 38px;
  padding: 4px 22px 4px 8px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-family: inherit;
  background: var(--tile-bg, var(--surface));
  transition: filter 120ms ease, box-shadow 120ms ease;
}
/* Era info pip inside the regime tile — sits right of the era name with
   a subtle white-on-tile look so it doesn't overpower the label, but is
   still legible. Reuses .ps-info's hover-tooltip wiring; an inline span
   (not a nested button) so the tile button stays valid markup. */
.rg-info {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 13px;
  height: 13px;
  font-size: 9px;
  border-color: var(--border);
  background: rgba(255, 255, 255, 0.7);
  color: var(--text-secondary);
  margin-left: 0;
  flex-shrink: 0;
}
.rg-info:hover, .rg-info:focus-visible {
  background: #fff;
  border-color: var(--text-secondary);
  color: var(--text);
  outline: none;
}
.regime-tile:hover { filter: brightness(1.06); }
.regime-tile.is-active { box-shadow: inset 0 0 0 2px var(--accent); }
/* Era tiles are tinted quantitatively (alpha on a green/red ramp by CAGR
   magnitude) rather than by a flat per-kind colour. The kind classes are
   retained as semantic hooks but no longer set background. */
.rg-name {
  max-width: 100%;
  font-size: 11.5px;
  font-weight: 700;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1.15;
}
.rg-cagr {
  font-family: var(--font-num);
  font-size: 10.5px;
  font-weight: 700;
  color: var(--text);
  letter-spacing: 0.01em;
  white-space: nowrap;
  line-height: 1.1;
  opacity: 0.85;
}

/* Year strip — a slim heatmap row above the chart. Cells flex to fill the
   width (no horizontal scroll); tint encodes each year's return. */
.year-row {
  display: grid;
  grid-template-columns: repeat(var(--ycols), 1fr);
  gap: 4px;
  margin-bottom: 10px;
}
.year-tile {
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  padding: 5px 3px;
  /* --tile-bg is the per-year heatmap fill (set inline from the
     template). Falls back to --surface for a neutral tile. */
  background: var(--tile-bg, var(--surface));
  border: 1px solid rgba(0, 0, 0, 0.06);
  border-radius: 6px;
  cursor: pointer;
  font-family: inherit;
  overflow: hidden;
  transition: background 160ms ease, opacity 160ms ease, box-shadow 120ms ease, transform 120ms ease;
}
.year-tile:hover {
  box-shadow: var(--shadow-md);
  transform: translateY(-1px);
}
.year-tile.is-active {
  border-color: var(--accent);
  box-shadow: inset 0 0 0 2px var(--accent);
}
.yt-year {
  font-family: var(--font-num);
  font-size: 12px;
  font-weight: 600;
  color: var(--text);
  letter-spacing: 0.01em;
}
.yt-return {
  font-family: var(--font-num);
  font-size: 11px;
  font-weight: 700;
  color: var(--text);
  letter-spacing: 0.01em;
  white-space: nowrap;
}
.year-tile-all {
  justify-content: center;
  align-items: center;
  padding: 0;
}
.yt-all {
  font-size: 14px;
  font-weight: 700;
  color: var(--text);
}

/* "ALL" reset-period tile — sits at the end of the year strip and spans
   both rows. Resets activeRange to ALL without touching the chart's
   layer overlays or Compare symbols. Square aspect, accent fill when
   active. */
.all-tile {
  flex-shrink: 0;
  align-self: stretch;
  width: 76px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text-secondary);
  font-family: var(--font-num);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.08em;
  cursor: pointer;
  transition: background 140ms ease, color 140ms ease, border-color 140ms ease;
}
.all-tile:hover {
  color: var(--text);
  border-color: #C7CAD3;
}
.all-tile.is-active {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

/* Honest-disclosure caption — only rendered when the rebase toggle is
   ON. Muted grey, sits below the chart so it does not compete with the
   curve itself. */
.rebase-note {
  margin-top: 8px;
  padding: 6px 12px;
  color: var(--text-secondary);
  font-size: 12px;
  font-style: italic;
  text-align: center;
}

/* Scope dim — when a year or era is selected, every other tile in the
   strip fades to a neutral so the active selection is unambiguous. The
   "All years" state (no scope) keeps every tile filled with its native
   heatmap colour. Contrast intentionally stays readable: secondary text
   on a slate-tint background, no compounded opacity. */
/* Gray is reserved for cash periods (see CASH_COLOR / .holdings-now-dot.is-cash).
   Out-of-scope era/year tiles use a warm cream wash instead so a dimmed
   tile is never confused with "in cash". */
.regime-row.has-scope .regime-tile:not(.is-selected):not(.is-implicit) {
  background: #F5F1E8;
  border: 1px solid #E7E0CE;
  filter: none;
}
.regime-row.has-scope .regime-tile:not(.is-selected):not(.is-implicit) .rg-name,
.regime-row.has-scope .regime-tile:not(.is-selected):not(.is-implicit) .rg-cagr {
  color: var(--text-secondary);
}
.year-row.has-scope .year-tile:not(.is-selected):not(.is-implicit) {
  background: #F5F1E8;
  border-color: #E7E0CE;
}
.year-row.has-scope .year-tile:not(.is-selected):not(.is-implicit) .yt-year,
.year-row.has-scope .year-tile:not(.is-selected):not(.is-implicit) .yt-return {
  color: var(--text-secondary);
}

/* Explicitly-clicked tiles get an accent ring so users see at a glance
   which tiles they actually picked. Implicit tiles (auto-pulled into
   the hull because the chart can only render a contiguous span) stay
   in their native colour but at reduced opacity, reading as "along for
   the ride" rather than "directly chosen". */
.regime-tile.is-selected,
.year-tile.is-selected {
  box-shadow: inset 0 0 0 2px var(--accent);
}
.regime-tile.is-implicit,
.year-tile.is-implicit {
  opacity: 0.62;
  box-shadow: none;
}

/* Detail stat grid */
.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.stat-grid-8 { grid-template-columns: repeat(4, 1fr); }
.stat {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 11px;
  background: var(--surface);
}
.stat-label { font-size: 12px; font-weight: 500; color: var(--text-secondary); }
.stat-value { font-size: 19px; font-weight: 700; letter-spacing: -0.01em; }
.stat-hint { font-size: 11px; color: var(--text-secondary); margin-top: 1px; line-height: 1.3; }

/* Compact final-value line in the stats card header */
.bt-final { display: inline-flex; align-items: baseline; gap: 8px; }
.bt-final-value { font-size: 22px; font-weight: 700; letter-spacing: -0.01em; }
.bt-final-delta { font-size: 14px; font-weight: 700; }
.bt-final-note { font-size: 12px; color: var(--text-secondary); }

/* Backtest trade log — capped, scrollable, sticky header */
.bt-trades { max-height: 440px; overflow-y: auto; }
.bt-trades thead th {
  position: sticky;
  top: 0;
  background: var(--surface);
  z-index: 1;
}

/* --- Responsive --- */
@media (max-width: 980px) {
  .dash-aside { grid-template-columns: 1fr; }
  .stat-grid-8 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 760px) {
  .topbar { gap: 10px; padding: 0 14px; }
  .dash-split { grid-template-columns: 1fr; }
  .live-grid { grid-template-columns: 1fr; }
  .stat-grid-8 { grid-template-columns: 1fr 1fr; }
  .bt-hero-value { font-size: 38px; }
  .content { padding: 16px; padding-bottom: 80px; }
  .mode-btn { padding: 0 10px; }
  .bottomtabs {
    display: flex;
    position: fixed;
    bottom: 0; left: 0; right: 0;
    background: var(--surface);
    border-top: 1px solid var(--border);
    z-index: 50;
  }
  .tab {
    flex: 1;
    text-align: center;
    padding: 10px 4px;
    min-height: 52px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-secondary);
    font-size: 13px;
    font-weight: 500;
  }
  .tab.is-active { color: var(--accent); }
}

/* ============================================================================
   Holdings tab (Decision X, 2026-05-21) — per-position trailing-stop view.
   Replaces the composite "portfolio stop NAV" overlay. Renders in all three
   modes (backtest as a tab inside the perf card; paper/live as a standalone
   card under the chart). Same table primitives the rankings + trade log use,
   plus a `dist-warn` accent for positions ≤ 2% from their trailing stop.
   ========================================================================== */
.holdings-card { padding: 0; }
.holdings-head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 14px 18px 10px;
  border-bottom: 1px solid var(--border-subtle, rgba(0,0,0,.06));
}
.holdings-head h3 {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--text);
}
.holdings-asof {
  font-size: 12px;
  color: var(--text-tertiary);
  font-variant-numeric: tabular-nums;
}
.holdings-table { width: 100%; }
.holdings-table th, .holdings-table td { padding: 10px 14px; }
.holdings-table th { font-weight: 600; color: var(--text-secondary); }
.holdings-table td.num,
.holdings-table th.num { text-align: right; font-variant-numeric: tabular-nums; }
.holdings-table td.ticker { font-weight: 600; }

/* Distance-to-stop column — red accent when within 2% (the trailing-stop
   ratchet is 8pp wide, so ≤2% means a swing day could trigger). */
.holdings-dist { color: var(--text); }
.holdings-dist-warn {
  color: #B83232;
  font-weight: 600;
}

.holdings-empty {
  padding: 24px;
  text-align: center;
  color: var(--text-tertiary);
  font-size: 13px;
}

/* Holdings chart — one Lightweight Charts panel; height fills the panel
   body in the backtest tab and uses a fixed comfortable height in the
   standalone paper/live card. */
.holdings-chart {
  width: 100%;
  height: 360px;
  min-height: 240px;
}
.ctab-panel .holdings-chart { height: auto; flex: 1; min-height: 240px; }

/* Market-regime block strip below the holdings chart — mirrors the main
   chart's #regime-strip. Painted by chart.js as DOM spans aligned to the
   holdings chart's time scale. */
.holdings-regime-strip {
  position: relative;
  height: 22px;
  margin: 4px 14px 0;
  border-radius: 4px;
  overflow: hidden;
  border: 1px solid var(--border);
}
.holdings-regime-strip[hidden], .holdings-regime-strip:empty { display: none; }
.ctab-panel .holdings-card {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}

/* Zone A — pinned "right now" card. Promotes the previously-flat footer
   row so the family's first answer ("what do I own, am I near a stop")
   is above the chart, not below it. Cash state collapses to a single
   muted row. */
.holdings-now {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 10px 18px;
  border-bottom: 1px solid var(--border-subtle, rgba(0,0,0,.06));
  background: var(--surface-elev, #FAFBFC);
}
.holdings-now-row {
  display: grid;
  grid-template-columns: 14px minmax(110px, 1fr) auto auto auto;
  align-items: center;
  gap: 14px;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}
.holdings-now-dot {
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--text-tertiary);
}
.holdings-now-dot.is-cash { background: #9AA0AC; }
.holdings-now-ident { display: flex; flex-direction: column; line-height: 1.15; }
.holdings-now-ticker { font-weight: 700; font-size: 14px; }
.holdings-now-shares { font-size: 11.5px; color: var(--text-secondary); }
.holdings-now-mark { font-weight: 600; }
.holdings-now-stop { color: var(--text-secondary); }
.holdings-now-stop-label {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em;
  margin-right: 4px; color: var(--text-tertiary);
}
.holdings-now-buffer {
  font-weight: 600; text-align: right;
}
.holdings-now-buffer.is-warn { color: #B83232; }
.holdings-now[data-state="cash"] .holdings-now-row { grid-template-columns: 14px 1fr; }
.holdings-now-cash .holdings-now-ticker { color: var(--text-secondary); font-weight: 600; }

/* Lane chart — four lanes (Slot 1/2/3 + Cash) inside a horizontal-scroll
   viewport. Inner ``.holdings-lanes`` is widened by --lane-zoom; the outer
   ``.holdings-lanes-scroll`` provides the scrollbar. Each slot lane has up
   to N sub-rows; bars are JS-packed so tight swaps don't collide. The
   left label rail is sticky so it survives the horizontal scroll. */
.holdings-lanes-shell {
  border-top: 1px solid var(--border-subtle, rgba(0,0,0,.06));
  padding: 6px 18px 12px;
  position: relative;
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}
/* Slice nav — replaces the broken granularity toggle. Prev/next walk
   the active slice (one quarter at a time) through the year/era window. */
.holdings-slice-nav {
  display: flex;
  align-items: stretch;
  justify-content: center;
  gap: 8px;
  padding: 8px 0 10px;
}
.holdings-slice-nav[hidden] { display: none; }
.holdings-slice-btn {
  width: 36px;
  height: 32px;
  border: 1px solid var(--border, rgba(0,0,0,0.12));
  border-radius: 6px;
  background: var(--surface-elev, #ffffff);
  font-size: 18px;
  font-weight: 600;
  line-height: 1;
  color: var(--text-secondary);
  cursor: pointer;
}
.holdings-slice-btn:hover:not(:disabled) {
  background: #f5f6f8;
  color: var(--text);
}
.holdings-slice-btn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}
.holdings-slice-pill {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-width: 160px;
  padding: 2px 18px;
  border: 1px solid var(--border, rgba(0,0,0,0.12));
  border-radius: 6px;
  background: var(--surface-elev, #ffffff);
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
}
.holdings-slice-label {
  font-size: 13.5px;
  font-weight: 700;
  color: var(--text);
}
.holdings-slice-range {
  font-size: 10.5px;
  color: var(--text-tertiary);
}
.holdings-lanes-controls {
  display: none;  /* legacy grain toggle — kept only to swallow if a
                     stale partial briefly shows it after deploy. */
}
.holdings-grain {
  display: inline-flex;
  border: 1px solid var(--border, rgba(0,0,0,0.12));
  border-radius: 6px;
  overflow: hidden;
  background: var(--surface-elev, #ffffff);
}
.holdings-grain-btn {
  padding: 4px 12px;
  background: transparent;
  border: 0;
  border-right: 1px solid var(--border, rgba(0,0,0,0.08));
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--text-secondary);
  cursor: pointer;
}
.holdings-grain-btn:last-child { border-right: 0; }
.holdings-grain-btn:hover { background: #f5f6f8; color: var(--text); }
.holdings-grain-btn.is-active {
  background: var(--accent, #2563eb);
  color: #ffffff;
}
/* Hover tooltip — JS-positioned, anchored to the shell so horizontal
   scrolling doesn't detach it from the cursor. Cash variant collapses
   bucket + price rows. */
.holdings-lane-tip {
  position: absolute;
  min-width: 200px;
  padding: 8px 10px;
  background: #1f2937;
  color: #f3f4f6;
  border-radius: 6px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.18);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
  z-index: 50;
  line-height: 1.35;
}
.holdings-lane-tip[hidden] { display: none; }
.holdings-lane-tip-head {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 4px;
}
.holdings-lane-tip-dot {
  width: 10px; height: 10px; border-radius: 50%;
  background: #6B7A8F;
  flex: 0 0 auto;
}
.holdings-lane-tip-tk { font-weight: 700; font-size: 13px; }
.holdings-lane-tip-bucket {
  margin-left: auto;
  font-size: 10.5px;
  color: #9ca3af;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.holdings-lane-tip-dates {
  color: #9ca3af;
  font-size: 11px;
  margin-bottom: 6px;
}
.holdings-lane-tip-grid {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 2px 12px;
}
.holdings-lane-tip-k {
  color: #9ca3af;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 10.5px;
}
.holdings-lane-tip-return.is-up   { color: #4ade80; font-weight: 600; }
.holdings-lane-tip-return.is-down { color: #f87171; font-weight: 600; }
.holdings-lane-tip.is-cash .holdings-lane-tip-bucket,
.holdings-lane-tip.is-cash .holdings-lane-tip-grid { display: none; }
.holdings-lanes-toolbar {
  display: flex; align-items: center;
  gap: 6px;
  padding: 4px 0 8px;
}
.holdings-zoom-btn {
  width: 28px; height: 24px;
  padding: 0;
  border: 1px solid var(--border, rgba(0,0,0,0.12));
  background: var(--surface-elev, #ffffff);
  border-radius: 4px;
  font-size: 13px; font-weight: 600; line-height: 1;
  color: var(--text-secondary);
  cursor: pointer;
}
.holdings-zoom-btn[data-zoom="fit"] {
  width: auto;
  padding: 0 8px;
  font-size: 10.5px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.holdings-zoom-btn:hover { background: #f5f6f8; color: var(--text); }
.holdings-zoom-hint {
  margin-left: 8px;
  font-size: 10.5px;
  color: var(--text-tertiary);
}
.holdings-lanes-scroll {
  position: relative;
  overflow-x: auto;
  overflow-y: hidden;
  cursor: grab;
  flex: 1;
  min-height: 0;
}
.holdings-lanes-scroll.is-panning { cursor: grabbing; user-select: none; }
.holdings-lanes {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 100%;
  width: calc(100% * var(--lane-zoom, 1));
  height: 100%;
  padding-bottom: 4px;
}
.holdings-lane {
  display: grid;
  grid-template-columns: 14px 1fr;
  align-items: stretch;
  gap: 10px;
  /* Bucket lanes flex-fill the remaining height (3 buckets share the
     panel space) while honoring sub-rows as a min for tight swap eras. */
  flex: 1;
  /* Each sub-row is exactly var(--sub-row-h) tall; lane fits sub-rows
     exactly (no trailing empty band that reads as a phantom row). */
  min-height: calc(var(--sub-row-h, 22px) * var(--sub-rows, 2) + 4px);
}
.holdings-lane[data-kind="cash"] {
  flex: 0 0 28px;
  min-height: 28px;
}
/* Color chip — replaces the previous text label rail. The full GICS
   name lives in the chip's title attribute so power-users can still
   surface the taxonomy on hover; the family-level audience just keys on
   the color. */
.holdings-lane-chip {
  width: 6px;
  border-radius: 3px;
  margin: 4px 0;
  background: #6B7A8F;
  cursor: help;
}
/* Cash row's chip is visually distinct from its bar: a thin solid grey
   pill rather than the bar's striped fill. Without this, the chip and
   bar both render as 45° stripes and visually merge — readers think the
   chip is hiding the "C" of "Cash". */
.holdings-lane[data-kind="cash"] .holdings-lane-chip {
  background: #9AA0AC;
  opacity: 0.6;
}
.holdings-lane-chip-axis { background: transparent; }
.holdings-lane-track {
  position: relative;
  background: rgba(0,0,0,0.03);
  border-radius: 4px;
  overflow: hidden;
}
/* Granularity gridlines — drawn at the active interval (month / quarter
   / year). Year boundaries get a heavier stroke so a multi-year window
   still reads correctly when grain is set to Quarter or Month. */
.holdings-lane-grid {
  position: absolute;
  top: 0; bottom: 0;
  width: 1px;
  background: rgba(0,0,0,0.06);
  pointer-events: none;
}
.holdings-lane-grid.is-year {
  background: rgba(0,0,0,0.14);
  width: 1px;
}
.holdings-lane-bar {
  --bar-color: #6B7A8F;
  --sub-row: 0;
  /* Percent-based positioning so the 3 sub-rows always fill the bucket
     lane evenly — fixed-pixel math left a phantom empty band at the
     bottom when the lane flex-grew to claim panel space. */
  position: absolute;
  top: calc(var(--sub-row) * (100% / 3) + 3px);
  height: calc(100% / 3 - 6px);
  background: color-mix(in srgb, var(--bar-color) 28%, #ffffff);
  border-left: 3px solid var(--bar-color);
  border-radius: 3px;
  padding: 0 6px;
  display: flex; align-items: center; gap: 6px;
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  overflow: hidden;
  white-space: nowrap;
  cursor: default;
  transition: box-shadow 120ms ease;
}
.holdings-lane-bar:hover {
  box-shadow: 0 0 0 1px var(--bar-color);
  z-index: 2;
}
.holdings-lane-bar.is-open {
  box-shadow: 0 0 0 1px var(--bar-color);
}
.holdings-lane-bar.is-cash {
  --bar-color: #9AA0AC;
  /* Cash lane is single-row, so override the bucket-lane percentage math
     and let the bar fill its own track. */
  top: 3px;
  height: calc(100% - 6px);
  background: repeating-linear-gradient(
    45deg,
    color-mix(in srgb, #9AA0AC 18%, #ffffff) 0,
    color-mix(in srgb, #9AA0AC 18%, #ffffff) 6px,
    color-mix(in srgb, #9AA0AC 26%, #ffffff) 6px,
    color-mix(in srgb, #9AA0AC 26%, #ffffff) 12px
  );
  border-left-color: #9AA0AC;
}
.holdings-lane-tk { font-weight: 700; }
.holdings-lane-ret { font-weight: 600; }
.holdings-lane-bar.is-up .holdings-lane-ret { color: #1B7F3A; }
.holdings-lane-bar.is-down .holdings-lane-ret { color: #B83232; }
/* Hide the return when the bar is narrower than ~50px — the title attr
   still surfaces full details on hover. */
.holdings-lane-bar { container-type: inline-size; }
@container (max-width: 60px) {
  .holdings-lane-ret { display: none; }
}
@container (max-width: 30px) {
  .holdings-lane-tk { display: none; }
}
/* Bottom axis row — month ticks + labels. Shares the lane grid columns
   so the labels align under the bars above. */
.holdings-lane-axis {
  display: grid;
  grid-template-columns: 14px 1fr;
  gap: 10px;
  height: 22px;
  margin-top: 2px;
  flex: 0 0 22px;
}
.holdings-lane-axis-strip {
  position: relative;
  border-top: 1px solid var(--border-subtle, rgba(0,0,0,.08));
}
.holdings-lane-axis-tick {
  position: absolute;
  top: 0;
  width: 1px;
  height: 4px;
  background: var(--border, rgba(0,0,0,0.15));
}
.holdings-lane-axis-label {
  position: absolute;
  top: 6px;
  transform: translateX(-50%);
  font-size: 10.5px;
  color: var(--text-tertiary);
  font-variant-numeric: tabular-nums;
}
.holdings-lane-axis-label.is-year {
  font-weight: 700;
  color: var(--text-secondary);
}

/* Strategy tab — long-form, scrollable technical doc. The tab body is a
   flex column that grows to fill the card; the article inside scrolls. */
.ctab-panel-body.strategy-doc {
  overflow-y: auto;
  padding: 0;
}
.strategy-doc-article {
  padding: var(--space-3) var(--space-4);
  max-width: 760px;
  margin: 0 auto;
  line-height: 1.55;
  color: var(--text);
}
.strategy-doc-header h2 {
  margin: 0 0 var(--space-2);
  font-size: 22px;
}
.strategy-doc-lede {
  margin: 0 0 var(--space-4);
  color: var(--text-secondary);
}
.strategy-doc-section { margin: var(--space-4) 0; }
.strategy-doc-section h3 {
  margin: 0 0 var(--space-2);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-secondary);
}
.strategy-doc-dl { margin: 0; }
.strategy-doc-dl dt {
  margin-top: var(--space-3);
  font-weight: 600;
  color: var(--text);
}
.strategy-doc-dl dt code {
  margin-left: 10px;
  padding: 3px 8px;
  font-size: 13px;
  font-weight: 700;
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, var(--bg));
  border: 1px solid color-mix(in srgb, var(--accent) 35%, var(--border));
  border-radius: var(--radius-sm);
  letter-spacing: 0.01em;
}
.strategy-doc-dl dd {
  margin: 4px 0 0;
  color: var(--text-secondary);
}
.strategy-doc-dl dd code {
  padding: 1px 5px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 3px;
}

/* ----- rich per-day tooltip (Holdings group, mini stop→HHV bars,
   alloc %, Bear-Gate-Closed footer, Backtested/Live sample badge) ----- */
.tt-sample {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 7px;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  vertical-align: middle;
}
.tt-sample-backtested {
  background: #EEF2FA;
  color: #3457B2;
}
.tt-sample-live {
  background: #E7F8EE;
  color: #1B7F3A;
}
.tt-holdings {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 2px;
}
.tt-holding {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 6px 8px;
  border-radius: 8px;
  background: var(--surface-elev, #F5F6F8);
}
/* Open-slot + cash rows share the holding row's footprint exactly — only
   the pill colouring and the muted bar/value distinguish them. */
.tt-holding-empty .tt-bar { background: #ECEEF2; }
.tt-val-empty { color: var(--text-tertiary); }
.tt-pill-empty {
  background: #ECEEF2 !important;
  color: var(--text-tertiary) !important;
  font-style: italic;
}
.tt-pill-empty .ps-tk-sym,
.tt-pill-empty .ps-tk-sub { color: var(--text-tertiary); }
.tt-pill-cash {
  background: #6C7480 !important;
  color: #fff !important;
  letter-spacing: 0.06em;
}
/* Three-row holding card: top = pill (full ticker + shares, no clip),
   mid = allocation bar + alloc %, bot = $ value + % growth. */
.tt-holding-top {
  display: flex;
  align-items: center;
  min-width: 0;
}
.tt-holding-pill {
  flex: 0 1 auto;
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
  padding: 3px 9px;
  gap: 5px;
}
.tt-holding-pill .ps-tk-sym { font-size: 13px; }
.tt-holding-pill .ps-tk-sub {
  font-size: 11px;
  white-space: nowrap;
}
/* Share count sits to the right of the ticker pill, plain text. The
   pill keeps its color identity; the share count is muted secondary
   text so the ticker is the dominant element. */
.tt-holding-shares {
  margin-left: 8px;
  font-family: var(--font-num);
  font-size: 11.5px;
  font-weight: 600;
  color: var(--text-secondary);
  white-space: nowrap;
}
.tt-holding-mid {
  display: flex;
  align-items: center;
  gap: 8px;
}
.tt-holding-bot {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}
.tt-holding-val {
  font-family: var(--font-num);
  font-size: 13px;
  font-weight: 700;
  color: var(--text);
  white-space: nowrap;
  text-align: left;
}
.tt-holding-growth {
  font-family: var(--font-num);
  font-weight: 700;
  white-space: nowrap;
  text-align: right;
}
.tt-holding-growth .ps-num { font-size: 12px; }
.tt-bar {
  position: relative;
  flex: 1 1 auto;
  height: 8px;
  border-radius: 4px;
  background: #E1E4EA;
  overflow: hidden;
}
.tt-bar-fill {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  border-radius: 4px;
  transition: width 120ms ease-out;
}
.tt-alloc {
  flex: 0 0 auto;
  font-family: var(--font-num);
  font-size: 11px;
  font-weight: 700;
  color: var(--text-secondary);
  white-space: nowrap;
  min-width: 30px;
  text-align: right;
}
/* .tt-cash-band retired — cash now renders as a full tt-holding row. */
.tt-bear-footer {
  margin: 10px 0 0;
  padding: 6px 10px;
  border-radius: 6px;
  background: #FDECEA;
  color: #B02A22;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-align: center;
}

/* ----- sidebar header pills + alpha line + accordions ----- */
.tt-header-pills {
  margin: 4px 0 0;
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.tt-regime {
  display: inline-block;
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.tt-regime-bull {
  background: #E7F8EE;
  color: #1B7F3A;
}
.tt-regime-bear {
  background: #FDECEA;
  color: #B02A22;
}
.tt-alpha-line {
  margin-top: 6px;
  font-family: var(--font-num);
  font-size: 13px;
  font-weight: 700;
}
.tt-alpha-line .ps-num { font-size: 14px; }
.tt-alpha-sub {
  font-size: 12px;
  color: var(--text-secondary);
  font-weight: 600;
}
.tt-alpha-sub .ps-num { font-size: 12px; }
.tt-acc {
  margin-top: 8px;
  border-top: 1px solid var(--divider);
}
.tt-acc-sec {
  border-bottom: 1px solid var(--divider);
}
.tt-acc-head {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  padding: 8px 4px;
  background: transparent;
  border: 0;
  cursor: pointer;
  text-align: left;
  font: inherit;
  color: var(--text-tertiary);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  transition: background-color 80ms;
}
.tt-acc-head:hover {
  background: rgba(0, 0, 0, 0.03);
}
.tt-acc-chev {
  display: inline-block;
  width: 10px;
  text-align: center;
  transition: transform 120ms ease-out;
  font-size: 14px;
  color: var(--text-tertiary);
}
.tt-acc-sec.is-open .tt-acc-chev {
  transform: rotate(90deg);
}
.tt-acc-sec.is-open .tt-acc-head {
  color: var(--text);
}
.tt-acc-body {
  max-height: 0;
  overflow: hidden;
  transition: max-height 160ms ease-out;
}
.tt-acc-sec.is-open .tt-acc-body {
  max-height: 600px;
  padding: 0 4px 8px;
}
.tt-empty {
  padding: 4px 0;
  font-size: 12px;
  color: var(--text-tertiary);
  font-style: italic;
}
.tt-trades-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.tt-trade-row {
  padding: 6px 8px;
  border-radius: 6px;
  background: var(--surface-elev, #F5F6F8);
  font-size: 12px;
}
.tt-trade-row b { color: var(--text); }
.tt-trade-tag {
  display: inline-block;
  margin-left: 4px;
  padding: 0 6px;
  border-radius: 4px;
  background: #ECEEF2;
  color: var(--text-secondary);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  vertical-align: middle;
}
.tt-trade-date {
  margin-left: 6px;
  color: var(--text-tertiary);
  font-weight: 500;
}
.tt-trade-sub {
  margin-top: 2px;
  font-family: var(--font-num);
  font-size: 11px;
  color: var(--text-secondary);
}

.tt-acc-link {
  display: block;
  width: 100%;
  margin-top: 8px;
  padding: 6px 8px;
  background: transparent;
  border: 1px solid var(--divider);
  border-radius: 6px;
  color: var(--text-secondary);
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
  text-align: center;
}
.tt-acc-link:hover {
  background: rgba(0, 0, 0, 0.03);
  color: var(--text);
}

/* ===== floating per-day card (pinned to chart's top-left) ===== */
.day-card {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: 6;
  /* Fixed width — same regardless of date string length, sample badge
     variant, or regime pill text. Prevents the chevron from drifting
     horizontally between hovers (muscle memory). */
  width: 220px;
  background: rgba(255, 255, 255, 0.96);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 2px 8px rgba(15, 23, 42, 0.08);
  pointer-events: auto;
  backdrop-filter: blur(6px);
}
.day-card:empty { display: none; }
.day-card-chip {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 8px 32px 8px 10px;  /* right pad reserves chevron column */
}
.day-card-row {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}
.day-card-row-tags { font-size: 11px; }
.day-card-date {
  font-weight: 600;
  color: var(--text-secondary);
  font-size: 11px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.day-card-date .tt-sample { margin-left: 4px; }
.day-card-row-regime { font-size: 11px; }
.day-card-nav {
  font-family: var(--font-num);
  font-weight: 700;
  font-size: 18px;
  color: var(--text);
  line-height: 1.1;
  white-space: nowrap;
}
.day-card-row-metrics {
  gap: 12px;
  margin-top: 2px;
}
.day-card-metric {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  font-family: var(--font-num);
}
.day-card-metric .ps-num { font-size: 12px; font-weight: 700; }
.day-card-mini-label {
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-tertiary);
  font-weight: 700;
}
.day-card-toggle {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: transparent;
  border: 0;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
  color: var(--text-secondary);
  font-family: inherit;
  z-index: 2;
}
.day-card-toggle:hover { background: rgba(0, 0, 0, 0.04); color: var(--text); }
.day-card-body {
  padding: 8px 10px 10px;
  border-top: 1px solid var(--divider);
}
.day-card-grp {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-tertiary);
  margin: 8px 0 4px;
}
.day-card-grp:first-child { margin-top: 0; }
.day-card[data-state="collapsed"] .day-card-body { display: none; }
/* Compact holdings rows inside the 220px-wide card — drop the heavy
   per-row padding and stack pill atop value to fit narrow width. */
.day-card-body .tt-holding {
  padding: 4px 6px;
  gap: 2px;
}
.day-card-body .tt-holding-pill { max-width: 100%; padding: 2px 7px; }
.day-card-body .tt-holding-val { font-size: 11px; }
.day-card-body .tt-holding-val .ps-num { font-size: 10.5px; }
.day-card-body .tt-alloc { font-size: 10px; }
.day-card-body .ps-row { padding: 2px 0; font-size: 11px; }
.day-card-body .ps-label { font-size: 11px; }
.day-card-body .ps-num { font-size: 12px; }
.day-card-body .ps-sub { font-size: 10px; }

/* Period sidebar — flat (no accordions) */
.period-scope {
  display: flex;
  flex-direction: column;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-tertiary);
  font-weight: 700;
}
.period-scope-sub {
  margin-top: 2px;
  font-size: 11px;
  text-transform: none;
  letter-spacing: 0;
  color: var(--text-secondary);
  font-weight: 500;
}
.period-headline {
  margin-top: 4px;
  display: flex;
  flex-direction: column;
  gap: 1px;
  font-family: var(--font-num);
}
.period-headline .ps-num {
  font-size: 22px;
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.01em;
}
.period-headline-label {
  font-size: 12px;
  color: var(--text-secondary);
  font-family: var(--font-sans, inherit);
}
.period-rows { margin-top: 8px; }

/* Two-up best/worst mini-cards inside the period sidebar. Each tile has a
   small label, the big signed %, an optional ticker badge, and a muted
   date/year footer that always carries the year when the active scope
   spans more than one calendar year. */
.ps-tile-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
  margin: 2px 0 4px;
}
.ps-tile {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 6px 8px;
  background: var(--surface-elev, rgba(0,0,0,0.025));
  border: 1px solid var(--border, rgba(0,0,0,0.08));
  border-radius: 6px;
  min-width: 0;
}
.ps-tile-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  white-space: nowrap;
  display: flex;
  align-items: center;
}
.ps-tile-val {
  font-size: 15px;
  font-weight: 700;
  line-height: 1.1;
  font-family: var(--font-num, inherit);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  letter-spacing: -0.01em;
}
.ps-tile-val.is-empty { color: var(--text-tertiary); font-weight: 500; }
.ps-tile-ticker {
  font-size: 12px;
  font-weight: 700;
  color: var(--text-primary);
  letter-spacing: 0.02em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ps-tile-sub {
  font-size: 11px;
  color: var(--text-tertiary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Symbol-toggles dropdown in the sidebar — sits above #chart-legend with
   a small bottom margin so it visually groups with the period content. */
.symbol-toggles-side {
  margin-bottom: 10px;
}

/* ===== three-column pivot ===== */
.chart-side-left {
  width: 256px;
  flex-shrink: 0;
}
.chart-side-right {
  /* Same height/scroll behaviour as the legacy single sidebar so the day
     card doesn't stretch the chart card when the body is long. */
  width: 240px;
  flex-shrink: 0;
}

/* Year strip — vertical layout in the left sidebar. Override the
   horizontal flex/grid the top-of-page version uses. !important
   beats the original `display: grid` rule on .regime-row / .year-row
   which uses --ycols for horizontal layout. */
.chart-side-left .year-strip {
  display: flex !important;
  flex-direction: column !important;
  align-items: stretch !important;
  margin: 0;
  padding: 0;
  background: transparent;
  border: 0;
  gap: 8px;
}
.chart-side-left .year-strip-grid {
  display: flex !important;
  flex-direction: column !important;
  flex: 0 0 auto !important;
  width: 100% !important;
  min-width: 0 !important;
  gap: 6px;
}
.chart-side-left .regime-row,
.chart-side-left .year-row {
  display: flex !important;
  flex-direction: column !important;
  gap: 4px !important;
  grid-template-columns: none !important;
  width: 100% !important;
  margin: 0 !important;
}
.chart-side-left .regime-tile,
.chart-side-left .year-tile {
  width: 100% !important;
  grid-column: auto !important;
  display: flex !important;
  flex-direction: row !important;
  align-items: center !important;
  justify-content: space-between !important;
  height: auto !important;
  min-height: 28px;
  padding: 5px 24px 5px 8px !important;
  text-align: left;
}
.chart-side-left .rg-name,
.chart-side-left .yt-year {
  font-size: 11.5px;
  text-align: left;
}
.chart-side-left .rg-cagr,
.chart-side-left .yt-return {
  font-family: var(--font-num);
  font-size: 11px;
  font-weight: 700;
  white-space: nowrap;
}
.chart-side-left .rg-info {
  position: absolute;
  right: 4px;
  top: 50%;
  transform: translateY(-50%);
}
.chart-side-left .all-tile {
  width: 100% !important;
  align-self: stretch !important;
  margin-top: 0;
  padding: 8px 10px !important;
  text-align: center;
}

/* Docked day card — flush with the sidebar, no container outline. The
   sidebar itself is the visual frame; nesting a bordered card inside
   would create a double-frame look. */
.day-card-docked {
  position: static;
  width: 100%;
  background: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  backdrop-filter: none;
}
/* Hide the chevron toggle inside the docked card — the body is now
   always-visible, no expand/collapse affordance needed. */
.day-card-docked .day-card-toggle { display: none; }
.day-card-docked .day-card-chip { padding: 0; }
.day-card-docked .day-card-body {
  padding: 0;
  border-top: 0;
  margin-top: 10px;
}
/* Match left-sidebar typography exactly so the two columns read as one
   coherent surface, not two competing cards. Group headings, row labels,
   row values, and section spacing all line up. */
.day-card-docked .day-card-grp {
  font-size: 12px;
  letter-spacing: 0.07em;
  margin: 12px 0 4px;
}
.day-card-docked .day-card-grp:first-child { margin-top: 0; }
.day-card-docked .ps-row { padding: 4px 0; }
.day-card-docked .ps-label { font-size: 13px; }
.day-card-docked .ps-num { font-size: 15px; }
.day-card-docked .ps-sub { font-size: 11px; }
/* Day card chip rows — bring NAV hero to the same scale as the left
   sidebar's hero. */
.day-card-docked .day-card-nav { font-size: 22px; }
.day-card-docked .day-card-date { font-size: 13px; }
.day-card-docked .day-card-row-tags,
.day-card-docked .day-card-row-regime { font-size: 13px; }
.day-card-docked .day-card-metric .ps-num { font-size: 13px; }
.day-card-docked .day-card-mini-label { font-size: 10px; }

/* ============================================================================
   Cross-cutting a11y + responsive polish (2026-05-25)
   - Keyboard focus is visible against the dark appbar.
   - Touch targets meet WCAG 2.5.5 minimums on phones.
   - Honour user preference for reduced motion.
   - Collapse the appbar to a compact top strip on narrow phones so the
     content column doesn't lose ~62px to a fixed rail.
   ========================================================================== */

/* Brighter focus ring on the dark sidebar (the default accent doesn't carry
   enough contrast against #2A2E35). */
.appbar-icon:focus-visible,
.mode-btn:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
  border-radius: var(--radius);
}

/* Honour OS-level "reduce motion" — kill the toast slide + icon hover
   transitions so vestibular-sensitive users don't get jolted. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* Phone breakpoint — appbar becomes a top strip, brand collapses to the
   horse glyph, content goes edge-to-edge. Below 480px the previous layout
   reserved ~70px of horizontal space for chrome that wasn't earning it. */
@media (max-width: 600px) {
  .shell { flex-direction: column; }
  .appbar {
    position: sticky;
    top: 0;
    width: auto;
    height: auto;
    margin: 0;
    padding: 8px 10px;
    flex-direction: row;
    align-items: center;
    gap: 12px;
    border-radius: 0;
    border-left: none;
    border-right: none;
    border-top: none;
  }
  .appbar-modes { flex-direction: row; }
  .appbar-brand {
    margin-top: 0;
    margin-left: auto;
    flex-direction: row;
    align-items: center;
    gap: 8px;
  }
  .appbar-horse { width: 28px; }
  .appbar-wordmark {
    writing-mode: horizontal-tb;
    transform: none;
    font-size: 15px;
    letter-spacing: 0.12em;
  }
  /* Tooltip would clip off the top of the viewport — suppress on touch. */
  .appbar-icon::after { display: none; }
  .content { padding: 14px; padding-bottom: 28px; }
}

/* Tablet / small-laptop polish — keeps the rail but tightens the content
   padding so the chart card isn't crowded against the right edge on
   ~768-980px viewports. */
@media (max-width: 980px) and (min-width: 601px) {
  .content { padding: var(--space-3) var(--space-3) var(--space-4) 0; }
}

/* ============================================================== */
/* /account + /admin + inbox — settings-page scale                 */
/* ============================================================== */
/* Density target: modern fintech admin (Stripe / Mercury / Linear).
   Scope is the .settings-page wrapper so the dashboard's 18px
   baseline is untouched. Body floor 13px; touch targets stay ≥32px
   on desktop, restored to ≥44px on mobile via the media query at
   the bottom. The canonical .btn (line 1600) handles the global
   button — settings only overrides padding/font-size, never colours. */

/* Left-rail avatar chip (global — sits outside the settings wrapper). */
.appbar-avatar {
  margin-top: auto;
  margin-bottom: var(--space-3);
  display: flex;
  justify-content: center;
  text-decoration: none;
  color: inherit;
}
.appbar-brand { margin-top: 0; }
.avatar-chip {
  width: 28px; height: 28px;
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--surface-2, #eef0f3);
  color: var(--ink-1, #111);
  font-weight: 600;
  font-size: 12.5px;
  letter-spacing: 0.02em;
  border: 1px solid var(--border-1, #d4d8de);
  transition: transform 120ms ease, background 120ms ease;
}
.appbar-avatar:hover .avatar-chip {
  background: var(--surface-1, #fff);
  transform: scale(1.05);
}

/* The settings-page wrapper sets the smaller baseline + content cap. */
.settings-page {
  font-size: 13px;
  line-height: 1.45;
  max-width: 780px;
  margin-left: 0;
}
.settings-page .page-head { margin-bottom: 12px; }
.settings-page .page-title { font-size: 20px; font-weight: 600; line-height: 1.3; margin: 0 0 2px; }
.settings-page .page-sub { font-size: 13px; margin: 0 0 12px; color: var(--ink-2, #475569); }

/* Cards — tight padding, tight inter-card spacing. */
.settings-page .card,
.settings-page .account-card,
.settings-page .admin-card { padding: 16px 18px; margin-bottom: 12px; }
.settings-page .card-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }
.settings-page .card-head h2 {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-2, #475569);
  margin: 0;
}
.settings-page .card-intro { margin: 0 0 10px; color: var(--ink-2, #475569); font-size: 13px; }

/* Section TOC strip at /account top. */
.account-toc {
  display: flex; flex-wrap: wrap;
  gap: 14px;
  padding: 4px 0 10px;
  border-bottom: 1px solid var(--border-1, #e3e6ea);
  margin-bottom: 14px;
}
.account-toc a {
  color: var(--ink-2, #475569);
  text-decoration: none;
  font-size: 12.5px;
  font-weight: 500;
}
.account-toc a:hover { color: var(--ink-1, #111); text-decoration: underline; }
.account-toc a.account-toc-cta {
  margin-left: auto;
  color: var(--ink-1, #111);
  font-weight: 600;
}
.account-toc a.account-toc-cta:hover { color: #0f172a; text-decoration: none; }

/* Read-only key/value blocks. */
.account-readonly { display: grid; grid-template-columns: max-content 1fr; gap: 4px 16px; margin: 0 0 10px; }
.account-readonly dt {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: 600;
  color: var(--ink-2, #475569);
  align-self: center;
}
.account-readonly dd { margin: 0; font-size: 13px; }

/* Inline forms. */
.account-form { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin: 8px 0 0; }
.account-form label { font-weight: 500; min-width: 120px; font-size: 13px; }
.settings-page input[type="text"],
.settings-page input[type="email"],
.settings-page select {
  min-width: 14rem;
  min-height: 32px;
  padding: 6px 10px;
  font-size: 13px;
  border: 1px solid var(--border-1, #d4d8de);
  border-radius: 6px;
  font-family: inherit;
  background: var(--surface-1, #fff);
}
.account-form-actions { display: flex; align-items: center; gap: 8px; flex-basis: 100%; margin-top: 6px; }

/* Toggle + radio cards. */
.account-toggles { flex-direction: column; align-items: stretch; gap: 8px; }
.account-radios { flex-direction: column; align-items: stretch; gap: 8px; }
.toggle, .radio-card {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 4px 10px;
  align-items: start;
  padding: 10px 12px;
  border: 1px solid var(--border-1, #e3e6ea);
  border-radius: 8px;
  cursor: pointer;
}
.toggle:hover, .radio-card:hover { background: var(--surface-2, #f7f8fa); }
.toggle input, .radio-card input { margin-top: 2px; }
.toggle-label, .radio-title { font-weight: 600; font-size: 13px; }
.toggle .muted, .radio-card .muted { grid-column: 2; color: var(--ink-2, #475569); font-size: 12px; line-height: 1.45; }

/* Buttons — only override padding + font on the canonical .btn within
   settings; never touch global .btn so the dashboard stays intact. */
.settings-page .btn {
  min-height: 32px;
  padding: 6px 12px;
  font-size: 13px;
  font-weight: 500;
  border-radius: 6px;
  border: 1px solid var(--border-1, #d4d8de);
  background: var(--surface-1, #fff);
  cursor: pointer;
}
.settings-page .btn:hover { background: var(--surface-2, #f7f8fa); }
.settings-page .btn-primary { background: #0f172a; color: #fff; border-color: #0f172a; }
.settings-page .btn-primary:hover { background: #1e293b; }
.settings-page .btn-danger { background: #fff; color: #b91c1c; border-color: #fecaca; }
.settings-page .btn-danger:hover { background: #fef2f2; }
.settings-page .btn-sm { min-height: 28px; padding: 4px 10px; font-size: 12px; }

/* Flash slot — sits next to a button after an HTMX swap. */
.flash-slot { min-width: 6rem; }
.flash { font-size: 12px; padding: 2px 8px; border-radius: 4px; }
.flash-ok { background: #e8f6ec; color: #1f6f3e; }

/* Role badge — compact status chip. */
.role-badge {
  display: inline-block;
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 2px 8px;
  border-radius: 999px;
  background: #fef3c7;
  color: #92400e;
}
.role-admin { background: #fde68a !important; color: #78350f !important; }

/* /admin banner — compact when healthy, opens up only on warning. */
.admin-banner {
  padding: 10px 14px;
  border-radius: 8px;
  border: 1px solid var(--border-1, #e3e6ea);
  background: #f0fdf4;
  margin-bottom: 10px;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px 12px;
  font-size: 13px;
}
.admin-banner h2 {
  margin: 0;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: inherit;
}
.admin-banner p { margin: 0; }
.admin-banner ul { margin: 4px 0 0; padding-left: 1.25em; font-size: 12px; }
.admin-banner-warn { background: #fef2f2; border-color: #fecaca; color: #7f1d1d; }

.status-dot {
  display: inline-block;
  width: 8px; height: 8px;
  border-radius: 50%;
  vertical-align: middle;
  margin-right: 4px;
}
.status-ok { background: #16a34a; }
.status-warn { background: #dc2626; }

/* Members + audit tables — flush to card edges, tight rows. */
.admin-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.admin-table th, .admin-table td {
  text-align: left;
  padding: 8px 12px;
  border-bottom: 1px solid var(--border-1, #eaecef);
}
.admin-table th {
  font-size: 10.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ink-2, #475569);
  background: var(--surface-2, #f7f8fa);
}
.admin-table tbody tr:hover { background: var(--surface-2, #f7f8fa); }
.inline-form { display: inline-flex; align-items: center; gap: 6px; margin: 0; }

.audit-table code { font-size: 11.5px; font-family: var(--font-mono, ui-monospace, Menlo, monospace); }
.audit-table .audit-meta { max-width: 28rem; word-break: break-word; }
.audit-table .muted { color: var(--ink-2, #475569); }

/* Inbox. */
.settings-page .inbox-page { /* uses card padding above */ }
.unread-pill {
  display: inline-block; min-width: 18px;
  padding: 1px 6px;
  margin-left: 6px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  background: #2563eb; color: #fff;
}
.inbox-list { list-style: none; padding: 0; margin: 10px 0 0; }
.inbox-item {
  padding: 12px 14px;
  border: 1px solid var(--border-1, #e3e6ea);
  border-radius: 8px;
  margin-bottom: 6px;
  background: var(--surface-1, #fff);
}
.inbox-item.is-unread { border-left: 3px solid #2563eb; }
.inbox-item.severity-warn { border-left: 3px solid #d97706; }
.inbox-item.severity-error,
.inbox-item.severity-critical { border-left: 3px solid #dc2626; }
.inbox-item-meta { display: flex; gap: 10px; font-size: 11.5px; margin-bottom: 4px; }
.inbox-subject { font-weight: 600; font-size: 13.5px; }
.inbox-body { margin-top: 4px; color: var(--ink-2, #475569); font-size: 13px; }
.inbox-item .inline-form { margin-top: 6px; }

/* Mobile: restore comfortable touch targets. */
@media (max-width: 720px) {
  .settings-page { max-width: none; font-size: 14px; }
  .settings-page .btn { min-height: 44px; padding: 10px 14px; font-size: 14px; }
  .settings-page .btn-sm { min-height: 36px; padding: 8px 12px; font-size: 13px; }
  .settings-page input[type="text"],
  .settings-page input[type="email"],
  .settings-page select { min-height: 44px; padding: 10px 12px; font-size: 14px; }
  .toggle, .radio-card { padding: 14px 14px; }
  .admin-table th, .admin-table td { padding: 12px 10px; }
}
