Harden onion boot flow and deepen site surfaces
Add persistent onion key backup and restore, improve startup resilience, and flesh out the major site verticals with richer navigation, search coverage, and operator documentation. Made-with: Cursor
This commit is contained in:
173
components/Hero.tsx
Normal file
173
components/Hero.tsx
Normal file
@@ -0,0 +1,173 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import Link from "next/link";
|
||||
import { SHOP_PRODUCT_COUNT } from "@/lib/shopCatalog";
|
||||
import { SHOP_SELLER_COUNT } from "@/lib/shopSellers";
|
||||
|
||||
const Hero = () => {
|
||||
const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });
|
||||
const [particles, setParticles] = useState<Array<{ x: number; y: number; size: number; speed: number }>>([]);
|
||||
|
||||
useEffect(() => {
|
||||
const handleMouseMove = (e: MouseEvent) => {
|
||||
setMousePosition({ x: e.clientX, y: e.clientY });
|
||||
};
|
||||
window.addEventListener("mousemove", handleMouseMove);
|
||||
|
||||
// Generate floating particles
|
||||
const particleCount = 30;
|
||||
const newParticles = [];
|
||||
for (let i = 0; i < particleCount; i++) {
|
||||
newParticles.push({
|
||||
x: Math.random() * 100,
|
||||
y: Math.random() * 100,
|
||||
size: Math.random() * 3 + 1,
|
||||
speed: Math.random() * 0.5 + 0.2,
|
||||
});
|
||||
}
|
||||
setParticles(newParticles);
|
||||
|
||||
return () => window.removeEventListener("mousemove", handleMouseMove);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<section className="relative min-h-screen overflow-hidden px-4 pt-32 md:pt-40">
|
||||
{/* Animated background particles */}
|
||||
<div className="absolute inset-0 -z-20">
|
||||
{particles.map((p, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="absolute rounded-full bg-neon-cyan opacity-20"
|
||||
style={{
|
||||
left: `${p.x}vw`,
|
||||
top: `${p.y}vh`,
|
||||
width: `${p.size}px`,
|
||||
height: `${p.size}px`,
|
||||
animation: `float ${3 / p.speed}s ease-in-out infinite`,
|
||||
animationDelay: `${i * 0.1}s`,
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
{/* Glowing orbs */}
|
||||
<div
|
||||
className="absolute left-1/4 top-1/4 h-64 w-64 rounded-full bg-neon-purple opacity-10 blur-3xl"
|
||||
style={{
|
||||
transform: `translate(${mousePosition.x * 0.01}px, ${mousePosition.y * 0.01}px)`,
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
className="absolute right-1/4 bottom-1/4 h-80 w-80 rounded-full bg-neon-cyan opacity-10 blur-3xl"
|
||||
style={{
|
||||
transform: `translate(${-mousePosition.x * 0.01}px, ${-mousePosition.y * 0.01}px)`,
|
||||
}}
|
||||
/>
|
||||
{/* Grid lines */}
|
||||
<div className="absolute inset-0 bg-[linear-gradient(90deg,transparent_49%,rgba(0,224,255,0.03)_50%,transparent_51%,transparent)] bg-[length:40px_40px]"></div>
|
||||
<div className="absolute inset-0 bg-[linear-gradient(transparent_49%,rgba(0,224,255,0.03)_50%,transparent_51%,transparent)] bg-[length:40px_40px]"></div>
|
||||
</div>
|
||||
|
||||
<div className="container relative mx-auto max-w-6xl">
|
||||
{/* Glitch text effect */}
|
||||
<div className="relative mb-6">
|
||||
<h1 className="font-orbitron text-5xl font-black leading-tight text-foreground md:text-7xl lg:text-8xl">
|
||||
<span className="block">REVOLUTIONARY</span>
|
||||
<span className="block text-transparent bg-gradient-to-r from-neon-cyan via-neon-purple to-neon-pink bg-clip-text">
|
||||
E‑COMMERCE
|
||||
</span>
|
||||
<span className="block">EXPERIENCE</span>
|
||||
</h1>
|
||||
<div className="absolute -top-2 left-0 -z-10 text-5xl font-black text-neon-cyan opacity-30 blur-md md:text-7xl lg:text-8xl">
|
||||
REVOLUTIONARY
|
||||
</div>
|
||||
<div className="absolute -bottom-2 right-0 -z-10 text-5xl font-black text-neon-purple opacity-30 blur-md md:text-7xl lg:text-8xl">
|
||||
EXPERIENCE
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p className="mb-8 max-w-2xl text-xl text-foreground/80 md:text-2xl">
|
||||
Curated <span className="text-neon-cyan">gray-market candy</span> storefront with live catalog, vendor hall, and BTC-settled
|
||||
checkout — plus companion onions for forums, listings, and the wiki rail.
|
||||
</p>
|
||||
|
||||
<div className="mb-10 flex flex-wrap gap-2 font-mono text-[10px] uppercase tracking-[0.2em] text-foreground/45">
|
||||
<Link href="#featured" className="rounded border border-white/10 px-3 py-1.5 hover:border-neon-cyan/40 hover:text-neon-cyan/90">
|
||||
Featured
|
||||
</Link>
|
||||
<Link href="#categories" className="rounded border border-white/10 px-3 py-1.5 hover:border-neon-cyan/40 hover:text-neon-cyan/90">
|
||||
Categories
|
||||
</Link>
|
||||
<Link href="/market" className="rounded border border-white/10 px-3 py-1.5 hover:border-neon-purple/40 hover:text-neon-purple/90">
|
||||
Full market
|
||||
</Link>
|
||||
<Link href="/forum" className="rounded border border-white/10 px-3 py-1.5 hover:border-[#ff9a3c]/40 hover:text-[#ffcb8a]">
|
||||
Forum
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* CTA Buttons */}
|
||||
<div className="flex flex-wrap gap-4 md:gap-6">
|
||||
<Link
|
||||
href="/market"
|
||||
className="group relative overflow-hidden rounded-full bg-gradient-to-r from-neon-cyan to-neon-purple px-8 py-4 font-bold text-background transition-all hover:scale-[1.02] hover:shadow-2xl hover:shadow-neon-cyan/40"
|
||||
>
|
||||
<span className="relative z-10">BROWSE CATALOG</span>
|
||||
<div className="absolute inset-0 -z-10 bg-gradient-to-r from-neon-purple to-neon-cyan opacity-0 transition-opacity group-hover:opacity-100"></div>
|
||||
<div className="absolute -inset-1 -z-20 animate-pulse rounded-full bg-neon-cyan blur-md opacity-30"></div>
|
||||
</Link>
|
||||
<Link
|
||||
href="/checkout"
|
||||
className="group glass rounded-full border border-neon-green/35 px-8 py-4 font-bold text-neon-green transition-all hover:border-neon-green hover:bg-neon-green/10"
|
||||
>
|
||||
<span className="flex items-center gap-2">
|
||||
<span className="text-lg">₿</span>
|
||||
CHECKOUT & BALANCE
|
||||
</span>
|
||||
</Link>
|
||||
<Link
|
||||
href="/sanctuary"
|
||||
className="group glass rounded-full border border-neon-cyan/30 px-7 py-4 text-sm font-bold text-neon-cyan transition-all hover:border-neon-cyan hover:bg-neon-cyan/10"
|
||||
>
|
||||
SANCTUARY
|
||||
</Link>
|
||||
<Link
|
||||
href="/drops"
|
||||
className="group glass rounded-full border border-neon-pink/25 px-7 py-4 text-sm font-medium text-foreground/85 transition-all hover:border-neon-pink/50"
|
||||
>
|
||||
<span className="flex items-center gap-2">
|
||||
<span className="text-lg">🚀</span>
|
||||
DROPS
|
||||
<span className="ml-1 inline-block h-2 w-2 animate-pulse rounded-full bg-neon-pink"></span>
|
||||
</span>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* Stats */}
|
||||
<div className="mt-20 grid grid-cols-2 gap-6 sm:grid-cols-4">
|
||||
{[
|
||||
{ value: String(SHOP_PRODUCT_COUNT), label: "Live SKUs", color: "text-neon-cyan" },
|
||||
{ value: String(SHOP_SELLER_COUNT), label: "Vendor stalls", color: "text-neon-green" },
|
||||
{ value: "₿ · Ξ · XMR", label: "Settlement rails", color: "text-neon-purple" },
|
||||
{ value: "v3 ring", label: "Tor-ready layout", color: "text-neon-pink" },
|
||||
].map((stat) => (
|
||||
<div
|
||||
key={stat.label}
|
||||
className="glass rounded-2xl border border-white/10 p-6 backdrop-blur-sm"
|
||||
>
|
||||
<div className={`font-orbitron text-3xl font-bold ${stat.color}`}>{stat.value}</div>
|
||||
<div className="mt-2 text-sm text-foreground/60">{stat.label}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Scroll indicator */}
|
||||
<div className="absolute bottom-10 left-1/2 -translate-x-1/2">
|
||||
<div className="h-10 w-px bg-gradient-to-b from-neon-cyan to-transparent"></div>
|
||||
<div className="mt-2 text-xs text-foreground/40">SCROLL TO UNCOVER</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Hero;
|
||||
Reference in New Issue
Block a user