139 lines
5.0 KiB
TypeScript
139 lines
5.0 KiB
TypeScript
"use client";
|
|
|
|
import { motion } from "framer-motion";
|
|
import { ArrowRight } from "lucide-react";
|
|
import GlowButton from "@/components/ui/GlowButton";
|
|
import { fadeUp, stagger } from "@/lib/animations";
|
|
import type { Dictionary, Locale } from "@/lib/dictionaries";
|
|
|
|
interface HeroProps {
|
|
locale: Locale;
|
|
dict: Dictionary;
|
|
}
|
|
|
|
export default function Hero({ locale, dict }: HeroProps) {
|
|
const stats = [
|
|
{ value: "13+", label: dict.hero.stats.projects },
|
|
{ value: "4", label: dict.hero.stats.clients },
|
|
{ value: "10", label: dict.hero.stats.infra },
|
|
{ value: "<24h", label: dict.hero.stats.response },
|
|
];
|
|
|
|
return (
|
|
<section className="relative isolate flex min-h-[100svh] items-center overflow-hidden pt-24">
|
|
{/* Grid background */}
|
|
<div className="pointer-events-none absolute inset-0 grid-bg [mask-image:radial-gradient(ellipse_at_center,#000_30%,transparent_70%)] opacity-50" />
|
|
|
|
{/* Floating orbs */}
|
|
<motion.div
|
|
className="pointer-events-none absolute left-[10%] top-[10%] h-[700px] w-[700px] rounded-full"
|
|
style={{
|
|
background:
|
|
"radial-gradient(circle, rgba(139, 92, 246, 0.55) 0%, transparent 70%)",
|
|
filter: "blur(60px)",
|
|
}}
|
|
animate={{
|
|
x: [0, 40, -20, 0],
|
|
y: [0, -30, 20, 0],
|
|
scale: [1, 1.1, 0.95, 1],
|
|
}}
|
|
transition={{ duration: 18, repeat: Infinity, ease: "easeInOut" }}
|
|
/>
|
|
<motion.div
|
|
className="pointer-events-none absolute right-[5%] top-[30%] h-[600px] w-[600px] rounded-full"
|
|
style={{
|
|
background:
|
|
"radial-gradient(circle, rgba(167, 139, 250, 0.35) 0%, transparent 70%)",
|
|
filter: "blur(70px)",
|
|
}}
|
|
animate={{
|
|
x: [0, -50, 30, 0],
|
|
y: [0, 40, -25, 0],
|
|
scale: [1, 0.9, 1.1, 1],
|
|
}}
|
|
transition={{ duration: 22, repeat: Infinity, ease: "easeInOut" }}
|
|
/>
|
|
|
|
{/* Top accent line */}
|
|
<div className="pointer-events-none absolute inset-x-0 top-0 mx-auto h-px max-w-3xl bg-gradient-to-r from-transparent via-purple-400/50 to-transparent" />
|
|
|
|
{/* Content */}
|
|
<div className="relative mx-auto w-full max-w-7xl px-6 lg:px-8">
|
|
<motion.div
|
|
variants={stagger(0.1)}
|
|
initial="hidden"
|
|
animate="visible"
|
|
className="mx-auto max-w-4xl text-center"
|
|
>
|
|
{/* Badge */}
|
|
<motion.div variants={fadeUp} className="mb-8 flex justify-center">
|
|
<span className="inline-flex items-center gap-2 rounded-full border border-emerald-500/30 bg-emerald-500/10 px-3.5 py-1.5 font-mono text-xs tracking-tight text-emerald-300 backdrop-blur-md">
|
|
<span className="relative flex h-1.5 w-1.5">
|
|
<span className="absolute inset-0 animate-ping rounded-full bg-emerald-400 opacity-75" />
|
|
<span className="relative inline-flex h-1.5 w-1.5 rounded-full bg-emerald-400" />
|
|
</span>
|
|
{dict.hero.badge}
|
|
</span>
|
|
</motion.div>
|
|
|
|
{/* Heading */}
|
|
<motion.h1
|
|
variants={fadeUp}
|
|
className="font-display text-display-2xl font-medium tracking-tight"
|
|
>
|
|
<span className="text-gradient-fade">{dict.hero.titleLine1}</span>
|
|
<br />
|
|
<span className="text-gradient-purple">{dict.hero.titleLine2}</span>
|
|
</motion.h1>
|
|
|
|
{/* Subtitle */}
|
|
<motion.p
|
|
variants={fadeUp}
|
|
className="mx-auto mt-8 max-w-2xl text-lg leading-relaxed text-text-secondary sm:text-xl"
|
|
>
|
|
{dict.hero.subtitle}
|
|
</motion.p>
|
|
|
|
{/* CTAs */}
|
|
<motion.div
|
|
variants={fadeUp}
|
|
className="mt-12 flex flex-wrap items-center justify-center gap-4"
|
|
>
|
|
<GlowButton
|
|
href={`/${locale}/contact`}
|
|
variant="primary"
|
|
size="lg"
|
|
icon={<ArrowRight className="h-4 w-4" />}
|
|
>
|
|
{dict.hero.cta}
|
|
</GlowButton>
|
|
</motion.div>
|
|
|
|
{/* Stats */}
|
|
<motion.div
|
|
variants={fadeUp}
|
|
className="mt-20 grid grid-cols-2 gap-px overflow-hidden rounded-2xl border border-border/60 bg-border/40 sm:grid-cols-4"
|
|
>
|
|
{stats.map((stat) => (
|
|
<div
|
|
key={stat.label}
|
|
className="bg-background/60 px-6 py-6 backdrop-blur-sm"
|
|
>
|
|
<div className="font-display text-3xl font-medium tracking-tight text-text-primary sm:text-4xl">
|
|
{stat.value}
|
|
</div>
|
|
<div className="mt-1 font-mono text-[11px] uppercase tracking-widest text-text-secondary">
|
|
{stat.label}
|
|
</div>
|
|
</div>
|
|
))}
|
|
</motion.div>
|
|
</motion.div>
|
|
</div>
|
|
|
|
{/* Bottom fade */}
|
|
<div className="pointer-events-none absolute inset-x-0 bottom-0 h-32 bg-gradient-to-t from-background to-transparent" />
|
|
</section>
|
|
);
|
|
}
|