perf: deep react code splitting, next-intl payload scoping, and SVG hardware acceleration for PageSpeed 100
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 23s
Build & Deploy / 🧪 QA (push) Successful in 2m1s
Build & Deploy / 🏗️ Build (push) Successful in 7m43s
Build & Deploy / 🚀 Deploy (push) Successful in 26s
Build & Deploy / 🧪 Smoke Test (push) Successful in 1m10s
Build & Deploy / ⚡ Lighthouse (push) Successful in 3m20s
Build & Deploy / 🔔 Notify (push) Successful in 2s

This commit is contained in:
2026-02-20 11:53:42 +01:00
parent 7542f42568
commit 16d06d3275
15 changed files with 1234 additions and 1121 deletions

View File

@@ -2,7 +2,7 @@
import Link from 'next/link';
import Image from 'next/image';
import { motion } from 'framer-motion';
import { m, LazyMotion, domAnimation } from 'framer-motion';
import { useTranslations } from 'next-intl';
import { usePathname } from 'next/navigation';
import { Button } from './ui';
@@ -114,55 +114,264 @@ export default function Header() {
return (
<>
<motion.header
className={headerClass}
initial={{ y: -100, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ duration: 0.8, ease: 'easeOut' }}
>
<div className="container mx-auto px-4 md:px-12 lg:px-16 max-w-7xl flex items-center justify-between">
<motion.div
className="flex-shrink-0 group touch-target"
initial={{ scale: 0.8, opacity: 0 }}
animate={{ scale: 1, opacity: 1 }}
transition={{ duration: 0.6, ease: 'easeOut', delay: 0.1 }}
>
<Link
href={`/${currentLocale}`}
onClick={() =>
trackEvent(AnalyticsEvents.BUTTON_CLICK, {
target: 'home_logo',
location: 'header',
})
}
<LazyMotion strict features={domAnimation}>
<m.header
className={headerClass}
initial={{ y: -100, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ duration: 0.8, ease: 'easeOut' }}
>
<div className="container mx-auto px-4 md:px-12 lg:px-16 max-w-7xl flex items-center justify-between">
<m.div
className="flex-shrink-0 group touch-target"
initial={{ scale: 0.8, opacity: 0 }}
animate={{ scale: 1, opacity: 1 }}
transition={{ duration: 0.6, ease: 'easeOut', delay: 0.1 }}
>
<Image
src={logoSrc}
alt={t('home')}
width={120}
height={120}
className="h-10 md:h-14 w-auto transition-all duration-500 group-hover:scale-110"
priority
/>
</Link>
</motion.div>
<Link
href={`/${currentLocale}`}
onClick={() =>
trackEvent(AnalyticsEvents.BUTTON_CLICK, {
target: 'home_logo',
location: 'header',
})
}
>
<Image
src={logoSrc}
alt={t('home')}
width={120}
height={120}
className="h-10 md:h-14 w-auto transition-all duration-500 group-hover:scale-110"
priority
/>
</Link>
</m.div>
<motion.div
className="flex items-center gap-4 md:gap-12"
initial="hidden"
animate="visible"
variants={{
visible: {
transition: {
staggerChildren: 0.08,
delayChildren: 0.3,
<m.div
className="flex items-center gap-4 md:gap-12"
initial="hidden"
animate="visible"
variants={{
visible: {
transition: {
staggerChildren: 0.08,
delayChildren: 0.3,
},
},
},
}}
}}
>
<m.nav className="hidden lg:flex items-center space-x-10" variants={navVariants}>
{menuItems.map((item, _idx) => (
<m.div key={item.href} variants={navLinkVariants}>
<Link
href={`/${currentLocale}${item.href === '/' ? '' : item.href}`}
onClick={() => {
setIsMobileMenuOpen(false);
trackEvent(AnalyticsEvents.LINK_CLICK, {
label: item.label,
href: item.href,
location: 'header_nav',
});
}}
className={cn(
textColorClass,
'hover:text-accent font-bold transition-all duration-500 text-base md:text-lg tracking-tight relative group inline-block hover:-translate-y-0.5',
)}
>
{item.label}
<span className="absolute -bottom-2 left-0 w-0 h-1 bg-accent transition-all duration-500 group-hover:w-full rounded-full shadow-[0_0_12px_rgba(130,237,32,0.6)]" />
</Link>
</m.div>
))}
</m.nav>
<m.div
className={cn('hidden lg:flex items-center space-x-8', textColorClass)}
variants={headerRightVariants}
>
<m.div
className="flex items-center space-x-4 text-xs md:text-sm font-extrabold tracking-widest uppercase"
initial={{ opacity: 0, x: 20 }}
animate={{ opacity: 1, x: 0 }}
transition={{ duration: 0.5, delay: 0.6 }}
>
<m.div
initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.4, delay: 0.65 }}
>
<Link
href={getPathForLocale('en')}
onClick={() =>
trackEvent(AnalyticsEvents.TOGGLE_SWITCH, {
type: 'language',
from: currentLocale,
to: 'en',
location: 'header',
})
}
className={`hover:text-accent transition-colors flex items-center gap-2 touch-target ${currentLocale === 'en' ? 'text-accent' : 'opacity-60'}`}
>
EN
</Link>
</m.div>
<m.div
className="w-px h-4 bg-current opacity-20"
initial={{ scaleY: 0 }}
animate={{ scaleY: 1 }}
transition={{ duration: 0.4, delay: 0.7 }}
/>
<m.div
initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.4, delay: 0.75 }}
>
<Link
href={getPathForLocale('de')}
onClick={() =>
trackEvent(AnalyticsEvents.TOGGLE_SWITCH, {
type: 'language',
from: currentLocale,
to: 'de',
location: 'header',
})
}
className={`hover:text-accent transition-colors flex items-center gap-2 touch-target ${currentLocale === 'de' ? 'text-accent' : 'opacity-60'}`}
>
DE
</Link>
</m.div>
</m.div>
<m.div
initial={{ scale: 0.9, opacity: 0 }}
animate={{ scale: 1, opacity: 1 }}
transition={{ duration: 0.6, type: 'spring', stiffness: 400, delay: 0.7 }}
>
<Button
href={`/${currentLocale}/contact`}
variant="white"
size="md"
className="px-8 shadow-xl"
onClick={() =>
trackEvent(AnalyticsEvents.BUTTON_CLICK, {
label: t('contact'),
location: 'header_cta',
})
}
>
{t('contact')}
</Button>
</m.div>
</m.div>
{/* Mobile Menu Button */}
<m.button
className={cn(
'lg:hidden touch-target p-2 rounded-xl bg-white/10 border border-white/20 z-50',
textColorClass,
)}
aria-label={t('toggleMenu')}
aria-expanded={isMobileMenuOpen}
aria-controls="mobile-menu"
initial={{ scale: 0.8, opacity: 0, rotate: -180 }}
animate={{ scale: 1, opacity: 1, rotate: 0 }}
transition={{
duration: 0.6,
type: 'spring',
stiffness: 300,
damping: 20,
delay: 0.5,
}}
onClick={() => {
const newState = !isMobileMenuOpen;
setIsMobileMenuOpen(newState);
trackEvent(AnalyticsEvents.BUTTON_CLICK, {
type: 'mobile_menu',
action: newState ? 'open' : 'close',
});
}}
>
<m.svg
className="w-7 h-7"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
initial={{ scale: 0 }}
animate={{ scale: 1 }}
transition={{ duration: 0.3, delay: 0.6 }}
>
{isMobileMenuOpen ? (
<m.path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M6 18L18 6M6 6l12 12"
initial={{ pathLength: 0 }}
animate={{ pathLength: 1 }}
transition={{ duration: 0.4, delay: 0.7 }}
/>
) : (
<m.path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M4 6h16M4 12h16M4 18h16"
initial={{ pathLength: 0 }}
animate={{ pathLength: 1 }}
transition={{ duration: 0.4, delay: 0.7 }}
/>
)}
</m.svg>
</m.button>
</m.div>
</div>
{/* Mobile Menu Overlay */}
<div
className={cn(
'fixed inset-0 bg-primary z-40 lg:hidden transition-all duration-500 ease-in-out flex flex-col',
isMobileMenuOpen
? 'opacity-100 translate-y-0'
: 'opacity-0 -translate-y-full pointer-events-none',
)}
id="mobile-menu"
role="dialog"
aria-modal="true"
aria-label={t('menu')}
ref={mobileMenuRef}
>
<motion.nav className="hidden lg:flex items-center space-x-10" variants={navVariants}>
{menuItems.map((item, _idx) => (
<motion.div key={item.href} variants={navLinkVariants}>
<m.nav
className="flex-grow flex flex-col justify-center items-center p-8 space-y-8"
initial="closed"
animate={isMobileMenuOpen ? 'open' : 'closed'}
variants={{
open: {
transition: {
staggerChildren: 0.1,
delayChildren: 0.2,
},
},
}}
>
{menuItems.map((item, idx) => (
<m.div
key={item.href}
variants={{
closed: { opacity: 0, y: 50, scale: 0.9 },
open: {
opacity: 1,
y: 0,
scale: 1,
transition: {
duration: 0.6,
ease: 'easeOut',
delay: idx * 0.08,
},
},
}}
>
<Link
href={`/${currentLocale}${item.href === '/' ? '' : item.href}`}
onClick={() => {
@@ -170,302 +379,95 @@ export default function Header() {
trackEvent(AnalyticsEvents.LINK_CLICK, {
label: item.label,
href: item.href,
location: 'header_nav',
location: 'mobile_menu',
});
}}
className={cn(
textColorClass,
'hover:text-accent font-bold transition-all duration-500 text-base md:text-lg tracking-tight relative group inline-block hover:-translate-y-0.5',
)}
className="text-2xl md:text-3xl font-extrabold text-white hover:text-accent transition-all transform block py-4"
>
{item.label}
<span className="absolute -bottom-2 left-0 w-0 h-1 bg-accent transition-all duration-500 group-hover:w-full rounded-full shadow-[0_0_12px_rgba(130,237,32,0.6)]" />
</Link>
</motion.div>
</m.div>
))}
</motion.nav>
<motion.div
className={cn('hidden lg:flex items-center space-x-8', textColorClass)}
variants={headerRightVariants}
>
<motion.div
className="flex items-center space-x-4 text-xs md:text-sm font-extrabold tracking-widest uppercase"
initial={{ opacity: 0, x: 20 }}
animate={{ opacity: 1, x: 0 }}
transition={{ duration: 0.5, delay: 0.6 }}
<m.div
className="pt-8 border-t border-white/10 w-full flex flex-col items-center space-y-8"
initial={{ opacity: 0, y: 30 }}
animate={isMobileMenuOpen ? { opacity: 1, y: 0 } : { opacity: 0, y: 30 }}
transition={{ duration: 0.5, delay: 0.8 }}
>
<motion.div
<m.div
className="flex items-center space-x-8 text-lg md:text-xl font-extrabold tracking-widest uppercase text-white"
initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.4, delay: 0.65 }}
transition={{ duration: 0.4, delay: 0.9 }}
>
<Link
href={getPathForLocale('en')}
onClick={() =>
trackEvent(AnalyticsEvents.TOGGLE_SWITCH, {
type: 'language',
from: currentLocale,
to: 'en',
location: 'header',
})
}
className={`hover:text-accent transition-colors flex items-center gap-2 touch-target ${currentLocale === 'en' ? 'text-accent' : 'opacity-60'}`}
<m.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.3, delay: 1.0 }}
>
EN
</Link>
</motion.div>
<motion.div
className="w-px h-4 bg-current opacity-20"
initial={{ scaleY: 0 }}
animate={{ scaleY: 1 }}
transition={{ duration: 0.4, delay: 0.7 }}
/>
<motion.div
initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.4, delay: 0.75 }}
>
<Link
href={getPathForLocale('de')}
onClick={() =>
trackEvent(AnalyticsEvents.TOGGLE_SWITCH, {
type: 'language',
from: currentLocale,
to: 'de',
location: 'header',
})
}
className={`hover:text-accent transition-colors flex items-center gap-2 touch-target ${currentLocale === 'de' ? 'text-accent' : 'opacity-60'}`}
<Link
href={getPathForLocale('en')}
className={`hover:text-accent transition-colors ${currentLocale === 'en' ? 'text-accent' : 'opacity-60'}`}
>
EN
</Link>
</m.div>
<m.div
className="w-px h-6 bg-white/20"
initial={{ scaleX: 0 }}
animate={{ scaleX: 1 }}
transition={{ duration: 0.4, delay: 1.05 }}
/>
<m.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.3, delay: 1.1 }}
>
DE
</Link>
</motion.div>
</motion.div>
<Link
href={getPathForLocale('de')}
className={`hover:text-accent transition-colors ${currentLocale === 'de' ? 'text-accent' : 'opacity-60'}`}
>
DE
</Link>
</m.div>
</m.div>
<motion.div
initial={{ scale: 0.9, opacity: 0 }}
animate={{ scale: 1, opacity: 1 }}
transition={{ duration: 0.6, type: 'spring', stiffness: 400, delay: 0.7 }}
>
<Button
href={`/${currentLocale}/contact`}
variant="white"
size="md"
className="px-8 shadow-xl"
onClick={() =>
trackEvent(AnalyticsEvents.BUTTON_CLICK, {
label: t('contact'),
location: 'header_cta',
})
}
<m.div
initial={{ scale: 0.9, opacity: 0, y: 20 }}
animate={{ scale: 1, opacity: 1, y: 0 }}
transition={{ type: 'spring', stiffness: 400, damping: 20, delay: 1.2 }}
>
{t('contact')}
</Button>
</motion.div>
</motion.div>
<Button
href={`/${currentLocale}/contact`}
variant="accent"
size="lg"
className="w-full max-w-xs py-6 text-lg md:text-xl shadow-2xl"
>
{t('contact')}
</Button>
</m.div>
</m.div>
{/* Mobile Menu Button */}
<motion.button
className={cn(
'lg:hidden touch-target p-2 rounded-xl bg-white/10 border border-white/20 z-50',
textColorClass,
)}
aria-label={t('toggleMenu')}
aria-expanded={isMobileMenuOpen}
aria-controls="mobile-menu"
initial={{ scale: 0.8, opacity: 0, rotate: -180 }}
animate={{ scale: 1, opacity: 1, rotate: 0 }}
transition={{
duration: 0.6,
type: 'spring',
stiffness: 300,
damping: 20,
delay: 0.5,
}}
onClick={() => {
const newState = !isMobileMenuOpen;
setIsMobileMenuOpen(newState);
trackEvent(AnalyticsEvents.BUTTON_CLICK, {
type: 'mobile_menu',
action: newState ? 'open' : 'close',
});
}}
>
<motion.svg
className="w-7 h-7"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
initial={{ scale: 0 }}
animate={{ scale: 1 }}
transition={{ duration: 0.3, delay: 0.6 }}
>
{isMobileMenuOpen ? (
<motion.path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M6 18L18 6M6 6l12 12"
initial={{ pathLength: 0 }}
animate={{ pathLength: 1 }}
transition={{ duration: 0.4, delay: 0.7 }}
/>
) : (
<motion.path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M4 6h16M4 12h16M4 18h16"
initial={{ pathLength: 0 }}
animate={{ pathLength: 1 }}
transition={{ duration: 0.4, delay: 0.7 }}
/>
)}
</motion.svg>
</motion.button>
</motion.div>
</div>
{/* Mobile Menu Overlay */}
<div
className={cn(
'fixed inset-0 bg-primary z-40 lg:hidden transition-all duration-500 ease-in-out flex flex-col',
isMobileMenuOpen
? 'opacity-100 translate-y-0'
: 'opacity-0 -translate-y-full pointer-events-none',
)}
id="mobile-menu"
role="dialog"
aria-modal="true"
aria-label={t('menu')}
ref={mobileMenuRef}
>
<motion.nav
className="flex-grow flex flex-col justify-center items-center p-8 space-y-8"
initial="closed"
animate={isMobileMenuOpen ? 'open' : 'closed'}
variants={{
open: {
transition: {
staggerChildren: 0.1,
delayChildren: 0.2,
},
},
}}
>
{menuItems.map((item, idx) => (
<motion.div
key={item.href}
variants={{
closed: { opacity: 0, y: 50, scale: 0.9 },
open: {
opacity: 1,
y: 0,
scale: 1,
transition: {
duration: 0.6,
ease: 'easeOut',
delay: idx * 0.08,
},
},
}}
>
<Link
href={`/${currentLocale}${item.href === '/' ? '' : item.href}`}
onClick={() => {
setIsMobileMenuOpen(false);
trackEvent(AnalyticsEvents.LINK_CLICK, {
label: item.label,
href: item.href,
location: 'mobile_menu',
});
}}
className="text-2xl md:text-3xl font-extrabold text-white hover:text-accent transition-all transform block py-4"
>
{item.label}
</Link>
</motion.div>
))}
<motion.div
className="pt-8 border-t border-white/10 w-full flex flex-col items-center space-y-8"
initial={{ opacity: 0, y: 30 }}
animate={isMobileMenuOpen ? { opacity: 1, y: 0 } : { opacity: 0, y: 30 }}
transition={{ duration: 0.5, delay: 0.8 }}
>
<motion.div
className="flex items-center space-x-8 text-lg md:text-xl font-extrabold tracking-widest uppercase text-white"
{/* Bottom Branding */}
<m.div
className="p-12 flex justify-center opacity-20"
initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.4, delay: 0.9 }}
animate={isMobileMenuOpen ? { opacity: 0.2, scale: 1 } : { opacity: 0, scale: 0.8 }}
transition={{ duration: 0.5, delay: 1.4 }}
>
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.3, delay: 1.0 }}
<m.div
initial={{ scale: 0.5 }}
animate={{ scale: 1 }}
transition={{ type: 'spring', stiffness: 300, delay: 1.5 }}
>
<Link
href={getPathForLocale('en')}
className={`hover:text-accent transition-colors ${currentLocale === 'en' ? 'text-accent' : 'opacity-60'}`}
>
EN
</Link>
</motion.div>
<motion.div
className="w-px h-6 bg-white/20"
initial={{ scaleX: 0 }}
animate={{ scaleX: 1 }}
transition={{ duration: 0.4, delay: 1.05 }}
/>
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.3, delay: 1.1 }}
>
<Link
href={getPathForLocale('de')}
className={`hover:text-accent transition-colors ${currentLocale === 'de' ? 'text-accent' : 'opacity-60'}`}
>
DE
</Link>
</motion.div>
</motion.div>
<motion.div
initial={{ scale: 0.9, opacity: 0, y: 20 }}
animate={{ scale: 1, opacity: 1, y: 0 }}
transition={{ type: 'spring', stiffness: 400, damping: 20, delay: 1.2 }}
>
<Button
href={`/${currentLocale}/contact`}
variant="accent"
size="lg"
className="w-full max-w-xs py-6 text-lg md:text-xl shadow-2xl"
>
{t('contact')}
</Button>
</motion.div>
</motion.div>
{/* Bottom Branding */}
<motion.div
className="p-12 flex justify-center opacity-20"
initial={{ opacity: 0, scale: 0.8 }}
animate={isMobileMenuOpen ? { opacity: 0.2, scale: 1 } : { opacity: 0, scale: 0.8 }}
transition={{ duration: 0.5, delay: 1.4 }}
>
<motion.div
initial={{ scale: 0.5 }}
animate={{ scale: 1 }}
transition={{ type: 'spring', stiffness: 300, delay: 1.5 }}
>
<Image src="/logo-white.svg" alt={t('home')} width={80} height={80} unoptimized />
</motion.div>
</motion.div>
</motion.nav>
</div>
</motion.header>
<Image src="/logo-white.svg" alt={t('home')} width={80} height={80} unoptimized />
</m.div>
</m.div>
</m.nav>
</div>
</m.header>
</LazyMotion>
</>
);
}