update redesign

This commit is contained in:
2026-06-24 18:31:06 +05:30
parent 6ddfc57217
commit d3c7d93cef
23 changed files with 1756 additions and 1518 deletions

View File

@@ -208,7 +208,7 @@ export function ContactForm() {
<button
type="submit"
disabled={isSubmitting}
className="w-full bg-primary hover:bg-primary-container disabled:bg-primary-container/60 text-on-primary font-black px-8 py-4 rounded-xl text-label-md hover:shadow-lg transition-all duration-300 hover:-translate-y-0.5 active:translate-y-0 active:scale-[0.98] flex items-center justify-center gap-2 cursor-pointer"
className="w-full bg-[#6330D6] hover:bg-[#5225b8] disabled:bg-[#6330D6]/60 text-on-primary font-black px-8 py-4 rounded-xl text-label-md hover:shadow-lg transition-all duration-300 hover:-translate-y-0.5 active:translate-y-0 active:scale-[0.98] flex items-center justify-center gap-2 cursor-pointer"
>
{isSubmitting ? (
<>

View File

@@ -31,7 +31,7 @@ const BENEFITS = [
export function BusinessSection() {
return (
<section className="pt-4 md:pt-5 lg:pt-6 pb-4 md:pb-5 lg:pb-6">
<section className="px-6 py-12 md:py-16">
<div className="w-full">
{/* Merchant Section Grid */}

View File

@@ -1,179 +1,178 @@
import Image from "next/image";
import Link from "next/link";
import Image from "next/image";
import { MaterialIcon } from "@/components/ui/MaterialIcon";
const QUICK_LINKS = [
{
name: "Daily Groceries",
icon: "shopping_basket",
label: "Fresh & On-Time",
},
{
name: "Hot Meals",
icon: "fastfood",
label: "Quick & tasty",
},
{
name: "wellness ",
icon: "medical_services",
label: "Essential & Trusted",
},
{
name: "More Services",
icon: "store",
label: "Explore More",
},
const PROOF_ITEMS = [
{ label: "1000+", text: "Verified Stores", icon: "store" },
{ label: "2km", text: "Neighbourhood Coverage", icon: "location_on" },
{ label: "50,000+", text: "Happy Customers", icon: "mood" },
{ label: "4.7 ★", text: "Average Rating", icon: "star" },
];
export function Hero() {
return (
<section className="relative pb-4 md:pb-6">
<div className="relative overflow-hidden rounded-[1.75rem] md:rounded-[2.25rem] bg-[#16001F]">
{/* ─── Base Dark Background Panel (Clipped diagonally) ─── */}
<div className="hero-dark-panel select-none pointer-events-none">
{/* Subtle Background Dot Texture */}
<div className="hero-map-layer select-none">
<Image
src="/images/slider-glob.png"
alt="Subtle Background"
fill
sizes="(max-width: 768px) 100vw, 40vw"
className="object-contain object-left-top"
priority
/>
<section className="relative overflow-hidden bg-white select-none w-full">
{/* ─── DECORATIONS (BEHIND CONTENT) ─── */}
{/* 1. Large pale lavender partial circle (top-left) */}
<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" />
{/* 2. Purple solid circle (center-right around collage) */}
<div className="hidden lg:block absolute right-[22%] top-[38%] w-[84px] h-[84px] rounded-full bg-[#6D28D9] z-0 shadow-[0_8px_32px_rgba(109,40,217,0.3)] pointer-events-none animate-pulse" />
{/* 3. Striped purple circle (lower-middle collage area) */}
<div
className="hidden lg:block absolute left-[45%] bottom-[15%] w-[100px] h-[100px] rounded-full opacity-80 z-0 pointer-events-none"
style={{
backgroundImage: 'repeating-linear-gradient(45deg, rgba(109, 40, 217, 0.2) 0px, rgba(109, 40, 217, 0.2) 2px, transparent 2px, transparent 8px)'
}}
/>
{/* 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>
{/* 5. Three small X marks */}
<div className="absolute top-[8%] left-[48%] text-[#6D28D9]/25 font-bold text-xl pointer-events-none select-none z-0"></div>
<div className="hidden lg:block absolute top-[52%] left-[44%] text-[#6D28D9]/20 font-bold text-lg pointer-events-none select-none z-0"></div>
<div className="absolute bottom-[14%] right-[5%] text-[#6D28D9]/25 font-bold text-xl pointer-events-none select-none z-0"></div>
{/* 6. Large partial purple circle (bottom-right corner) */}
<div className="absolute bottom-[-100px] right-[-100px] w-[200px] h-[200px] rounded-full bg-[#7C3AED]/80 z-0 pointer-events-none" />
{/* ─── TWO-COLUMN CONTENT GRID ─── */}
<div className="relative mx-auto grid min-h-[650px] grid-cols-1 lg:grid-cols-[0.92fr_1.08fr] items-center px-8 py-16 md:px-12 lg:px-16 xl:px-20 z-10 gap-12 lg:gap-6">
{/* LEFT COLUMN: Editorial Typography & Copy */}
<div className="flex flex-col text-left max-w-xl z-20 relative">
<span 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
</span>
<h1 className="font-display text-4xl sm:text-5xl lg:text-[68px] xl:text-[76px] font-black text-[#16001D] leading-[0.95] tracking-[-0.05em]">
Everything Local.
<br />
Everything <span className="text-[#6D28D9]">Near.</span>
</h1>
<p 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.
</p>
<div className="flex flex-col sm:flex-row gap-3.5 mt-8 w-full sm:w-auto">
<Link
href="/people"
className="bg-[#6D28D9] hover:bg-[#5225b8] text-white font-black px-8 py-3.5 rounded-xl text-sm md:text-base text-center shadow-md hover:shadow-lg transition-all duration-200 active:scale-98"
>
Explore Stores
</Link>
<Link
href="/people#download-section"
className="border-2 border-[#6D28D9]/20 hover:border-[#6D28D9]/40 text-[#6D28D9] font-black px-8 py-3.5 rounded-xl text-sm md:text-base text-center transition-all duration-200 hover:bg-[#6D28D9]/5 active:scale-98"
>
Get the App
</Link>
</div>
{/* Soft purple radial glow */}
<div className="absolute right-0 top-1/4 z-0 h-[60%] w-[45%] rounded-full bg-primary/45 blur-[120px] opacity-50 pointer-events-none" />
</div>
{/* ─── Main Content Wrapper ─── */}
<div className="hero-stage min-h-0 pb-10 md:pb-12 relative w-full flex flex-col z-10 md:justify-center md:items-start">
{/* Left Column: Text & Search Content */}
<div className="hero-content text-white select-none">
<span className="inline-block text-xs font-black tracking-widest uppercase mb-5 bg-brand-accent/15 px-4 py-1.5 rounded-full border border-brand-accent/20 text-brand-accent">
Neighbourhood commerce, made simple
</span>
<h1 className="text-4xl sm:text-5xl lg:text-[52px] xl:text-[62px] 2xl:text-[74px] lg:leading-[1.15] font-display font-black tracking-tight mb-8">
Your Favourite Local Stores,
<br />
<span className="text-brand-accent drop-shadow-md">
Now at Your Doorstep.
</span>
</h1>
<p className="text-body-lg md:text-[20px] md:leading-8 text-white/90 mb-10 leading-relaxed max-w-2xl">
Order groceries, medicines, food and everyday essentials from trusted stores near you all in one convenient app.
</p>
{/* CTAs */}
<div className="flex flex-col md:flex-row md:flex-wrap gap-4 mt-8 w-full md:w-auto">
<Link
href="/people"
className="bg-brand-accent hover:bg-brand-accent-light text-brand-dark font-black px-8 py-4 rounded-xl text-sm md:text-base hover:shadow-xl transition-all duration-300 active:scale-95 flex items-center justify-center gap-2 w-full md:w-auto min-h-[48px] whitespace-nowrap"
>
Explore Nearby Stores
</Link>
<Link
href="/businesses"
className="bg-white/10 hover:bg-white/15 border border-white/20 text-white font-black px-8 py-4 rounded-xl text-sm md:text-base transition-all duration-300 active:scale-95 flex items-center justify-center gap-2 w-full md:w-auto min-h-[48px] whitespace-nowrap"
>
List Your Store
</Link>
{/* RIGHT COLUMN: Creative Overlapping Strips Collage */}
<div className="w-full z-20">
{/* DESKTOP LAYOUT (lg and above) */}
<div className="hidden lg:block relative h-[500px] lg:h-[560px] w-full">
{/* left image: absolute left-[10%] top-[20%] w-[170px] h-[360px] */}
<div className="absolute left-[10%] top-[20%] w-[170px] h-[360px] rounded-[1.5rem] overflow-hidden shadow-lg border-2 border-white z-10 transition-transform duration-300 hover:scale-[1.02]">
<Image
src="/images/cat-daily-essentials.png"
alt="Local grocery products"
fill
className="object-cover"
sizes="170px"
/>
</div>
{/* Trust points */}
<div className="flex flex-wrap gap-x-8 gap-y-3 mt-12 text-sm md:text-base text-white/90">
<div className="flex items-center gap-2">
<MaterialIcon icon="store" size={18} className="text-brand-accent" />
<span>Real local shops</span>
</div>
<div className="flex items-center gap-2">
<MaterialIcon icon="sell" size={18} className="text-brand-accent" />
<span>Fair local prices</span>
</div>
<div className="flex items-center gap-2">
<MaterialIcon icon="local_shipping" size={18} className="text-brand-accent" />
<span>Neighbourhood delivery</span>
</div>
</div>
{/* Mobile/Tablet Only Nearle Bag Logo with context pins */}
<div className="hero-mobile-logo block lg:hidden mt-8 select-none pointer-events-none relative">
<div className="relative w-[280px] h-[230px] mx-auto">
<Image
src="/nearlenewlogo.png"
alt="Nearle delivery"
fill
sizes="(max-width: 1023px) 280px, 0px"
className="object-contain drop-shadow-2xl"
priority
/>
</div>
</div>
</div>
{/* Right Column: Centered Nearle bag visual with local commerce context pins and route line */}
<div className="hero-visual-layer select-none pointer-events-none relative">
<div className="hero-visual-panel" />
<div className="hero-visual-image relative">
<Image
src="/nearlenewlogo.png"
alt="Nearle delivery"
fill
sizes="(max-width: 768px) 95vw, 48vw"
className="object-contain drop-shadow-2xl"
{/* middle image: absolute left-[38%] top-[8%] w-[190px] h-[430px] */}
<div className="absolute left-[38%] top-[8%] w-[190px] h-[430px] rounded-[1.5rem] overflow-hidden shadow-xl border-2 border-white z-20 transition-transform duration-300 hover:scale-[1.02]">
<Image
src="/Nearle Business.png"
alt="Local merchant delivery"
fill
className="object-cover"
sizes="190px"
priority
/>
</div>
</div>
</div>
</div>
{/* Overlapping Quick Category Links */}
<div className="service-cards-wrapper max-w-container-max mx-auto relative z-20 -mt-8 md:-mt-10 lg:-mt-12">
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
{QUICK_LINKS.map((item) => (
<div
key={item.name}
className="flex items-center gap-4 bg-white p-5 rounded-2xl border border-outline-variant/15 shadow-xl hover:shadow-2xl premium-card cursor-pointer group"
>
<div className="flex-shrink-0 w-12 h-12 rounded-full bg-brand-accent/10 flex items-center justify-center group-hover:bg-brand-accent/20 transition-colors">
<MaterialIcon
icon={item.icon}
size={24}
className="text-brand-accent"
/>
</div>
<div className="flex-grow">
<h3 className="text-sm md:text-base font-extrabold text-brand-dark group-hover:text-primary transition-colors">
{item.name}
</h3>
<p className="text-xs text-on-surface-variant font-medium mt-0.5 leading-tight">
{item.label}
</p>
</div>
<div className="flex-shrink-0 w-8 h-8 rounded-full bg-surface-container flex items-center justify-center opacity-0 group-hover:opacity-100 group-hover:translate-x-1 transition-all duration-300">
<MaterialIcon
icon="arrow_forward"
size={16}
className="text-primary"
/>
</div>
{/* right image: absolute right-[2%] top-[18%] w-[180px] h-[390px] */}
<div className="absolute right-[2%] top-[18%] w-[180px] h-[390px] rounded-[1.5rem] overflow-hidden shadow-lg border-2 border-white z-10 transition-transform duration-300 hover:scale-[1.02]">
<Image
src="/nearle people.png"
alt="Local customer shopping"
fill
className="object-cover"
sizes="180px"
/>
</div>
))}
</div>
{/* MOBILE/TABLET COLLAGE (below lg) */}
<div className="lg:hidden flex items-center justify-center gap-2 mt-2 w-full relative h-[280px]">
<div className="relative w-[95px] h-[200px] rounded-2xl overflow-hidden border border-white shadow-md z-10">
<Image
src="/images/cat-daily-essentials.png"
alt="Grocery products"
fill
className="object-cover"
sizes="95px"
/>
</div>
<div className="relative w-[115px] h-[240px] rounded-2xl overflow-hidden border border-white shadow-lg -mx-5 z-20">
<Image
src="/Nearle Business.png"
alt="Merchant"
fill
className="object-cover"
sizes="115px"
/>
</div>
<div className="relative w-[105px] h-[220px] rounded-2xl overflow-hidden border border-white shadow-md z-10">
<Image
src="/nearle people.png"
alt="Customer"
fill
className="object-cover"
sizes="105px"
/>
</div>
</div>
</div>
</div>
{/* ─── BOTTOM PROOF STATS ROW ─── */}
<div className="grid grid-cols-2 md:grid-cols-4 gap-6 border-t border-[#EEE7F4] bg-white px-8 py-8 md:px-12 lg:px-16 z-20 relative">
{PROOF_ITEMS.map((item) => (
<div key={item.label} className="flex flex-col items-start text-left pl-2 md:pl-4">
<div className="w-8 h-8 rounded-full bg-[#6D28D9]/10 text-[#6D28D9] flex items-center justify-center mb-3">
<MaterialIcon icon={item.icon} size={16} />
</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>
))}
</div>
</section>
);
}

View File

@@ -26,7 +26,7 @@ const STEPS = [
export function HowItWorks() {
return (
<section className="border-t border-brand-dark/10 pt-12 md:pt-16 lg:pt-20 pb-6 md:pb-8 lg:pb-10">
<section className="px-6 py-12 md:py-16">
<div className="w-full">
{/* Header Section */}
<div className="text-center mb-12 md:mb-16">

View File

@@ -27,7 +27,7 @@ const FEATURES = [
export function HyperlocalFeatures() {
return (
<section className="pt-4 md:pt-5 lg:pt-6 pb-2 md:pb-3 lg:pb-4 relative">
<section className="px-6 py-12 md:py-16 relative">
{/* Scoped CSS styles for precise layout enforcement */}
<style>{`
@media (min-width: 901px) {

View File

@@ -55,7 +55,7 @@ const CATEGORIES = [
export function ServiceCategories() {
return (
<section className="pt-10 md:pt-14 lg:pt-16 pb-2 md:pb-3 lg:pb-4">
<section className="px-6 pt-20 md:pt-24 lg:pt-28 pb-12 md:pb-16">
<div className="w-full">
{/* Header Section */}
<div className="flex flex-col md:flex-row justify-between items-start md:items-end mb-12 md:mb-16 gap-6">

View File

@@ -9,7 +9,7 @@ const FLOW_STEPS = [
export function StoreQRSection() {
return (
<section id="download" className="bg-gradient-to-br from-[#1C0024] to-[#0D0012] rounded-[1.75rem] md:rounded-[2.25rem] border border-white/10 shadow-[0_20px_50px_rgba(20,0,30,0.28)] overflow-hidden py-16 md:py-20 px-6 md:px-12 lg:px-20 text-white relative flex items-center mt-2 md:mt-3 mb-2 md:mb-3">
<section id="download" className="section-card-dark py-16 md:py-20 px-6 md:px-12 lg:px-20 text-white relative flex items-center">
{/* 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="absolute left-[-10%] bottom-[-10%] w-[50%] h-[50%] rounded-full bg-primary/10 blur-[120px] pointer-events-none" />

View File

@@ -29,7 +29,7 @@ const CARDS = [
export function WhyNearle() {
return (
<section className="pt-4 md:pt-5 lg:pt-6 pb-4 md:pb-5 lg:pb-6">
<section className="px-6 py-12 md:py-16">
<div className="w-full">
{/* Header Section */}
<div className="text-center mb-8 md:mb-10">

View File

@@ -2,8 +2,7 @@
import Link from "next/link";
import Image from "next/image";
import { usePathname } from "next/navigation";
import React, { useState } from "react";
import React from "react";
import { MaterialIcon } from "@/components/ui/MaterialIcon";
const COMPANY = [
@@ -27,392 +26,131 @@ const LEGAL = [
{ label: "Sitemap", href: "#" },
];
type FooterFormData = {
name: string;
phone: string;
email: string;
message: string;
};
type FooterFormErrors = {
name?: string;
phone?: string;
email?: string;
message?: string;
};
export function Footer() {
const pathname = usePathname();
const isContactPage = pathname?.startsWith("/contact");
// Form states
const [formData, setFormData] = useState<FooterFormData>({
name: "",
phone: "",
email: "",
message: "",
});
const [errors, setErrors] = useState<FooterFormErrors>({});
const [isSubmitting, setIsSubmitting] = useState(false);
const [submitSuccess, setSubmitSuccess] = useState(false);
const handleInputChange = (
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
) => {
const { name, value } = e.target;
setFormData((prev) => ({
...prev,
[name]: value,
}));
if (errors[name as keyof FooterFormErrors]) {
setErrors((prev) => ({
...prev,
[name]: undefined,
}));
}
};
const validateForm = (): boolean => {
const tempErrors: FooterFormErrors = {};
let isValid = true;
if (!formData.name.trim()) {
tempErrors.name = "Name is required";
isValid = false;
}
if (!formData.phone.trim()) {
tempErrors.phone = "Phone is required";
isValid = false;
}
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!formData.email.trim()) {
tempErrors.email = "Email is required";
isValid = false;
} else if (!emailRegex.test(formData.email)) {
tempErrors.email = "Please enter a valid email address";
isValid = false;
}
if (!formData.message.trim()) {
tempErrors.message = "Message is required";
isValid = false;
}
setErrors(tempErrors);
return isValid;
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!validateForm()) return;
setIsSubmitting(true);
// Simulate API delay
await new Promise((resolve) => setTimeout(resolve, 1000));
setIsSubmitting(false);
setSubmitSuccess(true);
setFormData({ name: "", phone: "", email: "", message: "" });
// Hide success alert after 5 seconds
setTimeout(() => {
setSubmitSuccess(false);
}, 5000);
};
const brandCol = (
<div className="footer-brand min-w-0 self-start">
<Link href="/" className="mb-4 inline-block">
<Image
src="/logo-v2.png"
alt="Nearle"
width={220}
height={36}
style={{ width: "210px", height: "auto" }}
className="object-contain"
/>
</Link>
<p className="footer-desc mb-4 text-white/80">
India&apos;s leading hyperlocal neighborhood network, empowering
communities and verified local businesses within 2km.
</p>
{/* Social Links */}
<div className="flex gap-4">
<a href="#" className="footer-social-link" aria-label="Share">
<MaterialIcon icon="share" size={24} />
</a>
<a href="#" className="footer-social-link" aria-label="Website">
<MaterialIcon icon="public" size={24} />
</a>
</div>
</div>
);
return (
<footer className="bg-[#E6D7EA] px-3 sm:px-4 md:px-5 lg:px-6 xl:px-8 pb-0 w-full mt-3 md:mt-4">
<div className="mx-auto" style={{ maxWidth: "min(100% - 48px, 1520px)" }}>
<div className="bg-[#120217] rounded-[1.5rem] md:rounded-[2rem] lg:rounded-[2.5rem] overflow-hidden border border-white/10 shadow-[0_18px_45px_rgba(20,0,30,0.28)]">
{/* Top Helpdesk Bar */}
<div className="bg-[#2A0838] border-b border-white/10 px-5 py-4 md:px-8 md:py-5 flex flex-col md:flex-row justify-between items-center gap-6">
<div className="flex items-center gap-4 text-white">
<div className="w-12 h-12 rounded-full bg-brand-accent text-brand-dark flex items-center justify-center shadow-lg shrink-0">
<MaterialIcon icon="headset_mic" size={24} />
</div>
<div className="text-left">
<h4 className="text-headline-md font-black text-white">
24/7 Neighborhood Helpdesk
</h4>
<p className="text-sm font-semibold text-white/70 mt-0.5">
Need immediate assistance with an order or local service?
</p>
<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&apos;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 HQ</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:+918049123456"
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 80 4912 3456</span>
</a>
</div>
</div>
<a
href="tel:+918049123456"
className="flex items-center gap-3 bg-brand-accent hover:bg-brand-accent-light text-brand-dark font-black px-6 py-3 rounded-full text-base shadow-lg transition-all duration-300 hover:-translate-y-0.5 shrink-0"
>
<MaterialIcon
icon="phone"
size={20}
className="animate-pulse-subtle"
/>
<span>+91 80 4912 3456</span>
</a>
</div>
{/* Main Footer Content */}
<div className="px-5 pt-10 pb-8 md:px-8 md:pt-12 md:pb-10 lg:px-12 lg:pt-12 lg:pb-10 text-white">
<div
className={
isContactPage
? "grid grid-cols-1 sm:grid-cols-3 gap-8 lg:gap-10"
: "grid grid-cols-1 lg:grid-cols-[minmax(0,1fr)_minmax(500px,560px)] gap-10 xl:gap-14 items-start"
}
>
{isContactPage ? (
<>
{/* Brand Column */}
{brandCol}
{/* Company Links */}
<div className="footer-company min-w-0 self-start">
<FooterCol title="Company" links={COMPANY} />
</div>
{/* Partnerships Links */}
<div className="footer-partnerships min-w-0 self-start">
<FooterCol title="Partnerships" links={PARTNERSHIPS} />
</div>
</>
) : (
<>
<div className="flex flex-col self-start w-full">
<div className="grid grid-cols-1 sm:grid-cols-3 gap-8 lg:gap-10">
{/* Brand Column */}
{brandCol}
{/* Company Links */}
<div className="footer-company min-w-0 self-start">
<FooterCol title="Company" links={COMPANY} />
</div>
{/* Partnerships Links */}
<div className="footer-partnerships min-w-0 self-start">
<FooterCol title="Partnerships" links={PARTNERSHIPS} />
</div>
</div>
{/* HQ Office Location & Directions block */}
<div className="mt-8 border-t border-white/10 pt-7 max-w-[520px] text-left">
<p className="text-[11px] font-black uppercase tracking-[0.18em] text-brand-accent">
VISIT NEARLE HQ
</p>
<h4 className="mt-2 font-display text-xl md:text-2xl font-black text-white">
Meet the team behind your neighbourhood.
</h4>
<p className="mt-3 text-sm leading-6 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-4 inline-flex items-center gap-2 px-4 py-2 rounded-xl border border-white/15 hover:border-brand-accent/50 text-white hover:text-brand-accent text-xs md:text-sm font-black transition-all duration-300"
>
<MaterialIcon icon="location_on" size={16} />
<span>Get Directions</span>
</a>
</div>
</div>
{/* Contact Form Card */}
<div className="footer-contact-wrap w-full self-start">
<div className="footer-contact-card bg-white text-brand-dark shadow-2xl border border-outline-variant/15 relative overflow-hidden w-full max-w-[540px] lg:ml-auto p-7 md:p-8 lg:p-9">
{/* Background Glow Decors */}
<div className="absolute top-0 right-0 w-24 h-24 bg-primary/5 rounded-full blur-2xl" />
<div className="absolute bottom-0 left-0 w-24 h-24 bg-secondary/5 rounded-full blur-2xl" />
<div className="relative z-10 text-center lg:text-left">
<h3 className="footer-contact-title font-display text-2xl md:text-3xl font-black text-brand-dark tracking-tight">
Send us a Message
</h3>
<p className="footer-contact-subtitle text-sm md:text-base mt-1 mb-5">
We shall guide you through our Neighbourhood Experts.
</p>
<form onSubmit={handleSubmit} className="space-y-3">
{submitSuccess && (
<div className="p-3 bg-secondary/10 border border-secondary/20 text-secondary text-body-sm font-bold rounded-xl flex items-center justify-center gap-1.5 animate-bounce-subtle">
<MaterialIcon icon="check_circle" size={16} />
<span>Message sent successfully!</span>
</div>
)}
<div className="footer-form-row grid grid-cols-1 sm:grid-cols-2 gap-4">
<div className="flex flex-col text-left">
<label
htmlFor="footer-field-name"
className="text-xs font-black text-brand-dark/70 mb-1.5"
>
Your Name
</label>
<input
type="text"
id="footer-field-name"
name="name"
value={formData.name}
onChange={handleInputChange}
placeholder="Your Name..."
className={`footer-input h-12 md:h-13 ${errors.name ? "has-error" : ""}`}
/>
{errors.name && (
<span className="footer-error-text">
<MaterialIcon icon="error" size={16} />
{errors.name}
</span>
)}
</div>
<div className="flex flex-col text-left">
<label
htmlFor="footer-field-phone"
className="text-xs font-black text-brand-dark/70 mb-1.5"
>
Your Phone
</label>
<input
type="text"
id="footer-field-phone"
name="phone"
value={formData.phone}
onChange={handleInputChange}
placeholder="Your Phone..."
className={`footer-input h-12 md:h-13 ${errors.phone ? "has-error" : ""}`}
/>
{errors.phone && (
<span className="footer-error-text">
<MaterialIcon icon="error" size={16} />
{errors.phone}
</span>
)}
</div>
</div>
<div className="flex flex-col text-left">
<label
htmlFor="footer-field-email"
className="text-xs font-black text-brand-dark/70 mb-1.5"
>
Your Email Address
</label>
<input
type="email"
id="footer-field-email"
name="email"
value={formData.email}
onChange={handleInputChange}
placeholder="Your Email Address..."
className={`footer-input h-12 md:h-13 ${errors.email ? "has-error" : ""}`}
/>
{errors.email && (
<span className="footer-error-text">
<MaterialIcon icon="error" size={16} />
{errors.email}
</span>
)}
</div>
<div className="flex flex-col text-left">
<label
htmlFor="footer-field-message"
className="text-xs font-black text-brand-dark/70 mb-1.5"
>
Your Message
</label>
<textarea
id="footer-field-message"
name="message"
value={formData.message}
onChange={handleInputChange}
placeholder="Your Message..."
className={`footer-textarea min-h-[120px] md:min-h-[130px] ${errors.message ? "has-error" : ""}`}
/>
{errors.message && (
<span className="footer-error-text">
<MaterialIcon icon="error" size={16} />
{errors.message}
</span>
)}
</div>
<button
type="submit"
disabled={isSubmitting}
className="footer-submit-btn h-12 md:h-13"
>
{isSubmitting ? (
<>
<span className="w-5 h-5 border-2 border-white/30 border-t-white rounded-full animate-spin" />
<span>SUBMITTING...</span>
</>
) : (
<span>SUBMIT</span>
)}
</button>
</form>
</div>
</div>
</div>
</>
)}
</div>
{/* Footer Bottom Bar */}
<div className="mt-8 border-t border-white/10 pt-5 text-xs text-white/45">
<div className="flex flex-col md:flex-row justify-between items-start md:items-center gap-4">
<p>© {new Date().getFullYear()} Nearle. All rights reserved.</p>
<div className="flex flex-col md:flex-row gap-2 md:gap-6 text-left">
{LEGAL.map((link) => (
<Link
key={link.label}
href={link.href}
className="hover:text-[#e0c8f7] transition-colors"
>
{link.label}
</Link>
))}
</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>
@@ -421,28 +159,4 @@ export function Footer() {
);
}
// Ensure default export is also available for Next.js app router client components if needed
export default Footer;
function FooterCol({
title,
links,
}: {
title: string;
links: { label: string; href: string }[];
}) {
return (
<div>
<h5 className="footer-column-title">{title}</h5>
<ul className="footer-links-list">
{links.map((l) => (
<li key={l.label}>
<Link href={l.href} className="footer-link inline-block">
{l.label}
</Link>
</li>
))}
</ul>
</div>
);
}

View File

@@ -0,0 +1,138 @@
import Image from "next/image";
import { GlassInfoCard } from "../ui/GlassInfoCard";
type GlassCardItem = {
text: string;
icon?: string;
};
type HeroVisualCollageProps = {
centerImage: string;
leftImage?: string;
rightImage?: string;
glassCards: GlassCardItem[];
isPhoneCenter?: boolean;
};
export function HeroVisualCollage({
centerImage,
leftImage,
rightImage,
glassCards,
isPhoneCenter = true,
}: HeroVisualCollageProps) {
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 */}
{/* 1. Soft purple circle */}
<div className="absolute w-[240px] h-[240px] rounded-full bg-[#7C3AED]/10 blur-[60px] -z-10" />
{/* 2. SVG Dot grid */}
<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>
{/* 3. Small x marks */}
<div className="absolute top-12 left-6 text-[#6330D6]/15 font-display text-xl font-bold select-none pointer-events-none"></div>
<div className="absolute bottom-16 right-8 text-[#6330D6]/15 font-display text-xl font-bold select-none pointer-events-none"></div>
{/* LEFT IMAGE PANEL (Hidden or compact on small mobile) */}
{leftImage && (
<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 transition-transform hover:scale-105 duration-300">
<Image
src={leftImage}
alt="Collage left asset"
fill
className="object-cover"
sizes="(max-width: 640px) 100px, 130px"
/>
</div>
)}
{/* RIGHT IMAGE PANEL */}
{rightImage && (
<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 transition-transform hover:scale-105 duration-300">
<Image
src={rightImage}
alt="Collage right asset"
fill
className="object-cover"
sizes="(max-width: 640px) 100px, 130px"
/>
</div>
)}
{/* CENTER COMPONENT */}
<div className="relative z-20">
{isPhoneCenter ? (
/* Phone Frame Container */
<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
/>
</div>
) : (
/* Central Logo / Visual Panel */
<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 animate-[pulse_6s_infinite]"
priority
/>
</div>
)}
</div>
{/* FLOATING GLASS CARDS (Positioned Absolute, scaled down on mobile) */}
{glassCards.length > 0 && (
<div className="absolute inset-0 z-30 pointer-events-none">
{/* Card 1: Top Right */}
{glassCards[0] && (
<div className="absolute right-0 sm:right-[5%] top-[10%] pointer-events-auto hover:translate-y-[-2px] transition-transform duration-200">
<GlassInfoCard
text={glassCards[0].text}
icon={glassCards[0].icon}
className="scale-90 sm:scale-100"
/>
</div>
)}
{/* Card 2: Bottom Left */}
{glassCards[1] && (
<div className="absolute left-0 sm:left-[5%] bottom-[10%] pointer-events-auto hover:translate-y-[-2px] transition-transform duration-200">
<GlassInfoCard
text={glassCards[1].text}
icon={glassCards[1].icon}
className="scale-90 sm:scale-100"
/>
</div>
)}
{/* Card 3: Mid Left/Right */}
{glassCards[2] && (
<div className="absolute left-[5%] top-[45%] pointer-events-auto hover:translate-y-[-2px] transition-transform duration-200">
<GlassInfoCard
text={glassCards[2].text}
icon={glassCards[2].icon}
className="scale-90 sm:scale-100"
/>
</div>
)}
</div>
)}
</div>
);
}

View File

@@ -20,8 +20,8 @@ export function Navbar() {
return (
<div className="fixed top-0 left-0 right-0 z-50 w-full flex justify-center pointer-events-none">
<div className="w-full max-w-[1440px] px-4 md:px-8 lg:px-12 pt-5 md:pt-6 pointer-events-auto relative">
<nav className="w-full h-[68px] lg:h-[80px] rounded-[1.75rem] lg:rounded-[2rem] bg-gradient-to-r from-[#65108A] via-[#5A087B] to-[#3A044F] border border-white/10 shadow-[0_18px_40px_rgba(60,0,80,0.25)] backdrop-blur-md px-5 md:px-8 lg:px-10 flex items-center transition-all duration-300">
<div className="w-full max-w-[1920px] px-4 md:px-6 lg:px-8 xl:px-10 2xl:px-12 pt-[18px] md:pt-[24px] pointer-events-auto relative">
<nav className="w-full h-[68px] lg:h-[76px] rounded-full bg-white/88 border border-white/70 shadow-sm backdrop-blur-md px-5 md:px-8 lg:px-10 flex items-center transition-all duration-300">
<div className="grid grid-cols-2 md:grid-cols-[1fr_auto_1fr] items-center w-full h-full">
{/* Left: Brand */}
<div className="flex items-center justify-start">
@@ -30,7 +30,7 @@ export function Navbar() {
className="flex items-center hover:scale-[1.02] transition-transform active:scale-95 duration-200"
>
<Image
src="/logo-light.png"
src="/logo.png"
alt="Nearle"
width={400}
height={50}
@@ -48,13 +48,13 @@ export function Navbar() {
<Link
key={link.label}
href={link.href}
className={`relative py-2 text-[15px] font-medium leading-5 transition-all duration-200 whitespace-nowrap ${
isActive ? "text-white" : "text-white/80 hover:text-white"
className={`relative py-2 text-[15px] font-semibold leading-5 transition-all duration-200 whitespace-nowrap ${
isActive ? "text-[#2A1234]" : "text-[#2A1234]/70 hover:text-[#2A1234]"
} group`}
>
{link.label}
<span
className={`absolute bottom-[-6px] left-1/2 -translate-x-1/2 h-0.5 bg-white rounded-full transition-all duration-300 ${
className={`absolute bottom-[-6px] left-1/2 -translate-x-1/2 h-0.5 bg-[#65149A] rounded-full transition-all duration-300 ${
isActive
? "w-5 opacity-100"
: "w-0 opacity-0 group-hover:w-4 group-hover:opacity-60"
@@ -69,14 +69,14 @@ export function Navbar() {
<div className="flex items-center justify-end gap-3">
<Link
href="/#download"
className="hidden md:inline-flex items-center justify-center bg-white text-[#4d046a] font-bold px-7 h-[46px] rounded-full text-[15px] hover:shadow-[0_8px_24px_rgba(255,255,255,0.2)] hover:scale-[1.03] active:scale-95 transition-all duration-300 whitespace-nowrap"
className="hidden md:inline-flex items-center justify-center bg-[#65149A] text-white font-bold px-7 h-[46px] rounded-full text-[15px] hover:bg-[#7C3AED] hover:shadow-md hover:scale-[1.02] active:scale-95 transition-all duration-300 whitespace-nowrap"
>
Get App
</Link>
{/* Mobile menu toggle */}
<button
className="md:hidden flex items-center justify-center w-10 h-10 rounded-full hover:bg-white/10 text-white transition-all active:scale-90 cursor-pointer"
className="md:hidden flex items-center justify-center w-10 h-10 rounded-full hover:bg-[#2A1234]/5 text-[#2A1234] transition-all active:scale-90 cursor-pointer"
onClick={() => setMobileOpen(!mobileOpen)}
aria-label="Toggle menu"
>
@@ -88,7 +88,7 @@ export function Navbar() {
{/* Mobile Drawer */}
{mobileOpen && (
<div className="absolute top-[calc(100%+12px)] left-4 right-4 z-40 bg-gradient-to-b from-[#5A087B] to-[#3A044F] border border-white/10 rounded-2xl shadow-[0_20px_40px_rgba(0,0,0,0.4)] backdrop-blur-md p-4 md:hidden">
<div className="absolute top-[calc(100%+12px)] left-4 right-4 z-40 bg-white/95 border border-white/50 rounded-2xl shadow-[0_20px_40px_rgba(100,60,120,0.15)] backdrop-blur-md p-4 md:hidden">
<div className="flex flex-col gap-2">
{NAV_LINKS.map((link) => {
const isActive = pathname === link.href;
@@ -98,14 +98,14 @@ export function Navbar() {
href={link.href}
className={`px-4 py-3 text-body-md font-bold rounded-xl transition-all duration-200 flex items-center justify-between ${
isActive
? "bg-white/10 text-white"
: "text-white/85 hover:text-white hover:bg-white/5"
? "bg-[#65149A]/10 text-[#65149A]"
: "text-[#2A1234]/70 hover:text-[#2A1234] hover:bg-[#2A1234]/5"
}`}
onClick={() => setMobileOpen(false)}
>
{link.label}
{isActive && (
<span className="w-1.5 h-1.5 rounded-full bg-white animate-pulse" />
<span className="w-1.5 h-1.5 rounded-full bg-[#65149A] animate-pulse" />
)}
</Link>
);

View File

@@ -0,0 +1,147 @@
"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 PremiumFooter() {
return (
<footer className="bg-gradient-to-br from-[#16001D] to-[#25002F] rounded-[1.5rem] md:rounded-[2rem] overflow-hidden text-white p-8 md:p-12 select-none mx-3 sm:mx-4 md:mx-6 lg:mx-8 mb-3 sm:mb-4 md:mb-6 shadow-[0_12px_40px_rgba(22,0,29,0.22)]">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-8 items-start text-left">
{/* Column 1: Brand & Description */}
<div className="flex flex-col gap-4 lg:col-span-2 pr-0 lg:pr-8">
<Link href="/" className="inline-block">
<Image
src="/logo-light.png"
alt="Nearle"
width={130}
height={30}
className="h-7 w-auto object-contain"
/>
</Link>
<p className="text-xs md:text-sm leading-relaxed text-white/70 max-w-sm">
India&apos;s leading hyperlocal neighborhood network, empowering communities and verified local businesses within a 2km radius.
</p>
{/* Social Icons */}
<div className="flex gap-2.5 mt-2">
<a href="#" className="w-9 h-9 rounded-full bg-white/5 border border-white/10 flex items-center justify-center text-white hover:bg-white hover:text-[#16001D] transition-all duration-300" aria-label="Share">
<MaterialIcon icon="share" size={16} />
</a>
<a href="#" className="w-9 h-9 rounded-full bg-white/5 border border-white/10 flex items-center justify-center text-white hover:bg-white hover:text-[#16001D] transition-all duration-300" aria-label="Website">
<MaterialIcon icon="public" size={16} />
</a>
<a href="#" className="w-9 h-9 rounded-full bg-white/5 border border-white/10 flex items-center justify-center text-white hover:bg-white hover:text-[#16001D] transition-all duration-300" aria-label="Help">
<MaterialIcon icon="help" size={16} />
</a>
</div>
</div>
{/* Column 2: Company */}
<div>
<h5 className="text-xs font-black uppercase tracking-wider text-white/40 mb-4">Company</h5>
<ul className="flex flex-col gap-2.5">
{COMPANY.map((l) => (
<li key={l.label}>
<Link href={l.href} className="text-xs text-white/70 hover:text-white hover:translate-x-0.5 transition-all inline-block">
{l.label}
</Link>
</li>
))}
</ul>
</div>
{/* Column 3: Nearle */}
<div>
<h5 className="text-xs font-black uppercase tracking-wider text-white/40 mb-4">Nearle</h5>
<ul className="flex flex-col gap-2.5">
{PARTNERSHIPS.map((l) => (
<li key={l.label}>
<Link href={l.href} className="text-xs text-white/70 hover:text-white hover:translate-x-0.5 transition-all inline-block">
{l.label}
</Link>
</li>
))}
</ul>
</div>
{/* Column 4: Support */}
<div>
<h5 className="text-xs font-black uppercase tracking-wider text-white/40 mb-4">Support</h5>
<ul className="flex flex-col gap-2.5">
{LEGAL.map((l) => (
<li key={l.label}>
<Link href={l.href} className="text-xs text-white/70 hover:text-white hover:translate-x-0.5 transition-all inline-block">
{l.label}
</Link>
</li>
))}
</ul>
</div>
</div>
{/* HQ Address card at bottom-left and info */}
<div className="mt-10 pt-8 border-t border-white/10 flex flex-col md:flex-row justify-between items-start md:items-center gap-6">
{/* HQ Address Card */}
<div className="bg-white/5 border border-white/10 rounded-2xl p-4 flex items-start gap-3.5 max-w-sm">
<div className="w-8 h-8 rounded-lg bg-white/10 text-white flex items-center justify-center shrink-0 mt-0.5">
<MaterialIcon icon="location_on" size={16} />
</div>
<div className="text-left">
<h6 className="text-xs font-black text-white">Nearle HQ</h6>
<p className="text-[11px] text-white/60 leading-normal mt-0.5">
424, Diwan Bahadur Rd, Opp. Sri Krishna Sweets, R.S. Puram, Coimbatore, TN 641002
</p>
</div>
</div>
{/* Call center */}
<div className="flex flex-col items-start md:items-end gap-1">
<span className="text-[10px] font-black text-white/40 uppercase tracking-widest">Neighborhood Helpdesk</span>
<a
href="tel:+918049123456"
className="flex items-center gap-2 text-white hover:text-[#6330D6] transition-colors"
>
<div className="w-7 h-7 rounded-full bg-[#6330D6] flex items-center justify-center">
<MaterialIcon icon="phone" size={14} className="text-white" />
</div>
<span className="text-sm font-black tracking-tight">+91 80 4912 3456</span>
</a>
</div>
</div>
{/* Bottom Copyright & legal links */}
<div className="mt-8 pt-6 border-t border-white/5 flex flex-col sm:flex-row justify-between items-center gap-4 text-[11px] text-white/40 text-center sm:text-left">
<p>© {new Date().getFullYear()} Nearle. All rights reserved.</p>
<div className="flex flex-wrap gap-x-4 gap-y-1 justify-center">
<Link href="#" className="hover:text-white transition-colors">Privacy Policy</Link>
<span className="opacity-50"></span>
<Link href="#" className="hover:text-white transition-colors">Terms of Service</Link>
<span className="opacity-50"></span>
<Link href="#" className="hover:text-white transition-colors">Help Center</Link>
</div>
</div>
</footer>
);
}

View File

@@ -0,0 +1,129 @@
"use client";
import Link from "next/link";
import Image from "next/image";
import { useState } from "react";
import { usePathname } from "next/navigation";
import { MaterialIcon } from "@/components/ui/MaterialIcon";
const NAV_LINKS = [
{ label: "Home", href: "/" },
{ label: "Nearle for Business", href: "/businesses" },
{ label: "Nearle for People", href: "/people" },
{ label: "About", href: "/about" },
{ label: "Contact", href: "/contact" },
];
export function PremiumNavbar() {
const [mobileOpen, setMobileOpen] = useState(false);
const pathname = usePathname();
return (
<header className="w-full bg-white border-b border-[#EEE7F4] px-6 md:px-10 h-16 md:h-20 flex items-center relative z-40 select-none">
<div className="flex items-center justify-between w-full">
{/* LOGO (LEFT) */}
<Link
href="/"
className="flex items-center hover:scale-[1.02] transition-transform active:scale-95 duration-200"
>
<Image
src="/logo.png"
alt="Nearle"
width={120}
height={30}
className="h-7 md:h-8 w-auto object-contain"
priority
/>
</Link>
{/* LINKS (CENTER) */}
<nav className="hidden md:flex items-center gap-6 lg:gap-8">
{NAV_LINKS.map((link) => {
const isActive = pathname === link.href;
return (
<Link
key={link.label}
href={link.href}
className={`relative py-1 text-sm font-bold transition-all duration-200 ${
isActive ? "text-[#6330D6]" : "text-[#5E5866] hover:text-[#16001D]"
}`}
>
{link.label}
{isActive && (
<span className="absolute bottom-[-4px] left-0 right-0 h-0.5 bg-[#6330D6] rounded-full" />
)}
</Link>
);
})}
</nav>
{/* ACTIONS (RIGHT) */}
<div className="hidden md:flex items-center gap-3">
<Link
href="#"
className="inline-flex items-center justify-center border-2 border-[#6330D6]/20 text-[#6330D6] font-bold px-5 py-1.5 rounded-full text-xs hover:bg-[#6330D6]/5 active:scale-95 transition-all duration-200 whitespace-nowrap"
>
Login
</Link>
<Link
href="/people#download-section"
className="inline-flex items-center justify-center bg-[#6330D6] text-white font-bold px-5 py-2 rounded-full text-xs hover:bg-[#5225b8] hover:shadow-md hover:scale-[1.02] active:scale-95 transition-all duration-200 whitespace-nowrap"
>
Get App
</Link>
</div>
{/* Mobile menu toggle */}
<button
className="md:hidden flex items-center justify-center w-10 h-10 rounded-full hover:bg-[#6330D6]/5 text-[#16001D] transition-all active:scale-90 cursor-pointer"
onClick={() => setMobileOpen(!mobileOpen)}
aria-label="Toggle menu"
>
<MaterialIcon icon={mobileOpen ? "close" : "menu"} size={22} />
</button>
</div>
{/* Mobile Drawer */}
{mobileOpen && (
<div className="absolute top-full left-0 right-0 z-50 bg-white border-b border-[#6330D6]/10 shadow-lg p-4 md:hidden animate-fade-in flex flex-col gap-2">
{NAV_LINKS.map((link) => {
const isActive = pathname === link.href;
return (
<Link
key={link.label}
href={link.href}
className={`px-4 py-2.5 text-sm font-bold rounded-xl transition-all duration-200 flex items-center justify-between ${
isActive
? "bg-[#6330D6]/10 text-[#6330D6]"
: "text-[#5E5866] hover:text-[#16001D] hover:bg-[#6330D6]/5"
}`}
onClick={() => setMobileOpen(false)}
>
{link.label}
{isActive && (
<span className="w-1.5 h-1.5 rounded-full bg-[#6330D6]" />
)}
</Link>
);
})}
<div className="flex flex-col gap-2 pt-2 border-t border-[#6330D6]/5 mt-2">
<Link
href="#"
onClick={() => setMobileOpen(false)}
className="flex items-center justify-center border-2 border-[#6330D6]/20 text-[#6330D6] font-bold py-2.5 rounded-xl text-sm"
>
Login
</Link>
<Link
href="/people#download-section"
onClick={() => setMobileOpen(false)}
className="flex items-center justify-center bg-[#6330D6] text-white font-bold py-2.5 rounded-xl text-sm"
>
Get App
</Link>
</div>
</div>
)}
</header>
);
}

View File

@@ -0,0 +1,43 @@
import React from "react";
import { PremiumNavbar } from "./PremiumNavbar";
import { PremiumFooter } from "./PremiumFooter";
type PremiumPageShellProps = {
children: React.ReactNode;
className?: string;
};
export function PremiumPageShell({ children, className = "" }: PremiumPageShellProps) {
return (
<div className="min-h-screen bg-[#E8DCF2] p-2 sm:p-3 md:p-4 lg:p-5 xl:p-6 2xl:p-8 font-body text-[#16001D] antialiased">
<div className={`
mx-auto
w-full
max-w-[1880px]
overflow-hidden
rounded-[1.5rem]
sm:rounded-[2rem]
md:rounded-[2.5rem]
lg:rounded-[3rem]
border
border-white/80
bg-white
shadow-[0_20px_60px_rgba(93,57,128,0.16)]
flex
flex-col
${className}
`}>
{/* Header/Navbar */}
<PremiumNavbar />
{/* Page Content */}
<main className="flex-1 w-full">
{children}
</main>
{/* Footer */}
<PremiumFooter />
</div>
</div>
);
}

View File

@@ -0,0 +1,45 @@
import { MaterialIcon } from "./MaterialIcon";
type FeatureStatsItem = {
icon: string;
title: string;
desc?: string;
};
type FeatureStatsRowProps = {
items: FeatureStatsItem[];
className?: string;
};
export function FeatureStatsRow({ items, className = "" }: FeatureStatsRowProps) {
return (
<div className={`w-full py-6 md:py-8 ${className}`}>
<div className="grid grid-cols-2 lg:flex lg:flex-row items-center justify-between gap-y-6 gap-x-4 lg:gap-0">
{items.map((item, index) => (
<div
key={item.title}
className={`flex items-center gap-3.5 lg:flex-1 px-3 lg:px-8 text-left ${
index < items.length - 1
? "lg:border-r lg:border-[#6330D6]/10"
: ""
}`}
>
<div className="w-9 h-9 rounded-full bg-[#6330D6]/10 text-[#6330D6] flex items-center justify-center shrink-0">
<MaterialIcon icon={item.icon} size={18} />
</div>
<div className="min-w-0">
<h4 className="text-sm md:text-base font-black text-[#16001D] leading-tight truncate">
{item.title}
</h4>
{item.desc && (
<p className="text-[11px] md:text-xs text-[#5E5866] font-semibold mt-0.5 leading-tight truncate">
{item.desc}
</p>
)}
</div>
</div>
))}
</div>
</div>
);
}

View File

@@ -0,0 +1,26 @@
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 animate-pulse" />
)}
<span className="text-sm font-extrabold text-[#16001D] whitespace-nowrap">
{text}
</span>
</div>
);
}