/* =============================================================================
   MYOPTIONSFLOW — COMPONENT STYLES
   All colours reference CSS variables from design-system.css.
   All layout uses utilities from utilities.css.
   No hardcoded hex values below — change brand tokens in design-system.css.
   ============================================================================= */

/* ─────────────────────────────────────────────
   BASE
───────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }

body {
  font-family: var(--font-ui);
  background-color: var(--bg-global);
  color: var(--text-primary);
  margin: 0;
}

/* Financial font class — applied to all numeric table cells and KPI values */
.financial,
.font-financial {
  font-family: var(--font-financial);
}

/* Scrollbar */
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: var(--bg-surface-alt); border-radius: 10px; }
::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 10px; }
::-webkit-scrollbar-thumb:hover { background: var(--text-tertiary); }

/* ─────────────────────────────────────────────
   SIDEBAR
   Collapsed: 64px icon-only.
   Hover: expands to 240px with labels visible.
   Mobile: hidden off-screen, slides in on .open
───────────────────────────────────────────── */
.sidebar {
  width: var(--sidebar-w-collapsed);
  background-color: var(--bg-sidebar);
  border-right: 1px solid var(--border-sidebar);
  box-shadow: var(--shadow-sidebar);
  position: fixed;
  top: 0; left: 0;
  height: 100vh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  z-index: var(--z-sidebar);
  /* Mobile: slide out off-screen */
  transform: translateX(-100%);
  transition: var(--transition-sidebar), transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

/* Desktop hover-expand */
@media (min-width: 1024px) {
  .sidebar {
    transform: translateX(0);
    transition: var(--transition-sidebar);
  }
  .sidebar:hover {
    width: var(--sidebar-w-expanded);
  }
  .sidebar:hover ~ .content-area-wrapper {
    margin-left: var(--sidebar-w-expanded);
  }
}

/* Mobile open state */
.sidebar.open {
  transform: translateX(0);
  width: var(--sidebar-w-expanded);
}

/* Logo area — padding-left centres the 32px icon in the 64px collapsed bar */
.sidebar-logo-area {
  height: 64px;
  display: flex;
  align-items: center;
  padding-left: 16px;
  border-bottom: 1px solid var(--border-sidebar);
  flex-shrink: 0;
  overflow: hidden;
}
.sidebar-logo-icon {
  width: 32px; height: 32px;
  flex-shrink: 0;
  background: linear-gradient(135deg, var(--color-action), #0055cc);
  border-radius: var(--radius-sm);
  display: flex; align-items: center; justify-content: center;
  color: var(--text-inverse);
  font-size: 0.7rem; font-weight: 700; letter-spacing: 0.02em;
}
.sidebar-logo-text {
  margin-left: 12px;
  font-size: 0.8rem; font-weight: 700;
  color: var(--text-inverse);
  white-space: nowrap;
  opacity: 0;
  transition: var(--transition-sidebar-content);
  letter-spacing: -0.02em;
}
@media (min-width: 1024px) {
  .sidebar:hover .sidebar-logo-text { opacity: 1; }
}
.sidebar.open .sidebar-logo-text { opacity: 1; }

/* Nav section labels */
.sidebar .text-xs.uppercase.font-semibold,
.sidebar-section-label {
  color: var(--bg-sidebar-section);
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  padding: 16px 0 4px 20px;
  white-space: nowrap;
  opacity: 0;
  transition: var(--transition-sidebar-content);
}
@media (min-width: 1024px) {
  .sidebar:hover .text-xs.uppercase.font-semibold,
  .sidebar:hover .sidebar-section-label { opacity: 1; }
}
.sidebar.open .text-xs.uppercase.font-semibold,
.sidebar.open .sidebar-section-label { opacity: 1; }

/* Nav links */
.sidebar a {
  position: relative;
  display: flex;
  align-items: center;
  padding: 10px 0 10px 17px;
  color: var(--text-sidebar);
  text-decoration: none;
  font-size: 0.875rem;
  font-weight: 500;
  white-space: nowrap;
  transition: var(--transition-std);
  border-left: 3px solid transparent;
}
.sidebar a:hover {
  background-color: var(--bg-sidebar-hover);
  color: var(--text-sidebar-hover);
}
.sidebar a.active {
  background-color: var(--bg-sidebar-active);
  color: var(--text-sidebar-active);
  border-left-color: rgba(255, 255, 255, 0.4);
  font-weight: 600;
}
.sidebar a i.fa-fw,
.sidebar a i {
  width: 24px;
  text-align: center;
  font-size: 0.875rem;
  flex-shrink: 0;
  margin-right: 0;
  opacity: 0.8;
}
.sidebar a.active i { opacity: 1; }

/* Accent icon colours — reset to inherited white on active/hover */
.sidebar a:not(.active):not(:hover) .nav-icon-screener { color: #2dd4bf; opacity: 1; }
.sidebar a:not(.active):not(:hover) .nav-icon-digest   { color: #fbbf24; opacity: 1; }
.sidebar a:not(.active):not(:hover) .nav-icon-sync     { color: #a78bfa; opacity: 1; }

/* Nav label text (fades in on expand) */
.sidebar a .nav-label-text,
.sidebar .nav-label {
  margin-left: 12px;
  opacity: 0;
  transition: var(--transition-sidebar-content);
}
@media (min-width: 1024px) {
  .sidebar:hover a .nav-label-text,
  .sidebar:hover .nav-label { opacity: 1; }
}
.sidebar.open a .nav-label-text,
.sidebar.open .nav-label { opacity: 1; }

/* Notification count pill on nav items (Verify Activities / Campaign Manager).
   Inline + right-aligned when the sidebar is expanded; a small badge pinned over
   the icon when collapsed, so the indicator is always visible. */
.nav-count-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  margin-left: auto;
  border-radius: 9px;
  background: var(--color-loss-text, #dc2626);
  color: #fff;
  font-size: 0.68rem;
  font-weight: 700;
  line-height: 1;
  flex-shrink: 0;
}
/* Collapsed (desktop, not hovered, not open): pin the badge over the icon. */
@media (min-width: 1024px) {
  .sidebar:not(:hover):not(.open) .nav-count-badge {
    position: absolute;
    top: 5px;
    left: 26px;
    margin-left: 0;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    font-size: 0.6rem;
  }
}

/* Logout button */
.sidebar button[type="submit"] {
  display: flex;
  align-items: center;
  width: 100%;
  padding: 10px 0 10px 20px;
  background: transparent;
  border: none;
  color: #ef4444;
  font-size: 0.875rem;
  font-weight: 500;
  cursor: pointer;
  text-align: left;
  white-space: nowrap;
  transition: var(--transition-std);
}
.sidebar button[type="submit"]:hover {
  background-color: rgba(239, 68, 68, 0.1);
}

/* ─────────────────────────────────────────────
   CONTENT AREA WRAPPER
───────────────────────────────────────────── */
.content-area-wrapper {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  transition: margin-left 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

@media (min-width: 1024px) {
  .content-area-wrapper {
    margin-left: var(--sidebar-w-collapsed);
  }
}

/* ─────────────────────────────────────────────
   HEADER BAR
───────────────────────────────────────────── */
.header-bar {
  background-color: var(--bg-header);
  border-bottom: 1px solid var(--border-color);
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 1.5rem;
  height: 60px;
  position: sticky;
  top: 0;
  z-index: var(--z-overlay);
  box-shadow: var(--shadow-sm);
}
.header-bar h1 {
  font-size: 1.125rem;
  font-weight: 600;
  color: var(--text-primary);
  letter-spacing: -0.02em;
  margin: 0;
}
.header-bar input[type="text"],
.header-bar select {
  background-color: var(--bg-surface-alt);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  padding: 0.5rem 1rem;
  font-size: 0.8125rem;
  font-family: var(--font-ui);
  color: var(--text-primary);
  transition: var(--transition-std);
  box-shadow: var(--shadow-sm);
}
.header-bar input[type="text"]:focus,
.header-bar select:focus {
  background-color: var(--bg-surface);
  border-color: var(--border-focus);
  outline: none;
  box-shadow: var(--shadow-focus);
}

/* Account / currency selectors */
.account-selector select,
.currency-selector select {
  appearance: none;
  background-color: var(--color-action-bg);
  border: 1px solid var(--color-action-border);
  color: var(--color-action);
  padding: 6px 28px 6px 10px;
  font-size: 0.8125rem;
  font-weight: 600;
  font-family: var(--font-ui);
  border-radius: var(--radius-md);
  cursor: pointer;
  outline: none;
  transition: var(--transition-std);
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%23007AFF' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
  background-position: right 0.5rem center;
  background-repeat: no-repeat;
  background-size: 1.25em 1.25em;
}
.account-selector select:hover,
.currency-selector select:hover {
  background-color: rgba(0, 122, 255, 0.14);
}

/* Deviation state: selector changed from user's default — solid red, impossible to miss */
.account-selector.deviated select,
.currency-selector.deviated select {
  background-color: #FF3B30;
  border: 2px solid #cc1a10;
  color: #ffffff;
  font-weight: 700;
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%23ffffff' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
  box-shadow: 0 0 0 3px rgba(255, 59, 48, 0.4);
}
.account-selector.deviated select:hover,
.currency-selector.deviated select:hover {
  background-color: #cc1a10;
}

/* Symbol search */
.symbol-search-bar input[type="text"] {
  background-color: var(--bg-surface-alt);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md) 0 0 var(--radius-md);
  padding: 0.5rem 1rem;
  font-size: 0.8125rem;
  color: var(--text-primary);
  outline: none;
  transition: var(--transition-std);
  min-width: 150px;
}
.symbol-search-bar input[type="text"]:focus {
  border-color: var(--color-action);
  box-shadow: var(--shadow-focus);
}
.symbol-search-bar button {
  background-color: var(--color-action);
  color: var(--text-inverse);
  border: none;
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
  padding: 0.5rem 0.75rem;
  cursor: pointer;
  font-size: 0.875rem;
  transition: var(--transition-std);
}
.symbol-search-bar button:hover {
  background-color: var(--color-action-hover);
}

/* Dark mode toggle button */
.theme-toggle-btn {
  width: 32px; height: 32px;
  border-radius: var(--radius-md);
  border: 1px solid var(--border-color);
  background: var(--bg-surface-alt);
  color: var(--text-secondary);
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  font-size: 0.875rem;
  transition: var(--transition-std);
}
.theme-toggle-btn:hover {
  background: var(--border-color);
  color: var(--text-primary);
}

/* ─────────────────────────────────────────────
   MAIN CONTENT
───────────────────────────────────────────── */
.main-content-scrollable {
  flex-grow: 1;
  overflow-y: visible;
  overflow-x: visible;
}

/* ─────────────────────────────────────────────
   CARDS
───────────────────────────────────────────── */
.card {
  background-color: var(--bg-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  border: 1px solid var(--border-color);
}
.pnl-card {
  margin-bottom: 1.5rem;
  background-color: var(--bg-surface);
  padding: 1.5rem;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  border: 1px solid var(--border-color);
}
.pnl-line {
  display: flex;
  justify-content: space-between;
  font-size: 1.1rem;
  margin-bottom: 0.25rem;
  padding: 0.25rem 0;
}
.pnl-line-label { color: var(--text-secondary); }
.pnl-line-value { font-weight: 600; font-family: var(--font-financial); }
/* Secondary breakdown beneath a headline figure (e.g. the put-obligation coverage
   split on the Risk Analysis tile) — indented, quieter, never the primary number. */
.pnl-line-sub {
  font-size: var(--text-size-xs);
  padding: 0.0625rem 0 0.0625rem 0.875rem;
  margin-bottom: 0;
}
.pnl-line-sub .pnl-line-label { color: var(--text-tertiary); }
.pnl-line-sub .pnl-line-value { font-weight: 500; color: var(--text-tertiary); }
.pnl-line-note {
  font-size: var(--text-size-xs);
  color: var(--text-tertiary);
  margin: 0.375rem 0 0;
}
/* Inline checkbox + label for a declaration the data cannot infer (e.g. Campaign
   Manager's "these longs are insurance"). Reusable form component, so it lives here
   rather than in a per-template <style> block. */
.field-checkbox {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: var(--text-size-sm);
  color: var(--text-primary);
  cursor: pointer;
  padding: 0.25rem 0;
}
.field-checkbox input[type="checkbox"] {
  width: 1rem;
  height: 1rem;
  margin: 0;
  accent-color: var(--color-action);
  cursor: pointer;
  flex-shrink: 0;
}
.pnl-total {
  border-top: 1px solid var(--border-color);
  margin-top: 0.5rem;
  padding-top: 0.5rem;
  font-size: 1.25rem;
  font-weight: bold;
}
.detail-link {
  font-size: 0.85rem;
  color: var(--color-action);
  text-decoration: none;
  display: block;
}
.detail-link:hover { text-decoration: underline; color: var(--color-action-hover); }
.detail-link + .detail-link { margin-top: 0.25rem; }

/* Shared "back to where you came from" link for drill-down pages.
   Replaces the per-template inline anchors that had drifted into four different
   styles. Sits above the page card, not inside it. */
.page-back-link {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-bottom: 1rem;
  font-size: var(--text-size-sm);
  font-weight: 600;
  color: var(--color-action);
  text-decoration: none;
}
.page-back-link:hover { color: var(--color-action-hover); text-decoration: underline; }
.page-back-link i { font-size: 0.72rem; }

/* Row-cap truncation banner (2026-07-21 OOM guard).
   Moved out of screener_hub.html's inline <style> on 2026-08-20, when the Cash Flow
   drill-down became the second user — a reusable component belongs in the stylesheet,
   and a duplicated <style> block is what the styling rule forbids. */
.row-cap-banner {
  padding: 0.65rem 1rem;
  border-bottom: 1px solid var(--color-warning-border);
  background: var(--color-warning-bg);
  color: var(--color-warning);
  font-size: var(--text-size-sm);
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

/* Card table wrapper */
.card-table-wrapper {
  overflow-x: auto;
  padding: 0;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
}
.card h2.table-title {
  padding: 1rem 1rem 0.5rem 1rem;
  margin-bottom: 0;
}

/* ─────────────────────────────────────────────
   SNAPSHOT BAR (Overview KPI cards)
───────────────────────────────────────────── */
.snapshot-bar {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1rem;
  margin-bottom: 2rem;
}

/* Card shell */
.snapshot-card {
  background: var(--bg-surface);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  padding: 1.125rem 1.25rem 1rem;
  overflow: hidden;
  position: relative;
  min-height: 130px;
}

/* Cards with a sparkline need bottom room for it */
.snapshot-card.has-sparkline {
  padding-bottom: 58px;
}

.snapshot-label {
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-secondary);
  margin-bottom: 0.5rem;
}
.snapshot-value {
  font-family: var(--font-financial);
  font-size: var(--text-size-kpi);
  font-weight: 500;
  color: var(--text-primary);
  line-height: 1.2;
  margin-bottom: 0.3rem;
}
.snapshot-value.profit { color: var(--color-profit); }
.snapshot-value.loss   { color: var(--color-loss); }

.snapshot-change {
  font-size: 0.72rem;
  font-weight: 500;
  color: var(--text-tertiary);
  display: flex;
  align-items: center;
  gap: 0.25rem;
}
.snapshot-change .up   { color: var(--color-profit); }
.snapshot-change .down { color: var(--color-loss); }

/* Sparkline SVG — absolutely positioned, flush to card bottom */
.sparkline-wrap {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 52px;
  overflow: hidden;
  line-height: 0;
}
.sparkline-wrap svg { display: block; width: 100%; height: 100%; }

/* ─────────────────────────────────────────────
   SECTION HEADERS
───────────────────────────────────────────── */
.section-header {
  font-size: 1.5rem;
  font-weight: 600;
  color: var(--text-primary);
  margin-bottom: 1rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--border-color);
}

/* ─────────────────────────────────────────────
   TWO-COLUMN LAYOUT (Overview)
───────────────────────────────────────────── */
.main-content-flex {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}
.flex-left-70,
.flex-right-30 { width: 100%; }

@media (min-width: 1024px) {
  .main-content-flex { flex-direction: row; }
  .flex-left-70 { width: 70%; padding-right: 1.5rem; }
  .flex-right-30 { width: 30%; }
}

/* ─────────────────────────────────────────────
   TABLES — DASHBOARD TABLE
───────────────────────────────────────────── */
.dashboard-table th,
.dashboard-table td {
  padding: 8px 10px;
  vertical-align: middle;
  border-bottom: 1px solid var(--border-color);
  white-space: nowrap;
}
.dashboard-table tr:last-child td { border-bottom: none; }
.dashboard-table th {
  background-color: var(--bg-surface-alt);
  color: var(--text-secondary);
  font-weight: 600;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  text-align: left;
}
.dashboard-table th a {
  color: inherit; text-decoration: none; display: inline-block;
}
.dashboard-table th a:hover {
  text-decoration: underline; color: var(--color-action);
}
.dashboard-table td { font-size: 0.875rem; }
.dashboard-table td a.clickable-symbol { color: var(--color-action); text-decoration: underline; }
.dashboard-table td a.clickable-symbol:hover { color: var(--color-action-hover); }

/* ─────────────────────────────────────────────
   TABLES — DETAIL TABLE
───────────────────────────────────────────── */
.detail-table th,
.detail-table td {
  padding: 0.65rem 0.75rem;
  text-align: left;
  border-bottom: 1px solid var(--border-color);
  font-size: 0.875rem;
  vertical-align: middle;
  white-space: nowrap;
}
.detail-table th {
  background-color: var(--bg-surface-alt);
  font-weight: 600;
  color: var(--text-secondary);
}
.detail-table tbody tr:nth-child(even) { background-color: var(--bg-surface-alt); }
.detail-table tbody tr:hover { background-color: var(--row-stock-highlight); }

/* ─────────────────────────────────────────────
   TABLES — PERFORMANCE TABLE
───────────────────────────────────────────── */
.performance-table { width: 100%; border-collapse: collapse; }
.performance-table th,
.performance-table td {
  padding: 0.9rem 1.25rem;
  text-align: left;
  border-bottom: 1px solid var(--border-color);
}
.performance-table thead th {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-secondary);
  background-color: var(--bg-surface-alt);
}
.performance-table .period-header-row th {
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  background-color: var(--row-period-bg);
  color: var(--row-period-text);
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
}
.performance-table .past-period-header-row th {
  background-color: var(--bg-surface-alt);
  color: var(--text-secondary);
}
.performance-table .today-row {
  font-size: 1.1em;
  font-weight: var(--row-today-font-weight);
  background-color: var(--row-today-bg);
}
.performance-table .period-name { font-weight: 500; }
.performance-table .text-right { text-align: right; }

/* ─────────────────────────────────────────────
   TABLES — MONTHLY SUMMARY TABLE
───────────────────────────────────────────── */
.monthly-summary-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 1.5rem;
  font-size: 0.875rem;
}
.monthly-summary-table th,
.monthly-summary-table td {
  border: 1px solid var(--border-color);
  padding: 0.6rem 0.5rem;
  text-align: right;
  white-space: nowrap;
}
.monthly-summary-table thead th {
  background-color: var(--bg-surface-alt);
  font-weight: 600;
  position: sticky;
  top: 0;
  z-index: var(--z-raised);
}
.monthly-summary-table td.category-label {
  text-align: left;
  font-weight: 500;
  background-color: var(--bg-surface-alt);
  position: sticky;
  left: 0;
  z-index: 5;
  width: 1px;
  white-space: nowrap;
  padding-left: 0.75rem;
}
.monthly-summary-table th.category-header {
  background-color: var(--border-color);
  position: sticky;
  top: 0; left: 0;
  z-index: 15;
  min-width: 220px;
  text-align: left;
  padding-left: 0.75rem;
}
.monthly-summary-table .total-col {
  font-weight: bold;
  background-color: var(--row-subtotal-bg);
}

/* ─────────────────────────────────────────────
   TABLE SPECIAL ROWS
───────────────────────────────────────────── */
.stock-row-highlight td { background-color: var(--row-stock-highlight) !important; }

.subtotal-row td,
.net-profit-row td {
  font-weight: bold;
  background-color: var(--row-subtotal-bg);
  color: var(--row-subtotal-text);
}
.subtotal-row td {
  border-top: 2px solid var(--row-subtotal-border);
}
.subtotal-row td.category-label,
.net-profit-row td.category-label { padding-left: 1.5rem; }

.grand-total-row td {
  background-color: var(--row-grand-total-bg);
  font-weight: bold;
  font-size: 1.1rem;
  color: var(--row-grand-total-text);
  border-top: 2px solid var(--row-grand-total-border);
}

/* ── Cost-basis-pending markers ─────────────────────────────────────────
   A stock sale whose shares were acquired the same day has no StockLot yet,
   so its cost basis is unknowable until the overnight pipeline. The row is
   shown with proceeds but contributes 0 to the totals — these mark that. */
.basis-pending-notice {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 1rem;
  padding: 0.65rem 1rem;
  background-color: var(--color-warning-bg);
  border: 1px solid var(--color-warning-border);
  border-radius: var(--radius-md);
  color: var(--color-warning-text);
  font-size: var(--text-size-sm);
  font-weight: 500;
}
.basis-pending-tag {
  display: inline-block;
  margin-left: 0.4rem;
  padding: 0.05rem 0.35rem;
  background-color: var(--color-warning-bg);
  border: 1px solid var(--color-warning-border);
  border-radius: var(--radius-sm);
  color: var(--color-warning-text);
  font-size: var(--text-size-2xs);
  font-weight: 600;
  letter-spacing: 0.02em;
  vertical-align: middle;
  white-space: nowrap;
}
.account-header-row th {
  background-color: var(--row-account-header-bg);
  color: var(--row-account-header-text);
  padding: 0.75rem;
  font-size: 1rem;
  font-weight: bold;
}
.section-divider-row td {
  background-color: var(--row-section-div-bg);
  color: var(--row-section-div-text);
  font-weight: 600;
  padding: 0.5rem 1rem;
  font-size: 1.1rem;
}
.highlight-metric-row td {
  background-color: var(--row-highlight-metric-bg);
  font-weight: 600;
  color: var(--row-highlight-metric-text);
}
.highlight-metric-row td.category-label {
  background-color: var(--row-highlight-metric-bg) !important;
  color: var(--row-highlight-metric-text);
}

/* Section priority rows (Open Positions urgency headers) */
.section-header-row.section-priority-1 td {
  background-color: var(--priority-1-bg) !important;
  color: var(--priority-1-text);
  font-weight: bold;
  padding: 0.75rem 1rem !important;
  border-top: 2px solid var(--priority-1-border);
  border-bottom: 2px solid var(--priority-1-border) !important;
}
.section-header-row.section-priority-2 td {
  background-color: var(--priority-2-bg) !important;
  color: var(--priority-2-text);
  font-weight: bold;
  padding: 0.75rem 1rem !important;
  border-top: 2px solid var(--priority-2-border);
  border-bottom: 2px solid var(--priority-2-border) !important;
}
.section-header-row.section-priority-3 td {
  background-color: var(--priority-3-bg) !important;
  color: var(--priority-3-text);
  font-weight: bold;
  padding: 0.75rem 1rem !important;
  border-top: 2px solid var(--priority-3-border);
  border-bottom: 2px solid var(--priority-3-border) !important;
}

/* ─────────────────────────────────────────────
   TABLE STICKY HELPERS
───────────────────────────────────────────── */
.table-container { max-height: 80vh; overflow: auto; width: 100%; }
.header-sticky   { position: sticky; top: 0; z-index: var(--z-sticky); background-color: var(--bg-surface-alt); }
.category-sticky { position: sticky; left: 0; z-index: var(--z-raised); background-color: var(--bg-surface-alt); }
.top-left-sticky {
  position: sticky; top: 0; left: 0;
  z-index: 30;
  background-color: var(--border-color);
}

/* Floating table headers — driven by static/js/table_float_head.js, which explains why a
   transform and not `position: sticky` (horizontal-scroll wrappers disable sticky silently).
   The script sets --mof-head-y on the table; only the header CELLS move, never the thead. */
.mof-float-head > thead > tr > * {
  position: relative;
  z-index: var(--z-sticky);
  transform: translateY(var(--mof-head-y, 0px));
}
/* A cell that was already sticky keeps its sticky-LEFT (frozen column); its vertical stick is
   handed to the transform so the two do not add together. */
.mof-float-head > thead > tr > .mof-head-keep-sticky { position: sticky; top: auto !important; }
.mof-float-head.mof-head-floating > thead > tr:last-child > * {
  box-shadow: 0 1px 0 var(--border-color), 0 3px 6px -3px rgba(0, 0, 0, 0.18);
}
/* A table inside its own vertically-scrolling box: a plain sticky header inside that box. */
.mof-inner-sticky > thead > tr > *:not(.mof-head-keep-sticky) {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
}
.mof-float-head > thead > tr > .mof-head-needs-bg,
.mof-inner-sticky > thead > tr > .mof-head-needs-bg { background-color: var(--bg-surface-alt); }

/* ─────────────────────────────────────────────
   P&L COLOUR CLASSES
   Canonical definitions — these were duplicated
   3× in the old file with inconsistent values.
───────────────────────────────────────────── */
.pnl-positive { color: var(--color-profit) !important; }
.pnl-negative { color: var(--color-loss)   !important; }
.pnl-zero     { color: var(--text-secondary) !important; }

/* Links inside pnl-coloured cells must inherit — browser default link blue overrides cascade */
.pnl-positive a,
.pnl-negative a,
.pnl-zero a { color: inherit; text-decoration: none; }
.pnl-positive a:hover,
.pnl-negative a:hover,
.pnl-zero a:hover { text-decoration: underline; }

/* ─────────────────────────────────────────────
   RISK & DTE COLOUR CLASSES
───────────────────────────────────────────── */
.risk-text-green  { color: var(--color-profit);  font-weight: 500; }
.risk-text-orange { color: var(--color-warning); font-weight: 500; }
.risk-text-red    { color: var(--color-loss);    font-weight: 500; }

.dte-text-red    { color: var(--color-loss);    font-weight: 500; }
.dte-text-orange { color: var(--color-warning); font-weight: 500; }
.dte-text-green  { color: var(--color-profit);  font-weight: 500; }

/* Aliases used in open_positions_dashboard */
.dte-red    { color: var(--color-loss);    font-weight: 700; }
.dte-orange { color: var(--color-warning); font-weight: 700; }
.dte-green  { color: var(--color-profit);  font-weight: 700; }

.short-delta-red    { color: var(--color-loss);    font-weight: 700; }
.short-delta-orange { color: var(--color-warning); font-weight: 700; }
.short-delta-green  { color: var(--color-profit);  font-weight: 700; }

/* ─────────────────────────────────────────────
   SORT INDICATOR
───────────────────────────────────────────── */
.sort-indicator {
  display: inline-block;
  margin-left: 4px;
  font-size: 0.75em;
  line-height: 1;
}

/* ─────────────────────────────────────────────
   TEXT HELPERS
───────────────────────────────────────────── */
.text-deemphasized { color: var(--text-tertiary); }
.text-right-align  { text-align: right !important; }
.text-align-right  { text-align: right !important; }
.bold-text         { font-weight: bold; }
.description-col   { white-space: normal; min-width: 200px; }

/* ─────────────────────────────────────────────
   BUTTONS
───────────────────────────────────────────── */
.btn-primary {
  background-color: var(--color-action);
  color: var(--text-inverse);
  font-weight: bold;
  padding: 0.5rem 1rem;
  border-radius: var(--radius-sm);
  border: none;
  cursor: pointer;
  transition: var(--transition-std);
}
.btn-primary:hover { background-color: var(--color-action-hover); }

.btn-danger {
  background-color: var(--color-loss);
  color: #ffffff;
  font-weight: bold;
  padding: 0.5rem 1rem;
  border-radius: var(--radius-sm);
  border: none;
  cursor: pointer;
  transition: var(--transition-std);
}
.btn-danger:hover { background-color: #cc1a10; }
.btn-danger:disabled { opacity: 0.5; cursor: not-allowed; }

.btn-success {
  background-color: var(--color-profit);
  color: #ffffff;
  font-weight: bold;
  padding: 0.5rem 1rem;
  border-radius: var(--radius-sm);
  border: none;
  cursor: pointer;
  transition: var(--transition-std);
}
.btn-success:hover { background-color: var(--color-profit-text); }

/* ─────────────────────────────────────────────
   FILTER BAR
───────────────────────────────────────────── */
.filter-bar-container {
  background-color: var(--bg-surface-alt);
  border-bottom: 1px solid var(--border-color);
  padding: 1rem;
  border-radius: var(--radius-md) var(--radius-md) 0 0;
}
.filter-group { display: flex; flex-direction: column; }
@media (min-width: 640px) {
  .filter-group { flex-direction: row; align-items: center; gap: 1rem; }
}

/* ─────────────────────────────────────────────
   RISK ANALYSIS ITEMS
───────────────────────────────────────────── */
.risk-analysis-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--border-color);
}
.risk-analysis-item:last-child { border-bottom: none; }
.risk-analysis-item h4 { font-weight: 500; color: var(--text-primary); }
.risk-value { font-weight: 600; font-size: 1rem; color: var(--text-primary); font-family: var(--font-financial); }
.risk-label { font-size: 0.75rem; color: var(--text-secondary); margin-left: 0.25rem; }

/* ─────────────────────────────────────────────
   COMPARISON & VARIANCE COLUMNS
───────────────────────────────────────────── */
.comparison-col {
  background-color: var(--color-profit-bg);
  border-left: 2px solid var(--border-color);
}
.variance-col { font-size: 0.85em; color: var(--text-secondary); }

/* ─────────────────────────────────────────────
   CLICKABLE METRIC CELLS
───────────────────────────────────────────── */
.clickable-metric a {
  color: var(--color-action);
  text-decoration: underline;
  display: block;
  height: 100%;
  width: 100%;
}
.clickable-metric a:hover {
  color: var(--color-action-hover);
  background-color: var(--color-action-bg);
}

/* ─────────────────────────────────────────────
   ALERT / MESSAGE BANNERS
───────────────────────────────────────────── */
.alert-success {
  background-color: var(--color-profit-bg);
  color: var(--color-profit-text);
  border: 1px solid var(--color-profit-border);
  padding: 1rem; margin-bottom: 1rem;
  border-radius: var(--radius-md); font-size: 0.875rem;
}
.alert-error {
  background-color: var(--color-loss-bg);
  color: var(--color-loss-text);
  border: 1px solid var(--color-loss-border);
  padding: 1rem; margin-bottom: 1rem;
  border-radius: var(--radius-md); font-size: 0.875rem;
}
.alert-info {
  background-color: var(--color-action-bg);
  color: var(--color-action);
  border: 1px solid var(--color-action-border);
  padding: 1rem; margin-bottom: 1rem;
  border-radius: var(--radius-md); font-size: 0.875rem;
}

/* ─────────────────────────────────────────────
   SIDEBAR LOGO (legacy class names — keep for
   any template that still references them)
───────────────────────────────────────────── */
.sidebar-logo-container {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 0.5rem;
}
.sidebar-logo-image {
  max-height: 80px;
  width: auto;
  display: block;
  margin: 0 auto;
}

/* ─────────────────────────────────────────────
   MOBILE MENU TOGGLE BUTTON
───────────────────────────────────────────── */
#menu-toggle {
  display: none;
  position: fixed;
  top: 14px; left: 14px;
  z-index: var(--z-modal);
  padding: 0.5rem;
  background: var(--bg-sidebar);
  color: var(--text-inverse);
  border: none;
  border-radius: var(--radius-md);
  cursor: pointer;
}
@media (max-width: 1023px) {
  #menu-toggle { display: block; }
}

@media (max-width: 640px) {
  .header-bar {
    height: auto;
    min-height: 56px;
    padding: 0.625rem 1rem;
    flex-wrap: wrap;
    gap: 0.5rem;
  }
  .header-bar h1 {
    flex: 1 1 100%;
  }
  .symbol-search-bar input[type="text"] {
    min-width: 80px;
    width: 100%;
  }
}

/* ============================================================================
   SCORECARD — shared trade-review tile component.
   Extracted 2026-07-09 from reports/campaign_history.html's inline tile idiom so
   other detail pages can present the same visual language instead of
   duplicating it. Used by reports/campaign_history.html (real TradeCampaign) and
   Tokens only — never hardcode.
   ============================================================================ */

.scorecard-body {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

/* A labelled group of tiles ("Outcome", "Entry", "Exit", "Entry Setup"). */
.scorecard-section__label {
  font-size: var(--text-size-xs);
  font-weight: 700;
  color: var(--text-tertiary);
  text-transform: uppercase;
  letter-spacing: 0.07em;
  margin-bottom: 0.5rem;
}

/* A normal-weight, non-uppercase aside inside a section label. */
.scorecard-section__label-note {
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
}

/* Sections divided from the one above by a rule. */
.scorecard-section--divided {
  margin-top: 1.25rem;
  padding-top: 1rem;
  border-top: 1px solid var(--border-color);
}

/* ── Tile grids ──────────────────────────────────────────────────────────── */
.scorecard-grid       { display: grid; gap: 0.75rem; }
.scorecard-grid--2    { grid-template-columns: repeat(2, 1fr); }
.scorecard-grid--1    { grid-template-columns: 1fr; }
.scorecard-grid--auto { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }

/* Entry|Exit two-column layout. */
.scorecard-columns {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.25rem;
}

/* Small "how to read this" caption beneath a chart. */
.chart-caption {
  font-size: var(--text-size-2xs);
  color: var(--text-tertiary);
  line-height: 1.45;
  margin-top: 0.5rem;
}

/* ── Tile ────────────────────────────────────────────────────────────────── */
.scorecard-tile {
  border-radius: var(--radius-md);
  border: 1px solid var(--border-color);
  background: var(--bg-surface-alt);
  padding: 0.875rem;
  text-align: center;
}

.scorecard-tile--span2  { grid-column: span 2; }

/* Semantic tile skins. */
.scorecard-tile--win    { border-color: var(--color-profit-border); background: var(--color-profit-bg); }
.scorecard-tile--loss   { border-color: var(--color-loss-border);   background: var(--color-loss-bg); }
.scorecard-tile--action { border-color: var(--color-action-border); background: var(--color-action-bg); }
.scorecard-tile--purple { border-color: var(--color-purple-border); background: var(--color-purple-bg); }

.scorecard-tile__label {
  font-size: var(--text-size-xs);
  color: var(--text-secondary);
  text-transform: uppercase;
  font-weight: 600;
}

.scorecard-tile__value {
  font-size: var(--text-size-2xl);
  font-weight: 700;
  color: var(--text-primary);
  margin-top: 0.25rem;
}

/* Value size variants. */
.scorecard-tile__value--result { font-weight: 900; }
.scorecard-tile__value--md     { font-size: var(--text-size-xl); }
.scorecard-tile__value--sm     { font-size: 0.95rem; line-height: 1.3; }

/* Value colour variants (skin-independent). */
.scorecard-tile__value--profit { color: var(--color-profit); }
.scorecard-tile__value--loss   { color: var(--color-loss); }
.scorecard-tile__value--action { color: var(--color-action); }
.scorecard-tile__value--purple { color: var(--color-purple); }

/* A small qualifier rendered beside a value (e.g. a bias direction). */
.scorecard-tile__value-note {
  font-size: var(--text-size-xs);
  font-weight: 600;
  color: var(--text-secondary);
}

.scorecard-tile__hint {
  font-size: var(--text-size-2xs);
  color: var(--text-tertiary);
  margin-top: 0.25rem;
  line-height: 1.4;
}

@media (max-width: 640px) {
  .scorecard-columns { grid-template-columns: 1fr; }
}

/* Card header used by the scorecard pages (campaign_history). */
.scorecard-header {
  background: var(--bg-surface-alt);
}

.scorecard-header__title {
  font-weight: 700;
  color: var(--text-primary);
}

.scorecard-header__sub {
  font-size: var(--text-size-2xs);
  color: var(--text-tertiary);
  margin-top: 0.125rem;
}

/* The ticker symbol rendered inside a page title. */
.page-title-symbol {
  color: var(--color-purple);
  font-weight: 600;
}

/* ── Screener auto-refresh banner ───────────────────────────────────────────
   Shown by screener_hub.html when the auto-refresh poll detects that a newer
   run_all_screeners run has landed while the user was viewing the page. */
.screener-refresh-banner {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0.5rem 0;
  padding: 0.55rem 0.85rem;
  font-size: 0.85rem;
  color: var(--color-action-hover);
  background: var(--color-action-bg);
  border: 1px solid var(--color-action-border);
  border-radius: var(--radius-md);
}
.screener-refresh-banner[hidden] { display: none; }
.screener-refresh-banner .srb-text { flex: 1; color: var(--text-primary); }
.screener-refresh-banner .srb-refresh {
  padding: 0.28rem 0.8rem;
  font-size: 0.8rem;
  font-weight: 600;
  color: #fff;
  background: var(--color-action);
  border: none;
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.screener-refresh-banner .srb-refresh:hover { background: var(--color-action-hover); }
.screener-refresh-banner .srb-dismiss {
  padding: 0 0.4rem;
  font-size: 1.1rem;
  line-height: 1;
  color: var(--text-tertiary);
  background: none;
  border: none;
  cursor: pointer;
}
.screener-refresh-banner .srb-dismiss:hover { color: var(--text-primary); }

/* ⚠️ The credit-screener fill ladder (`.fill-cell`, `.fill-ladder`, `.fill-rung*`,
   `.fill-dot*`, `.fill-hint`, `.fill-cal`) was REMOVED 2026-08-29 by user ruling, along with
   `helpers/fill_analysis.analyze_fill`. It drew onto `screener_hub.html`, deleted in Custom
   Screener Phase 8. The CALIBRATION behind it is untouched and still runs nightly — only the
   drawing is gone.

   The `.ivhv-*` and `.bk-score*` rules below are likewise orphaned by Phase 8 but are LEFT IN
   PLACE: the per-contract IV/HV measure they coloured is being re-added as a screener metric,
   and deleting them now to re-add them in the same session is churn, not tidying. */

/* ── Breakout screener: contract volatility cost ────────────────────────────
   The long-option cost measure — this contract's own IV against the underlying's
   1-year historical volatility. Below 1.0 the option is priced under how far the
   stock actually moves (cheap premium to buy); above ~1.2 you are overpaying.
   Colour runs the OPPOSITE way to the credit screener, where rich IV is the goal. */
.ivhv-cheap { color: var(--color-profit-text); font-weight: 600; }
.ivhv-fair  { color: var(--text-secondary); }
.ivhv-rich  { color: var(--color-loss-text); font-weight: 600; }

/* Per-contract breakout score in the results table (the group header keeps the pill). */
.bk-score        { font-weight: 700; }
.bk-score-strong { color: var(--color-profit-text); }
.bk-score-mod    { color: var(--color-warning); }
.bk-score-weak   { color: var(--text-tertiary); }
.bk-score-avoid  { color: var(--color-loss-text); }

/* --------------------------------------------------------------------------
   Ledger-adjustment synthetic rows (2026-07-22)
   A LedgerAdjustment shown alongside broker activities in campaign/ledger
   tables — an out-of-ledger movement (e.g. a missing assignment buy) that MOF
   tracks outside the immutable Activity table. Visually distinct so it is never
   mistaken for a broker row. Used by campaign_manager, cycle_detail_report,
   campaign_history and symbol_detail_report.
   -------------------------------------------------------------------------- */
/* Long option leg held as protection on a wheel position (Open Positions → Wheel tab).
   Marks a long that is insurance on a CSP/covered call rather than a spread leg — the
   distinction comes from the user's manually-managed campaign, not the position shape. */
.protective-leg-badge {
  display: inline-block;
  margin-left: 0.4rem;
  padding: 1px 6px;
  font-size: var(--text-size-2xs, 0.6rem);
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--color-action);
  background: color-mix(in srgb, var(--color-action) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--color-action) 40%, transparent);
  border-radius: var(--radius-sm, 4px);
  flex-shrink: 0;
}

.ledger-adj-badge {
  display: inline-block;
  padding: 1px 6px;
  font-size: var(--text-size-2xs, 0.6rem);
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--color-warning, #b45309);
  background: color-mix(in srgb, var(--color-warning, #b45309) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--color-warning, #b45309) 40%, transparent);
  border-radius: var(--radius-sm, 4px);
  flex-shrink: 0;
}
.is-ledger-adj {
  background: color-mix(in srgb, var(--color-warning, #b45309) 7%, transparent);
}

/* --------------------------------------------------------------------------
   Campaign Manager leg-row cells shared by BOTH leg tables — the individual
   campaign card and the wheel-parent card. They are classes rather than inline
   styles precisely because two places use them (CLAUDE.md -> Styling & CSS);
   the wheel-parent table was added 2026-09-10 and must not re-inline them.
   The rest of the .camp-act-* family still lives in the template's <style>
   block; .ledger-adj-badge / .is-ledger-adj above set the precedent that new
   additions to this row belong here.
   -------------------------------------------------------------------------- */
.camp-act-qty {
  font-family: var(--font-financial);
  font-size: var(--text-size-2xs, 0.65rem);
  color: var(--text-secondary);
  min-width: 28px;
  text-align: right;
}
.camp-act-amt--profit { color: var(--color-profit-text); }
.camp-act-amt--loss   { color: var(--color-loss-text); }

/* Shared empty state for BOTH leg tables, and the wheel-parent leg-table heading. */
.camp-acts-empty {
  font-size: var(--text-size-xs);
  color: var(--text-tertiary);
  text-align: center;
  padding: 0.4rem;
  border: 1px dashed var(--border-color);
  border-radius: var(--radius-md);
  margin-bottom: 0.6rem;
}
.camp-act-rm { margin: 0; flex-shrink: 0; }
.camp-act-rm i { font-size: var(--text-size-2xs, 0.6rem); }
/* --------------------------------------------------------------------------
   Campaign Manager "needs attention" list (campaign_manager_search.html).
   Three states, one component: ready (one click to close), stuck (needs a
   human decision) and awaiting (resolves itself on the next sync). They were
   three inline-styled variants of the same chip; a third state made them
   reusable by definition (CLAUDE.md -> Styling & CSS).
   -------------------------------------------------------------------------- */
.rtc-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.5rem; flex-wrap: wrap;
  padding: 0.45rem 0.65rem;
  border-radius: var(--radius-md);
  background: var(--bg-surface-alt);
  border: 1px solid var(--border-color);
}
.rtc-row--awaiting { opacity: 0.75; }
.rtc-row--stuck { border-left: 3px solid var(--color-warning, #b45309); }
.rtc-row__main { display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; }
.rtc-sym {
  font-weight: 600; font-size: var(--text-size-sm);
  color: var(--color-action); text-decoration: none;
}
.rtc-meta { font-size: var(--text-size-xs); color: var(--text-secondary); }
.rtc-chip {
  font-size: var(--text-size-2xs, 0.6rem); font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.03em;
  padding: 0.1rem 0.4rem; border-radius: var(--radius-sm);
  background: var(--bg-surface); color: var(--text-secondary);
  border: 1px solid var(--border-color);
  white-space: nowrap;
}
.rtc-chip i { font-size: 0.55rem; }
.rtc-chip--ready {
  background: var(--color-profit-bg); color: var(--color-profit-text);
  border-color: var(--color-profit-border);
}
.rtc-chip--stuck {
  background: var(--color-loss-bg); color: var(--color-loss-text);
  border-color: var(--color-loss-border);
}
.rtc-chip--awaiting {
  background: var(--color-warning-bg, var(--bg-surface));
  color: var(--color-warning-text, var(--text-secondary));
  border-color: var(--color-warning-border, var(--border-color));
}
.rtc-action {
  font-size: var(--text-size-xs); color: var(--color-action);
  padding: 0.1rem 0.5rem; border-radius: var(--radius-sm);
  background: var(--color-action-bg);
  border: 1px solid var(--color-action-border);
  text-decoration: none; white-space: nowrap;
}
.rtc-action i { font-size: 0.6rem; }
.rtc-note { font-size: var(--text-size-xs); color: var(--text-tertiary); }
.rtc-legend {
  font-size: var(--text-size-xs); color: var(--text-tertiary);
  margin: 0 0 0.6rem; line-height: 1.5;
}
.rtc-legend dt { display: inline; font-weight: 700; color: var(--text-secondary); }
.rtc-legend dd { display: inline; margin: 0 0 0 0.25rem; }
.rtc-legend div { margin-bottom: 0.3rem; }

.wheel-legs-lbl {
  font-size: var(--text-size-2xs, 0.6rem);
  color: var(--text-secondary);
  text-transform: uppercase;
  font-weight: 600;
  letter-spacing: 0.04em;
  margin-bottom: 0.25rem;
}

/* --------------------------------------------------------------------------
   External quick-links (Barchart chart/overview, symbol-detail report).
   Small, subtle icon links that sit next to a symbol name in tables and
   detail-page headers. Open in a new tab. Reusable via
   includes/_barchart_links.html. Replaces the old per-template inline styles.
   -------------------------------------------------------------------------- */
.ext-link-icon {
  margin-left: 0.25rem;
  color: var(--color-action);
  font-size: 0.75rem;
  opacity: 0.7;
  text-decoration: none;
  flex-shrink: 0;
}
.ext-link-icon:hover { opacity: 1; }

/* ── Corporate-action (rights/warrants) alerts — Phase 7 ──────────────────────
   Plain-language rights/warrant notifications. Two surfaces: a dismissible dashboard
   banner and a persistent Verify-Activities header. Urgency: critical / warning / info.
   Tokens only — no hardcoded colours. */
.corp-alert-group { margin-bottom: 1rem; }
.corp-alert-group__title {
  font-size: var(--text-size-xs); font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.03em; color: var(--text-tertiary); margin: 0 0 0.4rem;
}
.corp-alert {
  display: flex; gap: 0.75rem; align-items: flex-start;
  padding: 0.875rem 1rem; margin-bottom: 0.75rem;
  border: 1px solid var(--border-color); border-left: 4px solid var(--text-tertiary);
  border-radius: var(--radius-md); background: var(--bg-surface);
}
.corp-alert--critical { border-left-color: var(--color-loss);    background: var(--color-loss-bg); }
.corp-alert--warning  { border-left-color: var(--color-warning); background: var(--color-warning-bg); }
.corp-alert--info     { border-left-color: var(--text-tertiary); }
.corp-alert__icon { font-size: 1.25rem; line-height: 1.3; flex-shrink: 0; }
.corp-alert__body { flex: 1; min-width: 0; }
.corp-alert__headline { font-size: var(--text-size-sm); font-weight: 700; color: var(--text-primary); margin-bottom: 0.25rem; }
.corp-alert__text { font-size: var(--text-size-sm); color: var(--text-secondary); line-height: 1.45; margin: 0.15rem 0; }
.corp-alert__action { font-weight: 600; color: var(--text-primary); }
.corp-alert__terms { font-size: var(--text-size-xs); color: var(--text-secondary); line-height: 1.4; margin: 0.35rem 0 0; }
.corp-alert__meta { font-size: var(--text-size-xs); color: var(--text-tertiary); margin-top: 0.4rem; }
.corp-alert__broker {
  font-size: var(--text-size-xs); color: var(--text-tertiary);
  font-family: var(--font-mono, monospace); white-space: pre-wrap; margin: 0.35rem 0 0;
}
.corp-alert__actions { margin-top: 0.5rem; }
.corp-alert__handled {
  background: none; border: 1px solid var(--border-color); border-radius: var(--radius-sm);
  color: var(--text-primary); font-weight: 600; font-size: var(--text-size-xs);
  cursor: pointer; padding: 0.25rem 0.6rem;
}
.corp-alert__handled:hover { background: var(--bg-hover, var(--color-warning-bg)); }
.corp-alert__toggle {
  background: none; border: none; padding: 0; cursor: pointer;
  color: var(--text-secondary); font-size: var(--text-size-xs); text-decoration: underline;
}
.corp-alert__dismiss {
  background: none; border: none; cursor: pointer; color: var(--text-tertiary);
  font-size: 1.15rem; line-height: 1; padding: 0 0.25rem; flex-shrink: 0;
}
.corp-alert__dismiss:hover { color: var(--text-primary); }

/* ──────────────────────────────────────────────────────────────────────────
   Sector grouping (2026-07-29)
   Shared by the three screener tabs (/screener/, ?tab=wheel, ?tab=breakout)
   and the Open Positions "All Positions" table. A collapsible sector band
   above each set of symbol groups / position rows. Tokens only — no
   hardcoded fonts or colours, so a theme change propagates.
   ────────────────────────────────────────────────────────────────────────── */
tr.sector-header-row { cursor: pointer; user-select: none; }
tr.sector-header-row > td {
  padding: 0.45rem 0.75rem;
  background: var(--bg-surface-alt);
  border-top: 2px solid var(--border-strong);
  border-bottom: 1px solid var(--border-color);
}
tr.sector-header-row:hover > td { background: var(--border-color); }

.sector-name {
  font-size: var(--text-size-xs);
  font-weight: 700;
  color: var(--text-primary);
  text-transform: uppercase;
  letter-spacing: 0.07em;
}
.sector-meta {
  margin-left: 0.5rem;
  font-size: var(--text-size-xs);
  font-weight: 400;
  color: var(--text-tertiary);
}
.sector-score {
  margin-left: 0.5rem;
  padding: 0.1rem 0.45rem;
  border-radius: 9999px;
  font-size: var(--text-size-xs);
  font-weight: 700;
  background: var(--color-action-bg);
  color: var(--color-action);
}
.sector-toggle-icon {
  display: inline-block;
  width: 0.85rem;
  font-size: var(--text-size-2xs);
  color: var(--text-tertiary);
  transition: transform 0.15s ease;
}
tr.sector-header-row.collapsed .sector-toggle-icon { transform: rotate(-90deg); }

/* Expand / Collapse All sector bands (2026-08-04). Sits above the Open Positions
   table; only rendered on the sector-grouped All Positions view. */
.sector-bulk-controls {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-bottom: 0.6rem;
}
.sector-bulk-label {
  margin-right: 0.25rem;
  font-size: var(--text-size-xs);
  font-weight: 600;
  color: var(--text-tertiary);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.sector-bulk-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.25rem 0.65rem;
  font-size: var(--text-size-xs);
  font-weight: 600;
  color: var(--text-secondary);
  background: var(--bg-surface);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: var(--transition-std);
}
.sector-bulk-btn:hover {
  color: var(--color-action);
  border-color: var(--color-action);
}

/* Per-sector unrealized P&L on the Open Positions band (2026-08-04). Follows the
   account selector, like the rows underneath it. */
.sector-pnl {
  margin-left: 0.6rem;
  font-size: var(--text-size-xs);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.sector-pnl--up   { color: var(--color-profit-text); }
.sector-pnl--down { color: var(--color-loss-text); }

/* "Already owned" chips (2026-07-30) — percent of each account's equity already
   committed to this sector, from live positions. All-accounts chip first, then one
   per account; a chip at or above 20% is emphasised as a concentration cue. */
.sector-owned {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  margin-left: 0.75rem;
  flex-wrap: wrap;
}
.sector-owned-label {
  font-size: var(--text-size-2xs);
  font-weight: 700;
  color: var(--text-tertiary);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.sector-owned-chip {
  padding: 0.05rem 0.4rem;
  border-radius: 9999px;
  font-size: var(--text-size-2xs);
  font-weight: 600;
  color: var(--text-secondary);
  background: var(--bg-surface);
  border: 1px solid var(--border-color);
  white-space: nowrap;
}
.sector-owned-chip--all {
  font-weight: 700;
  color: var(--text-primary);
  border-color: var(--border-strong);
}
.sector-owned-chip--heavy {
  color: var(--color-warning-text);
  background: var(--color-warning-bg);
  border-color: var(--color-warning-border);
}

/* ──────────────────────────────────────────────────────────────────────────
   Screener symbol-row chips (2026-08-04)
   Price at last capture + move from the prior session's close, and earnings
   proximity, on the collapsible symbol row of all three screener tabs.
   Tokens only — the same green/red pair the P&L surfaces use.
   ────────────────────────────────────────────────────────────────────────── */
.symrow-price {
  margin-left: 0.5rem;
  font-size: var(--text-size-xs);
  font-weight: 700;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}
.symrow-change {
  margin-left: 0.25rem;
  font-size: var(--text-size-xs);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.symrow-change--up   { color: var(--color-profit-text); }
.symrow-change--down { color: var(--color-loss-text); }
.symrow-change--flat { color: var(--text-tertiary); }

.symrow-earnings {
  margin-left: 0.5rem;
  padding: 0.1rem 0.45rem;
  border-radius: 9999px;
  font-size: var(--text-size-2xs);
  font-weight: 700;
  white-space: nowrap;
  border: 1px solid transparent;
}
.symrow-earnings--clear {
  color: var(--color-profit-text);
  background: var(--color-profit-bg);
  border-color: var(--color-profit-border);
}
.symrow-earnings--within {
  color: var(--color-loss-text);
  background: var(--color-loss-bg);
  border-color: var(--color-loss-border);
}
.symrow-earnings--unknown {
  color: var(--text-tertiary);
  background: var(--bg-surface);
  border-color: var(--border-color);
}

/* ──────────────────────────────────────────────────────────────────────────
   Position Risk Profile chips  (/dashboard/strategy-detail/…)  — 2026-09-22
   --------------------------------------------------------------------------
   The four Greek tiles: Directional Bias (delta), Stability (gamma), Daily
   Decay (theta), IV Sensitivity (vega).

   ⚠️ **EXTRACTED FROM FOUR COPIES OF THE SAME INLINE STYLE STRING.** Each tile
   repeated an identical ~340-character `style="…"` with only the colour varying,
   restated again on its badge — eight hand-maintained copies of one component,
   which is what the house rule against reusable inline styling exists to stop.
   The variant is now one class on the tile and the badge inherits it.

   ⚠️ **THE DESCRIPTION TEXT WAS 0.5625rem (9px) AND IS NOW 0.6875rem (11px).**
   The captions state what each Greek MEASURES, not just what it implies, so they
   are longer — and a caption nobody can read is a caption that is not doing its
   job. The tiles are taller; that is the trade, and it was the point.
   ────────────────────────────────────────────────────────────────────────── */

.riskprofile-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 0.75rem;
  padding: 1rem;
  border-bottom: 1px solid var(--border-color);
}

.riskprofile-chip {
  padding: 0.75rem;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  background: var(--bg-surface-alt);
}
.riskprofile-chip--good {
  background: var(--color-profit-bg);
  border-color: var(--color-profit-border);
}
.riskprofile-chip--bad {
  background: var(--color-loss-bg);
  border-color: var(--color-loss-border);
}
.riskprofile-chip--warn {
  background: var(--color-warning-bg);
  border-color: var(--color-warning-border);
}
.riskprofile-chip--info {
  background: var(--color-action-bg);
  border-color: var(--color-action-border);
}

.riskprofile-label {
  font-size: var(--text-size-2xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-tertiary);
}
/* The Greek's own name, kept beside the plain-English label rather than instead
   of it: "Stability" is what it tells you, "Gamma" is what to search for. */
.riskprofile-greek {
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: none;
  opacity: 0.85;
}

.riskprofile-value-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.375rem;
  margin-top: 0.25rem;
}

.riskprofile-value {
  font-family: var(--font-financial);
  font-size: 1rem;
  font-weight: 700;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}
.riskprofile-value--good { color: var(--color-profit-text); }
.riskprofile-value--bad  { color: var(--color-loss-text); }

.riskprofile-badge {
  padding: 0.1rem 0.35rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-color);
  background: var(--bg-surface);
  color: var(--text-secondary);
  font-size: var(--text-size-2xs);
  font-weight: 700;
  white-space: nowrap;
}
.riskprofile-chip--good .riskprofile-badge {
  background: var(--color-profit-bg);
  border-color: var(--color-profit-border);
  color: var(--color-profit-text);
}
.riskprofile-chip--bad .riskprofile-badge {
  background: var(--color-loss-bg);
  border-color: var(--color-loss-border);
  color: var(--color-loss-text);
}
.riskprofile-chip--warn .riskprofile-badge {
  background: var(--color-warning-bg);
  border-color: var(--color-warning-border);
  color: var(--color-warning-text);
}
.riskprofile-chip--info .riskprofile-badge {
  background: var(--color-action-bg);
  border-color: var(--color-action-border);
  color: var(--color-action);
}

/* What the number MEASURES — the sentence that was missing. */
.riskprofile-what {
  margin-top: 0.45rem;
  font-size: var(--text-size-xs);
  line-height: 1.45;
  color: var(--text-secondary);
}
/* What it MEANS for this position, given the reading above. */
.riskprofile-sowhat {
  margin-top: 0.3rem;
  font-size: var(--text-size-xs);
  line-height: 1.45;
  font-weight: 600;
  color: var(--text-primary);
}

/* ⚠️ The Greeks on this page cover the OPTION LEGS ONLY — the view filters on
   `option_root` + `option_expiry_date`, so stock has no row. A covered call
   therefore reads BEARISH on a position the holder is net long. The note says so
   rather than leaving the reader to discover it. */
.riskprofile-scope {
  margin: 0.3rem 0 0;
  font-size: var(--text-size-xs);
  line-height: 1.45;
  color: var(--text-tertiary);
}

/* Volatility reading on the screener symbol row (2026-09-22): IV Rank, IV Percentile and
   30-day realised (historical) volatility. One neutral chip, deliberately uncoloured — a
   high IV Rank is good for a seller and bad for a buyer, and the screener serves both, so
   a green/red pair here would assert a verdict the page does not hold. */
.symrow-iv {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-left: 0.5rem;
  padding: 0.1rem 0.45rem;
  border-radius: 9999px;
  border: 1px solid var(--border-color);
  background: var(--bg-surface-alt);
  white-space: nowrap;
}
.symrow-iv-part {
  display: inline-flex;
  align-items: baseline;
  gap: 0.2rem;
}
.symrow-iv-key {
  font-size: var(--text-size-2xs);
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--text-tertiary);
}
.symrow-iv-val {
  font-size: var(--text-size-xs);
  font-weight: 700;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}

/* ==========================================================================
   Background-job progress banner  (2026-09-06)
   --------------------------------------------------------------------------
   Used by Approve All on /dashboard/staging/verify-activities/ to report a job
   running on the Celery worker. Component classes, not page CSS — a second
   long-running button anywhere should reuse these rather than restyle them.

   Every colour is a design token. The four states (running / complete / failed
   / skipped-warning) are the ONLY thing the modifier classes change.
   ========================================================================== */
.job-banner {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.875rem 1.125rem;
  margin-bottom: 1.25rem;
  border: 1px solid var(--border-color);
  border-left: 4px solid var(--text-tertiary);
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
  background: var(--bg-surface-alt);
  font-family: var(--font-ui);
}
.job-banner--running  { border-left-color: var(--color-action); background: var(--color-action-bg); }
.job-banner--complete { border-left-color: var(--color-profit); background: var(--color-profit-bg); }
.job-banner--failed   { border-left-color: var(--color-loss);   background: var(--color-loss-bg); }

.job-banner__head {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  font-weight: 600;
  color: var(--text-primary);
}
.job-banner--complete .job-banner__head { color: var(--color-profit-text); }
.job-banner--failed   .job-banner__head { color: var(--color-loss-text); }

.job-banner__step {
  font-size: 0.8125rem;
  font-weight: 400;
  color: var(--text-secondary);
}

/* The bar is a STEP bar, never a time bar: it fills in whole steps, so it can
   only ever report progress the job has actually made. A time-based bar stalled
   at 80% reads worse than "step 3 of 4". */
.job-banner__track {
  height: 6px;
  border-radius: 999px;
  background: var(--border-color);
  overflow: hidden;
}
.job-banner__fill {
  height: 100%;
  border-radius: 999px;
  background: var(--color-action);
  transition: width 0.4s ease;
}
.job-banner--complete .job-banner__fill { background: var(--color-profit); }
.job-banner--failed   .job-banner__fill { background: var(--color-loss); }

.job-banner__counts {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  font-size: 0.8125rem;
  color: var(--text-secondary);
}
.job-banner__count-value { font-weight: 700; color: var(--text-primary); }

.job-banner__notes {
  margin: 0;
  padding-left: 1.125rem;
  font-size: 0.8125rem;
  color: var(--text-secondary);
}
.job-banner__notes li { margin-top: 0.25rem; }

.job-banner__error {
  font-size: 0.8125rem;
  color: var(--color-loss-text);
}

/* The spinner is decorative; the step label and elapsed clock carry the meaning. */
.job-banner__spinner {
  width: 14px;
  height: 14px;
  flex: 0 0 auto;
  border: 2px solid var(--color-action-border);
  border-top-color: var(--color-action);
  border-radius: 50%;
  animation: job-banner-spin 0.8s linear infinite;
}
@keyframes job-banner-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  .job-banner__spinner { animation: none; }
  .job-banner__fill { transition: none; }
}

/* The "you can leave this page" line inside a running job banner (2026-09-06). */
.job-banner__hint {
  margin: 0;
  font-size: 0.8125rem;
  color: var(--text-secondary);
}

/* ==========================================================================
   Close control on a job banner  (2026-09-06, made legible 2026-09-09)
   --------------------------------------------------------------------------
   ⚠️ IT IS A LABELLED BUTTON, NOT A BARE GLYPH. The first version was an
   unstyled `&times;` with no border and `--text-tertiary` — reported as not
   obviously a close control at all. A dismiss the user cannot recognise is the
   same outcome as no dismiss, which is the defect this control exists to fix.

   ⚠️ `margin-left:auto` sends it to the RIGHT EDGE of the header row, and it is
   the LAST child of that row for exactly this reason — placed mid-row it pushes
   everything after it right, stranding the × between the title and the step text.

   Two states, two labels: "Dismiss" deletes the finished run; "Hide" only hides a
   running one in this browser. Both use this class.
   ========================================================================== */
.job-banner__dismiss-form { margin-left: auto; display: flex; }
.job-banner__dismiss {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  flex: 0 0 auto;
  /* Comfortably above the ~24px minimum touch target — this is used on phones. */
  min-height: 1.75rem;
  padding: 0.125rem 0.625rem;
  font-family: var(--font-ui);
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  color: var(--text-secondary);
  background: var(--bg-surface);
  border: 1px solid var(--border-color);
  border-radius: 999px;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.job-banner__dismiss:hover {
  color: var(--text-primary);
  background: var(--bg-surface-alt);
  border-color: var(--border-strong);
}
.job-banner__dismiss:focus-visible {
  outline: none;
  border-color: var(--border-focus);
  box-shadow: var(--shadow-focus);
}
.job-banner__dismiss-x {
  font-size: 1rem;
  line-height: 1;
  /* Optical alignment: the glyph sits high in its own box. */
  margin-top: -0.0625rem;
}

@media (prefers-reduced-motion: reduce) {
  .job-banner__dismiss { transition: none; }
}

/* Win Rate Analytics — declared insurance is excluded from win rates (Option B, 2026-09-11) */
.wr-insurance-note { margin: 0 0 0.75rem; padding: 0.5rem 0.75rem; border-radius: var(--radius-md);
                     background: var(--bg-surface-alt); border: 1px solid var(--border-color);
                     color: var(--text-secondary); font-size: var(--text-size-xs); line-height: 1.5; }

/* Open Positions — insurance hidden from the Breakout tab (Option B, 2026-09-11) */
.op-insurance-note { margin: 0 0 1rem; padding: 0.5rem 0.75rem; border-radius: var(--radius-md);
                     background: var(--bg-surface-alt); border: 1px solid var(--border-color);
                     color: var(--text-secondary); font-size: var(--text-size-xs); line-height: 1.5; }

/* Partner position chip — "George-CC" on the screener and Open Positions (2026-09-25) */
.partner-chip { display: inline-flex; align-items: center; margin-left: 6px; padding: 1px 7px;
                border-radius: var(--radius-full); background: var(--color-purple-bg);
                border: 1px solid var(--color-purple-border); color: var(--color-purple);
                font-size: var(--text-size-2xs); font-weight: 700; white-space: nowrap; cursor: help; }
