// picpay/slides.jsx — PicPay case deck
// Shared primitives (TYPE_SCALE, entry, SlideFrame, etc.) come from /shared/primitives.jsx
// Locale strings come from /picpay/i18n/{lang}.json via useT()

// ── Palette — built from DECK_CONFIG (overrides applied by tweaks) ──────────
const PALETTES = {
  dark:  window.DECK_CONFIG.palette.dark,
  light: window.DECK_CONFIG.palette.light,
};

// ── Shared helpers ────────────────────────────────────────────────────────

function Meta({ k, v, big, c }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
      <span style={{ color: 'inherit', fontSize: 13 }}>{k}</span>
      <span style={{
        color: c.fg,
        fontFamily: big ? FONT_SANS : FONT_MONO,
        fontSize: big ? 28 : 18,
        letterSpacing: big ? '-0.01em' : '0.02em',
        textTransform: 'none',
        fontWeight: big ? 500 : 400,
      }}>{v}</span>
    </div>
  );
}

function ChapterTitle({ c, num, kicker, line1, line2, line2Color = 'primary', tick, total, index, label }) {
  return (
    <SlideFrame c={c} deckBg>
      <CornerLabel c={c} label={label} />
      <CornerNum c={c} index={index} total={total} />
      <div style={{
        position: 'absolute', left: 96, top: 200,
        fontFamily: FONT_MONO, fontSize: 360, fontWeight: 400,
        lineHeight: 0.85, letterSpacing: '-0.04em',
        color: c.fgDim,
        ...entry('rise', { tick, duration: 900 }),
      }}>
        {num}
      </div>
      <div style={{
        position: 'absolute', right: 96, bottom: 220,
        textAlign: 'right', maxWidth: 1280,
      }}>
        <div style={{
          fontFamily: FONT_MONO, fontSize: TYPE_SCALE.micro,
          letterSpacing: '0.18em', textTransform: 'uppercase',
          color: c.primary, marginBottom: 20,
          ...entry('fade', { tick, delay: 250, duration: 600 }),
        }}>
          — {kicker}
        </div>
        <h1 style={{
          margin: 0,
          fontSize: TYPE_SCALE.title + 24,
          fontWeight: 500, letterSpacing: '-0.03em', lineHeight: 1.0,
          ...entry('rise', { tick, delay: 350, duration: 900 }),
        }}>
          {line1}
        </h1>
        {line2 && (
          <h1 style={{
            margin: 0,
            fontSize: TYPE_SCALE.title + 24,
            fontWeight: 400, letterSpacing: '-0.03em', lineHeight: 1.0,
            fontStyle: 'italic',
            color: line2Color === 'primary' ? c.primary : line2Color === 'muted' ? c.fgMuted : c.accent,
            ...entry('rise', { tick, delay: 500, duration: 900 }),
          }}>
            {line2}
          </h1>
        )}
      </div>
      <Sig c={c} />
    </SlideFrame>
  );
}

function StatBlock({ c, k, v, sub, tick, delay, accent }) {
  return (
    <div style={{
      background: c.bg, padding: '24px 28px',
      display: 'flex', flexDirection: 'column', justifyContent: 'space-between',
      ...entry('drop-from-top', { tick, delay, duration: 700 }),
    }}>
      <div style={{
        fontFamily: FONT_MONO, fontSize: 13,
        color: accent ? c.accent : c.primary,
        letterSpacing: '0.18em', textTransform: 'uppercase',
      }}>{k}</div>
      <div style={{
        fontSize: 84, fontWeight: 500,
        letterSpacing: '-0.04em', lineHeight: 0.9,
        color: accent ? c.accent : c.fg,
        fontVariantNumeric: 'tabular-nums',
      }}>
        <CountUp value={v} tick={tick} delay={delay + 100} duration={1000} />
      </div>
      <div style={{
        fontFamily: FONT_MONO, fontSize: 14,
        color: c.fgMuted, letterSpacing: '0.04em',
      }}>{sub}</div>
    </div>
  );
}

function NarrativeRow({ c, k, v, accent, tick, delay }) {
  return (
    <div style={{
      display: 'grid',
      gridTemplateColumns: '180px 1fr',
      gap: 28,
      alignItems: 'baseline',
      paddingBottom: 18,
      borderBottom: `1px solid ${c.rule}`,
      ...entry('slide-in-right', { tick, delay, duration: 700 }),
    }}>
      <div style={{
        fontFamily: FONT_MONO, fontSize: TYPE_SCALE.micro,
        color: accent ? c.accent : c.primary,
        letterSpacing: '0.16em', textTransform: 'uppercase',
      }}>{k}</div>
      <div style={{
        fontSize: TYPE_SCALE.lead - 6,
        letterSpacing: '-0.01em', lineHeight: 1.2,
      }}>{v}</div>
    </div>
  );
}

function ProblemRow({ c, num, tag, tagColor, headline, steps, tick, delay }) {
  return (
    <div style={{
      display: 'grid',
      gridTemplateColumns: '110px 1fr 720px',
      gap: 48, alignItems: 'start',
      ...entry('fade-up', { tick, delay, duration: 800 }),
    }}>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
        <div style={{
          fontFamily: FONT_MONO, fontSize: 72, fontWeight: 400,
          color: tagColor, letterSpacing: '-0.04em', lineHeight: 0.85,
          fontVariantNumeric: 'tabular-nums',
        }}>{num}</div>
        <div style={{
          fontFamily: FONT_MONO, fontSize: 13,
          color: tagColor, letterSpacing: '0.22em', textTransform: 'uppercase',
        }}>{tag}</div>
      </div>
      <div style={{
        fontSize: 40, fontWeight: 500,
        letterSpacing: '-0.02em', lineHeight: 1.1,
        textWrap: 'balance', paddingTop: 6,
      }}>{headline}</div>
      <div style={{
        display: 'grid', gridTemplateColumns: '1fr auto 1fr auto 1fr',
        gap: 14, alignItems: 'center',
      }}>
        {steps.map((s, i) => (
          <React.Fragment key={i}>
            <div style={{
              border: `1px solid ${c.rule}`,
              padding: '20px 14px',
              textAlign: 'center',
              fontFamily: FONT_MONO, fontSize: 13,
              color: c.fg, letterSpacing: '0.06em',
              textTransform: 'uppercase',
              minHeight: 76,
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              ...entry('drop-from-top', { tick, delay: delay + 150 + i * 100, duration: 600 }),
            }}>{s}</div>
            {i < steps.length - 1 && (
              <span style={{
                color: tagColor, fontSize: 24, fontWeight: 400,
                ...entry('fade', { tick, delay: delay + 200 + i * 100, duration: 400 }),
              }}>→</span>
            )}
          </React.Fragment>
        ))}
      </div>
    </div>
  );
}

function EvidenceCell({ big, label, body, color, tick, delay, c }) {
  return (
    <div style={{
      display: 'flex', flexDirection: 'column', gap: 16,
      ...entry('fade-up', { tick, delay, duration: 700 }),
    }}>
      {big ? (
        <div style={{
          fontSize: 144, fontWeight: 500, color,
          letterSpacing: '-0.04em', lineHeight: 0.85,
          fontVariantNumeric: 'tabular-nums',
        }}>
          <CountUp value={big} tick={tick} delay={delay} duration={1100} />
        </div>
      ) : (
        <div style={{
          fontFamily: FONT_MONO, fontSize: TYPE_SCALE.micro,
          color: color || 'rgba(14,16,32,0.45)',
          letterSpacing: '0.18em', textTransform: 'uppercase',
        }}>{label}</div>
      )}
      <div style={{
        fontSize: TYPE_SCALE.body, lineHeight: 1.35,
        color: big ? '#0E1020' : 'rgba(14,16,32,0.66)',
        textWrap: 'pretty',
      }}>{body}</div>
    </div>
  );
}

function ContactCol({ c, k, v, href }) {
  const valueStyle = {
    fontFamily: FONT_MONO, fontSize: TYPE_SCALE.body - 6, fontWeight: 400,
    letterSpacing: '0.01em',
    color: c.fg,
    textDecoration: 'none',
    borderBottom: href ? `1px solid ${c.primary}` : 'none',
    paddingBottom: href ? 6 : 0,
  };
  return (
    <div>
      <div style={{
        fontFamily: FONT_MONO, fontSize: TYPE_SCALE.micro,
        color: c.fgDim, letterSpacing: '0.16em', textTransform: 'uppercase',
        marginBottom: 16,
      }}>{k}</div>
      {href ? (
        <a
          href={href}
          target={href.startsWith('mailto:') ? undefined : '_blank'}
          rel={href.startsWith('mailto:') ? undefined : 'noreferrer'}
          style={valueStyle}
        >
          {v}
        </a>
      ) : (
        <div style={valueStyle}>{v}</div>
      )}
    </div>
  );
}

// ── Slide 01 — Cover ─────────────────────────────────────────────────────

function SlideCover({ c, total }) {
  const t = useT();
  const { tick } = useSlideActive(0);

  const monoLabel = {
    fontFamily: FONT_MONO, fontSize: 13, fontWeight: 700,
    letterSpacing: '0.18em', textTransform: 'uppercase',
    color: 'rgba(244,246,250,0.64)',
  };

  return (
    <SlideFrame c={c} deckBg>
      <div style={{
        position: 'absolute', inset: 0,
        background: 'linear-gradient(90deg, rgba(0,0,0,0.44), rgba(0,0,0,0.10) 58%, rgba(0,0,0,0.52))',
        pointerEvents: 'none',
      }} />
      <div style={{
        position: 'absolute', left: 0, top: 0, bottom: 0, width: 720,
        background: 'linear-gradient(90deg, rgba(0,0,0,0.42), rgba(0,0,0,0))',
        pointerEvents: 'none',
      }} />

      <div style={{
        position: 'absolute', left: 80, right: 80, top: 60,
        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
        ...entry('fade-up', { tick, delay: 0, duration: 600 }),
      }}>
        <div style={{ ...monoLabel, display: 'flex', alignItems: 'center', gap: 16 }}>
          <span style={{ display: 'inline-block', width: 34, height: 1, background: 'currentColor', opacity: 0.62 }} />
          <span>{t('cover.eyebrow')}</span>
        </div>
        <div style={monoLabel}>{t('cover.case_label')}</div>
      </div>

      <div style={{
        position: 'absolute', left: 80, right: 80, top: 108,
        height: 1, background: 'rgba(244,246,250,0.22)',
        transformOrigin: 'left',
        ...entry('sweep-x', { tick, delay: 80, duration: 900 }),
      }} />

      <div style={{
        position: 'absolute', left: 80, top: 330,
        fontFamily: FONT_MONO, fontSize: 13, fontWeight: 700,
        letterSpacing: '0.22em', textTransform: 'uppercase',
        color: c.primary,
        ...entry('fade', { tick, delay: 160, duration: 560 }),
      }}>
        {t('cover.tagline')}
      </div>

      <div style={{
        position: 'absolute', left: 80, top: 390,
        ...entry('rise', { tick, delay: 240, duration: 880 }),
      }}>
        <div style={{
          fontFamily: FONT_SANS, fontWeight: 760,
          fontSize: 174, lineHeight: 0.88,
          letterSpacing: '-0.055em',
          color: c.fg,
        }}>
          {t('cover.line1')}
        </div>
        <div style={{
          marginTop: 8,
          fontFamily: FONT_SANS, fontWeight: 340,
          fontSize: 174, lineHeight: 0.88,
          letterSpacing: '-0.055em',
          color: 'rgba(244,246,250,0.50)',
        }}>
          <span style={{ color: c.primary, fontStyle: 'italic' }}>Impact</span> System.
        </div>
      </div>

      <div style={{
        position: 'absolute', left: 80, right: 80, bottom: 104,
        height: 1, background: 'rgba(244,246,250,0.22)',
        transformOrigin: 'left',
        ...entry('sweep-x', { tick, delay: 600, duration: 900 }),
      }} />

      <div style={{
        position: 'absolute', left: 80, right: 80, bottom: 56,
        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
        ...entry('fade-up', { tick, delay: 700, duration: 700 }),
      }}>
        <div style={{ ...monoLabel, color: c.fg, letterSpacing: '0.18em' }}>
          {t('cover.footer_name')}
        </div>
        <div style={monoLabel}>{t('cover.footer_year')}</div>
        <div style={monoLabel}>{t('cover.footer_location')}</div>
        <div style={{ ...monoLabel, display: 'flex', alignItems: 'center', gap: 16 }}>
          <span>{t('cover.footer_cta')}</span>
          <span style={{ display: 'inline-block', width: 28, height: 1, background: c.fgMuted }} />
        </div>
      </div>
    </SlideFrame>
  );
}

// ── Slide 02 — Role & Scope ───────────────────────────────────────────────

function SlideRole({ c, total }) {
  const t = useT();
  const { tick } = useSlideActive(1);
  const rows = t('role.rows');
  return (
    <SlideFrame c={c} deckBg>
      <CornerLabel c={c} label={t('role.corner')} />
      <CornerNum c={c} index={2} total={total} />

      <DeckTitle
        c={c} tick={tick}
        eyebrow={t('role.eyebrow')}
        line1={t('role.line1')}
        line2={t('role.line2')}
        top={200}
      />

      <div style={{ position: 'absolute', left: 96, right: 96, top: 580 }}>
        <div style={{ height: 1, background: c.fg, opacity: 0.9 }} />
        {rows.map((r, i) => (
          <div key={r.k} style={{
            display: 'grid',
            gridTemplateColumns: '90px 1.4fr 2fr 1.2fr',
            gap: 32,
            alignItems: 'baseline',
            padding: '32px 0 28px',
            borderBottom: `1px solid ${c.rule}`,
            ...entry('slide-in-left', { tick, delay: 200 + i * 140, duration: 700 }),
          }}>
            <div style={{
              fontFamily: FONT_MONO, fontSize: TYPE_SCALE.body,
              color: c.primary, fontVariantNumeric: 'tabular-nums',
            }}>0{i + 1}</div>
            <div style={{
              fontFamily: FONT_MONO, fontSize: TYPE_SCALE.micro,
              color: c.fgMuted, letterSpacing: '0.16em', textTransform: 'uppercase',
            }}>{r.k}</div>
            <div style={{
              fontSize: TYPE_SCALE.subtitle - 4,
              fontWeight: 500, letterSpacing: '-0.015em', lineHeight: 1.05,
              whiteSpace: 'nowrap',
            }}>{r.v}</div>
            <div style={{
              fontFamily: FONT_MONO, fontSize: TYPE_SCALE.micro,
              color: c.fgMuted, letterSpacing: '0.04em', textAlign: 'right',
            }}>{r.note}</div>
          </div>
        ))}
      </div>

      <Sig c={c} />
    </SlideFrame>
  );
}

// ── Slide 03 — Context ────────────────────────────────────────────────────

function SlideContext({ c, total }) {
  const t = useT();
  const { tick } = useSlideActive(2);

  const canvasRef = React.useRef(null);
  const rafRef = React.useRef(0);
  const startedAtRef = React.useRef(0);

  React.useEffect(() => {
    if (!tick) return;
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext('2d');
    const W = canvas.width = 1920;
    const H = canvas.height = 1080;

    const N = 80;
    const rng = (n) => {
      const x = Math.sin(n * 9301.13 + 49297) * 233280;
      return x - Math.floor(x);
    };

    const slots = [];
    const cols = 12, rowsN = 6;
    const gridX = 540, gridY = 320;
    const cellW = 78, cellH = 78;
    for (let r = 0; r < rowsN; r++) {
      for (let cl = 0; cl < cols; cl++) {
        slots.push({
          x: gridX + cl * cellW + cellW / 2,
          y: gridY + r * cellH + cellH / 2,
          w: cellW - 14, h: cellH - 14,
        });
      }
    }

    const fragments = [];
    for (let i = 0; i < N; i++) {
      const angle = rng(i + 1) * Math.PI * 2;
      const startDist = 1400 + rng(i + 7) * 600;
      const sx = 960 + Math.cos(angle) * startDist;
      const sy = 540 + Math.sin(angle) * startDist;
      const orbitAngle = i * 0.42 + rng(i + 17) * 0.4;
      const orbitR = 120 + i * 11 + rng(i + 23) * 30;
      const tx = 960 + Math.cos(orbitAngle) * orbitR * 1.05;
      const ty = 590 + Math.sin(orbitAngle) * orbitR * 0.62;
      const tN = i / N;
      fragments.push({
        i, x: sx, y: sy, vx: 0, vy: 0, tx, ty,
        w: 14 + Math.floor(rng(i + 31) * 60), h: 14 + Math.floor(rng(i + 37) * 50),
        rot: rng(i + 41) * Math.PI - Math.PI / 2, rotV: (rng(i + 43) - 0.5) * 0.012,
        ph1: rng(i + 53) * Math.PI * 2, ph2: rng(i + 59) * Math.PI * 2,
        f1: 0.0006 + rng(i + 61) * 0.0008, f2: 0.0004 + rng(i + 67) * 0.0006,
        delay: 200 + i * 18 + rng(i + 71) * 60,
        opacity: 0.22 + (1 - tN) * 0.5,
      });
    }

    const startTime = performance.now();
    startedAtRef.current = startTime;

    const grad = ctx.createRadialGradient(W * 0.3, H * 0.45, 80, W * 0.3, H * 0.45, 800);
    grad.addColorStop(0, 'rgba(0,0,0,0.92)');
    grad.addColorStop(0.4, 'rgba(0,0,0,0.72)');
    grad.addColorStop(0.85, 'transparent');

    function frame(now) {
      const elapsed = now - startTime;
      ctx.clearRect(0, 0, W, H);

      const slotProg = Math.min(1, Math.max(0, (elapsed - 600) / 1200));
      ctx.save();
      ctx.strokeStyle = c.fg;
      ctx.globalAlpha = 0.06 * slotProg;
      ctx.lineWidth = 1;
      for (const s of slots) ctx.strokeRect(s.x - s.w / 2, s.y - s.h / 2, s.w, s.h);
      ctx.restore();

      ctx.strokeStyle = c.fg;
      ctx.lineWidth = 1;
      for (const f of fragments) {
        const localT = elapsed - f.delay;
        if (localT < 0) continue;
        const entryProg = Math.min(1, localT / 1300);
        const ease = 1 - Math.pow(1 - entryProg, 3);
        const driftAmp = 18 + (f.i % 5) * 6;
        const dx = Math.sin(elapsed * f.f1 + f.ph1) * driftAmp;
        const dy = Math.cos(elapsed * f.f2 + f.ph2) * driftAmp * 0.8;
        const x = f.x + (f.tx + dx - f.x) * ease;
        const y = f.y + (f.ty + dy - f.y) * ease;
        const spin = (1 - ease) * (f.rot + elapsed * 0.003) + ease * (f.rot + elapsed * f.rotV * 0.4);
        const op = f.opacity * Math.min(1, localT / 800);
        ctx.save();
        ctx.globalAlpha = op;
        ctx.translate(x, y);
        ctx.rotate(spin);
        ctx.strokeRect(-f.w / 2, -f.h / 2, f.w, f.h);
        ctx.restore();
      }

      ctx.fillStyle = grad;
      ctx.fillRect(0, 0, W, H);
      rafRef.current = requestAnimationFrame(frame);
    }

    rafRef.current = requestAnimationFrame(frame);
    return () => cancelAnimationFrame(rafRef.current);
  }, [tick, c.bg, c.fg]);

  return (
    <SlideFrame c={c} deckBg>
      <CornerLabel c={c} label={t('context.corner')} />
      <CornerNum c={c} index={3} total={total} />

      <canvas ref={canvasRef} style={{
        position: 'absolute', inset: 0,
        width: '100%', height: '100%',
        pointerEvents: 'none',
      }} />

      <DeckTitle
        c={c} tick={tick}
        eyebrow={t('context.eyebrow')}
        line1={t('context.line1')}
        line2={t('context.line2')}
        top={220}
      />
      <div style={{
        position: 'absolute', left: 96, top: 470, zIndex: 2,
        fontFamily: FONT_MONO, fontSize: 14,
        color: c.fgMuted, letterSpacing: '0.16em', textTransform: 'uppercase',
        ...entry('fade', { tick, delay: 300, duration: 600 }),
      }}>
        {t('context.timeline')}
      </div>

      <div style={{
        position: 'absolute', right: 140, top: 380, width: 360,
        zIndex: 2, textAlign: 'right',
        ...entry('fade-up', { tick, delay: 700, duration: 800 }),
      }}>
        <div style={{
          fontFamily: FONT_MONO, fontSize: 13,
          color: c.accent, letterSpacing: '0.22em', textTransform: 'uppercase',
        }}>{t('context.stat_label')}</div>
        <div style={{
          marginTop: 8, fontSize: 168, fontWeight: 500,
          letterSpacing: '-0.05em', lineHeight: 0.9,
          color: c.accent, fontVariantNumeric: 'tabular-nums',
        }}>
          <CountUp value="283" tick={tick} delay={900} duration={1400} />
        </div>
        <div style={{
          marginTop: 6, fontFamily: FONT_MONO, fontSize: 13,
          color: c.fgMuted, letterSpacing: '0.04em',
        }}>{t('context.stat_sub')}</div>
      </div>

      <div style={{
        position: 'absolute', right: 140, bottom: 130,
        fontSize: 64, fontWeight: 500,
        letterSpacing: '-0.02em', lineHeight: 1.05,
        textAlign: 'right', zIndex: 2,
        ...entry('fade-up', { tick, delay: 1100, duration: 800 }),
      }}>
        <div style={{ color: c.fgMuted }}>{t('context.verdict_line1')}</div>
        <div style={{ color: c.accent, fontStyle: 'italic' }}>{t('context.verdict_line2')}</div>
      </div>

      <Sig c={c} />
    </SlideFrame>
  );
}

// ── Slide 04 — Problem ────────────────────────────────────────────────────

function SlideProblem({ c, total }) {
  const t = useT();
  const { tick } = useSlideActive(3);
  const row1 = t('problem.row1');
  const row2 = t('problem.row2');
  return (
    <SlideFrame c={c} deckBg>
      <CornerLabel c={c} label={t('problem.corner')} />
      <CornerNum c={c} index={4} total={total} />

      <DeckTitle
        c={c} tick={tick}
        eyebrow={t('problem.eyebrow')}
        line1={t('problem.line1')}
        line2={t('problem.line2')}
        top={200}
      />

      <div style={{
        position: 'absolute', left: 96, right: 96, top: 480,
        display: 'flex', flexDirection: 'column', gap: 36,
      }}>
        <ProblemRow c={c}
          num={row1.num} tag={row1.tag} tagColor={c.primary}
          headline={row1.headline} steps={row1.steps}
          tick={tick} delay={200}
        />
        <div style={{ height: 1, background: c.rule,
          ...entry('sweep-x', { tick, delay: 350, duration: 900 }) }} />
        <ProblemRow c={c}
          num={row2.num} tag={row2.tag} tagColor={c.accent}
          headline={row2.headline} steps={row2.steps}
          tick={tick} delay={500}
        />
      </div>

      <div style={{
        position: 'absolute', left: 96, right: 96, bottom: 110,
        display: 'flex', alignItems: 'baseline', gap: 24,
        paddingTop: 24, borderTop: `1px solid ${c.rule}`,
        ...entry('fade-up', { tick, delay: 900, duration: 700 }),
      }}>
        <span style={{
          fontFamily: FONT_MONO, fontSize: 13,
          color: c.fgDim, letterSpacing: '0.22em', textTransform: 'uppercase',
        }}>{t('problem.root_label')}</span>
        <span style={{
          fontSize: 36, fontWeight: 500,
          letterSpacing: '-0.02em', lineHeight: 1.1,
        }}>
          {t('problem.root_text')}{' '}
          <span style={{ color: c.fgMuted }}>{t('problem.root_sub')}</span>
        </span>
      </div>

      <Sig c={c} />
    </SlideFrame>
  );
}

// ── Slide 05 — Old PicPay ─────────────────────────────────────────────────

function SlideOldPP({ c, total }) {
  const t = useT();
  const { tick } = useSlideActive(4);
  const canvasRef = React.useRef(null);
  const rafRef = React.useRef(0);

  React.useEffect(() => {
    if (!tick) return;
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext('2d');
    canvas.width = 1920;
    canvas.height = 1080;
    const w = 1920, h = 1080;

    let seed = 42;
    const rng = () => { seed = (seed * 16807 + 0) % 2147483647; return (seed - 1) / 2147483646; };
    const jitter = (v, amt) => v + (rng() - 0.5) * amt;

    const scribbleLine = (x1, y1, x2, y2, steps = 10, j = 7) => {
      const pts = [[x1, y1]];
      for (let i = 1; i < steps; i++) {
        const tVal = i / steps;
        pts.push([jitter(x1 + (x2 - x1) * tVal, j), jitter(y1 + (y2 - y1) * tVal, j)]);
      }
      pts.push([x2, y2]);
      return pts;
    };

    const sc = (cx, cy, rx, ry) => Array.from({ length: 22 }, (_, i) => {
      const a = (i / 20) * Math.PI * 2 - Math.PI / 2;
      return [jitter(cx + Math.cos(a) * rx, 3), jitter(cy + Math.sin(a) * ry, 3)];
    });

    const sl = (x1, y1, x2, y2, j = 3) => scribbleLine(x1, y1, x2, y2, 5, j);
    const wavy = (x1, x2, y, amp = 4) => Array.from({ length: 16 }, (_, i) => {
      const tVal = i / 15;
      return [x1 + tVal * (x2 - x1), y + Math.sin(tVal * Math.PI * 5) * amp + jitter(0, 2)];
    });
    const R = '#E53935', O = '#FF6B35';

    const marks = [
      { pts: sl(60, 495, 410, 497),               color: R, lw: 1.5, delay: 0   },
      { pts: sc(240, 622, 115, 72),               color: R, lw: 1.8, delay: 180 },
      { pts: [[58,460],[46,460],[46,540],[58,540]], color: O, lw: 1.5, delay: 380 },
      { pts: wavy(68, 390, 790, 3),               color: R, lw: 1.5, delay: 560 },
      { pts: [[48,1005],[48,1068],[420,1068],[420,1005]], color: O, lw: 1.5, delay: 740 },
      { pts: sl(498, 494, 940, 494),              color: R, lw: 1.5, delay: 900 },
      { pts: sc(718, 618, 95, 58),                color: R, lw: 1.8, delay: 1060},
      { pts: sl(530, 730, 590, 790, 2),           color: R, lw: 1.5, delay: 1220},
      { pts: sl(590, 730, 530, 790, 2),           color: R, lw: 1.5, delay: 1300},
      { pts: wavy(500, 930, 840, 3),              color: O, lw: 1.5, delay: 1420},
      { pts: sl(968, 532, 1420, 534),             color: R, lw: 1.5, delay: 1580},
      { pts: sc(1060, 690, 68, 42),               color: R, lw: 1.8, delay: 1720},
      { pts: sc(1200, 690, 68, 42),               color: R, lw: 1.8, delay: 1820},
      { pts: [[970,750],[970,920],[1415,920],[1415,750]], color: O, lw: 1.5, delay: 1960},
      { pts: [[1455,462],[1455,510],[1510,510]],  color: O, lw: 1.5, delay: 2120},
      { pts: [[1885,462],[1885,510],[1830,510]],  color: O, lw: 1.5, delay: 2200},
      { pts: sl(1455, 720, 1885, 722),            color: R, lw: 1.5, delay: 2340},
      { pts: sc(1668, 830, 130, 70),              color: R, lw: 1.8, delay: 2500},
    ];

    const DRAW_DUR = 340, HOLD = 1200, FADE_DUR = 600;
    const CYCLE = marks[marks.length - 1].delay + DRAW_DUR + HOLD + FADE_DUR;

    function drawMark(mark, progress) {
      if (progress <= 0) return;
      const pts = mark.pts;
      const count = Math.max(2, Math.floor(pts.length * Math.min(1, progress)));
      ctx.beginPath();
      ctx.moveTo(pts[0][0], pts[0][1]);
      for (let i = 1; i < count; i++) ctx.lineTo(pts[i][0], pts[i][1]);
      ctx.strokeStyle = mark.color;
      ctx.lineWidth = mark.lw;
      ctx.lineCap = 'round';
      ctx.lineJoin = 'round';
      ctx.stroke();
    }

    const start = performance.now();
    function frame(now) {
      const elapsed = (now - start) % CYCLE;
      const fadeStart = marks[marks.length - 1].delay + DRAW_DUR + HOLD;
      const alpha = elapsed > fadeStart ? 1 - (elapsed - fadeStart) / FADE_DUR : 1;
      ctx.clearRect(0, 0, w, h);
      ctx.save();
      ctx.globalAlpha = Math.max(0, alpha);
      for (const mark of marks) {
        const local = elapsed - mark.delay;
        if (local <= 0) continue;
        drawMark(mark, Math.min(1, local / DRAW_DUR));
      }
      ctx.restore();
      rafRef.current = requestAnimationFrame(frame);
    }

    rafRef.current = requestAnimationFrame(frame);
    return () => cancelAnimationFrame(rafRef.current);
  }, [tick]);

  return (
    <SlideFrame c={c} bg="#0E1020">
      <img
        src="/picpay/assets/img/OLD-PP2.png"
        alt="Old PicPay interface"
        style={{
          position: 'absolute',
          width: '100%', height: 'auto',
          bottom: 0, display: 'block',
          ...entry('fade', { tick, delay: 100, duration: 900 }),
        }}
      />
      <div style={{
        position: 'absolute', inset: 0, pointerEvents: 'none',
        background: 'linear-gradient(to bottom, rgba(14,16,32,0.75) 0%, rgba(14,16,32,0) 28%, rgba(14,16,32,0) 72%, rgba(14,16,32,0.75) 100%)',
      }} />
      <canvas ref={canvasRef} style={{
        position: 'absolute', inset: 0,
        width: '100%', height: '100%',
        pointerEvents: 'none',
      }} />

      <CornerLabel c={c} label={t('old_pp.corner')} />
      <CornerNum c={c} index={5} total={total} />

      <DeckTitle
        c={c} tick={tick}
        eyebrow={t('old_pp.eyebrow')}
        line1={t('old_pp.line1')}
        line2={t('old_pp.line2')}
        accent top={140} maxWidth={900}
      />
      <Sig c={c} />
    </SlideFrame>
  );
}

// ── Slide 06 — Research ───────────────────────────────────────────────────

function SlideResearch({ c, total }) {
  const t = useT();
  const { tick } = useSlideActive(5);
  const stats = t('research.stats');
  return (
    <SlideFrame c={c} deckBg>
      <CornerLabel c={c} label={t('research.corner')} />
      <CornerNum c={c} index={6} total={total} />

      <DeckTitle
        c={c} tick={tick}
        eyebrow={t('research.eyebrow')}
        line1={t('research.line1')}
        line2={t('research.line2')}
        top={200}
      />

      <div style={{
        position: 'absolute', left: 96, right: 96, top: 460,
        display: 'grid', gridTemplateColumns: 'repeat(5, 1fr)',
        borderTop: `1px solid ${c.fg}`,
        borderBottom: `1px solid ${c.rule}`,
      }}>
        {stats.map((s, i) => (
          <div key={s.label} style={{
            padding: '32px 24px 28px 0',
            borderRight: i < stats.length - 1 ? `1px solid ${c.rule}` : 'none',
            paddingLeft: i === 0 ? 0 : 28,
            display: 'flex', flexDirection: 'column', gap: 16,
            minHeight: 230,
            ...entry('drop-from-top', { tick, delay: 250 + i * 130, duration: 700 }),
          }}>
            <div style={{
              fontFamily: FONT_MONO, fontSize: 13,
              color: c.fgMuted, letterSpacing: '0.18em',
            }}>0{i + 1}</div>
            <div style={{
              fontSize: 96, fontWeight: 500,
              letterSpacing: '-0.04em', lineHeight: 0.9,
              color: c.primary, fontFamily: FONT_SANS,
              fontVariantNumeric: 'tabular-nums',
            }}>
              <CountUp value={s.v} tick={tick} delay={250 + i * 130} duration={900} />
            </div>
            <div style={{
              marginTop: 'auto', fontSize: 22, fontWeight: 500, letterSpacing: '-0.005em',
            }}>{s.label}</div>
            <div style={{
              fontFamily: FONT_MONO, fontSize: 13,
              color: c.fgMuted, letterSpacing: '0.04em',
            }}>{s.sub}</div>
          </div>
        ))}
      </div>

      <div style={{
        position: 'absolute', left: 96, right: 96, bottom: 130,
        display: 'grid', gridTemplateColumns: '120px 1fr', gap: 36,
        alignItems: 'baseline',
        ...entry('fade-up', { tick, delay: 850, duration: 700 }),
      }}>
        <div style={{
          fontFamily: FONT_MONO, fontSize: 13,
          color: c.primary, letterSpacing: '0.22em', textTransform: 'uppercase',
        }}>{t('research.quote_label')}</div>
        <div style={{
          fontSize: 44, lineHeight: 1.2,
          color: c.fgMuted, letterSpacing: '-0.015em',
          fontStyle: 'italic', fontWeight: 300,
          textWrap: 'balance', maxWidth: 1500,
        }}>
          {t('research.quote_body')}{' '}
          <span style={{ color: c.fg, fontStyle: 'normal', fontWeight: 500 }}>
            {t('research.quote_emphasis')}
          </span>
        </div>
      </div>

      <Sig c={c} />
    </SlideFrame>
  );
}

// ── Slide 07 — Process ────────────────────────────────────────────────────

function SlideProcess({ c, total }) {
  const t = useT();
  const { tick } = useSlideActive(6);
  const steps = t('process.steps');
  return (
    <SlideFrame c={c} deckBg>
      <CornerLabel c={c} label={t('process.corner')} />
      <CornerNum c={c} index={7} total={total} />

      <DeckTitle
        c={c} tick={tick}
        eyebrow={t('process.eyebrow')}
        line1={t('process.line1')}
        line2={t('process.line2')}
        top={200}
      />

      <div style={{
        position: 'absolute', left: 96, right: 96, top: 500,
        display: 'grid', gridTemplateColumns: '1.1fr 1px 1fr', gap: 56,
      }}>
        <div style={{ display: 'flex', flexDirection: 'column' }}>
          <div style={{ height: 1, background: c.fg }} />
          {steps.map((s, i) => (
            <div key={s.n} style={{
              padding: '28px 0',
              borderBottom: `1px solid ${c.rule}`,
              display: 'grid', gridTemplateColumns: '90px 1fr',
              gap: 24, alignItems: 'baseline',
              ...entry('slide-in-left', { tick, delay: 200 + i * 140, duration: 700 }),
            }}>
              <div style={{
                fontFamily: FONT_MONO, fontSize: TYPE_SCALE.subtitle - 8,
                color: c.primary, fontVariantNumeric: 'tabular-nums',
              }}>{s.n}</div>
              <div>
                <div style={{
                  fontSize: TYPE_SCALE.body + 4, fontWeight: 500,
                  letterSpacing: '-0.015em', lineHeight: 1.15, marginBottom: 8,
                }}>{s.t}</div>
                <div style={{
                  fontFamily: FONT_MONO, fontSize: TYPE_SCALE.micro,
                  color: c.fgMuted, letterSpacing: '0.04em', lineHeight: 1.4,
                }}>{s.sub}</div>
              </div>
            </div>
          ))}
        </div>

        <div style={{ width: 1, background: c.rule,
          ...entry('sweep-y', { tick, delay: 200, duration: 900 }) }} />

        <div style={{
          ...entry('fade-up', { tick, delay: 600, duration: 800 }),
          paddingLeft: 4,
        }}>
          <div style={{ width: 80, height: 3, background: c.accent, marginBottom: 28 }} />
          <div style={{
            fontFamily: FONT_MONO, fontSize: TYPE_SCALE.micro,
            color: c.accent, letterSpacing: '0.22em', textTransform: 'uppercase',
            marginBottom: 28,
          }}>{t('process.tradeoff_label')}</div>
          <div style={{
            fontSize: TYPE_SCALE.subtitle + 2, fontWeight: 500,
            letterSpacing: '-0.02em', lineHeight: 1.1,
            marginBottom: 24, textWrap: 'balance',
          }}>
            {t('process.tradeoff_before')}{' '}
            <em style={{ color: c.accent, fontStyle: 'italic' }}>{t('process.tradeoff_emphasis')}</em>{' '}
            {t('process.tradeoff_after')}
          </div>
          <div style={{
            fontSize: TYPE_SCALE.body, color: c.fgMuted,
            lineHeight: 1.45, textWrap: 'pretty', maxWidth: 760,
          }}>
            {t('process.tradeoff_body_sponsor')}{' '}
            <span style={{ color: c.fg }}>
              {t('process.tradeoff_body_detail')}
            </span>
          </div>
        </div>
      </div>

      <Sig c={c} />
    </SlideFrame>
  );
}

// ── Slide 08 — Insight ────────────────────────────────────────────────────

function SlideInsight({ c, total }) {
  const t = useT();
  const { tick } = useSlideActive(7);
  return (
    <SlideFrame c={c} bg={c.paper} style={{ color: c.ink }}>
      <CornerLabel c={c} label={t('insight.corner')} dark />
      <CornerNum c={c} index={8} total={total} dark />

      <div style={{
        position: 'absolute', right: 96, top: 168,
        width: 520, height: 416,
        overflow: 'hidden',
        ...entry('fade', { tick, delay: 150, duration: 1100 }),
      }}>
        <img
          src="/picpay/assets/img/insight-portrait.png"
          alt="A user on the street, focused on his phone"
          style={{
            width: '100%', height: '100%',
            objectFit: 'cover', display: 'block',
            filter: 'sepia(0.18) contrast(1.02) brightness(0.96)',
            mixBlendMode: 'multiply',
          }}
        />
        <div style={{
          position: 'absolute', left: 0, right: 0, bottom: 0,
          padding: '12px 16px',
          background: 'linear-gradient(to top, rgba(14,16,32,0.55), rgba(14,16,32,0))',
          fontFamily: FONT_MONO, fontSize: 11,
          color: '#F2EFE6', letterSpacing: '0.16em', textTransform: 'uppercase',
        }}>
          {t('insight.photo_caption')}
        </div>
      </div>

      <DeckTitle
        c={c} tick={tick} dark
        eyebrow={t('insight.eyebrow')}
        line1={t('insight.line1')}
        line2={t('insight.line2')}
        accent top={200}
      />

      <div style={{
        position: 'absolute', left: 96, right: 96, bottom: 130,
        display: 'grid', gridTemplateColumns: '1.3fr 1px 1fr 1px 1fr',
        gap: 36, paddingTop: 28,
        borderTop: `1px solid ${c.ink}`,
      }}>
        <EvidenceCell big={t('insight.evidence1_big')} body={t('insight.evidence1_body')}
          color={c.primary} tick={tick} delay={700} c={c} />
        <div style={{ background: 'rgba(14,16,32,0.18)' }} />
        <EvidenceCell label={t('insight.evidence2_label')}
          body={t('insight.evidence2_body')}
          tick={tick} delay={820} c={c} />
        <div style={{ background: 'rgba(14,16,32,0.18)' }} />
        <EvidenceCell label={t('insight.evidence3_label')}
          color={c.accent}
          body={t('insight.evidence3_body')}
          tick={tick} delay={940} c={c} />
      </div>

      <div style={{
        position: 'absolute', bottom: 36, left: 96, right: 96,
        display: 'flex', justifyContent: 'space-between',
        fontFamily: FONT_MONO, fontSize: 14,
        color: 'rgba(14,16,32,0.45)', letterSpacing: '0.16em', textTransform: 'uppercase',
      }}>
        <span>{t('sig.left')}</span>
        <span>{t('sig.right')}</span>
      </div>
    </SlideFrame>
  );
}

// ── Slide 09 — Concept ────────────────────────────────────────────────────

function SlideConcept({ c, total }) {
  const t = useT();
  const { tick } = useSlideActive(8);

  const CX = 500, CY = 500;
  const rings = t('concept.rings').map((r, i) => {
    const opacities = [0.18, 0.40, 0.68, 1.00];
    const radii = [440, 320, 205, 100];
    return { r: radii[i], label: r.label, opacity: opacities[i] };
  });
  const pillars = t('concept.pillars');

  const hexPts = (r) =>
    Array.from({ length: 6 }, (_, i) => {
      const a = (Math.PI / 3) * i;
      return `${CX + r * Math.cos(a)},${CY + r * Math.sin(a)}`;
    }).join(' ');

  return (
    <SlideFrame c={c} deckBg>
      <CornerLabel c={c} label={t('concept.corner')} />
      <CornerNum c={c} index={9} total={total} />

      <DeckTitle
        c={c} tick={tick}
        eyebrow={t('concept.eyebrow')}
        line1={t('concept.line1')}
        line2={t('concept.line2')}
        accent top={200} maxWidth={820}
      />

      <svg viewBox="0 0 1000 1000" width={1000} height={1000}
           style={{ position: 'absolute', right: -60, top: 40, overflow: 'visible' }}>
        {rings.map(({ r, label, opacity }, i) => {
          const perim = 6 * r;
          const delay = (rings.length - 1 - i) * 240;
          const isCore = i === rings.length - 1;
          const labelY = isCore ? CY + 6 : CY - r * Math.sqrt(3) / 2 + 20;
          return (
            <g key={r}>
              <polygon points={hexPts(r)} fill="none"
                stroke={isCore ? c.primary : c.fg}
                strokeWidth={isCore ? 1.5 : 1}
                strokeOpacity={opacity}
                style={{
                  strokeDasharray: perim, strokeDashoffset: perim,
                  animation: tick ? `hex-draw 1000ms cubic-bezier(0.4,0,0.1,1) ${delay}ms forwards` : 'none',
                }}
              />
              <text x={CX} y={labelY} textAnchor="middle"
                fill={isCore ? c.primary : c.fg}
                fillOpacity={opacity}
                fontFamily="'Space Mono', monospace"
                fontSize={isCore ? 15 : 12}
                letterSpacing="0.14em"
                style={{
                  opacity: 0,
                  animation: tick ? `pp-fade 600ms ease ${delay + 700}ms forwards` : 'none',
                  textTransform: 'uppercase',
                }}>
                {label}
              </text>
            </g>
          );
        })}
      </svg>

      <div style={{
        position: 'absolute', left: 96, right: 1000, bottom: 140,
        display: 'flex', flexDirection: 'column',
      }}>
        {pillars.map((p, i) => (
          <div key={p.n} style={{
            display: 'grid', gridTemplateColumns: '48px 1fr', gap: 20,
            padding: '16px 0',
            borderTop: `1px solid ${c.rule}`,
            borderBottom: i === pillars.length - 1 ? `1px solid ${c.rule}` : 'none',
            ...entry('fade-up', { tick, delay: 700 + i * 140, duration: 700 }),
          }}>
            <div style={{
              fontFamily: FONT_MONO, fontSize: 11,
              color: c.fgDim, letterSpacing: '0.18em', paddingTop: 2,
            }}>{p.n}</div>
            <div>
              <div style={{
                fontFamily: FONT_MONO, fontSize: 11, fontWeight: 700,
                color: c.primary, letterSpacing: '0.16em',
                textTransform: 'uppercase', marginBottom: 5,
              }}>{p.k}</div>
              <div style={{
                fontSize: 18, lineHeight: 1.35,
                color: c.fgMuted, letterSpacing: '-0.01em',
              }}>{p.v}</div>
            </div>
          </div>
        ))}
      </div>

      <Sig c={c} />
    </SlideFrame>
  );
}

// ── Slide 10 — System ─────────────────────────────────────────────────────

function SlideSystem({ c, total }) {
  const t = useT();
  const { tick } = useSlideActive(9);
  const layers = t('system.layers');
  const stats = t('system.stats');
  return (
    <SlideFrame c={c} deckBg>
      <CornerLabel c={c} label={t('system.corner')} />
      <CornerNum c={c} index={10} total={total} />

      <DeckTitle
        c={c} tick={tick}
        eyebrow={t('system.eyebrow')}
        line1={t('system.line1')}
        line2={t('system.line2')}
        accent
      />

      <div style={{
        position: 'absolute', left: 96, right: 96, top: 440,
        display: 'grid', gridTemplateColumns: '1.05fr 1px 1.35fr', gap: 58,
      }}>
        <div style={{
          ...entry('fade-up', { tick, delay: 260, duration: 760 }),
          display: 'flex', flexDirection: 'column', justifyContent: 'space-between',
          minHeight: 390,
        }}>
          <div>
            <div style={{ height: 1, background: c.fg, marginBottom: 32 }} />
            <div style={{
              fontSize: 42, lineHeight: 1.08, letterSpacing: '-0.02em',
              fontWeight: 520, color: c.fg, textWrap: 'balance',
            }}>
              {t('system.quote')}
              <span style={{ color: c.fgMuted }}> {t('system.quote_sub')}</span>
            </div>
          </div>
          <div style={{
            display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 24,
          }}>
            {stats.map((s, i) => (
              <div key={s.k} style={{ borderTop: `1px solid ${c.rule}`, paddingTop: 16 }}>
                <div style={{
                  fontFamily: FONT_MONO, fontSize: 12, letterSpacing: '0.16em',
                  textTransform: 'uppercase', color: c.fgDim, marginBottom: 8,
                }}>{s.k}</div>
                <div style={{
                  fontSize: 48, lineHeight: 0.9, fontWeight: 650,
                  letterSpacing: '-0.035em',
                  color: i === 0 ? c.primary : c.fg,
                }}>{s.v}</div>
              </div>
            ))}
          </div>
        </div>

        <div style={{ width: 1, background: c.rule,
          ...entry('sweep-y', { tick, delay: 250, duration: 900 }) }} />

        <div style={{ display: 'flex', flexDirection: 'column' }}>
          <div style={{ height: 1, background: c.fg }} />
          {layers.map((l, i) => (
            <div style={{
              display: 'grid', gridTemplateColumns: '86px 280px 1fr',
              gap: 30, alignItems: 'baseline',
              padding: '24px 0', borderBottom: `1px solid ${c.rule}`,
              ...entry('slide-in-right', { tick, delay: 320 + i * 115, duration: 700 }),
            }} key={l.name}>
              <div style={{
                fontFamily: FONT_MONO, fontSize: 42,
                color: c.primary, fontVariantNumeric: 'tabular-nums',
                letterSpacing: '-0.035em',
              }}>{l.n}</div>
              <div style={{
                fontSize: 48, fontWeight: 560, letterSpacing: '-0.03em', lineHeight: 0.95,
              }}>{l.name}</div>
              <div style={{
                fontFamily: FONT_MONO, fontSize: 14,
                color: c.fgMuted, letterSpacing: '0.04em',
              }}>{l.what}</div>
            </div>
          ))}
        </div>
      </div>

      <div style={{
        position: 'absolute', left: 96, right: 96, bottom: 110,
        height: 1, background: c.rule,
        ...entry('sweep-x', { tick, delay: 860, duration: 900 }),
      }} />

      <Sig c={c} />
    </SlideFrame>
  );
}

// ── Slide 11 — System Forming ─────────────────────────────────────────────

function SlideSystemForming({ c, total }) {
  const t = useT();
  const { tick } = useSlideActive(10);
  const canvasRef = React.useRef(null);
  const rafRef = React.useRef(0);

  React.useEffect(() => {
    if (!tick) return;
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext('2d');
    const W = canvas.width = 1920;
    const H = canvas.height = 1080;

    const N_TOTAL = 283, N_KEEP = 72, cols = 12, rowsN = 6;
    const rng = (n) => { const x = Math.sin(n * 9301.13 + 49297) * 233280; return x - Math.floor(x); };

    const cellW = 88, cellH = 88;
    const gridW = cols * cellW, gridH = rowsN * cellH;
    const gridX = (W - gridW) / 2, gridY = 360;

    const slots = [];
    for (let r = 0; r < rowsN; r++)
      for (let cl = 0; cl < cols; cl++)
        slots.push({
          x: gridX + cl * cellW + cellW / 2, y: gridY + r * cellH + cellH / 2,
          w: cellW - 18, h: cellH - 18,
        });

    const indices = Array.from({ length: N_TOTAL }, (_, i) => i);
    for (let i = indices.length - 1; i > 0; i--) {
      const j = Math.floor(rng(i + 1000) * (i + 1));
      [indices[i], indices[j]] = [indices[j], indices[i]];
    }
    const survivorSet = new Set(indices.slice(0, N_KEEP));

    const fragments = [];
    let survivorCounter = 0;
    for (let i = 0; i < N_TOTAL; i++) {
      const angle = rng(i + 1) * Math.PI * 2;
      const startDist = 1500 + rng(i + 7) * 700;
      const sx = W / 2 + Math.cos(angle) * startDist;
      const sy = H / 2 + Math.sin(angle) * startDist;
      const orbitAngle = i * 0.35 + rng(i + 17) * 0.5;
      const orbitR = 80 + i * 4 + rng(i + 23) * 60;
      const ox = W / 2 + Math.cos(orbitAngle) * orbitR;
      const oy = 590 + Math.sin(orbitAngle) * orbitR * 0.55;
      const isSurvivor = survivorSet.has(i);
      fragments.push({
        i, sx, sy, ox, oy,
        slot: isSurvivor ? slots[survivorCounter++] : null,
        isSurvivor,
        wChaos: 14 + Math.floor(rng(i + 31) * 60), hChaos: 14 + Math.floor(rng(i + 37) * 50),
        rotChaos: rng(i + 41) * Math.PI - Math.PI / 2, rotV: (rng(i + 43) - 0.5) * 0.012,
        ph1: rng(i + 53) * Math.PI * 2, ph2: rng(i + 59) * Math.PI * 2,
        f1: 0.0006 + rng(i + 61) * 0.0008, f2: 0.0004 + rng(i + 67) * 0.0006,
        delay: 100 + i * 6 + rng(i + 71) * 40,
      });
    }

    const T_CHAOS_END = 2200, T_HOLD = 2900, T_FILTER = 3700, T_SNAP = 4600;
    const startTime = performance.now();

    const easeInOut = (t) => t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2;
    const easeOutCubic = (t) => 1 - Math.pow(1 - t, 3);

    function frame(now) {
      const elapsed = now - startTime;
      ctx.clearRect(0, 0, W, H);

      const filterProg = Math.min(1, Math.max(0, (elapsed - T_FILTER) / 700));
      const snapProg = Math.min(1, Math.max(0, (elapsed - T_SNAP) / 1100));
      const slotProg = Math.min(1, Math.max(0, (elapsed - T_HOLD) / 1400));

      ctx.save();
      ctx.strokeStyle = c.fg;
      ctx.globalAlpha = 0.07 * slotProg;
      ctx.lineWidth = 1;
      for (const s of slots) ctx.strokeRect(s.x - s.w / 2, s.y - s.h / 2, s.w, s.h);
      ctx.restore();

      for (const f of fragments) {
        const localT = elapsed - f.delay;
        if (localT < 0) continue;
        const entryProg = Math.min(1, localT / 1400);
        const entryEase = easeOutCubic(entryProg);
        const driftAmp = 16 + (f.i % 5) * 5;
        const dx = Math.sin(elapsed * f.f1 + f.ph1) * driftAmp;
        const dy = Math.cos(elapsed * f.f2 + f.ph2) * driftAmp * 0.8;
        const chaosX = f.sx + (f.ox + dx - f.sx) * entryEase;
        const chaosY = f.sy + (f.oy + dy - f.sy) * entryEase;
        let x = chaosX, y = chaosY, w = f.wChaos, h = f.hChaos;
        let rot = f.rotChaos + elapsed * f.rotV * 0.4 * (1 - entryEase) + (1 - entryEase) * elapsed * 0.003;
        let alpha = 0.22 + (1 - f.i / N_TOTAL) * 0.5;
        alpha *= Math.min(1, localT / 800);

        if (f.isSurvivor && snapProg > 0) {
          const e = easeInOut(snapProg);
          x = chaosX + (f.slot.x - chaosX) * e;
          y = chaosY + (f.slot.y - chaosY) * e;
          w = f.wChaos + (f.slot.w - f.wChaos) * e;
          h = f.hChaos + (f.slot.h - f.hChaos) * e;
          rot = rot * (1 - e);
          alpha = alpha * (1 - e) + 0.85 * e;
        } else if (!f.isSurvivor && filterProg > 0) {
          const e = easeOutCubic(filterProg);
          alpha *= (1 - e);
          const disperseAngle = Math.atan2(chaosY - H / 2, chaosX - W / 2);
          x = chaosX + Math.cos(disperseAngle) * 40 * e;
          y = chaosY + Math.sin(disperseAngle) * 40 * e;
        }

        if (alpha < 0.01) continue;
        ctx.save();
        ctx.globalAlpha = alpha;
        ctx.strokeStyle = c.fg;
        ctx.lineWidth = 1;
        ctx.translate(x, y);
        ctx.rotate(rot);
        ctx.strokeRect(-w / 2, -h / 2, w, h);
        ctx.restore();
      }

      rafRef.current = requestAnimationFrame(frame);
    }

    rafRef.current = requestAnimationFrame(frame);
    return () => cancelAnimationFrame(rafRef.current);
  }, [tick, c.fg]);

  return (
    <SlideFrame c={c} deckBg>
      <CornerLabel c={c} label={t('system_forming.corner')} />
      <CornerNum c={c} index={11} total={total} />

      <canvas ref={canvasRef} style={{
        position: 'absolute', inset: 0,
        width: '100%', height: '100%',
        pointerEvents: 'none',
      }} />

      <DeckTitle
        c={c} tick={tick}
        eyebrow={t('system_forming.eyebrow')}
        line1={t('system_forming.line1')}
        line2={t('system_forming.line2')}
        accent top={188}
      />

      <div style={{
        position: 'absolute', left: 96, right: 96, bottom: 110,
        display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)',
        gap: 32,
        fontFamily: FONT_MONO, fontSize: 13,
        letterSpacing: '0.12em', textTransform: 'uppercase',
        ...entry('fade', { tick, delay: 4800, duration: 800 }),
      }}>
        <div>
          <div style={{ color: c.accent, marginBottom: 6 }}>{t('system_forming.phase1_label')}</div>
          <div style={{ color: c.fgMuted, fontFamily: FONT_SANS, fontSize: 16,
            letterSpacing: '-0.005em', textTransform: 'none' }}>
            {t('system_forming.phase1_body')}
          </div>
        </div>
        <div>
          <div style={{ color: c.accent, marginBottom: 6 }}>{t('system_forming.phase2_label')}</div>
          <div style={{ color: c.fgMuted, fontFamily: FONT_SANS, fontSize: 16,
            letterSpacing: '-0.005em', textTransform: 'none' }}>
            {t('system_forming.phase2_body')}
          </div>
        </div>
        <div>
          <div style={{ color: c.primary, marginBottom: 6 }}>{t('system_forming.phase3_label')}</div>
          <div style={{ color: c.fgMuted, fontFamily: FONT_SANS, fontSize: 16,
            letterSpacing: '-0.005em', textTransform: 'none' }}>
            {t('system_forming.phase3_body')}
          </div>
        </div>
      </div>

      <Sig c={c} />
    </SlideFrame>
  );
}

// ── Slide 12 — DS Atoms ───────────────────────────────────────────────────

function SlideDSAtoms({ c: cIn, total }) {
  const t = useT();
  const { tick } = useSlideActive(11);

  const c = React.useMemo(() => ({
    ...cIn, bg: cIn.paper, bgAlt: '#EAE6D9',
    fg: cIn.ink, fgMuted: 'rgba(14,16,32,0.66)',
    fgDim: 'rgba(14,16,32,0.32)', rule: 'rgba(14,16,32,0.16)',
  }), [cIn]);

  return (
    <SlideFrame c={c} bg={c.bg}>
      <CornerLabel c={c} label={t('ds_atoms.corner')} />
      <CornerNum c={c} index={12} total={total} />

      <DeckTitle
        c={c} tick={tick} dark
        eyebrow={t('ds_atoms.eyebrow')}
        line1={t('ds_atoms.line1')}
        line2={t('ds_atoms.line2')}
        accent top={200} maxWidth={480}
      />

      <div style={{
        position: 'absolute', left: 96, top: 430, width: 480,
        ...entry('fade', { tick, delay: 320, duration: 700 }),
      }}>
        <div style={{ fontSize: 19, lineHeight: 1.45, color: c.fgMuted, maxWidth: 440 }}>
          {t('ds_atoms.body')}
        </div>

        <div style={{
          marginTop: 56, display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)',
          gap: 22, fontFamily: FONT_MONO, fontSize: 12,
          letterSpacing: '0.14em', textTransform: 'uppercase',
          ...entry('fade', { tick, delay: 500, duration: 700 }),
        }}>
          <div>
            <div style={{ color: c.fgDim, marginBottom: 6 }}>{t('ds_atoms.stat1_label')}</div>
            <div style={{ fontFamily: FONT_SANS, fontSize: 36, letterSpacing: '-0.02em',
              color: c.fg, textTransform: 'none' }}>{t('ds_atoms.stat1_value')}</div>
          </div>
          <div>
            <div style={{ color: c.fgDim, marginBottom: 6 }}>{t('ds_atoms.stat2_label')}</div>
            <div style={{ fontFamily: FONT_SANS, fontSize: 36, letterSpacing: '-0.02em',
              color: c.fg, textTransform: 'none' }}>{t('ds_atoms.stat2_value')}</div>
          </div>
        </div>
      </div>

      <div style={{
        position: 'absolute', left: 640, top: 168, right: 96, bottom: 110,
        ...entry('fade-up', { tick, delay: 280, duration: 900 }),
      }}>
        <img src="/picpay/assets/img/ds-components.png"
          alt="PicPay Design System component library"
          style={{ width: '100%', height: '100%', objectFit: 'contain', objectPosition: 'center', display: 'block' }}
        />
      </div>

      <Sig c={c} />
    </SlideFrame>
  );
}

// ── Slide 13 — In Production ──────────────────────────────────────────────

function SlideInProduction({ c: cIn, total }) {
  const t = useT();
  const { tick } = useSlideActive(12);

  const c = React.useMemo(() => ({
    ...cIn, bg: cIn.paper, bgAlt: '#EAE6D9',
    fg: cIn.ink, fgMuted: 'rgba(14,16,32,0.66)',
    fgDim: 'rgba(14,16,32,0.32)', rule: 'rgba(14,16,32,0.16)',
  }), [cIn]);

  const tileSrcs = [
    '/picpay/assets/img/concept-shop.png', '/picpay/assets/img/invest-empty.png',
    '/picpay/assets/img/invest-products.png', '/picpay/assets/img/shop-home.png',
    '/picpay/assets/img/shop-cashback.png', '/picpay/assets/img/shop-uberone.png',
    '/picpay/assets/img/theme-toggle.png',
  ];
  const tiles = t('in_production.tiles').map((tile, i) => ({ ...tile, src: tileSrcs[i] }));

  return (
    <SlideFrame c={c} bg={c.bgAlt}>
      <CornerLabel c={c} label={t('in_production.corner')} />
      <CornerNum c={c} index={13} total={total} />

      <DeckTitle
        c={c} tick={tick} dark
        eyebrow={t('in_production.eyebrow')}
        line1={t('in_production.line1')}
        line2={t('in_production.line2')}
        accent top={200}
      />

      <div style={{
        position: 'absolute', left: 96, right: 96, top: 440, bottom: 110,
        display: 'grid',
        gridTemplateColumns: 'repeat(4, 1fr)',
        gridTemplateRows: 'repeat(2, 1fr)',
        gap: 16,
      }}>
        {tiles.map((tile, i) => {
          const span = i === 0 ? { gridRow: 'span 2' } : {};
          return (
            <div key={i} style={{
              position: 'relative', background: c.bg,
              border: `1px solid ${c.rule}`, overflow: 'hidden',
              ...span,
              ...entry('fade-up', { tick, delay: 220 + i * 90, duration: 700 }),
            }}>
              <div style={{
                position: 'absolute', inset: 0,
                backgroundImage: `url(${tile.src})`,
                backgroundSize: 'cover', backgroundPosition: 'center',
              }} />
              <div style={{
                position: 'absolute', left: 0, bottom: 0, right: 0,
                padding: '14px 16px',
                background: 'linear-gradient(to top, rgba(242,239,230,0.94), rgba(242,239,230,0))',
                display: 'flex', justifyContent: 'space-between', alignItems: 'baseline',
                fontFamily: FONT_MONO, fontSize: 12,
                letterSpacing: '0.14em', textTransform: 'uppercase',
              }}>
                <span style={{ color: c.fg }}>{tile.label}</span>
                <span style={{ color: c.fgMuted }}>{tile.sub}</span>
              </div>
              <div style={{
                position: 'absolute', top: 12, left: 14,
                fontFamily: FONT_MONO, fontSize: 11,
                color: '#F2EFE6', letterSpacing: '0.16em',
                background: 'rgba(14,16,32,0.65)', padding: '4px 8px',
              }}>
                {String(i + 1).padStart(2, '0')}
              </div>
            </div>
          );
        })}
      </div>

      <Sig c={c} />
    </SlideFrame>
  );
}

// ── Slides 14–18 — Video series ───────────────────────────────────────────

function SlideVideoCartao({ c, total }) {
  const t = useT();
  return <VideoSlide c={c} total={total}
    activeIndex={13} index={14} label={t('video_cartao.corner')}
    src="/picpay/assets/video/cartaoprotobege2.mp4"
    eyebrow={t('video_cartao.eyebrow')}
    line1={t('video_cartao.line1')}
    line2={t('video_cartao.line2')}
  />;
}

function SlideVideoPix({ c, total }) {
  const t = useT();
  return <VideoSlide c={c} total={total}
    activeIndex={14} index={15} label={t('video_pix.corner')}
    src="/picpay/assets/video/picpay-send-pix.mp4"
    eyebrow={t('video_pix.eyebrow')}
    line1={t('video_pix.line1')}
    line2={t('video_pix.line2')}
  />;
}

function SlideVideoBankColor({ c, total }) {
  const t = useT();
  return <VideoSlide c={c} total={total}
    activeIndex={15} index={16} label={t('video_bank.corner')}
    src="/picpay/assets/video/pp-bank-color.mp4"
    eyebrow={t('video_bank.eyebrow')}
    line1={t('video_bank.line1')}
    line2={t('video_bank.line2')}
    rightAlign
  />;
}

function SlideVideoWallet({ c, total }) {
  const t = useT();
  return <VideoSlide c={c} total={total}
    activeIndex={16} index={17} label={t('video_wallet.corner')}
    src="/picpay/assets/video/picpay-wallet.mp4"
    eyebrow={t('video_wallet.eyebrow')}
    line1={t('video_wallet.line1')}
    line2={t('video_wallet.line2')}
  />;
}

function SlideVideoBlack({ c, total }) {
  const t = useT();
  return <VideoSlide c={c} total={total}
    activeIndex={17} index={18} label={t('video_black.corner')}
    src="/picpay/assets/video/picpay-black.mp4"
    eyebrow={t('video_black.eyebrow')}
    line1={t('video_black.line1')}
    line2={t('video_black.line2')}
  />;
}

// ── Slide 19 — Product Overview ───────────────────────────────────────────

function SlideProductOverview({ c, total }) {
  const t = useT();
  const { tick } = useSlideActive(18);

  const screens = [
    '/picpay/assets/img/Home black.png', '/picpay/assets/img/Home gold.png',
    '/picpay/assets/img/beneficios.png', '/picpay/assets/img/investimentos.png',
    '/picpay/assets/img/hub-pix.png', '/picpay/assets/img/Pix Flow 01.png',
    '/picpay/assets/img/Pix Flow 05.png', '/picpay/assets/img/shop.png',
    '/picpay/assets/img/cartoes-a.png', '/picpay/assets/img/cartoes-b.png',
    '/picpay/assets/img/Feedback.png', '/picpay/assets/img/Feedback Cross Sell.png',
    '/picpay/assets/img/Wallet Open Finance Nubank.png', '/picpay/assets/img/Comprovante.png',
  ];

  const PH_W = 260, PH_H = 500, GAP = 24;
  const BG = '#0E1020';
  const strip = [...screens, ...screens];
  const stripW = strip.length * (PH_W + GAP);

  return (
    <SlideFrame c={c} bg={BG}>
      <CornerLabel c={c} label={t('product_overview.corner')} />
      <CornerNum c={c} index={19} total={total} />

      <DeckTitle
        c={c} tick={tick}
        eyebrow={t('product_overview.eyebrow')}
        line1={t('product_overview.line1')}
        line2={t('product_overview.line2')}
        accent top={175} maxWidth={900}
      />

      <div style={{
        position: 'absolute', left: 96, top: 400, maxWidth: 860,
        fontFamily: FONT_MONO, fontSize: 15,
        color: c.fgMuted, letterSpacing: '0.02em', lineHeight: 1.6,
        ...entry('fade', { tick, delay: 400, duration: 700 }),
      }}>
        {t('product_overview.desc')}
      </div>

      <div style={{
        position: 'absolute', left: 0, right: 0,
        top: 420, bottom: 0,
        overflow: 'hidden', display: 'flex', alignItems: 'center',
        background: BG,
      }}>
        <div style={{
          position: 'absolute', left: 0, top: 0, bottom: 0, width: 120, zIndex: 2,
          background: `linear-gradient(to right, ${BG}, transparent)`,
          pointerEvents: 'none',
        }} />
        <div style={{
          position: 'absolute', right: 0, top: 0, bottom: 0, width: 120, zIndex: 2,
          background: `linear-gradient(to left, ${BG}, transparent)`,
          pointerEvents: 'none',
        }} />

        <div style={{
          display: 'flex', gap: GAP, alignItems: 'center',
          width: stripW,
          animation: tick ? 'pp-carousel 56s linear infinite' : 'none',
          opacity: tick ? 1 : 0,
          transition: 'opacity 700ms ease',
          paddingLeft: GAP,
          willChange: 'transform',
        }}>
          {strip.map((src, i) => (
            <div key={i} style={{
              flexShrink: 0, width: PH_W, height: PH_H,
              borderRadius: 24, overflow: 'hidden',
              boxShadow: '0 16px 48px rgba(0,0,0,0.55)',
            }}>
              <img src={src} alt="" style={{
                width: '100%', height: '100%',
                objectFit: 'cover', objectPosition: 'top center', display: 'block',
              }} />
            </div>
          ))}
        </div>
      </div>

      <Sig c={c} />
    </SlideFrame>
  );
}

// ── Slide 20 — Outcomes ───────────────────────────────────────────────────

function SlideOutcomes({ c, total }) {
  const t = useT();
  const { tick } = useSlideActive(19);
  const cells = t('outcomes.cells');
  return (
    <SlideFrame c={c} deckBg>
      <CornerLabel c={c} label={t('outcomes.corner')} />
      <CornerNum c={c} index={20} total={total} />

      <DeckTitle
        c={c} tick={tick}
        eyebrow={t('outcomes.eyebrow')}
        line1={t('outcomes.line1')}
        line2={t('outcomes.line2')}
        accent top={200}
      />

      <div style={{
        position: 'absolute', left: 96, right: 96, top: 460,
        display: 'grid',
        gridTemplateColumns: 'repeat(3, 1fr)',
        gridTemplateRows: 'repeat(2, 240px)',
        borderTop: `1px solid ${c.fg}`,
        borderBottom: `1px solid ${c.rule}`,
      }}>
        {cells.map((m, i) => {
          const color = m.accent ? c.accent : (m.primary ? c.primary : c.fg);
          const col = i % 3;
          const row = Math.floor(i / 3);
          return (
            <div key={m.label} style={{
              padding: '28px 28px 24px 0',
              paddingLeft: col === 0 ? 0 : 32,
              borderRight: col < 2 ? `1px solid ${c.rule}` : 'none',
              borderTop: row === 1 ? `1px solid ${c.rule}` : 'none',
              display: 'flex', flexDirection: 'column', justifyContent: 'space-between',
              ...entry('drop-from-top', { tick, delay: 200 + i * 110, duration: 800 }),
            }}>
              <div style={{
                fontFamily: FONT_SANS, fontSize: 92, fontWeight: 500, color,
                letterSpacing: '-0.04em', lineHeight: 0.9,
                fontVariantNumeric: 'tabular-nums', whiteSpace: 'nowrap',
              }}>
                <CountUp value={m.v} tick={tick} delay={200 + i * 110} duration={1100} />
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                <div style={{ fontSize: 22, fontWeight: 500, letterSpacing: '-0.005em' }}>{m.label}</div>
                <div style={{
                  fontFamily: FONT_MONO, fontSize: 13, color: c.fgMuted,
                  letterSpacing: '0.04em', lineHeight: 1.4,
                  whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
                }}>{m.sub}</div>
              </div>
            </div>
          );
        })}
      </div>

      <Sig c={c} />
    </SlideFrame>
  );
}

// ── Slide 21 — Learnings ──────────────────────────────────────────────────

function SlideLearnings({ c, total }) {
  const t = useT();
  const { tick } = useSlideActive(20);
  const items = t('learnings.items');
  return (
    <SlideFrame c={c} deckBg>
      <CornerLabel c={c} label={t('learnings.corner')} />
      <CornerNum c={c} index={21} total={total} />

      <DeckTitle
        c={c} tick={tick}
        eyebrow={t('learnings.eyebrow')}
        line1={t('learnings.line1')}
        line2={t('learnings.line2')}
        top={200}
      />

      <div style={{
        position: 'absolute', left: 96, right: 96, top: 480,
        display: 'grid', gridTemplateColumns: '1fr 1px 1fr 1px 1fr', gap: 40,
      }}>
        {items.map((it, i) => (
          <React.Fragment key={it.n}>
            <div style={{
              display: 'flex', flexDirection: 'column', gap: 24, minHeight: 480,
              ...entry('fade-up', { tick, delay: 200 + i * 180, duration: 800 }),
            }}>
              <div style={{
                fontFamily: FONT_MONO, fontSize: TYPE_SCALE.subtitle,
                color: c.primary, fontVariantNumeric: 'tabular-nums',
                letterSpacing: '-0.02em',
              }}>{it.n}</div>
              <div style={{
                fontSize: TYPE_SCALE.subtitle - 4, fontWeight: 500,
                letterSpacing: '-0.02em', lineHeight: 1.1,
                textWrap: 'balance', maxWidth: 480,
              }}>{it.t}</div>
              <div style={{
                marginTop: 'auto', fontSize: TYPE_SCALE.body - 2,
                color: c.fgMuted, lineHeight: 1.5, textWrap: 'pretty', maxWidth: 480,
              }}>{it.body}</div>
            </div>
            {i < items.length - 1 && (
              <div style={{ width: 1, background: c.rule,
                ...entry('sweep-y', { tick, delay: 280 + i * 180, duration: 800 }) }} />
            )}
          </React.Fragment>
        ))}
      </div>

      <Sig c={c} />
    </SlideFrame>
  );
}

// ── Slide 22 — Recap ──────────────────────────────────────────────────────

function SlideRecap({ c, total }) {
  const t = useT();
  const { tick } = useSlideActive(21);
  const items = t('recap.items');

  return (
    <SlideFrame c={c} deckBg>
      <CornerLabel c={c} label={t('recap.corner')} />
      <CornerNum c={c} index={22} total={total} />

      <div style={{
        position: 'absolute', left: 96, top: 88,
        fontFamily: FONT_MONO, fontSize: 13, fontWeight: 700,
        letterSpacing: '0.22em', textTransform: 'uppercase',
        color: c.primary, display: 'flex', alignItems: 'center', gap: 16,
        ...entry('fade', { tick, duration: 500 }),
      }}>
        <span style={{ width: 42, height: 1, background: 'currentColor', opacity: 0.62 }} />
        <span>{t('recap.eyebrow')}</span>
      </div>

      <div style={{
        position: 'absolute', left: 96, right: 96, top: 136,
        height: 1, background: c.rule,
        transformOrigin: 'left',
        ...entry('sweep-x', { tick, delay: 80, duration: 900 }),
      }} />

      <div style={{
        position: 'absolute', left: 96, right: 96, top: 200, bottom: 110,
        display: 'grid', gridTemplateColumns: '1fr 1px 1fr 1px 1fr', gap: 0,
      }}>
        {items.map((item, i) => {
          const lines = item.headline.split('\n');
          const lastLine = lines[lines.length - 1];
          const prevLines = lines.slice(0, -1);

          return (
            <React.Fragment key={item.n}>
              {i > 0 && (
                <div style={{
                  width: 1, background: c.rule,
                  ...entry('sweep-y', { tick, delay: 150 + i * 120, duration: 700 }),
                }} />
              )}
              <div style={{
                padding: '48px 56px 48px 0',
                paddingLeft: i === 0 ? 0 : 56,
                display: 'flex', flexDirection: 'column', justifyContent: 'space-between',
                ...entry('fade-up', { tick, delay: 200 + i * 160, duration: 800 }),
              }}>
                <div style={{
                  fontFamily: FONT_MONO, fontSize: 13,
                  color: c.fgDim, letterSpacing: '0.22em', marginBottom: 32,
                }}>{item.n}</div>

                <div style={{
                  fontSize: TYPE_SCALE.subtitle + 4, fontWeight: 500,
                  letterSpacing: '-0.025em', lineHeight: 1.1, flexGrow: 1,
                }}>
                  {prevLines.map((l, j) => (
                    <React.Fragment key={j}>{l}<br /></React.Fragment>
                  ))}
                  <span style={{ color: c.primary, fontStyle: 'italic', fontWeight: 400 }}>
                    {lastLine}
                  </span>
                </div>

                <div style={{
                  marginTop: 32, fontFamily: FONT_MONO, fontSize: 14,
                  color: c.fgMuted, letterSpacing: '0.02em', lineHeight: 1.55,
                  ...entry('fade', { tick, delay: 500 + i * 160, duration: 700 }),
                }}>{item.sub}</div>
              </div>
            </React.Fragment>
          );
        })}
      </div>

      <Sig c={c} />
    </SlideFrame>
  );
}

// ── Slide 23 — CTA ────────────────────────────────────────────────────────

function SlideCTA({ c, total }) {
  const t = useT();
  const { tick } = useSlideActive(22);
  const contacts = t('cta.contacts');
  return (
    <SlideFrame c={c} deckBg>
      <CornerLabel c={c} label={t('cta.corner')} />
      <CornerNum c={c} index={23} total={total} />

      <div style={{ position: 'absolute', left: 96, top: 240 }}>
        <div style={{
          fontSize: TYPE_SCALE.display, fontWeight: 500,
          letterSpacing: '-0.045em', lineHeight: 0.92,
          ...entry('rise', { tick, duration: 900 }),
        }}>
          {t('cta.line1')}
        </div>
        <div style={{
          fontSize: TYPE_SCALE.display, fontWeight: 400, fontStyle: 'italic',
          color: c.primary,
          letterSpacing: '-0.045em', lineHeight: 0.92, marginTop: -16,
          ...entry('rise', { tick, delay: 220, duration: 900 }),
        }}>
          {t('cta.line2')}
        </div>
      </div>

      <div style={{
        position: 'absolute', left: 96, right: 96, bottom: 130,
        ...entry('fade-up', { tick, delay: 600, duration: 700 }),
      }}>
        <div style={{ height: 1, background: c.fg, marginBottom: 32 }} />
        <div style={{
          display: 'grid', gridTemplateColumns: '2fr 1.4fr 1.4fr 1.4fr',
          gap: 48, alignItems: 'baseline',
        }}>
          {contacts.map((col) => (
            <ContactCol key={col.k} c={c} k={col.k} v={col.v} href={col.href} />
          ))}
        </div>
      </div>
    </SlideFrame>
  );
}

// ── Export ────────────────────────────────────────────────────────────────
Object.assign(window, {
  PALETTES, FONT_SANS, FONT_MONO,
  SlideCover, SlideRole, SlideContext, SlideProblem, SlideOldPP, SlideResearch,
  SlideProcess, SlideInsight, SlideConcept, SlideSystem, SlideSystemForming, SlideDSAtoms,
  SlideInProduction, SlideVideoCartao, SlideVideoPix, SlideVideoBankColor, SlideVideoWallet, SlideVideoBlack,
  SlideProductOverview, SlideOutcomes, SlideLearnings, SlideRecap, SlideCTA,
});
