/* design-system.css — CFIN Visual Language v2 tokens + primitives
   Loaded after theme.css. Defines the surface / state / elevation /
   typography / spacing / radius / motion system both /dashboard and
   /charts consume. See docs/superpowers/specs/2026-05-19-cfin-visual-language-v2.md
*/

:root {
  /* 5.1 Surface scale — substantial card tints (not see-through glass).
     Matches theme.css --bg-card opacity so /dashboard /charts and the
     21 standalone pages all read as one product. */
  --surface-0: transparent;
  --surface-1: rgba(44, 44, 46, 0.92);
  --surface-2: rgba(54, 54, 58, 0.94);
  --surface-3: rgba(64, 64, 68, 0.96);
  --surface-hover: rgba(76, 76, 82, 0.96);

  /* 5.2 State tints — profit */
  --ds-profit-tint:        rgba(82, 202, 116, 0.10);
  --ds-profit-tint-strong: rgba(82, 202, 116, 0.18);
  --ds-profit-border:      rgba(82, 202, 116, 0.35);
  --ds-profit-glow:        rgba(82, 202, 116, 0.55);
  /* loss */
  --ds-loss-tint:          rgba(237, 100, 95, 0.10);
  --ds-loss-tint-strong:   rgba(237, 100, 95, 0.18);
  --ds-loss-border:        rgba(237, 100, 95, 0.40);
  --ds-loss-glow:          rgba(237, 100, 95, 0.55);
  /* accent */
  --ds-accent-tint:        rgba(10, 132, 255, 0.12);
  --ds-accent-tint-strong: rgba(10, 132, 255, 0.20);
  --ds-accent-border:      rgba(10, 132, 255, 0.45);
  --ds-accent-glow:        rgba(10, 132, 255, 0.55);
  /* warn */
  --ds-warn-tint:          rgba(255, 204, 0, 0.14);
  --ds-warn-tint-strong:   rgba(255, 204, 0, 0.22);
  --ds-warn-border:        rgba(255, 204, 0, 0.40);
  --ds-warn-glow:          rgba(255, 204, 0, 0.50);
  /* neutral */
  --ds-neutral-tint:        rgba(255,255,255,0.06);
  --ds-neutral-tint-strong: rgba(255,255,255,0.10);
  --ds-neutral-border:      rgba(255,255,255,0.18);
  --ds-neutral-glow:        rgba(255,255,255,0.20);

  /* 5.3 Elevation — hairline border + drop shadow per tier */
  --ds-hairline: 1px solid var(--glass-border);
  --elev-rest:  none;
  --elev-card:  0 10px 32px rgba(0,0,0,0.55);
  --elev-float: 0 8px 24px rgba(0,0,0,0.40);

  /* 5.4 Typography ramp */
  --font-caption: 11px;
  --font-body:    13px;
  --font-subhead: 16px;
  --font-section: 22px;
  --font-hero:    40px;
  --font-display: 56px;
  --fw-regular: 400;
  --fw-medium:  500;
  --fw-semi:    600;

  /* 5.5 Spacing ramp */
  --space-1:  4px;
  --space-2:  8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;

  /* 5.6 Radius — use-named */
  --radius-chip:    6px;
  --radius-control: 8px;
  --radius-card:   12px;
  --radius-hero:   16px;
  /* --radius-pill already defined in theme.css; we alias here for clarity */
  --radius-pill-ds: 100px;

  /* 5.7 Motion */
  --dur-micro:  120ms;
  --dur-toggle: 200ms;
  --dur-enter:  320ms;
  --ease-standard: cubic-bezier(.2, .7, .2, 1);
}

:root.light {
  /* Light-mode surfaces: cards must read as DISTINCT against the white
     page bg without looking like blocks. Subtle off-white + reinforced
     hairline border (set below) does the job. */
  --surface-1: #fbfbfd;
  --surface-2: #f4f4f8;
  --surface-3: #ededf2;
  --surface-hover: #e6e6ec;
  /* Reinforce hairline in light mode so card edges are visible against
     the white body without resorting to heavy shadows. */
  --ds-hairline: 1px solid rgba(0, 0, 0, 0.10);

  --ds-profit-tint:        rgba(38, 148, 68, 0.10);
  --ds-profit-tint-strong: rgba(38, 148, 68, 0.16);
  --ds-profit-border:      rgba(38, 148, 68, 0.32);
  --ds-profit-glow:        rgba(38, 148, 68, 0.32);
  --ds-loss-tint:          rgba(206, 48, 42, 0.09);
  --ds-loss-tint-strong:   rgba(206, 48, 42, 0.16);
  --ds-loss-border:        rgba(206, 48, 42, 0.32);
  --ds-loss-glow:          rgba(206, 48, 42, 0.32);
  --ds-accent-tint:        rgba(20, 95, 200, 0.10);
  --ds-accent-tint-strong: rgba(20, 95, 200, 0.16);
  --ds-accent-border:      rgba(20, 95, 200, 0.30);
  --ds-accent-glow:        rgba(20, 95, 200, 0.30);
  --ds-warn-tint:          rgba(180, 130, 0, 0.12);
  --ds-warn-tint-strong:   rgba(180, 130, 0, 0.18);
  --ds-warn-border:        rgba(180, 130, 0, 0.32);
  --ds-warn-glow:          rgba(180, 130, 0, 0.32);
  --ds-neutral-tint:        rgba(0,0,0,0.04);
  --ds-neutral-tint-strong: rgba(0,0,0,0.08);
  --ds-neutral-border:      rgba(0,0,0,0.14);
  --ds-neutral-glow:        rgba(0,0,0,0.14);

  --elev-card:  0 8px 24px rgba(15,15,30,0.10), 0 2px 6px rgba(15,15,30,0.06);
  --elev-float: 0 6px 18px rgba(15,15,30,0.14);
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-micro:  0ms;
    --dur-toggle: 0ms;
    --dur-enter:  0ms;
  }
}

/* Number utility — tabular-nums for all numeric values. Body prose
   does NOT get this; it must be opted-in via .cfin-num or by being
   inside .cfin-stat__value. */
.cfin-num,
.cfin-stat__value {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1, 'cv11' 1;
}

/* ========================================================================
   PRIMITIVE: .cfin-card
   Glass surface with hairline border + elevation. Three size variants.
   ======================================================================== */
.cfin-card {
  background: var(--surface-1);
  border: var(--ds-hairline);
  border-radius: var(--radius-card);
  box-shadow: var(--elev-card);
  padding: var(--space-4);
  color: var(--text-main);
  transition:
    background var(--dur-micro) var(--ease-standard),
    border-color var(--dur-micro) var(--ease-standard),
    box-shadow var(--dur-micro) var(--ease-standard);
}
.cfin-card--hero {
  background: var(--surface-2);
  border-radius: var(--radius-hero);
  padding: var(--space-5);
}
.cfin-card--inline {
  background: var(--surface-1);
  border: none;
  box-shadow: none;
  border-radius: var(--radius-card);
  padding: var(--space-3);
}
.cfin-card--interactive { cursor: pointer; }
.cfin-card--interactive:hover {
  background: var(--surface-hover);
  border-color: var(--ds-accent-border);
}
.cfin-card--interactive:focus-visible {
  outline: 2px solid var(--ds-accent-border);
  outline-offset: 2px;
}
.cfin-card--state-profit { border-color: var(--ds-profit-border); }
.cfin-card--state-loss   { border-color: var(--ds-loss-border); }
.cfin-card--state-warn   { border-color: var(--ds-warn-border); }
.cfin-card--state-accent { border-color: var(--ds-accent-border); }

/* ========================================================================
   PRIMITIVE: .cfin-stat
   Single KPI: label + value, optional explainer popup target.
   ======================================================================== */
.cfin-stat {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-2) 0;
  min-width: 0;
}
.cfin-stat__label {
  font-size: var(--font-caption);
  font-weight: var(--fw-medium);
  color: var(--text-muted);
  letter-spacing: 0.02em;
  text-transform: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cfin-stat__value {
  /* Default matches existing .hero-metric-value (18px / 600) for parity
     with non-system pages. Use --lg for the big balance number, --xl
     for true hero display. */
  font-size: 18px;
  font-weight: var(--fw-semi);
  color: var(--text-main);
  line-height: 1.15;
}
.cfin-stat__value--sm { font-size: var(--font-body); }
.cfin-stat__value--md { font-size: var(--font-subhead); }
.cfin-stat__value--lg {
  font-size: 36px;
  font-weight: 700;
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  line-height: 1.1;
}
.cfin-stat__value--xl {
  font-size: var(--font-hero);
  font-weight: 700;
  line-height: 1.05;
}
.cfin-stat__value--state-profit { color: var(--profit); }
.cfin-stat__value--state-loss   { color: var(--loss); }
.cfin-stat--clickable {
  cursor: pointer;
  border-radius: var(--radius-control);
  padding: var(--space-2);
  transition: background var(--dur-micro) var(--ease-standard);
}
.cfin-stat--clickable:hover { background: var(--ds-neutral-tint); }
.cfin-stat--clickable:focus-visible {
  outline: 2px solid var(--ds-accent-border);
  outline-offset: 2px;
}

/* ========================================================================
   PRIMITIVES: chips, pills, status dots
   ======================================================================== */
.cfin-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 2px var(--space-2);
  font-size: var(--font-caption);
  font-weight: var(--fw-medium);
  border-radius: var(--radius-chip);
  background: var(--ds-neutral-tint);
  border: 1px solid var(--ds-neutral-border);
  color: var(--text-main);
  white-space: nowrap;
}
.cfin-chip--active { background: var(--ds-accent-tint); border-color: var(--ds-accent-border); }
.cfin-chip--profit { background: var(--ds-profit-tint); border-color: var(--ds-profit-border); color: var(--profit); }
.cfin-chip--loss   { background: var(--ds-loss-tint);   border-color: var(--ds-loss-border);   color: var(--loss); }
.cfin-chip--warn   { background: var(--ds-warn-tint);   border-color: var(--ds-warn-border); }

.cfin-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 2px 10px;
  font-size: var(--font-caption);
  font-weight: var(--fw-medium);
  border-radius: var(--radius-pill-ds);
  background: var(--ds-neutral-tint);
  border: 1px solid var(--ds-neutral-border);
}
.cfin-pill--profit { background: var(--ds-profit-tint); border-color: var(--ds-profit-border); color: var(--profit); }
.cfin-pill--loss   { background: var(--ds-loss-tint);   border-color: var(--ds-loss-border);   color: var(--loss); }
.cfin-pill--warn   { background: var(--ds-warn-tint);   border-color: var(--ds-warn-border); }

.cfin-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--ds-neutral-border);
  box-shadow: 0 0 0 1px var(--ds-neutral-border);
}
.cfin-dot--live   { background: var(--profit); box-shadow: 0 0 8px var(--ds-profit-glow); animation: cfin-dot-pulse 2s ease-in-out infinite; }
.cfin-dot--stale  { background: var(--loss);   box-shadow: 0 0 8px var(--ds-loss-glow); }
.cfin-dot--warn   { background: var(--ds-warn-glow); }
@keyframes cfin-dot-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.55; }
}
body.tab-hidden .cfin-dot--live { animation-play-state: paused; }

/* ========================================================================
   PRIMITIVES: popover, divider
   ======================================================================== */
.cfin-popover {
  background: var(--surface-3);
  border: var(--ds-hairline);
  border-radius: var(--radius-card);
  box-shadow: var(--elev-float);
  padding: var(--space-3);
  color: var(--text-main);
  font-size: var(--font-body);
  line-height: 1.45;
  max-width: 320px;
  z-index: 9000;
}
.cfin-popover--sm { padding: var(--space-2); font-size: var(--font-caption); max-width: 240px; }

.cfin-divider {
  height: 1px;
  background: var(--glass-border);
  border: 0;
  margin: var(--space-3) 0;
}
.cfin-divider--vertical {
  width: 1px;
  height: auto;
  align-self: stretch;
  margin: 0 var(--space-3);
}

/* ========================================================================
   GLOBAL ADAPTERS — retarget legacy classes used across all user-dashboard
   pages onto system tokens. This block is what makes /trades /stats /profile
   /ea_settings /support /withdrawal-guide /verify-balance read as the same
   product as /dashboard and /charts — without editing 21 templates.
   Surface + border + radius + pill/badge geometry only. Layout/padding/font-
   size of each component preserved so we don't shift page rhythms.
   ======================================================================== */

/* --- Cards & panels: one surface treatment everywhere ----------------- */
.glass-card,
.info-panel,
.support-card,
.ticket-card,
.trades-stat-card,
.page-header-card,
.loading-card,
.ai-chat-panel,
.filters-panel,
.version-details-panel,
.charts-card,
.kpi-card,
.stat-card,
.metric-card,
.widget-card,
.profile-section,
.settings-section,
.dashboard-section {
  background: var(--surface-1) !important;
  border: var(--ds-hairline) !important;
  border-radius: var(--radius-card) !important;
  box-shadow: var(--elev-card) !important;
  color: var(--text-main);
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

/* Hero / page-header cards get the larger radius for visual weight parity
   with .cfin-card--hero on /dashboard. */
.page-header-card,
.dashboard-hero {
  border-radius: var(--radius-hero) !important;
}

/* --- Buttons: unify chrome (radius + border) site-wide. Padding/size
   left alone so existing layouts don't reflow. ------------------------ */
.btn,
.btn-primary,
.btn-accent,
.btn-ghost,
.btn-icon,
.btn-cancel,
.btn-danger,
.btn-warning-outline,
.btn-submit,
.btn-submit-rating,
.btn-skip-rating,
.btn-new-ticket,
.btn-edit-profile,
.btn-text-link,
.btn-text-toggle,
.charts-btn,
.charts-btn-help,
.banner-link-btn,
.modal-close-btn,
.column-toggle-btn,
.filter-toggle-btn,
.filter-done-btn,
.search-clear-btn,
.sup-attach-btn,
.rating-helpful-btn,
.mobile-logout-btn,
.ai-chat-header-btn,
.ai-chat-send-btn,
.wg-cta-btn,
.vb-btn {
  border-radius: var(--radius-control);
  transition:
    background var(--dur-micro) var(--ease-standard),
    border-color var(--dur-micro) var(--ease-standard),
    color var(--dur-micro) var(--ease-standard),
    box-shadow var(--dur-micro) var(--ease-standard);
}
.btn-primary,
.btn-accent {
  background: var(--ds-accent-tint-strong);
  border: 1px solid var(--ds-accent-border);
  color: var(--text-main);
}
.btn-primary:hover,
.btn-accent:hover {
  background: var(--ds-accent-tint-strong);
  border-color: var(--ds-accent-glow);
}
.btn-danger {
  background: var(--ds-loss-tint-strong);
  border: 1px solid var(--ds-loss-border);
  color: var(--loss);
}
.btn-warning-outline {
  background: transparent;
  border: 1px solid var(--ds-warn-border);
  color: var(--text-main);
}
.btn-ghost,
.btn-text-link,
.btn-text-toggle {
  background: transparent;
  border: 1px solid transparent;
  color: var(--text-main);
}
.btn-ghost:hover {
  background: var(--surface-hover);
  border-color: var(--ds-neutral-border);
}
.btn-icon,
.modal-close-btn,
.search-clear-btn,
.column-toggle-btn,
.filter-toggle-btn,
.ai-chat-header-btn {
  background: var(--surface-1);
  border: 1px solid var(--ds-neutral-border);
  color: var(--text-main);
}
.btn-icon:hover,
.modal-close-btn:hover,
.search-clear-btn:hover,
.column-toggle-btn:hover,
.filter-toggle-btn:hover,
.ai-chat-header-btn:hover {
  background: var(--surface-hover);
  border-color: var(--ds-accent-border);
}
.btn-lg  { border-radius: var(--radius-card); }
.btn-sm  { border-radius: var(--radius-chip); }

/* --- Badges & pills: one pill geometry everywhere -------------------- */
.status-badge,
.account-badge,
.version-badge,
.unread-badge,
.filter-badge,
.ticket-filter-pill,
.qf-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 2px var(--space-2);
  font-size: var(--font-caption);
  font-weight: var(--fw-medium);
  border-radius: var(--radius-pill-ds);
  background: var(--ds-neutral-tint);
  border: 1px solid var(--ds-neutral-border);
  color: var(--text-main);
  white-space: nowrap;
  line-height: 1.4;
}
.status-badge.is-live,
.status-badge.live,
.status-badge.connected {
  background: var(--ds-profit-tint);
  border-color: var(--ds-profit-border);
  color: var(--profit);
}
.status-badge.is-stale,
.status-badge.stale,
.status-badge.error,
.status-badge.disconnected {
  background: var(--ds-loss-tint);
  border-color: var(--ds-loss-border);
  color: var(--loss);
}
.status-badge.is-warn,
.status-badge.warn,
.status-badge.warning {
  background: var(--ds-warn-tint);
  border-color: var(--ds-warn-border);
}
.unread-badge {
  background: var(--ds-accent-tint-strong);
  border-color: var(--ds-accent-border);
  color: var(--text-main);
}
.version-badge {
  background: var(--ds-accent-tint);
  border-color: var(--ds-accent-border);
}

/* Vault badge color is a brand token — surface it identically everywhere
   so anything labelled "vault" pulls the same blue across pages. */
.hm-dot.vault,
.legend-swatch.c-vault,
.badge-vault,
.vault-pill,
[data-metric="vault"] .cfin-stat__value {
  color: var(--series-vault) !important;
}
.hm-dot.vault,
.legend-swatch.solid.c-vault {
  background: var(--series-vault) !important;
}

/* --- Notification banners: shared chrome cross-page.
   theme.css hard-codes gradient backgrounds + white text on .beta-banner —
   override with !important so all banner types read as one component, just
   with different border-colour denoting severity. Pill geometry preserved
   so they still float at bottom-centre exactly as before. ------------- */
.notif-banner,
.session-idle-banner,
.maintenance-banner,
.beta-banner {
  background: var(--surface-2) !important;
  border: 1px solid var(--ds-accent-border) !important;
  border-radius: var(--radius-pill-ds) !important;
  box-shadow: var(--elev-float) !important;
  color: var(--text-main) !important;
  /* Drop the linear-gradient text-on-white look */
  background-image: none !important;
}
.beta-banner a,
.notif-banner a,
.session-idle-banner a {
  color: var(--accent, var(--ds-accent-border)) !important;
  text-decoration: underline;
}
.notif-banner.severity-warning,
.notif-banner.is-warning,
.session-idle-banner {
  border-color: var(--ds-warn-border) !important;
}
.notif-banner.severity-error,
.notif-banner.is-error {
  border-color: var(--ds-loss-border) !important;
}
.notif-banner.severity-success,
.notif-banner.is-success {
  border-color: var(--ds-profit-border) !important;
}
.notif-banner.severity-info,
.notif-banner.is-info,
.beta-banner {
  border-color: var(--ds-accent-border) !important;
}
.beta-banner.beta-banner-green {
  border-color: var(--ds-profit-border) !important;
}
.maintenance-banner {
  border-color: var(--ds-warn-border) !important;
}

/* --- Tables: one chrome cross-page (Trades, Stats, anywhere) ---------- */
.trades-table,
.standalone-table,
table.sortable,
table.cfin-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: var(--font-body);
  color: var(--text-main);
  background: transparent;
}
.trades-table thead th,
.standalone-table thead th,
table.sortable thead th,
table.cfin-table thead th {
  background: var(--surface-1);
  color: var(--text-muted);
  font-size: var(--font-caption);
  font-weight: var(--fw-medium);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-align: left;
  padding: var(--space-3) var(--space-3);
  border-bottom: var(--ds-hairline);
  position: sticky;
  top: 0;
  z-index: 1;
}
.trades-table tbody td,
.standalone-table tbody td,
table.sortable tbody td,
table.cfin-table tbody td {
  padding: var(--space-3) var(--space-3);
  border-bottom: 1px solid var(--ds-neutral-border);
  font-variant-numeric: tabular-nums;
}
.trades-table tbody tr:hover,
.standalone-table tbody tr:hover,
table.sortable tbody tr:hover,
table.cfin-table tbody tr:hover {
  background: var(--ds-neutral-tint);
}
.trades-table-container,
.cfin-table-container {
  background: var(--surface-1);
  border: var(--ds-hairline);
  border-radius: var(--radius-card);
  box-shadow: var(--elev-card);
  overflow: hidden;
}

/* --- Section headings & KPI numbers: same weight/size cross-page ----- */
.page-header h1,
.section-header h1,
.section-header h2,
.support-card-info h2,
.profile-section h2,
.settings-section h2,
.dashboard-section h2 {
  font-size: var(--font-section);
  font-weight: var(--fw-semi);
  color: var(--text-main);
  line-height: 1.2;
  letter-spacing: -0.01em;
}
.page-header h2,
.section-header h3 {
  font-size: var(--font-subhead);
  font-weight: var(--fw-semi);
  color: var(--text-main);
}
.kpi-value,
.stat-value,
.metric-value,
.trades-stat-card .value,
.trades-stat-card .stat-value {
  font-size: 18px;
  font-weight: var(--fw-semi);
  color: var(--text-main);
  font-variant-numeric: tabular-nums;
}
.kpi-label,
.stat-label,
.metric-label,
.trades-stat-card .label {
  font-size: var(--font-caption);
  font-weight: var(--fw-medium);
  color: var(--text-muted);
  letter-spacing: 0.02em;
}

/* --- Modals & notification dropdown: drop the glass/blur look the user
   asked us to remove. Opaque surface-2 + hairline matches every other
   panel on the dashboard so popovers read as the same product. --------- */
.modal-content,
.notification-dropdown,
.pending-modal,
.rating-modal {
  background: var(--surface-2) !important;
  border: var(--ds-hairline) !important;
  border-radius: var(--radius-hero) !important;
  box-shadow: var(--elev-float) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}
.notification-dropdown {
  border-radius: var(--radius-card) !important;
}
.modal-overlay {
  background: rgba(0, 0, 0, 0.55) !important;
  backdrop-filter: blur(2px) !important;
  -webkit-backdrop-filter: blur(2px) !important;
}

/* --- Withdrawal Guide cards (wg-*): page ships its own surfaces using the
   old --bg-panel / --border-subtle tokens. Route them through v2 so the
   step cards + FAQ details read identically to /dashboard cards. ------- */
.wg-step,
.wg-faq details,
.wg-card {
  background: var(--surface-1) !important;
  border: var(--ds-hairline) !important;
  border-radius: var(--radius-card) !important;
  box-shadow: var(--elev-card) !important;
}
.wg-step:hover,
.wg-faq details[open] {
  border-color: var(--ds-accent-border) !important;
  box-shadow: 0 0 0 1px var(--ds-accent-border), var(--elev-card) !important;
}
.wg-faq-answer {
  border-top: 1px solid var(--ds-neutral-border) !important;
}
.wg-tag {
  background: var(--ds-accent-tint) !important;
  border: 1px solid var(--ds-accent-border) !important;
  color: var(--accent, var(--text-main)) !important;
  border-radius: var(--radius-pill-ds) !important;
}

/* --- Verify Balance state boxes: replace hand-rolled rgba severity tints
   with v2 state tokens so warn/error/success match dashboard banners. - */
.vb-card {
  background: var(--surface-1) !important;
  border: var(--ds-hairline) !important;
  border-radius: var(--radius-card) !important;
  box-shadow: var(--elev-card) !important;
}
.vb-mismatch,
.vb-error {
  background: var(--ds-loss-tint) !important;
  border: 1px solid var(--ds-loss-border) !important;
  border-radius: var(--radius-card) !important;
}
.vb-email-sent {
  background: var(--ds-profit-tint) !important;
  border: 1px solid var(--ds-profit-border) !important;
  border-radius: var(--radius-card) !important;
}
.vb-noscript {
  background: var(--ds-warn-tint) !important;
  border: 1px solid var(--ds-warn-border) !important;
  border-radius: var(--radius-card) !important;
}

/* --- Remaining glass/blur surfaces across profile, referral, settings,
   trades, confirm/session/keyboard modals, VNC overlay. Drop the
   backdrop-filter + translucent --glass-bg so every panel reads as the
   same opaque v2 surface. Chat bubbles (.ai-msg-bubble, .message.staff)
   intentionally excluded — transparency there is deliberate. ----------- */
.profile-hero,
.referral-link-card,
.referral-stat-card,
.referred-user-card,
.your-plan-card,
.settings-version-card,
.confirm-modal,
.session-modal,
.keyboard-help-content,
.stat-card-accent,
.trade-card,
.vnc-modal-overlay .vnc-modal {
  background: var(--surface-1) !important;
  border: var(--ds-hairline) !important;
  border-radius: var(--radius-card) !important;
  box-shadow: var(--elev-card) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

/* --- Toast + export-toast + network-status: the popup family. The "All
   marked as read" / "All cleared" notifications come through here, plus
   the stale-data warning and the CSV export progress pill. Base layer is
   opaque surface-2 + hairline + elev-float so they read as the same
   product as the notification dropdown. Variant tints route through the
   v2 state tokens used by .vb-* and dashboard banners — no more
   hand-rolled 0.1-alpha gradients. ------------------------------------- */
.toast,
.export-toast,
.network-status {
  background: var(--surface-2) !important;
  border: var(--ds-hairline) !important;
  border-radius: var(--radius-card) !important;
  box-shadow: var(--elev-float) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}
.toast.success,
.export-toast.success {
  background: var(--ds-profit-tint) !important;
  border: 1px solid var(--ds-profit-border) !important;
}
.toast.error,
.export-toast.error,
.network-status.offline {
  background: var(--ds-loss-tint) !important;
  border: 1px solid var(--ds-loss-border) !important;
}
.toast.warning {
  background: var(--ds-warn-tint) !important;
  border: 1px solid var(--ds-warn-border) !important;
}
.toast.info,
.export-toast.info {
  background: var(--ds-accent-tint) !important;
  border: 1px solid var(--ds-accent-border) !important;
}

/* --- Table container, column-menu, pagination: trades/stats table chrome
   still hand-rolled with glass-bg. Wrap them in v2 surface so the table,
   its column-toggle dropdown, and its pagination strip all match. The
   column-menu specifically should look identical to .notification-dropdown
   since both are anchored dropdowns. ------------------------------------ */
.table-container,
.pagination {
  background: var(--surface-1) !important;
  border: var(--ds-hairline) !important;
  border-radius: var(--radius-card) !important;
  box-shadow: var(--elev-card) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}
.column-menu {
  background: var(--surface-2) !important;
  border: var(--ds-hairline) !important;
  border-radius: var(--radius-card) !important;
  box-shadow: var(--elev-float) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

/* --- KPI card flipped face: the reverse side that shows the formula
   when you hover/flip a KPI tile. Was rendered on --glass-bg with its
   own border-light treatment. Route through v2 surface so front + back
   are visually the same product. ---------------------------------------- */
.kpi-flip-back {
  background: var(--surface-2) !important;
  border: var(--ds-hairline) !important;
  box-shadow: var(--elev-card) !important;
}
:root.light .kpi-flip-back {
  background: var(--surface-2) !important;
  border-color: var(--ds-neutral-border) !important;
}

/* --- Inline code/formula chip inside info-popups + referral code chip.
   Both are mono-font tokens that should read like a soft pill, not a
   transparent glass swatch over the panel body. ------------------------- */
.info-panel-formula,
.referral-code {
  background: var(--surface-3, var(--surface-1)) !important;
  border: 1px solid var(--ds-neutral-border) !important;
}

/* --- Hero info popup: the (i) hover popover on KPI cards. Was hand-
   rolling its own --bg-card + blur(16px), out of step with the rest of
   the popover family (modal-content / notification-dropdown / column-menu).
   Route through opaque surface-2 + elev-float so all anchored popovers
   match. ---------------------------------------------------------------- */
.hero-info-popup {
  background: var(--surface-2) !important;
  border: var(--ds-hairline) !important;
  border-radius: var(--radius-card) !important;
  box-shadow: var(--elev-float) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

/* --- Notification banner: the dismissible bottom-floated banner showing
   the latest unread notification. Was rendering on --card-bg with
   blur(12px). Same family as toast/notification-dropdown — opaque
   surface-2 + elev-float. --------------------------------------------- */
.notif-banner {
  background: var(--surface-2) !important;
  border: var(--ds-hairline) !important;
  box-shadow: var(--elev-float) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

/* --- Session idle banner: the "you've been idle" warning pill anchored
   bottom-center. Was using --card-bg with hardcoded #1a1a2e fallback
   and a hardcoded #f59e0b border. Route through v2 surface + warn-token
   border so it matches the rest of the warning surfaces. The 3px left
   ribbon is preserved as the visual marker. ---------------------------- */
.session-idle-banner-inner {
  background: var(--surface-2) !important;
  border: var(--ds-hairline) !important;
  border-left: 3px solid var(--ds-warn-border) !important;
  box-shadow: var(--elev-float) !important;
}
:root.light .session-idle-banner-inner {
  background: var(--surface-2) !important;
  border-left-color: var(--ds-warn-border) !important;
}

/* --- Cookie consent modal: page-local <style> block in
   templates/cookie-consent-banner.html ships its own dark scrim (0.85)
   and --bg-main panel. Bring it into line with the v2 modal pattern
   (.modal-content + .modal-overlay) so the consent prompt looks like
   every other modal on the site. -------------------------------------- */
.cookie-consent-overlay {
  background: rgba(0, 0, 0, 0.55) !important;
  backdrop-filter: blur(2px) !important;
  -webkit-backdrop-filter: blur(2px) !important;
}
.cookie-consent-modal {
  background: var(--surface-2) !important;
  border: var(--ds-hairline) !important;
  border-radius: var(--radius-hero) !important;
  box-shadow: var(--elev-float) !important;
}

/* --- Modal overlay family: each modal flavour shipped its own scrim
   opacity (0.5, 0.55, 0.6, 0.7, 0.85) and blur (4-20px). Standardise
   on the same 0.55 + 2px scrim used by .modal-overlay so dimming
   feels consistent across confirm/session/keyboard/pending/rating
   modals. ------------------------------------------------------------- */
.session-modal-overlay,
.keyboard-help-overlay,
.confirm-modal-overlay,
.pending-modal-overlay,
.rating-modal-overlay {
  background: rgba(0, 0, 0, 0.55) !important;
  backdrop-filter: blur(2px) !important;
  -webkit-backdrop-filter: blur(2px) !important;
}

/* --- Support reply form: composer at the bottom of a support ticket
   thread was using --glass-bg + blur. Route through v2 surface-1 +
   hairline so the form matches the message bubbles above it instead
   of fighting them. --------------------------------------------------- */
.reply-form {
  background: var(--surface-1) !important;
  border: var(--ds-hairline) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

/* --- Mobile bottom nav: was --bg-secondary + blur(20px). Switch to
   opaque surface-2 + hairline top border so the nav reads as a solid
   chrome bar, not a translucent floating tile. ----------------------- */
@media (max-width: 768px) {
  .mobile-bottom-nav {
    background: var(--surface-2) !important;
    border-top: var(--ds-hairline) !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }
}

/* --- Discount code chip: was --bg-panel rectangle. Match the other
   small inline chips (info-panel-formula, referral-code). ------------ */
.discount-code-tag {
  background: var(--surface-3, var(--surface-1)) !important;
  border: 1px solid var(--ds-neutral-border) !important;
}

/* --- Small inline panels still using --bg-card. Route through v2
   surface-1 so they sit visually flush with the parent card instead
   of fighting it with a darker swatch. --------------------------------- */
.oauth-provider-card,
.ticket-rating-display,
.ticket-rating-prompt {
  background: var(--surface-1) !important;
  border: var(--ds-hairline) !important;
  border-radius: var(--radius-card) !important;
}
.dd-recovery-strip .growth-stat {
  background: var(--surface-1) !important;
  border: 1px solid var(--ds-neutral-border) !important;
}

/* --- Batch M: profile/stats/loading surfaces still on glass-bg+blur.
   Drop blur, route through opaque v2 surfaces. --------------------- */
.profile-section,
.standalone-table,
.loading-card {
  background: var(--surface-1) !important;
  border: var(--ds-hairline) !important;
  border-radius: var(--radius-card) !important;
  box-shadow: var(--elev-card) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

/* --- Tab strips on profile + stats pages: anchored chip rail, not
   floating glass. Match the surface-2 + hairline used elsewhere. --- */
.stats-tabs-container,
.profile-tabs-container {
  background: var(--surface-2) !important;
  border: var(--ds-hairline) !important;
  box-shadow: var(--elev-card) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

/* --- Trade-detail expansion row on /trades: was --glass-bg, sits
   below the main row so route to surface-3 for a subtle nested tone. */
.trades-table tbody tr.trade-details-row,
.trades-table tbody tr.trade-details-row td {
  background: var(--surface-3, var(--surface-2)) !important;
}

/* --- Sticky table headers (trades + standalone): opaque surface-2 so
   the column-label row reads as anchored chrome above scrolling rows. */
.trades-table th,
.table-container.standalone-table {
  background: var(--surface-2) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

/* --- Pause CSS animations when the tab is hidden. PWA dashboards stay
   open 8h+; ~200 infinite pulses/shimmers/gradient-shifts across the bundle
   would otherwise keep repainting in background tabs. Wired in
   page-transitions.js via a visibilitychange listener that toggles
   body.tab-hidden.

   Safari note: universal-selector + pseudo rules cause full-document style
   invalidation on every body-class flip and were observed as tab-refocus
   jitter. Curated to attribute-substring class matches naming the actual
   animated patterns in the bundle. */
body.tab-hidden [class*="pulse"],
body.tab-hidden [class*="shimmer"],
body.tab-hidden [class*="breathe"],
body.tab-hidden [class*="glow"],
body.tab-hidden [class*="flicker"],
body.tab-hidden [class*="shift"],
body.tab-hidden [class*="rotate"],
body.tab-hidden [class*="spin"],
body.tab-hidden .charts-stream-dot.live,
body.tab-hidden .live-edge,
body.tab-hidden .dot.hot,
body.tab-hidden .grp-live .dot {
  animation-play-state: paused !important;
}
