/* ──────────────────────────────────────────────────────────────────────────
   styles/nexus-design-v2.css — NEXUS Design v2 universal polish layer
   Authored 2026-05-01 in response to Kadeem cumulative directive escalation:
     "UI is one of the most important things in NEXUS"
     "completely revamped — go deeper"
     "as good as Firebase + Google" / "cooler than Bloomberg"
     "enjoy trading while making money"

   This file is the v1 of the multi-session UI revamp. Honest framing:
     - A complete revamp of a 50-page legacy HTML/JS PWA is multi-week work.
     - This v1 establishes the design LANGUAGE (motion, depth, materials,
       celebration) that subsequent sessions can apply page-by-page.
     - Layered ON TOP of existing app.min.css tokens — does NOT break or
       overwrite them. Pure-additive utilities + opt-in classes.

   Sections:
     1. Extended motion vocabulary (5-stage springs, page transitions)
     2. Depth + material system (glass, ambient shadows, color-tinted elev)
     3. Card stagger entrance (universal — applies to .card, .panel, .tile)
     4. Reward / celebration micro-animations (P&L glow, win pulse, streak)
     5. Hover micro-lift utility
     6. Refined loading shimmer
     7. Selection + focus polish (gold-tinted; matches accent identity)
     8. prefers-reduced-motion guards
   ────────────────────────────────────────────────────────────────────── */

:root {
  /* ── Extended motion vocabulary (composes with existing --dur/--ease) ─ */
  --ease-spring:        cubic-bezier(0.34, 1.56, 0.64, 1);   /* gentle overshoot */
  --ease-spring-soft:   cubic-bezier(0.25, 0.46, 0.45, 0.94); /* gentle ease */
  --ease-snap:          cubic-bezier(0.16, 1, 0.3, 1);        /* Apple snap */
  --ease-decelerate:    cubic-bezier(0, 0, 0.2, 1);           /* Material decelerate */
  --ease-accelerate:    cubic-bezier(0.4, 0, 1, 1);           /* Material accelerate */
  --dur-xfast:          0.10s;
  --dur-page:           0.36s;

  /* ── Depth: 4-layer ambient shadow with subtle gold tint at top elev ─ */
  --shadow-sm:    0 1px 2px rgba(0, 0, 0, 0.16);
  --shadow-md:    0 4px 12px rgba(0, 0, 0, 0.24), 0 1px 0 rgba(255, 255, 255, 0.04) inset;
  --shadow-lg:    0 12px 32px rgba(0, 0, 0, 0.36), 0 1px 0 rgba(255, 255, 255, 0.05) inset;
  --shadow-xl:    0 24px 60px rgba(0, 0, 0, 0.45), 0 8px 16px rgba(0, 0, 0, 0.20),
                  0 1px 0 rgba(255, 255, 255, 0.06) inset;
  --shadow-gold:  0 12px 32px rgba(212, 160, 23, 0.18), 0 1px 0 rgba(255, 255, 255, 0.05) inset;
  --shadow-pos:   0 12px 32px rgba(63, 211, 143, 0.18), 0 1px 0 rgba(255, 255, 255, 0.05) inset;
  --shadow-neg:   0 12px 32px rgba(242, 110, 110, 0.18), 0 1px 0 rgba(255, 255, 255, 0.05) inset;

  /* ── Glass material (Apple Vision Pro / Stripe Tax style) ────────── */
  --glass-bg:     rgba(18, 22, 29, 0.72);
  --glass-blur:   saturate(180%) blur(24px);
  --glass-border: 1px solid rgba(255, 255, 255, 0.08);

  /* ──────────────────────────────────────────────────────────────────
     Canonical SEMANTIC color grammar — Tier-D #5 closure 2026-05-05
     Per usability audit cross-cutting theme #2: the SAME GREEN was
     used for 4 different things across 4 pages (bullish chips on
     /security-deep, "Strong Buy" tier pills, high-DAR diversifier
     quality on /diversifiers, good Brier scores on /expected-returns).
     Pattern-match collision was most dangerous on /diversifiers where
     a portfolio-fit metric was being read as a buy signal.

     This block establishes a 3-axis semantic grammar:
        DIRECTIONAL (buy/sell/neutral) — only for tactical signals
        QUALITY     (good/middling/poor) — only for engineering metrics
        INFORMATIONAL (high/medium/low intensity) — for non-actionable
                                                     analytical surfaces

     PAGES MUST USE THE GRAMMAR AXIS THAT MATCHES THEIR INTENT.
     E.g.: /diversifiers DAR ≠ buy signal → use INFORMATIONAL not DIRECTIONAL.
     ────────────────────────────────────────────────────────────────── */

  /* AXIS 1: DIRECTIONAL — tactical buy/sell signals. Use ONLY for trade actions. */
  --color-directional-bullish:  #3fd38f;  /* Strong Buy / Bull / Long */
  --color-directional-bearish:  #f26e6e;  /* Strong Sell / Bear / Short */
  --color-directional-neutral:  #d4a017;  /* Hold / Mixed / Wait */

  /* AXIS 2: QUALITY — engineering health (Brier, calibration, drift, hit-rate). */
  --color-quality-strong:       #3fd38f;  /* Brier ≤0.20, Hit-rate ≥60%, drift CLEAN */
  --color-quality-acceptable:   #d4a017;  /* Brier 0.20-0.30, drift WARN */
  --color-quality-weak:         #d06854;  /* Brier >0.30, hit-rate ≤45%, drift FAIL */

  /* AXIS 3: INFORMATIONAL — analytical surfaces (DAR, diversifier-bonus,
     factor-IC, factor-attribution). NEVER read as buy/sell. Blue-only. */
  --color-info-high:            #5b8def;  /* High intensity informational */
  --color-info-medium:          #9ec0ff;  /* Medium intensity */
  --color-info-low:             #888888;  /* Low / muted */

  /* ──────────────────────────────────────────────────────────────────
     Canonical breadcrumb pattern — Tier-D #1 closure 2026-05-05
     Use .thv2-breadcrumb on a <nav> element with `aria-label="Breadcrumb"`.
     Replaces page-prefixed cb-crumb / sd-crumb / etc patterns; legacy
     classes can co-exist until each touch-edit migrates them.
     ────────────────────────────────────────────────────────────────── */
}

.thv2-breadcrumb {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-secondary, #9aa3b2);
  margin: 0 0 12px;
  padding: 6px 12px;
  display: inline-block;
}
.thv2-breadcrumb a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px dotted rgba(255, 255, 255, 0.15);
  transition: border-color 120ms ease;
}
.thv2-breadcrumb a:hover {
  border-bottom-color: var(--accent, #d4a017);
  color: var(--accent, #d4a017);
}
.thv2-breadcrumb a:focus-visible {
  outline: 2px solid var(--color-info-high, #5b8def);
  outline-offset: 2px;
}
.thv2-breadcrumb .thv2-breadcrumb-sep {
  margin: 0 8px;
  opacity: 0.5;
}

:root {
  /* (continuation marker — the canonical color grammar block above closes here) */

  /* Surface gradient backgrounds (subtle, never agitating) ──────── */
  --grad-hero-gold:
    radial-gradient(ellipse 60% 80% at 100% 0%, rgba(212, 160, 23, 0.16), transparent 60%),
    radial-gradient(ellipse 80% 60% at 0% 100%, rgba(91, 141, 239, 0.10), transparent 60%);
  --grad-hero-pos:
    radial-gradient(ellipse 60% 80% at 100% 0%, rgba(63, 211, 143, 0.14), transparent 60%);
  --grad-hero-neg:
    radial-gradient(ellipse 60% 80% at 100% 0%, rgba(242, 110, 110, 0.14), transparent 60%);
}

/* ─── 3. Card stagger entrance ─────────────────────────────────────────
   Applies to elements with .ndv2-stagger-parent — children staggered up
   to 8 deep. Creates the "Google polish" feel where cards cascade into
   place rather than dropping in all at once. */
.ndv2-stagger-parent > * {
  animation: ndv2-stagger-rise var(--dur-slow, 280ms) var(--ease-snap, cubic-bezier(0.16, 1, 0.3, 1)) both;
}

.ndv2-stagger-parent > *:nth-child(1) { animation-delay: 0.02s; }
.ndv2-stagger-parent > *:nth-child(2) { animation-delay: 0.06s; }
.ndv2-stagger-parent > *:nth-child(3) { animation-delay: 0.10s; }
.ndv2-stagger-parent > *:nth-child(4) { animation-delay: 0.14s; }
.ndv2-stagger-parent > *:nth-child(5) { animation-delay: 0.18s; }
.ndv2-stagger-parent > *:nth-child(6) { animation-delay: 0.22s; }
.ndv2-stagger-parent > *:nth-child(7) { animation-delay: 0.26s; }
.ndv2-stagger-parent > *:nth-child(8) { animation-delay: 0.30s; }

@keyframes ndv2-stagger-rise {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Apply stagger automatically to common THv2 grid containers if author
   added the parent class. (Opt-in — does not affect existing pages
   until they add .ndv2-stagger-parent.) */

/* ─── 4. Reward / celebration micro-animations ─────────────────────── */

/* P&L positive glow — subtle, non-disruptive. Triggered by adding
   .ndv2-celebrate when daily P&L turns green. */
.ndv2-celebrate {
  animation: ndv2-celebrate-pulse 1.2s var(--ease-spring-soft, cubic-bezier(0.25, 0.46, 0.45, 0.94)) 1;
}

@keyframes ndv2-celebrate-pulse {
  0%   { transform: scale(1);    text-shadow: 0 0 0 rgba(63, 211, 143, 0); }
  30%  { transform: scale(1.04); text-shadow: 0 0 18px rgba(63, 211, 143, 0.55); }
  100% { transform: scale(1);    text-shadow: 0 0 12px rgba(63, 211, 143, 0.20); }
}

/* Streak/win indicator — gentle breathing for ongoing-state */
.ndv2-breathe {
  animation: ndv2-breathe 4s ease-in-out infinite;
}

@keyframes ndv2-breathe {
  0%, 100% { opacity: 1;    transform: scale(1); }
  50%      { opacity: 0.85; transform: scale(0.985); }
}

/* "Win" flash — for events like a forecast hit or a target reached.
   One-shot, then settles. Trigger by adding .ndv2-win to the element
   for ~2s then removing. */
.ndv2-win {
  animation: ndv2-win-flash 1.6s var(--ease-spring, cubic-bezier(0.34, 1.56, 0.64, 1)) 1;
}

@keyframes ndv2-win-flash {
  0%   { box-shadow: 0 0 0 rgba(212, 160, 23, 0); }
  20%  { box-shadow: 0 0 0 6px rgba(212, 160, 23, 0.32), 0 0 32px rgba(212, 160, 23, 0.40); }
  100% { box-shadow: 0 0 0 rgba(212, 160, 23, 0); }
}

/* ─── 5. Hover micro-lift utility ──────────────────────────────────── */
.ndv2-lift {
  transition:
    transform 0.18s var(--ease-snap, cubic-bezier(0.16, 1, 0.3, 1)),
    box-shadow 0.18s var(--ease-snap, cubic-bezier(0.16, 1, 0.3, 1)),
    border-color 0.18s var(--ease-snap, cubic-bezier(0.16, 1, 0.3, 1));
}

.ndv2-lift:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-lg);
}

.ndv2-lift:active {
  transform: translateY(0) scale(0.99);
}

/* ─── 6. Refined loading shimmer ───────────────────────────────────── */
.ndv2-shimmer {
  background: linear-gradient(
    100deg,
    var(--bg-2, #1a1f28) 0%,
    var(--bg-3, #232935) 35%,
    rgba(212, 160, 23, 0.06) 50%,
    var(--bg-3, #232935) 65%,
    var(--bg-2, #1a1f28) 100%
  );
  background-size: 220% 100%;
  animation: ndv2-shimmer-slide 2.4s var(--ease-spring-soft, cubic-bezier(0.25, 0.46, 0.45, 0.94)) infinite;
  color: transparent !important;
  border-radius: 4px;
}

@keyframes ndv2-shimmer-slide {
  0%   { background-position: 220% 0; }
  100% { background-position: -120% 0; }
}

/* ─── 7. Selection + focus polish ──────────────────────────────────── */
::selection {
  background: rgba(212, 160, 23, 0.35);
  color: var(--fg-0, #f0f3f8);
}

/* Universal focus-visible — gold ring, never the default browser blue.
   Falls back gracefully where elements set their own focus styles. */
:focus-visible {
  outline: 2px solid var(--accent, #d4a017);
  outline-offset: 3px;
  border-radius: 4px;
}

/* Respect existing per-component focus rings (mbn, sl, teh) which are
   already polished. */
.mbn-tab:focus-visible,
.sl__closeBtn:focus-visible,
.teh__cta:focus-visible {
  outline-color: var(--focus, #5b8def);
}

/* ─── Glass-panel utility (opt-in) ─────────────────────────────────── */
.ndv2-glass {
  background: var(--glass-bg);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border: var(--glass-border);
  box-shadow: var(--shadow-md);
}

/* ──────────────────────────────────────────────────────────────────────
   9. The 2026 "cool" layer — strategic-tension language for NEXUS
   ────────────────────────────────────────────────────────────────────
   Inspired by 2026 design direction: liquid-glass + tactile-gummy +
   strategic-tension (warm gold × cool blue) + subtle imperfection
   (grain texture). Layered as opt-in utilities so the legacy app.min.css
   surfaces are untouched until they adopt.

   70/30 rule: 70% deep neutral charcoal + cool-blue clarity surfaces /
   30% gold accent jolts (today's edge, active-tab, key CTAs). The gold
   should feel scarce and earned — never wallpaper.
   ────────────────────────────────────────────────────────────────────── */

/* ─── Tactile gummy surface — soft inner glow + tangible outer depth ─ */
.ndv2-gummy {
  background: linear-gradient(180deg,
    color-mix(in oklab, var(--bg-1, #12161d) 92%, white 8%) 0%,
    var(--bg-1, #12161d) 100%);
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 18px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.10),
    inset 0 -1px 0 rgba(0, 0, 0, 0.30),
    0 4px 14px rgba(0, 0, 0, 0.32),
    0 18px 36px -12px rgba(0, 0, 0, 0.40);
  transition:
    transform var(--dur, 0.18s) var(--ease-spring, cubic-bezier(0.34, 1.56, 0.64, 1)),
    box-shadow var(--dur, 0.18s) var(--ease-snap, cubic-bezier(0.16, 1, 0.3, 1));
}

.ndv2-gummy:hover {
  transform: translateY(-2px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.14),
    inset 0 -1px 0 rgba(0, 0, 0, 0.34),
    0 8px 22px rgba(0, 0, 0, 0.40),
    0 24px 48px -12px rgba(0, 0, 0, 0.50);
}

.ndv2-gummy:active {
  transform: translateY(0) scale(0.99);
}

/* ─── Liquid glass — premium futuristic panel ────────────────────── */
.ndv2-liquid-glass {
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0.02)),
    rgba(18, 22, 29, 0.62);
  backdrop-filter: saturate(180%) blur(28px);
  -webkit-backdrop-filter: saturate(180%) blur(28px);
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 18px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.10),
    0 16px 48px rgba(0, 0, 0, 0.42);
  position: relative;
  overflow: hidden;
}

/* Liquid sheen — slow drift across the surface */
.ndv2-liquid-glass::before {
  content: '';
  position: absolute;
  inset: -50%;
  background: radial-gradient(ellipse 30% 40% at 30% 30%,
    rgba(212, 160, 23, 0.18), transparent 60%);
  animation: ndv2-liquid-drift 18s ease-in-out infinite;
  pointer-events: none;
  z-index: 0;
}

.ndv2-liquid-glass > * { position: relative; z-index: 1; }

@keyframes ndv2-liquid-drift {
  0%, 100% { transform: translate(0, 0); }
  33%      { transform: translate(8%, -6%); }
  66%      { transform: translate(-6%, 4%); }
}

/* ─── Strategic tension — gold accent CROWN over cool-blue body ─── */
.ndv2-tension {
  position: relative;
}

.ndv2-tension::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: linear-gradient(90deg,
    transparent 0%,
    var(--accent, #d4a017) 30%,
    var(--accent-hi, #e8b527) 50%,
    var(--accent, #d4a017) 70%,
    transparent 100%);
  border-radius: 18px 18px 0 0;
  z-index: 2;
}

/* ─── Subtle grain — imperfection layer ────────────────────────────
   Inline SVG noise (~1KB encoded) — sits at 4% opacity for tactile
   authenticity without distraction. Layered on .ndv2-grain wrappers. */
.ndv2-grain {
  position: relative;
}

.ndv2-grain::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.04;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");
  border-radius: inherit;
  z-index: 3;
}

/* ─── Cool-blue identity — informative accent for non-action chips ─ */
.ndv2-cool {
  color: #8ab4ff;
  background: rgba(91, 141, 239, 0.12);
  border: 1px solid rgba(91, 141, 239, 0.28);
  border-radius: 999px;
  padding: 3px 9px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  font-family: var(--font-sans, "Inter", sans-serif);
}

/* ─── Neobrutalism-lite — high-contrast pull-quote when needed ───── */
.ndv2-neobrut {
  background: var(--fg-0, #f0f3f8);
  color: #0a0d12;
  border: 2px solid #0a0d12;
  border-radius: 0;
  box-shadow: 6px 6px 0 var(--accent, #d4a017);
  padding: 14px 16px;
  font-weight: 800;
  letter-spacing: -0.01em;
  font-family: var(--font-sans, "Inter", sans-serif);
}

/* ─── Number-displayer — "scoreboard" feel for big stats ─────────── */
.ndv2-bignum {
  font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
  font-size: clamp(40px, 8vw, 64px);
  font-weight: 700;
  letter-spacing: -0.04em;
  color: var(--fg-0, #f0f3f8);
  font-feature-settings: 'tnum' on, 'cv11' on;
  line-height: 1;
}

/* ─── Compose: gummy-glass-grain (the "cool" stack) ──────────────── */
.ndv2-stack {
  position: relative;
  background: linear-gradient(180deg,
    rgba(255, 255, 255, 0.05),
    rgba(255, 255, 255, 0.01)),
    rgba(18, 22, 29, 0.78);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 18px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.10),
    inset 0 -1px 0 rgba(0, 0, 0, 0.30),
    0 12px 32px rgba(0, 0, 0, 0.36),
    0 24px 60px -16px rgba(0, 0, 0, 0.45);
  overflow: hidden;
  isolation: isolate;
}

.ndv2-stack::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--accent, #d4a017), transparent);
  z-index: 1;
}

.ndv2-stack::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.05;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");
  border-radius: inherit;
  z-index: 2;
}

/* ─── 8. prefers-reduced-motion guards ─────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .ndv2-stagger-parent > *,
  .ndv2-celebrate,
  .ndv2-breathe,
  .ndv2-win,
  .ndv2-lift,
  .ndv2-shimmer {
    animation: none !important;
    transition: none !important;
  }
  .ndv2-lift:hover { transform: none !important; }
}

/* ─── Wave-8 microstructure section (security-deep page) ────────────── */
/* Composes-with: wave-8-surface-bridge-2026-05-04-v1                    */
.sd-wave8 {
  margin: 12px 0;
  padding: 10px 14px;
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 10px;
  background: rgba(255,255,255,0.02);
}
.sd-wave8-hd { margin-bottom: 8px; font-size: 0.92em; opacity: 0.85; }
.sd-wave8-hd strong { font-weight: 600; }
.sd-wave8-sub { margin-left: 10px; opacity: 0.55; font-weight: 400; font-size: 0.88em; }
.sd-wave8-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.sd-w8-chip {
  display: inline-flex; align-items: center;
  padding: 4px 10px;
  font-size: 0.85em; font-weight: 500;
  border-radius: 12px;
  border: 1px solid rgba(255,255,255,0.10);
  background: rgba(255,255,255,0.04);
  white-space: nowrap;
}
.sd-w8-chip--ok    { color: #6cd3a4; border-color: rgba(108,211,164,0.30); }
.sd-w8-chip--warn  { color: #e6c469; border-color: rgba(230,196,105,0.30); }
.sd-w8-chip--alert { color: #e07171; border-color: rgba(224,113,113,0.32); }
.sd-w8-chip--info  { color: #79b3e6; border-color: rgba(121,179,230,0.30); }
.sd-w8-chip--cal   { color: #aaa;    border-color: rgba(255,255,255,0.10); font-style: italic; }
.sd-w8-chip--mute  { color: #777;    border-color: rgba(255,255,255,0.06); opacity: 0.7; }

/* ─── T1: content-visibility:auto — ~30% LCP gain on long pages (#3.1) ─ */
/* Third+ sibling panels are typically below the fold; skip paint until scroll. */
/* contain-intrinsic-size reserves space so scroll height is stable. */
.panel ~ .panel ~ .panel,
.strat ~ .strat ~ .strat ~ .strat {
  content-visibility: auto;
  contain-intrinsic-size: auto 320px;
}

/* ─── T2: CLS prevention — reserve space for async-populated tables (#3.11) ─ */
/* Prevents layout shift when JS populates empty tbody/divs after initial paint. */
#factor-table tbody:empty,
#archive-table tbody:empty,
#hypo-list:empty,
#log-list:empty,
#discovery-summary:empty,
#idea-list:empty {
  display: block;
  min-height: 120px;
}
/* Skeleton shimmer while async tables load */
@keyframes ndv2-skel-wave {
  0%   { background-position: 200% center; }
  100% { background-position: -200% center; }
}
#factor-table tbody:empty::after,
#archive-table tbody:empty::after {
  content: '';
  display: block;
  height: 100px;
  border-radius: 6px;
  background: linear-gradient(
    90deg,
    rgba(255,255,255,0.03) 25%,
    rgba(255,255,255,0.07) 50%,
    rgba(255,255,255,0.03) 75%
  );
  background-size: 400% 100%;
  animation: ndv2-skel-wave 1.6s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  #factor-table tbody:empty::after,
  #archive-table tbody:empty::after { animation: none; }
  .panel ~ .panel ~ .panel,
  .strat ~ .strat ~ .strat ~ .strat { content-visibility: visible; }
}

/* ══ State-of-the-art elevation 2026-05-19 ══ */
@keyframes hol-fade-up {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes hol-shimmer {
  0%   { background-position: -200% 0; }
  100% { background-position:  200% 0; }
}
.hol-animate          { animation: hol-fade-up 0.5s cubic-bezier(0.16,1,0.3,1) both; }
.hol-animate-delay-1  { animation-delay: 80ms; }
.hol-animate-delay-2  { animation-delay: 160ms; }
.hol-animate-delay-3  { animation-delay: 240ms; }
.hol-animate-delay-4  { animation-delay: 320ms; }
.hol-animate-delay-5  { animation-delay: 400ms; }
.hol-card-hover { transition: transform 0.25s cubic-bezier(0.16,1,0.3,1), box-shadow 0.25s ease; }
.hol-card-hover:hover { transform: translateY(-3px); box-shadow: 0 12px 40px rgba(0,0,0,0.35), 0 0 0 1px rgba(212,168,83,0.18); }
.hol-skeleton {
  background: linear-gradient(90deg, rgba(255,255,255,0.04) 25%, rgba(255,255,255,0.09) 50%, rgba(255,255,255,0.04) 75%);
  background-size: 200% 100%;
  animation: hol-shimmer 1.6s ease-in-out infinite;
  border-radius: 4px;
}
@media (prefers-reduced-motion: reduce) {
  .hol-animate, .hol-skeleton { animation: none !important; }
  .hol-card-hover { transition: none !important; }
}

/* ══ Wave P — Global numeric precision + live indicator (2026-06-08) ══ */

/* Tabular-nums on all financial data cells — prevents layout jitter
   when values update in place. Scoped narrowly to avoid breaking text. */
table td,
table th,
.tr-kpi-value,
.chip-value,
.hero-stat-chip .chip-value,
.stat-chip,
.score-num,
.thv2-value,
.price-display,
.pct-display,
.delta-display,
.sk-mono {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/* Live-update indicator: 4px green dot after any .thv2-live element.
   Use on values that refresh in real time (VIX, price, session state).
   Composes with existing .sota-live-dot (which is a sibling element;
   this is a pseudo-element alternative for inline values). */
.thv2-live {
  position: relative;
  padding-right: 10px;
}
.thv2-live::after {
  content: "";
  position: absolute;
  top: 50%;
  right: 0;
  transform: translateY(-50%);
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: #3fd38f;
  animation: thv2-live-pulse 2.4s ease-out infinite;
}
@keyframes thv2-live-pulse {
  0%   { opacity: 1; box-shadow: 0 0 0 0 rgba(63, 211, 143, 0.6); }
  60%  { opacity: 0.7; box-shadow: 0 0 0 5px rgba(63, 211, 143, 0); }
  100% { opacity: 1; box-shadow: 0 0 0 0 rgba(63, 211, 143, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .thv2-live::after { animation: none; }
}
