/* =========================================================================
   diagrams.css — stage-driven SVG instrument choreography
   Controlled by .viz-sticky[data-stage="N"]
   ========================================================================= */

/* base SVG text */
.viz-body text { font-family: var(--mono); fill: var(--ink-2); }
.viz-body .disp-svg, .viz-body .node-lbl, .viz-body .result-big { font-family: var(--display); }
.viz-body .node-lbl { fill: var(--ink); }
.viz-body .node-sub { fill: var(--muted); }
.viz-body .note, .viz-body .note2, .viz-body .note3,
.viz-body .note-easy, .viz-body .note-hard { fill: var(--muted); }
.viz-body .beta-lbl { fill: var(--accent-deep); }

/* layers hidden by default, crossfade in */
.viz-body .lyr { opacity: 0; transition: opacity 0.5s var(--ease); }

[data-stage="0"] .lyr-fixed,  [data-stage="0"] .lyr-classic,
[data-stage="1"] .lyr-instr,  [data-stage="1"] .lyr-split,
[data-stage="2"] .lyr-beta,   [data-stage="2"] .lyr-sample,
[data-stage="3"] .lyr-diff,   [data-stage="3"] .lyr-learn,
[data-stage="4"] .lyr-reward, [data-stage="4"] .lyr-meta,
[data-stage="5"] .lyr-result { opacity: 1; }

/* ---------- persistent nodes ---------- */
.node-box { transition: stroke 0.4s var(--ease), stroke-width 0.4s var(--ease); }
.persist .node-box { stroke: var(--ink-2); }
.flow { color: var(--muted); transition: stroke 0.4s, color 0.4s, opacity 0.4s; }
.fl { fill: var(--muted); transition: fill 0.4s, opacity 0.4s; }

/* ============ Meta-DiffuB ============ */
#vizDiffub .fp-in, #vizDiffub .fp-beta { color: var(--muted); }
#vizDiffub[data-stage="0"] .node-scheduler .node-box { stroke: var(--hair); }
#vizDiffub[data-stage="0"] .fp-beta,
#vizDiffub[data-stage="0"] .beta-lbl,
#vizDiffub[data-stage="1"] .node-exploiter .node-box,
#vizDiffub[data-stage="0"] .node-exploiter .node-box { opacity: 0.4; }

#vizDiffub[data-stage="1"] .node-scheduler .node-box,
#vizDiffub[data-stage="2"] .node-scheduler .node-box,
#vizDiffub[data-stage="4"] .node-scheduler .node-box { stroke: var(--accent); stroke-width: 2; }
#vizDiffub[data-stage="3"] .node-exploiter .node-box,
#vizDiffub[data-stage="4"] .node-exploiter .node-box { stroke: var(--accent); stroke-width: 2; }

#vizDiffub[data-stage="2"] .fp-beta,
#vizDiffub[data-stage="3"] .fp-beta,
#vizDiffub[data-stage="4"] .fp-beta {
  stroke: var(--accent); color: var(--accent);
  stroke-dasharray: 5 7; animation: dashMove 0.9s linear infinite;
}
@keyframes dashMove { to { stroke-dashoffset: -24; } }

/* curves */
.curve-sqrt { fill: none; stroke: var(--muted); stroke-width: 1.6; }
.curve-sqrt.faded { stroke: var(--faint); stroke-width: 1.4; stroke-dasharray: 3 4; }
.curve-beta { fill: none; stroke: var(--accent); stroke-width: 2.3; stroke-linecap: round;
  filter: drop-shadow(0 0 4px var(--accent-glow)); }
.curve-beta.hard { stroke: var(--accent-deep); stroke-dasharray: 6 5; }
.note-easy { fill: var(--accent-ink) !important; }
.note-hard { fill: var(--accent-deep) !important; }

/* meta-instruction chips */
.instr-chips .chip rect { transition: none; }
.instr-chips .chip.t rect { fill: var(--accent-soft); stroke: var(--accent); stroke-width: 1.4; }
.instr-chips .chip.t text { fill: var(--accent-deep); font-weight: 600; }
.instr-chips .chip.f rect { fill: var(--paper); stroke: var(--hair); stroke-width: 1.2; }
.instr-chips .chip.f text { fill: var(--muted); }
[data-stage="1"] .instr-chips .chip { opacity: 0; animation: chipIn 0.4s var(--ease) forwards; }
[data-stage="1"] .instr-chips .chip:nth-child(1) { animation-delay: 0.05s; }
[data-stage="1"] .instr-chips .chip:nth-child(2) { animation-delay: 0.13s; }
[data-stage="1"] .instr-chips .chip:nth-child(3) { animation-delay: 0.21s; }
[data-stage="1"] .instr-chips .chip:nth-child(4) { animation-delay: 0.29s; }
[data-stage="1"] .instr-chips .chip:nth-child(5) { animation-delay: 0.37s; }
[data-stage="1"] .instr-chips .chip:nth-child(6) { animation-delay: 0.45s; }
[data-stage="1"] .instr-chips .chip:nth-child(7) { animation-delay: 0.53s; }
@keyframes chipIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* diffusion chain */
.chain-track { stroke: var(--hair); stroke-width: 2; }
.chain-dots circle { fill: var(--paper); stroke: var(--muted); stroke-width: 1.6; }
.chain-flow { fill: var(--accent); filter: drop-shadow(0 0 6px var(--accent-glow)); }
[data-stage="3"] .chain-flow { animation: chainMove 2.6s var(--ease) infinite; }
@keyframes chainMove { 0% { transform: translateX(0); opacity: 0; } 8% { opacity: 1; } 92% { opacity: 1; } 100% { transform: translateX(340px); opacity: 0; } }
.denoise-out { fill: var(--accent-deep); letter-spacing: 0.04em; font-weight: 500; }
.cl { fill: var(--muted); }

/* reward layer */
.gbox rect { fill: var(--paper); stroke: var(--hair); stroke-width: 1.3; }
.gbox.alt rect { stroke: var(--accent); }
.gbox text { fill: var(--ink-2); }
.reward-eq { fill: var(--ink); font-weight: 600; }
.reward-arc { fill: none; stroke: var(--accent); color: var(--accent); stroke-width: 1.8;
  stroke-dasharray: 5 6; animation: dashMove 0.9s linear infinite; }

/* result layer */
.result-big { fill: var(--ink); letter-spacing: 0.01em; }
.bars .b-base { fill: var(--faint); }
.bars .b-ours { fill: var(--accent); }
[data-stage="5"] .bars rect { transform-box: fill-box; transform-origin: bottom; animation: barGrow 0.6s var(--ease) both; }
[data-stage="5"] .bars .bar-pair:nth-child(2) rect { animation-delay: 0.08s; }
[data-stage="5"] .bars .bar-pair:nth-child(3) rect { animation-delay: 0.16s; }
[data-stage="5"] .bars .bar-pair:nth-child(4) rect { animation-delay: 0.24s; }
@keyframes barGrow { from { transform: scaleY(0); } to { transform: scaleY(1); } }

/* ============ MetaEx-GAN ============ */
#vizGan .persist .flow { color: var(--muted); }
/* hide explorer + meta/sample flows in classic stage */
#vizGan[data-stage="0"] .node-explorer,
#vizGan[data-stage="0"] .f-sample,
#vizGan[data-stage="0"] .fl-sample,
#vizGan[data-stage="0"] .f-meta,
#vizGan[data-stage="0"] .fl-meta { opacity: 0; }
.node-explorer, .f-sample, .fl-sample, .f-meta, .fl-meta { transition: opacity 0.5s var(--ease); }

/* node emphasis */
#vizGan[data-stage="0"] .node-gen .node-box,
#vizGan[data-stage="3"] .node-gen .node-box,
#vizGan[data-stage="3"] .node-disc .node-box { stroke: var(--accent); stroke-width: 2; }
#vizGan[data-stage="1"] .node-explorer .node-box,
#vizGan[data-stage="2"] .node-explorer .node-box,
#vizGan[data-stage="4"] .node-explorer .node-box { stroke: var(--accent); stroke-width: 2; }

/* active flows */
#vizGan[data-stage="2"] .f-sample { stroke: var(--accent); color: var(--accent); stroke-dasharray: 5 7; animation: dashMove 0.9s linear infinite; }
#vizGan[data-stage="3"] .f-gen,
#vizGan[data-stage="3"] .f-reward { stroke: var(--accent); color: var(--accent); stroke-dasharray: 5 7; animation: dashMove 0.9s linear infinite; }
#vizGan[data-stage="4"] .f-meta { stroke: var(--accent); color: var(--accent); stroke-dasharray: 5 7; animation: dashMove 0.9s linear infinite; }

/* classic problem layer */
.role-badge { fill: var(--paper-3); stroke: var(--hair); stroke-width: 1; }
.badge-tx { fill: var(--ink-2); }
.collapse-dots circle { fill: var(--ink-2); opacity: 0.5; }
[data-stage="0"] .collapse-dots circle { animation: jitter 1.8s ease-in-out infinite; }
.collapse-dots circle:nth-child(2) { animation-delay: 0.2s; }
.collapse-dots circle:nth-child(3) { animation-delay: 0.4s; }
.collapse-dots circle:nth-child(4) { animation-delay: 0.6s; }
.collapse-dots circle:nth-child(5) { animation-delay: 0.8s; }
@keyframes jitter { 0%,100% { transform: translate(0,0); } 50% { transform: translate(1px,-1px); } }

/* sample / diversity */
.spread-dots circle { fill: var(--accent); }
[data-stage="2"] .spread-dots circle { animation: floaty 2.4s ease-in-out infinite; }
.spread-dots circle:nth-child(odd) { animation-delay: 0.5s; }
@keyframes floaty { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-3px); } }
.tok-fly text { fill: var(--accent-deep); }

/* learn / discriminate */
.disc-out { fill: var(--accent-deep); font-weight: 600; }

.lyr-meta .reward-eq, .lyr-result .result-big { }

/* result scatter */
.pt { transition: none; }
.pt.base { fill: var(--muted); }
.pt.ours { fill: var(--accent); filter: drop-shadow(0 0 6px var(--accent-glow)); }
.ours-lbl { fill: var(--accent-deep) !important; font-weight: 600; }

/* =========================================================================
   GENERIC LAYER STAGING — used by #vizRap and #vizSos
   ========================================================================= */
[data-stage="0"] .ly0, [data-stage="1"] .ly1, [data-stage="2"] .ly2,
[data-stage="3"] .ly3, [data-stage="4"] .ly4, [data-stage="5"] .ly5 { opacity: 1; }

/* ============ RapGAN (#vizRap) ============ */
#vizRap .persist .node-box { stroke: var(--ink-2); }
#vizRap[data-stage="2"] .node-gen .node-box,
#vizRap[data-stage="4"] .node-gen .node-box { stroke: var(--accent); stroke-width: 2; }
#vizRap[data-stage="3"] .node-disc .node-box,
#vizRap[data-stage="4"] .node-disc .node-box { stroke: var(--accent); stroke-width: 2; }
#vizRap[data-stage="2"] .f-gd,
#vizRap[data-stage="4"] .f-rew { stroke: var(--accent); color: var(--accent); stroke-dasharray: 5 7; animation: dashMove 0.9s linear infinite; }

/* MCTS rollout tree (problem) */
.mcts { fill: none; stroke: var(--faint); stroke-width: 1.3; }
.mcts.expensive { stroke: var(--ink-2); stroke-dasharray: 4 4; }
.mcts-leaf { fill: var(--paper); stroke: var(--muted); stroke-width: 1.3; }
.mcts-root { fill: var(--ink-2); }

/* phrase chips (PRO) */
.ph-chip rect { fill: var(--paper); stroke: var(--hair); stroke-width: 1.2; }
.ph-chip.meaning rect { fill: var(--accent-soft); stroke: var(--accent); stroke-width: 1.4; }
.ph-chip text { fill: var(--ink-2); }
.ph-chip.meaning text { fill: var(--accent-deep); font-weight: 600; }
.ph-bracket { fill: none; stroke: var(--accent); stroke-width: 1.4; }
[data-stage="1"] .ph-chip { opacity: 0; animation: chipIn 0.4s var(--ease) forwards; }
[data-stage="1"] .ph-chip:nth-child(2) { animation-delay: 0.06s; }
[data-stage="1"] .ph-chip:nth-child(3) { animation-delay: 0.14s; }
[data-stage="1"] .ph-chip:nth-child(4) { animation-delay: 0.22s; }
[data-stage="1"] .ph-chip:nth-child(5) { animation-delay: 0.30s; }
[data-stage="1"] .ph-chip:nth-child(6) { animation-delay: 0.38s; }

/* short phrase-bounded rollout arcs */
.roll-arc { fill: none; stroke: var(--accent); stroke-width: 1.6; stroke-linecap: round; }
[data-stage="2"] .roll-arc { stroke-dasharray: 4 5; animation: dashMove 0.9s linear infinite; }

/* attention bars (AREGS) */
.attn-bar { fill: var(--accent); }
[data-stage="3"] .attn-bar { transform-box: fill-box; transform-origin: bottom; animation: barGrow 0.5s var(--ease) both; }
[data-stage="3"] .attn-bar:nth-child(2) { animation-delay: 0.05s; }
[data-stage="3"] .attn-bar:nth-child(3) { animation-delay: 0.10s; }
[data-stage="3"] .attn-bar:nth-child(4) { animation-delay: 0.15s; }
[data-stage="3"] .attn-bar:nth-child(5) { animation-delay: 0.20s; }
[data-stage="3"] .attn-bar:nth-child(6) { animation-delay: 0.25s; }
[data-stage="3"] .attn-bar:nth-child(7) { animation-delay: 0.30s; }
.attn-base { fill: var(--faint); }

/* feature-matching distributions */
.fm-real { fill: none; stroke: var(--muted); stroke-width: 1.8; }
.fm-gen { fill: none; stroke: var(--accent); stroke-width: 2; filter: drop-shadow(0 0 3px var(--accent-glow)); }
.fm-sim { fill: var(--ink); font-weight: 600; }

/* ============ SODM / SOS (#vizSos) ============ */
.post { stroke-width: 1.2; transition: x 0.5s var(--ease), y 0.5s var(--ease); }
.post.norm { fill: var(--paper); stroke: var(--hair); }
.post.over { fill: var(--ink-2); stroke: var(--ink-2); }
.post.calm { fill: var(--accent-soft); stroke: var(--accent); }
.post-dot { fill: var(--muted); }

.load-track { fill: none; stroke: var(--hair); stroke-width: 1.2; }
.load-fill { transition: none; }
.load-fill.hot { fill: var(--ink-2); }
.load-fill.cool { fill: var(--accent); }
.gauge-lbl { fill: var(--muted); font-family: var(--mono); }

.src-chip rect { fill: var(--paper); stroke: var(--hair); stroke-width: 1.2; }
.src-chip.over rect { fill: var(--ink-2); }
.src-chip.over text { fill: var(--paper); }
.src-chip text { fill: var(--ink-2); }

.net-layer { fill: var(--paper); stroke: var(--ink-2); stroke-width: 1.3; }
.net-layer.active { stroke: var(--accent); fill: var(--accent-soft); }
.net-flow { fill: none; stroke: var(--hair); stroke-width: 1.4; }
#vizSos[data-stage="2"] .net-flow { stroke: var(--accent); stroke-dasharray: 4 5; animation: dashMove 0.9s linear infinite; }
.acc-big { fill: var(--accent-deep); font-weight: 600; }

.thresh-line { stroke: var(--accent); stroke-width: 1.4; stroke-dasharray: 5 4; }
.thresh-lbl { fill: var(--accent-deep); font-family: var(--mono); }
.score-tag { fill: var(--muted); font-family: var(--mono); }

.reorder-arc { fill: none; stroke: var(--accent); stroke-width: 1.5; stroke-linecap: round; }
[data-stage="4"] .reorder-arc { stroke-dasharray: 4 5; animation: dashMove 0.9s linear infinite; }
.insert-mark { fill: var(--accent); }

.stat-big { fill: var(--ink); font-weight: 600; }
.stat-accent { fill: var(--accent-deep); font-weight: 600; }
.stat-cap { fill: var(--muted); font-family: var(--mono); }

/* ============ QMVDet (#vizQmv) ============ */
.cam { fill: var(--paper); stroke: var(--ink-2); stroke-width: 1.3; transition: stroke 0.4s, fill 0.4s; }
.cam.reliable { stroke: var(--accent); fill: var(--accent-soft); }
.frustum { fill: none; stroke: var(--hair); stroke-width: 1; }
.frustum.active { stroke: var(--accent); stroke-dasharray: 4 5; }
#vizQmv[data-stage="2"] .frustum.active { animation: dashMove 0.9s linear infinite; }
.ground { fill: var(--paper-3); stroke: var(--ink-2); stroke-width: 1.2; }
.gp-grid { stroke: var(--hair); stroke-width: 1; }
.occ-dot { fill: var(--accent); }
[data-stage="2"] .occ-dot, [data-stage="5"] .occ-dot { animation: floaty 2.4s ease-in-out infinite; }
.occ-dot:nth-child(odd) { animation-delay: 0.5s; }
.cam-w { fill: var(--muted); font-family: var(--mono); }

.img-frame { fill: var(--paper); stroke: var(--ink-2); stroke-width: 1.3; }
.foot-2d { fill: var(--muted); }
.foot-3d { fill: var(--accent); }
.track-line { fill: none; stroke: var(--accent); stroke-width: 1.6; stroke-linecap: round; }
.disc-gap { stroke: var(--ink-2); stroke-width: 1.4; stroke-dasharray: 2 2; }

.cons-base { fill: var(--faint); }
.cons-bar { fill: var(--accent); }
[data-stage="3"] .cons-bar { transform-box: fill-box; transform-origin: bottom; animation: barGrow 0.5s var(--ease) both; }
[data-stage="3"] .cons-bar:nth-child(2) { animation-delay: 0.06s; }
[data-stage="3"] .cons-bar:nth-child(3) { animation-delay: 0.12s; }
[data-stage="3"] .cons-bar:nth-child(4) { animation-delay: 0.18s; }
[data-stage="3"] .cons-bar:nth-child(5) { animation-delay: 0.24s; }

.qbl-box { fill: var(--paper); stroke: var(--accent); stroke-width: 1.4; }
[data-stage="4"] .qbl-box { animation: pulseBox 2s ease-in-out infinite; }
@keyframes pulseBox { 0%,100% { stroke-width: 1.4; } 50% { stroke-width: 2.4; } }
.qbl-flow { fill: none; stroke: var(--accent); stroke-width: 1.6; stroke-dasharray: 5 6; }
[data-stage="4"] .qbl-flow { animation: dashMove 0.9s linear infinite; }
.attn-w { fill: var(--accent); }
.attn-w.dim { fill: var(--faint); }

@media (prefers-reduced-motion: reduce) {
  .viz-body * { animation: none !important; }
}
