Compare commits
36 Commits
feature/ta
...
v2.2.13-rc
| Author | SHA1 | Date | |
|---|---|---|---|
| f766c9c9db | |||
| c851a4f95e | |||
| 1dca7f79fe | |||
| d3eee45112 | |||
| c308035e77 | |||
| 44d8c22c97 | |||
| 9d3f918aef | |||
| a34bee6272 | |||
| 373017059e | |||
| 309a53624e | |||
| e994d79895 | |||
| 88e88c8b99 | |||
| e2a29b41e9 | |||
| 62727a7231 | |||
| 3a6189e0d8 | |||
| 01e2fdbb7d | |||
| fa7182d351 | |||
| e0d43f7f5f | |||
| d09b576137 | |||
| 04599827f9 | |||
| 5368f1a64d | |||
| 241c97e346 | |||
| 3334e327bf | |||
| 145bff90b6 | |||
| d2bf48fc60 | |||
| 5e7ee84dc9 | |||
| b42e53495d | |||
| 8813ed3910 | |||
| 1d3c6a0f70 | |||
| 8fb3b96bd3 | |||
| 67dc56d3ee | |||
| e5933bad69 | |||
| 11b9e4630b | |||
| a47d378521 | |||
| 30047cb1c4 | |||
| 394ac5a19c |
@@ -17,9 +17,6 @@ env:
|
||||
PUPPETEER_SKIP_DOWNLOAD: "true"
|
||||
COREPACK_NPM_REGISTRY: "https://registry.npmmirror.com"
|
||||
|
||||
concurrency:
|
||||
group: deploy-pipeline
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
# ──────────────────────────────────────────────────────────────────────────────
|
||||
@@ -146,6 +143,13 @@ jobs:
|
||||
echo "short_sha=$SHORT_SHA"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: 🚦 Priority Gate
|
||||
env:
|
||||
GITEA_PAT: ${{ secrets.GITEA_PAT }}
|
||||
CURRENT_RUN_ID: ${{ github.run_id }}
|
||||
CURRENT_TARGET: ${{ steps.determine.outputs.target }}
|
||||
run: bash scripts/priority-gate.sh
|
||||
|
||||
# ──────────────────────────────────────────────────────────────────────────────
|
||||
# JOB 2: QA (Lint, Typecheck, Test)
|
||||
# ──────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
25
INSTRUCTIONS.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Antigravity Instructions & Project Rules
|
||||
|
||||
This document contains critical project-specific rules for the e-tib.com codebase. Antigravity must read and follow these rules at all times.
|
||||
|
||||
## 1. Bilingual Site (German & English) - STRICT
|
||||
- **Always update BOTH languages!** The website is bilingual.
|
||||
- When changing content, adding pages, or updating text, you MUST always check and update both `content/de/` and `content/en/` simultaneously.
|
||||
- When adding new components with text, ensure they are built to support both languages or update the respective translation files/mechanisms. Do NOT just hardcode German text and forget the English version.
|
||||
|
||||
## 2. No Dummy Data / No Hallucinations
|
||||
- Do not invent or hallucinate placeholder text (e.g., "Nachweis liegt vor" for certificates that don't exist).
|
||||
- Only implement what is explicitly requested or what matches provided assets/data.
|
||||
- If data is missing, ask the user instead of inventing placeholders.
|
||||
|
||||
## 3. Git Workflow & RC Tagging
|
||||
- When instructed to "commit and tag" (or similar), always follow this process:
|
||||
1. Add and commit the changes with conventional commits (`feat:`, `fix:`, `chore:`, etc.).
|
||||
2. Check the latest tag using `git describe --tags --abbrev=0`.
|
||||
3. Increment the RC (Release Candidate) number of the current version (e.g., if latest is `v2.2.13-rc19`, the new tag is `v2.2.13-rc20`).
|
||||
4. Create the tag: `git tag vX.Y.Z-rcN`.
|
||||
5. Push the commit and the tag: `git push origin main --tags`.
|
||||
|
||||
## 4. Work Exclusively on the Correct Branch
|
||||
- Follow the `USER_GLOBAL` directive: If on `main`, create a branch unless explicitly told to work on `main`.
|
||||
- For e-tib.com, often small fixes are done on `main` if the user commands it ("auf main arbeiten"), but always verify context.
|
||||
@@ -17,7 +17,6 @@ import { CompetenceBentoGrid as HomeCompetenceBentoGrid } from '@/components/blo
|
||||
import { ReferencesSlider as HomeReferencesSlider } from '@/components/blocks/ReferencesSlider';
|
||||
import { CompanyTimeline } from '@/components/blocks/CompanyTimeline';
|
||||
import { JobListingBlock } from '@/components/blocks/JobListingBlock';
|
||||
import { CallToAction } from '@/components/blocks/CallToAction';
|
||||
import { ServiceDetailGrid } from '@/components/blocks/ServiceDetailGrid';
|
||||
import { BenefitGrid } from '@/components/blocks/BenefitGrid';
|
||||
import { InteractiveGermanyMap } from '@/components/blocks/InteractiveGermanyMap';
|
||||
@@ -40,7 +39,6 @@ const mdxComponents = {
|
||||
HomeReferencesSlider,
|
||||
CompanyTimeline,
|
||||
JobListingBlock,
|
||||
CallToAction,
|
||||
ServiceDetailGrid,
|
||||
BenefitGrid,
|
||||
InteractiveGermanyMap,
|
||||
@@ -50,6 +48,7 @@ const mdxComponents = {
|
||||
TeamGrid,
|
||||
JsonLd,
|
||||
Button,
|
||||
Badge,
|
||||
AnimatedCounter,
|
||||
GrowthChart,
|
||||
DeepDrillAnimation,
|
||||
@@ -186,7 +185,7 @@ export default async function Page(props: { params: Promise<{ locale: string; sl
|
||||
<div className={`flex flex-col min-h-screen ${isFullBleed ? '' : 'bg-white'}`}>
|
||||
{/* Generic Hero Section (only for standard pages) */}
|
||||
{!isFullBleed && (
|
||||
<section className="bg-primary-dark text-white pt-40 pb-12 md:pt-56 md:pb-16 min-h-[40vh] md:min-h-[45vh] flex flex-col justify-end relative overflow-hidden">
|
||||
<section key={`hero-section-${slug}`} className="bg-primary-dark text-white pt-40 pb-12 md:pt-56 md:pb-16 min-h-[40vh] md:min-h-[45vh] flex flex-col justify-end relative overflow-hidden">
|
||||
<div className="absolute inset-0 opacity-20 pointer-events-none">
|
||||
<div className="absolute top-0 left-0 w-full h-full bg-[radial-gradient(circle_at_center,_var(--tw-gradient-stops))] from-accent/50 via-transparent to-transparent" />
|
||||
</div>
|
||||
|
||||
@@ -19,7 +19,6 @@ import { TransitionProvider } from '@/components/providers/TransitionProvider';
|
||||
import { PageTransitionShutter } from '@/components/providers/PageTransitionShutter';
|
||||
import { InitialLoader } from '@/components/providers/InitialLoader';
|
||||
import { CorporateBackground } from '@/components/decorations/CorporateBackground';
|
||||
|
||||
const inter = Inter({
|
||||
subsets: ['latin'],
|
||||
display: 'swap',
|
||||
|
||||
@@ -79,6 +79,10 @@ export default async function ReferenzenOverview(props: { params: Promise<{ loca
|
||||
title={locale === 'en' ? 'Successfully realized projects.' : 'Erfolgreich umgesetzte Projekte.'}
|
||||
description={locale === 'en' ? 'From broadband expansion to complex 110kV lines: A selection of our nationwide projects where we have created infrastructure for the future.' : 'Vom Breitbandausbau bis zur komplexen 110kV-Trasse: Ein Auszug unserer bundesweiten Projekte, bei denen wir Infrastruktur für die Zukunft geschaffen haben.'}
|
||||
locations={enrichedLocations}
|
||||
stats={[
|
||||
{ value: '100', suffix: '%', label: locale === 'en' ? 'Nationwide Reach' : 'Überregionale Reichweite' },
|
||||
{ value: enrichedLocations.length.toString(), suffix: '+', label: locale === 'en' ? 'Completed Projects' : 'Abgeschlossene Projekte' }
|
||||
]}
|
||||
/>
|
||||
|
||||
{/* Main Content Area */}
|
||||
|
||||
@@ -65,7 +65,7 @@ export default async function StandortDetail(props: { params: Promise<{ locale:
|
||||
return (
|
||||
<div className="flex flex-col min-h-screen bg-white">
|
||||
{/* Generic Hero Section to match standard pages */}
|
||||
<section className="bg-primary-dark text-white pt-40 pb-12 md:pt-56 md:pb-16 min-h-[40vh] md:min-h-[45vh] flex flex-col justify-end relative overflow-hidden">
|
||||
<section key={`standort-hero-${slug}`} className="bg-primary-dark text-white pt-40 pb-12 md:pt-56 md:pb-16 min-h-[40vh] md:min-h-[45vh] flex flex-col justify-end relative overflow-hidden">
|
||||
<div className="absolute inset-0 opacity-20 pointer-events-none">
|
||||
<div className="absolute top-0 left-0 w-full h-full bg-[radial-gradient(circle_at_center,_var(--tw-gradient-stops))] from-accent/50 via-transparent to-transparent" />
|
||||
</div>
|
||||
|
||||
@@ -10,11 +10,13 @@
|
||||
}
|
||||
|
||||
.hide-scrollbar {
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
-ms-overflow-style: none !important; /* IE and Edge */
|
||||
scrollbar-width: none !important; /* Firefox */
|
||||
}
|
||||
.hide-scrollbar::-webkit-scrollbar {
|
||||
display: none; /* Chrome, Safari and Opera */
|
||||
display: none !important; /* Chrome, Safari and Opera */
|
||||
width: 0 !important;
|
||||
height: 0 !important;
|
||||
}
|
||||
|
||||
@keyframes bg-pulse-15 {
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import { Button } from '@/components/ui/Button';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useTranslations } from 'next-intl';
|
||||
|
||||
export interface CallToActionProps {
|
||||
title?: string;
|
||||
description?: string;
|
||||
text?: string; // Alias for description
|
||||
ctaLabel?: string;
|
||||
buttonText?: string; // Alias for ctaLabel
|
||||
ctaHref?: string;
|
||||
buttonLink?: string; // Alias for ctaHref
|
||||
theme?: 'light' | 'dark';
|
||||
}
|
||||
|
||||
const containerVariants = {
|
||||
hidden: { opacity: 0 },
|
||||
visible: {
|
||||
opacity: 1,
|
||||
transition: {
|
||||
staggerChildren: 0.15,
|
||||
delayChildren: 0.1,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const itemVariants = {
|
||||
hidden: { opacity: 0, y: 20 },
|
||||
visible: {
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
transition: { duration: 0.8, ease: [0.16, 1, 0.3, 1] as const },
|
||||
},
|
||||
};
|
||||
|
||||
export const CallToAction: React.FC<CallToActionProps> = (props) => {
|
||||
const { theme = 'light' } = props;
|
||||
const isDark = theme === 'dark';
|
||||
const t = useTranslations('CallToAction');
|
||||
|
||||
const title = props.title || t('title');
|
||||
const description = props.description || props.text || t('description');
|
||||
const ctaLabel = props.ctaLabel || props.buttonText || t('ctaLabel');
|
||||
const ctaHref = props.ctaHref || props.buttonLink || t('ctaHref');
|
||||
|
||||
return (
|
||||
<div className={`py-24 text-center ${isDark ? 'bg-primary-dark text-white' : 'bg-neutral-50 border-t border-neutral-100'}`}>
|
||||
<motion.div
|
||||
className="container max-w-3xl mx-auto px-4"
|
||||
variants={containerVariants}
|
||||
initial="hidden"
|
||||
whileInView="visible"
|
||||
viewport={{ once: true, margin: "-100px" }}
|
||||
>
|
||||
<motion.h2 variants={itemVariants} className={`font-heading text-4xl font-extrabold mb-6 ${isDark ? 'text-white' : 'text-neutral-dark'}`}>
|
||||
{title}
|
||||
</motion.h2>
|
||||
<motion.p variants={itemVariants} className={`text-xl mb-10 leading-relaxed ${isDark ? 'text-white/70' : 'text-text-secondary'}`}>
|
||||
{description}
|
||||
</motion.p>
|
||||
<motion.div variants={itemVariants}>
|
||||
<Button
|
||||
href={ctaHref}
|
||||
size="xl"
|
||||
variant={isDark ? 'white' : 'primary'}
|
||||
>
|
||||
{ctaLabel}
|
||||
</Button>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -68,31 +68,7 @@ const defaultCertificates: Certificate[] = [
|
||||
type: 'tax',
|
||||
date: '13.02.2025',
|
||||
},
|
||||
{
|
||||
title: 'Unbedenklichkeit IHK',
|
||||
description: 'Industrie- und Handelskammer',
|
||||
type: 'general',
|
||||
},
|
||||
{
|
||||
title: 'Unbedenklichkeit HWK',
|
||||
description: 'Handwerkskammer',
|
||||
type: 'general',
|
||||
},
|
||||
{
|
||||
title: 'Handelsregisterauszug',
|
||||
description: 'Amtsgericht Cottbus',
|
||||
type: 'general',
|
||||
},
|
||||
{
|
||||
title: 'Gewerbe-Anmeldung',
|
||||
description: 'Stadt Guben',
|
||||
type: 'general',
|
||||
},
|
||||
{
|
||||
title: 'Gewerbezentralregister',
|
||||
description: 'Auskunft aus dem Register',
|
||||
type: 'general',
|
||||
},
|
||||
|
||||
];
|
||||
|
||||
export function CertificatesBlock({ badge, title, description, certificates = defaultCertificates, hideHeader = false }: CertificatesBlockProps) {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import React from 'react';
|
||||
import Image from 'next/image';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import { motion } from 'framer-motion';
|
||||
import { Badge, Container, Heading } from '@/components/ui';
|
||||
import { Button } from '@/components/ui/Button';
|
||||
@@ -39,13 +40,15 @@ const itemVariants = {
|
||||
export const HeroSection: React.FC<HeroSectionProps> = (props) => {
|
||||
const { title, badge, subtitle, backgroundImage, alignment, ctaLabel, ctaHref } = props;
|
||||
const bgSrc = backgroundImage?.sizes?.card?.url || backgroundImage?.url;
|
||||
const pathname = usePathname();
|
||||
|
||||
return (
|
||||
<section
|
||||
className={`relative min-h-[45vh] md:min-h-[55vh] flex items-center pt-32 pb-20 md:pt-36 md:pb-24 overflow-hidden bg-neutral-dark ${alignment === 'center' ? 'justify-center text-center' : ''}`}
|
||||
className={`relative min-h-[45vh] md:min-h-[55vh] flex items-center pt-24 pb-16 md:pt-36 md:pb-24 overflow-hidden bg-neutral-dark ${alignment === 'center' ? 'justify-center text-center' : ''}`}
|
||||
>
|
||||
{bgSrc && (
|
||||
<motion.div
|
||||
key={`hero-bg-${pathname}`}
|
||||
className="absolute inset-0 z-0"
|
||||
initial={{ scale: 1.05, opacity: 0 }}
|
||||
animate={{ scale: 1, opacity: 1 }}
|
||||
@@ -75,6 +78,7 @@ export const HeroSection: React.FC<HeroSectionProps> = (props) => {
|
||||
)}
|
||||
<Container className={`relative z-10 ${alignment === 'center' ? 'max-w-5xl' : ''}`}>
|
||||
<motion.div
|
||||
key={`hero-content-${pathname}`}
|
||||
className={`max-w-4xl ${alignment === 'center' ? 'mx-auto' : ''}`}
|
||||
variants={containerVariants}
|
||||
initial="hidden"
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Button } from '@/components/ui/Button';
|
||||
import Image from 'next/image';
|
||||
import { motion, AnimatePresence } from 'framer-motion';
|
||||
import { useState, useEffect } from 'react';
|
||||
import { usePathname } from 'next/navigation';
|
||||
|
||||
interface HeroVideoProps {
|
||||
data?: any;
|
||||
@@ -28,6 +29,7 @@ export function HeroVideo(props: HeroVideoProps) {
|
||||
const subtitle = props.subtitle || props.description || data?.subtitle || 'Wir verbinden Infrastruktur mit Präzision. Von Horizontalbohrungen bis zu komplexen Leitungsnetzen.';
|
||||
const explicitNoVideo = props.videoUrl === 'none' || props.videoUrl === '';
|
||||
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";
|
||||
const posterAlt = props.backgroundImage?.alt || data?.posterImage?.alt || "E-TIB Gruppe Baustelle";
|
||||
@@ -35,19 +37,10 @@ export function HeroVideo(props: HeroVideoProps) {
|
||||
const ctaLabel = props.ctaLabel || props.linkText || data?.ctaLabel || 'Unternehmen entdecken';
|
||||
const ctaHref = props.ctaHref || props.linkHref || data?.ctaHref || '#unternehmen';
|
||||
|
||||
let currentLocale = 'de';
|
||||
try {
|
||||
// We can't unconditionally call hooks if they might fail outside context, but HeroVideo is usually in context.
|
||||
// However, to be safe and avoid adding new imports, we can use window.location or default to 'de' if not available.
|
||||
if (typeof window !== 'undefined') {
|
||||
currentLocale = window.location.pathname.startsWith('/en') ? 'en' : 'de';
|
||||
}
|
||||
} catch (e) {
|
||||
// Fallback to default locale if window/location access fails
|
||||
}
|
||||
const currentLocale = pathname?.startsWith('/en') ? 'en' : 'de';
|
||||
|
||||
const secondaryCtaLabel = props.secondaryCtaLabel || data?.secondaryCtaLabel || (currentLocale === 'de' ? 'Projekt anfragen' : 'Inquire Project');
|
||||
const secondaryCtaHref = props.secondaryCtaHref || data?.secondaryCtaHref || `/${currentLocale}/${currentLocale === 'de' ? 'contact' : 'contact'}`;
|
||||
const secondaryCtaHref = props.secondaryCtaHref || data?.secondaryCtaHref || `/${currentLocale}/contact`;
|
||||
|
||||
return (
|
||||
<div className="relative w-full h-[100svh] flex items-center justify-center overflow-hidden bg-neutral-dark">
|
||||
@@ -56,7 +49,7 @@ export function HeroVideo(props: HeroVideoProps) {
|
||||
|
||||
{videoUrl ? (
|
||||
<video
|
||||
key={videoUrl}
|
||||
key={`${pathname}-${videoUrl}`}
|
||||
className="absolute inset-0 w-full h-full object-cover z-1 pointer-events-none filter contrast-125 saturate-110 brightness-90"
|
||||
src={videoUrl}
|
||||
autoPlay
|
||||
@@ -67,6 +60,7 @@ export function HeroVideo(props: HeroVideoProps) {
|
||||
/>
|
||||
) : (
|
||||
<Image
|
||||
key={`img-${pathname}-${posterSrc}`}
|
||||
src={posterSrc}
|
||||
alt={posterAlt}
|
||||
fill
|
||||
@@ -88,13 +82,14 @@ export function HeroVideo(props: HeroVideoProps) {
|
||||
|
||||
<div className="container relative z-[4] text-center px-4">
|
||||
<motion.div
|
||||
key={`hero-content-${pathname}`}
|
||||
initial={{ opacity: 0, y: 40 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 1.2, ease: [0.16, 1, 0.3, 1] }}
|
||||
>
|
||||
<h1
|
||||
className="font-heading font-bold text-4xl md:text-6xl lg:text-8xl text-white mb-6 uppercase tracking-tight drop-shadow-lg"
|
||||
dangerouslySetInnerHTML={{ __html: title.replace('KABELTIEFBAU', '<span class="text-primary-light">KABELTIEFBAU</span>').replace(/\\n|\n/g, '<br />') }}
|
||||
dangerouslySetInnerHTML={{ __html: title.replace(/KABELTIEFBAU|Kabeltiefbau/g, '<span class="text-primary-light">Kabeltiefbau</span>').replace(/KABELNETZBAU|Kabelnetzbau/g, '<span class="text-primary-light">Kabelnetzbau</span>').replace(/\\n|\n/g, '<br />') }}
|
||||
/>
|
||||
|
||||
<p className="text-lg md:text-xl lg:text-2xl text-white/90 max-w-3xl mx-auto mb-12 drop-shadow">
|
||||
|
||||
@@ -4,7 +4,7 @@ import React, { useState } from 'react';
|
||||
import { motion, AnimatePresence } from 'framer-motion';
|
||||
import { MapPin, Factory, Zap, CheckCircle2, ArrowUpRight } from 'lucide-react';
|
||||
import Image from 'next/image';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useRouter, usePathname } from 'next/navigation';
|
||||
import Link from 'next/link';
|
||||
import { AnimatedGlossyBorder } from '@/components/ui/AnimatedGlossyBorder';
|
||||
import { Location, defaultLocations, minorLocations, projectLocations } from '@/lib/map-data';
|
||||
@@ -25,6 +25,7 @@ interface InteractiveGermanyMapProps {
|
||||
stats?: Stat[];
|
||||
locations?: Location[];
|
||||
isHero?: boolean;
|
||||
hideStandorte?: boolean;
|
||||
}
|
||||
|
||||
export function InteractiveGermanyMap({
|
||||
@@ -33,10 +34,12 @@ export function InteractiveGermanyMap({
|
||||
description,
|
||||
stats,
|
||||
locations = projectLocations,
|
||||
isHero = false
|
||||
isHero = false,
|
||||
hideStandorte = false
|
||||
}: InteractiveGermanyMapProps) {
|
||||
const [activeLocation, setActiveLocation] = useState<Location | null>(null);
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
const locale = useLocale();
|
||||
const t = useTranslations('InteractiveGermanyMap');
|
||||
const tStandard = useTranslations('StandardPage');
|
||||
@@ -51,13 +54,21 @@ export function InteractiveGermanyMap({
|
||||
const finalTitle = title || (locale === 'en' ? <>Nationwide<br/>in operation for you.</> : <>Deutschlandweit<br/>für Sie im Einsatz.</>);
|
||||
const finalDescription = description || (locale === 'en' ? 'From our strategic locations in Guben, Kirchheilingen and Bülstedt, we control and implement complex infrastructure projects nationwide.' : 'Von unseren strategischen Standorten in Guben, Kirchheilingen und Bülstedt steuern und realisieren wir komplexe Infrastrukturprojekte im gesamten Bundesgebiet.');
|
||||
|
||||
const hq = locations.find((l) => l.type === 'hq');
|
||||
const branch = locations.find((l) => l.type === 'branch');
|
||||
const projects = locations.filter((l) => l.type === 'project');
|
||||
const minorNodes = locations.filter((l) => l.type === 'minor_node');
|
||||
const finalLocations = React.useMemo(() => {
|
||||
if (hideStandorte) return locations;
|
||||
|
||||
// Ensure the 3 standorte are always included, without duplicating if already present by ID
|
||||
const base = [...locations];
|
||||
standorteLocations.forEach(sl => {
|
||||
if (!base.some(l => l.id === sl.id)) {
|
||||
base.push(sl as Location);
|
||||
}
|
||||
});
|
||||
return base;
|
||||
}, [locations, hideStandorte]);
|
||||
|
||||
return (
|
||||
<div className={isHero ? "relative w-full" : "relative w-full max-w-7xl mx-auto py-16 md:py-24 px-4 sm:px-6 mt-16 md:mt-20"}>
|
||||
<div key={isHero ? `hero-map-${pathname}` : undefined} className={isHero ? "relative w-full" : "relative w-full max-w-7xl mx-auto py-16 md:py-24 px-4 sm:px-6 mt-16 md:mt-20"}>
|
||||
<div className={`bg-[#050B14] ${isHero ? 'pt-32 pb-16 md:pt-40 md:pb-24' : 'rounded-[2.5rem] md:rounded-[3.5rem] shadow-2xl border border-white/5'} overflow-visible relative group/map`}>
|
||||
{/* Animated Border Glow */}
|
||||
{!isHero && <AnimatedGlossyBorder opacity={0.7} className="z-30" />}
|
||||
@@ -137,7 +148,7 @@ export function InteractiveGermanyMap({
|
||||
</div>
|
||||
|
||||
{/* Minor Location Markers (The 100+ generic projects) */}
|
||||
{locations.filter(l => l.type === 'minor_node').map((loc, idx) => (
|
||||
{finalLocations.filter(l => l.type === 'minor_node').map((loc, idx) => (
|
||||
<div
|
||||
key={`minor-${idx}`}
|
||||
className="absolute z-10 group/minor cursor-pointer w-10 h-10 flex items-center justify-center"
|
||||
@@ -154,8 +165,8 @@ export function InteractiveGermanyMap({
|
||||
</div>
|
||||
))}
|
||||
|
||||
{/* Major & Reference Location Markers (HQ, Branch, Project) */}
|
||||
{locations.filter(l => l.type !== 'minor_node').map((loc, idx) => {
|
||||
{/* Major Location Markers (HQ, Branch, Project) */}
|
||||
{finalLocations.filter(l => l.type !== 'minor_node').map((loc, idx) => {
|
||||
const isHQ = loc.type === 'hq';
|
||||
const isBranch = loc.type === 'branch';
|
||||
const isActive = activeLocation?.id === loc.id;
|
||||
@@ -272,7 +283,7 @@ export function InteractiveGermanyMap({
|
||||
</ul>
|
||||
)}
|
||||
|
||||
{activeLocation.href && (
|
||||
{activeLocation.href && (activeLocation.type === 'hq' || activeLocation.type === 'branch') && (
|
||||
<div className="inline-flex items-center text-xs font-bold text-primary">
|
||||
{t('learnMore')}
|
||||
<ArrowUpRight className="w-3.5 h-3.5 ml-1" />
|
||||
|
||||
@@ -133,14 +133,17 @@ export function ReferencesSlider(props: ReferencesSliderProps) {
|
||||
<Link
|
||||
href={`/${locale}/referenzen/${ref.slug}`}
|
||||
data-testid="reference-tile"
|
||||
draggable={false}
|
||||
onClick={(e) => {
|
||||
if (dragDistanceRef.current > 15) {
|
||||
e.preventDefault();
|
||||
}
|
||||
dragDistanceRef.current = 0;
|
||||
}}
|
||||
className="block relative aspect-[16/10] bg-neutral-800 rounded-2xl overflow-hidden mb-5 border border-white/5 shadow-2xl"
|
||||
className="block relative select-none aspect-[16/10] bg-neutral-800 rounded-2xl overflow-hidden mb-5 border border-white/5 shadow-2xl"
|
||||
>
|
||||
<Image
|
||||
draggable={false}
|
||||
src={imgSrc}
|
||||
alt={ref.title}
|
||||
fill
|
||||
|
||||
@@ -46,7 +46,7 @@ export function ScaleOfImpact() {
|
||||
)}
|
||||
</h2>
|
||||
|
||||
<p className="text-white/60 text-lg md:text-xl max-w-2xl font-medium mb-16">
|
||||
<p className="text-white/60 text-lg md:text-xl max-w-2xl font-medium mb-8 md:mb-16">
|
||||
{locale === 'en'
|
||||
? "We don't just talk about the energy transition. We build it. In the last 36 months alone, we have completed a route that stretches from our headquarters in Guben all the way to Munich."
|
||||
: "Wir sprechen nicht nur über die Energiewende. Wir bauen sie. Allein in den letzten 36 Monaten haben wir eine Strecke realisiert, die von unserem Hauptsitz in Guben bis nach München reicht."
|
||||
@@ -54,7 +54,7 @@ export function ScaleOfImpact() {
|
||||
</p>
|
||||
|
||||
{/* Abstract SVG Line Animation */}
|
||||
<div className="w-full max-w-4xl h-32 relative">
|
||||
<div className="w-full max-w-4xl h-20 md:h-32 relative">
|
||||
<svg
|
||||
width="100%"
|
||||
height="100%"
|
||||
@@ -82,21 +82,21 @@ export function ScaleOfImpact() {
|
||||
</div>
|
||||
|
||||
{/* Static Data Grid (No jumping text) */}
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-8 md:gap-12 w-full max-w-5xl mt-12">
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-y-8 gap-x-2 md:gap-12 w-full max-w-5xl mt-8 md:mt-12">
|
||||
<div className="flex flex-col items-center">
|
||||
<div className="font-mono text-4xl md:text-5xl font-black text-white tracking-tighter mb-2">200<span className="text-primary">+</span></div>
|
||||
<div className="font-mono text-4xl md:text-5xl font-black text-white tracking-tighter mb-2">200 <span className="text-primary">+</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-4xl md:text-5xl font-black text-white tracking-tighter mb-2">974<span className="text-primary text-2xl">km</span></div>
|
||||
<div className="font-mono text-4xl md:text-5xl font-black text-white tracking-tighter mb-2">974 <span className="text-primary text-2xl">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-4xl md:text-5xl font-black text-white tracking-tighter mb-2">300<span className="text-primary text-2xl">km</span></div>
|
||||
<div className="font-mono text-4xl md:text-5xl font-black text-white tracking-tighter mb-2">300 <span className="text-primary text-2xl">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-4xl md:text-5xl font-black text-white tracking-tighter mb-2">160<span className="text-primary text-2xl">km</span></div>
|
||||
<div className="font-mono text-4xl md:text-5xl font-black text-white tracking-tighter mb-2">160 <span className="text-primary text-2xl">km</span></div>
|
||||
<div className="text-xs font-bold uppercase tracking-widest text-white/50">{locale === 'en' ? 'HDD Drilling' : 'Spülbohrung'}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -79,7 +79,7 @@ export function SubCompanyTiles(props: SubCompanyTilesProps) {
|
||||
)}
|
||||
|
||||
<motion.div
|
||||
className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6"
|
||||
className="flex overflow-x-auto md:overflow-visible snap-x snap-mandatory pb-6 md:pb-0 md:grid md:grid-cols-2 lg:grid-cols-4 gap-4 md:gap-6 hide-scrollbar -mx-4 px-4 md:mx-0 md:px-0"
|
||||
variants={containerVariants}
|
||||
initial="hidden"
|
||||
whileInView="visible"
|
||||
@@ -172,7 +172,7 @@ export function SubCompanyTiles(props: SubCompanyTilesProps) {
|
||||
{/* LOGO RENDERING */}
|
||||
{isEtib ? (
|
||||
<div className="flex flex-col items-center">
|
||||
<div className="relative w-48 h-14 mb-2">
|
||||
<div className="relative w-32 md:w-40 lg:w-44 h-10 md:h-12 lg:h-14 mb-2 max-w-[85%]">
|
||||
<Image
|
||||
src="/assets/logo-white.png"
|
||||
alt="E-TIB Logo"
|
||||
@@ -181,17 +181,17 @@ export function SubCompanyTiles(props: SubCompanyTilesProps) {
|
||||
/>
|
||||
</div>
|
||||
{isIng && (
|
||||
<div className="text-white/80 tracking-[0.2em] text-[10px] sm:text-xs font-semibold uppercase mt-1 text-center">
|
||||
<div className="text-white/80 tracking-[0.15em] sm:tracking-[0.2em] text-[9px] sm:text-[10px] lg:text-[11px] font-semibold uppercase mt-1 text-center">
|
||||
Ingenieurgesellschaft
|
||||
</div>
|
||||
)}
|
||||
{isVerwaltung && (
|
||||
<div className="text-white/80 tracking-[0.2em] text-[10px] sm:text-xs font-semibold uppercase mt-1 text-center">
|
||||
<div className="text-white/80 tracking-[0.15em] sm:tracking-[0.2em] text-[9px] sm:text-[10px] lg:text-[11px] font-semibold uppercase mt-1 text-center">
|
||||
Verwaltung GmbH
|
||||
</div>
|
||||
)}
|
||||
{isBohrtechnik && (
|
||||
<div className="text-white/80 tracking-[0.2em] text-[10px] sm:text-xs font-semibold uppercase mt-1 text-center">
|
||||
<div className="text-white/80 tracking-[0.15em] sm:tracking-[0.2em] text-[9px] sm:text-[10px] lg:text-[11px] font-semibold uppercase mt-1 text-center">
|
||||
Bohrtechnik GmbH
|
||||
</div>
|
||||
)}
|
||||
@@ -236,7 +236,7 @@ export function SubCompanyTiles(props: SubCompanyTilesProps) {
|
||||
<motion.div
|
||||
key={index}
|
||||
variants={itemVariants}
|
||||
className="h-full"
|
||||
className="h-full flex-shrink-0 snap-center w-[85%] sm:w-[70%] md:w-full"
|
||||
>
|
||||
{hasUrl ? (
|
||||
isExternal ? (
|
||||
|
||||
@@ -78,7 +78,7 @@ export function CorporateBackground() {
|
||||
const y5 = useTransform(scrollYProgress, [0, 1], [0, -500]);
|
||||
|
||||
return (
|
||||
<div className="absolute inset-0 z-[50] overflow-hidden pointer-events-none" aria-hidden="true">
|
||||
<div className="absolute inset-0 z-[50] overflow-hidden pointer-events-none hidden md:block" aria-hidden="true">
|
||||
{/* 1. Top Right - Medium, rotating moderately */}
|
||||
<motion.div
|
||||
style={{
|
||||
|
||||
41
components/decorations/EUFundingBadge.tsx
Normal file
@@ -0,0 +1,41 @@
|
||||
'use client';
|
||||
|
||||
import { motion } from 'framer-motion';
|
||||
import Image from 'next/image';
|
||||
|
||||
export function EUFundingBadge() {
|
||||
return (
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 1.5, ease: [0.16, 1, 0.3, 1] }}
|
||||
className="absolute top-0 right-0 w-[260px] md:w-[380px] h-[260px] md:h-[380px] z-0 pointer-events-none select-none overflow-hidden"
|
||||
style={{
|
||||
// Perfekter weicher Fade, der sicherstellt, dass harte Kanten komplett unsichtbar werden
|
||||
maskImage: 'radial-gradient(100% 100% at top right, black 10%, rgba(0,0,0,0.8) 30%, transparent 70%)',
|
||||
WebkitMaskImage: 'radial-gradient(100% 100% at top right, black 10%, rgba(0,0,0,0.8) 30%, transparent 70%)',
|
||||
}}
|
||||
>
|
||||
{/* Background Flag */}
|
||||
<div className="absolute inset-0 w-full h-full opacity-95">
|
||||
<Image
|
||||
src="/assets/eu-flag.webp"
|
||||
alt="European Union Background"
|
||||
fill
|
||||
className="object-cover object-top"
|
||||
priority
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Text overlaid on the flag */}
|
||||
<div className="absolute top-0 right-0 p-5 md:p-8 flex flex-col items-end text-right z-10 drop-shadow-[0_2px_8px_rgba(0,0,0,0.9)]">
|
||||
<span className="block text-[9px] md:text-[11px] font-bold text-white/90 tracking-wide leading-snug drop-shadow-md">
|
||||
Kofinanziert von der
|
||||
</span>
|
||||
<span className="block text-[11px] md:text-[13px] font-extrabold text-white tracking-wider leading-snug uppercase drop-shadow-md">
|
||||
Europäischen Union
|
||||
</span>
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import { useAnalytics } from '../analytics/useAnalytics';
|
||||
import { AnalyticsEvents } from '../analytics/analytics-events';
|
||||
import { useState, useEffect, useRef, useCallback } from 'react';
|
||||
import { ChevronRight } from 'lucide-react';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import { AISearchResults } from '../search/AISearchResults';
|
||||
const HeroIllustration = dynamic(() => import('./HeroIllustration'), { ssr: false });
|
||||
const AIOrb = dynamic(() => import('../search/AIOrb'), { ssr: false });
|
||||
@@ -15,6 +16,7 @@ const AIOrb = dynamic(() => import('../search/AIOrb'), { ssr: false });
|
||||
export default function Hero({ data }: { data?: any }) {
|
||||
const t = useTranslations('Home.hero');
|
||||
const locale = useLocale();
|
||||
const pathname = usePathname();
|
||||
const { trackEvent } = useAnalytics();
|
||||
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
@@ -85,7 +87,7 @@ export default function Hero({ data }: { data?: any }) {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Section className="relative min-h-[85vh] md:h-[90vh] flex flex-col items-center justify-center overflow-hidden bg-primary py-12 md:py-0 lg:py-0">
|
||||
<Section key={`home-hero-${pathname}`} className="relative min-h-[85vh] md:h-[90vh] flex flex-col items-center justify-center overflow-hidden bg-primary py-12 md:py-0 lg:py-0">
|
||||
<Container className="relative z-10 text-center md:text-left text-white w-full order-2 md:order-none">
|
||||
<div className="max-w-5xl mx-auto md:mx-0">
|
||||
<div>
|
||||
|
||||
@@ -4,6 +4,7 @@ import { useLocale } from 'next-intl';
|
||||
import { ShieldCheck, Leaf, Lock, Accessibility, Zap, Mail, Phone } from 'lucide-react';
|
||||
import { LanguageSwitcher } from './LanguageSwitcher';
|
||||
import { Tooltip } from '@/components/ui/Tooltip';
|
||||
import { EUFundingBadge } from '@/components/decorations/EUFundingBadge';
|
||||
interface CompanyInfo {
|
||||
contactEmail: string;
|
||||
contactPhone: string;
|
||||
@@ -18,7 +19,7 @@ export function Footer({ companyInfo }: FooterProps) {
|
||||
const locale = useLocale();
|
||||
|
||||
return (
|
||||
<footer className="bg-[#050B14] text-neutral-light py-10 md:py-16 relative overflow-hidden border-t border-white/5">
|
||||
<footer className="bg-[#050B14] text-neutral-light pt-10 pb-28 md:py-16 relative overflow-hidden border-t border-white/5">
|
||||
{/* Subtle background tech grid */}
|
||||
<div className="absolute inset-0 bg-[linear-gradient(to_right,#8080800a_1px,transparent_1px),linear-gradient(to_bottom,#8080800a_1px,transparent_1px)] bg-[size:32px_32px] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_0%,#000_70%,transparent_100%)] pointer-events-none" />
|
||||
|
||||
@@ -26,9 +27,11 @@ export function Footer({ companyInfo }: FooterProps) {
|
||||
<div className="absolute top-0 left-0 w-full h-px bg-gradient-to-r from-transparent via-primary/40 to-transparent" />
|
||||
<div className="absolute top-0 left-1/2 -translate-x-1/2 w-1/3 h-[200px] bg-primary/20 blur-[100px] rounded-full pointer-events-none opacity-50" />
|
||||
|
||||
<EUFundingBadge />
|
||||
|
||||
<div className="container relative z-10 grid grid-cols-1 md:grid-cols-4 lg:grid-cols-12 gap-4 md:gap-6 lg:gap-8 mb-8 md:mb-12">
|
||||
{/* Brand Column Bento */}
|
||||
<div className="col-span-1 md:col-span-4 lg:col-span-5 flex flex-col justify-between bg-white/[0.02] border border-white/5 rounded-3xl p-6 md:p-8 lg:p-10 backdrop-blur-md relative group overflow-hidden">
|
||||
<div className="col-span-1 md:col-span-4 lg:col-span-5 flex flex-col justify-between bg-white/[0.02] border border-white/5 rounded-3xl p-5 md:p-8 lg:p-10 backdrop-blur-md relative group overflow-hidden">
|
||||
<div className="absolute inset-0 bg-gradient-to-br from-white/[0.04] to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-700" />
|
||||
|
||||
<div className="space-y-4 md:space-y-6 relative z-10">
|
||||
@@ -96,7 +99,7 @@ export function Footer({ companyInfo }: FooterProps) {
|
||||
<div className="col-span-1 md:col-span-4 lg:col-span-7 grid grid-cols-1 sm:grid-cols-2 gap-4 md:gap-6 lg:gap-8">
|
||||
|
||||
{/* Company Column */}
|
||||
<div className="bg-white/[0.02] border border-white/5 rounded-3xl p-6 md:p-8 lg:p-10 backdrop-blur-md relative group overflow-hidden flex flex-col">
|
||||
<div className="bg-white/[0.02] border border-white/5 rounded-3xl p-5 md:p-8 lg:p-10 backdrop-blur-md relative group overflow-hidden flex flex-col">
|
||||
<div className="absolute inset-0 bg-gradient-to-bl from-white/[0.04] to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-700 pointer-events-none" />
|
||||
<h4 className="font-heading font-bold uppercase tracking-widest text-sm mb-6 md:mb-8 text-white">
|
||||
{locale === 'de' ? 'Unternehmen' : 'Company'}
|
||||
@@ -124,7 +127,7 @@ export function Footer({ companyInfo }: FooterProps) {
|
||||
</div>
|
||||
|
||||
{/* Legal Column */}
|
||||
<div className="bg-white/[0.02] border border-white/5 rounded-3xl p-6 md:p-8 lg:p-10 backdrop-blur-md relative group overflow-hidden flex flex-col">
|
||||
<div className="bg-white/[0.02] border border-white/5 rounded-3xl p-5 md:p-8 lg:p-10 backdrop-blur-md relative group overflow-hidden flex flex-col">
|
||||
<div className="absolute inset-0 bg-gradient-to-tr from-white/[0.04] to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-700 pointer-events-none" />
|
||||
<h4 className="font-heading font-bold uppercase tracking-widest text-sm mb-6 md:mb-8 text-white">
|
||||
{locale === 'de' ? 'Rechtliches' : 'Legal'}
|
||||
|
||||
@@ -22,6 +22,7 @@ export function Header({ navLinks }: HeaderProps) {
|
||||
const [isScrolled, setIsScrolled] = React.useState(false);
|
||||
const [forceSolid, setForceSolid] = React.useState(false);
|
||||
const [headerVariant, setHeaderVariant] = React.useState<'capsule' | 'standard'>('capsule');
|
||||
const [isMobileMenuOpen, setIsMobileMenuOpen] = React.useState(false);
|
||||
const pathname = usePathname() || '/';
|
||||
|
||||
// Scroll bound shine effect (continuous looping as user scrolls)
|
||||
@@ -55,6 +56,7 @@ export function Header({ navLinks }: HeaderProps) {
|
||||
|
||||
// Re-check when pathname changes
|
||||
checkHeaderState();
|
||||
setIsMobileMenuOpen(false);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('scroll', handleScroll);
|
||||
@@ -72,7 +74,7 @@ export function Header({ navLinks }: HeaderProps) {
|
||||
className={`fixed top-0 left-0 right-0 z-50 flex justify-center transition-all duration-700 ease-[cubic-bezier(0.16,1,0.3,1)] ${
|
||||
isStandard
|
||||
? 'bg-[#050B14]/95 backdrop-blur-xl border-b border-white/10'
|
||||
: (isSolidMode ? 'pt-4 px-4' : 'pt-0 px-0')
|
||||
: (isSolidMode ? 'pt-4 px-4 sm:px-6' : 'pt-0 px-0')
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
@@ -80,7 +82,7 @@ export function Header({ navLinks }: HeaderProps) {
|
||||
isStandard
|
||||
? 'py-4 px-6 md:px-8'
|
||||
: isSolidMode
|
||||
? 'rounded-full bg-white/50 backdrop-blur-xl shadow-[0_8px_32px_rgba(0,0,0,0.08)] border border-white/40 py-2.5 px-6 md:px-8'
|
||||
? 'rounded-full bg-white/50 backdrop-blur-xl shadow-[0_8px_32px_rgba(0,0,0,0.08)] border border-white/40 py-2.5 px-8 md:px-10'
|
||||
: 'rounded-none bg-transparent py-6 px-4 md:px-8 border border-transparent'
|
||||
}`}
|
||||
>
|
||||
@@ -154,10 +156,82 @@ export function Header({ navLinks }: HeaderProps) {
|
||||
{/* 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" />
|
||||
</TransitionLink>
|
||||
|
||||
{/* Hamburger Menu (Mobile Only) */}
|
||||
<button
|
||||
className={`md:hidden ml-2 p-2 transition-colors focus:outline-none ${isSolidMode && !isMobileMenuOpen ? 'text-text-primary hover:text-primary' : 'text-white hover:text-primary z-[60] relative'}`}
|
||||
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
|
||||
aria-label="Toggle Menu"
|
||||
>
|
||||
<div className="w-6 h-5 flex flex-col justify-between relative">
|
||||
<span className={`w-full h-0.5 bg-current transform transition duration-300 ease-in-out ${isMobileMenuOpen ? 'rotate-45 translate-y-2' : ''}`} />
|
||||
<span className={`w-full h-0.5 bg-current transition duration-300 ease-in-out ${isMobileMenuOpen ? 'opacity-0' : 'opacity-100'}`} />
|
||||
<span className={`w-full h-0.5 bg-current transform transition duration-300 ease-in-out ${isMobileMenuOpen ? '-rotate-45 -translate-y-2.5' : ''}`} />
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{/* Mobile Menu Overlay */}
|
||||
<AnimatePresence>
|
||||
{isMobileMenuOpen && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: -20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: -20 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
className="fixed inset-0 z-[40] bg-[#050B14]/95 backdrop-blur-xl md:hidden pt-24 pb-24 px-6 overflow-y-auto"
|
||||
>
|
||||
<nav className="flex flex-col gap-6 mt-8">
|
||||
{navLinks && navLinks.length > 0 && navLinks.map((link) => {
|
||||
const mappedUrl = link.url.startsWith('/') && !link.url.match(/^\/(en|de)/)
|
||||
? `/${currentLocale}${link.url}`
|
||||
: link.url;
|
||||
const isActive = pathname === mappedUrl || (mappedUrl !== `/${currentLocale}` && pathname?.startsWith(`${mappedUrl}/`));
|
||||
|
||||
return (
|
||||
<div key={link.url} className="flex flex-col">
|
||||
<TransitionLink
|
||||
href={mappedUrl}
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
className={`text-2xl font-bold uppercase tracking-widest transition-colors ${isActive ? 'text-primary' : 'text-white'}`}
|
||||
>
|
||||
{link.label}
|
||||
</TransitionLink>
|
||||
|
||||
{link.children && (
|
||||
<div className="flex flex-col gap-3 mt-3 pl-4 border-l-2 border-white/10">
|
||||
{link.children.map((child, idx) => {
|
||||
if (child.isGroupLabel) {
|
||||
return <div key={idx} className="text-sm font-bold text-neutral-500 uppercase tracking-widest mt-2">{child.label}</div>;
|
||||
}
|
||||
const childUrl = child.url.startsWith('/') && !child.url.match(/^\/(en|de)/)
|
||||
? `/${currentLocale}${child.url}`
|
||||
: child.url;
|
||||
const isChildActive = pathname === childUrl;
|
||||
|
||||
return (
|
||||
<TransitionLink
|
||||
key={child.url}
|
||||
href={childUrl}
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
className={`text-lg font-medium transition-colors ${isChildActive ? 'text-primary' : 'text-white/70'}`}
|
||||
>
|
||||
{child.label}
|
||||
</TransitionLink>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</nav>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -165,6 +239,20 @@ export function Header({ navLinks }: HeaderProps) {
|
||||
function NavItem({ link, currentLocale, pathname, isSolidMode }: { link: NavLink, currentLocale: string, pathname: string, isSolidMode: boolean }) {
|
||||
const [isHovered, setIsHovered] = React.useState(false);
|
||||
|
||||
// Close dropdown on navigation
|
||||
React.useEffect(() => {
|
||||
setIsHovered(false);
|
||||
}, [pathname]);
|
||||
|
||||
// Close dropdown on scroll
|
||||
React.useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
if (isHovered) setIsHovered(false);
|
||||
};
|
||||
window.addEventListener('scroll', handleScroll, { passive: true });
|
||||
return () => window.removeEventListener('scroll', handleScroll);
|
||||
}, [isHovered]);
|
||||
|
||||
const mappedUrl = link.url.startsWith('/') && !link.url.match(/^\/(en|de)/)
|
||||
? `/${currentLocale}${link.url}`
|
||||
: link.url;
|
||||
@@ -237,6 +325,7 @@ function NavItem({ link, currentLocale, pathname, isSolidMode }: { link: NavLink
|
||||
<TransitionLink
|
||||
key={child.url}
|
||||
href={childUrl}
|
||||
onClick={() => setIsHovered(false)}
|
||||
className={`group/dropitem relative block px-4 py-3.5 rounded-2xl text-sm font-medium transition-all duration-300 overflow-hidden ${
|
||||
isSolidMode
|
||||
? isChildActive ? 'bg-primary/10 text-primary' : 'text-neutral-600 hover:text-primary hover:bg-neutral-50/80'
|
||||
|
||||
@@ -73,9 +73,3 @@ layout: "fullBleed"
|
||||
|
||||
<HomeReferencesSlider badge="Praxisbeispiele" title="Referenzen" description="Erfolgreiche HDD-Bohrungen und grabenlose Leitungsverlegungen unter komplexesten Bedingungen." />
|
||||
|
||||
<CallToAction
|
||||
title="Suchen Sie nach einer grabenlosen Lösung?"
|
||||
text="Wir beraten Sie gerne zu den Möglichkeiten der Horizontalspülbohrung für Ihr Vorhaben."
|
||||
buttonText="Kontakt aufnehmen"
|
||||
buttonLink="/de/kontakt"
|
||||
/>
|
||||
|
||||
@@ -71,9 +71,3 @@ layout: "fullBleed"
|
||||
|
||||
<HomeReferencesSlider badge="Praxisbeispiele" title="Referenzen" description="Wir haben bereits hunderte Kilometer FTTX-Netze erfolgreich realisiert. Entdecken Sie unsere Referenzen." />
|
||||
|
||||
<CallToAction
|
||||
title="Sie planen einen FTTX-Ausbau?"
|
||||
text="Wir beraten Sie gerne vollumfänglich rund um den Bereich FTTX und den Glasfaserausbau."
|
||||
buttonText="Kontakt aufnehmen"
|
||||
buttonLink="/de/kontakt"
|
||||
/>
|
||||
|
||||
@@ -5,7 +5,7 @@ description: "Die E-TIB GmbH ist Ihr zuverlässiger Partner für komplexe Kabelt
|
||||
|
||||
<HomeHero
|
||||
|
||||
title={"Die Experten für\nKabeltiefbau"}
|
||||
title={"Die Experten für\nKabelnetzbau"}
|
||||
description="Wir realisieren komplexe Versorgungsleitungen für eine moderne Gesellschaft. Verlässlich, innovativ und mit höchster Präzision im Kabeltiefbau und der Bohrtechnik."
|
||||
videoUrl="/assets/videos/web/hero-kabelpflug.mp4"
|
||||
linkText="Unsere Leistungen"
|
||||
|
||||
@@ -73,9 +73,3 @@ layout: "fullBleed"
|
||||
|
||||
<HomeReferencesSlider badge="Praxisbeispiele" title="Referenzen" description="Wir haben über hunderte Kilometer Kabel verlegt. Sehen Sie sich unsere Referenz-Projekte an." />
|
||||
|
||||
<CallToAction
|
||||
title="Sie haben ein konkretes Projekt?"
|
||||
text="Wir beraten Sie gerne zu allen Fragen rund um Kabeltiefbau und Leitungsverlegung."
|
||||
buttonText="Kontakt aufnehmen"
|
||||
buttonLink="/de/kontakt"
|
||||
/>
|
||||
|
||||
@@ -5,13 +5,14 @@ excerpt: "Werden Sie Teil eines dynamischen Teams und bauen Sie mit uns die Infr
|
||||
layout: "fullBleed"
|
||||
---
|
||||
|
||||
<HomeHero
|
||||
<HeroSection
|
||||
badge="Karriere"
|
||||
title="Zukunft bauen"
|
||||
description="Suchen Sie eine neue Herausforderung in einem zukunftssicheren Markt? Bei E-TIB arbeiten wir täglich daran, Deutschland zu vernetzen und die Energiewende voranzutreiben."
|
||||
videoUrl="/assets/videos/web/hero-kabelpflug.mp4"
|
||||
linkText="Offene Stellen"
|
||||
linkHref="#stellen"
|
||||
subtitle="Suchen Sie eine neue Herausforderung in einem zukunftssicheren Markt? Bei E-TIB arbeiten wir täglich daran, Deutschland zu vernetzen und die Energiewende voranzutreiben."
|
||||
backgroundImage={{ url: '/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-28.jpg' }}
|
||||
alignment="center"
|
||||
ctaLabel="Offene Stellen"
|
||||
ctaHref="#stellen"
|
||||
/>
|
||||
|
||||
<JobListingBlock showFairs={false} showJobs={true} />
|
||||
@@ -96,10 +97,3 @@ layout: "fullBleed"
|
||||
]}
|
||||
/>
|
||||
|
||||
<CallToAction
|
||||
title="Initiativbewerbung (m/w/d)"
|
||||
description="Sie können sich vorstellen, eine langfristige Herausforderung in unserem Unternehmen anzunehmen, finden aber kein passendes Stellenangebot? Bewerben Sie sich initiativ."
|
||||
ctaLabel="Zum Kontaktformular"
|
||||
ctaHref="/de/kontakt"
|
||||
theme="dark"
|
||||
/>
|
||||
|
||||
@@ -27,4 +27,3 @@ layout: "fullBleed"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<CallToAction />
|
||||
|
||||
@@ -71,9 +71,3 @@ layout: "fullBleed"
|
||||
|
||||
<HomeReferencesSlider badge="Praxisbeispiele" title="Planung in der Praxis" description="Erfolgreich geplante und begleitete Infrastrukturprojekte unserer Unternehmensgruppe." />
|
||||
|
||||
<CallToAction
|
||||
title="Benötigen Sie Planungssicherheit?"
|
||||
text="Lassen Sie uns über Ihr Vorhaben sprechen. Wir stehen Ihnen mit unserem Ingenieurwissen zur Seite."
|
||||
buttonText="Kontakt aufnehmen"
|
||||
buttonLink="/de/kontakt"
|
||||
/>
|
||||
|
||||
@@ -4,7 +4,7 @@ client: "Energiekontor AG"
|
||||
date: "2026-06-01"
|
||||
dateString: "01/2025 bis 06/2026"
|
||||
location: "18334 Dettmannsdorf"
|
||||
featuredImage: "/assets/photos/DSC08653.JPG"
|
||||
featuredImage: "/assets/photos/etib_ingenieure_tiefbau_solar_pv_planung_vermessung_gis-256.jpg"
|
||||
---
|
||||
|
||||
- 12.300 m Kabelgraben ausheben und verfüllen
|
||||
|
||||
@@ -4,7 +4,7 @@ client: "wpd GmbH"
|
||||
date: "2026-03-01"
|
||||
dateString: "seit 03/2026"
|
||||
location: "24808 Jevenstedt"
|
||||
featuredImage: "/assets/photos/DSC01137.JPG"
|
||||
featuredImage: "/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-15.jpg"
|
||||
---
|
||||
|
||||
- 500 m Kabelgraben ausheben und verfüllen
|
||||
|
||||
@@ -4,7 +4,7 @@ client: "E.DIS Netz GmbH"
|
||||
date: "2025-06-01"
|
||||
dateString: "01/2025 bis 06/2025"
|
||||
location: "14669 Ketzin"
|
||||
featuredImage: "/assets/photos/DJI_0048.JPG"
|
||||
featuredImage: "/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-14.jpg"
|
||||
---
|
||||
|
||||
- 1.600 m Kabelgraben ausheben und verfüllen
|
||||
|
||||
@@ -4,7 +4,7 @@ client: "NaturStromAnlagen GmbH"
|
||||
date: "2025-02-01"
|
||||
dateString: "04/2024 bis 02/2025"
|
||||
location: "15326 Petershagen"
|
||||
featuredImage: "/assets/photos/DSC01123.JPG"
|
||||
featuredImage: "/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-12.jpg"
|
||||
---
|
||||
|
||||
- 12.000 m Kabelgraben ausheben und verfüllen
|
||||
|
||||
@@ -4,7 +4,7 @@ client: "Trianel GmbH"
|
||||
date: "2025-08-01"
|
||||
dateString: "02/2025 bis 08/2025"
|
||||
location: "15345 Prötzel"
|
||||
featuredImage: "/assets/photos/DJI_0243.JPG"
|
||||
featuredImage: "/assets/photos/etib_ingenieure_tiefbau_solar_pv_planung_vermessung_gis-294.jpg"
|
||||
---
|
||||
|
||||
- 2.600 m Kabelgraben ausheben und verfüllen
|
||||
|
||||
@@ -82,9 +82,3 @@ layout: "fullBleed"
|
||||
]}
|
||||
/>
|
||||
|
||||
<CallToAction
|
||||
title="Werden Sie Teil unseres Teams"
|
||||
text="Wir sind immer auf der Suche nach motivierten Talenten für spannende Infrastrukturprojekte."
|
||||
buttonText="Offene Stellen ansehen"
|
||||
buttonLink="/de/karriere"
|
||||
/>
|
||||
|
||||
@@ -27,7 +27,7 @@ layout: "fullBleed"
|
||||
Seit unserer Gründung im Jahr 2015 in Guben haben wir es uns zur Aufgabe gemacht, den Ausbau der kritischen Infrastruktur in Deutschland aktiv mitzugestalten.
|
||||
</div>
|
||||
<div>
|
||||
Mit 100+ engagierten Mitarbeitenden und einem hochmodernen Maschinenpark meistern wir selbst anspruchsvollste Projekte im Kabelnetzbau, der Spülbohrtechnik und der Netzmontage. Verlässlichkeit, Termintreue und höchste Qualitätsstandards sind dabei unser Fundament.
|
||||
Mit über 100 Experten für Ihr Projekt (darunter Spezialisten der E-TIB GmbH, E-TIB Bohrtechnik und E-TIB Ingenieurgesellschaft) und einem hochmodernen Maschinenpark meistern wir selbst anspruchsvollste Projekte im Kabelnetzbau, der Spülbohrtechnik und der Netzmontage. Verlässlichkeit, Termintreue und höchste Qualitätsstandards sind dabei unser Fundament.
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-6">
|
||||
@@ -52,7 +52,20 @@ layout: "fullBleed"
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<InteractiveGermanyMap isHero={true} badge="Bundesweite Präsenz" title="Infrastruktur für ein ganzes Land" description="Seit 2016 haben wir in über 200 Projekten quer durch Deutschland bewiesen, dass wir Infrastrukturprojekte jeder Größenordnung verlässlich umsetzen." />
|
||||
<div className="bg-[#050B14] py-24 md:py-32 text-white relative overflow-hidden group my-16 md:my-24 rounded-[2.5rem] md:rounded-[3.5rem] mx-4 md:mx-auto max-w-7xl">
|
||||
<div className="absolute inset-0 bg-[url('/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-54.jpg')] opacity-20 bg-cover bg-center mix-blend-overlay group-hover:scale-105 transition-transform duration-1000"></div>
|
||||
<div className="absolute inset-0 bg-gradient-to-br from-[#050B14] via-[#0A1322]/90 to-[#050B14]"></div>
|
||||
<div className="container max-w-4xl mx-auto px-4 relative z-10 text-center">
|
||||
<div className="mb-8">
|
||||
<Badge variant="accent">Bundesweite Präsenz</Badge>
|
||||
</div>
|
||||
<h2 className="font-heading text-4xl md:text-5xl lg:text-6xl font-extrabold mb-6 leading-tight text-transparent bg-clip-text bg-gradient-to-r from-white to-white/70">Infrastruktur für<br />ein ganzes Land</h2>
|
||||
<p className="text-lg md:text-xl text-white/60 mb-12 max-w-2xl mx-auto leading-relaxed">Seit 2016 haben wir in über 200 Projekten quer durch Deutschland bewiesen, dass wir Infrastrukturprojekte jeder Größenordnung verlässlich umsetzen.</p>
|
||||
<Button href="/de/referenzen" variant="primary" size="lg" className="shadow-[0_0_20px_rgba(130,237,32,0.3)]">
|
||||
Zu unseren Referenzen <span className="text-xl leading-none">→</span>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<CompanyTimeline />
|
||||
|
||||
@@ -82,17 +95,16 @@ layout: "fullBleed"
|
||||
url: "/de/standorte/buelstedt",
|
||||
backgroundImage: "/assets/photos/DJI_0048.JPG"
|
||||
},
|
||||
{
|
||||
title: "E-TIB Bohrtechnik GmbH",
|
||||
description: "Präzise Horizontalspülbohrungen in allen Bodenklassen für eine oberflächenschonende und grabenlose Leitungsverlegung.",
|
||||
icon: "M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z",
|
||||
url: "/de/standorte/kirchheilingen",
|
||||
backgroundImage: "/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-47.jpg"
|
||||
}
|
||||
{
|
||||
title: "E-TIB Bohrtechnik GmbH",
|
||||
description: "Präzise Horizontalspülbohrungen in allen Bodenklassen für eine oberflächenschonende und grabenlose Leitungsverlegung.",
|
||||
icon: "M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z",
|
||||
url: "/de/bohrtechnik",
|
||||
backgroundImage: "/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-47.jpg"
|
||||
}
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<CallToAction />
|
||||
|
||||
@@ -72,9 +72,3 @@ layout: "fullBleed"
|
||||
|
||||
<HomeReferencesSlider badge="Praxisbeispiele" title="Dokumentierte Projekte" description="Wir haben hunderte Kilometer Trassen exakt eingemessen und digital dokumentiert." />
|
||||
|
||||
<CallToAction
|
||||
title="Stehen Sie vor hohen Dokumentationsanforderungen?"
|
||||
text="Kontaktieren Sie uns für professionelle Vermessungs- und GIS-Dienstleistungen."
|
||||
buttonText="Kontakt aufnehmen"
|
||||
buttonLink="/de/kontakt"
|
||||
/>
|
||||
|
||||
@@ -73,9 +73,3 @@ layout: "fullBleed"
|
||||
|
||||
<HomeReferencesSlider badge="Case Studies" title="References" description="Successful HDD drilling and trenchless cable laying under the most complex conditions." />
|
||||
|
||||
<CallToAction
|
||||
title="Looking for a trenchless solution?"
|
||||
text="We would be happy to advise you on the possibilities of horizontal directional drilling for your project."
|
||||
buttonText="Contact us"
|
||||
buttonLink="/en/contact"
|
||||
/>
|
||||
|
||||
@@ -71,9 +71,3 @@ layout: "fullBleed"
|
||||
|
||||
<HomeReferencesSlider badge="Case Studies" title="References" description="We have already successfully realized hundreds of kilometers of FTTX networks. Discover our references." />
|
||||
|
||||
<CallToAction
|
||||
title="Are you planning an FTTX expansion?"
|
||||
text="We are happy to advise you on all aspects of FTTX and fiber optic expansion."
|
||||
buttonText="Contact us"
|
||||
buttonLink="/en/contact"
|
||||
/>
|
||||
|
||||
@@ -73,9 +73,3 @@ layout: "fullBleed"
|
||||
|
||||
<HomeReferencesSlider badge="Case Studies" title="References" description="We have laid hundreds of kilometers of cables. Take a look at our reference projects." />
|
||||
|
||||
<CallToAction
|
||||
title="Do you have a specific project?"
|
||||
text="We would be happy to advise you on all questions regarding cable civil engineering and line laying."
|
||||
buttonText="Contact us"
|
||||
buttonLink="/en/contact"
|
||||
/>
|
||||
|
||||
@@ -5,13 +5,14 @@ excerpt: "Become part of a dynamic team and help us build the infrastructure of
|
||||
layout: "fullBleed"
|
||||
---
|
||||
|
||||
<HomeHero
|
||||
<HeroSection
|
||||
badge="Careers"
|
||||
title="Build the Future"
|
||||
description="Are you looking for a new challenge in a future-proof market? At E-TIB, we work daily to network Germany and drive the energy transition forward."
|
||||
videoUrl="/assets/videos/web/hero-kabelpflug.mp4"
|
||||
linkText="Open Positions"
|
||||
linkHref="#stellen"
|
||||
subtitle="Are you looking for a new challenge in a future-proof market? At E-TIB, we work daily to network Germany and drive the energy transition forward."
|
||||
backgroundImage={{ url: '/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-28.jpg' }}
|
||||
alignment="center"
|
||||
ctaLabel="Open Positions"
|
||||
ctaHref="#stellen"
|
||||
/>
|
||||
|
||||
<JobListingBlock showFairs={false} showJobs={true} />
|
||||
@@ -96,10 +97,3 @@ layout: "fullBleed"
|
||||
]}
|
||||
/>
|
||||
|
||||
<CallToAction
|
||||
title="Speculative Application (m/f/d)"
|
||||
description="Can you imagine taking on a long-term challenge in our company but can't find a suitable job offer? Apply speculatively."
|
||||
ctaLabel="To the contact form"
|
||||
ctaHref="/en/contact"
|
||||
theme="dark"
|
||||
/>
|
||||
|
||||
@@ -27,4 +27,3 @@ layout: "fullBleed"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<CallToAction />
|
||||
|
||||
@@ -71,9 +71,3 @@ layout: "fullBleed"
|
||||
|
||||
<HomeReferencesSlider badge="Case Studies" title="Planning in Practice" description="Successfully planned and accompanied infrastructure projects of our group." />
|
||||
|
||||
<CallToAction
|
||||
title="Do you need planning security?"
|
||||
text="Let's talk about your project. We are at your side with our engineering knowledge."
|
||||
buttonText="Contact us"
|
||||
buttonLink="/en/contact"
|
||||
/>
|
||||
|
||||
@@ -4,7 +4,7 @@ client: "Energiekontor AG"
|
||||
date: "2026-06-01"
|
||||
dateString: "01/2025 to 06/2026"
|
||||
location: "18334 Dettmannsdorf"
|
||||
featuredImage: "/assets/photos/DSC08653.JPG"
|
||||
featuredImage: "/assets/photos/etib_ingenieure_tiefbau_solar_pv_planung_vermessung_gis-256.jpg"
|
||||
---
|
||||
|
||||
- Excavation and backfilling of 12,300 m cable trench
|
||||
|
||||
@@ -4,7 +4,7 @@ client: "wpd GmbH"
|
||||
date: "2026-03-01"
|
||||
dateString: "since 03/2026"
|
||||
location: "24808 Jevenstedt"
|
||||
featuredImage: "/assets/photos/DSC01137.JPG"
|
||||
featuredImage: "/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-15.jpg"
|
||||
---
|
||||
|
||||
- Excavation and backfilling of 500 m cable trench
|
||||
|
||||
@@ -4,7 +4,7 @@ client: "E.DIS Netz GmbH"
|
||||
date: "2025-06-01"
|
||||
dateString: "01/2025 to 06/2025"
|
||||
location: "14669 Ketzin"
|
||||
featuredImage: "/assets/photos/DJI_0048.JPG"
|
||||
featuredImage: "/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-14.jpg"
|
||||
---
|
||||
|
||||
- Excavation and backfilling of 1,600 m cable trench
|
||||
|
||||
@@ -4,7 +4,7 @@ client: "NaturStromAnlagen GmbH"
|
||||
date: "2025-02-01"
|
||||
dateString: "04/2024 to 02/2025"
|
||||
location: "15326 Petershagen"
|
||||
featuredImage: "/assets/photos/DSC01123.JPG"
|
||||
featuredImage: "/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-12.jpg"
|
||||
---
|
||||
|
||||
- Excavation and backfilling of 12,000 m cable trench
|
||||
|
||||
@@ -4,7 +4,7 @@ client: "Trianel GmbH"
|
||||
date: "2025-08-01"
|
||||
dateString: "02/2025 to 08/2025"
|
||||
location: "15345 Prötzel"
|
||||
featuredImage: "/assets/photos/DJI_0243.JPG"
|
||||
featuredImage: "/assets/photos/etib_ingenieure_tiefbau_solar_pv_planung_vermessung_gis-294.jpg"
|
||||
---
|
||||
|
||||
- Excavation and backfilling of 2,600 m cable trench
|
||||
|
||||
@@ -82,9 +82,3 @@ layout: "fullBleed"
|
||||
]}
|
||||
/>
|
||||
|
||||
<CallToAction
|
||||
title="Become part of our team"
|
||||
text="We are always looking for motivated talents for exciting infrastructure projects."
|
||||
buttonText="View open positions"
|
||||
buttonLink="/en/career"
|
||||
/>
|
||||
|
||||
@@ -27,7 +27,7 @@ layout: "fullBleed"
|
||||
Since our foundation in 2015 in Guben, we have made it our mission to actively shape the expansion of critical infrastructure.
|
||||
</div>
|
||||
<div>
|
||||
With 100+ dedicated employees and a state-of-the-art machinery park, we master even the most demanding projects in cable network construction, directional drilling, and grid assembly. Reliability, adherence to schedules, and the highest quality standards are our foundation.
|
||||
With over 100 experts for your project (including specialists from E-TIB GmbH, E-TIB Bohrtechnik and E-TIB Ingenieurgesellschaft) and a state-of-the-art machinery park, we master even the most demanding projects in cable network construction, directional drilling, and grid assembly. Reliability, adherence to schedules, and the highest quality standards are our foundation.
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-6">
|
||||
@@ -52,7 +52,20 @@ layout: "fullBleed"
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<InteractiveGermanyMap isHero={true} badge="Nationwide Presence" title="Infrastructure for an entire country" description="Since 2016, we have proven in over 200 projects across Germany that we reliably implement infrastructure projects of any scale." />
|
||||
<div className="bg-[#050B14] py-24 md:py-32 text-white relative overflow-hidden group my-16 md:my-24 rounded-[2.5rem] md:rounded-[3.5rem] mx-4 md:mx-auto max-w-7xl">
|
||||
<div className="absolute inset-0 bg-[url('/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-54.jpg')] opacity-20 bg-cover bg-center mix-blend-overlay group-hover:scale-105 transition-transform duration-1000"></div>
|
||||
<div className="absolute inset-0 bg-gradient-to-br from-[#050B14] via-[#0A1322]/90 to-[#050B14]"></div>
|
||||
<div className="container max-w-4xl mx-auto px-4 relative z-10 text-center">
|
||||
<div className="mb-8">
|
||||
<Badge variant="accent">Nationwide Presence</Badge>
|
||||
</div>
|
||||
<h2 className="font-heading text-4xl md:text-5xl lg:text-6xl font-extrabold mb-6 leading-tight text-transparent bg-clip-text bg-gradient-to-r from-white to-white/70">Infrastructure for<br />an entire country</h2>
|
||||
<p className="text-lg md:text-xl text-white/60 mb-12 max-w-2xl mx-auto leading-relaxed">Since 2016, we have proven in over 200 projects across Germany that we reliably implement infrastructure projects of any scale.</p>
|
||||
<Button href="/en/referenzen" variant="primary" size="lg" className="shadow-[0_0_20px_rgba(130,237,32,0.3)]">
|
||||
View our references <span className="text-xl leading-none">→</span>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<CompanyTimeline />
|
||||
|
||||
@@ -86,7 +99,7 @@ layout: "fullBleed"
|
||||
title: "E-TIB Bohrtechnik GmbH",
|
||||
description: "Precise horizontal directional drilling in all soil classes for surface-friendly and trenchless pipe laying.",
|
||||
icon: "M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z",
|
||||
url: "/en/standorte/kirchheilingen",
|
||||
url: "/en/bohrtechnik",
|
||||
backgroundImage: "/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-47.jpg"
|
||||
}
|
||||
]}
|
||||
@@ -95,4 +108,3 @@ layout: "fullBleed"
|
||||
|
||||
|
||||
|
||||
<CallToAction />
|
||||
|
||||
@@ -73,9 +73,3 @@ layout: "fullBleed"
|
||||
|
||||
<HomeReferencesSlider badge="Case Studies" title="Documented Projects" description="We have precisely surveyed and digitally documented hundreds of kilometers of routes." />
|
||||
|
||||
<CallToAction
|
||||
title="Are you facing high documentation requirements?"
|
||||
text="Contact us for professional surveying and GIS services."
|
||||
buttonText="Contact us"
|
||||
buttonLink="/en/contact"
|
||||
/>
|
||||
|
||||
@@ -60,30 +60,6 @@ layout: "fullBleed"
|
||||
type: 'tax',
|
||||
date: '13.02.2025',
|
||||
},
|
||||
{
|
||||
title: 'IHK Clearance Certificate',
|
||||
description: 'Chamber of Industry and Commerce',
|
||||
type: 'general',
|
||||
},
|
||||
{
|
||||
title: 'HWK Clearance Certificate',
|
||||
description: 'Chamber of Crafts',
|
||||
type: 'general',
|
||||
},
|
||||
{
|
||||
title: 'Commercial Register Extract',
|
||||
description: 'District Court Cottbus',
|
||||
type: 'general',
|
||||
},
|
||||
{
|
||||
title: 'Trade Registration',
|
||||
description: 'City of Guben',
|
||||
type: 'general',
|
||||
},
|
||||
{
|
||||
title: 'Central Trade Register',
|
||||
description: 'Information from the Register',
|
||||
type: 'general',
|
||||
}
|
||||
|
||||
]}
|
||||
/>
|
||||
|
||||
206
lib/map-data.ts
@@ -18,6 +18,7 @@ export const defaultLocations: Location[] = [
|
||||
x: 66.38,
|
||||
y: 14.04,
|
||||
description: 'Netzanbindung Solarpark',
|
||||
featuredImage: '/assets/photos/etib_ingenieure_tiefbau_solar_pv_planung_vermessung_gis-256.jpg',
|
||||
},
|
||||
{
|
||||
id: 'proetzel',
|
||||
@@ -26,6 +27,7 @@ export const defaultLocations: Location[] = [
|
||||
x: 78.84,
|
||||
y: 32.5,
|
||||
description: 'Kabeltrasse Solarpark',
|
||||
featuredImage: '/assets/photos/etib_ingenieure_tiefbau_solar_pv_planung_vermessung_gis-294.jpg',
|
||||
},
|
||||
{
|
||||
id: 'ostbevern',
|
||||
@@ -34,6 +36,7 @@ export const defaultLocations: Location[] = [
|
||||
x: 26.64,
|
||||
y: 39.84,
|
||||
description: 'Netzanbindung Windpark',
|
||||
featuredImage: '/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-100.jpg',
|
||||
},
|
||||
{
|
||||
id: 'petershagen',
|
||||
@@ -42,22 +45,25 @@ export const defaultLocations: Location[] = [
|
||||
x: 36.26,
|
||||
y: 35.79,
|
||||
description: 'Netzanbindung Windpark',
|
||||
featuredImage: '/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-12.jpg',
|
||||
},
|
||||
{
|
||||
id: 'ketzin',
|
||||
name: 'Ketzin (Wind)',
|
||||
name: 'Ketzin (Netzausbau)',
|
||||
type: 'project',
|
||||
x: 72,
|
||||
y: 34,
|
||||
description: 'Netzanbindung Windpark',
|
||||
description: 'Netzausbau Gewerbegebiet',
|
||||
featuredImage: '/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-14.jpg',
|
||||
},
|
||||
{
|
||||
id: 'jevenstedt',
|
||||
name: 'Jevenstedt (Wind)',
|
||||
name: 'Jevenstedt (Kabeltrasse)',
|
||||
type: 'project',
|
||||
x: 43,
|
||||
y: 9,
|
||||
description: 'Netzanbindung Windpark',
|
||||
description: '110 kV Kabeltrasse',
|
||||
featuredImage: '/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-15.jpg',
|
||||
}
|
||||
];
|
||||
|
||||
@@ -895,5 +901,197 @@ export const minorLocations: Location[] = [
|
||||
y: 77.37,
|
||||
description: 'pv',
|
||||
},
|
||||
{
|
||||
id: 'lautzenhausen-55483',
|
||||
name: 'PV-Anlage, 55483 Lautzenhausen',
|
||||
type: 'minor_node',
|
||||
x: 22.12,
|
||||
y: 66.90,
|
||||
description: 'pv',
|
||||
},
|
||||
{
|
||||
id: 'schleiz-07907',
|
||||
name: 'Breitbandausbau, 07907 Schleiz',
|
||||
type: 'minor_node',
|
||||
x: 60.19,
|
||||
y: 58.32,
|
||||
description: 'fiber',
|
||||
},
|
||||
{
|
||||
id: 'grosshartau-01909',
|
||||
name: 'PV-Anlage, 01909 Großhartau',
|
||||
type: 'minor_node',
|
||||
x: 79.46,
|
||||
y: 51.69,
|
||||
description: 'pv',
|
||||
},
|
||||
{
|
||||
id: 'halsbrücke-09600',
|
||||
name: 'Breitbandausbau, 09600 Halsbrücke',
|
||||
type: 'minor_node',
|
||||
x: 73.13,
|
||||
y: 53.60,
|
||||
description: 'fiber',
|
||||
},
|
||||
{
|
||||
id: 'seinsheim-97342',
|
||||
name: 'PV-Anlage, 97342 Seinsheim',
|
||||
type: 'minor_node',
|
||||
x: 46.84,
|
||||
y: 70.21,
|
||||
description: 'pv',
|
||||
},
|
||||
{
|
||||
id: 'schenkenberg-17291',
|
||||
name: 'Kabelschutzrohrtrasse, 17291 Schenkenberg-Polen',
|
||||
type: 'minor_node',
|
||||
x: 78.11,
|
||||
y: 23.31,
|
||||
description: 'power',
|
||||
},
|
||||
{
|
||||
id: 'thundorf-97711',
|
||||
name: 'PV-Anlage, 97711 Thundorf OT Theinfeld',
|
||||
type: 'minor_node',
|
||||
x: 47.79,
|
||||
y: 62.99,
|
||||
description: 'pv',
|
||||
},
|
||||
{
|
||||
id: 'tarnow-18249',
|
||||
name: 'Windpark, 18249 Tarnow-Prüzen',
|
||||
type: 'minor_node',
|
||||
x: 61.91,
|
||||
y: 17.91,
|
||||
description: 'wind',
|
||||
},
|
||||
{
|
||||
id: 'ennigerloh-59320',
|
||||
name: 'PV-Anlage, 59320 Ennigerloh-Oelde',
|
||||
type: 'minor_node',
|
||||
x: 28.56,
|
||||
y: 42.47,
|
||||
description: 'pv',
|
||||
},
|
||||
{
|
||||
id: 'schenkend-bern-03172',
|
||||
name: 'NS-Verkabelung, Klein Gastrose, 03172 Schenkendöbern',
|
||||
type: 'minor_node',
|
||||
x: 83.38,
|
||||
y: 41.01,
|
||||
description: 'power',
|
||||
},
|
||||
{
|
||||
id: 'cottbus-03051',
|
||||
name: 'MS-Verkabelung, Auras-Cottbus, 03051 Cottbus',
|
||||
type: 'minor_node',
|
||||
x: 81.78,
|
||||
y: 44.10,
|
||||
description: 'power',
|
||||
},
|
||||
{
|
||||
id: 'rietz-neuendorf-15848',
|
||||
name: 'MS-Verkabelung, 15848 Rietz-Neuendorf',
|
||||
type: 'minor_node',
|
||||
x: 80.54,
|
||||
y: 38.42,
|
||||
description: 'power',
|
||||
},
|
||||
{
|
||||
id: 'schlepzig-15910',
|
||||
name: 'NS-Verkabelung, 15910 Schlepzig',
|
||||
type: 'minor_node',
|
||||
x: 76.88,
|
||||
y: 40.21,
|
||||
description: 'power',
|
||||
},
|
||||
{
|
||||
id: 'falkenhagen-mark-15306',
|
||||
name: 'MS-Verkabelung, 15306 Falkenhagen Mark',
|
||||
type: 'minor_node',
|
||||
x: 81.61,
|
||||
y: 33.99,
|
||||
description: 'power',
|
||||
},
|
||||
{
|
||||
id: 'neuzelle-15898',
|
||||
name: 'MS-Verkabelung, 15898 Neuzelle',
|
||||
type: 'minor_node',
|
||||
x: 83.71,
|
||||
y: 39.69,
|
||||
description: 'power',
|
||||
},
|
||||
{
|
||||
id: 'eisenh-ttenstadt-15890',
|
||||
name: 'MS-Verkabelung, 15890 Eisenhüttenstadt OT Diehlo',
|
||||
type: 'minor_node',
|
||||
x: 83.26,
|
||||
y: 38.35,
|
||||
description: 'power',
|
||||
},
|
||||
{
|
||||
id: 'karras-15848',
|
||||
name: 'MS-Verkabelung, 15848 Karras',
|
||||
type: 'minor_node',
|
||||
x: 80.52,
|
||||
y: 38.32,
|
||||
description: 'power',
|
||||
},
|
||||
{
|
||||
id: 'ketzin-14669',
|
||||
name: 'MS-Verkabelung, Gewerbegebiet, 14669 Ketzin',
|
||||
type: 'minor_node',
|
||||
x: 68.81,
|
||||
y: 34.10,
|
||||
description: 'power',
|
||||
},
|
||||
{
|
||||
id: 'lieberose-15868',
|
||||
name: 'MS-Verkabelung, 15868 Lieberose',
|
||||
type: 'minor_node',
|
||||
x: 81.35,
|
||||
y: 40.33,
|
||||
description: 'power',
|
||||
},
|
||||
{
|
||||
id: 'strausberg-15344',
|
||||
name: 'MS-Verkabelung, 15344 Strausberg',
|
||||
type: 'minor_node',
|
||||
x: 77.72,
|
||||
y: 33.40,
|
||||
description: 'power',
|
||||
},
|
||||
{
|
||||
id: 'neuenhagen-15366',
|
||||
name: 'MS-Verkabelung, 15366 Neuenhagen',
|
||||
type: 'minor_node',
|
||||
x: 75.84,
|
||||
y: 33.94,
|
||||
description: 'power',
|
||||
},
|
||||
{
|
||||
id: 'jamlitz-15868',
|
||||
name: 'MS-Verkabelung, 15868 Jamlitz',
|
||||
type: 'minor_node',
|
||||
x: 81.40,
|
||||
y: 40.37,
|
||||
description: 'power',
|
||||
},
|
||||
{
|
||||
id: 'burg-03096',
|
||||
name: 'MS-Verkabelung, 03096 Burg (Spreewald)',
|
||||
type: 'minor_node',
|
||||
x: 80.27,
|
||||
y: 42.54,
|
||||
description: 'power',
|
||||
},
|
||||
{
|
||||
id: 'bohsdorf-03130',
|
||||
name: 'MS-Verkabelung, 03130 Bohsdorf',
|
||||
type: 'minor_node',
|
||||
x: 82.25,
|
||||
y: 45.64,
|
||||
description: 'power',
|
||||
},
|
||||
];
|
||||
export const projectLocations = [...defaultLocations, ...minorLocations];
|
||||
|
||||
@@ -34,7 +34,7 @@ export interface StandortData {
|
||||
export const standorteData: StandortData[] = [
|
||||
{
|
||||
id: 'guben',
|
||||
name: 'E-TIB GmbH Holding & Bohrtechnik GmbH',
|
||||
name: 'E-TIB GmbH',
|
||||
shortName: 'Guben (Hauptsitz)',
|
||||
type: 'hq',
|
||||
description: {
|
||||
|
||||
@@ -143,7 +143,7 @@
|
||||
"prepare": "husky",
|
||||
"preinstall": "npx only-allow pnpm"
|
||||
},
|
||||
"version": "2.2.12",
|
||||
"version": "2.2.13-rc.2",
|
||||
"pnpm": {
|
||||
"onlyBuiltDependencies": [
|
||||
"@parcel/watcher",
|
||||
|
||||
BIN
public/assets/eu-flag-perspective.png
Normal file
|
After Width: | Height: | Size: 572 KiB |
BIN
public/assets/eu-flag.webp
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
public/assets/photos/DSC00010.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 5.7 MiB After Width: | Height: | Size: 447 KiB |
BIN
public/assets/photos/DSC00033.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 6.3 MiB After Width: | Height: | Size: 570 KiB |
BIN
public/assets/photos/DSC00808.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 5.2 MiB After Width: | Height: | Size: 434 KiB |
BIN
public/assets/photos/DSC00830.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 4.1 MiB After Width: | Height: | Size: 336 KiB |
BIN
public/assets/photos/DSC00850.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 5.2 MiB After Width: | Height: | Size: 422 KiB |
BIN
public/assets/photos/DSC01021.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 8.9 MiB After Width: | Height: | Size: 702 KiB |
BIN
public/assets/photos/DSC01022.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 4.9 MiB After Width: | Height: | Size: 380 KiB |
BIN
public/assets/photos/DSC01103.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 4.8 MiB After Width: | Height: | Size: 406 KiB |
BIN
public/assets/photos/DSC01119.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 7.4 MiB After Width: | Height: | Size: 664 KiB |
BIN
public/assets/photos/DSC01122.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 6.3 MiB After Width: | Height: | Size: 546 KiB |
BIN
public/assets/photos/DSC01123.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 7.5 MiB After Width: | Height: | Size: 636 KiB |
BIN
public/assets/photos/DSC01129.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 10 MiB After Width: | Height: | Size: 877 KiB |
BIN
public/assets/photos/DSC01137.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 10 MiB After Width: | Height: | Size: 894 KiB |
BIN
public/assets/photos/DSC01163.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 5.0 MiB After Width: | Height: | Size: 402 KiB |
BIN
public/assets/photos/DSC01168.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 8.3 MiB After Width: | Height: | Size: 755 KiB |
BIN
public/assets/photos/DSC01174.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 3.9 MiB After Width: | Height: | Size: 306 KiB |
BIN
public/assets/photos/DSC01178.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 8.6 MiB After Width: | Height: | Size: 686 KiB |
BIN
public/assets/photos/DSC01200.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 8.3 MiB After Width: | Height: | Size: 660 KiB |
BIN
public/assets/photos/DSC01567.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 7.3 MiB After Width: | Height: | Size: 606 KiB |
BIN
public/assets/photos/DSC01572.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 5.9 MiB After Width: | Height: | Size: 432 KiB |
BIN
public/assets/photos/DSC02639.JPG
Normal file
|
After Width: | Height: | Size: 710 KiB |
BIN
public/assets/photos/DSC02642.JPG
Normal file
|
After Width: | Height: | Size: 844 KiB |
BIN
public/assets/photos/DSC02643.JPG
Normal file
|
After Width: | Height: | Size: 655 KiB |
BIN
public/assets/photos/DSC02656.JPG
Normal file
|
After Width: | Height: | Size: 771 KiB |
BIN
public/assets/photos/DSC02676.JPG
Normal file
|
After Width: | Height: | Size: 919 KiB |
BIN
public/assets/photos/DSC02690.JPG
Normal file
|
After Width: | Height: | Size: 577 KiB |
BIN
public/assets/photos/DSC02691.JPG
Normal file
|
After Width: | Height: | Size: 675 KiB |
BIN
public/assets/photos/DSC02693.JPG
Normal file
|
After Width: | Height: | Size: 689 KiB |
BIN
public/assets/photos/DSC02700.JPG
Normal file
|
After Width: | Height: | Size: 614 KiB |
BIN
public/assets/photos/DSC03612.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 10 MiB After Width: | Height: | Size: 895 KiB |
BIN
public/assets/photos/DSC08626.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 4.6 MiB After Width: | Height: | Size: 315 KiB |
BIN
public/assets/photos/DSC08641.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 4.4 MiB After Width: | Height: | Size: 346 KiB |
BIN
public/assets/photos/DSC08645.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 5.1 MiB After Width: | Height: | Size: 404 KiB |
BIN
public/assets/photos/DSC08649.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 4.0 MiB After Width: | Height: | Size: 248 KiB |
BIN
public/assets/photos/DSC08653.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 7.2 MiB After Width: | Height: | Size: 664 KiB |
BIN
public/assets/photos/DSC08744.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 8.0 MiB After Width: | Height: | Size: 633 KiB |
BIN
public/assets/photos/DSC08753.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 7.2 MiB After Width: | Height: | Size: 543 KiB |
BIN
public/assets/photos/DSC09945.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 5.9 MiB After Width: | Height: | Size: 468 KiB |
BIN
public/assets/photos/DSC09951.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 5.9 MiB After Width: | Height: | Size: 492 KiB |
BIN
public/assets/photos/DSC09953.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 4.7 MiB After Width: | Height: | Size: 384 KiB |
BIN
public/assets/photos/DSC09955.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 4.0 MiB After Width: | Height: | Size: 317 KiB |
BIN
public/assets/photos/DSC09960.JPG
Executable file → Normal file
|
Before Width: | Height: | Size: 4.6 MiB After Width: | Height: | Size: 328 KiB |
BIN
public/assets/photos/IMG_6070.jpg
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
public/assets/photos/IMG_6083.jpg
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
public/assets/photos/IMG_6100.jpg
Normal file
|
After Width: | Height: | Size: 1.0 MiB |