"use client"; import type { ReactNode } from "react"; import { motion, useMotionTemplate, useMotionValue, useReducedMotion, useSpring, useTransform, } from "motion/react"; type TiltCraftProps = { children: ReactNode; className?: string; /** Largest tilt in degrees. */ max?: number; /** Soft light that follows the pointer over the card. */ glare?: boolean; }; const SPRING = { stiffness: 220, damping: 20 }; /* TiltCraft: the card tilts toward the pointer in 3D and springs flat when it leaves. */ export function TiltCraft({ children, className = "rounded-2xl border border-white/10 bg-[#16132a] p-6 text-white", max = 12, glare = true, }: TiltCraftProps) { const reduce = useReducedMotion(); const px = useMotionValue(0.5); const py = useMotionValue(0.5); const rotateX = useSpring(useTransform(py, [0, 1], [max, -max]), SPRING); const rotateY = useSpring(useTransform(px, [0, 1], [-max, max]), SPRING); const glareOpacity = useSpring(0, SPRING); const gx = useTransform(px, (v) => `${v * 100}%`); const gy = useTransform(py, (v) => `${v * 100}%`); const glareBg = useMotionTemplate`radial-gradient(circle at ${gx} ${gy}, rgba(255,255,255,0.22), transparent 55%)`; const onMove = (e: React.PointerEvent) => { if (reduce) return; const r = e.currentTarget.getBoundingClientRect(); px.set((e.clientX - r.left) / r.width); py.set((e.clientY - r.top) / r.height); glareOpacity.set(1); }; const onLeave = () => { px.set(0.5); py.set(0.5); glareOpacity.set(0); }; return ( {children} {glare && ( )} ); }