fix home page

This commit is contained in:
2026-06-20 16:30:35 +05:30
parent 2778527442
commit be15ae458c
12 changed files with 344 additions and 210 deletions

BIN
public/apple-icon-v2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
public/favicon-v2.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
public/favicon-v2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 751 KiB

BIN
public/logo-purple-v3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
public/logo-v3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
public/logo-white-v3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

124
scratch/update_logos.py Normal file
View File

@@ -0,0 +1,124 @@
import os
from PIL import Image, ImageDraw
def update_logos():
src_logo_path = "/Users/apple/.gemini/antigravity-ide/brain/822556bd-47a7-4c07-8975-803618af0a3a/media__1781948467684.png"
rider_image_base = "public/images/slider-courier-mask-purple-v3.png"
rider_image_out = "public/images/slider-courier-mask-purple-v5.png"
if not os.path.exists(src_logo_path):
print(f"Source logo not found at {src_logo_path}")
return
# 1. Load the original logo
logo_img = Image.open(src_logo_path).convert("RGBA")
logo_w, logo_h = logo_img.size
# 2. Save original logo directly as logo-v3.png (white text, purple icon, white icon bg)
# Just in case we need it, but we will make logo-white-v3.png the default white logo
logo_img.save("public/logo-v3.png", "PNG")
# 3. Create logo-purple-v3.png (for Navbar)
# Icon (x < 40) is kept as-is (purple outline/bag, white background)
# Text (x >= 40) white pixels become purple #662582 (102, 37, 130)
logo_purple = Image.new("RGBA", (logo_w, logo_h))
pixels_orig = logo_img.load()
pixels_purple = logo_purple.load()
for x in range(logo_w):
for y in range(logo_h):
r, g, b, a = pixels_orig[x, y]
if a > 0:
if x < 40:
# Keep original icon colors
pixels_purple[x, y] = (r, g, b, a)
else:
# Convert white text to purple, keep ® sign purple
if r > 200 and g > 200 and b > 200:
pixels_purple[x, y] = (102, 37, 130, a)
else:
pixels_purple[x, y] = (r, g, b, a)
else:
pixels_purple[x, y] = (0, 0, 0, 0)
logo_purple.save("public/logo-purple-v3.png", "PNG")
print("Saved public/logo-purple-v3.png")
# 4. Create logo-white-v3.png (for Footer and Backpack)
# Icon (x < 40): convert purple border/bag to white, convert white background circle to transparent
# Text (x >= 40): convert all text/® sign to white
logo_white = Image.new("RGBA", (logo_w, logo_h))
pixels_white = logo_white.load()
for x in range(logo_w):
for y in range(logo_h):
r, g, b, a = pixels_orig[x, y]
if a > 0:
if x < 40:
# Icon area
if r > 200 and g > 200 and b > 200:
# White background of circle -> transparent
pixels_white[x, y] = (0, 0, 0, 0)
else:
# Purple outline and purple shopping bag -> white
pixels_white[x, y] = (255, 255, 255, a)
else:
# Text area: make everything white (text is already white, ® sign becomes white)
pixels_white[x, y] = (255, 255, 255, a)
else:
pixels_white[x, y] = (0, 0, 0, 0)
logo_white.save("public/logo-white-v3.png", "PNG")
print("Saved public/logo-white-v3.png")
# 5. Create Favicon from the icon area (X: 0 to 39, Y: 4 to 43)
# Note: we use original icon crop (has white background circle and purple border)
icon_crop = logo_img.crop((0, 4, 40, 44))
# Save as versioned Favicon and Apple Icon
icon_crop.save("public/favicon-v2.png", "PNG")
icon_crop.save("public/apple-icon-v2.png", "PNG")
# Save as favicon-v2.ico to both public/ and src/app/
icon_crop.save("public/favicon-v2.ico", format="ICO", sizes=[(32, 32), (48, 48)])
icon_crop.save("src/app/favicon-v2.ico", format="ICO", sizes=[(32, 32), (48, 48)])
print("Saved favicon-v2.ico and apple-icon-v2.png to public/ and src/app/")
# 6. Overlay the new logo-white-v3.png onto the delivery rider's backpack
if os.path.exists(rider_image_base):
rider_img = Image.open(rider_image_base).convert("RGBA")
# Draw a fresh badge (matching --brand-dark / #120217)
badge_w = 148
badge_h = 38
badge_left = 887 - (badge_w // 2)
badge_top = 270 - (badge_h // 2)
badge_right = badge_left + badge_w
badge_bottom = badge_top + badge_h
draw_rider = ImageDraw.Draw(rider_img)
draw_rider.rounded_rectangle(
[badge_left, badge_top, badge_right, badge_bottom],
radius=8,
fill=(18, 2, 23, 255)
)
# Resize logo-white-v3.png (original ratio 275x45 -> width 120, height 20)
logo_w_badge = 120
logo_h_badge = 20
resized_white_logo = logo_white.resize((logo_w_badge, logo_h_badge), Image.Resampling.LANCZOS)
logo_left = 887 - (logo_w_badge // 2)
logo_top = 270 - (logo_h_badge // 2)
# Paste logo on top of the black badge
rider_img.paste(resized_white_logo, (logo_left, logo_top), resized_white_logo)
# Save output
rider_img.save(rider_image_out, "PNG")
print(f"Created updated rider image with white logo at {rider_image_out}")
else:
print(f"Rider base image not found at {rider_image_base}")
if __name__ == "__main__":
update_logos()

BIN
src/app/favicon-v2.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -376,20 +376,19 @@ body {
.hero-map-layer { .hero-map-layer {
position: absolute; position: absolute;
width: 86%; width: 35%;
left: 2%; left: -5%;
top: -1%; top: 20px;
height: 610px; height: 280px;
opacity: 0.72; opacity: 0.10;
z-index: 1; z-index: 1;
mix-blend-mode: screen; mix-blend-mode: normal;
animation: hero-map-drift 18s ease-in-out infinite alternate; animation: none;
} }
.hero-map-layer img { .hero-map-layer img {
filter: sepia(1) saturate(4.6) hue-rotate(230deg) brightness(0.9) contrast(1.35) filter: brightness(0.6) contrast(1.1);
drop-shadow(0 0 22px rgba(189, 52, 254, 0.34)); opacity: 0.8;
opacity: 0.95;
} }
.hero-content { .hero-content {
@@ -452,17 +451,17 @@ body {
.hero-map-layer { .hero-map-layer {
position: absolute; position: absolute;
width: 120%; width: 100%;
left: -10%; left: 0;
top: 5%; top: 10%;
height: 380px; /* Explicit height on mobile */ height: 300px;
opacity: 0.3; opacity: 0.08;
z-index: 1; z-index: 1;
mix-blend-mode: screen; mix-blend-mode: normal;
} }
.hero-map-layer img { .hero-map-layer img {
filter: sepia(1) saturate(4) hue-rotate(230deg) brightness(0.76) contrast(1.18); filter: brightness(0.5) contrast(1);
opacity: 0.7; opacity: 0.7;
} }

View File

@@ -31,112 +31,61 @@ export function Hero() {
{/* ─── Base Dark Background Panel (Clipped diagonally) ─── */} {/* ─── Base Dark Background Panel (Clipped diagonally) ─── */}
<div className="hero-dark-panel select-none pointer-events-none"> <div className="hero-dark-panel select-none pointer-events-none">
{/* Flat Dotted World Map Layer */} {/* Subtle Background Dot Texture (Minimal, barely visible) */}
<div className="hero-map-layer select-none mix-blend-screen"> <div className="hero-map-layer select-none">
<Image <Image
src="/images/slider-glob.png" src="/images/slider-glob.png"
alt="Dotted World Map" alt="Subtle Background"
fill fill
sizes="(max-width: 768px) 100vw, 75vw" sizes="(max-width: 768px) 100vw, 40vw"
className="object-contain object-left" className="object-contain object-left-top"
priority priority
/> />
</div>
{/* Animated Route Lines & Glowing Location Nodes */} {/* Minimal Route Animation (2-3 thin lines only, very subtle) */}
<svg <svg
className="absolute inset-0 w-full h-full opacity-85 pointer-events-none" className="absolute inset-0 w-full h-full pointer-events-none"
viewBox="0 0 1000 800" viewBox="0 0 1000 800"
preserveAspectRatio="none" preserveAspectRatio="none"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
> >
<defs> <defs>
<filter id="heroRouteGlow" x="-50%" y="-50%" width="200%" height="200%"> <filter id="heroRouteGlow" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur stdDeviation="5" result="blur" /> <feGaussianBlur stdDeviation="3" result="blur" />
<feMerge> <feMerge>
<feMergeNode in="blur" /> <feMergeNode in="blur" />
<feMergeNode in="SourceGraphic" /> <feMergeNode in="SourceGraphic" />
</feMerge> </feMerge>
</filter> </filter>
</defs> </defs>
{/* Glowing nodes */} {/* Minimal glow nodes - only 2 small ones at top */}
<circle cx="150" cy="180" r="8" className="fill-[#bd34fe] opacity-70 animate-pulse" filter="url(#heroRouteGlow)" /> <circle cx="140" cy="100" r="5" className="fill-[#bd34fe] opacity-20 animate-pulse" filter="url(#heroRouteGlow)" />
<circle cx="150" cy="180" r="2.5" className="fill-white" /> <circle cx="140" cy="100" r="1.5" className="fill-white" />
<circle cx="350" cy="110" r="8" className="fill-[#bd34fe] opacity-70 animate-pulse" filter="url(#heroRouteGlow)" /> <circle cx="300" cy="80" r="5" className="fill-[#bd34fe] opacity-20 animate-pulse" filter="url(#heroRouteGlow)" />
<circle cx="350" cy="110" r="2.5" className="fill-white" /> <circle cx="300" cy="80" r="1.5" className="fill-white" />
<circle cx="280" cy="300" r="8" className="fill-[#bd34fe] opacity-70 animate-pulse" filter="url(#heroRouteGlow)" /> {/* Only 2 very thin route lines at top - staying clear of text area */}
<circle cx="280" cy="300" r="2.5" className="fill-white" />
<circle cx="480" cy="220" r="8" className="fill-[#bd34fe] opacity-70 animate-pulse" filter="url(#heroRouteGlow)" />
<circle cx="480" cy="220" r="2.5" className="fill-white" />
<circle cx="650" cy="165" r="8" className="fill-[#bd34fe] opacity-70 animate-pulse" filter="url(#heroRouteGlow)" />
<circle cx="650" cy="165" r="2.5" className="fill-white" />
<circle cx="780" cy="250" r="8" className="fill-[#bd34fe] opacity-70 animate-pulse" filter="url(#heroRouteGlow)" />
<circle cx="780" cy="250" r="2.5" className="fill-white" />
<circle cx="580" cy="140" r="8" className="fill-[#bd34fe] opacity-70 animate-pulse" filter="url(#heroRouteGlow)" />
<circle cx="580" cy="140" r="2.5" className="fill-white" />
{/* Arc dashed lines with moving stroke-dash animation */}
<path <path
d="M150,180 Q250,120 350,110" d="M140,100 Q220,85 300,80"
fill="none" fill="none"
stroke="#c02cff" stroke="#c02cff"
strokeWidth="2" strokeWidth="1"
strokeDasharray="6,6" strokeDasharray="4,4"
className="animate-route opacity-70" className="animate-route opacity-15"
filter="url(#heroRouteGlow)" filter="url(#heroRouteGlow)"
/> />
<path <path
d="M150,180 Q200,240 280,300" d="M300,80 Q370,110 420,140"
fill="none" fill="none"
stroke="#c02cff" stroke="#c02cff"
strokeWidth="2" strokeWidth="1"
strokeDasharray="6,6" strokeDasharray="4,4"
className="animate-route opacity-70" className="animate-route opacity-12"
filter="url(#heroRouteGlow)"
/>
<path
d="M350,110 Q420,165 480,220"
fill="none"
stroke="#c02cff"
strokeWidth="2"
strokeDasharray="6,6"
className="animate-route opacity-70"
filter="url(#heroRouteGlow)"
/>
<path
d="M280,300 Q380,250 480,220"
fill="none"
stroke="#c02cff"
strokeWidth="2"
strokeDasharray="6,6"
className="animate-route opacity-70"
filter="url(#heroRouteGlow)"
/>
<path
d="M480,220 Q520,180 580,140 Q630,120 650,165"
fill="none"
stroke="#c02cff"
strokeWidth="2"
strokeDasharray="6,6"
className="animate-route opacity-70"
filter="url(#heroRouteGlow)"
/>
<path
d="M480,220 Q620,250 780,250"
fill="none"
stroke="#c02cff"
strokeWidth="2"
strokeDasharray="6,6"
className="animate-route opacity-70"
filter="url(#heroRouteGlow)" filter="url(#heroRouteGlow)"
/> />
</svg> </svg>
</div>
{/* Soft purple radial glow behind the bike near the diagonal edge (clipped) */} {/* Soft purple radial glow behind the bike near the diagonal edge (clipped) */}
<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 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" />

View File

@@ -21,47 +21,96 @@ const FEATURES = [
export function HyperlocalFeatures() { export function HyperlocalFeatures() {
return ( return (
<section className="py-20 bg-surface-container-low border-y border-outline-variant/10 relative overflow-hidden"> <section className="bg-[#f7f7f9] py-[72px] px-4 min-[901px]:py-[100px] min-[901px]:px-8 relative overflow-hidden border-y border-outline-variant/10">
{/* Background soft blur */} {/* Scoped CSS styles for precise layout enforcement */}
<div className="absolute -left-20 top-1/3 w-80 h-80 bg-primary/5 rounded-full blur-3xl pointer-events-none" /> <style>{`
@media (min-width: 901px) {
.custom-care-grid {
grid-template-columns: minmax(420px, 0.9fr) minmax(560px, 1.1fr) !important;
gap: 56px !important;
width: min(1280px, calc(100% - 64px)) !important;
}
.custom-care-visual {
max-width: 470px !important;
height: 520px !important;
}
.custom-care-card {
min-height: 520px !important;
padding: 60px !important;
}
}
@media (max-width: 900px) {
.custom-care-grid {
grid-template-columns: 1fr !important;
gap: 32px !important;
width: min(1280px, calc(100% - 32px)) !important;
}
.custom-care-visual {
max-width: 420px !important;
height: 460px !important;
}
.custom-care-card {
min-height: auto !important;
padding: 36px 24px !important;
}
}
`}</style>
<div className="max-w-container-max mx-auto px-margin-mobile md:px-margin-desktop"> {/* Subtle background radial glows */}
<div className="grid lg:grid-cols-12 gap-12 items-center"> <div className="absolute left-[15%] top-1/2 -translate-x-1/2 -translate-y-1/2 w-[55%] h-[55%] rounded-full bg-brand-accent/[0.03] blur-[130px] pointer-events-none z-0" />
<div className="absolute right-[15%] top-1/2 translate-x-1/2 -translate-y-1/2 w-[55%] h-[55%] rounded-full bg-primary/[0.03] blur-[130px] pointer-events-none z-0" />
{/* Left Column: Visual Storytelling (5 cols) */} {/* Inner container */}
<div className="lg:col-span-5 relative"> <div className="custom-care-grid mx-auto grid items-center">
<div className="relative aspect-[4/5] w-full max-w-[420px] mx-auto rounded-[3rem] overflow-hidden border-4 border-white shadow-2xl">
{/* Left Column: Visual Storytelling */}
<div className="custom-care-visual w-full justify-self-center relative rounded-[32px] border-2 border-white/90 bg-gradient-to-br from-[#fdfbf7] to-[#f5f0e6] shadow-[0_20px_50px_rgba(20,0,30,0.12)] z-10">
{/* Grocery image inside the lower area (occupies exactly 62% height) */}
<div className="absolute inset-x-0 bottom-0 h-[62%] w-full overflow-hidden select-none pointer-events-none">
<Image <Image
src="/images/cat-daily-essentials.png" src="/images/cat-daily-essentials.png"
alt="Fresh groceries and goods delivered at home" alt="Fresh groceries and goods delivered at home"
width={500} fill
height={600} sizes="(max-width: 900px) 420px, 470px"
className="w-full h-full object-cover group-hover:scale-102 transition-transform duration-500" className="object-cover object-bottom block transition-transform duration-500 hover:scale-[1.02]"
priority
/> />
<div className="absolute inset-0 bg-gradient-to-t from-black/50 via-transparent to-transparent" /> </div>
{/* Floating Badge */} {/* Eco-Friendly floating pill */}
<div className="absolute bottom-6 left-6 right-6 bg-white/95 backdrop-blur-md p-5 rounded-2xl border border-outline-variant/20 shadow-xl"> <div className="absolute bottom-[22px] left-[22px] right-[22px] bg-white/95 backdrop-blur-sm p-4 rounded-2xl border border-outline-variant/15 shadow-xl z-20">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<div className="w-10 h-10 rounded-full bg-brand-accent/20 flex items-center justify-center"> <div className="w-9 h-9 rounded-full bg-brand-accent/15 flex items-center justify-center flex-shrink-0">
<MaterialIcon icon="eco" className="text-brand-accent" size={22} /> <MaterialIcon icon="eco" className="text-brand-accent" size={20} />
</div> </div>
<div> <div>
<h4 className="text-label-md font-black text-brand-dark">100% Eco-Friendly</h4> <h4 className="text-[13px] font-black text-brand-dark leading-tight">100% Eco-Friendly</h4>
<p className="text-[11px] text-on-surface-variant font-semibold mt-0.5">Reducing neighbor carbon footprint</p> <p className="text-[10px] text-on-surface-variant font-bold mt-0.5 leading-none">Reducing neighbor carbon footprint</p>
</div>
</div> </div>
</div> </div>
</div> </div>
{/* Background Decorative Circle */} {/* Floating Proof Badges near the image (Desktop only, hidden below 900px) */}
<div className="absolute -bottom-8 -right-8 w-32 h-32 bg-brand-accent/10 rounded-full blur-xl pointer-events-none" /> <div className="absolute top-[40px] -left-[24px] hidden min-[901px]:flex items-center gap-2 bg-white px-4 py-2.5 rounded-full border border-outline-variant/15 shadow-lg z-30 select-none pointer-events-none">
<div className="w-6 h-6 rounded-full bg-brand-accent/10 flex items-center justify-center">
<MaterialIcon icon="location_on" className="text-brand-accent" size={14} />
</div>
<span className="text-[11px] font-black text-brand-dark tracking-wide uppercase">2KM Local Delivery</span>
</div> </div>
{/* Right Column: Dark Feature Panel (7 cols) */} <div className="absolute top-[144px] -right-[24px] hidden min-[901px]:flex items-center gap-2 bg-white px-4 py-2.5 rounded-full border border-outline-variant/15 shadow-lg z-30 select-none pointer-events-none">
<div className="lg:col-span-7"> <div className="w-6 h-6 rounded-full bg-brand-accent/10 flex items-center justify-center">
<div className="bg-brand-dark text-white p-8 md:p-16 rounded-[3rem] shadow-2xl relative overflow-hidden border border-white/5"> <MaterialIcon icon="verified" className="text-brand-accent" size={14} />
{/* Internal vector decor */} </div>
<span className="text-[11px] font-black text-brand-dark tracking-wide uppercase">Verified Partners</span>
</div>
</div>
{/* Right Column: Dark Feature Panel */}
<div className="custom-care-card w-full rounded-[36px] bg-[#16001d] text-white shadow-[0_24px_60px_rgba(20,0,30,0.18)] relative overflow-hidden z-10">
{/* Internal ambient glows (subtle) */}
<div className="absolute right-0 top-0 w-64 h-64 bg-brand-accent/5 rounded-full blur-3xl pointer-events-none" /> <div className="absolute right-0 top-0 w-64 h-64 bg-brand-accent/5 rounded-full blur-3xl pointer-events-none" />
<div className="absolute -left-16 -bottom-16 w-48 h-48 bg-primary/10 rounded-full blur-2xl pointer-events-none" /> <div className="absolute -left-16 -bottom-16 w-48 h-48 bg-primary/10 rounded-full blur-2xl pointer-events-none" />
@@ -79,17 +128,24 @@ export function HyperlocalFeatures() {
Nearle connects you to local, trusted neighborhood shops, bringing you the best essentials while taking care of the logistics and safety standards. Nearle connects you to local, trusted neighborhood shops, bringing you the best essentials while taking care of the logistics and safety standards.
</p> </p>
{/* Features List */} {/* Features List with vertical connector line */}
<div className="space-y-8"> <div className="relative space-y-8">
{/* Vertical connector line (orange low-opacity) */}
<div className="absolute left-6 top-6 bottom-6 w-0.5 bg-brand-accent/20 -translate-x-1/2 z-0" />
{FEATURES.map((item) => ( {FEATURES.map((item) => (
<div key={item.title} className="flex gap-5 group"> <div key={item.title} className="flex gap-5 group relative z-10">
<div className="flex-shrink-0 w-12 h-12 rounded-full bg-brand-accent/15 border border-brand-accent/30 flex items-center justify-center group-hover:bg-brand-accent group-hover:text-brand-dark transition-colors duration-300">
{/* Orange icon circle */}
<div className="flex-shrink-0 w-12 h-12 rounded-full bg-brand-accent text-brand-dark flex items-center justify-center shadow-md relative z-10 group-hover:scale-105 transition-transform duration-300">
<MaterialIcon <MaterialIcon
icon={item.icon} icon={item.icon}
className="text-brand-accent group-hover:text-brand-dark transition-colors" className="text-brand-dark"
size={22} size={22}
/> />
</div> </div>
<div> <div>
<h4 className="text-headline-md font-black text-white group-hover:text-brand-accent transition-colors"> <h4 className="text-headline-md font-black text-white group-hover:text-brand-accent transition-colors">
{item.title} {item.title}
@@ -102,8 +158,11 @@ export function HyperlocalFeatures() {
))} ))}
</div> </div>
{/* Divider Line above CTA Area */}
<hr className="border-t border-white/10 my-8 relative z-10" />
{/* Onboarding Call to Action */} {/* Onboarding Call to Action */}
<div className="mt-12 flex flex-wrap gap-4 items-center"> <div className="mt-8 flex flex-wrap gap-6 items-center relative z-10">
<a <a
href="#download" href="#download"
className="bg-brand-accent hover:bg-brand-accent/90 text-brand-dark font-black px-8 py-3.5 rounded-full text-label-md hover:shadow-lg hover:-translate-y-0.5 active:translate-y-0 active:scale-95 transition-all duration-200" className="bg-brand-accent hover:bg-brand-accent/90 text-brand-dark font-black px-8 py-3.5 rounded-full text-label-md hover:shadow-lg hover:-translate-y-0.5 active:translate-y-0 active:scale-95 transition-all duration-200"
@@ -115,15 +174,18 @@ export function HyperlocalFeatures() {
className="text-white hover:text-brand-accent font-bold text-label-md flex items-center gap-1 group py-2" className="text-white hover:text-brand-accent font-bold text-label-md flex items-center gap-1 group py-2"
> >
Partner Code of Ethics Partner Code of Ethics
<MaterialIcon icon="arrow_forward" size={16} className="transition-transform group-hover:translate-x-1" /> <MaterialIcon
icon="arrow_forward"
size={16}
className="transition-transform group-hover:translate-x-1"
/>
</a> </a>
</div> </div>
</div>
</div>
</div>
</div> </div>
</div> </div>
</div>
</section> </section>
); );
} }