"use client"; import { motion, useMotionTemplate, useMotionValue, useSpring, useTransform } from "framer-motion"; import { ArrowRight, ShieldCheck } from "lucide-react"; import Image from "next/image"; import { useEffect, useState } from "react"; import { business } from "@/config/business"; import type { Messages } from "@/messages"; import PhysicsButton from "./PhysicsButton"; export default function HeroSection({ t, whatsappUrl }: { t: Messages; whatsappUrl: string }) { const [canAnimateIntro, setCanAnimateIntro] = useState(false); const pointerX = useMotionValue(0); const pointerY = useMotionValue(0); const smoothX = useSpring(pointerX, { stiffness: 90, damping: 22, mass: 0.4 }); const smoothY = useSpring(pointerY, { stiffness: 90, damping: 22, mass: 0.4 }); const rotateX = useTransform(smoothY, [-0.5, 0.5], [4, -4]); const rotateY = useTransform(smoothX, [-0.5, 0.5], [-5, 5]); const imageTransform = useMotionTemplate`perspective(1200px) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`; useEffect(() => { const reduced = window.matchMedia("(prefers-reduced-motion: reduce)").matches; const desktop = window.matchMedia("(min-width: 1024px)").matches; setCanAnimateIntro(desktop && !reduced); }, []); return (
{t.hero.eyebrow}

{t.hero.title}

{t.hero.subtitle}

{t.hero.primary} {t.hero.secondary}

{t.hero.note}

{ if (!canAnimateIntro) return; const bounds = event.currentTarget.getBoundingClientRect(); pointerX.set((event.clientX - bounds.left) / bounds.width - 0.5); pointerY.set((event.clientY - bounds.top) / bounds.height - 0.5); }} onPointerLeave={() => { pointerX.set(0); pointerY.set(0); }} style={canAnimateIntro ? { transform: imageTransform } : undefined} className="relative mx-auto w-full max-w-xl lg:max-w-none lg:will-change-transform" >
{t.hero.imageAlt}

{business.name}

Temara, Morocco

2011
); }