wip
Some checks failed
Build & Deploy / deploy (push) Failing after 17s

This commit is contained in:
2026-01-17 16:06:16 +01:00
parent f64cb71170
commit e6651761f3
20 changed files with 453 additions and 350 deletions

View File

@@ -1,3 +0,0 @@
{
"extends": "next/core-web-vitals"
}

View File

@@ -20,53 +20,53 @@ export default async function StandardPage({ params: { locale, slug } }: PagePro
return (
<div className="flex flex-col min-h-screen bg-neutral-light">
{/* Hero Section */}
<section className="bg-primary-dark text-white py-32 relative overflow-hidden">
<section className="bg-primary-dark text-white py-20 md:py-32 relative overflow-hidden">
<div className="absolute inset-0 opacity-20">
<div className="absolute top-0 left-0 w-full h-full bg-[radial-gradient(circle_at_center,_var(--tw-gradient-stops))] from-accent via-transparent to-transparent" />
</div>
<Container className="relative z-10">
<div className="max-w-4xl animate-slide-up">
<Badge variant="accent" className="mb-6">Information</Badge>
<Heading level={1} className="text-white mb-0">
<Badge variant="accent" className="mb-4 md:mb-6">Information</Badge>
<Heading level={1} className="text-3xl md:text-6xl lg:text-7xl xl:text-8xl text-white mb-0">
<span className="text-white">{pageData.frontmatter.title}</span>
</Heading>
</div>
</Container>
</section>
<Section className="bg-white -mt-12 relative z-20 rounded-t-[60px] shadow-2xl">
<Section className="bg-white -mt-8 md:-mt-12 relative z-20 rounded-t-[32px] md:rounded-t-[60px] shadow-2xl py-12 md:py-28">
<Container>
<div className="grid grid-cols-1 lg:grid-cols-12 gap-16">
<div className="sticky-narrative-container">
{/* Sticky Narrative Sidebar */}
<div className="lg:col-span-4">
<div className="sticky top-32 space-y-8">
<div className="p-8 bg-neutral-light rounded-3xl border border-neutral-medium">
<h3 className="text-xl font-bold text-primary mb-4">Quick Navigation</h3>
<nav className="space-y-4">
<div className="h-1 w-12 bg-accent rounded-full" />
<p className="text-text-secondary leading-relaxed">
<div className="sticky-narrative-sidebar mb-8 lg:mb-0">
<div className="lg:sticky lg:top-32 space-y-4 md:space-y-8">
<div className="p-6 md:p-8 bg-neutral-light rounded-2xl md:rounded-3xl border border-neutral-medium">
<h3 className="text-lg md:text-xl font-bold text-primary mb-3 md:mb-4">Quick Navigation</h3>
<nav className="space-y-3 md:space-y-4">
<div className="h-1 w-10 md:w-12 bg-accent rounded-full" />
<p className="text-sm md:text-base text-text-secondary leading-relaxed">
Explore the details of {pageData.frontmatter.title}. KLZ provides comprehensive information on all our services and corporate policies.
</p>
</nav>
</div>
<div className="p-8 bg-primary-dark rounded-3xl text-white">
<h3 className="text-xl font-bold mb-4">Need Help?</h3>
<p className="text-white/70 mb-6">Our support team is available for any questions regarding this topic.</p>
<a href={`/${locale}/contact`} className="text-accent font-bold hover:underline">Contact Us &rarr;</a>
<div className="p-6 md:p-8 bg-primary-dark rounded-2xl md:rounded-3xl text-white">
<h3 className="text-lg md:text-xl font-bold mb-3 md:mb-4">Need Help?</h3>
<p className="text-sm md:text-base text-white/70 mb-4 md:mb-6">Our support team is available for any questions regarding this topic.</p>
<a href={`/${locale}/contact`} className="text-accent font-bold hover:underline touch-target">Contact Us &rarr;</a>
</div>
</div>
</div>
{/* Main Content */}
<div className="lg:col-span-8">
<article className="prose prose-xl prose-primary max-w-none
<div className="sticky-narrative-content">
<article className="prose prose-sm md:prose-lg lg:prose-xl prose-primary max-w-none
prose-headings:text-primary prose-headings:font-bold prose-headings:tracking-tight
prose-p:text-text-secondary prose-p:leading-relaxed
prose-strong:text-primary prose-strong:font-extrabold
prose-a:text-primary prose-a:font-bold prose-a:no-underline hover:prose-a:underline
prose-img:rounded-3xl prose-img:shadow-2xl
prose-ul:list-disc prose-ul:pl-6
prose-img:rounded-2xl md:prose-img:rounded-3xl prose-img:shadow-2xl
prose-ul:list-disc prose-ul:pl-5 md:prose-ul:pl-6
prose-li:text-text-secondary
">
<MDXRemote source={pageData.content} />

View File

@@ -1,6 +1,7 @@
import Link from 'next/link';
import { getAllPosts } from '@/lib/blog';
import { Section, Container, Heading, Card, Badge, Button } from '@/components/ui';
import Reveal from '@/components/Reveal';
interface BlogIndexProps {
params: {
@@ -31,30 +32,30 @@ export default async function BlogIndex({ params: { locale } }: BlogIndexProps)
return (
<div className="bg-neutral-light min-h-screen">
{/* Hero Section - Immersive Magazine Feel */}
<section className="relative h-[70vh] min-h-[600px] flex items-center overflow-hidden bg-primary-dark">
<section className="relative h-[50vh] md:h-[70vh] min-h-[400px] md:min-h-[600px] flex items-center overflow-hidden bg-primary-dark">
{featuredPost && featuredPost.frontmatter.featuredImage && (
<>
<img
src={featuredPost.frontmatter.featuredImage}
alt={featuredPost.frontmatter.title}
className="absolute inset-0 w-full h-full object-cover scale-105 animate-slow-zoom opacity-60"
className="absolute inset-0 w-full h-full object-cover scale-105 animate-slow-zoom opacity-40 md:opacity-60"
/>
<div className="absolute inset-0 bg-gradient-to-t from-primary-dark via-primary-dark/40 to-transparent" />
<div className="absolute inset-0 image-overlay-gradient" />
</>
)}
<Container className="relative z-10">
<div className="max-w-4xl animate-slide-up">
<Badge variant="accent" className="mb-6">Featured Post</Badge>
<Badge variant="accent" className="mb-4 md:mb-6">Featured Post</Badge>
{featuredPost && (
<>
<h1 className="text-5xl md:text-7xl font-extrabold text-white mb-8 leading-[1.1]">
<h1 className="text-3xl md:text-7xl font-extrabold text-white mb-4 md:mb-8 leading-[1.1] line-clamp-3 md:line-clamp-none">
{featuredPost.frontmatter.title}
</h1>
<p className="text-xl md:text-2xl text-white/80 mb-10 line-clamp-2 max-w-2xl">
<p className="text-base md:text-2xl text-white/80 mb-6 md:mb-10 line-clamp-2 md:line-clamp-2 max-w-2xl">
{featuredPost.frontmatter.excerpt}
</p>
<Button href={`/${locale}/blog/${featuredPost.slug}`} variant="accent" size="xl" className="group">
<Button href={`/${locale}/blog/${featuredPost.slug}`} variant="accent" size="lg" className="group w-full md:w-auto md:h-16 md:px-10 md:text-xl">
{locale === 'de' ? 'Vollständigen Artikel lesen' : 'Read Full Article'}
<span className="ml-3 transition-transform group-hover:translate-x-2">&rarr;</span>
</Button>
@@ -64,78 +65,81 @@ export default async function BlogIndex({ params: { locale } }: BlogIndexProps)
</Container>
</section>
<Section className="bg-neutral-light">
<Section className="bg-neutral-light py-12 md:py-28">
<Container>
<div className="flex flex-col md:flex-row items-end justify-between mb-16 gap-6">
<Heading level={2} subtitle="Latest News" className="mb-0">
{locale === 'de' ? 'Alle Beiträge' : 'All Articles'}
</Heading>
<div className="flex gap-4">
{/* Category filters could go here */}
<Badge variant="primary" className="cursor-pointer hover:bg-primary hover:text-white transition-colors">All</Badge>
<Badge variant="neutral" className="cursor-pointer hover:bg-primary hover:text-white transition-colors">Industry</Badge>
<Badge variant="neutral" className="cursor-pointer hover:bg-primary hover:text-white transition-colors">Technical</Badge>
<Badge variant="neutral" className="cursor-pointer hover:bg-primary hover:text-white transition-colors">Sustainability</Badge>
<Reveal>
<div className="flex flex-col md:flex-row items-start md:items-end justify-between mb-8 md:mb-16 gap-4 md:gap-6">
<Heading level={2} subtitle="Latest News" className="mb-0">
{locale === 'de' ? 'Alle Beiträge' : 'All Articles'}
</Heading>
<div className="flex flex-wrap gap-2 md:gap-4">
{/* Category filters could go here */}
<Badge variant="primary" className="cursor-pointer hover:bg-primary hover:text-white transition-colors touch-target px-3 md:px-4">All</Badge>
<Badge variant="neutral" className="cursor-pointer hover:bg-primary hover:text-white transition-colors touch-target px-3 md:px-4">Industry</Badge>
<Badge variant="neutral" className="cursor-pointer hover:bg-primary hover:text-white transition-colors touch-target px-3 md:px-4">Technical</Badge>
<Badge variant="neutral" className="cursor-pointer hover:bg-primary hover:text-white transition-colors touch-target px-3 md:px-4">Sustainability</Badge>
</div>
</div>
</div>
</Reveal>
{/* Grid for remaining posts */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-12">
{remainingPosts.map((post) => (
<Link key={post.slug} href={`/${locale}/blog/${post.slug}`} className="group block">
<Card className="h-full flex flex-col border-none shadow-lg hover:shadow-2xl transition-all duration-500 rounded-3xl overflow-hidden">
{post.frontmatter.featuredImage && (
<div className="relative h-72 overflow-hidden">
<img
src={post.frontmatter.featuredImage}
alt={post.frontmatter.title}
className="w-full h-full object-cover transition-transform duration-1000 group-hover:scale-110"
/>
<div className="absolute inset-0 bg-gradient-to-t from-primary-dark/80 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
{post.frontmatter.category && (
<Badge variant="accent" className="absolute top-6 left-6 shadow-lg">
{post.frontmatter.category}
</Badge>
)}
</div>
)}
<div className="p-10 flex flex-col flex-1">
<div className="text-sm font-bold text-accent-dark mb-4 tracking-widest uppercase">
{new Date(post.frontmatter.date).toLocaleDateString(locale, {
year: 'numeric',
month: 'long',
day: 'numeric'
})}
</div>
<h3 className="text-2xl font-bold text-primary mb-6 group-hover:text-accent-dark transition-colors line-clamp-2 leading-tight">
{post.frontmatter.title}
</h3>
<p className="text-text-secondary text-lg line-clamp-3 mb-8 leading-relaxed">
{post.frontmatter.excerpt}
</p>
<div className="mt-auto pt-8 border-t border-neutral-medium flex items-center justify-between">
<span className="text-primary font-extrabold group-hover:text-accent-dark transition-colors">
{locale === 'de' ? 'Weiterlesen' : 'Read more'}
</span>
<div className="w-10 h-10 rounded-full bg-primary-light flex items-center justify-center text-primary group-hover:bg-accent group-hover:text-primary-dark transition-all duration-300">
<svg className="w-5 h-5 transition-transform group-hover:translate-x-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 8l4 4m0 0l-4 4m4-4H3" />
</svg>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 md:gap-12">
{remainingPosts.map((post, idx) => (
<Reveal key={post.slug} delay={idx * 100}>
<Link href={`/${locale}/blog/${post.slug}`} className="group block">
<Card className="h-full flex flex-col border-none shadow-lg hover:shadow-2xl transition-all duration-500 rounded-2xl md:rounded-3xl overflow-hidden">
{post.frontmatter.featuredImage && (
<div className="relative h-48 md:h-72 overflow-hidden">
<img
src={post.frontmatter.featuredImage}
alt={post.frontmatter.title}
className="w-full h-full object-cover transition-transform duration-1000 group-hover:scale-110"
/>
<div className="absolute inset-0 image-overlay-gradient opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
{post.frontmatter.category && (
<Badge variant="accent" className="absolute top-3 left-3 md:top-6 md:left-6 shadow-lg">
{post.frontmatter.category}
</Badge>
)}
</div>
)}
<div className="p-5 md:p-10 flex flex-col flex-1">
<div className="text-[10px] md:text-sm font-bold text-accent-dark mb-2 md:mb-4 tracking-widest uppercase">
{new Date(post.frontmatter.date).toLocaleDateString(locale, {
year: 'numeric',
month: 'long',
day: 'numeric'
})}
</div>
<h3 className="text-lg md:text-2xl font-bold text-primary mb-3 md:mb-6 group-hover:text-accent-dark transition-colors line-clamp-2 leading-tight">
{post.frontmatter.title}
</h3>
<p className="text-text-secondary text-sm md:text-lg line-clamp-2 md:line-clamp-3 mb-4 md:mb-8 leading-relaxed">
{post.frontmatter.excerpt}
</p>
<div className="mt-auto pt-4 md:pt-8 border-t border-neutral-medium flex items-center justify-between">
<span className="text-primary text-sm md:text-base font-extrabold group-hover:text-accent-dark transition-colors">
{locale === 'de' ? 'Weiterlesen' : 'Read more'}
</span>
<div className="w-8 h-8 md:w-10 md:h-10 rounded-full bg-primary-light flex items-center justify-center text-primary group-hover:bg-accent group-hover:text-primary-dark transition-all duration-300">
<svg className="w-4 h-4 md:w-5 md:h-5 transition-transform group-hover:translate-x-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 8l4 4m0 0l-4 4m4-4H3" />
</svg>
</div>
</div>
</div>
</div>
</Card>
</Link>
</Card>
</Link>
</Reveal>
))}
</div>
{/* Pagination Placeholder */}
<div className="mt-24 flex justify-center gap-4">
<Button variant="outline" size="md" disabled>Previous</Button>
<Button variant="primary" size="md">1</Button>
<Button variant="outline" size="md">2</Button>
<Button variant="outline" size="md">3</Button>
<Button variant="outline" size="md">Next</Button>
<div className="mt-12 md:mt-24 flex justify-center gap-2 md:gap-4">
<Button variant="outline" size="sm" className="md:h-11 md:px-6 md:text-base" disabled>Prev</Button>
<Button variant="primary" size="sm" className="md:h-11 md:px-6 md:text-base">1</Button>
<Button variant="outline" size="sm" className="md:h-11 md:px-6 md:text-base">2</Button>
<Button variant="outline" size="sm" className="md:h-11 md:px-6 md:text-base">Next</Button>
</div>
</Container>
</Section>

View File

@@ -7,81 +7,81 @@ export default function ContactPage() {
return (
<div className="flex flex-col min-h-screen bg-neutral-light">
{/* Hero Section */}
<section className="bg-primary-dark text-white py-32 relative overflow-hidden">
<section className="bg-primary-dark text-white py-20 md:py-32 relative overflow-hidden">
<div className="absolute inset-0 opacity-20">
<div className="absolute top-0 left-0 w-full h-full bg-[radial-gradient(circle_at_center,_var(--tw-gradient-stops))] from-accent via-transparent to-transparent" />
</div>
<Container className="relative z-10">
<div className="max-w-4xl animate-slide-up">
<Heading level={1} subtitle="Get in Touch" className="text-white mb-6">
<Heading level={1} subtitle="Get in Touch" className="text-white mb-4 md:mb-6">
<span className="text-white">{t('title')}</span>
</Heading>
<p className="text-2xl text-white/70 leading-relaxed max-w-2xl">
<p className="text-lg md:text-2xl text-white/70 leading-relaxed max-w-2xl">
{t('subtitle')}
</p>
</div>
</Container>
</section>
<Section className="bg-neutral-light -mt-20 relative z-20">
<Section className="bg-neutral-light -mt-8 md:-mt-20 relative z-20 py-12 md:py-28">
<Container>
<div className="grid grid-cols-1 lg:grid-cols-12 gap-16">
<div className="grid grid-cols-1 lg:grid-cols-12 gap-8 md:gap-16">
{/* Contact Info */}
<div className="lg:col-span-5 space-y-12">
<div className="lg:col-span-5 space-y-6 md:space-y-12">
<div className="animate-fade-in">
<Heading level={3} subtitle="Contact Details" className="mb-8">
<Heading level={3} subtitle="Contact Details" className="mb-6 md:mb-8">
How to Reach Us
</Heading>
<div className="space-y-8">
<div className="flex items-start gap-6 group">
<div className="w-14 h-14 rounded-2xl bg-primary-light flex items-center justify-center text-primary group-hover:bg-accent group-hover:text-primary-dark transition-all duration-300 shadow-sm">
<svg className="w-7 h-7" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<div className="space-y-4 md:space-y-8">
<div className="flex items-start gap-4 md:gap-6 group">
<div className="w-10 h-10 md:w-14 md:h-14 rounded-xl md:rounded-2xl bg-primary-light flex items-center justify-center text-primary group-hover:bg-accent group-hover:text-primary-dark transition-all duration-300 shadow-sm flex-shrink-0">
<svg className="w-5 h-5 md:w-7 md:h-7" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
</div>
<div>
<h4 className="text-xl font-bold text-primary mb-2">Our Office</h4>
<p className="text-lg text-text-secondary leading-relaxed whitespace-pre-line">
<h4 className="text-base md:text-xl font-bold text-primary mb-1 md:mb-2">Our Office</h4>
<p className="text-sm md:text-lg text-text-secondary leading-relaxed whitespace-pre-line">
{t('info.address')}
</p>
</div>
</div>
<div className="flex items-start gap-6 group">
<div className="w-14 h-14 rounded-2xl bg-primary-light flex items-center justify-center text-primary group-hover:bg-accent group-hover:text-primary-dark transition-all duration-300 shadow-sm">
<svg className="w-7 h-7" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<div className="flex items-start gap-4 md:gap-6 group">
<div className="w-10 h-10 md:w-14 md:h-14 rounded-xl md:rounded-2xl bg-primary-light flex items-center justify-center text-primary group-hover:bg-accent group-hover:text-primary-dark transition-all duration-300 shadow-sm flex-shrink-0">
<svg className="w-5 h-5 md:w-7 md:h-7" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z" />
</svg>
</div>
<div>
<h4 className="text-xl font-bold text-primary mb-2">Phone</h4>
<a href="tel:+4988192537298" className="text-lg text-text-secondary hover:text-primary transition-colors font-medium">+49 881 92537298</a>
<h4 className="text-base md:text-xl font-bold text-primary mb-1 md:mb-2">Phone</h4>
<a href="tel:+4988192537298" className="text-sm md:text-lg text-text-secondary hover:text-primary transition-colors font-medium touch-target">+49 881 92537298</a>
</div>
</div>
<div className="flex items-start gap-6 group">
<div className="w-14 h-14 rounded-2xl bg-primary-light flex items-center justify-center text-primary group-hover:bg-accent group-hover:text-primary-dark transition-all duration-300 shadow-sm">
<svg className="w-7 h-7" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<div className="flex items-start gap-4 md:gap-6 group">
<div className="w-10 h-10 md:w-14 md:h-14 rounded-xl md:rounded-2xl bg-primary-light flex items-center justify-center text-primary group-hover:bg-accent group-hover:text-primary-dark transition-all duration-300 shadow-sm flex-shrink-0">
<svg className="w-5 h-5 md:w-7 md:h-7" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
</svg>
</div>
<div>
<h4 className="text-xl font-bold text-primary mb-2">Email</h4>
<a href="mailto:info@klz-vertriebs-gmbh.com" className="text-lg text-text-secondary hover:text-primary transition-colors font-medium">info@klz-vertriebs-gmbh.com</a>
<h4 className="text-base md:text-xl font-bold text-primary mb-1 md:mb-2">Email</h4>
<a href="mailto:info@klz-vertriebs-gmbh.com" className="text-sm md:text-lg text-text-secondary hover:text-primary transition-colors font-medium touch-target">info@klz-vertriebs-gmbh.com</a>
</div>
</div>
</div>
</div>
<div className="p-10 bg-white rounded-3xl border border-neutral-medium shadow-sm animate-fade-in">
<Heading level={4} className="mb-6">{t('hours.title')}</Heading>
<ul className="space-y-4">
<li className="flex justify-between items-center pb-4 border-b border-neutral-medium">
<div className="p-6 md:p-10 bg-white rounded-2xl md:rounded-3xl border border-neutral-medium shadow-sm animate-fade-in">
<Heading level={4} className="mb-4 md:mb-6">{t('hours.title')}</Heading>
<ul className="space-y-2 md:space-y-4">
<li className="flex justify-between items-center pb-2 md:pb-4 border-b border-neutral-medium text-sm md:text-base">
<span className="font-bold text-primary">{t('hours.weekdays')}</span>
<span className="text-text-secondary">{t('hours.weekdaysTime')}</span>
</li>
<li className="flex justify-between items-center">
<li className="flex justify-between items-center text-sm md:text-base">
<span className="font-bold text-primary">{t('hours.weekend')}</span>
<span className="text-accent-dark font-bold">{t('hours.closed')}</span>
</li>
@@ -91,40 +91,40 @@ export default function ContactPage() {
{/* Contact Form */}
<div className="lg:col-span-7">
<Card className="p-12 rounded-[40px] border-none shadow-2xl animate-slide-up">
<Heading level={3} subtitle="Send a Message" className="mb-10">
<Card className="p-6 md:p-12 rounded-2xl md:rounded-[40px] border-none shadow-2xl animate-slide-up">
<Heading level={3} subtitle="Send a Message" className="mb-6 md:mb-10">
{t('form.title')}
</Heading>
<form className="grid grid-cols-1 md:grid-cols-2 gap-8">
<div className="space-y-2">
<label htmlFor="name" className="text-sm font-extrabold text-primary uppercase tracking-widest">{t('form.name')}</label>
<form className="grid grid-cols-1 md:grid-cols-2 gap-4 md:gap-8">
<div className="space-y-1 md:space-y-2">
<label htmlFor="name" className="text-[10px] md:text-xs font-extrabold text-primary uppercase tracking-widest">{t('form.name')}</label>
<input
type="text"
id="name"
className="w-full px-6 py-4 bg-neutral rounded-2xl border-2 border-transparent focus:border-primary focus:bg-white transition-all outline-none text-lg"
className="w-full px-4 md:px-6 py-2.5 md:py-4 bg-neutral rounded-xl md:rounded-2xl border-2 border-transparent focus:border-primary focus:bg-white transition-all outline-none text-sm md:text-lg"
placeholder="Your Name"
/>
</div>
<div className="space-y-2">
<label htmlFor="email" className="text-sm font-extrabold text-primary uppercase tracking-widest">{t('form.email')}</label>
<div className="space-y-1 md:space-y-2">
<label htmlFor="email" className="text-[10px] md:text-xs font-extrabold text-primary uppercase tracking-widest">{t('form.email')}</label>
<input
type="email"
id="email"
className="w-full px-6 py-4 bg-neutral rounded-2xl border-2 border-transparent focus:border-primary focus:bg-white transition-all outline-none text-lg"
className="w-full px-4 md:px-6 py-2.5 md:py-4 bg-neutral rounded-xl md:rounded-2xl border-2 border-transparent focus:border-primary focus:bg-white transition-all outline-none text-sm md:text-lg"
placeholder="your@email.com"
/>
</div>
<div className="md:col-span-2 space-y-2">
<label htmlFor="message" className="text-sm font-extrabold text-primary uppercase tracking-widest">{t('form.message')}</label>
<div className="md:col-span-2 space-y-1 md:space-y-2">
<label htmlFor="message" className="text-[10px] md:text-xs font-extrabold text-primary uppercase tracking-widest">{t('form.message')}</label>
<textarea
id="message"
rows={6}
className="w-full px-6 py-4 bg-neutral rounded-2xl border-2 border-transparent focus:border-primary focus:bg-white transition-all outline-none text-lg resize-none"
rows={4}
className="w-full px-4 md:px-6 py-2.5 md:py-4 bg-neutral rounded-xl md:rounded-2xl border-2 border-transparent focus:border-primary focus:bg-white transition-all outline-none text-sm md:text-lg resize-none"
placeholder="How can we help you?"
></textarea>
</div>
<div className="md:col-span-2 pt-4">
<Button type="submit" size="xl" className="w-full shadow-xl shadow-primary/20">
<div className="md:col-span-2 pt-2 md:pt-4">
<Button type="submit" size="lg" className="w-full shadow-xl shadow-primary/20 md:h-16 md:px-10 md:text-xl">
{t('form.submit')}
</Button>
</div>
@@ -136,7 +136,7 @@ export default function ContactPage() {
</Section>
{/* Map Placeholder */}
<section className="h-[500px] bg-neutral-medium relative overflow-hidden grayscale hover:grayscale-0 transition-all duration-1000">
<section className="h-[300px] md:h-[500px] bg-neutral-medium relative overflow-hidden grayscale hover:grayscale-0 transition-all duration-1000">
<div className="absolute inset-0 flex items-center justify-center">
<div className="text-center">
<div className="w-20 h-20 bg-primary rounded-full flex items-center justify-center text-white mb-4 mx-auto shadow-2xl animate-bounce">

View File

@@ -3,6 +3,21 @@ import {getMessages} from 'next-intl/server';
import '../../styles/globals.css';
import Header from '@/components/Header';
import Footer from '@/components/Footer';
import { Metadata, Viewport } from 'next';
export const metadata: Metadata = {
title: 'KLZ Cables',
description: 'Premium Cable Solutions',
};
export const viewport: Viewport = {
width: 'device-width',
initialScale: 1,
maximumScale: 1,
userScalable: false,
viewportFit: 'cover',
themeColor: '#001a4d',
};
export default async function LocaleLayout({
children,
@@ -16,8 +31,8 @@ export default async function LocaleLayout({
const messages = await getMessages();
return (
<html lang={locale} className="scroll-smooth">
<body className="flex flex-col min-h-screen font-sans selection:bg-accent selection:text-primary-dark">
<html lang={locale} className="scroll-smooth overflow-x-hidden">
<body className="flex flex-col min-h-screen font-sans selection:bg-accent selection:text-primary-dark antialiased overflow-x-hidden">
<NextIntlClientProvider messages={messages} locale={locale}>
<Header />
<main className="flex-grow animate-fade-in overflow-visible">

View File

@@ -9,6 +9,7 @@ import MeetTheTeam from '@/components/home/MeetTheTeam';
import GallerySection from '@/components/home/GallerySection';
import VideoSection from '@/components/home/VideoSection';
import CTA from '@/components/home/CTA';
import Reveal from '@/components/Reveal';
export default function HomePage({ params: { locale } }: { params: { locale: string } }) {
const t = useTranslations('Index');
@@ -16,15 +17,15 @@ export default function HomePage({ params: { locale } }: { params: { locale: str
return (
<div className="flex flex-col min-h-screen">
<Hero />
<ProductCategories />
<WhatWeDo />
<RecentPosts locale={locale} />
<Experience />
<WhyChooseUs />
<MeetTheTeam />
<GallerySection />
<VideoSection />
<CTA />
<Reveal><ProductCategories /></Reveal>
<Reveal><WhatWeDo /></Reveal>
<Reveal><RecentPosts locale={locale} /></Reveal>
<Reveal><Experience /></Reveal>
<Reveal><WhyChooseUs /></Reveal>
<Reveal><MeetTheTeam /></Reveal>
<Reveal><GallerySection /></Reveal>
<Reveal><VideoSection /></Reveal>
<Reveal><CTA /></Reveal>
</div>
);
}

View File

@@ -48,28 +48,28 @@ export default function ProductsPage({ params }: ProductsPageProps) {
return (
<div className="flex flex-col min-h-screen bg-neutral-light">
{/* Hero Section */}
<section className="relative min-h-[70vh] flex items-center pt-40 pb-32 overflow-hidden bg-primary-dark">
<section className="relative min-h-[50vh] md:min-h-[70vh] flex items-center pt-32 pb-20 md:pt-40 md:pb-32 overflow-hidden bg-primary-dark">
<ProductsIllustration />
<Container className="relative z-10">
<div className="max-w-4xl animate-slide-up">
<Badge variant="accent" className="mb-8 bg-white/10 text-white border border-white/20 backdrop-blur-md px-4 py-1.5">
<Badge variant="accent" className="mb-4 md:mb-8 bg-white/10 text-white border border-white/20 backdrop-blur-md px-3 py-1 md:px-4 md:py-1.5">
{t('heroSubtitle')}
</Badge>
<h1 className="text-5xl md:text-7xl lg:text-8xl font-extrabold text-white mb-8 tracking-tight leading-[1.05]">
<h1 className="text-4xl md:text-7xl lg:text-8xl font-extrabold text-white mb-4 md:mb-8 tracking-tight leading-[1.05]">
{t.rich('title', {
green: (chunks) => (
<span className="relative inline-block">
<span className="relative z-10 text-accent italic">{chunks}</span>
<Scribble variant="circle" className="w-[140%] h-[140%] -top-[20%] -left-[20%] text-accent/30" />
<Scribble variant="circle" className="w-[140%] h-[140%] -top-[20%] -left-[20%] text-accent/30 hidden md:block" />
</span>
)
})}
</h1>
<p className="text-xl md:text-2xl text-white/70 leading-relaxed max-w-2xl mb-12">
<p className="text-lg md:text-2xl text-white/70 leading-relaxed max-w-2xl mb-8 md:mb-12 line-clamp-2 md:line-clamp-none">
{t('subtitle')}
</p>
<div className="flex flex-wrap gap-6">
<Button href="#categories" variant="accent" size="lg" className="group">
<div className="flex flex-wrap gap-4 md:gap-6">
<Button href="#categories" variant="accent" size="lg" className="group w-full md:w-auto">
{t('viewProducts')}
<span className="ml-3 transition-transform group-hover:translate-y-1"></span>
</Button>
@@ -78,44 +78,45 @@ export default function ProductsPage({ params }: ProductsPageProps) {
</Container>
</section>
<Section id="categories" className="bg-neutral-light relative z-20 -mt-16 rounded-t-[48px] md:rounded-t-[64px] pt-24">
<Section id="categories" className="bg-neutral-light relative z-20 -mt-8 md:-mt-16 rounded-t-[32px] md:rounded-t-[64px] pt-12 md:pt-24">
<Container>
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 lg:gap-12">
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 md:gap-8 lg:gap-12">
{categories.map((category, idx) => (
<Link key={idx} href={category.href} className="group block">
<Card className="h-full border-none shadow-sm hover:shadow-2xl transition-all duration-500 rounded-[32px] md:rounded-[48px] overflow-hidden bg-white">
<div className="relative h-[300px] md:h-[400px] overflow-hidden">
<Card className="h-full border-none shadow-sm hover:shadow-2xl transition-all duration-500 rounded-[24px] md:rounded-[48px] overflow-hidden bg-white">
<div className="relative h-[200px] md:h-[400px] overflow-hidden">
<Image
src={category.img}
alt={category.title}
fill
className="object-cover transition-transform duration-1000 group-hover:scale-105"
sizes="(max-width: 768px) 100vw, 50vw"
/>
<div className="absolute inset-0 bg-gradient-to-t from-primary-dark/60 via-transparent to-transparent 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" />
<div className="absolute top-6 right-6 md:top-8 md:right-8 w-16 h-16 md:w-20 md:h-20 bg-white/10 backdrop-blur-md rounded-2xl md:rounded-[24px] flex items-center justify-center border border-white/20 shadow-2xl transition-all duration-500 group-hover:scale-110 group-hover:bg-white/20">
<img src={category.icon} alt="" className="w-10 h-10 md:w-12 md:h-12 brightness-0 invert opacity-80" />
<div className="absolute top-3 right-3 md:top-8 md:right-8 w-10 h-10 md:w-20 md:h-20 bg-white/10 backdrop-blur-md rounded-xl md:rounded-[24px] flex items-center justify-center border border-white/20 shadow-2xl transition-all duration-500 group-hover:scale-110 group-hover:bg-white/20">
<img src={category.icon} alt="" className="w-6 h-6 md:w-12 md:h-12 brightness-0 invert opacity-80" />
</div>
<div className="absolute bottom-8 left-8 md:bottom-10 md:left-10 right-8 md:right-10">
<Badge variant="accent" className="mb-4 shadow-lg bg-accent text-primary-dark border-none">
<div className="absolute bottom-4 left-4 md:bottom-10 md:left-10 right-4 md:right-10">
<Badge variant="accent" className="mb-2 md:mb-4 shadow-lg bg-accent text-primary-dark border-none text-[10px] md:text-xs">
{t('categoryLabel')}
</Badge>
<h2 className="text-3xl md:text-4xl font-bold text-white leading-tight transition-transform duration-500 group-hover:translate-x-1">
<h2 className="text-xl md:text-4xl font-bold text-white leading-tight transition-transform duration-500 group-hover:translate-x-1">
{category.title}
</h2>
</div>
</div>
<div className="p-8 md:p-10">
<p className="text-text-secondary text-lg leading-relaxed mb-8">
<div className="p-5 md:p-10">
<p className="text-text-secondary text-sm md:text-lg leading-relaxed mb-4 md:mb-8 line-clamp-2 md:line-clamp-none">
{category.desc}
</p>
<div className="flex items-center text-primary font-bold text-lg group-hover:text-accent-dark transition-colors">
<div className="flex items-center text-primary font-bold text-base md:text-lg group-hover:text-accent-dark transition-colors">
<span className="border-b-2 border-primary/10 group-hover:border-accent-dark transition-colors pb-1">
{t('viewProducts')}
</span>
<div className="ml-4 w-10 h-10 rounded-full bg-primary-light flex items-center justify-center text-primary group-hover:bg-accent group-hover:text-primary-dark transition-all duration-300 shadow-sm">
<svg className="w-5 h-5 transition-transform group-hover:translate-x-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<div className="ml-3 md:ml-4 w-8 h-8 md:w-10 md:h-10 rounded-full bg-primary-light flex items-center justify-center text-primary group-hover:bg-accent group-hover:text-primary-dark transition-all duration-300 shadow-sm">
<svg className="w-4 h-4 md:w-5 md:h-5 transition-transform group-hover:translate-x-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 8l4 4m0 0l-4 4m4-4H3" />
</svg>
</div>
@@ -129,18 +130,18 @@ export default function ProductsPage({ params }: ProductsPageProps) {
</Section>
{/* Technical Support CTA */}
<Section className="bg-white">
<Section className="bg-white py-12 md:py-28">
<Container>
<div className="bg-primary-dark rounded-[48px] md:rounded-[64px] p-12 md:p-20 lg:p-24 relative overflow-hidden">
<div className="bg-primary-dark rounded-[32px] md:rounded-[64px] p-6 md:p-20 lg:p-24 relative overflow-hidden">
<div className="absolute top-0 right-0 w-1/2 h-full bg-accent/5 -skew-x-12 translate-x-1/4" />
<div className="relative z-10 flex flex-col lg:flex-row items-center justify-between gap-12">
<div className="relative z-10 flex flex-col lg:flex-row items-center justify-between gap-6 md:gap-12">
<div className="max-w-2xl text-center lg:text-left">
<h2 className="text-4xl md:text-5xl lg:text-6xl font-bold text-white mb-8 tracking-tight">{t('cta.title')}</h2>
<p className="text-xl text-white/70 leading-relaxed">
<h2 className="text-2xl md:text-5xl lg:text-6xl font-bold text-white mb-4 md:mb-8 tracking-tight">{t('cta.title')}</h2>
<p className="text-base md:text-xl text-white/70 leading-relaxed">
{t('cta.description')}
</p>
</div>
<Button href={`/${params.locale}/contact`} variant="accent" size="xl" className="group whitespace-nowrap">
<Button href={`/${params.locale}/contact`} variant="accent" size="lg" className="group whitespace-nowrap w-full md:w-auto md:h-16 md:px-10 md:text-xl">
{t('cta.button')}
<span className="ml-4 transition-transform group-hover:translate-x-2">&rarr;</span>
</Button>

View File

@@ -8,24 +8,24 @@ export default function TeamPage() {
return (
<div className="flex flex-col min-h-screen bg-neutral-light">
{/* Hero Section */}
<section className="relative flex items-center justify-center overflow-hidden bg-primary-dark pt-[14%] pb-[12%]">
<section className="relative flex items-center justify-center overflow-hidden bg-primary-dark pt-32 pb-24 md:pt-[14%] md:pb-[12%]">
<div className="absolute inset-0 z-0">
<Image
src="/uploads/2024/12/DSC07655-Large.webp"
alt="KLZ Team"
fill
className="object-cover scale-105 animate-slow-zoom opacity-40"
className="object-cover scale-105 animate-slow-zoom opacity-30 md:opacity-40"
priority
/>
<div className="absolute inset-0 bg-gradient-to-b from-primary-dark/80 via-primary-dark/40 to-primary-dark/80" />
</div>
<Container className="relative z-10 text-center text-white max-w-5xl animate-slide-up">
<Badge variant="accent" className="mb-8 shadow-lg">Our People</Badge>
<h1 className="text-5xl md:text-7xl lg:text-8xl font-extrabold tracking-tight leading-[1.1] mb-8">
<Badge variant="accent" className="mb-4 md:mb-8 shadow-lg">Our People</Badge>
<h1 className="text-3xl md:text-7xl lg:text-8xl font-extrabold tracking-tight leading-[1.1] mb-4 md:mb-8">
{t('hero.subtitle')}
</h1>
<p className="text-2xl md:text-3xl text-white/70 font-medium italic">
<p className="text-lg md:text-3xl text-white/70 font-medium italic">
{t('hero.title')}
</p>
</Container>
@@ -34,39 +34,40 @@ export default function TeamPage() {
{/* Michael Bodemer Section - Sticky Narrative Split Layout */}
<section className="relative bg-white overflow-hidden">
<div className="flex flex-col lg:flex-row">
<div className="w-full lg:w-1/2 p-12 md:p-24 lg:p-32 flex flex-col justify-center bg-primary-dark text-white relative">
<div className="w-full lg:w-1/2 p-6 md:p-24 lg:p-32 flex flex-col justify-center bg-primary-dark text-white relative">
<div className="absolute top-0 right-0 w-32 h-full bg-accent/5 -skew-x-12 translate-x-1/2" />
<div className="relative z-10 animate-fade-in">
<Badge variant="accent" className="mb-8">Managing Director</Badge>
<Heading level={2} className="text-white mb-10 text-5xl md:text-6xl">
<Badge variant="accent" className="mb-4 md:mb-8">Managing Director</Badge>
<Heading level={2} className="text-white mb-6 md:mb-10 text-3xl md:text-6xl">
<span className="text-white">{t('michael.name')}</span>
</Heading>
<div className="relative mb-12">
<div className="absolute -left-8 top-0 bottom-0 w-1.5 bg-accent rounded-full" />
<p className="text-2xl md:text-3xl font-bold italic leading-relaxed pl-8 text-white/90">
<div className="relative mb-6 md:mb-12">
<div className="absolute -left-4 md:-left-8 top-0 bottom-0 w-1 md:w-1.5 bg-accent rounded-full" />
<p className="text-lg md:text-3xl font-bold italic leading-relaxed pl-5 md:pl-8 text-white/90">
"{t('michael.quote')}"
</p>
</div>
<p className="text-xl leading-relaxed text-white/70 mb-12 max-w-xl">
<p className="text-base md:text-xl leading-relaxed text-white/70 mb-6 md:mb-12 max-w-xl line-clamp-4 md:line-clamp-none">
{t('michael.description')}
</p>
<Button
href="https://www.linkedin.com/in/michael-bodemer-33b493122/"
variant="accent"
size="xl"
className="group"
size="lg"
className="group w-full md:w-auto md:h-16 md:px-10 md:text-xl"
>
{t('michael.linkedin')}
<span className="ml-3 transition-transform group-hover:translate-x-2">&rarr;</span>
</Button>
</div>
</div>
<div className="w-full lg:w-1/2 relative min-h-[600px] lg:min-h-screen overflow-hidden">
<div className="w-full lg:w-1/2 relative min-h-[300px] md:min-h-[600px] lg:min-h-screen overflow-hidden">
<Image
src="/uploads/2024/12/DSC07768-Large.webp"
alt={t('michael.name')}
fill
className="object-cover scale-105 hover:scale-100 transition-transform duration-1000"
sizes="(max-width: 1024px) 100vw, 50vw"
/>
<div className="absolute inset-0 bg-gradient-to-r from-primary-dark/20 to-transparent" />
</div>
@@ -74,39 +75,40 @@ export default function TeamPage() {
</section>
{/* Legacy Section - Immersive Background */}
<section className="relative py-32 md:py-48 bg-primary-dark text-white overflow-hidden">
<section className="relative py-16 md:py-48 bg-primary-dark text-white overflow-hidden">
<div className="absolute inset-0 z-0">
<Image
src="/uploads/2024/12/1694273920124-copy.webp"
alt="Legacy"
fill
className="object-cover opacity-30 scale-110 animate-slow-zoom"
className="object-cover opacity-20 md:opacity-30 scale-110 animate-slow-zoom"
sizes="100vw"
/>
<div className="absolute inset-0 bg-primary-dark/60 mix-blend-multiply" />
</div>
<Container className="relative z-10">
<div className="grid grid-cols-1 lg:grid-cols-12 gap-16 items-center">
<div className="grid grid-cols-1 lg:grid-cols-12 gap-8 md:gap-16 items-center">
<div className="lg:col-span-6">
<Heading level={2} subtitle="Our Heritage" className="text-white mb-10">
<Heading level={2} subtitle="Our Heritage" className="text-white mb-6 md:mb-10">
<span className="text-white">{t('legacy.title')}</span>
</Heading>
<div className="space-y-8 text-xl md:text-2xl text-white/80 leading-relaxed font-medium">
<p className="border-l-4 border-accent pl-8 py-2 bg-white/5 backdrop-blur-sm rounded-r-2xl">
<div className="space-y-4 md:space-y-8 text-base md:text-2xl text-white/80 leading-relaxed font-medium">
<p className="border-l-4 border-accent pl-5 md:pl-8 py-2 bg-white/5 backdrop-blur-sm rounded-r-xl md:rounded-r-2xl">
{t('legacy.p1')}
</p>
<p className="pl-9">
<p className="pl-6 md:pl-9 line-clamp-3 md:line-clamp-none">
{t('legacy.p2')}
</p>
</div>
</div>
<div className="lg:col-span-6 grid grid-cols-1 md:grid-cols-2 gap-6">
<div className="p-8 bg-white/5 backdrop-blur-md border border-white/10 rounded-[32px] hover:bg-white/10 transition-colors">
<div className="text-4xl font-extrabold text-accent mb-2">Expertise</div>
<div className="text-sm font-bold uppercase tracking-widest text-white/50">Decades of Industry Knowledge</div>
<div className="lg:col-span-6 grid grid-cols-2 md:grid-cols-2 gap-3 md:gap-6">
<div className="p-4 md:p-8 bg-white/5 backdrop-blur-md border border-white/10 rounded-2xl md:rounded-[32px] hover:bg-white/10 transition-colors">
<div className="text-xl md:text-4xl font-extrabold text-accent mb-1 md:mb-2">Expertise</div>
<div className="text-[10px] md:text-sm font-bold uppercase tracking-widest text-white/50">Decades of Knowledge</div>
</div>
<div className="p-8 bg-white/5 backdrop-blur-md border border-white/10 rounded-[32px] hover:bg-white/10 transition-colors">
<div className="text-4xl font-extrabold text-accent mb-2">Network</div>
<div className="text-sm font-bold uppercase tracking-widest text-white/50">Strong Global Partnerships</div>
<div className="p-4 md:p-8 bg-white/5 backdrop-blur-md border border-white/10 rounded-2xl md:rounded-[32px] hover:bg-white/10 transition-colors">
<div className="text-xl md:text-4xl font-extrabold text-accent mb-1 md:mb-2">Network</div>
<div className="text-[10px] md:text-sm font-bold uppercase tracking-widest text-white/50">Global Partnerships</div>
</div>
</div>
</div>
@@ -116,36 +118,37 @@ export default function TeamPage() {
{/* Klaus Mintel Section - Reversed Split Layout */}
<section className="relative bg-white overflow-hidden">
<div className="flex flex-col lg:flex-row">
<div className="w-full lg:w-1/2 relative min-h-[600px] lg:min-h-screen overflow-hidden order-2 lg:order-1">
<div className="w-full lg:w-1/2 relative min-h-[300px] md:min-h-[600px] lg:min-h-screen overflow-hidden order-2 lg:order-1">
<Image
src="/uploads/2024/12/DSC07963-Large.webp"
alt={t('klaus.name')}
fill
className="object-cover scale-105 hover:scale-100 transition-transform duration-1000"
sizes="(max-width: 1024px) 100vw, 50vw"
/>
<div className="absolute inset-0 bg-gradient-to-l from-primary-dark/20 to-transparent" />
</div>
<div className="w-full lg:w-1/2 p-12 md:p-24 lg:p-32 flex flex-col justify-center bg-neutral-light text-primary relative order-1 lg:order-2">
<div className="w-full lg:w-1/2 p-6 md:p-24 lg:p-32 flex flex-col justify-center bg-neutral-light text-primary relative order-1 lg:order-2">
<div className="absolute top-0 left-0 w-32 h-full bg-primary/5 skew-x-12 -translate-x-1/2" />
<div className="relative z-10 animate-fade-in">
<Badge variant="primary" className="mb-8">Founder & Visionary</Badge>
<Heading level={2} className="text-primary mb-10 text-5xl md:text-6xl">
<Badge variant="primary" className="mb-4 md:mb-8">Founder & Visionary</Badge>
<Heading level={2} className="text-primary mb-6 md:mb-10 text-3xl md:text-6xl">
{t('klaus.name')}
</Heading>
<div className="relative mb-12">
<div className="absolute -left-8 top-0 bottom-0 w-1.5 bg-primary rounded-full" />
<p className="text-2xl md:text-3xl font-bold italic leading-relaxed pl-8 text-text-secondary">
<div className="relative mb-6 md:mb-12">
<div className="absolute -left-4 md:-left-8 top-0 bottom-0 w-1 md:w-1.5 bg-primary rounded-full" />
<p className="text-lg md:text-3xl font-bold italic leading-relaxed pl-5 md:pl-8 text-text-secondary">
"{t('klaus.quote')}"
</p>
</div>
<p className="text-xl leading-relaxed text-text-secondary mb-12 max-w-xl">
<p className="text-base md:text-xl leading-relaxed text-text-secondary mb-6 md:mb-12 max-w-xl line-clamp-4 md:line-clamp-none">
{t('klaus.description')}
</p>
<Button
href="https://www.linkedin.com/in/klaus-mintel-b80a8b193/"
variant="primary"
size="xl"
className="group"
size="lg"
className="group w-full md:w-auto md:h-16 md:px-10 md:text-xl"
>
{t('klaus.linkedin')}
<span className="ml-3 transition-transform group-hover:translate-x-2">&rarr;</span>
@@ -156,27 +159,27 @@ export default function TeamPage() {
</section>
{/* Manifesto Section - Modern Grid */}
<Section className="bg-white text-primary">
<Section className="bg-white text-primary py-16 md:py-28">
<Container>
<div className="grid grid-cols-1 lg:grid-cols-12 gap-20">
<div className="lg:col-span-4">
<div className="sticky top-32">
<Heading level={2} subtitle="Our Values">
<div className="sticky-narrative-container">
<div className="sticky-narrative-sidebar mb-8 lg:mb-0">
<div className="lg:sticky lg:top-32">
<Heading level={2} subtitle="Our Values" className="mb-4 md:mb-8">
{t('manifesto.title')}
</Heading>
<p className="text-xl text-text-secondary leading-relaxed">
<p className="text-base md:text-xl text-text-secondary leading-relaxed">
Our core principles guide every decision we make and every cable we deliver.
</p>
</div>
</div>
<div className="lg:col-span-8 grid grid-cols-1 md:grid-cols-2 gap-10">
<div className="sticky-narrative-content grid grid-cols-1 md:grid-cols-2 gap-4 md:gap-10">
{[0, 1, 2, 3, 4, 5].map((idx) => (
<div key={idx} className="p-10 bg-neutral-light rounded-[40px] border border-transparent hover:border-accent hover:bg-white hover:shadow-2xl transition-all duration-500 group">
<div className="w-16 h-16 bg-white rounded-2xl flex items-center justify-center mb-8 shadow-sm group-hover:bg-accent transition-colors duration-500">
<span className="text-primary font-extrabold text-2xl group-hover:text-primary-dark">0{idx + 1}</span>
<div key={idx} className="p-6 md:p-10 bg-neutral-light rounded-2xl md:rounded-[40px] border border-transparent hover:border-accent hover:bg-white hover:shadow-2xl transition-all duration-500 group">
<div className="w-10 h-10 md:w-16 md:h-16 bg-white rounded-xl md:rounded-2xl flex items-center justify-center mb-4 md:mb-8 shadow-sm group-hover:bg-accent transition-colors duration-500">
<span className="text-primary font-extrabold text-lg md:text-2xl group-hover:text-primary-dark">0{idx + 1}</span>
</div>
<h3 className="text-2xl font-bold mb-4 text-primary">{t(`manifesto.items.${idx}.title`)}</h3>
<p className="text-text-secondary text-lg leading-relaxed">{t(`manifesto.items.${idx}.description`)}</p>
<h3 className="text-lg md:text-2xl font-bold mb-2 md:mb-4 text-primary">{t(`manifesto.items.${idx}.title`)}</h3>
<p className="text-sm md:text-lg text-text-secondary leading-relaxed line-clamp-3 md:line-clamp-none">{t(`manifesto.items.${idx}.description`)}</p>
</div>
))}
</div>
@@ -185,12 +188,12 @@ export default function TeamPage() {
</Section>
{/* Gallery Section - Premium Treatment */}
<Section className="bg-primary-dark py-32">
<Section className="bg-primary-dark py-16 md:py-32">
<Container>
<Heading level={2} subtitle="Behind the Scenes" align="center" className="text-white mb-20">
<Heading level={2} subtitle="Behind the Scenes" align="center" className="text-white mb-12 md:mb-20">
<span className="text-white">Life at KLZ</span>
</Heading>
<div className="grid grid-cols-2 md:grid-cols-5 gap-6">
<div className="grid grid-cols-2 md:grid-cols-5 gap-3 md:gap-6">
{[
'/uploads/2024/12/DSC07539-Large-600x400.webp',
'/uploads/2024/12/DSC07460-Large-600x400.webp',
@@ -198,10 +201,10 @@ export default function TeamPage() {
'/uploads/2024/12/DSC07433-Large-600x400.webp',
'/uploads/2024/12/DSC07387-Large-600x400.webp'
].map((src, idx) => (
<div key={idx} className="relative aspect-[3/4] rounded-[32px] overflow-hidden group shadow-2xl">
<div key={idx} className="relative aspect-[3/4] rounded-2xl md:rounded-[32px] overflow-hidden group shadow-2xl">
<Image src={src} alt="Team Gallery" fill className="object-cover transition-transform duration-1000 group-hover:scale-110" />
<div className="absolute inset-0 bg-primary-dark/40 group-hover:bg-transparent transition-all duration-500" />
<div className="absolute inset-0 border-0 group-hover:border-[12px] border-white/10 transition-all duration-500 pointer-events-none" />
<div className="absolute inset-0 border-0 group-hover:border-[8px] md:group-hover:border-[12px] border-white/10 transition-all duration-500 pointer-events-none" />
</div>
))}
</div>

View File

@@ -43,10 +43,10 @@ export default function Header() {
];
const headerClass = cn(
"fixed top-0 left-0 right-0 z-50 transition-all duration-500",
"fixed top-0 left-0 right-0 z-50 transition-all duration-500 safe-area-p",
{
"bg-transparent py-8": isHomePage && !isScrolled,
"bg-primary py-4 shadow-2xl": !isHomePage || isScrolled,
"bg-transparent py-4 md:py-8": isHomePage && !isScrolled,
"bg-primary py-3 md:py-4 shadow-2xl": !isHomePage || isScrolled,
}
);
@@ -56,20 +56,20 @@ export default function Header() {
return (
<>
<header className={headerClass}>
<div className="container mx-auto px-6 md:px-12 lg:px-16 max-w-7xl flex items-center justify-between">
<Link href={`/${currentLocale}`} className="flex-shrink-0 group">
<div className="container mx-auto px-4 md:px-12 lg:px-16 max-w-7xl flex items-center justify-between">
<Link href={`/${currentLocale}`} className="flex-shrink-0 group touch-target">
<Image
src={logoSrc}
alt="KLZ Cables"
width={120}
height={120}
className="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
unoptimized
/>
</Link>
<div className="flex items-center gap-12">
<div className="flex items-center gap-4 md:gap-12">
<nav className="hidden lg:flex items-center space-x-10">
{menuItems.map((item) => (
<Link
@@ -90,14 +90,14 @@ export default function Header() {
<div className="flex items-center space-x-4 text-sm font-extrabold tracking-widest uppercase">
<Link
href={getPathForLocale('en')}
className={`hover:text-accent transition-colors flex items-center gap-2 ${currentLocale === 'en' ? 'text-accent' : 'opacity-60'}`}
className={`hover:text-accent transition-colors flex items-center gap-2 touch-target ${currentLocale === 'en' ? 'text-accent' : 'opacity-60'}`}
>
EN
</Link>
<div className="w-px h-4 bg-current opacity-20" />
<Link
href={getPathForLocale('de')}
className={`hover:text-accent transition-colors flex items-center gap-2 ${currentLocale === 'de' ? 'text-accent' : 'opacity-60'}`}
className={`hover:text-accent transition-colors flex items-center gap-2 touch-target ${currentLocale === 'de' ? 'text-accent' : 'opacity-60'}`}
>
DE
</Link>
@@ -114,8 +114,8 @@ export default function Header() {
</div>
{/* Mobile Menu Button */}
<button className={cn("lg:hidden p-2 rounded-xl bg-white/10 backdrop-blur-md border border-white/20", textColorClass)}>
<svg className="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<button className={cn("lg:hidden touch-target p-2 rounded-xl bg-white/10 backdrop-blur-md border border-white/20", textColorClass)}>
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 12h16M4 18h16" />
</svg>
</button>

48
components/Reveal.tsx Normal file
View File

@@ -0,0 +1,48 @@
'use client';
import React, { useEffect, useRef, useState } from 'react';
import { cn } from '@/components/ui';
interface RevealProps {
children: React.ReactNode;
className?: string;
threshold?: number;
delay?: number;
}
export default function Reveal({ children, className, threshold = 0.1, delay = 0 }: RevealProps) {
const [isVisible, setIsVisible] = useState(false);
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) {
setIsVisible(true);
observer.unobserve(entry.target);
}
},
{ threshold }
);
if (ref.current) {
observer.observe(ref.current);
}
return () => {
if (ref.current) {
observer.unobserve(ref.current);
}
};
}, [threshold]);
return (
<div
ref={ref}
className={cn('reveal-on-scroll', isVisible && 'is-visible', className)}
style={{ transitionDelay: `${delay}ms` }}
>
{children}
</div>
);
}

View File

@@ -8,34 +8,37 @@ export default function Hero() {
const t = useTranslations('Home.hero');
return (
<section className="relative h-[90vh] flex items-center justify-center overflow-hidden bg-primary-dark">
<section className="relative h-[70vh] md:h-[90vh] flex items-center justify-center overflow-hidden bg-primary-dark">
<HeroIllustration />
<Container className="relative z-10 text-left text-white w-full">
<div className="max-w-5xl animate-slide-up">
<h1 className="text-5xl md:text-7xl lg:text-8xl font-extrabold mb-8 tracking-tight leading-[1.05]">
<h1 className="text-4xl md:text-7xl lg:text-8xl font-extrabold mb-4 md:mb-8 tracking-tight leading-[1.05] max-w-[15ch] md:max-w-none">
{t.rich('title', {
green: (chunks) => (
<span className="relative inline-block">
<span className="relative z-10 text-accent italic">{chunks}</span>
<Scribble variant="circle" className="w-[140%] h-[140%] -top-[20%] -left-[20%] text-accent/30" />
<Scribble variant="circle" className="w-[140%] h-[140%] -top-[20%] -left-[20%] text-accent/30 hidden md:block" />
</span>
)
})}
</h1>
<div className="mt-12 flex flex-wrap gap-6">
<Button href="/contact" variant="accent" size="xl" className="group">
<p className="text-lg md:text-2xl text-white/70 leading-relaxed max-w-2xl mb-8 md:mb-12 line-clamp-2 md:line-clamp-none">
{t('subtitle')}
</p>
<div className="flex flex-col md:flex-row gap-3 md:gap-6">
<Button href="/contact" variant="accent" size="lg" className="group w-full md:w-auto md:h-16 md:px-10 md:text-xl">
{t('cta')}
<span className="ml-3 transition-transform group-hover:translate-x-1">&rarr;</span>
</Button>
<Button href="/products" variant="white" size="xl" className="group">
<Button href="/products" variant="ghost" size="lg" className="group w-full md:w-auto text-white hover:bg-white/10 md:bg-white md:text-primary md:hover:bg-neutral-light md:h-16 md:px-10 md:text-xl">
{t('exploreProducts')}
</Button>
</div>
</div>
</Container>
<div className="absolute bottom-10 left-1/2 -translate-x-1/2 animate-bounce">
<div className="absolute bottom-6 md:bottom-10 left-1/2 -translate-x-1/2 animate-bounce hidden sm:block">
<div className="w-6 h-10 border-2 border-white/30 rounded-full flex justify-center p-1">
<div className="w-1 h-2 bg-white rounded-full" />
</div>

View File

@@ -166,7 +166,7 @@ export default function HeroIllustration() {
<div className="absolute inset-0 z-0 overflow-hidden bg-primary">
<svg
viewBox="-400 -200 1800 1100"
className="w-full h-full"
className="w-full h-full opacity-40 md:opacity-100 scale-150 md:scale-100 translate-x-1/4 md:translate-x-0"
preserveAspectRatio="xMidYMid slice"
fill="none"
xmlns="http://www.w3.org/2000/svg"

View File

@@ -43,26 +43,27 @@ export default function ProductCategories() {
<Section className="bg-neutral-light py-0 -mt-px">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4">
{categories.map((category, idx) => (
<Link key={idx} href={category.href} className="group block relative h-[500px] lg:h-[650px] overflow-hidden border-r border-white/10 last:border-r-0">
<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">
<Image
src={category.img}
alt={category.title}
fill
className="object-cover transition-transform duration-1000 group-hover:scale-110"
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 p-10 flex flex-col justify-end text-white">
<div className="mb-6 transform transition-all duration-500 group-hover:-translate-y-4">
<div className="w-16 h-16 bg-white/10 backdrop-blur-md rounded-xl flex items-center justify-center mb-6 border border-white/20">
<img src={category.icon} alt="" className="w-10 h-10 brightness-0 invert" />
<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="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">
<img src={category.icon} alt="" className="w-8 h-8 md:w-10 md:h-10 brightness-0 invert" />
</div>
<h3 className="text-3xl font-bold mb-4 leading-tight">{category.title}</h3>
<p className="text-white/80 text-lg line-clamp-3 opacity-0 group-hover:opacity-100 transition-all duration-500 max-h-0 group-hover:max-h-32">
<h3 className="text-2xl md:text-3xl font-bold mb-2 md:mb-4 leading-tight">{category.title}</h3>
<p className="text-white/80 text-base md:text-lg 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}
</p>
</div>
<div className="flex items-center text-accent font-bold tracking-wider uppercase text-sm 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-sm 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>
</div>
</div>

View File

@@ -15,22 +15,22 @@ export default async function RecentPosts({ locale }: RecentPostsProps) {
if (recentPosts.length === 0) return null;
return (
<Section className="bg-neutral py-24">
<Section className="bg-neutral py-16 md:py-24">
<Container>
<div className="flex flex-col md:flex-row items-end justify-between mb-16 gap-6">
<div className="flex flex-col md:flex-row items-start md:items-end justify-between mb-12 md:mb-16 gap-6">
<Heading level={2} subtitle="Insights" className="mb-0">
{locale === 'de' ? 'Aktuelle Blogbeiträge' : 'Recent Blog Posts'}
</Heading>
<Link href={`/${locale}/blog`} className="group flex items-center text-primary font-bold text-lg">
<Link href={`/${locale}/blog`} className="group flex items-center text-primary font-bold text-lg touch-target">
{locale === 'de' ? 'Alle Beiträge ansehen' : 'View all posts'}
<span className="ml-2 transition-transform group-hover:translate-x-2">&rarr;</span>
</Link>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-10">
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 md:gap-10">
{recentPosts.map((post) => (
<Link key={post.slug} href={`/${locale}/blog/${post.slug}`} className="group block">
<Card className="h-full flex flex-col border-none shadow-lg hover:shadow-2xl transition-all duration-500">
<Card className="h-full flex flex-col border-none shadow-lg hover:shadow-2xl transition-all duration-500 rounded-3xl">
{post.frontmatter.featuredImage && (
<div className="relative h-64 overflow-hidden">
<img
@@ -38,7 +38,7 @@ export default async function RecentPosts({ locale }: RecentPostsProps) {
alt={post.frontmatter.title}
className="w-full h-full object-cover transition-transform duration-700 group-hover:scale-110"
/>
<div className="absolute inset-0 bg-gradient-to-t from-primary-dark/60 to-transparent 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 && (
<Badge variant="accent" className="absolute top-4 left-4 shadow-md">
{post.frontmatter.category}
@@ -46,16 +46,16 @@ export default async function RecentPosts({ locale }: RecentPostsProps) {
)}
</div>
)}
<div className="p-8 flex flex-col flex-grow">
<div className="text-sm font-medium text-text-light mb-4 flex items-center gap-2">
<span className="w-8 h-px bg-neutral-medium" />
<div className="p-6 md:p-8 flex flex-col flex-grow">
<div className="text-xs md:text-sm font-medium text-text-light mb-3 md:mb-4 flex items-center gap-2">
<span className="w-6 md:w-8 h-px bg-neutral-medium" />
{new Date(post.frontmatter.date).toLocaleDateString(locale, {
year: 'numeric',
month: 'long',
day: 'numeric'
})}
</div>
<h3 className="text-2xl font-bold text-primary group-hover:text-accent-dark transition-colors line-clamp-2 mb-6 leading-tight">
<h3 className="text-xl md:text-2xl font-bold text-primary group-hover:text-accent-dark transition-colors line-clamp-2 mb-4 md:mb-6 leading-tight">
{post.frontmatter.title}
</h3>
<div className="mt-auto flex items-center text-primary font-bold group-hover:underline decoration-2 underline-offset-4">

View File

@@ -8,33 +8,33 @@ export default function WhatWeDo() {
return (
<Section className="bg-white text-neutral-dark">
<Container>
<div className="grid grid-cols-1 lg:grid-cols-12 gap-16 lg:gap-24">
<div className="lg:col-span-4">
<div className="sticky top-32">
<div className="sticky-narrative-container">
<div className="sticky-narrative-sidebar">
<div className="lg:sticky lg:top-32">
<Heading level={2} subtitle="Our Expertise">
{t('title')}
</Heading>
<p className="text-xl text-text-secondary leading-relaxed">
<p className="text-lg md:text-xl text-text-secondary leading-relaxed">
{t('subtitle')}
</p>
<div className="mt-12 p-8 bg-primary-light rounded-2xl border border-primary/10">
<p className="text-primary font-bold text-lg italic">
<div className="mt-8 md:mt-12 p-6 md:p-8 bg-primary-light rounded-2xl border border-primary/10">
<p className="text-primary font-bold text-base md:text-lg italic">
"{t('quote')}"
</p>
</div>
</div>
</div>
<div className="lg:col-span-8 grid grid-cols-1 md:grid-cols-2 gap-x-12 gap-y-20">
<div className="sticky-narrative-content grid grid-cols-1 md:grid-cols-2 gap-x-8 md:gap-x-12 gap-y-12 md:gap-y-20">
{[0, 1, 2, 3].map((idx) => (
<div key={idx} className="group">
<div className="flex items-center gap-4 mb-6">
<span className="flex items-center justify-center w-12 h-12 rounded-full bg-primary text-white font-bold text-lg shadow-lg shadow-primary/20 group-hover:scale-110 transition-transform">
<div className="flex items-center gap-4 mb-4 md:mb-6">
<span className="flex items-center justify-center w-10 h-10 md:w-12 md:h-12 rounded-full bg-primary text-white font-bold text-base md:text-lg shadow-lg shadow-primary/20 group-hover:scale-110 transition-transform">
{idx + 1}
</span>
<div className="h-px flex-grow bg-neutral-medium" />
</div>
<h3 className="text-2xl font-bold mb-4 text-primary group-hover:text-accent-dark transition-colors">{t(`items.${idx}.title`)}</h3>
<p className="text-text-secondary text-lg leading-relaxed">{t(`items.${idx}.description`)}</p>
<h3 className="text-xl md:text-2xl font-bold mb-3 md:mb-4 text-primary group-hover:text-accent-dark transition-colors">{t(`items.${idx}.title`)}</h3>
<p className="text-text-secondary text-base md:text-lg leading-relaxed">{t(`items.${idx}.description`)}</p>
</div>
))}
</div>

View File

@@ -51,7 +51,7 @@ export function Button({ className, variant = 'primary', size = 'md', href, ...p
export function Section({ className, children, ...props }: React.HTMLAttributes<HTMLElement>) {
return (
<section className={cn('py-20 md:py-28 lg:py-36 overflow-hidden', className)} {...props}>
<section className={cn('py-16 md:py-28 lg:py-36 overflow-hidden content-visibility-auto', className)} {...props}>
{children}
</section>
);
@@ -59,7 +59,7 @@ export function Section({ className, children, ...props }: React.HTMLAttributes<
export function Container({ className, children, ...props }: React.HTMLAttributes<HTMLDivElement>) {
return (
<div className={cn('container mx-auto px-6 md:px-12 lg:px-16 max-w-7xl', className)} {...props}>
<div className={cn('container mx-auto px-4 md:px-12 lg:px-16 max-w-7xl', className)} {...props}>
{children}
</div>
);
@@ -81,8 +81,8 @@ export function Heading({
const Tag = `h${level}` as any;
const sizes = {
1: 'text-5xl md:text-6xl lg:text-7xl font-extrabold leading-[1.1]',
2: 'text-4xl md:text-5xl lg:text-6xl font-bold leading-tight',
1: 'text-4xl md:text-6xl lg:text-7xl xl:text-8xl font-extrabold leading-[1.1]',
2: 'text-3xl md:text-5xl lg:text-6xl font-bold leading-tight',
3: 'text-2xl md:text-3xl lg:text-4xl font-bold',
4: 'text-xl md:text-2xl font-bold',
};
@@ -94,9 +94,9 @@ export function Heading({
};
return (
<div className={cn('mb-12 md:mb-16', alignments[align], className)}>
<div className={cn('mb-8 md:mb-16', alignments[align], className)}>
{subtitle && (
<span className="inline-block text-accent font-bold tracking-widest uppercase text-sm mb-4 animate-fade-in">
<span className="inline-block text-accent font-bold tracking-widest uppercase text-xs md:text-sm mb-3 md:mb-4 animate-fade-in">
{subtitle}
</span>
)}

36
eslint.config.mjs Normal file
View File

@@ -0,0 +1,36 @@
import { dirname } from 'path';
import { fileURLToPath } from 'url';
import { FlatCompat } from '@eslint/eslintrc';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
});
const eslintConfig = [
{
ignores: [
'.next/**',
'node_modules/**',
'reference/**',
'public/**',
'dist/**',
],
},
...compat.extends('next/core-web-vitals'),
...compat.extends('next/typescript'),
{
rules: {
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unused-vars': 'warn',
'@typescript-eslint/no-require-imports': 'off',
'prefer-const': 'warn',
'react/no-unescaped-entities': 'off',
'@next/next/no-img-element': 'warn',
}
}
];
export default eslintConfig;

View File

@@ -48,6 +48,8 @@
"build": "next build",
"start": "next start",
"lint": "next lint",
"typecheck": "tsc --noEmit",
"test": "vitest run",
"pdf:datasheets": "tsx ./scripts/generate-pdf-datasheets.ts",
"pdf:datasheets:legacy": "tsx ./scripts/generate-pdf-datasheets-pdf-lib.ts"
},

View File

@@ -33,6 +33,7 @@
--animate-fade-in: fade-in 0.5s ease-out;
--animate-slide-up: slide-up 0.6s ease-out;
--animate-slow-zoom: slow-zoom 20s linear infinite;
--animate-reveal: reveal 0.8s cubic-bezier(0.16, 1, 0.3, 1) forwards;
@keyframes fade-in {
from { opacity: 0; }
@@ -46,15 +47,28 @@
from { transform: scale(1); }
to { transform: scale(1.1); }
}
@keyframes reveal {
from { opacity: 0; transform: translateY(30px); }
to { opacity: 1; transform: translateY(0); }
}
}
@layer base {
body {
@apply text-text-primary bg-neutral-light antialiased;
@apply text-text-primary bg-neutral-light antialiased selection:bg-accent selection:text-primary-dark;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
h1, h2, h3, h4, h5, h6 {
@apply font-heading font-bold tracking-tight;
}
/* Mobile-first typography hierarchy */
h1 { @apply text-3xl md:text-6xl lg:text-7xl xl:text-8xl; }
h2 { @apply text-2xl md:text-5xl lg:text-6xl; }
h3 { @apply text-xl md:text-3xl lg:text-4xl; }
h4 { @apply text-lg md:text-2xl; }
}
@layer components {
@@ -62,92 +76,70 @@
@apply bg-white/80 backdrop-blur-md border border-white/20 shadow-lg;
}
.image-overlay-gradient {
@apply absolute inset-0 bg-gradient-to-t from-black/80 via-black/20 to-transparent;
@apply absolute inset-0 bg-gradient-to-t from-black/90 via-black/40 to-transparent;
}
.premium-card {
@apply bg-white rounded-xl border border-neutral-medium shadow-sm transition-all duration-300 hover:shadow-xl hover:-translate-y-1;
@apply bg-white rounded-3xl border border-neutral-medium shadow-sm transition-all duration-500 hover:shadow-2xl hover:-translate-y-1;
}
.sticky-narrative-container {
@apply grid grid-cols-1 lg:grid-cols-12 gap-12 lg:gap-20;
}
.sticky-narrative-sidebar {
@apply lg:col-span-4 lg:sticky lg:top-32 h-fit;
}
.sticky-narrative-content {
@apply lg:col-span-8;
}
}
/* Custom Utilities */
@utility touch-target {
min-height: 44px;
min-width: 44px;
min-height: 48px; /* Increased for better touch-first feel */
min-width: 48px;
display: inline-flex;
align-items: center;
justify-content: center;
}
@utility mobile-hidden {
@media (max-width: 767px) {
display: none !important;
@utility reveal-on-scroll {
opacity: 0;
transform: translateY(30px);
transition: opacity 0.8s cubic-bezier(0.16, 1, 0.3, 1), transform 0.8s cubic-bezier(0.16, 1, 0.3, 1);
&.is-visible {
opacity: 1;
transform: translateY(0);
}
@media (prefers-reduced-motion: reduce) {
transition: opacity 0.5s ease-out;
transform: none !important;
}
}
@utility tablet-hidden {
@media (min-width: 768px) and (max-width: 1023px) {
display: none !important;
}
}
@utility desktop-hidden {
@media (min-width: 1024px) {
display: none !important;
}
}
@utility mobile-only {
@media (min-width: 768px) {
display: none !important;
}
}
@utility tablet-only {
@media (max-width: 767px), (min-width: 1024px) {
display: none !important;
}
}
@utility desktop-only {
@media (max-width: 1023px) {
display: none !important;
@utility hover-effect {
@media (hover: hover) {
@apply transition-all duration-300 hover:scale-105;
}
}
@utility fluid-spacing {
padding: clamp(1rem, 3vw, 3rem);
margin: clamp(0.5rem, 2vw, 2rem);
}
@utility text-start-mobile {
@media (max-width: 767px) {
text-align: left;
}
}
@utility text-center-mobile {
@media (max-width: 767px) {
text-align: center;
}
}
@utility text-end-mobile {
@media (max-width: 767px) {
text-align: right;
}
padding: clamp(1.5rem, 5vw, 5rem);
margin: clamp(1rem, 3vw, 3rem);
}
@utility grid-mobile-stacked {
@media (max-width: 767px) {
display: flex;
flex-direction: column;
gap: 1rem;
}
@apply grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 md:gap-8 lg:gap-12;
}
@utility safe-area-p {
padding-top: env(safe-area-inset-top);
padding-bottom: env(safe-area-inset-bottom);
padding-left: env(safe-area-inset-left);
padding-right: env(safe-area-inset-right);
padding-top: max(1rem, env(safe-area-inset-top));
padding-bottom: max(1rem, env(safe-area-inset-bottom));
padding-left: max(1rem, env(safe-area-inset-left));
padding-right: max(1rem, env(safe-area-inset-right));
}
@utility content-visibility-auto {
content-visibility: auto;
contain-intrinsic-size: 1px 1000px;
}

File diff suppressed because one or more lines are too long