'use client'; import { motion, useScroll, useSpring } from 'framer-motion'; import { usePrefersReducedMotion } from '@/lib/motion'; // One continuous gold line running the height of the page, drawing itself as // the reader scrolls. It is the spine of the layout: it stitches the sections // together so the landing reads as a route rather than a stack of blocks. // // Positioned `absolute`, never `fixed` — the thread belongs to the document // and scrolls with it. A fixed layer would read as an ornament stuck to the // window. // // Uses the page-level useScroll() with no target ref on purpose: no element // measuring, no "container has a static position" warnings, and one scroll // listener for the whole page. const TRAZO = 'M50 0 C 20 140, 80 260, 50 400 C 20 540, 80 660, 50 800 C 20 940, 80 1060, 50 1200'; export function HiloConductor({ className = '' }: { className?: string }) { const reduced = usePrefersReducedMotion(); const { scrollYProgress } = useScroll(); const avance = useSpring(scrollYProgress, { stiffness: 90, damping: 30, restDelta: 0.001 }); const base = `pointer-events-none absolute inset-y-0 left-1/2 -translate-x-1/2 w-full max-w-content h-full ${className}`; // The positioning/pointer-events classes live on a wrapping
rather // than the itself: per spec `SVGElement.className` is an // SVGAnimatedString, not a plain string, so tests (and any other reader of // `.className`) can't inspect it as text. A plain HTMLElement keeps that // contract simple. // Plain for reduced motion: motion.path applies dash scaffolding even // without initial/animate and would leave the thread invisible. if (reduced) { return (
); } return (
); }