// Componentes pequeños compartidos function Reveal({ children, delay = 0, as: As = 'div', className = '', ...rest }) { const ref = React.useRef(null); const [shown, setShown] = React.useState(false); React.useEffect(() => { const el = ref.current; if (!el) return; const r = el.getBoundingClientRect(); if (r.top < window.innerHeight && r.bottom > 0) { setShown(true); return; } const io = new IntersectionObserver((entries) => { entries.forEach((e) => { if (e.isIntersecting) { setShown(true); io.disconnect(); } }); }, { threshold: 0.05, rootMargin: '0px 0px -50px 0px' }); io.observe(el); return () => io.disconnect(); }, []); return ( {children} ); } function Badge({ children, dot, grad }) { return ( {dot && } {children} ); } function SectionLabel({ children }) { return
{children}
; } function Btn({ children, primary, warm, href = '#contacto', onClick, ...rest }) { const cls = primary ? 'btn btn-primary' : warm ? 'btn btn-warm' : 'btn'; return ( {children} ); } Object.assign(window, { Reveal, Badge, SectionLabel, Btn });