cleanup unused iamges
This commit is contained in:
@@ -1,295 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { motion, useReducedMotion } from "framer-motion";
|
||||
import { MaterialIcon } from "@/components/ui/MaterialIcon";
|
||||
|
||||
// ─── Floating feature card ───────────────────────────────────────────────────
|
||||
|
||||
type CardData = { icon: string; title: string; desc: string };
|
||||
|
||||
const CARDS: CardData[] = [
|
||||
{ icon: "verified", title: "Verified Visibility", desc: "Get discovered by nearby shoppers" },
|
||||
{ icon: "people", title: "More Customers", desc: "Build trust and attract local customers" },
|
||||
{ icon: "trending_up", title: "Grow Faster", desc: "Increase repeat business" },
|
||||
];
|
||||
|
||||
function FloatingCard({
|
||||
card, className, entryDelay, floatDelay, floatDist,
|
||||
}: { card: CardData; className: string; entryDelay: number; floatDelay: number; floatDist: number }) {
|
||||
const reduce = useReducedMotion();
|
||||
return (
|
||||
<motion.div
|
||||
className={`absolute z-30 ${className}`}
|
||||
initial={{ opacity: 0, y: 14, scale: 0.92 }}
|
||||
whileInView={{ opacity: 1, y: 0, scale: 1 }}
|
||||
viewport={{ once: true, margin: "-30px" }}
|
||||
transition={{ duration: 0.5, delay: entryDelay, ease: [0.22, 1, 0.36, 1] }}
|
||||
>
|
||||
<motion.div
|
||||
animate={reduce ? {} : { y: [0, floatDist, 0] }}
|
||||
transition={{ duration: 3.8, repeat: Infinity, ease: "easeInOut", delay: floatDelay }}
|
||||
className="bg-white/95 backdrop-blur-xl border border-white/80 shadow-[0_8px_28px_rgba(99,48,214,0.13),0_2px_8px_rgba(0,0,0,0.06)] rounded-[14px] px-3.5 py-2.5 flex items-center gap-2.5 w-max"
|
||||
>
|
||||
<div className="w-7 h-7 rounded-full bg-[#6330D6]/10 text-[#6330D6] flex items-center justify-center shrink-0">
|
||||
<MaterialIcon icon={card.icon} size={15} />
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-[12.5px] font-extrabold text-[#16001D] leading-tight">{card.title}</div>
|
||||
<div className="text-[11px] font-semibold text-[#5E5866] mt-[2px] leading-tight">{card.desc}</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
|
||||
// ─── Phone screen UI (React + Tailwind, no image) ────────────────────────────
|
||||
|
||||
function PhoneScreen() {
|
||||
return (
|
||||
<div className="w-full h-full flex flex-col bg-[#F6F2FF] overflow-hidden text-[#16001D]">
|
||||
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between px-3 pt-2 pb-1.5 bg-white border-b border-[#6330D6]/8 shrink-0">
|
||||
<div className="flex items-center gap-1">
|
||||
<div className="w-[18px] h-[18px] rounded-full bg-[#6330D6] flex items-center justify-center shrink-0">
|
||||
<span className="text-white font-black leading-none" style={{ fontSize: 9 }}>n</span>
|
||||
</div>
|
||||
<span className="font-black tracking-tight" style={{ fontSize: 10 }}>nearle</span>
|
||||
<span className="font-bold text-[#6330D6] bg-[#6330D6]/10 rounded-full leading-none px-1 py-[2px]" style={{ fontSize: 6 }}>BIZ</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-1">
|
||||
<div className="w-[18px] h-[18px] rounded-full bg-[#F0EBF9] flex items-center justify-center">
|
||||
<MaterialIcon icon="notifications" size={10} className="text-[#6330D6]" />
|
||||
</div>
|
||||
<div className="w-[18px] h-[18px] rounded-full bg-[#6330D6] flex items-center justify-center">
|
||||
<span className="text-white font-black" style={{ fontSize: 7 }}>M</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Scrollable content */}
|
||||
<div className="flex-1 flex flex-col gap-1.5 px-2.5 pt-2 pb-1 overflow-hidden">
|
||||
|
||||
{/* Search bar */}
|
||||
<div className="flex items-center gap-1.5 bg-white rounded-lg px-2 py-[5px] border border-[#6330D6]/10 shrink-0">
|
||||
<MaterialIcon icon="search" size={9} className="text-[#9B8BB0] shrink-0" />
|
||||
<span className="text-[#9B8BB0] font-medium" style={{ fontSize: 8 }}>Search shops, offers…</span>
|
||||
</div>
|
||||
|
||||
{/* Analytics strip */}
|
||||
<div className="grid grid-cols-3 gap-1 shrink-0">
|
||||
{[
|
||||
{ val: "₹2.4k", label: "Revenue", color: "text-[#6330D6]" },
|
||||
{ val: "38", label: "Orders", color: "text-[#16001D]" },
|
||||
{ val: "↑12%", label: "Growth", color: "text-[#16a34a]" },
|
||||
].map(s => (
|
||||
<div key={s.label} className="bg-white rounded-lg p-[5px] border border-[#6330D6]/8 flex flex-col gap-[1px]">
|
||||
<span className={`font-black leading-none ${s.color}`} style={{ fontSize: 10 }}>{s.val}</span>
|
||||
<span className="font-semibold text-[#5E5866] leading-none" style={{ fontSize: 6.5 }}>{s.label}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Featured store card */}
|
||||
<div className="bg-white rounded-xl overflow-hidden border border-[#6330D6]/8 shadow-[0_2px_8px_rgba(99,48,214,0.07)] shrink-0">
|
||||
<div className="h-[38px] bg-gradient-to-r from-[#5225b8] to-[#7C3AED] flex items-center px-2.5 gap-1.5">
|
||||
<div className="w-6 h-6 rounded-lg bg-white/20 flex items-center justify-center shrink-0">
|
||||
<MaterialIcon icon="storefront" size={12} className="text-white" />
|
||||
</div>
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="text-white font-black truncate" style={{ fontSize: 8 }}>Green Valley Mart</div>
|
||||
<div className="flex items-center gap-[3px]">
|
||||
<MaterialIcon icon="star" size={7} fill className="text-[#FCD34D]" />
|
||||
<span className="text-white/80 font-medium" style={{ fontSize: 6.5 }}>4.8 · 0.3 km away</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-[2px] bg-[#16a34a]/25 rounded-full px-1.5 py-[2px] shrink-0">
|
||||
<MaterialIcon icon="verified" size={7} fill className="text-[#4ade80]" />
|
||||
<span className="text-[#4ade80] font-bold" style={{ fontSize: 6.5 }}>Verified</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="px-2.5 py-1.5 flex items-center justify-between">
|
||||
<span className="text-[#5E5866] font-medium" style={{ fontSize: 7 }}>Visitors today</span>
|
||||
<span className="text-[#6330D6] font-black" style={{ fontSize: 8 }}>124 customers</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Quick actions */}
|
||||
<div className="shrink-0">
|
||||
<div className="font-black mb-1" style={{ fontSize: 8 }}>Quick Actions</div>
|
||||
<div className="grid grid-cols-4 gap-1">
|
||||
{[
|
||||
{ icon: "add_box", label: "Add Item" },
|
||||
{ icon: "local_offer", label: "Offers" },
|
||||
{ icon: "analytics", label: "Stats" },
|
||||
{ icon: "chat", label: "Chat" },
|
||||
].map(a => (
|
||||
<div key={a.label} className="flex flex-col items-center gap-[3px]">
|
||||
<div className="w-7 h-7 rounded-xl bg-[#6330D6]/8 flex items-center justify-center">
|
||||
<MaterialIcon icon={a.icon} size={13} className="text-[#6330D6]" />
|
||||
</div>
|
||||
<span className="text-[#5E5866] font-semibold text-center" style={{ fontSize: 6 }}>{a.label}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Active offers */}
|
||||
<div className="shrink-0">
|
||||
<div className="font-black mb-1" style={{ fontSize: 8 }}>Active Offers</div>
|
||||
<div className="flex gap-1.5">
|
||||
<div className="flex-1 bg-gradient-to-br from-[#6330D6]/12 to-[#6330D6]/5 rounded-lg p-2 border border-[#6330D6]/15">
|
||||
<div className="font-black text-[#6330D6]" style={{ fontSize: 10 }}>20% OFF</div>
|
||||
<div className="text-[#5E5866] font-medium" style={{ fontSize: 6.5 }}>Groceries</div>
|
||||
</div>
|
||||
<div className="flex-1 bg-gradient-to-br from-[#f59e0b]/12 to-[#f59e0b]/5 rounded-lg p-2 border border-[#f59e0b]/15">
|
||||
<div className="font-black text-[#d97706]" style={{ fontSize: 10 }}>15% OFF</div>
|
||||
<div className="text-[#5E5866] font-medium" style={{ fontSize: 6.5 }}>Daily items</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Latest order */}
|
||||
<div className="bg-white rounded-lg px-2 py-1.5 border border-[#6330D6]/8 flex items-center gap-1.5 shrink-0">
|
||||
<div className="w-6 h-6 rounded-lg bg-[#6330D6]/10 flex items-center justify-center shrink-0">
|
||||
<MaterialIcon icon="package_2" size={12} className="text-[#6330D6]" />
|
||||
</div>
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="font-black" style={{ fontSize: 8 }}>Order #1042</div>
|
||||
<div className="text-[#5E5866] font-medium truncate" style={{ fontSize: 6.5 }}>₹340 · 2 items · Preparing</div>
|
||||
</div>
|
||||
<div className="w-1.5 h-1.5 rounded-full bg-[#f59e0b] animate-pulse shrink-0" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{/* Bottom navigation */}
|
||||
<div className="flex items-center justify-around px-1 py-[5px] bg-white border-t border-[#6330D6]/8 shrink-0">
|
||||
{[
|
||||
{ icon: "home", active: true },
|
||||
{ icon: "bar_chart", active: false },
|
||||
{ icon: "shopping_bag", active: false },
|
||||
{ icon: "group", active: false },
|
||||
{ icon: "settings", active: false },
|
||||
].map(tab => (
|
||||
<div key={tab.icon} className="flex flex-col items-center gap-[2px]">
|
||||
<MaterialIcon
|
||||
icon={tab.icon}
|
||||
size={14}
|
||||
fill={tab.active}
|
||||
className={tab.active ? "text-[#6330D6]" : "text-[#9B8BB0]"}
|
||||
/>
|
||||
{tab.active && <div className="w-3 h-[2px] rounded-full bg-[#6330D6]" />}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// ─── Main visual component ────────────────────────────────────────────────────
|
||||
|
||||
export function BusinessHeroVisual() {
|
||||
const reduce = useReducedMotion();
|
||||
|
||||
return (
|
||||
<div className="relative w-full h-[440px] sm:h-[500px] lg:h-[540px] xl:h-[600px] max-w-[560px] xl:max-w-none mx-auto xl:mx-0 flex items-center justify-center select-none">
|
||||
|
||||
{/* Soft radial glows — centred on phone */}
|
||||
<div className="absolute inset-0 pointer-events-none" aria-hidden>
|
||||
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[400px] h-[400px] xl:w-[500px] xl:h-[500px] rounded-full bg-[#7C3AED]/[0.08] blur-[80px]" />
|
||||
<div className="absolute top-[42%] left-1/2 -translate-x-1/2 -translate-y-1/2 w-[220px] h-[220px] xl:w-[320px] xl:h-[320px] rounded-full bg-[#6330D6]/[0.11] blur-[45px]" />
|
||||
</div>
|
||||
|
||||
{/* Dotted pattern — top-right */}
|
||||
<div className="absolute top-0 right-0 w-36 h-36 pointer-events-none opacity-20" aria-hidden>
|
||||
<svg className="w-full h-full text-[#6330D6]" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="biz-dots-tr" x="0" y="0" width="14" height="14" patternUnits="userSpaceOnUse">
|
||||
<circle cx="2" cy="2" r="1.2" opacity="0.45" />
|
||||
</pattern>
|
||||
</defs>
|
||||
<rect width="100%" height="100%" fill="url(#biz-dots-tr)" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
{/* Dotted pattern — bottom-left */}
|
||||
<div className="absolute bottom-6 left-2 w-24 h-24 pointer-events-none opacity-15" aria-hidden>
|
||||
<svg className="w-full h-full text-[#6330D6]" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="biz-dots-bl" x="0" y="0" width="14" height="14" patternUnits="userSpaceOnUse">
|
||||
<circle cx="2" cy="2" r="1.2" opacity="0.45" />
|
||||
</pattern>
|
||||
</defs>
|
||||
<rect width="100%" height="100%" fill="url(#biz-dots-bl)" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
{/* ── Phone mockup ─────────────────────────────────────────────────── */}
|
||||
<motion.div
|
||||
className="relative z-20"
|
||||
initial={{ opacity: 0, scale: 0.88 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
transition={{ duration: 0.7, ease: [0.22, 1, 0.36, 1] }}
|
||||
style={{ rotate: 6 }}
|
||||
>
|
||||
<motion.div
|
||||
animate={reduce ? {} : { y: [0, -11, 0] }}
|
||||
transition={{ duration: 4.5, repeat: Infinity, ease: "easeInOut", delay: 0.7 }}
|
||||
>
|
||||
{/* Outer bezel */}
|
||||
<div
|
||||
className="relative rounded-[34px] sm:rounded-[38px] xl:rounded-[46px] border-[7px] sm:border-[8px] xl:border-[9px] border-[#1d0d30] bg-[#1d0d30] overflow-hidden"
|
||||
style={{
|
||||
width: "clamp(164px, 22vw, 280px)",
|
||||
height: "clamp(328px, 44vw, 560px)",
|
||||
boxShadow: "0 32px 72px rgba(99,48,214,0.30), 0 10px 28px rgba(0,0,0,0.28)",
|
||||
}}
|
||||
>
|
||||
{/* Screen */}
|
||||
<div className="absolute inset-0">
|
||||
<PhoneScreen />
|
||||
</div>
|
||||
|
||||
{/* Dynamic island */}
|
||||
<div className="absolute top-2.5 left-1/2 -translate-x-1/2 bg-[#0a0515] rounded-full z-20"
|
||||
style={{ width: "clamp(50px, 6.5vw, 74px)", height: "clamp(17px, 2.2vw, 25px)" }}
|
||||
/>
|
||||
|
||||
{/* Screen glare */}
|
||||
<div className="absolute inset-0 bg-gradient-to-br from-white/[0.04] via-transparent to-transparent pointer-events-none z-10" />
|
||||
</div>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
|
||||
{/* ── Floating cards ────────────────────────────────────────────────── */}
|
||||
|
||||
{/* Card 1 — Verified Visibility · top-right */}
|
||||
<FloatingCard
|
||||
card={CARDS[0]}
|
||||
className="top-[5%] right-[2%] sm:right-[0%] xl:top-[4%] xl:right-[2%]"
|
||||
entryDelay={0.55}
|
||||
floatDelay={0}
|
||||
floatDist={-7}
|
||||
/>
|
||||
|
||||
{/* Card 2 — More Customers · bottom-left */}
|
||||
<FloatingCard
|
||||
card={CARDS[1]}
|
||||
className="bottom-[9%] left-[1%] sm:left-[0%] xl:bottom-[6%] xl:left-[3%]"
|
||||
entryDelay={0.75}
|
||||
floatDelay={0.9}
|
||||
floatDist={-8}
|
||||
/>
|
||||
|
||||
{/* Card 3 — Grow Faster · mid-right */}
|
||||
<FloatingCard
|
||||
card={CARDS[2]}
|
||||
className="top-[43%] right-[1%] sm:right-[0%] xl:top-[44%] xl:right-[3%]"
|
||||
entryDelay={0.95}
|
||||
floatDelay={1.7}
|
||||
floatDist={-6}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,198 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import Link from "next/link";
|
||||
import Image from "next/image";
|
||||
import React from "react";
|
||||
import { MaterialIcon } from "@/components/ui/MaterialIcon";
|
||||
|
||||
const COMPANY = [
|
||||
{ label: "About Us", href: "/about" },
|
||||
{ label: "Careers", href: "#" },
|
||||
{ label: "Press & News", href: "#" },
|
||||
{ label: "Help Center", href: "#" },
|
||||
];
|
||||
|
||||
const PARTNERSHIPS = [
|
||||
{ label: "Merchant Partner", href: "/businesses" },
|
||||
{ label: "Delivery Partner", href: "#" },
|
||||
{ label: "Corporate Gifting", href: "#" },
|
||||
{ label: "Local Real Estate", href: "#" },
|
||||
];
|
||||
|
||||
const LEGAL = [
|
||||
{ label: "Privacy Policy", href: "#" },
|
||||
{ label: "Terms of Service", href: "#" },
|
||||
{ label: "Cookie Policy", href: "#" },
|
||||
{ label: "Sitemap", href: "#" },
|
||||
];
|
||||
|
||||
export function Footer() {
|
||||
return (
|
||||
<footer className="bg-[#E6D7EA] px-3 sm:px-4 md:px-6 lg:px-8 xl:px-10 2xl:px-12 pb-6 md:pb-8 lg:pb-10 w-full mt-4">
|
||||
<div className="mx-auto w-full max-w-[1920px]">
|
||||
<div className="section-card-dark p-8 md:p-12 lg:p-14 text-white relative">
|
||||
{/* Background ambient glowing details */}
|
||||
<div className="absolute right-[-10%] top-[-10%] w-[50%] h-[50%] rounded-full bg-brand-accent/5 blur-[120px] pointer-events-none" />
|
||||
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-10 lg:gap-12 relative z-10 items-start text-left">
|
||||
{/* Col 1: Brand info */}
|
||||
<div className="flex flex-col gap-4">
|
||||
<Link href="/" className="inline-block">
|
||||
<Image
|
||||
src="/logo-light.png"
|
||||
alt="Nearle"
|
||||
width={220}
|
||||
height={36}
|
||||
style={{ width: "160px", height: "auto" }}
|
||||
className="object-contain"
|
||||
/>
|
||||
</Link>
|
||||
<p className="text-sm leading-relaxed text-white/70">
|
||||
India's leading hyperlocal neighborhood network, empowering
|
||||
communities and verified local businesses within 2km.
|
||||
</p>
|
||||
{/* Social Links */}
|
||||
<div className="flex gap-3 mt-2">
|
||||
<a
|
||||
href="#"
|
||||
className="w-10 h-10 rounded-full bg-white/5 border border-white/10 flex items-center justify-center text-white hover:bg-[#E6D7EA] hover:text-[#17001F] transition-all duration-300"
|
||||
aria-label="Share"
|
||||
>
|
||||
<MaterialIcon icon="share" size={20} />
|
||||
</a>
|
||||
<a
|
||||
href="#"
|
||||
className="w-10 h-10 rounded-full bg-white/5 border border-white/10 flex items-center justify-center text-white hover:bg-[#E6D7EA] hover:text-[#17001F] transition-all duration-300"
|
||||
aria-label="Website"
|
||||
>
|
||||
<MaterialIcon icon="public" size={20} />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Col 2: Company Links */}
|
||||
<div>
|
||||
<h5 className="text-sm font-bold uppercase tracking-wider text-white/50 mb-6">
|
||||
Company
|
||||
</h5>
|
||||
<ul className="flex flex-col gap-3">
|
||||
{COMPANY.map((l) => (
|
||||
<li key={l.label}>
|
||||
<Link
|
||||
href={l.href}
|
||||
className="text-sm text-white/70 hover:text-[#E6D7EA] hover:translate-x-1 transition-all inline-block"
|
||||
>
|
||||
{l.label}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Col 3: Partnerships */}
|
||||
<div>
|
||||
<h5 className="text-sm font-bold uppercase tracking-wider text-white/50 mb-6">
|
||||
Partnerships
|
||||
</h5>
|
||||
<ul className="flex flex-col gap-3">
|
||||
{PARTNERSHIPS.map((l) => (
|
||||
<li key={l.label}>
|
||||
<Link
|
||||
href={l.href}
|
||||
className="text-sm text-white/70 hover:text-[#E6D7EA] hover:translate-x-1 transition-all inline-block"
|
||||
>
|
||||
{l.label}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Col 4: Support / Legal */}
|
||||
<div>
|
||||
<h5 className="text-sm font-bold uppercase tracking-wider text-white/50 mb-6">
|
||||
Support & Legal
|
||||
</h5>
|
||||
<ul className="flex flex-col gap-3">
|
||||
{LEGAL.map((l) => (
|
||||
<li key={l.label}>
|
||||
<Link
|
||||
href={l.href}
|
||||
className="text-sm text-white/70 hover:text-[#E6D7EA] hover:translate-x-1 transition-all inline-block"
|
||||
>
|
||||
{l.label}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Col 5: HQ Address & Helpdesk */}
|
||||
<div className="flex flex-col gap-4">
|
||||
<div>
|
||||
<h5 className="text-sm font-bold uppercase tracking-wider text-white/50 mb-4">
|
||||
Visit Nearle
|
||||
</h5>
|
||||
<p className="text-xs leading-relaxed text-white/60">
|
||||
424, Diwan Bahadur Rd,
|
||||
<br />
|
||||
Opposite to Sri Krishna Sweets,
|
||||
<br />
|
||||
R.S. Puram, Coimbatore,
|
||||
<br />
|
||||
Tamil Nadu 641002
|
||||
</p>
|
||||
<a
|
||||
href="https://maps.google.com/?q=424,+Diwan+Bahadur+Rd,+Opposite+To+Sri+Krishna+Sweets,+R.S.+Puram,+Coimbatore,+Tamil+Nadu+641002"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="mt-3 inline-flex items-center gap-1.5 px-3.5 py-1.5 rounded-xl border border-white/10 hover:border-[#E6D7EA]/50 text-white/80 hover:text-[#E6D7EA] text-xs font-bold transition-all duration-300"
|
||||
>
|
||||
<MaterialIcon icon="location_on" size={14} />
|
||||
<span>Get Directions</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="border-t border-white/10 pt-4 flex flex-col gap-2">
|
||||
<p className="text-[10px] font-bold text-white/40 uppercase tracking-widest">
|
||||
Neighborhood Helpdesk
|
||||
</p>
|
||||
<a
|
||||
href="tel:+919092068666"
|
||||
className="flex items-center gap-2 text-white hover:text-[#E6D7EA] transition-all"
|
||||
>
|
||||
<MaterialIcon
|
||||
icon="phone"
|
||||
size={16}
|
||||
className="text-[#E6D7EA] shrink-0"
|
||||
/>
|
||||
<span className="text-sm font-black tracking-tight">
|
||||
+91 90920 68666
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Bottom Copyright Divider & Bar */}
|
||||
<div className="mt-12 pt-6 border-t border-white/10 relative z-10 flex flex-col sm:flex-row justify-between items-center gap-4 text-xs text-white/40">
|
||||
<p>© {new Date().getFullYear()} Nearle. All rights reserved.</p>
|
||||
<div className="flex flex-wrap gap-x-6 gap-y-2 justify-center">
|
||||
{LEGAL.map((link) => (
|
||||
<Link
|
||||
key={link.label}
|
||||
href={link.href}
|
||||
className="hover:text-[#E6D7EA] transition-colors"
|
||||
>
|
||||
{link.label}
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
|
||||
export default Footer;
|
||||
@@ -1,209 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import Image from "next/image";
|
||||
import { motion } from "framer-motion";
|
||||
import { GlassInfoCard } from "../ui/GlassInfoCard";
|
||||
import { scaleIn, viewport } from "@/lib/animations";
|
||||
import type { Variants } from "framer-motion";
|
||||
|
||||
type GlassCardItem = {
|
||||
text: string;
|
||||
icon?: string;
|
||||
};
|
||||
|
||||
type HeroVisualCollageProps = {
|
||||
centerImage: string;
|
||||
leftImage?: string;
|
||||
rightImage?: string;
|
||||
glassCards: GlassCardItem[];
|
||||
isPhoneCenter?: boolean;
|
||||
cardVariant?: Variants;
|
||||
};
|
||||
|
||||
const leftPanelVariant: Variants = {
|
||||
hidden: { opacity: 0, x: -28 },
|
||||
visible: {
|
||||
opacity: 1,
|
||||
x: 0,
|
||||
transition: { duration: 0.6, ease: [0.22, 1, 0.36, 1] as [number, number, number, number] },
|
||||
},
|
||||
};
|
||||
|
||||
const rightPanelVariant: Variants = {
|
||||
hidden: { opacity: 0, x: 28 },
|
||||
visible: {
|
||||
opacity: 1,
|
||||
x: 0,
|
||||
transition: { duration: 0.6, ease: [0.22, 1, 0.36, 1] as [number, number, number, number] },
|
||||
},
|
||||
};
|
||||
|
||||
const glasscardVariant: Variants = {
|
||||
hidden: { opacity: 0, scale: 0.88, y: 8 },
|
||||
visible: {
|
||||
opacity: 1,
|
||||
scale: 1,
|
||||
y: 0,
|
||||
transition: { type: "spring", stiffness: 260, damping: 22 },
|
||||
},
|
||||
};
|
||||
|
||||
const glassCardStagger: Variants = {
|
||||
hidden: {},
|
||||
visible: { transition: { staggerChildren: 0.1, delayChildren: 0.3 } },
|
||||
};
|
||||
|
||||
export function HeroVisualCollage({
|
||||
centerImage,
|
||||
leftImage,
|
||||
rightImage,
|
||||
glassCards,
|
||||
isPhoneCenter = true,
|
||||
cardVariant,
|
||||
}: HeroVisualCollageProps) {
|
||||
const activeCardVariant = cardVariant ?? glasscardVariant;
|
||||
return (
|
||||
<div className="relative w-full h-[380px] sm:h-[450px] lg:h-[500px] max-w-[540px] mx-auto flex items-center justify-center select-none">
|
||||
{/* Decorative backgrounds */}
|
||||
<div className="absolute w-[240px] h-[240px] rounded-full bg-[#7C3AED]/10 blur-[60px] -z-10" />
|
||||
|
||||
<div className="absolute -top-4 -right-4 w-32 h-32 text-[#6330D6]/10 -z-10 opacity-20">
|
||||
<svg className="w-full h-full" fill="currentColor">
|
||||
<pattern id="collage-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(#collage-dots)" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
|
||||
{/* LEFT IMAGE PANEL */}
|
||||
{leftImage && (
|
||||
<motion.div
|
||||
className="absolute left-2 sm:left-4 top-[15%] w-[100px] sm:w-[130px] h-[180px] sm:h-[220px] rounded-[18px] overflow-hidden border-2 border-white shadow-[0_8px_24px_rgba(0,0,0,0.06)] z-10"
|
||||
variants={leftPanelVariant}
|
||||
initial="hidden"
|
||||
whileInView="visible"
|
||||
viewport={viewport}
|
||||
whileHover={{ scale: 1.04, transition: { duration: 0.25, ease: [0.22, 1, 0.36, 1] } }}
|
||||
>
|
||||
<Image
|
||||
src={leftImage}
|
||||
alt="Collage left asset"
|
||||
fill
|
||||
className="object-cover"
|
||||
sizes="(max-width: 640px) 100px, 130px"
|
||||
/>
|
||||
</motion.div>
|
||||
)}
|
||||
|
||||
{/* RIGHT IMAGE PANEL */}
|
||||
{rightImage && (
|
||||
<motion.div
|
||||
className="absolute right-2 sm:right-4 bottom-[15%] w-[100px] sm:w-[130px] h-[180px] sm:h-[220px] rounded-[18px] overflow-hidden border-2 border-white shadow-[0_8px_24px_rgba(0,0,0,0.06)] z-10"
|
||||
variants={rightPanelVariant}
|
||||
initial="hidden"
|
||||
whileInView="visible"
|
||||
viewport={viewport}
|
||||
whileHover={{ scale: 1.04, transition: { duration: 0.25, ease: [0.22, 1, 0.36, 1] } }}
|
||||
>
|
||||
<Image
|
||||
src={rightImage}
|
||||
alt="Collage right asset"
|
||||
fill
|
||||
className="object-cover"
|
||||
sizes="(max-width: 640px) 100px, 130px"
|
||||
/>
|
||||
</motion.div>
|
||||
)}
|
||||
|
||||
{/* CENTER COMPONENT */}
|
||||
<motion.div
|
||||
className="relative z-20"
|
||||
variants={scaleIn}
|
||||
initial="hidden"
|
||||
whileInView="visible"
|
||||
viewport={viewport}
|
||||
>
|
||||
{isPhoneCenter ? (
|
||||
<div className="relative w-[180px] sm:w-[220px] h-[360px] sm:h-[440px] rounded-[36px] border-[5px] sm:border-[6px] border-white/95 shadow-[0_20px_50px_rgba(99,48,214,0.12)] bg-[#FAF8FC] overflow-hidden flex flex-col justify-center items-center">
|
||||
<Image
|
||||
src={centerImage}
|
||||
alt="Phone Mockup Screen"
|
||||
fill
|
||||
className="object-cover"
|
||||
sizes="(max-width: 640px) 180px, 220px"
|
||||
priority
|
||||
fetchPriority="high"
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div className="relative w-[180px] sm:w-[220px] h-[280px] sm:h-[340px] rounded-[24px] border-[5px] sm:border-[6px] border-white/95 shadow-[0_20px_40px_rgba(99,48,214,0.1)] bg-[#FAF8FC] overflow-hidden flex items-center justify-center p-6">
|
||||
<Image
|
||||
src={centerImage}
|
||||
alt="Central logo panel"
|
||||
width={160}
|
||||
height={160}
|
||||
className="object-contain max-h-[140px] w-auto motion-safe:animate-[pulse_6s_infinite]"
|
||||
priority
|
||||
fetchPriority="high"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</motion.div>
|
||||
|
||||
{/* FLOATING GLASS CARDS — stagger in after center */}
|
||||
{glassCards.length > 0 && (
|
||||
<motion.div
|
||||
className="absolute inset-0 z-30 pointer-events-none"
|
||||
variants={glassCardStagger}
|
||||
initial="hidden"
|
||||
whileInView="visible"
|
||||
viewport={viewport}
|
||||
>
|
||||
{glassCards[0] && (
|
||||
<motion.div
|
||||
variants={activeCardVariant}
|
||||
className="absolute right-0 sm:right-[5%] top-[10%] pointer-events-auto"
|
||||
whileHover={{ y: -2, transition: { duration: 0.2, ease: [0.22, 1, 0.36, 1] } }}
|
||||
>
|
||||
<GlassInfoCard
|
||||
text={glassCards[0].text}
|
||||
icon={glassCards[0].icon}
|
||||
className="scale-90 sm:scale-100"
|
||||
/>
|
||||
</motion.div>
|
||||
)}
|
||||
|
||||
{glassCards[1] && (
|
||||
<motion.div
|
||||
variants={activeCardVariant}
|
||||
className="absolute left-0 sm:left-[5%] bottom-[10%] pointer-events-auto"
|
||||
whileHover={{ y: -2, transition: { duration: 0.2, ease: [0.22, 1, 0.36, 1] } }}
|
||||
>
|
||||
<GlassInfoCard
|
||||
text={glassCards[1].text}
|
||||
icon={glassCards[1].icon}
|
||||
className="scale-90 sm:scale-100"
|
||||
/>
|
||||
</motion.div>
|
||||
)}
|
||||
|
||||
{glassCards[2] && (
|
||||
<motion.div
|
||||
variants={activeCardVariant}
|
||||
className="absolute left-[5%] top-[45%] pointer-events-auto"
|
||||
whileHover={{ y: -2, transition: { duration: 0.2, ease: [0.22, 1, 0.36, 1] } }}
|
||||
>
|
||||
<GlassInfoCard
|
||||
text={glassCards[2].text}
|
||||
icon={glassCards[2].icon}
|
||||
className="scale-90 sm:scale-100"
|
||||
/>
|
||||
</motion.div>
|
||||
)}
|
||||
</motion.div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
import { MaterialIcon } from "./MaterialIcon";
|
||||
|
||||
type GlassInfoCardProps = {
|
||||
text: string;
|
||||
icon?: string;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
export function GlassInfoCard({ text, icon, className = "" }: GlassInfoCardProps) {
|
||||
return (
|
||||
<div
|
||||
className={`bg-white/80 backdrop-blur-md border border-white/40 shadow-[0_8px_24px_rgba(99,48,214,0.08)] rounded-[16px] px-4 py-2.5 flex items-center gap-2.5 select-none ${className}`}
|
||||
>
|
||||
{icon ? (
|
||||
<div className="w-6 h-6 rounded-full bg-[#6330D6]/10 text-[#6330D6] flex items-center justify-center shrink-0">
|
||||
<MaterialIcon icon={icon} size={14} />
|
||||
</div>
|
||||
) : (
|
||||
<span className="w-2.5 h-2.5 rounded-full bg-[#6330D6] shrink-0 motion-safe:animate-pulse" />
|
||||
)}
|
||||
<span className="text-sm font-extrabold text-[#16001D] whitespace-nowrap">
|
||||
{text}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user