/* Institutional dashboard theme. Dense, sober, terminal-flavoured. */
:root {
  --bg-0:    #0a0f1c;
  --bg-1:    #0f1626;
  --bg-2:    #131c30;
  --panel:   #111a2c;
  --border:  #1d2a44;
  --border-2:#2c3a55;
  --text:    #d8dee9;
  --muted:   #7c879b;
  --muted-2: #586176;
  --pos:     #3fa67a;
  --neg:     #d56666;
  --accent:  #9eb8ff;
  --accent-2:#e0c87a;
  --warn:    #e0a35d;
  --crit:    #e15e5e;
  /* RGB channels for translucent tints / gradients (used by the elevation
     layer + hero bands so we can alpha-blend the palette colours). */
  --accent-rgb: 158,184,255;
  --pos-rgb:    63,166,122;
  --neg-rgb:    213,102,102;
  --warn-rgb:   224,163,93;
  --accent2-rgb:224,200,122;
  /* Layered, glow-free elevation (Bloomberg/FactSet sobriety). Tuned for the
     dark surface; the light theme overrides --panel-shadow below. */
  --panel-shadow:   0 1px 0 rgba(0,0,0,0.20), 0 2px 6px -2px rgba(0,0,0,0.35), 0 12px 28px -16px rgba(0,0,0,0.55);
  --panel-shadow-hi: 0 1px 0 rgba(0,0,0,0.22), 0 4px 10px -2px rgba(0,0,0,0.42), 0 20px 44px -18px rgba(0,0,0,0.65);
  --elev-hairline: inset 0 1px 0 rgba(255,255,255,0.035);
  /* NOTE: --ring is intentionally NOT defined here — a theme-aware --ring is
     already defined later (dark + light) and drives the focus rule below. */
}

* { box-sizing: border-box; }

html, body {
  background: var(--bg-0);
  color: var(--text);
  font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-size: 13px;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
}

.mono, .num {
  font-family: 'JetBrains Mono', 'IBM Plex Mono', 'Consolas', monospace;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}

.app-navbar {
  background: var(--bg-1);
  border-bottom: 1px solid var(--border);
  padding: 0.5rem 1rem;
  min-height: 48px;
}
.app-navbar .navbar-brand {
  font-size: 13px; font-weight: 600; color: var(--text);
  letter-spacing: 0.4px; text-transform: uppercase;
}
.app-navbar .nav-link {
  font-size: 12px; font-weight: 500; color: var(--muted);
  padding: 0.35rem 0.7rem; border-radius: 3px;
  text-transform: uppercase; letter-spacing: 0.4px;
}
.app-navbar .nav-link:hover { color: var(--text); background: var(--bg-2); }
.app-navbar .nav-link.active { color: var(--text); background: var(--bg-2); border-bottom: 2px solid var(--accent); border-radius: 3px 3px 0 0; }
.app-navbar .navbar-text { font-size: 11px; color: var(--muted); }
.status-dot { display:inline-block; width:8px; height:8px; border-radius:50%; box-shadow: 0 0 6px currentColor; }
.bg-success { background-color: var(--pos) !important; }
.bg-secondary { background-color: var(--muted-2) !important; }

main.container-fluid { padding: 16px; }

.panel {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 4px;
  overflow: hidden;
}
.panel-header {
  padding: 8px 12px;
  border-bottom: 1px solid var(--border);
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.8px;
  text-transform: uppercase; color: var(--muted);
  background: var(--bg-1);
  display: flex; justify-content: space-between; align-items: center;
}
.panel-body { padding: 12px; }
.panel-body.compact { padding: 8px; }
.panel-body.no-padding { padding: 0; }

.glass-card { background: var(--panel); border: 1px solid var(--border); border-radius: 4px; color: var(--text); }

.kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 8px;
}
.kpi-tile {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 10px 12px;
  display: flex; flex-direction: column; gap: 2px;
  position: relative;
}
.kpi-tile::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 2px; background: var(--border-2);
}
.kpi-tile.pos::before { background: var(--pos); }
.kpi-tile.neg::before { background: var(--neg); }
.kpi-tile.warn::before { background: var(--warn); }
.kpi-tile .label {
  font-size: 10px; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.6px;
}
.kpi-tile .value {
  font-family: 'JetBrains Mono', 'IBM Plex Mono', 'Consolas', monospace;
  font-size: 17px; font-weight: 600; color: var(--text);
  font-variant-numeric: tabular-nums;
}
.kpi-tile .sub {
  font-size: 10px; color: var(--muted-2);
  font-family: 'JetBrains Mono', monospace;
}
.kpi-tile.pos .value { color: var(--pos); }
.kpi-tile.neg .value { color: var(--neg); }

.chart { width: 100%; min-height: 220px; }

table.dt {
  width: 100%; border-collapse: collapse; font-size: 11.5px;
}
table.dt th {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.6px;
  color: var(--muted); font-weight: 600;
  padding: 6px 10px; border-bottom: 1px solid var(--border);
  background: var(--bg-1); text-align: left;
  position: sticky; top: 0;
}
table.dt th.r { text-align: right; }
table.dt td {
  padding: 5px 10px;
  border-bottom: 1px solid rgba(255,255,255,0.03);
  font-family: 'JetBrains Mono', 'IBM Plex Mono', 'Consolas', monospace;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
table.dt td.r { text-align: right; }
table.dt td.label-cell { font-family: 'Inter', sans-serif; }
table.dt tr:hover td { background: rgba(158,184,255,0.04); }
table.dt td.pos { color: var(--pos); }
table.dt td.neg { color: var(--neg); }

.sidebar {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 12px;
}
.sidebar h6 {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.8px;
  color: var(--muted); margin: 14px 0 8px; font-weight: 600;
}
.sidebar h6:first-child { margin-top: 0; }
.sidebar .strategy-row {
  display: flex; align-items: center; gap: 8px;
  padding: 4px 6px; border-radius: 3px;
  cursor: pointer; font-size: 11.5px;
}
.sidebar .strategy-row:hover { background: var(--bg-2); }
.sidebar .strategy-row input { accent-color: var(--accent); }
.sidebar .strategy-row .dot { width:6px; height:6px; border-radius:50%; flex-shrink:0; background: var(--accent); }

.filter-input, .filter-select {
  background: var(--bg-2);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 3px;
  padding: 4px 8px;
  font-size: 12px;
  width: 100%;
}
.filter-input:focus, .filter-select:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 1px rgba(158,184,255,0.25);
}
.filter-label {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.5px;
  color: var(--muted); margin-bottom: 3px; display: block;
}

.btn-inst {
  background: var(--bg-2); border: 1px solid var(--border); color: var(--text);
  font-size: 11px; letter-spacing: 0.4px; text-transform: uppercase;
  padding: 5px 12px; border-radius: 3px; cursor: pointer; font-weight: 500;
}
.btn-inst:hover { background: var(--bg-1); border-color: var(--border-2); }
.btn-inst.primary { background: linear-gradient(180deg, #3a6dd6, #2c52a8); border-color: #2c52a8; color: #fff; }
.btn-inst.primary:hover { filter: brightness(1.1); }
.btn-inst.success { background: linear-gradient(180deg, var(--pos), #2c8462); border-color: #2c8462; color: #fff; }
.btn-inst.ghost { background: transparent; }

.btn-success { background: linear-gradient(180deg, var(--pos), #2c8462); border: none; }
.btn-outline-light { border-color: var(--border); color: var(--text); }
.btn-outline-light:hover { background: var(--bg-2); border-color: var(--border-2); color: var(--text); }
.form-control, .form-select {
  background: var(--bg-2); border-color: var(--border); color: var(--text); font-size: 12px;
}
.form-control:focus, .form-select:focus {
  background: var(--bg-2); color: var(--text); border-color: var(--accent);
  box-shadow: 0 0 0 1px rgba(158,184,255,0.25);
}

.dash-row { display: grid; gap: 8px; margin-bottom: 8px; }
.dash-row.cols-12 { grid-template-columns: repeat(12, 1fr); }
.dash-row .span-3 { grid-column: span 3; }
.dash-row .span-4 { grid-column: span 4; }
.dash-row .span-5 { grid-column: span 5; }
.dash-row .span-6 { grid-column: span 6; }
.dash-row .span-7 { grid-column: span 7; }
.dash-row .span-8 { grid-column: span 8; }
.dash-row .span-9 { grid-column: span 9; }
.dash-row .span-12 { grid-column: span 12; }
@media (max-width: 1100px) {
  .dash-row.cols-12 > * { grid-column: span 12; }
}

.badge-inst {
  background: var(--bg-2); border: 1px solid var(--border); color: var(--muted);
  font-size: 10px; padding: 2px 6px; border-radius: 3px;
  letter-spacing: 0.3px; font-family: 'JetBrains Mono', monospace;
}
.badge-inst.pos { color: var(--pos); border-color: rgba(63,166,122,0.4); }
.badge-inst.neg { color: var(--neg); border-color: rgba(213,102,102,0.4); }

.alerts-list .alert {
  border: none; border-radius: 3px; margin-bottom: 6px;
  padding: 8px 10px; font-size: 12px;
}
.alert-info     { background: rgba(158,184,255,0.08); color: #b6c4f5; }
.alert-warning  { background: rgba(224,163,93,0.12); color: var(--warn); }
.alert-danger, .alert-critical { background: rgba(225,94,94,0.14); color: var(--crit); }

.progress { background-color: var(--bg-2); border-radius: 2px; }
.progress-bar { background: var(--accent); }

footer { color: var(--muted-2); font-size: 11px; }

::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border-2); border-radius: 2px; }
::-webkit-scrollbar-thumb:hover { background: var(--muted-2); }

.scroll-y { max-height: 380px; overflow-y: auto; }

/* Monthly returns matrix (institutional factsheet table). */
table.monthly-dt {
  font-size: 11px;
  border-collapse: separate;
  border-spacing: 1px;
  background: var(--panel);
}
table.monthly-dt th {
  font-size: 9.5px; padding: 5px 6px; min-width: 56px;
}
table.monthly-dt th.r { text-align: right; }
table.monthly-dt td {
  padding: 4px 6px;
  border-bottom: none;
  text-align: right;
  min-width: 56px;
}
table.monthly-dt td.label-cell {
  text-align: left;
  background: var(--bg-1);
  color: var(--muted);
  font-weight: 600;
}
table.monthly-dt tr:hover td { background: rgba(158,184,255,0.04); }

/* Bottom status bar. */
.status-bar {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  background: var(--bg-1);
  border-top: 1px solid var(--border);
  padding: 4px 14px;
  font-size: 10.5px;
  letter-spacing: 0.4px;
  color: var(--muted);
  display: flex;
  align-items: center;
  gap: 18px;
  z-index: 50;
  font-family: 'JetBrains Mono', 'IBM Plex Mono', 'Consolas', monospace;
}
.status-bar .status-item { display: flex; align-items: center; gap: 6px; }
.status-bar .status-item.right { margin-left: auto; }
.status-bar .status-label {
  color: var(--muted-2);
  text-transform: uppercase;
  font-size: 9.5px;
  letter-spacing: 0.6px;
}
.status-bar .status-dot { width: 7px; height: 7px; border-radius: 50%; }
.status-bar .pos { color: var(--pos); }
.status-bar .neg { color: var(--neg); }
body { padding-bottom: 30px; }

/* Sidebar refinement when there are many strategies. */
.sidebar .strategy-row .dot {
  background: var(--accent);
}
.sidebar .strategy-row input:not(:checked) ~ .dot {
  background: var(--muted-2);
  opacity: 0.5;
}

/* Active tab button (Combined / Per strategy). */
.btn-inst.ghost.active {
  background: var(--bg-2);
  border-color: var(--accent);
  color: var(--accent);
}

/* Toggle groups in panel headers. */
.toggle-group {
  display: inline-flex;
  background: var(--bg-0);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 1px;
  gap: 1px;
}
.toggle-group .btn-inst {
  border: none;
  background: transparent;
  border-radius: 2px;
  padding: 3px 8px;
  color: var(--muted);
}
.toggle-group .btn-inst:hover { color: var(--text); background: var(--bg-2); }
.toggle-group .btn-inst.active {
  background: var(--bg-2);
  color: var(--accent);
  border: none;
}
.toggle-group .btn-inst[disabled] { opacity: 0.4; cursor: not-allowed; }
.hdr-sep {
  width: 1px; height: 16px;
  background: var(--border-2);
  display: inline-block;
}

/* ---------------------------------------------------------------------------
   Dashboard upgrades: PNG export button, drill-down affordances, loading
   skeletons, status-bar pulsing dot, and the warn colour for DD %.
   --------------------------------------------------------------------------- */

/* PNG download button in chart panel headers. */
.panel-header .png-btn {
  font-size: 9.5px;
  padding: 2px 7px;
  letter-spacing: 0.5px;
  color: var(--muted);
  background: transparent;
  border: 1px solid var(--border);
  margin-left: 6px;
}
.panel-header .png-btn:hover {
  color: var(--accent);
  border-color: var(--border-2);
  background: var(--bg-2);
}
.panel-header .png-btn i { margin-right: 3px; opacity: 0.85; }

/* Drill-down info hint next to panel titles. */
.drill-hint {
  color: var(--muted-2);
  font-size: 11px;
  margin-left: 6px;
  cursor: help;
  vertical-align: middle;
  opacity: 0.7;
}
.drill-hint:hover { color: var(--accent); opacity: 1; }

/* Clickable strategy rows (drill-down to single-EA view). */
.dt.drill-table tbody tr.drill-row { cursor: pointer; }
.dt.drill-table tbody tr.drill-row:hover td {
  background: rgba(158,184,255,0.07);
}

/* Cursor hint over chart bars that drill down. */
#chartSymbols .nsewdrag { cursor: pointer !important; }

/* Loading state: fade panels containing plots and add a small spinner next
   to the panel-header text. Tables and KPI tiles stay legible. */
body.dashboard-loading .panel:has(.chart) { opacity: 0.6; transition: opacity 0.15s ease; }
body.dashboard-loading .panel-header > span:first-child::after {
  content: "";
  display: inline-block;
  width: 10px; height: 10px;
  margin-left: 8px;
  border: 1.5px solid var(--border-2);
  border-top-color: var(--accent);
  border-radius: 50%;
  vertical-align: -1px;
  animation: panel-spin 0.7s linear infinite;
}
@keyframes panel-spin {
  to { transform: rotate(360deg); }
}

/* Status-bar refinements: warn (yellow) drawdown band, and pulsing status dot
   while a refresh is in flight. */
.status-bar .warn { color: var(--warn); }
.status-bar .status-dot.pulsing {
  animation: status-pulse 1.1s ease-in-out infinite;
}
@keyframes status-pulse {
  0%   { opacity: 1.0; box-shadow: 0 0 4px currentColor; }
  50%  { opacity: 0.35; box-shadow: 0 0 10px currentColor; }
  100% { opacity: 1.0; box-shadow: 0 0 4px currentColor; }
}

/* ---------------------------------------------------------------------------
   Live pill — small status badge for WS connection state.
   --------------------------------------------------------------------------- */
.live-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--bg-2);
  border: 1px solid var(--border);
  color: var(--muted);
  border-radius: 12px;
  padding: 2px 10px 2px 8px;
  font-size: 10px;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  font-family: 'JetBrains Mono', 'IBM Plex Mono', 'Consolas', monospace;
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease;
}
.live-pill:hover { border-color: var(--border-2); color: var(--text); }
.live-pill .live-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--muted-2);
  box-shadow: 0 0 4px transparent;
  flex-shrink: 0;
}
.live-pill.live {
  border-color: rgba(63,166,122,0.45);
  color: var(--pos);
}
.live-pill.live .live-dot {
  background: var(--pos);
  box-shadow: 0 0 6px rgba(63,166,122,0.7);
  animation: live-pulse 2s ease-in-out infinite;
}
.live-pill.connecting {
  border-color: rgba(224,200,122,0.45);
  color: var(--accent-2);
}
.live-pill.connecting .live-dot {
  background: var(--accent-2);
  animation: live-pulse 1s ease-in-out infinite;
}
@keyframes live-pulse {
  0%   { opacity: 1.0; }
  50%  { opacity: 0.45; }
  100% { opacity: 1.0; }
}

/* Flash animation when a new journal entry arrives via WS. */
@keyframes flash-new {
  0%   { box-shadow: 0 0 0 2px rgba(63,166,122,0.55), 0 0 16px rgba(63,166,122,0.35); background: rgba(63,166,122,0.07); }
  60%  { box-shadow: 0 0 0 2px rgba(63,166,122,0.20), 0 0 12px rgba(63,166,122,0.10); }
  100% { box-shadow: 0 0 0 0 transparent; background: transparent; }
}
.flash-new {
  animation: flash-new 1.6s ease-out 1;
}

/* Smooth fade-out for deleted entries. */
@keyframes flash-deleted {
  0%   { opacity: 1; transform: translateY(0); }
  100% { opacity: 0; transform: translateY(-8px); }
}
.flash-deleted {
  animation: flash-deleted 0.35s ease-in forwards;
  pointer-events: none;
}

/* ---------------------------------------------------------------------------
   EasyMDE dark-theme overrides. The default EasyMDE chrome assumes a light
   background — we re-skin toolbar, editor surface and preview to match the
   institutional dark theme.
   --------------------------------------------------------------------------- */
.EasyMDEContainer {
  background: var(--bg-2);
  border-radius: 3px;
}
.EasyMDEContainer .editor-toolbar {
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-bottom: none;
  border-radius: 3px 3px 0 0;
  opacity: 1;
}
.EasyMDEContainer .editor-toolbar a,
.EasyMDEContainer .editor-toolbar button {
  color: var(--text) !important;
  border: 1px solid transparent;
  border-radius: 2px;
}
.EasyMDEContainer .editor-toolbar a::before,
.EasyMDEContainer .editor-toolbar button::before {
  color: var(--text);
}
.EasyMDEContainer .editor-toolbar a:hover,
.EasyMDEContainer .editor-toolbar a.active,
.EasyMDEContainer .editor-toolbar button:hover,
.EasyMDEContainer .editor-toolbar button.active {
  background: var(--bg-2);
  border-color: var(--border-2);
  color: var(--accent) !important;
}
.EasyMDEContainer .editor-toolbar i.separator {
  border-left: 1px solid var(--border-2);
  border-right: 1px solid transparent;
}
.EasyMDEContainer .CodeMirror {
  background: var(--bg-2);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 0 0 3px 3px;
  caret-color: var(--accent);
}
.EasyMDEContainer .CodeMirror-cursor { border-left-color: var(--accent); }
.EasyMDEContainer .CodeMirror-selected { background: rgba(158,184,255,0.15) !important; }
.EasyMDEContainer .CodeMirror-focused .CodeMirror-selected { background: rgba(158,184,255,0.22) !important; }
.EasyMDEContainer .cm-s-easymde .cm-header,
.EasyMDEContainer .cm-s-easymde .cm-strong { color: var(--accent); }
.EasyMDEContainer .cm-s-easymde .cm-em { color: var(--accent-2); font-style: italic; }
.EasyMDEContainer .cm-s-easymde .cm-link,
.EasyMDEContainer .cm-s-easymde .cm-url { color: var(--accent); }
.EasyMDEContainer .cm-s-easymde .cm-comment,
.EasyMDEContainer .cm-s-easymde .cm-quote { color: var(--muted); }
.EasyMDEContainer .editor-preview,
.EasyMDEContainer .editor-preview-side {
  background: var(--bg-1);
  color: var(--text);
  border: 1px solid var(--border);
}
.EasyMDEContainer .editor-preview a { color: var(--accent); }
.EasyMDEContainer .editor-preview code,
.EasyMDEContainer .editor-preview pre {
  background: var(--bg-0);
  color: var(--accent-2);
  padding: 1px 4px;
  border-radius: 2px;
}
.EasyMDEContainer .editor-preview blockquote {
  border-left: 3px solid var(--border-2);
  color: var(--muted);
  padding-left: 10px;
}
.EasyMDEContainer .editor-statusbar {
  color: var(--muted-2);
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-top: none;
}

/* Markdown preview inside journal cards. */
.markdown-body p { margin: 0 0 6px; }
.markdown-body p:last-child { margin-bottom: 0; }
.markdown-body code {
  background: var(--bg-0); color: var(--accent-2);
  padding: 1px 4px; border-radius: 2px;
  font-family: 'JetBrains Mono', monospace; font-size: 11px;
}
.markdown-body pre {
  background: var(--bg-0); padding: 8px; border-radius: 3px;
  overflow-x: auto;
}
.markdown-body a { color: var(--accent); text-decoration: none; }
.markdown-body a:hover { text-decoration: underline; }
.markdown-body blockquote {
  border-left: 3px solid var(--border-2);
  margin: 4px 0 6px;
  padding-left: 8px;
  color: var(--muted);
}
.markdown-body ul, .markdown-body ol { margin: 4px 0 6px 18px; padding: 0; }
.markdown-body h1, .markdown-body h2, .markdown-body h3,
.markdown-body h4, .markdown-body h5, .markdown-body h6 {
  margin: 6px 0 4px;
  color: var(--accent);
  font-weight: 600;
}

/* ---------------------------------------------------------------------------
   LIGHT THEME OVERRIDES
   ---------------------------------------------------------------------------
   Activated by `<html data-bs-theme="light">` (set by theme.js). We re-bind the
   palette tokens so every existing rule that uses `var(--bg-0)` etc. flips
   automatically. Plotly charts read these vars in dashboard.js::cssVar(), so
   they get re-themed on the next refresh.
   --------------------------------------------------------------------------- */
:root[data-bs-theme="light"] {
  /* Off-white / cream surfaces — institutional terminals avoid pure #fff so
     panels read as "lifted cards" rather than floating on a flat screen. */
  --bg-0:    #f3f5f9;
  --bg-1:    #fbfcfe;
  --bg-2:    #eef2f7;
  --panel:   #fbfcfe;
  --border:  #e1e7ef;
  --border-2:#c3cdda;
  --text:    #0d1117;
  --muted:   #5a6b80;
  --muted-2: #8593a8;
  --pos:     #15803d;
  --neg:     #b91c1c;
  --accent:  #1f4ec9;
  --accent-2:#a07c1f;
  --warn:    #b45309;
  --crit:    #b91c1c;
  /* Layered shadow for "lifted" cards on the off-white background. */
  --panel-shadow: 0 1px 0 rgba(15,23,42,0.04), 0 1px 2px rgba(15,23,42,0.04), 0 4px 12px -8px rgba(15,23,42,0.08);
  /* Light-tuned overrides for the PASS 6 elevation tokens (the dark :root
     defines them with dark/periwinkle values; without these the verdict pills,
     kpi-delta chips, accent ticks and hover shadow read muddy/heavy on cream). */
  --accent-rgb: 31,78,201;
  --pos-rgb:    21,128,61;
  --neg-rgb:    185,28,28;
  --warn-rgb:   180,83,9;
  --accent2-rgb:160,124,31;
  --panel-shadow-hi: 0 1px 0 rgba(15,23,42,0.05), 0 4px 10px -2px rgba(15,23,42,0.10), 0 16px 36px -16px rgba(15,23,42,0.16);
}

/* The body class (theme-light / theme-dark) is added by theme.js. Most rules
   above already reference the CSS variables, so the palette flip cascades for
   free; the rules below patch the handful of places that still need explicit
   light-mode adjustments (subtle shadow, alpha tints, modal chrome). */
.theme-light body {
  background: var(--bg-0);
  color: var(--text);
}

.theme-light .app-navbar {
  background: var(--bg-1);
  border-bottom: 1px solid var(--border);
}
.theme-light .app-navbar .nav-link:hover,
.theme-light .app-navbar .nav-link.active {
  background: var(--bg-2);
}

/* Glass card / panel / sidebar: layered "lifted" shadow on the off-white
   surface — sober, no glow, mirrors what Bloomberg / FactSet use. */
.theme-light .glass-card,
.theme-light .panel,
.theme-light .sidebar {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 6px;
  box-shadow: var(--panel-shadow);
}
.theme-light .panel-header {
  background: linear-gradient(180deg, rgba(15,23,42,0.020), transparent);
  border-bottom: 1px solid rgba(15,23,42,0.05);
  color: var(--muted);
}

/* KPI tiles in light mode: cream surface with the same lifted shadow + a
   barely-there accent gradient to give each tile a subtle directional cue. */
.theme-light .kpi-tile {
  background: var(--panel);
  background-image: linear-gradient(135deg, rgba(31,78,201,0.05), transparent 60%);
  box-shadow: var(--panel-shadow);
  border-radius: 6px;
}
.theme-light .kpi-tile .value { color: var(--text); }

/* Tables. */
.theme-light table.dt th {
  background: var(--bg-2);
}
.theme-light table.dt td {
  border-bottom: 1px solid rgba(13, 17, 23, 0.06);
}
.theme-light table.dt tr:hover td { background: rgba(59, 111, 209, 0.06); }
.theme-light table.monthly-dt {
  background: var(--panel);
}
.theme-light table.monthly-dt td.label-cell {
  background: var(--bg-2);
}

/* Form controls + buttons. */
.theme-light .filter-input,
.theme-light .filter-select,
.theme-light .form-control,
.theme-light .form-select {
  background: #ffffff;
  color: var(--text);
}
.theme-light .form-control:focus,
.theme-light .form-select:focus {
  background: #ffffff;
  color: var(--text);
}
.theme-light .btn-inst {
  background: #ffffff;
  color: var(--text);
}
.theme-light .btn-inst:hover {
  background: var(--bg-2);
}
.theme-light .btn-inst.ghost { background: transparent; }
.theme-light .btn-inst.primary {
  background: linear-gradient(180deg, #3b6fd1, #2c52a8);
  color: #ffffff;
}
.theme-light .btn-outline-light {
  border-color: var(--border);
  color: var(--text);
}
.theme-light .btn-outline-light:hover {
  background: var(--bg-2);
  color: var(--text);
}

/* Badges. */
.theme-light .badge-inst.pos { color: var(--pos); border-color: rgba(46, 139, 98, 0.4); }
.theme-light .badge-inst.neg { color: var(--neg); border-color: rgba(193, 69, 69, 0.4); }

/* Alerts re-tinted for white background. */
.theme-light .alert-info     { background: rgba(59, 111, 209, 0.10); color: #2a55a6; }
.theme-light .alert-warning  { background: rgba(201, 136, 38, 0.14); color: #8a5e16; }
.theme-light .alert-danger,
.theme-light .alert-critical { background: rgba(193, 69, 69, 0.12); color: #8c2f2f; }

/* Bottom status bar + footer. */
.theme-light .status-bar {
  background: var(--bg-1);
  border-top: 1px solid var(--border);
  color: var(--muted);
}
.theme-light footer { color: var(--muted-2); }

/* Scrollbars. */
.theme-light ::-webkit-scrollbar-thumb { background: var(--border-2); }
.theme-light ::-webkit-scrollbar-thumb:hover { background: var(--muted); }

/* Loading panel spinner colour. */
.theme-light body.dashboard-loading .panel-header > span:first-child::after {
  border-color: var(--border-2);
  border-top-color: var(--accent);
}

/* Toggle groups (Combined / Per strategy). */
.theme-light .toggle-group {
  background: var(--bg-2);
}
.theme-light .toggle-group .btn-inst:hover { background: #ffffff; }
.theme-light .toggle-group .btn-inst.active {
  background: #ffffff;
  color: var(--accent);
}

/* Modal chrome. */
.theme-light .modal-content {
  background: var(--panel);
  color: var(--text);
}

/* Hover tint for strategy/drill rows in light mode. */
.theme-light .dt.drill-table tbody tr.drill-row:hover td {
  background: rgba(59, 111, 209, 0.08);
}

/* EasyMDE light-mode tweaks: the dark overrides above force a dark editor, so
   we re-light them when the page is in light mode. */
.theme-light .EasyMDEContainer { background: var(--bg-2); }
.theme-light .EasyMDEContainer .editor-toolbar { background: var(--bg-1); }
.theme-light .EasyMDEContainer .CodeMirror,
.theme-light .EasyMDEContainer .editor-preview,
.theme-light .EasyMDEContainer .editor-preview-side {
  background: #ffffff;
  color: var(--text);
}
.theme-light .EasyMDEContainer .editor-statusbar { background: var(--bg-1); }

/* ===========================================================================
   VISUAL POLISH — Bloomberg-grade refinements (appended).
   These rules layer on top of the institutional base without modifying any
   existing tokens or selectors. Safe to remove or extend independently.
   =========================================================================== */

/* Panel hover lift (desktop only). Subtle shadow + 1px border accent. */
@media (hover: hover) {
  .panel {
    transition: box-shadow 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
  }
  .panel:hover {
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.28), 0 1px 2px rgba(0, 0, 0, 0.18);
    border-color: var(--border-2);
  }
  .theme-light .panel:hover {
    box-shadow: 0 6px 18px rgba(15, 22, 38, 0.06), 0 1px 2px rgba(15, 22, 38, 0.04);
  }
}

/* Panel-header bottom border becomes a soft gradient — terminal-grade chrome. */
.panel-header {
  border-bottom: 1px solid transparent;
  background-image:
    linear-gradient(var(--bg-1), var(--bg-1)),
    linear-gradient(90deg, transparent, var(--border-2), transparent);
  background-origin: padding-box, border-box;
  background-clip: padding-box, border-box;
  background-repeat: no-repeat;
  background-size: 100% calc(100% - 1px), 100% 1px;
  background-position: top left, bottom left;
}
.theme-light .panel-header {
  background-image:
    linear-gradient(var(--bg-2), var(--bg-2)),
    linear-gradient(90deg, transparent, var(--border-2), transparent);
}

/* KPI tiles: subtle gradient backdrop + lift on hover. */
.kpi-tile {
  background-image: linear-gradient(135deg, rgba(31, 111, 235, 0.06), transparent 60%);
  transition: transform 0.16s ease, box-shadow 0.16s ease, border-color 0.16s ease;
}
.kpi-tile:hover {
  transform: translateY(-1px);
  border-color: var(--border-2);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
}
.theme-light .kpi-tile:hover {
  box-shadow: 0 4px 14px rgba(15, 22, 38, 0.05);
}
.kpi-tile.pos {
  background-image: linear-gradient(135deg, rgba(34, 197, 94, 0.08), transparent 60%);
}
.kpi-tile.neg {
  background-image: linear-gradient(135deg, rgba(239, 68, 68, 0.08), transparent 60%);
}
.kpi-tile.warn {
  background-image: linear-gradient(135deg, rgba(245, 158, 11, 0.08), transparent 60%);
}

/* Tiny inline sparkline under the KPI value. */
.kpi-tile .sparkline {
  display: block;
  width: 100%;
  height: 26px;
  margin: 2px 0 0;
  pointer-events: none;
  opacity: 0.85;
}

/* Tables: tighter row dividers + refined hover tint. */
table.dt tbody tr { transition: background 0.12s ease; }
table.dt tbody tr:hover { background: rgba(31, 111, 235, 0.06); }
.theme-light table.dt tbody tr:hover { background: rgba(31, 111, 235, 0.06); }
table.dt td { padding-top: 6px; padding-bottom: 6px; }

/* Lock the Plotly modebar down to PNG download only.
   The dashboard ships its own PNG button per panel; this rule is defensive
   in case displayModeBar is ever flipped back on via devtools. */
.modebar-container .modebar-btn:not([data-title="Download plot as a png"]) {
  display: none !important;
}
.modebar { background: transparent !important; }
.modebar-btn path { fill: var(--muted) !important; }
.modebar-btn:hover path { fill: var(--accent) !important; }

/* Empty state for charts with no data. */
.chart-empty {
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  width: 100%; height: 100%;
  min-height: 220px;
  padding: 24px;
  color: var(--muted);
  font-size: 11.5px;
  text-align: center;
  gap: 8px;
}
.chart-empty i {
  font-size: 32px;
  opacity: 0.4;
  color: var(--muted-2);
  margin-bottom: 4px;
}
.chart-empty div { line-height: 1.4; }

/* Status-bar: slightly larger sign glyphs + smoother pulse. */
.status-bar .pos::before,
.status-bar .neg::before {
  display: inline-block;
  margin-right: 3px;
  font-size: 11px;
  line-height: 1;
}
.status-bar .pos::before { content: "\25B2"; }   /* ▲ */
.status-bar .neg::before { content: "\25BC"; }   /* ▼ */
@keyframes status-pulse {
  0%   { opacity: 1.0; box-shadow: 0 0 4px currentColor; }
  50%  { opacity: 0.45; box-shadow: 0 0 9px currentColor; }
  100% { opacity: 1.0; box-shadow: 0 0 4px currentColor; }
}
.status-bar .status-dot.pulsing {
  animation: status-pulse 1.5s ease-in-out infinite;
}

/* Slight refinement: Plotly tick labels become a hair lighter so the grid
   doesn't dominate. */
.js-plotly-plot .xtick text,
.js-plotly-plot .ytick text {
  font-family: 'Inter', system-ui, sans-serif !important;
}

/* ===========================================================================
   RISK MONITOR — Bloomberg-terminal redesign (append-only block)
   ===========================================================================
   Self-contained; touches only `.risk-*`, `.alert-row`, `.exposure-bar-row`,
   `.row-flash-new`. The base `.chart-empty` defined above is reused.
   --------------------------------------------------------------------------- */

/* Tighten chart-empty inside the risk page's slim spark containers (140px,
   160px) so it doesn't overflow with the default 220px min-height. */
.risk-panel .chart-empty { min-height: 0; padding: 8px; }

/* Panel wrapper — tighter than `.glass-card`, with a hairline header strip. */
.risk-panel {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 5px;
  box-shadow: 0 1px 0 rgba(0,0,0,0.15);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.risk-panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 12px;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.7px;
  text-transform: uppercase;
  color: var(--muted);
  background: linear-gradient(180deg, var(--bg-1), var(--panel));
  border-bottom: 1px dotted var(--border-2);
}
.risk-panel-header > span:first-child { display:inline-flex; align-items:center; gap:6px; }
.risk-panel-header i { font-size: 12px; color: var(--accent); }
.risk-panel-action {
  text-transform: none;
  letter-spacing: 0;
  font-weight: 400;
  font-size: 11px;
}
.risk-panel-divider {
  height: 1px;
  background: var(--border);
  margin: 8px 0;
}

/* Status pill — chip with pulsing dot. */
.risk-status-pill {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 4px 12px 4px 10px;
  border-radius: 12px;
  font-size: 11px;
  font-family: 'JetBrains Mono', 'IBM Plex Mono', 'Consolas', monospace;
  letter-spacing: 0.4px;
  border: 1px solid var(--border);
  background: var(--bg-2);
  color: var(--muted);
  transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.risk-pulse-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--muted-2);
  flex-shrink: 0;
  box-shadow: 0 0 4px transparent;
}
.risk-status-pill.chip-live {
  border-color: rgba(63,166,122,0.55);
  background: rgba(63,166,122,0.10);
  color: var(--pos);
}
.risk-status-pill.chip-live .risk-pulse-dot {
  background: var(--pos);
  box-shadow: 0 0 8px rgba(63,166,122,0.7);
  animation: risk-pulse 1.6s ease-in-out infinite;
}
.risk-status-pill.chip-poll {
  border-color: rgba(158,184,255,0.45);
  background: rgba(158,184,255,0.08);
  color: var(--accent);
}
.risk-status-pill.chip-poll .risk-pulse-dot {
  background: var(--accent);
  box-shadow: 0 0 6px rgba(158,184,255,0.55);
  animation: risk-pulse 2.4s ease-in-out infinite;
}
.risk-status-pill.chip-warn {
  border-color: rgba(224,163,93,0.55);
  background: rgba(224,163,93,0.10);
  color: var(--warn);
}
.risk-status-pill.chip-warn .risk-pulse-dot {
  background: var(--warn);
  box-shadow: 0 0 6px rgba(224,163,93,0.6);
  animation: risk-pulse 1.0s ease-in-out infinite;
}
.risk-status-pill.chip-idle .risk-pulse-dot { animation: none; }
@keyframes risk-pulse {
  0%   { opacity: 1.0; }
  50%  { opacity: 0.35; }
  100% { opacity: 1.0; }
}

/* KPI tile — denser variant of `.kpi-tile` with semantic left-border. */
.risk-kpi {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
  height: 88px;
  padding: 10px 12px 10px 14px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 4px;
  transition: transform 0.15s ease, border-color 0.15s ease, background 0.15s ease;
  overflow: hidden;
}
.risk-kpi::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--accent-color, var(--border-2));
  transition: background 0.15s ease;
}
.risk-kpi::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(135deg, var(--accent-color, transparent) 0%, transparent 35%);
  opacity: 0.06;
  pointer-events: none;
}
.risk-kpi:hover {
  transform: translateY(-1px);
  border-color: var(--border-2);
}
.risk-kpi .risk-kpi-label {
  font-size: 10px;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.risk-kpi .risk-kpi-value {
  font-family: 'JetBrains Mono', 'IBM Plex Mono', 'Consolas', monospace;
  font-size: 19px;
  font-weight: 600;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  line-height: 1.15;
  max-height: 28px;
  display: flex;
  align-items: center;
  gap: 4px;
}
.risk-kpi .risk-kpi-sub {
  font-size: 10px;
  color: var(--muted-2);
  font-family: 'JetBrains Mono', monospace;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.risk-kpi.pos .risk-kpi-value { color: var(--pos); }
.risk-kpi.neg .risk-kpi-value { color: var(--neg); }
.risk-kpi.warn .risk-kpi-value { color: var(--warn); }
.risk-kpi .arrow { font-size: 13px; }

/* Positions table improvements layered on `.table-dark`. */
.risk-positions { font-size: 11.5px; }
.risk-positions thead th {
  font-size: 10px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--muted);
  background: var(--bg-1);
  border-bottom: 1px solid var(--border);
  padding: 7px 10px;
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}
.risk-positions thead th:hover { color: var(--accent); }
.risk-positions thead th.sorted-asc::after  { content: " \25B2"; font-size: 8px; color: var(--accent); }
.risk-positions thead th.sorted-desc::after { content: " \25BC"; font-size: 8px; color: var(--accent); }
.risk-positions tbody td {
  font-family: 'JetBrains Mono', 'IBM Plex Mono', 'Consolas', monospace;
  font-variant-numeric: tabular-nums;
  padding: 6px 10px;
  border-bottom: 1px solid rgba(255,255,255,0.03);
  color: var(--text);
}
.risk-positions tbody tr:hover td { background: rgba(158,184,255,0.04); }
.risk-positions .pl-cell { position: relative; }
.row-flash-new { animation: row-flash-new 1.6s ease-out 1; }
@keyframes row-flash-new {
  0%   { background-color: rgba(63,166,122,0.30); }
  60%  { background-color: rgba(63,166,122,0.10); }
  100% { background-color: transparent; }
}

/* Risk budget bar — CSS-only gradient track. */
.risk-budget-track {
  position: relative;
  height: 22px;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: 11px;
  overflow: hidden;
}
.risk-budget-fill {
  position: absolute;
  inset: 0 auto 0 0;
  background: linear-gradient(90deg, #22c55e 0%, #eab308 50%, #ef4444 100%);
  transition: width 0.4s ease;
  border-radius: 11px 0 0 11px;
}
.risk-budget-marker {
  position: absolute;
  top: -2px; bottom: -2px;
  width: 2px;
  background: var(--text);
  opacity: 0.7;
}

/* Alert feed — rich rows. */
.alerts-list-rich {
  max-height: 380px;
  overflow-y: auto;
  padding: 6px;
}
.alert-row {
  display: flex;
  gap: 10px;
  padding: 8px 10px;
  margin-bottom: 6px;
  border-left: 3px solid var(--border-2);
  background: var(--bg-2);
  border-radius: 3px;
  transition: transform 0.15s ease, background 0.15s ease;
  position: relative;
}
.alert-row:hover { transform: translateX(2px); background: var(--bg-1); }
.alert-row.sev-critical { border-left-color: var(--crit); background: rgba(225,94,94,0.07); }
.alert-row.sev-warning  { border-left-color: var(--warn); background: rgba(224,163,93,0.07); }
.alert-row.sev-info     { border-left-color: var(--accent); background: rgba(158,184,255,0.06); }
.alert-row.acked { opacity: 0.45; filter: grayscale(0.4); }
.alert-row .alert-icon {
  font-size: 16px;
  flex-shrink: 0;
  margin-top: 1px;
}
.alert-row.sev-critical .alert-icon { color: var(--crit); }
.alert-row.sev-warning  .alert-icon { color: var(--warn); }
.alert-row.sev-info     .alert-icon { color: var(--accent); }
.alert-row .alert-body { flex: 1; min-width: 0; }
.alert-row .alert-title {
  font-size: 11px; font-weight: 600;
  color: var(--text); letter-spacing: 0.3px;
}
.alert-row .alert-msg {
  font-size: 11px;
  color: var(--muted);
  margin-top: 1px;
  word-wrap: break-word;
}
.alert-row .alert-meta {
  display: flex; gap: 10px;
  font-size: 9.5px;
  color: var(--muted-2);
  font-family: 'JetBrains Mono', monospace;
  margin-top: 3px;
  letter-spacing: 0.3px;
}
.alert-row .alert-ack {
  flex-shrink: 0;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--muted);
  border-radius: 3px;
  padding: 2px 6px;
  cursor: pointer;
  font-size: 11px;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.alert-row .alert-ack:hover { color: var(--pos); border-color: var(--pos); }
.alert-row.acked .alert-ack { cursor: default; color: var(--pos); }

/* Risk limit rows — label/value pair with usage tint. */
.risk-limit-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 5px 10px;
  border-bottom: 1px solid rgba(255,255,255,0.03);
  font-size: 11px;
}
.risk-limit-row:last-child { border-bottom: none; }
.risk-limit-row .lim-label { color: var(--muted); letter-spacing: 0.3px; }
.risk-limit-row .lim-value {
  font-family: 'JetBrains Mono', monospace;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.risk-limit-row .lim-bar {
  display: inline-block;
  width: 48px; height: 5px;
  border-radius: 2px;
  background: var(--bg-2);
  position: relative;
  overflow: hidden;
}
.risk-limit-row .lim-bar > span {
  display: block; height: 100%;
  background: var(--pos);
  transition: width 0.3s ease, background 0.3s ease;
}
.risk-limit-row.usage-warn  { background: rgba(224,163,93,0.04); }
.risk-limit-row.usage-warn  .lim-bar > span { background: var(--warn); }
.risk-limit-row.usage-crit  { background: rgba(225,94,94,0.06); }
.risk-limit-row.usage-crit  .lim-bar > span { background: var(--crit); }

/* Exposure top-5 bars (slimmer than Bootstrap progress). */
.exposure-bar-row { margin-bottom: 8px; }
.exposure-bar-row .ebr-head {
  display: flex; justify-content: space-between;
  font-size: 10.5px; color: var(--muted);
  margin-bottom: 3px;
  font-family: 'JetBrains Mono', monospace;
}
.exposure-bar-row .ebr-track {
  height: 4px;
  background: var(--bg-2);
  border-radius: 2px;
  overflow: hidden;
}
.exposure-bar-row .ebr-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--accent), var(--accent-2));
  border-radius: 2px;
  transition: width 0.3s ease;
}

/* Light-theme tweaks for the risk panels. */
.theme-light .risk-panel { box-shadow: 0 1px 2px rgba(15, 22, 38, 0.04); }
.theme-light .risk-panel-header { background: linear-gradient(180deg, var(--bg-2), var(--panel)); }
.theme-light .risk-status-pill { background: #ffffff; }
.theme-light .risk-kpi { box-shadow: 0 1px 2px rgba(15, 22, 38, 0.04); }
.theme-light .alert-row { background: var(--bg-2); }
.theme-light .alert-row:hover { background: #ffffff; }
.theme-light .alert-row.sev-critical { background: rgba(193,69,69,0.06); }
.theme-light .alert-row.sev-warning  { background: rgba(201,136,38,0.07); }
.theme-light .alert-row.sev-info     { background: rgba(59,111,209,0.05); }

/* TradingView equity chart  */
.tv-chart-wrap { background: var(--panel-bg); border-radius: 10px; overflow: hidden; }

.tv-tooltip {
  position: absolute; top: 12px; left: 12px; z-index: 5;
  padding: 8px 12px; min-width: 180px;
  font-family: Inter, system-ui, sans-serif; font-size: 11px;
  background: rgba(13,17,23,0.85);
  color: #c9d1d9;
  border: 1px solid rgba(148,163,184,0.20);
  border-radius: 6px;
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  pointer-events: none;
  box-shadow: 0 4px 20px rgba(0,0,0,0.4);
}
.theme-light .tv-tooltip {
  background: rgba(255,255,255,0.92);
  color: #1f2937;
  border: 1px solid rgba(15,23,42,0.12);
  box-shadow: 0 4px 20px rgba(15,23,42,0.10);
}
.tv-tip-date { font-weight: 600; font-size: 10px; opacity: 0.7; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 4px; }
.tv-tip-row { display: flex; justify-content: space-between; gap: 16px; line-height: 1.5; }
.tv-tip-label { opacity: 0.6; }
.tv-tip-val { font-family: "JetBrains Mono", "SF Mono", Consolas, monospace; font-weight: 600; }
.tv-tip-val.pos { color: #26a69a; }
.tv-tip-val.neg { color: #ef5350; }

.tv-pricetag {
  position: absolute; top: 12px; right: 12px; z-index: 5;
  padding: 6px 12px; font-family: "JetBrains Mono", "SF Mono", Consolas, monospace;
  font-size: 14px; font-weight: 700;
  background: rgba(13,17,23,0.85);
  color: #c9d1d9;
  border: 1px solid rgba(148,163,184,0.18);
  border-radius: 6px;
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  display: flex; gap: 10px; align-items: baseline;
  pointer-events: none;
}
.theme-light .tv-pricetag {
  background: rgba(255,255,255,0.92);
  color: #1f2937;
  border: 1px solid rgba(15,23,42,0.12);
}
.tv-tag-value { font-size: 16px; }
.tv-tag-delta { font-size: 11px; opacity: 0.85; }
.tv-tag-delta.pos { color: #26a69a; }
.tv-tag-delta.neg { color: #ef5350; }
.theme-light .tv-tag-delta.pos { color: #15803d; }
.theme-light .tv-tag-delta.neg { color: #b91c1c; }

.tv-timeframe {
  position: absolute; bottom: 12px; left: 12px; z-index: 5;
  display: flex; gap: 4px;
  background: rgba(13,17,23,0.75); border: 1px solid rgba(148,163,184,0.15);
  border-radius: 6px; padding: 3px;
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
}
.theme-light .tv-timeframe {
  background: rgba(255,255,255,0.90); border-color: rgba(15,23,42,0.10);
}
.tv-tf-btn {
  background: transparent; border: 0; color: var(--muted);
  font-family: Inter, system-ui, sans-serif; font-size: 10px; font-weight: 600;
  letter-spacing: 0.5px; padding: 4px 10px; border-radius: 4px;
  cursor: pointer; transition: background 0.15s, color 0.15s;
}
.tv-tf-btn:hover { color: var(--text); background: rgba(148,163,184,0.10); }
.tv-tf-btn.active { background: #1f4ec9; color: #fff; }
.theme-dark .tv-tf-btn.active { background: #26a69a; color: #0d1117; }

/* Confirmation modal accent strip — picks up Bootstrap danger / warning */
.confirm-modal-header.danger  { border-top: 3px solid var(--bs-danger, #dc3545); }
.confirm-modal-header.warning { border-top: 3px solid var(--bs-warning, #ffc107); }
.backtest-card { transition: opacity 0.25s ease, transform 0.25s ease; }
.backtest-card.removing { opacity: 0; transform: scale(0.96); }

/* ── Institutional polish (pass 2) ── */
/* These rules extend the institutional design system to the secondary pages
 * (/trades, /strategies, /strategies/{id}, /journal, /upload, /governance).
 * Append-only — no existing tokens or selectors are modified.
 */

/* Sticky table headers across .dt instances on secondary pages. The base
 * table.dt th already has position:sticky; this reinforces background/border
 * so it never clashes with surrounding content as users scroll. */
.dt thead th {
  position: sticky; top: 0; z-index: 1;
  background: var(--bg-1);
  text-transform: uppercase; letter-spacing: 0.5px;
  font-size: 10px; color: var(--muted); font-weight: 600;
  border-bottom: 1px solid var(--border);
}
.theme-light .dt thead th { background: var(--bg-2); }

/* Tabular-nums helper for any numeric cell that hasn't already inherited it. */
.dt td.r, .dt th.r,
.tabular { font-variant-numeric: tabular-nums; font-family: "JetBrains Mono", "SF Mono", Consolas, monospace; }

/* Cell tint helpers for profit/loss heatmaps — usage proportional to
 * magnitude. Applied via inline class on each td. */
.cell-pos-1 { background: linear-gradient(90deg, transparent, rgba(34,197,94,0.06)); }
.cell-pos-2 { background: linear-gradient(90deg, transparent, rgba(34,197,94,0.12)); }
.cell-pos-3 { background: linear-gradient(90deg, transparent, rgba(34,197,94,0.18)); }
.cell-neg-1 { background: linear-gradient(90deg, transparent, rgba(239,68,68,0.06)); }
.cell-neg-2 { background: linear-gradient(90deg, transparent, rgba(239,68,68,0.12)); }
.cell-neg-3 { background: linear-gradient(90deg, transparent, rgba(239,68,68,0.18)); }

/* Empty state used across pages (tables, panels, timelines). */
.empty-state {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 8px; padding: 48px 16px; color: var(--muted);
  text-align: center;
}
.empty-state i { font-size: 32px; opacity: 0.5; color: var(--muted-2); }
.empty-state .es-title { font-size: 12px; font-weight: 600; letter-spacing: 0.4px; }
.empty-state .es-hint { font-size: 11px; color: var(--muted-2); }

/* Two-column page layout (used in /journal). */
.page-2col { display: grid; grid-template-columns: 220px 1fr; gap: 16px; }
@media (max-width: 768px) { .page-2col { grid-template-columns: 1fr; } }

/* Inline filter sidebar (journal). */
.filter-sidebar {
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 6px; padding: 14px;
  height: fit-content; position: sticky; top: 80px;
}
.filter-sidebar h6 {
  font-size: 10px; letter-spacing: 0.5px; text-transform: uppercase;
  color: var(--muted); margin: 12px 0 6px; font-weight: 600;
}
.filter-sidebar h6:first-child { margin-top: 0; }
.theme-light .filter-sidebar { box-shadow: var(--panel-shadow); }

/* Tag chips (clickable filter chips for journal). */
.tag-chip {
  display: inline-block; padding: 3px 8px; margin: 2px;
  background: var(--bg-2); color: var(--text);
  border: 1px solid var(--border);
  border-radius: 100px; font-size: 10px; font-weight: 600;
  cursor: pointer; user-select: none;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
  font-family: 'JetBrains Mono', monospace; letter-spacing: 0.3px;
}
.tag-chip:hover { border-color: var(--accent); color: var(--accent); }
.tag-chip.active { background: var(--accent); color: #fff; border-color: var(--accent); }
.tag-chip .tag-count { opacity: 0.6; margin-left: 4px; font-weight: 500; }

/* Code blocks for governance / snippets. */
:root { --code-bg: #0d1117; --code-text: #c9d1d9; }
:root[data-bs-theme="light"] { --code-bg: #1f2937; --code-text: #e2e8f0; }
.code-snippet {
  background: var(--code-bg); color: var(--code-text);
  padding: 12px; border-radius: 6px;
  font-family: "JetBrains Mono", "SF Mono", Consolas, monospace;
  font-size: 11px; line-height: 1.55;
  overflow-x: auto;
  border: 1px solid var(--border);
  margin: 6px 0;
  white-space: pre-wrap; word-break: break-all;
}

/* Page header strip used by secondary pages — mirrors the dashboard. */
.page-header {
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: 12px;
  margin-bottom: 12px;
}
.page-header .page-title {
  font-size: 14px; font-weight: 600; letter-spacing: 0.6px;
  display: inline-flex; align-items: center; gap: 8px; margin: 0;
}
.page-header .page-title i { color: var(--accent); font-size: 16px; }

/* Compact form-controls inside .glass-card filter rows. */
.filter-row .form-control-sm,
.filter-row .form-select-sm {
  background: var(--bg-2); border-color: var(--border); color: var(--text);
  font-size: 11px;
}
.filter-row .form-control-sm:focus,
.filter-row .form-select-sm:focus {
  background: var(--bg-2); color: var(--text);
  border-color: var(--accent); box-shadow: 0 0 0 1px rgba(158,184,255,0.25);
}
.theme-light .filter-row .form-control-sm,
.theme-light .filter-row .form-select-sm { background: #ffffff; }

/* Strategy color accent (left-border) on name cell. */
.dt td.strat-name {
  font-family: 'Inter', sans-serif;
  border-left: 4px solid var(--strat-color, var(--border-2));
  padding-left: 12px;
  cursor: pointer;
}

/* Mood stars styling — solid stars with muted empty ones. */
.mood-stars {
  font-size: 11px; letter-spacing: 1px; color: var(--accent-2);
  font-family: 'JetBrains Mono', monospace;
}
.mood-stars .empty { color: var(--muted-2); opacity: 0.55; }

/* Journal timeline cards: tighter, with hover lift. */
.journal-card {
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 6px; padding: 12px 14px;
  transition: border-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
}
.journal-card:hover { border-color: var(--border-2); transform: translateY(-1px); }
.theme-light .journal-card { box-shadow: var(--panel-shadow); }
.journal-card .jc-title {
  font-size: 13px; font-weight: 600; letter-spacing: 0.2px;
  color: var(--text); display: inline-flex; align-items: center; gap: 8px;
}
.journal-card .jc-meta {
  font-size: 10.5px; color: var(--muted-2);
  font-family: 'JetBrains Mono', monospace; letter-spacing: 0.3px;
  margin-top: 2px;
}
.journal-card .jc-body { font-size: 12px; margin-top: 6px; }
.journal-card .jc-foot { margin-top: 6px; display: flex; flex-wrap: wrap; gap: 4px; }

/* FAB — refined floating add button. */
.fab-add {
  position: fixed; right: 24px; bottom: 48px;
  width: 48px; height: 48px;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(180deg, #3a6dd6, #2c52a8);
  border: 1px solid #2c52a8;
  border-radius: 50%;
  color: #fff; font-size: 20px;
  box-shadow: 0 4px 14px rgba(0,0,0,0.45);
  cursor: pointer; z-index: 1000;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.fab-add:hover { transform: translateY(-2px) scale(1.04); box-shadow: 0 6px 20px rgba(0,0,0,0.55); }
.theme-light .fab-add { box-shadow: 0 4px 14px rgba(15,22,38,0.18); }

/* Strategy detail header — chip strip + delete button. */
.strat-header {
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: 12px; margin-bottom: 14px;
}
.strat-header .strat-title {
  font-size: 20px; font-weight: 700; letter-spacing: 0.2px;
  display: inline-flex; align-items: center; gap: 10px;
  margin: 0;
}
.strat-header .strat-color-dot {
  display: inline-block; width: 12px; height: 12px;
  border-radius: 50%; box-shadow: 0 0 6px currentColor;
}

/* Danger ghost button — used for delete actions in headers. */
.btn-inst.danger {
  border-color: rgba(225,94,94,0.45);
  color: var(--neg);
}
.btn-inst.danger:hover {
  background: rgba(225,94,94,0.10);
  border-color: var(--neg);
  color: var(--neg);
}

/* Apply-to-SQX red-glow on hover. */
.btn-apply-sqx {
  background: linear-gradient(180deg, #d04848, #a83a3a) !important;
  border: 1px solid #a83a3a !important;
  color: #fff !important;
  padding: 8px 18px !important;
  font-weight: 600 !important;
  transition: box-shadow 0.18s ease, transform 0.15s ease, filter 0.15s ease;
}
.btn-apply-sqx:hover {
  filter: brightness(1.08);
  box-shadow: 0 0 0 1px rgba(225,94,94,0.50), 0 4px 18px rgba(225,94,94,0.45);
  transform: translateY(-1px);
}

/* Governance: tighter snippet labels. */
.snippet-label {
  font-size: 10px; letter-spacing: 0.5px; text-transform: uppercase;
  color: var(--muted); margin: 8px 0 3px; font-weight: 600;
  font-family: 'Inter', sans-serif;
}

/* Upload page: help-card list styling. */
.upload-tips {
  list-style: none; padding: 0; margin: 0;
}
.upload-tips li {
  padding: 6px 0; border-bottom: 1px dotted var(--border);
  font-size: 12px; color: var(--text);
}
.upload-tips li:last-child { border-bottom: none; }
.upload-tips li b { color: var(--accent); font-weight: 600; }
.upload-tips li em { color: var(--accent-2); font-style: normal; }

/* Light-mode tweaks for journal + page-header polish. */
.theme-light .tag-chip { background: #ffffff; }
.theme-light .tag-chip:hover { background: var(--bg-2); }
.theme-light .tag-chip.active { background: var(--accent); color: #fff; }

/* ============================================================================
 * ── UI bump pass 3 ──
 * ============================================================================
 * Institutional-desk feel: refined typography, spacing scale, skeleton
 * loaders, hover/focus microinteractions, sticky sub-headers, breadcrumbs,
 * brand-mark, notification panel, refined neutral palette.
 * Append-only — all rules are additive. Later `:root` overrides at the
 * bottom of this section win over earlier token definitions thanks to CSS
 * source order.
 * ============================================================================ */

/* — Font stack vars — */
:root {
  --font-ui:   'Inter', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-mono: 'JetBrains Mono', 'SF Mono', Consolas, ui-monospace, monospace;
  --easing:    cubic-bezier(0.16, 1, 0.3, 1);
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 48px;
}

body {
  font-family: var(--font-ui);
}

/* The `.mono` utility class is already declared above — extend it with
 * the new var so future tweaks happen in one place. */
.mono, .num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

/* — Brand mark — */
.brand-mark { display: inline-flex; align-items: center; gap: 8px; }
.brand-mark svg { color: #2e7df0; flex-shrink: 0; }
.brand-name {
  font-weight: 700;
  letter-spacing: -0.2px;
  font-family: var(--font-ui);
  text-transform: uppercase;
  font-size: 13px;
}

/* — Skeleton loader — */
.skeleton {
  background: linear-gradient(90deg,
    rgba(148,163,184,0.08) 25%,
    rgba(148,163,184,0.16) 37%,
    rgba(148,163,184,0.08) 63%);
  background-size: 400% 100%;
  animation: skeleton-shimmer 1.4s ease infinite;
  border-radius: 4px;
  color: transparent !important;
  pointer-events: none;
  user-select: none;
}
@keyframes skeleton-shimmer {
  0%   { background-position: 100% 0; }
  100% { background-position: -100% 0; }
}
.skeleton.text-sm { height: 12px; width: 60%; display: inline-block; }
.skeleton.text-lg { height: 18px; width: 80%; display: inline-block; }
.skeleton.kpi     { height: 28px; width: 70%; display: inline-block; }
.skeleton.row     { height: 14px; width: 100%; display: block; margin: 6px 0; }
.theme-light .skeleton {
  background: linear-gradient(90deg,
    rgba(15,23,42,0.06) 25%,
    rgba(15,23,42,0.12) 37%,
    rgba(15,23,42,0.06) 63%);
  background-size: 400% 100%;
}

/* — Hover & focus microinteractions — */
.panel, .kpi-tile, .ea-card, .journal-card, .risk-kpi {
  transition: transform 0.2s var(--easing),
              box-shadow 0.2s var(--easing),
              border-color 0.18s var(--easing);
}
.btn, .btn-inst {
  transition: background-color 0.15s ease,
              color 0.15s ease,
              border-color 0.15s ease,
              transform 0.1s ease;
}
.btn:active, .btn-inst:active { transform: translateY(1px); }

input.filter-input:focus,
input.form-control:focus,
select.filter-select:focus,
.form-select:focus,
textarea.form-control:focus {
  outline: none;
  box-shadow: 0 0 0 3px rgba(31,78,201,0.18);
  border-color: #1f4ec9;
}
a:focus-visible, button:focus-visible {
  outline: 2px solid #1f4ec9;
  outline-offset: 2px;
  border-radius: 3px;
}
::selection { background: rgba(31,78,201,0.30); color: #ffffff; }
.theme-light ::selection { background: rgba(31,78,201,0.20); color: #0d1117; }

/* — Sticky page sub-header —
 * Wrap any page title row in `.sticky-subheader` to keep the title
 * pinned with a blurred backdrop while the user scrolls. */
.sticky-subheader {
  position: sticky;
  top: 48px;
  background: color-mix(in srgb, var(--bg-0) 85%, transparent);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  margin: -16px -16px 16px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
  z-index: 10;
}
.theme-light .sticky-subheader {
  background: color-mix(in srgb, var(--bg-0) 85%, transparent);
  border-bottom: 1px solid var(--border);
}

/* — Breadcrumb component — */
.breadcrumb-bar {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  color: var(--muted);
  margin-bottom: 16px;
  font-family: var(--font-ui);
  letter-spacing: 0.2px;
}
.breadcrumb-bar a {
  color: var(--muted);
  text-decoration: none;
  transition: color 0.15s ease;
}
.breadcrumb-bar a:hover { color: var(--text); }
.breadcrumb-bar .active {
  color: var(--text);
  font-weight: 600;
}
.breadcrumb-bar i.bi-chevron-right {
  font-size: 9px;
  opacity: 0.5;
}

/* — Top-right notification center — */
.notif-btn { position: relative; }
.notif-btn .notif-badge {
  position: absolute;
  top: -4px;
  right: -4px;
  background: #ef4444;
  color: #fff;
  font-size: 9px;
  font-weight: 700;
  border-radius: 100px;
  padding: 1px 5px;
  min-width: 16px;
  text-align: center;
  font-family: var(--font-mono);
  line-height: 1.2;
  letter-spacing: 0;
  box-shadow: 0 0 0 2px var(--bg-1);
}
.notif-panel {
  position: absolute;
  right: 12px;
  top: 56px;
  z-index: 1050;
  width: 360px;
  max-height: 480px;
  overflow-y: auto;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 8px 32px rgba(0,0,0,0.35);
  display: none;
  font-family: var(--font-ui);
}
.theme-light .notif-panel {
  box-shadow: 0 8px 32px rgba(15,22,38,0.18);
}
.notif-panel.open { display: block; }
.notif-panel .notif-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-1);
  position: sticky;
  top: 0;
  z-index: 2;
}
.theme-light .notif-panel .notif-head { background: var(--bg-2); }
.notif-panel .notif-title {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: var(--muted);
}
.notif-panel .notif-mark-read {
  background: transparent;
  border: 0;
  color: var(--accent);
  font-size: 10px;
  font-weight: 600;
  cursor: pointer;
  padding: 2px 6px;
  border-radius: 3px;
  letter-spacing: 0.3px;
  text-transform: uppercase;
}
.notif-panel .notif-mark-read:hover { background: var(--bg-2); }
.notif-item {
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
  display: flex;
  gap: 10px;
  align-items: flex-start;
  cursor: pointer;
  transition: background-color 0.12s ease;
}
.notif-item:hover { background: var(--bg-2); }
.notif-item:last-of-type { border-bottom: 0; }
.notif-item .ni-icon {
  width: 28px;
  height: 28px;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  flex: 0 0 28px;
}
.notif-item.kind-risk .ni-icon { background: rgba(239,68,68,0.15); color: #ef4444; }
.notif-item.kind-journal .ni-icon { background: rgba(31,78,201,0.15); color: #1f4ec9; }
.notif-item .ni-body { flex: 1; min-width: 0; }
.notif-item .ni-title {
  font-size: 12px;
  font-weight: 600;
  color: var(--text);
  display: flex;
  align-items: center;
  gap: 6px;
}
.notif-item .ni-unread-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #1f4ec9;
  flex-shrink: 0;
}
.notif-item .ni-msg {
  font-size: 11px;
  color: var(--muted);
  margin-top: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.notif-item .ni-meta {
  display: inline-block;
  font-size: 10px;
  color: var(--muted-2);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  margin-top: 4px;
  font-family: var(--font-mono);
}
.notif-empty {
  padding: 32px 16px;
  text-align: center;
  color: var(--muted);
  font-size: 11px;
}
.notif-panel .notif-foot {
  display: flex;
  gap: 6px;
  padding: 8px 14px;
  border-top: 1px solid var(--border);
  background: var(--bg-1);
  position: sticky;
  bottom: 0;
}
.theme-light .notif-panel .notif-foot { background: var(--bg-2); }
.notif-panel .notif-link {
  flex: 1;
  text-align: center;
  font-size: 10px;
  font-weight: 600;
  color: var(--muted);
  text-decoration: none;
  padding: 4px 8px;
  border-radius: 4px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  transition: background-color 0.15s ease, color 0.15s ease;
}
.notif-panel .notif-link:hover { background: var(--bg-2); color: var(--accent); }
.notif-panel .notif-link i { margin-right: 4px; }

/* — Refined neutral palette (subtle dark mode upgrade) —
 * Overrides the dark-theme tokens via a `:root` block at the bottom of
 * the file so later rules win. Light theme tokens stay untouched.
 * Existing `--accent`/`--text`/`--muted` choices stay consistent so the
 * institutional chart palette remains stable. Only the deep slate
 * backgrounds + tighter borders get the polish. */
:root {
  --bg-0:    #0a0e14;
  --bg-1:    #0f141c;
  --bg-2:    #131a24;
  --panel:   #11161d;
  --border:  #1c2330;
  --border-2:#2a3445;
  --panel-shadow: 0 1px 0 rgba(255,255,255,0.02), 0 0 0 1px rgba(255,255,255,0.01), 0 12px 24px -16px rgba(0,0,0,0.5);
}

/* End ── UI bump pass 3 ── */

/* ── EA live control ─────────────────────────────────────────────────
 * Horizontal scrollable strip of EA cards on the /risk page. One card
 * per active EA on the currently selected account; status badge, live
 * stats (open positions / floating P/L / daily realized) and Pause/Kill
 * action buttons. CSS variable fallbacks let it ride the dark + light
 * institutional themes already wired in style.css.
 * ──────────────────────────────────────────────────────────────────── */
.ea-live-strip {
  display: flex;
  gap: 12px;
  overflow-x: auto;
  padding-bottom: 4px;
  scroll-snap-type: x mandatory;
  scrollbar-width: thin;
}
.ea-live-strip::-webkit-scrollbar { height: 6px; }
.ea-live-strip::-webkit-scrollbar-thumb { background: var(--border-2); border-radius: 3px; }

.ea-card {
  flex: 0 0 280px;
  scroll-snap-align: start;
  background: var(--panel, var(--bg-1));
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
  position: relative;
}
.ea-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--panel-shadow, 0 6px 20px rgba(0,0,0,0.30));
  border-color: var(--border-2);
}
.ea-card .ea-color-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  display: inline-block;
  flex: 0 0 8px;
  box-shadow: 0 0 0 2px rgba(255,255,255,0.06);
}
.ea-card-name {
  font-weight: 600;
  font-size: 12px;
  flex: 1;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ea-card-meta {
  font-size: 10px;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
.ea-card-stats {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 4px 12px;
  font-size: 11px;
  border-top: 1px dashed var(--border);
  border-bottom: 1px dashed var(--border);
  padding: 6px 0;
}
.ea-card-stats .label {
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  font-size: 10px;
}
.ea-card-stats .val {
  font-family: 'JetBrains Mono', 'IBM Plex Mono', 'Consolas', monospace;
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.ea-card-actions {
  display: flex;
  gap: 6px;
}
.ea-card-actions .btn-inst {
  flex: 1;
  font-size: 10px;
  padding: 4px 8px;
  text-transform: uppercase;
  letter-spacing: 0.4px;
}

/* Status badge — sits in the top-right of the card name row. */
.ea-status-badge {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.6px;
  padding: 2px 6px;
  border-radius: 4px;
  text-transform: uppercase;
  border: 1px solid currentColor;
  background: transparent;
  white-space: nowrap;
}
.ea-status-active        { color: #22c55e; }
.ea-status-paused        { color: #f59e0b; }
.ea-status-kill_pending  { color: #ef4444; animation: pulse-warn 1.2s infinite; }
.ea-status-killed        { color: var(--muted); }
@keyframes pulse-warn {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.4; }
}

.ea-card.highlighted {
  box-shadow: 0 0 0 2px #1f4ec9 inset, 0 6px 20px rgba(0,0,0,0.30);
  border-color: #1f4ec9;
}
.positions-row-highlight {
  background: rgba(31,78,201,0.10) !important;
  box-shadow: inset 2px 0 0 #1f4ec9;
}

/* Light-mode tweaks for the EA strip. */
.theme-light .ea-card { background: #ffffff; }
.theme-light .ea-card:hover { box-shadow: 0 6px 20px rgba(15,30,60,0.08); }
.theme-light .ea-status-killed { color: #586176; }

/* ── Risk live equity chart ── */
.risk-live-eq-wrap {
  position: relative;
  background: var(--panel);
  border-radius: 10px;
  overflow: hidden;
  min-height: 380px;
}
.risk-live-eq-chart { position: absolute; inset: 0; }
.risk-live-eq-tooltip {
  position: absolute; top: 12px; left: 12px; z-index: 5;
  padding: 8px 12px; min-width: 200px;
  font-family: Inter, system-ui, sans-serif; font-size: 11px;
  background: rgba(13,17,23,0.85);
  color: #c9d1d9;
  border: 1px solid rgba(148,163,184,0.20);
  border-radius: 6px;
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  pointer-events: none;
  box-shadow: 0 4px 20px rgba(0,0,0,0.4);
  display: none;
}
.theme-light .risk-live-eq-tooltip {
  background: rgba(255,255,255,0.92); color: #1f2937;
  border: 1px solid rgba(15,23,42,0.12);
}
.risk-live-eq-tip-row { display: flex; justify-content: space-between; gap: 16px; line-height: 1.5; }
.risk-live-eq-tip-label { opacity: 0.6; }
.risk-live-eq-tip-val { font-family: "JetBrains Mono", monospace; font-weight: 600; }
.risk-live-eq-tip-val.pos { color: #26a69a; } .risk-live-eq-tip-val.neg { color: #ef5350; }

.risk-live-eq-tag {
  position: absolute; top: 12px; right: 12px; z-index: 5;
  padding: 6px 12px; font-family: "JetBrains Mono", monospace;
  font-size: 14px; font-weight: 700;
  background: rgba(13,17,23,0.85);
  color: #c9d1d9;
  border: 1px solid rgba(148,163,184,0.18);
  border-radius: 6px;
  backdrop-filter: blur(8px);
  display: flex; gap: 10px; align-items: baseline;
  pointer-events: none;
}
.theme-light .risk-live-eq-tag { background: rgba(255,255,255,0.92); color: #1f2937; border-color: rgba(15,23,42,0.12); }
.risk-live-eq-tag-value { font-size: 15px; }
.risk-live-eq-tag-delta { font-size: 10px; opacity: 0.85; }
.risk-live-eq-tag-delta.pos { color: #26a69a; } .risk-live-eq-tag-delta.neg { color: #ef5350; }
.theme-light .risk-live-eq-tag-delta.pos { color: #15803d; } .theme-light .risk-live-eq-tag-delta.neg { color: #b91c1c; }

.risk-live-eq-tf {
  position: absolute; bottom: 12px; left: 12px; z-index: 5;
  display: flex; gap: 4px; padding: 3px;
  background: rgba(13,17,23,0.75); border: 1px solid rgba(148,163,184,0.15);
  border-radius: 6px; backdrop-filter: blur(8px);
}
.theme-light .risk-live-eq-tf { background: rgba(255,255,255,0.90); border-color: rgba(15,23,42,0.10); }
.risk-live-eq-tf-btn {
  background: transparent; border: 0; color: var(--muted);
  font-family: Inter; font-size: 10px; font-weight: 600; letter-spacing: 0.5px;
  padding: 4px 10px; border-radius: 4px; cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.risk-live-eq-tf-btn:hover { color: var(--text); background: rgba(148,163,184,0.10); }
.risk-live-eq-tf-btn.active { background: #1f4ec9; color: #fff; }
.theme-dark .risk-live-eq-tf-btn.active { background: #26a69a; color: #0d1117; }

.risk-live-eq-reset {
  position: absolute; bottom: 12px; right: 12px; z-index: 5;
  background: rgba(13,17,23,0.75); border: 1px solid rgba(148,163,184,0.15);
  color: var(--muted); border-radius: 6px; padding: 5px 8px; font-size: 11px;
  cursor: pointer; backdrop-filter: blur(8px);
  transition: color 0.15s, border-color 0.15s;
}
.risk-live-eq-reset:hover { color: var(--text); border-color: var(--text); }
.theme-light .risk-live-eq-reset { background: rgba(255,255,255,0.90); border-color: rgba(15,23,42,0.10); }
.theme-light .positions-row-highlight { background: rgba(31,78,201,0.06) !important; }

/* ── Calendar heatmap ────────────────────────────────────────────── */
.cal-grid {
  display: grid;
  grid-template-rows: repeat(7, 1fr);
  grid-auto-flow: column;
  grid-auto-columns: 11px;
  gap: 2px;
  align-items: stretch;
  justify-content: start;
}
.cal-cell {
  width: 11px; height: 11px;
  border-radius: 2px;
  border: 1px solid rgba(148,163,184,0.08);
  cursor: pointer;
  transition: transform 0.1s;
}
.cal-cell:hover {
  transform: scale(1.4);
  border-color: var(--accent, #1f4ec9);
  position: relative;
  z-index: 2;
}
.cal-empty {
  color: var(--muted-2);
  font-size: 11px;
  padding: 18px;
  text-align: center;
}

/* ── Stress test cards (Risk decomposition panel on /risk) ─────────
 *
 * Each card represents one historical-crisis scenario. The header carries
 * the scenario label and the estimated P/L, the body shows a short text
 * description and 3 mini horizontal bars for the top-3 affected symbols.
 */
.srd-stress-card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 10px 12px;
  height: 100%;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.srd-stress-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}
.srd-stress-label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.3px;
  color: var(--fg, #e3e8f0);
}
.srd-stress-pl {
  font-size: 13px;
  font-weight: 600;
}
.srd-stress-desc {
  line-height: 1.35;
  min-height: 32px;
  /* Keep the description block compact: 2-line clamp on capable browsers. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.srd-stress-bars { display: flex; flex-direction: column; gap: 3px; }
.srd-stress-sub  { font-size: 10.5px; opacity: 0.85; }

.srd-mini-row {
  display: grid;
  grid-template-columns: 64px 1fr 72px;
  align-items: center;
  gap: 6px;
  font-size: 11px;
}
.srd-mini-sym { color: var(--muted, #a8b1c3); }
.srd-mini-bar {
  display: block;
  height: 6px;
  background: rgba(255, 255, 255, 0.06);
  border-radius: 3px;
  overflow: hidden;
}
.srd-mini-fill {
  display: block;
  height: 100%;
  background: rgba(76, 142, 255, 0.45);
}
.srd-mini-val { text-align: right; font-size: 11px; }

/* Body of the stress + decomposition panel — explicit padding hook so the
 * panel doesn't depend on a Bootstrap utility class to look right. The
 * .p-3 class wins when both are present, but adding this lets the markup
 * also use just `risk-panel-body` and still get sensible spacing. */
.risk-panel-body { padding: 12px; }

/* ── Strategy charts polish ──
 * Visual refinements for the per-strategy chart on /dashboard and the
 * TradingView lightweight-charts equity panel on /strategies/{id}.
 * Append-only — no existing rules altered.
 */

/* Per-strategy chart trace highlight: when one line is hovered, the
 * dashboard.js handler restyles the others to opacity 0.2 via Plotly.restyle.
 * This rule keeps the line transition smooth (cubic-in-out) instead of the
 * abrupt default. Applied to every Plotly SVG path inside #chartPerStrategy. */
#chartPerStrategy .scatterlayer .trace .lines path,
#chartPerStrategy .scatterlayer .trace path {
  transition: opacity 0.18s cubic-bezier(0.4, 0, 0.2, 1),
              stroke-width 0.18s cubic-bezier(0.4, 0, 0.2, 1);
}
#chartPerStrategy .annotation-text {
  transition: opacity 0.18s cubic-bezier(0.4, 0, 0.2, 1);
}
#chartPerStrategy {
  cursor: pointer;
}

/* Empty-state styling unification for the per-strategy chart and the
 * TradingView strategy detail chart. The base `.chart-empty` already covers
 * most cases; this just gives the inline (tv-chart-wrap) variant a centered
 * absolute layout so it overlays the TV container without breaking the wrap. */
.tv-chart-wrap .chart-empty {
  position: absolute;
  inset: 0;
  background: rgba(13, 17, 23, 0.55);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  z-index: 4;
  border-radius: inherit;
}
.theme-light .tv-chart-wrap .chart-empty {
  background: rgba(255, 255, 255, 0.65);
}

/* Strategy-detail price tag — picks up the EA's `color` (set inline via
 * --strat-color on the chip itself when rendered). The base .tv-pricetag
 * already handles dark/light backgrounds; this just gives the strategy
 * variant a slightly accent-tinted border so it visually ties to the line. */
.tv-strategy-tag {
  border-width: 1px;
  transition: border-color 0.2s ease;
}
.tv-strategy-tag .tv-tag-value {
  letter-spacing: 0.3px;
}

/* Hover-fade animation hint for chartPerStrategy: the per-strategy traces
 * get an inline opacity via Plotly.restyle on plotly_hover; we just provide
 * the easing curve above. As a small bonus, on touch devices we kill the
 * cursor:pointer (no hover layer there). */
@media (hover: none) {
  #chartPerStrategy { cursor: default; }
}


/* ── /copier page polish ──
 * Each link card is a glass-card with a status-tinted left border, mirroring
 * the strategy/alert-row pattern used elsewhere. Tabs reuse Bootstrap's
 * .nav-tabs but with our institutional dark palette. */
.copier-card {
  position: relative;
  transition: transform 120ms ease, box-shadow 120ms ease, border-color 120ms ease;
}
.copier-card:hover {
  transform: translateY(-1px);
  border-color: var(--border-2);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35);
}
.copier-card .copier-card-name { font-size: 13px; line-height: 1.3; }
.copier-card .copier-card-flow { font-size: 11px; letter-spacing: 0.3px; }
.copier-card .copier-card-key  { font-size: 10.5px; opacity: 0.85; word-break: break-all; }

/* Tabs inside the per-link drill-down. Match the dark palette by
 * suppressing Bootstrap's white tab backgrounds. */
.copier-tabs.nav-tabs { border-bottom-color: var(--border); }
.copier-tabs .nav-link {
  color: var(--muted-2);
  background: transparent;
  border: 1px solid transparent;
  border-bottom: none;
  font-size: 12px;
  letter-spacing: 0.3px;
  padding: 6px 12px;
  margin-right: 2px;
}
.copier-tabs .nav-link:hover { color: var(--text); border-color: var(--border); }
.copier-tabs .nav-link.active {
  color: var(--text);
  background: var(--panel);
  border-color: var(--border) var(--border) var(--panel);
}

/* ===========================================================================
 * ════════════════  INSTITUTIONAL POLISH — PASS 4  ════════════════
 * ===========================================================================
 * Global "institutional terminal" tightening: a coherent type scale + spacing
 * rhythm, refined dark/light depth, sharper micro-interactions, denser tables,
 * a cleaner nav shell and unified KPI / badge / button / scrollbar treatments.
 *
 * APPEND-ONLY and source-order-last, so these rules win over earlier passes
 * without removing a single selector the JS/templates depend on. Everything is
 * expressed through the existing CSS variables so both themes flip for free.
 * Variables reused: --space-*, --easing, --font-ui, --font-mono, --panel-shadow.
 * =========================================================================== */

/* ── 4.0 · Design tokens — radii, ring, elevation, type scale ──────────────
 * Consolidated knobs so the whole system tunes from one place. */
:root {
  --radius-xs: 3px;
  --radius-sm: 4px;
  --radius-md: 6px;
  --radius-lg: 10px;
  --radius-pill: 100px;

  --ring: 0 0 0 3px rgba(110, 145, 230, 0.30);   /* accent focus ring (dark) */
  --hairline: rgba(255, 255, 255, 0.05);          /* subtle divider (dark)    */

  /* Elevation scale — layered, never a single flat blur. */
  --elev-1: 0 1px 0 rgba(0,0,0,0.25), 0 1px 2px rgba(0,0,0,0.25);
  --elev-2: 0 1px 0 rgba(0,0,0,0.20), 0 4px 14px -6px rgba(0,0,0,0.55);
  --elev-3: 0 2px 0 rgba(0,0,0,0.20), 0 18px 40px -18px rgba(0,0,0,0.70);

  /* Type scale (institutional, dense). Used by the rules below + available
   * as utilities. Line-heights tuned for a terminal cadence. */
  --fs-caption: 10px;   /* uppercase micro-labels                 */
  --fs-label:   11px;   /* secondary text, table cells            */
  --fs-body:    12px;   /* default body                           */
  --fs-base:    13px;   /* base UI                                */
  --fs-h3:      14px;   /* panel / page sub-titles                */
  --fs-h2:      17px;   /* KPI values, section titles             */
  --fs-h1:      20px;   /* page hero titles                       */
  --fs-display: 26px;   /* marketing / hero numerals              */
  --lh-tight:   1.2;
  --lh-snug:    1.35;
  --lh-normal:  1.5;
}
:root[data-bs-theme="light"] {
  --ring: 0 0 0 3px rgba(31, 78, 201, 0.18);
  --hairline: rgba(13, 17, 23, 0.06);
  --elev-1: 0 1px 0 rgba(15,23,42,0.04), 0 1px 2px rgba(15,23,42,0.05);
  --elev-2: 0 1px 0 rgba(15,23,42,0.04), 0 6px 18px -8px rgba(15,23,42,0.12);
  --elev-3: 0 2px 0 rgba(15,23,42,0.04), 0 18px 40px -16px rgba(15,23,42,0.18);
}

/* ── 4.1 · Base typography & rhythm ─────────────────────────────────────── */
html, body {
  font-size: var(--fs-base);
  line-height: var(--lh-normal);
  letter-spacing: -0.005em;       /* a hair tighter — premium Inter feel */
  text-rendering: optimizeLegibility;
}
body { color: var(--text); }

/* Numerals everywhere read as aligned tabular figures. */
.num, .mono, .tabular,
table.dt td, table.dt th.r, table.dt td.r,
.kpi-tile .value, .kpi-tile .sub {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1, "cv01" 1;
}

/* Uppercase micro-label utility — unifies every eyebrow/caption. */
.app-navbar .nav-link,
.panel-header, .filter-label, .kpi-tile .label,
.snippet-label, .sidebar h6, .filter-sidebar h6,
table.dt th, .dt thead th {
  font-feature-settings: "cpsp" 1;   /* capital spacing */
}

/* Page titles: consistent weight + measured tracking across the system. */
.page-header .page-title { font-size: var(--fs-h3); font-weight: 650; letter-spacing: 0.3px; }
.strat-header .strat-title { font-size: var(--fs-h1); font-weight: 700; letter-spacing: -0.1px; }
/* Dashboard sub-header eyebrow title — same rank as page-title. */
.subheader-title { font-size: var(--fs-h3); font-weight: 650; letter-spacing: 0.7px; color: var(--text); }
/* Toggle-group buttons read as compact captions without per-button inline css. */
.toggle-group .btn-inst { font-size: var(--fs-caption); letter-spacing: 0.4px; }

/* ── 4.2 · Theme-switch smoothing ──────────────────────────────────────────
 * One global, cheap transition on colour-bearing properties so toggling the
 * theme cross-fades instead of snapping. Charts/canvas opt out (perf + flicker)
 * and anyone with reduced-motion gets none of it. */
body, .panel, .glass-card, .sidebar, .filter-sidebar, .kpi-tile,
.journal-card, .ea-card, .badge-inst, .btn-inst, .app-navbar,
.status-bar, table.dt th, table.dt td {
  transition: background-color 0.35s ease, border-color 0.35s ease,
              color 0.35s ease, box-shadow 0.25s ease;
}
canvas, svg, .js-plotly-plot, .tv-chart-wrap, .tv-chart-wrap * { transition: none; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

/* ── 4.3 · Selection ───────────────────────────────────────────────────── */
::selection { background: rgba(110, 145, 230, 0.32); color: #fff; }
.theme-light ::selection { background: rgba(31, 78, 201, 0.18); color: #0d1117; }

/* ── 4.4 · Nav / shell ─────────────────────────────────────────────────────
 * Sticky navbar gains a translucent, blurred backdrop so content scrolls
 * underneath it like a desk terminal. Active links get a clean centred pill +
 * underline indicator. Bell / theme / session controls align on one baseline. */
.app-navbar {
  background: color-mix(in srgb, var(--bg-1) 86%, transparent);
  -webkit-backdrop-filter: saturate(140%) blur(10px);
  backdrop-filter: saturate(140%) blur(10px);
  border-bottom: 1px solid var(--border);
  box-shadow: 0 1px 0 var(--hairline);
}
.theme-light .app-navbar {
  background: color-mix(in srgb, var(--bg-1) 88%, transparent);
}
.app-navbar .navbar-brand { letter-spacing: 0.3px; }
.app-navbar .brand-mark svg { color: var(--accent); }

.app-navbar .nav-link {
  position: relative;
  color: var(--muted);
  border-radius: var(--radius-xs);
  transition: color 0.15s ease, background-color 0.15s ease;
}
.app-navbar .nav-link i { opacity: 0.85; margin-right: 2px; }
.app-navbar .nav-link:hover { color: var(--text); background: var(--bg-2); }
/* Underline indicator (override the earlier border-radius hack). */
.app-navbar .nav-link.active {
  color: var(--text);
  background: var(--bg-2);
  border-bottom: 0;
  border-radius: var(--radius-xs);
}
.app-navbar .nav-link.active::after {
  content: "";
  position: absolute;
  left: 8px; right: 8px; bottom: -7px; height: 2px;
  background: var(--accent);
  border-radius: 2px 2px 0 0;
  box-shadow: 0 0 8px color-mix(in srgb, var(--accent) 60%, transparent);
}

/* Nav control buttons (bell, theme toggle, session) — quiet ghost squares
 * that tie into the institutional palette instead of Bootstrap greys. */
.app-navbar .btn-outline-secondary,
.app-navbar .btn-outline-success {
  border-color: var(--border);
  color: var(--muted);
  background: transparent;
  border-radius: var(--radius-sm);
  transition: color 0.15s ease, border-color 0.15s ease, background-color 0.15s ease;
}
.app-navbar .btn-outline-secondary:hover,
.app-navbar .btn-outline-success:hover {
  color: var(--text);
  border-color: var(--border-2);
  background: var(--bg-2);
}
.app-navbar .navbar-text .badge.bg-secondary {
  background: var(--bg-2) !important;
  color: var(--muted);
  border: 1px solid var(--border);
  font-weight: 600;
  letter-spacing: 0.3px;
  font-size: 9px;
  text-transform: uppercase;
}
.app-navbar .status-dot { box-shadow: 0 0 8px currentColor; }

/* ── 4.5 · Panels & depth ──────────────────────────────────────────────────
 * Resting elevation + a slightly stronger lift on hover, layered (never flat). */
.panel, .glass-card {
  box-shadow: var(--elev-1);
  border-radius: var(--radius-sm);
}
.theme-light .panel,
.theme-light .glass-card,
.theme-light .sidebar { box-shadow: var(--panel-shadow); }

@media (hover: hover) {
  .panel:hover {
    box-shadow: var(--elev-2);
    border-color: var(--border-2);
  }
  .theme-light .panel:hover { box-shadow: var(--elev-2); }
}

/* Panel header: crisper micro-label, tighter baseline. */
.panel-header {
  padding: var(--space-2) var(--space-3);
  font-size: var(--fs-caption);
  letter-spacing: 0.8px;
  color: var(--muted);
}
.panel-header > span:first-child { display: inline-flex; align-items: center; gap: 6px; }
.panel-header i { color: var(--accent); opacity: 0.9; }
.panel-body { padding: var(--space-3); }

/* ── 4.6 · KPI tiles — unified hierarchy & accent gradient ──────────────────
 * One look for `.kpi-tile` across dashboard + strategy detail. Crisp value,
 * muted uppercase label, dim mono sub. Subtle directional gradient + lift. */
.kpi-tile {
  padding: var(--space-3);
  gap: 3px;
  border-radius: var(--radius-sm);
  background-image: linear-gradient(135deg, rgba(110,145,230,0.07), transparent 62%);
}
.kpi-tile .label {
  font-size: var(--fs-caption);
  letter-spacing: 0.7px;
  color: var(--muted);
  line-height: var(--lh-tight);
}
.kpi-tile .value {
  font-family: var(--font-mono);
  font-size: var(--fs-h2);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: var(--text);
}
.kpi-tile .sub {
  font-size: var(--fs-caption);
  color: var(--muted-2);
  font-family: var(--font-mono);
  line-height: var(--lh-tight);
}
/* Left accent rail reads stronger + tinted gradient per semantic state. */
.kpi-tile::before { width: 3px; }
.kpi-tile.pos  { background-image: linear-gradient(135deg, rgba(63,166,122,0.10), transparent 62%); }
.kpi-tile.neg  { background-image: linear-gradient(135deg, rgba(213,102,102,0.10), transparent 62%); }
.kpi-tile.warn { background-image: linear-gradient(135deg, rgba(224,163,93,0.10), transparent 62%); }
@media (hover: hover) {
  .kpi-tile:hover { transform: translateY(-1px); box-shadow: var(--elev-2); border-color: var(--border-2); }
}
.theme-light .kpi-tile {
  background-image: linear-gradient(135deg, rgba(31,78,201,0.05), transparent 60%);
}
.theme-light .kpi-tile.pos  { background-image: linear-gradient(135deg, rgba(21,128,61,0.07), transparent 60%); }
.theme-light .kpi-tile.neg  { background-image: linear-gradient(135deg, rgba(185,28,28,0.06), transparent 60%); }
.theme-light .kpi-tile.warn { background-image: linear-gradient(135deg, rgba(180,83,9,0.07), transparent 60%); }

/* ── 4.7 · Tables — denser, hairline rows, sticky uppercase headers ─────────
 * Applies to both `table.dt` and Bootstrap `.table` inside our panels. */
table.dt { font-size: var(--fs-label); }
table.dt th, .dt thead th {
  font-size: var(--fs-caption);
  letter-spacing: 0.7px;
  font-weight: 600;
  color: var(--muted);
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--border);
  background: var(--bg-1);
  white-space: nowrap;
}
.theme-light table.dt th, .theme-light .dt thead th { background: var(--bg-2); }
table.dt td {
  padding: 6px var(--space-3);
  border-bottom: 1px solid var(--hairline);
}
.theme-light table.dt td { border-bottom: 1px solid var(--hairline); }
/* Hover highlight uses the accent at low alpha, in both themes. */
table.dt tbody tr { transition: background-color 0.12s ease; }
table.dt tbody tr:hover td { background: rgba(110,145,230,0.06); }
.theme-light table.dt tbody tr:hover td { background: rgba(31,78,201,0.055); }
/* Label cells use the UI font; numeric cells stay mono. */
table.dt td.label-cell, table.dt td.strat-name { font-family: var(--font-ui); }

/* Bootstrap tables that live inside our panels inherit the institutional skin. */
.panel .table, .glass-card .table {
  --bs-table-bg: transparent;
  --bs-table-color: var(--text);
  color: var(--text);
  font-size: var(--fs-label);
  margin-bottom: 0;
}
.panel .table > :not(caption) > * > * { border-bottom-color: var(--hairline); }
.panel .table > thead th {
  text-transform: uppercase;
  font-size: var(--fs-caption);
  letter-spacing: 0.7px;
  color: var(--muted);
  background: var(--bg-1);
  border-bottom: 1px solid var(--border);
}
.theme-light .panel .table > thead th { background: var(--bg-2); }

/* ── 4.8 · Badges, chips, buttons — unified radius / padding / hover ───────── */
.badge-inst {
  font-size: var(--fs-caption);
  padding: 2px 7px;
  border-radius: var(--radius-xs);
  letter-spacing: 0.4px;
  line-height: 1.5;
  font-family: var(--font-mono);
  transition: border-color 0.15s ease, color 0.15s ease, background-color 0.15s ease;
}
.badge-inst.pos { background: color-mix(in srgb, var(--pos) 10%, transparent); }
.badge-inst.neg { background: color-mix(in srgb, var(--neg) 10%, transparent); }

.btn-inst {
  font-size: var(--fs-label);
  letter-spacing: 0.4px;
  padding: 5px 12px;
  border-radius: var(--radius-sm);
  font-weight: 550;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  line-height: 1.3;
}
.btn-inst i { opacity: 0.9; }
.btn-inst:active { transform: translateY(1px); }
/* Compact + extra-compact size variants (replace repeated inline font/padding). */
.btn-inst.sm { font-size: var(--fs-caption); padding: 4px 9px; }
.btn-inst.xs { font-size: var(--fs-caption); padding: 3px 7px; letter-spacing: 0.3px; }
.btn-inst.primary {
  background: linear-gradient(180deg, color-mix(in srgb, var(--accent) 78%, #5577dd), color-mix(in srgb, var(--accent) 55%, #21347e));
  border-color: color-mix(in srgb, var(--accent) 55%, #21347e);
  color: #fff;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.12);
}
.btn-inst.primary:hover { filter: brightness(1.08); box-shadow: inset 0 1px 0 rgba(255,255,255,0.15), 0 2px 10px -2px color-mix(in srgb, var(--accent) 55%, transparent); }
.theme-light .btn-inst.primary {
  background: linear-gradient(180deg, #3b6fd1, #2c52a8);
  border-color: #2c52a8;
  color: #fff;
}

/* ── 4.9 · Inputs — accent focus ring + crisp resting state ───────────────── */
.filter-input, .filter-select,
.form-control, .form-select,
.filter-row .form-control-sm, .filter-row .form-select-sm {
  border-radius: var(--radius-sm);
  transition: border-color 0.15s ease, box-shadow 0.15s ease, background-color 0.2s ease;
}
.filter-input:focus, .filter-select:focus,
.form-control:focus, .form-select:focus,
.filter-row .form-control-sm:focus, .filter-row .form-select-sm:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: var(--ring);
}
input::placeholder, textarea::placeholder { color: var(--muted-2); opacity: 0.8; }

/* ── 4.10 · Scrollbars — thin custom rails, both themes ────────────────────
 * Firefox via scrollbar-width/color; WebKit via ::-webkit-scrollbar. Scoped to
 * the scrolling containers we own so we never fight the OS chrome elsewhere. */
.scroll-y, .table-responsive, .alerts-list-rich, .notif-panel, .ea-live-strip {
  scrollbar-width: thin;
  scrollbar-color: var(--border-2) transparent;
}
.scroll-y::-webkit-scrollbar,
.table-responsive::-webkit-scrollbar,
.alerts-list-rich::-webkit-scrollbar,
.notif-panel::-webkit-scrollbar { width: 8px; height: 8px; }
.scroll-y::-webkit-scrollbar-track,
.table-responsive::-webkit-scrollbar-track,
.alerts-list-rich::-webkit-scrollbar-track,
.notif-panel::-webkit-scrollbar-track { background: transparent; }
.scroll-y::-webkit-scrollbar-thumb,
.table-responsive::-webkit-scrollbar-thumb,
.alerts-list-rich::-webkit-scrollbar-thumb,
.notif-panel::-webkit-scrollbar-thumb {
  background: var(--border-2);
  border-radius: var(--radius-pill);
  border: 2px solid transparent;
  background-clip: padding-box;
}
.scroll-y::-webkit-scrollbar-thumb:hover,
.table-responsive::-webkit-scrollbar-thumb:hover,
.alerts-list-rich::-webkit-scrollbar-thumb:hover,
.notif-panel::-webkit-scrollbar-thumb:hover { background: var(--muted-2); background-clip: padding-box; }

/* ── 4.11 · Empty states — consistent, calmer ──────────────────────────────  */
.empty-state { padding: var(--space-10) var(--space-4); gap: var(--space-2); }
.empty-state i { font-size: 30px; opacity: 0.45; }
.empty-state .es-title { font-size: var(--fs-body); font-weight: 600; letter-spacing: 0.3px; color: var(--text); }
.empty-state .es-hint { font-size: var(--fs-label); color: var(--muted-2); line-height: var(--lh-snug); }
.empty-state a { color: var(--accent); text-decoration: none; }
.empty-state a:hover { text-decoration: underline; }

/* ── 4.12 · Sticky sub-header — align blur radius to the navbar height ────── */
.sticky-subheader {
  top: 49px;
  -webkit-backdrop-filter: saturate(140%) blur(10px);
  backdrop-filter: saturate(140%) blur(10px);
}

/* ── 4.13 · Status bar — hairline top + crisper labels ─────────────────────  */
.status-bar { box-shadow: 0 -1px 0 var(--hairline); }
.status-bar .status-label { letter-spacing: 0.7px; }

/* ── 4.14 · Marketing / auth surfaces (index, login) ───────────────────────
 * The landing + login cards used raw Bootstrap greens/whites — pull them into
 * the institutional palette so they don't feel like a different product. */
.glass-card .text-success,
.glass-card h1 .text-success,
.glass-card h4 .text-success { color: var(--accent) !important; }
/* Hero / login icons read in the brand accent. */
.index-hero h1 > i.bi,
.index-hero h6 > i.bi,
.login-card h4 > i.bi { color: var(--accent); }
.index-hero h6 { font-size: var(--fs-h3); font-weight: 650; color: var(--text); }
.btn-success {
  background: linear-gradient(180deg, color-mix(in srgb, var(--pos) 92%, #fff), color-mix(in srgb, var(--pos) 70%, #000));
  border: 1px solid color-mix(in srgb, var(--pos) 60%, #000);
  color: #fff;
}
.btn-success:hover { filter: brightness(1.06); color: #fff; }
.index-hero .glass-card { box-shadow: var(--elev-3); }

/* ── 4.15 · Focus-visible for keyboard users (a11y, both themes) ──────────── */
a:focus-visible, button:focus-visible,
.btn-inst:focus-visible, .nav-link:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}

/* End ════════════  INSTITUTIONAL POLISH — PASS 4  ════════════ */


/* ===========================================================================
 * ════════════  PASS 5 — HEDGE-FUND TERMINAL  ════════════
 * ===========================================================================
 * The definitive institutional layer (Bloomberg / Aladdin / Two-Sigma feel).
 * APPEND-ONLY and SOURCE-ORDER-LAST: every rule here is additive and wins over
 * earlier passes by cascade, so NOT A SINGLE existing class/selector that the
 * JS or risk/copier templates rely on is removed or renamed. Everything is
 * expressed through the existing design tokens (--bg-*, --panel, --border*,
 * --accent, --pos/--neg, --space-*, --font-*, --easing, --elev-*, --radius-*),
 * so both the dark and light themes flip for free.
 *
 * Index
 *   5.0  Token refinement — deeper desaturated palette + new semantic tokens
 *   5.1  Typographic system — precise scale, tracking, optical numerics
 *   5.2  Nav / shell — terminal top accent strip, aligned controls
 *   5.3  Panels & depth — hairline chrome, header rhythm, chart wrappers
 *   5.4  KPI tiles — value/label/sub rank, accent rail, calm lift
 *   5.5  Data tables (.dt) — risk-report density, P&L tinting helpers
 *   5.6  Badges / chips / buttons — refined press + accent discipline
 *   5.7  Inputs & focus rings — 3px accent-soft, crisp resting state
 *   5.8  Account / strategy cards — unified card grammar
 *   5.9  Status bar / live pills — terminal footer polish
 *   5.10 Scrollbars — thin rails (WebKit + Firefox), both themes
 *   5.11 Empty states / spinners / selection — calm micro-interactions
 *   5.12 Per-page once-over — utility classes that retire template inline css
 *   5.13 Reduced-motion guard (re-assert, last word)
 * =========================================================================== */

/* ── 5.0 · Token refinement ─────────────────────────────────────────────────
 * A hair deeper + more desaturated dark palette (navy/slate, never pure black),
 * warmer off-white light surfaces, and a set of NEW semantic tokens used by the
 * rules below. New names only — no existing token is dropped. */
:root {
  /* Dark: deep desaturated slate-navy with layered elevations. */
  --bg-0:    #090d13;
  --bg-1:    #0e131b;
  --bg-2:    #131a25;
  --panel:   #101620;
  --panel-2: #141c28;          /* second elevation surface (insets, heads)   */
  --border:  #1b2230;
  --border-2:#2a3447;

  /* New semantic / system tokens (referenced throughout pass 5). */
  --accent-soft:   rgba(110, 145, 230, 0.16);   /* focus rings, soft fills    */
  --accent-line:   rgba(110, 145, 230, 0.45);   /* accent hairline / rails    */
  --accent-glow:   rgba(110, 145, 230, 0.55);
  --pos-soft:      rgba(63, 166, 122, 0.14);
  --neg-soft:      rgba(213, 102, 102, 0.14);
  --warn-soft:     rgba(224, 163, 93, 0.14);
  --hairline-strong: rgba(255, 255, 255, 0.08);
  --inset-shadow:  inset 0 1px 0 rgba(255,255,255,0.03);
  --row-hover:     rgba(110, 145, 230, 0.06);
  --row-zebra:     rgba(255, 255, 255, 0.013);
  --tnum: "tnum" 1, "cv01" 1, "ss01" 1;          /* aligned, single-storey 1  */
}
:root[data-bs-theme="light"] {
  /* Light: warm off-white / parchment, soft layered shadows (no sterile #fff). */
  --bg-0:    #f1f3f7;
  --bg-1:    #fbfcfe;
  --bg-2:    #eaeef4;
  --panel:   #ffffff;
  --panel-2: #f6f8fb;
  --border:  #e2e7ef;
  --border-2:#c6d0dd;

  --accent-soft:   rgba(31, 78, 201, 0.12);
  --accent-line:   rgba(31, 78, 201, 0.40);
  --accent-glow:   rgba(31, 78, 201, 0.35);
  --pos-soft:      rgba(21, 128, 61, 0.10);
  --neg-soft:      rgba(185, 28, 28, 0.09);
  --warn-soft:     rgba(180, 83, 9, 0.10);
  --hairline-strong: rgba(13, 17, 23, 0.08);
  --inset-shadow:  inset 0 1px 0 rgba(255,255,255,0.6);
  --row-hover:     rgba(31, 78, 201, 0.055);
  --row-zebra:     rgba(13, 17, 23, 0.018);
  --panel-shadow:  0 1px 0 rgba(15,23,42,0.03), 0 1px 2px rgba(15,23,42,0.05), 0 6px 16px -10px rgba(15,23,42,0.10);
}

/* ── 5.1 · Typographic system ───────────────────────────────────────────────
 * One coherent rank: page title > panel title > kpi value > labels > caption.
 * Numerics everywhere read as condensed, aligned tabular figures. */
html, body {
  font-family: var(--font-ui);
  letter-spacing: -0.006em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Every numeric surface: tabular, single-storey, slightly tight tracking so
 * columns of figures align like a risk report. */
.mono, .num, .tabular,
table.dt td, table.dt th.r, table.dt td.r,
.kpi-tile .value, .kpi-tile .sub,
.risk-kpi-value, .risk-kpi-sub,
.acct-equity, .acct-metric-value, .acct-equity-sub,
.badge-inst, .lim-value, .status-bar {
  font-variant-numeric: tabular-nums;
  font-feature-settings: var(--tnum);
}

/* Uppercase micro-labels: deliberate tracking + capital-spacing, never shouty. */
.panel-header, .filter-label, .kpi-tile .label,
.snippet-label, .sidebar h6, .filter-sidebar h6,
.app-navbar .nav-link, table.dt th, .dt thead th,
.risk-kpi-label, .acct-metric-label, .status-label,
.subheader-title, .notif-title {
  font-feature-settings: "cpsp" 1, "ss01" 1;
}

/* Visual-rank anchors (sizes already exist as tokens; we lock weight/tracking). */
.page-header .page-title   { font-size: var(--fs-h3);  font-weight: 650; letter-spacing: 0.3px; }
.strat-header .strat-title { font-size: var(--fs-h1);  font-weight: 720; letter-spacing: -0.2px; }
.subheader-title           { font-size: var(--fs-h3);  font-weight: 680; letter-spacing: 0.65px; }
.panel-header              { font-weight: 620; }
.kpi-tile .value           { font-weight: 620; letter-spacing: -0.02em; }
/* analyze.html page hero (inline <h1>) — pull into the same rank as page-title. */
#analyzeHeader h1          { font-size: var(--fs-h1) !important; font-weight: 720; letter-spacing: -0.2px; }

/* A reusable caption utility for templates that previously used inline css. */
.eyebrow {
  font-size: var(--fs-caption);
  letter-spacing: 0.7px;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 600;
}

/* ── 5.2 · Nav / shell — terminal top accent strip + aligned controls ──────── */
/* Thin status-strip line across the very top of the navbar: the signature
 * "terminal" cue. Sits inside the existing sticky navbar, costs no layout. */
.app-navbar {
  position: relative;
  background: color-mix(in srgb, var(--bg-1) 88%, transparent);
  -webkit-backdrop-filter: saturate(145%) blur(12px);
  backdrop-filter: saturate(145%) blur(12px);
  border-bottom: 1px solid var(--border);
  box-shadow: 0 1px 0 var(--hairline-strong);
}
.app-navbar::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 0; height: 2px;
  background: linear-gradient(90deg,
    transparent 0%,
    var(--accent-line) 18%,
    var(--accent) 50%,
    var(--accent-line) 82%,
    transparent 100%);
  opacity: 0.7;
  pointer-events: none;
}
.app-navbar .brand-mark svg { color: var(--accent); filter: drop-shadow(0 0 6px var(--accent-glow)); }
.app-navbar .brand-name { font-weight: 720; letter-spacing: 0.4px; }

/* Active link: crisp centred underline pill (re-asserted last). */
.app-navbar .nav-link { font-weight: 540; }
.app-navbar .nav-link.active::after {
  left: 9px; right: 9px; bottom: -7px; height: 2px;
  background: var(--accent);
  box-shadow: 0 0 8px var(--accent-glow);
}
/* Nav control cluster: bell / theme / session optically aligned on one row. */
.app-navbar .navbar-text { gap: 0.65rem; }
.app-navbar .notif-btn,
.app-navbar #themeToggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; padding: 0;
}
.app-navbar #sessionSlot .btn,
.app-navbar #sessionSlot .badge { vertical-align: middle; }

/* ── 5.3 · Panels & depth — hairline chrome + chart-wrapper hygiene ────────── */
.panel, .glass-card {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  box-shadow: var(--elev-1);
}
.theme-light .panel,
.theme-light .glass-card,
.theme-light .sidebar { box-shadow: var(--panel-shadow); }

/* Panel header: tighter cadence, accent icon, hairline base. The base 1px
 * gradient border from pass-VISUAL stays; we just tune type + spacing. */
.panel-header {
  padding: 9px var(--space-3);
  font-size: var(--fs-caption);
  letter-spacing: 0.85px;
  color: var(--muted);
  min-height: 36px;
}
.panel-header > span:first-child { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }
.panel-header i { color: var(--accent); opacity: 0.92; }
.panel-body { padding: var(--space-3); }
.panel-body.compact { padding: var(--space-2); }

/* Chart wrappers: clean, no overflow glitches, consistent rounded inner area.
 * Applies to every Plotly `.chart` and TradingView `.tv-chart-wrap` we own. */
.panel .chart, .panel .tv-chart-wrap { border-radius: 0 0 var(--radius-sm) var(--radius-sm); }
.panel-body.no-padding > .chart,
.panel-body.no-padding > .tv-chart-wrap { overflow: hidden; }
.js-plotly-plot, .js-plotly-plot * { outline: none; }
/* Plotly tick labels read in the UI font, a hair lighter so the grid recedes. */
.js-plotly-plot .xtick text, .js-plotly-plot .ytick text {
  font-family: var(--font-ui) !important;
}

/* ── 5.4 · KPI tiles — unified value/label/sub rank + calm lift ────────────── */
.kpi-tile {
  padding: var(--space-3);
  gap: 3px;
  border-radius: var(--radius-sm);
  background-image: linear-gradient(135deg, var(--accent-soft), transparent 60%);
  box-shadow: var(--elev-1), var(--inset-shadow);
}
.theme-light .kpi-tile { box-shadow: var(--panel-shadow); }
.kpi-tile .label {
  font-size: var(--fs-caption);
  letter-spacing: 0.7px;
  text-transform: uppercase;
  color: var(--muted);
  line-height: var(--lh-tight);
}
.kpi-tile .value {
  font-family: var(--font-mono);
  font-size: var(--fs-h2);
  line-height: 1.12;
  color: var(--text);
}
.kpi-tile .sub {
  font-size: var(--fs-caption);
  color: var(--muted-2);
  font-family: var(--font-mono);
  line-height: var(--lh-tight);
}
.kpi-tile::before { width: 3px; background: var(--border-2); }
.kpi-tile.pos::before  { background: var(--pos); }
.kpi-tile.neg::before  { background: var(--neg); }
.kpi-tile.warn::before { background: var(--warn); }
.kpi-tile.pos  { background-image: linear-gradient(135deg, var(--pos-soft),  transparent 60%); }
.kpi-tile.neg  { background-image: linear-gradient(135deg, var(--neg-soft),  transparent 60%); }
.kpi-tile.warn { background-image: linear-gradient(135deg, var(--warn-soft), transparent 60%); }
@media (hover: hover) {
  .kpi-tile { transition: transform 0.2s var(--easing), box-shadow 0.2s var(--easing), border-color 0.18s var(--easing); }
  .kpi-tile:hover { transform: translateY(-2px); box-shadow: var(--elev-2); border-color: var(--border-2); }
}

/* The /risk KPI tiles share the same family — keep their value rank in lockstep
 * so the dashboard and risk monitor read as one product. */
.risk-kpi .risk-kpi-value { letter-spacing: -0.015em; }

/* ── 5.5 · Data tables (.dt) — reads like a risk report ─────────────────────
 * Sticky uppercase muted headers, hairline separators, right-aligned mono
 * figures, subtle hover, optional zebra, P&L cell tinting helpers. */
table.dt { font-size: var(--fs-label); border-collapse: collapse; width: 100%; }
table.dt th, .dt thead th {
  position: sticky; top: 0; z-index: 1;
  font-size: var(--fs-caption);
  letter-spacing: 0.7px;
  text-transform: uppercase;
  font-weight: 640;
  color: var(--muted);
  padding: 7px var(--space-3);
  background: var(--bg-1);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.theme-light table.dt th, .theme-light .dt thead th { background: var(--bg-2); }
table.dt th.r, table.dt td.r { text-align: right; }
table.dt td {
  padding: 6px var(--space-3);
  border-bottom: 1px solid var(--hairline);
  font-family: var(--font-mono);
  color: var(--text);
  vertical-align: middle;
}
table.dt td.label-cell, table.dt td.strat-name { font-family: var(--font-ui); }
table.dt tbody tr { transition: background-color 0.12s ease; }
table.dt tbody tr:hover td { background: var(--row-hover); }
table.dt td.pos { color: var(--pos); }
table.dt td.neg { color: var(--neg); }
/* P&L numbers carry a touch more weight so winners/losers pop in a dense grid. */
table.dt td.pos, table.dt td.neg { font-weight: 560; }

/* Opt-in zebra striping for very long ledgers: add `.zebra` on the table. */
table.dt.zebra tbody tr:nth-child(even) td { background: var(--row-zebra); }
table.dt.zebra tbody tr:hover td { background: var(--row-hover); }

/* First/last data columns get a hair more breathing room from the panel edge. */
table.dt th:first-child, table.dt td:first-child { padding-left: var(--space-3); }
table.dt th:last-child,  table.dt td:last-child  { padding-right: var(--space-3); }

/* Bootstrap `.table` inside our panels inherits the institutional skin. */
.panel .table, .glass-card .table {
  --bs-table-bg: transparent;
  --bs-table-color: var(--text);
  color: var(--text); font-size: var(--fs-label); margin-bottom: 0;
}
.panel .table > :not(caption) > * > * { border-bottom-color: var(--hairline); }
.panel .table > thead th {
  text-transform: uppercase; font-size: var(--fs-caption);
  letter-spacing: 0.7px; color: var(--muted);
  background: var(--bg-1); border-bottom: 1px solid var(--border);
}
.theme-light .panel .table > thead th { background: var(--bg-2); }

/* ── 5.6 · Badges / chips / buttons ─────────────────────────────────────────  */
.badge-inst {
  font-size: var(--fs-caption);
  padding: 2px 7px;
  border-radius: var(--radius-xs);
  letter-spacing: 0.4px;
  line-height: 1.5;
  font-family: var(--font-mono);
  background: var(--bg-2);
  color: var(--muted);
  border: 1px solid var(--border);
}
.badge-inst.pos { color: var(--pos); border-color: var(--accent-line); border-color: color-mix(in srgb, var(--pos) 42%, transparent); background: var(--pos-soft); }
.badge-inst.neg { color: var(--neg); border-color: color-mix(in srgb, var(--neg) 42%, transparent); background: var(--neg-soft); }

.btn-inst {
  font-size: var(--fs-label);
  letter-spacing: 0.4px;
  padding: 5px 12px;
  border-radius: var(--radius-sm);
  font-weight: 560;
  display: inline-flex; align-items: center; gap: 6px; line-height: 1.3;
  background: var(--bg-2);
  border: 1px solid var(--border);
  color: var(--text);
}
.btn-inst:hover { background: var(--panel-2); border-color: var(--border-2); }
.btn-inst i { opacity: 0.9; }
.btn-inst:active { transform: translateY(1px); }
.btn-inst.ghost { background: transparent; }
.btn-inst.ghost:hover { background: var(--bg-2); border-color: var(--border-2); }
.btn-inst.sm { font-size: var(--fs-caption); padding: 4px 9px; }
.btn-inst.xs { font-size: var(--fs-caption); padding: 3px 7px; letter-spacing: 0.3px; }
.btn-inst.primary {
  background: linear-gradient(180deg, color-mix(in srgb, var(--accent) 80%, #5577dd), color-mix(in srgb, var(--accent) 55%, #21347e));
  border-color: color-mix(in srgb, var(--accent) 55%, #21347e);
  color: #fff;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.12);
}
.btn-inst.primary:hover {
  filter: brightness(1.08);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.16), 0 2px 12px -3px var(--accent-glow);
}
.theme-light .btn-inst { background: #ffffff; }
.theme-light .btn-inst.ghost { background: transparent; }
.theme-light .btn-inst.primary { background: linear-gradient(180deg, #3b6fd1, #2c52a8); border-color: #2c52a8; color: #fff; }

/* tag-chip (journal) — keep working; just refine resting + active. */
.tag-chip { font-family: var(--font-mono); letter-spacing: 0.3px; }
.tag-chip.active { box-shadow: 0 0 0 1px var(--accent-line); }

/* ── 5.7 · Inputs & focus rings — 3px accent-soft ──────────────────────────  */
.filter-input, .filter-select,
.form-control, .form-select,
.filter-row .form-control-sm, .filter-row .form-select-sm {
  border-radius: var(--radius-sm);
  background: var(--bg-2);
  border: 1px solid var(--border);
  color: var(--text);
  transition: border-color 0.15s ease, box-shadow 0.15s ease, background-color 0.2s ease;
}
.theme-light .filter-input, .theme-light .filter-select,
.theme-light .form-control, .theme-light .form-select,
.theme-light .filter-row .form-control-sm, .theme-light .filter-row .form-select-sm { background: #ffffff; }
.filter-input:focus, .filter-select:focus,
.form-control:focus, .form-select:focus,
.filter-row .form-control-sm:focus, .filter-row .form-select-sm:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.theme-light .form-control:focus, .theme-light .form-select:focus { background: #ffffff; color: var(--text); }
input::placeholder, textarea::placeholder { color: var(--muted-2); opacity: 0.85; }
input[type="color"].form-control-color { padding: 2px; height: 31px; }

/* ── 5.8 · Account / strategy cards — unified card grammar ──────────────────
 * The /risk + dashboard `.acct-card` markup is built by JS; we only style the
 * classes it already emits so the cards match the institutional shell. */
.acct-card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--elev-1);
  transition: transform 0.16s var(--easing), box-shadow 0.16s var(--easing), border-color 0.16s var(--easing);
}
.theme-light .acct-card { box-shadow: var(--panel-shadow); }
@media (hover: hover) { .acct-card:hover { transform: translateY(-2px); box-shadow: var(--elev-2); border-color: var(--border-2); } }
.acct-card-head { display: flex; align-items: center; gap: 8px; }
.acct-card-num, .acct-card-broker { font-family: var(--font-mono); color: var(--muted-2); }
.acct-metric-label { font-size: var(--fs-caption); letter-spacing: 0.6px; text-transform: uppercase; color: var(--muted); }
.acct-metric-value, .acct-equity { font-family: var(--font-mono); color: var(--text); }
.acct-equity { font-weight: 620; letter-spacing: -0.015em; }
.acct-dot { box-shadow: 0 0 6px currentColor; }
.platform-badge {
  font-size: var(--fs-caption); letter-spacing: 0.4px;
  font-family: var(--font-mono); padding: 2px 7px;
  border-radius: var(--radius-xs); border: 1px solid var(--border);
  background: var(--bg-2); color: var(--muted);
}

/* Backtest cards (upload page) ride the same lift as panels — already `.panel`,
 * so they inherit; this just keeps the removing-state transition crisp. */
.backtest-card .panel { height: 100%; }

/* ── 5.9 · Status bar / live pills — terminal footer polish ─────────────────  */
.status-bar {
  background: color-mix(in srgb, var(--bg-1) 94%, transparent);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  border-top: 1px solid var(--border);
  box-shadow: 0 -1px 0 var(--hairline-strong);
  font-size: 10.5px;
  color: var(--muted);
}
.status-bar .status-label { letter-spacing: 0.7px; color: var(--muted-2); }
.status-bar .status-item.right .status-label { color: var(--muted-2); }
.live-pill { font-family: var(--font-mono); letter-spacing: 0.5px; border-radius: var(--radius-pill); }

/* ── 5.10 · Scrollbars — thin custom rails (WebKit + Firefox), both themes ─── */
* { scrollbar-width: thin; scrollbar-color: var(--border-2) transparent; }
::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--border-2);
  border-radius: var(--radius-pill);
  border: 2px solid transparent;
  background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--muted-2); background-clip: padding-box; }
::-webkit-scrollbar-corner { background: transparent; }

/* ── 5.11 · Empty states / spinners / selection ────────────────────────────  */
.empty-state { padding: var(--space-10) var(--space-4); gap: var(--space-2); color: var(--muted); }
.empty-state i { font-size: 30px; opacity: 0.45; color: var(--muted-2); }
.empty-state .es-title { font-size: var(--fs-body); font-weight: 620; letter-spacing: 0.3px; color: var(--text); }
.empty-state .es-hint  { font-size: var(--fs-label); color: var(--muted-2); line-height: var(--lh-snug); }
.empty-state a { color: var(--accent); text-decoration: none; }
.empty-state a:hover { text-decoration: underline; }

/* Bootstrap spinners pulled into the institutional accent (calm, not loud). */
.spinner-border { border-right-color: transparent; color: var(--accent); }
.spinner-border.text-secondary { color: var(--muted) !important; }

::selection { background: var(--accent-soft); color: var(--text); }
.theme-dark ::selection { background: rgba(110, 145, 230, 0.30); color: #fff; }

/* ── 5.12 · Per-page once-over — utility classes that retire inline css ──────
 * These reusable helpers let the templates drop ad-hoc inline `style="…"`
 * (replaced below) while keeping identical layout. */
.stack    { display: flex; flex-direction: column; }
.stack-2  { display: flex; flex-direction: column; gap: var(--space-2); }
.stack-3  { display: flex; flex-direction: column; gap: 10px; }
.h-fit    { height: fit-content; }
.sidebar-scroll { max-height: 340px; }
.help-note { font-size: 10px; color: var(--muted-2); line-height: 1.4; }
.grid-2    { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.mt-2-fl   { margin-top: var(--space-2); }
.chart-tall   { min-height: 560px; }
.chart-md     { min-height: 340px; }
.chart-sm     { min-height: 300px; }
.chart-xs     { min-height: 240px; }

/* Dashboard sidebar list: cap height via class instead of inline style. */
#strategyList.sidebar-scroll { max-height: 340px; }

/* Strategy attribution / trade tables: a comfortable max viewport via class. */
.scroll-y.scroll-tall { max-height: 420px; }
.scroll-y.scroll-mid  { max-height: 240px; }

/* analyze.html / strategy_detail.html chart panels already use .tv-chart-wrap;
 * give the chart-empty overlay the institutional muted treatment. */
.tv-chart-wrap .chart-empty,
.tv-chart-wrap .empty-state { color: var(--muted); }

/* Marketing / auth surfaces (index, login) — keep them on-brand. */
.index-hero .glass-card { box-shadow: var(--elev-3); }
.login-card { box-shadow: var(--elev-3); }
.index-hero h6 { font-size: var(--fs-h3); font-weight: 650; color: var(--text); }
.glass-card .text-success { color: var(--accent) !important; }

/* Governance code snippets: a hair tighter, terminal-flavoured. */
.code-snippet { line-height: 1.5; box-shadow: var(--inset-shadow); }

/* ════════════════════════════════════════════════════════════════════════════
   PASS 6 — INSTITUTIONAL ELEVATION
   Depth, refinement and premium chart chrome layered over the existing sober
   palette. Glow-free (Bloomberg/FactSet sobriety): depth comes from layered
   shadows + hairline highlights, not neon. Theme-aware via the tokens above.
   ════════════════════════════════════════════════════════════════════════════ */

/* Subtle background depth — a barely-there top vignette so panels read as
   lifted cards rather than floating on a flat fill. */
body::before {
  content: "";
  position: fixed; inset: 0;
  pointer-events: none; z-index: -1;
  background:
    radial-gradient(1200px 520px at 50% -8%, rgba(var(--accent-rgb), 0.06), transparent 70%),
    radial-gradient(900px 600px at 100% 0%, rgba(var(--accent2-rgb), 0.035), transparent 60%);
}
.theme-light body::before {
  background:
    radial-gradient(1200px 520px at 50% -10%, rgba(31,78,201,0.05), transparent 70%),
    radial-gradient(900px 600px at 100% 0%, rgba(160,124,31,0.03), transparent 60%);
}

/* Lifted surfaces: layered shadow + a hairline top highlight + smooth motion. */
.panel,
.glass-card,
.sidebar,
.risk-panel,
.fw-panel {
  box-shadow: var(--panel-shadow), var(--elev-hairline);
  transition: box-shadow 0.18s ease, transform 0.18s ease, border-color 0.18s ease;
}
/* Charts must not jump, so only opt-in cards lift on hover. */
.glass-card.hoverable:hover,
.kpi-tile:hover,
.copier-card:hover {
  box-shadow: var(--panel-shadow-hi), var(--elev-hairline);
  border-color: var(--border-2);
  transform: translateY(-1px);
}

/* Panel headers: a hair more contrast. (No leading accent tick — many headers
   already carry a bootstrap icon, which would produce a double leading mark.) */
.panel-header {
  background: linear-gradient(180deg, rgba(var(--accent-rgb), 0.05), transparent 90%);
  letter-spacing: 0.9px;
}

/* KPI tiles: richer rail + a directional tint + larger, calmer numerals. */
.kpi-tile {
  background-image: linear-gradient(140deg, rgba(255,255,255,0.018), transparent 55%);
  transition: box-shadow 0.18s ease, transform 0.18s ease, border-color 0.18s ease;
}
.kpi-tile::before { width: 3px; border-radius: 3px 0 0 3px; }
.kpi-tile.pos    { background-image: linear-gradient(140deg, rgba(var(--pos-rgb), 0.10), transparent 60%); }
.kpi-tile.neg    { background-image: linear-gradient(140deg, rgba(var(--neg-rgb), 0.10), transparent 60%); }
.kpi-tile.warn   { background-image: linear-gradient(140deg, rgba(var(--warn-rgb), 0.10), transparent 60%); }
.kpi-tile .value { font-size: 18px; letter-spacing: -0.02em; }
/* Trend chip that pages can drop into a KPI tile's .sub line. */
.kpi-delta {
  display: inline-flex; align-items: center; gap: 3px;
  font-family: 'JetBrains Mono', monospace; font-size: 10px; font-weight: 600;
  padding: 1px 6px; border-radius: 999px; line-height: 1.5;
  background: var(--bg-2); color: var(--muted);
}
.kpi-delta.pos { color: var(--pos); background: rgba(var(--pos-rgb), 0.12); }
.kpi-delta.neg { color: var(--neg); background: rgba(var(--neg-rgb), 0.12); }

/* Navbar: subtle vertical sheen + a soft active glow under the accent border. */
.app-navbar {
  background: linear-gradient(180deg, var(--bg-1), var(--bg-0));
  box-shadow: 0 1px 0 rgba(0,0,0,0.25);
}
.app-navbar .nav-link { transition: color 0.15s ease, background 0.15s ease; }
.app-navbar .nav-link.active {
  box-shadow: 0 2px 10px -4px rgba(var(--accent-rgb), 0.55);
}
.brand-mark svg { filter: drop-shadow(0 0 6px rgba(var(--accent-rgb), 0.35)); }

/* Buttons: a touch more life on press. */
.btn-inst, .btn-inst.primary, .btn-inst.success {
  transition: filter 0.15s ease, background 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
}
.btn-inst:active { transform: translateY(1px); }

/* Unified focus ring (keyboard + programmatic) — accessible + on-brand. */
.filter-input:focus, .filter-select:focus,
.form-control:focus, .form-select:focus,
.btn-inst:focus-visible, .btn:focus-visible {
  outline: none;
  box-shadow: var(--ring);
}

/* ── Module hero band — used by Forward / Risk live page headers ──────────── */
.hero-band {
  position: relative; overflow: hidden;
  background:
    radial-gradient(700px 240px at 0% 0%, rgba(var(--accent-rgb), 0.10), transparent 65%),
    linear-gradient(180deg, var(--bg-1), var(--panel));
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: var(--panel-shadow), var(--elev-hairline);
  padding: 14px 18px;
}
.hero-band::after {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: linear-gradient(180deg, var(--accent), rgba(var(--accent-rgb), 0.25));
}
.hero-band .hero-title {
  font-size: 12px; font-weight: 700; letter-spacing: 0.8px; text-transform: uppercase;
  color: var(--text);
}
.hero-band .hero-sub { font-size: 11px; color: var(--muted); }
.hero-band .hero-metric { display: flex; flex-direction: column; gap: 1px; }
.hero-band .hero-metric .hm-label {
  font-size: 9.5px; text-transform: uppercase; letter-spacing: 0.6px; color: var(--muted);
}
/* Methodology tooltip affordance (native title) on hero metrics. */
.hm-tip {
  font-size: 9.5px; color: var(--muted-2); cursor: help;
  margin-left: 2px; opacity: 0.65; vertical-align: 1px;
}
.hm-tip:hover { color: var(--accent); opacity: 1; }
.hero-band .hero-metric .hm-value {
  font-family: 'JetBrains Mono', monospace; font-size: 16px; font-weight: 600;
  color: var(--text); font-variant-numeric: tabular-nums;
}
.hero-band .hero-metric .hm-value.pos { color: var(--pos); }
.hero-band .hero-metric .hm-value.neg { color: var(--neg); }
.hero-band .hero-metric .hm-value.warn { color: var(--warn); }

/* Verdict pill (GO / WATCH / STOP / PENDING) for hero bands + cards. */
.verdict-pill {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11px; font-weight: 700; letter-spacing: 0.8px; text-transform: uppercase;
  padding: 5px 12px; border-radius: 999px; border: 1px solid var(--border-2);
  background: var(--bg-2); color: var(--text);
}
.verdict-pill::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: currentColor; box-shadow: 0 0 8px currentColor; }
.verdict-pill.go      { color: var(--pos);  border-color: rgba(var(--pos-rgb), 0.45);  background: rgba(var(--pos-rgb), 0.10); }
.verdict-pill.watch   { color: var(--warn); border-color: rgba(var(--warn-rgb), 0.45); background: rgba(var(--warn-rgb), 0.10); }
.verdict-pill.stop    { color: var(--neg);  border-color: rgba(var(--neg-rgb), 0.45);  background: rgba(var(--neg-rgb), 0.10); }
.verdict-pill.pending { color: var(--muted); }

/* Chart panels: give the plot a hair of breathing room + a faint inner frame. */
.panel-body .chart, .chart.framed {
  border-radius: 4px;
}

/* Light-theme parity for the elevation layer (shadows already softened via the
   light --panel-shadow token; here we calm the tint intensities). */
.theme-light .panel-header {
  background: linear-gradient(180deg, rgba(31,78,201,0.035), transparent 90%);
}
.theme-light .app-navbar { background: linear-gradient(180deg, var(--bg-1), var(--bg-1)); box-shadow: 0 1px 0 var(--hairline-strong); }
.theme-light .kpi-tile { background-image: linear-gradient(140deg, rgba(31,78,201,0.05), transparent 60%); }
.theme-light .hero-band {
  box-shadow: var(--panel-shadow);
  background:
    radial-gradient(700px 240px at 0% 0%, rgba(31,78,201,0.07), transparent 65%),
    linear-gradient(180deg, #ffffff, var(--panel));
}

/* ── 5.13 · Reduced-motion guard (re-assert as the last word) ──────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* End ════════════  PASS 6 — INSTITUTIONAL ELEVATION  ════════════ */
