update about section
This commit is contained in:
25
src/components/about/FloatingDelivery.tsx
Normal file
25
src/components/about/FloatingDelivery.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
"use client";
|
||||
|
||||
import Image from "next/image";
|
||||
import { motion, useReducedMotion } from "framer-motion";
|
||||
|
||||
export function FloatingDelivery() {
|
||||
const shouldReduce = useReducedMotion();
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
className="pointer-events-none select-none absolute right-[4%] xl:right-[8%] top-1/2 -translate-y-1/2 hidden lg:block w-[180px] xl:w-[220px] z-0"
|
||||
animate={shouldReduce ? undefined : { y: [0, -8, 0] }}
|
||||
transition={{ duration: 6, ease: "easeInOut", repeat: Infinity }}
|
||||
>
|
||||
<Image
|
||||
src="/images/nearle-redesign/delivery-doorstep.webp"
|
||||
alt=""
|
||||
width={220}
|
||||
height={220}
|
||||
className="w-full h-auto object-contain opacity-80"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
@@ -1,12 +1,11 @@
|
||||
"use client";
|
||||
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { motion } from "framer-motion";
|
||||
import { MaterialIcon } from "@/components/ui/MaterialIcon";
|
||||
import { FeatureStatsRow } from "@/components/ui/FeatureStatsRow";
|
||||
import {
|
||||
fadeInSlow,
|
||||
staggerSlow,
|
||||
} from "@/lib/animations";
|
||||
import { fadeUp, fadeUpStrong, staggerContainer } from "@/lib/animations";
|
||||
|
||||
const HERO_STATS = [
|
||||
{ title: "2km Coverage", icon: "explore", desc: "Hyperlocal radius" },
|
||||
@@ -15,28 +14,31 @@ const HERO_STATS = [
|
||||
{ title: "Coimbatore & Beyond", icon: "location_city", desc: "Growing neighbourhood reach" },
|
||||
];
|
||||
|
||||
const badgeVariant = fadeInSlow;
|
||||
const titleVariant = {
|
||||
hidden: { opacity: 0, x: -30 },
|
||||
visible: {
|
||||
opacity: 1,
|
||||
x: 0,
|
||||
transition: { duration: 0.7, ease: [0.22, 1, 0.36, 1] as [number, number, number, number] },
|
||||
},
|
||||
const EASE = [0.22, 1, 0.36, 1] as [number, number, number, number];
|
||||
|
||||
const badgeVariant = {
|
||||
hidden: { opacity: 0, y: 10, scale: 0.95 },
|
||||
visible: { opacity: 1, y: 0, scale: 1, transition: { duration: 0.38, ease: EASE } },
|
||||
};
|
||||
|
||||
const titleVariant = {
|
||||
hidden: { opacity: 0, y: 28 },
|
||||
visible: { opacity: 1, y: 0, transition: { duration: 0.65, ease: EASE } },
|
||||
};
|
||||
|
||||
const descVariant = {
|
||||
hidden: { opacity: 0, y: 20 },
|
||||
visible: {
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
transition: { duration: 0.6, ease: [0.22, 1, 0.36, 1] as [number, number, number, number] },
|
||||
},
|
||||
hidden: { opacity: 0, y: 18 },
|
||||
visible: { opacity: 1, y: 0, transition: { duration: 0.5, ease: EASE } },
|
||||
};
|
||||
|
||||
export function AboutHero() {
|
||||
return (
|
||||
<section className="w-full flex flex-col select-none bg-white">
|
||||
|
||||
{/* ─── Hero Banner ─── */}
|
||||
<div className="relative overflow-hidden border-b border-[#6330D6]/10 bg-[#FAF8FC]">
|
||||
|
||||
{/* Background image — scooter anchored to the right */}
|
||||
<Image
|
||||
src="/about.png"
|
||||
alt=""
|
||||
@@ -46,45 +48,76 @@ export function AboutHero() {
|
||||
priority
|
||||
aria-hidden="true"
|
||||
/>
|
||||
|
||||
{/* Gradient overlay — dark-purple toned to preserve the purple scene and protect white text */}
|
||||
<div className="absolute inset-0 z-[1] bg-[linear-gradient(180deg,rgba(23,5,31,0.72)_0%,rgba(23,5,31,0.52)_30%,rgba(23,5,31,0.22)_62%,rgba(23,5,31,0.06)_100%)] md:bg-[radial-gradient(ellipse_72%_88%_at_50%_42%,rgba(23,5,31,0.65)_0%,rgba(23,5,31,0.42)_38%,rgba(23,5,31,0.16)_65%,rgba(23,5,31,0.02)_100%)]" />
|
||||
|
||||
{/* Content */}
|
||||
<div className="relative z-10 flex min-h-[560px] items-center justify-center px-6 pt-20 pb-10 sm:min-h-[580px] sm:px-8 sm:pt-24 md:min-h-[610px] md:px-12 md:py-20 lg:min-h-[650px] lg:px-16 lg:py-24 xl:min-h-[680px] max-w-[1600px] mx-auto">
|
||||
|
||||
<motion.div
|
||||
className="flex flex-col items-center text-center w-full max-w-[780px] relative z-20"
|
||||
variants={staggerSlow}
|
||||
variants={staggerContainer}
|
||||
initial="hidden"
|
||||
animate="visible"
|
||||
>
|
||||
{/* Badge */}
|
||||
<motion.span
|
||||
variants={badgeVariant}
|
||||
className="inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-xs font-black tracking-widest bg-white/15 backdrop-blur-[8px] border border-white/20 text-white uppercase mb-6 w-fit [text-shadow:0_2px_6px_rgba(0,0,0,0.35),0_8px_24px_rgba(0,0,0,0.25)]"
|
||||
className="inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-xs font-black tracking-widest bg-white/15 backdrop-blur-[8px] border border-white/20 text-white uppercase mb-6 w-fit"
|
||||
>
|
||||
About Nearle
|
||||
</motion.span>
|
||||
|
||||
{/* Heading */}
|
||||
<motion.h1
|
||||
variants={titleVariant}
|
||||
className="font-display text-4xl sm:text-5xl lg:text-[48px] xl:text-[54px] font-black text-white leading-[1.1] tracking-tight [text-shadow:0_2px_6px_rgba(0,0,0,0.35),0_8px_24px_rgba(0,0,0,0.25)]"
|
||||
>
|
||||
Built for Every
|
||||
<br />
|
||||
<span className="text-white">Neighbourhood.</span>
|
||||
<span className="text-[#C4B5FD]">Neighbourhood.</span>
|
||||
</motion.h1>
|
||||
|
||||
{/* Description */}
|
||||
<motion.p
|
||||
variants={descVariant}
|
||||
className="text-sm md:text-base font-bold mt-6 leading-[1.75] text-white/96 [text-shadow:0_1px_4px_rgba(0,0,0,0.45)]"
|
||||
className="mt-6 max-w-[560px] text-sm font-semibold leading-[1.75] text-white/85 md:text-base [text-shadow:0_1px_4px_rgba(0,0,0,0.45)]"
|
||||
>
|
||||
Nearle is India's first hyper-local managed “Neighbourhood living platform” which brings all the amenities and requirements of residents to their fingertips.
|
||||
</motion.p>
|
||||
|
||||
{/* CTA Buttons */}
|
||||
<motion.div
|
||||
variants={descVariant}
|
||||
className="mt-8 flex flex-wrap justify-center gap-3"
|
||||
>
|
||||
<Link
|
||||
href="/businesses"
|
||||
className="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-full bg-white px-7 py-3.5 text-base font-black text-[#6330D6] shadow-sm transition-all duration-200 hover:bg-white/90 hover:shadow-lg hover:-translate-y-0.5 active:translate-y-0 active:scale-95"
|
||||
>
|
||||
Partner with Nearle
|
||||
<MaterialIcon icon="arrow_forward" size={18} />
|
||||
</Link>
|
||||
<Link
|
||||
href="/people"
|
||||
className="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-full border border-white/30 bg-white/10 px-7 py-3.5 text-base font-black text-white backdrop-blur-[6px] transition-all duration-200 hover:bg-white/18 hover:border-white/45 hover:-translate-y-0.5 active:translate-y-0 active:scale-95"
|
||||
>
|
||||
Explore Nearle
|
||||
</Link>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* ─── Stats Row ─── */}
|
||||
<div className="bg-[#FAF7FD] border-b border-[#6330D6]/10">
|
||||
<div className="px-6 sm:px-10 max-w-[1600px] mx-auto">
|
||||
<FeatureStatsRow items={HERO_STATS} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -162,7 +162,8 @@ export function BusinessSection() {
|
||||
<motion.article
|
||||
key={feature.title}
|
||||
variants={fadeUp}
|
||||
className="merchant-feature-card flex min-w-0 flex-col overflow-hidden rounded-[1.5rem] border border-primary/10 bg-white shadow-[0_4px_24px_rgba(22,0,29,0.07)]"
|
||||
whileHover={{ y: -6, transition: { duration: 0.22, ease: [0.22, 1, 0.36, 1] } }}
|
||||
className="merchant-feature-card flex min-w-0 flex-col overflow-hidden rounded-[1.5rem] border border-primary/10 bg-white shadow-[0_4px_24px_rgba(22,0,29,0.07)] hover:shadow-[0_16px_40px_rgba(22,0,29,0.12)] hover:border-primary/20 transition-[box-shadow,border-color] duration-[250ms]"
|
||||
>
|
||||
<div className="p-5">
|
||||
<div className="flex items-start gap-3">
|
||||
@@ -244,7 +245,7 @@ export function BusinessSection() {
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-sm font-black text-brand-dark">{b.title}</div>
|
||||
<div className="mt-0.5 text-xs leading-relaxed text-on-surface-variant">{b.desc}</div>
|
||||
<div className="mt-0.5 text-sm leading-relaxed text-on-surface-variant">{b.desc}</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { Fragment } from "react";
|
||||
import Image from "next/image";
|
||||
import { motion } from "framer-motion";
|
||||
import { motion, useReducedMotion } from "framer-motion";
|
||||
import { MaterialIcon } from "@/components/ui/MaterialIcon";
|
||||
import { viewport } from "@/lib/animations";
|
||||
|
||||
@@ -53,18 +53,27 @@ const statItem = {
|
||||
};
|
||||
|
||||
export function Hero() {
|
||||
const shouldReduce = useReducedMotion();
|
||||
|
||||
return (
|
||||
<section className="bg-white select-none w-full">
|
||||
<div className="relative overflow-hidden bg-[#FAF8FC]">
|
||||
<Image
|
||||
src="/images/home1.png"
|
||||
alt=""
|
||||
fill
|
||||
sizes="100vw"
|
||||
className="absolute inset-0 z-0 h-full w-full object-cover object-[62%_center] md:object-[58%_center] xl:object-center"
|
||||
priority
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<motion.div
|
||||
className="absolute inset-0 z-0"
|
||||
initial={{ scale: 1 }}
|
||||
animate={shouldReduce ? undefined : { scale: 1.06 }}
|
||||
transition={{ duration: 28, ease: "linear", repeat: Infinity, repeatType: "reverse" }}
|
||||
>
|
||||
<Image
|
||||
src="/images/home1.png"
|
||||
alt=""
|
||||
fill
|
||||
sizes="100vw"
|
||||
className="absolute inset-0 h-full w-full object-cover object-[62%_center] md:object-[58%_center] xl:object-center"
|
||||
priority
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</motion.div>
|
||||
<div className="absolute inset-0 z-[1] bg-[linear-gradient(180deg,rgba(250,248,252,0.85)_0%,rgba(250,248,252,0.68)_28%,rgba(250,248,252,0.38)_58%,rgba(250,248,252,0.10)_100%)] md:bg-[radial-gradient(ellipse_72%_88%_at_50%_42%,rgba(250,248,252,0.72)_0%,rgba(250,248,252,0.50)_38%,rgba(250,248,252,0.18)_65%,rgba(250,248,252,0.04)_100%)]" />
|
||||
|
||||
<div className="page-container relative z-10 flex min-h-[560px] items-center justify-center px-6 pt-20 pb-10 sm:min-h-[580px] sm:px-8 sm:pt-24 md:min-h-[610px] md:py-20 lg:min-h-[650px] lg:py-24 xl:min-h-[680px]">
|
||||
|
||||
@@ -328,7 +328,8 @@ export function HowItWorks() {
|
||||
<motion.article
|
||||
key={step.num}
|
||||
variants={fadeUp}
|
||||
className="relative flex min-h-[380px] min-w-0 flex-col overflow-hidden rounded-3xl border border-primary/10 bg-white p-7 shadow-[0_18px_45px_rgba(22,0,29,0.08)] md:min-h-[420px] lg:min-h-[460px] xl:min-h-[420px] lg:p-8"
|
||||
whileHover={{ y: -6, transition: { duration: 0.22, ease: [0.22, 1, 0.36, 1] } }}
|
||||
className="relative flex min-h-[380px] min-w-0 flex-col overflow-hidden rounded-3xl border border-primary/10 bg-white p-7 shadow-[0_18px_45px_rgba(22,0,29,0.08)] hover:shadow-[0_24px_60px_rgba(22,0,29,0.14)] hover:border-primary/20 transition-[box-shadow,border-color] duration-[250ms] md:min-h-[420px] lg:min-h-[460px] xl:min-h-[420px] lg:p-8"
|
||||
>
|
||||
<span className="absolute right-5 top-4 font-display text-6xl font-black leading-none text-primary/[0.07]">
|
||||
{step.num}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import Image from "next/image";
|
||||
import { motion } from "framer-motion";
|
||||
import { MaterialIcon } from "@/components/ui/MaterialIcon";
|
||||
import { siteContent } from "@/config/site-content";
|
||||
import { fadeUp, scaleIn, slideInRight, staggerContainer, viewport } from "@/lib/animations";
|
||||
|
||||
const FLOW_STEPS = [
|
||||
@@ -11,6 +12,10 @@ const FLOW_STEPS = [
|
||||
{ label: "Order Anytime", icon: "shopping_bag" },
|
||||
];
|
||||
|
||||
// TODO: Replace fallback hrefs once the app is confirmed live on both stores.
|
||||
const APP_STORE_URL = siteContent.app.iosUrl || "about:blank#todo-app-store-url";
|
||||
const GOOGLE_PLAY_URL = siteContent.app.androidUrl || "about:blank#todo-google-play-url";
|
||||
|
||||
export function StoreQRSection() {
|
||||
return (
|
||||
<section className="mb-2 bg-white w-full px-2 pt-2 md:mb-3 md:px-3 md:pt-3 lg:mb-4 lg:px-4 lg:pt-4 xl:mb-4 xl:px-5 xl:pt-4 2xl:mb-4 2xl:px-6">
|
||||
@@ -71,9 +76,14 @@ export function StoreQRSection() {
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* TODO: Replace with real app store URLs once app is confirmed live (siteContent.app.iosUrl / androidUrl) */}
|
||||
<div className="flex flex-wrap gap-4">
|
||||
<div className="h-[60px] border border-white/20 rounded-2xl bg-white/10 text-white/60 px-8 py-2 flex items-center gap-3.5 shrink-0 cursor-not-allowed select-none">
|
||||
<a
|
||||
href={APP_STORE_URL}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
aria-label="Download Nearle on the App Store"
|
||||
className="h-[60px] border border-white/20 rounded-2xl bg-white/10 text-white/60 px-8 py-2 flex items-center gap-3.5 shrink-0 cursor-pointer select-none hover:bg-white/[0.16] transition-all duration-300 active:scale-[0.98]"
|
||||
>
|
||||
<svg viewBox="0 0 24 24" className="w-7 h-7 shrink-0 fill-current opacity-60" fill="currentColor">
|
||||
<path d="M17.537 12.625c-.023-2.949 2.398-4.37 2.506-4.44-1.364-2.008-3.48-2.282-4.227-2.307-1.79-.186-3.504 1.064-4.413 1.064-.918 0-2.323-1.04-3.827-1.01-1.963.028-3.788 1.146-4.796 2.91-2.06 3.587-.526 8.9 1.466 11.808.98 1.428 2.147 3.035 3.685 2.975 1.47-.059 2.03-.964 3.807-.964 1.767 0 2.266.964 3.818.932 1.58-.03 2.58-1.453 3.536-2.89 1.116-1.628 1.57-3.21 1.596-3.29-.035-.016-3.057-1.18-3.087-4.678l.036-.002zM14.87 4.058c.821-.99 1.375-2.361 1.223-3.733-1.184.05-2.618.784-3.47 1.77-.762.875-1.43 2.28-1.25 3.623 1.327.102 2.673-.668 3.497-1.66z" />
|
||||
</svg>
|
||||
@@ -85,9 +95,15 @@ export function StoreQRSection() {
|
||||
Available on
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<div className="h-[60px] border border-white/20 rounded-2xl bg-white/10 text-white/60 px-8 py-2 flex items-center gap-3.5 shrink-0 cursor-not-allowed select-none">
|
||||
<a
|
||||
href={GOOGLE_PLAY_URL}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
aria-label="Download Nearle on Google Play"
|
||||
className="h-[60px] border border-white/20 rounded-2xl bg-white/10 text-white/60 px-8 py-2 flex items-center gap-3.5 shrink-0 cursor-pointer select-none hover:bg-white/[0.16] transition-all duration-300 active:scale-[0.98]"
|
||||
>
|
||||
<svg viewBox="0 0 24 24" className="w-7 h-7 shrink-0 fill-current opacity-60" fill="currentColor">
|
||||
<path d="M3.609 1.814L13.414 12 3.609 22.186c-.244-.178-.395-.466-.395-.786V2.6c0-.32.151-.608.395-.786zM14.244 12.83l2.705 2.688-4.073 2.276-4.073 2.276L14.244 12.83zm1-1.66l2.838-2.8 4.153 2.336c.464.26.464.688 0 .948l-4.153 2.336-2.838-2.82zM8.803 4.93l4.073 2.276 4.073 2.276-2.705 2.688L8.803 4.93z" />
|
||||
</svg>
|
||||
@@ -99,7 +115,7 @@ export function StoreQRSection() {
|
||||
Available on
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
@@ -238,9 +254,14 @@ export function StoreQRSection() {
|
||||
/>
|
||||
</motion.div>
|
||||
|
||||
{/* 5. App store buttons — TODO: replace with real URLs once app is live */}
|
||||
<div className="flex flex-col sm:flex-row items-center justify-center gap-4">
|
||||
<div className="h-14 w-60 sm:w-auto border border-white/20 rounded-2xl bg-white/10 text-white/60 px-6 py-2 flex items-center justify-center gap-3 cursor-not-allowed select-none">
|
||||
<a
|
||||
href={APP_STORE_URL}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
aria-label="Download Nearle on the App Store"
|
||||
className="h-14 w-60 sm:w-auto border border-white/20 rounded-2xl bg-white/10 text-white/60 px-6 py-2 flex items-center justify-center gap-3 cursor-pointer select-none hover:bg-white/[0.16] transition-all duration-300 active:scale-[0.98]"
|
||||
>
|
||||
<svg viewBox="0 0 24 24" className="w-6 h-6 shrink-0 fill-current opacity-60" fill="currentColor">
|
||||
<path d="M17.537 12.625c-.023-2.949 2.398-4.37 2.506-4.44-1.364-2.008-3.48-2.282-4.227-2.307-1.79-.186-3.504 1.064-4.413 1.064-.918 0-2.323-1.04-3.827-1.01-1.963.028-3.788 1.146-4.796 2.91-2.06 3.587-.526 8.9 1.466 11.808.98 1.428 2.147 3.035 3.685 2.975 1.47-.059 2.03-.964 3.807-.964 1.767 0 2.266.964 3.818.932 1.58-.03 2.58-1.453 3.536-2.89 1.116-1.628 1.57-3.21 1.596-3.29-.035-.016-3.057-1.18-3.087-4.678l.036-.002zM14.87 4.058c.821-.99 1.375-2.361 1.223-3.733-1.184.05-2.618.784-3.47 1.77-.762.875-1.43 2.28-1.25 3.623 1.327.102 2.673-.668 3.497-1.66z" />
|
||||
</svg>
|
||||
@@ -252,9 +273,15 @@ export function StoreQRSection() {
|
||||
Available on
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<div className="h-14 w-60 sm:w-auto border border-white/20 rounded-2xl bg-white/10 text-white/60 px-6 py-2 flex items-center justify-center gap-3 cursor-not-allowed select-none">
|
||||
<a
|
||||
href={GOOGLE_PLAY_URL}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
aria-label="Download Nearle on Google Play"
|
||||
className="h-14 w-60 sm:w-auto border border-white/20 rounded-2xl bg-white/10 text-white/60 px-6 py-2 flex items-center justify-center gap-3 cursor-pointer select-none hover:bg-white/[0.16] transition-all duration-300 active:scale-[0.98]"
|
||||
>
|
||||
<svg viewBox="0 0 24 24" className="w-6 h-6 shrink-0 fill-current opacity-60" fill="currentColor">
|
||||
<path d="M3.609 1.814L13.414 12 3.609 22.186c-.244-.178-.395-.466-.395-.786V2.6c0-.32.151-.608.395-.786zM14.244 12.83l2.705 2.688-4.073 2.276-4.073 2.276L14.244 12.83zm1-1.66l2.838-2.8 4.153 2.336c.464.26.464.688 0 .948l-4.153 2.336-2.838-2.82zM8.803 4.93l4.073 2.276 4.073 2.276-2.705 2.688L8.803 4.93z" />
|
||||
</svg>
|
||||
@@ -266,7 +293,7 @@ export function StoreQRSection() {
|
||||
Available on
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user