/* ============================================================
   AES INVESTOMANIA — Component Library
   ============================================================ */

/* ---------- Glass surface ---------- */
.glass {
  background: var(--glass-surface);
  backdrop-filter: blur(18px) saturate(125%);
  -webkit-backdrop-filter: blur(18px) saturate(125%);
  border: 1px solid var(--glass-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-soft), inset 0 1px 0 var(--glass-highlight);
}

/* A card is a slightly raised plane, not a pane of frosted glass.
   Backdrop blur is reserved for surfaces that actually sit OVER
   something (the top bar, modals, toasts) — everywhere else it costs
   a compositor layer per card and buys nothing visually. */
.card {
  background: linear-gradient(180deg, rgba(255,250,240,0.045), rgba(255,250,240,0.022));
  border: 1px solid var(--glass-border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  box-shadow: inset 0 1px 0 var(--glass-highlight);
  transition:
    border-color var(--dur-base) var(--ease-standard),
    transform var(--dur-slow) var(--ease-emphasis),
    box-shadow var(--dur-slow) var(--ease-emphasis);
}

.card--interactive {
  position: relative;
  overflow: hidden;
}
.card--interactive::before {
  content: "";
  position: absolute;
  inset: -1px;
  background: linear-gradient(115deg, rgba(233, 220, 187,0.09) 0%, transparent 34%);
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease-emphasis);
  pointer-events: none;
}
.card--interactive:hover::before { opacity: 1; }
.card--interactive:hover {
  border-color: var(--hairline-strong);
  transform: translateY(-2px);
  box-shadow: var(--shadow-lift), inset 0 1px 0 var(--glass-highlight);
}
.card--interactive:active {
  transform: translateY(-1px) scale(0.995);
  transition-duration: var(--dur-fast);
}

.card--gold-edge {
  border-color: rgba(198, 164, 100, 0.30);
  box-shadow: var(--shadow-soft), inset 0 1px 0 rgba(233, 220, 187, 0.14);
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  height: 44px;
  padding: 0 var(--space-5);
  border-radius: var(--radius-md);
  border: 1px solid transparent;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.01em;
  transition:
    transform var(--dur-fast) var(--ease-emphasis),
    filter var(--dur-fast) var(--ease-standard),
    background var(--dur-fast) var(--ease-standard),
    border-color var(--dur-fast) var(--ease-standard),
    box-shadow var(--dur-base) var(--ease-emphasis);
  white-space: nowrap;
  position: relative;
}
/* No lift on hover — a button that jumps under the cursor reads as a
   toy. Brightness and shadow carry the state; the press is the only
   thing that moves, and it moves down, like a real key. */
.btn:hover { filter: brightness(1.07); }
.btn:active { transform: translateY(1px) scale(0.994); transition-duration: 70ms; filter: brightness(0.96); }
.btn:disabled { cursor: not-allowed; filter: none; transform: none; }

/* METAL. A struck brass key: bevelled edges, a specular sweep that
   travels on hover, and a cast shadow rather than a glow. */
.btn--primary {
  background: var(--gold-sheen);
  color: var(--on-gold);
  border-color: rgba(110, 84, 36, 0.62);
  box-shadow: var(--metal-bevel), var(--metal-cast);
  text-shadow: 0 1px 0 rgba(246, 238, 214, 0.40);
  overflow: hidden;
  isolation: isolate;
}
.btn--primary::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg, transparent 32%, rgba(255, 252, 240, 0.40) 48%, transparent 62%);
  transform: translateX(-120%);
  transition: transform 620ms var(--ease-emphasis);
  pointer-events: none;
}
.btn--primary:hover::after { transform: translateX(120%); }
.btn--primary:hover { box-shadow: var(--metal-bevel), 0 1px 1px rgba(0,0,0,0.45), 0 8px 20px rgba(110, 84, 36, 0.44); }
.btn--primary:active { box-shadow: var(--metal-bevel), 0 1px 2px rgba(0,0,0,0.5); }
.btn--primary:disabled::after { display: none; }
@media (prefers-reduced-motion: reduce) { .btn--primary::after { display: none; } }
.btn--primary:disabled {
  background: linear-gradient(150deg, #4A4238, #38322A);
  color: rgba(244, 241, 234, 0.34);
  border-color: rgba(232, 220, 196, 0.10);
  box-shadow: none;
  text-shadow: none;
}

/* RELIEF. Raised from the page surface; pressing it pushes it in. */
.btn--ghost {
  background: linear-gradient(180deg, rgba(255,250,240,0.055), rgba(255,250,240,0.022));
  color: var(--text-primary);
  border-color: var(--glass-border);
  box-shadow: var(--relief-raised);
}
.btn--ghost:hover { border-color: var(--hairline-strong); box-shadow: var(--relief-raised-lg); }
.btn--ghost:active { box-shadow: var(--relief-pressed); }

.btn--danger {
  background: rgba(232, 105, 95, 0.13);
  color: var(--negative);
  border-color: rgba(232, 105, 95, 0.34);
}
.btn--danger:hover { background: rgba(232, 105, 95, 0.20); }

.btn--sell {
  background: rgba(232, 105, 95, 0.11);
  color: var(--negative);
  border-color: rgba(232, 105, 95, 0.28);
}
.btn--sell.is-active { background: var(--negative); color: #1A0D0C; border-color: var(--negative); }

.btn--buy.is-active {
  background: var(--gold-sheen);
  color: var(--on-gold);
  border-color: rgba(110, 84, 36, 0.55);
  box-shadow: var(--shadow-gold);
}

.btn--block { width: 100%; }
.btn--sm { height: 34px; padding: 0 var(--space-4); font-size: 13px; }

/* ---------- Top navigation ---------- */
.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  gap: var(--space-6);
  padding: var(--space-3) var(--space-6);
  /* GLASS. The bar genuinely floats over scrolling content, so the
     blur is doing real work here. The gradient plus the two inset
     edges are what stop it reading as flat tinted plastic: a pane of
     glass catches light on its top edge and goes dark where it meets
     what's beneath it. */
  background: linear-gradient(180deg, rgba(28, 25, 22, 0.82), rgba(14, 12, 11, 0.88));
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border-bottom: 1px solid var(--hairline);
  box-shadow: var(--glass-edge), 0 12px 28px -18px rgba(0,0,0,0.9);
}

.topbar__brand {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  font-family: var(--font-display);
}
.topbar__brand-mark { color: var(--gold); font-weight: 800; font-size: 17px; letter-spacing: 0.04em; }
.topbar__brand-text { font-weight: 700; font-size: 13px; letter-spacing: 0.08em; color: var(--text-secondary); }

.topbar__nav { display: flex; align-items: center; gap: var(--space-1); flex: 1; }
.topbar__link {
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text-secondary);
  transition: color var(--dur-fast), background var(--dur-fast);
}
.topbar__link:hover { color: var(--text-primary); background: var(--glass-surface); }
.topbar__link--active {
  /* RELIEF, inset. The current section is the one pressed *into* the
     bar — which is a state you can read without relying on colour. */
  color: var(--gold-pale);
  background: rgba(198, 164, 100, 0.07);
  box-shadow: var(--relief-pressed), inset 0 0 0 1px rgba(198, 164, 100, 0.16);
}

.topbar__actions { display: flex; align-items: center; gap: var(--space-3); }
.topbar__avatar {
  display: flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: 50%;
  background: linear-gradient(135deg, rgba(198, 164, 100, 0.24), rgba(198, 164, 100, 0.06));
  border: 1px solid var(--glass-border);
  font-size: 12px; font-weight: 800; color: var(--gold);
}
.topbar__logout {
  background: transparent; border: 1px solid var(--glass-border);
  color: var(--text-secondary); border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3); font-size: 13px; font-weight: 600;
  transition: all var(--dur-fast);
}
.topbar__logout:hover { color: var(--negative); border-color: rgba(232,105,95,0.42); }

.sound-toggle {
  width: 34px; height: 34px; border-radius: var(--radius-sm);
  background: var(--glass-surface); border: 1px solid var(--glass-border);
  font-size: 15px; display: flex; align-items: center; justify-content: center;
  transition: all var(--dur-fast) var(--ease-standard);
}
.sound-toggle { box-shadow: var(--relief-raised); }
.sound-toggle:hover { border-color: rgba(198, 164, 100, 0.32); color: var(--gold-pale); box-shadow: var(--relief-raised-lg); }
.sound-toggle:active { box-shadow: var(--relief-pressed); }
.sound-toggle:active { transform: scale(0.94); }

.topbar__menu-toggle { display: none; flex-direction: column; gap: 4px; background: none; border: none; padding: 8px; }
.topbar__menu-toggle span { width: 20px; height: 2px; background: var(--text-primary); border-radius: 2px; transition: transform var(--dur-base), opacity var(--dur-base); }
.topbar__menu-toggle--open span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.topbar__menu-toggle--open span:nth-child(2) { opacity: 0; }
.topbar__menu-toggle--open span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

.mobile-nav {
  display: none;
  flex-direction: column;
  background: rgba(13,13,13,0.97);
  border-bottom: 1px solid var(--hairline);
  padding: var(--space-2) var(--space-4) var(--space-4);
}
.mobile-nav__link { padding: var(--space-3) var(--space-2); font-size: 15px; font-weight: 600; color: var(--text-secondary); border-bottom: 1px solid var(--hairline); }
.mobile-nav__link--active { color: var(--gold-pale); }
.mobile-nav__sound-row {
  display: flex; align-items: center; justify-content: space-between;
  width: 100%; background: none; border: none; border-bottom: none;
  font-family: inherit; text-align: left;
}

@media (max-width: 900px) {
  .topbar__nav { display: none; }
  .topbar__menu-toggle { display: flex; }
  .sound-toggle { display: none; }
  .mobile-nav:not([hidden]) { display: flex; }
}

/* The refresh control reuses the sound button's geometry exactly — it
   is the same class of thing in the same place, so it should not look
   like a new component. The only addition is a spin while it works. */
.refresh-btn.is-spinning svg { animation: refreshSpin 700ms var(--ease-standard) infinite; }
@keyframes refreshSpin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .refresh-btn.is-spinning svg { animation: none; opacity: 0.5; }
}

/* ---------- Status pill ---------- */
.status-pill {
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  border-radius: 999px;
  background: var(--glass-surface);
  border: 1px solid var(--glass-border);
  font-size: 12px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--text-secondary);
}
.status-pill__dot {
  width: 7px; height: 7px; border-radius: 50%; background: var(--positive);
  box-shadow: 0 0 0 3px rgba(70,201,139,0.14);
  animation: pulseDot 2.6s var(--ease-standard) infinite;
}
@keyframes pulseDot {
  0%, 100% { box-shadow: 0 0 0 3px rgba(70,201,139,0.14); }
  50%      { box-shadow: 0 0 0 6px rgba(70,201,139,0.05); }
}
@media (prefers-reduced-motion: reduce) { .status-pill__dot { animation: none; } }
.status-pill--closed .status-pill__dot { background: var(--negative); box-shadow: 0 0 8px var(--negative); }
.status-pill--upcoming .status-pill__dot { background: var(--gold); box-shadow: 0 0 8px var(--gold-glow); }

/* ---------- Stats ---------- */
.stat { display: flex; flex-direction: column; gap: 6px; }
.stat__label { font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-tertiary); }
.stat__value {
  font-family: var(--font-ui);
  font-size: 28px;
  font-weight: 650;
  letter-spacing: -0.025em;
  color: var(--white);
  font-variant-numeric: tabular-nums;
}
.stat__delta { font-size: 13px; font-weight: 700; }

.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--space-4); }
.stat-grid > * { min-width: 0; }

/* ---------- Tables ---------- */
.financial-table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.financial-table th {
  text-align: right; font-size: 11px; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--text-tertiary);
  padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--hairline-strong);
}
.financial-table th:first-child, .financial-table td:first-child { text-align: left; }
.financial-table td { padding: var(--space-3); border-bottom: 1px solid var(--hairline); text-align: right; color: var(--text-primary); }
.financial-table tbody tr:hover { background: var(--glass-surface); }
.financial-table .cagr-cell { font-weight: 650; color: var(--gold-pale); }
.financial-table-wrap { overflow-x: auto; }

.data-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.data-table th {
  text-align: left; font-size: 11px; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--text-tertiary); padding: var(--space-3);
  border-bottom: 1px solid var(--hairline-strong); position: sticky; top: 0; background: var(--matte-black);
}
.data-table td { padding: var(--space-3); border-bottom: 1px solid var(--hairline); }
.data-table tbody tr { cursor: pointer; transition: background var(--dur-fast); }
.data-table tbody tr:hover { background: var(--glass-surface); }
.data-table-wrap { overflow-x: auto; border-radius: var(--radius-lg); }

.ticker-cell { display: flex; align-items: center; gap: var(--space-3); }
.ticker-badge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 52px; height: 26px; padding: 0 8px; border-radius: var(--radius-sm);
  /* METAL, engraved: the plate is recessed and the letters sit in it,
     so the highlight runs along the BOTTOM edge — the opposite of a
     raised surface. */
  background: linear-gradient(180deg, rgba(110, 84, 36, 0.30), rgba(198, 164, 100, 0.10));
  box-shadow:
    inset 0 1px 2px rgba(0,0,0,0.55),
    inset 0 -1px 0 rgba(233, 220, 187, 0.16),
    0 1px 0 rgba(255, 250, 238, 0.045);
  color: var(--gold-pale); font-weight: 650; font-size: 12px; letter-spacing: 0.05em;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 1px 0 rgba(0,0,0,0.5);
}

/* ---------- Tabs ---------- */
.tabs { display: flex; gap: var(--space-2); overflow-x: auto; padding-bottom: 2px; border-bottom: 1px solid var(--hairline); }
.tabs::-webkit-scrollbar { height: 4px; }
.tab {
  position: relative;
  padding: var(--space-3) var(--space-4);
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: 0.005em;
  color: var(--text-secondary);
  white-space: nowrap;
  background: none;
  border: none;
  transition: color var(--dur-fast) var(--ease-standard);
}
/* The indicator is a pseudo-element that grows from the centre, so
   moving between tabs reads as one continuous thing rather than two
   separate borders blinking. */
.tab::after {
  content: "";
  position: absolute;
  left: 50%; right: 50%; bottom: -1px;
  height: 2px;
  border-radius: 2px 2px 0 0;
  background: var(--gold);
  transition: left var(--dur-base) var(--ease-emphasis), right var(--dur-base) var(--ease-emphasis);
}
.tab:hover { color: var(--text-primary); }
.tab.is-active::after { left: var(--space-3); right: var(--space-3); }
.tab.is-active { color: var(--gold-pale); }
.tab-panel { display: none; animation: fadeIn var(--dur-slow) var(--ease-emphasis); }
.tab-panel.is-active { display: block; }

@keyframes fadeIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }

/* ---------- Ticker selector ---------- */
.ticker-selector { display: flex; gap: var(--space-2); overflow-x: auto; padding: var(--space-1) 0; }
.ticker-chip {
  flex-shrink: 0;
  padding: 7px var(--space-4);
  border-radius: 999px;
  border: 1px solid var(--glass-border);
  background: var(--glass-surface);
  font-weight: 650; font-size: 12.5px; letter-spacing: 0.045em; color: var(--text-secondary);
  /* No scale, no glow. The selected ticker is identified by the fill
     and by being the only warm thing in the row — growing it as well
     pushes the neighbouring chips around every time you change scenario. */
  transition:
    color var(--dur-fast) var(--ease-standard),
    background var(--dur-fast) var(--ease-standard),
    border-color var(--dur-fast) var(--ease-standard);
}
.ticker-chip { box-shadow: var(--relief-raised); }
.ticker-chip:hover { color: var(--text-primary); border-color: var(--hairline-strong); box-shadow: var(--relief-raised-lg); }
.ticker-chip:active { box-shadow: var(--relief-pressed); }
/* METAL — the selected ticker is the one moment in this row worth
   spending the material on. */
.ticker-chip.is-active {
  color: var(--on-gold);
  background: var(--gold-sheen);
  border-color: rgba(110, 84, 36, 0.6);
  box-shadow: var(--metal-bevel), var(--metal-cast);
  text-shadow: 0 1px 0 rgba(246, 238, 214, 0.35);
}
.ticker-chip--disabled { opacity: 0.4; cursor: not-allowed; }

/* ---------- Forms ---------- */
.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: var(--space-4); }
.field label { font-size: 12.5px; font-weight: 700; color: var(--text-secondary); }
.field input, .field select, .field textarea {
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--glass-border);
  border-radius: var(--radius-sm);
  padding: 12px 14px;
  font-size: 14.5px;
  /* RELIEF, inset: an input is a recess you put something into, not
     a raised object. The inner shadow is what makes it read that way
     without needing a heavy border. */
  box-shadow: inset 2px 2px 4px rgba(0,0,0,0.42), inset -1px -1px 1px rgba(255,250,238,0.03);
  transition: border-color var(--dur-fast), background var(--dur-fast), box-shadow var(--dur-fast);
}
.field input:focus, .field select:focus, .field textarea:focus {
  border-color: rgba(198, 164, 100, 0.5);
  background: rgba(255,250,240,0.05);
  box-shadow:
    inset 2px 2px 4px rgba(0,0,0,0.40),
    0 0 0 3px rgba(198, 164, 100, 0.12);
  outline: none;
}
.field textarea { resize: vertical; min-height: 90px; font-family: inherit; }
.field-error { color: var(--negative); font-size: 12.5px; min-height: 16px; }
.field input.has-error, .field textarea.has-error { border-color: var(--negative); }

.field-hint { font-size: 12px; color: var(--text-tertiary); }

.slider-row { display: flex; align-items: center; gap: var(--space-4); }
input[type="range"] {
  flex: 1; -webkit-appearance: none; height: 6px; border-radius: 999px;
  background: rgba(0,0,0,0.42);
  box-shadow: inset 1px 1px 3px rgba(0,0,0,0.6), inset -1px -1px 1px rgba(255,250,238,0.04);
  outline: none;
}
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; width: 20px; height: 20px; border-radius: 50%;
  background: var(--gold-sheen);
  box-shadow: var(--metal-bevel), 0 2px 5px rgba(0,0,0,0.55);
  cursor: grab;
}
.slider-value { font-family: var(--font-ui); font-weight: 650; font-size: 18px; color: var(--gold-pale); min-width: 42px; text-align: center; font-variant-numeric: tabular-nums; }

.recommendation-toggle { display: flex; gap: var(--space-2); }
.recommendation-toggle button {
  flex: 1; height: 46px; border-radius: var(--radius-md); border: 1px solid var(--glass-border);
  background: linear-gradient(180deg, rgba(255,250,240,0.05), rgba(255,250,240,0.02));
  color: var(--text-secondary); font-weight: 650; letter-spacing: 0.06em; font-size: 13px;
  box-shadow: var(--relief-raised);
  transition: color var(--dur-fast), background var(--dur-fast), box-shadow var(--dur-fast);
}
.recommendation-toggle button:hover { color: var(--text-primary); box-shadow: var(--relief-raised-lg); }
.recommendation-toggle button.is-active { color: var(--on-gold); border-color: transparent; box-shadow: inset 0 1px 0 rgba(255,255,255,0.22); }
.recommendation-toggle button[data-rec="BUY"].is-active { background: var(--positive); color: #06180F; }
.recommendation-toggle button[data-rec="HOLD"].is-active { background: var(--gold-sheen); }
.recommendation-toggle button[data-rec="AVOID"].is-active { background: var(--negative); color: #1A0D0C; }

/* ---------- Toasts ---------- */
.toast-stack {
  /* Cleared below the sticky top bar — at var(--space-5) the first
     toast landed directly on top of the nav's Logout button. */
  position: fixed; top: 76px; right: var(--space-5); z-index: 200;
  display: flex; flex-direction: column; gap: var(--space-3); max-width: 380px;
}
.toast {
  display: flex; align-items: flex-start; gap: var(--space-3);
  /* GLASS — floats over whatever the person was reading. */
  background: linear-gradient(180deg, rgba(34, 30, 26, 0.92), rgba(20, 18, 16, 0.94));
  backdrop-filter: var(--glass-blur-heavy);
  -webkit-backdrop-filter: var(--glass-blur-heavy);
  border: 1px solid var(--glass-border);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  box-shadow: var(--shadow-lift);
  opacity: 0; transform: translateX(24px) scale(0.96);
  transition: opacity var(--dur-slow) var(--ease-emphasis), transform var(--dur-slow) var(--ease-emphasis);
}
.toast--visible { opacity: 1; transform: translateX(0) scale(1); }
.toast--leaving { opacity: 0; transform: translateX(24px) scale(0.98); transition-duration: var(--dur-base); }
.toast__icon { display: flex; margin-top: 1px; }
.toast__icon svg { width: 15px; height: 15px; display: block; }
.toast--success .toast__icon { color: var(--positive); }
.toast--warning .toast__icon { color: var(--gold-pale); }
.toast--error .toast__icon { color: var(--negative); }
.toast__body { flex: 1; }
.toast__title { font-weight: 700; font-size: 14px; color: var(--white); }
.toast__message { font-size: 13px; color: var(--text-secondary); margin-top: 2px; }
.toast__close { background: none; border: none; color: var(--text-tertiary); font-size: 18px; line-height: 1; padding: 0; }

@media (max-width: 480px) {
  .toast-stack { left: var(--space-3); right: var(--space-3); max-width: none; }
}

/* ---------- Modal ---------- */
.modal-overlay {
  position: fixed; inset: 0; z-index: 300;
  background: rgba(6, 5, 4, 0.62);
  backdrop-filter: blur(8px) saturate(80%);
  -webkit-backdrop-filter: blur(8px) saturate(80%);
  display: flex; align-items: center; justify-content: center;
  padding: var(--space-4);
  opacity: 0; transition: opacity var(--dur-base) var(--ease-standard);
}
.modal-overlay--visible { opacity: 1; }
body.modal-open { overflow: hidden; }
.modal {
  width: 100%; max-width: 440px;
  background: var(--matte-black);
  border: 1px solid var(--glass-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lift);
  transform: scale(0.92) translateY(12px);
  transition: transform var(--dur-slow) var(--ease-spring);
}
.modal-overlay--visible .modal { transform: scale(1) translateY(0); }
.modal__header { padding: var(--space-5) var(--space-5) var(--space-3); }
.modal__title { font-size: 17px; }
.modal__body { padding: 0 var(--space-5) var(--space-4); font-size: 14px; color: var(--text-secondary); }
.modal__actions { display: flex; gap: var(--space-3); padding: var(--space-4) var(--space-5) var(--space-5); }
.modal__actions .btn { flex: 1; }

.confirm-row { display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid var(--hairline); }
.confirm-row:last-child { border-bottom: none; }
.confirm-row__label { color: var(--text-tertiary); }
.confirm-row__value { color: var(--white); font-weight: 700; }
.confirm-row--total .confirm-row__value { color: var(--gold); font-size: 17px; }

/* ---------- Skeleton sizes ----------
   The skeleton surface + sweep animation live in the loading layer at
   the end of this file; only the sizes are here. */
.skeleton--text { height: 14px; width: 100%; margin-bottom: 8px; }
.skeleton--title { height: 26px; width: 60%; margin-bottom: 12px; }
.skeleton--card { height: 96px; width: 100%; }

/* ---------- Tooltip ---------- */
.tooltip { position: relative; cursor: help; border-bottom: 1px dotted var(--text-tertiary); }
.tooltip:hover::after {
  content: attr(data-tip);
  position: absolute; bottom: 130%; left: 50%; transform: translateX(-50%);
  background: var(--matte-black); border: 1px solid var(--glass-border);
  padding: 8px 12px; border-radius: var(--radius-sm); font-size: 12px;
  width: max-content; max-width: 220px; color: var(--text-primary);
  box-shadow: var(--shadow-soft); z-index: 50;
}

/* ---------- Misc ---------- */
.pill { display: inline-flex; align-items: center; padding: 3px 10px; border-radius: 999px; font-size: 11px; font-weight: 800; letter-spacing: 0.04em; }
.pill--buy { background: rgba(51,209,122,0.14); color: var(--positive); }
.pill--sell { background: rgba(255,92,92,0.14); color: var(--negative); }
/* A close is neither a buy nor a sell — it is the exit. Neutral, so
   the green/red in the Result column beside it carries the outcome. */
.pill--close { background: rgba(198, 164, 100, 0.13); color: var(--gold-pale); }

/* ---------- Direction tag ----------
   LONG or SHORT on an open position. A short is not a loss and a long
   is not a win, so this is not the green/red scale — it is an engraved
   plate, the same treatment ticker badges get, differing only in edge
   colour. Without it a short is indistinguishable from a long and the
   numbers beside it read backwards. */
.dir-tag {
  display: inline-block;
  padding: 2px 7px;
  margin-right: 6px;
  border-radius: var(--radius-sm);
  font-size: 10px; font-weight: 800; letter-spacing: 0.1em;
  vertical-align: middle;
  background: rgba(0,0,0,0.34);
  box-shadow: inset 0 1px 2px rgba(0,0,0,0.55), inset 0 -1px 0 rgba(255,250,238,0.05);
}
.dir-tag--long { color: var(--gold-pale); border: 1px solid rgba(198,164,100,0.36); }
.dir-tag--short { color: #9FC3E8; border: 1px solid rgba(120, 165, 210, 0.42); }

/* ---------- Close Trade ----------
   The third action in the same family as .btn--buy / .btn--sell: same
   height, radius and weight, differing only in fill. Hairline and text
   in the negative tone because it ends exposure; it fills solid only
   while pressed, so it never competes with the primary action above it. */
.btn--close {
  background: transparent;
  color: var(--negative);
  border-color: rgba(232, 105, 95, 0.42);
  box-shadow: none;
}
.btn--close:hover { background: rgba(232, 105, 95, 0.10); border-color: rgba(232, 105, 95, 0.62); }
.btn--close:active { background: rgba(232, 105, 95, 0.85); color: #1A0D0C; }
.close-note {
  margin-top: 8px;
  font-size: 11.5px; line-height: 1.5;
  color: var(--text-tertiary);
}
.pill--hold { background: rgba(198, 164, 100, 0.14); color: var(--gold); }
.pill--avoid { background: rgba(255,92,92,0.14); color: var(--negative); }

.allocation-bar {
  display: flex; height: 9px; border-radius: 999px; overflow: hidden;
  background: var(--glass-border);
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.35);
}
/* A hairline between slices so two adjacent lightness steps still read
   as two slices rather than one gradient. */
.allocation-bar > div + div { box-shadow: inset 1px 0 0 rgba(11,10,9,0.55); }
.allocation-bar > div { transition: width var(--dur-slow) var(--ease-emphasis); }
.allocation-legend { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-top: var(--space-3); }
.allocation-legend__item { display: flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--text-secondary); }
.allocation-legend__dot { width: 8px; height: 8px; border-radius: 2px; flex-shrink: 0; }

/* ============================================================
   LOADING & TRANSITION LAYER
   Everything here exists to cover a wait. Nothing here is
   decorative — if there is no wait, none of it is visible.
   ============================================================ */

/* ---------- Route progress bar ----------
   Two-phase: it runs quickly to ~72% (which is honest — the request
   is genuinely in flight and we cannot know how far along it is),
   then creeps, then snaps to 100% when the document commits. The
   creep is what stops a slow connection reading as a frozen bar. */
.route-progress {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 2px;
  z-index: 900;
  opacity: 0;
  pointer-events: none;
  transition: opacity 200ms var(--ease-standard);
}
.route-progress.is-active { opacity: 1; }
.route-progress__fill {
  display: block;
  height: 100%;
  width: 0;
  background: linear-gradient(90deg, var(--gold-deep), var(--gold-pale) 60%, var(--gold));
  box-shadow: 0 0 10px var(--gold-glow);
  border-radius: 0 2px 2px 0;
}
.route-progress.is-active .route-progress__fill {
  animation: routeCreep 9s var(--ease-out-expo) forwards;
}
.route-progress.is-done .route-progress__fill {
  animation: none;
  width: 100%;
  transition: width 180ms var(--ease-emphasis);
}
@keyframes routeCreep {
  0%   { width: 0; }
  18%  { width: 42%; }
  45%  { width: 72%; }
  100% { width: 94%; }
}

/* ---------- Page entrance ----------
   Applied only when JS is running (js-enabled), so a no-JS browser
   never gets a permanently invisible page. */
.js-enabled body { opacity: 0; }
.js-enabled.page-ready body {
  opacity: 1;
  transition: opacity 280ms var(--ease-standard);
}
@media (prefers-reduced-motion: reduce) {
  .js-enabled body { opacity: 1; }
}

/* Cross-document view transitions where the browser supports them.
   Everywhere else this rule is simply ignored. */
@view-transition { navigation: auto; }

/* ---------- Skeletons ----------
   A sweep, not a pulse. A pulsing block reads as "broken"; a sweep
   reads as "arriving", because the motion has a direction. */
.skeleton {
  position: relative;
  overflow: hidden;
  background: rgba(255, 250, 240, 0.045);
  border-radius: var(--radius-sm);
}
.skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(
    90deg,
    transparent,
    rgba(233, 220, 187, 0.075) 45%,
    rgba(233, 220, 187, 0.11) 50%,
    rgba(233, 220, 187, 0.075) 55%,
    transparent
  );
  animation: skeletonSweep 1.5s var(--ease-standard) infinite;
}
@keyframes skeletonSweep { to { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) {
  .skeleton::after { animation: none; }
}

/* ---------- Inline spinner ----------
   For a wait attached to one control (a trade confirming, a decision
   saving) rather than to the whole page. */
.spinner {
  display: inline-block;
  width: 15px; height: 15px;
  border-radius: 50%;
  border: 2px solid rgba(23, 18, 8, 0.28);
  border-top-color: var(--on-gold);
  animation: spin 620ms linear infinite;
  vertical-align: -2px;
}
.spinner--onDark { border-color: rgba(233, 220, 187,0.22); border-top-color: var(--gold-pale); }
.spinner--lg { width: 26px; height: 26px; border-width: 2.5px; }
@keyframes spin { to { transform: rotate(360deg); } }

.btn.is-busy { pointer-events: none; }
.btn.is-busy .btn__label { opacity: 0.55; }

/* ---------- Full-panel loading ---------- */
.loading-panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  padding: var(--space-8) var(--space-5);
  color: var(--text-tertiary);
  font-size: 13.5px;
}

/* ---------- Live value change ----------
   When a number updates because of someone else's action (an admin
   adjustment, a rank shift), flash the change so it isn't silent. */
@keyframes valueFlash {
  0%   { background: var(--gold-wash); }
  100% { background: transparent; }
}
.value-changed {
  animation: valueFlash 900ms var(--ease-standard);
  border-radius: 4px;
}
@media (prefers-reduced-motion: reduce) { .value-changed { animation: none; } }

/* ---------- Offline banner ---------- */
.net-banner {
  position: fixed;
  left: 50%;
  bottom: var(--space-5);
  transform: translate(-50%, 140%);
  z-index: 850;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 10px var(--space-4);
  border-radius: 999px;
  background: rgba(24, 21, 18, 0.94);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border: 1px solid var(--hairline-strong);
  box-shadow: var(--shadow-lift);
  font-size: 13px;
  color: var(--text-primary);
  transition: transform 340ms var(--ease-emphasis);
}
.net-banner.is-visible { transform: translate(-50%, 0); }
.net-banner__dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--negative);
  box-shadow: 0 0 0 3px rgba(232,105,95,0.16);
}
.net-banner--back .net-banner__dot { background: var(--positive); box-shadow: 0 0 0 3px rgba(70,201,139,0.16); }

/* ---------- Fatal / error screen ---------- */
.fatal {
  min-height: 100vh;
  display: flex; align-items: center; justify-content: center;
  padding: var(--space-5);
}
.fatal__card {
  max-width: 430px; text-align: center;
  padding: var(--space-7) var(--space-6);
  border-radius: var(--radius-xl);
  background: linear-gradient(180deg, rgba(255,250,240,0.05), rgba(255,250,240,0.022));
  border: 1px solid var(--glass-border);
  box-shadow: var(--shadow-lift), inset 0 1px 0 var(--glass-highlight);
}
.fatal__mark {
  width: 44px; height: 44px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  margin: 0 auto var(--space-5);
  color: var(--negative);
  background: rgba(232,105,95,0.11);
  box-shadow: inset 0 0 0 1px rgba(232,105,95,0.22);
}
.fatal__title { font-size: 19px; font-weight: 700; letter-spacing: -0.02em; margin-bottom: var(--space-3); }
.fatal__body { font-size: 14px; color: var(--text-secondary); line-height: 1.65; }
.fatal__detail {
  margin-top: var(--space-3); font-size: 11.5px; color: var(--text-tertiary);
  font-variant-numeric: tabular-nums; letter-spacing: 0.02em;
}
.fatal__card .btn { margin-top: var(--space-6); }


/* ---------- Empty & error states ----------
   These used to inherit whatever height their container had, which
   left a "no transactions yet" message floating in 200px of nothing.
   A quiet state should take quiet space. */
.empty-state, .error-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  text-align: center;
  padding: var(--space-5) var(--space-4);
}
.empty-state__title, .error-state__title {
  font-size: 14.5px;
  font-weight: 600;
  color: var(--text-primary);
}
.empty-state__message, .error-state__message {
  font-size: 13px;
  color: var(--text-tertiary);
  max-width: 40ch;
  line-height: 1.6;
}
.empty-state .btn { margin-top: var(--space-4); }
.error-state__title { color: var(--negative); }

/* The sound toggle holds an inline SVG now, not an emoji glyph. */
.sound-toggle svg { display: block; }
.mobile-nav__sound-row svg { vertical-align: -3px; margin-right: 4px; }

/* ---------- Scenario price reveal ----------
   Centre of screen, not a corner toast: this is the event's headline
   moment, and it arrives while the person is looking at the projector
   rather than at their laptop. */
.reveal-card {
  position: fixed;
  left: 50%;
  top: 50%;
  z-index: 400;
  width: min(340px, calc(100vw - 32px));
  transform: translate(-50%, -46%) scale(0.94);
  opacity: 0;
  pointer-events: none;
  text-align: center;
  padding: var(--space-6) var(--space-5) var(--space-5);
  border-radius: var(--radius-xl);
  background: linear-gradient(180deg, rgba(38, 33, 28, 0.94), rgba(18, 16, 14, 0.96));
  backdrop-filter: var(--glass-blur-heavy);
  -webkit-backdrop-filter: var(--glass-blur-heavy);
  border: 1px solid var(--hairline-strong);
  box-shadow: var(--glass-edge), 0 24px 70px rgba(0, 0, 0, 0.7);
  transition: opacity 240ms var(--ease-emphasis), transform 340ms var(--ease-emphasis);
}
.reveal-card.is-visible { opacity: 1; transform: translate(-50%, -50%) scale(1); pointer-events: auto; }
.reveal-card__eyebrow {
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--gold); margin-bottom: var(--space-4);
}
.reveal-card__ticker {
  font-size: 30px; font-weight: 700; letter-spacing: -0.02em; color: var(--white); line-height: 1;
}
.reveal-card__company { font-size: 12.5px; color: var(--text-tertiary); margin-top: 4px; }
.reveal-card__price {
  font-size: 40px; font-weight: 650; letter-spacing: -0.035em;
  font-variant-numeric: tabular-nums; margin-top: var(--space-4); line-height: 1;
  overflow-wrap: anywhere;
}
.reveal-card__delta {
  margin-top: var(--space-3); font-size: 14px; font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.reveal-card__from { display: block; font-size: 11.5px; font-weight: 400; color: var(--text-tertiary); margin-top: 6px; }
.reveal-card--up .reveal-card__price, .reveal-card--up .reveal-card__delta { color: var(--positive); }
.reveal-card--down .reveal-card__price, .reveal-card--down .reveal-card__delta { color: var(--negative); }
.reveal-card--flat .reveal-card__price, .reveal-card--flat .reveal-card__delta { color: var(--text-primary); }
/* The personal half of a reveal: what it did to money this person
   actually holds. Separated from the price block by a rule and set on
   an inset panel, because it is a different fact about a different
   subject — the price is the hall's news, this is theirs. */
.reveal-position {
  margin-top: var(--space-5);
  padding: var(--space-4) var(--space-4) var(--space-3);
  border-radius: var(--radius-md);
  background: rgba(0, 0, 0, 0.30);
  box-shadow: var(--relief-pressed);
}
.reveal-position__label {
  font-size: 11px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--text-tertiary);
}
.reveal-position__delta {
  margin-top: var(--space-2);
  font-size: 22px; font-weight: 700; letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums; overflow-wrap: anywhere;
  color: var(--text-primary);
}
.reveal-position__pct { font-size: 14px; font-weight: 600; }
.reveal-position__totals {
  margin-top: 6px; font-size: 11.5px; color: var(--text-tertiary);
  font-variant-numeric: tabular-nums;
}
.reveal-position--up .reveal-position__delta { color: var(--positive); }
.reveal-position--down .reveal-position__delta { color: var(--negative); }

.reveal-card__close { margin-top: var(--space-5); }

/* The bulk variant: no single price to shout, so the headline carries
   the weight and the actions row replaces the lone dismiss button. */
.reveal-card__headline {
  font-size: 26px; font-weight: 700; letter-spacing: -0.02em;
  color: var(--white); line-height: 1.15; margin-top: var(--space-2);
}
.reveal-card--bulk .reveal-card__company { margin-top: var(--space-2); font-size: 13px; color: var(--text-secondary); }
.reveal-card__actions {
  display: flex; gap: var(--space-3); justify-content: center;
  margin-top: var(--space-5); flex-wrap: wrap;
}
.reveal-card__actions .reveal-card__close { margin-top: 0; }
@media (prefers-reduced-motion: reduce) {
  .reveal-card { transition: opacity 1ms; transform: translate(-50%, -50%); }
}

/* ---------- Long-number safety ----------
   Every surface that can hold a monetary value gets a floor on how it
   behaves when the value is enormous, so a billion-dollar portfolio
   wraps or scrolls instead of pushing its neighbours off screen. */
.stat__value, .reveal-card__price, .confirm-row__value,
.rank-card__value, .portfolio-hero__value {
  overflow-wrap: anywhere;
  min-width: 0;
}
.stat { min-width: 0; }
.data-table td.num, .financial-table td.num { white-space: nowrap; }

/* ---------- Email verification banner ----------
   Sits under the nav on every page until the address is confirmed.
   Informative rather than alarming: nothing has gone wrong, one step
   is outstanding. */
.verify-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  max-width: 1360px;
  margin: 0 auto;
  padding: var(--space-3) var(--space-5);
  border-bottom: 1px solid rgba(198, 164, 100, 0.22);
  background: rgba(198, 164, 100, 0.07);
  font-size: 13px;
  color: var(--text-secondary);
  line-height: 1.6;
}
.verify-banner__text { min-width: 0; max-width: 74ch; }
.verify-banner__text strong { color: var(--gold-pale); font-weight: 650; }
.verify-banner__email { color: var(--text-primary); overflow-wrap: anywhere; }
.verify-banner__actions { display: flex; gap: var(--space-2); flex-wrap: wrap; }
@media (max-width: 700px) {
  .verify-banner { padding: var(--space-3) var(--space-4); }
  .verify-banner__actions { width: 100%; }
}

/* ---------------------------------------------------------------
   Market conditions strip
   Sits under the top bar on every participant page when the
   organisers have broadcast a condition. Deliberately a thin rule of
   text, not a card or a coloured banner: it must be readable at a
   glance from across a hall without competing with the prices, and it
   is present for most of the event, so anything louder becomes noise
   by the second round.
   --------------------------------------------------------------- */
.regime-strip {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  flex-wrap: wrap;
  max-width: 1360px;
  margin: 0 auto;
  padding: 10px var(--space-5);
  border-bottom: 1px solid var(--hairline);
  font-size: 13px;
  line-height: 1.45;
}
.regime-strip__k {
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  white-space: nowrap;
}
.regime-strip__v {
  color: var(--gold);
  font-weight: 600;
}
.regime-strip__note { color: var(--text-secondary); }
@media (max-width: 768px) {
  .regime-strip { padding: 9px var(--space-4); gap: var(--space-2); }
  .regime-strip__k { width: 100%; }
}

/* An 'optional' marker on a form label. Lowercase and quiet on
   purpose: it must be readable without competing with the question
   itself, which is what people are actually meant to answer. */
.field-optional {
  margin-left: 6px;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  font-weight: 500;
}

/* An empty or failed table says so in the row itself. Replacing the
   whole card, which is what this used to do, deleted the tbody the
   next render needed. */
.table-empty {
  text-align: center;
  padding: 30px 16px;
  color: var(--text-tertiary);
  font-size: 13px;
}

/* ---------- Pre-event notice (status UPCOMING) ----------
   Reads like a letter of confirmation, not a promo banner: a gold rule,
   a serif headline, then two plain columns of what to do now and what
   happens on the day. */
.upcoming-notice {
  border-left: 2px solid var(--gold);
  padding: var(--space-4) var(--space-5);
  background: rgba(198, 164, 100, 0.04);
}
.upcoming-notice--full { margin-bottom: var(--space-6); padding: var(--space-5) var(--space-6); }
.upcoming-notice__eyebrow {
  font-size: 11.5px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--gold); margin: 0 0 var(--space-2);
}
.upcoming-notice__title {
  font-family: var(--font-display); font-weight: 600; color: var(--text-primary);
  font-size: 17px; line-height: 1.3; margin: 0 0 var(--space-2);
}
.upcoming-notice--full .upcoming-notice__title { font-size: clamp(22px, 2.6vw, 28px); letter-spacing: -0.01em; }
.upcoming-notice__body { margin: 0; max-width: 68ch; font-size: 14px; line-height: 1.65; color: var(--text-secondary); }
.upcoming-notice__cols {
  display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: var(--space-5); margin-top: var(--space-5); padding-top: var(--space-4);
  border-top: 1px solid var(--hairline);
}
.upcoming-notice__label { font-size: 12px; font-weight: 600; color: var(--gold-pale); margin: 0 0 var(--space-2); }
.upcoming-notice__list { margin: 0; padding-left: 1.1em; font-size: 13.5px; line-height: 1.8; color: var(--text-secondary); }
.upcoming-notice__list a { color: var(--text-primary); text-decoration: underline; text-decoration-color: rgba(198, 164, 100, 0.5); text-underline-offset: 3px; }
.upcoming-notice__list a:hover { text-decoration-color: var(--gold); }
.upcoming-notice__text { margin: 0; font-size: 13.5px; line-height: 1.7; color: var(--text-secondary); }
.price-withheld { color: var(--text-tertiary); font-size: 12.5px; letter-spacing: 0.02em; }
@media (max-width: 700px) {
  .upcoming-notice--full { padding: var(--space-4); }
  .upcoming-notice__cols { grid-template-columns: 1fr; gap: var(--space-4); }
}

/* ---------- Round start + price reveal ----------
   Two short interruptions, both tied to something the organisers just
   did in the hall: a round opening, and its prices landing. Nothing
   here animates on its own and nothing here is decorative. */
.round-flash {
  position: fixed; inset: 0; z-index: 90;
  display: flex; align-items: center; justify-content: center;
  background: rgba(11, 10, 9, 0.72);
  opacity: 1; transition: opacity 320ms ease;
  pointer-events: none;
}
.round-flash--out { opacity: 0; }
.round-flash__card {
  text-align: center; padding: var(--space-6) var(--space-7);
  border: 1px solid var(--hairline-strong); border-left: 2px solid var(--gold);
  background: var(--matte-black);
}
.round-flash__label {
  margin: 0 0 var(--space-2); font-size: 11.5px; font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--gold);
}
.round-flash__round {
  margin: 0; font-family: var(--font-display); font-weight: 600;
  font-size: clamp(30px, 7vw, 48px); line-height: 1; color: var(--text-primary);
}

.reveal-countdown {
  position: fixed; inset: 0; z-index: 95;
  display: flex; align-items: center; justify-content: center;
  /* Opaque on purpose: the market behind it is mid-update. */
  background: var(--black);
  opacity: 1; transition: opacity 320ms ease;
}
.reveal-countdown--out { opacity: 0; }
.reveal-countdown__inner { text-align: center; }
.reveal-countdown__label {
  margin: 0 0 var(--space-3); font-size: 12px; font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--gold);
}
.reveal-countdown__n {
  margin: 0; font-family: var(--font-display); font-weight: 600;
  font-size: clamp(64px, 22vw, 140px); line-height: 1;
  color: var(--text-primary); font-variant-numeric: tabular-nums;
}
.reveal-countdown__n.is-beat { animation: reveal-beat 220ms ease-out; }
@keyframes reveal-beat { from { transform: scale(1.18); } to { transform: scale(1); } }
@media (prefers-reduced-motion: reduce) {
  .reveal-countdown__n.is-beat { animation: none; }
  .round-flash, .reveal-countdown { transition: none; }
}

/* The held beat between the last number and the market reappearing. */
.reveal-countdown__sub {
  margin: var(--space-3) 0 0; font-size: 14px; letter-spacing: 0.04em;
  color: var(--text-secondary);
}
.reveal-countdown--reveal .reveal-countdown__n {
  font-size: clamp(28px, 7vw, 52px); color: var(--gold-pale); letter-spacing: 0.01em;
}
