perf: site-wide performance optimizations including image delivery and hero overhaul
Some checks failed
Some checks failed
This commit is contained in:
@@ -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 && (
|
||||||
|
|||||||
@@ -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" />
|
||||||
|
|||||||
@@ -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" />
|
||||||
|
|
||||||
|
|||||||
@@ -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" />
|
||||||
|
|||||||
@@ -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')} →</span>
|
<span className="text-xs text-white/40 uppercase tracking-widest">
|
||||||
|
{t('readArticle')} →
|
||||||
|
</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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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" />
|
||||||
|
|||||||
@@ -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">→</span>
|
<span className="transition-transform group-hover/btn:translate-x-1">→</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
@@ -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">→</span>
|
<span className="ml-3 transition-transform group-hover:translate-x-2">→</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">
|
||||||
|
|||||||
@@ -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">→</span>
|
{t('exploreCategory')}{' '}
|
||||||
|
<span className="ml-2 transition-transform group-hover:translate-x-2">→</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -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 && (
|
||||||
|
|||||||
Reference in New Issue
Block a user