"use client"; import { useEffect, useRef, useState, type CSSProperties, type ReactNode } from "react"; /** * Wraps content and reveals it (via the `is-visible` class) when it scrolls into * view. Pair with the `.reveal` or `.reveal-stagger` CSS classes. Respects * prefers-reduced-motion (CSS forces content visible there). */ export function Reveal({ children, className = "", style, id, }: { children: ReactNode; className?: string; style?: CSSProperties; id?: string; }) { const ref = useRef(null); const [visible, setVisible] = useState(false); useEffect(() => { const el = ref.current; if (!el) return; if (typeof IntersectionObserver === "undefined") { setVisible(true); return; } const obs = new IntersectionObserver( (entries) => { entries.forEach((e) => { if (e.isIntersecting) { setVisible(true); obs.disconnect(); } }); }, { threshold: 0.12, rootMargin: "0px 0px -8% 0px" } ); obs.observe(el); return () => obs.disconnect(); }, []); return (
{children}
); }