/* =============================================================================
   STOCKSAATHI — Component styles
   Scoped, namespaced, theme-aware.
   ============================================================================= */

/* ============================== NAV ================================= */
.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(255, 255, 255, 0.88);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid var(--divider);
  height: var(--nav-h);
  padding-top: env(safe-area-inset-top);
  box-sizing: content-box;
}
[data-theme="dark"] .nav { background: rgba(10, 11, 15, 0.85); }

.nav-inner {
  max-width: var(--max-w);
  margin: 0 auto;
  height: 100%;
  padding: 0 var(--sp-6);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-5);
}
.brand-logo {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-weight: 700;
  font-size: var(--text-lg);
  color: var(--text-strong);
  letter-spacing: -0.02em;
}
.brand-logo:hover { color: var(--text-strong); }
.logo-mark {
  width: 30px; height: 30px;
  border-radius: 8px;
  background: linear-gradient(135deg, var(--brand), var(--brand-dark));
  display: grid; place-items: center;
  color: white;
  font-weight: 800;
  font-size: 14px;
  box-shadow: var(--sh-sm);
}
.nav-links {
  display: flex;
  gap: var(--sp-1);
  align-items: center;
}
.nav-link {
  padding: 8px 14px;
  color: var(--text-muted);
  font-size: var(--text-md);
  font-weight: 500;
  border-radius: var(--r);
  transition: color var(--dur-1), background var(--dur-1);
}
.nav-link:hover { color: var(--text-strong); background: var(--bg-soft); }
.nav-link.active { color: var(--text-strong); background: var(--brand-soft); }
.nav-right {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
}
.nav-cash {
  font-family: var(--font-mono);
  padding: 6px 12px;
  background: var(--bg-soft);
  border: 1px solid var(--border);
  border-radius: var(--r);
  display: flex; flex-direction: column;
  line-height: 1.15;
}
.nav-cash .label { font-size: 9px; color: var(--text-dim); margin-bottom: 0; letter-spacing: 0.06em; text-transform: uppercase; }
.nav-cash .val { font-weight: 700; font-size: var(--text-md); color: var(--text-strong); }
.nav-avatar {
  width: 36px; height: 36px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--saffron), #E06B00);
  color: white;
  font-weight: 700;
  font-size: 13px;
  display: grid; place-items: center;
  cursor: pointer;
  transition: transform var(--dur-1);
}
.nav-avatar:hover { transform: scale(1.05); }

@media (max-width: 820px) {
  .nav-inner { padding: 0 var(--sp-3); gap: var(--sp-2); }
  .nav-links { display: none; }
  .nav-cash { display: none; }
  .market-status { display: none; }
  /* Log in + Sign up live in the mobile bottom-nav and the hamburger
     drawer at this width — hiding them here keeps the top bar from
     overflowing and shoving the theme-toggle / cmdk button off-screen
     to the left (which is what was making the dark-mode button look
     "missing" until the user logged in). */
  .nav-auth-btn { display: none; }
}
/* When the coach panel is docked, body content shrinks by var(--coach-w) =
   380 px. On narrow desktops (1280-1479 px) the full nav bar (brand + 6
   links + cmdk + theme + market-status + cash + avatar) no longer fits in
   the remaining 900-1100 px of usable width, so we hide the secondary
   informational items (portfolio cash pill + NSE live-status pill) to
   keep the primary navigation readable. At ≥ 1480 px there's room for
   everything again, so they come back. */
@media (min-width: 1280px) and (max-width: 1479px) {
  body.coach-docked .nav-cash { display: none; }
  body.coach-docked .market-status { display: none; }
}

/* Mobile bottom nav — fixed thumb-zone navigation bar shown only on phones.
   Replaces the old "must tap burger → drawer → item" 3-tap path with a
   1-tap path to the 4 key destinations. The drawer is still accessible
   via the ☰ More item for less-frequent routes. */
.mobile-bottom-nav {
  display: none;
  position: fixed;
  left: 0; right: 0; bottom: 0;
  background: var(--surface);
  border-top: 1px solid var(--divider);
  z-index: 40;
  padding: 4px 0 env(safe-area-inset-bottom);
  box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.15);
}
.mobile-bottom-nav > * {
  display: inline-flex !important;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  padding: 8px 4px;
  min-height: 52px;
  color: var(--text-muted);
  text-decoration: none;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.02em;
  background: transparent;
  border: none;
  font-family: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: color 60ms linear, background 60ms linear;
}
.mobile-bottom-nav { display: none; }
.mobile-bottom-nav .mbn-link-icon { font-size: 20px; line-height: 1; }
.mobile-bottom-nav .mbn-link-label { font-size: 10px; }
.mobile-bottom-nav .mbn-link.active { color: var(--brand); }
.mobile-bottom-nav .mbn-link:active,
.mobile-bottom-nav [data-mobile-menu]:active { background: var(--bg-soft); }
@media (max-width: 820px) {
  .mobile-bottom-nav { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; }
  /* Push page content up so the bottom nav never overlays real content */
  body .main { padding-bottom: calc(76px + env(safe-area-inset-bottom)) !important; }
  /* The coach FAB would collide with the bottom nav — nudge it up */
  .coach-fab { bottom: calc(84px + env(safe-area-inset-bottom)) !important; }
}

/* Hamburger button — only visible on mobile */
.nav-burger {
  display: none;
  width: 40px;
  height: 40px;
  border-radius: var(--r);
  background: transparent;
  color: var(--text);
  place-items: center;
  border: 1px solid transparent;
  transition: background var(--dur-1);
}
.nav-burger:hover, .nav-burger:focus-visible {
  background: var(--bg-soft);
  border-color: var(--border);
}
.nav-burger svg { display: block; width: 22px; height: 22px; }
@media (max-width: 820px) {
  .nav-burger { display: grid; }
}

/* Site-wide theme toggle in the nav. Same subtle shape as the burger so
   it reads as "controls" rather than content. Shown on every page. */
.nav-theme-toggle {
  display: grid;
  width: 36px;
  height: 36px;
  border-radius: var(--r);
  background: transparent;
  color: var(--text-muted);
  place-items: center;
  border: 1px solid transparent;
  transition: background var(--dur-1), color var(--dur-1), border-color var(--dur-1);
  cursor: pointer;
}
.nav-theme-toggle:hover, .nav-theme-toggle:focus-visible {
  background: var(--bg-soft);
  border-color: var(--border);
  color: var(--text);
}
.nav-theme-toggle svg { display: block; }

/* Mobile drawer — slides in from the right when burger is tapped */
.nav-drawer {
  position: fixed;
  inset: 0;
  z-index: 110;
  display: none;
  pointer-events: none;
}
.nav-drawer.open {
  display: block;
  pointer-events: auto;
}
.nav-drawer-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(10, 14, 26, 0.45);
  backdrop-filter: blur(2px);
  opacity: 0;
  transition: opacity var(--dur-2) var(--ease);
}
.nav-drawer.open .nav-drawer-backdrop { opacity: 1; }
.nav-drawer-panel {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(320px, 88vw);
  background: var(--surface);
  box-shadow: var(--sh-lg);
  padding: var(--sp-5);
  padding-top: calc(var(--sp-5) + env(safe-area-inset-top));
  padding-bottom: calc(var(--sp-5) + env(safe-area-inset-bottom));
  padding-right: calc(var(--sp-5) + env(safe-area-inset-right));
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  transform: translateX(100%);
  transition: transform var(--dur-2) var(--ease);
  overflow-y: auto;
}
.nav-drawer.open .nav-drawer-panel { transform: translateX(0); }
.nav-drawer-panel .drawer-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--sp-3);
}
.nav-drawer-panel .drawer-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px var(--sp-3);
  border-radius: var(--r);
  color: var(--text);
  font-size: var(--text-base);
  font-weight: 500;
  min-height: 48px;
  transition: background var(--dur-1);
}
.nav-drawer-panel .drawer-link:hover,
.nav-drawer-panel .drawer-link:active,
.nav-drawer-panel .drawer-link.active {
  background: var(--bg-soft);
  color: var(--text-strong);
}
.nav-drawer-panel .drawer-link.active {
  background: var(--brand-soft);
}
.nav-drawer-panel .drawer-divider {
  height: 1px;
  background: var(--divider);
  margin: var(--sp-2) 0;
}
.nav-drawer-panel .drawer-section {
  font-size: 11px;
  font-weight: 700;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: var(--sp-2) var(--sp-3) 4px;
}
.nav-drawer-panel .drawer-stat {
  padding: var(--sp-3);
  background: var(--bg-soft);
  border-radius: var(--r);
  margin-bottom: var(--sp-2);
}
.nav-drawer-panel .drawer-stat .val {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: var(--text-lg);
  color: var(--text-strong);
  letter-spacing: -0.02em;
}

/* ============================== COACH PANEL ========================= */
.coach-panel {
  position: fixed;
  top: var(--nav-h);
  right: 0;
  bottom: 0;
  width: var(--coach-w);
  background: var(--surface);
  border-left: 1px solid var(--divider);
  display: flex;
  flex-direction: column;
  z-index: 40;
  transform: translateX(100%);
  transition: transform var(--dur-2) var(--ease);
  box-shadow: var(--sh-md);
}
.coach-panel.open { transform: translateX(0); }
/* Docked mode only applies on wide desktop viewports. On mobile the panel
   would otherwise sit as a full-width fixed overlay when settings.coachPanelOpen
   is true, covering the entire app and making it unusable. The FAB + explicit
   open action still works on mobile via the .open class. */
@media (min-width: 1280px) {
  body.coach-docked .coach-panel { transform: translateX(0); box-shadow: none; border-left-color: var(--divider); }
}

.coach-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--sp-4) var(--sp-5);
  border-bottom: 1px solid var(--divider);
}
.coach-header-title {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  font-weight: 600;
  font-size: var(--text-md);
}
.coach-avatar-sm {
  width: 32px; height: 32px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--brand), var(--brand-dark));
  display: grid; place-items: center;
  color: white;
  font-weight: 800;
  font-size: 13px;
}
.coach-messages {
  flex: 1;
  overflow-y: auto;
  padding: var(--sp-4) var(--sp-5);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}
.coach-message {
  display: flex;
  flex-direction: column;
  animation: slideUp 320ms var(--ease);
}
.coach-bubble {
  background: var(--bg-soft);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: var(--sp-3) var(--sp-4);
  font-size: var(--text-md);
  line-height: 1.55;
  color: var(--text);
}
.coach-bubble.strong-caution {
  border-color: var(--negative);
  background: var(--negative-soft);
}
.coach-bubble.caution {
  border-color: var(--warning);
  background: var(--warning-soft);
}
.coach-bubble-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--sp-2);
  font-size: var(--text-xs);
  color: var(--text-dim);
}
.coach-context {
  font-size: var(--text-sm);
  color: var(--text-muted);
  margin-top: var(--sp-2);
  padding-top: var(--sp-2);
  border-top: 1px dashed var(--border);
  font-style: italic;
}
.coach-question {
  margin-top: var(--sp-2);
  font-weight: 500;
  color: var(--text-strong);
  font-size: var(--text-md);
}
.coach-citations {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: var(--sp-2);
}
.coach-citation {
  font-size: 10px;
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text-muted);
  padding: 2px 8px;
  border-radius: var(--r-sm);
  font-family: var(--font-mono);
}
.coach-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  text-align: center;
  gap: var(--sp-3);
  color: var(--text-muted);
  padding: var(--sp-8);
}
.coach-empty .emoji { font-size: 40px; }
.coach-footer {
  padding: var(--sp-3) var(--sp-5);
  border-top: 1px solid var(--divider);
  font-size: 11px;
  color: var(--text-dim);
  text-align: center;
}

.coach-fab {
  position: fixed;
  bottom: calc(var(--sp-5) + env(safe-area-inset-bottom));
  right: calc(var(--sp-5) + env(safe-area-inset-right));
  width: 56px; height: 56px;
  border-radius: 50%;
  background: var(--brand);
  color: white;
  box-shadow: var(--sh-md);
  z-index: 39;
  display: grid;
  place-items: center;
  font-size: 22px;
  transition: transform var(--dur-2) var(--ease);
}
.coach-fab:hover, .coach-fab:focus-visible { transform: scale(1.08); background: var(--brand-dark); }
.coach-fab:active { transform: scale(0.95); }
.coach-fab .dot {
  position: absolute;
  top: 8px; right: 8px;
  width: 10px; height: 10px;
  background: var(--negative);
  border-radius: 50%;
  border: 2px solid var(--surface);
}

@media (min-width: 1280px) { .coach-fab { display: none; } }
@media (max-width: 1279px) {
  body.coach-docked { padding-right: 0; }
  .coach-panel {
    top: 0;
    width: min(420px, 100vw);
    height: 100vh;
    height: 100dvh;
    padding-top: env(safe-area-inset-top);
    padding-bottom: env(safe-area-inset-bottom);
    padding-right: env(safe-area-inset-right);
  }
}
@media (max-width: 480px) {
  .coach-panel {
    width: 100vw;
    border-left: none;
  }
  .coach-fab {
    width: 52px; height: 52px;
    font-size: 20px;
  }
}

/* ============================== MODAL =============================== */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(20, 20, 20, 0.55);
  backdrop-filter: blur(4px);
  z-index: 100;
  display: grid;
  place-items: center;
  padding: var(--sp-4);
  animation: fadeIn var(--dur-2) var(--ease);
}
.modal {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  padding: var(--sp-6);
  max-width: 520px;
  width: 100%;
  box-shadow: var(--sh-lg);
  animation: slideUp var(--dur-2) var(--ease);
  max-height: 90vh;
  max-height: 90dvh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
@media (max-width: 520px) {
  .modal-overlay { padding: 0; align-items: flex-end; }
  .modal {
    border-radius: var(--r-xl) var(--r-xl) 0 0;
    max-height: 88vh;
    max-height: 88dvh;
    padding: var(--sp-5) var(--sp-4) calc(var(--sp-5) + env(safe-area-inset-bottom));
    animation: slideUpSheet 260ms var(--ease);
  }
  @keyframes slideUpSheet {
    from { opacity: 0; transform: translateY(20%); }
    to { opacity: 1; transform: translateY(0); }
  }
  .modal-foot { flex-direction: column-reverse; }
  .modal-foot .btn { width: 100%; }
}
.modal-head {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  margin-bottom: var(--sp-4);
}
.modal-icon {
  width: 48px; height: 48px;
  border-radius: var(--r-md);
  display: grid; place-items: center;
  font-size: 22px;
  flex-shrink: 0;
}
.modal-icon.warn { background: var(--warning-soft); color: var(--warning); }
.modal-icon.danger { background: var(--negative-soft); color: var(--negative); }
.modal-icon.info { background: var(--accent-soft); color: var(--accent); }
.modal-icon.success { background: var(--positive-soft); color: var(--positive); }
.modal h2 { font-size: var(--text-xl); margin: 0; }
.modal-body { color: var(--text-muted); line-height: 1.65; font-size: var(--text-md); }
.modal-body p + p { margin-top: var(--sp-3); }
.modal-foot {
  display: flex;
  gap: var(--sp-3);
  justify-content: flex-end;
  margin-top: var(--sp-5);
  flex-wrap: wrap;
}

.intervention-data {
  background: var(--bg-soft);
  border: 1px solid var(--border);
  border-radius: var(--r);
  padding: var(--sp-4);
  margin: var(--sp-4) 0;
}
.intervention-data .big-num {
  font-family: var(--font-mono);
  font-size: var(--text-4xl);
  font-weight: 700;
  color: var(--positive);
  line-height: 1;
  letter-spacing: -0.03em;
}
.intervention-data .big-num.red { color: var(--negative); }
.intervention-data .sublabel {
  color: var(--text-muted);
  font-size: var(--text-sm);
  margin-top: var(--sp-2);
}

/* ============================== TOAST =============================== */
.toast-root {
  position: fixed;
  bottom: calc(var(--sp-6) + env(safe-area-inset-bottom));
  left: 50%;
  transform: translateX(-50%);
  z-index: 200;
  display: flex;
  flex-direction: column-reverse;
  gap: var(--sp-2);
  pointer-events: none;
  width: calc(100vw - var(--sp-6));
  max-width: 480px;
  padding: 0 var(--sp-2);
}
@media (max-width: 420px) {
  .toast-root { bottom: calc(80px + env(safe-area-inset-bottom)); }
  .toast { min-width: 0; width: 100%; }
}
.toast {
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 12px 16px;
  border-radius: var(--r);
  box-shadow: var(--sh-md);
  font-size: var(--text-md);
  min-width: 260px;
  max-width: 420px;
  animation: slideUp var(--dur-2) var(--ease);
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  pointer-events: auto;
  font-weight: 500;
}
.toast.success { border-left: 3px solid var(--positive); }
.toast.error { border-left: 3px solid var(--negative); }
.toast.warn { border-left: 3px solid var(--warning); }
.toast.info { border-left: 3px solid var(--accent); }
.toast .toast-icon {
  font-size: var(--text-lg);
  line-height: 1;
  flex-shrink: 0;
}
.toast.leaving { animation: toastOut 220ms var(--ease) forwards; }
@keyframes toastOut {
  to { opacity: 0; transform: translateY(8px); }
}

/* ============================== CHART primitives ==================== */
.chart-svg { display: block; width: 100%; height: auto; font-family: var(--font-mono); }
.chart-axis-label { fill: var(--text-strong); font-size: 11px; font-weight: 600; }
.chart-grid line { stroke: var(--divider); stroke-dasharray: 2 3; }
.chart-line { fill: none; stroke-width: 2; }
.chart-area { fill-opacity: 0.12; }
/* Zoom-gesture capture on the stock chart. touch-action:none tells the
   browser "this element handles its own touch events" — without it an
   iOS Safari two-finger pinch gets hijacked by the page-zoom layer and
   our chartZoom handler never sees the touchmove events. pan-y would
   let vertical page scroll pass through, but pan-x doesn't exist as a
   value; none is the reliable choice. Only applied to .stock-chart
   (the container rendered by stockChart()), NOT to .chart-svg used by
   lineChart/areaChart/candleChart elsewhere. */
.stock-chart { touch-action: none; }
/* Tiny transition on the plot-area group so wheel-tick steps feel
   smooth instead of stepping per-discrete-wheel-event. 40ms is below
   human motion threshold (~50ms) so it reads as direct manipulation. */
.stock-chart .chart-plot-area { transition: transform 40ms linear; }
.chart-tooltip {
  position: absolute;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--r);
  padding: 8px 12px;
  font-size: var(--text-xs);
  box-shadow: var(--sh-md);
  pointer-events: none;
  z-index: 10;
  font-family: var(--font-mono);
  white-space: nowrap;
}
.chart-candle-up { fill: var(--positive); stroke: var(--positive); }
.chart-candle-down { fill: var(--negative); stroke: var(--negative); }

/* Pre-trade AI nudge slot inside the order-confirm modal */
.trade-nudge-slot {
  display: flex;
  gap: 8px;
  padding: 10px 12px;
  margin: 12px 0;
  border-radius: var(--r);
  background: var(--bg-soft);
  border-left: 3px solid var(--brand);
  font-size: var(--text-sm);
  line-height: 1.5;
  align-items: flex-start;
}
.trade-nudge-slot.sev-warn { border-left-color: var(--warning, var(--negative)); background: var(--negative-soft); }
.trade-nudge-slot.sev-note { border-left-color: var(--brand); }
.trade-nudge-slot .trade-nudge-body { flex: 1; }

/* Nav 'Ask' button that opens the Command-K palette */
.nav-cmdk-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  border-radius: var(--r);
  background: var(--bg-soft);
  border: 1px solid var(--border);
  color: var(--text);
  cursor: pointer;
  font-size: var(--text-sm);
  transition: background var(--dur-1), border-color var(--dur-1);
}
.nav-cmdk-btn:hover {
  background: color-mix(in srgb, var(--brand) 10%, var(--bg-soft));
  border-color: var(--brand);
}
.nav-cmdk-kbd {
  font-family: var(--font-mono, monospace);
  font-size: 10px;
  padding: 1px 5px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--text-muted);
}
@media (max-width: 820px) { .nav-cmdk-label, .nav-cmdk-kbd { display: none; } }

/* Command-K overlay */
.cmdk-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.5);
  display: none;
  align-items: flex-start;
  justify-content: center;
  padding: 12vh var(--sp-3) var(--sp-4);
  z-index: 9999;
}
.cmdk-overlay.open { display: flex; animation: cmdk-fade 150ms var(--ease, ease-out); }
@keyframes cmdk-fade { from { opacity: 0; } to { opacity: 1; } }

.cmdk-panel {
  width: min(640px, 100%);
  max-height: 72vh;
  overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--border-strong, var(--border));
  border-radius: var(--r-lg, var(--r));
  box-shadow: 0 20px 80px rgba(0,0,0,0.5), 0 4px 12px rgba(0,0,0,0.2);
  animation: cmdk-pop 180ms var(--ease, ease-out);
}
@keyframes cmdk-pop { from { transform: translateY(-8px) scale(0.98); opacity: 0; } to { transform: translateY(0) scale(1); opacity: 1; } }

.cmdk-inputwrap {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--divider);
}
.cmdk-icon { font-size: 18px; }
.cmdk-input {
  flex: 1;
  border: 0;
  outline: 0;
  background: transparent;
  font-size: var(--text-lg);
  color: var(--text-strong);
  font-family: inherit;
}
.cmdk-kbd {
  font-family: var(--font-mono, monospace);
  font-size: 11px;
  padding: 2px 6px;
  background: var(--bg-soft);
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--text-muted);
}
.cmdk-spinner {
  width: 14px; height: 14px; border-radius: 50%;
  border: 2px solid var(--brand);
  border-top-color: transparent;
  animation: cmdk-spin 0.7s linear infinite;
}
@keyframes cmdk-spin { to { transform: rotate(360deg); } }

.cmdk-section-label {
  font-size: var(--text-10);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--text-muted);
  padding: 12px 16px 6px;
}
.cmdk-quick {
  padding: 0 12px 8px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.cmdk-quick-item {
  text-align: left;
  background: transparent;
  border: 0;
  color: var(--text);
  font-size: var(--text-md);
  padding: 8px 10px;
  border-radius: var(--r);
  cursor: pointer;
}
.cmdk-quick-item:hover, .cmdk-quick-item:focus { background: var(--bg-soft); outline: none; }

.cmdk-examples {
  padding: 0 16px 14px;
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.cmdk-example {
  font-size: var(--text-xs);
  background: var(--bg-soft);
  padding: 4px 10px;
  border-radius: var(--r-full);
  color: var(--text-muted);
  font-family: var(--font-mono, monospace);
}

.cmdk-answer {
  padding: 14px 16px;
  line-height: 1.55;
  color: var(--text);
  font-size: var(--text-md);
}
.cmdk-cta {
  margin: 0 16px 16px;
  padding: 8px 12px;
  background: var(--brand);
  color: #fff;
  border: 0;
  border-radius: var(--r);
  font-weight: 700;
  cursor: pointer;
}
.cmdk-cta:hover { filter: brightness(0.95); }
.cmdk-loading { padding: 16px; color: var(--text-muted); }
.cmdk-error { padding: 12px 16px; color: var(--negative); font-size: var(--text-sm); }

/* AI-suggested crash prompts — chip row under the custom-crash input */
.custom-crash-suggestions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: var(--sp-3);
}
.crash-sugg-chip {
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  font-size: var(--text-xs);
  padding: 4px 10px;
  border-radius: var(--r-full);
  cursor: pointer;
  transition: background var(--dur-1), border-color var(--dur-1);
}
.crash-sugg-chip:hover {
  background: color-mix(in srgb, var(--brand) 10%, var(--surface));
  border-color: var(--brand);
}

/* Report-card AI strengths + watch-outs grid */
.report-ai-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-3);
  margin-top: var(--sp-2);
}
.report-ai-list {
  margin: 0;
  padding-left: 18px;
  line-height: 1.55;
  color: var(--text);
  font-size: var(--text-sm);
}
.report-ai-list li { margin-bottom: 4px; }
@media (max-width: 620px) { .report-ai-grid { grid-template-columns: 1fr; } }

/* Today's market mood — AI one-paragraph summary at top of /#/stocks */
.market-mood-card {
  padding: var(--sp-4);
  border-radius: var(--r-lg, var(--r));
  background: var(--bg-soft);
  border: 1px solid var(--divider);
  margin-bottom: var(--sp-4);
}
.market-mood-card.mood-hot   { border-top: 3px solid var(--negative); }
.market-mood-card.mood-warm  { border-top: 3px solid var(--brand); }
.market-mood-card.mood-mild  { border-top: 3px solid var(--text-muted); }
.market-mood-card.mood-cold  { border-top: 3px solid var(--positive); opacity: 0.95; }
.mood-head { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.mood-pill {
  font-size: var(--text-10);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 2px 10px;
  border-radius: var(--r-full);
}
.mood-pill.mood-hot  { background: var(--negative-soft); color: var(--negative); }
.mood-pill.mood-warm { background: color-mix(in srgb, var(--brand) 15%, transparent); color: var(--brand); }
.mood-pill.mood-mild { background: var(--bg-soft); color: var(--text-muted); }
.mood-pill.mood-cold { background: var(--positive-soft); color: var(--positive); }
.mood-body { line-height: 1.55; color: var(--text-strong); font-size: var(--text-md); }

/* Hotfix59a: pinch-of-personalization line below the shared mood
   narrative. Renders the user's top holding's day-change from the
   client-side quoteCache — no LLM call, so the shared mood paragraph
   stays cacheable across all users and only this trailing line
   varies per visitor. */
.mood-personal {
  color: var(--text-muted);
  font-size: var(--text-sm);
  line-height: 1.55;
  padding-top: 8px;
  border-top: 1px dashed color-mix(in srgb, var(--text-muted) 30%, transparent);
}
.mood-personal strong {
  color: var(--text-strong);
  font-weight: 600;
}

/* Hotfix59a: card-shaped skeleton for the mood card during cold-load.
   Same outer dimensions as the real card so the page doesn't reflow
   when the LLM-generated paragraph lands — only the inner shimmer
   blocks swap to prose. Border-top is muted (no temperature class
   yet) to avoid a green/red flash before we know the actual mood. */
.market-mood-card-skeleton {
  border-top: 3px solid color-mix(in srgb, var(--text-muted) 25%, var(--border));
  min-height: 116px;
}
.market-mood-card-skeleton .mood-head {
  margin-bottom: 12px;
}
.skeleton-shimmer {
  display: inline-block;
  border-radius: 4px;
  background: linear-gradient(
    90deg,
    color-mix(in srgb, var(--text-muted) 12%, var(--surface)) 0%,
    color-mix(in srgb, var(--text-muted) 22%, var(--surface)) 50%,
    color-mix(in srgb, var(--text-muted) 12%, var(--surface)) 100%
  );
  background-size: 200% 100%;
  animation: skeletonShimmer 1.6s ease-in-out infinite;
}
.skeleton-pill { border-radius: 999px; }
.skeleton-line { display: block; }
@keyframes skeletonShimmer {
  0%   { background-position: 100% 50%; }
  100% { background-position: -100% 50%; }
}
@media (prefers-reduced-motion: reduce) {
  .skeleton-shimmer { animation: none; }
}

.ai-search-result-card {
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r);
  background: color-mix(in srgb, var(--brand) 6%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--brand) 25%, var(--border));
  margin-bottom: var(--sp-3);
}

/* Stock "Why is this moving?" AI card on the detail page */
.stock-why-card {
  border-left: 3px solid var(--brand);
}
.stock-why-card .card-head h3 {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--text-md);
}
#stock-why-body {
  font-size: var(--text-md);
  line-height: 1.6;
  color: var(--text-strong);
}

/* Portfolio daily digest card — one-paragraph AI take at the top of
   /#/portfolio, tinted subtly by day mood. Loads async then fades in. */
.pf-digest-card {
  padding: var(--sp-4) var(--sp-5);
  border-radius: var(--r-lg, var(--r));
  background: var(--bg-soft);
  border: 1px solid var(--divider);
  margin-bottom: var(--sp-4);
  position: relative;
  overflow: hidden;
}
.pf-digest-card::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 3px;
  background: var(--brand);
  opacity: 0.7;
}
.pf-digest-card.mood-up::before   { background: var(--positive); }
.pf-digest-card.mood-down::before { background: var(--negative); }
.pf-digest-card.mood-flat::before { background: var(--text-muted); }
.pf-digest-card.mood-empty::before { background: var(--brand); }
.pf-digest-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
}
.pf-digest-label {
  font-size: var(--text-10);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 800;
  color: var(--brand);
  padding: 3px 8px;
  border-radius: var(--r-full);
  background: color-mix(in srgb, var(--brand) 12%, transparent);
}
.pf-digest-body {
  font-size: var(--text-md);
  line-height: 1.6;
  color: var(--text-strong);
}

/* AI term wrapper — subtle dotted underline on terms that have an AI
   hover explainer wired. Doesn't look clickable; looks like a hint.
   Tooltip pops on :hover / :focus and fetches the definition lazily. */
.ai-term {
  text-decoration: underline dotted;
  text-underline-offset: 3px;
  text-decoration-color: var(--text-muted);
  text-decoration-thickness: 1px;
  cursor: help;
  font-style: normal;
}
.ai-term:hover, .ai-term:focus-visible {
  text-decoration-color: var(--brand);
  color: var(--text-strong);
  outline: none;
}
.ai-term-tooltip {
  position: absolute;
  z-index: 999;
  /* Width bounds. min-width gives us room for a full sentence even while
     the explanation is still loading ("…" placeholder). max-width caps
     growth so a chatty LLM can't blow past the card grid. */
  min-width: 240px;
  max-width: 320px;
  background: var(--surface-elev, var(--surface));
  color: var(--text);
  border: 1px solid var(--border-strong, var(--border));
  border-radius: var(--r);
  padding: 10px 12px;
  font-size: var(--text-sm);
  line-height: 1.45;
  box-shadow: var(--sh-lg, var(--sh-md));
  pointer-events: none;
  animation: ai-tip-in 140ms var(--ease, ease-out);
  /* Explicit text-flow rules so no inherited or global nowrap / overflow
     can clip the body to a single-token width (observed symptom: tooltip
     only showed "The P/E" or "A" instead of the full sentence). */
  white-space: normal;
  overflow-wrap: break-word;
  word-break: normal;
}
.ai-term-tooltip-head {
  font-weight: 700;
  font-size: var(--text-xs);
  color: var(--brand);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 4px;
  white-space: normal;
}
.ai-term-tooltip-body {
  color: var(--text);
  /* Block + explicit wrap rules so the body always fills the tooltip
     width and wraps. Prevents any text-overflow / nowrap / clip from
     an ancestor rule from accidentally truncating the explanation. */
  display: block;
  white-space: normal;
  overflow-wrap: break-word;
  word-break: normal;
}
@keyframes ai-tip-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Hover cursor: single vertical guide line + breathing price-dot. The
   line tracks cursor X; the dot bar-snaps to the nearest candle's close
   (matches the numbers in the tooltip) and colour-flips green/red vs the
   range's first close.
   Animation technique: animate SVG `r` + `opacity` DIRECTLY, never
   `transform: scale()` with transform-box:fill-box — that combo was what
   made the halo "drift" during mousemove on some browsers (the fill-box
   origin doesn't always resolve consistently during attribute updates,
   so the scale centre decoupled from the moving cx/cy and you saw
   jitter). Animating r is a pure radial expand from the true centre
   defined by cx/cy, immune to that issue. */
.chart-cursor-x { pointer-events: none; }
.chart-dot-halo, .chart-dot-core { pointer-events: none; }
.chart-dot-halo.breathing {
  animation: chart-dot-pulse 1.8s ease-in-out infinite;
}
.chart-dot-core.breathing {
  animation: chart-dot-shimmer 1.8s ease-in-out infinite;
}
@keyframes chart-dot-pulse {
  0%, 100% { r: 8;  opacity: 0.18; }
  50%      { r: 12; opacity: 0.38; }
}
@keyframes chart-dot-shimmer {
  0%, 100% { r: 4.5; opacity: 1;    }
  50%      { r: 5;   opacity: 0.92; }
}
@media (prefers-reduced-motion: reduce) {
  .chart-dot-halo.breathing, .chart-dot-core.breathing { animation: none; }
  .chart-dot-halo { opacity: 0.22; }
}

/* ============================== LANDING / HERO ====================== */
.hero {
  text-align: center;
  padding: var(--sp-20) var(--sp-4) var(--sp-16);
  max-width: 920px;
  margin: 0 auto;
}
@media (max-width: 640px) {
  .hero { padding: var(--sp-10) var(--sp-3) var(--sp-8); }
  .hero .tagline { font-size: var(--text-base); }
  .hero .cta-row { flex-direction: column; width: 100%; }
  .hero .cta-row .btn { width: 100%; }
  .hero .stat-row { margin-top: var(--sp-6); grid-template-columns: 1fr; }
  .hero .stat { padding: var(--sp-4); }
}
.hero h1 {
  font-size: clamp(2.2rem, 6vw, 4.25rem);
  line-height: 1.05;
  letter-spacing: -0.035em;
  margin-bottom: var(--sp-5);
  color: var(--text-strong);
}
.hero .grad-accent { color: var(--brand); }
.hero .tagline {
  font-size: var(--text-lg);
  color: var(--text-muted);
  margin-bottom: var(--sp-6);
  max-width: 680px;
  margin-left: auto;
  margin-right: auto;
  line-height: 1.55;
}
.hero .cta-row {
  display: flex;
  gap: var(--sp-3);
  justify-content: center;
  flex-wrap: wrap;
  margin-bottom: var(--sp-8);
}
.hero .stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--sp-4);
  max-width: 820px;
  margin: var(--sp-10) auto 0;
}
.hero .stat {
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: var(--sp-5);
  background: var(--surface);
  transition: transform var(--dur-2) var(--ease), border-color var(--dur-1);
}
.hero .stat:hover { transform: translateY(-2px); border-color: var(--brand); }
.hero .stat .n {
  font-family: var(--font-mono);
  font-size: var(--text-3xl);
  font-weight: 700;
  color: var(--brand);
  letter-spacing: -0.03em;
  display: block;
  line-height: 1;
}
.hero .stat .l {
  font-size: var(--text-sm);
  color: var(--text-muted);
  margin-top: var(--sp-2);
}
.feature-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--sp-4);
  margin: var(--sp-16) 0;
}
.feature-card {
  padding: var(--sp-5);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  transition: transform var(--dur-2) var(--ease), border-color var(--dur-1);
}
.feature-card:hover {
  transform: translateY(-3px);
  border-color: var(--brand);
  box-shadow: var(--sh-sm);
}
.feature-card .icon {
  font-size: 26px;
  display: inline-grid;
  place-items: center;
  width: 48px; height: 48px;
  border-radius: var(--r-md);
  background: var(--brand-soft);
  margin-bottom: var(--sp-3);
}
.feature-card h3 {
  font-size: var(--text-lg);
  margin-bottom: var(--sp-2);
}
.feature-card p {
  color: var(--text-muted);
  font-size: var(--text-md);
  line-height: 1.65;
}

/* ============================== PORTFOLIO =========================== */
.portfolio-hero {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--sp-5);
  align-items: end;
  margin-bottom: var(--sp-5);
}
@media (max-width: 600px) {
  .portfolio-hero { grid-template-columns: 1fr; }
}
.pf-value {
  font-family: var(--font-mono);
  font-size: clamp(2rem, 5vw, 2.75rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1;
  color: var(--text-strong);
}
.pf-delta {
  font-family: var(--font-mono);
  font-size: var(--text-md);
  margin-top: 6px;
  font-weight: 600;
}
.portfolio-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: var(--sp-3);
  margin-bottom: var(--sp-5);
}
.stat-tile {
  padding: var(--sp-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
}
.stat-tile.has-pending {
  border-color: color-mix(in srgb, var(--brand) 50%, var(--border));
  background: color-mix(in srgb, var(--brand) 6%, var(--surface));
}
.stat-tile.has-pending .l { color: var(--brand); }
.stat-tile .l {
  font-size: var(--text-10);
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 4px;
}
.stat-tile .v {
  font-family: var(--font-mono);
  font-size: var(--text-xl);
  font-weight: 700;
  color: var(--text-strong);
}

.portfolio-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--sp-5);
}
@media (min-width: 1024px) {
  .portfolio-grid { grid-template-columns: 2fr 1fr; }
}
/* Compact holdings table on phones */
@media (max-width: 600px) {
  .table-wrap { font-size: var(--text-sm); }
  .table th, .table td { padding: 10px 12px; }
  .pf-value { font-size: clamp(1.75rem, 9vw, 2.25rem); }
  .portfolio-stats { grid-template-columns: repeat(2, 1fr); }
}

/* ============================== STOCKS LIST ========================= */
.stocks-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: var(--sp-4);
}
@media (max-width: 480px) {
  .stocks-grid { grid-template-columns: 1fr; }
}
.stock-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: var(--sp-4);
  cursor: pointer;
  transition: transform var(--dur-2) var(--ease), border-color var(--dur-1), box-shadow var(--dur-1);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  /* Match the stub's inline min-height so hydrated cards reserve the same
     layout space. Without this, hydrating a stub triggers a height delta
     (typically -12px to +18px depending on content), all cards below
     reflow, and cards near the IO 200% boundary can re-cross the threshold
     and re-trigger hydrate/dehydrate cycles. The cumulative layout shift
     also adds visible jank on every chunked render batch. Matching the
     stub keeps the grid pixel-stable through the hydrate transition. */
  min-height: 172px;
}
/* Virtualization: tells Chromium to skip paint + style + layout for cards
   outside the viewport. At ~2700 cards on /stocks All NSE this is the
   difference between 40-60ms per scroll frame and 8-12ms on a mid-range
   Android. contain-intrinsic-size reserves the right scroll height
   (180px matches the real rendered card). iOS Safari shipped support in
   18.0 (Sept 2024); older Safari falls into the @supports-not branch
   below for a partial improvement (paint/layout containment without the
   skip-when-offscreen behaviour). */
/* IMPORTANT: content-visibility: auto suppresses IntersectionObserver
   callbacks for offscreen elements in Chromium. Our Hotfix4 stub virtualization
   relies on the IO firing within rootMargin "200% 0px" to hydrate stubs BEFORE
   they scroll into view — but if the stub itself is content-visibility-skipped,
   the IO sees isIntersecting:false and the hydrate branch never runs. Cards
   then stay frozen at the skeleton state until they fully enter the visible
   viewport, which defeats the whole pre-warm purpose.

   Fix: apply content-visibility ONLY to stubs (.stock-card-stub), where the
   skipped-paint behaviour is desired AND the IO doesn't need to fire (a stub
   that hydrates while still offscreen is what we want). Hydrated cards
   (.stock-card without .stock-card-stub) get standard paint containment via
   the @supports-not branch, preserving the IO callback timing.

   Also bumped contain-intrinsic-size from 0 180px to 0 172px to match the
   stub's inline min-height — eliminates the 8px CLS reflow when stubs hydrate. */
@supports (content-visibility: auto) {
  .stock-card-stub {
    content-visibility: auto;
    contain-intrinsic-size: 0 172px;
  }
  .stock-card { contain: layout paint; }
}
@supports not (content-visibility: auto) {
  .stock-card { contain: layout paint; }
}
/* Sector pill row + pagination row mobile compaction. */
@media (max-width: 600px) {
  .filter-pills { gap: 6px; }
  .filter-pill { padding: 6px 10px; font-size: 12px; }
}
@media (max-width: 480px) {
  /* Stack the "Show 100 more" + "Show all 2686" buttons full-width on
     small screens so both labels are readable. */
  .stocks-pager { flex-direction: column; align-items: stretch !important; }
  .stocks-pager > .btn { width: 100%; }
}
.stock-card:hover {
  transform: translateY(-2px);
  border-color: var(--brand);
  box-shadow: var(--sh-sm);
}
.stock-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-2);
}
.stock-avatar {
  width: 40px; height: 40px;
  border-radius: var(--r-sm);
  background: var(--bg-soft);
  border: 1px solid var(--border);
  color: var(--text);
  display: grid; place-items: center;
  font-weight: 700;
  font-size: var(--text-xs);
  flex-shrink: 0;
}
.stock-title { flex: 1; min-width: 0; }
.stock-title .name {
  font-weight: 600;
  font-size: var(--text-md);
  color: var(--text-strong);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.stock-title .sym {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--text-dim);
  margin-top: 2px;
}
.stock-price {
  font-family: var(--font-mono);
  font-size: var(--text-xl);
  font-weight: 700;
  color: var(--text-strong);
  letter-spacing: -0.02em;
}
.stock-change {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 600;
}
.stock-sparkline { height: 40px; width: 100%; margin-top: auto; }

.stocks-toolbar {
  display: flex;
  gap: var(--sp-3);
  align-items: center;
  margin-bottom: var(--sp-4);
  flex-wrap: wrap;
}
.stocks-toolbar .input-prefix { max-width: 360px; flex: 1; }

.filter-pills {
  display: flex;
  gap: var(--sp-2);
  flex-wrap: wrap;
}
.filter-pill {
  padding: 7px 14px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-muted);
  font-size: var(--text-sm);
  font-weight: 500;
  border-radius: var(--r-full);
  transition: all var(--dur-1);
}
.filter-pill.active {
  background: var(--brand);
  color: white;
  border-color: var(--brand);
}
.filter-pill:hover:not(.active) {
  color: var(--text-strong);
  border-color: var(--border-strong);
}
/* Hotfix63a: tasteful count badge inside every category pill so users
   see "Banking 42" / "Oil & Gas 37" / "IT 186" upfront — same as
   Groww's screener. Slightly dimmer + smaller than the pill label so
   it reads as metadata, not as part of the name. On the active pill
   the badge inverts to white-on-translucent so it stays legible. */
.filter-pill .pill-count {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  font-size: 10px;
  font-weight: 700;
  line-height: 1.4;
  border-radius: var(--r-full);
  background: var(--bg-soft);
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
  min-width: 18px;
  text-align: center;
}
.filter-pill.active .pill-count {
  background: rgba(255, 255, 255, 0.22);
  color: white;
}

/* ============================== VIEW TOGGLE ========================== */
/* Hotfix65a: segmented control to switch /stocks between tile (compact
   list) and card (detailed) views. Sits in the toolbar after the sort
   dropdown. Margin-left:auto pushes it to the right edge on desktop;
   on mobile the toolbar is flex-wrap so it falls into the natural row. */
.view-toggle {
  display: inline-flex;
  align-items: stretch;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--surface);
  padding: 2px;
  gap: 2px;
  margin-left: auto;
  flex-shrink: 0;
}
.view-toggle-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  border: none;
  background: transparent;
  color: var(--text-dim);
  font-size: var(--text-xs);
  font-weight: 600;
  border-radius: 4px;
  cursor: pointer;
  transition: color var(--dur-1) var(--ease), background var(--dur-1) var(--ease);
}
.view-toggle-btn:hover:not(.active) { color: var(--text-strong); }
.view-toggle-btn.active {
  background: var(--bg-soft);
  color: var(--text-strong);
}
.view-toggle-btn svg { display: block; flex-shrink: 0; }
@media (max-width: 480px) {
  .view-toggle { margin-left: 0; }
  .view-toggle-btn .view-label { display: none; }
  .view-toggle-btn { padding: 6px 8px; }
}

/* ============================== STOCKS TILE VIEW ===================== */
/* Hotfix65a/65b: alternative compact list view for /stocks. Tile mode
   uses its OWN stub + body HTML (renderStubTile + renderStockTileBody)
   so the layout matches the row form factor — name + ticker visible
   on the left, sparkline middle, price+change on the right. The CSS
   wraps each tile in a 3-col grid: head | sparkline | price-col.
   Card mode keeps the original detailed cards. Toggle via
   localStorage["ss.stocks-view"]; switching calls renderList() to
   rebuild stubs in the new mode. */

/* Card-view container — explicit alias for the base behaviour. Both
   selectors map to the same auto-fill grid so legacy callers without
   the modifier still get card-grid layout. */
.stocks-grid,
.stocks-grid--cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: var(--sp-4);
}

/* Tile-view container — single column of full-width rows wrapped in a
   shared border + rounded outer corners (panel feel, like Groww). */
.stocks-grid--tiles {
  display: flex;
  flex-direction: column;
  gap: 0;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface);
  overflow: hidden;
}

/* Each tile row — 6-column grid matching Groww's screener layout:
     Company | Sparkline | Market price | 1D change | 1D volume | 52W bar
   Both stub and hydrated body emit the SAME 6 direct children in this
   exact order (.tile-head + .stock-sparkline + .tile-price-cell +
   .tile-change-cell + .tile-vol-cell + .tile-52w-cell), so auto-place
   slots them in column order without flex tricks. min-width:0 on the
   head column lets the name truncate with ellipsis instead of forcing
   horizontal scroll. */
.stocks-grid--tiles .stock-card {
  display: grid;
  grid-template-columns:
    minmax(0, 1.5fr)   /* Company */
    96px               /* Sparkline */
    96px               /* Market price */
    minmax(110px, max-content) /* 1D change */
    72px               /* 1D volume */
    minmax(110px, 130px); /* 52W bar */
  align-items: center;
  gap: 12px;
  padding: 10px var(--sp-3);
  margin: 0;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--border);
  border-radius: 0;
  min-height: auto !important;     /* defeat the inline 172px stub style */
}
.stocks-grid--tiles .stock-card:last-child { border-bottom: 0; }
.stocks-grid--tiles .stock-card:hover {
  transform: none;
  background: var(--bg-soft);
  border-bottom-color: var(--border);
  box-shadow: none;
}

/* Header row — column titles above the grid. Sticky-style label strip
   matching the screener's "Company | Market price | 1D price change |
   1D volume | 52W performance" headers. */
.stocks-grid--tiles-header {
  display: grid;
  grid-template-columns:
    minmax(0, 1.5fr) 96px 96px minmax(110px, max-content) 72px minmax(110px, 130px);
  gap: 12px;
  padding: 10px var(--sp-3);
  background: var(--bg-soft);
  border: 1px solid var(--border);
  border-radius: var(--r-md) var(--r-md) 0 0;
  border-bottom: 0;
  font-size: 11px;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: none;
  letter-spacing: 0.01em;
  align-items: center;
}
.stocks-grid--tiles-header > .col-spark { /* spark column is unlabeled */ }
.stocks-grid--tiles-header > .col-num { text-align: right; font-variant-numeric: tabular-nums; }
.stocks-grid--tiles-header > .col-center { text-align: center; }
/* When tiles-header is rendered, drop the top border-radius from the
   .stocks-grid--tiles wrapper since the header now caps it. */
.stocks-grid--tiles-header + .stocks-grid--tiles {
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}

/* Tile head: avatar + name/ticker stacked. Min-width 0 so flex/grid
   shrinks let ellipsis kick in. */
.tile-head {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.tile-avatar {
  width: 32px; height: 32px;
  font-size: 10px;
  flex-shrink: 0;
}
.tile-title {
  min-width: 0;
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.tile-name {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-strong);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
.tile-sym {
  font-size: 10px;
  color: var(--text-dim);
  font-family: var(--font-mono);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

/* Tile sparkline cell — fixed 88x28 wrapper. Inner SVG fills 100% via
   the existing .chart-svg rule. */
.tile-spark {
  width: 88px;
  height: 28px;
  margin-top: 0;
  flex-shrink: 0;
}
.tile-spark .chart-svg {
  width: 100% !important;
  height: 100% !important;
}

/* Price cell — right-aligned, mono, bold. */
.tile-price-cell {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  text-align: right;
}
.tile-price {
  font-size: var(--text-sm);
  font-weight: 700;
  font-family: var(--font-mono);
  color: var(--text-strong);
  line-height: 1.2;
  letter-spacing: -0.01em;
}

/* 1D change cell — shows absolute (₹X.XX) + percentage on the same line,
   coloured by direction. Mono. Right-aligned. */
.tile-change-cell {
  display: flex;
  align-items: center;
  justify-content: flex-end;
}
.tile-change {
  font-size: 11px;
  font-weight: 600;
  font-family: var(--font-mono);
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  white-space: nowrap;
  text-align: right;
}
.tile-change-abs {
  font-size: 11px;
  font-weight: 700;
}
.tile-change-pct {
  font-size: 11px;
  font-weight: 500;
  opacity: 0.85;
}

/* Volume cell — compact "23.4M" / "1.2L" / "847", dim text. */
.tile-vol-cell {
  font-size: 11px;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  text-align: right;
  color: var(--text-muted);
}

/* 52W performance bar cell — gradient track with the current price as
   a marker. Matches Groww's "L ──●── H" indicator. */
.tile-52w-cell {
  display: flex;
  align-items: center;
  justify-content: center;
}
.tile-52w {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
}
.tile-52w-end {
  font-size: 9px;
  color: var(--text-faint);
  font-family: var(--font-mono);
  font-weight: 600;
  flex-shrink: 0;
}
.tile-52w-track {
  position: relative;
  flex: 1 1 auto;
  height: 4px;
  background: linear-gradient(to right,
    var(--negative-soft, rgba(235, 87, 87, 0.18)) 0%,
    var(--bg-soft) 50%,
    var(--positive-soft, rgba(0, 179, 134, 0.18)) 100%);
  border-radius: var(--r-full);
  overflow: visible;
}
.tile-52w-marker {
  position: absolute;
  top: 50%;
  width: 8px; height: 8px;
  background: var(--text-strong);
  border: 1.5px solid var(--surface);
  border-radius: 50%;
  transform: translate(-50%, -50%);
  box-shadow: 0 0 0 0.5px var(--border);
}
.tile-52w-empty {
  justify-content: center;
  font-size: 11px;
  color: var(--text-faint);
}

/* Tablet ≤1100px: drop the 52W bar column (low value at this width) */
@media (max-width: 1100px) {
  .stocks-grid--tiles-header,
  .stocks-grid--tiles .stock-card {
    grid-template-columns:
      minmax(0, 1.5fr) 88px 96px minmax(110px, max-content) 72px;
  }
  .tile-52w-cell,
  .stocks-grid--tiles-header .col-52w { display: none; }
}

/* Smaller tablet ≤900px: drop the volume column too */
@media (max-width: 900px) {
  .stocks-grid--tiles-header,
  .stocks-grid--tiles .stock-card {
    grid-template-columns:
      minmax(0, 1.5fr) 76px 88px minmax(110px, max-content);
    padding: 9px 10px;
    gap: 10px;
  }
  .tile-vol-cell,
  .stocks-grid--tiles-header .col-vol { display: none; }
  .tile-spark { width: 76px; }
}

/* Mobile ≤640px: name + sparkline + price + change only */
@media (max-width: 640px) {
  .stocks-grid--tiles-header,
  .stocks-grid--tiles .stock-card {
    grid-template-columns:
      minmax(0, 1fr) 60px 80px minmax(86px, max-content);
    padding: 8px 10px;
    gap: 8px;
  }
  .tile-avatar { width: 28px; height: 28px; font-size: 9px; }
  .tile-spark { width: 60px; height: 24px; }
  .tile-name { font-size: 12px; }
  .tile-sym  { font-size: 9px; }
  .tile-price { font-size: 13px; }
  .tile-change-abs { display: none; }   /* keep just the % on phones */
}

/* Very narrow ≤380px: drop the sparkline column entirely (Galaxy Z
   Flip folded mode) so price/change has breathing room. */
@media (max-width: 380px) {
  .stocks-grid--tiles-header,
  .stocks-grid--tiles .stock-card {
    grid-template-columns: minmax(0, 1fr) 76px minmax(80px, max-content);
  }
  .tile-spark,
  .stocks-grid--tiles-header .col-spark { display: none; }
}

.risk-pill {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.05em;
  padding: 2px 8px;
  border-radius: var(--r-sm);
  background: var(--bg-soft);
  color: var(--text-muted);
  /* Hotfix43f: pin so the pill never gets squeezed off the right edge of
     the card on narrow viewports. The parent uses flex justify-between
     with the price/change column on the left â€” without flex-shrink:0
     here, a wide price+change text was eating all the row width and
     pushing the pill outside the card's padding. */
  flex-shrink: 0;
  white-space: nowrap;
}
.risk-pill.low { background: var(--positive-soft); color: var(--positive); }
.risk-pill.med { background: var(--warning-soft); color: var(--warning); }
.risk-pill.high { background: var(--negative-soft); color: var(--negative); }

/* Hotfix43f companion: constrain the price/change column inside a stock
   card's price-row so it can shrink/clip when content (e.g. 'â‚¹1,63,600
   +5.59% today DELAYED') is too wide for the viewport, instead of
   pushing the risk-pill off-screen. The flex container needs gap +
   min-width:0 on the child so flex-shrink can actually take effect. */
.stock-card > .flex.items-center.justify-between {
  gap: var(--sp-2);
  min-width: 0;
}
.stock-card > .flex.items-center.justify-between > div:first-child {
  min-width: 0;
  overflow: hidden;
}
.stock-card .stock-change {
  /* Long change-line text ('-2.53% today DELAYED 18m old') wraps now
     instead of forcing horizontal overflow. */
  flex-wrap: wrap;
  row-gap: 2px;
}

.data-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 10px;
  color: var(--text-dim);
  padding: 2px 6px;
  border-radius: var(--r-sm);
  background: var(--bg-soft);
}
.data-badge .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--positive); animation: pulse-dot 2s infinite; }
.data-badge .dot.offline { background: var(--text-faint); animation: none; }
.data-badge .dot.closed  { background: var(--text-faint); animation: none; }
.data-badge .dot.preopen { background: var(--warning, #F5A623); animation: pulse-dot 2s infinite; }
.market-status .dot.preopen { background: var(--warning, #F5A623); }
.market-status .dot.closed  { background: var(--text-faint); }

/* Rich hover popover for the NSE market status badge. Uses the same
   subtle card style as the AI term tooltip. Anchored to the parent
   via position:relative on the badge. */
.market-status { position: relative; cursor: help; }
.market-status-pop {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  min-width: 260px;
  max-width: 320px;
  background: var(--surface-elev, var(--surface));
  border: 1px solid var(--border-strong, var(--border));
  border-radius: var(--r);
  padding: 10px 12px;
  font-size: var(--text-sm);
  line-height: 1.45;
  box-shadow: var(--sh-lg, 0 12px 40px rgba(0,0,0,0.35));
  opacity: 0;
  visibility: hidden;
  transform: translateY(-4px);
  transition: opacity 140ms, transform 140ms, visibility 140ms;
  z-index: 100;
  pointer-events: none;
  box-sizing: border-box;
}
/* Mobile / narrow viewports — hover is flaky on touch and absolute-anchored
   popovers clip off-screen. Pin as a bottom sheet with a scrim. Show/hide
   is controlled EXCLUSIVELY by the .ms-open class set by the popover JS;
   :hover / :focus-within effects are neutralised so random focus events
   don't half-show the sheet. */
@media (max-width: 640px) {
  .market-status-pop {
    position: fixed !important;
    top: auto !important;
    bottom: 16px !important;
    left: 16px !important;
    right: 16px !important;
    max-width: none !important;
    min-width: 0 !important;
    width: auto !important;
    z-index: 9999 !important;
    transform: translateY(20px) !important;
    opacity: 0 !important;
    visibility: hidden !important;
    pointer-events: none !important;
  }
  .market-status.ms-open .market-status-pop {
    opacity: 1 !important;
    visibility: visible !important;
    transform: translateY(0) !important;
    pointer-events: auto !important;
  }
  .market-status.ms-open::before {
    content: "";
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.55);
    z-index: 9998;
    animation: cmdk-fade 150ms ease-out;
  }
}
.market-status:hover .market-status-pop,
.market-status:focus-visible .market-status-pop,
.market-status:focus-within .market-status-pop {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
.ms-pop-head { margin-bottom: 8px; display: flex; align-items: center; gap: 6px; }
.ms-pop-label {
  font-size: var(--text-10);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 800;
  color: var(--brand);
  padding: 2px 8px;
  border-radius: var(--r-full);
  background: color-mix(in srgb, var(--brand) 12%, transparent);
}
.ms-pop-dim { color: var(--text-muted); font-size: var(--text-xs); }
.ms-pop-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 3px 0;
  color: var(--text-strong);
}
.ms-pop-key {
  color: var(--text-muted);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 600;
}
.ms-pop-foot {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px dashed var(--divider);
  font-size: var(--text-xs);
  color: var(--text-muted);
  line-height: 1.5;
}

/* ================== ADMIN GOD-MODE PANEL ========================= */
.admin-shell { padding: var(--sp-4) 0; }
.admin-shell-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--sp-3);
  margin-bottom: var(--sp-4);
}
.admin-tabs {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--divider);
  margin-bottom: var(--sp-4);
  overflow-x: auto;
}
.admin-tab {
  background: transparent;
  border: 0;
  padding: 10px 16px;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-muted);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  white-space: nowrap;
  transition: color var(--dur-1), border-color var(--dur-1);
}
.admin-tab:hover { color: var(--text); }
.admin-tab.active { color: var(--brand); border-bottom-color: var(--brand); }

.tail-indicator {
  font-size: var(--text-10);
  font-weight: 800;
  letter-spacing: 0.06em;
  padding: 3px 8px;
  border-radius: var(--r-full);
  background: var(--bg-soft);
  color: var(--text-muted);
}
.tail-indicator.live { background: color-mix(in srgb, var(--positive) 12%, transparent); color: var(--positive); animation: pulse-dot 2s infinite; }

.admin-filter-bar {
  display: flex;
  gap: var(--sp-2);
  flex-wrap: wrap;
  align-items: center;
  padding: var(--sp-3);
}
.admin-filter-bar .select { max-width: 170px; }

.admin-overview-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--sp-3);
}
.admin-row-counts { display: flex; flex-direction: column; gap: 4px; }
.admin-lb { list-style: none; margin: 0; padding: 0; }
.admin-lb li {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 6px 10px;
  border-bottom: 1px solid var(--divider);
  font-size: var(--text-sm);
}
.admin-lb li:last-child { border-bottom: none; }
.admin-lb a { color: var(--text-strong); text-decoration: none; font-weight: 600; }
.admin-lb a:hover { color: var(--brand); }

.admin-drill-nav {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  padding: 10px;
  background: var(--bg-soft);
  border-radius: var(--r);
  margin-bottom: var(--sp-3);
  position: sticky;
  top: 0;
  z-index: 5;
}
.drill-jump {
  font-size: var(--text-10);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 3px 8px;
  background: var(--surface);
  border: 1px solid var(--divider);
  border-radius: var(--r-full);
  color: var(--text-muted);
  text-decoration: none;
  font-weight: 700;
  font-family: inherit;
  cursor: pointer;
}
.drill-jump:hover { background: var(--brand); color: white; border-color: var(--brand); }
.drill-jump:active { transform: translateY(1px); }

.admin-coach-row {
  padding: 8px 12px;
  background: var(--surface);
  border: 1px solid var(--divider);
  border-radius: var(--r);
}
.admin-coach-row summary { cursor: pointer; font-size: var(--text-sm); }
.admin-coach-payload {
  background: var(--bg-soft);
  padding: 10px;
  margin-top: 8px;
  border-radius: 4px;
  font-family: var(--font-mono, monospace);
  font-size: var(--text-xs);
  white-space: pre-wrap;
  word-wrap: break-word;
  max-height: 300px;
  overflow: auto;
}

/* Mini chat UI inside the admin user-detail modal (section 10). Renders
   each user/assistant turn as a bubble so admins can skim conversations
   the way a user would have experienced them. */
.admin-chat-thread {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px;
  margin-top: 8px;
  background: var(--bg-soft);
  border-radius: var(--r);
  max-height: 480px;
  overflow: auto;
}
.admin-chat-bubble {
  padding: 8px 12px;
  border-radius: 12px;
  font-size: var(--text-sm);
  line-height: 1.45;
  max-width: 82%;
  border: 1px solid var(--divider);
}
.admin-chat-bubble.user {
  align-self: flex-end;
  background: rgba(64, 128, 255, 0.12);
  border-color: rgba(64, 128, 255, 0.3);
  border-bottom-right-radius: 4px;
}
.admin-chat-bubble.assistant {
  align-self: flex-start;
  background: var(--surface);
  border-bottom-left-radius: 4px;
}
.admin-chat-role {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  margin-bottom: 3px;
}
.admin-chat-text {
  white-space: pre-wrap;
  word-wrap: break-word;
  color: var(--text);
}
.admin-chat-ts {
  font-size: 10px;
  color: var(--text-muted);
  margin-top: 4px;
  font-family: var(--font-mono, ui-monospace, monospace);
}

.activity-list {
  max-height: 70vh;
  overflow-y: auto;
  padding: 0;
}
.activity-row {
  display: grid;
  grid-template-columns: 28px 90px 1fr 90px;
  gap: 8px;
  align-items: center;
  padding: 8px 12px;
  border-bottom: 1px solid var(--divider);
  font-size: var(--text-sm);
}
.act-icon { font-size: 16px; }
.act-kind { font-size: var(--text-10); text-transform: uppercase; letter-spacing: 0.05em; font-weight: 800; color: var(--text-muted); }
.act-summary { color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.act-ts { font-size: var(--text-xs); text-align: right; }

.positive { color: var(--positive); }
.negative { color: var(--negative); }

.active-btn { background: color-mix(in srgb, var(--brand) 10%, transparent) !important; border-color: var(--brand) !important; color: var(--brand) !important; }

/* Themed select — custom dropdown replacing native <select> for full
   theme control on both closed and open states (native <select> lets
   the browser paint the menu, which breaks dark-mode consistency). */
.themed-select {
  display: inline-flex;
  align-items: center;
  padding: 10px 14px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface);
  color: var(--text);
  font-size: var(--text-md);
  min-height: 44px;
  cursor: pointer;
  user-select: none;
  transition: border-color var(--dur-1), box-shadow var(--dur-1);
  box-shadow: var(--sh-xs);
  box-sizing: border-box;
  gap: 10px;
  min-width: 0;
}
.themed-select:hover { border-color: var(--border-strong); }
.themed-select:focus,
.themed-select[aria-expanded="true"] {
  outline: none;
  border-color: var(--brand);
  box-shadow: var(--sh-focus, 0 0 0 3px color-mix(in srgb, var(--brand) 25%, transparent));
}
.themed-select .ts-trigger {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  width: 100%;
  min-width: 0;
}
.themed-select .ts-label {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text-strong);
}
.themed-select .ts-label.placeholder { color: var(--text-muted); font-style: italic; }
.themed-select .ts-chevron {
  font-size: 11px;
  color: var(--text-muted);
  transition: transform var(--dur-1);
}
.themed-select[aria-expanded="true"] .ts-chevron { transform: rotate(180deg); color: var(--brand); }

/* Menu renders at document root (position: fixed) so it's not clipped
   by parent overflow:hidden. JS positions it under the trigger. */
.ts-menu {
  background: var(--surface-elev, var(--surface));
  border: 1px solid var(--border-strong, var(--border));
  border-radius: var(--r);
  box-shadow: var(--sh-lg, 0 12px 40px rgba(0,0,0,0.35));
  padding: 6px;
  z-index: 9999;
  overflow: auto;
  animation: ts-fade-in 120ms ease-out;
}
@keyframes ts-fade-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: translateY(0); } }
.ts-option {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: var(--r-sm, 4px);
  font-size: var(--text-sm);
  cursor: pointer;
  color: var(--text);
  transition: background var(--dur-1);
}
.ts-option.ts-active,
.ts-option:hover { background: color-mix(in srgb, var(--brand) 14%, transparent); color: var(--text-strong); }
.ts-option.ts-selected { color: var(--brand); font-weight: 600; }
.ts-option-main {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.ts-option-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ts-option-hint { font-size: var(--text-xs); color: var(--text-muted); }
.ts-option.ts-active .ts-option-hint,
.ts-option:hover .ts-option-hint { color: var(--text); }
.ts-check { color: var(--brand); font-weight: 700; }
.ts-divider {
  height: 1px;
  background: var(--divider);
  margin: 6px 2px;
}
.db-sql-warn { background: color-mix(in srgb, var(--warning, #F5A623) 15%, transparent); color: var(--text-strong); padding: 10px 12px; border-radius: var(--r); margin-bottom: var(--sp-3); font-size: var(--text-sm); border-left: 3px solid var(--warning, #F5A623); }
.db-sql-input { font-family: var(--font-mono, monospace); font-size: var(--text-sm); min-height: 150px; }

/* ================== ADMIN PANEL ================================== */
.admin-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--sp-3);
  margin-bottom: var(--sp-4);
}
.admin-day-bars {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 4px;
  margin-top: var(--sp-3);
  height: 72px;
}
.admin-day-bar {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  gap: 4px;
  min-width: 0;
}
.admin-day-bar .bar {
  width: 100%;
  min-height: 2px;
  background: color-mix(in srgb, var(--brand) 45%, transparent);
  border-radius: 2px 2px 0 0;
  transition: background var(--dur-1);
}
.admin-day-bar:hover .bar { background: var(--brand); }
.admin-day-bar .label {
  font-size: 9px;
  color: var(--text-muted);
  font-family: var(--font-mono, monospace);
  letter-spacing: -0.02em;
}
.admin-table-wrap {
  overflow-x: auto;
  margin: var(--sp-3) calc(var(--sp-4) * -1) 0;
  padding: 0 var(--sp-4);
}
.admin-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}
.admin-table th {
  text-align: left;
  padding: 10px 8px;
  font-size: var(--text-10);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  border-bottom: 1px solid var(--divider);
  white-space: nowrap;
}
.admin-table th.sortable { cursor: pointer; user-select: none; }
.admin-table th.sortable:hover { color: var(--text-strong); }
.admin-table td {
  padding: 10px 8px;
  border-bottom: 1px solid var(--divider);
  vertical-align: top;
}
.admin-table tbody tr { cursor: pointer; transition: background var(--dur-1); }
.admin-table tbody tr:hover { background: var(--bg-soft); }
.admin-user-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-4);
}
@media (max-width: 640px) { .admin-user-grid { grid-template-columns: 1fr; } }
.admin-user-section-label {
  font-size: var(--text-10);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
  font-weight: 800;
  margin-bottom: var(--sp-2);
}
.admin-kv {
  display: flex;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: 4px 0;
  font-size: var(--text-sm);
}
.admin-kv > span:first-child { color: var(--text-muted); }
.admin-kv > span:last-child { color: var(--text-strong); font-weight: 500; text-align: right; }

/* Stock-card CLOSED/PRE-OPEN pill: use the same rich hover card as the
   nav + stock-detail. Because the pill is tiny and lives inside a
   layout-constrained card, anchor the popover to the pill itself and
   make it zoom toward the card edges on narrow widths. */
.stock-card-ms-pill { cursor: help; }
.stock-card-ms-pill .market-status-pop {
  top: calc(100% + 6px);
  right: auto;
  left: 0;
  min-width: 240px;
}
@media (max-width: 520px) {
  .stock-card-ms-pill .market-status-pop { left: auto; right: 0; }
}

/* ============================== STOCK DETAIL ======================== */
.stock-detail-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--sp-5);
}
@media (min-width: 960px) {
  .stock-detail-grid { grid-template-columns: 1.55fr 1fr; align-items: start; }
}
/* On phones, trade box jumps above the chart so it's immediately reachable */
@media (max-width: 640px) {
  .stock-detail-grid { gap: var(--sp-4); }
  .price-block { flex-direction: column; align-items: flex-start; gap: var(--sp-2); }
  .price-block .price { font-size: clamp(1.8rem, 9vw, 2.4rem); }
  /* Let the TF strip + reset-zoom pill + chart-mode toggle wrap onto
     multiple rows instead of forcing a horizontal scroll strip — at
     280-360 px, margin-left:auto on .chart-mode-toggle collapses in
     a nowrap context and Candle/Line crashed straight into the reset
     pill. `flex-wrap: wrap` + explicit flex-basis lets each piece
     size itself naturally. */
  .tf-buttons {
    width: 100%;
    overflow-x: visible;
    justify-content: flex-start;
    flex-wrap: wrap;
    gap: 6px;
    row-gap: 8px;
  }
  .tf-buttons > div:first-child { flex: 1 1 auto; }
  .tf-buttons #zoom-reset-btn { flex: 0 0 auto; }
  .tf-buttons .chart-mode-toggle {
    margin-left: 0;
    flex: 0 0 auto;
  }
  /* Touch-target compliance on mobile. Apple's spec is 44 px min;
     Google's is 48 px. We compromise at 36 px on the inline TF strip
     to avoid bloating it, and push interactive pills closer to 44 px
     where they have more room. */
  .tf-btn {
    min-height: 36px;
    padding: 10px 14px;
  }
  .chart-mode-btn {
    padding: 8px 12px !important;
    min-height: 36px !important;
  }
  #price-refresh-btn {
    min-height: 36px !important;
    padding: 6px 10px !important;
  }
  /* Portfolio pending-orders list — each order row has pill + symbol +
     metadata on the left and a Cancel button on the right. Without a
     min-width / flex-basis guard, on 280-360 px the metadata wraps to
     multiple lines and pushes Cancel under the content or off-screen.
     flex-wrap + 44 px touch target ensures Cancel is always tappable. */
  #order-list > div {
    flex-wrap: wrap;
    gap: 8px;
  }
  #order-list [data-cancel-order] {
    flex: 0 0 auto;
    min-width: 80px;
    min-height: 44px;
  }
}

.price-block {
  display: flex;
  align-items: baseline;
  gap: var(--sp-4);
  flex-wrap: wrap;
}
.price-block .price {
  font-family: var(--font-mono);
  font-size: clamp(2.2rem, 5vw, 2.85rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1;
  color: var(--text-strong);
}
.price-block .change {
  font-family: var(--font-mono);
  font-size: var(--text-lg);
  font-weight: 600;
}
.tf-buttons {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
  margin: var(--sp-4) 0;
  padding: 4px;
  background: var(--bg-soft);
  border-radius: var(--r);
  width: fit-content;
}
.tf-btn {
  padding: 6px 14px;
  background: transparent;
  color: var(--text-muted);
  font-size: var(--text-sm);
  font-weight: 600;
  border-radius: var(--r-sm);
  transition: all var(--dur-1);
}
.tf-btn.active {
  background: var(--surface);
  color: var(--text-strong);
  box-shadow: var(--sh-xs);
}
.tf-btn:hover:not(.active) {
  color: var(--text-strong);
}

.trade-box {
  position: sticky;
  top: calc(var(--nav-h) + var(--sp-4));
}
@media (max-width: 960px) {
  .trade-box { position: static; }
}
.trade-tabs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  margin-bottom: var(--sp-4);
  background: var(--bg-soft);
  padding: 4px;
  border-radius: var(--r);
}
.trade-tab {
  padding: 10px;
  text-align: center;
  font-weight: 700;
  font-size: var(--text-md);
  border-radius: var(--r-sm);
  color: var(--text-muted);
  transition: all var(--dur-1);
}
.trade-tab.active.buy {
  background: var(--positive);
  color: white;
  box-shadow: var(--sh-xs);
}
.trade-tab.active.sell {
  background: var(--negative);
  color: white;
  box-shadow: var(--sh-xs);
}

.qty-stepper {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}
.qty-stepper button {
  width: 40px; height: 44px;
  border: 1px solid var(--border);
  background: var(--surface);
  border-radius: var(--r-md);
  font-size: var(--text-lg);
  font-weight: 700;
  color: var(--text);
  transition: background var(--dur-1);
}
.qty-stepper button:hover { background: var(--bg-soft); border-color: var(--border-strong); }
.qty-stepper .input { text-align: center; font-family: var(--font-mono); font-weight: 700; }

.qty-quick-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--sp-2);
  margin-top: var(--sp-3);
}
.qty-quick {
  padding: 7px;
  background: var(--bg-soft);
  border: 1px solid var(--border);
  color: var(--text-muted);
  font-size: var(--text-xs);
  font-weight: 700;
  border-radius: var(--r-sm);
  transition: all var(--dur-1);
}
.qty-quick:hover { color: var(--text-strong); border-color: var(--border-strong); }
.qty-quick.active { background: var(--brand-soft); color: var(--brand); border-color: var(--brand); }

.qty-slider-wrap {
  margin: var(--sp-3) 0;
}
.qty-slider {
  -webkit-appearance: none;
  width: 100%;
  height: 4px;
  border-radius: 4px;
  background: var(--bg-soft);
  cursor: pointer;
  outline: none;
}
.qty-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 18px; height: 18px;
  border-radius: 50%;
  background: var(--brand);
  border: 2px solid var(--surface);
  box-shadow: var(--sh-sm);
  cursor: grab;
}
.qty-slider::-moz-range-thumb {
  width: 18px; height: 18px;
  border-radius: 50%;
  background: var(--brand);
  border: 2px solid var(--surface);
  box-shadow: var(--sh-sm);
  cursor: grab;
}

.order-summary {
  background: var(--bg-soft);
  padding: var(--sp-4);
  border-radius: var(--r);
  margin: var(--sp-4) 0;
  font-size: var(--text-md);
}
.order-summary .row {
  display: flex;
  justify-content: space-between;
  padding: 3px 0;
  color: var(--text-muted);
}
.order-summary .row.total {
  border-top: 1px solid var(--border);
  margin-top: var(--sp-2);
  padding-top: var(--sp-3);
  font-weight: 700;
  font-size: var(--text-base);
  color: var(--text-strong);
}
.order-summary .num { font-family: var(--font-mono); color: var(--text-strong); font-weight: 600; }

.fundamentals {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--sp-3);
}
.fundamentals .item {
  padding: var(--sp-3);
  background: var(--bg-soft);
  border-radius: var(--r);
}
.fundamentals .l {
  font-size: var(--text-10);
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 3px;
}
.fundamentals .v {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: var(--text-md);
  color: var(--text-strong);
}

/* ============================== CRASH REPLAY ======================== */
.crash-hero {
  text-align: center;
  padding: var(--sp-5) 0 var(--sp-6);
}
.crash-hero h1 {
  font-size: clamp(1.9rem, 4.5vw, 3rem);
  letter-spacing: -0.035em;
  margin-bottom: var(--sp-3);
}
.crash-scenarios {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--sp-4);
  margin-bottom: var(--sp-6);
}
.crash-scenario {
  padding: var(--sp-5);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  cursor: pointer;
  transition: all var(--dur-2) var(--ease);
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  font-family: inherit;
}
.crash-scenario:hover {
  border-color: var(--brand);
  transform: translateY(-3px);
  box-shadow: var(--sh-sm);
}
.crash-scenario h4 { font-size: var(--text-lg); color: var(--text-strong); }
.crash-scenario .desc { font-size: var(--text-md); color: var(--text-muted); line-height: 1.55; }
.crash-scenario .meta { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--text-dim); margin-top: auto; }

.replay-panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  padding: var(--sp-6);
  position: relative;
  overflow: hidden;
  box-shadow: var(--sh-xs);
}

.replay-stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-4);
  margin-bottom: var(--sp-5);
}
@media (max-width: 640px) {
  .replay-stats { grid-template-columns: 1fr; gap: var(--sp-3); }
  .replay-stat { padding: var(--sp-4); }
  .replay-panel { padding: var(--sp-4); }
  .replay-slider-wrap { padding: var(--sp-3) var(--sp-4); }
  .replay-controls .btn-sm { flex: 1 0 auto; }
}
.replay-stat {
  padding: var(--sp-5);
  border-radius: var(--r-lg);
  border: 1.5px solid var(--border);
  background: var(--surface);
  transition: border-color var(--dur-2) var(--ease);
}
.replay-stat.held { border-color: var(--positive); background: linear-gradient(180deg, var(--positive-soft), transparent 60%); }
.replay-stat.panic { border-color: var(--negative); background: linear-gradient(180deg, var(--negative-soft), transparent 60%); }
.replay-stat .header { display: flex; justify-content: space-between; margin-bottom: var(--sp-3); font-size: var(--text-sm); color: var(--text-muted); font-weight: 600; }
.replay-stat .big { font-family: var(--font-mono); font-size: clamp(1.6rem, 4vw, 2.35rem); font-weight: 700; letter-spacing: -0.03em; line-height: 1; color: var(--text-strong); }
.replay-stat .delta { font-family: var(--font-mono); font-size: var(--text-md); margin-top: var(--sp-2); font-weight: 700; }
.replay-stat.held .delta { color: var(--positive); }
.replay-stat.panic .delta { color: var(--negative); }
.replay-stat.held .header > span:first-child { color: var(--positive); }
.replay-stat.panic .header > span:first-child { color: var(--negative); }

.replay-slider-wrap {
  background: var(--bg-soft);
  padding: var(--sp-4) var(--sp-6);
  border-radius: var(--r-lg);
  margin: var(--sp-5) 0;
}
.replay-slider-meta {
  display: flex;
  justify-content: space-between;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin-bottom: var(--sp-2);
}
.replay-slider {
  -webkit-appearance: none;
  width: 100%;
  height: 6px;
  border-radius: 3px;
  background: linear-gradient(90deg, var(--positive) 0%, var(--warning) 50%, var(--negative) 100%);
  outline: none;
  cursor: pointer;
}
.replay-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 22px; height: 22px;
  border-radius: 50%;
  background: white;
  border: 3px solid var(--brand);
  box-shadow: var(--sh-md);
  cursor: grab;
}
.replay-slider::-moz-range-thumb {
  width: 22px; height: 22px;
  border-radius: 50%;
  background: white;
  border: 3px solid var(--brand);
  cursor: grab;
}

.replay-controls {
  display: flex;
  gap: var(--sp-2);
  justify-content: center;
  margin: var(--sp-4) 0;
  flex-wrap: wrap;
}

/* Sticky top-of-page bar: back link + inline title + playback controls.
   Keeps the play / slow / reset / bottom / end buttons above the fold
   on every resolution so users can start the replay without scrolling. */
.replay-topbar {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex-wrap: wrap;
  padding: var(--sp-3) 0;
  margin-bottom: var(--sp-3);
  position: sticky;
  top: 60px;
  z-index: 40;
  background: var(--bg);
  border-bottom: 1px solid var(--divider);
}
.replay-title-inline {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex-wrap: wrap;
  flex: 1 1 auto;
  min-width: 0;
}
.replay-title-inline strong {
  font-size: var(--text-lg);
  color: var(--text-strong);
}
.replay-controls-top {
  margin: 0;
  justify-content: flex-end;
}
.replay-context-details {
  margin-top: var(--sp-5);
  padding: var(--sp-3) var(--sp-4);
  background: var(--bg-soft);
  border: 1px solid var(--divider);
  border-radius: var(--r);
}
.replay-context-details summary {
  cursor: pointer;
  font-size: var(--text-md);
  font-weight: 700;
  color: var(--text-strong);
  user-select: none;
  list-style-position: outside;
}
.replay-context-body { margin-top: var(--sp-3); }

/* =============================================================================
 * GENERATING STAGE v2 — INLINE overlay inside the selector input card.
 * Selector page hero + featured cards stay visible; the input card itself
 * morphs into a live console showing the 4-stage flow + tape ticker +
 * mini-sparkline that builds with real Phase B prices. NOT a full takeover.
 * ============================================================================= */
.generating-stage.gen-inline {
  padding: var(--sp-2) 0 0 0;
  background: transparent;
  border: none;
  margin: 0;
  max-width: none;
  animation: gen-inline-in 280ms cubic-bezier(0.22, 1, 0.36, 1) both;
}
@keyframes gen-inline-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.gen-inline .gen-header {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: var(--sp-3);
  font-size: var(--text-base);
}
.gen-pulse {
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--brand);
  position: relative;
  animation: gen-pulse-glow 1.4s ease-in-out infinite;
}
.gen-pulse::after {
  content: ""; position: absolute; inset: -6px;
  border-radius: 50%;
  border: 2px solid var(--brand);
  animation: gen-pulse-ring 1.4s ease-out infinite;
}
@keyframes gen-pulse-glow { 0%,100% { opacity: 0.6; } 50% { opacity: 1; } }
@keyframes gen-pulse-ring { 0% { transform: scale(0.6); opacity: 1; } 100% { transform: scale(1.6); opacity: 0; } }
.gen-inline .gen-query {
  color: var(--brand);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.95em;
}

/* Stage flow — dots connected by lines, glowing as they complete */
.gen-flow {
  display: flex; align-items: center;
  margin: var(--sp-3) 0;
  padding: var(--sp-2) 0;
  gap: 0;
}
.gen-flow-node {
  display: flex; flex-direction: column; align-items: center;
  text-align: center;
  flex: 0 0 auto;
  min-width: 90px;
  position: relative;
}
.gen-flow-dot {
  width: 18px; height: 18px;
  border-radius: 50%;
  border: 2px solid var(--text-faint);
  background: var(--surface);
  margin-bottom: 6px;
  transition: all 280ms ease;
  position: relative;
}
.gen-flow-node[data-state="active"] .gen-flow-dot {
  border-color: var(--brand);
  background: var(--brand);
  box-shadow: 0 0 0 4px rgba(34,197,94,0.18), 0 0 12px rgba(34,197,94,0.5);
  animation: gen-dot-pulse 1.2s ease-in-out infinite;
}
.gen-flow-node[data-state="done"] .gen-flow-dot {
  border-color: var(--positive);
  background: var(--positive);
}
.gen-flow-node[data-state="done"] .gen-flow-dot::after {
  content: "✓"; color: white; font-size: 11px; font-weight: bold;
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
}
.gen-flow-node[data-state="error"] .gen-flow-dot {
  border-color: var(--negative);
  background: var(--negative);
}
.gen-flow-node[data-state="error"] .gen-flow-dot::after {
  content: "!"; color: white; font-size: 11px; font-weight: bold;
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
}
@keyframes gen-dot-pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.18); }
}
.gen-flow-label {
  font-size: var(--text-xs);
  color: var(--muted);
  font-weight: 500;
  transition: color 200ms ease;
}
.gen-flow-node[data-state="active"] .gen-flow-label { color: var(--text); font-weight: 600; }
.gen-flow-node[data-state="done"]   .gen-flow-label { color: var(--positive); }
.gen-flow-node[data-state="error"]  .gen-flow-label { color: var(--negative); }
.gen-flow-detail {
  font-size: 10px;
  color: var(--muted);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-variant-numeric: tabular-nums;
  margin-top: 2px;
  min-height: 12px;
}
.gen-flow-link {
  flex: 1 1 auto;
  height: 2px;
  background: var(--text-faint);
  margin-top: -16px; /* center on the dots vertically */
  position: relative;
  overflow: hidden;
}
.gen-flow-link::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(to right, var(--positive), var(--brand));
  transform-origin: left center;
  transform: scaleX(0);
  transition: transform 380ms cubic-bezier(0.22, 1, 0.36, 1);
}
.gen-flow-link.gen-link-done::after { transform: scaleX(1); }

/* Body: live feed (left) + sparkline (right) side-by-side */
.gen-inline .gen-body {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-3);
  margin-top: var(--sp-3);
}
.gen-feed-col, .gen-spark-col { min-width: 0; }
.gen-feed-label {
  font-size: 10px;
  letter-spacing: 0.08em;
  color: var(--text-faint);
  margin-bottom: 6px;
  font-weight: 600;
}
.gen-inline .gen-feed {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 8px 12px;
  height: 100px;
  overflow: hidden;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--text-xs);
}
.gen-inline .gen-feed-empty {
  color: var(--muted);
  font-size: var(--text-xs);
}
.gen-inline .gen-spark {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 16px 12px;
  height: 100px;
  display: flex; align-items: center;
}
.gen-inline .gen-spark svg { width: 100%; height: 60px; }

@media (max-width: 720px) {
  .gen-inline .gen-body { grid-template-columns: 1fr; }
  .gen-flow-node { min-width: 70px; }
  .gen-flow-label { font-size: 10px; }
}
@media (prefers-reduced-motion: reduce) {
  .gen-pulse, .gen-pulse::after, .gen-flow-node[data-state="active"] .gen-flow-dot { animation: none; }
}

/* ================ legacy full-takeover fallback (used if input card missing) === */
.generating-stage {
  max-width: 720px;
  margin: var(--sp-6) auto;
  padding: var(--sp-6);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  font-size: var(--text-base);
}
.generating-stage h2 {
  margin: 0 0 var(--sp-2) 0;
  font-size: var(--text-xl);
  display: flex; align-items: center; gap: 8px;
}
.generating-stage .gen-query {
  color: var(--brand);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.95em;
}
.generating-stage .gen-sub {
  color: var(--muted);
  font-size: var(--text-sm);
  margin: 0 0 var(--sp-4) 0;
}
.generating-stage .gen-stages {
  display: flex; flex-direction: column;
  gap: var(--sp-2);
  margin-bottom: var(--sp-4);
}
.gen-stage-row {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 0;
  color: var(--muted);
  transition: color 200ms ease, transform 200ms ease;
}
.gen-stage-row[data-state="active"]   { color: var(--text); }
.gen-stage-row[data-state="done"]     { color: var(--positive); }
.gen-stage-row[data-state="error"]    { color: var(--negative); }
.gen-stage-icon {
  width: 22px; height: 22px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%;
  border: 1.5px solid var(--text-faint);
  font-size: 13px;
  flex-shrink: 0;
}
.gen-stage-row[data-state="active"] .gen-stage-icon {
  border-color: var(--brand);
  background: var(--brand);
  color: white;
  animation: gen-spin 1.2s linear infinite;
}
.gen-stage-row[data-state="done"] .gen-stage-icon {
  border-color: var(--positive);
  background: var(--positive);
  color: white;
}
.gen-stage-row[data-state="error"] .gen-stage-icon {
  border-color: var(--negative);
  background: var(--negative);
  color: white;
}
.gen-stage-detail {
  margin-left: auto;
  font-size: var(--text-xs);
  color: var(--muted);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-variant-numeric: tabular-nums;
}
.generating-stage .gen-feed {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 10px 14px;
  height: 180px;
  overflow: hidden;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--text-xs);
  position: relative;
}
.gen-feed-row {
  display: flex; gap: 12px;
  white-space: nowrap;
  line-height: 1.7;
  opacity: 0;
  animation: gen-feed-row-in 240ms ease-out forwards;
}
.gen-feed-row .day  { color: var(--muted); width: 56px; }
.gen-feed-row .date { color: var(--text-muted); width: 96px; }
.gen-feed-row .px   { color: var(--text); }
.gen-feed-row .delta-up   { color: var(--positive); margin-left: auto; }
.gen-feed-row .delta-down { color: var(--negative); margin-left: auto; }
.gen-feed-narrative {
  white-space: pre-wrap;
  line-height: 1.6;
  color: var(--text-muted);
  word-wrap: break-word;
}
.gen-feed-narrative::after {
  content: "▋";
  margin-left: 2px;
  color: var(--brand);
  animation: ss-caret-blink 0.8s step-end infinite;
}
.generating-stage .gen-progress {
  margin-top: var(--sp-3);
  height: 4px;
  background: var(--border);
  border-radius: 2px;
  overflow: hidden;
}
.generating-stage .gen-progress-bar {
  height: 100%;
  background: linear-gradient(to right, var(--brand), var(--positive));
  width: 0%;
  transition: width 280ms cubic-bezier(0.22, 1, 0.36, 1);
}
@keyframes gen-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}
@keyframes gen-feed-row-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}
.generating-stage.gen-fading-out {
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity 80ms ease, transform 80ms ease;
}
@media (prefers-reduced-motion: reduce) {
  .gen-stage-row[data-state="active"] .gen-stage-icon { animation: none; }
  .gen-feed-row { animation: none; opacity: 1; transform: none; }
}

/* =============================================================================
 * REPLAY INTRO ANIMATION — typewriter + stagger reveal
 * ============================================================================= */
@keyframes ss-fade-slide-up {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes ss-fade-only {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes ss-caret-blink {
  0%, 49%   { opacity: 1; }
  50%, 100% { opacity: 0; }
}
.ss-anim-hidden        { opacity: 0 !important; }
.ss-anim-fade          { animation: ss-fade-only 320ms ease-out forwards; }
.ss-anim-slide-up      { animation: ss-fade-slide-up 380ms cubic-bezier(.2,.8,.2,1) both; }
.ss-typewriter-caret::after {
  content: "▋";
  margin-left: 2px;
  color: var(--brand);
  animation: ss-caret-blink 0.8s step-end infinite;
  font-weight: 100;
}
@media (prefers-reduced-motion: reduce) {
  .ss-anim-fade, .ss-anim-slide-up { animation: none; }
  .ss-anim-hidden { opacity: 1 !important; }
}
.replay-streaming-pulse {
  display: flex;
  align-items: center;
  margin: 0 0 var(--sp-3) 0;
  padding: var(--sp-3);
  background: var(--surface);
  border-radius: var(--radius-md);
  border: 1px dashed var(--border);
}
.replay-streaming-pulse .dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--brand);
  margin-right: 4px;
  animation: ss-pulse 1.4s infinite ease-in-out both;
}
.replay-streaming-pulse .dot:nth-child(1) { animation-delay: -0.32s; }
.replay-streaming-pulse .dot:nth-child(2) { animation-delay: -0.16s; }
@keyframes ss-pulse {
  0%, 80%, 100% { transform: scale(0.6); opacity: 0.5; }
  40%           { transform: scale(1.0); opacity: 1.0; }
}
.replay-context-para {
  font-size: var(--text-base);
  line-height: 1.7;
  color: var(--text);
  margin: 0 0 var(--sp-3) 0;
}
.replay-context-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: var(--sp-3);
  padding: var(--sp-3);
  background: var(--surface);
  border: 1px solid var(--divider);
  border-radius: var(--r);
  margin: var(--sp-3) 0;
}
.replay-context-stats > div { display: flex; flex-direction: column; gap: 2px; }
.rc-key { font-size: var(--text-10); text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-muted); font-weight: 700; }
.rc-val { font-size: var(--text-md); font-weight: 600; color: var(--text-strong); }
.rc-val.positive { color: var(--positive); }
.rc-val.negative { color: var(--negative); }
.replay-timeline {
  margin-top: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface);
  border: 1px solid var(--divider);
  border-radius: var(--r);
}
.replay-timeline-head {
  font-size: var(--text-10);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
  font-weight: 800;
  margin-bottom: var(--sp-3);
}
.replay-timeline-row {
  display: grid;
  grid-template-columns: 120px 1fr;
  gap: var(--sp-3);
  padding: var(--sp-2) 0;
  border-top: 1px dashed var(--divider);
  line-height: 1.5;
}
.replay-timeline-row:first-of-type { border-top: none; }
.replay-timeline-day { font-size: var(--text-sm); font-weight: 700; color: var(--text-strong); }
.replay-timeline-body { font-size: var(--text-sm); color: var(--text); }
.replay-timeline .positive { color: var(--positive); }
.replay-timeline .negative { color: var(--negative); }
@media (max-width: 620px) {
  .replay-timeline-row { grid-template-columns: 1fr; }
}
@media (max-width: 680px) {
  .replay-topbar { top: 56px; flex-direction: column; align-items: stretch; }
  .replay-controls-top { justify-content: center; }
  .replay-controls-top .btn-sm { flex: 1 0 auto; }
  .replay-title-inline strong { font-size: var(--text-md); }
}
.replay-narration {
  background: var(--bg-soft);
  border-left: 3px solid var(--brand);
  padding: var(--sp-4) var(--sp-5);
  border-radius: var(--r);
  font-size: var(--text-md);
  line-height: 1.6;
  color: var(--text);
  min-height: 80px;
  transition: opacity 0.25s;
}
.replay-narration.fading { opacity: 0; }

.replay-final-banner {
  background: linear-gradient(135deg, var(--brand), var(--brand-dark));
  color: white;
  padding: var(--sp-5);
  border-radius: var(--r-lg);
  text-align: center;
  margin-top: var(--sp-4);
  font-weight: 600;
  font-size: var(--text-lg);
  animation: slideUp 400ms var(--ease);
  box-shadow: var(--sh-md);
}
.replay-final-banner .num {
  font-family: var(--font-mono);
  font-size: var(--text-3xl);
  font-weight: 700;
  display: block;
  margin-top: var(--sp-1);
  letter-spacing: -0.02em;
}

/* Generic segmented-tab pill row. Originally written for the leaderboard
   (hence the .lb- prefix), now reused by friends.js, news.js, and the
   trade-form Market/Limit picker on stockDetail.js. Keep the class names
   even though the leaderboard page is gone — renaming would break three
   pages for no benefit. */
.lb-tabs {
  display: flex;
  gap: 2px;
  padding: 4px;
  background: var(--bg-soft);
  border-radius: var(--r);
  width: fit-content;
}
.lb-tab {
  padding: 7px 14px;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-muted);
  border-radius: var(--r-sm);
  transition: all var(--dur-1);
}
.lb-tab.active {
  background: var(--surface);
  color: var(--text-strong);
  box-shadow: var(--sh-xs);
}

/* Chat session picker menu — dropdown that lists past conversations. */
.chat-session-menu {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  min-width: 280px;
  max-width: 360px;
  max-height: 60vh;
  overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--divider);
  border-radius: var(--r);
  padding: 4px;
  box-shadow: var(--sh-lg);
  z-index: 30;
}
.chat-session-menu[hidden] { display: none !important; }
.chat-session-row {
  display: flex;
  gap: 2px;
  align-items: stretch;
  border-radius: 6px;
  margin-bottom: 2px;
}
.chat-session-row:last-child { margin-bottom: 0; }
.chat-session-row:hover { background: var(--bg-soft); }
.chat-session-row.active { background: var(--brand-soft); }
.chat-session-row-main {
  flex: 1;
  background: transparent;
  border: none;
  padding: 8px 10px;
  text-align: left;
  cursor: pointer;
  color: var(--text);
  font-family: inherit;
  border-radius: 4px;
  overflow: hidden;
  min-width: 0;
}
.chat-session-row-title {
  font-size: var(--text-sm);
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.chat-session-row-meta {
  font-size: 11px;
  color: var(--text-muted);
  margin-top: 2px;
}
.chat-session-row-del {
  flex-shrink: 0;
  width: 32px;
  height: auto;
  align-self: stretch;
  border-radius: 4px;
  background: transparent;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  font-size: 18px;
  line-height: 1;
  font-family: inherit;
  padding: 0;
}
.chat-session-row-del:hover {
  background: var(--negative-soft);
  color: var(--negative);
}
@media (max-width: 520px) {
  /* Full-width dropdown on small phones so long session titles don't get cut off */
  .chat-session-menu { left: 0; right: 0; min-width: 0; max-width: none; }
}

/* ============================== REPORT CARD ========================= */
.report-grade {
  display: flex;
  align-items: center;
  gap: var(--sp-6);
  padding: var(--sp-6);
  background: linear-gradient(135deg, var(--brand-soft), transparent);
  border: 1px solid var(--brand);
  border-radius: var(--r-xl);
  margin-bottom: var(--sp-5);
}
@media (max-width: 640px) { .report-grade { flex-direction: column; text-align: center; } }
.report-grade-circle {
  width: 110px; height: 110px;
  border-radius: 50%;
  background: conic-gradient(var(--brand) calc(var(--pct, 70) * 1%), var(--bg-soft) 0);
  display: grid; place-items: center;
  flex-shrink: 0;
  position: relative;
}
.report-grade-circle::before {
  content: "";
  position: absolute;
  inset: 7px;
  background: var(--surface);
  border-radius: 50%;
}
.report-grade-circle .letter {
  position: relative;
  font-size: var(--text-4xl);
  font-weight: 700;
  color: var(--text-strong);
  letter-spacing: -0.05em;
}

.behavior-list { display: flex; flex-direction: column; gap: var(--sp-2); }
.behavior-row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: var(--sp-4);
  align-items: center;
  padding: var(--sp-3) var(--sp-4);
  background: var(--bg-soft);
  border-radius: var(--r);
}
.behavior-row .icon {
  width: 36px; height: 36px;
  border-radius: 50%;
  display: grid; place-items: center;
  font-size: var(--text-md);
  font-weight: 700;
}
.behavior-row .icon.good { background: var(--positive-soft); color: var(--positive); }
.behavior-row .icon.warn { background: var(--warning-soft); color: var(--warning); }
.behavior-row .icon.bad { background: var(--negative-soft); color: var(--negative); }
.behavior-row .name { font-weight: 600; font-size: var(--text-md); color: var(--text-strong); }
.behavior-row .desc { font-size: var(--text-xs); color: var(--text-muted); margin-top: 2px; }
.behavior-row .count { font-family: var(--font-mono); font-size: var(--text-xl); font-weight: 700; }

.badges-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: var(--sp-3);
}
.badge-card {
  padding: var(--sp-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r);
  text-align: center;
  transition: all var(--dur-2) var(--ease);
}
.badge-card.earned {
  border-color: var(--brand);
  background: linear-gradient(180deg, var(--brand-soft), var(--surface));
}
.badge-card .emoji { font-size: 30px; }
.badge-card .title { font-weight: 600; font-size: var(--text-sm); margin-top: var(--sp-1); color: var(--text-strong); }
.badge-card .desc { font-size: var(--text-xs); color: var(--text-muted); margin-top: 2px; line-height: 1.45; }
.badge-card.locked { opacity: 0.35; filter: grayscale(1); }

/* ============================== ONBOARDING ========================== */
.onboard-wrap {
  max-width: 480px;
  margin: var(--sp-10) auto;
  padding: 0 var(--sp-4);
}
.onboard-steps {
  display: flex;
  justify-content: space-between;
  margin-bottom: var(--sp-5);
  position: relative;
}
.onboard-steps::before {
  content: "";
  position: absolute;
  top: 15px;
  left: 18px;
  right: 18px;
  height: 2px;
  background: var(--border);
}
.onboard-step {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-2);
  background: var(--bg);
  padding: 0 var(--sp-2);
}
.onboard-step .dot {
  width: 32px; height: 32px;
  border-radius: 50%;
  background: var(--surface);
  color: var(--text-muted);
  display: grid; place-items: center;
  font-weight: 700;
  font-size: var(--text-sm);
  border: 2px solid var(--border);
  transition: all var(--dur-2) var(--ease);
}
.onboard-step.active .dot {
  background: var(--brand);
  color: white;
  border-color: var(--brand);
  transform: scale(1.08);
}
.onboard-step.done .dot {
  background: var(--positive);
  color: white;
  border-color: var(--positive);
}
.onboard-step .label {
  font-size: var(--text-11);
  color: var(--text-dim);
  text-align: center;
  font-weight: 500;
}
.onboard-step.active .label { color: var(--text-strong); font-weight: 600; }

/* FIXED: Risk quiz options no longer stretch full-width awkwardly; they are
   compact rows with tight padding, left-aligned radio + body, consistent */
.quiz-list {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  margin: var(--sp-4) 0;
}
.quiz-option {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border: 1.5px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface);
  cursor: pointer;
  transition: all var(--dur-1);
  position: relative;
}
.quiz-option:hover {
  border-color: var(--border-strong);
  background: var(--bg-soft);
}
.quiz-option.selected {
  border-color: var(--brand);
  background: var(--brand-soft);
}
.quiz-option input[type="radio"] {
  margin-top: 3px;
  accent-color: var(--brand);
  flex-shrink: 0;
  cursor: pointer;
}
.quiz-option .body { flex: 1; min-width: 0; }
.quiz-option .main { font-weight: 600; color: var(--text-strong); font-size: var(--text-md); line-height: 1.3; }
.quiz-option .desc { font-size: var(--text-sm); color: var(--text-muted); margin-top: 3px; line-height: 1.45; }

/* ============================== RISK CARDS (onboarding) ============ */
.risk-cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-3);
  margin: var(--sp-4) 0;
}
@media (max-width: 600px) {
  .risk-cards { grid-template-columns: 1fr; gap: var(--sp-2); }
  .risk-card { flex-direction: row; text-align: left; padding: var(--sp-3) var(--sp-4); align-items: center; gap: var(--sp-3); }
  .risk-card .risk-icon { font-size: 22px; }
}
.risk-card {
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: var(--r-md);
  padding: var(--sp-4) var(--sp-3);
  text-align: center;
  cursor: pointer;
  transition: all var(--dur-1) var(--ease);
  font-family: inherit;
  display: flex;
  flex-direction: column;
  gap: 6px;
  align-items: center;
}
.risk-card:hover {
  border-color: var(--border-strong);
  background: var(--bg-soft);
  transform: translateY(-2px);
}
.risk-card.selected {
  border-color: var(--brand);
  background: var(--brand-soft);
  box-shadow: var(--sh-xs);
}
.risk-icon { font-size: 26px; line-height: 1; }
.risk-title { font-weight: 700; color: var(--text-strong); font-size: var(--text-md); }
.risk-desc { font-size: var(--text-xs); color: var(--text-muted); line-height: 1.45; }

/* ============================== COACH CHAT (panel) ================= */
.coach-chat-input {
  display: flex;
  gap: 6px;
  padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--divider);
  background: var(--surface);
}
.coach-chat-input input {
  flex: 1;
  border: 1px solid var(--border);
  border-radius: var(--r);
  padding: 8px 12px;
  font-size: var(--text-sm);
  outline: none;
  background: var(--bg-soft);
}
.coach-chat-input input:focus {
  border-color: var(--brand);
  background: var(--surface);
}
.coach-chat-input button {
  background: var(--brand);
  color: white;
  border: none;
  padding: 8px 14px;
  border-radius: var(--r);
  font-weight: 600;
  font-size: var(--text-sm);
  cursor: pointer;
}
.coach-chat-input button:hover { background: var(--brand-dark); }
.coach-chat-input button:disabled { opacity: 0.5; cursor: not-allowed; }
.coach-user-msg {
  align-self: flex-end;
  width: fit-content;
  max-width: 82%;
  background: var(--brand);
  color: white;
  /* Match the chat-page user-bubble — was 8px/12px + line-height 1.5
     which made the pill look button-chunky for short messages like
     "HELLO". Now hugs the text the same way /chat does. */
  padding: 3px 8px;
  border-radius: 10px 10px 2px 10px;
  font-size: var(--text-sm);
  line-height: 1.35;
  white-space: pre-wrap;
  word-wrap: break-word;
  box-shadow: var(--sh-xs);
  animation: slideUp 280ms var(--ease);
}

/* ============================== CRASH CALLOUTS ===================== */
.replay-callout {
  background: linear-gradient(135deg, var(--saffron-soft), transparent);
  border: 1px solid var(--saffron);
  border-radius: var(--r);
  padding: 10px 14px;
  margin-top: var(--sp-3);
  font-size: var(--text-sm);
  line-height: 1.55;
  color: var(--text);
  animation: slideUp 320ms var(--ease);
}
.replay-callout strong { color: var(--saffron); }

.replay-markers {
  position: relative;
  height: 22px;
  margin: 4px 0 -6px;
}
.replay-marker {
  position: absolute;
  top: 0;
  transform: translateX(-50%);
  font-size: 10px;
  color: var(--text-dim);
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  padding: 1px 6px;
  border-radius: 4px;
  transition: color var(--dur-1);
}
.replay-marker::before {
  content: "";
  display: block;
  width: 2px;
  height: 6px;
  background: var(--text-faint);
  margin: 0 auto 2px;
}
.replay-marker:hover { color: var(--brand); }
.replay-marker.active { color: var(--brand); }
.replay-marker.active::before { background: var(--brand); }

.crash-mood {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--text-sm);
  margin-top: 6px;
  color: var(--text-muted);
}
.mood-indicator {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 10px;
  border-radius: var(--r-full);
  font-size: var(--text-xs);
  font-weight: 700;
}
.mood-indicator.calm { background: var(--positive-soft); color: var(--positive); }
.mood-indicator.nervous { background: var(--warning-soft); color: var(--warning); }
.mood-indicator.panic { background: var(--negative-soft); color: var(--negative); }
.mood-indicator.euphoric { background: var(--accent-soft); color: var(--accent); }

/* ============================== SETTINGS =========================== */
.settings-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--sp-4) 0;
  border-bottom: 1px solid var(--divider);
  gap: var(--sp-4);
}
.settings-row:last-child { border-bottom: none; }
.settings-row .label-wrap { flex: 1; min-width: 0; }
.settings-row .label-wrap .title { font-weight: 600; color: var(--text-strong); margin-bottom: 2px; font-size: var(--text-md); }
.settings-row .label-wrap .desc { font-size: var(--text-xs); color: var(--text-muted); line-height: 1.55; }
/* Rows that only make sense on desktop — e.g. "Coach panel docked" which
   controls the persistent right rail that doesn't exist on mobile. Hidden
   below 1280 px (the same breakpoint the coach panel itself uses to flip
   between dock and FAB-drawer behaviour). */
@media (max-width: 1279px) {
  .settings-row[data-desktop-only] { display: none; }
}

.switch {
  position: relative;
  display: inline-block;
  /* Visible track stays compact, but the hit area reaches 44×44 for WCAG
     touch-target compliance (expanded via padding on the clickable label
     elsewhere + this invisible pseudo below). */
  width: 44px; height: 24px;
  flex-shrink: 0;
}
.switch input { opacity: 0; width: 0; height: 0; }
/* Invisible expanded hit area — makes the whole 44×44 tappable even though
   the toggle itself is smaller. */
.switch::after {
  content: "";
  position: absolute;
  inset: -10px -6px;
  border-radius: var(--r);
  pointer-events: none;
}
.slider {
  position: absolute; inset: 0;
  background: var(--border-strong);
  border-radius: 24px;
  cursor: pointer;
  transition: background var(--dur-1);
}
.slider::before {
  content: "";
  position: absolute;
  width: 18px; height: 18px;
  left: 3px; top: 3px;
  background: white;
  border-radius: 50%;
  transition: transform var(--dur-1);
  box-shadow: var(--sh-xs);
}
.switch input:checked + .slider { background: var(--brand); }
.switch input:checked + .slider::before { transform: translateX(20px); }

/* ============================== EMPTY STATE ========================= */
.empty-state {
  text-align: center;
  padding: var(--sp-16) var(--sp-4);
  color: var(--text-muted);
}
.empty-state .emoji { font-size: 56px; margin-bottom: var(--sp-3); display: block; }
.empty-state h3 { margin-bottom: var(--sp-2); color: var(--text-strong); }
.empty-state p { margin-bottom: var(--sp-4); max-width: 400px; margin-left: auto; margin-right: auto; }

/* ============================== MARKET STATUS ====================== */
.market-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-xs);
  color: var(--text-muted);
  font-weight: 500;
}
.market-status .dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--positive);
  animation: pulse-dot 2s ease-in-out infinite;
}
.market-status .dot.closed { background: var(--text-faint); animation: none; }

/* ============================== NEWS ================================ */
.news-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--sp-3);
}
@media (min-width: 900px) {
  .news-grid.compact { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 480px) {
  .news-item { padding: var(--sp-3); }
  .news-item .headline { font-size: var(--text-sm); line-height: 1.45; }
}
.news-item {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r);
  padding: var(--sp-4);
  transition: border-color var(--dur-1);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}
.news-item:hover { border-color: var(--border-strong); box-shadow: var(--sh-xs); }
.news-item .headline {
  font-weight: 600;
  color: var(--text-strong);
  font-size: var(--text-md);
  line-height: 1.4;
}
.news-item .meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: var(--text-xs);
  color: var(--text-dim);
}
.news-item .summary {
  font-size: var(--text-sm);
  color: var(--text-muted);
  line-height: 1.55;
}
.news-source {
  font-size: var(--text-10);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--text-muted);
}
.sentiment {
  font-size: var(--text-10);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 2px 8px;
  border-radius: var(--r-full);
}
.sentiment.bull, .sentiment.bullish { background: var(--positive-soft); color: var(--positive); }
.sentiment.bear, .sentiment.bearish { background: var(--negative-soft); color: var(--negative); }
.sentiment.neutral { background: var(--bg-soft); color: var(--text-muted); }

/* Saathi-take row — subtle AI-tagged retail-relevance one-liner below
   the headline. Loads async; shows a skeleton shimmer until the tag
   returns from /api/news-tldr. */
.news-ai-take {
  display: flex;
  gap: 8px;
  align-items: baseline;
  font-size: var(--text-sm);
  line-height: 1.45;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px dashed var(--divider);
  color: var(--text);
}
.news-ai-take.loading .news-ai-body { font-style: italic; opacity: 0.7; }
.news-ai-take.sentiment-bullish { border-top-color: var(--positive); }
.news-ai-take.sentiment-bearish { border-top-color: var(--negative); }
.news-ai-label {
  font-size: var(--text-10);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--brand);
  white-space: nowrap;
  padding: 2px 6px;
  border-radius: var(--r);
  background: color-mix(in srgb, var(--brand) 10%, transparent);
}
.news-ai-body { flex: 1; }

/* ============================== FRIENDS / TRANSFERS ================ */
.friend-row {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r);
  transition: border-color var(--dur-1);
}
.friend-row:hover { border-color: var(--border-strong); }
.friend-avatar {
  width: 40px; height: 40px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--accent), #3A47CF);
  color: white;
  font-weight: 700;
  font-size: 13px;
  display: grid; place-items: center;
  flex-shrink: 0;
}
.friend-avatar.saffron { background: linear-gradient(135deg, var(--saffron), #E06B00); }
.friend-avatar.green { background: linear-gradient(135deg, var(--brand), var(--brand-dark)); }
.friend-avatar.purple { background: linear-gradient(135deg, #A855F7, #7E3EDB); }
.friend-name { font-weight: 600; color: var(--text-strong); }
.friend-handle { font-size: var(--text-xs); color: var(--text-dim); margin-top: 2px; }

.transfer-code {
  display: inline-flex;
  font-family: var(--font-mono);
  font-size: var(--text-base);
  font-weight: 700;
  letter-spacing: 0.1em;
  padding: 10px 18px;
  background: var(--bg-soft);
  border: 1.5px dashed var(--border-strong);
  border-radius: var(--r);
  color: var(--text-strong);
  user-select: all;
}

/* ============================== LOGIN / REGISTER =================== */
.auth-wrap {
  max-width: 420px;
  margin: var(--sp-12) auto;
  padding: 0 var(--sp-4);
}
.auth-card {
  padding: var(--sp-6);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  box-shadow: var(--sh-sm);
}
.auth-card h1 { font-size: var(--text-2xl); margin-bottom: var(--sp-2); }
.auth-card .sub { color: var(--text-muted); font-size: var(--text-md); margin-bottom: var(--sp-5); }
.auth-form { display: flex; flex-direction: column; gap: var(--sp-3); }
.auth-form > .field > .label { margin-bottom: 4px; }
.auth-pw-wrap { position: relative; }
.auth-pw-wrap > .input { padding-right: 44px; }
.auth-pw-toggle {
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  border-radius: 6px;
  cursor: pointer;
  color: var(--text-muted);
  font-size: 18px;
  line-height: 1;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}
.auth-pw-toggle:hover, .auth-pw-toggle:focus-visible {
  background: var(--bg-subtle);
  color: var(--text);
  outline: none;
}
.auth-pw-toggle[aria-pressed="true"] { color: var(--brand); }

.auth-switch {
  text-align: center;
  margin-top: var(--sp-4);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--divider);
  font-size: var(--text-sm);
  color: var(--text-muted);
}
.error-msg {
  background: var(--negative-soft);
  color: var(--negative);
  padding: 10px 14px;
  border-radius: var(--r);
  font-size: var(--text-sm);
  font-weight: 500;
}
.info-msg {
  background: var(--accent-soft);
  color: var(--accent);
  padding: 10px 14px;
  border-radius: var(--r);
  font-size: var(--text-sm);
  font-weight: 500;
}
.success-msg {
  background: var(--positive-soft);
  color: var(--positive);
  padding: 10px 14px;
  border-radius: var(--r);
  font-size: var(--text-sm);
  font-weight: 500;
}

/* ============================== DROPDOWN =========================== */
.dropdown {
  position: relative;
  display: inline-block;
}
.dropdown-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  box-shadow: var(--sh-md);
  padding: 6px;
  min-width: 220px;
  z-index: 45;
  display: none;
  animation: fadeIn var(--dur-1) var(--ease);
}
.dropdown.open .dropdown-menu { display: block; }
.dropdown-item {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 8px 12px;
  border-radius: var(--r-sm);
  color: var(--text);
  font-size: var(--text-md);
  cursor: pointer;
  transition: background var(--dur-1);
  width: 100%;
  text-align: left;
}
.dropdown-item:hover { background: var(--bg-soft); }
.dropdown-item.danger { color: var(--negative); }
.dropdown-divider { height: 1px; background: var(--divider); margin: 4px 0; }

/* =============================================================================
 * EVENT MARQUEE — Hotfix46d
 * Slim announcement bar above the main nav, only rendered when there's an
 * active event (NSE holiday, MF wound up, etc.). Otherwise the wrapper is
 * display:none and takes zero layout. Single-line scrolling text.
 * =============================================================================
 */
.event-marquee {
  width: 100%;
  overflow: hidden;
  white-space: nowrap;
  font-size: 12px;
  font-weight: 500;
  line-height: 32px;
  height: 32px;
  border-bottom: 1px solid var(--divider);
}
.event-marquee--info {
  background: var(--bg-soft);
  color: var(--text-muted);
}
.event-marquee--warning {
  background: var(--warning-soft, rgba(217, 119, 6, 0.12));
  color: var(--warning, #d97706);
}
.event-marquee-track {
  display: inline-block;
  padding-left: 100%;
  animation: event-marquee-scroll 38s linear infinite;
}
.event-marquee:hover .event-marquee-track {
  animation-play-state: paused;
}
@keyframes event-marquee-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-100%); }
}
@media (prefers-reduced-motion: reduce) {
  /* Stop the scrolling animation for accessibility settings users.
     Show the static text wrapped to the bar's full width instead. */
  .event-marquee { white-space: normal; height: auto; padding: 6px 12px; }
  .event-marquee-track { padding-left: 0; animation: none; }
}
