"use client";
import { Fragment, useRef, type MouseEvent } from "react";
import Image from "next/image";
import Link from "next/link";
import { motion, useReducedMotion, useMotionValue, useSpring, useTransform } from "framer-motion";
import { MaterialIcon } from "@/components/ui/MaterialIcon";
import { MagneticButton } from "@/components/ui/MagneticButton";
import { HeroLogo } from "@/components/heroes/HeroLogo";
import { viewport } from "@/lib/animations";
const EASE = [0.22, 1, 0.36, 1] as [number, number, number, number];
// power4.out approximation, matches HeroLogo's entrance ease
const EASE_LOGO = [0.16, 1, 0.3, 1] as [number, number, number, number];
// 1. Verified Store SVG
function VerifiedStoreSVG({ reduce = false }: { reduce?: boolean }) {
return (
);
}
// 2. Neighborhood Pin SVG
function NeighborhoodPinSVG({ reduce = false }: { reduce?: boolean }) {
return (
);
}
// 3. Happy Customers SVG
function HappyCustomerSVG({ reduce = false }: { reduce?: boolean }) {
return (
);
}
// 4. Trusted Star SVG
function TrustedStarSVG({ reduce = false }: { reduce?: boolean }) {
return (
);
}
const PROOF_ITEMS = [
{
label: "Verified",
text: "Local Stores",
dotColor: "bg-[#6D28D9]",
renderSVG: (reduce: boolean) => ,
},
{
label: "Neighborhood",
text: "Coverage",
dotColor: "bg-[#A855F7]",
renderSVG: (reduce: boolean) => ,
},
{
label: "Growing",
text: "Happy Customers",
dotColor: "bg-[#EC4899]",
renderSVG: (reduce: boolean) => ,
},
{
label: "Trusted",
text: "Local Platform",
dotColor: "bg-[#F59E0B]",
renderSVG: (reduce: boolean) => ,
},
];
// Shared cascade timing: logo settles at ~1.2s, then badge → heading → description
const badgeVariant = {
hidden: { opacity: 0, y: 25 },
visible: { opacity: 1, y: 0, transition: { duration: 0.6, delay: 0.9, ease: EASE } },
};
const lineStagger = {
hidden: {},
visible: { transition: { staggerChildren: 0.13, delayChildren: 1.0 } },
};
const lineReveal = {
hidden: { y: 60, opacity: 0, filter: "blur(8px)" },
visible: { y: 0, opacity: 1, filter: "blur(0px)", transition: { duration: 0.9, ease: EASE_LOGO } },
};
const descVariant = {
hidden: { opacity: 0, y: 30 },
visible: { opacity: 1, y: 0, transition: { duration: 0.6, delay: 1.4, ease: EASE } },
};
const ctaVariant = {
hidden: { opacity: 0, y: 22 },
visible: { opacity: 1, y: 0, transition: { duration: 0.55, delay: 1.6, ease: EASE } },
};
const statStagger = {
hidden: {},
visible: { transition: { staggerChildren: 0.08 } },
};
const statItem = {
hidden: { opacity: 0, y: 14 },
visible: { opacity: 1, y: 0, transition: { duration: 0.45, ease: EASE } },
};
export function Hero() {
const shouldReduce = useReducedMotion();
const sectionRef = useRef(null);
// Subtle mouse parallax: background drifts 5px toward the cursor
const mouseX = useMotionValue(0);
const mouseY = useMotionValue(0);
const springX = useSpring(mouseX, { stiffness: 60, damping: 20, mass: 0.5 });
const springY = useSpring(mouseY, { stiffness: 60, damping: 20, mass: 0.5 });
const bgParallaxX = useTransform(springX, [-0.5, 0.5], [-5, 5]);
const bgParallaxY = useTransform(springY, [-0.5, 0.5], [-5, 5]);
function handleMouseMove(e: MouseEvent) {
if (shouldReduce) return;
const rect = e.currentTarget.getBoundingClientRect();
mouseX.set((e.clientX - rect.left) / rect.width - 0.5);
mouseY.set((e.clientY - rect.top) / rect.height - 0.5);
}
function handleMouseLeave() {
mouseX.set(0);
mouseY.set(0);
}
return (
{/* `compact` logo spacing: this hero now carries CTAs and the evolution
strip inside it, the same reason BrandsHero uses it. */}
{/* Badge */}
Welcome to Nearle
{/* H1: line-by-line reveal. Two lines, with the closing word
highlighted in the Nearle purple. */}
Everything Local.
Everything Near.
{/* Description */}
Discover verified local stores, exclusive offers, fast delivery, and a
better way to shop within your neighbourhood.
{/* CTAs */}
Discover Nearby Stores
See How Nearle Works
{/* ─── BOTTOM PROOF STATS ROW ─── */}
{/* Floating Particle Glow Dots on Hover */}
{PROOF_ITEMS.map((item, idx) => (
{/* Corner Hover Glowing Dot on Item */}
{item.renderSVG(!!shouldReduce)}
{idx < PROOF_ITEMS.length - 1 && (
)}
))}
);
}