animation fixed in section
This commit is contained in:
139
src/components/heroes/ContactHero.tsx
Normal file
139
src/components/heroes/ContactHero.tsx
Normal file
@@ -0,0 +1,139 @@
|
||||
"use client";
|
||||
|
||||
import { motion } from "framer-motion";
|
||||
import { MaterialIcon } from "@/components/ui/MaterialIcon";
|
||||
import { ContactForm } from "@/components/contact/ContactForm";
|
||||
import { fadeUp, fadeUpStrong, slideInRight, staggerContainer, viewport } from "@/lib/animations";
|
||||
|
||||
const CONTACT_INFO = [
|
||||
{
|
||||
icon: "phone",
|
||||
label: "Call Us",
|
||||
value: "+91 909 206 8666",
|
||||
},
|
||||
{
|
||||
icon: "mail",
|
||||
label: "Email Us",
|
||||
value: "nearle@care.in",
|
||||
},
|
||||
{
|
||||
icon: "location_on",
|
||||
label: "Address",
|
||||
value: "424, DB Rd, R.S. Puram, Coimbatore, TN 641002",
|
||||
},
|
||||
];
|
||||
|
||||
// Choreography: professional, clear sequence
|
||||
// Left column — each info row staggers in from left; h1 has strong upward entry
|
||||
// Form card slides in from right with slight delay
|
||||
// Info rows use a tighter stagger to feel organised and systematic
|
||||
const infoRowVariant = {
|
||||
hidden: { opacity: 0, x: -18 },
|
||||
visible: {
|
||||
opacity: 1,
|
||||
x: 0,
|
||||
transition: { duration: 0.45, ease: [0.22, 1, 0.36, 1] as [number, number, number, number] },
|
||||
},
|
||||
};
|
||||
|
||||
const formVariant = {
|
||||
hidden: { opacity: 0, x: 40 },
|
||||
visible: {
|
||||
opacity: 1,
|
||||
x: 0,
|
||||
transition: { duration: 0.65, ease: [0.22, 1, 0.36, 1] as [number, number, number, number], delay: 0.25 },
|
||||
},
|
||||
};
|
||||
|
||||
const infoStagger = {
|
||||
hidden: {},
|
||||
visible: { transition: { staggerChildren: 0.08 } },
|
||||
};
|
||||
|
||||
export function ContactHero() {
|
||||
return (
|
||||
<section className="relative border-b border-[#6330D6]/10 px-4 py-10 md:px-6 md:py-12 lg:px-8 lg:py-14 xl:px-10 xl:py-16 2xl:px-12 2xl:py-20">
|
||||
|
||||
{/* Decorative map grid — not animated so it stays subtle */}
|
||||
<div className="absolute left-[5%] top-[10%] w-[400px] h-[300px] opacity-[0.04] select-none pointer-events-none -z-10">
|
||||
<svg className="w-full h-full text-[#6330D6]" stroke="currentColor" fill="none" strokeWidth="1.5" viewBox="0 0 400 300">
|
||||
<path d="M0,50 L400,50 M0,130 L400,130 M0,210 L400,210 M80,0 L80,300 M200,0 L200,300 M320,0 L320,300" />
|
||||
<path d="M 80,130 C 120,90 160,170 200,130 C 240,90 280,170 320,130" strokeDasharray="3,3" />
|
||||
<circle cx="200" cy="130" r="4" fill="currentColor" />
|
||||
<circle cx="200" cy="130" r="14" strokeWidth="1" />
|
||||
<circle cx="80" cy="50" r="3" fill="currentColor" />
|
||||
<circle cx="320" cy="210" r="3" fill="currentColor" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div className="relative z-10 mx-auto w-full max-w-[1520px]">
|
||||
<div className="grid grid-cols-1 items-start gap-10 lg:grid-cols-[1.2fr_0.8fr] lg:gap-12 xl:gap-16">
|
||||
|
||||
{/* Left Column — Contact Info: sequential stagger from top */}
|
||||
<motion.div
|
||||
className="w-full max-w-[760px] py-6 md:py-8 lg:py-10 relative z-10 text-[#16001D]"
|
||||
variants={staggerContainer}
|
||||
initial="hidden"
|
||||
animate="visible"
|
||||
>
|
||||
<motion.span
|
||||
variants={fadeUp}
|
||||
className="inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-xs font-black tracking-widest bg-[#6330D6]/10 text-[#6330D6] uppercase mb-6 w-fit"
|
||||
>
|
||||
Contact Us
|
||||
</motion.span>
|
||||
|
||||
<motion.h1
|
||||
variants={fadeUpStrong}
|
||||
className="font-display text-4xl font-black leading-[1.05] text-[#16001D] md:text-5xl lg:text-[58px] xl:text-[64px] 2xl:text-[70px]"
|
||||
>
|
||||
We're Here to <br />
|
||||
<span className="text-[#6330D6]">Help You.</span>
|
||||
</motion.h1>
|
||||
|
||||
<motion.p
|
||||
variants={fadeUp}
|
||||
className="mt-6 max-w-[620px] text-sm font-bold leading-8 text-[#5E5866] md:text-base xl:text-lg"
|
||||
>
|
||||
Whether you are a customer, local store owner, or delivery partner, our team is here to help you get started with Nearle.
|
||||
</motion.p>
|
||||
|
||||
{/* Info rows: each row staggers in from left */}
|
||||
<motion.div
|
||||
className="mt-8 border-t border-[#6330D6]/10"
|
||||
variants={infoStagger}
|
||||
initial="hidden"
|
||||
animate="visible"
|
||||
>
|
||||
{CONTACT_INFO.map((item) => (
|
||||
<motion.div
|
||||
key={item.label}
|
||||
variants={infoRowVariant}
|
||||
className="flex gap-4 py-4.5 border-b border-[#6330D6]/10 items-center"
|
||||
>
|
||||
<div className="w-10 h-10 rounded-full bg-[#6330D6]/10 text-[#6330D6] flex items-center justify-center shrink-0">
|
||||
<MaterialIcon icon={item.icon} size={18} />
|
||||
</div>
|
||||
<div className="text-left">
|
||||
<h4 className="text-[#16001D] text-sm font-black">{item.label}</h4>
|
||||
<p className="text-[#5E5866] text-sm font-semibold mt-0.5">{item.value}</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
|
||||
{/* Right Column: form slides in from right */}
|
||||
<motion.div
|
||||
className="w-full max-w-[660px] justify-self-end pt-10 lg:pt-14 xl:pt-26"
|
||||
variants={formVariant}
|
||||
initial="hidden"
|
||||
animate="visible"
|
||||
>
|
||||
<ContactForm />
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user