arrenge the home page order

This commit is contained in:
2026-07-24 15:28:46 +05:30
parent a4328a791a
commit 4a0adea793
37 changed files with 2532 additions and 1564 deletions

View File

@@ -0,0 +1,352 @@
"use client";
import { motion, useReducedMotion } from "framer-motion";
import { MaterialIcon } from "@/components/ui/MaterialIcon";
import { Spotlight } from "@/components/ui/Spotlight";
import { fadeUp, staggerContainer, staggerSlow, viewport } from "@/lib/animations";
// 1. Trust Graphic (Emerald Shield & Checkmark)
function TrustGraphic({ reduce = false }: { reduce?: boolean }) {
return (
<div className="relative flex items-center justify-center p-2">
<motion.div
className="absolute h-20 w-20 rounded-full bg-emerald-500/20 blur-xl pointer-events-none"
animate={reduce ? {} : { scale: [0.9, 1.25, 0.9], opacity: [0.25, 0.5, 0.25] }}
transition={{ duration: 3.5, repeat: Infinity, ease: "easeInOut" }}
/>
<svg
width="110"
height="110"
viewBox="0 0 110 110"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="relative z-10 w-24 h-24 md:w-28 md:h-28 filter drop-shadow-[0_10px_20px_rgba(0,0,0,0.35)] transition-transform duration-300 group-hover:scale-105"
>
<motion.path
d="M 55 12 L 88 24 C 88 56 72 82 55 96 C 38 82 22 56 22 24 L 55 12 Z"
fill="url(#trust-grad)"
stroke="#6EE7B7"
strokeWidth="2"
animate={reduce ? {} : { y: [0, -4, 0] }}
transition={{ duration: 3, repeat: Infinity, ease: "easeInOut" }}
/>
<motion.path
d="M 40 52 L 50 62 L 72 40"
stroke="#FFFFFF"
strokeWidth="6"
strokeLinecap="round"
strokeLinejoin="round"
animate={reduce ? {} : { opacity: [0.8, 1, 0.8] }}
transition={{ duration: 2.5, repeat: Infinity, ease: "easeInOut" }}
/>
<defs>
<linearGradient id="trust-grad" x1="22" y1="12" x2="88" y2="96" gradientUnits="userSpaceOnUse">
<stop stopColor="#059669" stopOpacity="0.8" />
<stop offset="1" stopColor="#34D399" stopOpacity="0.4" />
</linearGradient>
</defs>
</svg>
</div>
);
}
// 2. AI Graphic (Purple Sparkles Cluster)
function AIGraphic({ reduce = false }: { reduce?: boolean }) {
return (
<div className="relative flex items-center justify-center p-2">
<motion.div
className="absolute h-20 w-20 rounded-full bg-[#7C3AED]/25 blur-xl pointer-events-none"
animate={reduce ? {} : { scale: [0.9, 1.25, 0.9], opacity: [0.25, 0.5, 0.25] }}
transition={{ duration: 3.5, repeat: Infinity, ease: "easeInOut" }}
/>
<svg
width="120"
height="120"
viewBox="0 0 120 120"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="relative z-10 w-24 h-24 md:w-28 md:h-28 filter drop-shadow-[0_10px_20px_rgba(0,0,0,0.35)] transition-transform duration-300 group-hover:scale-105"
>
<motion.path
d="M 45 10 C 45 29.33 29.33 45 10 45 C 29.33 45 45 60.67 45 80 C 45 60.67 60.67 45 80 45 C 60.67 45 45 29.33 45 10 Z"
fill="#818CF8"
style={{ transformOrigin: "45px 45px" }}
animate={reduce ? {} : { scale: [1, 1.08, 1], rotate: [0, 4, 0, -4, 0] }}
transition={{ duration: 3.6, repeat: Infinity, ease: "easeInOut" }}
/>
<motion.path
d="M 88 15 C 88 23 81 30 73 30 C 81 30 88 37 88 45 C 88 37 95 30 103 30 C 95 30 88 23 88 15 Z"
fill="#C084FC"
style={{ transformOrigin: "88px 30px" }}
animate={reduce ? {} : { scale: [0.85, 1.2, 0.85], y: [0, -4, 0] }}
transition={{ duration: 2.8, delay: 0.4, repeat: Infinity, ease: "easeInOut" }}
/>
<motion.path
d="M 82 72 C 82 78.6 76.6 84 70 84 C 76.6 84 82 89.4 82 96 C 82 89.4 87.4 84 94 84 C 87.4 84 82 78.6 82 72 Z"
fill="#F5D0FE"
style={{ transformOrigin: "82px 84px" }}
animate={reduce ? {} : { scale: [1.15, 0.8, 1.15], rotate: [0, -8, 0] }}
transition={{ duration: 3.0, delay: 1.1, repeat: Infinity, ease: "easeInOut" }}
/>
</svg>
</div>
);
}
// 3. Merchant First Graphic (Golden Storefront & Canopy)
function MerchantGraphic({ reduce = false }: { reduce?: boolean }) {
return (
<div className="relative flex items-center justify-center p-2">
<motion.div
className="absolute h-20 w-20 rounded-full bg-amber-500/20 blur-xl pointer-events-none"
animate={reduce ? {} : { scale: [0.9, 1.25, 0.9], opacity: [0.25, 0.5, 0.25] }}
transition={{ duration: 3.5, repeat: Infinity, ease: "easeInOut" }}
/>
<svg
width="110"
height="110"
viewBox="0 0 110 110"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="relative z-10 w-24 h-24 md:w-28 md:h-28 filter drop-shadow-[0_10px_20px_rgba(0,0,0,0.35)] transition-transform duration-300 group-hover:scale-105"
>
<motion.path
d="M 20 40 L 90 40 L 82 22 L 28 22 Z"
fill="#FBBF24"
animate={reduce ? {} : { y: [0, -3, 0] }}
transition={{ duration: 3, repeat: Infinity, ease: "easeInOut" }}
/>
<path d="M 34 22 L 30 40 M 48 22 L 46 40 M 62 22 L 62 40 M 76 22 L 78 40" stroke="#D97706" strokeWidth="2.5" />
<rect x="25" y="40" width="60" height="46" rx="4" fill="url(#merchant-grad)" stroke="#FDE047" strokeWidth="2" />
<rect x="43" y="56" width="24" height="30" rx="3" fill="#78350F" />
<circle cx="55" cy="48" r="4" fill="#FDE047" />
<defs>
<linearGradient id="merchant-grad" x1="25" y1="40" x2="85" y2="86" gradientUnits="userSpaceOnUse">
<stop stopColor="#D97706" stopOpacity="0.8" />
<stop offset="1" stopColor="#F59E0B" stopOpacity="0.4" />
</linearGradient>
</defs>
</svg>
</div>
);
}
// 4. Local Graphic (Sky Pin & Radar Pulse)
function LocalGraphic({ reduce = false }: { reduce?: boolean }) {
return (
<div className="relative flex items-center justify-center p-2">
<motion.div
className="absolute h-20 w-20 rounded-full bg-sky-500/20 blur-xl pointer-events-none"
animate={reduce ? {} : { scale: [0.9, 1.25, 0.9], opacity: [0.25, 0.5, 0.25] }}
transition={{ duration: 3.5, repeat: Infinity, ease: "easeInOut" }}
/>
<svg
width="110"
height="110"
viewBox="0 0 110 110"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="relative z-10 w-24 h-24 md:w-28 md:h-28 filter drop-shadow-[0_10px_20px_rgba(0,0,0,0.35)] transition-transform duration-300 group-hover:scale-105"
>
<motion.path
d="M 55 18 C 40 18 28 30 28 45 C 28 65 55 88 55 88 C 55 88 82 65 82 45 C 82 30 70 18 55 18 Z"
fill="url(#local-grad)"
stroke="#7DD3FC"
strokeWidth="2"
animate={reduce ? {} : { y: [0, -6, 0] }}
transition={{ duration: 2.8, repeat: Infinity, ease: "easeInOut" }}
/>
<circle cx="55" cy="43" r="9" fill="#0284C7" />
<circle cx="55" cy="43" r="4" fill="#FFFFFF" />
<defs>
<linearGradient id="local-grad" x1="28" y1="18" x2="82" y2="88" gradientUnits="userSpaceOnUse">
<stop stopColor="#0284C7" stopOpacity="0.8" />
<stop offset="1" stopColor="#38BDF8" stopOpacity="0.4" />
</linearGradient>
</defs>
</svg>
</div>
);
}
const CARD_MOTES = [
{ left: "20%", top: "35%", size: 4, duration: 4.5, delay: 0 },
{ left: "75%", top: "60%", size: 3, duration: 5.5, delay: 0.8 },
];
const PRINCIPLES = [
{
word: "Trust",
icon: "verified_user",
line: "Local relationships cannot be replaced.",
badgeStyle: "bg-emerald-500/15 border-emerald-500/30 text-emerald-400",
dotColor: "bg-emerald-400",
spotlightColor: "rgba(52,211,153,0.18)",
renderGraphic: (reduce: boolean) => <TrustGraphic reduce={reduce} />,
},
{
word: "AI",
icon: "psychology",
line: "Removes complexity instead of adding more choices.",
badgeStyle: "bg-[#7C3AED]/20 border-[#7C3AED]/40 text-[#C084FC]",
dotColor: "bg-[#C084FC]",
spotlightColor: "rgba(168,85,247,0.20)",
renderGraphic: (reduce: boolean) => <AIGraphic reduce={reduce} />,
},
{
word: "Merchant First",
icon: "storefront",
line: "Technology should empower neighbourhood businesses.",
badgeStyle: "bg-amber-500/15 border-amber-500/30 text-amber-400",
dotColor: "bg-amber-400",
spotlightColor: "rgba(251,191,36,0.18)",
renderGraphic: (reduce: boolean) => <MerchantGraphic reduce={reduce} />,
},
{
word: "Local",
icon: "near_me",
line: "Every recommendation starts with nearby trusted merchants.",
badgeStyle: "bg-sky-500/15 border-sky-500/30 text-sky-400",
dotColor: "bg-sky-400",
spotlightColor: "rgba(56,189,248,0.18)",
renderGraphic: (reduce: boolean) => <LocalGraphic reduce={reduce} />,
},
];
export function CorePrinciples() {
const reduce = useReducedMotion();
return (
<section
aria-labelledby="core-principles-title"
className="w-full bg-white px-2 py-6 sm:px-4 md:py-8"
>
<div className="mx-auto max-w-[1840px]">
<div className="section-card-dark relative px-6 py-10 text-white md:px-12 md:py-12 lg:px-14 lg:py-14">
{/* Ambient purple wash */}
<div aria-hidden="true" className="pointer-events-none absolute inset-0">
<div className="absolute left-[-8%] top-[-10%] h-[420px] w-[420px] rounded-full bg-[#7C3AED]/18 blur-[130px]" />
<div className="absolute right-[-6%] bottom-[-12%] h-[380px] w-[380px] rounded-full bg-[#A855F7]/12 blur-[120px]" />
</div>
<motion.div
variants={staggerContainer}
initial="hidden"
whileInView="visible"
viewport={viewport}
className="relative z-10 max-w-[1100px]"
>
<motion.span
variants={fadeUp}
className="inline-flex items-center gap-2 rounded-full border border-white/15 px-3.5 py-1 text-xs font-black uppercase tracking-widest text-white/70"
>
What We Build On
</motion.span>
<motion.h2
id="core-principles-title"
variants={fadeUp}
className="mt-3 text-balance font-display font-black tracking-tight"
style={{ fontSize: "clamp(32px, 3.8vw, 54px)", lineHeight: 1.06 }}
>
Four principles behind{" "}
<span className="text-[#C084FC]">every decision.</span>
</motion.h2>
</motion.div>
{/* Editorial principle blocks with left text and right distinct SVG graphic */}
<motion.div
variants={staggerSlow}
initial="hidden"
whileInView="visible"
viewport={viewport}
className="relative z-10 mt-8 grid gap-5 overflow-hidden rounded-3xl md:mt-10 md:grid-cols-2 lg:gap-7"
>
{PRINCIPLES.map((principle) => (
<motion.div
key={principle.word}
variants={fadeUp}
whileHover={reduce ? undefined : { y: -5, scale: 1.008 }}
transition={{ type: "spring", stiffness: 260, damping: 22 }}
className="group relative h-full"
>
<Spotlight
className="relative overflow-hidden h-full rounded-3xl border border-white/10 bg-[#150320] p-6 md:p-8 lg:p-9 transition-all duration-300 group-hover:border-white/25 group-hover:shadow-[0_20px_40px_-15px_rgba(0,0,0,0.5)]"
color={principle.spotlightColor}
size={460}
>
{/* Floating Flying Particle Glow Dots (Motes) - Shown ONLY on Hover */}
<div aria-hidden="true" className="pointer-events-none absolute inset-0 overflow-hidden z-0 opacity-0 transition-opacity duration-500 group-hover:opacity-100">
{CARD_MOTES.map((mote, idx) => (
<motion.span
key={idx}
className={`absolute rounded-full ${principle.dotColor} shadow-[0_0_8px_currentColor]`}
style={{
left: mote.left,
top: mote.top,
width: mote.size,
height: mote.size,
}}
animate={
reduce
? {}
: {
y: [0, -12, 0],
x: [0, 6, 0],
opacity: [0.3, 0.9, 0.3],
scale: [0.8, 1.2, 0.8],
}
}
transition={{
duration: mote.duration,
delay: mote.delay,
repeat: Infinity,
ease: "easeInOut",
}}
/>
))}
</div>
{/* Corner Hover Glowing Dot */}
<div className="absolute top-5 right-5 z-20 flex items-center gap-2 opacity-50 transition-opacity duration-300 group-hover:opacity-100">
<span className="relative flex h-2.5 w-2.5">
<span className={`absolute inline-flex h-full w-full animate-ping rounded-full ${principle.dotColor} opacity-75`} />
<span className={`relative inline-flex h-2.5 w-2.5 rounded-full ${principle.dotColor} shadow-[0_0_8px_currentColor]`} />
</span>
</div>
{/* Ambient Corner Glow Orb */}
<div
aria-hidden="true"
className={`pointer-events-none absolute -bottom-10 -right-10 h-44 w-44 rounded-full blur-3xl opacity-20 transition-all duration-500 group-hover:scale-150 group-hover:opacity-50 ${principle.dotColor}`}
/>
<div className="relative z-10 flex items-center justify-between gap-6">
{/* Left Column: Badge + Title + Description */}
<div className="flex-1 min-w-0 pr-2">
<span className={`inline-flex h-10 w-10 items-center justify-center rounded-2xl border ${principle.badgeStyle} mb-4 shadow-sm transition-transform duration-300 group-hover:scale-110`}>
<MaterialIcon icon={principle.icon} size={20} />
</span>
<h3 className="font-display font-black text-white text-xl md:text-2xl lg:text-3xl tracking-tight mb-2">
{principle.word}
</h3>
<p className="text-sm md:text-base leading-relaxed text-white/75 max-w-[500px]">
{principle.line}
</p>
</div>
{/* Right Column: Tailored Animated SVG Graphic */}
<div className="shrink-0 flex items-center justify-center self-center">
{principle.renderGraphic(reduce)}
</div>
</div>
</Spotlight>
</motion.div>
))}
</motion.div>
</div>
</div>
</section>
);
}