// Promo Video — Scenes 1-4
//   1. Cold open (0-8s)
//   2. Why generic AI failed (8-18s)
//   3. Mentor energy check (18-30s)
//   4. 4-level hint ladder (30-43s)

// ============================================================================
// SCENE 1 — Cold Open. Pi refuses to give the answer.
// ============================================================================
function Scene1ColdOpen() {
  const { localTime } = useSprite();
  const t = localTime;

  // Frame fade in
  const frameOp = Math.min(1, t / 0.6);
  const frameTy = (1 - Easing.easeOutCubic(Math.min(1, t / 0.6))) * 30;

  return (
    <div style={{
      position: 'absolute', inset: 0,
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      background: palette.paper,
    }}>
      <SceneNumber idx={1} total={8} label="The cold open" />
      <PaperChrome time="00:18 · TUES" />

      <div style={{
        opacity: frameOp,
        transform: `translateY(${frameTy}px)`,
      }}>
        <ChatFrame
          width={1240}
          padBody={36}
          header={<ChatHeader name="PROFESSOR PI" subject="MATHS" meta="18 MIN BEFORE PIANO" />}
          footer={
            <div style={{
              padding: '20px 36px',
              borderTop: `1px solid ${palette.hair}`,
              background: palette.paper2,
              display: 'flex', alignItems: 'center', justifyContent: 'space-between',
              fontFamily: fonts.mono, fontSize: 14, letterSpacing: '0.06em',
              color: palette.muted, textTransform: 'uppercase',
            }}>
              <span>↻ session 03 · year 8 · algebra</span>
              <span style={{
                background: palette.accent, color: palette.onDark,
                padding: '12px 22px', borderRadius: 10,
                fontFamily: fonts.sans, textTransform: 'none', letterSpacing: 0,
                fontWeight: 500, fontSize: 16,
              }}>Show your working →</span>
            </div>
          }
        >
          <ChatBubble who="tutor" name="PROFESSOR PI" avatar="Pi" appearAt={0.9}>
            Hi Rina — I see you've got 18 minutes before piano. Let's expand <InlineCode>3(x + 4)</InlineCode>.{' '}
            <strong style={{ color: palette.accentDeep, fontWeight: 600 }}>
              Before I tell you how — what do you remember about the distributive property?
            </strong>
          </ChatBubble>

          {/* Rina typing dots */}
          {t >= 3.0 && t < 3.9 && (
            <div style={{
              display: 'flex', justifyContent: 'flex-end',
              alignItems: 'center', gap: 8,
              padding: '0 60px',
              opacity: Math.min(1, (t - 3.0) / 0.3),
            }}>
              <div style={{ display: 'flex', gap: 6, alignItems: 'center', padding: '8px 0' }}>
                {[0, 1, 2].map(i => (
                  <i key={i} style={{
                    width: 10, height: 10, borderRadius: '50%',
                    background: palette.muted,
                    opacity: 0.3 + 0.7 * (0.5 + 0.5 * Math.sin(t * 6 + i * 1.2)),
                  }} />
                ))}
              </div>
              <div style={{ fontFamily: fonts.mono, fontSize: 13, color: palette.muted, letterSpacing: '0.06em', textTransform: 'uppercase' }}>
                Rina is typing
              </div>
            </div>
          )}

          <ChatBubble who="kid" name="RINA · Y8" avatar="R" appearAt={3.9}>
            Multiply the 3 with both terms?
          </ChatBubble>
        </ChatFrame>
      </div>

      {/* Highlighted question callout at end */}
      {t >= 5.5 && (
        <div style={{
          position: 'absolute',
          top: 920, left: '50%',
          transform: `translateX(-50%) translateY(${(1 - Math.min(1, (t - 5.5) / 0.5)) * 12}px)`,
          opacity: Math.min(1, (t - 5.5) / 0.5),
          fontFamily: fonts.serif, fontStyle: 'italic',
          fontSize: 30,
          color: palette.inkDeep,
          letterSpacing: '-0.01em',
        }}>
          A tutor that <span style={{ background: 'oklch(0.92 0.05 150 / 0.7)', padding: '2px 8px' }}>opens with a question</span>.
        </div>
      )}
    </div>
  );
}

// ============================================================================
// SCENE 2 — Why generic AI failed her. Side-by-side comparison.
// ============================================================================
function Scene2Comparison() {
  const { localTime } = useSprite();
  const t = localTime;

  // Left card: enters 0-1s
  const leftOp = Math.min(1, t / 0.6);
  const leftTx = (1 - Easing.easeOutCubic(Math.min(1, t / 0.7))) * -60;

  // Right card: enters at 4.5s
  const rightStart = 4.5;
  const rightOp = t < rightStart ? 0 : Math.min(1, (t - rightStart) / 0.6);
  const rightTx = t < rightStart ? 60 : (1 - Easing.easeOutCubic(Math.min(1, (t - rightStart) / 0.7))) * 60;

  // Red strike on left card: 3.6s
  const strikeStart = 3.6;
  const strikeProg = Math.max(0, Math.min(1, (t - strikeStart) / 0.5));

  return (
    <div style={{
      position: 'absolute', inset: 0,
      background: palette.paper,
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      gap: 56,
    }}>
      <SceneNumber idx={2} total={8} label="Why generic AI failed her" />
      <PaperChrome time="EVERY OTHER AI" />

      {/* LEFT — generic AI */}
      <div style={{
        opacity: leftOp,
        transform: `translateX(${leftTx}px)`,
        width: 720, position: 'relative',
      }}>
        <div style={{
          background: palette.card,
          border: `1px solid ${palette.hair}`,
          borderRadius: 18,
          overflow: 'hidden',
          filter: strikeProg > 0 ? `grayscale(${strikeProg}) opacity(${1 - strikeProg * 0.3})` : 'none',
          transition: 'none',
        }}>
          <div style={{
            padding: '18px 24px', borderBottom: `1px solid ${palette.hair}`,
            background: palette.paper2,
            fontFamily: fonts.mono, fontSize: 14, letterSpacing: '0.08em',
            color: palette.muted, textTransform: 'uppercase',
            display: 'flex', justifyContent: 'space-between',
          }}>
            <span>◇ Generic AI helper</span>
            <span>instant answers</span>
          </div>
          <div style={{ padding: 28, display: 'flex', flexDirection: 'column', gap: 14, minHeight: 320 }}>
            {/* Kid question */}
            {t >= 1.0 && (
              <div style={{
                opacity: Math.min(1, (t - 1.0) / 0.4),
                alignSelf: 'flex-end',
                background: palette.inkDeep,
                color: palette.onDark,
                padding: '14px 20px',
                borderRadius: 14, borderBottomRightRadius: 4,
                fontFamily: fonts.sans, fontSize: 22,
                maxWidth: '80%',
              }}>
                what is <InlineCode dark>3(x + 4)</InlineCode>?
              </div>
            )}
            {/* Instant AI reply */}
            {t >= 2.2 && (
              <div style={{
                opacity: Math.min(1, (t - 2.2) / 0.3),
                alignSelf: 'flex-start',
                background: palette.paper2,
                color: palette.inkDeep,
                padding: '14px 20px',
                borderRadius: 14, borderBottomLeftRadius: 4,
                fontFamily: fonts.sans, fontSize: 22,
                maxWidth: '80%',
                display: 'flex', alignItems: 'center', gap: 12,
              }}>
                <span><InlineCode>3x + 12</InlineCode></span>
                <span style={{
                  background: palette.go, color: palette.onDark,
                  width: 26, height: 26, borderRadius: '50%',
                  display: 'grid', placeItems: 'center',
                  fontSize: 16, fontWeight: 600,
                }}>✓</span>
              </div>
            )}
            {/* Outcome stamp */}
            {t >= 3.2 && (
              <div style={{
                opacity: Math.min(1, (t - 3.2) / 0.3),
                fontFamily: fonts.mono, fontSize: 13, letterSpacing: '0.08em',
                color: palette.muted, textTransform: 'uppercase',
                marginTop: 16, paddingTop: 16,
                borderTop: `1px dashed ${palette.hair}`,
              }}>
                ↳ homework done in 4 seconds · nothing retained
              </div>
            )}
          </div>
        </div>

        {/* Red strike-through across the card */}
        {strikeProg > 0 && (
          <svg
            viewBox="0 0 720 420"
            preserveAspectRatio="none"
            style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', pointerEvents: 'none' }}
          >
            <line
              x1="20" y1="40" x2={20 + strikeProg * 680} y2={40 + strikeProg * 340}
              stroke={palette.stop} strokeWidth="6" strokeLinecap="round"
              opacity={Math.min(1, strikeProg * 2)}
            />
            {strikeProg > 0.8 && (
              <text
                x="360" y="220" textAnchor="middle"
                fill={palette.stop}
                style={{ fontFamily: fonts.serif, fontStyle: 'italic', fontSize: 36, opacity: Math.min(1, (strikeProg - 0.8) * 5) }}
              >
                she stopped learning.
              </text>
            )}
          </svg>
        )}
      </div>

      {/* RIGHT — aitutors.me */}
      <div style={{
        opacity: rightOp,
        transform: `translateX(${rightTx}px)`,
        width: 720, position: 'relative',
      }}>
        <div style={{
          background: palette.card,
          border: `2px solid ${palette.accent}`,
          borderRadius: 18, overflow: 'hidden',
          boxShadow: '0 30px 80px -40px ' + palette.accentDeep,
        }}>
          <div style={{
            padding: '18px 24px', borderBottom: `1px solid ${palette.hair}`,
            background: palette.accentSoft,
            fontFamily: fonts.mono, fontSize: 14, letterSpacing: '0.08em',
            color: palette.accentDeep, textTransform: 'uppercase',
            display: 'flex', justifyContent: 'space-between',
          }}>
            <span><SparkGlyph size={11} color={palette.accentDeep} /> aitutors.me · Pi</span>
            <span>understanding first</span>
          </div>
          <div style={{ padding: 28, display: 'flex', flexDirection: 'column', gap: 14, minHeight: 320 }}>
            {t >= rightStart + 0.4 && (
              <div style={{
                opacity: Math.min(1, (t - rightStart - 0.4) / 0.4),
                alignSelf: 'flex-end',
                background: palette.inkDeep,
                color: palette.onDark,
                padding: '14px 20px',
                borderRadius: 14, borderBottomRightRadius: 4,
                fontFamily: fonts.sans, fontSize: 22,
                maxWidth: '80%',
              }}>
                what is <InlineCode dark>3(x + 4)</InlineCode>?
              </div>
            )}
            {t >= rightStart + 1.6 && (
              <div style={{
                opacity: Math.min(1, (t - rightStart - 1.6) / 0.4),
                alignSelf: 'flex-start',
                background: palette.paper2,
                color: palette.inkDeep,
                padding: '16px 22px',
                borderRadius: 14, borderBottomLeftRadius: 4,
                fontFamily: fonts.sans, fontSize: 22,
                maxWidth: '85%',
                lineHeight: 1.45,
              }}>
                <span style={{ color: palette.accentDeep, fontWeight: 600 }}>Before I tell you —</span> what do you remember about the distributive property?
              </div>
            )}
            {t >= rightStart + 3.4 && (
              <div style={{
                opacity: Math.min(1, (t - rightStart - 3.4) / 0.3),
                fontFamily: fonts.mono, fontSize: 13, letterSpacing: '0.08em',
                color: palette.accentDeep, textTransform: 'uppercase',
                marginTop: 16, paddingTop: 16,
                borderTop: `1px dashed ${palette.hair}`,
              }}>
                ↳ misconception caught · understanding built
              </div>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

// ============================================================================
// SCENE 3 — Mentor energy check (GREEN / AMBER / RED).
// ============================================================================
function Scene3EnergyCheck() {
  const { localTime } = useSprite();
  const t = localTime;

  const lights = [
    { key: 'green', label: 'GREEN', sub: 'rested · sharp', color: palette.go, action: 'push hard' },
    { key: 'amber', label: 'AMBER', sub: 'okay · scattered', color: palette.amber, action: '15 min · light' },
    { key: 'red',   label: 'RED',   sub: 'spent · drained', color: palette.stop, action: 'rest tonight' },
  ];

  // Cursor moves and clicks AMBER around t=4
  const clickTime = 4.5;
  const selectedAt = clickTime + 0.2;
  // Cursor moves from off-screen to AMBER ring center
  const targetX = 1100, targetY = 690;
  const cursorEntry = Math.min(1, Math.max(0, (t - 2.5) / 1.8));
  const cursorX = -100 + (targetX + 100) * Easing.easeInOutCubic(cursorEntry);
  const cursorY = 420 + (targetY - 420) * Easing.easeInOutCubic(cursorEntry);
  const cursorPress = t >= clickTime && t < clickTime + 0.25 ? 0.85 : 1;
  const cursorVisible = t >= 2.2 && t < clickTime + 2;
  const cursorOp = cursorVisible
    ? Math.min(1, (t - 2.2) / 0.3) * Math.max(0, 1 - Math.max(0, (t - clickTime - 1.7) / 0.4))
    : 0;

  return (
    <div style={{
      position: 'absolute', inset: 0,
      background: palette.paper,
    }}>
      <SceneNumber idx={3} total={8} label="The energy check" />
      <PaperChrome time="MENTOR · WEEK 03" />

      {/* The Mentor card */}
      <div style={{
        position: 'absolute', top: 180, left: '50%',
        transform: `translateX(-50%) translateY(${(1 - Easing.easeOutCubic(Math.min(1, t / 0.6))) * 30}px)`,
        opacity: Math.min(1, t / 0.5),
        width: 1260,
      }}>
        <div style={{
          background: palette.card,
          border: `1px solid ${palette.hair}`,
          borderRadius: 22, overflow: 'hidden',
          boxShadow: '0 40px 80px -40px rgba(0,0,0,0.2)',
        }}>
          {/* Header */}
          <div style={{
            padding: '22px 36px', borderBottom: `1px solid ${palette.hair}`,
            background: palette.paper2,
            display: 'flex', justifyContent: 'space-between', alignItems: 'center',
            fontFamily: fonts.mono, fontSize: 15, letterSpacing: '0.08em',
            color: palette.muted, textTransform: 'uppercase',
          }}>
            <span style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
              <span style={{
                width: 10, height: 10, borderRadius: '50%', background: palette.go,
                boxShadow: '0 0 0 4px oklch(0.58 0.115 145 / 0.18)',
              }} />
              The Mentor · routing today's session
            </span>
            <span>tues 17:42 · before piano</span>
          </div>

          {/* Mentor's question */}
          <div style={{ padding: '36px 64px 24px' }}>
            {t >= 0.6 && (
              <div style={{
                opacity: Math.min(1, (t - 0.6) / 0.5),
                transform: `translateY(${(1 - Math.min(1, (t - 0.6) / 0.5)) * 10}px)`,
                fontFamily: fonts.serif,
                fontSize: 42, lineHeight: 1.25,
                color: palette.inkDeep,
                letterSpacing: '-0.018em',
                maxWidth: 980,
              }}>
                <span style={{ fontFamily: fonts.mono, fontSize: 14, letterSpacing: '0.08em', color: palette.accentDeep, textTransform: 'uppercase', display: 'block', marginBottom: 10 }}>
                  Mentor asks
                </span>
                Hi Rina — football was a long one. How's your energy right now?
              </div>
            )}
          </div>

          {/* Three energy chips */}
          <div style={{
            padding: '8px 56px 36px',
            display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 22,
          }}>
            {lights.map((l, i) => {
              const showAt = 1.6 + i * 0.2;
              const op = Math.min(1, Math.max(0, (t - showAt) / 0.4));
              const isAmber = l.key === 'amber';
              const isSelected = isAmber && t >= selectedAt;
              const pulse = isSelected ? 1 + 0.04 * Math.sin((t - selectedAt) * 6) : 1;
              const dim = !isSelected && t >= selectedAt + 0.4 ? 0.45 : 1;
              return (
                <div key={l.key} style={{
                  opacity: op * dim,
                  transform: `translateY(${(1 - op) * 14}px) scale(${pulse})`,
                  border: isSelected ? `2px solid ${l.color}` : `1px solid ${palette.hair}`,
                  borderRadius: 16,
                  background: isSelected
                    ? `color-mix(in oklch, ${l.color} 14%, ${palette.card})`
                    : palette.card,
                  padding: '28px 26px',
                  display: 'flex', alignItems: 'center', gap: 22,
                  boxShadow: isSelected
                    ? `0 20px 40px -20px ${l.color}, 0 0 0 6px color-mix(in oklch, ${l.color} 12%, transparent)`
                    : 'none',
                  transition: 'box-shadow 200ms',
                }}>
                  <div style={{
                    width: 56, height: 56, borderRadius: '50%',
                    background: l.color,
                    boxShadow: `0 0 0 8px color-mix(in srgb, ${l.color} 18%, transparent)`,
                    flex: 'none',
                  }} />
                  <div>
                    <div style={{
                      fontFamily: fonts.mono, fontSize: 16, letterSpacing: '0.08em',
                      color: l.color, fontWeight: 600,
                    }}>{l.label}</div>
                    <div style={{
                      fontFamily: fonts.serif, fontSize: 24, color: palette.inkDeep,
                      fontStyle: 'italic', marginTop: 4,
                    }}>{l.sub}</div>
                    <div style={{
                      fontFamily: fonts.mono, fontSize: 12, letterSpacing: '0.06em',
                      color: palette.muted, textTransform: 'uppercase',
                      marginTop: 8,
                    }}>→ {l.action}</div>
                  </div>
                </div>
              );
            })}
          </div>

          {/* Mentor's adapted response */}
          {t >= selectedAt + 1.0 && (
            <div style={{
              padding: '20px 64px 32px',
              opacity: Math.min(1, (t - selectedAt - 1.0) / 0.5),
              transform: `translateY(${(1 - Math.min(1, (t - selectedAt - 1.0) / 0.5)) * 12}px)`,
            }}>
              <div style={{
                padding: '22px 28px',
                background: palette.accentSoft,
                border: `1px solid color-mix(in oklch, ${palette.accent} 35%, ${palette.hair})`,
                borderRadius: 14,
                fontFamily: fonts.sans,
                fontSize: 23, lineHeight: 1.5,
                color: palette.inkDeep,
                display: 'flex', alignItems: 'flex-start', gap: 18,
              }}>
                <span style={{
                  fontFamily: fonts.mono, fontSize: 13, letterSpacing: '0.08em',
                  color: palette.accentDeep, textTransform: 'uppercase',
                  paddingTop: 5, flex: 'none',
                }}>MENTOR →</span>
                <span>Got it. Let's keep it light — <strong style={{ color: palette.accentDeep, fontWeight: 600 }}>15 minutes of fractions</strong>, not Pythagoras. Save the hard stuff for Sunday morning.</span>
              </div>
            </div>
          )}
        </div>
      </div>

      {/* Animated cursor */}
      {cursorOp > 0 && (
        <svg
          width="36" height="44"
          viewBox="0 0 36 44"
          style={{
            position: 'absolute',
            left: cursorX, top: cursorY,
            transform: `scale(${cursorPress})`,
            transformOrigin: 'top left',
            opacity: cursorOp,
            filter: 'drop-shadow(0 2px 6px rgba(0,0,0,0.3))',
            zIndex: 30,
          }}
        >
          <path d="M2 2 L2 30 L10 24 L15 36 L20 34 L15 22 L24 22 Z" fill={palette.inkDeep} stroke="white" strokeWidth="1.5" strokeLinejoin="round" />
        </svg>
      )}
    </div>
  );
}

// ============================================================================
// SCENE 4 — 4-level hint ladder. Pi guides without giving answer.
// ============================================================================
function Scene4HintLadder() {
  const { localTime } = useSprite();
  const t = localTime;

  const hints = [
    { lvl: 'L1', text: 'What operation might help here?', start: 1.0 },
    { lvl: 'L2', text: <>You've got <InlineCode>3(x + 4)</InlineCode>. What does <em style={{ color: palette.accentDeep, fontStyle: 'italic' }}>distributing</em> mean?</>, start: 3.6 },
    { lvl: 'L3', text: <>Try multiplying the 3 across each term — <InlineCode>3 × x</InlineCode>, then <InlineCode>3 × 4</InlineCode>.</>, start: 6.6 },
    { lvl: 'L4', text: 'Worked example with one number swapped (locked — not needed yet)', start: 9.6, locked: true },
  ];

  // Rina solves at 9.5s, before L4 unlocks
  const solveAt = 9.5;

  return (
    <div style={{
      position: 'absolute', inset: 0,
      background: palette.paper,
      display: 'flex', flexDirection: 'column', alignItems: 'center',
      paddingTop: 130,
    }}>
      <SceneNumber idx={4} total={8} label="The hint ladder" />
      <PaperChrome time="PROFESSOR PI · LIVE" />

      <div style={{ display: 'flex', gap: 56, alignItems: 'flex-start', width: 1700, marginTop: 30 }}>
        {/* LEFT — the chat */}
        <div style={{ flex: 1.05, display: 'flex', flexDirection: 'column', gap: 14 }}>
          {/* Pi opens */}
          {t >= 0.3 && (
            <div style={{
              opacity: Math.min(1, (t - 0.3) / 0.4),
              transform: `translateY(${(1 - Math.min(1, (t - 0.3) / 0.4)) * 10}px)`,
              padding: '20px 26px',
              background: palette.paper2,
              border: `1px solid ${palette.hair}`,
              borderRadius: 16, borderBottomLeftRadius: 4,
              fontFamily: fonts.sans, fontSize: 24,
              color: palette.inkDeep, lineHeight: 1.45,
            }}>
              <div style={{ fontFamily: fonts.mono, fontSize: 13, letterSpacing: '0.08em', color: palette.accentDeep, textTransform: 'uppercase', marginBottom: 8 }}>
                Professor Pi
              </div>
              Expand <InlineCode>3(x + 4)</InlineCode>. Show your working.
            </div>
          )}
          {/* Rina hesitant */}
          {t >= 2.2 && t < solveAt + 0.5 && (
            <div style={{
              opacity: Math.min(1, (t - 2.2) / 0.4) * Math.max(0, 1 - Math.max(0, (t - solveAt - 0.2) / 0.3)),
              alignSelf: 'flex-end',
              padding: '18px 24px',
              background: palette.inkDeep, color: palette.onDark,
              borderRadius: 16, borderBottomRightRadius: 4,
              fontFamily: fonts.sans, fontSize: 22, fontStyle: 'italic',
              maxWidth: '70%',
            }}>
              um… not sure
            </div>
          )}
          {/* Rina's answer */}
          {t >= solveAt && (
            <div style={{
              opacity: Math.min(1, (t - solveAt) / 0.4),
              transform: `translateY(${(1 - Easing.easeOutBack(Math.min(1, (t - solveAt) / 0.5))) * 14}px)`,
              alignSelf: 'flex-end',
              padding: '20px 26px',
              background: palette.inkDeep, color: palette.onDark,
              borderRadius: 16, borderBottomRightRadius: 4,
              fontFamily: fonts.sans, fontSize: 24,
              maxWidth: '75%',
            }}>
              <div style={{ fontFamily: fonts.mono, fontSize: 13, letterSpacing: '0.08em', color: palette.onDark2, textTransform: 'uppercase', marginBottom: 8 }}>RINA · Y8</div>
              Oh — <InlineCode dark>3x</InlineCode> and <InlineCode dark>12</InlineCode>. So <InlineCode dark>3x + 12</InlineCode>.
            </div>
          )}
          {/* Pi confirms */}
          {t >= solveAt + 1.5 && (
            <div style={{
              opacity: Math.min(1, (t - solveAt - 1.5) / 0.4),
              padding: '20px 26px',
              background: palette.accentSoft,
              border: `1px solid color-mix(in oklch, ${palette.accent} 35%, ${palette.hair})`,
              borderRadius: 16, borderBottomLeftRadius: 4,
              fontFamily: fonts.sans, fontSize: 24,
              color: palette.inkDeep,
            }}>
              <div style={{ fontFamily: fonts.mono, fontSize: 13, letterSpacing: '0.08em', color: palette.accentDeep, textTransform: 'uppercase', marginBottom: 8 }}>
                Professor Pi
              </div>
              <strong style={{ fontWeight: 600 }}>Exactly.</strong> You did the move yourself.
            </div>
          )}
        </div>

        {/* RIGHT — the hint ladder */}
        <div style={{
          flex: 0.95,
          background: palette.card,
          border: `1px solid ${palette.hair}`,
          borderRadius: 18,
          padding: '26px 28px',
          opacity: Math.min(1, t / 0.5),
          boxShadow: '0 30px 80px -50px rgba(0,0,0,0.18)',
        }}>
          <div style={{
            display: 'flex', justifyContent: 'space-between', alignItems: 'center',
            paddingBottom: 14, borderBottom: `1px solid ${palette.hair}`, marginBottom: 16,
          }}>
            <div style={{
              fontFamily: fonts.serif, fontSize: 22, color: palette.inkDeep,
              fontStyle: 'italic', letterSpacing: '-0.01em',
            }}>Pi's hint ladder</div>
            <div style={{
              fontFamily: fonts.mono, fontSize: 12, letterSpacing: '0.06em',
              color: palette.muted, textTransform: 'uppercase',
            }}>4 levels · escalate only when stuck</div>
          </div>

          <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
            {hints.map((h, i) => {
              const shown = t >= h.start;
              const op = shown ? Math.min(1, (t - h.start) / 0.45) : 0;
              const ty = shown ? (1 - Easing.easeOutBack(Math.min(1, (t - h.start) / 0.5))) * 12 : 0;
              // Pulse the latest live hint until next one comes (or solve)
              const next = hints[i + 1];
              const live = shown && (next ? t < next.start : t < solveAt);
              const skipped = h.locked && t >= solveAt;
              return (
                <div key={h.lvl} style={{
                  opacity: op * (skipped ? 0.45 : 1),
                  transform: `translateY(${ty}px)`,
                  border: live
                    ? `1px solid ${palette.accent}`
                    : `1px solid ${palette.hair}`,
                  background: live
                    ? `color-mix(in oklch, ${palette.accentSoft} 70%, ${palette.card})`
                    : palette.card,
                  borderRadius: 12,
                  padding: '16px 18px',
                  display: 'grid',
                  gridTemplateColumns: '52px 1fr',
                  gap: 14,
                  alignItems: 'center',
                  fontFamily: fonts.sans,
                  fontSize: 19,
                  color: skipped ? palette.muted : palette.inkDeep,
                  lineHeight: 1.45,
                  position: 'relative',
                  filter: h.locked && !skipped ? 'grayscale(0.5)' : 'none',
                  transition: 'border-color 200ms',
                }}>
                  <span style={{
                    fontFamily: fonts.mono, fontSize: 13,
                    color: live ? palette.accentDeep : palette.quiet,
                    letterSpacing: '0.06em', fontWeight: 600,
                    background: live ? palette.card : palette.paper2,
                    border: `1px solid ${palette.hair}`,
                    borderRadius: 6, padding: '6px 8px',
                    textAlign: 'center',
                  }}>{h.lvl}</span>
                  <span style={{ textDecoration: skipped ? 'line-through' : 'none' }}>
                    {h.text}
                  </span>
                  {skipped && (
                    <div style={{
                      position: 'absolute', top: -10, right: 18,
                      fontFamily: fonts.mono, fontSize: 11, letterSpacing: '0.06em',
                      textTransform: 'uppercase', whiteSpace: 'nowrap',
                      background: palette.card, padding: '2px 8px',
                      border: `1px solid ${palette.hair}`,
                      borderRadius: 4, color: palette.accentDeep,
                    }}>skipped — she got it</div>
                  )}
                </div>
              );
            })}
          </div>

          {/* Result chip */}
          {t >= solveAt + 1.5 && (
            <div style={{
              marginTop: 18, paddingTop: 16, borderTop: `1px dashed ${palette.hair}`,
              opacity: Math.min(1, (t - solveAt - 1.5) / 0.4),
              fontFamily: fonts.mono, fontSize: 13, letterSpacing: '0.06em',
              textTransform: 'uppercase', color: palette.accentDeep,
              display: 'flex', alignItems: 'center', gap: 12,
            }}>
              <span style={{
                width: 10, height: 10, borderRadius: '50%', background: palette.go,
                boxShadow: '0 0 0 3px oklch(0.58 0.115 145 / 0.2)',
              }} />
              answer reached at L2 · misconception caught
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, {
  Scene1ColdOpen, Scene2Comparison, Scene3EnergyCheck, Scene4HintLadder,
});
