Initial commit
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
"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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user