// interactive.jsx. Pool calculator, checkout flow, animated counters const { useState, useEffect, useRef, useMemo } = React; /* ────────────────────────────────────────────────────────────── AnimatedNumber. counts up to target when in view ────────────────────────────────────────────────────────────── */ function AnimatedNumber({ value, prefix = "", suffix = "", duration = 1200, decimals = 0, format }) { const [n, setN] = useState(0); const ref = useRef(null); const startedRef = useRef(false); useEffect(() => { const el = ref.current; if (!el) return; const io = new IntersectionObserver((entries) => { entries.forEach((e) => { if (e.isIntersecting && !startedRef.current) { startedRef.current = true; const t0 = performance.now(); const step = (t) => { const p = Math.min(1, (t - t0) / duration); const eased = 1 - Math.pow(1 - p, 3); setN(value * eased); if (p < 1) requestAnimationFrame(step); else setN(value); }; requestAnimationFrame(step); } }); }, { threshold: 0.4 }); io.observe(el); return () => io.disconnect(); }, [value, duration]); const display = format ? format(n) : n.toFixed(decimals); return {prefix}{display}{suffix}; } /* ────────────────────────────────────────────────────────────── PoolCalculator. interactive widget in the hero ────────────────────────────────────────────────────────────── */ function PoolCalculator({ onCta, variant = "vertical" }) { const [amount, setAmount] = useState(500); const fmtUSD = (v) => v.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 }); const periods = [ { rate: 0.01, period: "/ dia", label: "1%" }, { rate: 0.07, period: "/ Mês", label: "7%" }, { rate: 0.33, period: "/ ano", label: "33%" }, ]; const chips = [100, 500, 1000, 5000]; return (
Simulador de pool ao vivo
$ setAmount(Math.max(0, Number(e.target.value) || 0))} inputMode="decimal" />
{chips.map((c) => ( ))}
{periods.map((p, i) => (
{p.label} {p.period} ${fmtUSD(amount * p.rate)}
))}

Simulação ilustrativa. Taxas de pool variam por liquidez, par e momento de mercado. Não é garantia de rendimento.

Quero montar minha pool →
); } function buildSpark() { return ""; } // legacy, unused after refactor /* ────────────────────────────────────────────────────────────── CheckoutModal. multi-step simulated flow ────────────────────────────────────────────────────────────── */ function CheckoutModal({ onClose }) { const [step, setStep] = useState(0); // 0 method, 1 details, 2 success const [method, setMethod] = useState("card"); const [loading, setLoading] = useState(false); useEffect(() => { const onKey = (e) => { if (e.key === "Escape") onClose(); }; window.addEventListener("keydown", onKey); document.body.style.overflow = "hidden"; return () => { window.removeEventListener("keydown", onKey); document.body.style.overflow = ""; }; }, [onClose]); const next = () => setStep((s) => s + 1); const submit = (e) => { e.preventDefault(); setLoading(true); setTimeout(() => { setLoading(false); setStep(2); }, 1100); }; return (
{ if (e.target === e.currentTarget) onClose(); }}>

Entrar no Método DTD

= 0 ? (step > 0 ? "done" : "active") : ""}`} />
= 1 ? (step > 1 ? "done" : "active") : ""}`} />
= 2 ? "active" : ""}`} />
{step === 0 && ( <>
Escolha a forma de pagamento
R$ 867,35 à vista · ou 12x de R$ 89,70.
🔒 Pagamento seguro Garantia 7 dias
)} {step === 1 && (
Seus dados
Acesso será liberado nesse e-mail.
{method === "card" && ( <>
)}
)} {step === 2 && (
Bem-vindo ao Método DTD
Esse é apenas um protótipo. Em produção, aqui você cairia na área de membros, com acesso imediato às aulas e ao grupo VIP no WhatsApp.
)}
); } /* ────────────────────────────────────────────────────────────── FAQ. accordion with single-open behavior ────────────────────────────────────────────────────────────── */ function FAQ({ items }) { const [open, setOpen] = useState(0); return (
{items.map((it, i) => (
{it.a}
))}
); } /* ────────────────────────────────────────────────────────────── Reveal on scroll helper ────────────────────────────────────────────────────────────── */ function useReveal() { useEffect(() => { const els = document.querySelectorAll(".reveal"); const io = new IntersectionObserver((entries) => { entries.forEach((e) => { if (e.isIntersecting) { e.target.classList.add("visible"); io.unobserve(e.target); } }); }, { threshold: 0.1 }); els.forEach((el) => io.observe(el)); return () => io.disconnect(); }, []); } /* expose to global */ Object.assign(window, { AnimatedNumber, PoolCalculator, CheckoutModal, FAQ, useReveal, FallingPattern }); /* ────────────────────────────────────────────────────────────── FallingPattern — subtle "falling code" backdrop Pure CSS animation (keyframes in styles.css), no framer-motion. ────────────────────────────────────────────────────────────── */ function FallingPattern({ color = "var(--accent)", bgColor = "var(--bg)", duration = 200, blur = "1em", density = 1.4 }) { const bgImage = useMemo(() => { const lines = []; const rowYs = [ [235, 117.5], [252, 126], [150, 75], [253, 126.5], [204, 102], [134, 67], [179, 89.5], [299, 149.5], [215, 107.5], [281, 140.5], [158, 79], [210, 105], ]; rowYs.forEach(([streak, dot]) => { lines.push(`radial-gradient(4px 100px at 0px ${streak}px, ${color}, transparent)`); lines.push(`radial-gradient(4px 100px at 300px ${streak}px, ${color}, transparent)`); lines.push(`radial-gradient(1.5px 1.5px at 150px ${dot}px, ${color} 100%, transparent 150%)`); }); return lines.join(", "); }, [color]); const bgSizes = useMemo(() => { const sizes = [235, 252, 150, 253, 204, 134, 179, 299, 215, 281, 158, 210]; return sizes.flatMap((h) => [`300px ${h}px`, `300px ${h}px`, `300px ${h}px`]).slice(0, 35).join(", "); }, []); return (
); }