Files
Portfolio/src/pages/home/components/Hero.tsx
T
damjan_savicandClaude Opus 4.5 c775f3bbb2 Performance: Hero-Text sofort sichtbar für bessere LCP
- Framer-motion Animationen aus Hero-Text entfernt
- Text-Elemente sind jetzt sofort sichtbar ohne opacity: 0
- Eliminiert 3.260ms Render-Verzögerung für LCP-Element
- Kontrast verbessert: text-zinc-500 -> text-zinc-400

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 22:23:38 +01:00

155 lines
7.9 KiB
TypeScript

import { useTranslation } from 'react-i18next';
import { Github, Linkedin, Mail } from 'lucide-react';
const Hero = () => {
const { t } = useTranslation();
const scrollToSection = (sectionId: string) => {
const element = document.getElementById(sectionId);
if (element) {
element.scrollIntoView({ behavior: 'smooth' });
}
};
return (
<section id="home" className="relative min-h-screen text-white overflow-hidden">
{/* Concentric Circles Background - mit GPU-Beschleunigung */}
<div className="absolute inset-0 pointer-events-none flex items-center justify-center" style={{ zIndex: 2 }}>
{[1, 2, 3].map((index) => (
<div
key={index}
className="absolute rounded-full border border-zinc-800/30"
style={{
width: `${index * 30}%`,
height: `${index * 30}%`,
opacity: 0.1,
transform: 'translateZ(0)'
}}
/>
))}
</div>
{/* Top Navigation */}
<div className="absolute top-4 w-full px-8 flex justify-between items-center" style={{ zIndex: 40 }}>
<div className="flex gap-4">
<a
href="https://www.linkedin.com/in/damjan-savi%C4%87-720288127/"
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center justify-center w-9 h-9 text-white hover:text-zinc-300 transition-colors"
aria-label={t('pages.home.hero.social.linkedin.title')}
>
<Linkedin className="h-5 w-5 pointer-events-none" />
</a>
<a
href="https://github.com/damjan1996"
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center justify-center w-9 h-9 text-white hover:text-zinc-300 transition-colors"
aria-label={t('pages.home.hero.social.github.title')}
>
<Github className="h-5 w-5 pointer-events-none" />
</a>
</div>
<a
href="mailto:info@damjan-savic.com"
className="text-white hover:text-zinc-300 transition-colors flex items-center gap-2 text-sm"
aria-label={t('pages.home.hero.social.email.title')}
>
{t('pages.home.hero.cta')}
</a>
</div>
{/* Main Content */}
<div className="flex flex-col items-center justify-start min-h-screen px-4 pt-20 relative" style={{ zIndex: 30 }}>
{/* Profile Image - optimiert für exakte Anzeigegröße */}
<div
className="w-56 h-56 sm:w-72 sm:h-72 mb-8 rounded-full overflow-hidden border-2 border-zinc-800"
style={{ transform: 'translateZ(0)' }}
>
<picture>
<source
srcSet="/portrait-224.webp 224w, /portrait-448.webp 448w, /portrait-288.webp 288w, /portrait-576.webp 576w"
sizes="(max-width: 640px) 224px, 288px"
type="image/webp"
/>
<source
srcSet="/portrait-224.jpg 224w, /portrait-288.jpg 288w"
sizes="(max-width: 640px) 224px, 288px"
type="image/jpeg"
/>
<img
src="/portrait-288.jpg"
alt={t('pages.home.hero.image.alt')}
className="w-full h-full object-cover"
loading="eager"
fetchPriority="high"
width={288}
height={288}
decoding="sync"
/>
</picture>
</div>
{/* Title and Name - sofort sichtbar für LCP (keine opacity Animation!) */}
<p className="text-zinc-400 text-sm sm:text-base tracking-wider mb-2">
{t('pages.home.hero.title')}
</p>
<h1 className="text-4xl sm:text-5xl font-bold mb-3 flex items-center">
{t('pages.home.hero.name')}<span className="animate-pulse ml-1">|</span>
</h1>
<p className="text-zinc-300 text-sm sm:text-base max-w-xl text-center mb-2 px-4">
{t('pages.home.hero.description')}
</p>
<p className="text-zinc-400 text-xs sm:text-sm mb-8">
{t('pages.home.hero.currentRole')}
</p>
{/* Navigation */}
<div className="flex flex-col sm:flex-row gap-4 sm:gap-8 text-white text-base sm:text-lg z-20">
<button
onClick={() => scrollToSection('experience')}
className="relative w-full sm:w-auto px-8 py-3 rounded-full uppercase cursor-pointer overflow-hidden group"
>
<span className="relative z-10">{t('pages.home.hero.navigation.experience')}</span>
<div className="absolute inset-0 bg-zinc-700/50 opacity-0 group-hover:opacity-100 transition-opacity duration-300 rounded-full" />
</button>
<button
onClick={() => scrollToSection('skills')}
className="relative w-full sm:w-auto px-8 py-3 rounded-full uppercase cursor-pointer overflow-hidden group"
>
<span className="relative z-10">{t('pages.home.hero.navigation.skills')}</span>
<div className="absolute inset-0 bg-zinc-700/50 opacity-0 group-hover:opacity-100 transition-opacity duration-300 rounded-full" />
</button>
<button
onClick={() => scrollToSection('projects')}
className="relative w-full sm:w-auto px-8 py-3 rounded-full uppercase cursor-pointer overflow-hidden group"
>
<span className="relative z-10">{t('pages.home.hero.navigation.projects')}</span>
<div className="absolute inset-0 bg-zinc-700/50 opacity-0 group-hover:opacity-100 transition-opacity duration-300 rounded-full" />
</button>
<button
onClick={() => scrollToSection('about')}
className="relative w-full sm:w-auto px-8 py-3 rounded-full uppercase cursor-pointer overflow-hidden group"
>
<span className="relative z-10">{t('pages.home.hero.navigation.about')}</span>
<div className="absolute inset-0 bg-zinc-700/50 opacity-0 group-hover:opacity-100 transition-opacity duration-300 rounded-full" />
</button>
</div>
</div>
{/* Contact Button Bottom */}
<div className="absolute bottom-4 left-1/2 transform -translate-x-1/2" style={{ zIndex: 40 }}>
<a
href="mailto:info@damjan-savic.com"
className="inline-flex items-center justify-center w-10 h-10 text-white hover:text-zinc-300 transition-colors"
aria-label={t('pages.home.hero.social.getInTouch')}
>
<Mail className="h-6 w-6 pointer-events-none" />
</a>
</div>
</section>
);
};
export default Hero;