// 9:16 portrait composition — 1080x1920, all 5 acts redesigned for vertical
// Reuses existing Sprite/CueLayer infra. Width 1080, height 1920.

// ── Act 1 — Problema ────────────────────────────────────────────────────────
function Act1ProblemV() {
  return (
    <Sprite start={0} end={5.0}>
      <Act1VInner />
    </Sprite>
  );
}
function Act1VInner() {
  const { localTime: t } = useSprite();
  const bars = Array.from({ length: 32 }, (_, i) => 8 + Math.abs(Math.sin(i * 0.4 + t * 4)) * 80 + Math.abs(Math.sin(i * 1.7 + t * 3)) * 50);
  const pulse = 0.7 + Math.sin(t * 6) * 0.3;
  const chatLines = [
    { u: 'gabriela_91', m: '🔥🔥🔥', c: '#F59E0B' },
    { u: 'el_madmax', m: 'NO J*DAS', c: '#EA580C' },
    { u: 'streamfan', m: 'guarda eso pa shorts', c: '#9061f9' },
    { u: 'kevin_g', m: 'clip clip clip', c: '#EA580C' },
    { u: 'lia_88', m: 'a tiktok ya', c: '#F59E0B' },
  ];
  const visibleChat = Math.min(5, Math.floor(t * 2.4));
  // Captions alineadas con Act1 (3 captions, 5s total)
  const captions = [
    { t: 0.0, end: 1.8, text: '3 horas de stream.' },
    { t: 1.9, end: 3.4, text: '0 clips publicados.' },
    { t: 3.5, end: 5.0, text: 'La competencia publica a diario.' },
  ];
  return (
    <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(180deg, #0f0f0f 0%, #000 100%)', overflow: 'hidden' }}>
      {/* Stream panel — dentro de safe-zone TikTok/Reels (top 220 reservado) */}
      <div style={{ position: 'absolute', left: 60, top: 240, right: 60, height: 620, borderRadius: 22, background: '#000', border: '1px solid rgba(234,88,12,0.3)', overflow: 'hidden', boxShadow: '0 0 80px rgba(234,88,12,0.2)' }}>
        <div style={{ position: 'absolute', top: 0, left: 0, right: 0, height: 56, background: 'rgba(0,0,0,0.7)', borderBottom: '1px solid rgba(255,255,255,0.06)', display: 'flex', alignItems: 'center', padding: '0 20px', gap: 14, fontSize: 16, color: 'rgba(255,255,255,0.5)', fontFamily: 'Inter, system-ui, sans-serif' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 7, padding: '5px 12px', background: '#EA580C', borderRadius: 5, color: '#fff', fontWeight: 700, fontSize: 13, letterSpacing: '0.08em', opacity: pulse }}>
            <div style={{ width: 7, height: 7, background: '#fff', borderRadius: 4 }} />EN VIVO
          </div>
          <div style={{ marginLeft: 'auto', fontVariantNumeric: 'tabular-nums' }}>2.847 espectadores</div>
        </div>
        <div style={{ position: 'absolute', top: 100, left: 30, right: 30, height: 280, display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 4 }}>
          {bars.map((h, i) => {
            const fade = Math.max(0.2, 1 - Math.abs(i - 16) / 16);
            return <div key={i} style={{ width: 22, height: h * 1.6, background: 'linear-gradient(180deg, #F59E0B 0%, #EA580C 100%)', borderRadius: 3, opacity: fade }} />;
          })}
        </div>
        {t > 3 && t < 6 && (
          <div style={{ position: 'absolute', top: 410, left: '50%', transform: `translateX(-50%) scale(${Math.min(1, (t-3)*2)})`, padding: '10px 18px', background: 'rgba(234,88,12,0.15)', border: '1px solid rgba(234,88,12,0.5)', borderRadius: 999, color: '#F59E0B', fontSize: 16, fontFamily: 'JetBrains Mono, monospace', letterSpacing: '0.06em' }}>
            ● momento detectado
          </div>
        )}
        <div style={{ position: 'absolute', bottom: 30, left: 30, right: 30, padding: 18, background: 'rgba(255,255,255,0.04)', borderRadius: 10 }}>
          <div style={{ color: 'rgba(255,255,255,0.4)', fontSize: 13, letterSpacing: '0.08em', textTransform: 'uppercase', marginBottom: 8, fontFamily: 'Inter, system-ui, sans-serif' }}>Título del directo</div>
          <div style={{ color: '#fff', fontSize: 22, fontWeight: 600, fontFamily: 'Inter, system-ui, sans-serif' }}>Probando el nuevo update · gameplay caótico</div>
        </div>
      </div>

      {/* Chat panel — below stream, fuera de bottom safe-zone (400 reservados) */}
      <div style={{ position: 'absolute', left: 60, right: 60, top: 880, height: 280, borderRadius: 22, background: 'rgba(255,255,255,0.02)', border: '1px solid rgba(255,255,255,0.08)', overflow: 'hidden' }}>
        <div style={{ padding: '16px 22px', borderBottom: '1px solid rgba(255,255,255,0.06)', fontSize: 14, color: 'rgba(255,255,255,0.5)', letterSpacing: '0.08em', textTransform: 'uppercase', fontFamily: 'Inter, system-ui, sans-serif' }}>Chat en directo</div>
        <div style={{ padding: '16px 22px', display: 'flex', flexDirection: 'column', gap: 14, fontFamily: 'Inter, system-ui, sans-serif' }}>
          {chatLines.slice(0, visibleChat).map((c, i) => (
            <div key={i} style={{ fontSize: 22, opacity: Math.min(1, (t*1.5 - i)*1.5) }}>
              <span style={{ color: c.c, fontWeight: 600 }}>{c.u}</span>
              <span style={{ color: 'rgba(255,255,255,0.85)', marginLeft: 12 }}>{c.m}</span>
            </div>
          ))}
        </div>
      </div>

      {/* Kinetic captions — bottom */}
      {captions.map((c, i) => {
        if (t < c.t || t > c.end) return null;
        const local = t - c.t, dur = c.end - c.t;
        let opacity = 1, ty = 0, scale = 1;
        if (local < 0.3) { const k = local/0.3; opacity = k; ty = (1-k)*40; scale = 0.9 + k*0.1; }
        else if (local > dur - 0.3) { const k = (dur-local)/0.3; opacity = k; }
        return (
          <div key={i} style={{ position: 'absolute', left: 60, right: 60, bottom: 460, transform: `translateY(${ty}px) scale(${scale})`, opacity, fontFamily: 'Inter, system-ui, sans-serif', fontSize: 96, fontWeight: 800, letterSpacing: '-0.035em', color: '#fff', textShadow: '0 4px 30px rgba(0,0,0,0.85)', textAlign: 'center', lineHeight: 1.05 }}>
            {c.text}
          </div>
        );
      })}
    </div>
  );
}

// ── Act 2 — Solución ────────────────────────────────────────────────────────
function Act2SolutionV() {
  return <Sprite start={5.0} end={20.0}><Act2VInner /></Sprite>;
}
function Act2VInner() {
  const { localTime: t } = useSprite();
  // 15s total, idéntico mapeo a Act2 desktop
  return (
    <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(180deg, #0f0f0f 0%, #000 100%)', overflow: 'hidden' }}>
      {t < 1.5 && <LogoRevealV t={t} />}
      {t >= 1.5 && t < 4.5 && <PhaseURLV t={t - 1.5} />}
      {t >= 4.5 && t < 7.5 && <PhaseAnalysisV t={t - 4.5} />}
      {t >= 7.5 && t < 11.0 && <PhaseClipV t={t - 7.5} />}
      {t >= 11.0 && t < 15.0 && <PhasePublishV t={t - 11.0} />}
      <CueLayer t={t} cues={[
        { t: 1.5,  end: 4.5,  es: 'Pega tu URL · Twitch o YouTube.',     en: 'Paste your URL · Twitch or YouTube.' },
        { t: 4.5,  end: 7.5,  es: 'La IA detecta los momentos virales.', en: 'AI spots the viral moments.' },
        { t: 7.5,  end: 11.0, es: 'Corta, encuadra y quema subtítulos.', en: 'Cuts, frames and burns subtitles.' },
        { t: 11.0, end: 15.0, es: 'Publica adaptado a cada red.',        en: 'Publishes adapted to each network.' },
      ]} />
    </div>
  );
}
function BoltSvgV({ size }) {
  return <svg width={size} height={size} viewBox="0 0 100 100"><defs><linearGradient id={`bv${size}`} x1="0" y1="0" x2="1" y2="1"><stop offset="0%" stopColor="#F59E0B"/><stop offset="100%" stopColor="#EA580C"/></linearGradient></defs><path d="M55 8 L25 52 L48 52 L42 92 L75 42 L52 42 Z" fill={`url(#bv${size})`}/></svg>;
}
function LogoRevealV({ t }) {
  // 1.5s logo reveal, slogan reservado para Act 5
  if (t >= 1.5) return null;
  const fadeIn = Easing.easeOutCubic(clamp(t / 0.4, 0, 1));
  const fadeOut = t > 1.1 ? Easing.easeInCubic(clamp((1.5 - t) / 0.4, 0, 1)) : 1;
  const opacity = Math.min(fadeIn, fadeOut);
  const scaleK = Easing.easeOutBack(clamp(t / 0.55, 0, 1));
  const scale = 0.6 + scaleK * 0.4;
  return (
    <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', opacity }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 24, transform: `scale(${scale}) translateX(-40px)` }}>
        <BoltSvgV size={160} />
        <div style={{ fontFamily: 'Inter, system-ui, sans-serif', fontSize: 160, fontWeight: 800, letterSpacing: '-0.04em', color: '#fff' }}>Chispa</div>
      </div>
    </div>
  );
}
function PhaseURLV({ t }) {
  // 3s phase, 1 URL typed + 1 instant (paridad con desktop)
  const opacity = t < 0.3 ? Easing.easeOutCubic(t / 0.3) : t > 2.6 ? Easing.easeInCubic(clamp((3.0 - t) / 0.4, 0, 1)) : 1;
  const url1 = 'twitch.tv/streamer/v/2847391';
  const url2 = 'youtube.com/watch?v=Hk9oG7tT4nQ';
  const typed1 = t < 1.4 ? url1.slice(0, Math.min(url1.length, Math.floor(t * 26))) : url1;
  const url1Active = t < 1.4;
  const url1Done = t >= 1.4;
  const url2In = clamp((t - 1.4) / 0.35, 0, 1);
  const url2Eased = Easing.easeOutBack(url2In);
  const url2Done = t >= 1.6;
  const showCursor = Math.floor(t * 4) % 2 === 0;
  const buttonProgress = Easing.easeOutCubic(clamp((t - 1.8) * 4, 0, 1));
  let pressed = t >= 2.35;
  return (
    <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 60, opacity }}>
      <div style={{
        width: '100%',
        padding: 44,
        background: 'rgba(255,255,255,0.04)',
        border: '1px solid rgba(255,255,255,0.1)',
        borderRadius: 26,
        display: 'flex',
        flexDirection: 'column',
        gap: 26,
      }}>
        <div style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 22, color: '#F59E0B', letterSpacing: '0.14em', textTransform: 'uppercase', fontWeight: 600 }}>
          paso 1 · directo o vídeo
        </div>

        <URLRowV label="TWITCH · DIRECTO" labelColor="#9146FF" iconColor="#9146FF" typed={typed1} active={url1Active} done={url1Done} cursor={showCursor} kind="twitch" />
        <div style={{ opacity: url2Eased, transform: `scale(${0.94 + url2Eased * 0.06})`, transformOrigin: 'left center' }}>
          <URLRowV label="YOUTUBE · VÍDEO" labelColor="#FF0033" iconColor="#FF0033" typed={url2} active={false} done={url2Done} cursor={false} kind="youtube" />
        </div>

        {/* In-product CTA — neutral, no compite con Act 5 */}
        <div style={{ height: 96, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          <div style={{
            padding: '20px 36px',
            background: pressed ? 'rgba(234,88,12,0.18)' : 'rgba(234,88,12,0.08)',
            border: '1.5px solid rgba(234,88,12,0.7)',
            borderRadius: 14,
            fontFamily: 'Inter, system-ui, sans-serif',
            fontSize: 28, fontWeight: 700, color: '#F59E0B',
            textAlign: 'center',
            boxShadow: pressed ? '0 0 24px rgba(234,88,12,0.4)' : '0 4px 16px rgba(0,0,0,0.4)',
            opacity: buttonProgress,
            transform: `translateY(${(1 - buttonProgress) * 10}px)`,
          }}>
            Detectar la chispa →
          </div>
        </div>
      </div>
    </div>
  );
}
function URLRowV({ label, labelColor, typed, active, done, cursor, kind }) {
  const borderColor = active ? '#EA580C' : done ? 'rgba(34,197,94,0.5)' : 'rgba(255,255,255,0.08)';
  const glow = active ? '0 0 40px rgba(234,88,12,0.3)' : 'none';
  const icon = kind === 'twitch'
    ? <svg width="28" height="28" viewBox="0 0 24 24" fill="#9146FF"><path d="M2.149 0l-1.612 4.119v16.836h5.731v3.045h3.224l3.045-3.045h4.657l6.269-6.269v-14.686h-21.314zm19.164 13.612l-3.582 3.582h-5.731l-3.045 3.045v-3.045h-4.836v-15.045h17.194v11.463zm-3.582-7.343v6.262h-2.149v-6.262h2.149zm-5.731 0v6.262h-2.149v-6.262h2.149z"/></svg>
    : <svg width="32" height="26" viewBox="0 0 24 18" fill="#FF0033"><path d="M23.498 2.815c-.276-1.034-1.087-1.847-2.117-2.123C19.505.225 12 .225 12 .225s-7.505 0-9.381.467C1.589.968.776 1.781.502 2.815.04 4.694.04 8.6.04 8.6s0 3.906.462 5.785c.275 1.034 1.087 1.847 2.117 2.123 1.876.467 9.381.467 9.381.467s7.505 0 9.381-.467c1.03-.276 1.841-1.089 2.117-2.123.462-1.879.462-5.785.462-5.785s0-3.906-.462-5.785zM9.602 12.225V4.975L15.83 8.6l-6.228 3.625z"/></svg>;
  return (
    <div>
      <div style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 14, color: labelColor, letterSpacing: '0.16em', fontWeight: 700, marginBottom: 10 }}>{label}</div>
      <div style={{
        padding: '24px 26px',
        background: '#0a0a0a',
        border: `2px solid ${borderColor}`,
        borderRadius: 16,
        fontFamily: 'JetBrains Mono, monospace', fontSize: 26,
        color: '#fff',
        boxShadow: glow,
        wordBreak: 'break-all',
        display: 'flex', alignItems: 'center', gap: 18,
        minHeight: 88,
        boxSizing: 'border-box',
      }}>
        <div style={{ flexShrink: 0 }}>{icon}</div>
        <span style={{ flex: 1 }}>
          {typed}{active && cursor && <span style={{ color: '#EA580C' }}>▋</span>}
        </span>
        {done && (
          <svg width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="#22c55e" strokeWidth="2.8" strokeLinecap="round" strokeLinejoin="round" style={{ flexShrink: 0 }}>
            <polyline points="4 12 10 18 20 6"/>
          </svg>
        )}
      </div>
    </div>
  );
}
function PhaseAnalysisV({ t }) {
  // 3s phase
  const opacity = t < 0.3 ? Easing.easeOutCubic(t / 0.3) : t > 2.5 ? Easing.easeInCubic(clamp((3.0 - t) / 0.5, 0, 1)) : 1;
  const bars = Array.from({ length: 36 }, (_, i) => 10 + Math.abs(Math.sin(i*0.4 + t*3))*60 + Math.abs(Math.sin(i*1.3 + t*2))*40);
  const markers = [
    { pos: 8, label: 'grito', appear: 0.6 },
    { pos: 16, label: 'reacción', appear: 1.2 },
    { pos: 24, label: 'giro', appear: 1.8 },
    { pos: 30, label: 'climax', appear: 2.4 },
  ];
  return (
    <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', flexDirection: 'column', gap: 40, opacity, padding: 60 }}>
      <div style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 18, color: '#F59E0B', letterSpacing: '0.12em', textTransform: 'uppercase' }}>paso 2 · IA analiza</div>
      <div style={{ width: '100%', height: 600, position: 'relative', background: 'rgba(255,255,255,0.02)', border: '1px solid rgba(255,255,255,0.08)', borderRadius: 22, padding: 30 }}>
        <div style={{ position: 'absolute', left: 30, right: 30, top: 140, bottom: 140, display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 3 }}>
          {bars.map((h, i) => {
            const isNear = markers.some(m => Math.abs(m.pos - i) < 2 && t > m.appear);
            return <div key={i} style={{ width: 22, height: h*2, background: isNear ? '#EA580C' : 'linear-gradient(180deg, #F59E0B, #EA580C)', borderRadius: 3, boxShadow: isNear ? '0 0 14px rgba(234,88,12,0.8)' : 'none' }} />;
          })}
        </div>
        {markers.map((m, i) => {
          if (t < m.appear) return null;
          return (
            <div key={i} style={{ position: 'absolute', top: 50, left: `calc(30px + ${m.pos * 26.5}px)`, opacity: Math.min(1, (t-m.appear)*3), transform: 'translateX(-50%)' }}>
              <div style={{ padding: '6px 14px', background: '#EA580C', borderRadius: 999, fontFamily: 'JetBrains Mono, monospace', fontSize: 14, color: '#fff', letterSpacing: '0.05em', textTransform: 'uppercase' }}>{m.label}</div>
            </div>
          );
        })}
        <div style={{ position: 'absolute', left: 30, bottom: 50, fontFamily: 'JetBrains Mono, monospace', fontSize: 16, color: 'rgba(255,255,255,0.5)' }}>analizando · 03:24:18</div>
        <div style={{ position: 'absolute', right: 30, bottom: 50, fontFamily: 'JetBrains Mono, monospace', fontSize: 16, color: '#F59E0B' }}>● {markers.filter(m => t > m.appear).length} momentos</div>
      </div>
    </div>
  );
}
function PhaseClipV({ t }) {
  // 3.5s phase
  const opacity = t < 0.3 ? Easing.easeOutCubic(t / 0.3) : t > 3.0 ? Easing.easeInCubic(clamp((3.5 - t) / 0.5, 0, 1)) : 1;
  const subProgress = Math.min(1, Math.max(0, (t - 0.5) / 0.5));
  const cap = Math.min(2, Math.floor(Math.max(0, t - 0.6) / 0.55));
  const captions = ['¡NO J*DAS!', 'NO ME LO CREO', 'ESTO ES BRUTAL'];
  return (
    <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', flexDirection: 'column', gap: 36, opacity, padding: 60 }}>
      <div style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 22, color: '#F59E0B', letterSpacing: '0.18em', textTransform: 'uppercase', fontWeight: 600 }}>paso 3 · clip vertical listo</div>
      <div style={{ width: 480, height: 800, background: 'linear-gradient(135deg, #2a1810, #0a0a0a)', borderRadius: 32, border: '4px solid rgba(234,88,12,0.55)', boxShadow: '0 0 100px rgba(234,88,12,0.4)', position: 'relative', overflow: 'hidden' }}>
        <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          <div style={{ width: 260, height: 360, background: 'radial-gradient(ellipse at 50% 40%, rgba(245,158,11,0.18) 0%, rgba(234,88,12,0.06) 60%, transparent 100%)', borderRadius: '50%' }} />
        </div>
        <div style={{ position: 'absolute', top: 24, left: 24, padding: '8px 16px', background: 'rgba(0,0,0,0.7)', borderRadius: 8, fontFamily: 'JetBrains Mono, monospace', fontSize: 18, color: '#F59E0B', fontWeight: 700 }}>9:16 · 28s</div>
        <div style={{ position: 'absolute', top: 24, right: 24, padding: '8px 16px', background: 'rgba(234,88,12,0.18)', border: '1px solid rgba(234,88,12,0.5)', borderRadius: 999, fontFamily: 'JetBrains Mono, monospace', fontSize: 16, color: '#F59E0B', fontWeight: 700, display: 'flex', alignItems: 'center', gap: 8 }}>
          <span style={{ display: 'inline-block', width: 9, height: 9, borderRadius: 5, background: '#EA580C' }} />
          renderizado
        </div>
        {subProgress > 0 && (
          <div style={{ position: 'absolute', bottom: 120, left: '50%', transform: `translateX(-50%) scale(${0.85 + subProgress*0.15})`, opacity: subProgress, padding: '14px 26px', background: '#fff', color: '#000', fontFamily: 'Inter, system-ui, sans-serif', fontSize: 36, fontWeight: 900, letterSpacing: '-0.01em', textTransform: 'uppercase', borderRadius: 10, whiteSpace: 'nowrap', boxShadow: '0 12px 32px rgba(0,0,0,0.5)' }}>
            {captions[cap]}
          </div>
        )}
        <div style={{ position: 'absolute', bottom: 40, left: 0, right: 0, display: 'flex', justifyContent: 'center', gap: 10 }}>
          {[0, 1, 2].map(i => (
            <div key={i} style={{ width: i === cap ? 40 : 12, height: 12, borderRadius: 6, background: i === cap ? '#F59E0B' : 'rgba(255,255,255,0.3)', transition: 'width 200ms' }} />
          ))}
        </div>
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 14, width: '100%', maxWidth: 540 }}>
        <ClipFeatureV delay={0.0} t={t} icon="✂️" label="Cortado 9:16" />
        <ClipFeatureV delay={0.25} t={t} icon="📝" label="Subtítulos quemados" />
        <ClipFeatureV delay={0.5} t={t} icon="🎬" label="Hook en frame 0" />
      </div>
    </div>
  );
}
function ClipFeatureV({ delay, t, icon, label }) {
  const local = t - delay;
  const slide = Math.max(0, Math.min(1, local * 4));
  const ease = 1 - Math.pow(1-slide, 3);
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 18, padding: '16px 22px', background: 'rgba(255,255,255,0.04)', border: '1px solid rgba(255,255,255,0.08)', borderRadius: 14, opacity: ease, transform: `translateX(${(1-ease)*30}px)` }}>
      <div style={{ fontSize: 36, width: 50, textAlign: 'center' }}>{icon}</div>
      <div style={{ fontFamily: 'Inter, system-ui, sans-serif', fontSize: 26, fontWeight: 700, color: '#fff', letterSpacing: '-0.01em' }}>{label}</div>
    </div>
  );
}
function PhasePublishV({ t }) {
  // 4s phase (Adapt+Publish fusionado para paridad con desktop)
  const opacity = t < 0.3 ? Easing.easeOutCubic(t / 0.3) : t > 3.5 ? Easing.easeInCubic(clamp((4.0 - t) / 0.5, 0, 1)) : 1;
  const headlineProgress = Math.max(0, Math.min(1, t / 0.5));
  const logos = [
    { name: 'YouTube',   color: '#FF0033', delay: 0.0 },
    { name: 'TikTok',    color: '#fff',    delay: 0.18 },
    { name: 'Instagram', color: '#E1306C', delay: 0.36 },
  ];
  const showTs = t > 1.0;
  return (
    <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', flexDirection: 'column', gap: 80, opacity, padding: 60 }}>
      <div style={{
        textAlign: 'center',
        opacity: headlineProgress,
        transform: `translateY(${(1 - headlineProgress) * 18}px)`,
      }}>
        <div style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 22, color: '#F59E0B', letterSpacing: '0.22em', textTransform: 'uppercase', fontWeight: 600, marginBottom: 22 }}>
          paso 4 · adapta + publica
        </div>
        <div style={{
          fontFamily: 'Inter, system-ui, sans-serif',
          fontSize: 144,
          fontWeight: 900,
          color: '#fff',
          letterSpacing: '-0.045em',
          lineHeight: 0.92,
          textTransform: 'uppercase',
          textShadow: '0 10px 50px rgba(234,88,12,0.3)',
        }}>
          publica<br/>mientras<br/><span style={{ color: '#F59E0B' }}>duermes</span>.
        </div>
        {showTs && (
          <div style={{
            fontFamily: 'JetBrains Mono, monospace',
            fontSize: 28,
            color: 'rgba(255,255,255,0.5)',
            letterSpacing: '0.08em',
            marginTop: 24,
            opacity: Math.min(1, (t - 1.0) * 2),
          }}>
            · 03:47 a.m. ·
          </div>
        )}
      </div>

      {/* Subtítulo: cada red, su versión */}
      <div style={{
        fontFamily: 'Inter, system-ui, sans-serif',
        fontSize: 28,
        color: 'rgba(255,255,255,0.65)',
        textAlign: 'center',
        marginTop: -50,
        opacity: Math.min(1, Math.max(0, (t - 0.35) / 0.4)),
        letterSpacing: '-0.005em',
        lineHeight: 1.35,
      }}>
        Cada clip <span style={{ color: '#F59E0B', fontWeight: 600 }}>optimizado</span> para su red.
      </div>

      <div style={{ display: 'flex', gap: 30, alignItems: 'center', justifyContent: 'center' }}>
        {logos.map((l, i) => {
          const local = t - l.delay;
          const ease = Easing.easeOutBack(clamp(local * 3, 0, 1));
          const done = t > l.delay + 0.6;
          let icon;
          if (l.name === 'YouTube') {
            icon = <svg width="100" height="74" viewBox="0 0 24 18" fill="#FF0033"><path d="M23.498 2.815c-.276-1.034-1.087-1.847-2.117-2.123C19.505.225 12 .225 12 .225s-7.505 0-9.381.467C1.589.968.776 1.781.502 2.815.04 4.694.04 8.6.04 8.6s0 3.906.462 5.785c.275 1.034 1.087 1.847 2.117 2.123 1.876.467 9.381.467 9.381.467s7.505 0 9.381-.467c1.03-.276 1.841-1.089 2.117-2.123.462-1.879.462-5.785.462-5.785s0-3.906-.462-5.785zM9.602 12.225V4.975L15.83 8.6l-6.228 3.625z"/></svg>;
          } else if (l.name === 'TikTok') {
            icon = <svg width="88" height="100" viewBox="0 0 24 24" fill="#fff"><path d="M19.59 6.69a4.83 4.83 0 0 1-3.77-4.25V2h-3.45v13.67a2.89 2.89 0 0 1-5.2 1.74 2.89 2.89 0 0 1 2.31-4.64 2.93 2.93 0 0 1 .88.13V9.4a6.84 6.84 0 0 0-1-.05A6.33 6.33 0 0 0 5.8 20.1a6.34 6.34 0 0 0 10.86-4.43v-7a8.16 8.16 0 0 0 4.77 1.52v-3.4a4.85 4.85 0 0 1-1.84-.1z"/></svg>;
          } else {
            icon = (
              <svg width="92" height="92" viewBox="0 0 24 24">
                <defs>
                  <linearGradient id="ig-grad-v" x1="0%" y1="0%" x2="100%" y2="100%">
                    <stop offset="0%" stopColor="#F58529"/>
                    <stop offset="35%" stopColor="#DD2A7B"/>
                    <stop offset="70%" stopColor="#8134AF"/>
                    <stop offset="100%" stopColor="#515BD4"/>
                  </linearGradient>
                </defs>
                <rect x="2" y="2" width="20" height="20" rx="5.5" fill="url(#ig-grad-v)"/>
                <circle cx="12" cy="12" r="4.5" fill="none" stroke="#fff" strokeWidth="2"/>
                <circle cx="17.5" cy="6.5" r="1.3" fill="#fff"/>
              </svg>
            );
          }
          return (
            <div key={i} style={{
              display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 18,
              opacity: ease,
              transform: `translateY(${(1 - ease) * 30}px) scale(${0.92 + ease * 0.08})`,
            }}>
              <div style={{
                width: 180, height: 180,
                borderRadius: 36,
                background: 'rgba(255,255,255,0.04)',
                border: `2px solid ${l.color}55`,
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                boxShadow: `0 28px 70px ${l.color}33`,
                position: 'relative',
              }}>
                {icon}
                {done && (
                  <div style={{ position: 'absolute', top: -12, right: -12, width: 44, height: 44, borderRadius: 22, background: '#22c55e', display: 'flex', alignItems: 'center', justifyContent: 'center', boxShadow: '0 0 24px rgba(34,197,94,0.6)' }}>
                    <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="3.2" strokeLinecap="round" strokeLinejoin="round">
                      <polyline points="4 12 10 18 20 6"/>
                    </svg>
                  </div>
                )}
              </div>
              <div style={{ fontFamily: 'Inter, system-ui, sans-serif', fontSize: 22, fontWeight: 700, color: '#fff' }}>{l.name}</div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

// ── Act 3 — IA aprende ──────────────────────────────────────────────────────
function Act3AIV() {
  return <Sprite start={20.0} end={32.0}><Act3VInner /></Sprite>;
}
function Act3VInner() {
  const { localTime: t } = useSprite();
  return (
    <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(180deg, #0f0f0f 0%, #000 100%)', overflow: 'hidden' }}>
      {/* Multi-idioma chip — 2s breve, no persistente */}
      {t < 2.0 && (
        <div style={{ position: 'absolute', top: 260, left: '50%', transform: 'translateX(-50%)', padding: '10px 22px', background: 'rgba(234,88,12,0.1)', border: '1px solid rgba(234,88,12,0.3)', borderRadius: 999, fontFamily: 'JetBrains Mono, monospace', fontSize: 18, color: '#F59E0B', letterSpacing: '0.08em', textTransform: 'uppercase', display: 'flex', alignItems: 'center', gap: 10, zIndex: 5, opacity: t < 0.3 ? Easing.easeOutCubic(t/0.3) : t > 1.7 ? Easing.easeInCubic(clamp((2.0 - t) / 0.3, 0, 1)) : 1 }}>
          🌐 español · català · english
        </div>
      )}
      {t < 1.5 && <div style={{ position: 'absolute', top: 350, left: 0, right: 0, textAlign: 'center', opacity: t < 0.3 ? Easing.easeOutCubic(t/0.3) : t > 1.0 ? Easing.easeInCubic(clamp((1.4-t)/0.4, 0, 1)) : 1 }}>
        <div style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 20, color: '#F59E0B', letterSpacing: '0.16em', textTransform: 'uppercase' }}>diferenciador · IA personal</div>
      </div>}
      {t >= 1.0 && t < 4.5 && <LearningCurveV t={t - 1.0} />}
      {t >= 4.5 && t < 7.0 && <HookABV t={t - 4.5} />}
      {t >= 7.0 && t < 12.0 && <TrainYourAIV t={t - 7.0} />}
      <CueLayer t={t} cues={[
        { t: 1.0, end: 4.5,  es: 'Mejora con cada clip que publicas.',     en: 'Sharper with every clip you post.' },
        { t: 4.5, end: 7.0,  es: 'Y replica el hook que funcionó.',        en: 'And replays the hook that worked.' },
        { t: 7.0, end: 12.0, es: 'PRO+: una IA exclusiva para tu canal.',  en: 'PRO+: an AI dedicated to your channel.' },
      ]} />
    </div>
  );
}
function LearningCurveV({ t }) {
  const opacity = t < 0.3 ? t/0.3 : t > 4.0 ? Math.max(0, (4.5-t)/0.5) : 1;
  const points = 20;
  // Faster: complete by t=2.0
  const drawProgress = Math.min(1, t / 2.0);
  const xs = Array.from({ length: points }, (_, i) => 60 + (i/(points-1))*840);
  const ys = Array.from({ length: points }, (_, i) => { const x = i/(points-1); return 320 - Math.pow(x,0.5)*240 + Math.sin(i*1.7)*10; });
  // Smooth continuous draw with partial last segment
  const totalSeg = points - 1;
  const segF = drawProgress * totalSeg;
  const fullSeg = Math.floor(segF);
  const frac = segF - fullSeg;
  let path = '';
  let headX = xs[0], headY = ys[0];
  if (fullSeg < 1 && frac > 0) {
    headX = xs[0] + (xs[1]-xs[0])*frac;
    headY = ys[0] + (ys[1]-ys[0])*frac;
    path = `M${xs[0]} ${ys[0]} L${headX} ${headY}`;
  } else {
    for (let i = 0; i <= fullSeg; i++) { path += (i===0?'M':'L') + xs[i] + ' ' + ys[i] + ' '; headX = xs[i]; headY = ys[i]; }
    if (fullSeg < totalSeg && frac > 0) {
      const nx = xs[fullSeg] + (xs[fullSeg+1]-xs[fullSeg])*frac;
      const ny = ys[fullSeg] + (ys[fullSeg+1]-ys[fullSeg])*frac;
      path += `L${nx} ${ny}`; headX = nx; headY = ny;
    }
  }
  // Sin claims numéricos: solo curva visual relativa
  return (
    <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', opacity, padding: 60 }}>
      <div style={{ width: '100%', padding: 36, background: 'rgba(255,255,255,0.03)', border: '1px solid rgba(255,255,255,0.08)', borderRadius: 24 }}>
        <div style={{ marginBottom: 28, fontFamily: 'Inter, system-ui, sans-serif' }}>
          <div style={{ color: 'rgba(255,255,255,0.5)', fontSize: 18, letterSpacing: '0.08em', textTransform: 'uppercase', marginBottom: 8, fontFamily: 'JetBrains Mono, monospace' }}>Curva de aprendizaje</div>
          <div style={{ color: '#fff', fontSize: 56, fontWeight: 800, letterSpacing: '-0.025em', lineHeight: 1.05 }}>Cada clip que publicas,<br/><span style={{ color: '#F59E0B' }}>la IA mejora</span>.</div>
        </div>
        <svg width="900" height="380" style={{ display: 'block' }}>
          <defs><linearGradient id="curve-gv" x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stopColor="#EA580C" stopOpacity="0.35"/><stop offset="100%" stopColor="#EA580C" stopOpacity="0"/></linearGradient></defs>
          {[0,1,2,3,4].map(i => <line key={i} x1={60} x2={900} y1={80 + i*60} y2={80 + i*60} stroke="rgba(255,255,255,0.05)" />)}
          {drawProgress > 0.02 && <path d={path + ` L ${headX} 360 L ${xs[0]} 360 Z`} fill="url(#curve-gv)" />}
          <path d={path} fill="none" stroke="#EA580C" strokeWidth="4" strokeLinecap="round" strokeLinejoin="round" />
          {drawProgress > 0.02 && <circle cx={headX} cy={headY} r="9" fill="#F59E0B" stroke="#fff" strokeWidth="3" />}
          <text x={60} y={86} fill="rgba(255,255,255,0.4)" fontSize="18" fontFamily="JetBrains Mono, monospace" textAnchor="start">engagement</text>
          <text x={60} y={376} fill="rgba(255,255,255,0.4)" fontSize="18" fontFamily="JetBrains Mono, monospace">primer clip</text>
          <text x={900} y={376} fill="rgba(255,255,255,0.4)" fontSize="18" fontFamily="JetBrains Mono, monospace" textAnchor="end">tras meses</text>
        </svg>
      </div>
    </div>
  );
}
function ABSubsV({ t }) {
  const opacity = t < 0.3 ? t/0.3 : t > 5.0 ? Math.max(0, (5.5-t)/0.5) : 1;
  // Barras relativas (sin cifras absolutas).
  const b1 = Easing.easeOutCubic(clamp(t/1.5, 0, 1)) * 0.32;
  const b2 = Easing.easeOutCubic(clamp(t/2.0, 0, 1)) * 0.92;
  const winnerVisible = t > 2.5;
  return (
    <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', flexDirection: 'column', gap: 30, opacity, padding: 60 }}>
      <div style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 16, color: '#EA580C', letterSpacing: '0.06em', textAlign: 'center', textTransform: 'uppercase' }}>🔥 Estrategia dual YouTube + TikTok</div>
      <ABCardV label="A · YouTube Shorts" sub="limpio · sin subs" barW={b1} winner={false} bg="#0f0f0f" cleanClip />
      <ABCardV label="B · TikTok bold_pop" sub="grandes + alto contraste" barW={b2} winner={winnerVisible} bg="#0f0f0f" />
    </div>
  );
}
function ABCardV({ label, sub, barW, winner, bg, cleanClip }) {
  return (
    <div style={{ width: '100%', height: 280, background: bg, borderRadius: 20, border: winner ? '2px solid #EA580C' : '1px solid rgba(255,255,255,0.1)', position: 'relative', display: 'flex', alignItems: 'center', padding: 24, gap: 24, boxShadow: winner ? '0 0 60px rgba(234,88,12,0.4)' : 'none' }}>
      <div style={{ width: 180, height: 232, background: 'linear-gradient(135deg, #2a1810, #000)', borderRadius: 12, position: 'relative', overflow: 'hidden', flexShrink: 0 }}>
        <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          <div style={{ width: '70%', display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', gap: 2, height: 80 }}>
            {Array.from({ length: 14 }).map((_, i) => <div key={i} style={{ width: 5, height: 12 + Math.abs(Math.sin(i*0.5 + Date.now()/200))*50, background: 'rgba(245,158,11,0.5)', borderRadius: 2 }} />)}
          </div>
        </div>
        {!cleanClip ? (
          <div style={{ position: 'absolute', bottom: 20, left: '50%', transform: 'translateX(-50%) rotate(-2deg)', padding: '7px 12px', background: '#fff', color: '#000', fontFamily: 'Inter, system-ui, sans-serif', fontSize: 18, fontWeight: 900, letterSpacing: '-0.01em', textTransform: 'uppercase', borderRadius: 5, whiteSpace: 'nowrap' }}>¿QUÉ PASÓ?!</div>
        ) : (
          <div style={{ position: 'absolute', bottom: 20, left: '50%', transform: 'translateX(-50%)', padding: '4px 8px', background: 'rgba(255,255,255,0.92)', color: '#000', fontFamily: 'Inter, system-ui, sans-serif', fontSize: 12, fontWeight: 500, borderRadius: 3, whiteSpace: 'nowrap' }}>que pasó después...</div>
        )}
      </div>
      <div style={{ flex: 1, fontFamily: 'Inter, system-ui, sans-serif' }}>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12 }}>
          <div style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 16, color: '#F59E0B', letterSpacing: '0.06em', textTransform: 'uppercase' }}>{label}</div>
          {winner && <div style={{ fontSize: 13, padding: '4px 12px', background: '#EA580C', color: '#fff', borderRadius: 999, letterSpacing: '0.06em', fontFamily: 'JetBrains Mono, monospace', fontWeight: 700 }}>WINNER</div>}
        </div>
        {/* Barra relativa de engagement — sin claims numéricos */}
        <div style={{ width: '100%', height: 22, background: 'rgba(255,255,255,0.06)', borderRadius: 11, overflow: 'hidden' }}>
          <div style={{ width: `${barW * 100}%`, height: '100%', background: winner ? 'linear-gradient(90deg, #EA580C, #F59E0B)' : 'rgba(255,255,255,0.22)', borderRadius: 11, transition: 'width 200ms' }} />
        </div>
        <div style={{ fontSize: 18, color: 'rgba(255,255,255,0.55)', marginTop: 12 }}>{sub}</div>
      </div>
    </div>
  );
}
function HookABV({ t }) {
  const opacity = t < 0.3 ? t/0.3 : t > 4.0 ? Math.max(0, (4.5-t)/0.5) : 1;
  const showV2 = t > 1.0;
  const showResult = t > 2.5;
  return (
    <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', flexDirection: 'column', gap: 24, opacity, padding: 60 }}>
      <div style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 16, color: '#F59E0B', letterSpacing: '0.12em', textTransform: 'uppercase' }}>hooks · qué titular gana</div>
      <HookRowV version="V1" text="Aquí está el momento." barW={0.18} winner={false} />
      {showV2 && <HookRowV version="V2" text="¿Sabes qué pasó después?" barW={0.92} winner={true} />}
      {showResult && <div style={{ display: 'flex', alignItems: 'center', gap: 12, opacity: Math.min(1, (t-2.5)*3), padding: '14px 24px', background: 'rgba(234,88,12,0.1)', border: '1px solid rgba(234,88,12,0.3)', borderRadius: 999 }}>
        <span style={{ fontSize: 24 }}>💡</span>
        <span style={{ fontFamily: 'Inter, system-ui, sans-serif', fontSize: 22, color: '#F59E0B', fontWeight: 600 }}>Y lo replica automáticamente.</span>
      </div>}
    </div>
  );
}
function HookRowV({ version, text, barW, winner }) {
  return (
    <div style={{ width: '100%', padding: '24px 28px', background: winner ? 'rgba(234,88,12,0.08)' : 'rgba(255,255,255,0.02)', border: `1px solid ${winner ? 'rgba(234,88,12,0.4)' : 'rgba(255,255,255,0.08)'}`, borderRadius: 18, display: 'flex', flexDirection: 'column', gap: 14, fontFamily: 'Inter, system-ui, sans-serif' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
        <div style={{ padding: '8px 14px', background: winner ? '#EA580C' : 'rgba(255,255,255,0.06)', color: winner ? '#fff' : 'rgba(255,255,255,0.5)', borderRadius: 8, fontFamily: 'JetBrains Mono, monospace', fontSize: 15, fontWeight: 700 }}>{version}</div>
        <div style={{ flex: 1, fontSize: 26, fontWeight: 600, color: winner ? '#fff' : 'rgba(255,255,255,0.55)' }}>"{text}"</div>
        <div style={{ fontSize: 28 }}>{winner ? '✅' : '❌'}</div>
      </div>
      <div style={{ width: '100%', height: 14, background: 'rgba(255,255,255,0.06)', borderRadius: 7, overflow: 'hidden' }}>
        <div style={{ width: `${barW * 100}%`, height: '100%', background: winner ? 'linear-gradient(90deg, #EA580C, #F59E0B)' : 'rgba(255,255,255,0.18)', borderRadius: 7 }} />
      </div>
    </div>
  );
}

// ── Act 4 — Resultados ──────────────────────────────────────────────────────
function Act4ResultsV() {
  return <Sprite start={32.0} end={42.0}><Act4VInner /></Sprite>;
}
function Act4VInner() {
  const { localTime: t } = useSprite();
  return (
    <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(180deg, #0f0f0f 0%, #000 100%)', overflow: 'hidden' }}>
      <div style={{ position: 'absolute', top: 280, left: 0, right: 0, textAlign: 'center', opacity: t < 0.4 ? Easing.easeOutCubic(t/0.4) : t > 9 ? Easing.easeInCubic(clamp((9.5-t)/0.5, 0, 1)) : 1 }}>
        <div style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 18, color: '#F59E0B', letterSpacing: '0.16em', textTransform: 'uppercase', marginBottom: 12 }}>tres formas de usar Chispa</div>
        <div style={{ fontFamily: 'Inter, system-ui, sans-serif', fontSize: 64, fontWeight: 800, color: '#fff', letterSpacing: '-0.025em', padding: '0 60px', lineHeight: 1.1 }}>Un mismo motor IA. <span style={{ color: '#F59E0B' }}>Tres formatos</span>.</div>
      </div>
      {t >= 1.4 && t < 9.5 && <UseCasesV t={t - 1.4} />}
      {/* Act 4: no cue layer — visuals carry the message */}
    </div>
  );
}
function BigStatsV({ t }) {
  const opacity = t < 0.3 ? t/0.3 : t > 4.5 ? Math.max(0, (5.0-t)/0.5) : 1;
  const easeT = Math.min(1, t/2.5);
  const easeO = 1 - Math.pow(1-easeT, 3);
  const clips = (23.4*easeO).toFixed(1);
  const views = (1.2*easeO).toFixed(1);
  const tikTok = (4.7*easeO).toFixed(1);
  return (
    <div style={{ position: 'absolute', top: 320, left: 60, right: 60, display: 'flex', flexDirection: 'column', gap: 24, opacity }}>
      <div style={{ padding: 36, background: 'linear-gradient(135deg, rgba(234,88,12,0.12), rgba(245,158,11,0.04))', border: '1px solid rgba(234,88,12,0.25)', borderRadius: 26 }}>
        <div style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 14, color: '#F59E0B', letterSpacing: '0.12em', textTransform: 'uppercase', marginBottom: 12 }}>clips · 7 días</div>
        <div style={{ fontFamily: 'Inter, system-ui, sans-serif', fontSize: 180, fontWeight: 800, color: '#fff', letterSpacing: '-0.04em', lineHeight: 0.9, fontVariantNumeric: 'tabular-nums' }}>{clips}<span style={{ color: '#EA580C' }}>M</span></div>
        <div style={{ fontFamily: 'Inter, system-ui, sans-serif', fontSize: 22, color: 'rgba(255,255,255,0.5)', marginTop: 12 }}>generados desde directos</div>
      </div>
      <div style={{ display: 'flex', gap: 18 }}>
        <TickerCardV label="vistas total" value={views} suffix="B" delta="+147M" />
        <TickerCardV label="multi TikTok" value={tikTok} suffix="×" delta="vs genérica" highlight />
      </div>
    </div>
  );
}
function TickerCardV({ label, value, suffix, delta, highlight }) {
  return (
    <div style={{ flex: 1, padding: '24px 28px', background: highlight ? 'rgba(234,88,12,0.08)' : 'rgba(255,255,255,0.03)', border: `1px solid ${highlight ? 'rgba(234,88,12,0.3)' : 'rgba(255,255,255,0.08)'}`, borderRadius: 18, fontFamily: 'Inter, system-ui, sans-serif' }}>
      <div style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 13, color: 'rgba(255,255,255,0.5)', letterSpacing: '0.12em', textTransform: 'uppercase', marginBottom: 10 }}>{label}</div>
      <div style={{ fontSize: 72, fontWeight: 800, color: highlight ? '#F59E0B' : '#fff', letterSpacing: '-0.03em', fontVariantNumeric: 'tabular-nums', lineHeight: 1 }}>{value}<span style={{ color: highlight ? '#EA580C' : 'rgba(255,255,255,0.5)' }}>{suffix}</span></div>
      <div style={{ fontSize: 14, color: highlight ? '#EA580C' : 'rgba(34,197,94,0.85)', fontFamily: 'JetBrains Mono, monospace', marginTop: 8 }}>↑ {delta}</div>
    </div>
  );
}
function UseCasesV({ t }) {
  const opacity = t < 0.3 ? Easing.easeOutCubic(t / 0.3) : t > 8.5 ? Easing.easeInCubic(clamp((9.0 - t) / 0.5, 0, 1)) : 1;
  const cases = [
    { tag: '01', label: 'Clips personalizados', meta: 'el día a día',     desc: 'IA entrenada en TU canal. Gaming, deportes, podcast, comedy, lifestyle.', delay: 0.2 },
    { tag: '02', label: 'Recortar bruto',       meta: 'montaje · sin silencios', desc: 'Elimina silencios, voz de producción y tomas falladas. Pieza lista para entregar.', delay: 0.7 },
    { tag: '03', label: 'Highlights del directo', meta: '3 h → 5 min',     desc: 'Detecta los picos de un stream o podcast y los condensa sin perder el hilo.', delay: 1.2, highlight: true },
  ];
  return (
    <div style={{ position: 'absolute', top: 380, left: 60, right: 60, display: 'flex', flexDirection: 'column', gap: 20, opacity }}>
      {cases.map((c, i) => {
        const local = t - c.delay;
        const slide = Easing.easeOutCubic(clamp(local * 2.5, 0, 1));
        return (
          <div key={i} style={{ padding: 32, background: c.highlight ? 'linear-gradient(135deg, rgba(234,88,12,0.14), rgba(245,158,11,0.04))' : 'rgba(255,255,255,0.03)', border: `1px solid ${c.highlight ? 'rgba(234,88,12,0.4)' : 'rgba(255,255,255,0.08)'}`, borderRadius: 22, fontFamily: 'Inter, system-ui, sans-serif', transform: `translateY(${(1-slide)*30}px)`, opacity: local < 0 ? 0 : slide, display: 'flex', alignItems: 'center', gap: 28, boxShadow: c.highlight ? '0 12px 40px rgba(234,88,12,0.18)' : 'none' }}>
            <div style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 32, color: c.highlight ? '#F59E0B' : 'rgba(255,255,255,0.4)', fontWeight: 700, letterSpacing: '0.1em' }}>{c.tag}</div>
            <div style={{ flex: 1 }}>
              <div style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 16, color: 'rgba(255,255,255,0.4)', letterSpacing: '0.08em', textTransform: 'uppercase', fontWeight: 600, marginBottom: 6 }}>{c.meta}</div>
              <div style={{ fontSize: 40, fontWeight: 700, color: '#fff', letterSpacing: '-0.02em', marginBottom: 6, lineHeight: 1.1 }}>{c.label}</div>
              <div style={{ fontSize: 20, color: 'rgba(255,255,255,0.55)', lineHeight: 1.5 }}>{c.desc}</div>
            </div>
          </div>
        );
      })}
    </div>
  );
}

// ── Act 5 — CTA ─────────────────────────────────────────────────────────────
function Act5CTAV() {
  return <Sprite start={42.0} end={54.0}><Act5VInner /></Sprite>;
}
function Act5VInner() {
  const { localTime: t } = useSprite();
  const pulseScale = 1 + Math.sin(t*2)*0.02;
  return (
    <div style={{ position: 'absolute', inset: 0, background: 'radial-gradient(ellipse at center, #1a0a00 0%, #0f0f0f 80%)', overflow: 'hidden', opacity: Math.min(1, t/0.4) }}>
      {/* Logo top=260 (fuera de top safe-zone 220px) */}
      {t < 11 && (
        <div style={{ position: 'absolute', top: 260, left: 0, right: 0, textAlign: 'center', opacity: Math.min(1, t/0.5) }}>
          <div style={{ display: 'inline-flex', alignItems: 'center', gap: 18, transform: `scale(${pulseScale})` }}>
            <BoltSvgV size={84} />
            <div style={{ fontFamily: 'Inter, system-ui, sans-serif', fontSize: 84, fontWeight: 800, color: '#fff', letterSpacing: '-0.04em' }}>Chispa</div>
          </div>
        </div>
      )}
      {/* Headline */}
      {t > 0.4 && t < 11 && (
        <div style={{ position: 'absolute', top: 420, left: 60, right: 60, textAlign: 'center', opacity: Math.min(1, (t-0.4)/0.5) }}>
          <div style={{ fontFamily: 'Inter, system-ui, sans-serif', fontSize: 96, fontWeight: 800, color: '#fff', letterSpacing: '-0.035em', lineHeight: 1.0 }}>Genera tu primera <span style={{ color: '#F59E0B' }}>chispa.</span></div>
          <div style={{ fontFamily: 'Inter, system-ui, sans-serif', fontSize: 28, color: 'rgba(255,255,255,0.6)', marginTop: 24 }}>5 clips gratis. Sin tarjeta.</div>
        </div>
      )}
      {/* Pricing (PricingColV usa top=800) */}
      {t >= 1.5 && t < 11 && <PricingColV t={t - 1.5} />}
      {/* Closing tagline + compliance, fuera de bottom safe-zone 400px */}
      {t >= 5.5 && t < 11 && (
        <div style={{ position: 'absolute', bottom: 620, left: 60, right: 60, textAlign: 'center', opacity: Math.min(1, (t-5.5)/0.5), fontFamily: 'Inter, system-ui, sans-serif' }}>
          <div style={{ fontSize: 30, fontWeight: 700, color: '#fff', letterSpacing: '-0.02em', lineHeight: 1.2 }}>Tu IA, entrenada con <span style={{ color: '#F59E0B' }}>tu contenido</span>.</div>
          <div style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 16, color: 'rgba(255,255,255,0.4)', letterSpacing: '0.1em', textTransform: 'uppercase', marginTop: 14 }}>RGPD · ENS-BÁSICA · OWASP ASVS L2</div>
        </div>
      )}
      {/* CTA button — bottom=460 (justo por encima del bottom safe-zone) */}
      {t >= 3.0 && t < 11 && <CTAButtonV t={t - 3.0} />}
      {/* Domain — bottom=240 (dentro de bottom safe-zone donde TikTok superpone description: lo subimos arriba) */}
      {/* Eliminado: el wordmark Chispa de top ya transmite la marca. */}
      <CueLayer t={t} cues={[]} />
    </div>
  );
}
function PricingColV({ t }) {
  const tiers = [
    { name: 'Free', price: '€0', clips: '5 clips/mes', delay: 0.0, accent: 'rgba(255,255,255,0.5)' },
    { name: 'Creator', price: '€29', clips: '50 clips · YT + TT + IG', delay: 0.2, accent: '#F59E0B' },
    { name: 'Pro', price: '€79', clips: '200 clips · IA entrenada', delay: 0.4, accent: '#9061f9', highlight: true },
    { name: 'Studio', price: '€199', clips: 'ilimitado · editorial', delay: 0.6, accent: '#fff' },
  ];
  const proPulse = 0.5 + Math.sin(t*3)*0.5;
  return (
    <div style={{ position: 'absolute', top: 800, left: 60, right: 60, display: 'flex', flexDirection: 'column', gap: 12 }}>
      {tiers.map((tier, i) => {
        const local = t - tier.delay;
        if (local < 0) return null;
        const slide = Math.min(1, local*3);
        const ease = 1 - Math.pow(1-slide, 3);
        return (
          <div key={i} style={{ padding: '18px 26px', background: tier.highlight ? 'linear-gradient(135deg, rgba(144,97,249,0.14), rgba(234,88,12,0.06))' : 'rgba(255,255,255,0.03)', border: `${tier.highlight ? 2 : 1}px solid ${tier.highlight ? `rgba(144,97,249,${0.4 + proPulse*0.3})` : 'rgba(255,255,255,0.1)'}`, borderRadius: 18, fontFamily: 'Inter, system-ui, sans-serif', transform: `translateX(${(1-ease)*40}px)`, opacity: ease, boxShadow: tier.highlight ? `0 0 ${30 + proPulse*30}px rgba(144,97,249,${0.2 + proPulse*0.2})` : 'none', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
            <div>
              <div style={{ fontSize: 18, color: tier.accent, letterSpacing: '0.08em', textTransform: 'uppercase', fontWeight: 700, marginBottom: 4 }}>{tier.name}</div>
              <div style={{ fontSize: 18, color: 'rgba(255,255,255,0.7)' }}>{tier.clips}</div>
            </div>
            <div style={{ display: 'flex', alignItems: 'baseline', gap: 6 }}>
              <div style={{ fontSize: 44, fontWeight: 800, color: '#fff', letterSpacing: '-0.03em', lineHeight: 1 }}>{tier.price}</div>
              <div style={{ fontSize: 15, color: 'rgba(255,255,255,0.4)' }}>/mes</div>
            </div>
          </div>
        );
      })}
    </div>
  );
}
function CTAButtonV({ t }) {
  const opacity = Math.min(1, t/0.4);
  const pulse = 1 + Math.sin(t*4)*0.015;
  const glow = 0.5 + Math.sin(t*4)*0.5;
  return (
    <div style={{ position: 'absolute', bottom: 460, left: 0, right: 0, display: 'flex', justifyContent: 'center', opacity }}>
      <div style={{ padding: '26px 56px', background: 'linear-gradient(90deg, #EA580C, #F59E0B)', borderRadius: 16, fontFamily: 'Inter, system-ui, sans-serif', fontSize: 32, fontWeight: 700, color: '#fff', boxShadow: `0 0 ${40 + glow*40}px rgba(234,88,12,${0.4 + glow*0.3})`, transform: `scale(${pulse})` }}>
        Empezar gratis →
      </div>
    </div>
  );
}

window.Act1ProblemV = Act1ProblemV;
window.Act2SolutionV = Act2SolutionV;
window.Act3AIV = Act3AIV;
window.Act4ResultsV = Act4ResultsV;
// ── Act 3 PRO+ phase (vertical) ─────────────────────────────────────────────
function TrainYourAIV({ t }) {
  // 5s phase (paridad con desktop)
  const opacity = t < 0.4 ? Easing.easeOutCubic(t / 0.4) : t > 4.3 ? Easing.easeInCubic(clamp((4.8 - t) / 0.5, 0, 1)) : 1;
  const proPulse = 0.85 + Easing.easeInOutSine((Math.sin(t * 3) + 1) / 2) * 0.15;
  const traits = [
    { icon: '🎙️', label: 'Tu voz',         desc: 'humor, ritmo, muletillas' },
    { icon: '👥', label: 'Tu audiencia',    desc: 'qué responden tus fans' },
    { icon: '🚀', label: 'Lo que triunfa',  desc: 'replica los hooks que ganan' },
  ];
  return (
    <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', flexDirection: 'column', gap: 28, opacity, padding: '80px 60px' }}>
      <div style={{
        display: 'flex', alignItems: 'center', gap: 14,
        padding: '14px 26px',
        background: 'linear-gradient(90deg, rgba(144,97,249,0.18), rgba(234,88,12,0.12))',
        border: '2px solid rgba(144,97,249,0.5)',
        borderRadius: 999,
        fontFamily: 'JetBrains Mono, monospace',
        fontSize: 18,
        color: '#fff', letterSpacing: '0.18em', textTransform: 'uppercase', fontWeight: 700,
        boxShadow: `0 0 ${24 + proPulse*36}px rgba(144,97,249,${0.3 + proPulse*0.2})`,
        transform: `scale(${0.97 + proPulse*0.05})`,
      }}>
        <svg width="20" height="20" viewBox="0 0 100 100">
          <defs><linearGradient id="pro-seal-grad-v" x1="0" y1="0" x2="1" y2="1"><stop offset="0%" stopColor="#9061f9"/><stop offset="100%" stopColor="#F59E0B"/></linearGradient></defs>
          <path d="M55 8 L25 52 L48 52 L42 92 L75 42 L52 42 Z" fill="url(#pro-seal-grad-v)" />
        </svg>
        exclusivo plan PRO+
      </div>
      <div style={{ textAlign: 'center', maxWidth: 900 }}>
        <div style={{ fontFamily: 'Inter, system-ui, sans-serif', fontSize: 88, fontWeight: 800, color: '#fff', letterSpacing: '-0.03em', lineHeight: 1.05 }}>
          Una IA que <span style={{ background: 'linear-gradient(90deg, #9061f9, #F59E0B)', WebkitBackgroundClip: 'text', WebkitTextFillColor: 'transparent', backgroundClip: 'text' }}>conoce tu canal</span>.
        </div>
        <div style={{ fontFamily: 'Inter, system-ui, sans-serif', fontSize: 28, color: 'rgba(255,255,255,0.6)', marginTop: 18, lineHeight: 1.35, letterSpacing: '-0.005em' }}>
          Entrenada con tus vídeos, tus clips ganadores y la reacción real de tu audiencia.
        </div>
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 12, width: '100%' }}>
        {traits.map((tr, i) => {
          const delay = 0.3 + i*0.16;
          const local = t - delay;
          const slide = Math.max(0, Math.min(1, local*3));
          const ease = 1 - Math.pow(1-slide, 3);
          return (
            <div key={i} style={{
              padding: '20px 24px',
              background: 'rgba(144,97,249,0.06)',
              border: '1px solid rgba(144,97,249,0.25)',
              borderRadius: 16,
              fontFamily: 'Inter, system-ui, sans-serif',
              opacity: ease,
              transform: `translateX(${(1-ease)*30}px)`,
              display: 'flex', alignItems: 'center', gap: 22,
            }}>
              <div style={{ fontSize: 42, width: 64, textAlign: 'center', flexShrink: 0 }}>{tr.icon}</div>
              <div>
                <div style={{ fontSize: 26, fontWeight: 700, color: '#fff', letterSpacing: '-0.01em', marginBottom: 4 }}>{tr.label}</div>
                <div style={{ fontSize: 17, color: 'rgba(255,255,255,0.55)', lineHeight: 1.4 }}>{tr.desc}</div>
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

window.Act5CTAV = Act5CTAV;
