"use client"; /** * Cinematic section divider — a thin gradient rule that DRAWS itself across the * viewport (GSAP DrawSVG) as it scrolls into view, with a travelling node that * rides along it. Pure decoration; adds rhythm + "life" between sections so the * page never reads as empty stacked blocks. * Reduced-motion: renders fully drawn, no travel. */ import { useEffect, useRef } from "react"; import { gsap } from "./gsap"; export default function SectionDivider({ label }: { label?: string }) { const ref = useRef(null); useEffect(() => { const el = ref.current; if (!el) return; const reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches; if (reduce) return; const ctx = gsap.context(() => { const tl = gsap.timeline({ scrollTrigger: { trigger: el, start: "top 88%", once: true }, }); tl.from(".divider__line", { drawSVG: "50% 50%", duration: 1.2, ease: "power2.inOut", }) .from( ".divider__node", { scale: 0, transformOrigin: "center", duration: 0.5, ease: "back.out(2.2)" }, "-=0.4" ) .from( ".divider__label", { autoAlpha: 0, y: 8, filter: "blur(4px)", duration: 0.6, ease: "power2.out" }, "-=0.4" ); // node drifts gently along the line on scroll => parallax life gsap.to(".divider__node", { x: 120, ease: "none", scrollTrigger: { trigger: el, start: "top bottom", end: "bottom top", scrub: 1 }, }); }, el); return () => ctx.revert(); }, []); return ( ); }