"use client"; import { useEffect, useRef, useState, type CSSProperties, type ReactNode } from "react"; type RevealProps = { children: ReactNode; className?: string; /** Verzögerung in Sekunden (für Stagger) */ delay?: number; y?: number; }; /** * Leichte Scroll-Reveal-Variante ohne ScrollTrigger. IntersectionObserver * verursacht keine fortlaufende Scroll-Arbeit und lädt keine GSAP-Plugins. */ export default function Reveal({ children, className, delay = 0, y = 30, }: RevealProps) { const ref = useRef(null); const [visible, setVisible] = useState(false); useEffect(() => { const element = ref.current; if (!element) return; const reducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)"); if (reducedMotion.matches || !window.IntersectionObserver) { const frame = window.requestAnimationFrame(() => setVisible(true)); return () => window.cancelAnimationFrame(frame); } const observer = new IntersectionObserver( ([entry]) => { if (entry.isIntersecting) { setVisible(true); observer.disconnect(); } }, { rootMargin: "0px 0px -12%" }, ); observer.observe(element); return () => observer.disconnect(); }, []); return (
{children}
); }