/* eslint-disable */ /* Hooks + utility components */ function useReveal() { const ref = React.useRef(null); React.useEffect(() => { const el = ref.current; if (!el) return; // 1) If already in (or near) the viewport on mount — mark visible immediately. const rect = el.getBoundingClientRect(); const vh = window.innerHeight || document.documentElement.clientHeight || 800; if (rect.top < vh + 80 && rect.bottom > -80) { el.classList.add('is-visible'); return; } // 2) Otherwise, observe. if (typeof IntersectionObserver === 'undefined') { el.classList.add('is-visible'); return; } const io = new IntersectionObserver((entries) => { entries.forEach((e) => { if (e.isIntersecting) { e.target.classList.add('is-visible'); io.unobserve(e.target); } }); }, { threshold: 0.1, rootMargin: '0px 0px -40px 0px' }); io.observe(el); // 3) Hard fallback: if for any reason IO never fires within 2.5s, force visible. const fallback = setTimeout(() => { el.classList.add('is-visible'); }, 2500); return () => { io.disconnect(); clearTimeout(fallback); }; }, []); return ref; } function Reveal({ as: Tag = 'div', delay = 0, className = '', style = {}, children, ...rest }) { const ref = useReveal(); const cls = `reveal ${className}`.trim(); return ( {children} ); } window.useReveal = useReveal; window.Reveal = Reveal;