// scenes.jsx — Yohann Escher Motion 30s — v2 (cinematic) const ASSETS = { homem: 'https://imagedelivery.net/mYdfeAeRRdkIXG5w7XJhtQ/4107162a-97fa-4750-fcd6-b664090fd600/public', emaranhado: 'https://imagedelivery.net/mYdfeAeRRdkIXG5w7XJhtQ/d3218d34-0d91-4586-dab5-b2664d041700/public', cubo: 'https://imagedelivery.net/mYdfeAeRRdkIXG5w7XJhtQ/6895dfab-4fdb-4898-f8d8-0dbc8586ee00/public', cerebroPress: 'https://imagedelivery.net/mYdfeAeRRdkIXG5w7XJhtQ/41b16920-7e66-4aa9-f3a2-6789a7beda00/public', cerebro: 'https://imagedelivery.net/mYdfeAeRRdkIXG5w7XJhtQ/b653b8f9-354a-4901-3f85-daa03c10f800/public', cabecaProgresso: 'https://imagedelivery.net/mYdfeAeRRdkIXG5w7XJhtQ/511ab5bf-2760-4610-4b62-b27717353e00/public', cabecaCaos: 'https://imagedelivery.net/mYdfeAeRRdkIXG5w7XJhtQ/a3ef3c98-1613-4b2a-fe3f-deba90023d00/public', nucleo: 'https://imagedelivery.net/mYdfeAeRRdkIXG5w7XJhtQ/9fd367fc-ecdd-424e-930b-1867b4095700/public', }; const COLORS = { graphite: '#101214', graphiteDeep: '#0A0C0D', graphiteCard: '#191C1E', graphiteCard2: '#202325', offwhite: '#F7EFE6', cream: '#FFF8F0', orange: '#FF6B1A', orangeDeep: '#E9580C', orangeBright: '#FF8540', textLight: '#F7EFE6', textDark: '#1E2224', borderLight: 'rgba(255,255,255,0.12)', borderDark: '#E6D9C7', }; const FONT_SANS = '"Manrope", "Inter", system-ui, sans-serif'; const FONT_SERIF = '"Instrument Serif", "Cormorant Garamond", Georgia, serif'; const FONT_MONO = '"JetBrains Mono", ui-monospace, monospace'; // ═══════════════════════════════════════════════════════════════════════════ // BACKGROUND — animated, with grain & vignette // ═══════════════════════════════════════════════════════════════════════════ function SceneBackground() { const t = useTime(); let bg = COLORS.graphite; let dark = true; if (t >= 7 && t < 13) { bg = COLORS.offwhite; dark = false; } else if (t >= 13 && t < 16) { bg = COLORS.graphiteDeep; dark = true; } else if (t >= 16 && t < 20) { bg = COLORS.offwhite; dark = false; } else if (t >= 20 && t < 24) { bg = COLORS.graphite; dark = true; } else if (t >= 24 && t < 27) { bg = COLORS.cream; dark = false; } if (t >= 27) { const splitProgress = clamp((t - 27) / 0.6, 0, 1); const splitX = Easing.easeOutCubic(splitProgress) * 100; return (
); } return ( <>
); } function Vignette({ dark }) { return (
); } // ═══════════════════════════════════════════════════════════════════════════ // TRANSITIONS — dramatic // ═══════════════════════════════════════════════════════════════════════════ function CircularWipe({ start, fillColor = COLORS.orange, duration = 0.7 }) { const t = useTime(); if (t < start - 0.2 || t > start + duration + 0.4) return null; const phase1 = clamp((t - start) / duration, 0, 1); // expand const phase2 = clamp((t - start - duration) / 0.4, 0, 1); // shrink reveal const e1 = Easing.easeInOutCubic(phase1); const e2 = Easing.easeInOutCubic(phase2); const r1 = e1 * 2400; const r2 = e2 * 2400; return (
); } function FlashCut({ start, color = '#fff', duration = 0.18 }) { const t = useTime(); if (t < start || t > start + duration) return null; const local = (t - start) / duration; const opacity = local < 0.3 ? local / 0.3 : 1 - (local - 0.3) / 0.7; return (
); } function ScreenShake({ start, end, intensity = 8, children }) { const t = useTime(); const active = t >= start && t <= end; const shake = active ? { x: (Math.random() - 0.5) * intensity, y: (Math.random() - 0.5) * intensity } : { x: 0, y: 0 }; return (
{children}
); } // ═══════════════════════════════════════════════════════════════════════════ // KINETIC TYPOGRAPHY — words ripping across screen // ═══════════════════════════════════════════════════════════════════════════ function MarqueeText({ start, end, text, y, speed = 600, size = 120, color = COLORS.orange, italic = true, opacity = 1 }) { const t = useTime(); if (t < start || t > end) return null; const local = t - start; const x = 1920 - (local * speed); return (
{text}
); } // SplitText: word reveal with stagger and serif italic on accent function SplitHeadline({ words, x = 960, y = 540, size = 64, dark = true, align = 'center', accentColor = COLORS.orange }) { const { localTime, duration } = useSprite(); const exitDur = 0.4; const exitStart = duration - exitDur; return (
{words.map((w, i) => { const delay = i * 0.07; const entryT = clamp((localTime - delay) / 0.5, 0, 1); const e = Easing.easeOutCubic(entryT); let opacity = e; let ty = (1 - e) * 24; if (localTime > exitStart) { const ex = Easing.easeInCubic(clamp((localTime - exitStart) / exitDur, 0, 1)); opacity *= 1 - ex; ty -= ex * 12; } const isAccent = w.italic; return ( {w.text} ); })}
); } // ═══════════════════════════════════════════════════════════════════════════ // CHIPS & CARDS // ═══════════════════════════════════════════════════════════════════════════ function Chip({ label, x, y, dark = true, rot = 0, delay = 0, accent = false, size = 'md', icon, exitAt }) { const { localTime, duration } = useSprite(); const t = clamp((localTime - delay) / 0.45, 0, 1); const e = Easing.easeOutBack(t); let opacity = clamp(t * 1.4, 0, 1); let extraY = 0; let extraScale = 1; // Optional collapse-on-exit if (exitAt != null && localTime >= exitAt) { const ex = clamp((localTime - exitAt) / 0.5, 0, 1); const exE = Easing.easeInQuad(ex); opacity *= 1 - exE; extraScale = 1 - exE * 0.4; // suck toward center const cx = 960, cy = 540; extraY = 0; return (
{icon && {icon}} {label}
); } return (
{icon && {icon}} {label}
); } function HeroAsset({ src, x = 960, y = 540, size = 480, dark = true, rotate = 0, drift = 0, breathe = 0, kenBurns = 0 }) { const { localTime, progress } = useSprite(); const entry = clamp(localTime / 0.7, 0, 1); const e = Easing.easeOutCubic(entry); const breatheS = breathe ? 1 + Math.sin(localTime * 1.2) * breathe : 1; const kbS = kenBurns ? 1 + progress * kenBurns : 1; const scale = (0.92 + 0.08 * e) * breatheS * kbS; const opacity = e; const driftY = Math.sin(localTime * 1.0) * drift; return (
); } // Subtle moving grid background function TechGrid({ dark = true, opacity = 0.08 }) { const t = useTime(); const offset = (t * 30) % 80; return ( ); } // ═══════════════════════════════════════════════════════════════════════════ // SCENE 1 — 0–4s — Information overload — heavy chaos buildup // ═══════════════════════════════════════════════════════════════════════════ function Scene1() { const { localTime } = useSprite(); const chips = [ { label: 'ChatGPT', x: 360, y: 220, rot: -4, delay: 0.05 }, { label: 'Claude', x: 1560, y: 200, rot: 3, delay: 0.1 }, { label: 'Prompts', x: 240, y: 460, rot: 5, delay: 0.15, accent: true }, { label: 'Agentes', x: 1680, y: 480, rot: -3, delay: 0.2 }, { label: 'n8n', x: 320, y: 720, rot: 4, delay: 0.25 }, { label: 'APIs', x: 1620, y: 740, rot: -4, delay: 0.3 }, { label: 'RAG', x: 460, y: 880, rot: 2, delay: 0.35 }, { label: 'Embeddings', x: 1480, y: 900, rot: -3, delay: 0.4 }, { label: 'Tutoriais', x: 200, y: 600, rot: -3, delay: 0.45 }, { label: '+1 vídeo salvo', x: 1700, y: 620, rot: 4, delay: 0.5, accent: true }, { label: '+1 prompt', x: 540, y: 120, rot: -3, delay: 0.55 }, { label: '+1 ferramenta', x: 1380, y: 100, rot: 3, delay: 0.6, accent: true }, { label: 'MCP', x: 720, y: 940, rot: -2, delay: 0.65 }, { label: 'Cursor', x: 1240, y: 940, rot: 3, delay: 0.7 }, { label: 'LangChain', x: 180, y: 320, rot: -5, delay: 0.75 }, { label: 'Make', x: 1740, y: 340, rot: 4, delay: 0.8 }, ]; const camShake = localTime > 2.8 ? Math.sin(localTime * 60) * 3 : 0; return ( {/* Broken connector mess */} {[ 'M 360 220 L 700 380 L 540 500 L 800 600', 'M 1560 200 L 1300 400 L 1480 540 L 1200 660', 'M 240 460 L 600 600 L 380 780', 'M 1680 480 L 1320 620 L 1500 800', 'M 200 600 L 540 720 L 320 880', 'M 1740 340 L 1380 480', ].map((d, i) => { const t = clamp((localTime - 0.4 - i * 0.06) / 0.7, 0, 1); return ( ); })} {/* Pulsing chromatic aberration as chaos peaks */} {localTime > 2.5 && (
)} {chips.map((c, i) => )} {/* Marquee word "INFORMAÇÃO" passing through */}
); } // ═══════════════════════════════════════════════════════════════════════════ // SCENE 2 — 4–7s — Brain under pressure — orbit + glitch // ═══════════════════════════════════════════════════════════════════════════ function Scene2() { const { localTime } = useSprite(); const dots = Array.from({ length: 18 }, (_, i) => { const angle = (i / 18) * Math.PI * 2 + localTime * 0.7; const r = 320 + Math.sin(localTime * 2.5 + i) * 40; const x = 960 + Math.cos(angle) * r; const y = 480 + Math.sin(angle) * r * 0.7; const blink = (Math.sin(localTime * 5 + i * 1.3) + 1) / 2; return { x, y, blink, key: i }; }); const orbiters = [ { label: 'notif', x: 380, y: 260, rot: -3, delay: 0.15, icon: '●' }, { label: 'inbox', x: 1540, y: 280, rot: 3, delay: 0.3, icon: '●' }, { label: 'task', x: 360, y: 700, rot: 2, delay: 0.45, icon: '●' }, { label: 'TODO', x: 1560, y: 720, rot: -2, delay: 0.55, icon: '●' }, { label: 'pendente', x: 240, y: 480, rot: -4, delay: 0.65, accent: true }, { label: 'urgente', x: 1700, y: 500, rot: 4, delay: 0.75, accent: true }, ]; return ( <> {dots.map(d => (
))} {/* Lines feeding INTO brain (input) but never out */} {[ { from: [80, 200], to: [800, 460] }, { from: [1840, 200], to: [1120, 460] }, { from: [80, 760], to: [800, 480] }, { from: [1840, 760], to: [1120, 480] }, { from: [60, 480], to: [780, 480] }, { from: [1860, 480], to: [1140, 480] }, ].map((l, i) => { const dashOffset = -localTime * 60; return ( ); })} {orbiters.map((c, i) => )} ); } // ═══════════════════════════════════════════════════════════════════════════ // SCENE 3 — 7–10s — Inner chaos — head opens, fragments fly out // ═══════════════════════════════════════════════════════════════════════════ function Scene3() { const { localTime } = useSprite(); const items = ['Clareza', 'Método', 'Stack', 'Execução', 'Projeto']; // Floating fragments coming OUT of head const fragments = Array.from({ length: 14 }, (_, i) => { const baseAngle = -Math.PI / 2 + (i / 14 - 0.5) * Math.PI * 0.8; const dist = 80 + (i % 4) * 60 + localTime * 30; const x = 620 + Math.cos(baseAngle) * dist; const y = 380 + Math.sin(baseAngle) * dist - localTime * 40; const opacity = clamp(1 - (localTime - 0.5) * 0.2 - (i % 5) * 0.1, 0, 1); return { x, y, opacity, key: i, label: ['{}', '[]', '01', '<>', '⌘', '#'][i % 6] }; }); return ( <> {fragments.map(f => (
{f.label}
))} {/* Right column — cards lighting up sequentially */} {items.map((label, i) => { const delay = 0.4 + i * 0.18; const t = clamp((localTime - delay) / 0.6, 0, 1); const e = Easing.easeOutCubic(t); const lit = localTime >= delay + 0.4; return (
{label} {String(i + 1).padStart(2, '0')}
); })} {/* Failed line trying to connect */} ); } // ═══════════════════════════════════════════════════════════════════════════ // SCENE 4 — 10–13s — The reset cycle // ═══════════════════════════════════════════════════════════════════════════ function Scene4() { const { localTime } = useSprite(); const cycle = (localTime % 1.3) / 1.3; const progress = cycle < 0.85 ? Easing.easeOutQuad(cycle / 0.85) * 0.95 : (1 - (cycle - 0.85) / 0.15) * 0.12; const pct = Math.floor(progress * 100); const resetting = cycle >= 0.85; const microTexts = [ { text: 'vou estudar mais um pouco', x: 360, y: 300, delay: 0.2 }, { text: 'só falta entender essa ferramenta', x: 1500, y: 260, delay: 0.5 }, { text: 'depois eu começo', x: 320, y: 720, delay: 0.9 }, { text: 'preciso ver mais um tutorial', x: 1520, y: 760, delay: 1.3 }, { text: 'amanhã eu foco de verdade', x: 960, y: 200, delay: 1.7 }, ]; return ( <> {/* Progress bar with reset flash */}
{pct.toString().padStart(2, '0')}% {resetting && ↺ reset}
100%
{microTexts.map((m, i) => { const t = clamp((localTime - m.delay) / 0.4, 0, 1); const fadeOut = clamp((localTime - m.delay - 1.2) / 0.4, 0, 1); return (
"{m.text}"
); })} ); } // ═══════════════════════════════════════════════════════════════════════════ // SCENE 5 — 13–16s — TANGLE — climax. tools trapped, dramatic // ═══════════════════════════════════════════════════════════════════════════ function Scene5() { const { localTime } = useSprite(); const rot = localTime * 6; const trapped = [ { label: 'IA', x: 540, y: 360, delay: 0.3 }, { label: 'Conteúdo', x: 1380, y: 340, delay: 0.4 }, { label: 'Automação', x: 500, y: 720, delay: 0.5 }, { label: 'Código', x: 1420, y: 700, delay: 0.6 }, { label: 'Dados', x: 720, y: 200, delay: 0.7 }, { label: 'Vendas', x: 1200, y: 880, delay: 0.8 }, ]; // Stuck dot trying to escape const dotAngle = localTime * 1.2; const dotR = 220 + Math.sin(localTime * 3) * 50; const dotX = 960 + Math.cos(dotAngle * 1.3) * dotR; const dotY = 540 + Math.sin(dotAngle * 2.1) * dotR * 0.7; // Big background word const bgWordOpacity = clamp((localTime - 0.2) / 0.5, 0, 1) * 0.06; return ( <> {/* Massive background word */}
CAOS
{/* Spotlight on tangle */}
{/* Stuck dot with trail */}
{trapped.map((c, i) => )} {/* Text 1: "Não é falta de ferramenta." appears, then gets struck through */} {/* Text 2: huge dramatic "É falta de ESTRUTURA" */} ); } function StrikethroughLine() { const { localTime, duration } = useSprite(); const e = Easing.easeOutCubic(clamp(localTime / 0.4, 0, 1)); const strike = clamp((localTime - 0.9) / 0.3, 0, 1); const exit = clamp((localTime - duration + 0.4) / 0.4, 0, 1); return (
Não é falta de ferramenta.
); } function BigImpactText() { const { localTime } = useSprite(); const e = Easing.easeOutBack(clamp(localTime / 0.5, 0, 1)); return (
É falta de{' '} estrutura .
); } // ═══════════════════════════════════════════════════════════════════════════ // SCENE 6 — 16–20s — Architecture forms // ═══════════════════════════════════════════════════════════════════════════ function Scene6() { const { localTime } = useSprite(); const labels = [ { label: 'Fundamentos', angle: 0 }, { label: 'Prompting', angle: 36 }, { label: 'Claude Code', angle: 72 }, { label: 'Automações', angle: 108 }, { label: 'Agentes', angle: 144 }, { label: 'APIs', angle: 180 }, { label: 'Sistemas', angle: 216 }, { label: 'Conteúdo', angle: 252 }, { label: 'Produto', angle: 288 }, { label: 'Execução', angle: 324 }, ]; return ( <> {/* Animated grid drawing in */} {Array.from({ length: 20 }).map((_, i) => { const t = clamp((localTime - 0.1 - i * 0.02) / 0.5, 0, 1); return ( ); })} {Array.from({ length: 12 }).map((_, i) => { const t = clamp((localTime - 0.2 - i * 0.025) / 0.5, 0, 1); return ( ); })} {labels.map((l, i) => { const delay = 0.5 + i * 0.09; const t = clamp((localTime - delay) / 0.5, 0, 1); const e = Easing.easeOutBack(t); const rad = (l.angle * Math.PI) / 180; const r = 400; const x = 960 + Math.cos(rad) * r; const y = 500 + Math.sin(rad) * r * 0.85; return (
{l.label}
); })} {/* Lines from cube to each label */} {labels.map((l, i) => { const delay = 0.5 + i * 0.09 + 0.3; const t = clamp((localTime - delay) / 0.4, 0, 1); const rad = (l.angle * Math.PI) / 180; const r = 400; const x = 960 + Math.cos(rad) * r; const y = 500 + Math.sin(rad) * r * 0.85; const cx = 960 + Math.cos(rad) * 220; const cy = 500 + Math.sin(rad) * 220 * 0.85; const tx = cx + (x - cx) * t; const ty = cy + (y - cy) * t; return ( ); })} ); } // ═══════════════════════════════════════════════════════════════════════════ // SCENE 7 — 20–24s — Steps lighting + flow // ═══════════════════════════════════════════════════════════════════════════ function Scene7() { const { localTime } = useSprite(); const steps = [ 'Entender IA', 'Prompts com intenção', 'Usar Claude Code', 'Automatizar fluxos', 'Criar agentes', 'Construir sistemas', 'Aplicar em marketing', 'Transformar em oportunidade', ]; return ( <> {/* Side brain (organized, lateral) */}
{/* Steps stack with active sweep */}
{steps.map((s, i) => { const delay = 0.2 + i * 0.16; const t = clamp((localTime - delay) / 0.45, 0, 1); const e = Easing.easeOutCubic(t); const active = localTime >= delay && localTime <= delay + 0.9; const done = localTime > delay + 0.9; return (
{String(i + 1).padStart(2, '0')}
{s} {done && ( )}
); })}
); } function MiniFlow() { const { localTime } = useSprite(); const steps = ['Ideia', 'Prompt', 'Código', 'Automação', 'Sistema', 'Resultado']; const W = 1300; const stepW = W / (steps.length - 1); const startX = (1920 - W) / 2; const dotProgress = clamp(localTime / 1.6, 0, 1); const dotE = Easing.easeInOutCubic(dotProgress); const dotX = startX + dotE * W; return ( <> {steps.map((s, i) => { const x = startX + i * stepW; const reached = dotX >= x - 5; return (
{s}
); })}
); } // ═══════════════════════════════════════════════════════════════════════════ // SCENE 8 — 24–27s — Nucleus // ═══════════════════════════════════════════════════════════════════════════ function Scene8() { const { localTime } = useSprite(); const pulse = 1 + Math.sin(localTime * 3) * 0.04; const modules = [ { label: 'Estratégia', angle: -90 }, { label: 'IA', angle: -30 }, { label: 'Automação', angle: 30 }, { label: 'Software', angle: 90 }, { label: 'Marketing', angle: 150 }, { label: 'Dados', angle: 210 }, ]; return ( <> {/* Soft radial gradient glow */}
{/* Concentric pulse rings */} {[0, 0.4, 0.8].map((offset, i) => { const phase = ((localTime + offset) % 1.2) / 1.2; const r = 200 + phase * 320; const op = (1 - phase) * 0.4; return (
); })} {modules.map((m, i) => { const delay = 0.3 + i * 0.12; const t = clamp((localTime - delay) / 0.6, 0, 1); const e = Easing.easeOutBack(t); const rad = (m.angle * Math.PI) / 180; const r = 380; const x = 960 + Math.cos(rad) * r; const y = 480 + Math.sin(rad) * r * 0.85; return (
{m.label}
); })} {modules.map((m, i) => { const delay = 0.3 + i * 0.12; const t = clamp((localTime - delay - 0.4) / 0.5, 0, 1); const rad = (m.angle * Math.PI) / 180; const r = 380; const x = 960 + Math.cos(rad) * r; const y = 480 + Math.sin(rad) * r * 0.85; const dashPos = -localTime * 30; return ( ); })} ); } // ═══════════════════════════════════════════════════════════════════════════ // SCENE 9 — 27–30s — Final // ═══════════════════════════════════════════════════════════════════════════ function Scene9() { const { localTime } = useSprite(); const pulse = 1 + Math.sin(localTime * 2.5) * 0.03; const results = [ { label: 'clareza', x: 360, y: 280, delay: 0.3, side: 'dark' }, { label: 'projetos', x: 1560, y: 260, delay: 0.4, side: 'light' }, { label: 'automações', x: 300, y: 540, delay: 0.5, side: 'dark' }, { label: 'agentes', x: 1620, y: 540, delay: 0.6, side: 'light' }, { label: 'sistemas', x: 360, y: 800, delay: 0.7, side: 'dark' }, { label: 'execução', x: 1560, y: 800, delay: 0.8, side: 'light' }, ]; return ( <> {/* Cube faded behind */}
{/* Nucleus */}
{/* Connector lines */} {results.map((r, i) => { const t = clamp((localTime - r.delay - 0.3) / 0.6, 0, 1); return ( ); })} {results.map((r, i) => { const t = clamp((localTime - r.delay) / 0.5, 0, 1); const e = Easing.easeOutBack(t); const onDark = r.side === 'dark'; return (
{r.label}
); })} ); } function FinalText({ text, accent, post }) { const { localTime } = useSprite(); const t = clamp(localTime / 0.4, 0, 1); const e = Easing.easeOutCubic(t); return (
{text} {accent && ( {accent} )} {post}
); } function CTA() { const { localTime } = useSprite(); const t = clamp(localTime / 0.5, 0, 1); const e = Easing.easeOutBack(t); const glow = 0.5 + Math.sin(localTime * 4) * 0.3; const tweaks = (typeof window !== 'undefined' && window.__tweaks) || {}; const label = tweaks.ctaLabel || 'Entrar na mentoria'; const accent = tweaks.accentColor || COLORS.orange; return (
{label}
); } // ═══════════════════════════════════════════════════════════════════════════ // CROSS-SCENE KINETIC OVERLAY — Words sweeping the entire timeline // ═══════════════════════════════════════════════════════════════════════════ function KineticOverlay() { return ( <> {/* SCENE 5 lead-in — big tension words flying */} {/* SCENE 6 reveal word */} {/* SCENE 7 momentum */} {/* SCENE 8 build */} {/* SCENE 9 finale ribbon */} ); } // ═══════════════════════════════════════════════════════════════════════════ // TIME LABEL // ═══════════════════════════════════════════════════════════════════════════ function TimeLabel() { const t = useTime(); React.useEffect(() => { const sec = Math.floor(t); const stage = document.querySelector('[data-screen-label]'); if (stage) stage.setAttribute('data-screen-label', `${sec}s`); }, [Math.floor(t)]); return null; } // ═══════════════════════════════════════════════════════════════════════════ // MAIN // ═══════════════════════════════════════════════════════════════════════════ function MotionVideo({ tweaks }) { return (
{/* Dramatic transitions */} {/* Brand mark */}
YOHANN ESCHER · MENTORIA
{/* Time code badge */} {/* Grain overlay */}
); } function TimeCode() { const t = useTime(); return (
REC  {t.toFixed(2).padStart(5, '0')}s / 30.00s
); } Object.assign(window, { MotionVideo, COLORS, ASSETS, FONT_SANS, FONT_SERIF });