portfolio anim

This commit is contained in:
2026-03-27 18:17:50 +01:00
parent eaa87310f1
commit 7754bce7af

View File

@@ -1,4 +1,25 @@
import { useEffect, useState } from 'react'
export function HeroSection() {
const [stage, setStage] = useState(0)
useEffect(() => {
const t1 = setTimeout(() => setStage(1), 300)
const t2 = setTimeout(() => setStage(2), 1600)
const t3 = setTimeout(() => setStage(3), 3000)
return () => {
clearTimeout(t1)
clearTimeout(t2)
clearTimeout(t3)
}
}, [])
const fadeUp = (active: boolean) => ({
opacity: active ? 1 : 0,
transform: active ? 'translateY(0)' : 'translateY(16px)',
transition: 'opacity 0.8s ease, transform 0.8s ease',
})
return (
<section
id="hero"
@@ -18,31 +39,74 @@ export function HeroSection() {
<div className="absolute top-1/3 left-1/2 -translate-x-1/2 -translate-y-1/2 w-96 h-96 rounded-full bg-accent/5 blur-3xl pointer-events-none" />
<div className="relative z-10 max-w-4xl mx-auto px-6 py-24 text-center">
{/* Location badge */}
{/* Location badge — Stage 3 */}
<div style={fadeUp(stage >= 3)}>
<div className="inline-flex items-center gap-2 px-3 py-1.5 mb-8 rounded-full border border-zinc-800 bg-zinc-900/60 text-xs text-zinc-400 font-mono tracking-wider">
<span className="w-1.5 h-1.5 rounded-full bg-accent animate-pulse" />
Switzerland, Bern
</div>
</div>
{/* Name */}
{/* Name — animated across 3 stages */}
<h1 className="font-heading font-extrabold text-6xl md:text-8xl tracking-tight mb-4 leading-none">
<span className="text-white">Alexander</span>
{/* "b" slides in from the left — Stage 2 */}
<span
style={{
display: 'inline-block',
color: '#22d3ee',
opacity: stage >= 2 ? 1 : 0,
transform: stage >= 2 ? 'translateX(0)' : 'translateX(-160px)',
transition: 'opacity 1s ease, transform 1s ease',
}}
>
b
</span>
{/* "Alex" fades in centered — Stage 1 */}
<span
style={{
display: 'inline-block',
color: 'white',
opacity: stage >= 1 ? 1 : 0,
transition: 'opacity 0.8s ease',
}}
>
Alex
</span>
{/* "vic.com" slides in from the right — Stage 2 */}
<span
style={{
display: 'inline-block',
color: '#22d3ee',
opacity: stage >= 2 ? 1 : 0,
transform: stage >= 2 ? 'translateX(0)' : 'translateX(160px)',
transition: 'opacity 1s ease, transform 1s ease',
}}
>
vic.com
</span>
</h1>
{/* Role */}
{/* Role — Stage 3 */}
<div style={fadeUp(stage >= 3)}>
<p className="font-heading font-medium text-2xl md:text-3xl text-gradient mb-6 tracking-tight">
Java / Fullstack Developer
</p>
</div>
{/* Description */}
{/* Description — Stage 3 */}
<div style={{ ...fadeUp(stage >= 3), transitionDelay: '0.1s' }}>
<p className="text-zinc-400 text-lg max-w-xl mx-auto mb-10 font-body leading-relaxed">
Building backend systems and intelligent applications with{' '}
<span className="text-zinc-200 font-mono text-base">Spring Boot</span>,{' '}
<span className="text-zinc-200 font-mono text-base">React</span>, and{' '}
<span className="text-zinc-200 font-mono text-base">AI</span>.
</p>
</div>
{/* CTA buttons */}
{/* CTA buttons — Stage 3 */}
<div style={{ ...fadeUp(stage >= 3), transitionDelay: '0.2s' }}>
<div className="flex flex-wrap items-center justify-center gap-4">
<a
href="/static/cv.pdf"
@@ -84,8 +148,10 @@ export function HeroSection() {
LinkedIn
</a>
</div>
</div>
{/* Scroll hint */}
{/* Scroll hint — Stage 3 */}
<div style={{ ...fadeUp(stage >= 3), transitionDelay: '0.3s' }}>
<div className="mt-16 flex flex-col items-center gap-2 text-zinc-600 text-xs font-mono tracking-widest">
<span>SCROLL</span>
<svg
@@ -108,6 +174,7 @@ export function HeroSection() {
</svg>
</div>
</div>
</div>
</section>
)
}