// Primitives — icons, small UI atoms const { useState, useEffect, useRef, useCallback, useMemo } = React; const Icon = ({ name, size = 16 }) => { const s = size; const stroke = { fill: 'none', stroke: 'currentColor', strokeWidth: 1.4, strokeLinecap: 'round', strokeLinejoin: 'round' }; switch (name) { case 'arrow': return (); case 'arrow-left': return (); case 'arrow-right': return (); case 'check': return (); case 'instagram': return (); case 'mail': return (); case 'phone': return (); case 'map': return (); case 'whatsapp': return (); default: return null; } }; const Reveal = ({ children, delay = 0, className = '' }) => { const ref = useRef(null); const [v, setV] = useState(false); useEffect(() => { if (typeof IntersectionObserver === 'undefined') { setV(true); return; } const el = ref.current; if (!el) { setV(true); return; } // If element is already in viewport on mount, reveal immediately const r = el.getBoundingClientRect(); const vh = window.innerHeight || document.documentElement.clientHeight; if (r.top < vh && r.bottom > 0) { setV(true); return; } const obs = new IntersectionObserver(([e]) => { if (e.isIntersecting) { setV(true); obs.disconnect(); } }, { threshold: 0, rootMargin: '0px 0px -80px 0px' }); obs.observe(el); // Safety fallback: always show after 1.2s const t = setTimeout(() => setV(true), 1200); return () => { obs.disconnect(); clearTimeout(t); }; }, []); return (