Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e83d3c0933 | |||
| f69d1977ad | |||
| 4f73ac109e | |||
| 535d6d0588 | |||
| c2ce09c106 | |||
| 265f93716e | |||
| 66fb4f3939 | |||
| 10f5dd9774 |
@@ -184,7 +184,6 @@ export default async function Layout(props: {
|
||||
data-scroll-behavior="smooth"
|
||||
>
|
||||
<head>
|
||||
<link rel="preconnect" href="https://img.infra.mintel.me" />
|
||||
<link rel="icon" href="/favicon.ico" sizes="any" />
|
||||
<link rel="apple-touch-icon" href="/apple-icon.png" sizes="180x180" />
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ export const runtime = 'nodejs';
|
||||
export default async function Image({ params }: { params: Promise<{ locale: string }> }) {
|
||||
const { locale } = await params;
|
||||
const t = await getTranslations({ locale, namespace: 'Index.meta' });
|
||||
|
||||
|
||||
const fonts = await getOgFonts();
|
||||
const bg = getOgBackground();
|
||||
const logo = getOgLogo();
|
||||
@@ -27,4 +27,4 @@ export default async function Image({ params }: { params: Promise<{ locale: stri
|
||||
fonts,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -28,9 +28,9 @@ const CustomLi = ({ children, ...props }: any) => {
|
||||
else if (lowerText.includes('vlf') || lowerText.includes('otdr')) Icon = Zap;
|
||||
|
||||
return (
|
||||
<li className="flex items-start gap-3 p-3 bg-neutral-50/50 border border-neutral-100 rounded-xl" {...props}>
|
||||
<Icon className="w-4 h-4 text-primary shrink-0 mt-[2px]" />
|
||||
<span className="text-sm font-medium text-neutral-700 leading-tight">{children}</span>
|
||||
<li className="flex items-start gap-3 pl-4 pr-6 py-3.5 bg-neutral-50/50 border border-neutral-100 rounded-xl" {...props}>
|
||||
<Icon className="w-5 h-5 text-primary shrink-0 mt-0.5" />
|
||||
<span className="text-sm font-medium text-neutral-700 leading-snug [&>p]:mb-0">{children}</span>
|
||||
</li>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -70,7 +70,7 @@ export function CompetenceBentoGrid(props: CompetenceBentoGridProps) {
|
||||
<h3 className="font-heading text-3xl md:text-5xl font-extrabold text-neutral-dark mb-4">{title}</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-4 gap-4 auto-rows-[220px]">
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-4 gap-4 auto-rows-[minmax(220px,auto)]">
|
||||
{/* Simplified static grid */}
|
||||
</div>
|
||||
</Container>
|
||||
@@ -88,7 +88,7 @@ export function CompetenceBentoGrid(props: CompetenceBentoGridProps) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-4 gap-4 auto-rows-[220px] px-4 md:px-0">
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-4 gap-4 auto-rows-[minmax(220px,auto)] px-4 md:px-0">
|
||||
{items.map((item, idx) => {
|
||||
const isLarge = item.size === 'large';
|
||||
const isMedium = item.size === 'medium';
|
||||
|
||||
@@ -30,7 +30,12 @@ export function HeroVideo(props: HeroVideoProps) {
|
||||
const videoUrl = explicitNoVideo ? null : (props.videoUrl || data?.videoUrl || '/assets/dummy-hero.mp4');
|
||||
const pathname = usePathname();
|
||||
|
||||
const posterSrc = props.backgroundImage?.url || props.posterImage?.url || data?.posterImage?.url || "/assets/photos/DJI_0048.JPG";
|
||||
let defaultPoster = "/assets/photos/DJI_0048.JPG";
|
||||
if (videoUrl && videoUrl.endsWith('.mp4')) {
|
||||
defaultPoster = videoUrl.replace('.mp4', '-poster.jpg');
|
||||
}
|
||||
|
||||
const posterSrc = props.backgroundImage?.url || props.posterImage?.url || data?.posterImage?.url || defaultPoster;
|
||||
const posterAlt = props.backgroundImage?.alt || data?.posterImage?.alt || "E-TIB Gruppe Baustelle";
|
||||
|
||||
const ctaLabel = props.ctaLabel || props.linkText || data?.ctaLabel || 'Unternehmen entdecken';
|
||||
|
||||
@@ -239,7 +239,7 @@ export function InteractiveGermanyMap({
|
||||
animate={{ opacity: 1, y: 0, scale: 1 }}
|
||||
exit={{ opacity: 0, y: 10, scale: 0.95 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
className="absolute z-[9999] pointer-events-auto bottom-[-60px] left-1/2 -translate-x-1/2 w-[calc(100vw-2rem)] max-w-[320px] md:w-max md:bottom-auto md:left-[var(--md-left)] md:top-[var(--md-top)] md:[transform:var(--md-transform)]"
|
||||
className="absolute z-[9999] pointer-events-auto bottom-[-60px] left-1/2 -translate-x-1/2 w-[calc(100vw_-_2rem)] max-w-[320px] md:w-max md:bottom-auto md:left-[var(--md-left)] md:top-[var(--md-top)] md:[transform:var(--md-transform)]"
|
||||
style={{
|
||||
'--md-left': `${activeLocation.x}%`,
|
||||
'--md-top': `${activeLocation.y}%`,
|
||||
|
||||
@@ -115,7 +115,7 @@ export function ReferencesSlider(props: ReferencesSliderProps) {
|
||||
onMouseLeave={onMouseLeave}
|
||||
onMouseUp={onMouseUp}
|
||||
onMouseMove={onMouseMove}
|
||||
className={`select-none flex gap-6 overflow-x-auto pb-8 pt-4 px-6 md:px-[max(2rem,calc((100vw-1280px)/2))] lg:px-[max(2.5rem,calc((100vw-1280px)/2))] [scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden ${isDragging ? 'cursor-grabbing snap-none' : 'cursor-grab snap-x snap-mandatory'}`}
|
||||
className={`select-none flex gap-6 overflow-x-auto pb-8 pt-4 px-6 md:px-[max(2rem,calc((100vw_-_1280px)_/_2))] lg:px-[max(2.5rem,calc((100vw_-_1280px)_/_2))] [scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden ${isDragging ? 'cursor-grabbing snap-none' : 'cursor-grab snap-x snap-mandatory'}`}
|
||||
>
|
||||
{references.map((ref, i) => {
|
||||
const imgSrc = ref.image
|
||||
|
||||
@@ -84,19 +84,19 @@ export function ScaleOfImpact() {
|
||||
{/* Static Data Grid (No jumping text) */}
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-y-4 gap-x-2 md:gap-12 w-full max-w-5xl mt-4 md:mt-12">
|
||||
<div className="flex flex-col items-center">
|
||||
<div className="font-mono text-3xl md:text-5xl font-black text-white tracking-tighter mb-2">200<span className="text-primary">+</span></div>
|
||||
<div className="font-mono text-3xl md:text-5xl font-black text-white tracking-tighter mb-2">200<span className="text-emerald-400">+</span></div>
|
||||
<div className="text-xs font-bold uppercase tracking-widest text-white/50">{locale === 'en' ? 'Projects' : 'Projekte'}</div>
|
||||
</div>
|
||||
<div className="flex flex-col items-center">
|
||||
<div className="font-mono text-3xl md:text-5xl font-black text-white tracking-tighter mb-2">974<span className="text-primary text-xl md:text-2xl ml-1">km</span></div>
|
||||
<div className="font-mono text-3xl md:text-5xl font-black text-white tracking-tighter mb-2">974<span className="text-emerald-400 text-xl md:text-2xl ml-1">km</span></div>
|
||||
<div className="text-xs font-bold uppercase tracking-widest text-white/50">{locale === 'en' ? 'Cable Laying' : 'Kabelverlegung'}</div>
|
||||
</div>
|
||||
<div className="flex flex-col items-center">
|
||||
<div className="font-mono text-3xl md:text-5xl font-black text-white tracking-tighter mb-2">300<span className="text-primary text-xl md:text-2xl ml-1">km</span></div>
|
||||
<div className="font-mono text-3xl md:text-5xl font-black text-white tracking-tighter mb-2">300<span className="text-emerald-400 text-xl md:text-2xl ml-1">km</span></div>
|
||||
<div className="text-xs font-bold uppercase tracking-widest text-white/50">{locale === 'en' ? 'Open Trenching' : 'Offener Tiefbau'}</div>
|
||||
</div>
|
||||
<div className="flex flex-col items-center">
|
||||
<div className="font-mono text-3xl md:text-5xl font-black text-white tracking-tighter mb-2">160<span className="text-primary text-xl md:text-2xl ml-1">km</span></div>
|
||||
<div className="font-mono text-3xl md:text-5xl font-black text-white tracking-tighter mb-2">160<span className="text-emerald-400 text-xl md:text-2xl ml-1">km</span></div>
|
||||
<div className="text-xs font-bold uppercase tracking-widest text-white/50">{locale === 'en' ? 'HDD Drilling' : 'Spülbohrung'}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -73,7 +73,7 @@ export function SubCompanyTiles(props: SubCompanyTilesProps) {
|
||||
|
||||
{(badge || title) && (
|
||||
<div className="text-center md:text-left max-w-3xl mx-auto md:mx-0 mb-16">
|
||||
{badge && <h2 className="text-primary font-bold tracking-wider uppercase text-sm mb-3">{badge}</h2>}
|
||||
{badge && <h2 className="text-emerald-400 font-bold tracking-wider uppercase text-sm mb-3">{badge}</h2>}
|
||||
{title && <h3 className="font-heading text-3xl md:text-5xl font-extrabold text-white">{title}</h3>}
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -94,7 +94,7 @@ export function MobileBottomNav({ navLinks, currentLocale }: MobileBottomNavProp
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="md:hidden fixed bottom-0 left-0 right-0 z-[9999] px-2 pb-[calc(env(safe-area-inset-bottom)+12px)] pt-4 pointer-events-none flex justify-center">
|
||||
<div className="md:hidden fixed bottom-0 left-0 right-0 z-[9999] px-2 pb-[calc(env(safe-area-inset-bottom)_+_12px)] pt-4 pointer-events-none flex justify-center">
|
||||
<nav className="flex justify-between items-center bg-white/75 backdrop-blur-2xl border border-white/60 shadow-[0_8px_32px_rgba(0,0,0,0.12)] rounded-3xl p-1.5 pointer-events-auto w-full max-w-[480px]">
|
||||
{items.map((item) => {
|
||||
const mappedUrl = item.url.startsWith('/') && !item.url.match(/^\/(en|de)/)
|
||||
@@ -129,7 +129,7 @@ export function MobileBottomNav({ navLinks, currentLocale }: MobileBottomNavProp
|
||||
{item.icon}
|
||||
</motion.div>
|
||||
<motion.span
|
||||
animate={{ opacity: isActive ? 1 : 0.7, y: isActive ? 0 : 2 }}
|
||||
animate={{ y: isActive ? 0 : 2 }}
|
||||
className="text-[9px] font-bold mt-1 tracking-wide"
|
||||
>
|
||||
{item.label}
|
||||
@@ -144,7 +144,7 @@ export function MobileBottomNav({ navLinks, currentLocale }: MobileBottomNavProp
|
||||
key={item.label}
|
||||
onClick={() => setIsFlyoutOpen(!isFlyoutOpen)}
|
||||
className={`relative flex flex-col items-center justify-center flex-1 h-[62px] transition-colors duration-300 select-none w-full focus:outline-none ${
|
||||
isActive ? 'text-primary' : 'text-neutral-500 hover:text-neutral-900'
|
||||
isActive ? 'text-primary' : 'text-neutral-600 hover:text-neutral-900'
|
||||
}`}
|
||||
style={{ WebkitTapHighlightColor: 'transparent', touchAction: 'manipulation' }}
|
||||
>
|
||||
@@ -159,7 +159,7 @@ export function MobileBottomNav({ navLinks, currentLocale }: MobileBottomNavProp
|
||||
href={mappedUrl}
|
||||
onClick={() => setIsFlyoutOpen(false)}
|
||||
className={`relative flex flex-col items-center justify-center flex-1 h-[62px] transition-colors duration-300 select-none ${
|
||||
isActive ? 'text-primary' : 'text-neutral-500 hover:text-neutral-900'
|
||||
isActive ? 'text-primary' : 'text-neutral-600 hover:text-neutral-900'
|
||||
}`}
|
||||
style={{ WebkitTapHighlightColor: 'transparent', touchAction: 'manipulation' }}
|
||||
>
|
||||
@@ -194,7 +194,7 @@ export function MobileBottomNav({ navLinks, currentLocale }: MobileBottomNavProp
|
||||
setIsFlyoutOpen(false);
|
||||
}
|
||||
}}
|
||||
className="fixed bottom-0 left-0 right-0 z-[9998] bg-white rounded-t-[32px] pt-4 pb-[calc(env(safe-area-inset-bottom)+7rem)] px-6 md:hidden shadow-[0_-20px_40px_rgba(0,0,0,0.1)] border-t border-neutral-100"
|
||||
className="fixed bottom-0 left-0 right-0 z-[9998] bg-white rounded-t-[32px] pt-4 pb-[calc(env(safe-area-inset-bottom)_+_7rem)] px-6 md:hidden shadow-[0_-20px_40px_rgba(0,0,0,0.1)] border-t border-neutral-100"
|
||||
>
|
||||
<div className="w-16 h-1.5 bg-neutral-200 rounded-full mx-auto mb-6 cursor-grab active:cursor-grabbing" />
|
||||
<h3 className="text-xs font-bold uppercase tracking-widest text-neutral-400 mb-4 px-2">{currentLocale === 'de' ? 'Über uns & Mehr' : 'About us & More'}</h3>
|
||||
|
||||
13155
lh-single.json
13155
lh-single.json
File diff suppressed because one or more lines are too long
@@ -15,6 +15,7 @@ const nextConfig = {
|
||||
pagesBufferLength: 2,
|
||||
},
|
||||
experimental: {
|
||||
optimizeCss: true,
|
||||
staleTimes: {
|
||||
dynamic: 0,
|
||||
static: 30,
|
||||
|
||||
@@ -138,7 +138,7 @@
|
||||
"prepare": "husky",
|
||||
"preinstall": "npx only-allow pnpm"
|
||||
},
|
||||
"version": "2.2.32",
|
||||
"version": "2.2.35",
|
||||
"pnpm": {
|
||||
"onlyBuiltDependencies": [
|
||||
"@parcel/watcher",
|
||||
|
||||
BIN
public/assets/videos/web/hero-bahnkreuzung-poster.jpg
Normal file
BIN
public/assets/videos/web/hero-bahnkreuzung-poster.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.5 KiB |
BIN
public/assets/videos/web/hero-bohrung-poster.jpg
Normal file
BIN
public/assets/videos/web/hero-bohrung-poster.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 152 KiB |
BIN
public/assets/videos/web/hero-kabelpflug-poster.jpg
Normal file
BIN
public/assets/videos/web/hero-kabelpflug-poster.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.5 KiB |
BIN
public/assets/videos/web/hero-messe-poster.jpg
Normal file
BIN
public/assets/videos/web/hero-messe-poster.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.5 KiB |
Reference in New Issue
Block a user