"use client"; /** * Magnetic wrapper: the child is pulled toward the cursor while hovered, * then springs back on leave. Transform-only (GPU). No-op on coarse pointers * and with prefers-reduced-motion, so keyboard/touch users get a static, * fully-clickable element. */ import { useRef } from "react"; import { motion, useMotionValue, useSpring } from "motion/react"; export default function Magnetic({ children, strength = 0.4, className, }: { children: React.ReactNode; strength?: number; className?: string; }) { const ref = useRef(null); const x = useMotionValue(0); const y = useMotionValue(0); const sx = useSpring(x, { stiffness: 250, damping: 18, mass: 0.4 }); const sy = useSpring(y, { stiffness: 250, damping: 18, mass: 0.4 }); const onMove = (e: React.PointerEvent) => { if (e.pointerType !== "mouse") return; if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return; const el = ref.current; if (!el) return; const r = el.getBoundingClientRect(); x.set((e.clientX - (r.left + r.width / 2)) * strength); y.set((e.clientY - (r.top + r.height / 2)) * strength); }; const reset = () => { x.set(0); y.set(0); }; return ( {children} ); }