feat: add initial cinematic loader and global shutter page transitions
Former-commit-id: 641bf3103e29559d7bdff1dc1e034b21a11dbad6
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import Link from 'next/link';
|
||||
import { TransitionLink } from '@/components/ui/TransitionLink';
|
||||
import Image from 'next/image';
|
||||
import { useLocale } from 'next-intl';
|
||||
import { ShieldCheck, Leaf, Lock, Accessibility, Zap } from 'lucide-react';
|
||||
@@ -24,14 +24,14 @@ export function Footer({ companyInfo }: FooterProps) {
|
||||
<div className="container grid grid-cols-1 md:grid-cols-4 lg:grid-cols-12 gap-12 lg:gap-8 mb-12">
|
||||
{/* Brand Column */}
|
||||
<div className="col-span-1 md:col-span-2 lg:col-span-4 space-y-6">
|
||||
<Link href={`/${locale}`} className="relative block h-14 w-48 mb-6 group">
|
||||
<TransitionLink href={`/${locale}`} className="relative block h-14 w-48 mb-6 group">
|
||||
<Image
|
||||
src="/assets/logo-white.png"
|
||||
alt="E-TIB Gruppe"
|
||||
fill
|
||||
className="object-contain object-left transition-transform duration-500 group-hover:scale-105"
|
||||
/>
|
||||
</Link>
|
||||
</TransitionLink>
|
||||
<p className="text-white/60 text-base leading-relaxed max-w-sm">
|
||||
{locale === 'de'
|
||||
? 'Die Experten für Kabeltiefbau, Horizontalspülbohrungen und umfassende Infrastrukturprojekte. Qualität und Zuverlässigkeit aus Guben.'
|
||||
@@ -53,29 +53,29 @@ export function Footer({ companyInfo }: FooterProps) {
|
||||
</h4>
|
||||
<ul className="space-y-4">
|
||||
<li>
|
||||
<Link href={`/${locale}/kompetenzen`} className="text-white/70 hover:text-white hover:translate-x-1 inline-block transition-all">
|
||||
<TransitionLink href={`/${locale}/kompetenzen`} className="text-white/70 hover:text-white hover:translate-x-1 inline-block transition-all">
|
||||
{locale === 'de' ? 'Kompetenzen' : 'Competencies'}
|
||||
</Link>
|
||||
</TransitionLink>
|
||||
</li>
|
||||
<li>
|
||||
<Link href={`/${locale}/ueber-uns`} className="text-white/70 hover:text-white hover:translate-x-1 inline-block transition-all">
|
||||
<TransitionLink href={`/${locale}/ueber-uns`} className="text-white/70 hover:text-white hover:translate-x-1 inline-block transition-all">
|
||||
{locale === 'de' ? 'Über uns' : 'About us'}
|
||||
</Link>
|
||||
</TransitionLink>
|
||||
</li>
|
||||
<li>
|
||||
<Link href={`/${locale}/karriere`} className="text-white/70 hover:text-white hover:translate-x-1 inline-block transition-all">
|
||||
<TransitionLink href={`/${locale}/karriere`} className="text-white/70 hover:text-white hover:translate-x-1 inline-block transition-all">
|
||||
{locale === 'de' ? 'Karriere' : 'Career'}
|
||||
</Link>
|
||||
</TransitionLink>
|
||||
</li>
|
||||
<li>
|
||||
<Link href={`/${locale}/messen`} className="text-white/70 hover:text-white hover:translate-x-1 inline-block transition-all">
|
||||
<TransitionLink href={`/${locale}/messen`} className="text-white/70 hover:text-white hover:translate-x-1 inline-block transition-all">
|
||||
{locale === 'de' ? 'Messen & Events' : 'Fairs & Events'}
|
||||
</Link>
|
||||
</TransitionLink>
|
||||
</li>
|
||||
<li>
|
||||
<Link href={`/${locale}/${locale === 'de' ? 'kontakt' : 'contact'}`} className="text-white/70 hover:text-white hover:translate-x-1 inline-block transition-all">
|
||||
<TransitionLink href={`/${locale}/${locale === 'de' ? 'kontakt' : 'contact'}`} className="text-white/70 hover:text-white hover:translate-x-1 inline-block transition-all">
|
||||
{locale === 'de' ? 'Kontakt' : 'Contact'}
|
||||
</Link>
|
||||
</TransitionLink>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -87,19 +87,19 @@ export function Footer({ companyInfo }: FooterProps) {
|
||||
</h4>
|
||||
<ul className="space-y-4">
|
||||
<li>
|
||||
<Link href={`/${locale}/impressum`} className="text-white/70 hover:text-white hover:translate-x-1 inline-block transition-all">
|
||||
<TransitionLink href={`/${locale}/impressum`} className="text-white/70 hover:text-white hover:translate-x-1 inline-block transition-all">
|
||||
{locale === 'de' ? 'Impressum' : 'Imprint'}
|
||||
</Link>
|
||||
</TransitionLink>
|
||||
</li>
|
||||
<li>
|
||||
<Link href={`/${locale}/datenschutz`} className="text-white/70 hover:text-white hover:translate-x-1 inline-block transition-all">
|
||||
<TransitionLink href={`/${locale}/datenschutz`} className="text-white/70 hover:text-white hover:translate-x-1 inline-block transition-all">
|
||||
{locale === 'de' ? 'Datenschutz' : 'Privacy Policy'}
|
||||
</Link>
|
||||
</TransitionLink>
|
||||
</li>
|
||||
<li>
|
||||
<Link href={`/${locale}/${locale === 'de' ? 'agb' : 'terms'}`} className="text-white/70 hover:text-white hover:translate-x-1 inline-block transition-all">
|
||||
<TransitionLink href={`/${locale}/${locale === 'de' ? 'agb' : 'terms'}`} className="text-white/70 hover:text-white hover:translate-x-1 inline-block transition-all">
|
||||
{locale === 'de' ? 'AGB' : 'Terms'}
|
||||
</Link>
|
||||
</TransitionLink>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import * as React from 'react';
|
||||
import Link from 'next/link';
|
||||
import { TransitionLink } from '@/components/ui/TransitionLink';
|
||||
import Image from 'next/image';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import { motion, AnimatePresence, useScroll, useTransform } from 'framer-motion';
|
||||
@@ -97,7 +98,7 @@ export function Header({ navLinks }: HeaderProps) {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Link href={`/${currentLocale}`} className={`relative flex items-center transition-all duration-500 ease-out z-50 group ${isSolidMode ? 'h-9 w-36' : 'h-12 w-48'}`}>
|
||||
<TransitionLink href={`/${currentLocale}`} className={`relative flex items-center transition-all duration-500 ease-out z-50 group ${isSolidMode ? 'h-9 w-36' : 'h-12 w-48'}`}>
|
||||
<Image
|
||||
src={(isSolidMode || isMobileMenuOpen) ? "/assets/logo.png" : "/assets/logo-white.png"}
|
||||
alt="E-TIB Gruppe"
|
||||
@@ -106,7 +107,7 @@ export function Header({ navLinks }: HeaderProps) {
|
||||
priority
|
||||
sizes="192px"
|
||||
/>
|
||||
</Link>
|
||||
</TransitionLink>
|
||||
|
||||
<nav className="relative z-10 hidden md:flex items-center gap-8 lg:gap-10">
|
||||
{navLinks && navLinks.length > 0 && navLinks.map((link) => {
|
||||
@@ -117,7 +118,7 @@ export function Header({ navLinks }: HeaderProps) {
|
||||
const isActive = pathname === mappedUrl || (mappedUrl !== `/${currentLocale}` && pathname?.startsWith(`${mappedUrl}/`));
|
||||
|
||||
return (
|
||||
<Link
|
||||
<TransitionLink
|
||||
key={link.url}
|
||||
href={mappedUrl}
|
||||
className={`relative font-bold text-xs lg:text-sm uppercase tracking-widest transition-colors duration-300 group py-2 ${
|
||||
@@ -139,7 +140,7 @@ export function Header({ navLinks }: HeaderProps) {
|
||||
|
||||
{/* Subtle hover underline */}
|
||||
<span className={`absolute -bottom-1 left-1/2 w-0 h-0.5 -translate-x-1/2 rounded-full transition-all duration-300 ease-out group-hover:w-full ${isSolidMode ? 'bg-primary/30' : 'bg-white/30'} ${isActive ? 'opacity-0' : 'opacity-100'}`} />
|
||||
</Link>
|
||||
</TransitionLink>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -147,7 +148,7 @@ export function Header({ navLinks }: HeaderProps) {
|
||||
|
||||
<LanguageSwitcher isSolidMode={isSolidMode} />
|
||||
|
||||
<Link
|
||||
<TransitionLink
|
||||
href={`/${currentLocale}/${currentLocale === 'de' ? 'kontakt' : 'contact'}`}
|
||||
className={`relative ml-2 px-7 py-2.5 rounded-full font-bold text-xs lg:text-sm uppercase tracking-widest transition-all duration-500 overflow-hidden group/cta isolate ${
|
||||
isSolidMode
|
||||
@@ -158,7 +159,7 @@ export function Header({ navLinks }: HeaderProps) {
|
||||
<span className="relative z-10 transition-transform duration-300 group-hover/cta:scale-105 inline-block">{currentLocale === 'de' ? 'Kontakt' : 'Contact'}</span>
|
||||
{/* Sleek shine sweep effect */}
|
||||
<span className="absolute top-0 -left-[150%] h-[200%] w-[150%] bg-gradient-to-r from-transparent via-white/30 to-transparent skew-x-[-20deg] group-hover/cta:left-[100%] transition-all duration-1000 ease-[cubic-bezier(0.16,1,0.3,1)] z-30 pointer-events-none" />
|
||||
</Link>
|
||||
</TransitionLink>
|
||||
</nav>
|
||||
|
||||
{/* Mobile Nav Button */}
|
||||
@@ -203,22 +204,24 @@ export function Header({ navLinks }: HeaderProps) {
|
||||
: link.url;
|
||||
|
||||
return (
|
||||
<Link
|
||||
<TransitionLink
|
||||
key={link.url}
|
||||
href={mappedUrl}
|
||||
className="text-2xl font-heading font-bold text-neutral-dark border-b border-neutral-100 pb-4"
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
>
|
||||
{link.label}
|
||||
</Link>
|
||||
</TransitionLink>
|
||||
);
|
||||
})}
|
||||
|
||||
<Link
|
||||
<TransitionLink
|
||||
href={`/${currentLocale}/${currentLocale === 'de' ? 'kontakt' : 'contact'}`}
|
||||
className="text-2xl font-heading font-bold text-primary border-b border-neutral-100 pb-4"
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
>
|
||||
{currentLocale === 'de' ? 'Kontakt' : 'Contact'}
|
||||
</Link>
|
||||
</TransitionLink>
|
||||
|
||||
<div className="mt-8 pt-6">
|
||||
<p className="text-text-secondary text-sm font-bold uppercase tracking-widest mb-4">Sprache wählen</p>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import Link from 'next/link';
|
||||
import { TransitionLink } from '@/components/ui/TransitionLink';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import { HoverShineOverlay } from '@/components/ui/HoverShineOverlay';
|
||||
|
||||
@@ -27,7 +27,7 @@ export function LanguageSwitcher({ mobile = false, isSolidMode = false }: Langua
|
||||
return (
|
||||
<div className="flex flex-col gap-3">
|
||||
{locales.map((loc) => (
|
||||
<Link
|
||||
<TransitionLink
|
||||
key={loc.code}
|
||||
href={getSwitchedUrl(loc.code)}
|
||||
className={`group relative overflow-hidden flex items-center gap-3 px-5 py-3 rounded-xl text-lg font-semibold transition-all duration-300 ${
|
||||
@@ -45,7 +45,7 @@ export function LanguageSwitcher({ mobile = false, isSolidMode = false }: Langua
|
||||
<polyline points="20 6 9 17 4 12" />
|
||||
</svg>
|
||||
)}
|
||||
</Link>
|
||||
</TransitionLink>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
@@ -73,7 +73,7 @@ export function LanguageSwitcher({ mobile = false, isSolidMode = false }: Langua
|
||||
}
|
||||
|
||||
return (
|
||||
<Link
|
||||
<TransitionLink
|
||||
key={loc.code}
|
||||
href={getSwitchedUrl(loc.code)}
|
||||
className={`relative z-10 flex items-center gap-1.5 px-3 py-1.5 rounded-full text-xs font-bold uppercase tracking-wider transition-all duration-300 ${linkClass}`}
|
||||
@@ -81,7 +81,7 @@ export function LanguageSwitcher({ mobile = false, isSolidMode = false }: Langua
|
||||
>
|
||||
<span className="text-sm" aria-hidden="true">{loc.flag}</span>
|
||||
<span>{loc.label}</span>
|
||||
</Link>
|
||||
</TransitionLink>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user