perf: site-wide performance optimizations including image delivery and hero overhaul
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 11s
Build & Deploy / 🧪 QA (push) Successful in 1m31s
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
Build & Deploy / 🏗️ Build (push) Has been cancelled

This commit is contained in:
2026-02-11 18:47:13 +01:00
parent c7807610f6
commit 72e85b99ee
13 changed files with 300 additions and 1105 deletions

View File

@@ -66,7 +66,8 @@ export default async function BlogIndex({ params }: BlogIndexProps) {
alt={featuredPost.frontmatter.title} alt={featuredPost.frontmatter.title}
fill fill
className="absolute inset-0 w-full h-full object-cover scale-105 animate-slow-zoom opacity-40 md:opacity-60" className="absolute inset-0 w-full h-full object-cover scale-105 animate-slow-zoom opacity-40 md:opacity-60"
unoptimized sizes="100vw"
priority
/> />
<div className="absolute inset-0 image-overlay-gradient" /> <div className="absolute inset-0 image-overlay-gradient" />
</> </>
@@ -153,7 +154,7 @@ export default async function BlogIndex({ params }: BlogIndexProps) {
alt={post.frontmatter.title} alt={post.frontmatter.title}
fill fill
className="w-full h-full object-cover transition-transform duration-1000 group-hover:scale-110" className="w-full h-full object-cover transition-transform duration-1000 group-hover:scale-110"
unoptimized sizes="(max-width: 768px) 100vw, (max-width: 1024px) 50vw, 33vw"
/> />
<div className="absolute inset-0 image-overlay-gradient opacity-0 group-hover:opacity-100 transition-opacity duration-500" /> <div className="absolute inset-0 image-overlay-gradient opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
{post.frontmatter.category && ( {post.frontmatter.category && (

View File

@@ -243,6 +243,7 @@ export default async function ProductPage({ params }: ProductPageProps) {
alt={product.frontmatter.title} alt={product.frontmatter.title}
fill fill
className="object-contain p-8 transition-transform duration-700 group-hover:scale-110 z-10" className="object-contain p-8 transition-transform duration-700 group-hover:scale-110 z-10"
sizes="(max-width: 768px) 100vw, (max-width: 1024px) 50vw, 33vw"
/> />
{/* Subtle reflection/shadow effect */} {/* Subtle reflection/shadow effect */}
<div className="absolute bottom-4 left-1/2 -translate-x-1/2 w-2/3 h-4 bg-black/5 blur-xl rounded-full" /> <div className="absolute bottom-4 left-1/2 -translate-x-1/2 w-2/3 h-4 bg-black/5 blur-xl rounded-full" />

View File

@@ -143,8 +143,7 @@ export default async function ProductsPage({ params }: ProductsPageProps) {
alt={category.title} alt={category.title}
fill fill
className="object-cover transition-transform duration-1000 group-hover:scale-105" className="object-cover transition-transform duration-1000 group-hover:scale-105"
sizes="(max-width: 768px) 100vw, 50vw" sizes="(max-width: 768px) 100vw, (max-width: 1024px) 50vw, 33vw"
unoptimized
/> />
<div className="absolute inset-0 image-overlay-gradient opacity-80 group-hover:opacity-90 transition-opacity duration-500" /> <div className="absolute inset-0 image-overlay-gradient opacity-80 group-hover:opacity-90 transition-opacity duration-500" />

View File

@@ -94,6 +94,7 @@ export default async function TeamPage({ params }: TeamPageProps) {
alt="KLZ Team" alt="KLZ Team"
fill fill
className="object-cover scale-105 animate-slow-zoom opacity-30 md:opacity-40" className="object-cover scale-105 animate-slow-zoom opacity-30 md:opacity-40"
sizes="100vw"
priority priority
/> />
<div className="absolute inset-0 bg-gradient-to-b from-primary-dark/80 via-primary-dark/40 to-primary-dark/80" /> <div className="absolute inset-0 bg-gradient-to-b from-primary-dark/80 via-primary-dark/40 to-primary-dark/80" />

View File

@@ -12,29 +12,33 @@ export default function Footer() {
return ( return (
<footer className="bg-primary text-white py-24 relative overflow-hidden"> <footer className="bg-primary text-white py-24 relative overflow-hidden">
<div className="absolute top-0 left-0 w-full h-px bg-gradient-to-r from-transparent via-white/20 to-transparent" /> <div className="absolute top-0 left-0 w-full h-px bg-gradient-to-r from-transparent via-white/20 to-transparent" />
<Container> <Container>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-12 gap-16 mb-20"> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-12 gap-16 mb-20">
{/* Brand Column */} {/* Brand Column */}
<div className="lg:col-span-4 space-y-8"> <div className="lg:col-span-4 space-y-8">
<Link href={`/${locale}`} className="inline-block group"> <Link href={`/${locale}`} className="inline-block group">
<Image <Image
src="/logo-white.svg" src="/logo-white.svg"
alt={t('products')} alt={t('products')}
width={150} width={150}
height={40} height={40}
className="h-10 w-auto transition-transform duration-500 group-hover:scale-110" className="h-10 w-auto transition-transform duration-500 group-hover:scale-110"
unoptimized
/> />
</Link> </Link>
<p className="text-white/60 text-base md:text-lg leading-relaxed max-w-sm"> <p className="text-white/60 text-base md:text-lg leading-relaxed max-w-sm">
{t('tagline')} {t('tagline')}
</p> </p>
<div className="flex gap-4"> <div className="flex gap-4">
<a href="https://www.linkedin.com/company/klz-vertriebs-gmbh/" target="_blank" rel="noopener noreferrer" className="w-12 h-12 rounded-full bg-white/5 flex items-center justify-center text-white hover:bg-accent hover:text-primary-dark transition-all duration-300 border border-white/10"> <a
href="https://www.linkedin.com/company/klz-vertriebs-gmbh/"
target="_blank"
rel="noopener noreferrer"
className="w-12 h-12 rounded-full bg-white/5 flex items-center justify-center text-white hover:bg-accent hover:text-primary-dark transition-all duration-300 border border-white/10"
>
<span className="sr-only">LinkedIn</span> <span className="sr-only">LinkedIn</span>
<svg className="w-5 h-5 fill-current" viewBox="0 0 24 24"> <svg className="w-5 h-5 fill-current" viewBox="0 0 24 24">
<path d="M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z"/> <path d="M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z" />
</svg> </svg>
</a> </a>
</div> </div>
@@ -42,52 +46,113 @@ export default function Footer() {
{/* Links Columns */} {/* Links Columns */}
<div className="lg:col-span-2"> <div className="lg:col-span-2">
<h4 className="text-accent font-bold uppercase tracking-widest text-xs md:text-sm mb-8">{t('legal')}</h4> <h4 className="text-accent font-bold uppercase tracking-widest text-xs md:text-sm mb-8">
{t('legal')}
</h4>
<ul className="space-y-4 text-white/70 list-none m-0 p-0"> <ul className="space-y-4 text-white/70 list-none m-0 p-0">
<li><Link href={`/${locale}/${t('legalNoticeSlug')}`} className="text-white/70 hover:text-accent transition-all duration-300 hover:translate-x-1 inline-block">{t('legalNotice')}</Link></li> <li>
<li><Link href={`/${locale}/${t('privacyPolicySlug')}`} className="text-white/70 hover:text-accent transition-all duration-300 hover:translate-x-1 inline-block">{t('privacyPolicy')}</Link></li> <Link
<li><Link href={`/${locale}/${t('termsSlug')}`} className="text-white/70 hover:text-accent transition-all duration-300 hover:translate-x-1 inline-block">{t('terms')}</Link></li> href={`/${locale}/${t('legalNoticeSlug')}`}
className="text-white/70 hover:text-accent transition-all duration-300 hover:translate-x-1 inline-block"
>
{t('legalNotice')}
</Link>
</li>
<li>
<Link
href={`/${locale}/${t('privacyPolicySlug')}`}
className="text-white/70 hover:text-accent transition-all duration-300 hover:translate-x-1 inline-block"
>
{t('privacyPolicy')}
</Link>
</li>
<li>
<Link
href={`/${locale}/${t('termsSlug')}`}
className="text-white/70 hover:text-accent transition-all duration-300 hover:translate-x-1 inline-block"
>
{t('terms')}
</Link>
</li>
</ul> </ul>
</div> </div>
<div className="lg:col-span-2"> <div className="lg:col-span-2">
<h4 className="text-accent font-bold uppercase tracking-widest text-xs md:text-sm mb-8">{t('company')}</h4> <h4 className="text-accent font-bold uppercase tracking-widest text-xs md:text-sm mb-8">
{t('company')}
</h4>
<ul className="space-y-4 text-white/70 list-none m-0 p-0"> <ul className="space-y-4 text-white/70 list-none m-0 p-0">
<li><Link href={`/${locale}/team`} className="text-white/70 hover:text-accent transition-all duration-300 hover:translate-x-1 inline-block">{navT('team')}</Link></li> <li>
<li><Link href={`/${locale}/products`} className="text-white/70 hover:text-accent transition-all duration-300 hover:translate-x-1 inline-block">{navT('products')}</Link></li> <Link
<li><Link href={`/${locale}/blog`} className="text-white/70 hover:text-accent transition-all duration-300 hover:translate-x-1 inline-block">{navT('blog')}</Link></li> href={`/${locale}/team`}
<li><Link href={`/${locale}/contact`} className="text-white/70 hover:text-accent transition-all duration-300 hover:translate-x-1 inline-block">{navT('contact')}</Link></li> className="text-white/70 hover:text-accent transition-all duration-300 hover:translate-x-1 inline-block"
>
{navT('team')}
</Link>
</li>
<li>
<Link
href={`/${locale}/products`}
className="text-white/70 hover:text-accent transition-all duration-300 hover:translate-x-1 inline-block"
>
{navT('products')}
</Link>
</li>
<li>
<Link
href={`/${locale}/blog`}
className="text-white/70 hover:text-accent transition-all duration-300 hover:translate-x-1 inline-block"
>
{navT('blog')}
</Link>
</li>
<li>
<Link
href={`/${locale}/contact`}
className="text-white/70 hover:text-accent transition-all duration-300 hover:translate-x-1 inline-block"
>
{navT('contact')}
</Link>
</li>
</ul> </ul>
</div> </div>
{/* Recent Posts Column */} {/* Recent Posts Column */}
<div className="lg:col-span-4"> <div className="lg:col-span-4">
<h4 className="text-accent font-bold uppercase tracking-widest text-xs md:text-sm mb-8">{t('recentPosts')}</h4> <h4 className="text-accent font-bold uppercase tracking-widest text-xs md:text-sm mb-8">
{t('recentPosts')}
</h4>
<ul className="space-y-6 list-none m-0 p-0"> <ul className="space-y-6 list-none m-0 p-0">
{[ {[
{ {
title: locale === 'de' title:
? "Windparkbau im Fokus: drei typische Kabelherausforderungen" locale === 'de'
: "Focus on wind farm construction: three typical cable challenges", ? 'Windparkbau im Fokus: drei typische Kabelherausforderungen'
slug: locale === 'de' : 'Focus on wind farm construction: three typical cable challenges',
? "windparkbau-im-fokus-drei-typische-kabelherausforderungen" slug:
: "focus-on-wind-farm-construction-three-typical-cable-challenges" locale === 'de'
? 'windparkbau-im-fokus-drei-typische-kabelherausforderungen'
: 'focus-on-wind-farm-construction-three-typical-cable-challenges',
}, },
{ {
title: locale === 'de' title:
? "Warum das N2XS(F)2Y das ideale Kabel für Ihr Energieprojekt ist" locale === 'de'
: "Why the N2XS(F)2Y is the ideal cable for your energy project", ? 'Warum das N2XS(F)2Y das ideale Kabel für Ihr Energieprojekt ist'
slug: locale === 'de' : 'Why the N2XS(F)2Y is the ideal cable for your energy project',
? "n2xsf2y-mittelspannungskabel-energieprojekt" slug:
: "why-the-n2xsf2y-is-the-ideal-cable-for-your-energy-project" locale === 'de'
} ? 'n2xsf2y-mittelspannungskabel-energieprojekt'
: 'why-the-n2xsf2y-is-the-ideal-cable-for-your-energy-project',
},
].map((post, i) => ( ].map((post, i) => (
<li key={i}> <li key={i}>
<Link href={`/${locale}/blog/${post.slug}`} className="group block text-white/80"> <Link href={`/${locale}/blog/${post.slug}`} className="group block text-white/80">
<p className="text-white/80 font-bold group-hover:text-accent transition-colors leading-snug mb-2 text-base md:text-base"> <p className="text-white/80 font-bold group-hover:text-accent transition-colors leading-snug mb-2 text-base md:text-base">
{post.title} {post.title}
</p> </p>
<span className="text-xs text-white/40 uppercase tracking-widest">{t('readArticle')} &rarr;</span> <span className="text-xs text-white/40 uppercase tracking-widest">
{t('readArticle')} &rarr;
</span>
</Link> </Link>
</li> </li>
))} ))}
@@ -98,8 +163,12 @@ export default function Footer() {
<div className="pt-12 border-t border-white/10 flex flex-col md:flex-row justify-between items-center gap-8 text-white/40 text-xs md:text-sm font-medium"> <div className="pt-12 border-t border-white/10 flex flex-col md:flex-row justify-between items-center gap-8 text-white/40 text-xs md:text-sm font-medium">
<p>{t('copyright', { year: currentYear })}</p> <p>{t('copyright', { year: currentYear })}</p>
<div className="flex gap-8"> <div className="flex gap-8">
<Link href="/en" locale="en" className="hover:text-white transition-colors">English</Link> <Link href="/en" locale="en" className="hover:text-white transition-colors">
<Link href="/de" locale="de" className="hover:text-white transition-colors">Deutsch</Link> English
</Link>
<Link href="/de" locale="de" className="hover:text-white transition-colors">
Deutsch
</Link>
</div> </div>
</div> </div>
</Container> </Container>

View File

@@ -87,7 +87,6 @@ export default function Header() {
height={120} height={120}
className="h-10 md:h-14 w-auto transition-all duration-500 group-hover:scale-110" className="h-10 md:h-14 w-auto transition-all duration-500 group-hover:scale-110"
priority priority
unoptimized
/> />
</Link> </Link>
</motion.div> </motion.div>

View File

@@ -9,17 +9,17 @@ export default function Experience() {
return ( return (
<Section className="relative py-32 md:py-48 overflow-hidden text-white"> <Section className="relative py-32 md:py-48 overflow-hidden text-white">
<div className="absolute inset-0 z-0"> <div className="absolute inset-0 z-0">
<Image <Image
src="/uploads/2024/12/1694273920124-copy-2.webp" src="/uploads/2024/12/1694273920124-copy-2.webp"
alt={t('subtitle')} alt={t('subtitle')}
fill fill
className="object-cover object-center scale-105 animate-slow-zoom" className="object-cover object-center scale-105 animate-slow-zoom"
unoptimized sizes="100vw"
/> />
<div className="absolute inset-0 bg-primary/80 mix-blend-multiply" /> <div className="absolute inset-0 bg-primary/80 mix-blend-multiply" />
<div className="absolute inset-0 bg-gradient-to-r from-primary via-primary/40 to-transparent" /> <div className="absolute inset-0 bg-gradient-to-r from-primary via-primary/40 to-transparent" />
</div> </div>
<Container className="relative z-10"> <Container className="relative z-10">
<div className="max-w-3xl"> <div className="max-w-3xl">
<Heading level={2} subtitle={t('subtitle')} className="text-white"> <Heading level={2} subtitle={t('subtitle')} className="text-white">
@@ -29,19 +29,25 @@ export default function Experience() {
<p className="border-l-4 border-accent pl-8 py-2 bg-white/5 backdrop-blur-sm rounded-r-xl"> <p className="border-l-4 border-accent pl-8 py-2 bg-white/5 backdrop-blur-sm rounded-r-xl">
{t('p1')} {t('p1')}
</p> </p>
<p className="pl-9"> <p className="pl-9">{t('p2')}</p>
{t('p2')}
</p>
</div> </div>
<div className="mt-16 grid grid-cols-1 md:grid-cols-2 gap-12"> <div className="mt-16 grid grid-cols-1 md:grid-cols-2 gap-12">
<div className="animate-fade-in"> <div className="animate-fade-in">
<div className="text-2xl md:text-3xl font-extrabold text-accent mb-4">{t('certifiedQuality')}</div> <div className="text-2xl md:text-3xl font-extrabold text-accent mb-4">
<div className="text-base md:text-lg font-bold uppercase tracking-widest text-white/60">{t('vdeApproved')}</div> {t('certifiedQuality')}
</div>
<div className="text-base md:text-lg font-bold uppercase tracking-widest text-white/60">
{t('vdeApproved')}
</div>
</div> </div>
<div className="animate-fade-in" style={{ animationDelay: '100ms' }}> <div className="animate-fade-in" style={{ animationDelay: '100ms' }}>
<div className="text-2xl md:text-3xl font-extrabold text-accent mb-4">{t('fullSpectrum')}</div> <div className="text-2xl md:text-3xl font-extrabold text-accent mb-4">
<div className="text-base md:text-lg font-bold uppercase tracking-widest text-white/60">{t('solutionsRange')}</div> {t('fullSpectrum')}
</div>
<div className="text-base md:text-lg font-bold uppercase tracking-widest text-white/60">
{t('solutionsRange')}
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -46,7 +46,7 @@ export default function GallerySection() {
alt={`${t('alt')} ${idx + 1}`} alt={`${t('alt')} ${idx + 1}`}
fill fill
className="object-cover transition-transform duration-1000 group-hover:scale-110" className="object-cover transition-transform duration-1000 group-hover:scale-110"
unoptimized sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
/> />
<div className="absolute inset-0 bg-primary-dark/20 group-hover:bg-transparent transition-all duration-500" /> <div className="absolute inset-0 bg-primary-dark/20 group-hover:bg-transparent transition-all duration-500" />
<div className="absolute inset-0 border-0 group-hover:border-[16px] border-white/10 transition-all duration-500 pointer-events-none" /> <div className="absolute inset-0 border-0 group-hover:border-[16px] border-white/10 transition-all duration-500 pointer-events-none" />

View File

@@ -4,7 +4,8 @@ import Scribble from '@/components/Scribble';
import { Button, Container, Heading, Section } from '@/components/ui'; import { Button, Container, Heading, Section } from '@/components/ui';
import { motion } from 'framer-motion'; import { motion } from 'framer-motion';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import HeroIllustration from './HeroIllustration'; import dynamic from 'next/dynamic';
const HeroIllustration = dynamic(() => import('./HeroIllustration'), { ssr: false });
export default function Hero() { export default function Hero() {
const t = useTranslations('Home.hero'); const t = useTranslations('Home.hero');
@@ -19,7 +20,10 @@ export default function Hero() {
variants={containerVariants} variants={containerVariants}
> >
<motion.div variants={headingVariants}> <motion.div variants={headingVariants}>
<Heading level={1} className="text-center md:text-left mb-6 md:mb-8 md:max-w-none text-white text-4xl sm:text-5xl md:text-7xl font-extrabold [text-shadow:_-2px_-2px_0_#002b49,_2px_-2px_0_#002b49,_-2px_2px_0_#002b49,_2px_2px_0_#002b49,_-2px_0_0_#002b49,_2px_0_0_#002b49,_0_-2px_0_#002b49,_0_2px_0_#002b49]"> <Heading
level={1}
className="text-center md:text-left mb-6 md:mb-8 md:max-w-none text-white text-4xl sm:text-5xl md:text-7xl font-extrabold [text-shadow:_-2px_-2px_0_#002b49,_2px_-2px_0_#002b49,_-2px_2px_0_#002b49,_2px_2px_0_#002b49,_-2px_0_0_#002b49,_2px_0_0_#002b49,_0_-2px_0_#002b49,_0_2px_0_#002b49]"
>
{t.rich('title', { {t.rich('title', {
green: (chunks) => ( green: (chunks) => (
<span className="relative inline-block"> <span className="relative inline-block">
@@ -36,7 +40,7 @@ export default function Hero() {
<Scribble variant="circle" /> <Scribble variant="circle" />
</motion.div> </motion.div>
</span> </span>
) ),
})} })}
</Heading> </Heading>
</motion.div> </motion.div>
@@ -50,13 +54,23 @@ export default function Hero() {
variants={buttonContainerVariants} variants={buttonContainerVariants}
> >
<motion.div variants={buttonVariants}> <motion.div variants={buttonVariants}>
<Button href="/contact" variant="accent" size="lg" className="group w-full sm:w-auto h-14 md:h-16 px-8 md:px-10 text-base md:text-lg"> <Button
href="/contact"
variant="accent"
size="lg"
className="group w-full sm:w-auto h-14 md:h-16 px-8 md:px-10 text-base md:text-lg"
>
{t('cta')} {t('cta')}
<span className="transition-transform group-hover/btn:translate-x-1">&rarr;</span> <span className="transition-transform group-hover/btn:translate-x-1">&rarr;</span>
</Button> </Button>
</motion.div> </motion.div>
<motion.div variants={buttonVariants}> <motion.div variants={buttonVariants}>
<Button href="/products" variant="white" size="lg" className="group w-full sm:w-auto h-14 md:h-16 px-8 md:px-10 text-base md:text-lg md:bg-white md:text-primary md:hover:bg-neutral-light md:border-none"> <Button
href="/products"
variant="white"
size="lg"
className="group w-full sm:w-auto h-14 md:h-16 px-8 md:px-10 text-base md:text-lg md:bg-white md:text-primary md:hover:bg-neutral-light md:border-none"
>
{t('exploreProducts')} {t('exploreProducts')}
</Button> </Button>
</motion.div> </motion.div>
@@ -77,7 +91,7 @@ export default function Hero() {
className="absolute bottom-6 md:bottom-10 left-1/2 -translate-x-1/2 hidden sm:block" className="absolute bottom-6 md:bottom-10 left-1/2 -translate-x-1/2 hidden sm:block"
initial={{ opacity: 0, y: 16 }} initial={{ opacity: 0, y: 16 }}
animate={{ opacity: 1, y: 0 }} animate={{ opacity: 1, y: 0 }}
transition={{ duration: 1, ease: "easeOut", delay: 3 }} transition={{ duration: 1, ease: 'easeOut', delay: 3 }}
> >
<div className="w-6 h-10 border-2 border-white/30 rounded-full flex justify-center p-1"> <div className="w-6 h-10 border-2 border-white/30 rounded-full flex justify-center p-1">
<motion.div <motion.div
@@ -86,7 +100,7 @@ export default function Hero() {
transition={{ transition={{
duration: 1.5, duration: 1.5,
repeat: Infinity, repeat: Infinity,
ease: "easeInOut" ease: 'easeInOut',
}} }}
/> />
</div> </div>
@@ -101,9 +115,9 @@ const containerVariants = {
opacity: 1, opacity: 1,
transition: { transition: {
staggerChildren: 0.12, staggerChildren: 0.12,
delayChildren: 0.4 delayChildren: 0.4,
} },
} },
} as const; } as const;
const headingVariants = { const headingVariants = {
@@ -112,8 +126,8 @@ const headingVariants = {
opacity: 1, opacity: 1,
y: 0, y: 0,
scale: 1, scale: 1,
transition: { duration: 1.2, ease: [0.25, 0.46, 0.45, 0.94] } transition: { duration: 1.2, ease: [0.25, 0.46, 0.45, 0.94] },
} },
} as const; } as const;
const accentVariants = { const accentVariants = {
@@ -122,8 +136,8 @@ const accentVariants = {
opacity: 1, opacity: 1,
scale: 1, scale: 1,
rotate: 0, rotate: 0,
transition: { duration: 0.8, ease: [0.25, 0.46, 0.45, 0.94] } transition: { duration: 0.8, ease: [0.25, 0.46, 0.45, 0.94] },
} },
} as const; } as const;
const scribbleVariants = { const scribbleVariants = {
@@ -132,8 +146,8 @@ const scribbleVariants = {
opacity: 1, opacity: 1,
scale: 1, scale: 1,
rotate: 0, rotate: 0,
transition: { duration: 1, type: "spring", stiffness: 300, damping: 20 } transition: { duration: 1, type: 'spring', stiffness: 300, damping: 20 },
} },
} as const; } as const;
const subtitleVariants = { const subtitleVariants = {
@@ -142,8 +156,8 @@ const subtitleVariants = {
opacity: 1, opacity: 1,
y: 0, y: 0,
scale: 1, scale: 1,
transition: { duration: 1, ease: [0.25, 0.46, 0.45, 0.94] } transition: { duration: 1, ease: [0.25, 0.46, 0.45, 0.94] },
} },
} as const; } as const;
const buttonContainerVariants = { const buttonContainerVariants = {
@@ -152,9 +166,9 @@ const buttonContainerVariants = {
opacity: 1, opacity: 1,
transition: { transition: {
staggerChildren: 0.15, staggerChildren: 0.15,
delayChildren: 0.4 delayChildren: 0.4,
} },
} },
} as const; } as const;
const buttonVariants = { const buttonVariants = {
@@ -163,6 +177,6 @@ const buttonVariants = {
opacity: 1, opacity: 1,
y: 0, y: 0,
scale: 1, scale: 1,
transition: { type: "spring", stiffness: 400, damping: 20 } transition: { type: 'spring', stiffness: 400, damping: 20 },
} },
} as const; } as const;

File diff suppressed because it is too large Load Diff

View File

@@ -11,43 +11,53 @@ export default function MeetTheTeam() {
return ( return (
<Section className="relative py-32 md:py-48 overflow-hidden"> <Section className="relative py-32 md:py-48 overflow-hidden">
<div className="absolute inset-0 z-0"> <div className="absolute inset-0 z-0">
<Image <Image
src="/uploads/2024/12/DSC08036-Large.webp" src="/uploads/2024/12/DSC08036-Large.webp"
alt={t('subtitle')} alt={t('subtitle')}
fill fill
className="object-cover scale-105 animate-slow-zoom" className="object-cover scale-105 animate-slow-zoom"
unoptimized sizes="100vw"
/> />
<div className="absolute inset-0 bg-primary/70 mix-blend-multiply" /> <div className="absolute inset-0 bg-primary/70 mix-blend-multiply" />
<div className="absolute inset-0 bg-gradient-to-t from-primary via-primary/20 to-transparent" /> <div className="absolute inset-0 bg-gradient-to-t from-primary via-primary/20 to-transparent" />
</div> </div>
<Container className="relative z-10"> <Container className="relative z-10">
<div className="max-w-3xl text-white animate-slide-up"> <div className="max-w-3xl text-white animate-slide-up">
<Heading level={2} subtitle={t('subtitle')} className="text-white mb-8"> <Heading level={2} subtitle={t('subtitle')} className="text-white mb-8">
<span className="text-white">{t('title')}</span> <span className="text-white">{t('title')}</span>
</Heading> </Heading>
<div className="relative mb-12"> <div className="relative mb-12">
<div className="absolute -left-8 top-0 bottom-0 w-1 bg-accent rounded-full" /> <div className="absolute -left-8 top-0 bottom-0 w-1 bg-accent rounded-full" />
<p className="text-xl md:text-2xl leading-relaxed font-medium italic text-white/90 pl-8"> <p className="text-xl md:text-2xl leading-relaxed font-medium italic text-white/90 pl-8">
"{t('description')}" "{t('description')}"
</p> </p>
</div> </div>
<div className="flex flex-wrap gap-8 items-center"> <div className="flex flex-wrap gap-8 items-center">
<Button href={`/${locale}/team`} variant="accent" size="xl" className="group"> <Button href={`/${locale}/team`} variant="accent" size="xl" className="group">
{t('cta')} {t('cta')}
<span className="ml-3 transition-transform group-hover:translate-x-2">&rarr;</span> <span className="ml-3 transition-transform group-hover:translate-x-2">&rarr;</span>
</Button> </Button>
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
<div className="flex -space-x-4"> <div className="flex -space-x-4">
<div className="w-14 h-14 rounded-full border-4 border-primary overflow-hidden relative"> <div className="w-14 h-14 rounded-full border-4 border-primary overflow-hidden relative">
<Image src="/uploads/2024/12/DSC07768-Large.webp" alt={teamT('michael.name')} fill className="object-cover" /> <Image
src="/uploads/2024/12/DSC07768-Large.webp"
alt={teamT('michael.name')}
fill
className="object-cover"
/>
</div> </div>
<div className="w-14 h-14 rounded-full border-4 border-primary overflow-hidden relative"> <div className="w-14 h-14 rounded-full border-4 border-primary overflow-hidden relative">
<Image src="/uploads/2024/12/DSC07963-Large.webp" alt={teamT('klaus.name')} fill className="object-cover" /> <Image
src="/uploads/2024/12/DSC07963-Large.webp"
alt={teamT('klaus.name')}
fill
className="object-cover"
/>
</div> </div>
</div> </div>
<span className="text-white/60 font-bold text-xs md:text-sm uppercase tracking-widest"> <span className="text-white/60 font-bold text-xs md:text-sm uppercase tracking-widest">

View File

@@ -9,62 +9,74 @@ export default function ProductCategories() {
const locale = useLocale(); const locale = useLocale();
const categories = [ const categories = [
{ {
title: t('categories.lowVoltage.title'), title: t('categories.lowVoltage.title'),
desc: t('categories.lowVoltage.description'), desc: t('categories.lowVoltage.description'),
img: '/uploads/2024/11/low-voltage-category.webp', img: '/uploads/2024/11/low-voltage-category.webp',
icon: '/uploads/2024/11/Low-Voltage.svg', icon: '/uploads/2024/11/Low-Voltage.svg',
href: `/${locale}/products/low-voltage-cables` href: `/${locale}/products/low-voltage-cables`,
}, },
{ {
title: t('categories.mediumVoltage.title'), title: t('categories.mediumVoltage.title'),
desc: t('categories.mediumVoltage.description'), desc: t('categories.mediumVoltage.description'),
img: '/uploads/2024/11/medium-voltage-category.webp', img: '/uploads/2024/11/medium-voltage-category.webp',
icon: '/uploads/2024/11/Medium-Voltage.svg', icon: '/uploads/2024/11/Medium-Voltage.svg',
href: `/${locale}/products/medium-voltage-cables` href: `/${locale}/products/medium-voltage-cables`,
}, },
{ {
title: t('categories.highVoltage.title'), title: t('categories.highVoltage.title'),
desc: t('categories.highVoltage.description'), desc: t('categories.highVoltage.description'),
img: '/uploads/2024/11/high-voltage-category.webp', img: '/uploads/2024/11/high-voltage-category.webp',
icon: '/uploads/2024/11/High-Voltage.svg', icon: '/uploads/2024/11/High-Voltage.svg',
href: `/${locale}/products/high-voltage-cables` href: `/${locale}/products/high-voltage-cables`,
}, },
{ {
title: t('categories.solar.title'), title: t('categories.solar.title'),
desc: t('categories.solar.description'), desc: t('categories.solar.description'),
img: '/uploads/2024/11/solar-category.webp', img: '/uploads/2024/11/solar-category.webp',
icon: '/uploads/2024/11/Solar.svg', icon: '/uploads/2024/11/Solar.svg',
href: `/${locale}/products/solar-cables` href: `/${locale}/products/solar-cables`,
} },
]; ];
return ( return (
<Section className="bg-neutral-light py-0 md:py-0 lg:py-0 -mt-px"> <Section className="bg-neutral-light py-0 md:py-0 lg:py-0 -mt-px">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4"> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4">
{categories.map((category, idx) => ( {categories.map((category, idx) => (
<Link key={idx} href={category.href} className="group block relative h-[400px] md:h-[500px] lg:h-[650px] overflow-hidden border-b md:border-b-0 md:border-r border-white/10 last:border-0"> <Link
<Image key={idx}
src={category.img} href={category.href}
className="group block relative h-[400px] md:h-[500px] lg:h-[650px] overflow-hidden border-b md:border-b-0 md:border-r border-white/10 last:border-0"
>
<Image
src={category.img}
alt={category.title} alt={category.title}
fill fill
className="object-cover transition-transform duration-1000 group-hover:scale-110" className="object-cover transition-transform duration-1000 group-hover:scale-110"
sizes="(max-width: 768px) 100vw, (max-width: 1024px) 50vw, 25vw" sizes="(max-width: 768px) 100vw, (max-width: 1024px) 50vw, 25vw"
unoptimized
/> />
<div className="absolute inset-0 bg-primary-dark/40 group-hover:bg-primary-dark/60 transition-all duration-500" /> <div className="absolute inset-0 bg-primary-dark/40 group-hover:bg-primary-dark/60 transition-all duration-500" />
<div className="absolute inset-0 p-8 md:p-10 flex flex-col justify-end text-white"> <div className="absolute inset-0 p-8 md:p-10 flex flex-col justify-end text-white">
<div className="mb-4 md:mb-6 transform transition-all duration-500 group-hover:-translate-y-4"> <div className="mb-4 md:mb-6 transform transition-all duration-500 group-hover:-translate-y-4">
<div className="w-12 h-12 md:w-16 md:h-16 bg-white/10 backdrop-blur-md rounded-xl flex items-center justify-center mb-4 md:mb-6 border border-white/20"> <div className="w-12 h-12 md:w-16 md:h-16 bg-white/10 backdrop-blur-md rounded-xl flex items-center justify-center mb-4 md:mb-6 border border-white/20">
<Image src={category.icon} alt="" width={40} height={40} className="w-8 h-8 md:w-10 md:h-10 brightness-0 invert" unoptimized /> <Image
src={category.icon}
alt=""
width={40}
height={40}
className="w-8 h-8 md:w-10 md:h-10 brightness-0 invert"
/>
</div> </div>
<h3 className="text-xl md:text-2xl font-bold mb-2 md:mb-4 leading-tight">{category.title}</h3> <h3 className="text-xl md:text-2xl font-bold mb-2 md:mb-4 leading-tight">
{category.title}
</h3>
<p className="text-white/80 text-sm md:text-base line-clamp-3 opacity-100 md:opacity-0 group-hover:opacity-100 transition-all duration-500 max-h-24 md:max-h-0 group-hover:max-h-32"> <p className="text-white/80 text-sm md:text-base line-clamp-3 opacity-100 md:opacity-0 group-hover:opacity-100 transition-all duration-500 max-h-24 md:max-h-0 group-hover:max-h-32">
{category.desc} {category.desc}
</p> </p>
</div> </div>
<div className="flex items-center text-accent font-bold tracking-wider uppercase text-xs md:text-xs opacity-100 md:opacity-0 group-hover:opacity-100 transition-all duration-500 delay-100"> <div className="flex items-center text-accent font-bold tracking-wider uppercase text-xs md:text-xs opacity-100 md:opacity-0 group-hover:opacity-100 transition-all duration-500 delay-100">
{t('exploreCategory')} <span className="ml-2 transition-transform group-hover:translate-x-2">&rarr;</span> {t('exploreCategory')}{' '}
<span className="ml-2 transition-transform group-hover:translate-x-2">&rarr;</span>
</div> </div>
</div> </div>
</Link> </Link>

View File

@@ -43,7 +43,7 @@ export default async function RecentPosts({ locale }: RecentPostsProps) {
alt={post.frontmatter.title} alt={post.frontmatter.title}
fill fill
className="w-full h-full object-cover transition-transform duration-700 group-hover:scale-110" className="w-full h-full object-cover transition-transform duration-700 group-hover:scale-110"
unoptimized sizes="(max-width: 768px) 100vw, 33vw"
/> />
<div className="absolute inset-0 image-overlay-gradient opacity-0 group-hover:opacity-100 transition-opacity duration-500" /> <div className="absolute inset-0 image-overlay-gradient opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
{post.frontmatter.category && ( {post.frontmatter.category && (