// ============================================================ // BOT FLOW — Diseño anterior (timeline + stage), 8s por gatito. // Stacked slots para nunca quedar en blanco. // ============================================================ function BotFlow() { const [step, setStep] = React.useState(0); const [playing, setPlaying] = React.useState(true); const total = BOT_FLOW.length; const timerRef = React.useRef(null); React.useEffect(() => { CHARACTERS.forEach(c => { const i = new Image(); i.src = c.img; }); }, []); // 8 segundos por gatito React.useEffect(() => { if (!playing) return; clearTimeout(timerRef.current); timerRef.current = setTimeout(() => setStep(s => (s + 1) % total), 8000); return () => clearTimeout(timerRef.current); }, [step, playing, total]); const current = BOT_FLOW[step]; const host = CHARACTERS.find(c => c.id === current.host); const prevStep = (step - 1 + total) % total; const firstHost = CHARACTERS.find(c => c.id === BOT_FLOW[0].host); return (

Cómo funciona un bot

{/* TIMELINE */}
{BOT_FLOW.map((b, i) => { const h = CHARACTERS.find(c => c.id === b.host); const active = i === step; const done = i < step; return ( ); })}
{/* STAGE */}
{/* CHARACTERS COLUMN — stacked slots */}
{BOT_FLOW.map((b, i) => { const h = CHARACTERS.find(c => c.id === b.host); let state = "hidden"; if (i === step) state = "active"; else if (i === prevStep) state = "leaving"; return (
{h.name}
); })}
{host.tool} {host.name} {current.label}
{/* MESSAGE COLUMN */}
{BOT_FLOW.map((b, i) => { const h = CHARACTERS.find(c => c.id === b.host); let state = "hidden"; if (i === step) state = "active"; else if (i === prevStep) state = "leaving"; return (
{h.name} · paso {i + 1}/{total}

{b.title}

{b.line}

); })}
); } window.BotFlow = BotFlow;