/* ==================================================================
 * CSP Enforcement — replaces all inline style="" attributes in index.html
 * JS continues to toggle visibility via element.style.display = 'X';
 * inline styles set by JS override these CSS declarations.
 * ================================================================== */

/* Initial hidden state — !important so it beats inline display set by transitions, animations, or specific ID rules */
.is-hidden { display: none !important; }

/* Monospace tabular-numeric data font — used across rebalance inputs, movers pill, and any numeric cell that needs aligned digits */
.font-data {
  font-family: "DM Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
}

/* ---------- Verification banner ---------- */
#verification-banner {
  background: var(--accent); color: #fff;
  padding: 0.45rem 1rem; text-align: center;
  font-size: 0.78rem; line-height: 1.6;
  transition: padding 0.2s ease, line-height 0.2s ease;
  overflow: hidden;
}
.vbanner-resend-btn {
  margin: 0.15rem 1.25rem; background: rgba(255,255,255,0.2);
  border: none; color: #fff; padding: 0.15rem 0.6rem;
  border-radius: var(--radius-xs, 4px); cursor: pointer; font-size: 0.75rem; vertical-align: baseline;
}
.vbanner-resend-ok { margin-left: 0.5rem; opacity: 0.85; font-size: 0.75rem; }

/* ---------- Header ---------- */
header { background: var(--bg-card); }
.hdr-eurusd {
  background: var(--bg-deep);
  border: 1px solid transparent; white-space: nowrap;
  flex-shrink: 0; min-width: 9em; text-align: center;
  /* Real <button>: inherit type/colour from the header row (font-size stays
     with the .text-xs utility), drop the UA outline in favour of the same
     subtle-fill / accent hover+focus treatment as .theme-select. */
  font-family: inherit; color: inherit; outline: none;
  transition: border-color 0.15s;
}
.hdr-eurusd:hover { border-color: var(--accent); }
.hdr-eurusd:focus-visible { border-color: var(--accent); }

/* ---------- Summary cards responsive grid ---------- */
#card-total-value { grid-row: span 2 / span 2; }

@media (min-width: 900px) {
  #main-content { grid-template-columns: repeat(5, minmax(0, 1fr)); }
  #card-total-value { grid-row: span 1 / span 1; }
}

/* ---------- Header responsive collapse ---------- */
@media (max-width: 1060px) {
  #market-hours-bar          { display: none; }
  #eurusd-badge              { display: none; }
  #eurusd-sep                { display: none; }
  .hdr-status .hdr-sep       { display: none; }
  .hdr-status                { gap: 0.5rem; }
}

@media (max-width: 720px) {
  #theme-picker-label        { display: none; }
  header .page-inner         { padding-left: 1rem; padding-right: 1rem; }
}

/* ---------- Skeleton lines ---------- */
.sk-row-h { height: 1rem; }
.card-divider-tight { margin: 2px 0; }
.sk-line-w90 { width: 90px; height: 24px; }
.sk-line-w80 { width: 80px; height: 24px; }
.sk-line-w75 { width: 75px; height: 24px; }
.sk-line-w40 { width: 40px; height: 24px; }
.sk-line-xl  { width: 110px; height: 1.75rem; }
.sk-p-38 { width: 38%; } .sk-p-25 { width: 25%; }
.sk-p-42 { width: 42%; } .sk-p-22 { width: 22%; }
.sk-p-35 { width: 35%; } .sk-p-28 { width: 28%; }
.sk-p-40 { width: 40%; } .sk-p-24 { width: 24%; }
.sk-p-36 { width: 36%; } .sk-p-26 { width: 26%; }
.sk-p-44 { width: 44%; } .sk-p-21 { width: 21%; }

/* ---------- Benchmark dropdown ---------- */
.bench-arrow { font-size: 0.6rem; line-height: 1; }
.bench-dropdown-menu {
  min-width: 140px; background: var(--bg-card);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-dropdown, 0 8px 24px rgba(0,0,0,0.18));
}

/* ---------- Chart wrappers ---------- */
.chart-hist-wrap     { height: clamp(220px, 26vh, 380px); position: relative; }
.chart-280-wrap      { height: clamp(240px, 28vh, 400px); position: relative; }
.chart-320-wrap      { position: relative; height: clamp(280px, 32vh, 460px); }
.forecast-chart-wrap { position: relative; height: clamp(300px, 34vh, 480px); }
.bench-perf-invisible { visibility: hidden; }

/* ---------- Period performance footer ---------- */
.perf-bar-label   { font-size: 0.68rem; }
.perf-tip-formula { font-size: 0.75em; opacity: 0.85; }
.perf-tip-caveat  { opacity: 0.7; }
.pnl-pct-muted    { font-size: 0.92em; font-weight: 400; opacity: 0.82; }

/* ---------- Allocation card ---------- */
.alloc-card-flex   { display: flex; flex-direction: column; }
.alloc-chart-inner { flex: 1; min-height: clamp(220px, 28vh, 400px); position: relative; overflow: hidden; }
.canvas-fill { position: absolute; inset: 0; width: 100%; height: 100%; }
.abs-fill    { position: absolute; inset: 0; }

/* Treemap blocks — positioned + styled via JS el.style.* (CSP-safe; avoids blocked inline style="") */
.alloc-blocks-wrap { position: relative; }
.alloc-block {
  position: absolute;
  border-radius: var(--radius-xs, 4px);
  overflow: hidden;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: 2px;
  box-sizing: border-box;
}
.alloc-block-sym {
  font-weight: 700;
  line-height: 1.2;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.alloc-block-lbl {
  line-height: 1.1;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.alloc-toggle-row {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 4px;
  padding-top: 4px;
  height: 26px;
  position: relative;
}

/* ---------- Tab overflow menu ---------- */
#tab-overflow-wrap {
  position: relative;
  flex-shrink: 0;
}
.tab-overflow-menu {
  display: none;
  position: absolute;
  right: 0;
  top: calc(100% + 4px);
  list-style: none;
  margin: 0;
  padding: 3px;
  min-width: 160px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm, 6px);
  box-shadow: var(--shadow-dropdown, 0 8px 24px rgba(0,0,0,0.18));
  z-index: var(--z-dropdown);
}
#tab-overflow-wrap[data-open] .tab-overflow-menu { display: block; }
.tab-overflow-item {
  display: block;
  width: 100%;
  text-align: left;
  padding: 6px 10px;
  background: none;
  border: none;
  border-radius: var(--radius-sm, 4px);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--text-sub);
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease;
}
.tab-overflow-item:hover      { background: var(--bg-hover); color: var(--text-primary); }
.tab-overflow-item.tab-active { background: var(--accent); color: #fff; }

/* ---------- Searchable combobox ---------- */
.combo { position: relative; }
.combo-menu {
  position: absolute; left: 0; right: 0; top: calc(100% + 4px);
  list-style: none; margin: 0; padding: 3px;
  max-height: 240px; overflow-y: auto;
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius-sm, 6px);
  box-shadow: var(--shadow-dropdown, 0 8px 24px rgba(0,0,0,0.18));
  z-index: var(--z-dropdown);
}
.combo-option {
  padding: 6px 10px; border-radius: var(--radius-sm, 4px);
  font-size: 0.8rem; color: var(--text-sub); cursor: pointer;
}
.combo-option:hover,
.combo-option.is-active { background: var(--bg-hover); color: var(--text-primary); }

/* ---------- Export menu popup ---------- */
.export-menu-popup { position: absolute; top: calc(100% + 4px); right: 0; z-index: 200; min-width: 220px; border-radius: 8px; padding: 4px 0; }

/* ---------- Table th sizing ---------- */
.th-ext-col { width: 1px; padding: 0; }

/* ---------- Modal overlays ---------- */
.modal-overlay-dark {
  position: fixed; inset: 0;
  display: none; /* JS overrides with flex */
  align-items: center; justify-content: center;
  background: rgba(0,0,0,0.7); backdrop-filter: blur(4px);
}
/* z-index scale: confirm (10001) > login-overlay (9999) > account-modal (9998) > admin-modal (9997) > var(--z-modal) > var(--z-dropdown) */
#login-overlay  { z-index: 9999; }
#account-modal  { z-index: 9998; }
.modal-overlay-medium { z-index: var(--z-modal); }
/* Confirmation dialog must always appear above any open content modal */
#confirm-modal  { z-index: var(--z-confirm); }
.modal-overlay-medium { display: flex; align-items: center; justify-content: center; background: rgba(0,0,0,0.65); }

/* ---------- Modal panels ---------- */
.modal-panel-lg { width: min(92vw, 860px); padding: 1.5rem; position: relative; }
.modal-panel-md { width: min(92vw, 420px); padding: 2rem;   position: relative; }
.modal-panel-xs      { width: min(92vw, 460px); padding: 2rem;   position: relative; }
.modal-panel-confirm { width: min(92vw, 480px); padding: 1.5rem; position: relative; }
.modal-panel-xl { width: min(98vw, 1280px); padding: 1.5rem; position: relative; }
.modal-panel-lg,
.modal-panel-md,
.modal-panel-xl { max-height: 90vh; overflow-y: auto; }
#gen-modal-content { max-height: 90vh; overflow-y: auto; }
/* Import modal: the rounded card clips (overflow:hidden) and scrolling lives on the
   inner .import-modal-scroll. That keeps the inner scrollbar inset behind the card's
   rounded corners instead of running over them on themes with a large corner radius. */
#import-modal-content { max-height: 90vh; overflow: hidden; }
.import-modal-scroll  { max-height: 90vh; overflow-y: auto; }
#admin-modal    { z-index: 9997; }

/* Account modal: top-anchored with a fixed header + tab bar and a scrollable pane
   area, so switching tabs doesn't shift the header and it stays reachable on small
   screens / high zoom. Scoped to #account-modal so other modals keep centering. */
#account-modal { align-items: flex-start; }
#account-modal .modal-panel-md {
  margin-top: min(8vh, 4rem);
  max-height: calc(100vh  - min(8vh, 4rem) - 1rem);
  max-height: calc(100dvh - min(8vh, 4rem) - 1rem);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
#account-modal .modal-panel-md > * { flex: 0 0 auto; }
/* Specificity must beat the `> *` rule above (1,1,0); the bare `#account-panes`
   selector (1,0,0) loses, leaving the panes sized to content and the modal
   unable to scroll once content overflows the panel max-height. */
#account-modal #account-panes { flex: 1 1 auto; min-height: 0; overflow-y: auto; }

/* Admin modal: same top-anchored, fixed header/tabs, scrollable panes treatment. */
#admin-modal { align-items: flex-start; }
#admin-modal .modal-panel-xl {
  margin-top: min(5vh, 2.5rem);
  max-height: calc(100vh  - min(5vh, 2.5rem) - 1rem);
  max-height: calc(100dvh - min(5vh, 2.5rem) - 1rem);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
#admin-modal .modal-panel-xl > * { flex: 0 0 auto; }
/* See #account-panes note above — `#admin-panes` alone (1,0,0) cannot beat the
   `> *` rule (1,1,0); scope to #admin-modal so the override actually applies. */
#admin-modal #admin-panes { flex: 1 1 auto; min-height: 0; overflow-y: auto; }

/* ---------- Modal section tabs (underline style) ---------- */
.modal-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  margin-bottom: 1.25rem;
  border-bottom: 1px solid var(--border);
}
.modal-tab {
  flex: 0 0 auto;
  appearance: none;
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;            /* overlap the bar's border */
  padding: 8px 14px;
  font-size: 0.8rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  white-space: nowrap;
  color: var(--text-sub);
  cursor: pointer;
  transition: color 0.12s ease, border-color 0.12s ease;
}
.modal-tab:hover           { color: var(--text-primary); }
.modal-tab.is-tab-active {
  color: var(--text-primary);
  border-bottom-color: var(--accent);
}
.modal-tab:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
  border-radius: var(--radius-sm, 4px);
}

/* Admin page */
.admin-tab-pane      { min-height: 320px; }
.admin-table-wrap    { overflow: auto; max-height: 420px; border: 1px solid var(--border); border-radius: 8px; }
.admin-table-wrap td { padding: 6px 8px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.admin-table-wrap tr:last-child td { border-bottom: none; }
.admin-audit-filter-input { max-width: 220px; }
.admin-audit-scroll  { overflow-y: auto; max-height: 380px; border: 1px solid var(--border); border-radius: 8px; padding: 8px; white-space: pre-wrap; word-break: break-all; line-height: 1.5; }
.admin-stat-card     { border: 1px solid var(--border); border-radius: 10px; padding: 12px 16px; background: var(--bg-deep); }
.admin-stat-card .stat-label { font-size: .7rem; text-transform: uppercase; letter-spacing: .04em; color: var(--text-muted); }
.admin-stat-card .stat-value { font-size: 1.4rem; font-weight: 700; color: var(--text-primary); margin-top: 4px; }
.admin-sys-card { border: 1px solid var(--border); border-radius: 10px; padding: 10px 14px; background: var(--bg-deep); display: flex; align-items: center; justify-content: space-between; }
.admin-sys-card .sys-key      { font-size: .8rem; color: var(--text-sub); }
.admin-sys-card .sys-val      { font-size: .8rem; font-weight: 600; color: var(--text-primary); }
.admin-sys-card .sys-badge-on  { color: var(--gain, #22c55e); font-weight: 600; }
.admin-sys-card .sys-badge-off { color: var(--text-muted); font-weight: 600; }
.admin-sys-card-toggle .sys-val { cursor: pointer; background: transparent; border: 1px dashed var(--border); border-radius: 5px; padding: 2px 8px; font-family: inherit; line-height: 1; }
.admin-sys-card-toggle .sys-val:hover { border-style: solid; border-color: var(--accent, var(--text-sub)); }
.admin-sys-card-toggle .sys-val:focus-visible { outline: 2px solid var(--accent, var(--text-sub)); outline-offset: 2px; }
.admin-action-btn { padding: 2px 8px; border-radius: 5px; font-size: .7rem; font-weight: 500; cursor: pointer; border: 1px solid var(--border); background: var(--bg-deep); color: var(--text-sub); }

/* Admin – Usage tab */
.admin-usage-section          { border: 1px solid var(--border); border-radius: 10px; padding: 12px 16px; background: var(--bg-deep); }
.admin-usage-section-title    { font-size: .7rem; text-transform: uppercase; letter-spacing: .04em; color: var(--text-muted); margin-bottom: 8px; }
.admin-activity-pills         { display: flex; gap: 12px; flex-wrap: wrap; }
.admin-activity-pill          { display: flex; flex-direction: column; align-items: center; border: 1px solid var(--border); border-radius: 8px; padding: 8px 16px; min-width: 72px; }
.admin-activity-pill > span:first-child { font-size: 1.4rem; font-weight: 700; color: var(--text-primary); }
.admin-pill-label             { font-size: .65rem; text-transform: uppercase; color: var(--text-muted); margin-top: 2px; }
.admin-chart-wrap             { position: relative; height: 180px; }
.admin-usage-toolbar          { display: flex; align-items: center; justify-content: flex-end; gap: 12px; margin-bottom: 12px; }
.admin-usage-section-header   { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.admin-usage-section-header .admin-usage-section-title { margin-bottom: 0; flex: 1; }
.admin-usage-range            { display: flex; gap: 4px; }
.admin-usage-csv              { font-size: .65rem; text-transform: uppercase; letter-spacing: .04em; color: var(--text-muted); text-decoration: none; border: 1px solid var(--border); border-radius: 6px; padding: 2px 8px; }
.admin-usage-csv:hover        { color: var(--accent); border-color: var(--accent); }
.admin-tier-bar-row           { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.admin-tier-bar-label         { font-size: .75rem; color: var(--text-muted); min-width: 100px; }
.admin-tier-bar-wrap          { flex: 1; height: 8px; background: var(--border); border-radius: 4px; overflow: hidden; }
.admin-tier-bar-fill          { height: 100%; background: var(--accent, #6366f1); border-radius: 4px; }
.admin-action-btn:hover { border-color: var(--accent); color: var(--accent); }
.admin-action-btn.danger { border-color: var(--loss); color: var(--loss); }
.admin-action-btn.danger:hover { background: var(--loss); color: #fff; }

/* Kebab "⋮" trigger sits in the row alongside the detail-expand button. */
.admin-kebab-btn { padding: 2px 6px; border-radius: 5px; border: 1px solid var(--border); background: var(--bg-deep); color: var(--text-sub); cursor: pointer; font-size: .9rem; line-height: 1; }
.admin-kebab-btn:hover, .admin-kebab-btn[aria-expanded="true"] { border-color: var(--accent); color: var(--accent); }

/* Popover menu opened by the kebab. Position is set via JS (CSSOM .style.*),
   not inline HTML attributes, so CSP style-src 'self' is satisfied. */
.admin-kebab-menu {
  position: fixed; z-index: 9998;
  min-width: 160px;
  display: flex; flex-direction: column;
  padding: 4px 0;
  background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.25);
}
.admin-kebab-menu .admin-kebab-item {
  display: block; width: 100%;
  padding: 6px 12px;
  border: 0; background: transparent;
  font: inherit; font-size: .75rem; color: var(--text-sub);
  text-align: left; cursor: pointer;
}
.admin-kebab-menu .admin-kebab-item:hover,
.admin-kebab-menu .admin-kebab-item:focus {
  background: var(--bg-deep); color: var(--accent); outline: none;
}
.admin-kebab-menu .admin-kebab-item.danger { color: var(--loss); }
.admin-kebab-menu .admin-kebab-item.danger:hover,
.admin-kebab-menu .admin-kebab-item.danger:focus { background: var(--loss); color: #fff; }
.admin-kebab-menu .admin-kebab-sep { height: 1px; margin: 4px 0; background: var(--border); }

.admin-tier-badge { display:inline-block; padding:1px 6px; border-radius:4px; font-size:.65rem; font-weight:600; text-transform:uppercase; letter-spacing:.04em; }
.admin-tier-premium { color:var(--accent); border:1px solid var(--accent); background:transparent; }
.admin-tier-free { color:var(--text-muted); border:1px solid var(--border); background:transparent; }
.admin-tier-expiry { font-size: .65rem; }

/* Identifies the row representing the current operator or the local-admin
   sentinel. Sits next to the email so it's obvious before clicking anything. */
.admin-row-badge { display:inline-block; margin-left:6px; padding:1px 6px; border-radius:4px; font-size:.6rem; font-weight:700; text-transform:uppercase; letter-spacing:.05em; border:1px solid var(--border); background:var(--bg-deep); color:var(--text-muted); }
.admin-row-badge.is-self    { border-color: var(--accent); color: var(--accent); }
.admin-row-badge.is-system  { border-color: var(--text-muted); color: var(--text-muted); }

/* Audit-tab chip showing the current user_filter — dismissable. */
.admin-audit-userchip { display:inline-flex; align-items:center; gap:6px; padding:2px 8px; margin-bottom:8px; border:1px solid var(--border); border-radius:999px; background:var(--bg-deep); font-size:.7rem; color:var(--text-sub); }
.admin-audit-userchip button { border:0; background:transparent; color:var(--text-muted); cursor:pointer; font-size:.9rem; line-height:1; padding:0; }
.admin-audit-userchip button:hover { color: var(--loss); }

/* Audit log toolbar — filters + date pickers + CSV link wrap as needed. */
.admin-audit-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.admin-audit-date-label { display: inline-flex; align-items: center; gap: 4px; }

/* Overview — table-counts collapsible. */
.admin-overview-tables-summary { font-size: .75rem; color: var(--text-muted); cursor: pointer; user-select: none; }
.admin-overview-tables[open] .admin-overview-tables-summary { color: var(--text-sub); }

/* System diagnostic action cards. */
.admin-sys-action-card { border: 1px solid var(--border); border-radius: 10px; padding: 12px 16px; background: var(--bg-deep); display: flex; flex-direction: column; gap: 8px; }
.admin-sys-action-title { font-size: .7rem; text-transform: uppercase; letter-spacing: .04em; color: var(--text-muted); }
.admin-sys-action-row   { display: flex; align-items: center; gap: 8px; }
.admin-sys-action-status { min-height: 1em; }

/* Billing preflight checklist (stripe-ping). */
.admin-sys-check-list { list-style: none; margin: 4px 0 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.admin-sys-check-list li { font-size: .72rem; line-height: 1.35; }
.admin-sys-check-ok   { color: var(--gain); }
.admin-sys-check-fail { color: var(--loss); }

.admin-oauth-badge { display:inline-block; padding:1px 5px; border-radius:3px; font-size:.6rem; font-weight:700; border:1px solid var(--border); background:var(--bg-deep); color:var(--text-sub); }

.admin-detail-row { background:var(--bg-deep); padding:10px 16px !important; }
.admin-detail-grid { display:grid; grid-template-columns:max-content 1fr; gap:4px 16px; font-size:.75rem; }
.admin-detail-grid > span:nth-child(odd) { font-size:.7rem; text-transform:uppercase; letter-spacing:.03em; white-space:nowrap; color:var(--text-muted); }

.admin-sessions-section { margin-top:10px; }
.admin-sessions-header { font-size:.7rem; text-transform:uppercase; letter-spacing:.03em; color:var(--text-muted); margin-bottom:4px; }
.admin-sessions-table { width:100%; border-collapse:collapse; font-size:.75rem; }
.admin-sessions-table th { text-align:left; font-size:.65rem; text-transform:uppercase; letter-spacing:.03em; color:var(--text-muted); padding:2px 8px 4px 0; border-bottom:1px solid var(--border); }
.admin-sessions-table td { padding:3px 8px 3px 0; border-bottom:1px solid color-mix(in srgb, var(--border) 50%, transparent); }

.modal-close-sm {
  padding: 3px 9px; border-radius: 6px;
  border: 1px solid var(--border); background: var(--bg-deep);
  font-size: 0.85rem; cursor: pointer;
}

/* ---------- Chart expand panel ---------- */
#chart-expand-modal {
  position: fixed; top: 12.5vh; left: 3vw; right: 3vw; bottom: 12.5vh;
  z-index: 999; padding: 16px 20px; flex-direction: column;
  animation: panel-expand-enter 0.2s cubic-bezier(0.34, 1.05, 0.64, 1) both;
}
#chart-expand-body { flex: 1; display: flex; flex-direction: column; min-height: 0; overflow: hidden; }

/* ---------- Per-symbol transaction manager ---------- */
#sym-tx-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,0.55); z-index: var(--z-sym-tx-bg); }
#sym-tx-modal {
  position: fixed; top: 6vh; left: 50%;
  transform: translateX(-50%);
  width: min(96vw, 860px); max-height: 88vh;
  z-index: var(--z-sym-tx); padding: 20px 24px; flex-direction: column; overflow: hidden;
}
.sym-tx-hdr { display: flex; align-items: center; justify-content: space-between; flex-shrink: 0; margin-bottom: 14px; }
#sym-tx-body { flex: 1; overflow-y: auto; min-height: 0; }
.sym-tx-foot { flex-shrink: 0; display: flex; justify-content: flex-end; margin-top: 12px; }

/* ---------- Shared buttons ---------- */
.btn-accent-sm   { background: var(--accent); color: #fff; }
.btn-full-accent {
  width: 100%; padding: 0.55rem 1rem; border-radius: 0.5rem;
  background: var(--accent); color: #fff; font-size: 0.875rem;
  font-weight: 600; cursor: pointer; border: none;
}
.btn-full-accent-sm {
  width: 100%; padding: 0.5rem; border-radius: 0.5rem;
  background: var(--accent); color: #fff; border: none;
  font-size: 0.875rem; font-weight: 600; cursor: pointer;
}
.btn-full-outlined {
  width: 100%; padding: 0.55rem 1rem; border-radius: 0.5rem;
  background: transparent; color: var(--text-primary);
  font-size: 0.875rem; font-weight: 500; cursor: pointer; border: 1px solid var(--border);
}
.btn-full-demo {
  width: 100%; padding: 0.55rem 1rem; border-radius: 0.5rem;
  background: #92400e; color: #fef3c7;
  font-size: 0.875rem; font-weight: 600; cursor: pointer; border: none;
}
.btn-full-demo:hover { background: #78350f; }
.btn-link-subtle {
  background: none; border: none; color: var(--text-sub);
  font-size: 0.75rem; cursor: pointer;
  text-decoration: underline; text-underline-offset: 2px;
}
.btn-center-wrap    { text-align: center; margin-top: 0.4rem; }
.btn-center-wrap-lg { text-align: center; margin-top: 0.6rem; }
/* Size + brighter text; visual treatment (bg/border/hover/focus) is inherited
   from the universal .btn-soft group in 03-components.css. */
.btn-outlined-subtle {
  padding: 0.35rem 0.75rem; border-radius: 0.5rem; font-size: 0.8rem;
  color: var(--text-primary);
}
.btn-delete {
  background: var(--neg, #ef4444); color: #fff; border: none;
  padding: 0.35rem 0.75rem; border-radius: 0.5rem; font-size: 0.8rem; font-weight: 600; cursor: pointer;
}
.show-delete-btn {
  border: 1px solid var(--neg, #ef4444); color: var(--neg, #ef4444);
  background: transparent; padding: 0.35rem 0.9rem; border-radius: 0.5rem; font-size: 0.8rem; cursor: pointer;
}

/* Confirmation-dialog action button. Variant is set per-call by
   showConfirm({ confirmVariant }): danger (default) for destructive actions,
   success for positive ones (e.g. starting the free trial). */
.btn-danger  { background: var(--loss); color: #fff; border: none; cursor: pointer; transition: opacity 0.13s; }
.btn-success { background: var(--gain); color: #fff; border: none; cursor: pointer; transition: opacity 0.13s; }
.btn-danger:hover, .btn-success:hover { opacity: 0.85; }

/* ---------- Form inputs ---------- */
.t-input-field {
  border: 1px solid var(--border); background: var(--bg-surface);
  color: var(--text-primary); outline: none; box-sizing: border-box; width: 100%;
}
.login-input {
  width: 100%; padding: 0.45rem 0.75rem; border-radius: 0.5rem;
  border: 1px solid var(--border); background: var(--bg-surface);
  color: var(--text-primary); font-size: 0.875rem; box-sizing: border-box;
}
.login-input-mb  { margin-bottom: 0.4rem; }
.login-input-mb2 { margin-bottom: 0.5rem; }
.input-uppercase { text-transform: uppercase; }

/* File input — style the browser-native "Choose file" button using theme accent */
input[type="file"]::file-selector-button {
  background: var(--accent); color: #fff; border: none;
  border-radius: var(--radius-sm, 6px); padding: 0.3rem 0.75rem;
  font-size: 0.75rem; font-weight: 600; cursor: pointer; margin-right: 0.75rem;
  transition: opacity 0.15s;
}
input[type="file"]::file-selector-button:hover { opacity: 0.85; }

/* ---------- Form messages ---------- */
.form-msg-neg    { color: var(--neg, #ef4444); font-size: 0.75rem; margin-bottom: 0.75rem; }
.form-msg-pos    { color: var(--pos, #22c55e); font-size: 0.75rem; margin-bottom: 0.75rem; }
.form-msg-neg-sm { color: var(--neg, #ef4444); font-size: 0.75rem; margin-bottom: 0.4rem; }
.form-msg-pos-sm { color: var(--pos, #22c55e); font-size: 0.75rem; margin-bottom: 0.4rem; }

/* ---------- Account & data sections ---------- */
.form-section-border { margin-top: 1.5rem; padding-top: 1.25rem; border-top: 1px solid var(--border); }
.link-btn-outlined   { border: 1px solid var(--border); color: var(--text-primary); }
.delete-confirm-inner { margin-top: 0.75rem; }
.delete-confirm-row   { display: flex; gap: 0.5rem; justify-content: flex-end; }
.delete-error-msg     { color: var(--neg, #ef4444); font-size: 0.75rem; margin-bottom: 0.5rem; }

/* ---------- Login modal specifics ---------- */
.brand-size-lg       { font-size: 1.1rem; }
.forgot-pw-wrap      { margin-top: 0.5rem; }
.forgot-pw-note      { font-size: 0.75rem; color: var(--text-sub); margin-bottom: 0.5rem; }
.local-admin-divider { text-align: center; margin: 1rem 0; font-size: 0.75rem; color: var(--text-sub); }
.local-admin-error   { color: var(--neg, #ef4444); font-size: 0.75rem; margin-top: 0.5rem; }
.disclaimer-block { display: flex; flex-direction: column; align-items: center; gap: 0.25rem; margin-top: 1.25rem; }
.disclaimer-line { font-size: 0.75rem; color: var(--text-muted, #a1a1aa); text-align: center; line-height: 1.5; }
.disclaimer-line-privacy { text-decoration: underline; text-underline-offset: 2px; opacity: 0.8; transition: opacity 0.1s; }
.disclaimer-line-privacy:hover { opacity: 1; }
.disclaimer-links { display: flex; align-items: center; gap: 0.4rem; margin-top: 0.4rem; }
.disclaimer-sep { color: var(--text-muted, #a1a1aa); opacity: 0.4; font-size: 0.75rem; }
.disclaimer-link { font-size: 0.75rem; color: var(--text-muted, #a1a1aa); text-decoration: none; transition: color 0.1s; }
.disclaimer-link:hover { color: var(--text-primary); text-decoration: underline; }
.t-danger { color: var(--neg, #ef4444); }

/* ---------- Holdings table — Symbol cells ---------- */
.sym-td               { cursor: pointer; }
.sym-td:hover .sym-lnk { text-decoration: underline; }
.sym-lnk              { font-weight: 600; color: var(--accent); }

/* Ext (after-hours) tiny spacer column — replaces blocked inline style */
/* vertical-align: middle keeps it in line with Today; translateY pulls it up into superscript position */
.ext-td { width: 1px; padding: 0 2px 0 0; white-space: nowrap; vertical-align: middle; }
td:has(.today-wrap) { padding-right: 1px !important; }

/* ---------- Holdings table — Today / Ext columns ---------- */
.today-wrap   { display:flex; align-items:center; width:140px; margin-left:auto; }
.today-bubble { width:20px; height:20px; position:relative; flex-shrink:0; margin-right:6px; }
.today-dot          { border-radius:50%; opacity:0.75; position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); }
.today-dot-gain     { background: var(--gain); }
.today-dot-loss     { background: var(--loss); }
.today-dot-neutral  { background: var(--neutral); }
.today-spark  { width:64px; height:22px; display:flex; align-items:center; flex-shrink:0; margin-right:4px; }
.today-spark svg { overflow:visible; }
.today-pct    { width:46px; text-align:right; flex-shrink:0; display:block; font-variant-numeric:tabular-nums; }
.ext-pct-wrap { display:inline-flex; align-items:center; gap:2px; transform:translateY(-0.65em); }
.ext-pct-wrap.ext-pct-overnight { opacity:0.6; }
/* position:relative + top nudges icon up to optically match small text center */
.ext-session-icon { width:15px; height:15px; flex-shrink:0; color:var(--accent-soft); opacity:0.5; position:relative; top:-2px; }
.ext-pct      { font-size:0.82em; display:inline-block; }

/* ---------- Holdings table — manage-transactions (···) buttons ---------- */
.tx-btn { opacity:0.2; background:none; border:none; cursor:pointer; color:inherit; font-size:1rem; letter-spacing:0.05em; transition:opacity 0.15s; padding:2px 5px; }
.tx-btn:hover { opacity:1; }

/* ---------- CSP-safe replacements for inline style="..." ---------- */

/* Sym-tx modal table */
.sym-tx-tbl { border-collapse: collapse; font-size: 0.8rem; }

/* Admin tables */
.tbl-bc     { border-collapse: collapse; }
.t-border-t2 { border-top: 2px solid var(--border); }
.t-card-border { border: 1px solid var(--border); }

/* Correlation panel */
.corr-pair-row { font-size: 0.78rem; }

/* Diversification score */
.div-bar-wrap  { flex: 1; height: 6px; background: var(--bg-deep); border-radius: 3px; overflow: hidden; }
.div-bar-fill  { height: 100%; border-radius: 3px; transition: width 0.4s ease; }
.div-score-val { min-width: 3rem; text-align: right; }
.legend-swatch { display: inline-block; width: 28px; height: 8px; border-radius: var(--radius-tiny, 2px); }

/* Tax panel */
.tax-chart-wrap { height: 180px; position: relative; margin-bottom: 16px; }

/* Rebalance panel */
.rb-bar-td   { min-width: 100px; }
.rb-save-btn { font-size: 0.75rem; padding: 4px 14px; }

/* PDF export print area (moved from inline <style> block) */
#pdf-wrap { font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;font-size:12px;padding:28px 32px;color:#0f172a }
#pdf-tbl  { width:100%;border-collapse:collapse;font-size:11px;table-layout:fixed }
#pdf-tbl th,#pdf-tbl td { padding:6px 7px;overflow:hidden;white-space:nowrap }
#pdf-tbl thead tr { background:#0f172a;color:#fff }
#pdf-tbl th { font-size:9px;font-weight:700;letter-spacing:0.05em;text-transform:uppercase }
#pdf-tbl .r0 { background:#fff }
#pdf-tbl .r1 { background:#f8f9fa }
#pdf-tbl .sym  { text-align:left;font-weight:700 }
#pdf-tbl .name { text-align:left;color:#555;font-size:10px;text-overflow:ellipsis }
#pdf-tbl .ctr  { text-align:center }
#pdf-tbl .num  { text-align:right;font-variant-numeric:tabular-nums }
#pdf-tbl .bold { font-weight:600 }
#pdf-tbl .sm   { font-size:10px }
#pdf-tbl .tot  { background:#0f172a;color:#fff;font-weight:700 }
/* th alignment via nth-child (matches col order: sym, name, ctr, num×7) */
#pdf-tbl th:nth-child(1),#pdf-tbl th:nth-child(2) { text-align:left }
#pdf-tbl th:nth-child(3)                           { text-align:center }
#pdf-tbl th:nth-child(n+4)                         { text-align:right }
/* colgroup widths */
#pdf-tbl colgroup col:nth-child(1)  { width:9% }
#pdf-tbl colgroup col:nth-child(2)  { width:20% }
#pdf-tbl colgroup col:nth-child(3)  { width:7% }
#pdf-tbl colgroup col:nth-child(4)  { width:9% }
#pdf-tbl colgroup col:nth-child(5)  { width:10% }
#pdf-tbl colgroup col:nth-child(6)  { width:10% }
#pdf-tbl colgroup col:nth-child(7)  { width:11% }
#pdf-tbl colgroup col:nth-child(8)  { width:8% }
#pdf-tbl colgroup col:nth-child(9)  { width:8% }
#pdf-tbl colgroup col:nth-child(10) { width:8% }
/* Structural helper classes */
.pdf-hdr       { display:flex;align-items:flex-end;justify-content:space-between;margin-bottom:20px;padding-bottom:12px;border-bottom:2px solid #0f172a }
.pdf-hdr-title { font-size:20px;font-weight:800;letter-spacing:-0.02em }
.pdf-hdr-sub   { font-size:11px;color:#64748b;margin-top:2px }
.pdf-hdr-right { font-size:11px;color:#64748b;text-align:right }
.pdf-kpi-row   { display:flex;gap:10px;flex-wrap:wrap;margin-bottom:22px }
.pdf-kpi-card  { flex:1;min-width:110px;padding:10px 14px;border-radius:8px;background:#f1f5f9;border:1px solid #e2e8f0 }
.pdf-kpi-lbl   { font-size:9px;font-weight:700;letter-spacing:0.08em;text-transform:uppercase;color:#64748b;margin-bottom:4px }
.pdf-kpi-val   { font-size:15px;font-weight:700;color:#0f172a;white-space:nowrap }
.pdf-kpi-sub   { font-size:10px;color:#64748b;margin-top:2px;white-space:nowrap }
.pdf-footer    { margin-top:16px;font-size:9px;color:#94a3b8;border-top:1px solid #e2e8f0;padding-top:8px }
.pdf-badge     { display:inline-block;padding:1px 6px;border-radius:3px;font-size:9px;font-weight:700;letter-spacing:0.04em;color:#fff }

/* Ticker skeleton animation defaults (overridden by _startTicker via JS) */
.ticker-track { --ticker-dur: 50s; --ticker-shift: -25%; }

/* Visibility utility */
.invisible { visibility: hidden; }

/* Today's movers card */
.mover-row    { height: 1rem; line-height: 1; }
.mover-spacer { height: 1rem; }
.mover-pct    { font-size: 0.72rem; }

/* Benchmark performance chips */
.perf-chip       { background: var(--bg-deep); padding: 0.1rem 0; }
.perf-chip-label { font-size: 0.68rem; }
.perf-chip-val   { font-size: 0.68rem; font-weight: 600; }

/* Mini charts grid */
.charts-grid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
.mc-wrap     { height: 170px; position: relative; padding: 0 2px; }
/* Skeleton overlays the canvas (same pattern as .chart-sk on the main chart),
   so the previously-drawn chart stays visible while a refresh is in flight. */
.mc-sk       { position: absolute; inset: 0; border-radius: 6px;
               z-index: 10; pointer-events: none; opacity: 0.85; }
.mc-canvas   { position: absolute; inset: 0; }

/* Analysis panel */
.analysis-th-cov  { min-width: 130px; }
.analysis-td-date { width: 110px; }
.coverage-bar     { width: 72px; height: 5px; border-radius: 3px; overflow: hidden; background: var(--bg-deep); }
.coverage-fill    { height: 100%; }

/* Market hours status dots & verb */
.status-dot  { display:inline-block; width:5px; height:5px; border-radius:50%; flex-shrink:0; vertical-align:middle; margin-bottom:1px; }
.mkt-tip-verb { font-variant-numeric: tabular-nums; }

/* Transaction type colors */
.tx-buy  { color: var(--gain); }
.tx-sell { color: var(--loss); }

/* Transaction table buttons */
.btn-natural   { letter-spacing: 0; text-transform: none; }
.btn-danger-sm       { background: #7f1d1d; color: #fecaca; transition: opacity 0.13s, transform 0.11s ease, box-shadow 0.14s ease; }
.btn-danger-sm:hover { opacity: 0.85; transform: translateY(-1px); box-shadow: 0 4px 14px rgba(0,0,0,0.25); }
.btn-danger-sm:active { transform: scale(0.97); box-shadow: none; }
/* .btn-edit-sm — visual treatment inherited from the universal .btn-soft group
   in 03-components.css; consumers add their own padding/font-size via utilities. */

/* Welcome overlay theme swatches */
.welcome-theme-swatch {
  padding: 3px;
  border-radius: 8px;
  border: 2px solid transparent;
  background: none;
  cursor: pointer;
  line-height: 0;
  transition: border-color 0.15s, transform 0.1s;
}
.welcome-theme-swatch:hover { transform: scale(1.1); border-color: var(--border); }
.welcome-swatch-active      { border-color: var(--accent) !important; }

/* ---------------------------------------------------------------------------
 * Watchlist group action menu
 * --------------------------------------------------------------------------- */
.wg-action-menu {
  position:absolute; z-index:300;
  background:var(--bg-card); border:1px solid var(--border); border-radius:8px;
  padding:4px 0; min-width:140px; box-shadow:0 4px 14px rgba(0,0,0,.35);
}
.wg-action-menu button {
  display:block; width:100%; padding:6px 14px; text-align:left;
  font-size:.75rem; background:none; border:none; cursor:pointer; color:var(--text-primary);
}
.wg-action-menu button:hover { background:var(--bg-hover); }
.wg-action-menu .wg-menu-danger { color:var(--loss); }

/* ---------------------------------------------------------------------------
 * Watchlist RSI badge
 * --------------------------------------------------------------------------- */
.rsi-badge {
  display:inline-block; padding:1px 5px; border-radius:3px; font-size:.7rem;
  border:1px solid var(--border); background:var(--bg-deep);
  font-variant-numeric:tabular-nums; color:var(--text-muted);
}
.rsi-badge.rsi-hot  { color:var(--loss); border-color:var(--loss); }
.rsi-badge.rsi-cold { color:var(--gain); border-color:var(--gain); }

/* ---------------------------------------------------------------------------
 * Watchlist 52-week range bar
 * --------------------------------------------------------------------------- */
.wg-range-wrap { display:inline-flex; align-items:center; gap:4px; }
.wg-range-bar  { width:52px; height:4px; background:var(--bg-deep); border-radius:2px; overflow:hidden; flex-shrink:0; }
.wg-range-fill { display:block; height:100%; width:var(--wg-fill-w,0%); background:var(--accent); border-radius:2px; }
/* Inline-style replacements (CSP compliance) */
.csp-gain     { color:var(--gain); }
.csp-loss     { color:var(--loss); }
.csp-accent   { color:var(--accent); }
.csp-audit-entry      { margin-bottom:6px; }
.csp-audit-pre        { margin:2px 0 0; white-space:pre-wrap; font-size:.7rem; }
.csp-audit-hr         { border-color:var(--border); margin:4px 0; }
.csp-import-ok        { color:var(--gain); font-weight:600; margin-bottom:.25rem; }
.csp-import-err       { color:var(--loss); margin-bottom:.25rem; }
.csp-import-warn      { color:#d4a017; margin-bottom:.25rem; }
.forecast-chart-wrap  { position:relative; height:340px; }

/* ---------------------------------------------------------------------------
 * Import preview table (two-phase import: preview → commit)
 * --------------------------------------------------------------------------- */
#import-modal-content.import-wide { max-width:48rem; }
/* Outer wrapper owns the rounded border and clips its content (overflow:hidden); the
   inner element does the scrolling. Keeping the border on a non-scrolling, clipped box
   means the rounded corners stay crisp and the sticky header can never paint over them. */
.csp-preview-wrap               { border:1px solid var(--border); border-radius:.5rem; overflow:hidden; }
.csp-preview-scroll             { max-height:20rem; overflow:auto; }
.csp-preview-table              { border-collapse:separate; border-spacing:0; }
.csp-preview-table th,
.csp-preview-table td           { padding:.3rem .4rem; text-align:left; white-space:nowrap; }
/* The divider is drawn with an inset box-shadow rather than border-bottom so it travels
   with the sticky header. A real border is left behind on scroll, which leaves a 1px gap
   at the top that made the header appear to stick just below the edge. */
.csp-preview-head th            { position:sticky; top:0; color:var(--text-muted);
                                  /* Flatten over the opaque --bg-surface so the sticky header occludes
                                     scrolled rows on glass themes where --bg-deep is translucent. */
                                  background:linear-gradient(var(--bg-deep), var(--bg-deep)), var(--bg-surface);
                                  font-weight:600; box-shadow:inset 0 -1px 0 var(--border); z-index:1; }
.csp-preview-row td             { border-bottom:1px solid var(--border); }
.csp-preview-row                { color:var(--text); }
.csp-preview-row:hover          { background:var(--bg-deep); }
/* Action row pinned to the bottom of the scrolling modal so Back / Import stay reachable
   however long the preview grows. Negative margins cancel the .import-modal-scroll p-6
   padding so the footer spans edge-to-edge and covers the card's bottom padding. */
.import-preview-actions         { position:sticky; bottom:0; z-index:2; gap:.75rem;
                                  margin:1rem -1.5rem -1.5rem; padding:1rem 1.5rem;
                                  /* Flatten the card tint over the opaque --bg-surface: on glass themes
                                     --bg-card is translucent and scrolled rows would bleed through. */
                                  background:linear-gradient(var(--bg-card), var(--bg-card)), var(--bg-surface);
                                  border-top:1px solid var(--border); }
.csp-preview-muted              { color:var(--text-muted); opacity:.65; }
.csp-num                        { text-align:right; font-variant-numeric:tabular-nums; }
.csp-preview-type               { background:var(--bg-deep); color:var(--text); border:1px solid var(--border);
                                  border-radius:.35rem; padding:.1rem .25rem; font-size:.7rem; max-width:8rem; }
.csp-type-uncertain             { border-color:#d4a017; }
.csp-verdict                    { display:inline-block; padding:1px 6px; border-radius:4px; font-size:.6rem; font-weight:700;
                                  text-transform:uppercase; letter-spacing:.04em; }
.csp-verdict-ok                 { background:color-mix(in srgb, var(--gain) 20%, transparent); color:var(--gain); }
.csp-verdict-dup                { background:color-mix(in srgb, var(--text-muted) 22%, transparent); color:var(--text-muted); }
.csp-verdict-skip               { background:color-mix(in srgb, var(--text-muted) 22%, transparent); color:var(--text-muted); }
.csp-verdict-err                { background:color-mix(in srgb, var(--loss) 20%, transparent); color:var(--loss); }
.csp-map-grid                   { display:grid; grid-template-columns:repeat(2, minmax(0, 1fr)); gap:.4rem; }
.csp-map-field                  { display:flex; align-items:center; justify-content:space-between; gap:.4rem;
                                  font-size:.7rem; color:var(--text-muted); }
.csp-map-field select           { background:var(--bg-deep); color:var(--text); border:1px solid var(--border);
                                  border-radius:.35rem; padding:.1rem .25rem; font-size:.7rem; flex:1; min-width:0; }

/* Sortable watchlist column headers */
#wg-groups-container th[data-wg-col] { cursor:pointer; user-select:none; }

/* ---------------------------------------------------------------------------
 * Watchlist — market status dot
 * --------------------------------------------------------------------------- */
.wg-market-dot         { font-size:.55rem; vertical-align:middle; margin-right:3px; }
.wg-dot-live           { color:var(--gain); }
.wg-dot-pre            { color:#d4a017; }
.wg-dot-closed         { color:var(--text-muted); }

/* ---------------------------------------------------------------------------
 * Watchlist — group header aggregate (subtotal) row values
 * --------------------------------------------------------------------------- */
/* Per-column group means in the header row. Medium weight + .82rem reads as a
   summary line distinct from the data rows below, while keeping the same column
   alignment and gain/loss coloring as the cells it summarizes. */
.wg-agg-val { font-size:.82rem; font-weight:600; }

/* ---------------------------------------------------------------------------
 * Watchlist — inline "Add Symbol" row button
 * --------------------------------------------------------------------------- */
.wg-inline-add {
  background:none; border:none; cursor:pointer; font-size:.72rem;
  color:var(--text-muted); transition:color .15s; padding:0;
}
.wg-inline-add:hover { color:var(--accent); }
/* Empty-state "create your first watchlist" CTA: stronger hover affordance. */
.wg-create-cta:hover { text-decoration:underline; }

/* ---------------------------------------------------------------------------
 * Watchlist — sparkline
 * --------------------------------------------------------------------------- */
.wg-spark { display:block; overflow:visible; }

/* ---------------------------------------------------------------------------
 * Watchlist — stacked multi-bar (Ranges column: Day / Week / 52w)
 * --------------------------------------------------------------------------- */
.wg-mbar-wrap { display:inline-flex; flex-direction:column; gap:1px; vertical-align:middle; }
.wg-mbar-row  { display:inline-flex; align-items:center; gap:4px; }
.wg-mbar-lbl  { font-size:.55rem; width:14px; text-align:right; flex-shrink:0; color:var(--text-muted); line-height:1; font-variant-numeric:tabular-nums; }
.wg-mbar-bar  { position:relative; width:116px; height:5px; background:var(--bg-deep); border-radius:var(--radius-tiny, 2px); overflow:hidden; flex-shrink:0; }
.wg-mbar-bar::before,
.wg-mbar-bar::after { content:''; position:absolute; top:0; bottom:0; width:3px; background:var(--border); z-index:2; pointer-events:none; }
.wg-mbar-bar::before { left:0;  border-radius:var(--radius-tiny, 2px) 0 0 var(--radius-tiny, 2px); }
.wg-mbar-bar::after  { right:0; border-radius:0 var(--radius-tiny, 2px) var(--radius-tiny, 2px) 0; }

/* ---------------------------------------------------------------------------
 * Watchlist — earnings countdown badge
 * --------------------------------------------------------------------------- */
/* Compact earnings marker by the ticker — full detail (quarter + countdown) in the tooltip. */
.wg-earn-dot   { font-size:.5rem; margin-left:4px; vertical-align:middle; line-height:1; }
.wg-earn-near  { color:var(--loss); }   /* ≤7 days out — urgent */
.wg-earn-far   { color:#d4a017; }       /* 8–45 days out — same amber as the pre-market dot */

/* ---------------------------------------------------------------------------
 * Watchlist — analyst target column
 * --------------------------------------------------------------------------- */
.wg-tgt-cell { display:inline-flex; flex-direction:column; align-items:flex-start; gap:2px; vertical-align:middle; }
.wg-tgt-pct  { font-size:.75rem; font-variant-numeric:tabular-nums; }
.wg-tgt-bar         { position:relative; width:144px; height:5px; background:var(--bg-deep); border-radius:var(--radius-tiny, 2px); overflow:hidden; flex-shrink:0; }
.wg-tgt-bar::before,
.wg-tgt-bar::after  { content:''; position:absolute; top:0; bottom:0; width:3px; background:var(--border); z-index:2; pointer-events:none; }
.wg-tgt-bar::before { left:0;  border-radius:var(--radius-tiny, 2px) 0 0 var(--radius-tiny, 2px); }
.wg-tgt-bar::after  { right:0; border-radius:0 var(--radius-tiny, 2px) var(--radius-tiny, 2px) 0; }
.wg-tgt-divider     { position:absolute; left:50%; top:0; width:1px; height:100%; background:var(--border); z-index:1; transform:translateX(-50%); }
.wg-tgt-fill        { position:absolute; top:0; height:100%; width:calc(var(--wg-tgt-w,0%) / 2); }
.wg-tgt-gain        { background:var(--gain); left:50%; }
.wg-tgt-loss        { background:var(--loss); right:50%; }

/* ---------------------------------------------------------------------------
 * Watchlist — flat table base
 * --------------------------------------------------------------------------- */
.wg-table { border-collapse: collapse; table-layout: fixed; }
/* Vertically center every cell — keeps multi-line bar stacks aligned with single-line text */
.wg-table > thead > tr > th,
.wg-table > tbody > tr > td { vertical-align: middle; }
/* Fixed layout: all cells clip overflowing content */
.wg-table > thead > tr > th,
.wg-table > tbody > tr > td:not([colspan]) { white-space: nowrap; overflow: hidden; }
.wg-table .ext-td { overflow: visible; }
/* Name column: no explicit width on its <col> so it absorbs all remaining space */
.wg-table > thead > tr > th.wg-col-flex,
.wg-table > tbody > tr > td.wg-col-flex { text-overflow: ellipsis; }
/* Column widths via named <col> classes — wg-col-name has no rule, absorbs remaining space */
.wg-table col.wg-col-sym    { width: 108px; }
.wg-table col.wg-col-price  { width: 112px; }
.wg-table col.wg-col-today  { width: 175px; }
.wg-table col.wg-col-ext    { width: 1px;   }
.wg-table col.wg-col-spark  { width: 72px;  }
.wg-table col.wg-col-wk     { width: 80px;  }
.wg-table col.wg-col-mo     { width: 80px;  }
.wg-table col.wg-col-3m     { width: 96px;  }
.wg-table col.wg-col-1y     { width: 96px;  }
.wg-table col.wg-col-tgt    { width: 180px; }
.wg-table col.wg-col-pe     { width: 56px;  }
.wg-table col.wg-col-fpe    { width: 64px;  }
.wg-table col.wg-col-hv     { width: 68px;  }
.wg-table col.wg-col-rsi    { width: 64px;  }
.wg-table col.wg-col-vol    { width: 64px;  }
.wg-table col.wg-col-ranges { width: 168px; }
.wg-table col.wg-col-rm     { width: 34px;  }

/* ---------------------------------------------------------------------------
 * Watchlist — single column header row (rendered once, at the top)
 * --------------------------------------------------------------------------- */
.wg-col-header th {
  font-size: .65rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--accent);
  background: var(--wg-band-bg);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
  cursor: default;
}
.wg-col-header th[data-wg-col] { cursor: pointer; user-select: none; }

/* ---------------------------------------------------------------------------
 * Watchlist — floating column header. The data table keeps its real <thead>, but it
 * lives in an overflow-x-auto wrapper (horizontal scroll) that would trap a sticky
 * header inside that scroll container. So an aria-hidden visual CLONE sits OUTSIDE
 * the wrapper and sticks to the page viewport (below the global sticky header, via
 * --wg-col-top), revealed on scroll once the real <thead> passes under it. Its inner
 * table is width-matched to the data table and translated by -scrollLeft (set in JS)
 * to stay column-aligned during horizontal scroll.
 * --------------------------------------------------------------------------- */
.wg-float-head {
  position: sticky;
  top: var(--wg-col-top, 0);
  z-index: 10;
  overflow: hidden;
  background: var(--wg-band-bg);
}
.wg-float-head-inner { will-change: transform; }

/* The scroller is the card's bottom-most element. When every group is collapsed the
   last visible row is a wg-group-hdr — a filled band with a square border-bottom — whose
   corners would poke past the card's rounded bottom. The card itself can't use
   overflow:hidden (it would trap the sticky .wg-float-head), so we round + clip the
   scroller instead. overflow-x:auto already clips it vertically; this just rounds the
   bottom corners to sit inside the card's 1px border. Harmless when expanded (the bottom
   row is then transparent). */
[data-wg-scroller] {
  border-bottom-left-radius: calc(var(--radius-card, 14px) - 1px);
  border-bottom-right-radius: calc(var(--radius-card, 14px) - 1px);
}

/* ---------------------------------------------------------------------------
 * Watchlist — group header row (section separator between groups)
 * --------------------------------------------------------------------------- */
/* Each group reads as a bounded band: the deepened --wg-band-bg fill plus a 2px opening
   rule and a 1px closing rule, so the header clearly starts a new section rather than
   looking like another data row. */
.wg-group-hdr {
  background: var(--wg-band-bg);
  border-top: 2px solid var(--border);
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  user-select: none;
}
/* A touch more height than the data rows (py-2.5) so the band has more presence. */
.wg-group-hdr > td { padding-top: 0.7rem; padding-bottom: 0.7rem; }
/* The band already carries a faint accent tint, so hover deepens that accent
   further (clearly stronger than the ~9% band) to read as interactive. */
.wg-group-hdr:hover td { background: color-mix(in srgb, var(--bg-hover), var(--accent) 22%); }

/* ---------------------------------------------------------------------------
 * Watchlist — group header action menu anchor (in the remove-button column)
 * --------------------------------------------------------------------------- */
#wg-groups-container {
  position: relative;
  /* Shared "band" fill for the column header and the group section bands. A faint tint
     of the theme's own --accent over its --bg-hover surface. Using the accent (each
     theme's defining colour) makes the band read as on-scheme in every theme — light or
     dark — instead of a neutral grey bar; --bg-hover (not --bg-card) is the base because
     it is palette-matched, light, and correctly translucent in glass/aurora. This single
     formula also covers aurora's violet, so no per-theme override is needed. */
  --wg-band-tint: color-mix(in srgb, var(--accent) 9%, var(--bg-hover));
  /* Flatten the tint onto the opaque --bg-surface. In glass themes (aurora/glass) the
     surfaces are translucent, so the bare tint would let scrolling rows bleed through the
     *sticky* column header; compositing over an opaque surface makes the bar occlude
     properly. In opaque themes the tint already covers the surface — identical result. */
  --wg-band-bg: linear-gradient(var(--wg-band-tint), var(--wg-band-tint)), var(--bg-surface);
}
.wg-hdr-actions { display: inline-block; line-height: 1; }

/* ---------------------------------------------------------------------------
 * Watchlist — hover-reveal remove button (icon-only, appears on row hover)
 * --------------------------------------------------------------------------- */
.wg-remove-btn {
  background: none;
  border: none;
  cursor: pointer;
  font-size: .7rem;
  color: var(--text-dim);
  opacity: 0;
  transition: opacity .15s, color .15s;
  padding: 2px 5px;
  border-radius: 3px;
  line-height: 1;
}
.wg-table tbody tr:hover .wg-remove-btn { opacity: 1; }
.wg-remove-btn:hover { color: var(--loss); }

/* ---------- Demo mode banner ---------- */
#demo-banner {
  background: #92400e;
  color: #fef3c7;
  padding: 0.45rem 1rem;
  text-align: center;
  font-size: 0.78rem;
  line-height: 1.6;
  transition: padding 0.2s ease, line-height 0.2s ease;
  overflow: hidden;
}

/* ---------- Beta + privacy notice banners ----------
   Theme-surface banners (not the colored accent/amber ones above), so text and
   the dismiss control read from theme variables to stay legible in every theme. */
#beta-banner {
  background: color-mix(in srgb, var(--accent) 12%, var(--bg-card));
  color: var(--text-primary);
  border-bottom: 1px solid var(--border);
  padding: 0.45rem 1rem;
  text-align: center;
  font-size: 0.78rem;
  line-height: 1.6;
  transition: padding 0.2s ease, line-height 0.2s ease;
  overflow: hidden;
}
#privacy-notice {
  /* bg-card (not bg-deep) so the dismiss button's bg-deep fill reads against it,
     matching the filled-button idiom of the verification/demo banners. */
  background: var(--bg-card);
  color: var(--text-sub);
  border-bottom: 1px solid var(--border);
  padding: 0.4rem 1rem;
  text-align: center;
  font-size: 0.75rem;
  line-height: 1.5;
  transition: padding 0.2s ease, line-height 0.2s ease;
  overflow: hidden;
}
.vbanner-link {
  margin: 0 0.4rem;
  color: var(--accent);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
  /* Button-safe: used on both <a> and <button> triggers. */
  background: none;
  border: none;
  padding: 0;
  font-size: inherit;
  font-family: inherit;
  cursor: pointer;
}
.vbanner-link:hover { color: var(--accent-soft); }
.vbanner-link:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius-tiny, 2px);
}

/* Dismiss control: sizing only. The accent fill, white text (with per-theme
   corrections, e.g. shadow), and hover come from the shared .btn-accent class
   in markup, so it matches the app's primary buttons exactly. */
.banner-dismiss-btn {
  margin-left: 0.85rem;
  vertical-align: baseline;
  border-radius: var(--radius-sm, 6px);
  padding: 0.12rem 0.7rem;
  font-size: 0.72rem;
  font-weight: 600;
}
/* No lift/shadow on hover — overrides .btn-accent's hover transform + box-shadow
   (a thin banner shouldn't have a floating button). Opacity hover is kept. */
.banner-dismiss-btn:hover {
  transform: none;
  box-shadow: none;
}
.banner-dismiss-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Collapsed state: applied when page is scrolled — shrinks banners to ~1/3 height */
#verification-banner.banner-scrolled,
#demo-banner.banner-scrolled,
#beta-banner.banner-scrolled,
#privacy-notice.banner-scrolled {
  padding-top: 0.1rem;
  padding-bottom: 0.1rem;
  line-height: 1.1;
}

/* ---------- Upgrade (premium) modal ---------- */
.upgrade-price-row { margin-top: 1.75rem; margin-bottom: 1.25rem; }
.upgrade-feature-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.upgrade-feature-list li {
  display: flex;
  align-items: baseline;
  gap: 9px;
  font-size: 0.8125rem;
  color: var(--text-sub);
  line-height: 1.4;
}
.upgrade-feature-list li::before {
  content: '✓';
  color: var(--gain);
  font-weight: 700;
  font-size: 0.75rem;
  flex-shrink: 0;
}
.upgrade-price-amount {
  font-size: 2rem;
  font-weight: 800;
  letter-spacing: -0.04em;
  line-height: 1;
  color: var(--accent);
}
.upgrade-cancel-link {
  display: block;
  width: 100%;
  background: none;
  border: none;
  font-size: 0.75rem;
  text-align: center;
  cursor: pointer;
  padding: 4px;
  color: var(--text-muted);
}
.upgrade-cancel-link:hover { color: var(--text-sub); }
/* Context-specific intro note + matching feature emphasis (e.g. watchlist gate) */
.upgrade-context-note {
  font-size: 0.8125rem;
  line-height: 1.45;
  color: var(--text-sub);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  border-radius: 8px;
  padding: 10px 12px;
}
.upgrade-context-note strong { color: var(--text); font-weight: 700; }
.upgrade-feature-list li.upgrade-feature-highlight {
  color: var(--text);
  font-weight: 600;
}

/* ---------- Partial data teaser notice ---------- */
.partial-data-notice {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  margin-top: 10px;
  padding: 7px 12px;
  border-radius: var(--radius-sm);
  background: var(--bg-deep);
  font-size: 0.78rem;
  color: var(--text-sub);
}
.partial-data-upgrade-link {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--accent);
  font-size: inherit;
  font-weight: 600;
  padding: 0;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.partial-data-upgrade-link:hover { opacity: 0.8; }

/* Premium tab lock icon — SVG uses currentColor to inherit theme accent */
.tab-lock-icon {
  display: inline-flex;
  align-items: center;
  margin-left: 4px;
  color: var(--accent);
  opacity: 0.75;
  vertical-align: middle;
  line-height: 1;
}
