all hero section add image
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
"use client";
|
||||
|
||||
import Link from "next/link";
|
||||
import { Fragment } from "react";
|
||||
import Image from "next/image";
|
||||
import { motion, useReducedMotion } from "framer-motion";
|
||||
import { motion } from "framer-motion";
|
||||
import { MaterialIcon } from "@/components/ui/MaterialIcon";
|
||||
import { viewport } from "@/lib/animations";
|
||||
|
||||
@@ -15,7 +15,6 @@ const PROOF_ITEMS = [
|
||||
{ label: "Trusted", text: "Local Platform", icon: "star" },
|
||||
];
|
||||
|
||||
// Left column: badge → line1 mask-reveal → line2 mask-reveal → desc → primary CTA → secondary CTA
|
||||
const heroStagger = {
|
||||
hidden: {},
|
||||
visible: { transition: { staggerChildren: 0.12, delayChildren: 0.05 } },
|
||||
@@ -43,21 +42,6 @@ const descVariant = {
|
||||
visible: { opacity: 1, y: 0, transition: { duration: 0.55, ease: EASE } },
|
||||
};
|
||||
|
||||
const primaryCtaVariant = {
|
||||
hidden: { opacity: 0, y: 14, scale: 0.97 },
|
||||
visible: { opacity: 1, y: 0, scale: 1, transition: { duration: 0.45, ease: EASE } },
|
||||
};
|
||||
|
||||
const secondaryCtaVariant = {
|
||||
hidden: { opacity: 0, x: -14 },
|
||||
visible: { opacity: 1, x: 0, transition: { duration: 0.4, ease: EASE } },
|
||||
};
|
||||
|
||||
const logoReveal = {
|
||||
hidden: { opacity: 0, scale: 0.88, y: 20 },
|
||||
visible: { opacity: 1, scale: 1, y: 0, transition: { duration: 0.75, ease: EASE, delay: 0.15 } },
|
||||
};
|
||||
|
||||
const statStagger = {
|
||||
hidden: {},
|
||||
visible: { transition: { staggerChildren: 0.08 } },
|
||||
@@ -69,175 +53,102 @@ const statItem = {
|
||||
};
|
||||
|
||||
export function Hero() {
|
||||
const reducedMotion = useReducedMotion();
|
||||
|
||||
return (
|
||||
<section className="relative overflow-hidden bg-gradient-to-b from-[#FAF8FC] to-[#FFFFFF] select-none w-full">
|
||||
{/* ─── DECORATIONS (BEHIND CONTENT) ─── */}
|
||||
<section className="bg-white select-none w-full">
|
||||
<div className="relative overflow-hidden bg-[#FAF8FC]">
|
||||
<Image
|
||||
src="/images/home1.png"
|
||||
alt=""
|
||||
fill
|
||||
sizes="100vw"
|
||||
className="absolute inset-0 z-0 h-full w-full object-cover object-[62%_center] md:object-[58%_center] xl:object-center"
|
||||
priority
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<div className="absolute inset-0 z-[1] bg-[linear-gradient(180deg,rgba(250,248,252,0.85)_0%,rgba(250,248,252,0.68)_28%,rgba(250,248,252,0.38)_58%,rgba(250,248,252,0.10)_100%)] md:bg-[radial-gradient(ellipse_72%_88%_at_50%_42%,rgba(250,248,252,0.72)_0%,rgba(250,248,252,0.50)_38%,rgba(250,248,252,0.18)_65%,rgba(250,248,252,0.04)_100%)]" />
|
||||
|
||||
{/* 1. Large pale lavender partial circle (top-left) */}
|
||||
<motion.div
|
||||
className="hidden md:block absolute top-[-100px] left-[-100px] w-[350px] h-[350px] rounded-full border-[1.5px] border-[#6D28D9]/15 bg-[#6D28D9]/5 opacity-[0.55] z-0 pointer-events-none"
|
||||
animate={{ y: [0, -14, 0] }}
|
||||
transition={{ duration: 14, repeat: Infinity, ease: "easeInOut" }}
|
||||
/>
|
||||
<div className="page-container relative z-10 flex min-h-[560px] items-center justify-center px-6 pt-20 pb-10 sm:min-h-[580px] sm:px-8 sm:pt-24 md:min-h-[610px] md:py-20 lg:min-h-[650px] lg:py-24 xl:min-h-[680px]">
|
||||
|
||||
|
||||
{/* 4. Dotted pattern (between left text and right collage) */}
|
||||
<div className="hidden lg:block absolute left-[41%] top-[25%] w-48 h-48 opacity-[0.35] z-0 pointer-events-none">
|
||||
<svg className="w-full h-full text-[#6D28D9]" fill="currentColor">
|
||||
<pattern id="hero-decor-dots" x="0" y="0" width="16" height="16" patternUnits="userSpaceOnUse">
|
||||
<circle cx="2" cy="2" r="1.5" />
|
||||
</pattern>
|
||||
<rect width="100%" height="100%" fill="url(#hero-decor-dots)" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
|
||||
{/* 6. Large partial purple circle (bottom-right corner) */}
|
||||
<motion.div
|
||||
className="absolute bottom-[-100px] right-[-100px] w-[200px] h-[200px] rounded-full bg-[#7C3AED]/80 z-0 pointer-events-none"
|
||||
animate={{ y: [0, 12, 0] }}
|
||||
transition={{ duration: 12, repeat: Infinity, ease: "easeInOut" }}
|
||||
/>
|
||||
|
||||
{/* ─── TWO-COLUMN CONTENT GRID ─── */}
|
||||
<div className="page-container relative grid min-h-[650px] grid-cols-1 lg:grid-cols-[0.92fr_1.08fr] items-center py-16 md:py-20 lg:py-24 z-10 gap-12 lg:gap-6">
|
||||
|
||||
{/* LEFT COLUMN: Editorial Typography & Copy */}
|
||||
<motion.div
|
||||
className="flex flex-col text-left max-w-xl z-20 relative"
|
||||
variants={heroStagger}
|
||||
initial="hidden"
|
||||
animate="visible"
|
||||
>
|
||||
{/* Badge */}
|
||||
<motion.span
|
||||
variants={badgeVariant}
|
||||
className="inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-xs font-black tracking-widest bg-[#6D28D9]/10 text-[#6D28D9] uppercase mb-6 w-fit"
|
||||
>
|
||||
Welcome to Nearle
|
||||
</motion.span>
|
||||
|
||||
{/* H1: line-by-line mask reveal */}
|
||||
<motion.div variants={lineStagger} className="font-display text-4xl sm:text-5xl lg:text-[68px] xl:text-[76px] font-black text-[#16001D] tracking-[-0.05em]">
|
||||
<div className="overflow-hidden pb-1">
|
||||
<motion.div variants={lineReveal} className="leading-[0.95]">
|
||||
Everything Local.
|
||||
</motion.div>
|
||||
</div>
|
||||
<div className="overflow-hidden pb-1">
|
||||
<motion.div variants={lineReveal} className="leading-[0.95]">
|
||||
Everything <span className="text-[#6D28D9]">Near.</span>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Description */}
|
||||
<motion.p
|
||||
variants={descVariant}
|
||||
className="max-w-[480px] text-base md:text-lg text-[#6D6172] leading-relaxed font-bold mt-6"
|
||||
>
|
||||
Discover verified local stores, exclusive offers, fast delivery, and a better way to shop within your neighbourhood.
|
||||
</motion.p>
|
||||
|
||||
{/* CTAs: primary scales in, secondary slides from left */}
|
||||
<div className="hidden md:flex md:flex-row md:gap-3.5 mt-8">
|
||||
<motion.div
|
||||
variants={primaryCtaVariant}
|
||||
whileHover={{ scale: 1.03, transition: { duration: 0.2, ease: EASE } }}
|
||||
whileTap={{ scale: 0.97, transition: { duration: 0.1 } }}
|
||||
>
|
||||
<Link
|
||||
href="/people"
|
||||
className="bg-[#6D28D9] hover:bg-[#5225b8] text-white font-black px-5 sm:px-8 py-3.5 rounded-xl text-sm md:text-base text-center shadow-md hover:shadow-lg transition-colors duration-200 block"
|
||||
>
|
||||
Explore Stores
|
||||
</Link>
|
||||
</motion.div>
|
||||
<motion.div
|
||||
variants={secondaryCtaVariant}
|
||||
whileHover={{ scale: 1.03, transition: { duration: 0.2, ease: EASE } }}
|
||||
whileTap={{ scale: 0.97, transition: { duration: 0.1 } }}
|
||||
>
|
||||
<Link
|
||||
href="/people#download-section"
|
||||
className="border-2 border-[#6D28D9]/20 hover:border-[#6D28D9]/40 text-[#6D28D9] font-black px-5 sm:px-8 py-3.5 rounded-xl text-sm md:text-base text-center transition-colors duration-200 hover:bg-[#6D28D9]/5 block"
|
||||
>
|
||||
Get the App
|
||||
</Link>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* RIGHT COLUMN: Nearle brand logo composition */}
|
||||
<div className="w-full z-20 flex items-center justify-center py-4 lg:py-0">
|
||||
<motion.div
|
||||
className="relative flex items-center justify-center"
|
||||
variants={logoReveal}
|
||||
className="relative z-20 flex w-full max-w-[780px] flex-col items-center text-center"
|
||||
variants={heroStagger}
|
||||
initial="hidden"
|
||||
animate="visible"
|
||||
>
|
||||
{/* Atmospheric glow — elliptical, not circular, fades naturally */}
|
||||
<div
|
||||
className="absolute pointer-events-none"
|
||||
style={{
|
||||
width: '160%',
|
||||
height: '160%',
|
||||
top: '-30%',
|
||||
left: '-30%',
|
||||
background: 'radial-gradient(ellipse 60% 50% at 50% 53%, rgba(109,40,217,0.15) 0%, rgba(109,40,217,0.05) 48%, transparent 75%)',
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Logo with slow float and grounding shadow */}
|
||||
<motion.div
|
||||
animate={!reducedMotion ? { y: [0, -16, 0] } : {}}
|
||||
transition={{ duration: 11, repeat: Infinity, ease: "easeInOut", delay: 0.8 }}
|
||||
{/* Badge */}
|
||||
<motion.span
|
||||
variants={badgeVariant}
|
||||
className="inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-xs font-black tracking-widest bg-[#6D28D9]/10 text-[#6D28D9] uppercase mb-6 w-fit"
|
||||
>
|
||||
<Image
|
||||
src="/nearlenewlogo.png"
|
||||
alt="Nearle – Your Neighbourhood Commerce Platform"
|
||||
width={480}
|
||||
height={480}
|
||||
className="relative z-10 w-[200px] sm:w-[260px] lg:w-[400px] xl:w-[460px] h-auto object-contain select-none"
|
||||
style={{ filter: 'drop-shadow(0 28px 52px rgba(109,40,217,0.22)) drop-shadow(0 4px 10px rgba(22,0,29,0.06))' }}
|
||||
priority
|
||||
/>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
</div>
|
||||
Welcome to Nearle
|
||||
</motion.span>
|
||||
|
||||
{/* H1: line-by-line mask reveal */}
|
||||
<motion.div variants={lineStagger} className="font-display text-[34px] sm:text-5xl lg:text-[68px] xl:text-[76px] font-black text-[#16001D] tracking-[-0.05em]">
|
||||
<div className="overflow-hidden pb-1">
|
||||
<motion.div variants={lineReveal} className="leading-[0.95]">
|
||||
Everything Local.
|
||||
</motion.div>
|
||||
</div>
|
||||
<div className="overflow-hidden pb-1">
|
||||
<motion.div variants={lineReveal} className="leading-[0.95]">
|
||||
Everything <span className="text-[#6D28D9]">Near.</span>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Description */}
|
||||
<motion.p
|
||||
variants={descVariant}
|
||||
className="max-w-[520px] text-base md:text-lg text-[#16001D] leading-relaxed font-bold mt-6 [text-shadow:0_1px_2px_rgba(255,255,255,0.55)]"
|
||||
>
|
||||
Discover verified local stores, exclusive offers, fast delivery, and a better way to shop within your neighbourhood.
|
||||
</motion.p>
|
||||
</motion.div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* ─── BOTTOM PROOF STATS ROW ─── */}
|
||||
<div className="border-t border-[#EEE7F4]/80 bg-white">
|
||||
<motion.div
|
||||
className="page-container py-8 grid grid-cols-2 md:grid-cols-4 gap-8 md:gap-4 relative z-20"
|
||||
variants={statStagger}
|
||||
initial="hidden"
|
||||
whileInView="visible"
|
||||
viewport={viewport}
|
||||
>
|
||||
{PROOF_ITEMS.map((item, idx) => (
|
||||
<motion.div key={item.label} variants={statItem} className="flex items-center gap-4 text-left md:justify-center relative">
|
||||
{idx > 0 && (
|
||||
<div className="hidden md:block absolute left-0 top-1/2 -translate-y-1/2 w-[1px] h-10 bg-[#EEE7F4]" />
|
||||
)}
|
||||
<div className="w-10 h-10 rounded-full bg-[#6D28D9]/8 text-[#6D28D9] flex items-center justify-center shrink-0">
|
||||
<MaterialIcon icon={item.icon} size={18} />
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-2xl md:text-3xl font-black text-[#16001D] leading-none tracking-tight">
|
||||
{item.label}
|
||||
</div>
|
||||
<div className="text-xs text-[#6D6172] font-semibold mt-1">
|
||||
{item.text}
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</motion.div>
|
||||
<div className="px-6 sm:px-10 max-w-[1600px] mx-auto py-6 md:py-8 lg:py-10">
|
||||
<motion.div
|
||||
className="bg-white rounded-[32px] border border-[#E9D8FD] shadow-[0_10px_35px_rgba(124,58,237,0.08),0_2px_8px_rgba(124,58,237,0.05)] px-6 py-6 md:px-8 md:py-7 lg:px-12 lg:py-8"
|
||||
variants={statStagger}
|
||||
initial="hidden"
|
||||
whileInView="visible"
|
||||
viewport={viewport}
|
||||
>
|
||||
<div className="flex flex-col gap-6 md:grid md:grid-cols-2 md:gap-x-8 md:gap-y-6 lg:flex lg:flex-row lg:items-center lg:justify-between lg:gap-0">
|
||||
{PROOF_ITEMS.map((item, idx) => (
|
||||
<Fragment key={item.label}>
|
||||
<motion.div
|
||||
variants={statItem}
|
||||
className="flex items-center gap-[18px] group cursor-default transition-transform duration-[250ms] hover:-translate-y-1 lg:flex-1 lg:py-2"
|
||||
>
|
||||
<div className="w-16 h-16 rounded-full bg-[#F5EDFF] text-[#6D28D9] flex items-center justify-center shrink-0 transition-colors duration-[250ms] group-hover:bg-[#E4D1FF]">
|
||||
<MaterialIcon icon={item.icon} size={28} />
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-2xl lg:text-[28px] font-black text-[#17051F] leading-none tracking-tight transition-colors duration-[250ms] group-hover:text-[#6D28D9]">
|
||||
{item.label}
|
||||
</div>
|
||||
<div className="text-sm lg:text-[15px] font-medium text-[#6B7280] mt-1.5">
|
||||
{item.text}
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
{idx < PROOF_ITEMS.length - 1 && (
|
||||
<div
|
||||
className="hidden lg:block w-px h-[72px] bg-[#E9D8FD] shrink-0 self-center"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
)}
|
||||
</Fragment>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
Reference in New Issue
Block a user