import { useEffect, useRef, useState } from 'react' /** * Scroll-in animation, matching the original page: fires once at 12% visibility * and then stops observing. The `.reveal` / `.is-visible` pair lives in CSS so * that `prefers-reduced-motion` can neutralise it in one place. */ export function useReveal() { const ref = useRef(null) const [visible, setVisible] = useState(false) useEffect(() => { const element = ref.current if (!element || visible) return const observer = new IntersectionObserver( (entries) => { for (const entry of entries) { if (!entry.isIntersecting) continue setVisible(true) observer.unobserve(entry.target) } }, { threshold: 0.12 }, ) observer.observe(element) return () => observer.disconnect() }, [visible]) return { ref, visible, revealClass: visible ? 'reveal is-visible' : 'reveal' } }