:root {
  /* One corner radius for every box/panel. */
  --box-radius: 6px;
  /* TradingView palette for the chart and watchlist (light theme) */
  --tv-bg: #ffffff;
  --tv-panel: #ffffff;
  --tv-border: #e0e3eb;
  --tv-grid: #f0f3fa;
  --tv-text: #131722;
  --tv-muted: #787b86;
  --tv-up: #089981;
  --tv-down: #f23645;
  --tv-list-up: #089981;
  --tv-list-down: #f23645;
  --tv-hover: #f0f3fa;
  --tv-selected: #e3effd;
  --tv-volume-up: rgba(8, 153, 129, 0.35);
  --tv-volume-down: rgba(242, 54, 69, 0.35);
  --tv-ext-shade: rgba(41, 98, 255, 0.05);
  /* Page colours, the same palette as the chart (light) */
  --bg-primary: #ffffff;
  --bg-secondary: #f0f3fa;
  --bg-form: #ffffff;
  --bg-input: #ffffff;
  --text-primary: #131722;
  --text-primary-strong: #131722;
  --text-secondary: #5d606b;
  --text-muted-soft: #787b86;
  --border-color: #e0e3eb;
  --border-input: #d1d4dc;
  --accent-green: #089981;
  --accent-red: #f23645;
  --profit-positive: #089981;
  --profit-negative: #f23645;
  --placeholder-color: #787b86;
  --button-gradient: linear-gradient(135deg, #2962ff, #1e53e5);
  --button-gradient-hover: linear-gradient(135deg, #1e53e5, #1848c7);
}

[data-theme='dark'] {
  /* TradingView palette (dark theme) */
  --tv-bg: #131722;
  --tv-panel: #131722;
  --tv-border: #2a2e39;
  --tv-grid: #1e222d;
  --tv-text: #d1d4dc;
  --tv-muted: #787b86;
  --tv-up: #089981;
  --tv-down: #f23645;
  --tv-list-up: #22ab94;
  --tv-list-down: #f7525f;
  --tv-hover: #1e222d;
  --tv-selected: #2a2e39;
  --tv-volume-up: rgba(8, 153, 129, 0.4);
  --tv-volume-down: rgba(242, 54, 69, 0.4);
  --tv-ext-shade: rgba(41, 98, 255, 0.06);
  /* Page colours, the same palette as the chart (dark) */
  --bg-primary: #131722;
  --bg-secondary: #1e222d;
  --bg-form: #131722;
  --bg-input: #1e222d;
  --text-primary: #d1d4dc;
  --text-primary-strong: #ffffff;
  --text-secondary: #b2b5be;
  --text-muted-soft: #787b86;
  --border-color: #2a2e39;
  --border-input: #363a45;
  --accent-green: #089981;
  --accent-red: #f23645;
  --profit-positive: #22ab94;
  --profit-negative: #f7525f;
  --placeholder-color: #787b86;
  --button-gradient: linear-gradient(135deg, #2962ff, #1e53e5);
  --button-gradient-hover: linear-gradient(135deg, #1e53e5, #1848c7);
}

html {
  background-color: var(--bg-primary);
}

body {
  font-family: system-ui, -apple-system, sans-serif;
  background-color: var(--bg-primary);
  color: var(--text-primary);
}

/* Navbar styles */
.navbar {
  background-color: var(--bg-primary) !important;
  border-bottom: 1px solid var(--border-color) !important;
}

.navbar-brand {
  color: var(--text-primary) !important;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

/* The monogram's letters are currentColor, so they follow the theme with the
   wordmark; the trend inside it stays green. */
.navbar-mark {
  flex: 0 0 auto;
  display: block;
}

/* On a phone the mark alone carries the brand, and the row gets its width
   back for the chart tools. */
@media (max-width: 480px) {
  .navbar-brand span { display: none; }
}

.nav-link {
  color: var(--text-secondary) !important;
  border-bottom: 2px solid transparent;
  padding-bottom: 2px;
}

.nav-link.active {
  color: var(--text-primary) !important;
  font-weight: 600;
  border-bottom-color: var(--text-primary);
}

/* Navbar layout */
.navbar-inner {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

/* The page's chart tools (indicators, layouts) sit left of the actions; the
   watchlists page fills the slot, other pages leave it empty. */
.navbar-tools {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  flex: 1;
  min-width: 0;
}
.navbar-tools:empty { display: none; }
.navbar-tools .price-chart-range { color: var(--text-secondary); }
.navbar-tools .price-chart-range:hover,
.navbar-tools .price-chart-range.active { color: var(--text-primary); }

.navbar-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-left: auto;
  /* Positioning context for the sync popover so it right-aligns to the bar edge
     (and can't clip off-screen) regardless of where the dot sits. */
  position: relative;
}

@media (max-width: 768px) {
  .navbar-inner { gap: 0.5rem; }
  .navbar-brand { margin-right: 0; }
}

/* Sync status indicator (navbar) */
.sync-status {
  display: inline-flex;
}

/* "Synced" is the normal state and tells you nothing worth navbar space, so
   the dot only shows once there is something to act on: changes pending or
   saving, a failed sync, offline, or newer data on another device. */
.sync-status.sync-quiet {
  display: none;
}

.sync-status-btn {
  background: none;
  border: none;
  padding: 6px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
}

.sync-status-btn:hover {
  background-color: var(--bg-secondary);
}

.sync-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  display: inline-block;
  flex: 0 0 auto;
  background-color: var(--text-muted-soft);
}

.sync-dot-green { background-color: var(--accent-green); }
.sync-dot-amber { background-color: #f5a623; }
.sync-dot-red   { background-color: var(--accent-red); }
.sync-dot-blue  { background-color: #3b82f6; }

.sync-dot-pulse { animation: sync-pulse 1s ease-in-out infinite; }

@keyframes sync-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.3; }
}

.sync-popover {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 1100;
  min-width: 230px;
  background-color: var(--bg-primary);
  border: 1px solid var(--border-color);
  border-radius: var(--box-radius);
  padding: 10px 12px;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.28);
  font-size: 0.85rem;
  color: var(--text-primary);
}

.sync-popover-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  padding: 3px 0;
  color: var(--text-secondary);
}

.sync-popover-row > span:last-child {
  color: var(--text-primary);
  text-align: right;
}

.sync-popover-title {
  align-items: center;
  padding-bottom: 6px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--border-color);
}

.sync-popover-title strong {
  color: var(--text-primary);
}

.sync-popover-error > span:last-child {
  color: var(--accent-red);
  word-break: break-word;
}

.sync-popover-note {
  margin-top: 6px;
  padding: 6px 8px;
  border-radius: 6px;
  background-color: rgba(59, 130, 246, 0.12);
  color: var(--text-secondary);
  font-size: 0.8rem;
  line-height: 1.3;
}

.sync-popover-action {
  margin-top: 8px;
  width: 100%;
  background-color: var(--bg-secondary);
  border: 1px solid var(--border-color);
  color: var(--text-primary);
  border-radius: 6px;
  padding: 6px;
  cursor: pointer;
  font-weight: 600;
}

.sync-popover-action:hover {
  background-color: var(--text-primary);
  color: var(--bg-primary);
}

/* Market open/close countdown pill (navbar) */
.market-clock {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 0.8rem;
  font-weight: 600;
  white-space: nowrap;
  border: 1px solid var(--border-color);
  background-color: var(--bg-secondary);
  color: var(--text-primary);
  cursor: default;
}

.market-clock-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex: 0 0 auto;
  background-color: var(--text-muted-soft);
}

.market-clock-sep {
  color: var(--text-muted-soft);
}

.market-closed .market-clock-status {
  color: var(--text-secondary);
}

.market-open {
  border-color: var(--accent-green);
}

.market-open .market-clock-status {
  color: var(--accent-green);
}

.market-open .market-clock-dot {
  background-color: var(--accent-green);
  animation: market-pulse 1.8s infinite;
}

@keyframes market-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(0, 200, 5, 0.5); }
  70%  { box-shadow: 0 0 0 6px rgba(0, 200, 5, 0); }
  100% { box-shadow: 0 0 0 0 rgba(0, 200, 5, 0); }
}

/* On very small screens, keep just the dot + countdown to save space */
@media (max-width: 575px) {
  .market-clock-status,
  .market-clock-sep {
    display: none;
  }
}

/* Form styles */
.form-control {
  background-color: var(--bg-input) !important;
  border-color: var(--border-input) !important;
  color: var(--text-primary) !important;
}

.form-control:focus {
  background-color: var(--bg-input);
  border-color: var(--text-primary);
  box-shadow: none;
}

.form-label {
  color: var(--text-primary);
}

.form-control::placeholder {
  color: var(--placeholder-color) !important;
  opacity: 1;
}

/* Mobile-only live results preview (hidden on desktop via d-lg-none). It sits in
   a .form-section card, so borders/corners/background match the other cards; this
   rule only handles the inner layout. */
.mobile-preview {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.mobile-preview-profit {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.mobile-preview-label {
  font-size: 0.75rem;
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.mobile-preview-profit .result-value {
  font-size: 1.6rem;
  font-weight: 700;
  line-height: 1.1;
}

.mobile-preview-pct {
  font-size: 0.9rem;
  font-weight: 600;
  margin-left: 6px;
}

.mobile-preview-sub {
  display: flex;
  flex-direction: column;
  gap: 2px;
  text-align: right;
  font-size: 0.8rem;
  color: var(--text-secondary);
  white-space: nowrap;
}

/* Compact label/value rows inside the mobile result cards */
.mobile-stat-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

.mobile-stat-row + .mobile-stat-row {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--border-color);
}

.mobile-stat-label {
  color: var(--text-secondary);
  font-size: 0.9rem;
}

.mobile-stat-value {
  font-weight: 700;
  font-size: 1.15rem;
  white-space: nowrap;
}

.profit-positive .mobile-stat-value { color: var(--profit-positive); }
.profit-negative .mobile-stat-value { color: var(--profit-negative); }

/* Tabs styles */
.tabs-container {
  background-color: var(--bg-primary);
  border-bottom: 1px solid var(--border-color);
}

.tabs {
  display: flex;
  gap: 0.5rem;
  padding: 1rem 0 0 0;
  align-items: stretch; /* tab and + button share the same height */
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}

.tabs::-webkit-scrollbar {
  display: none;
}

.tab {
  background-color: var(--bg-secondary);
  border: 1px solid var(--border-color);
  color: var(--text-primary);
  padding: 0.75rem 1rem;
  border-radius: 8px 8px 0 0;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  transition: background-color 0.2s;
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  /* Tabs are draggable: no text selection or long-press callout mid-drag. */
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}

/* The tab being dragged — lifted out of the strip so the drop slot is obvious. */
.tab.dragging {
  opacity: 0.85;
  cursor: grabbing;
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
  transition: none;
}

.tab.active {
  background-color: var(--text-primary);
  color: var(--bg-primary);
  border-color: var(--text-primary);
}

.close-tab {
  background: none;
  border: none;
  color: inherit;
  margin: 0;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.5rem;
  min-height: 1.5rem;
  padding: 0;
  font-size: 1.1rem;
  line-height: 1;
  border-radius: 4px;
  flex-shrink: 0;
}

.close-tab:hover {
  background-color: rgba(128, 128, 128, 0.2);
}

.add-tab {
  background-color: var(--bg-secondary);
  border: 1px solid var(--border-color);
  color: var(--text-primary);
  padding: 0.75rem 1rem;
  border-radius: 8px 8px 0 0;
  cursor: pointer;
  font-size: 1.2rem;
  line-height: 1;
  margin: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.add-tab:hover {
  background-color: var(--text-secondary);
  color: var(--bg-primary);
}

/* Closed-tabs (archive) toggle + panel */
.archive-toggle {
  gap: 0.35rem;
  font-size: 1rem;
  margin-left: auto; /* pin to the right end of the tab strip */
  flex-shrink: 0;
}

.archive-count {
  font-size: 0.75rem;
  font-weight: 600;
}

.archive-panel {
  padding: 0.75rem 0 1rem 0;
  border-bottom: 1px solid var(--border-color);
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.archive-item {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.35rem 0.5rem;
  border-radius: 6px;
}

.archive-item:hover {
  background-color: var(--bg-secondary);
}

.archive-restore {
  background: none;
  border: none;
  padding: 0;
  color: var(--text-primary);
  font-weight: 600;
  cursor: pointer;
  text-align: left;
}

.archive-restore:hover {
  text-decoration: underline;
}

.archive-meta,
.archive-empty {
  color: var(--text-secondary);
  font-size: 0.85rem;
}

.archive-delete {
  margin-left: auto;
  padding: 0 0.5rem;
  line-height: 1;
}

.archive-recover {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-top: 0.5rem;
  padding: 0 0.5rem;
}

/* Form section */
.form-section {
  background-color: var(--bg-form);
  border: 1px solid var(--border-color);
  border-radius: var(--box-radius);
  /* Overrides the px-4/py-* utilities on these cards: less dead space. */
  padding: 0.75rem 1rem !important;
}

/* Results */
.result-value {
  color: var(--text-primary);
  font-weight: 600;
  white-space: nowrap;
}

.result-label {
  color: var(--text-secondary);
}

.profit-positive .result-value {
  color: var(--profit-positive);
}

.profit-negative .result-value {
  color: var(--profit-negative);
}

/* Utility classes */
.text-secondary {
  color: var(--text-secondary) !important;
}

/* Responsive adjustments */
@media (max-width: 768px) {
  .result-value {
    font-size: 1.75rem !important;
  }

  .result-label {
    font-size: 0.9rem;
  }

  .tabs {
    padding: 0.5rem 0 0 0;
    flex-wrap: nowrap;
    -webkit-overflow-scrolling: touch;
  }

  .tab {
    padding: 0.5rem 0.75rem;
    font-size: 0.9rem;
    max-width: 150px;
    flex-shrink: 0;
  }

  .add-tab {
    padding: 0.5rem 0.75rem;
  }

  .form-section {
    padding: 0.75rem !important;
  }

  .form-control {
    font-size: 1rem;
    padding: 0.375rem 0.5rem;
  }
}

@media (max-width: 576px) {
  .result-value {
    font-size: 1.5rem !important;
  }

  .tabs {
    gap: 0.25rem;
  }

  .tab {
    padding: 0.4rem 0.6rem;
    font-size: 0.85rem;
    max-width: 120px;
  }

  .add-tab {
    padding: 0.4rem 0.7rem;
    font-size: 1.1rem;
  }
}

/* Calculate button styles */
.btn-calculate {
  background: var(--button-gradient);
  border: none;
  color: white !important;
  padding: 0.75rem 2rem;
  border-radius: 8px;
  font-weight: 600;
  transition: all 0.3s ease;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.btn-calculate:hover {
  background: var(--button-gradient-hover);
  transform: translateY(-1px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}

.btn-calculate:active {
  transform: translateY(0);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

/* ============================================
   Robinhood-Style Global Overrides
   ============================================ */

/* Card neutralization */
.card {
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
}

.card-body {
  padding: 0 !important;
}

.card-title {
  color: var(--text-primary);
}

/* Table overrides */
.table {
  color: var(--text-primary);
  border-color: var(--border-color);
  --bs-table-bg: transparent;
  --bs-table-color: var(--text-primary);
  --bs-table-border-color: var(--border-color);
  --bs-table-striped-bg: transparent;
  --bs-table-striped-color: var(--text-primary);
  --bs-table-hover-bg: rgba(128, 128, 128, 0.08);
  --bs-table-hover-color: var(--text-primary);
}

.table thead th {
  color: var(--text-muted-soft);
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  border-bottom: 1px solid var(--border-color);
}

.table td {
  border-color: var(--border-color);
  vertical-align: middle;
}

.table tfoot td,
.table tfoot th {
  border-top: 1px solid var(--border-color);
  color: var(--text-primary);
  background: transparent !important;
}

/* Neutralize Bootstrap table variants */
.table-dark,
.table-light,
.table-secondary,
.table-active {
  --bs-table-bg: transparent !important;
  --bs-table-color: var(--text-primary) !important;
  --bs-table-border-color: var(--border-color) !important;
  background-color: transparent !important;
  color: var(--text-primary) !important;
}

.table-dark td,
.table-dark th,
.table-light td,
.table-light th,
.table-secondary td,
.table-secondary th {
  background-color: transparent !important;
  color: var(--text-primary) !important;
}

/* Alert overrides — transparent bg, left accent border */
.alert {
  background: transparent;
  border: none;
  border-left: 3px solid var(--text-muted-soft);
  border-radius: 0;
  color: var(--text-primary);
  padding: 0.75rem 1rem;
}

.alert-danger {
  border-left-color: var(--accent-red);
  color: var(--accent-red);
}

.alert-success {
  border-left-color: var(--accent-green);
  color: var(--accent-green);
}

.alert-info,
.alert-dark,
.alert-secondary {
  border-left-color: var(--text-muted-soft);
  color: var(--text-secondary);
}

/* ---- New button classes ---- */

/* Primary filled pill button */
.btn-action {
  background-color: var(--accent-green);
  color: #fff;
  border: none;
  border-radius: 999px;
  padding: 0.5rem 1.5rem;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
  transition: opacity 0.15s ease;
}

.btn-action:hover {
  opacity: 0.85;
  color: #fff;
}

.btn-action:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* Outlined ghost pill button */
.btn-ghost {
  background: none;
  color: var(--text-primary);
  border: 1px solid var(--border-color);
  border-radius: 999px;
  padding: 0.5rem 1.5rem;
  font-size: 0.85rem;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.15s ease;
}

.btn-ghost:hover {
  border-color: var(--text-primary);
  color: var(--text-primary);
}

/* Red ghost for destructive actions */
.btn-ghost-danger {
  background: none;
  color: var(--accent-red);
  border: 1px solid var(--accent-red);
  border-radius: 999px;
  padding: 0.5rem 1.5rem;
  font-size: 0.85rem;
  font-weight: 500;
  cursor: pointer;
  transition: opacity 0.15s ease;
}

.btn-ghost-danger:hover {
  opacity: 0.7;
}

/* Underline-style tab button */
.btn-tab {
  background: none;
  border: none;
  padding: 6px 12px;
  font-size: 0.85rem;
  font-weight: 400;
  color: var(--text-muted-soft);
  border-bottom: 2px solid transparent;
  cursor: pointer;
  border-radius: 0;
  transition: all 0.15s ease;
}

.btn-tab:hover {
  color: var(--text-primary);
}

.btn-tab.active {
  font-weight: 600;
  color: var(--text-primary);
  border-bottom-color: var(--text-primary);
}

/* Utility classes */
.hero-value {
  font-size: 2.5rem;
  font-weight: 700;
  line-height: 1.1;
  color: var(--text-primary);
}

.hero-subtitle {
  font-size: 1rem;
  color: var(--text-muted-soft);
  margin-top: 4px;
}

/* Form check / switch uses CSS vars */
.form-check-label {
  color: var(--text-primary);
}

/* Muted text uses CSS var */
.text-muted-soft {
  color: var(--text-muted-soft) !important;
}

/* Override Bootstrap .text-muted in our theme */
.text-muted {
  color: var(--text-muted-soft) !important;
}

/* Form label always uses theme color */
.form-label {
  color: var(--text-primary);
  font-size: 0.85rem;
  font-weight: 500;
}
/* Price chart under the calculator */
.price-chart-canvas {
  position: relative;
  height: 320px;
}

.price-chart-empty {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.price-chart-ranges {
  display: flex;
  gap: 0.25rem;
}

.price-chart-range {
  background: none;
  border: 1px solid transparent;
  color: var(--text-secondary);
  border-radius: 6px;
  padding: 0.2rem 0.55rem;
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
}

.price-chart-range:hover {
  border-color: var(--border-color);
}

.price-chart-range.active {
  background-color: var(--bg-input);
  border-color: var(--border-color);
  color: var(--text-primary);
}

.price-chart-quote {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem;
  font-variant-numeric: tabular-nums;
}

.price-chart-price {
  font-size: 1.35rem;
  font-weight: 700;
  color: var(--text-primary);
}

.price-chart-canvas canvas {
  cursor: crosshair;
}

.price-chart-canvas.over-level canvas,
.price-chart-canvas.dragging-level canvas,
.price-chart-canvas.over-axis canvas {
  cursor: ns-resize;
}

@media (max-width: 576px) {
  .price-chart-canvas {
    height: 240px;
  }
}

/* Target probability panel */
.target-prob-from {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem;
}

.target-prob-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 2rem;
  margin-bottom: 0.75rem;
}

.target-prob-value {
  font-size: 1.75rem;
  font-weight: 700;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
}

.price-chart .profit-positive,
.target-prob .profit-positive { color: var(--profit-positive); }
.price-chart .profit-negative,
.target-prob .profit-negative { color: var(--profit-negative); }

.target-prob-bar {
  display: flex;
  height: 8px;
  border-radius: 4px;
  overflow: hidden;
  background-color: var(--border-color);
  margin-bottom: 0.75rem;
}

.target-prob-bar-target { background-color: var(--profit-positive); }
.target-prob-bar-neither { background-color: var(--text-muted-soft); }
.target-prob-bar-stop { background-color: var(--profit-negative); }

.target-prob-details {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}


/* Entry check */
.entry-check-auto {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  color: var(--text-secondary);
  cursor: pointer;
}

.entry-check-btn {
  padding: 0.45rem 1.1rem;
}

.entry-check-result {
  margin-top: 0.75rem;
  padding-left: 0.9rem;
  border-left: 4px solid var(--text-muted-soft);
}

.entry-check-result.tone-good { border-left-color: var(--profit-positive); }
.entry-check-result.tone-wait { border-left-color: #F5A623; }
.entry-check-result.tone-bad { border-left-color: var(--profit-negative); }

.entry-check-headline {
  font-size: 1.35rem;
  font-weight: 700;
  color: var(--text-primary);
}

.tone-good .entry-check-headline { color: var(--profit-positive); }
.tone-wait .entry-check-headline { color: #F5A623; }
.tone-bad .entry-check-headline { color: var(--profit-negative); }

.entry-check-reason {
  color: var(--text-secondary);
  margin-bottom: 0.75rem;
}

.entry-check-plan {
  display: flex;
  flex-wrap: wrap;
  gap: 1.75rem;
  margin-bottom: 0.5rem;
}

.entry-check-label {
  font-size: 0.75rem;
  color: var(--text-secondary);
}

.entry-check-value {
  font-size: 1.2rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
}

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

.entry-check-warning {
  color: #F5A623;
  margin-bottom: 0.5rem;
}

.entry-check-use {
  padding: 0.35rem 0.9rem;
  font-size: 0.85rem;
}

.more-odds > summary {
  cursor: pointer;
  color: var(--text-secondary);
  font-size: 0.9rem;
  padding: 0.25rem 0;
}

.more-odds[open] > summary {
  margin-bottom: 0.5rem;
}

.entry-check-why {
  font-size: 0.72rem;
  color: var(--text-muted-soft);
  max-width: 11rem;
}

.entry-check-levels {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem;
  margin-bottom: 0.5rem;
}

.price-chart-ext {
  margin-top: 0.1rem;
  font-variant-numeric: tabular-nums;
}

.entry-check-ext {
  margin-bottom: 0.25rem;
  font-variant-numeric: tabular-nums;
}

.entry-check-result.tone-neutral { border-left-color: var(--text-secondary); }

.entry-check-evidence {
  margin: -0.4rem 0 0.75rem;
}

.entry-check-mode {
  display: inline-block;
  font-weight: 600;
  color: var(--text-primary);
  margin-right: 0.25rem;
}

/* Watchlists — modelled on TradingView's watchlist panel */
.watchlist {
  max-width: 640px;
  margin: 0 auto;
  width: 100%;
  background-color: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--box-radius);
  overflow: visible;
}

.watchlist-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.5rem 0.75rem 0.35rem;
}

.watchlist-picker {
  position: relative;
}

.watchlist-title {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  background: none;
  border: none;
  color: var(--text-primary);
  font-size: 1.15rem;
  font-weight: 700;
  padding: 0.1rem 0.3rem;
  border-radius: 6px;
  cursor: pointer;
}

.watchlist-title:hover { background-color: rgba(128, 128, 128, 0.15); }

.watchlist-menu {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  z-index: 20;
  min-width: 240px;
  background-color: var(--bg-primary);
  border: 1px solid var(--border-color);
  border-radius: var(--box-radius);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
  padding: 0.35rem;
}

.watchlist-menu-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  background: none;
  border: none;
  color: var(--text-primary);
  text-align: left;
  padding: 0.45rem 0.6rem;
  border-radius: 6px;
  cursor: pointer;
}

.watchlist-menu-item:hover { background-color: rgba(128, 128, 128, 0.15); }
.watchlist-menu-item.active { font-weight: 700; }
.watchlist-menu-item.danger { color: var(--profit-negative); }

.watchlist-menu-sep {
  height: 1px;
  background-color: var(--border-color);
  margin: 0.3rem 0;
}

.watchlist-menu-confirm { padding: 0.45rem 0.6rem; }

.watchlist-menu-heading { padding: 0.3rem 0.6rem 0.15rem; text-transform: uppercase; letter-spacing: 0.04em; font-size: 0.72rem; }
.watchlist-menu-item.archived { opacity: 0.7; }

/* "archived" next to the open list's name. */
.watchlist-archived-tag {
  margin-left: 0.45rem;
  padding: 0.05rem 0.4rem;
  border: 1px solid currentColor;
  border-radius: 999px;
  font-size: 0.65rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  opacity: 0.7;
}

.watchlist-actions {
  display: flex;
  gap: 0.25rem;
}

.watchlist-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  background: none;
  border: none;
  color: var(--text-secondary);
  border-radius: 6px;
  cursor: pointer;
  text-decoration: none;
  font-size: 1.2rem;
  line-height: 1;
}

.watchlist-icon-btn:hover {
  background-color: rgba(128, 128, 128, 0.18);
  color: var(--text-primary);
}

/* Search and plus glyphs drawn with CSS and text. Inline SVG with
   currentColor didn't paint inside these buttons on iPhones in dark mode;
   borders and text did, so the icons use those. The colour is a variable
   set per button, not currentColor. */
.watchlist-icon-btn, .watchlist-mobile-search { --ico: var(--text-secondary); }
.watchlist-icon-btn:hover { --ico: var(--text-primary); }

.ico-search {
  position: relative;
  display: block;
  width: 18px;
  height: 18px;
  flex: none;
}
.ico-search::before {
  content: '';
  position: absolute;
  left: 1px;
  top: 1px;
  width: 12px;
  height: 12px;
  box-sizing: border-box;
  border: 2px solid var(--ico);
  border-radius: 50%;
}
.ico-search::after {
  content: '';
  position: absolute;
  left: 11px;
  top: 10.5px;
  width: 2px;
  height: 7px;
  border-radius: 1px;
  background-color: var(--ico);
  transform: rotate(-45deg);
  transform-origin: 50% 0;
}

.ico-plus {
  display: block;
  color: var(--ico);
  font-size: 1.6rem;
  font-weight: 300;
  line-height: 1;
  margin-top: -2px;
}

.watchlist-quick {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
  padding: 0 0.75rem 0.5rem;
}

.watchlist-quick-btn {
  width: 2.1rem;
  height: 2.1rem;
  border-radius: 50%;
  border: 1px solid var(--border-color);
  background: none;
  color: var(--text-secondary);
  font-weight: 600;
  font-size: 0.85rem;
  cursor: pointer;
  /* Centre the letter ourselves: iOS Safari gives buttons their own padding
     and line-height, which pushed it off-centre. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  line-height: 1;
  -webkit-appearance: none;
  appearance: none;
}

.watchlist-quick-btn.active {
  background-color: var(--text-primary);
  color: var(--bg-primary);
  border-color: var(--text-primary);
}

.watchlist-form {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  padding: 0 0.75rem 0.6rem;
}

.watchlist-form .form-control { flex: 1 1 200px; }
.watchlist-form .btn-action,
.watchlist-form .btn-ghost { padding: 0.3rem 0.8rem; }

.watchlist-form-error {
  flex-basis: 100%;
  color: var(--profit-negative);
}

.watchlist-table-wrap { overflow-x: auto; }

.watchlist-table {
  width: 100%;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}

.watchlist-table th {
  padding: 0.4rem 0.5rem;
  border-bottom: 1px solid var(--border-color);
  font-weight: 500;
}

.watchlist-table th button {
  background: none;
  border: none;
  padding: 0;
  color: var(--text-secondary);
  font-size: 0.95rem;
  cursor: pointer;
}

.watchlist-table th.num { text-align: right; }

.watchlist-sort {
  font-size: 0.6rem;
  margin-left: 0.25rem;
}

.watchlist-table td {
  padding: 0.45rem 0.5rem;
  border-bottom: 1px solid var(--border-color);
  font-size: 1.05rem;
  white-space: nowrap;
}

.watchlist-table th:first-child,
.watchlist-table td:first-child { padding-left: 0.75rem; }

.watchlist-table tbody tr:hover { background-color: rgba(128, 128, 128, 0.08); }

.watchlist-table td.num {
  text-align: right;
  color: var(--text-primary);
}

.watchlist-table td.num.profit-positive { color: var(--profit-positive); }
.watchlist-table td.num.profit-negative { color: var(--profit-negative); }

.watchlist-symbol {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.watchlist-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 50%;
  color: #fff;
  font-size: 0.8rem;
  font-weight: 700;
  flex-shrink: 0;
  position: relative;
  overflow: hidden;
}

/* The company logo sits over the letter and only shows once it has loaded;
   on a white disc so dark marks stay visible in dark mode, as TradingView's. */
.watchlist-badge img {
  position: absolute;
  inset: 2px;
  width: calc(100% - 4px);
  height: calc(100% - 4px);
  border-radius: 50%;
  object-fit: cover;
  opacity: 0;
}

.watchlist-badge.has-logo { background: #fff; }
.watchlist-badge.has-logo img { opacity: 1; }

.watchlist-ticker {
  color: var(--text-primary);
  font-weight: 500;
}

.watchlist-ext-dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background-color: #2962FF;
  flex-shrink: 0;
}

.watchlist-ext-dot.inline { vertical-align: middle; margin-right: 0.15rem; }

/* Row buttons: no column of their own; they cover the end of the row (the
   change %) on hover, on the row's own background. */
.watchlist-table td.watchlist-last { position: relative; }

.watchlist-row-actions {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  display: none;
  align-items: center;
  gap: 0.1rem;
  padding: 0 0.4rem 0 0.9rem;
  background: linear-gradient(to right, transparent, var(--row-bg, var(--tv-hover)) 0.8rem);
}

.watchlist-row-actions .watchlist-icon-btn {
  width: 1.75rem;
  height: 1.75rem;
}

.watchlist-table tbody tr:hover .watchlist-row-actions,
.watchlist-row-actions:focus-within { display: inline-flex; }
.watchlist-table tbody tr.selected { --row-bg: var(--tv-selected); }

/* Touch screens have no hover: the selected row shows its buttons. */
@media (hover: none) {
  .watchlist-table tbody tr:hover .watchlist-row-actions { display: none; }
  .watchlist-table tbody tr.selected .watchlist-row-actions { display: inline-flex; }
}

.watchlist-remove:hover { color: var(--profit-negative) !important; }

/* Sections, as in TradingView: a header row that folds its symbols on click
   and shows add / rename / remove on hover. */
.watchlist-table tr.watchlist-section td {
  position: relative;
  padding: 0.3rem 0.5rem 0.3rem 0.6rem;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--text-secondary);
  background-color: rgba(128, 128, 128, 0.07);
  user-select: none;
  -webkit-user-select: none;
}

/* Two glyphs rather than one rotated: a rotated ▾ sits off its baseline. */
.watchlist-section-chevron {
  display: inline-block;
  width: 1.1rem;
  font-size: 0.75rem;
  line-height: 1;
  vertical-align: 0.05em;
}

.watchlist-section-count { margin-left: 0.5rem; font-weight: 400; }

/* Touch screens: no hover, so the section buttons are always there. */
@media (hover: none) {
  .watchlist-table tr.watchlist-section .watchlist-row-actions { display: inline-flex; }
}

/* Dragging a row (or a section with its rows) to reorder. */
.watchlist-table tbody tr.dragging { opacity: 0.4; }

.watchlist-table.dragging {
  user-select: none;
  -webkit-user-select: none;
  cursor: grabbing;
}

.watchlist-empty { padding: 1.5rem 1rem; text-align: center; }

.btn-link-inline {
  background: none;
  border: none;
  padding: 0;
  color: var(--text-primary);
  text-decoration: underline;
  cursor: pointer;
}

.watchlist-footer { padding: 0.6rem 1rem 0.8rem; }

@media (max-width: 576px) {
  .watchlist-table td { font-size: 0.95rem; padding: 0.5rem 0.35rem; }
  .watchlist-badge { width: 1.5rem; height: 1.5rem; font-size: 0.7rem; }
}

/* Watchlist page: chart on the left, list docked on the right (TradingView
   layout); stacked on narrow screens, chart first. */
.watchlist-page {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(320px, 420px);
  gap: 0.5rem;
  padding: 0.5rem !important;
  align-items: start;
  max-width: 1600px;
  margin: 0 auto;
}

.watchlist-page .watchlist {
  max-width: none;
  position: sticky;
  top: 1rem;
}


.watchlist-table tbody tr { cursor: pointer; }

.watchlist-table tbody tr.selected {
  background-color: rgba(41, 98, 255, 0.16);
}

.watchlist-table tbody tr.selected:hover {
  background-color: rgba(41, 98, 255, 0.22);
}

@media (max-width: 992px) {
  .watchlist-page { grid-template-columns: minmax(0, 1fr); }
  .watchlist-page .watchlist { position: static; }
}

/* --- TradingView look: chart + watchlist ------------------------------- */
.tv-up { color: var(--tv-up); }
.tv-down { color: var(--tv-down); }

.price-chart {
  background-color: var(--tv-bg) !important;
  border: 1px solid var(--tv-border);
  color: var(--tv-text);
}

/* The chart fills its card. The legend floats in front of the plot and the
   axis labels are drawn inside the canvas, so the card's own padding was only
   dead space around the plot. Beats .form-section's !important padding. */
.price-chart.form-section {
  padding: 0 !important;
}

.price-chart .fw-bold,
.price-chart .price-chart-price { color: var(--tv-text); }
.price-chart .text-muted-soft { color: var(--tv-muted) !important; }

.price-chart-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 0.9rem;
  align-items: center;
}

.price-chart .price-chart-range { color: var(--tv-muted); }
.price-chart .price-chart-range:hover { border-color: var(--tv-border); color: var(--tv-text); }
.price-chart .price-chart-range.active {
  background-color: var(--tv-grid);
  border-color: var(--tv-border);
  color: var(--tv-text);
}

.price-chart-icon {
  display: inline-flex;
  align-items: center;
  padding: 0.25rem 0.4rem;
}

.price-chart-ohlc {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  font-variant-numeric: tabular-nums;
  margin-top: 0.1rem;
}
/* O H L C (change) on the first row, volume on the second */
.price-chart-ohlc-row {
  display: flex;
  flex-wrap: nowrap;
  gap: 0.75rem;
  white-space: nowrap;
  overflow: hidden;
  min-width: 0;
}

.price-chart-canvas { touch-action: pan-y; }

.price-chart-zoom {
  position: absolute;
  left: 50%;
  bottom: 1.6rem;
  transform: translateX(-50%);
  display: flex;
  gap: 0.25rem;
  opacity: 0;
  transition: opacity 0.15s;
}

.price-chart-canvas:hover .price-chart-zoom,
.price-chart-zoom:focus-within { opacity: 1; }

@media (hover: none) {
  .price-chart-zoom { opacity: 0.85; }
}

.price-chart-zoom button {
  width: 2rem;
  height: 2rem;
  border-radius: 6px;
  border: 1px solid var(--tv-border);
  background-color: var(--tv-bg);
  color: var(--tv-text);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
}

.price-chart-zoom button:hover { background-color: var(--tv-grid); }

/* Watchlist in TradingView colours */
.watchlist {
  background-color: var(--tv-panel);
  border-color: var(--tv-border);
  color: var(--tv-text);
}

.watchlist .watchlist-title,
.watchlist .watchlist-ticker,
.watchlist-table td.num { color: var(--tv-text); }

.watchlist-table tr.watchlist-section td { color: var(--tv-muted); }

.watchlist-table th,
.watchlist-table td { border-bottom-color: var(--tv-border); }

.watchlist-table th button { color: var(--tv-muted); }

.watchlist-table td.num.profit-positive { color: var(--tv-list-up); }
.watchlist-table td.num.profit-negative { color: var(--tv-list-down); }

.watchlist-table tbody tr:hover { background-color: var(--tv-hover); }

.watchlist-table tbody tr.selected,
.watchlist-table tbody tr.selected:hover {
  background-color: var(--tv-selected);
  box-shadow: inset 0 0 0 1px var(--tv-muted);
}

.watchlist .text-muted-soft { color: var(--tv-muted) !important; }

.watchlist-menu {
  background-color: var(--tv-panel);
  border-color: var(--tv-border);
}

.watchlist-quick-btn { border-color: var(--tv-border); color: var(--tv-muted); }
.watchlist-quick-btn.active { background-color: var(--tv-text); color: var(--tv-bg); border-color: var(--tv-text); }

/* Watchlist page fills the window below the navbar: chart as tall as it can
   be, the list scrolling inside its own panel (as in TradingView). */
.watchlist-page {
  height: var(--watchlist-page-height, auto);
  /* One row exactly the page's height, so the chart and list fill it
     rather than growing past the bottom of the window. */
  grid-template-rows: minmax(0, 1fr);
  align-items: stretch;
}

.watchlist-page > * { min-height: 0; }

.watchlist-page .watchlist-chart .price-chart-canvas { min-height: 0; }

.watchlist-page .watchlist-chart,
.watchlist-page .watchlist-chart .price-chart {
  height: 100%;
}

.watchlist-page .watchlist-chart .price-chart {
  display: flex;
  flex-direction: column;
}

.watchlist-page .watchlist-chart .price-chart-canvas {
  flex: 1 1 auto;
  height: auto;
  min-height: 280px;
}

.watchlist-page .watchlist-side {
  display: flex;
  flex-direction: column;
  min-height: 0;
}

/* Drag handle between the list and the details panel. */
.watchlist-splitter {
  flex: none;
  height: 8px;
  cursor: row-resize;
  position: relative;
  touch-action: none;
}

.watchlist-splitter::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 36px;
  height: 4px;
  border-radius: 2px;
  background-color: var(--tv-border);
  transform: translate(-50%, -50%);
  transition: background-color 0.15s;
}

.watchlist-splitter:hover::after,
.watchlist-splitter:active::after { background-color: var(--tv-muted); }

/* List on top (scrolls), details below (scrolls, up to about half). */
.watchlist-page .watchlist {
  flex: 1 1 0;
  min-height: 200px;
  display: flex;
  flex-direction: column;
  position: static;
}

.watchlist-page .symbol-info {
  flex: 0 1 auto;
  max-height: 55%;
  overflow-y: auto;
}

.watchlist-page .watchlist-table-wrap {
  flex: 1 1 auto;
  overflow-y: auto;
  min-height: 0;
}

.watchlist-page .watchlist-table thead th {
  position: sticky;
  top: 0;
  background-color: var(--tv-panel);
  z-index: 1;
}

@media (max-width: 992px) {
  .watchlist-page { height: auto; grid-template-rows: none; }
  .watchlist-page .watchlist-chart { height: 60vh; }
  .watchlist-page .watchlist { height: auto; flex: none; }
  .watchlist-page .symbol-info { max-height: none; height: auto !important; }
  .watchlist-splitter { display: none; }
  .watchlist-page .watchlist-side { gap: 0.75rem; }
  .watchlist-page .watchlist-table-wrap { overflow-y: visible; }
}

/* Selected symbol's details (under the watchlist) */
.symbol-info {
  background-color: var(--tv-panel);
  border: 1px solid var(--tv-border);
  border-radius: var(--box-radius);
  padding: 0.75rem;
  color: var(--tv-text);
}

.symbol-info .text-muted-soft { color: var(--tv-muted) !important; }
.tv-list-up { color: var(--tv-list-up); }
.tv-list-down { color: var(--tv-list-down); }

.symbol-info-head {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.symbol-info-symbol { font-size: 1.15rem; font-weight: 700; }

.symbol-info-name { margin-top: 0.6rem; }
.symbol-info-sector { font-size: 0.9rem; }

.symbol-info-price {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.2rem 0.55rem;
  margin-top: 0.6rem;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  font-size: 1.05rem;
}

.symbol-info-last { font-size: 2rem; font-weight: 700; line-height: 1.1; }
.symbol-info-last.small-last { font-size: 1.35rem; }
.symbol-info-ccy { font-size: 0.8rem; color: var(--tv-muted); font-weight: 500; }
.symbol-info-session { color: #2962ff; font-weight: 600; }

.symbol-info-range { margin-top: 1rem; }

.symbol-info-range-top {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: 1.05rem;
  font-variant-numeric: tabular-nums;
  margin-bottom: 0.35rem;
}

.symbol-info-range-label {
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--tv-muted);
}

.symbol-info-range-bar {
  position: relative;
  height: 6px;
  border-radius: 3px;
  background-color: var(--tv-border);
  margin-bottom: 0.9rem; /* room for the ▲ marker */
}

.symbol-info-range-seg {
  position: absolute;
  top: 0;
  bottom: 0;
}

/* ▲ under the track at the current price */
.symbol-info-range-marker {
  position: absolute;
  top: calc(100% + 3px);
  width: 0;
  height: 0;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-bottom: 8px solid var(--tv-text);
  transform: translateX(-50%);
}

.symbol-info-stats-title {
  font-weight: 700;
  margin-top: 1.1rem;
  margin-bottom: 0.35rem;
}

.symbol-info-stats { margin: 0; }

.symbol-info-stats > div {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.3rem 0;
}

.symbol-info-stats dt { font-weight: 400; color: var(--tv-text); }
.symbol-info-stats dd { margin: 0; font-weight: 600; font-variant-numeric: tabular-nums; text-align: right; }

/* Chart owns touch gestures (pan + pinch) where asked, e.g. the phone view. */
.price-chart-canvas.touch-gestures { touch-action: none; }

/* --- Watchlists on phones: one screen at a time ------------------------ */
.watchlist-mobile-bar { display: none; }

@media (max-width: 991.98px) {
  .watchlist-page { padding-top: 0.5rem !important; }

  /* List screen: just the watchlist. */
  .watchlist-page.mobile-list .watchlist-chart,
  .watchlist-page.mobile-list .symbol-info { display: none; }

  /* Symbol screen: back bar, a tall chart, then the details. */
  .watchlist-page.mobile-symbol .watchlist { display: none; }
  /* The chart sets the height and the card grows around it (legend, chart,
     controls), so nothing overlaps while iOS's address bar resizes the
     viewport. */
  .watchlist-page.mobile-symbol .watchlist-chart,
  .watchlist-page.mobile-symbol .watchlist-chart .price-chart { height: auto; }
  .watchlist-page.mobile-symbol .watchlist-chart .price-chart-canvas {
    flex: none;
    min-height: 0;
    height: clamp(240px, 64vh - 150px, 560px);
    height: clamp(240px, 64dvh - 150px, 560px);
  }

  .watchlist-mobile-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    position: sticky;
    top: env(safe-area-inset-top, 0px);
    z-index: 5;
    background-color: var(--bg-primary);
    padding: 0.25rem 0;
  }

  .watchlist-mobile-back {
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
    background: none;
    border: none;
    color: var(--tv-text);
    font-weight: 600;
    font-size: 1rem;
    padding: 0.4rem 0.2rem;
    cursor: pointer;
  }

  .watchlist-mobile-step {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    color: var(--tv-muted);
    font-size: 0.85rem;
    font-variant-numeric: tabular-nums;
  }

  .watchlist-mobile-step button {
    /* Centred by the box, not by the glyph: Safari's default button padding
       and the chevrons' own metrics both pull them off centre otherwise. */
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    width: 2.4rem;
    height: 2.2rem;
    border-radius: 8px;
    border: 1px solid var(--tv-border);
    background-color: var(--tv-panel);
    color: var(--tv-text);
    font-size: 1.3rem;
    line-height: 1;
  }

  .watchlist-mobile-step button:disabled { opacity: 0.35; }

  /* Search, next to the ‹ n / N › stepper. */
  .watchlist-mobile-search {
    margin-left: auto;
    margin-right: 0.5rem;
    width: 2.4rem;
    height: 2.2rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 8px;
    border: 1px solid var(--tv-border);
    background-color: var(--tv-panel);
    color: var(--tv-text);
  }

  /* List screen: search and add as visible bordered buttons (same look as the
     symbol screen's search), not bare glyphs that can get lost on a dark panel. */
  .watchlist-header .watchlist-actions { gap: 0.5rem; }
  .watchlist-header .watchlist-actions .watchlist-icon-btn {
    width: 2.4rem;
    height: 2.2rem;
    border-radius: 8px;
    border: 1px solid var(--tv-border);
    background-color: var(--tv-panel);
    color: var(--tv-text);
  }
  .watchlist-header .watchlist-actions .watchlist-icon-btn,
  .watchlist-mobile-search { --ico: var(--tv-text); }

  /* "+ Add" where the stepper goes, for a symbol that isn't in the list. */
  .watchlist-mobile-add {
    height: 2.2rem;
    padding: 0 0.8rem;
    border-radius: 8px;
    border: 1px solid #2962ff;
    background: none;
    color: #2962ff;
    font-weight: 600;
    font-size: 0.9rem;
    white-space: nowrap;
  }

  /* Tighter chart chrome on a small screen. */
  .watchlist-page .price-chart { padding: 0.5rem 0.6rem !important; }
  .watchlist-page .price-chart-controls { gap: 0.35rem 0.5rem; }
  .watchlist-page .price-chart-range { padding: 0.2rem 0.45rem; }

  /* Bigger touch targets in the list. */
  .watchlist-table td { padding-top: 0.7rem; padding-bottom: 0.7rem; }
}

/* 2. The chart header keeps one line per row at any width, so hovering never
   changes its height: long bits (the hovered timestamp) are cut with "…". */
.price-chart-quote {
  flex-wrap: nowrap;
  white-space: nowrap;
  min-width: 0;
  overflow: hidden;
}

.price-chart-quote > span:last-child {
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

@media (max-width: 576px) {
  .price-chart-ohlc { font-size: 0.78rem; }
  .price-chart-ohlc-row { gap: 0.5rem; }
  .price-chart-quote { gap: 0.35rem; }
  .price-chart-price { font-size: 1.15rem; }
}

/* Let the header's left block shrink to the card, so its rows can clip. */
.price-chart > .d-flex > div:first-child {
  min-width: 0;
  max-width: 100%;
}

/* No two-finger "swipe back" navigation: the app never scrolls sideways, and
   on the chart that gesture is for scrolling through time. */
html,
body {
  overscroll-behavior-x: none;
}

/* Symbol switch: the old chart/details stay, slightly dimmed, until the new
   ones swap in (as in TradingView). */
.price-chart-canvas canvas,
.symbol-info > * { transition: opacity 0.12s ease; }
.price-chart-canvas.is-loading canvas { opacity: 0.55; }
.symbol-info.is-loading > * { opacity: 0.55; }

.price-chart-spinner {
  position: absolute;
  top: 10px;
  left: 10px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 2px solid var(--tv-border);
  border-top-color: var(--tv-text);
  animation: price-chart-spin 0.7s linear infinite;
  pointer-events: none;
}

@keyframes price-chart-spin { to { transform: rotate(360deg); } }

/* TradingView-density watchlist rows: ~14px text, ~34px rows, 20px badges. */
.watchlist-table td {
  font-size: 0.875rem;
  padding-top: 0.3rem;
  padding-bottom: 0.3rem;
}

.watchlist-table th { padding-top: 0.3rem; padding-bottom: 0.3rem; }
.watchlist-table th button { font-size: 0.8rem; }

.watchlist-symbol { gap: 0.5rem; }

.watchlist-badge {
  width: 1.25rem;
  height: 1.25rem;
  font-size: 0.62rem;
}

.watchlist-ext-dot { width: 6px; height: 6px; }

.watchlist-row-actions .watchlist-icon-btn {
  width: 1.5rem;
  height: 1.5rem;
}

@media (max-width: 991.98px) {
  /* Still compact on phones, with a little more room for fingers. */
  .watchlist-table td { font-size: 0.9rem; padding-top: 0.5rem; padding-bottom: 0.5rem; }
}

.watchlist-import {
  flex-basis: 100% !important;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.78rem;
  resize: vertical;
}

.watchlist-import-preview {
  flex-basis: 100%;
  line-height: 1.35;
  /* Never so tall that the buttons under it leave the panel. */
  max-height: 5.4em;
  overflow-y: auto;
}

/* --- Accounts: navbar + sign-in dialog --------------------------------- */
.navbar-signin {
  padding: 4px 12px;
  font-weight: 600;
  font-size: 0.85rem;
}

.navbar-account {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 4px 8px;
  line-height: 1;
}

.navbar-account-email {
  font-size: 0.8rem;
  max-width: 14rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text-secondary);
}

@media (max-width: 768px) {
  .navbar-account-email { display: none; }
}

.signin-backdrop {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  background-color: rgba(0, 0, 0, 0.55);
}

.signin-dialog {
  position: relative;
  width: min(380px, 100%);
  background-color: var(--bg-form);
  border: 1px solid var(--border-color);
  border-radius: var(--box-radius);
  padding: 1.5rem 1.25rem 1.25rem;
  color: var(--text-primary);
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.35);
}

.signin-close {
  position: absolute;
  top: 0.5rem;
  right: 0.6rem;
  background: none;
  border: none;
  color: var(--text-secondary);
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
}

.signin-title {
  font-size: 1.2rem;
  font-weight: 700;
  margin-bottom: 0.5rem;
}

.signin-note {
  font-size: 0.875rem;
  color: var(--text-secondary);
  margin-bottom: 0.9rem;
}

.signin-code {
  font-size: 1.5rem;
  letter-spacing: 0.4em;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.signin-error {
  color: var(--profit-negative);
  font-size: 0.85rem;
  margin-top: 0.5rem;
}

.signin-links {
  display: flex;
  justify-content: space-between;
  margin-top: 0.75rem;
  font-size: 0.85rem;
}

.account-ok { color: var(--profit-positive); }

/* Quick-switch buttons can be dragged to reorder lists. */
.watchlist-quick-btn {
  touch-action: none; /* a drag on a button moves it, not the page */
  user-select: none;
  -webkit-user-select: none;
}

.watchlist-quick-btn.dragging {
  cursor: grabbing;
  transform: scale(1.12);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.35);
  border-color: var(--tv-text);
}

/* Chart controls under the chart, left-aligned (TradingView's range bar). */
.price-chart-footer {
  margin-top: 0.4rem;
  justify-content: flex-start;
}

/* --- Admin panel (like rank-goat's) --------------------------------------- */
.admin-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1rem;
}

.admin-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 0.75rem;
  margin-bottom: 1.5rem;
}

.admin-stat {
  padding: 0.75rem 0.9rem;
  border: 1px solid var(--border-color);
  border-radius: 10px;
  background: var(--bg-secondary);
}

.admin-stat-value {
  font-size: 1.6rem;
  font-weight: 600;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  color: var(--text-primary-strong);
}

.admin-stat-label {
  margin-top: 0.2rem;
  font-size: 0.85rem;
  color: var(--text-secondary);
}

.admin-stat-hint {
  margin-top: 0.15rem;
  font-size: 0.75rem;
  color: var(--text-muted-soft);
}

.admin-section { margin-bottom: 1.5rem; }

.admin-section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.5rem;
}

.admin-search { max-width: 240px; }

.admin-table td { font-size: 0.95rem; }
/* Plain headers match the sortable ones (whose buttons the list styles size). */
.admin-table th { text-align: left; color: var(--tv-muted); font-size: 0.8rem; font-weight: 400; }
.admin-table th button { font-weight: 400; }
.admin-table th.num button { width: 100%; text-align: right; }
.admin-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
.admin-email { max-width: 260px; overflow: hidden; text-overflow: ellipsis; }

.admin-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.admin-chip {
  padding: 0.2rem 0.6rem;
  border: 1px solid var(--border-color);
  border-radius: 999px;
  font-size: 0.85rem;
  color: var(--text-secondary);
}

.admin-chip b { color: var(--text-primary); font-weight: 600; margin-left: 0.15rem; }

/* --- Navbar account menu (like rank-goat's) ------------------------------ */
.user-menu-wrap {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.user-menu-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  padding: 0;
  border-radius: 50%;
  border: 1px solid var(--border-color);
  background: none;
  color: var(--text-primary);
  cursor: pointer;
}

.user-menu-btn.has-account { border: none; }
.user-menu-btn:hover { background-color: rgba(128, 128, 128, 0.15); }

.user-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  flex-shrink: 0;
  border-radius: 50%;
  background-color: #2962ff;
  color: #fff;
  font-weight: 700;
  font-size: 0.9rem;
}

.user-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 1000;
  min-width: 220px;
  padding: 0.35rem;
  background-color: var(--bg-form);
  border: 1px solid var(--border-color);
  border-radius: var(--box-radius);
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.35);
}

.user-menu-header {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.45rem 0.55rem;
}

.user-menu-email {
  font-size: 0.85rem;
  color: var(--text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 13rem;
}

.user-menu-item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  padding: 0.5rem 0.55rem;
  border: none;
  border-radius: 4px;
  background: none;
  color: var(--text-primary);
  font-size: 0.9rem;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}

.user-menu-item:hover { background-color: rgba(128, 128, 128, 0.15); color: var(--text-primary); }
.user-menu-item.active { color: var(--text-primary); font-weight: 600; }
.user-menu-item svg { color: var(--text-secondary); flex-shrink: 0; }
.user-menu-signout, .user-menu-signout svg { color: var(--profit-negative); }

.user-menu-divider {
  height: 1px;
  margin: 0.3rem 0;
  background-color: var(--border-color);
}

/* Chart legend: one wide line (symbol · price · change · when · ext hours),
   then OHLC. Clipped, not wrapped, on wide screens so hovering can't change
   its height; on phones the extended-hours part drops to its own line. */
/* It floats in front of the plot's top-left, the way TradingView's does,
   rather than taking a row above it. The chart reserves no space for it, so
   the candles run under it; scaling the price axis moves them clear. Clicks
   fall through to the chart, except on the controls inside the legend. */
.price-chart-legend {
  position: absolute;
  top: 0.2rem;
  left: 0.5rem;
  right: 0.5rem;
  z-index: 6;
  min-width: 0;
  pointer-events: none;
}

/* Everything you can actually operate takes its clicks back. Keep this list
   in step with the legend's contents: the shares box went missing from it
   once, and the field silently stopped accepting input. */
.price-chart-legend button,
.price-chart-legend a,
.price-chart-legend input,
.price-chart-legend select,
.price-chart-legend textarea,
.price-chart-legend label,
.price-chart-legend .price-chart-ind-actions {
  pointer-events: auto;
}

.price-chart-headline {
  display: flex;
  align-items: baseline;
  gap: 0.25rem 0.9rem;
  white-space: nowrap;
  overflow: hidden;
  font-variant-numeric: tabular-nums;
}

.price-chart-symbol { font-weight: 700; font-size: 1.05rem; color: var(--tv-text); }
.price-chart-name { font-size: 0.85rem; overflow: hidden; text-overflow: ellipsis; min-width: 0; flex-shrink: 1; }
.price-chart-headline .price-chart-quote { display: inline-flex; align-items: baseline; gap: 0.5rem; flex-shrink: 0; overflow: visible; }
.price-chart-when { font-size: 0.8rem; }
.price-chart-ext { font-size: 0.85rem; flex-shrink: 0; padding-left: 0.9rem; border-left: 1px solid var(--tv-border); }

/* Narrow charts — phones, or one half of a split view — use fixed lines
   (symbol + name / price + change + when / ext), each clipped, so a longer
   hover timestamp can't add a line. Sized by the chart, not the window. */
.price-chart { container-type: inline-size; }

@container (max-width: 640px) {
  .price-chart-headline { flex-wrap: wrap; }
  .price-chart-headline .price-chart-quote { flex-basis: 100%; min-width: 0; overflow: hidden; }
  .price-chart-when { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
  .price-chart-ext { flex-basis: 100%; padding-left: 0; border-left: none; }
}

/* --- Indicators ---------------------------------------------------------- */
.price-chart-indicators { position: relative; }
.price-chart-fx { font-style: italic; font-weight: 700; margin-right: 0.15rem; }
.price-chart-fx-btn { white-space: nowrap; }
/* On phones the navbar has room for the ƒx alone. */
@media (max-width: 576px) {
  .navbar-tools .price-chart-fx-label { display: none; }
}

.price-chart-ind-menu {
  position: absolute;
  bottom: calc(100% + 6px);
  left: 0;
  z-index: 40;
  min-width: 300px;
  white-space: nowrap;
  padding: 0.35rem;
  background-color: var(--tv-panel);
  border: 1px solid var(--tv-border);
  border-radius: var(--box-radius);
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.35);
}

/* In a navbar or toolbar the menu opens downward. */
.price-chart-ind-menu.below { top: calc(100% + 6px); bottom: auto; }
.price-chart-ind-menu .user-menu-item { color: var(--tv-text); }
.price-chart-ind-menu .user-menu-item:hover { background-color: var(--tv-grid); }

.price-chart-ind-check { display: inline-block; width: 1rem; color: #2962ff; font-weight: 700; }

/* An indicator pane under the price chart (RSI): its own scale, the same
   time axis, with its legend row over the top-left corner. */
.price-chart-pane {
  position: relative;
  flex: none;
  height: 120px;
  margin-top: 0.25rem;
  border-top: 1px solid var(--tv-border);
}
.price-chart-pane canvas { cursor: crosshair; }
.price-chart-pane { touch-action: pan-y; }
.price-chart-pane.touch-gestures { touch-action: none; }
.price-chart-pane.is-loading canvas { opacity: 0.55; }
/* `right` is a starting value only: fitLegend() replaces it with the pane's
   own axis width, so a long row clips at the plot's edge instead of running
   under the numbers. The same goes for .price-chart-legend above. */
.price-chart-pane-legend {
  position: absolute;
  top: 0.2rem;
  left: 0.25rem;
  right: 0.5rem;
  z-index: 2;
  pointer-events: none;
}
.price-chart-pane-legend .price-chart-ind { margin-top: 0; }
.price-chart-pane-legend .price-chart-ind-actions { pointer-events: auto; }
@media (max-width: 576px) {
  .price-chart-pane { height: 100px; }
}

.price-chart-ind {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  white-space: nowrap;
  overflow: hidden;
  font-variant-numeric: tabular-nums;
  margin-top: 0.1rem;
}

.price-chart-ind.off > :not(.price-chart-ind-actions) { opacity: 0.45; }
.price-chart-ind-name { font-weight: 600; color: var(--tv-text); }

.price-chart-ind-actions { display: inline-flex; gap: 0.1rem; }

/* Position row: shares input, then cost / value / gain-loss segments. */
.price-chart-position > span { white-space: nowrap; }
/* No hover on touch screens, so no cursor segment appearing and disappearing:
   the row can wrap onto more lines without the legend's height jumping. */
@media (hover: none) {
  .price-chart-position { flex-wrap: wrap; white-space: normal; row-gap: 0.15rem; }
}
.price-chart-shares {
  width: 5.5rem;
  padding: 0.05rem 0.4rem;
  font: inherit;
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
  background-color: var(--tv-panel);
  color: var(--tv-text);
  border: 1px solid var(--tv-border);
  border-radius: 4px;
  -moz-appearance: textfield;
  appearance: textfield;
}
.price-chart-shares:focus { outline: none; border-color: #2962ff; }
.price-chart-shares::placeholder { color: var(--tv-muted); }
.price-chart-shares::-webkit-outer-spin-button,
.price-chart-shares::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.price-chart-ind-actions button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.4rem;
  height: 1.4rem;
  border: none;
  border-radius: 4px;
  background: none;
  color: var(--tv-muted);
  cursor: pointer;
  line-height: 1;
}
.price-chart-ind-actions button:hover { background-color: var(--tv-grid); color: var(--tv-text); }

/* Indicator settings dialog (TradingView-like). */
.ind-dialog { width: min(420px, 100%); max-height: 90vh; overflow-y: auto; }
.ind-tabs { display: flex; gap: 1.2rem; border-bottom: 1px solid var(--border-color); margin-bottom: 0.75rem; }
.ind-tab { background: none; border: none; padding: 0.4rem 0; color: var(--text-secondary); font-weight: 600; border-bottom: 2px solid transparent; cursor: pointer; }
.ind-tab.active { color: var(--text-primary); border-bottom-color: var(--text-primary); }
.ind-body { display: flex; flex-direction: column; gap: 0.6rem; }
.ind-section { font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-secondary); margin-top: 0.4rem; }
.ind-row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; font-size: 0.9rem; }
.ind-row .form-control { width: 11rem; flex-shrink: 0; }
.ind-inline { display: inline-flex; gap: 0.4rem; align-items: center; }
.ind-inline .form-control { width: 6rem; }
.ind-check { display: flex; align-items: center; gap: 0.5rem; font-size: 0.9rem; cursor: pointer; }
.ind-dialog input[type="color"] { width: 2.4rem; height: 1.8rem; padding: 0; border: 1px solid var(--border-color); border-radius: 4px; background: none; }
.ind-footer { display: flex; justify-content: space-between; margin-top: 1rem; }

/* Right end of the chart's bottom bar: live clock + data freshness. */
.price-chart-clock {
  order: 99;
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  font-size: 0.8rem;
  color: var(--tv-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  cursor: default;
}

.price-chart-clock-time { color: var(--tv-text); }

.price-chart-fresh { display: inline-flex; align-items: center; gap: 0.35rem; }

.price-chart-fresh-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background-color: var(--tv-up);
}

.price-chart-fresh.fresh .price-chart-fresh-dot { box-shadow: 0 0 0 3px rgba(8, 153, 129, 0.2); }
.price-chart-fresh.stale { color: #f5a623; }
.price-chart-fresh.stale .price-chart-fresh-dot { background-color: #f5a623; }
.price-chart-fresh.paused .price-chart-fresh-dot { background-color: var(--tv-muted); }
button.price-chart-fresh {
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  padding: 0.15rem 0.4rem;
  margin: -0.15rem -0.4rem;
  border-radius: 4px;
  cursor: pointer;
}
button.price-chart-fresh:hover { background: var(--tv-hover); color: var(--tv-text); }
button.price-chart-fresh:disabled { cursor: progress; }
.price-chart-fresh.pending .price-chart-fresh-dot { background-color: var(--tv-muted); animation: fresh-pulse 0.8s ease-in-out infinite alternate; }
@keyframes fresh-pulse { from { opacity: 0.3; } to { opacity: 1; } }

@media (max-width: 576px) {
  /* On phones the bar wraps; the clock takes its own row, left-aligned. */
  .price-chart-clock { margin-left: 0; flex-basis: 100%; }
}

/* --- Watchlists: resizable list column + split view ---------------------- */
.watchlist-page {
  grid-template-columns: minmax(0, 1fr) 10px var(--side-w, 380px);
  column-gap: 0;
}

/* Vertical divider between the chart(s) and the list. */
.watchlist-vsplitter {
  position: relative;
  cursor: col-resize;
  touch-action: none;
  height: 100%;
}

.watchlist-vsplitter::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 4px;
  height: 36px;
  border-radius: 2px;
  background-color: var(--tv-border);
  transform: translate(-50%, -50%);
  transition: background-color 0.15s;
}

.watchlist-vsplitter:hover::after,
.watchlist-vsplitter:active::after { background-color: var(--tv-muted); }

/* One or two chart panes filling the chart area. */
.watchlist-pane { height: 100%; min-width: 0; min-height: 0; }

.watchlist-panes { flex: 1 1 auto; min-height: 0; }
.watchlist-panes.split { display: grid; gap: 0.5rem; }
.watchlist-panes.split-cols { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.watchlist-panes.split-rows { grid-template-rows: minmax(0, 1fr) minmax(0, 1fr); }
.watchlist-panes.split-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); grid-template-rows: minmax(0, 1fr) minmax(0, 1fr); }

/* Two rows of charts: each canvas may be shorter than a lone chart's 280px,
   or in a short window the top row would run into the bottom one. The page
   also keeps a taller minimum for these layouts (see the fit effect). */
.watchlist-page .watchlist-panes.split-rows .price-chart-canvas,
.watchlist-page .watchlist-panes.split-grid .price-chart-canvas { min-height: 140px; }

/* The active chart (where list clicks go) gets a blue outline. */
.watchlist-pane.active .price-chart { box-shadow: 0 0 0 1px #2962ff; border-color: #2962ff; }

/* The other chart's symbol is marked lightly in the list. */
.watchlist-table tbody tr.selected-other { box-shadow: inset 3px 0 0 var(--tv-muted); }

/* The page's tools in the navbar: the indicators menu, then the saved
   layouts picker and the layout buttons. The demo frame has no navbar and
   shows them in a row above the chart instead. */
.watchlist-toolbar {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  flex: none;
}
.watchlist-layouts {
  display: inline-flex;
  align-items: center;
  gap: 0.1rem;
}
.watchlist-layout-btn { width: 1.8rem; height: 1.8rem; color: var(--text-secondary); }
.watchlist-layout-btn:hover { color: var(--text-primary); }
.watchlist-layout-btn.active { color: var(--text-primary); background-color: rgba(128, 128, 128, 0.18); }

/* Saved layouts menu, left of the layout buttons. */
.layout-picker { position: relative; display: inline-flex; margin-right: 0.15rem; }
.layout-picker-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  height: 1.8rem;
  max-width: 11rem;
  padding: 0 0.5rem;
  border: none;
  border-radius: 6px;
  background: none;
  color: var(--text-secondary);
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
}
.layout-picker-btn:hover, .layout-picker-btn[aria-expanded="true"] { color: var(--text-primary); background-color: rgba(128, 128, 128, 0.18); }
.layout-picker-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.watchlist-menu.layout-menu { left: 0; right: auto; min-width: 260px; z-index: 40; }
.layout-menu-empty { padding: 0.45rem 0.6rem 0.6rem; line-height: 1.35; }
.layout-menu-row { display: flex; align-items: center; }
.layout-menu-row .watchlist-menu-item { flex: 1 1 auto; min-width: 0; gap: 0.75rem; }
.layout-menu-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.layout-menu-del {
  flex-shrink: 0;
  width: 1.7rem;
  height: 1.7rem;
  border: none;
  border-radius: 6px;
  background: none;
  color: var(--text-secondary);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  opacity: 0.6;
}
.layout-menu-del:hover { opacity: 1; color: var(--profit-negative); background-color: rgba(128, 128, 128, 0.15); }
.layout-menu-form { display: flex; gap: 0.4rem; padding: 0.3rem; }
.layout-menu-note { padding: 0.35rem 0.6rem 0.45rem; line-height: 1.35; }
.layout-menu-link { border: none; background: none; padding: 0; color: #2962ff; font: inherit; cursor: pointer; }
.layout-menu-link:hover { text-decoration: underline; }
.layout-menu-form .btn-action { white-space: nowrap; padding: 0.2rem 0.7rem; }

@media (max-width: 992px) {
  .watchlist-page { grid-template-columns: minmax(0, 1fr); }
  .watchlist-vsplitter, .watchlist-layouts { display: none; }
}

/* Watchlist chart area: the chart(s), then one shared control bar. */
.watchlist-page .watchlist-chart {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-height: 0;
}

.watchlist-controls {
  flex: none;
  background-color: var(--tv-bg);
  border: 1px solid var(--tv-border);
  border-radius: var(--box-radius);
  padding: 0.4rem 0.6rem;
}

.watchlist-controls .price-chart-footer { margin-top: 0; }
.watchlist-controls .price-chart-range { color: var(--tv-muted); }
.watchlist-controls .price-chart-range.active { background-color: var(--tv-grid); border-color: var(--tv-border); color: var(--tv-text); }

/* List column hidden: the chart takes the full width; the divider stays at
   the right edge with a button to bring the list back. */
.watchlist-page.side-collapsed { grid-template-columns: minmax(0, 1fr) 22px 0; }
.watchlist-page.side-collapsed .watchlist-side { display: none; }

.watchlist-vsplitter.collapsed::after { display: none; }

.watchlist-vsplitter-open {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 20px;
  height: 44px;
  padding: 0;
  border: 1px solid var(--tv-border);
  border-radius: var(--box-radius);
  background-color: var(--tv-panel);
  color: var(--tv-text);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
}

.watchlist-vsplitter-open:hover { background-color: var(--tv-grid); }

@media (max-width: 992px) {
  .watchlist-page.side-collapsed { grid-template-columns: minmax(0, 1fr); }
  .watchlist-page.side-collapsed .watchlist-side { display: flex; }
}

/* ⊕ beside the crosshair price (TradingView): alerts and levels at a price. */
.price-chart-plus {
  position: absolute;
  z-index: 7;
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: none;
  border-radius: 4px;
  background-color: var(--tv-text);
  color: var(--tv-bg);
  cursor: pointer;
  opacity: 0.92;
}

.price-chart-plus:hover { opacity: 1; }

.price-chart-plus-menu {
  position: absolute;
  z-index: 8;
  min-width: 220px;
  padding: 0.35rem;
  background-color: var(--tv-panel);
  border: 1px solid var(--tv-border);
  border-radius: var(--box-radius);
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.35);
}

.price-chart-plus-head {
  padding: 0.3rem 0.55rem 0.4rem;
  font-size: 0.78rem;
  color: var(--tv-muted);
  font-variant-numeric: tabular-nums;
}

.price-chart-plus-swatch { width: 10px; height: 10px; border-radius: 2px; flex-shrink: 0; }
.price-chart-plus-remove { color: var(--tv-muted); font-size: 0.85rem; }

/* Triggered price alerts */
.alert-notices {
  position: fixed;
  right: 16px;
  bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  z-index: 2000;
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: min(380px, calc(100vw - 32px));
}
.alert-notice {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 8px;
  border-left: 4px solid #FF9800;
  background: var(--bg-primary);
  border-top: 1px solid var(--border-color);
  border-right: 1px solid var(--border-color);
  border-bottom: 1px solid var(--border-color);
  color: var(--text-primary);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);
  font-size: 0.9rem;
}
.alert-notice-close {
  margin-left: auto;
  border: 0;
  background: none;
  color: inherit;
  opacity: 0.6;
  font-size: 1.2rem;
  line-height: 1;
  cursor: pointer;
}
.alert-notice-close:hover { opacity: 1; }

/* OHLC on the symbol line (compact legend). When the line is too narrow for
   symbol, name and O H L C at their natural widths, the OHLC block moves to
   the next line whole (volume follows below it) instead of clipping the name. */
.price-chart-headline .price-chart-ohlc { margin-top: 0; font-size: 0.85rem; min-width: 0; }
.price-chart-legend.compact .price-chart-headline { flex-wrap: wrap; }
.price-chart-legend.compact .price-chart-ohlc { flex-shrink: 0; }
.price-chart-legend.compact .price-chart-name { flex-shrink: 1; }
/* Volume sits on its own line, flush with the symbol, instead of indenting
   under the O of the row it used to share. */
.price-chart-legend.compact .price-chart-vol {
  margin-top: 0;
  font-size: 0.85rem;
}

/* --- Symbol search (TradingView-style) ------------------------------------ */
.symbol-search-backdrop { align-items: flex-start; padding-top: max(8vh, calc(env(safe-area-inset-top, 0px) + 1rem)); }
.symbol-search {
  width: min(640px, 100%);
  max-height: min(70vh, 640px);
  display: flex;
  flex-direction: column;
  background-color: var(--tv-bg, var(--bg-primary));
  color: var(--tv-text, var(--text-primary));
  border: 1px solid var(--tv-border, var(--border-color));
  border-radius: 10px;
  box-shadow: 0 16px 48px rgba(0, 0, 0, 0.45);
  overflow: hidden;
}
.symbol-search-head {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.7rem 0.9rem;
  border-bottom: 1px solid var(--tv-border, var(--border-color));
  color: var(--tv-muted);
}
.symbol-search-input {
  flex: 1 1 auto;
  min-width: 0;
  border: none;
  outline: none;
  background: none;
  color: var(--tv-text, var(--text-primary));
  font-size: 1.1rem;
  font-weight: 600;
  text-transform: uppercase;
}
.symbol-search-input::placeholder { text-transform: none; font-weight: 400; color: var(--tv-muted); }
.symbol-search-close { border: none; background: none; color: var(--tv-muted); font-size: 1.4rem; line-height: 1; cursor: pointer; }
.symbol-search-close:hover { color: var(--tv-text); }
.symbol-search-results { overflow-y: auto; padding: 0.3rem 0; }
.symbol-search-row {
  display: grid;
  grid-template-columns: auto 6.5rem minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 0.75rem;
  padding: 0.45rem 0.9rem;
  cursor: pointer;
}
.symbol-search-row.active { background-color: var(--tv-hover); }
.symbol-search-symbol { font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.symbol-search-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.symbol-search-meta { font-size: 0.8rem; color: var(--tv-muted); white-space: nowrap; text-align: right; }
.symbol-search-add {
  width: 1.8rem;
  height: 1.8rem;
  border: 1px solid var(--tv-border, var(--border-color));
  border-radius: 6px;
  background: none;
  color: var(--tv-text, var(--text-primary));
  font-size: 1.05rem;
  line-height: 1;
  cursor: pointer;
}
.symbol-search-add:hover:not(:disabled) { background-color: #2962ff; border-color: #2962ff; color: #fff; }
.symbol-search-add.added { border-color: transparent; color: var(--tv-up, var(--profit-positive)); cursor: default; }
.symbol-search-hint { padding: 0.9rem; color: var(--tv-muted); font-size: 0.9rem; }
.symbol-search-status {
  padding: 0.45rem 0.9rem;
  font-size: 0.85rem;
  color: var(--tv-up, var(--profit-positive));
  border-bottom: 1px solid var(--tv-border, var(--border-color));
}
.symbol-search-status.error { color: var(--tv-down, var(--profit-negative)); }
/* The "add all" row spans the symbol, name and meta columns. */
.symbol-search-bulk { grid-column: 2 / 5; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.symbol-search-foot {
  display: flex;
  gap: 1rem;
  padding: 0.5rem 0.9rem;
  border-top: 1px solid var(--tv-border, var(--border-color));
}
.symbol-search-foot kbd {
  font-family: inherit;
  font-size: 0.72rem;
  padding: 0.05rem 0.3rem;
  margin-right: 0.2rem;
  border: 1px solid var(--tv-border, var(--border-color));
  border-radius: 4px;
  background: none;
  color: inherit;
}
@media (max-width: 576px) {
  .symbol-search-row { grid-template-columns: auto 5rem minmax(0, 1fr) auto; }
  .symbol-search-meta, .symbol-search-foot { display: none; }
  .symbol-search-bulk { grid-column: 2 / 4; }
}
@media (hover: none) {
  .symbol-search-foot { display: none; }
}

/* Click the chart's symbol to search. */
.price-chart-symbol-btn {
  border: none;
  background: none;
  padding: 0.05rem 0.3rem;
  margin: -0.05rem -0.3rem;
  border-radius: 4px;
  cursor: pointer;
  font: inherit;
  font-weight: 700;
  font-size: 1.05rem;
}
.price-chart-symbol-btn:hover { background-color: var(--tv-hover); }

/* Details of a looked-up symbol that isn't in the list. */
.symbol-info-add {
  margin-left: auto;
  border: 1px solid #2962ff;
  border-radius: 6px;
  background: none;
  color: #2962ff;
  font-size: 0.82rem;
  font-weight: 600;
  padding: 0.2rem 0.6rem;
  white-space: nowrap;
  cursor: pointer;
  max-width: 60%;
  overflow: hidden;
  text-overflow: ellipsis;
}
.symbol-info-add:hover { background-color: #2962ff; color: #fff; }
.symbol-info-remove { border-color: var(--tv-border, var(--border-color)); color: var(--tv-muted, var(--text-secondary)); }
.symbol-info-remove:hover { background-color: var(--tv-down, var(--profit-negative)); border-color: var(--tv-down, var(--profit-negative)); color: #fff; }

/* The newest story, as a card high in the panel next to the price. */
.symbol-info-latest {
  display: block;
  margin: 0.75rem 0 0.25rem;
  padding: 0.6rem 0.7rem;
  border-radius: 8px;
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  color: inherit;
  text-decoration: none;
}
.symbol-info-latest:hover {
  color: inherit;
  text-decoration: none;
  border-color: var(--text-muted-soft);
}
.symbol-info-latest-meta {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.78rem;
}
.symbol-info-latest-tag { color: var(--tv-accent, #7c6cf0); font-weight: 600; }
.symbol-info-latest-title {
  margin-top: 0.25rem;
  font-size: 0.92rem;
  font-weight: 500;
  line-height: 1.35;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.symbol-info-latest-more {
  display: inline-block;
  margin-top: 0.4rem;
  font-size: 0.78rem;
}

/* Details panel: company description ("About") */
/* News feed under the stats, like TradingView's: source · age, headline,
   thumbnail on the right. Rows are links; the whole row highlights. */
.symbol-info-news { margin-top: 1rem; }
.symbol-info-news-list { list-style: none; margin: 0 -0.5rem; padding: 0; }
.symbol-info-news-item {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 0.5rem;
  border-radius: 6px;
  color: inherit;
  text-decoration: none;
}
.symbol-info-news-item:hover { background: var(--tv-hover, rgba(128, 128, 128, 0.12)); color: inherit; text-decoration: none; }
.symbol-info-news-body { flex: 1 1 auto; min-width: 0; }
.symbol-info-news-meta { font-size: 0.78rem; display: flex; gap: 0.35rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.symbol-info-news-source { overflow: hidden; text-overflow: ellipsis; }
.symbol-info-news-title {
  margin-top: 0.15rem;
  font-size: 0.9rem;
  font-weight: 500;
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.symbol-info-news-thumb {
  flex: 0 0 auto;
  width: 56px;
  height: 56px;
  object-fit: cover;
  border-radius: 4px;
  background: rgba(128, 128, 128, 0.15);
}
.symbol-info-news .btn-link-inline { color: #2962ff; text-decoration: none; margin-top: 0.25rem; }
.symbol-info-news .btn-link-inline:hover { text-decoration: underline; }

.symbol-info-about { margin-top: 1rem; }
.symbol-info-desc {
  margin: 0.3rem 0 0.2rem;
  font-size: 0.85rem;
  line-height: 1.4;
  color: var(--tv-text, var(--text-primary));
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 5;
  line-clamp: 5;
  overflow: hidden;
}
.symbol-info-desc.open { display: block; -webkit-line-clamp: unset; line-clamp: unset; }
.symbol-info-about dd a { color: #2962ff; text-decoration: none; }
.symbol-info-about dd a:hover { text-decoration: underline; }
.symbol-info-about .btn-link-inline { color: #2962ff; text-decoration: none; }
.symbol-info-about .btn-link-inline:hover { text-decoration: underline; }

/* Watchlist: pre-market / after-hours line under a row's numbers */
.watchlist-ext {
  margin-top: 0.1rem;
  font-size: 0.78rem;
  line-height: 1.2;
  color: var(--tv-text, var(--text-primary));
  white-space: nowrap;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 0.3rem;
}
.watchlist-ext.profit-positive { color: var(--tv-list-up, var(--profit-positive)); }
.watchlist-ext.profit-negative { color: var(--tv-list-down, var(--profit-negative)); }
.watchlist-ext-icon { flex-shrink: 0; }
.watchlist-ext-icon.pre { color: #f5a623; }
.watchlist-ext-icon.post { color: #7b8cff; }
.watchlist-table td { vertical-align: top; }

/* --- /login page: the sign-in dialog as a page ------------------------------ */
.login-page { min-height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1.5rem; padding: 2rem 1rem; }
.login-brand { display: inline-flex; align-items: center; gap: 0.55rem; font-size: 1.4rem; font-weight: 700; color: var(--text-primary); text-decoration: none; }
.login-mark { flex: 0 0 auto; display: block; }
.login-card { position: relative; width: min(420px, 100%); }

/* A live tick flashes the price cell, like TradingView. */
@keyframes flash-up { from { background-color: rgba(34, 171, 148, 0.35); } to { background-color: transparent; } }
@keyframes flash-down { from { background-color: rgba(247, 82, 95, 0.35); } to { background-color: transparent; } }
.watchlist-table td.flash-up { animation: flash-up 0.7s ease-out; }
.watchlist-table td.flash-down { animation: flash-down 0.7s ease-out; }

/* The chart clock while ticks are arriving. */
.price-chart-fresh.live { color: var(--tv-list-up); }
.price-chart-fresh.live .price-chart-fresh-dot { background: var(--tv-list-up); box-shadow: 0 0 0 3px rgba(34, 171, 148, 0.2); }
.price-chart-fresh.live.ticking .price-chart-fresh-dot { animation: live-pulse 1.6s infinite; }
@keyframes live-pulse { 0% { box-shadow: 0 0 0 0 rgba(34, 171, 148, 0.6); } 100% { box-shadow: 0 0 0 7px rgba(34, 171, 148, 0); } }

/* Ready-made lists inside the list menu: indented under their toggle. */
.watchlist-menu-item.template { padding-left: 1.4rem; }

/* Touch screens: the ⊕ appears on a tap (no hover), so it is always fully visible
   and a little easier to hit. */
@media (hover: none) {
  .price-chart-plus { opacity: 1; width: 26px; height: 26px; margin: -2px 0 0 -2px; }
}

/* News reader over the chart. Covers the chart area only (not the whole
   page), so the watchlist stays visible and in place beside it. */
.news-overlay {
  position: absolute;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: stretch;
  justify-content: center;
  padding: 0.5rem;
  background: rgba(0, 0, 0, 0.45);
  border-radius: inherit;
}

.news-overlay-card {
  display: flex;
  flex-direction: column;
  width: min(560px, 100%);
  max-height: 100%;
  background: var(--tv-bg, var(--bg-primary));
  border: 1px solid var(--tv-border, var(--border-color));
  border-radius: 10px;
  overflow: hidden;
}

.news-overlay-top {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.5rem 0.4rem 0.5rem 0.8rem;
  border-bottom: 1px solid var(--tv-border, var(--border-color));
}

.news-overlay-meta {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.78rem;
  min-width: 0;
}

.news-overlay-source {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.news-overlay-close {
  flex: none;
  background: none;
  border: none;
  color: var(--text-secondary);
  font-size: 1.4rem;
  line-height: 1;
  padding: 0.1rem 0.5rem;
  border-radius: 6px;
  cursor: pointer;
}

.news-overlay-close:hover {
  background: var(--bg-secondary);
  color: var(--text-primary);
}

.news-overlay-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 0.9rem;
}

.news-overlay-img {
  width: 100%;
  max-height: 220px;
  object-fit: cover;
  border-radius: 8px;
  margin-bottom: 0.75rem;
  background: rgba(128, 128, 128, 0.15);
}

.news-overlay-title {
  margin: 0;
  font-size: 1.15rem;
  font-weight: 600;
  line-height: 1.3;
}

.news-overlay-tickers {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: 0.6rem;
}

.news-overlay-ticker {
  font-size: 0.75rem;
  padding: 0.1rem 0.45rem;
  border-radius: 4px;
  background: rgba(128, 128, 128, 0.18);
}

.news-overlay-read {
  display: inline-block;
  margin-top: 0.9rem;
  padding: 0.45rem 0.9rem;
  border-radius: 6px;
  font-weight: 500;
  text-decoration: none;
  color: #fff;
  background: var(--tv-accent, #7c6cf0);
}

.news-overlay-read:hover {
  color: #fff;
  text-decoration: none;
  filter: brightness(1.08);
}

.news-overlay-note {
  margin: 0.5rem 0 0;
  font-size: 0.75rem;
  line-height: 1.4;
}

.news-overlay-more {
  margin-top: 1.1rem;
  border-top: 1px solid var(--tv-border, var(--border-color));
  padding-top: 0.7rem;
}

.news-overlay-more-title {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--text-secondary);
  margin-bottom: 0.3rem;
}

.news-overlay-more-list {
  list-style: none;
  margin: 0 -0.4rem;
  padding: 0;
}

.news-overlay-more-item {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  color: inherit;
  padding: 0.4rem;
  border-radius: 6px;
  cursor: pointer;
}

.news-overlay-more-item:hover {
  background: var(--tv-hover, rgba(128, 128, 128, 0.12));
}

.news-overlay-more-meta {
  display: block;
  font-size: 0.72rem;
}

.news-overlay-more-headline {
  display: block;
  font-size: 0.85rem;
  line-height: 1.3;
  margin-top: 0.1rem;
}

@media (max-width: 640px) {
  .news-overlay { padding: 0; }
  .news-overlay-card { width: 100%; border-radius: 0; border: none; }
}
