content order changes
This commit is contained in:
@@ -102,30 +102,30 @@ function InstantFulfillmentSVG({ reduce = false }: { reduce?: boolean }) {
|
||||
const STEPS = [
|
||||
{
|
||||
step: "01",
|
||||
title: "Natural Intent",
|
||||
desc: "Tell Nearle what you need in plain Tamil or English. AI understands local store products, brands, and quantities without manual searching.",
|
||||
title: "Just Ask",
|
||||
desc: "Tell Nearle what you need in your own words — in Tamil or English. No searching, no scrolling through endless lists.",
|
||||
icon: "psychology",
|
||||
badge: "Voice & Text AI",
|
||||
badge: "Voice or Text",
|
||||
iconBg: "bg-primary/10 text-primary border-primary/20",
|
||||
badgeStyle: "bg-primary/10 text-primary border-primary/20",
|
||||
renderSVG: (reduce: boolean) => <NaturalIntentSVG reduce={reduce} />,
|
||||
},
|
||||
{
|
||||
step: "02",
|
||||
title: "Live Local Discovery",
|
||||
desc: "AI instantly checks live stock and pricing at verified neighbourhood stores right around your street to find exact matches.",
|
||||
title: "We Find It Nearby",
|
||||
desc: "Nearle checks what's on the shelves at trusted shops around your street, so you get exactly what you asked for.",
|
||||
icon: "storefront",
|
||||
badge: "Real-Time Stock",
|
||||
badge: "In Stock Nearby",
|
||||
iconBg: "bg-secondary/10 text-secondary border-secondary/20",
|
||||
badgeStyle: "bg-secondary/10 text-secondary border-secondary/20",
|
||||
renderSVG: (reduce: boolean) => <LocalDiscoverySVG reduce={reduce} />,
|
||||
},
|
||||
{
|
||||
step: "03",
|
||||
title: "Instant Fulfillment",
|
||||
desc: "Confirms your order, alerts the local shopkeeper to pack, and dispatches a Nearle rider for fast doorstep delivery — all in 1 chat.",
|
||||
title: "Delivered to You",
|
||||
desc: "Confirm your order and the shopkeeper packs it while a Nearle rider brings it to your door — all in one chat.",
|
||||
icon: "bolt",
|
||||
badge: "1-Tap Fulfillment",
|
||||
badge: "To Your Door",
|
||||
iconBg: "bg-[#7C3AED]/10 text-[#7C3AED] border-[#7C3AED]/20",
|
||||
badgeStyle: "bg-[#7C3AED]/10 text-[#7C3AED] border-[#7C3AED]/20",
|
||||
renderSVG: (reduce: boolean) => <InstantFulfillmentSVG reduce={reduce} />,
|
||||
@@ -134,8 +134,8 @@ const STEPS = [
|
||||
|
||||
const HIGHLIGHTS = [
|
||||
{
|
||||
title: "Zero App Switching",
|
||||
sub: "Everything in 1 conversation",
|
||||
title: "No App Switching",
|
||||
sub: "Everything in one chat",
|
||||
icon: "forum",
|
||||
iconColor: "bg-primary/10 text-primary",
|
||||
},
|
||||
@@ -146,14 +146,14 @@ const HIGHLIGHTS = [
|
||||
iconColor: "bg-secondary/10 text-secondary",
|
||||
},
|
||||
{
|
||||
title: "Live Inventory",
|
||||
sub: "Real-time store stock",
|
||||
title: "Real Availability",
|
||||
sub: "See what's in stock nearby",
|
||||
icon: "inventory_2",
|
||||
iconColor: "bg-blue-600/10 text-blue-600",
|
||||
},
|
||||
{
|
||||
title: "Fast Rider Delivery",
|
||||
sub: "Direct doorstep fulfillment",
|
||||
title: "Fast Local Delivery",
|
||||
sub: "Straight to your door",
|
||||
icon: "local_shipping",
|
||||
iconColor: "bg-[#7C3AED]/10 text-[#7C3AED]",
|
||||
},
|
||||
@@ -181,7 +181,7 @@ export function AICommerceIntro() {
|
||||
variants={fadeUp}
|
||||
className="inline-flex items-center rounded-full bg-[#6330D6]/[0.08] px-3.5 py-1.5 text-xs font-black uppercase tracking-widest text-[#6330D6]"
|
||||
>
|
||||
Nearle AI Engine
|
||||
Powered by Nearle AI
|
||||
</motion.span>
|
||||
|
||||
<motion.h2
|
||||
@@ -189,14 +189,14 @@ export function AICommerceIntro() {
|
||||
variants={fadeUp}
|
||||
className="mt-4 font-display font-black tracking-tight text-[#16001D] text-4xl md:text-5xl lg:text-[56px] leading-tight"
|
||||
>
|
||||
Neighbourhood Shopping, <span className="text-[#7C3AED]">Reimagined by AI</span>
|
||||
Just Tell Us <span className="text-[#7C3AED]">What You Need</span>
|
||||
</motion.h2>
|
||||
|
||||
<motion.p
|
||||
variants={fadeUp}
|
||||
className="mx-auto mt-4 max-w-[760px] text-base md:text-lg leading-relaxed text-[#5E5866]"
|
||||
>
|
||||
Instead of searching across multiple apps and comparing items manually, simply tell Nearle what you need. AI handles discovery, stock checking, and ordering — all in one conversation.
|
||||
No more hopping between apps or scrolling endless lists. Tell Nearle what you need, and we’ll find it at a shop nearby, make sure it’s in stock, and get it on its way — all in one chat.
|
||||
</motion.p>
|
||||
</motion.div>
|
||||
|
||||
@@ -217,13 +217,13 @@ export function AICommerceIntro() {
|
||||
<div className="lg:col-span-7">
|
||||
<div className="inline-flex items-center gap-2 rounded-xl bg-[#7C3AED]/10 px-3.5 py-1.5 text-xs font-black text-[#7C3AED] mb-5">
|
||||
<MaterialIcon icon="auto_awesome" size={18} />
|
||||
<span>Conversational Commerce</span>
|
||||
<span>Just Say It</span>
|
||||
</div>
|
||||
<h3 className="font-display text-2xl md:text-3xl lg:text-4xl font-black text-[#16001D] leading-tight mb-4">
|
||||
Talk to Nearle AI like you speak to your local shopkeeper
|
||||
Shop like you’re talking to your local shopkeeper
|
||||
</h3>
|
||||
<p className="text-base md:text-lg text-[#5E5866] leading-relaxed max-w-2xl">
|
||||
Nearle connects natural consumer intent directly to verified local merchant inventory. You ask, AI discovers nearby availability, confirms with the merchant, and dispatches delivery.
|
||||
Just say what you’re after. Nearle finds it at a trusted shop nearby, confirms it with the owner, and sends it to your door.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -233,8 +233,8 @@ export function AICommerceIntro() {
|
||||
<MaterialIcon icon="mic" size={22} />
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-xs font-black text-primary uppercase tracking-wider">Step 1 Intent</p>
|
||||
<p className="text-sm md:text-base font-bold text-[#16001D]">Natural Voice & Text Query</p>
|
||||
<p className="text-xs font-black text-primary uppercase tracking-wider">Step 1 Ask</p>
|
||||
<p className="text-sm md:text-base font-bold text-[#16001D]">Tell us what you need</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -243,8 +243,8 @@ export function AICommerceIntro() {
|
||||
<MaterialIcon icon="travel_explore" size={22} />
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-xs font-black text-[#EC4899] uppercase tracking-wider">Step 2 Match</p>
|
||||
<p className="text-sm md:text-base font-bold text-[#16001D]">Live Local Shop Scan</p>
|
||||
<p className="text-xs font-black text-[#EC4899] uppercase tracking-wider">Step 2 Find</p>
|
||||
<p className="text-sm md:text-base font-bold text-[#16001D]">We find it nearby</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -254,7 +254,7 @@ export function AICommerceIntro() {
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-xs font-black text-[#10B981] uppercase tracking-wider">Step 3 Deliver</p>
|
||||
<p className="text-sm md:text-base font-bold text-[#16001D]">Shopkeeper Pack & Rider Delivery</p>
|
||||
<p className="text-sm md:text-base font-bold text-[#16001D]">Packed by the shop, brought to you</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -8,8 +8,8 @@ import { fadeUp, fadeIn, scaleIn, staggerContainer, viewport } from "@/lib/anima
|
||||
|
||||
const FEATURES = [
|
||||
{
|
||||
title: "AI Catalogue",
|
||||
desc: "Turn your shelf into a live online catalogue with ProductLLM — no manual data entry.",
|
||||
title: "Digital Catalogue",
|
||||
desc: "Turn your shelves into an online catalogue in minutes — no manual data entry.",
|
||||
icon: "menu_book",
|
||||
visual: "/images/stores/catalogue-ui.webp",
|
||||
alt: "Clean grocery catalogue interface preview",
|
||||
|
||||
@@ -13,11 +13,134 @@ 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 (
|
||||
<div className="relative flex items-center justify-center">
|
||||
<motion.div
|
||||
className="absolute h-10 w-10 rounded-full bg-[#6D28D9]/15 blur-md pointer-events-none"
|
||||
animate={reduce ? {} : { scale: [0.9, 1.25, 0.9], opacity: [0.25, 0.6, 0.25] }}
|
||||
transition={{ duration: 3, repeat: Infinity, ease: "easeInOut" }}
|
||||
/>
|
||||
<svg width="44" height="44" viewBox="0 0 44 44" fill="none" className="relative z-10 w-8 h-8 md:w-9 md:h-9">
|
||||
<motion.path
|
||||
d="M 8 16 L 36 16 L 33 8 L 11 8 Z"
|
||||
fill="#A855F7"
|
||||
animate={reduce ? {} : { y: [0, -2, 0] }}
|
||||
transition={{ duration: 2.8, repeat: Infinity, ease: "easeInOut" }}
|
||||
/>
|
||||
<rect x="10" y="16" width="24" height="20" rx="2" fill="#6D28D9" />
|
||||
<rect x="18" y="24" width="8" height="12" rx="1.5" fill="#E4D1FF" />
|
||||
<motion.circle cx="32" cy="28" r="5" fill="#10B981"
|
||||
animate={reduce ? {} : { scale: [0.85, 1.15, 0.85] }}
|
||||
transition={{ duration: 2, repeat: Infinity, ease: "easeInOut" }}
|
||||
/>
|
||||
<path d="M 29.5 28 L 31.5 30 L 34.5 26.5" stroke="#FFFFFF" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
|
||||
</svg>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// 2. Neighborhood Pin SVG
|
||||
function NeighborhoodPinSVG({ reduce = false }: { reduce?: boolean }) {
|
||||
return (
|
||||
<div className="relative flex items-center justify-center">
|
||||
<motion.div
|
||||
className="absolute h-10 w-10 rounded-full bg-[#6D28D9]/15 blur-md pointer-events-none"
|
||||
animate={reduce ? {} : { scale: [0.9, 1.25, 0.9], opacity: [0.25, 0.6, 0.25] }}
|
||||
transition={{ duration: 3, repeat: Infinity, ease: "easeInOut" }}
|
||||
/>
|
||||
<svg width="44" height="44" viewBox="0 0 44 44" fill="none" className="relative z-10 w-8 h-8 md:w-9 md:h-9">
|
||||
<motion.circle cx="22" cy="30" r="11" stroke="#A855F7" strokeWidth="1.5" strokeDasharray="3 3"
|
||||
animate={reduce ? {} : { scale: [0.8, 1.3, 0.8], opacity: [0.3, 0.8, 0.3] }}
|
||||
transition={{ duration: 2.8, repeat: Infinity, ease: "easeInOut" }}
|
||||
/>
|
||||
<motion.path
|
||||
d="M 22 6 C 15 6 9 12 9 19 C 9 28 22 38 22 38 C 22 38 35 28 35 19 C 35 12 29 6 22 6 Z"
|
||||
fill="#6D28D9"
|
||||
animate={reduce ? {} : { y: [0, -3, 0] }}
|
||||
transition={{ duration: 2.5, repeat: Infinity, ease: "easeInOut" }}
|
||||
/>
|
||||
<circle cx="22" cy="18" r="4" fill="#FFFFFF" />
|
||||
</svg>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// 3. Happy Customers SVG
|
||||
function HappyCustomerSVG({ reduce = false }: { reduce?: boolean }) {
|
||||
return (
|
||||
<div className="relative flex items-center justify-center">
|
||||
<motion.div
|
||||
className="absolute h-10 w-10 rounded-full bg-[#EC4899]/15 blur-md pointer-events-none"
|
||||
animate={reduce ? {} : { scale: [0.9, 1.25, 0.9], opacity: [0.25, 0.6, 0.25] }}
|
||||
transition={{ duration: 3, repeat: Infinity, ease: "easeInOut" }}
|
||||
/>
|
||||
<svg width="44" height="44" viewBox="0 0 44 44" fill="none" className="relative z-10 w-8 h-8 md:w-9 md:h-9">
|
||||
<motion.circle cx="22" cy="22" r="16" fill="#F472B6"
|
||||
animate={reduce ? {} : { scale: [1, 1.06, 1] }}
|
||||
transition={{ duration: 2.6, repeat: Infinity, ease: "easeInOut" }}
|
||||
/>
|
||||
<circle cx="16" cy="18" r="2.5" fill="#FFFFFF" />
|
||||
<circle cx="28" cy="18" r="2.5" fill="#FFFFFF" />
|
||||
<motion.path d="M 15 26 C 18 31 26 31 29 26" stroke="#FFFFFF" strokeWidth="2.5" strokeLinecap="round"
|
||||
animate={reduce ? {} : { opacity: [0.8, 1, 0.8] }}
|
||||
transition={{ duration: 2.4, repeat: Infinity, ease: "easeInOut" }}
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// 4. Trusted Star SVG
|
||||
function TrustedStarSVG({ reduce = false }: { reduce?: boolean }) {
|
||||
return (
|
||||
<div className="relative flex items-center justify-center">
|
||||
<motion.div
|
||||
className="absolute h-10 w-10 rounded-full bg-[#F59E0B]/20 blur-md pointer-events-none"
|
||||
animate={reduce ? {} : { scale: [0.9, 1.25, 0.9], opacity: [0.25, 0.6, 0.25] }}
|
||||
transition={{ duration: 3, repeat: Infinity, ease: "easeInOut" }}
|
||||
/>
|
||||
<svg width="44" height="44" viewBox="0 0 44 44" fill="none" className="relative z-10 w-8 h-8 md:w-9 md:h-9">
|
||||
<motion.path
|
||||
d="M 22 4 L 27.5 15.5 L 40 17 L 31 26 L 33.5 38 L 22 32 L 10.5 38 L 13 26 L 4 17 L 16.5 15.5 Z"
|
||||
fill="#F59E0B"
|
||||
stroke="#FDE047"
|
||||
strokeWidth="1.5"
|
||||
style={{ transformOrigin: "22px 22px" }}
|
||||
animate={reduce ? {} : { scale: [1, 1.1, 1], rotate: [0, 4, 0, -4, 0] }}
|
||||
transition={{ duration: 3, repeat: Infinity, ease: "easeInOut" }}
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const PROOF_ITEMS = [
|
||||
{ label: "Verified", text: "Local Stores", icon: "store" },
|
||||
{ label: "Neighborhood", text: "Coverage", icon: "location_on" },
|
||||
{ label: "Growing", text: "Happy Customers", icon: "mood" },
|
||||
{ label: "Trusted", text: "Local Platform", icon: "star" },
|
||||
{
|
||||
label: "Verified",
|
||||
text: "Local Stores",
|
||||
dotColor: "bg-[#6D28D9]",
|
||||
renderSVG: (reduce: boolean) => <VerifiedStoreSVG reduce={reduce} />,
|
||||
},
|
||||
{
|
||||
label: "Neighborhood",
|
||||
text: "Coverage",
|
||||
dotColor: "bg-[#A855F7]",
|
||||
renderSVG: (reduce: boolean) => <NeighborhoodPinSVG reduce={reduce} />,
|
||||
},
|
||||
{
|
||||
label: "Growing",
|
||||
text: "Happy Customers",
|
||||
dotColor: "bg-[#EC4899]",
|
||||
renderSVG: (reduce: boolean) => <HappyCustomerSVG reduce={reduce} />,
|
||||
},
|
||||
{
|
||||
label: "Trusted",
|
||||
text: "Local Platform",
|
||||
dotColor: "bg-[#F59E0B]",
|
||||
renderSVG: (reduce: boolean) => <TrustedStarSVG reduce={reduce} />,
|
||||
},
|
||||
];
|
||||
|
||||
// Shared cascade timing: logo settles at ~1.2s, then badge → heading → description
|
||||
@@ -182,7 +305,7 @@ export function Hero() {
|
||||
className="flex items-center gap-2 rounded-xl bg-[#6330D6] px-7 py-3.5 text-sm font-black text-white shadow-lg transition-all duration-200 hover:bg-[#5225b8] hover:shadow-xl active:scale-95 sm:px-8"
|
||||
>
|
||||
<MaterialIcon icon="auto_awesome" size={18} />
|
||||
<span>Explore AI Commerce</span>
|
||||
<span>Discover Nearby Stores</span>
|
||||
</Link>
|
||||
</MagneticButton>
|
||||
<MagneticButton>
|
||||
@@ -204,24 +327,60 @@ export function Hero() {
|
||||
<div className="border-t border-[#EEE7F4]/80 bg-white">
|
||||
<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"
|
||||
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 relative overflow-hidden group"
|
||||
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">
|
||||
{/* Floating Particle Glow Dots on Hover */}
|
||||
<div aria-hidden="true" className="pointer-events-none absolute inset-0 overflow-hidden z-0 opacity-0 transition-opacity duration-500 group-hover:opacity-100">
|
||||
<motion.span
|
||||
className="absolute h-1.5 w-1.5 rounded-full bg-[#6D28D9] shadow-[0_0_8px_#6D28D9]"
|
||||
style={{ left: "12%", top: "35%" }}
|
||||
animate={shouldReduce ? {} : { y: [0, -10, 0], opacity: [0.3, 0.9, 0.3] }}
|
||||
transition={{ duration: 4, repeat: Infinity, ease: "easeInOut" }}
|
||||
/>
|
||||
<motion.span
|
||||
className="absolute h-1.5 w-1.5 rounded-full bg-[#A855F7] shadow-[0_0_8px_#A855F7]"
|
||||
style={{ left: "38%", top: "60%" }}
|
||||
animate={shouldReduce ? {} : { y: [0, -12, 0], opacity: [0.3, 0.9, 0.3] }}
|
||||
transition={{ duration: 4.8, delay: 0.8, repeat: Infinity, ease: "easeInOut" }}
|
||||
/>
|
||||
<motion.span
|
||||
className="absolute h-1.5 w-1.5 rounded-full bg-[#EC4899] shadow-[0_0_8px_#EC4899]"
|
||||
style={{ left: "62%", top: "25%" }}
|
||||
animate={shouldReduce ? {} : { y: [0, -10, 0], opacity: [0.3, 0.9, 0.3] }}
|
||||
transition={{ duration: 4.2, delay: 1.2, repeat: Infinity, ease: "easeInOut" }}
|
||||
/>
|
||||
<motion.span
|
||||
className="absolute h-1.5 w-1.5 rounded-full bg-[#F59E0B] shadow-[0_0_8px_#F59E0B]"
|
||||
style={{ left: "85%", top: "55%" }}
|
||||
animate={shouldReduce ? {} : { y: [0, -12, 0], opacity: [0.3, 0.9, 0.3] }}
|
||||
transition={{ duration: 5, delay: 0.4, repeat: Infinity, ease: "easeInOut" }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="relative z-10 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"
|
||||
className="relative flex items-center gap-[18px] group/item 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} />
|
||||
{/* Corner Hover Glowing Dot on Item */}
|
||||
<div className="absolute -top-1 right-2 z-20 flex items-center gap-2 opacity-0 transition-opacity duration-300 group-hover/item:opacity-100">
|
||||
<span className="relative flex h-2 w-2">
|
||||
<span className={`absolute inline-flex h-full w-full animate-ping rounded-full ${item.dotColor} opacity-75`} />
|
||||
<span className={`relative inline-flex h-2 w-2 rounded-full ${item.dotColor} shadow-[0_0_6px_currentColor]`} />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="w-16 h-16 rounded-full bg-[#F5EDFF] text-[#6D28D9] flex items-center justify-center shrink-0 transition-all duration-[250ms] group-hover/item:bg-[#E4D1FF] group-hover/item:scale-110">
|
||||
{item.renderSVG(!!shouldReduce)}
|
||||
</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]">
|
||||
<div className="text-2xl lg:text-[28px] font-black text-[#17051F] leading-none tracking-tight transition-colors duration-[250ms] group-hover/item:text-[#6D28D9]">
|
||||
{item.label}
|
||||
</div>
|
||||
<div className="text-sm lg:text-[15px] font-medium text-[#6B7280] mt-1.5">
|
||||
|
||||
@@ -175,7 +175,7 @@ export function VoiceCommerceExperience() {
|
||||
<span className="relative flex h-1.5 w-1.5">
|
||||
<span className="absolute inline-flex h-full w-full rounded-full bg-[#7C3AED] opacity-60" />
|
||||
</span>
|
||||
Live AI Commerce demo
|
||||
See Nearle in action
|
||||
</p>
|
||||
<Link
|
||||
href="/platform"
|
||||
|
||||
@@ -120,10 +120,15 @@ function OfflineCommerceGraphic({ reduce = false }: { reduce?: boolean }) {
|
||||
);
|
||||
}
|
||||
|
||||
const CARD_MOTES = [
|
||||
{ left: "20%", top: "35%", size: 4, duration: 4.5, delay: 0 },
|
||||
{ left: "75%", top: "60%", size: 3, duration: 5.5, delay: 0.8 },
|
||||
];
|
||||
|
||||
const CARDS = [
|
||||
{
|
||||
title: "Neighbourhood Trust",
|
||||
desc: "Every order is fulfilled by a real local shop your street already knows — not an anonymous warehouse.",
|
||||
desc: "Every order comes from a real shop on your street — the people you already know, not a faraway warehouse.",
|
||||
icon: "handshake",
|
||||
color: "bg-primary/5 text-primary border-primary/10",
|
||||
glowColor: "268 85 65",
|
||||
@@ -132,8 +137,8 @@ const CARDS = [
|
||||
renderSVG: (reduce: boolean) => <TrustCardGraphic reduce={reduce} />,
|
||||
},
|
||||
{
|
||||
title: "AI-Powered Catalog",
|
||||
desc: "ProductLLM turns a shelf into a live, shoppable catalog in minutes — so any store can go online without the busywork.",
|
||||
title: "Your Shops, On Your Phone",
|
||||
desc: "The shops you love are now a tap away — browse their shelves and order in seconds, without leaving home.",
|
||||
icon: "auto_awesome",
|
||||
color: "bg-emerald-500/10 text-emerald-600 border-emerald-500/20",
|
||||
glowColor: "160 84 45",
|
||||
@@ -142,8 +147,8 @@ const CARDS = [
|
||||
renderSVG: (reduce: boolean) => <AICatalogGraphic reduce={reduce} />,
|
||||
},
|
||||
{
|
||||
title: "Offline-First Commerce",
|
||||
desc: "Billing and inventory keep working even when the network drops. Built for how neighbourhood stores really run.",
|
||||
title: "Always Reliable",
|
||||
desc: "Nearle keeps working the way local shops really do — steady even when the network drops, so your order always goes through.",
|
||||
icon: "wifi_off",
|
||||
color: "bg-[#de96f9]/10 text-primary border-[#de96f9]/20",
|
||||
glowColor: "280 85 65",
|
||||
@@ -167,14 +172,14 @@ export function WhyAICommerceWins() {
|
||||
viewport={viewport}
|
||||
>
|
||||
<span className="text-xs text-primary uppercase tracking-widest font-black bg-primary/5 px-3.5 py-1.5 rounded-full">
|
||||
AI Commerce
|
||||
Shop Local
|
||||
</span>
|
||||
<h2 className="text-4xl md:text-5xl lg:text-[54px] font-display font-black text-brand-dark mt-3 leading-tight tracking-tight">
|
||||
Why AI Commerce <span className="text-primary font-normal">Wins</span>
|
||||
A Smarter Way to <span className="text-primary font-normal">Shop Local</span>
|
||||
</h2>
|
||||
<p className="text-body-lg text-on-surface-variant mt-2.5 max-w-xl mx-auto leading-relaxed">
|
||||
Nearle isn’t another delivery app. It’s the AI layer that brings
|
||||
neighbourhood stores online — without replacing them.
|
||||
Nearle isn’t another delivery app. We bring the shops on your street online — so
|
||||
you can order from them in seconds, while they stay the ones serving you.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
@@ -207,6 +212,38 @@ export function WhyAICommerceWins() {
|
||||
animated={true}
|
||||
>
|
||||
<div className="p-6 md:p-8 flex flex-col h-full bg-white rounded-[24px] relative group overflow-hidden">
|
||||
{/* Floating Flying Particle Glow Dots (Motes) - Shown ONLY on Hover */}
|
||||
<div aria-hidden="true" className="pointer-events-none absolute inset-0 overflow-hidden z-0 opacity-0 transition-opacity duration-500 group-hover:opacity-100">
|
||||
{CARD_MOTES.map((mote, idx) => (
|
||||
<motion.span
|
||||
key={idx}
|
||||
className={`absolute rounded-full ${card.dotColor} shadow-[0_0_8px_currentColor]`}
|
||||
style={{
|
||||
left: mote.left,
|
||||
top: mote.top,
|
||||
width: mote.size,
|
||||
height: mote.size,
|
||||
}}
|
||||
animate={
|
||||
reduce
|
||||
? {}
|
||||
: {
|
||||
y: [0, -12, 0],
|
||||
x: [0, 6, 0],
|
||||
opacity: [0.3, 0.9, 0.3],
|
||||
scale: [0.8, 1.2, 0.8],
|
||||
}
|
||||
}
|
||||
transition={{
|
||||
duration: mote.duration,
|
||||
delay: mote.delay,
|
||||
repeat: Infinity,
|
||||
ease: "easeInOut",
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Corner Hover Glowing Dot */}
|
||||
<div className="absolute top-5 right-5 z-20 flex items-center gap-2 opacity-40 transition-opacity duration-300 group-hover:opacity-100">
|
||||
<span className="relative flex h-2.5 w-2.5">
|
||||
|
||||
@@ -15,8 +15,8 @@ const CARDS = [
|
||||
alt: "Friendly local grocery shop owner inside a kirana store",
|
||||
},
|
||||
{
|
||||
title: "AI Assisted Shopping",
|
||||
desc: "Search naturally. Nearle AI understands what you’re looking for and recommends relevant products.",
|
||||
title: "Find Things Faster",
|
||||
desc: "Search in your own words and Nearle helps you find exactly what you need, in seconds.",
|
||||
icon: "auto_awesome",
|
||||
color: "bg-[#de96f9]/10 text-primary border-[#de96f9]/20",
|
||||
image: "/images/illustrations/easy-reordering.webp",
|
||||
|
||||
@@ -20,21 +20,284 @@ const TRADITIONAL = [
|
||||
];
|
||||
|
||||
const NEARLE = [
|
||||
{ icon: "psychology", text: "AI understands intent" },
|
||||
{ icon: "storefront", text: "Merchant stays at the center" },
|
||||
{ icon: "near_me", text: "Customers discover nearby stores naturally" },
|
||||
{ icon: "handshake", text: "Technology empowers merchants instead of replacing them" },
|
||||
{ icon: "psychology", text: "Just ask in your own words" },
|
||||
{ icon: "storefront", text: "The shop you trust stays at the centre" },
|
||||
{ icon: "near_me", text: "You discover the shops right around you" },
|
||||
{ icon: "handshake", text: "Local shops grow — they never get replaced" },
|
||||
];
|
||||
|
||||
// The gentle S-curve the transformation flow travels. Stretched full-bleed via
|
||||
// preserveAspectRatio="none", so exact geometry matters less than the direction:
|
||||
// it always reads left (traditional) → right (Nearle).
|
||||
const FLOW_PATH = "M0 168 C 300 96, 470 236, 640 168 S 960 96, 1200 152";
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
// Storytelling layer — everything below is decorative, pointer-events-none,
|
||||
// low-opacity, and sits behind the cards. It reinforces one idea:
|
||||
// Traditional (isolated, grey) → transformation beam → Nearle (connected, purple).
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
|
||||
// Ambient depth: soft drifting blobs + a faint dot texture so the band never
|
||||
// reads as flat.
|
||||
function AmbientBackdrop({ reduce }: { reduce: boolean }) {
|
||||
return (
|
||||
<div className="absolute inset-0 overflow-hidden">
|
||||
{/* faint dot texture for subtle depth */}
|
||||
<svg className="absolute inset-0 h-full w-full opacity-70" aria-hidden="true">
|
||||
<defs>
|
||||
<pattern id="wnd-dots" width="28" height="28" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1.5" cy="1.5" r="1.5" fill="#7C3AED" fillOpacity="0.05" />
|
||||
</pattern>
|
||||
</defs>
|
||||
<rect width="100%" height="100%" fill="url(#wnd-dots)" />
|
||||
</svg>
|
||||
|
||||
{/* two slow gradient blobs, kept out toward the margins */}
|
||||
<motion.div
|
||||
className="absolute -left-32 top-[22%] h-72 w-72 rounded-full bg-[#C084FC]/[0.10] blur-[120px]"
|
||||
animate={reduce ? undefined : { y: [0, -26, 0], opacity: [0.55, 1, 0.55] }}
|
||||
transition={{ duration: 17, repeat: Infinity, ease: "easeInOut" }}
|
||||
/>
|
||||
<motion.div
|
||||
className="absolute -right-28 top-[34%] h-80 w-80 rounded-full bg-[#7C3AED]/[0.08] blur-[130px]"
|
||||
animate={reduce ? undefined : { y: [0, 28, 0], opacity: [0.5, 0.9, 0.5] }}
|
||||
transition={{ duration: 21, repeat: Infinity, ease: "easeInOut", delay: 1.6 }}
|
||||
/>
|
||||
|
||||
{/* a few tiny floating particles */}
|
||||
{[
|
||||
{ c: "left-[12%] top-[30%]", d: 6, dur: 9 },
|
||||
{ c: "left-[46%] top-[18%]", d: 5, dur: 11 },
|
||||
{ c: "right-[18%] top-[62%]", d: 7, dur: 10 },
|
||||
{ c: "right-[40%] top-[26%]", d: 4, dur: 13 },
|
||||
].map((p, i) => (
|
||||
<motion.span
|
||||
key={i}
|
||||
className={`absolute ${p.c} rounded-full bg-[#A855F7]/40`}
|
||||
style={{ height: p.d, width: p.d }}
|
||||
animate={reduce ? undefined : { y: [0, -14, 0], opacity: [0.2, 0.7, 0.2] }}
|
||||
transition={{ duration: p.dur, repeat: Infinity, ease: "easeInOut", delay: i * 0.7 }}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// The centrepiece: a full-width flow line whose stroke shifts grey → purple,
|
||||
// with a constant dotted drift plus a single brighter beam that sweeps slowly
|
||||
// left → right — the transformation itself.
|
||||
function TransformationFlow({ reduce }: { reduce: boolean }) {
|
||||
return (
|
||||
<div className="absolute inset-x-0 top-1/2 hidden h-[340px] -translate-y-1/2 md:block">
|
||||
<svg
|
||||
viewBox="0 0 1200 340"
|
||||
preserveAspectRatio="none"
|
||||
className="h-full w-full"
|
||||
fill="none"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<defs>
|
||||
<linearGradient id="wnd-flow" x1="0" y1="0" x2="1200" y2="0" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stopColor="#B6ADC6" stopOpacity="0.45" />
|
||||
<stop offset="0.5" stopColor="#9F7AE8" stopOpacity="0.6" />
|
||||
<stop offset="1" stopColor="#A855F7" stopOpacity="0.85" />
|
||||
</linearGradient>
|
||||
<linearGradient id="wnd-beam" x1="0" y1="0" x2="1200" y2="0" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stopColor="#7C3AED" stopOpacity="0" />
|
||||
<stop offset="0.5" stopColor="#A855F7" stopOpacity="0.9" />
|
||||
<stop offset="1" stopColor="#C084FC" stopOpacity="0" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
{/* base line */}
|
||||
<path d={FLOW_PATH} stroke="url(#wnd-flow)" strokeWidth="1.5" opacity="0.22" />
|
||||
|
||||
{/* constant drifting dots */}
|
||||
<motion.path
|
||||
d={FLOW_PATH}
|
||||
stroke="url(#wnd-flow)"
|
||||
strokeWidth="2.4"
|
||||
strokeLinecap="round"
|
||||
strokeDasharray="2 17"
|
||||
opacity="0.5"
|
||||
animate={reduce ? undefined : { strokeDashoffset: [0, -190] }}
|
||||
transition={{ duration: 10, repeat: Infinity, ease: "linear" }}
|
||||
/>
|
||||
|
||||
{/* single slow transformation beam sweeping left → right */}
|
||||
{!reduce && (
|
||||
<motion.path
|
||||
d={FLOW_PATH}
|
||||
stroke="url(#wnd-beam)"
|
||||
strokeWidth="3.5"
|
||||
strokeLinecap="round"
|
||||
strokeDasharray="40 1200"
|
||||
animate={{ strokeDashoffset: [0, -1240] }}
|
||||
transition={{ duration: 11, repeat: Infinity, ease: "easeInOut" }}
|
||||
/>
|
||||
)}
|
||||
</svg>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Left gutter — the "before": a lone grey storefront and a few disconnected
|
||||
// nodes. Isolation is the whole point.
|
||||
function TraditionalCluster({ reduce }: { reduce: boolean }) {
|
||||
return (
|
||||
<motion.div
|
||||
aria-hidden="true"
|
||||
className="absolute left-4 top-1/2 hidden w-[150px] -translate-y-1/2 xl:block 2xl:left-10"
|
||||
animate={reduce ? undefined : { y: [0, -10, 0] }}
|
||||
transition={{ duration: 12, repeat: Infinity, ease: "easeInOut" }}
|
||||
>
|
||||
<div className="relative opacity-[0.55]">
|
||||
<svg width="112" height="112" viewBox="0 0 80 80" fill="none">
|
||||
{/* awning */}
|
||||
<path d="M14 30 L66 30 L62 20 L18 20 Z" fill="#B4ABC4" fillOpacity="0.06" stroke="#B4ABC4" strokeWidth="1.6" />
|
||||
<path
|
||||
d="M14 30 L20 37 L26 30 L32 37 L38 30 L44 37 L50 30 L56 37 L62 30"
|
||||
stroke="#B4ABC4"
|
||||
strokeWidth="1.4"
|
||||
fill="none"
|
||||
/>
|
||||
{/* body */}
|
||||
<rect x="18" y="30" width="44" height="34" stroke="#B4ABC4" strokeWidth="1.6" fill="none" />
|
||||
{/* door */}
|
||||
<rect x="34" y="45" width="12" height="19" stroke="#B4ABC4" strokeWidth="1.3" fill="none" />
|
||||
</svg>
|
||||
|
||||
{/* disconnected nodes — no lines between them */}
|
||||
{[
|
||||
{ c: "left-1 top-2", d: 6 },
|
||||
{ c: "right-2 top-8", d: 5 },
|
||||
{ c: "right-4 bottom-3", d: 7 },
|
||||
].map((n, i) => (
|
||||
<motion.span
|
||||
key={i}
|
||||
className={`absolute ${n.c} rounded-full bg-[#B4ABC4]/50`}
|
||||
style={{ height: n.d, width: n.d }}
|
||||
animate={reduce ? undefined : { opacity: [0.3, 0.6, 0.3] }}
|
||||
transition={{ duration: 3.4 + i, repeat: Infinity, ease: "easeInOut" }}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
|
||||
// Right gutter — the "after": a connected AI network with a pulsing core, a
|
||||
// living location pin, and a sparkle. Connection is the whole point.
|
||||
function NearleCluster({ reduce }: { reduce: boolean }) {
|
||||
const nodes = [
|
||||
{ x: 20, y: 26 },
|
||||
{ x: 92, y: 30 },
|
||||
{ x: 26, y: 90 },
|
||||
{ x: 90, y: 88 },
|
||||
{ x: 56, y: 16 },
|
||||
];
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
aria-hidden="true"
|
||||
className="absolute right-4 top-1/2 hidden w-[160px] -translate-y-1/2 xl:block 2xl:right-10"
|
||||
animate={reduce ? undefined : { y: [0, 12, 0] }}
|
||||
transition={{ duration: 13, repeat: Infinity, ease: "easeInOut" }}
|
||||
>
|
||||
<div className="relative flex flex-col items-center gap-3 opacity-[0.7]">
|
||||
{/* connected network */}
|
||||
<svg width="128" height="128" viewBox="0 0 112 112" fill="none">
|
||||
<g stroke="#A855F7" strokeWidth="1.3" strokeOpacity="0.5">
|
||||
{nodes.map((n, i) => (
|
||||
<line key={i} x1="56" y1="56" x2={n.x} y2={n.y} />
|
||||
))}
|
||||
</g>
|
||||
{nodes.map((n, i) => (
|
||||
<motion.circle
|
||||
key={i}
|
||||
cx={n.x}
|
||||
cy={n.y}
|
||||
r="3.6"
|
||||
fill="#C084FC"
|
||||
animate={reduce ? undefined : { opacity: [0.5, 1, 0.5] }}
|
||||
transition={{ duration: 2.6 + i * 0.4, repeat: Infinity, ease: "easeInOut" }}
|
||||
/>
|
||||
))}
|
||||
{/* expanding ring off the core */}
|
||||
{!reduce && (
|
||||
<motion.circle
|
||||
cx="56"
|
||||
cy="56"
|
||||
r="8"
|
||||
fill="none"
|
||||
stroke="#A855F7"
|
||||
strokeWidth="1.4"
|
||||
animate={{ r: [8, 22], opacity: [0.6, 0] }}
|
||||
transition={{ duration: 3.2, repeat: Infinity, ease: "easeOut" }}
|
||||
/>
|
||||
)}
|
||||
{/* pulsing core */}
|
||||
<motion.circle
|
||||
cx="56"
|
||||
cy="56"
|
||||
r="7"
|
||||
fill="#7C3AED"
|
||||
animate={reduce ? undefined : { scale: [1, 1.16, 1], opacity: [0.85, 1, 0.85] }}
|
||||
style={{ transformOrigin: "56px 56px" }}
|
||||
transition={{ duration: 2.8, repeat: Infinity, ease: "easeInOut" }}
|
||||
/>
|
||||
</svg>
|
||||
|
||||
{/* living location pin */}
|
||||
<div className="relative flex items-center justify-center text-[#7C3AED]">
|
||||
{!reduce && (
|
||||
<motion.span
|
||||
className="absolute h-8 w-8 rounded-full bg-[#A855F7]/20"
|
||||
animate={{ scale: [0.6, 1.5], opacity: [0.5, 0] }}
|
||||
transition={{ duration: 2.6, repeat: Infinity, ease: "easeOut" }}
|
||||
/>
|
||||
)}
|
||||
<MaterialIcon icon="location_on" size={26} />
|
||||
</div>
|
||||
|
||||
{/* sparkle */}
|
||||
<motion.div
|
||||
className="absolute -right-1 top-1 text-[#C084FC]"
|
||||
animate={reduce ? undefined : { scale: [0.8, 1.15, 0.8], opacity: [0.4, 1, 0.4], rotate: [0, 12, 0] }}
|
||||
transition={{ duration: 3.4, repeat: Infinity, ease: "easeInOut" }}
|
||||
>
|
||||
<MaterialIcon icon="auto_awesome" size={16} />
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
|
||||
export function WhyNearleDifferent() {
|
||||
const reduce = useReducedMotion();
|
||||
|
||||
return (
|
||||
<section
|
||||
aria-labelledby="why-different-title"
|
||||
className="section section-soft w-full overflow-hidden border-y border-[#6330D6]/10"
|
||||
className="section section-soft relative w-full overflow-hidden border-y border-[#6330D6]/10"
|
||||
>
|
||||
<div className="page-container">
|
||||
{/* Decorative storytelling layer — revealed after the cards (delay), so the
|
||||
content leads and the illustration follows. */}
|
||||
<motion.div
|
||||
aria-hidden="true"
|
||||
className="pointer-events-none absolute inset-0 z-0"
|
||||
initial={{ opacity: 0 }}
|
||||
whileInView={{ opacity: 1 }}
|
||||
viewport={viewport}
|
||||
transition={{ duration: 1.2, delay: 0.55, ease: "easeOut" }}
|
||||
>
|
||||
<AmbientBackdrop reduce={!!reduce} />
|
||||
<TransformationFlow reduce={!!reduce} />
|
||||
<TraditionalCluster reduce={!!reduce} />
|
||||
<NearleCluster reduce={!!reduce} />
|
||||
</motion.div>
|
||||
|
||||
<div className="page-container relative z-10">
|
||||
<motion.div
|
||||
variants={staggerContainer}
|
||||
initial="hidden"
|
||||
@@ -65,17 +328,22 @@ export function WhyNearleDifferent() {
|
||||
</motion.p>
|
||||
</motion.div>
|
||||
|
||||
<div className="mt-14 grid gap-5 lg:grid-cols-2 lg:gap-6">
|
||||
{/* Sequential reveal: heading (above) → left card → right card, staggered
|
||||
by the parent; rows stagger within each card. */}
|
||||
<motion.div
|
||||
variants={staggerContainer}
|
||||
initial="hidden"
|
||||
whileInView="visible"
|
||||
viewport={viewport}
|
||||
className="mt-14 grid gap-5 lg:grid-cols-2 lg:gap-6"
|
||||
>
|
||||
{/* Traditional commerce */}
|
||||
<motion.div
|
||||
variants={slideInLeftSubtle}
|
||||
initial="hidden"
|
||||
whileInView="visible"
|
||||
viewport={viewport}
|
||||
whileHover={reduce ? undefined : { y: -6, scale: 1.02 }}
|
||||
transition={{ type: "spring", stiffness: 260, damping: 22 }}
|
||||
>
|
||||
<div className="flex h-full flex-col rounded-[32px] border border-[#16001D]/8 bg-white p-7 shadow-[0_10px_30px_rgba(22,0,29,0.05)] md:p-9">
|
||||
<div className="flex h-full flex-col rounded-[32px] border border-[#16001D]/8 bg-white p-7 shadow-[0_10px_30px_rgba(22,0,29,0.05)] transition-shadow duration-300 hover:shadow-[0_18px_44px_rgba(22,0,29,0.09)] md:p-9">
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="flex h-11 w-11 items-center justify-center rounded-2xl bg-[#F1EEF5] text-[#6D6172]">
|
||||
<MaterialIcon icon="apartment" size={22} />
|
||||
@@ -118,12 +386,17 @@ export function WhyNearleDifferent() {
|
||||
{/* Nearle AI Commerce — highlighted */}
|
||||
<motion.div
|
||||
variants={slideInRight}
|
||||
initial="hidden"
|
||||
whileInView="visible"
|
||||
viewport={viewport}
|
||||
whileHover={reduce ? undefined : { y: -6, scale: 1.02 }}
|
||||
transition={{ type: "spring", stiffness: 260, damping: 22 }}
|
||||
className="relative"
|
||||
>
|
||||
{/* soft border glow behind the highlighted card */}
|
||||
<motion.div
|
||||
aria-hidden="true"
|
||||
className="pointer-events-none absolute -inset-1 -z-10 rounded-[36px] bg-[#7C3AED]/10 blur-2xl"
|
||||
animate={reduce ? undefined : { opacity: [0.4, 0.75, 0.4] }}
|
||||
transition={{ duration: 4.5, repeat: Infinity, ease: "easeInOut" }}
|
||||
/>
|
||||
<Spotlight
|
||||
className="flex h-full flex-col overflow-hidden rounded-[32px] border border-[#6330D6]/20 bg-[linear-gradient(135deg,#ffffff_0%,#fbf7ff_55%,#f1e8fb_100%)] p-7 shadow-[0_16px_44px_-16px_rgba(99,48,214,0.28)] md:p-9"
|
||||
color="rgba(168,85,247,0.14)"
|
||||
@@ -131,7 +404,13 @@ export function WhyNearleDifferent() {
|
||||
>
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="flex h-11 w-11 items-center justify-center rounded-2xl bg-[#7C3AED]/10 text-[#7C3AED] ring-1 ring-[#7C3AED]/15">
|
||||
<MaterialIcon icon="auto_awesome" size={22} />
|
||||
<motion.span
|
||||
className="inline-flex"
|
||||
animate={reduce ? undefined : { scale: [1, 1.12, 1], opacity: [0.85, 1, 0.85] }}
|
||||
transition={{ duration: 2.6, repeat: Infinity, ease: "easeInOut" }}
|
||||
>
|
||||
<MaterialIcon icon="auto_awesome" size={22} />
|
||||
</motion.span>
|
||||
</span>
|
||||
<div>
|
||||
<p className="text-[10px] font-black uppercase tracking-[0.14em] text-[#7C3AED]">
|
||||
@@ -167,7 +446,7 @@ export function WhyNearleDifferent() {
|
||||
</motion.ul>
|
||||
</Spotlight>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user