/* Interactive phone mockup — mouse tracking 3D tilt + floating animation */ function InteractiveMockup({ src = 'assets/phones.png', alt = 'Mockup do app Copa no Shape' }) { const wrapRef = React.useRef(null); const innerRef = React.useRef(null); const [isHovered, setIsHovered] = React.useState(false); const targetRef = React.useRef({ rx: 0, ry: 0, tx: 0, ty: 0 }); const currentRef = React.useRef({ rx: 0, ry: 0, tx: 0, ty: 0 }); const rafRef = React.useRef(null); React.useEffect(() => { const loop = () => { const c = currentRef.current; const t = targetRef.current; const ease = 0.08; c.rx += (t.rx - c.rx) * ease; c.ry += (t.ry - c.ry) * ease; c.tx += (t.tx - c.tx) * ease; c.ty += (t.ty - c.ty) * ease; if (innerRef.current) { innerRef.current.style.transform = `perspective(1200px) rotateX(${c.rx}deg) rotateY(${c.ry}deg) translate3d(${c.tx}px, ${c.ty}px, 0)`; } rafRef.current = requestAnimationFrame(loop); }; rafRef.current = requestAnimationFrame(loop); return () => cancelAnimationFrame(rafRef.current); }, []); const handleMove = (e) => { if (!wrapRef.current) return; const rect = wrapRef.current.getBoundingClientRect(); const cx = rect.left + rect.width / 2; const cy = rect.top + rect.height / 2; const dx = (e.clientX - cx) / (rect.width / 2); const dy = (e.clientY - cy) / (rect.height / 2); targetRef.current = { rx: -dy * 10, ry: dx * 14, tx: dx * 6, ty: dy * 6, }; }; const handleLeave = () => { targetRef.current = { rx: 0, ry: 0, tx: 0, ty: 0 }; setIsHovered(false); }; return (