nicholais-website/app/sections/HeroSection.tsx

95 lines
3.6 KiB
TypeScript

"use client";
import React from "react";
import { motion } from "motion/react";
import { Parallax } from "@/components/parallax/Parallax";
import { FlipWords } from "@/components/ui/flip-words";
import { AvatarMotion } from "@/app/components/avatar-motion";
import { TRANSITIONS } from "@/lib/animation";
export function HeroSection() {
return (
<section
id="hero"
aria-label="Hero"
className="relative min-h-[130vh] w-full overflow-clip flex items-center"
>
{/* Background depth layers */}
<Parallax speed={0.05} className="pointer-events-none absolute inset-0 -z-20">
<div className="absolute inset-0 bg-[radial-gradient(1200px_600px_at_50%_-20%,rgba(255,255,255,0.10),transparent_70%)]" />
</Parallax>
<Parallax speed={0.08} className="pointer-events-none absolute inset-0 -z-10">
<div className="absolute -inset-x-10 -inset-y-20 bg-gradient-to-b from-transparent via-white/5 to-transparent blur-2xl" />
</Parallax>
{/* Content */}
<div className="relative z-10 mx-auto flex w-full max-w-5xl flex-col items-center gap-8 px-6">
<Parallax speed={-0.12} className="mt-24">
<AvatarMotion
src="/images/profile.jpg"
srcSet={{
avif: {
'120': '/images/profile-120.avif',
'160': '/images/profile-160.avif',
'original': '/images/profile.avif'
},
fallback: '/images/profile.jpg'
}}
alt="Hand drawn portrait of Nicholai"
size={200}
className="ring-1 ring-white/10"
/>
</Parallax>
<div className="text-center">
<motion.h1
className="mx-auto max-w-3xl bg-clip-text text-5xl font-extrabold tracking-tight text-transparent sm:text-6xl md:text-7xl
bg-gradient-to-b from-neutral-100 to-neutral-300"
initial={{ opacity: 0, y: 24, filter: "blur(8px)" }}
animate={{ opacity: 1, y: 0, filter: "blur(0px)" }}
transition={TRANSITIONS.base}
>
Nicholai
</motion.h1>
<motion.p
className="mx-auto mt-3 max-w-xl text-balance text-sm text-neutral-300 sm:text-base"
initial={{ opacity: 0, y: 12 }}
animate={{ opacity: 1, y: 0 }}
transition={{ ...TRANSITIONS.base, delay: 0.1 }}
>
Building cinematic web moments with code and craft.
</motion.p>
<motion.div
className="mx-auto mt-4 text-base sm:text-lg text-neutral-200"
initial={{ opacity: 0, y: 8 }}
animate={{ opacity: 1, y: 0 }}
transition={{ ...TRANSITIONS.base, delay: 0.2 }}
>
<FlipWords
words={["VFX Artist", "Developer", "Experience Designer"]}
className="font-medium"
/>
</motion.div>
</div>
{/* Scroll cue */}
<motion.div
aria-hidden
className="absolute bottom-8 left-1/2 -translate-x-1/2 text-neutral-400"
initial={{ opacity: 0, y: 0 }}
animate={{ opacity: 1, y: [0, 6, 0] }}
transition={{ duration: 1.8, repeat: Infinity, ease: [0.2, 0.8, 0.2, 1] }}
>
<svg width="20" height="28" viewBox="0 0 20 28" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="1.5" y="1.5" width="17" height="25" rx="8.5" stroke="currentColor" opacity="0.45"/>
<circle cx="10" cy="7" r="2" fill="currentColor"/>
</svg>
</motion.div>
</div>
</section>
);
}