/* Site-wide micro-interaction layer: custom cursor, scroll progress, magnetic buttons, card tilt, ripple clicks, count-up numbers. All opt out under prefers-reduced-motion. */ const NO_MOTION = () => typeof window.matchMedia === 'function' && window.matchMedia('(prefers-reduced-motion: reduce)').matches; function CursorHalo() { const dot = React.useRef(null), ring = React.useRef(null); React.useEffect(() => { if (NO_MOTION() || window.matchMedia('(pointer: coarse)').matches) return; let x = innerWidth / 2, y = innerHeight / 2, rx = x, ry = y, raf = 0; const move = (e) => { x = e.clientX; y = e.clientY; }; const over = (e) => { const hit = e.target.closest('a,button,[data-cursor="grow"]'); if (ring.current) ring.current.toggleAttribute('data-grow', !!hit); }; const loop = () => { raf = requestAnimationFrame(loop); rx += (x - rx) * 0.16; ry += (y - ry) * 0.16; if (dot.current) dot.current.style.transform = 'translate3d(' + x + 'px,' + y + 'px,0)'; if (ring.current) ring.current.style.transform = 'translate3d(' + rx + 'px,' + ry + 'px,0)'; }; loop(); window.addEventListener('pointermove', move, { passive: true }); window.addEventListener('pointerover', over, { passive: true }); document.documentElement.setAttribute('data-cursor-on', ''); return () => { cancelAnimationFrame(raf); window.removeEventListener('pointermove', move); window.removeEventListener('pointerover', over); document.documentElement.removeAttribute('data-cursor-on'); }; }, []); return (<>