Compare commits

...

39 Commits

Author SHA1 Message Date
d63f196693 chore(content): remove team statistics section from about page
All checks were successful
CI - Lint, Typecheck & Test / quality-assurance (pull_request) Successful in 2m32s
Build & Deploy / 🔍 Prepare (push) Successful in 27s
Build & Deploy / 🧪 QA (push) Successful in 1m33s
Build & Deploy / 🏗️ Build (push) Successful in 2m34s
Build & Deploy / 🚀 Deploy (push) Successful in 29s
Build & Deploy / 🔔 Notify (push) Successful in 2s
Build & Deploy / 🧪 Post-Deploy Verification (push) Successful in 1m3s
2026-06-15 15:13:20 +02:00
6092f1d827 fix(tests): update english terms path from terms.mdx to agb.mdx
Some checks failed
CI - Lint, Typecheck & Test / quality-assurance (pull_request) Has been cancelled
Build & Deploy / 🔍 Prepare (push) Successful in 21s
Build & Deploy / 🧪 QA (push) Successful in 56s
Build & Deploy / 🏗️ Build (push) Successful in 1m37s
Build & Deploy / 🚀 Deploy (push) Successful in 27s
Build & Deploy / 🧪 Post-Deploy Verification (push) Successful in 42s
Build & Deploy / 🔔 Notify (push) Successful in 2s
2026-06-15 14:55:48 +02:00
766c385704 fix(content): replace video hero with image hero on messen pages
Some checks failed
CI - Lint, Typecheck & Test / quality-assurance (pull_request) Failing after 58s
Build & Deploy / 🔍 Prepare (push) Successful in 22s
Build & Deploy / 🧪 QA (push) Failing after 59s
Build & Deploy / 🏗️ Build (push) Has been skipped
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 1s
2026-06-15 14:42:56 +02:00
6c9d2b6832 fix(content): update images and review feedback
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 21s
CI - Lint, Typecheck & Test / quality-assurance (pull_request) Failing after 59s
Build & Deploy / 🧪 QA (push) Failing after 49s
Build & Deploy / 🏗️ Build (push) Has been skipped
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 1s
2026-06-15 13:54:57 +02:00
7a9d4d7f18 fix(content): Update URL for Werkstatt Kabel 2026
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Failing after 49s
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🏗️ Build (push) Has been skipped
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 1s
2026-06-15 13:41:03 +02:00
0b9929c2ec fix(content): Address all user review feedback
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 22s
Build & Deploy / 🧪 QA (push) Failing after 50s
Build & Deploy / 🏗️ Build (push) Has been skipped
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 2s
- Replace Mitarbeiter with Mitarbeitenden
- Add specialization sentence to Kabeltiefbau
- Update Werkstatt Kabel link
- Add Karriere to main navigation
- Add Referenzen to Footer
- Fix 404 for EN legal pages by using consistent internal slugs
2026-06-15 13:38:52 +02:00
aa0dfdf331 fix: refactor standorte detail page layout to match standard mdx pages and fix bohrtechnik links
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 34s
Build & Deploy / 🧪 QA (push) Successful in 1m10s
Build & Deploy / 🏗️ Build (push) Successful in 2m13s
Build & Deploy / 🚀 Deploy (push) Successful in 27s
Build & Deploy / 🧪 Post-Deploy Verification (push) Successful in 45s
Build & Deploy / 🔔 Notify (push) Successful in 2s
2026-06-15 11:26:09 +02:00
4c9028f58b feat(map): separate standorte and project map variants
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 24s
Build & Deploy / 🧪 QA (push) Successful in 56s
Build & Deploy / 🏗️ Build (push) Successful in 1m36s
Build & Deploy / 🚀 Deploy (push) Successful in 25s
Build & Deploy / 🧪 Post-Deploy Verification (push) Successful in 42s
Build & Deploy / 🔔 Notify (push) Successful in 2s
2026-06-15 00:19:56 +02:00
9de5f2938b fix(map): include standorteLocations in md pages
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 21s
Build & Deploy / 🧪 QA (push) Successful in 56s
Build & Deploy / 🏗️ Build (push) Successful in 1m35s
Build & Deploy / 🚀 Deploy (push) Successful in 26s
Build & Deploy / 🧪 Post-Deploy Verification (push) Successful in 43s
Build & Deploy / 🔔 Notify (push) Successful in 2s
2026-06-15 00:02:20 +02:00
de41a0e29d fix(nav): simplify standorte in dropdown
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 21s
Build & Deploy / 🧪 QA (push) Successful in 1m7s
Build & Deploy / 🏗️ Build (push) Successful in 2m6s
Build & Deploy / 🚀 Deploy (push) Successful in 26s
Build & Deploy / 🧪 Post-Deploy Verification (push) Successful in 43s
Build & Deploy / 🔔 Notify (push) Successful in 1s
2026-06-14 23:47:25 +02:00
6689dd3013 fix(standorte): fix layout and navigation structure
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 21s
Build & Deploy / 🧪 QA (push) Successful in 57s
Build & Deploy / 🏗️ Build (push) Successful in 2m6s
Build & Deploy / 🚀 Deploy (push) Successful in 25s
Build & Deploy / 🧪 Post-Deploy Verification (push) Successful in 42s
Build & Deploy / 🔔 Notify (push) Successful in 1s
2026-06-14 23:40:19 +02:00
31fbcb32dd feat(standorte): re-add kirchheilingen, add to dropdown, unify maps
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 21s
Build & Deploy / 🧪 QA (push) Successful in 56s
Build & Deploy / 🏗️ Build (push) Successful in 1m35s
Build & Deploy / 🚀 Deploy (push) Successful in 25s
Build & Deploy / 🧪 Post-Deploy Verification (push) Successful in 42s
Build & Deploy / 🔔 Notify (push) Successful in 1s
2026-06-14 23:23:31 +02:00
68eca73df2 fix: rename Bohrtechnik competence title, remove Kirchheilingen from standorte description, fix google maps lychee link
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 21s
Build & Deploy / 🧪 QA (push) Successful in 57s
Build & Deploy / 🏗️ Build (push) Successful in 1m44s
Build & Deploy / 🚀 Deploy (push) Successful in 25s
Build & Deploy / 🧪 Post-Deploy Verification (push) Successful in 43s
Build & Deploy / 🔔 Notify (push) Successful in 1s
2026-06-14 23:05:51 +02:00
3bb6eb3447 fix: revert bohrtechnik to competence link, remove kirchheilingen location
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Successful in 1m5s
Build & Deploy / 🏗️ Build (push) Successful in 2m11s
Build & Deploy / 🚀 Deploy (push) Successful in 33s
Build & Deploy / 🧪 Post-Deploy Verification (push) Successful in 42s
Build & Deploy / 🔔 Notify (push) Successful in 1s
2026-06-14 22:46:16 +02:00
a3c732dd13 fix: add individual standorte to header dropdown
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 44s
Build & Deploy / 🧪 QA (push) Successful in 1m6s
Build & Deploy / 🏗️ Build (push) Successful in 2m5s
Build & Deploy / 🚀 Deploy (push) Failing after 31s
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 1s
2026-06-14 22:33:33 +02:00
aaa1a8793c fix(types): resolve typecheck errors for SubCompanyTiles and standorteLocations
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Successful in 55s
Build & Deploy / 🏗️ Build (push) Successful in 1m40s
Build & Deploy / 🚀 Deploy (push) Successful in 24s
Build & Deploy / 🧪 Post-Deploy Verification (push) Successful in 41s
Build & Deploy / 🔔 Notify (push) Successful in 2s
2026-06-14 22:02:36 +02:00
233509db67 fix(links): update all maps and tiles to use standorte pages as single source of truth
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 43s
Build & Deploy / 🧪 QA (push) Failing after 1m5s
Build & Deploy / 🏗️ Build (push) Has been skipped
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 2s
2026-06-14 21:40:48 +02:00
17a807c48b feat: integrate standalone standorte pages with real photos and map routing
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 21s
Build & Deploy / 🧪 QA (push) Successful in 1m6s
Build & Deploy / 🏗️ Build (push) Successful in 1m35s
Build & Deploy / 🚀 Deploy (push) Successful in 25s
Build & Deploy / 🧪 Post-Deploy Verification (push) Successful in 41s
Build & Deploy / 🔔 Notify (push) Successful in 2s
2026-06-14 10:03:46 +02:00
d8634efa9a fix(ui): make reference slider tiles clickable links
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 22s
Build & Deploy / 🧪 QA (push) Successful in 55s
Build & Deploy / 🏗️ Build (push) Successful in 1m38s
Build & Deploy / 🚀 Deploy (push) Successful in 25s
Build & Deploy / 🧪 Post-Deploy Verification (push) Successful in 43s
Build & Deploy / 🔔 Notify (push) Successful in 1s
2026-06-14 09:52:11 +02:00
0f2aa500e9 test(smoke): fix ERR_ABORTED and form hydration timing
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 47s
Build & Deploy / 🧪 QA (push) Successful in 1m4s
Build & Deploy / 🏗️ Build (push) Successful in 2m5s
Build & Deploy / 🚀 Deploy (push) Successful in 25s
Build & Deploy / 🧪 Post-Deploy Verification (push) Successful in 41s
Build & Deploy / 🔔 Notify (push) Successful in 2s
2026-06-14 09:26:14 +02:00
2c465bc16b test(smoke): apply Gatekeeper Test Resilience standard
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 35s
Build & Deploy / 🧪 QA (push) Successful in 1m8s
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
Build & Deploy / 🏗️ Build (push) Has been cancelled
2026-06-14 09:23:48 +02:00
68717bf0ce chore: setup analytics, error tracking, and configure mailgun sender
All checks were successful
CI - Lint, Typecheck & Test / quality-assurance (pull_request) Successful in 1m39s
Build & Deploy / 🔍 Prepare (push) Successful in 22s
Build & Deploy / 🧪 QA (push) Successful in 1m6s
Build & Deploy / 🏗️ Build (push) Successful in 2m14s
Build & Deploy / 🚀 Deploy (push) Successful in 32s
Build & Deploy / 🧪 Post-Deploy Verification (push) Successful in 44s
Build & Deploy / 🔔 Notify (push) Successful in 2s
2026-06-13 22:55:34 +02:00
6444281c6f fix(mail): use E-TIB GmbH instead of KLZ Cables for confirmation emails
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 28s
CI - Lint, Typecheck & Test / quality-assurance (pull_request) Successful in 1m39s
Build & Deploy / 🧪 QA (push) Successful in 56s
Build & Deploy / 🏗️ Build (push) Successful in 2m7s
Build & Deploy / 🚀 Deploy (push) Successful in 31s
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 2s
2026-06-13 20:10:01 +02:00
4b98fa9b4c fix(map): update locations count to 3 & sync EN md structure
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 28s
CI - Lint, Typecheck & Test / quality-assurance (pull_request) Successful in 1m40s
Build & Deploy / 🧪 QA (push) Successful in 56s
Build & Deploy / 🏗️ Build (push) Successful in 2m5s
Build & Deploy / 🚀 Deploy (push) Successful in 31s
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 2s
2026-06-13 19:47:21 +02:00
fa4385af4c feat: Add historical data from 2016 to GrowthChart with i18n support
All checks were successful
CI - Lint, Typecheck & Test / quality-assurance (pull_request) Successful in 1m31s
Build & Deploy / 🔍 Prepare (push) Successful in 33s
Build & Deploy / 🧪 QA (push) Successful in 1m7s
Build & Deploy / 🏗️ Build (push) Successful in 2m5s
Build & Deploy / 🚀 Deploy (push) Successful in 51s
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 2s
2026-06-13 19:07:49 +02:00
d98eb20430 fix(content): sync English copy with recent German corrections
Some checks failed
CI - Lint, Typecheck & Test / quality-assurance (pull_request) Successful in 1m38s
Build & Deploy / 🔍 Prepare (push) Successful in 34s
Build & Deploy / 🧪 QA (push) Successful in 1m5s
Build & Deploy / 🏗️ Build (push) Successful in 2m6s
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
2026-06-13 19:02:16 +02:00
3cfe8ff379 fix(content): update copy as requested by user screenshots
Some checks failed
CI - Lint, Typecheck & Test / quality-assurance (pull_request) Successful in 1m30s
Build & Deploy / 🔍 Prepare (push) Successful in 21s
Build & Deploy / 🧪 QA (push) Successful in 1m5s
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
Build & Deploy / 🏗️ Build (push) Has been cancelled
2026-06-13 18:57:25 +02:00
2abcd386f0 feat(referenzen): implement smart metric cards and typography improvements
Some checks failed
CI - Lint, Typecheck & Test / quality-assurance (pull_request) Successful in 1m30s
Build & Deploy / 🔍 Prepare (push) Successful in 19s
Build & Deploy / 🧪 QA (push) Has started running
Build & Deploy / 🏗️ Build (push) Has been cancelled
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
2026-06-13 18:52:57 +02:00
d7ff6a3415 fix(map): update Kirchheilingen marker naming to exactly match requested text from email
Some checks failed
Build & Deploy / 🧪 QA (push) Has been cancelled
Build & Deploy / 🔍 Prepare (push) Has been cancelled
Build & Deploy / 🏗️ Build (push) Has been cancelled
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
CI - Lint, Typecheck & Test / quality-assurance (pull_request) Successful in 1m39s
2026-06-13 18:52:11 +02:00
d8f5d9bfc6 fix(data): update project quantities and totals from data sources
All checks were successful
CI - Lint, Typecheck & Test / quality-assurance (pull_request) Successful in 1m34s
Build & Deploy / 🔍 Prepare (push) Successful in 35s
Build & Deploy / 🧪 QA (push) Successful in 1m4s
Build & Deploy / 🏗️ Build (push) Successful in 2m6s
Build & Deploy / 🚀 Deploy (push) Successful in 25s
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 2s
2026-06-13 14:36:14 +02:00
f81a85fdd7 feat: Implement client feedback & visual verifications
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 30s
CI - Lint, Typecheck & Test / quality-assurance (pull_request) Successful in 1m41s
Build & Deploy / 🧪 QA (push) Successful in 57s
Build & Deploy / 🏗️ Build (push) Successful in 2m11s
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
Build & Deploy / 🚀 Deploy (push) Has been cancelled
- Update contact map container alignment
- Remove outdated marketing copy on service pages
- Update HDD specs to 400m / 600mm
- Unify reference slider titles globally
- Add employee breakdown stats to Über Uns page
2026-06-13 14:30:23 +02:00
4968315ebf fix(content): update stats, links, and design accents
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 29s
CI - Lint, Typecheck & Test / quality-assurance (pull_request) Successful in 1m42s
Build & Deploy / 🧪 QA (push) Successful in 57s
Build & Deploy / 🏗️ Build (push) Successful in 2m11s
Build & Deploy / 🚀 Deploy (push) Successful in 33s
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 1s
2026-06-13 12:08:59 +02:00
eaaa3b7251 fix(ci): clean up stray docker containers on ssh deploy to prevent network delete failure
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 28s
CI - Lint, Typecheck & Test / quality-assurance (pull_request) Successful in 1m36s
Build & Deploy / 🧪 QA (push) Successful in 55s
Build & Deploy / 🏗️ Build (push) Successful in 2m4s
Build & Deploy / 🚀 Deploy (push) Successful in 26s
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 1s
2026-06-13 10:22:22 +02:00
bbc8716da6 chore: retry deploy after network release
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 34s
CI - Lint, Typecheck & Test / quality-assurance (pull_request) Successful in 1m36s
Build & Deploy / 🧪 QA (push) Successful in 55s
Build & Deploy / 🏗️ Build (push) Successful in 2m11s
Build & Deploy / 🚀 Deploy (push) Failing after 29s
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 2s
2026-06-13 10:09:06 +02:00
f4d65452a6 chore: restrict build worker CPUs to 1 on CI to prevent OOM
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 23s
CI - Lint, Typecheck & Test / quality-assurance (pull_request) Successful in 1m39s
Build & Deploy / 🧪 QA (push) Successful in 55s
Build & Deploy / 🏗️ Build (push) Successful in 2m5s
Build & Deploy / 🚀 Deploy (push) Failing after 56s
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 1s
2026-06-13 09:16:20 +02:00
1b2e0793d3 chore: trigger rebuild
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 34s
Build & Deploy / 🧪 QA (push) Successful in 1m40s
CI - Lint, Typecheck & Test / quality-assurance (pull_request) Successful in 3m6s
Build & Deploy / 🏗️ Build (push) Failing after 15m43s
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
2026-06-13 02:35:20 +02:00
b378bb168f feat: implement visual feedback updates (team grid, contact maps, job titles, and interactive map link)
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 38s
Build & Deploy / 🧪 QA (push) Successful in 2m11s
CI - Lint, Typecheck & Test / quality-assurance (pull_request) Successful in 3m43s
Build & Deploy / 🏗️ Build (push) Failing after 13m14s
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
2026-06-12 19:17:13 +02:00
9134d6b070 feat(task-12): link Bohrtechnik to service pages and remove reference detailed links
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 36s
Build & Deploy / 🧪 QA (push) Successful in 2m7s
CI - Lint, Typecheck & Test / quality-assurance (pull_request) Successful in 3m31s
Build & Deploy / 🏗️ Build (push) Successful in 3m45s
Build & Deploy / 🚀 Deploy (push) Successful in 33s
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 4s
2026-06-10 11:39:38 +02:00
0105c8c9a3 feat(content): update website content for tasks 6-10 including competencies, team, references, and statistics
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 54s
Build & Deploy / 🧪 QA (push) Successful in 2m7s
CI - Lint, Typecheck & Test / quality-assurance (pull_request) Successful in 3m31s
Build & Deploy / 🏗️ Build (push) Successful in 3m47s
Build & Deploy / 🚀 Deploy (push) Successful in 34s
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 4s
2026-06-10 10:59:14 +02:00
110 changed files with 1498 additions and 784 deletions

8
.env
View File

@@ -1,5 +1,5 @@
# ============================================================================
# KLZ Cables - Environment Configuration
# E-TIB GmbH - Environment Configuration
# ============================================================================
# Copy this file to .env for local development
# For production, use .env.production as a template
@@ -20,14 +20,14 @@ NEXT_PUBLIC_RECORD_MODE_ENABLED=true
# Analytics (Umami)
# ────────────────────────────────────────────────────────────────────────────
# Optional: Leave empty to disable analytics
UMAMI_WEBSITE_ID=
UMAMI_WEBSITE_ID=d773ea10-a3b3-4ccf-9024-987e14c4d669
UMAMI_API_ENDPOINT=https://analytics.infra.mintel.me
# ────────────────────────────────────────────────────────────────────────────
# Error Tracking (GlitchTip/Sentry)
# ────────────────────────────────────────────────────────────────────────────
# Optional: Leave empty to disable error tracking
SENTRY_DSN=
SENTRY_DSN=https://dcb81958-dbf2-4a3d-b422-875f4672c14b@glitchtip.infra.mintel.me/5
# ────────────────────────────────────────────────────────────────────────────
# Email Configuration (SMTP)
@@ -37,7 +37,7 @@ MAIL_HOST=smtp.eu.mailgun.org
MAIL_PORT=587
MAIL_USERNAME=
MAIL_PASSWORD=
MAIL_FROM=KLZ Cables <noreply@e-tib.com>
MAIL_FROM=E-TIB GmbH <noreply@mg.mintel.me>
MAIL_RECIPIENTS=info@e-tib.com
# ────────────────────────────────────────────────────────────────────────────

View File

@@ -363,6 +363,7 @@ jobs:
env:
ENV_FILE: ${{ needs.prepare.outputs.env_file }}
run: |
SLUG=$(echo "${{ github.ref_name }}" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g' | sed 's/^-//;s/-$//')
mkdir -p ~/.ssh
echo "${{ secrets.ALPHA_SSH_KEY }}" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
@@ -375,7 +376,6 @@ jobs:
elif [[ "$TARGET" == "staging" ]]; then
SITE_DIR="/home/deploy/sites/staging.e-tib.com"
else
SLUG=$(echo "${{ github.ref_name }}" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g' | sed 's/^-//;s/-$//')
SITE_DIR="/home/deploy/sites/branch.e-tib.com/$SLUG"
fi
@@ -384,6 +384,7 @@ jobs:
scp docker-compose.yml root@alpha.mintel.me:$SITE_DIR/docker-compose.yml
ssh root@alpha.mintel.me "docker system prune -f"
ssh root@alpha.mintel.me "docker rm -f \$(docker ps -a -q --filter name=${SLUG}-etib-) 2>/dev/null || true"
ssh root@alpha.mintel.me "cd $SITE_DIR && echo '${{ secrets.REGISTRY_PASS }}' | docker login registry.infra.mintel.me -u '${{ secrets.REGISTRY_USER }}' --password-stdin"
ssh root@alpha.mintel.me "cd $SITE_DIR && docker compose -p '${{ needs.prepare.outputs.project_name }}' --env-file '$ENV_FILE' pull"
ssh root@alpha.mintel.me "cd $SITE_DIR && docker compose -p '${{ needs.prepare.outputs.project_name }}' --env-file '$ENV_FILE' up -d --remove-orphans"

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,21 @@
2019
Offener Tiefbau 32445 Meter
HDD 8505Meter
Kabelverlegung 87468 Meter
2020
Offener Tiefbau 31305 Meter
HDD 9050 Meter
Kabelverlegung 93556 Meter
2021
Offener Tiefbau 38756 Meter
HDD 10957 Meter
Kabelverlegung 110127 Meter

Binary file not shown.

View File

@@ -0,0 +1,8 @@
2022
Offener Tiefbau 41445 Meter
HDD 9505Meter
Kabelverlegung 102468 Meter

View File

@@ -0,0 +1 @@
{"files":{".turbo/turbo-test.log":{"size":2776,"mtime_nanos":1781469605328811961,"mode":420,"is_dir":false}},"order":[".turbo/turbo-test.log"]}

View File

@@ -0,0 +1 @@
{"hash":"41698960411f6bf6","duration":4168,"sha":"a3c732dd133b1b8261b19cf64b3bf684e269e839","dirty_hash":"1ef3b75af417f41468b9558671572e75e0fc055f9dbe6e805cfa6f59b1cddf70"}

Binary file not shown.

View File

@@ -0,0 +1 @@
{"files":{".turbo/turbo-lint.log":{"size":12987,"mtime_nanos":1781469609469080321,"mode":420,"is_dir":false}},"order":[".turbo/turbo-lint.log"]}

View File

@@ -0,0 +1 @@
{"hash":"bb46018d4a7bc516","duration":8307,"sha":"a3c732dd133b1b8261b19cf64b3bf684e269e839","dirty_hash":"1ef3b75af417f41468b9558671572e75e0fc055f9dbe6e805cfa6f59b1cddf70"}

Binary file not shown.

View File

@@ -0,0 +1 @@
{"files":{".turbo/turbo-typecheck.log":{"size":85,"mtime_nanos":1781469608726900998,"mode":420,"is_dir":false}},"order":[".turbo/turbo-typecheck.log"]}

View File

@@ -0,0 +1 @@
{"hash":"eb4eeeb717c1af0c","duration":7565,"sha":"a3c732dd133b1b8261b19cf64b3bf684e269e839","dirty_hash":"1ef3b75af417f41468b9558671572e75e0fc055f9dbe6e805cfa6f59b1cddf70"}

Binary file not shown.

View File

@@ -2,128 +2,4 @@
> e-tib-nextjs@2.2.12 lint /Volumes/Alpha SSD/Coding/e-tib.com
> eslint .
/Volumes/Alpha SSD/Coding/e-tib.com/app/[locale]/[slug]/page.tsx
1:20 warning 'redirect' is defined but never used @typescript-eslint/no-unused-vars
75:24 warning Using `<img>` could result in slower LCP and higher bandwidth. Consider using `<Image />` from `next/image` or a custom image loader to automatically optimize images. This may incur additional usage or cost from your provider. See: https://nextjs.org/docs/messages/no-img-element @next/next/no-img-element
/Volumes/Alpha SSD/Coding/e-tib.com/app/[locale]/blog/[slug]/page.tsx
1:20 warning 'redirect' is defined but never used @typescript-eslint/no-unused-vars
39:24 warning Using `<img>` could result in slower LCP and higher bandwidth. Consider using `<Image />` from `next/image` or a custom image loader to automatically optimize images. This may incur additional usage or cost from your provider. See: https://nextjs.org/docs/messages/no-img-element @next/next/no-img-element
/Volumes/Alpha SSD/Coding/e-tib.com/app/[locale]/error.tsx
7:30 warning 'AlertTriangle' is defined but never used @typescript-eslint/no-unused-vars
/Volumes/Alpha SSD/Coding/e-tib.com/app/[locale]/not-found.tsx
6:10 warning 'Terminal' is defined but never used @typescript-eslint/no-unused-vars
/Volumes/Alpha SSD/Coding/e-tib.com/app/[locale]/referenzen/[slug]/page.tsx
92:26 warning Using `<img>` could result in slower LCP and higher bandwidth. Consider using `<Image />` from `next/image` or a custom image loader to automatically optimize images. This may incur additional usage or cost from your provider. See: https://nextjs.org/docs/messages/no-img-element @next/next/no-img-element
/Volumes/Alpha SSD/Coding/e-tib.com/app/[locale]/referenzen/page.tsx
1:21 warning 'Heading' is defined but never used @typescript-eslint/no-unused-vars
1:30 warning 'Badge' is defined but never used @typescript-eslint/no-unused-vars
/Volumes/Alpha SSD/Coding/e-tib.com/components/JsonLd.tsx
1:30 warning 'Graph' is defined but never used @typescript-eslint/no-unused-vars
43:31 warning '_' is assigned a value but never used @typescript-eslint/no-unused-vars
48:29 warning '_' is assigned a value but never used @typescript-eslint/no-unused-vars
/Volumes/Alpha SSD/Coding/e-tib.com/components/blocks/CertificatesBlock.tsx
6:10 warning 'Button' is defined but never used @typescript-eslint/no-unused-vars
9:10 warning 'FileText' is defined but never used @typescript-eslint/no-unused-vars
102:5 warning Error: Calling setState synchronously within an effect can trigger cascading renders
Effects are intended to synchronize state between React and external systems such as manually updating the DOM, state management libraries, or other platform APIs. In general, the body of an effect should do one or both of the following:
* Update external systems with the latest state from React.
* Subscribe for updates from some external system, calling setState in a callback function when external state changes.
Calling setState synchronously within an effect body causes cascading renders that can hurt performance, and is not recommended. (https://react.dev/learn/you-might-not-need-an-effect).
/Volumes/Alpha SSD/Coding/e-tib.com/components/blocks/CertificatesBlock.tsx:102:5
100 |
101 | useEffect(() => {
> 102 | setIsMounted(true);
| ^^^^^^^^^^^^ Avoid calling setState() directly within an effect
103 | }, []);
104 |
105 | const badgeText = badge || 'Zertifizierungen & Nachweise'; react-hooks/set-state-in-effect
/Volumes/Alpha SSD/Coding/e-tib.com/components/blocks/CompetenceBentoGrid.tsx
53:5 warning Error: Calling setState synchronously within an effect can trigger cascading renders
Effects are intended to synchronize state between React and external systems such as manually updating the DOM, state management libraries, or other platform APIs. In general, the body of an effect should do one or both of the following:
* Update external systems with the latest state from React.
* Subscribe for updates from some external system, calling setState in a callback function when external state changes.
Calling setState synchronously within an effect body causes cascading renders that can hurt performance, and is not recommended. (https://react.dev/learn/you-might-not-need-an-effect).
/Volumes/Alpha SSD/Coding/e-tib.com/components/blocks/CompetenceBentoGrid.tsx:53:5
51 |
52 | useEffect(() => {
> 53 | setIsMounted(true);
| ^^^^^^^^^^^^ Avoid calling setState() directly within an effect
54 | }, []);
55 |
56 | const badge = props.badge || data?.badge || 'Leistungsspektrum'; react-hooks/set-state-in-effect
/Volumes/Alpha SSD/Coding/e-tib.com/components/blocks/HeroVideo.tsx
5:18 warning 'AnimatePresence' is defined but never used @typescript-eslint/no-unused-vars
6:10 warning 'useState' is defined but never used @typescript-eslint/no-unused-vars
6:20 warning 'useEffect' is defined but never used @typescript-eslint/no-unused-vars
45:12 warning 'e' is defined but never used @typescript-eslint/no-unused-vars
/Volumes/Alpha SSD/Coding/e-tib.com/components/blocks/InteractiveGermanyMap.tsx
5:18 warning 'Factory' is defined but never used @typescript-eslint/no-unused-vars
5:27 warning 'Zap' is defined but never used @typescript-eslint/no-unused-vars
53:9 warning 'hq' is assigned a value but never used @typescript-eslint/no-unused-vars
54:9 warning 'branch' is assigned a value but never used @typescript-eslint/no-unused-vars
55:9 warning 'projects' is assigned a value but never used @typescript-eslint/no-unused-vars
56:9 warning 'minorNodes' is assigned a value but never used @typescript-eslint/no-unused-vars
/Volumes/Alpha SSD/Coding/e-tib.com/components/blocks/ReferencesSlider.test.tsx
5:10 warning 'NextIntlClientProvider' is defined but never used @typescript-eslint/no-unused-vars
21:12 warning Using `<img>` could result in slower LCP and higher bandwidth. Consider using `<Image />` from `next/image` or a custom image loader to automatically optimize images. This may incur additional usage or cost from your provider. See: https://nextjs.org/docs/messages/no-img-element @next/next/no-img-element
/Volumes/Alpha SSD/Coding/e-tib.com/components/blocks/TeamGridBlock.tsx
20:39 warning 'title' is defined but never used. Allowed unused args must match /^_/u @typescript-eslint/no-unused-vars
20:46 warning 'department' is defined but never used. Allowed unused args must match /^_/u @typescript-eslint/no-unused-vars
20:58 warning 'showContact' is assigned a value but never used. Allowed unused args must match /^_/u @typescript-eslint/no-unused-vars
/Volumes/Alpha SSD/Coding/e-tib.com/components/decorations/CorporateBackground.tsx
36:13 warning 'distance' is assigned a value but never used @typescript-eslint/no-unused-vars
/Volumes/Alpha SSD/Coding/e-tib.com/components/home/Hero.tsx
9:39 warning 'useCallback' is defined but never used @typescript-eslint/no-unused-vars
77:6 warning React Hook useEffect has missing dependencies: 'HERO_PLACEHOLDERS' and 't'. Either include them or remove the dependency array react-hooks/exhaustive-deps
/Volumes/Alpha SSD/Coding/e-tib.com/components/home/MeetTheTeam.tsx
8:9 warning 'teamT' is assigned a value but never used @typescript-eslint/no-unused-vars
/Volumes/Alpha SSD/Coding/e-tib.com/components/layout/Footer.tsx
4:35 warning 'Accessibility' is defined but never used @typescript-eslint/no-unused-vars
/Volumes/Alpha SSD/Coding/e-tib.com/components/providers/InitialLoader.tsx
5:8 warning 'Image' is defined but never used @typescript-eslint/no-unused-vars
/Volumes/Alpha SSD/Coding/e-tib.com/components/providers/PageTransitionShutter.tsx
6:8 warning 'Image' is defined but never used @typescript-eslint/no-unused-vars
/Volumes/Alpha SSD/Coding/e-tib.com/components/search/AIOrb.tsx
153:13 warning 'breathe' is assigned a value but never used @typescript-eslint/no-unused-vars
212:15 warning 'targetExcite' is assigned a value but never used @typescript-eslint/no-unused-vars
/Volumes/Alpha SSD/Coding/e-tib.com/components/search/AISearchResults.tsx
100:6 warning React Hook useEffect has missing dependencies: 'handleSearch' and 'initialQuery'. Either include them or remove the dependency array react-hooks/exhaustive-deps
/Volumes/Alpha SSD/Coding/e-tib.com/components/ui/AnimatedCounter.tsx
3:28 warning 'useState' is defined but never used @typescript-eslint/no-unused-vars
/Volumes/Alpha SSD/Coding/e-tib.com/lib/blog.ts
6:7 warning 'BLOG_DIR' is assigned a value but never used @typescript-eslint/no-unused-vars
94:7 warning 'next' is never reassigned. Use 'const' instead prefer-const
95:7 warning 'prev' is never reassigned. Use 'const' instead prefer-const
✖ 45 problems (0 errors, 45 warnings)
0 errors and 2 warnings potentially fixable with the `--fix` option.
ELIFECYCLE Command failed.

View File

@@ -5,27 +5,51 @@
 RUN  v4.1.2 /Volumes/Alpha SSD/Coding/e-tib.com
✓ tests/mdx-links.test.ts (1 test) 4ms
✓ lib/mail/mailer.test.ts (1 test) 2ms
✓ lib/env.test.ts (6 tests) 6ms
(node:64961) [DEP0205] DeprecationWarning: `module.register()` is deprecated. Use `module.registerHooks()` instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
✓ tests/mdx-links.test.ts (1 test) 29ms
✓ tests/homepage-and-competence-content.test.ts (4 tests) 14ms
 tests/legal-pages.test.ts (2 tests | 1 failed) 9ms
✓ should contain highly professional B2B sections in German AGB 5ms
 × should contain professional corresponding B2B sections in English Terms 2ms
✓ tests/task-12-links.test.ts (2 tests) 8ms
✓ tests/messen-content.test.ts (2 tests) 8ms
✓ lib/mail/mailer.test.ts (1 test) 7ms
stderr | components/layout/LanguageSwitcher.test.tsx > LanguageSwitcher TDD > translates /en/trade-fairs to /de/messen when switching to German
React does not recognize the `transitionMessage` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `transitionmessage` instead. If you accidentally passed it from a parent component, remove it from the DOM element.
✓ components/layout/LanguageSwitcher.test.tsx (5 tests) 21ms
✓ components/search/AISearchResults.test.tsx (1 test) 26ms
✓ components/layout/LanguageSwitcher.test.tsx (5 tests) 25ms
✓ components/search/AISearchResults.test.tsx (1 test) 52ms
stderr | components/blocks/ReferencesSlider.test.tsx > ReferencesSlider TDD > renders reference tiles correctly
Received `true` for a non-boolean attribute `fill`.
If you want to write it to the DOM, pass a string instead: fill="true" or fill={value.toString()}.
✓ components/blocks/ReferencesSlider.test.tsx (4 tests) 40ms
✓ components/blocks/ReferencesSlider.test.tsx (2 tests) 43ms
✓ lib/env.test.ts (6 tests) 4ms
stdout | app/[locale]/referenzen/[slug]/page.test.tsx
[Config] Initializing Toggles: { feedbackEnabled: false }
✓ app/[locale]/referenzen/[slug]/page.test.tsx (1 test) 6ms
✓ app/[locale]/referenzen/[slug]/page.test.tsx (1 test) 26ms
 Test Files  7 passed (7)
 Tests  19 passed (19)
 Start at  14:12:48
 Duration  1.80s (transform 863ms, setup 0ms, import 2.94s, tests 105ms, environment 3.18s)
⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯
 FAIL  tests/legal-pages.test.ts > Legal Pages Content Validation > should contain professional corresponding B2B sections in English Terms
Error: ENOENT: no such file or directory, open '/Volumes/Alpha SSD/Coding/e-tib.com/content/en/terms.mdx'
  tests/legal-pages.test.ts:25:24
 23|
 24| it('should contain professional corresponding B2B sections in Englis…
 25| const content = fs.readFileSync(enTermsPath, 'utf8');
 | ^
 26|
 27| expect(content).toContain('title: "Terms and Conditions"');
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯
 Test Files  1 failed | 10 passed (11)
 Tests  1 failed | 26 passed (27)
 Start at  14:54:33
 Duration  5.94s (transform 5.27s, setup 0ms, import 9.43s, tests 222ms, environment 13.80s)
ELIFECYCLE Test failed. See above for more details.

View File

@@ -2,3 +2,4 @@
> e-tib-nextjs@2.2.12 typecheck /Volumes/Alpha SSD/Coding/e-tib.com
> tsc --noEmit
ELIFECYCLE Command failed.

BIN
after-login.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 KiB

View File

@@ -10,7 +10,6 @@ import TrackedLink from '@/components/analytics/TrackedLink';
import { getButtonClasses, ButtonOverlay } from '@/components/ui/Button';
import { getAllReferences } from '@/lib/references';
import { defaultLocations, minorLocations } from '@/lib/map-data';
// Import components used in MDX
import { HeroVideo as HomeHero } from '@/components/blocks/HeroVideo';
import { SubCompanyTiles as HomeSubCompanyTiles } from '@/components/blocks/SubCompanyTiles';

View File

@@ -93,13 +93,18 @@ export default async function Layout(props: {
children: [
{ label: safeLocale === 'de' ? 'Firma' : 'Company', url: `/${safeLocale}/${await mapFileSlugToTranslated('ueber-uns', safeLocale)}` },
{ label: safeLocale === 'de' ? 'Unser Team' : 'Our Team', url: `/${safeLocale}/team` },
{ label: safeLocale === 'de' ? 'Zertifikate' : 'Certificates', url: `/${safeLocale}/zertifikate` }
{ label: safeLocale === 'de' ? 'Zertifikate' : 'Certificates', url: `/${safeLocale}/zertifikate` },
{ label: safeLocale === 'de' ? 'Standorte' : 'Locations', url: `/${safeLocale}/standorte` }
]
},
{
label: safeLocale === 'de' ? 'Referenzen' : 'References',
url: `/${safeLocale}/referenzen`
},
{
label: safeLocale === 'de' ? 'Karriere' : 'Career',
url: `/${safeLocale}/${safeLocale === 'de' ? 'karriere' : 'career'}`
},
{
label: safeLocale === 'de' ? 'Messen' : 'Events',
url: `/${safeLocale}/${await mapFileSlugToTranslated('messen', safeLocale)}`
@@ -130,6 +135,7 @@ export default async function Layout(props: {
'CompanyTimeline',
'TeamGrid',
'AISearch',
'GrowthChart',
];
const clientMessages: Record<string, any> = {};
for (const key of clientKeys) {

View File

@@ -67,22 +67,48 @@ export default async function ReferenceDetail(props: { params: Promise<{ locale:
const mdxComponents = {
Heading,
h1: (props: any) => <Heading level={1} size="2" className="hidden" {...props} />, // Hidden because Hero handles H1
h2: (props: any) => <Heading level={2} size="3" className="mt-16 mb-6 border-b border-neutral-100 pb-4" {...props} />,
h2: (props: any) => <Heading level={2} size="3" className="mt-16 mb-6 border-b border-neutral-100 pb-4 text-neutral-dark" {...props} />,
h3: (props: any) => <Heading level={3} size="4" className="mt-12 mb-4 text-primary" {...props} />,
h4: (props: any) => <Heading level={4} size="5" className="mt-8 mb-4 uppercase tracking-widest text-neutral-500" {...props} />,
p: (props: any) => <p className="text-base md:text-lg text-text-secondary leading-[1.8] mb-6 font-medium max-w-3xl" {...props} />,
ul: (props: any) => <ul className="grid grid-cols-1 md:grid-cols-2 gap-4 my-12" {...props} />,
ul: (props: any) => <ul className="grid grid-cols-1 md:grid-cols-2 gap-4 md:gap-6 my-12" {...props} />,
ol: (props: any) => <ol className="list-decimal pl-6 mb-8 space-y-3 text-base md:text-lg text-text-secondary font-medium max-w-3xl" {...props} />,
li: (props: any) => (
<li className="bg-neutral-50 p-6 rounded-2xl border border-neutral-100 flex items-start gap-4 hover:shadow-md transition-shadow group" {...props}>
<div className="w-6 h-6 rounded-full bg-primary/10 flex items-center justify-center shrink-0 mt-0.5 group-hover:bg-primary/20 transition-colors">
<svg className="w-3.5 h-3.5 text-primary" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={3}>
<path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" />
</svg>
</div>
<span className="text-neutral-700 font-semibold leading-snug">{props.children}</span>
</li>
),
li: (props: any) => {
// Smart Metric Card Logic
let text = '';
if (typeof props.children === 'string') {
text = props.children;
} else if (Array.isArray(props.children)) {
text = props.children.map((c: any) => typeof c === 'string' ? c : '').join('');
}
const match = text.match(/^([\d.,]+)\s*(m|Satz|Stück|km|kV|Fasern)\b(.*)/);
if (match && typeof props.children === 'string') {
const [, value, unit, rest] = match;
return (
<li className="bg-white p-6 md:p-8 rounded-3xl border border-neutral-100 flex flex-col justify-center hover:shadow-[0_20px_40px_-15px_rgba(0,0,0,0.05)] hover:border-primary/30 transition-all duration-500 group hover:-translate-y-1 relative overflow-hidden">
<div className="absolute top-0 right-0 w-32 h-32 bg-gradient-to-bl from-neutral-50 to-transparent rounded-bl-full -z-10 group-hover:from-primary/5 transition-colors duration-500" />
<div className="flex items-baseline gap-2 mb-3">
<span className="text-4xl md:text-5xl font-bold font-heading text-primary tracking-tight">{value}</span>
<span className="text-lg md:text-xl font-bold text-neutral-400">{unit}</span>
</div>
<span className="text-neutral-600 font-semibold text-sm md:text-base leading-snug">{rest.replace(/^[\s-]*\s/, '')}</span>
</li>
);
}
return (
<li className="bg-neutral-50 p-6 rounded-3xl border border-neutral-100 flex items-start gap-4 hover:shadow-md transition-all duration-300 group hover:-translate-y-1">
<div className="w-8 h-8 rounded-full bg-primary/10 flex items-center justify-center shrink-0 mt-0.5 group-hover:bg-primary/20 transition-colors">
<svg className="w-4 h-4 text-primary" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={3}>
<path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" />
</svg>
</div>
<span className="text-neutral-700 font-semibold leading-relaxed">{props.children}</span>
</li>
);
},
a: (props: any) => <a className="text-primary hover:text-primary-dark underline decoration-primary/30 underline-offset-4 hover:decoration-primary transition-all font-bold" {...props} />,
strong: (props: any) => <strong className="font-bold text-neutral-900" {...props} />,
blockquote: (props: any) => (
@@ -95,62 +121,62 @@ export default async function ReferenceDetail(props: { params: Promise<{ locale:
return (
<div className="flex flex-col min-h-screen bg-white">
{/* Hero Section */}
<section className="bg-[#050B14] text-white pt-40 pb-16 md:pt-48 md:pb-20 min-h-[35vh] flex flex-col justify-end relative overflow-hidden">
<section className="bg-[#050B14] text-white pt-40 pb-16 md:pt-52 md:pb-24 min-h-[45vh] flex flex-col justify-end relative overflow-hidden">
{reference.frontmatter.featuredImage && (
<div className="absolute inset-0 z-0">
<Image
src={reference.frontmatter.featuredImage}
alt={reference.frontmatter.title}
fill
className="object-cover opacity-25 mix-blend-luminosity scale-105"
className="object-cover opacity-30 mix-blend-luminosity scale-105"
priority
/>
<div className="absolute inset-0 bg-gradient-to-t from-[#050B14] via-[#050B14]/60 to-transparent" />
<div className="absolute inset-0 bg-gradient-to-r from-[#050B14] via-transparent to-transparent" />
<div className="absolute inset-0 bg-gradient-to-t from-[#050B14] via-[#050B14]/70 to-transparent" />
<div className="absolute inset-0 bg-gradient-to-r from-[#050B14] via-[#050B14]/40 to-transparent" />
</div>
)}
<div className="absolute inset-0 opacity-20 z-0">
<div className="absolute inset-0 opacity-20 z-0 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-primary/30 via-transparent to-transparent" />
</div>
<Container className="relative z-10">
<div className="mb-12">
<TrackedLink
href={`/${locale}/referenzen`}
className="inline-flex items-center gap-2 text-white/60 hover:text-white transition-colors"
className="inline-flex items-center gap-2 text-white/60 hover:text-white transition-colors uppercase tracking-widest text-xs font-bold"
eventProperties={{ location: 'reference_back_btn' }}
>
<ChevronLeft className="w-5 h-5" />
<ChevronLeft className="w-4 h-4" />
{t('backToOverview')}
</TrackedLink>
</div>
<div className="max-w-4xl">
<Badge variant="accent" className="mb-4 md:mb-6">
<div className="max-w-5xl">
<Badge variant="accent" className="mb-6">
{t('projectReference')}
</Badge>
<Heading level={1} variant="white" className="mb-8 leading-tight">
<Heading level={1} variant="white" className="mb-10 leading-[1.1] md:text-6xl lg:text-7xl drop-shadow-lg">
{reference.frontmatter.title}
</Heading>
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 mt-12">
<div className="flex items-start gap-4 p-6 bg-white/5 rounded-2xl border border-white/10 backdrop-blur-sm">
<MapPin className="w-8 h-8 text-primary shrink-0" />
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 md:gap-6 mt-12 md:mt-16">
<div className="flex items-start gap-4 p-6 md:p-8 bg-white/5 rounded-3xl border border-white/10 backdrop-blur-md transition-all hover:bg-white/10">
<MapPin className="w-8 h-8 text-primary shrink-0 opacity-80" />
<div>
<p className="text-sm text-white/50 mb-1 uppercase tracking-wider font-bold">{t('location')}</p>
<p className="font-semibold text-lg">{reference.frontmatter.location}</p>
<p className="text-xs text-white/50 mb-1.5 uppercase tracking-widest font-bold">{t('location')}</p>
<p className="font-semibold text-lg md:text-xl text-white/90">{reference.frontmatter.location}</p>
</div>
</div>
<div className="flex items-start gap-4 p-6 bg-white/5 rounded-2xl border border-white/10 backdrop-blur-sm">
<Briefcase className="w-8 h-8 text-primary shrink-0" />
<div className="flex items-start gap-4 p-6 md:p-8 bg-white/5 rounded-3xl border border-white/10 backdrop-blur-md transition-all hover:bg-white/10">
<Briefcase className="w-8 h-8 text-primary shrink-0 opacity-80" />
<div>
<p className="text-sm text-white/50 mb-1 uppercase tracking-wider font-bold">{t('client')}</p>
<p className="font-semibold text-lg">{reference.frontmatter.client}</p>
<p className="text-xs text-white/50 mb-1.5 uppercase tracking-widest font-bold">{t('client')}</p>
<p className="font-semibold text-lg md:text-xl text-white/90 line-clamp-2">{reference.frontmatter.client}</p>
</div>
</div>
<div className="flex items-start gap-4 p-6 bg-white/5 rounded-2xl border border-white/10 backdrop-blur-sm">
<Calendar className="w-8 h-8 text-primary shrink-0" />
<div className="flex items-start gap-4 p-6 md:p-8 bg-white/5 rounded-3xl border border-white/10 backdrop-blur-md transition-all hover:bg-white/10">
<Calendar className="w-8 h-8 text-primary shrink-0 opacity-80" />
<div>
<p className="text-sm text-white/50 mb-1 uppercase tracking-wider font-bold">{t('period')}</p>
<p className="font-semibold text-lg">{reference.frontmatter.dateString || new Date(reference.frontmatter.date).getFullYear()}</p>
<p className="text-xs text-white/50 mb-1.5 uppercase tracking-widest font-bold">{t('period')}</p>
<p className="font-semibold text-lg md:text-xl text-white/90">{reference.frontmatter.dateString || new Date(reference.frontmatter.date).getFullYear()}</p>
</div>
</div>
</div>

View File

@@ -3,7 +3,7 @@ import { getTranslations, setRequestLocale } from 'next-intl/server';
import { Metadata } from 'next';
import { getAllReferences } from '@/lib/references';
import TrackedLink from '@/components/analytics/TrackedLink';
import { MapPin, Calendar, Briefcase, ArrowUpRight } from 'lucide-react';
import { MapPin, Calendar, Briefcase } from 'lucide-react';
import { getButtonClasses, ButtonOverlay } from '@/components/ui/Button';
import { SITE_URL } from '@/lib/schema';
import Image from 'next/image';
@@ -77,7 +77,7 @@ export default async function ReferenzenOverview(props: { params: Promise<{ loca
isHero={true}
badge={locale === 'en' ? 'Our References' : 'Unsere Referenzen'}
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. Discover our locations.' : 'Vom Breitbandausbau bis zur komplexen 110kV-Trasse: Ein Auszug unserer bundesweiten Projekte, bei denen wir Infrastruktur für die Zukunft geschaffen haben. Entdecken Sie unsere Standorte.'}
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}
/>
@@ -88,11 +88,8 @@ export default async function ReferenzenOverview(props: { params: Promise<{ loca
<TrackedLink
key={ref.slug}
href={`/${locale}/referenzen/${ref.slug}`}
className="group flex flex-col bg-white border border-neutral-100 rounded-3xl overflow-hidden shadow-sm hover:shadow-2xl transition-all duration-300 transform hover:-translate-y-2"
eventProperties={{
location: 'referenzen_grid',
target_slug: ref.slug,
}}
eventProperties={{ location: 'reference_list_card', slug: ref.slug }}
className="group flex flex-col bg-white border border-neutral-100 rounded-3xl overflow-hidden shadow-sm hover:shadow-2xl transition-all duration-300 transform hover:-translate-y-1 cursor-pointer block"
>
<div className="flex flex-col h-full relative">
{/* Image Section */}
@@ -102,14 +99,14 @@ export default async function ReferenzenOverview(props: { params: Promise<{ loca
src={ref.frontmatter.featuredImage}
alt={ref.frontmatter.title}
fill
className="object-cover group-hover:scale-105 transition-transform duration-1000 ease-[cubic-bezier(0.16,1,0.3,1)] filter grayscale-[20%] group-hover:grayscale-0"
className="object-cover transition-transform duration-1000 ease-[cubic-bezier(0.16,1,0.3,1)] filter grayscale-[20%]"
/>
) : (
<div className="absolute inset-0 bg-[#f4f4f5] flex items-center justify-center">
<Image src="/assets/logo.png" alt="E-TIB Logo" width={80} height={80} className="opacity-20 grayscale" />
</div>
)}
<div className="absolute inset-0 bg-black/5 group-hover:bg-transparent transition-colors duration-500" />
<div className="absolute inset-0 bg-black/5 transition-colors duration-500" />
{/* Location Badge */}
<div className="absolute top-4 left-4 z-10">
@@ -122,12 +119,12 @@ export default async function ReferenzenOverview(props: { params: Promise<{ loca
{/* Content Section */}
<div className="flex flex-col flex-grow p-6 md:p-8 bg-white">
<h3 className="text-xl md:text-2xl font-bold font-heading text-neutral-dark mb-6 group-hover:text-primary transition-colors line-clamp-3 leading-[1.2]">
<h3 className="text-xl md:text-2xl font-bold font-heading text-neutral-dark mb-6 transition-colors line-clamp-3 leading-[1.2] group-hover:text-primary">
{ref.frontmatter.title}
</h3>
{/* Technical Meta Data */}
<div className="flex flex-col gap-3 mt-auto border-t border-neutral-100 pt-6 pr-16 md:pr-20 relative z-10">
<div className="flex flex-col gap-3 mt-auto border-t border-neutral-100 pt-6 relative z-10">
<div className="min-w-0">
<span className="block text-[10px] uppercase tracking-widest text-neutral-400 font-bold mb-1">{t('client')}</span>
<span className="flex items-start gap-2 text-sm font-semibold text-neutral-700 leading-tight">
@@ -144,11 +141,6 @@ export default async function ReferenzenOverview(props: { params: Promise<{ loca
</div>
</div>
</div>
{/* Industrial Hover Indicator */}
<div className="absolute right-6 bottom-6 md:right-8 md:bottom-8 w-10 h-10 bg-neutral-50 border border-neutral-200 rounded flex items-center justify-center transform group-hover:bg-primary group-hover:border-primary transition-colors duration-300">
<ArrowUpRight className="w-5 h-5 text-neutral-dark group-hover:text-white transform group-hover:translate-x-0.5 group-hover:-translate-y-0.5 transition-transform duration-300" />
</div>
</div>
</TrackedLink>
))}

View File

@@ -0,0 +1,187 @@
import { Container, Badge, Heading } from '@/components/ui';
import { getTranslations, setRequestLocale } from 'next-intl/server';
import { Metadata } from 'next';
import { notFound } from 'next/navigation';
import { standorteData, getStandortById } from '@/lib/standorte-data';
import { SITE_URL } from '@/lib/schema';
import Image from 'next/image';
import { MapPin, Phone, Mail, Navigation, CheckCircle2, ArrowUpRight } from 'lucide-react';
import { getButtonClasses, ButtonOverlay } from '@/components/ui/Button';
import TrackedLink from '@/components/analytics/TrackedLink';
import { AnimatedGlossyBorder } from '@/components/ui/AnimatedGlossyBorder';
interface PageProps {
params: Promise<{
locale: string;
slug: string;
}>;
}
export async function generateStaticParams() {
const locales = ['de', 'en'];
const params: { locale: string; slug: string }[] = [];
for (const locale of locales) {
for (const standort of standorteData) {
params.push({ locale, slug: standort.id });
}
}
return params;
}
export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
const { locale, slug } = await params;
if (locale !== 'de' && locale !== 'en') return {};
const standort = getStandortById(slug);
if (!standort) return {};
return {
title: `${standort.name} | E-TIB Gruppe`,
description: standort.description[locale],
alternates: {
canonical: `${SITE_URL}/${locale}/standorte/${slug}`,
languages: {
de: `${SITE_URL}/de/standorte/${slug}`,
en: `${SITE_URL}/en/standorte/${slug}`,
'x-default': `${SITE_URL}/en/standorte/${slug}`,
},
},
};
}
export default async function StandortDetail(props: { params: Promise<{ locale: string; slug: string }> }) {
const { locale, slug } = await props.params;
const safeLocale = locale === 'de' ? 'de' : 'en';
setRequestLocale(safeLocale);
const t = await getTranslations('StandardPage');
const standort = getStandortById(slug);
if (!standort) {
notFound();
}
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">
<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>
<Container className="relative z-10">
<div className="max-w-4xl">
<Badge variant="accent" className="mb-4 md:mb-6 shadow-sm flex inline-flex items-center gap-2">
<MapPin className="w-4 h-4" />
{standort.type === 'hq' ? (safeLocale === 'de' ? 'Hauptsitz' : 'Headquarters') : (safeLocale === 'de' ? 'Niederlassung' : 'Branch')}
</Badge>
<Heading level={1} variant="white" className="mb-0 drop-shadow-sm">
{standort.name}
</Heading>
</div>
</Container>
</section>
{/* Main Content Area */}
<Container className="py-16 md:py-24">
{/* Excerpt/Lead paragraph */}
<div className="mb-16 max-w-4xl mx-auto">
<p className="text-xl md:text-2xl text-text-primary leading-relaxed font-medium border-l-4 border-primary pl-8 py-2 italic">
{standort.description[safeLocale]}
</p>
</div>
{/* Main content in prose style */}
<div className="max-w-4xl mx-auto">
<div className="prose prose-lg md:prose-xl prose-neutral max-w-none prose-headings:font-heading prose-headings:font-bold prose-headings:tracking-tight prose-h1:text-4xl prose-h2:text-3xl prose-h2:mt-12 prose-h2:border-b prose-h2:border-neutral-200 prose-h2:pb-4 prose-h3:text-2xl prose-p:text-text-secondary prose-p:leading-relaxed prose-a:text-primary prose-a:font-medium prose-a:underline prose-a:underline-offset-4 prose-a:decoration-primary/30 hover:prose-a:decoration-primary prose-strong:text-text-primary prose-strong:font-semibold prose-li:text-text-secondary prose-ul:list-disc prose-ol:list-decimal">
<img className="rounded-2xl shadow-2xl my-12 max-w-full h-auto border border-neutral-100" src={standort.image} alt={standort.name} />
<h2 className="mt-16 mb-6 border-b border-neutral-100 pb-4">{safeLocale === 'de' ? 'Unsere Leistungen vor Ort' : 'Our Local Services'}</h2>
<ul className="list-none mb-8 space-y-3 text-base md:text-lg text-text-secondary font-medium max-w-3xl">
{standort.keyFeatures[safeLocale].map((feature, idx) => (
<li key={idx} className="relative pl-6 before:content-[''] before:absolute before:left-0 before:top-[0.6em] before:w-2 before:h-2 before:bg-primary/50 before:rounded-sm">
{feature}
</li>
))}
</ul>
<h2 className="mt-16 mb-6 border-b border-neutral-100 pb-4">{safeLocale === 'de' ? 'Kontakt & Anfahrt' : 'Contact & Directions'}</h2>
<p className="text-base md:text-lg text-text-secondary leading-[1.8] mb-6 font-medium max-w-3xl">
<strong>{safeLocale === 'de' ? 'Adresse:' : 'Address:'}</strong><br/>
{standort.address.street}<br/>
{standort.address.city}
</p>
<p className="text-base md:text-lg text-text-secondary leading-[1.8] mb-6 font-medium max-w-3xl">
<TrackedLink
href={`https://maps.google.com/?q=${encodeURIComponent(`${standort.address.street}, ${standort.address.city}`)}`}
target="_blank"
rel="noopener noreferrer"
className="text-primary hover:text-primary-dark underline decoration-primary/30 underline-offset-4 hover:decoration-primary transition-all font-bold flex items-center gap-1 w-fit"
eventProperties={{ location: 'standort_maps_link', slug: standort.id }}
>
{safeLocale === 'de' ? 'In Google Maps öffnen' : 'Open in Google Maps'}
<ArrowUpRight className="w-4 h-4 inline-block" />
</TrackedLink>
</p>
<p className="text-base md:text-lg text-text-secondary leading-[1.8] mb-6 font-medium max-w-3xl">
<strong>{safeLocale === 'de' ? 'Telefon:' : 'Phone:'}</strong><br/>
<a href={`tel:${standort.contact.phone.replace(/[^0-9+]/g, '')}`} className="text-primary hover:text-primary-dark underline decoration-primary/30 underline-offset-4 hover:decoration-primary transition-all font-bold">
{standort.contact.phone}
</a>
</p>
<p className="text-base md:text-lg text-text-secondary leading-[1.8] mb-6 font-medium max-w-3xl">
<strong>Email:</strong><br/>
<a href={`mailto:${standort.contact.email}`} className="text-primary hover:text-primary-dark underline decoration-primary/30 underline-offset-4 hover:decoration-primary transition-all font-bold">
{standort.contact.email}
</a>
</p>
{standort.gallery && standort.gallery.length > 0 && (
<>
<h2 className="mt-16 mb-6 border-b border-neutral-100 pb-4">Galerie</h2>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 not-prose my-12">
{standort.gallery.map((img, idx) => (
<div key={idx} className="relative aspect-[4/3] rounded-2xl overflow-hidden bg-neutral-100 border border-neutral-200 shadow-md hover:shadow-xl transition-shadow duration-300">
<Image src={img} alt={`Gallery ${idx + 1}`} fill className="object-cover transition-transform duration-700 hover:scale-105" />
</div>
))}
</div>
</>
)}
</div>
</div>
</Container>
{/* Support Section */}
<Container>
<div className="mt-12 mb-24 p-8 md:p-12 bg-primary-dark rounded-3xl text-white shadow-2xl relative overflow-hidden group animate-slight-fade-in-from-bottom">
<div className="absolute top-0 right-0 w-64 h-full bg-accent/5 -skew-x-12 translate-x-1/2 transition-transform group-hover:translate-x-1/3" />
<div className="relative z-10 max-w-2xl">
<h3 className="text-2xl md:text-3xl font-bold mb-4">{t('needHelp')}</h3>
<p className="text-lg text-white/70 mb-8">{t('supportTeamAvailable')}</p>
<TrackedLink
href={`/${locale}/${locale === 'de' ? 'kontakt' : 'contact'}`}
className={getButtonClasses('accent', 'lg')}
eventProperties={{
location: 'standort_page_support_cta',
page_slug: slug,
}}
>
<span className="relative z-10 flex items-center justify-center gap-2 transition-colors duration-500 group-hover/btn:text-primary-dark">
{t('contactUs')}
<span className="ml-2 transition-transform group-hover/btn:translate-x-1">
&rarr;
</span>
</span>
<ButtonOverlay variant="accent" />
</TrackedLink>
</div>
</div>
</Container>
</div>
);
}

View File

@@ -0,0 +1,142 @@
import { Container } from '@/components/ui';
import { getTranslations, setRequestLocale } from 'next-intl/server';
import { Metadata } from 'next';
import TrackedLink from '@/components/analytics/TrackedLink';
import { MapPin, Navigation, ArrowUpRight } from 'lucide-react';
import { getButtonClasses, ButtonOverlay } from '@/components/ui/Button';
import { SITE_URL } from '@/lib/schema';
import Image from 'next/image';
import { standorteData, standorteLocations } from '@/lib/standorte-data';
import { InteractiveGermanyMap } from '@/components/blocks/InteractiveGermanyMap';
interface PageProps {
params: Promise<{
locale: string;
}>;
}
export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }): Promise<Metadata> {
const { locale } = await params;
const safeLocale = locale === 'de' ? 'de' : 'en';
return {
title: safeLocale === 'en' ? 'Our Locations' : 'Unsere Standorte',
description: safeLocale === 'en' ? 'Our operational locations across Germany.' : 'Unsere operativen Standorte deutschlandweit.',
alternates: {
canonical: `${SITE_URL}/${safeLocale}/standorte`,
languages: {
de: `${SITE_URL}/de/standorte`,
en: `${SITE_URL}/en/standorte`,
'x-default': `${SITE_URL}/en/standorte`,
},
},
};
}
export default async function StandorteOverview(props: { params: Promise<{ locale: string }> }) {
const { locale } = await props.params;
const safeLocale = locale === 'de' ? 'de' : 'en';
setRequestLocale(safeLocale);
const t = await getTranslations('StandardPage');
return (
<div className="flex flex-col min-h-screen bg-neutral-50 pb-16 md:pb-24">
{/* Map Hero Section */}
<InteractiveGermanyMap
isHero={true}
locations={standorteLocations}
badge={safeLocale === 'en' ? 'Our Locations' : 'Unsere Standorte'}
title={safeLocale === 'en' ? 'Nationwide operational for you.' : 'Deutschlandweit für Sie im Einsatz.'}
description={safeLocale === '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.'}
/>
{/* Main Content Area */}
<Container className="relative z-20 mt-16 md:mt-24">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 md:gap-8">
{standorteData.map((standort) => (
<TrackedLink
key={standort.id}
href={`/${safeLocale}/standorte/${standort.id}`}
eventProperties={{ location: 'standorte_list_card', slug: standort.id }}
className="group flex flex-col bg-white border border-neutral-100 rounded-3xl overflow-hidden shadow-sm hover:shadow-2xl transition-all duration-300 transform hover:-translate-y-1 cursor-pointer block"
>
<div className="flex flex-col h-full relative">
{/* Image Section */}
<div className="relative h-64 w-full bg-[#050B14] overflow-hidden shrink-0 border-b border-neutral-100">
<Image
src={standort.image}
alt={standort.name}
fill
className="object-cover transition-transform duration-1000 ease-[cubic-bezier(0.16,1,0.3,1)] filter grayscale-[20%] group-hover:scale-105 group-hover:grayscale-0"
/>
<div className="absolute inset-0 bg-black/10 transition-colors duration-500" />
{/* Location Badge */}
<div className="absolute top-4 left-4 z-10">
<span className="bg-white/95 backdrop-blur-md text-neutral-dark px-3 py-1.5 rounded-sm text-[10px] font-bold uppercase tracking-widest flex items-center gap-1.5 shadow-sm border border-neutral-200">
<MapPin className="w-3 h-3 text-primary" />
{standort.address.city}
</span>
</div>
</div>
{/* Content Section */}
<div className="flex flex-col flex-grow p-6 md:p-8 bg-white">
<div className="flex items-start justify-between gap-4 mb-4">
<h3 className="text-xl md:text-2xl font-bold font-heading text-neutral-dark transition-colors leading-[1.2] group-hover:text-primary">
{standort.name}
</h3>
<ArrowUpRight className="w-5 h-5 text-neutral-400 group-hover:text-primary transition-colors shrink-0" />
</div>
<p className="text-neutral-500 text-sm leading-relaxed mb-8 line-clamp-3">
{standort.description[safeLocale]}
</p>
{/* Meta Data */}
<div className="flex flex-col gap-3 mt-auto border-t border-neutral-100 pt-6 relative z-10">
<div className="min-w-0">
<span className="block text-[10px] uppercase tracking-widest text-neutral-400 font-bold mb-1">
{safeLocale === 'de' ? 'Adresse' : 'Address'}
</span>
<span className="flex items-start gap-2 text-sm font-semibold text-neutral-700 leading-tight">
<Navigation className="w-3.5 h-3.5 text-primary shrink-0 mt-[2px]" />
<span className="line-clamp-2">{standort.address.street}, {standort.address.city}</span>
</span>
</div>
</div>
</div>
</div>
</TrackedLink>
))}
</div>
{/* Support Section */}
<div className="mt-24 p-8 md:p-12 bg-primary-dark rounded-3xl text-white shadow-2xl relative overflow-hidden group">
<div className="absolute top-0 right-0 w-64 h-full bg-accent/5 -skew-x-12 translate-x-1/2 transition-transform group-hover:translate-x-1/3" />
<div className="relative z-10 max-w-2xl">
<h3 className="text-2xl md:text-3xl font-bold mb-4">{t('nextProjectTitle')}</h3>
<p className="text-lg text-white/70 mb-8">{t('nextProjectDesc')}</p>
<TrackedLink
href={`/${safeLocale}/${safeLocale === 'de' ? 'kontakt' : 'contact'}`}
className={getButtonClasses('accent', 'lg')}
eventProperties={{
location: 'standorte_support_cta',
}}
>
<span className="relative z-10 flex items-center justify-center gap-2 transition-colors duration-500 group-hover/btn:text-primary-dark">
{t('contactUs')}
<span className="ml-2 transition-transform group-hover/btn:translate-x-1">
&rarr;
</span>
</span>
<ButtonOverlay variant="accent" />
</TrackedLink>
</div>
</div>
</Container>
</div>
);
}

View File

@@ -99,7 +99,7 @@ export async function sendContactFormAction(formData: FormData) {
const confirmationHtml = await render(
React.createElement(ConfirmationMessage, {
name,
clientName: 'KLZ Cables',
clientName: 'E-TIB GmbH',
// brandColor: '#82ed20', // Optional: could be KLZ specific
}),
);

View File

@@ -13,11 +13,13 @@ const LeafletMap = dynamic(() => import('@/components/LeafletMap'), {
});
interface ContactMapProps {
address: string;
lat: number;
lng: number;
address?: string;
lat?: number;
lng?: number;
locations?: Array<{name: string, address: string, lat: number, lng: number}>;
}
export default function ContactMap({ address, lat, lng }: ContactMapProps) {
return <LeafletMap locations={[{ name: 'E-TIB Gruppe', address, lat, lng }]} />;
export default function ContactMap({ address, lat, lng, locations }: ContactMapProps) {
const mapLocations = locations || (address && lat && lng ? [{ name: 'E-TIB Gruppe', address, lat, lng }] : []);
return <LeafletMap locations={mapLocations} />;
}

View File

@@ -12,6 +12,8 @@ interface TrackedLinkProps {
className?: string;
children: React.ReactNode;
onClick?: () => void;
target?: string;
rel?: string;
}
/**
@@ -25,6 +27,8 @@ export default function TrackedLink({
className,
children,
onClick,
target,
rel,
}: TrackedLinkProps) {
const { trackEvent } = useAnalytics();
@@ -41,7 +45,7 @@ export default function TrackedLink({
};
return (
<Link href={href} className={className} onClick={handleClick}>
<Link href={href} className={className} onClick={handleClick} target={target} rel={rel}>
{children}
</Link>
);

View File

@@ -129,9 +129,10 @@ export const ContactSection: React.FC<ContactSectionProps> = (props) => {
fallback={<div className="h-full w-full bg-neutral-medium animate-pulse" />}
>
<ContactMap
address="Gewerbestraße 22\n03172 Guben"
lat={51.9547}
lng={14.7214}
locations={[
{ name: 'E-TIB GmbH (Hauptsitz)', address: 'Gewerbestraße 22\n03172 Guben', lat: 51.9547, lng: 14.7214 },
{ name: 'E-TIB Bohrtechnik GmbH', address: 'Bahnhofstraße 180a\n99947 Kirchheilingen', lat: 51.1852, lng: 10.6865 }
]}
/>
</Suspense>
</motion.section>

View File

@@ -2,12 +2,22 @@
import React from 'react';
import { motion } from 'framer-motion';
import { useTranslations } from 'next-intl';
export function GrowthChart() {
const t = useTranslations('GrowthChart');
const data = [
{ year: '2023', hdd: 29436, kabel: 76727 },
{ year: '2024', hdd: 28680, kabel: 131964 },
{ year: '2025', hdd: 44655, kabel: 163470 },
{ year: '2016', offener: 5000, hdd: 1200, kabel: 16064 },
{ year: '2017', offener: 33401, hdd: 8363, kabel: 84675 },
{ year: '2018', offener: 30773, hdd: 10225, kabel: 108127 },
{ year: '2019', offener: 32445, hdd: 8505, kabel: 87468 },
{ year: '2020', offener: 31305, hdd: 9050, kabel: 93556 },
{ year: '2021', offener: 38756, hdd: 10957, kabel: 110127 },
{ year: '2022', offener: 41445, hdd: 9505, kabel: 102468 },
{ year: '2023', offener: 17908, hdd: 29436, kabel: 76727 },
{ year: '2024', offener: 30801, hdd: 28680, kabel: 131964 },
{ year: '2025', offener: 38166, hdd: 44655, kabel: 163470 },
];
const maxVal = 163470; // Highest value for scaling
@@ -15,14 +25,15 @@ export function GrowthChart() {
return (
<div className="w-full bg-white rounded-3xl p-8 md:p-12 shadow-sm border border-neutral-100 my-16">
<div className="mb-10">
<h3 className="text-3xl font-heading font-extrabold text-neutral-dark mb-2">Bewiesene Leistungsfähigkeit</h3>
<p className="text-neutral-500 font-medium">Unsere verlässliche Baukapazität der letzten drei Jahre (in Metern)</p>
<h3 className="text-3xl font-heading font-extrabold text-neutral-dark mb-2">{t('title')}</h3>
<p className="text-neutral-500 font-medium">{t('subtitle')}</p>
</div>
<div className="space-y-8">
{data.map((item, index) => {
const hddWidth = (item.hdd / maxVal) * 100;
const kabelWidth = (item.kabel / maxVal) * 100;
const offenerWidth = (item.offener / maxVal) * 100;
const hddWidth = (item.hdd / maxVal) * 100;
return (
<div key={item.year} className="relative">
@@ -40,7 +51,23 @@ export function GrowthChart() {
/>
</div>
<div className="w-24 text-right text-xs font-bold text-neutral-500 uppercase">
Kabel: {new Intl.NumberFormat('de-DE').format(item.kabel)}m
{t('kabel')}: {new Intl.NumberFormat('de-DE').format(item.kabel)}m
</div>
</div>
{/* Offener Tiefbau Bar */}
<div className="flex items-center gap-4">
<div className="flex-1 bg-neutral-100 rounded-full h-5 overflow-hidden relative">
<motion.div
initial={{ width: 0 }}
whileInView={{ width: `${offenerWidth}%` }}
viewport={{ once: true, margin: "-50px" }}
transition={{ duration: 1.5, delay: 0.15 + 0.1 * index, ease: "easeOut" }}
className="absolute top-0 left-0 h-full bg-neutral-300 rounded-full"
/>
</div>
<div className="w-24 text-right text-xs font-bold text-neutral-500 uppercase">
{t('offener')}: {new Intl.NumberFormat('de-DE').format(item.offener)}m
</div>
</div>
@@ -56,7 +83,7 @@ export function GrowthChart() {
/>
</div>
<div className="w-24 text-right text-xs font-bold text-neutral-500 uppercase">
HDD: {new Intl.NumberFormat('de-DE').format(item.hdd)}m
{t('hdd')}: {new Intl.NumberFormat('de-DE').format(item.hdd)}m
</div>
</div>
</div>
@@ -65,14 +92,18 @@ export function GrowthChart() {
})}
</div>
<div className="mt-8 flex gap-6 border-t border-neutral-100 pt-6">
<div className="mt-8 flex flex-wrap gap-6 border-t border-neutral-100 pt-6">
<div className="flex items-center gap-2">
<div className="w-3 h-3 rounded-full bg-primary" />
<span className="text-xs font-bold text-neutral-500 uppercase">Kabelverlegung</span>
<span className="text-xs font-bold text-neutral-500 uppercase">{t('kabel')}</span>
</div>
<div className="flex items-center gap-2">
<div className="w-3 h-3 rounded-full bg-neutral-300" />
<span className="text-xs font-bold text-neutral-500 uppercase">{t('offener')}</span>
</div>
<div className="flex items-center gap-2">
<div className="w-3 h-3 rounded-full bg-neutral-dark" />
<span className="text-xs font-bold text-neutral-500 uppercase">HDD Spülbohrung</span>
<span className="text-xs font-bold text-neutral-500 uppercase">{t('hdd')}</span>
</div>
</div>
</div>

View File

@@ -5,16 +5,17 @@ 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 Link from 'next/link';
import { AnimatedGlossyBorder } from '@/components/ui/AnimatedGlossyBorder';
import { Location, defaultLocations, minorLocations } from '@/lib/map-data';
import { Location, defaultLocations, minorLocations, projectLocations } from '@/lib/map-data';
import { standorteLocations } from '@/lib/standorte-data';
import { useLocale, useTranslations } from 'next-intl';
const allLocations = [...defaultLocations, ...minorLocations];
interface Stat {
value: string;
suffix?: string;
label: string;
href?: string;
}
interface InteractiveGermanyMapProps {
@@ -31,7 +32,7 @@ export function InteractiveGermanyMap({
title,
description,
stats,
locations = allLocations,
locations = projectLocations,
isHero = false
}: InteractiveGermanyMapProps) {
const [activeLocation, setActiveLocation] = useState<Location | null>(null);
@@ -42,13 +43,13 @@ export function InteractiveGermanyMap({
const finalStats = stats || [
{ value: '100', suffix: '%', label: locale === 'en' ? 'Nationwide Reach' : 'Überregionale Reichweite' },
{ value: '2', suffix: '+', label: locale === 'en' ? 'Operational Locations' : 'Operative Standorte' },
{ value: '3', suffix: '', label: locale === 'en' ? 'Operational Locations' : 'Operative Standorte', href: `/${locale}/standorte` },
];
const finalBadge = badge || tStandard('badge');
// the map is mostly used with specific props, so we leave title & description to fallbacks if not provided
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 and Bülstedt, we control and implement complex infrastructure projects nationwide.' : 'Von unseren strategischen Standorten in Guben und Bülstedt steuern und realisieren wir komplexe Infrastrukturprojekte im gesamten Bundesgebiet.');
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');
@@ -90,17 +91,32 @@ export function InteractiveGermanyMap({
{/* Industrial Stats Grid */}
<div className="grid grid-cols-2 gap-4">
{finalStats.map((stat, i) => (
<div key={i} className="bg-white/5 border border-white/10 rounded-2xl p-6 backdrop-blur-md relative overflow-hidden group">
<div className="absolute inset-0 bg-gradient-to-br from-primary/10 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
<div className="relative z-10">
<div className="text-4xl font-extrabold text-white mb-1 flex items-baseline gap-1">
{stat.value}<span className="text-xl text-primary">{stat.suffix}</span>
{finalStats.map((stat, i) => {
const StatCard = () => (
<div className={`bg-white/5 border border-white/10 rounded-2xl p-6 backdrop-blur-md relative overflow-hidden group h-full ${stat.href ? 'cursor-pointer' : ''}`}>
<div className="absolute inset-0 bg-gradient-to-br from-primary/10 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
<div className="relative z-10 flex flex-col h-full justify-between">
<div className="text-4xl font-extrabold text-white mb-1 flex items-baseline gap-1">
{stat.value}<span className="text-xl text-primary">{stat.suffix}</span>
</div>
<div className={`text-sm text-white/50 font-medium flex items-center ${stat.href ? 'group-hover:text-primary transition-colors' : ''}`}>
{stat.label}
{stat.href && <ArrowUpRight className="w-4 h-4 ml-1 opacity-0 -translate-y-1 translate-x-1 group-hover:opacity-100 group-hover:translate-y-0 group-hover:translate-x-0 transition-all duration-300" />}
</div>
</div>
<div className="text-sm text-white/50 font-medium">{stat.label}</div>
</div>
</div>
))}
);
return stat.href ? (
<Link key={i} href={stat.href} className="block group/link hover:-translate-y-1 transition-transform duration-300">
<StatCard />
</Link>
) : (
<div key={i}>
<StatCard />
</div>
);
})}
</div>
</div>

View File

@@ -1,8 +1,7 @@
import * as React from 'react';
import { describe, it, expect, vi } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/react';
import { render, screen } from '@testing-library/react';
import { ReferencesSlider, Reference } from './ReferencesSlider';
import { NextIntlClientProvider } from 'next-intl';
// Mock next/link to render standard <a> tag
vi.mock('next/link', () => ({
@@ -52,45 +51,14 @@ describe('ReferencesSlider TDD', () => {
expect(screen.getByText('Referenz Projekt Zwei')).toBeTruthy();
});
it('wraps each tile in a link to /referenzen/[slug]', () => {
it('renders each tile as a static block and NOT wrapped in a link', () => {
render(<ReferencesSlider references={mockReferences} />);
const links = screen.getAllByTestId('reference-tile-link');
expect(links).toHaveLength(2);
expect(links[0].getAttribute('href')).toBe('/en/referenzen/referenz-projekt-eins');
expect(links[1].getAttribute('href')).toBe('/en/referenzen/referenz-projekt-zwei');
});
const links = screen.queryAllByTestId('reference-tile-link');
expect(links).toHaveLength(0);
it('allows navigation on simple click (no drag)', () => {
render(<ReferencesSlider references={mockReferences} />);
const firstLink = screen.getAllByTestId('reference-tile-link')[0];
// Simulate simple click sequence
fireEvent.mouseDown(firstLink, { pageX: 100, clientX: 100 });
fireEvent.mouseUp(firstLink);
const clickEvent = new MouseEvent('click', { bubbles: true, cancelable: true });
firstLink.dispatchEvent(clickEvent);
expect(clickEvent.defaultPrevented).toBe(false);
});
it('prevents navigation if mouse was dragged', () => {
render(<ReferencesSlider references={mockReferences} />);
const firstLink = screen.getAllByTestId('reference-tile-link')[0];
// Simulate drag sequence
fireEvent.mouseDown(firstLink, { pageX: 100, clientX: 100 });
// Simulate mouse move of 20px
fireEvent.mouseMove(firstLink, { pageX: 120, clientX: 120 });
fireEvent.mouseUp(firstLink);
const clickEvent = new MouseEvent('click', { bubbles: true, cancelable: true });
firstLink.dispatchEvent(clickEvent);
expect(clickEvent.defaultPrevented).toBe(true);
const tiles = screen.getAllByTestId('reference-tile');
expect(tiles).toHaveLength(2);
});
});

View File

@@ -92,11 +92,6 @@ export function ReferencesSlider(props: ReferencesSliderProps) {
dragDistanceRef.current = Math.abs(x - startXRef.current);
};
const handleTileClick = (e: React.MouseEvent) => {
if (dragDistanceRef.current > 10) {
e.preventDefault();
}
};
return (
<section id="referenzen" className="py-24 bg-neutral-dark text-white relative overflow-hidden">
@@ -137,8 +132,12 @@ export function ReferencesSlider(props: ReferencesSliderProps) {
>
<Link
href={`/${locale}/referenzen/${ref.slug}`}
onClick={handleTileClick}
data-testid="reference-tile-link"
data-testid="reference-tile"
onClick={(e) => {
if (dragDistanceRef.current > 15) {
e.preventDefault();
}
}}
className="block relative aspect-[16/10] bg-neutral-800 rounded-2xl overflow-hidden mb-5 border border-white/5 shadow-2xl"
>
<Image

View File

@@ -31,7 +31,7 @@ export function ScaleOfImpact() {
className="absolute inset-0 flex flex-col items-center justify-center pointer-events-none select-none overflow-hidden mix-blend-overlay"
>
<div className="font-heading font-black text-[20vw] leading-none text-white opacity-20 whitespace-nowrap">
<span className="font-mono tracking-tighter">474.932</span>
<span className="font-mono tracking-tighter">1.435.223</span>
</div>
</motion.div>
@@ -73,26 +73,30 @@ export function ScaleOfImpact() {
<motion.path
d="M0,50 Q250,0 500,50 T1000,50"
fill="none"
stroke="#82ED20" // primary color
stroke="#ffc107" // warning/yellow color
strokeWidth="4"
style={{ pathLength }}
className="drop-shadow-[0_0_15px_rgba(130,237,32,0.8)]"
className="drop-shadow-[0_0_15px_rgba(255,193,7,0.8)]"
/>
</svg>
</div>
{/* Static Data Grid (No jumping text) */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 md:gap-16 w-full max-w-4xl mt-12">
<div className="grid grid-cols-2 md:grid-cols-4 gap-8 md:gap-12 w-full max-w-5xl mt-12">
<div className="flex flex-col items-center">
<div className="font-mono text-5xl md:text-6xl font-black text-white tracking-tighter mb-2">100<span className="text-primary">+</span></div>
<div className="text-xs font-bold uppercase tracking-widest text-white/50">{locale === 'en' ? 'Major Projects' : 'Großprojekte'}</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-5xl md:text-6xl font-black text-white tracking-tighter mb-2">372<span className="text-primary text-3xl">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-5xl md:text-6xl font-black text-white tracking-tighter mb-2">102<span className="text-primary text-3xl">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="text-xs font-bold uppercase tracking-widest text-white/50">{locale === 'en' ? 'HDD Drilling' : 'Spülbohrung'}</div>
</div>
</div>

View File

@@ -195,7 +195,7 @@ export function ServiceDetailGrid({
<div className="relative z-10 flex flex-col md:flex-row justify-between items-start mb-12 gap-6">
<div className="pt-2 flex-1 min-w-0 pr-4">
<h4 className="text-2xl md:text-3xl font-extrabold text-neutral-dark uppercase tracking-wider break-words hyphens-auto" lang="de">{panel.title}</h4>
<h4 className="text-xl md:text-2xl font-extrabold text-neutral-dark uppercase tracking-wider text-balance break-words" lang="de">{panel.title}</h4>
<div className="h-1 w-12 bg-primary mt-6 transition-all duration-700 group-hover:w-24 rounded-full"></div>
</div>

View File

@@ -3,6 +3,7 @@
import * as React from 'react';
import { motion, Variants } from 'framer-motion';
import Image from 'next/image';
import Link from 'next/link';
import { HoverShineOverlay } from '@/components/ui/HoverShineOverlay';
import { AnimatedGlossyBorder } from '@/components/ui/AnimatedGlossyBorder';
@@ -87,8 +88,9 @@ export function SubCompanyTiles(props: SubCompanyTilesProps) {
{companiesData.map((company: any, index: number) => {
const isCurrent = company.title.toUpperCase() === 'E-TIB GMBH';
const hasUrl = !!company.url;
const CardWrapper = hasUrl ? 'a' : 'div';
const wrapperProps = hasUrl ? { href: company.url, target: "_blank", rel: "noopener noreferrer" } : {};
const isExternal = hasUrl && company.url.startsWith('http');
const CardWrapper = hasUrl ? (isExternal ? 'a' : Link) : 'div';
const wrapperProps = hasUrl ? (isExternal ? { href: company.url, target: "_blank", rel: "noopener noreferrer" } : { href: company.url }) : {};
// Generate logo representation based on title
const isEtib = company.title.includes('E-TIB');
@@ -112,33 +114,21 @@ export function SubCompanyTiles(props: SubCompanyTilesProps) {
const positionClass = bgPositionClasses[index % bgPositionClasses.length];
const animationClass = animationClasses[index % animationClasses.length];
return (
<motion.div
key={index}
variants={itemVariants}
className="h-full"
>
<CardWrapper
{...wrapperProps}
className={`group relative overflow-hidden aspect-[4/3] flex flex-col justify-center items-center shadow-xl transition-all duration-500 bg-neutral-dark block w-full h-full sm:rounded-xl select-none ${
isCurrent
? 'border-2 border-primary shadow-[0_0_30px_rgba(17,124,97,0.15)] cursor-default'
: 'border border-white/5 hover:shadow-2xl hover:-translate-y-1 hover:border-white/10 cursor-pointer'
}`}
>
<div className="absolute inset-0 bg-[#0a192f] z-0">
<Image
src={company.backgroundImage}
alt="Background"
fill
className={`object-cover transition-all duration-1000 ease-out ${
isCurrent
? 'opacity-30 grayscale-0 scale-105'
: 'opacity-40 grayscale-[50%] group-hover:opacity-30 group-hover:grayscale-0 group-hover:scale-110'
}`}
sizes="(max-width: 768px) 100vw, 33vw"
/>
</div>
const CardContent = (
<>
<div className="absolute inset-0 bg-[#0a192f] z-0">
<Image
src={company.backgroundImage}
alt="Background"
fill
className={`object-cover transition-all duration-1000 ease-out ${
isCurrent
? 'opacity-30 grayscale-0 scale-105'
: 'opacity-40 grayscale-[50%] group-hover:opacity-30 group-hover:grayscale-0 group-hover:scale-110'
}`}
sizes="(max-width: 768px) 100vw, 33vw"
/>
</div>
{/* Heavy dark gradient overlay to make logos pop */}
<div className={`absolute inset-0 z-0 transition-colors duration-700 mix-blend-multiply ${
@@ -227,13 +217,42 @@ export function SubCompanyTiles(props: SubCompanyTilesProps) {
{company.url && (
<div className="absolute bottom-6 left-0 right-0 flex justify-center opacity-0 group-hover:opacity-100 transform translate-y-4 group-hover:translate-y-0 transition-all duration-500 z-20">
<div className="flex items-center text-white font-bold uppercase text-xs tracking-widest bg-white/10 backdrop-blur-md px-4 py-2 rounded-full border border-white/20">
Website Besuchen
{isExternal ? (isDe ? 'Website Besuchen' : 'Visit Website') : (isDe ? 'Zum Standort' : 'View Location')}
<svg className="w-4 h-4 ml-2" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M5 12h14M12 5l7 7-7 7"/></svg>
</div>
</div>
)}
</CardWrapper>
</>
);
const sharedClass = `group relative overflow-hidden aspect-[4/3] flex flex-col justify-center items-center shadow-xl transition-all duration-500 bg-neutral-dark block w-full h-full sm:rounded-xl select-none ${
isCurrent
? 'border border-white/5 hover:shadow-2xl hover:-translate-y-1 hover:border-white/10 cursor-pointer'
: 'border border-white/5 hover:shadow-2xl hover:-translate-y-1 hover:border-white/10 cursor-pointer'
}`;
return (
<motion.div
key={index}
variants={itemVariants}
className="h-full"
>
{hasUrl ? (
isExternal ? (
<a href={company.url} target="_blank" rel="noopener noreferrer" className={sharedClass}>
{CardContent}
</a>
) : (
<Link href={company.url as string} className={sharedClass}>
{CardContent}
</Link>
)
) : (
<div className={sharedClass}>
{CardContent}
</div>
)}
</motion.div>
);
})}

View File

@@ -38,77 +38,8 @@ export function TeamGrid({ members }: TeamGridProps) {
</p>
</div>
{members.length > 0 && (
<div className="mb-20">
<motion.div
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
className="relative rounded-[2.5rem] bg-neutral-dark overflow-hidden shadow-2xl border border-white/10"
>
{/* Premium Background Effects */}
<div className="absolute inset-0 bg-[radial-gradient(circle_at_top_right,rgba(238,114,3,0.15),transparent_50%)] pointer-events-none" />
<div className="absolute top-0 right-0 w-[500px] h-[500px] bg-primary/20 blur-[120px] mix-blend-screen rounded-full pointer-events-none" />
<div className="absolute inset-0 opacity-20 pointer-events-none" style={{ backgroundImage: "url('data:image/svg+xml,%3Csvg width=\\'40\\' height=\\'40\\' viewBox=\\'0 0 40 40\\' xmlns=\\'http://www.w3.org/2000/svg\\'%3E%3Cpath d=\\'M0 0h40v40H0V0zm20 20h20v20H20V20zM0 20h20v20H0V20z\\' fill=\\'%23ffffff\\' fill-opacity=\\'0.02\\' fill-rule=\\'evenodd\\'/%3E%3C/svg%3E')" }} />
<div className="relative z-10 flex flex-col lg:flex-row items-center justify-between p-8 md:p-12 lg:p-20 gap-12 lg:gap-16">
{/* Text Content */}
<div className="w-full lg:w-[55%] flex flex-col justify-center text-white">
<div className="inline-flex items-center space-x-2 px-4 py-1.5 mb-8 rounded-full border border-primary/30 bg-primary/10 text-primary text-xs font-bold uppercase tracking-widest self-start backdrop-blur-md shadow-[0_0_20px_rgba(238,114,3,0.2)]">
<span className="relative flex h-2 w-2 mr-1">
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-primary opacity-75"></span>
<span className="relative inline-flex rounded-full h-2 w-2 bg-primary"></span>
</span>
{t('management')}
</div>
<h3 className="font-heading font-black text-5xl md:text-6xl lg:text-7xl mb-4 leading-[1.1] tracking-tight">
{members[0].name}
</h3>
<p className="text-xl md:text-2xl text-white/70 font-medium mb-10 leading-relaxed max-w-xl">
{members[0].position}
</p>
<div className="flex flex-col sm:flex-row gap-4">
{members[0].email && (
<a href={`mailto:${members[0].email}`} className="group flex items-center justify-center sm:justify-start gap-4 bg-white/5 hover:bg-primary border border-white/10 hover:border-primary px-6 py-4 rounded-2xl transition-all duration-300 shadow-lg">
<svg className="w-5 h-5 text-white/70 group-hover:text-white transition-colors" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"></path><polyline points="22,6 12,13 2,6"></polyline></svg>
<span className="font-semibold text-white/90 group-hover:text-white transition-colors">{members[0].email}</span>
</a>
)}
{members[0].phone && (
<a href={`tel:${members[0].phone}`} className="group flex items-center justify-center sm:justify-start gap-4 bg-white/5 hover:bg-white/10 border border-white/10 px-6 py-4 rounded-2xl transition-all duration-300 shadow-lg">
<svg className="w-5 h-5 text-white/70 group-hover:text-white transition-colors" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"></path></svg>
<span className="font-semibold text-white/90 group-hover:text-white transition-colors">{members[0].phone}</span>
</a>
)}
</div>
</div>
{/* Premium Image Block */}
<div className="w-full lg:w-[45%] flex justify-center lg:justify-end perspective-1000">
<div className="relative w-64 h-64 md:w-80 md:h-80 lg:w-[400px] lg:h-[400px] rounded-[3rem] overflow-hidden border-4 border-white/10 shadow-[0_30px_60px_rgba(0,0,0,0.6)] transform md:rotate-3 hover:rotate-0 transition-all duration-700 bg-neutral-800 group">
{members[0].image && (typeof members[0].image === 'string' ? members[0].image : members[0].image.url) ? (
<Image
src={typeof members[0].image === 'string' ? members[0].image : members[0].image.url}
alt={members[0].name}
fill
sizes="400px"
className="object-cover scale-110 group-hover:scale-100 transition-transform duration-1000 ease-out"
/>
) : (
<div className="absolute inset-0 flex items-center justify-center text-white/20">
<svg className="w-20 h-20" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1"><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"></path><circle cx="12" cy="7" r="4"></circle></svg>
</div>
)}
</div>
</div>
</div>
</motion.div>
</div>
)}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 xl:gap-10">
{members.slice(1).map((member, i) => (
{members.map((member, i) => (
<motion.div
key={member.id}
initial={{ opacity: 0, y: 30 }}

View File

@@ -108,6 +108,7 @@ export function Footer({ companyInfo }: FooterProps) {
{ label: locale === 'de' ? 'Über uns' : 'About us', href: `/${locale}/${locale === 'de' ? 'ueber-uns' : 'about-us'}` },
{ label: locale === 'de' ? 'Unser Team' : 'Our Team', href: `/${locale}/team` },
{ label: locale === 'de' ? 'Zertifikate' : 'Certificates', href: `/${locale}/zertifikate` },
{ label: locale === 'de' ? 'Referenzen' : 'References', href: `/${locale}/referenzen` },
{ label: locale === 'de' ? 'Karriere' : 'Career', href: `/${locale}/${locale === 'de' ? 'karriere' : 'career'}` },
{ label: locale === 'de' ? 'Messen & Events' : 'Fairs & Events', href: `/${locale}/${locale === 'de' ? 'messen' : 'trade-fairs'}` },
{ label: locale === 'de' ? 'Kontakt' : 'Contact', href: `/${locale}/${locale === 'de' ? 'kontakt' : 'contact'}` },

View File

@@ -11,6 +11,7 @@ export interface NavLink {
label: string;
url: string;
children?: NavLink[];
isGroupLabel?: boolean;
}
interface HeaderProps {
@@ -218,11 +219,20 @@ function NavItem({ link, currentLocale, pathname, isSolidMode }: { link: NavLink
{/* Top glowing accent line */}
<div className="absolute top-0 left-0 w-full h-[2px] bg-gradient-to-r from-transparent via-primary to-transparent opacity-70" />
{link.children.map((child) => {
{link.children.map((child, idx) => {
const childUrl = child.url.startsWith('/') && !child.url.match(/^\/(en|de)/)
? `/${currentLocale}${child.url}`
: child.url;
const isChildActive = pathname === childUrl;
if (child.isGroupLabel) {
return (
<div key={`group-${idx}`} className={`mt-2 mb-1 px-4 text-[11px] font-bold uppercase tracking-wider ${isSolidMode ? 'text-neutral-400' : 'text-neutral-500'}`}>
{child.label}
</div>
);
}
return (
<TransitionLink
key={child.url}

File diff suppressed because one or more lines are too long

1
contact-page-debug.html Normal file

File diff suppressed because one or more lines are too long

BIN
contact.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

View File

@@ -1,5 +1,5 @@
---
title: "Grabenlose Leitungsverlegung"
title: "Bohrtechnik"
date: "2024-03-20"
excerpt: "Präzise Horizontalspülbohrungen und Erdraketen in allen Bodenklassen für eine absolut oberflächenschonende und effiziente Leitungsverlegung."
layout: "fullBleed"
@@ -7,9 +7,9 @@ layout: "fullBleed"
<HeroSection
badge="Kernkompetenz"
title="Grabenlose Verlegung"
subtitle="Oberflächenschonende Horizontalspülbohrungen und Erdraketen"
backgroundImage={{ url: '/assets/photos/DSC08653.JPG' }}
title="Bohrtechnik"
subtitle="Grabenlose Leitungsverlegung, Horizontalspülbohrungen und Erdraketen"
backgroundImage={{ url: '/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-47.jpg' }}
alignment="center"
ctaLabel="Projekt anfragen"
ctaHref="/de/kontakt"
@@ -26,7 +26,7 @@ layout: "fullBleed"
## HDD-Spülbohrungen und Erdraketen
Mit unserem spezialisierten Gerätepark beherrschen wir die unterschiedlichsten Verfahren. Beim **Horizontalspülbohrverfahren (HDD)** steuern wir den Bohrkopf punktgenau unter der Erde hindurch. Wir realisieren dabei Bohrlängen von bis zu 250 Metern am Stück und können Schutzrohre mit einem Durchmesser von bis zu 400 mm einziehen.
Mit unserem spezialisierten Gerätepark beherrschen wir die unterschiedlichsten Verfahren. Beim **Horizontalspülbohrverfahren (HDD)** steuern wir den Bohrkopf punktgenau unter der Erde hindurch. Wir können bis zu 400 Meter am Stück bohren und, je nach Bohrlänge, Schutzrohre mit einem Durchmesser von bis zu 600 mm einziehen.
Für kürzere Distanzen, wie beispielsweise schnelle und schonende Hausanschlüsse, setzen wir unsere **Erdraketen** (Bodenverdrängungsverfahren) ein. Hierbei erreichen wir Durchörterungslängen von bis zu 15 Metern für Rohre bis 160 mm Durchmesser ideal um Vorgärten und Einfahrten komplett unversehrt zu lassen.
@@ -47,8 +47,8 @@ layout: "fullBleed"
fullWidth: false,
lists: [
[
"Max. Bohrlänge: 250 m",
"Max. Durchmesser: 400er Rohr",
"Max. Bohrlänge: 400 m",
"Max. Durchmesser: 600er Rohr",
"Zentimetergenaue Steuerbarkeit",
"Querung von Bahn, Autobahn & Gewässern"
]
@@ -71,7 +71,7 @@ layout: "fullBleed"
]}
/>
<HomeReferencesSlider badge="Praxisbeispiele" title="Abgeschlossene Bohr-Projekte" description="Erfolgreiche HDD-Bohrungen und grabenlose Leitungsverlegungen unter komplexesten Bedingungen." />
<HomeReferencesSlider badge="Praxisbeispiele" title="Referenzen" description="Erfolgreiche HDD-Bohrungen und grabenlose Leitungsverlegungen unter komplexesten Bedingungen." />
<CallToAction
title="Suchen Sie nach einer grabenlosen Lösung?"

View File

@@ -69,7 +69,7 @@ layout: "fullBleed"
]}
/>
<HomeReferencesSlider badge="Praxisbeispiele" title="Abgeschlossene Breitband-Projekte" description="Wir haben bereits hunderte Kilometer FTTX-Netze erfolgreich realisiert. Entdecken Sie unsere Referenzen." />
<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?"

View File

@@ -18,27 +18,30 @@ description: "Die E-TIB GmbH ist Ihr zuverlässiger Partner für komplexe Kabelt
companies={[
{
title: "E-TIB GMBH",
description: "Das Unternehmen hat sich voll und ganz auf den Kabelleitungstiefbau spezialisiert. Das komplette Leistungsspektrum zur Errichtung von Kabeltrassen aus einer Hand.",
description: "Das komplette Leistungsspektrum zur Errichtung von Kabeltrassen aus einer Hand.",
icon: "M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z",
backgroundImage: "/assets/photos/DJI_0243.JPG"
url: "/de/standorte/guben",
backgroundImage: "/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-54.jpg"
},
{
title: "E-TIB Ingenieurgesellschaft mbH",
description: "Unsere Ingenieure planen für Sie die Energie- und Telekommunikationsnetze der Zukunft - Vermessung und Dokumentation inklusive.",
icon: "M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4",
url: "https://www.etib-ing.com/",
backgroundImage: "/assets/photos/DSC01137.JPG"
backgroundImage: "/assets/photos/etib_ingenieure_tiefbau_solar_pv_planung_vermessung_gis-298.jpg"
},
{
title: "E-TIB Verwaltung GmbH",
description: "Zentrale Dienste, Einkauf und Finanzen sowie Verwaltung von Immobilien, Grundstücken, Maschinen und Geräten.",
icon: "M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4",
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/bohrtechnik",
backgroundImage: "/assets/photos/DSC08653.JPG"
}
]}
@@ -59,21 +62,25 @@ description: "Die E-TIB GmbH ist Ihr zuverlässiger Partner für komplexe Kabelt
subtitle="Über E-TIB"
badgeStyle="industrial"
className="mb-6 md:mb-8"
>Ihr <span className="text-primary relative whitespace-nowrap">starker<svg className="absolute -bottom-2 left-0 w-full h-3 text-primary/20" viewBox="0 0 100 10" preserveAspectRatio="none"><path d="M0 5 Q 50 10 100 5" stroke="currentColor" strokeWidth="4" fill="none"/></svg></span> Partner <br/>für Infrastruktur</Heading>
>Ihr <span className="text-primary relative whitespace-nowrap">starker<svg className="absolute -bottom-2 left-0 w-full h-3 text-warning/60" viewBox="0 0 100 10" preserveAspectRatio="none"><path d="M0 5 Q 50 10 100 5" stroke="currentColor" strokeWidth="4" fill="none"/></svg></span> Partner <br/>für Infrastruktur</Heading>
<div className="text-xl text-text-secondary leading-relaxed mb-8">
Die E-TIB GmbH ist ein leistungsfähiger und moderner Anbieter von technischen Dienstleistungen. Wir haben uns auf zukunftsweisende Kernbereiche der Infrastruktur spezialisiert.
</div>
{/* Stats Grid */}
<div className="grid grid-cols-2 gap-6 pt-8 border-t border-neutral-200">
<div className="grid grid-cols-3 gap-6 pt-8 border-t border-neutral-200">
<div>
<div className="text-4xl font-black text-primary mb-1 tracking-tighter">2015</div>
<div className="text-sm font-bold text-text-secondary uppercase tracking-wider">Gründung</div>
</div>
<div>
<div className="text-4xl font-black text-primary mb-1 tracking-tighter">50+</div>
<div className="text-sm font-bold text-text-secondary uppercase tracking-wider">Mitarbeiter</div>
<div className="text-4xl font-black text-primary mb-1 tracking-tighter">100+</div>
<div className="text-sm font-bold text-text-secondary uppercase tracking-wider">Mitarbeitende</div>
</div>
<div>
<div className="text-4xl font-black text-primary mb-1 tracking-tighter">100+</div>
<div className="text-sm font-bold text-text-secondary uppercase tracking-wider">Kunden</div>
</div>
</div>
</div>
@@ -110,12 +117,12 @@ description: "Die E-TIB GmbH ist Ihr zuverlässiger Partner für komplexe Kabelt
ctaHref="/de/kompetenzen"
items={[
{
title: "Kabeltiefbau",
description: "Verlegung von Mittel- und Niederspannungskabeln",
title: "Kabelleitungstiefbau",
description: "Kabelleitungstiefbau (Hoch-/Mittel- und Niederspannung) sowie Kabelmontagen bis 110 kV",
tag: "Energie",
size: "large",
href: "/de/kabeltiefbau",
image: { url: "/assets/photos/DSC01123.JPG", alt: "Kabeltiefbau" }
image: { url: "/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-54.jpg", alt: "Kabelleitungstiefbau" }
},
{
title: "Bohrtechnik",
@@ -123,7 +130,7 @@ description: "Die E-TIB GmbH ist Ihr zuverlässiger Partner für komplexe Kabelt
tag: "Innovation",
size: "medium",
href: "/de/bohrtechnik",
image: { url: "/assets/photos/DSC08653.JPG", alt: "Bohrtechnik" }
image: { url: "/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-47.jpg", alt: "Bohrtechnik" }
},
{
title: "Planung",
@@ -131,14 +138,15 @@ description: "Die E-TIB GmbH ist Ihr zuverlässiger Partner für komplexe Kabelt
tag: "Präzision",
size: "small",
href: "/de/planung",
image: { url: "/assets/photos/DJI_0048.JPG", alt: "Planung" }
image: { url: "/assets/photos/etib_ingenieure_tiefbau_solar_pv_planung_vermessung_gis-298.jpg", alt: "Planung" }
},
{
title: "Vermessung",
description: "Digitale Bestandsdokumentation",
tag: "Digital",
size: "accent",
href: "/de/vermessung"
href: "/de/vermessung",
image: { url: "/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie_Vermessung_(26_von_99).jpg", alt: "Vermessung" }
}
]}
/>

View File

@@ -1,14 +1,14 @@
---
title: "Kabelleitungstiefbau"
date: "2024-03-20"
excerpt: "Professioneller Kabeltiefbau für Mittel- und Niederspannungsnetze. Wir garantieren höchste Sicherheitsstandards und lückenlose Dokumentation für Ihr Projekt."
excerpt: "Professioneller Kabelleitungstiefbau (Hoch-, Mittel- und Niederspannung) und Kabelmontagen bis 110 kV. Wir garantieren höchste Sicherheitsstandards und lückenlose Dokumentation für Ihr Projekt."
layout: "fullBleed"
---
<HeroSection
badge="Kernkompetenz"
title="Kabelleitungstiefbau"
subtitle="Komplette Infrastruktur-Lösungen für Mittel- und Niederspannungsnetze"
subtitle="Komplette Infrastruktur-Lösungen für Hoch-, Mittel- und Niederspannungsnetze sowie Kabelmontagen bis 110 kV"
backgroundImage={{ url: '/assets/photos/DSC01123.JPG' }}
alignment="center"
ctaLabel="Projekt anfragen"
@@ -24,13 +24,11 @@ layout: "fullBleed"
Auf vielen Baustellen werden zunehmend Billiganbieter aus dem Ausland eingesetzt, was häufig dazu führt, dass **Sicherheitsstandards und Dokumentationsanforderungen missachtet** werden. Die Folgen sind gravierend: Unfälle, defekte Fremdleitungen (wie Strom, Wasser und Gas) sowie massive Bauverzögerungen und teure Nachträge. Ein vermeintliches Schnäppchen entpuppt sich so schnell als finanzielle Belastung.
Besonders bei geförderten Infrastruktur-Projekten gestaltet sich der Abruf der Fördergelder ohne eine absolut lückenlose, normgerechte Dokumentation äußerst problematisch.
## Alles aus einer Hand
Durch unsere langjährige Erfahrung erkennen wir Problemstellungen frühzeitig und erarbeiten für unsere Auftraggeber im Vorfeld sichere und zufriedenstellende Lösungen. Die E-TIB GmbH hat sich voll und ganz auf den Kabelleitungstiefbau spezialisiert.
Die E-TIB GmbH hat sich voll und ganz auf den Kabelnetzbau spezialisiert. Durch unsere langjährige Erfahrung erkennen wir Problemstellungen frühzeitig und erarbeiten für unsere Auftraggeber im Vorfeld sichere und zufriedenstellende Lösungen.
Wir bieten Ihnen das komplette Leistungsspektrum zur Errichtung von Kabeltrassen aus einer Hand mit eigenem, hochmodernem Maschinenpark und festangestelltem Fachpersonal aus der Region. In direkter Zusammenarbeit mit unserem Partnerbüro, der E-TIB Ingenieurgesellschaft mbH, können wir zudem frühzeitig Planungsfehler ausschließen und selbst die komplexesten Dokumentationsanforderungen souverän erfüllen.
Wir bieten Ihnen das komplette Leistungsspektrum zur Errichtung von Kabeltrassen aus einer Hand mit eigenem, hochmodernem Maschinenpark und festangestelltem Fachpersonal. In direkter Zusammenarbeit mit unserem Partnerbüro, der E-TIB Ingenieurgesellschaft mbH, können wir zudem frühzeitig Planungsfehler ausschließen und selbst die komplexesten Dokumentationsanforderungen souverän erfüllen.
<DataGridPulse />
</div>
@@ -39,7 +37,7 @@ layout: "fullBleed"
badge="Leistungsspektrum"
title="Alles für Ihr Netz"
descriptionParagraphs={[
"Wir bieten höchste Präzision, modernste Maschinen und zertifizierte Experten für jedes Tiefbau-Projekt von der Kabelverlegung bis zur Transformatorstation."
"Wir bieten höchste Präzision, modernste Maschinen und zertifizierte Experten für Ihr Projekt."
]}
panels={[
{
@@ -51,7 +49,7 @@ layout: "fullBleed"
[
"Herstellung von Kabel- und Rohrgräben",
"Kabelverlegung von 0,4 kV bis 110 kV",
"Kabelmontagen von 0,4 kV bis 30 kV",
"Kabelmontagen bis 110 kV",
"Kabelpflugarbeiten für schnelle Verlegung"
]
]
@@ -73,7 +71,7 @@ layout: "fullBleed"
]}
/>
<HomeReferencesSlider badge="Praxisbeispiele" title="Abgeschlossene Tiefbau-Projekte" description="Wir haben über hunderte Kilometer Kabel verlegt. Sehen Sie sich unsere Referenz-Projekte an." />
<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?"

View File

@@ -18,8 +18,8 @@ layout: "fullBleed"
<BenefitGrid
badge="E-TIB Standard"
title="Wir bieten unseren Mitarbeitern"
description="Die E-TIB GmbH wurde aus der Motivation gegründet, hochwertige Leistungen sowie faire Entlohnung zu ermöglichen. Neben der Entlohnung steht die Wertschätzung jedes einzelnen Mitarbeiters bei uns an oberster Stelle."
title="Wir bieten unseren Mitarbeitenden"
description="Die E-TIB GmbH wurde aus der Motivation gegründet, hochwertige Leistungen sowie faire Entlohnung zu ermöglichen. Neben der Entlohnung steht die Wertschätzung jedes einzelnen Mitarbeitenden bei uns an oberster Stelle."
benefits={[
{
id: "region",

View File

@@ -23,12 +23,12 @@ layout: "fullBleed"
ctaHref="/de/kontakt"
items={[
{
title: "Kabeltiefbau",
description: "Klassischer Grabenbau und professionelle Verlegung von Mittel- und Niederspannungskabeln.",
title: "Kabelleitungstiefbau",
description: "Klassischer Grabenbau, professionelle Verlegung und Kabelmontage (Hoch-, Mittel- und Niederspannung) bis 110 kV.",
tag: "Energie",
size: "large",
href: "/de/kabeltiefbau",
image: { url: "/assets/photos/DSC01123.JPG", alt: "Kabeltiefbau" }
image: { url: "/assets/photos/DSC01123.JPG", alt: "Kabelleitungstiefbau" }
},
{
title: "Bohrtechnik",
@@ -70,13 +70,13 @@ layout: "fullBleed"
panels={[
{
id: "energy",
title: "Kabelleitungstiefbau (Mittel-/Niederspannung)",
title: "Kabelleitungstiefbau (Hoch-/Mittel- und Niederspannung)",
icon: "energy",
lists: [
[
"Herstellung von Kabel- und Rohrgräben",
"Kabelverlegung (0,4kV - 110kV)",
"Kabelmontagen 0,4 kV - 30 kV",
"Kabelmontagen bis 110 kV",
"Errichtung von Transformatorstationen",
"Erstellung von Erdungsanlagen",
"Errichtung von Straßenbeleuchtung",
@@ -143,8 +143,8 @@ layout: "fullBleed"
<JsonLd data={[
{
"@type": "Service",
"name": "Kabeltiefbau",
"description": "Klassischer Grabenbau und professionelle Verlegung von Mittel- und Niederspannungskabeln.",
"name": "Kabelleitungstiefbau",
"description": "Klassischer Grabenbau, professionelle Verlegung und Kabelmontage (Hoch-, Mittel- und Niederspannung) bis 110 kV.",
"provider": { "@type": "Organization", "name": "E-TIB GmbH" }
},
{

View File

@@ -5,13 +5,14 @@ excerpt: "Treffen Sie das Team der E-TIB Gruppe persönlich auf Fachmessen und B
layout: "fullBleed"
---
<HomeHero
<HeroSection
badge="Messen & Events"
title="Treffen Sie uns persönlich"
description="Lernen Sie die E-TIB Gruppe auf den führenden Branchenmessen kennen."
videoUrl="/assets/videos/web/hero-bahnkreuzung.mp4"
linkText="Kontakt aufnehmen"
linkHref="/de/kontakt"
subtitle="Lernen Sie die E-TIB Gruppe auf den führenden Branchenmessen kennen."
backgroundImage={{ url: '/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-100.jpg' }}
alignment="center"
ctaLabel="Kontakt aufnehmen"
ctaHref="/de/kontakt"
/>
<div id="termine">
@@ -21,7 +22,7 @@ layout: "fullBleed"
fairs={[
{ name: 'Intersolar München', date: '23. - 25. Juni 2026', type: 'Messe', location: 'München', url: 'https://www.intersolar.de/' },
{ name: 'Windenergietage Linstow', date: '10. - 12. November 2026', type: 'Fachkongress', location: 'Linstow', url: 'https://www.windenergietage.de/' },
{ name: 'Werkstatt Kabel 2026', date: '24. - 25. November 2026', type: 'Fachtagung', location: 'Wiesbaden' }
{ name: 'Werkstatt Kabel 2026', date: '24. - 25. November 2026', type: 'Fachtagung', location: 'Wiesbaden', url: 'https://werkstatt-kabel.essociation.de/' }
]}
/>
</div>

View File

@@ -9,7 +9,7 @@ layout: "fullBleed"
badge="Kernkompetenz"
title="Planung & Beratung"
subtitle="Kompetente Begleitung für Energie- und Telekommunikationsnetze"
backgroundImage={{ url: '/assets/photos/DJI_0048.JPG' }}
backgroundImage={{ url: '/assets/photos/etib_ingenieure_tiefbau_solar_pv_planung_vermessung_gis-298.jpg' }}
alignment="center"
ctaLabel="Projekt anfragen"
ctaHref="/de/kontakt"

View File

@@ -1,14 +0,0 @@
---
title: "Breitbandausbau FTTH, Landkreis Börde"
client: "EKN Breitband GmbH & Co. KG"
date: "2019-05-01"
dateString: "Seit 05/2019"
location: "Landkreis Börde"
featuredImage: "/assets/photos/etib_ingenieure_tiefbau_solar_pv_planung_vermessung_gis-294.jpg"
---
- 109.000 m Leitungstrasse herstellen (Tiefbau/HDD)
- 63 Stück Aufstellung Netzverteiler
- 747 Stück Herstellung Hausanschlüsse
- Koordination und Realisierung der gesamten Trassenführung
- Dokumentation und Abnahme der Hausanschlüsse

View File

@@ -1,13 +0,0 @@
---
title: "Breitbandausbau FTTH, Bomlitz / Schwarmstedt"
client: "inexio Informationstechnologie und Telekommunikation GmbH"
date: "2018-08-01"
dateString: "08/2018 bis 03/2021"
location: "29699 Bomlitz / 29690 Schwarmstedt"
featuredImage: "/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-60.jpg"
---
- 88.890 m Leitungstrasse herstellen (Tiefbau/HDD)
- 23 Stück Aufstellung Multifunktionsgehäuse
- 52 Stück Aufstellung Netzverteiler
- 571 Stück Herstellung Hausanschlüsse

View File

@@ -0,0 +1,17 @@
---
title: "PV-Anlage Dettmannsdorf"
client: "Energiekontor AG"
date: "2026-06-01"
dateString: "01/2025 bis 06/2026"
location: "18334 Dettmannsdorf"
featuredImage: "/assets/photos/DSC08653.JPG"
---
- 12.300 m Kabelgraben ausheben und verfüllen
- 14.200 m Horizontalspülbohrung d 225 / d 200 / d 180
- 26.500 m Verlegung MS-Kabel 630 mm², 18/30 kV
- 7.100 m Verlegung MS-Kabel 1000 mm², 18/30 kV
- 26.500 m Verlegung PE-Schutzrohr 50 x 4,6 mm
- 26.500 m Einblasen LWL-Kabel, 12 Fasern
- sämtliche Mittelspannungsmontagen
- VLF/Mantelprüfungen/OTDR

View File

@@ -1,19 +0,0 @@
---
title: "Kabelverbindung U30 - T10, Eisenhüttenstadt"
client: "ArcelorMittal Eisenhüttenstadt GmbH"
date: "2019-07-01"
dateString: "07/2019 bis 12/2019"
location: "15890 Eisenhüttenstadt"
featuredImage: "/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie_Vermessung_(24_von_99)_groß2.jpg"
---
- 2.095 m Kabelgraben ausheben und verfüllen
- 180 m Horizontalspülbohrung d 160 + d 50
- 5.700 m Lieferung und Verlegung MS-Kabel 240 mm², 18/30 kV
- 3.000 m Lieferung und Verlegung PE-Schutzrohr 50 x 4,6 mm
- 3.000 m Lieferung und Einblasen LWL-Kabel, 12 Fasern
- 3.000 m Lieferung und Verlegung Steuerkabel, 0,6/1 kV
- 16 Satz Lieferung und Montage MS-Verbindungsmuffe 240 mm², 18/30 kV
- 1 Stück Lieferung und Montage LWL-Verbindungsmuffe, 12 Fasern
- 4 Satz Lieferung und Montage MS-T-Stecker 240 mm², 18/30 kV
- Hauptprüfung / Mantelprüfung / OTDR-Messung

View File

@@ -1,16 +0,0 @@
---
title: "Neubau Kabeltrasse, Forst"
client: "Mitteldeutsche Netzgesellschaft Strom mbH"
date: "2020-03-01"
dateString: "03/2020 bis 09/2020"
location: "03149 Forst"
featuredImage: "/assets/photos/DSC02156.jpg"
---
- 2984 m Kabelgraben ausheben und verfüllen
- 945 m Horizontalspülbohrung d 160 + d 50
- 3.929 m Verlegung MS-Kabel 240 mm², 12/20 kV
- 3.929 m Verlegung PE-Schutzrohr 50 x 4,6 mm
- 11 Satz Montage MS-Verbindungsmuffe 240 mm², 12/20 kV
- 1 Satz Montage MS-Endverschluss 240 mm², 12/20 kV
- 2.000 m Rückbau Freileitung (inkl. 16 Stück Maste)

View File

@@ -1,19 +0,0 @@
---
title: "Einspeisung PV-Anlage, Görne"
client: "EVH GmbH"
date: "2020-05-01"
dateString: "05/2020 bis 07/2020"
location: "14728 Görne"
featuredImage: "/assets/photos/DSC08744.JPG"
---
- 4.215 m Kabelgraben ausheben und verfüllen
- 1.285 m Horizontalspülbohrung d 140 + d 50
- 5.500 m Verlegung MS-Kabel 300 mm², 12/20 kV
- 4.500 m Verlegung MS-Kabel 300 mm², 12/20 kV mittels Kabelpflug
- 10.000 m Verlegung PE-Schutzrohr 50 x 4,6 mm
- 10.000 m Einblasen LWL-Kabel, 12 Fasern
- 3 Stück Lieferung und Montage LWL-Verbindungsmuffe, 12 Fasern
- 16 Satz Montage MS-Verbindungsmuffe 300 mm², 12/20 kV
- 4 Satz Montage MS-T-Stecker 300 mm², 12/20 kV
- Mantelprüfung, VLF-Prüfung, OTDR-Messung

View File

@@ -0,0 +1,17 @@
---
title: "110 kV Kabeltrasse Jevenstedt OT Altenkattbek"
client: "wpd GmbH"
date: "2026-03-01"
dateString: "seit 03/2026"
location: "24808 Jevenstedt"
featuredImage: "/assets/photos/DSC01137.JPG"
---
- 500 m Kabelgraben ausheben und verfüllen
- 4.500 m Einpflügen von 3 x PE-Schutzrohr d 160
- 3.200 m Horizontalspülbohrung d 160
- 8.500 m Verlegung HS-Kabel 1.000 mm² 64/110 kV
- 11 Satz Verbindungsmuffen 1.000 mm² 64/110 kV
- 2 Satz Freiluftendverschlüsse 1.000 mm² 64/110 kV
- 8.500 m Einblasen LWL-Kabel, 12 Fasern
- Hochspannungsprüfung mit TE-Messung/OTDR

View File

@@ -0,0 +1,15 @@
---
title: "Netzausbau Gewerbegebiet Ketzin"
client: "E.DIS Netz GmbH"
date: "2025-06-01"
dateString: "01/2025 bis 06/2025"
location: "14669 Ketzin"
featuredImage: "/assets/photos/DJI_0048.JPG"
---
- 1.600 m Kabelgraben ausheben und verfüllen
- 7.500 m Horizontalspülbohrung d 180
- 11.200 m Verlegung MS-Kabel 240 mm², 12/20 kV
- 11.200 m Verlegung PE-Schutzrohr 50 x 4,6 mm
- sämtliche Mittelspannungsmontagen
- VLF/Mantelprüfungen

View File

@@ -0,0 +1,17 @@
---
title: "Windpark Ostbevern"
client: "GP Joule Anlagenbau GmbH & Co. KG"
date: "2026-03-01"
dateString: "02/2025 bis 03/2026"
location: "48346 Ostbevern"
featuredImage: "/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-100.jpg"
---
- 4.100 m Kabelgraben ausheben und verfüllen
- 3.200 m Horizontalspülbohrung d 180 + d 50
- 3.200 m Verlegung MS-Kabel 150 mm², 18/30 kV
- 4.000 m Verlegung MS-Kabel 300 mm², 18/30 kV
- 7.500 m Verlegung PE-Schutzrohr 50 x 4,6 mm
- 7.500 m Einblasen LWL-Kabel, 12 Fasern
- sämtliche Mittelspannungsmontagen
- VLF/Mantelprüfungen/OTDR

View File

@@ -0,0 +1,17 @@
---
title: "PV-Anlage Petershagen"
client: "NaturStromAnlagen GmbH"
date: "2025-02-01"
dateString: "04/2024 bis 02/2025"
location: "15326 Petershagen"
featuredImage: "/assets/photos/DSC01123.JPG"
---
- 12.000 m Kabelgraben ausheben und verfüllen
- 3.000 m Horizontalspülbohrung d 225 / d 200 / d 160
- 10.000 m Verlegung MS-Kabel 630 mm², 18/30 kV
- 17.000 m Verlegung MS-Kabel 800 mm², 18/30 kV
- 10.000 m Verlegung PE-Schutzrohr 50 x 4,6 mm
- 10.000 m Einblasen LWL-Kabel, 12 Fasern
- sämtliche Mittelspannungsmontagen
- VLF/Mantelprüfungen/OTDR

View File

@@ -0,0 +1,17 @@
---
title: "PV-Anlage Prötzel OT Sternebeck"
client: "Trianel GmbH"
date: "2025-08-01"
dateString: "02/2025 bis 08/2025"
location: "15345 Prötzel"
featuredImage: "/assets/photos/DJI_0243.JPG"
---
- 2.600 m Kabelgraben ausheben und verfüllen
- 3.800 m Horizontalspülbohrung d 225 / d 200 / d 160
- 7.500 m Verlegung MS-Kabel 240 mm², 18/30 kV
- 8.800 m Verlegung MS-Kabel 800 mm², 18/30 kV
- 15.800 m Verlegung PE-Schutzrohr 50 x 4,6 mm
- 15.800 m Einblasen LWL-Kabel, 12 Fasern
- sämtliche Mittelspannungsmontagen
- VLF/Mantelprüfungen/OTDR

View File

@@ -1,17 +0,0 @@
---
title: "Breitbandausbau FTTC, Planungsregion Spreewald"
client: "Telekom Deutschland GmbH"
date: "2017-09-01"
dateString: "09/2017 bis 01/2018"
location: "Planungsregion Spreewald"
featuredImage: "/assets/photos/DSC01129.JPG"
---
- 4.006 m Kabelgraben ausheben und verfüllen
- 4.006 m Verlegung PE-Schutzrohr 50 x 4,6 mm
- 13.008 m Horizontalspülbohrung D 50
- 94.951 m Einblasen von Kabel/Rohren unbelegt
- 42 Stück Stellen von Multifunktionsgehäusen
- Aufbau von Energieanschlusssäulen und elektrischen Anlagen 230V
- Koordination mit Energieversorgungsunternehmen und Inbetriebnahme der elektrischen Anlagen
- Oberflächen- und Tiefbauarbeiten für Multifunktionsgehäuse

View File

@@ -42,7 +42,7 @@ layout: "fullBleed"
{
id: "martin-polan",
name: "Martin Polan",
position: "Polier",
position: "Bauleiter",
email: "m.polan@e-tib.com",
phone: "+49 171 3868167",
image: "/assets/photos/team/martin.jpg"

View File

@@ -27,13 +27,13 @@ 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 über 50 engagierten Fachkräften und einem hochmodernen Maschinenpark meistern wir selbst anspruchsvollste Projekte im Kabelleitungstiefbau, der Spülbohrtechnik und der Netzmontage. Verlässlichkeit, Termintreue und höchste Qualitätsstandards sind dabei unser Fundament.
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.
</div>
</div>
<div className="grid grid-cols-2 gap-6">
<div className="bg-white p-8 rounded-2xl shadow-sm border border-neutral-100">
<div className="text-4xl font-extrabold text-primary mb-2">50+</div>
<div className="text-neutral-dark font-semibold">Mitarbeiter</div>
<div className="text-4xl font-extrabold text-primary mb-2">100+</div>
<div className="text-neutral-dark font-semibold">Mitarbeitende</div>
</div>
<div className="bg-white p-8 rounded-2xl shadow-sm border border-neutral-100">
<div className="text-4xl font-extrabold text-primary mb-2">2015</div>
@@ -52,7 +52,7 @@ layout: "fullBleed"
</div>
</div>
<InteractiveGermanyMap isHero={true} badge="Bundesweite Präsenz" title="Infrastruktur für ein ganzes Land" description="Seit 2023 haben wir in über 100 Projekten quer durch Deutschland bewiesen, dass wir Infrastrukturprojekte jeder Größenordnung verlässlich umsetzen." />
<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." />
<CompanyTimeline />
@@ -63,32 +63,36 @@ layout: "fullBleed"
companies={[
{
title: "E-TIB GMBH",
description: "Das Unternehmen hat sich voll und ganz auf den Kabelleitungstiefbau spezialisiert. Das komplette Leistungsspektrum zur Errichtung von Kabeltrassen aus einer Hand.",
description: "Das komplette Leistungsspektrum zur Errichtung von Kabeltrassen aus einer Hand.",
icon: "M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z",
url: "https://www.e-tib.com/",
backgroundImage: "/assets/photos/DJI_0243.JPG"
url: "/de/standorte/guben",
backgroundImage: "/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-54.jpg"
},
{
title: "E-TIB Ingenieurgesellschaft mbH",
description: "Unsere Ingenieure planen für Sie die Energie- und Telekommunikationsnetze der Zukunft - Vermessung und Dokumentation inklusive.",
icon: "M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4",
url: "https://www.etib-ing.com/",
backgroundImage: "/assets/photos/DSC01137.JPG"
backgroundImage: "/assets/photos/etib_ingenieure_tiefbau_solar_pv_planung_vermessung_gis-298.jpg"
},
{
title: "E-TIB Verwaltung GmbH",
description: "Zentrale Dienste, Einkauf und Finanzen sowie Verwaltung von Immobilien, Grundstücken, Maschinen und Geräten.",
icon: "M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4",
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",
backgroundImage: "/assets/photos/DSC08653.JPG"
url: "/de/standorte/kirchheilingen",
backgroundImage: "/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-47.jpg"
}
]}
/>
</div>
<CallToAction />

View File

@@ -8,8 +8,8 @@ layout: "fullBleed"
<HeroSection
badge="Kernkompetenz"
title="Vermessung & Dokumentation"
subtitle="Lückenlose und rechtssichere Erfassung aller Bauphasen"
backgroundImage={{ url: '/assets/photos/DSC08653.JPG' }}
subtitle="Hochpräzise digitale Bestandsdokumentation, 3D-Scans und Drohnenvermessung für Ihre Leitungstrassen und Anlagen."
backgroundImage={{ url: '/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie_Vermessung_(24_von_99)_groß2.jpg' }}
alignment="center"
ctaLabel="Projekt anfragen"
ctaHref="/de/kontakt"

View File

@@ -1,5 +1,5 @@
---
title: "Trenchless Line Laying"
title: "Drilling Technology"
date: "2024-03-20"
excerpt: "Precise horizontal directional drilling and earth rockets in all soil classes for surface-friendly and efficient line laying."
layout: "fullBleed"
@@ -7,9 +7,9 @@ layout: "fullBleed"
<HeroSection
badge="Core Competency"
title="Trenchless Laying"
subtitle="Surface-friendly horizontal directional drilling and earth rockets"
backgroundImage={{ url: '/assets/photos/DSC08653.JPG' }}
title="Drilling Technology"
subtitle="Trenchless Laying, horizontal directional drilling and earth rockets"
backgroundImage={{ url: '/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-47.jpg' }}
alignment="center"
ctaLabel="Request a project"
ctaHref="/en/contact"
@@ -26,7 +26,7 @@ layout: "fullBleed"
## HDD Directional Drilling & Pneumatic Earth Rockets
Armed with a state-of-the-art, specialized fleet of drilling rigs, we master complex subterranean conditions. Utilizing the **Horizontal Directional Drilling (HDD)** method, we guide the drill head with centimeter-level accuracy beneath obstacles. This enables us to achieve continuous drilling lengths of up to 250 meters in a single run, pulling in high-durability protective conduits with diameters up to 400 mm.
Armed with a state-of-the-art, specialized fleet of drilling rigs, we master complex subterranean conditions. Utilizing the **Horizontal Directional Drilling (HDD)** method, we guide the drill head with centimeter-level accuracy beneath obstacles. This enables us to achieve continuous drilling lengths of up to 400 meters in a single run and, depending on the drilling length, pull in high-durability protective conduits with diameters up to 600 mm.
For localized, rapid deployments—such as residential service connections—we deploy high-speed **pneumatic earth rockets** (soil displacement). This method allows us to complete under-crossings of up to 15 meters for conduits up to 160 mm in diameter, ensuring pristine driveways, manicured gardens, and pedestrian walks remain completely undisturbed.
@@ -47,8 +47,8 @@ layout: "fullBleed"
fullWidth: false,
lists: [
[
"Max. drilling length: 250 m",
"Max. diameter: 400mm pipe",
"Max. drilling length: 400 m",
"Max. diameter: 600mm pipe",
"Precision control and steerability",
"Crossing of railways, highways & water bodies"
]
@@ -71,7 +71,7 @@ layout: "fullBleed"
]}
/>
<HomeReferencesSlider badge="Case Studies" title="Completed Drilling Projects" description="Successful HDD drilling and trenchless cable laying under the most complex conditions." />
<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?"

View File

@@ -69,7 +69,7 @@ layout: "fullBleed"
]}
/>
<HomeReferencesSlider badge="Case Studies" title="Completed Broadband Projects" description="We have already successfully realized hundreds of kilometers of FTTX networks. Discover our references." />
<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?"

View File

@@ -18,27 +18,30 @@ description: "E-TIB GmbH is your reliable partner for complex cable routes, hori
companies={[
{
title: "E-TIB GMBH",
description: "The company has fully specialized in cable civil engineering. The complete range of services for the construction of cable routes from a single source.",
description: "The complete range of services for the construction of cable routes from a single source.",
icon: "M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z",
backgroundImage: "/assets/photos/DJI_0243.JPG"
url: "/en/standorte/guben",
backgroundImage: "/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-54.jpg"
},
{
title: "E-TIB Ingenieurgesellschaft mbH",
description: "Our engineers plan the energy and telecommunications networks of the future for you - surveying and documentation included.",
icon: "M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4",
url: "https://www.etib-ing.com/",
backgroundImage: "/assets/photos/DSC01137.JPG"
backgroundImage: "/assets/photos/etib_ingenieure_tiefbau_solar_pv_planung_vermessung_gis-298.jpg"
},
{
title: "E-TIB Verwaltung GmbH",
description: "Central services, purchasing, finance, and management of real estate, properties, machinery, and equipment.",
icon: "M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4",
url: "/en/standorte/buelstedt",
backgroundImage: "/assets/photos/DJI_0048.JPG"
},
{
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/drilling-technology",
backgroundImage: "/assets/photos/DSC08653.JPG"
}
]}
@@ -59,22 +62,26 @@ description: "E-TIB GmbH is your reliable partner for complex cable routes, hori
subtitle="About E-TIB"
badgeStyle="industrial"
className="mb-6 md:mb-8"
>Your <span className="text-primary relative whitespace-nowrap">strong<svg className="absolute -bottom-2 left-0 w-full h-3 text-primary/20" viewBox="0 0 100 10" preserveAspectRatio="none"><path d="M0 5 Q 50 10 100 5" stroke="currentColor" strokeWidth="4" fill="none"/></svg></span> Partner <br/>for Infrastructure</Heading>
>Your <span className="text-primary relative whitespace-nowrap">strong<svg className="absolute -bottom-2 left-0 w-full h-3 text-warning/60" viewBox="0 0 100 10" preserveAspectRatio="none"><path d="M0 5 Q 50 10 100 5" stroke="currentColor" strokeWidth="4" fill="none"/></svg></span> Partner <br/>for Infrastructure</Heading>
<div className="text-xl text-text-secondary leading-relaxed mb-8">
E-TIB GmbH is an efficient and modern provider of technical services. We specialize in future-oriented core areas of infrastructure.
</div>
{/* Stats Grid */}
<div className="grid grid-cols-2 gap-6 pt-8 border-t border-neutral-200">
<div className="grid grid-cols-3 gap-6 pt-8 border-t border-neutral-200">
<div>
<div className="text-4xl font-black text-primary mb-1 tracking-tighter">2015</div>
<div className="text-sm font-bold text-text-secondary uppercase tracking-wider">Founded</div>
</div>
<div>
<div className="text-4xl font-black text-primary mb-1 tracking-tighter">50+</div>
<div className="text-4xl font-black text-primary mb-1 tracking-tighter">100+</div>
<div className="text-sm font-bold text-text-secondary uppercase tracking-wider">Employees</div>
</div>
<div>
<div className="text-4xl font-black text-primary mb-1 tracking-tighter">100+</div>
<div className="text-sm font-bold text-text-secondary uppercase tracking-wider">Clients</div>
</div>
</div>
</div>
@@ -110,12 +117,12 @@ description: "E-TIB GmbH is your reliable partner for complex cable routes, hori
ctaHref="/en/competencies"
items={[
{
title: "Cable Construction",
description: "Installation of medium and low voltage cables",
title: "Cable Civil Engineering",
description: "Cable civil engineering (high, medium, low voltage) and cable assembly up to 110 kV",
tag: "Energy",
size: "large",
href: "/en/cable-civil-engineering",
image: { url: "/assets/photos/DSC01123.JPG", alt: "Cable Construction" }
image: { url: "/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-54.jpg", alt: "Cable Civil Engineering" }
},
{
title: "Drilling Technology",
@@ -123,7 +130,7 @@ description: "E-TIB GmbH is your reliable partner for complex cable routes, hori
tag: "Innovation",
size: "medium",
href: "/en/drilling-technology",
image: { url: "/assets/photos/DSC08653.JPG", alt: "Drilling Technology" }
image: { url: "/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-47.jpg", alt: "Drilling Technology" }
},
{
title: "Planning",
@@ -131,14 +138,15 @@ description: "E-TIB GmbH is your reliable partner for complex cable routes, hori
tag: "Precision",
size: "small",
href: "/en/planning",
image: { url: "/assets/photos/DJI_0048.JPG", alt: "Planning" }
image: { url: "/assets/photos/etib_ingenieure_tiefbau_solar_pv_planung_vermessung_gis-298.jpg", alt: "Planning" }
},
{
title: "Surveying",
description: "Digital as-built documentation",
tag: "Digital",
size: "accent",
href: "/en/surveying"
href: "/en/surveying",
image: { url: "/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie_Vermessung_(26_von_99).jpg", alt: "Surveying" }
}
]}
/>

View File

@@ -1,14 +1,14 @@
---
title: "Cable Civil Engineering"
date: "2024-03-20"
excerpt: "Professional cable civil engineering for medium and low voltage networks. We guarantee maximum safety standards and seamless documentation for your project."
excerpt: "Professional cable civil engineering (high, medium, and low voltage) and cable assembly up to 110 kV. We guarantee maximum safety standards and seamless documentation for your project."
layout: "fullBleed"
---
<HeroSection
badge="Core Competency"
title="Cable Civil Engineering"
subtitle="Complete infrastructure solutions for medium and low voltage networks"
subtitle="Complete infrastructure solutions for high, medium, and low voltage networks and cable assembly up to 110 kV"
backgroundImage={{ url: '/assets/photos/DSC01123.JPG' }}
alignment="center"
ctaLabel="Request a project"
@@ -24,22 +24,20 @@ layout: "fullBleed"
Modern civil engineering is plagued by low-cost contractors who routinely **compromise on safety margins and technical documentation**. The repercussions are severe: catastrophic utility strikes (power, water, gas, telecom), costly project delays, and massive budget overruns. What begins as a low-bid shortcut quickly turns into a financial and legal nightmare.
Furthermore, public or subsidized infrastructure projects require meticulously structured, standard-compliant documentation. Without flawless records, the release of critical funding and subsidies is regularly delayed or denied.
## Everything from a single source
## Integrated Excellence from a Single Source
E-TIB GmbH is fully specialized in cable network construction. Thanks to our many years of experience, we identify problems early on and develop safe and satisfactory solutions for our clients in advance.
At E-TIB, we leverage decades of collective expertise to anticipate structural and geological bottlenecks long before the first shovel hits the ground. Our specialization in cable civil engineering guarantees that every deployment runs with absolute precision.
We deliver turnkey cable routes entirely in-house. Our operations are powered by a cutting-edge fleet of heavy machinery and staffed exclusively by highly trained, permanent regional professionals. Working in close synergy with our sister firm, **E-TIB Ingenieurgesellschaft mbH**, we eliminate planning oversights at the inception phase and effortlessly handle the most complex GIS and administrative documentation requirements in the industry.
We offer you the complete range of services for the construction of cable routes from a single source - with our own ultra-modern machine park and permanently employed specialist staff. In direct cooperation with our partner office, E-TIB Ingenieurgesellschaft mbH, we can also rule out planning errors early on and master even the most complex documentation requirements confidently.
<DataGridPulse />
</div>
<ServiceDetailGrid
badge="Service Portfolio"
title="Everything for Your Network"
badge="Service Spectrum"
title="Everything for your network"
descriptionParagraphs={[
"We offer the highest precision, modern machines and certified experts for every civil engineering project - from cable laying to transformer stations."
"We offer the highest precision, state-of-the-art machinery, and certified experts for your project."
]}
panels={[
{
@@ -51,7 +49,7 @@ layout: "fullBleed"
[
"Production of cable and pipe trenches",
"Cable laying from 0.4 kV to 110 kV",
"Cable assembly from 0.4 kV to 30 kV",
"Cable assembly up to 110 kV",
"Cable plowing works for fast laying"
]
]
@@ -73,7 +71,7 @@ layout: "fullBleed"
]}
/>
<HomeReferencesSlider badge="Case Studies" title="Completed Civil Engineering Projects" description="We have laid hundreds of kilometers of cables. Take a look at our reference projects." />
<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?"

View File

@@ -23,12 +23,12 @@ layout: "fullBleed"
ctaHref="/en/contact"
items={[
{
title: "Cable Construction",
description: "Classic trench construction and professional laying of medium and low voltage cables.",
title: "Cable Civil Engineering",
description: "Classic trench construction, professional laying and cable assembly (high, medium, and low voltage) up to 110 kV.",
tag: "Energy",
size: "large",
href: "/en/cable-civil-engineering",
image: { url: "/assets/photos/DSC01123.JPG", alt: "Cable Construction" }
image: { url: "/assets/photos/DSC01123.JPG", alt: "Cable Civil Engineering" }
},
{
title: "Drilling Technology",
@@ -70,13 +70,13 @@ layout: "fullBleed"
panels={[
{
id: "energy",
title: "Cable Civil Engineering (Medium/Low Voltage)",
title: "Cable Civil Engineering (High/Medium/Low Voltage)",
icon: "energy",
lists: [
[
"Production of cable and pipe trenches",
"Cable laying (0.4kV - 110kV)",
"Cable assembly 0.4 kV - 30 kV",
"Cable assembly up to 110 kV",
"Construction of transformer stations",
"Establishment of grounding systems",
"Erection of street lighting",
@@ -143,8 +143,8 @@ layout: "fullBleed"
<JsonLd data={[
{
"@type": "Service",
"name": "Cable Construction",
"description": "Classic trench construction and professional laying of medium and low voltage cables.",
"name": "Cable Civil Engineering",
"description": "Classic trench construction, professional laying and cable assembly (high, medium, and low voltage) up to 110 kV.",
"provider": { "@type": "Organization", "name": "E-TIB GmbH" }
},
{

View File

@@ -5,13 +5,14 @@ excerpt: "Meet the team of the E-TIB Group personally at trade fairs and industr
layout: "fullBleed"
---
<HomeHero
<HeroSection
badge="Fairs & Events"
title="Meet us personally"
description="Get to know the E-TIB Group at the leading industry trade fairs."
videoUrl="/assets/videos/web/hero-bahnkreuzung.mp4"
linkText="Get in Touch"
linkHref="/en/contact"
subtitle="Get to know the E-TIB Group at the leading industry trade fairs."
backgroundImage={{ url: '/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-100.jpg' }}
alignment="center"
ctaLabel="Get in Touch"
ctaHref="/en/contact"
/>
<div id="termine">
@@ -21,7 +22,7 @@ layout: "fullBleed"
fairs={[
{ name: 'Intersolar Munich', date: 'June 2325, 2026', type: 'Fair', location: 'Munich', url: 'https://www.intersolar.de/' },
{ name: 'Wind Energy Days Linstow', date: 'November 1012, 2026', type: 'Specialist Congress', location: 'Linstow', url: 'https://www.windenergietage.de/' },
{ name: 'Werkstatt Kabel 2026', date: 'November 2425, 2026', type: 'Symposium', location: 'Wiesbaden' }
{ name: 'Werkstatt Kabel 2026', date: 'November 2425, 2026', type: 'Symposium', location: 'Wiesbaden', url: 'https://werkstatt-kabel.essociation.de/' }
]}
/>
</div>

View File

@@ -9,7 +9,7 @@ layout: "fullBleed"
badge="Core Competency"
title="Planning & Consulting"
subtitle="Competent support for energy and telecommunications networks"
backgroundImage={{ url: '/assets/photos/DJI_0048.JPG' }}
backgroundImage={{ url: '/assets/photos/etib_ingenieure_tiefbau_solar_pv_planung_vermessung_gis-298.jpg' }}
alignment="center"
ctaLabel="Request a project"
ctaHref="/en/contact"

View File

@@ -1,14 +0,0 @@
---
title: "Broadband Expansion FTTH, Börde District"
client: "EKN Breitband GmbH & Co. KG"
date: "2019-05-01"
dateString: "Since 05/2019"
location: "Börde District"
featuredImage: "/assets/photos/etib_ingenieure_tiefbau_solar_pv_planung_vermessung_gis-294.jpg"
---
- 109,000 m production of cable route (civil engineering/HDD)
- 63 units installation of network distributors
- 747 units production of house connections
- Coordination and realization of the entire route guidance
- Documentation and acceptance of the house connections

View File

@@ -1,13 +0,0 @@
---
title: "Broadband Expansion FTTH, Bomlitz / Schwarmstedt"
client: "inexio Informationstechnologie und Telekommunikation GmbH"
date: "2018-08-01"
dateString: "08/2018 to 03/2021"
location: "29699 Bomlitz / 29690 Schwarmstedt"
featuredImage: "/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-60.jpg"
---
- 88,890 m production of cable route (civil engineering/HDD)
- 23 units installation of multi-functional cabinets
- 52 units installation of network distributors
- 571 units production of house connections

View File

@@ -0,0 +1,17 @@
---
title: "PV Plant Dettmannsdorf"
client: "Energiekontor AG"
date: "2026-06-01"
dateString: "01/2025 to 06/2026"
location: "18334 Dettmannsdorf"
featuredImage: "/assets/photos/DSC08653.JPG"
---
- Excavation and backfilling of 12,300 m cable trench
- 14,200 m HDD directional drilling d 225 / d 200 / d 180
- 26,500 m laying of MV cable 630 mm², 18/30 kV
- 7,100 m laying of MV cable 1000 mm², 18/30 kV
- 26,500 m laying of PE protective pipe 50 x 4.6 mm
- 26,500 m fiber optic cable blowing, 12 fibers
- All medium voltage assembly works
- VLF / Sheath testing / OTDR

View File

@@ -1,19 +0,0 @@
---
title: "Cable Connection U30 - T10, Eisenhüttenstadt"
client: "ArcelorMittal Eisenhüttenstadt GmbH"
date: "2019-07-01"
dateString: "07/2019 to 12/2019"
location: "15890 Eisenhüttenstadt"
featuredImage: "/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie_Vermessung_(24_von_99)_groß2.jpg"
---
- 2,095 m cable trench excavation and backfilling
- 180 m horizontal directional drilling d 160 + d 50
- 5,700 m delivery and installation of MV cable 240 mm², 18/30 kV
- 3,000 m delivery and installation of PE protection pipe 50 x 4.6 mm
- 3,000 m delivery and blowing in of FO cable, 12 fibers
- 3,000 m delivery and installation of control cable, 0.6/1 kV
- 16 sets delivery and assembly of MV connection joint 240 mm², 18/30 kV
- 1 unit delivery and assembly of FO connection joint, 12 fibers
- 4 sets delivery and assembly of MV T-connectors 240 mm², 18/30 kV
- Main testing / sheath testing / OTDR measurement

View File

@@ -1,16 +0,0 @@
---
title: "New Cable Route, Forst"
client: "Mitteldeutsche Netzgesellschaft Strom mbH"
date: "2020-03-01"
dateString: "03/2020 to 09/2020"
location: "03149 Forst"
featuredImage: "/assets/photos/DSC02156.jpg"
---
- 2,984 m cable trench excavation and backfilling
- 945 m horizontal directional drilling d 160 + d 50
- 3,929 m installation of MV cable 240 mm², 12/20 kV
- 3,929 m installation of PE protection pipe 50 x 4.6 mm
- 11 sets assembly of MV connection joint 240 mm², 12/20 kV
- 1 set assembly of MV end termination 240 mm², 12/20 kV
- 2,000 m dismantling of overhead line (incl. 16 poles)

View File

@@ -1,19 +0,0 @@
---
title: "PV System Feed-in, Görne"
client: "EVH GmbH"
date: "2020-05-01"
dateString: "05/2020 to 07/2020"
location: "14728 Görne"
featuredImage: "/assets/photos/DSC08744.JPG"
---
- 4,215 m cable trench excavation and backfilling
- 1,285 m horizontal directional drilling d 140 + d 50
- 5,500 m installation of MV cable 300 mm², 12/20 kV
- 4,500 m installation of MV cable 300 mm², 12/20 kV by cable plow
- 10,000 m installation of PE protection pipe 50 x 4.6 mm
- 10,000 m blowing in of FO cable, 12 fibers
- 3 units delivery and assembly of FO connection joint, 12 fibers
- 16 sets assembly of MV connection joint 300 mm², 12/20 kV
- 4 sets assembly of MV T-connectors 300 mm², 12/20 kV
- Sheath testing, VLF testing, OTDR measurement

View File

@@ -0,0 +1,17 @@
---
title: "110 kV Cable Route Jevenstedt OT Altenkattbek"
client: "wpd GmbH"
date: "2026-03-01"
dateString: "since 03/2026"
location: "24808 Jevenstedt"
featuredImage: "/assets/photos/DSC01137.JPG"
---
- Excavation and backfilling of 500 m cable trench
- 4,500 m plowing of 3 x PE protective pipe d 160
- 3,200 m HDD directional drilling d 160
- 8,500 m laying of HV cable 1,000 mm² 64/110 kV
- 11 sets of connection joints 1,000 mm² 64/110 kV
- 2 sets of outdoor terminations 1,000 mm² 64/110 kV
- 8,500 m fiber optic cable blowing, 12 fibers
- High-voltage testing with PD measurement/OTDR

View File

@@ -0,0 +1,15 @@
---
title: "Grid Expansion Commercial Area Ketzin"
client: "E.DIS Netz GmbH"
date: "2025-06-01"
dateString: "01/2025 to 06/2025"
location: "14669 Ketzin"
featuredImage: "/assets/photos/DJI_0048.JPG"
---
- Excavation and backfilling of 1,600 m cable trench
- 7,500 m HDD directional drilling d 180
- 11,200 m laying of MV cable 240 mm², 12/20 kV
- 11,200 m laying of PE protective pipe 50 x 4.6 mm
- All medium voltage assembly works
- VLF testing

View File

@@ -0,0 +1,17 @@
---
title: "Wind Farm Ostbevern"
client: "GP Joule Anlagenbau GmbH & Co. KG"
date: "2026-03-01"
dateString: "02/2025 to 03/2026"
location: "48346 Ostbevern"
featuredImage: "/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-100.jpg"
---
- Excavation and backfilling of 4,100 m cable trench
- 3,200 m HDD directional drilling d 180 + d 50
- 3,200 m laying of MV cable 150 mm², 18/30 kV
- 4,000 m laying of MV cable 300 mm², 18/30 kV
- 7,500 m laying of PE protective pipe 50 x 4.6 mm
- 7,500 m fiber optic cable blowing, 12 fibers
- All medium voltage assembly works
- VLF / Sheath testing / OTDR

View File

@@ -0,0 +1,17 @@
---
title: "PV Plant Petershagen"
client: "NaturStromAnlagen GmbH"
date: "2025-02-01"
dateString: "04/2024 to 02/2025"
location: "15326 Petershagen"
featuredImage: "/assets/photos/DSC01123.JPG"
---
- Excavation and backfilling of 12,000 m cable trench
- 3,000 m HDD directional drilling d 225 / d 200 / d 160
- 10,000 m laying of MV cable 630 mm², 18/30 kV
- 17,000 m laying of MV cable 800 mm², 18/30 kV
- 10,000 m laying of PE protective pipe 50 x 4.6 mm
- 10,000 m fiber optic cable blowing, 12 fibers
- All medium voltage assembly works
- VLF / Sheath testing / OTDR

View File

@@ -0,0 +1,17 @@
---
title: "PV Plant Prötzel OT Sternebeck"
client: "Trianel GmbH"
date: "2025-08-01"
dateString: "02/2025 to 08/2025"
location: "15345 Prötzel"
featuredImage: "/assets/photos/DJI_0243.JPG"
---
- Excavation and backfilling of 2,600 m cable trench
- 3,800 m HDD directional drilling d 225 / d 200 / d 160
- 7,500 m laying of MV cable 240 mm², 18/30 kV
- 8,800 m laying of MV cable 800 mm², 18/30 kV
- 15,800 m laying of PE protective pipe 50 x 4.6 mm
- 15,800 m fiber optic cable blowing, 12 fibers
- All medium voltage assembly works
- VLF / Sheath testing / OTDR

View File

@@ -1,17 +0,0 @@
---
title: "Broadband Expansion FTTC, Spreewald Planning Region"
client: "Telekom Deutschland GmbH"
date: "2017-09-01"
dateString: "09/2017 to 01/2018"
location: "Spreewald Planning Region"
featuredImage: "/assets/photos/DSC01129.JPG"
---
- 4,006 m cable trench excavation and backfilling
- 4,006 m installation of PE protection pipe 50 x 4.6 mm
- 13,008 m horizontal directional drilling D 50
- 94,951 m blowing in of cables/pipes (unoccupied)
- 42 units installation of multi-functional cabinets
- Setup of energy connection pillars and electrical systems 230V
- Coordination with utility companies and commissioning of the electrical systems
- Surface and civil engineering work for multi-function enclosures

View File

@@ -42,7 +42,7 @@ layout: "fullBleed"
{
id: "martin-polan",
name: "Martin Polan",
position: "Foreman",
position: "Site Manager",
email: "m.polan@e-tib.com",
phone: "+49 171 3868167",
image: "/assets/photos/team/martin.jpg"

View File

@@ -27,12 +27,12 @@ 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 over 50 dedicated professionals and a state-of-the-art machinery park, we master even the most demanding projects in cable civil engineering, directional drilling, and grid assembly. Reliability, adherence to schedules, and the highest quality standards are our foundation.
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.
</div>
</div>
<div className="grid grid-cols-2 gap-6">
<div className="bg-white p-8 rounded-2xl shadow-sm border border-neutral-100">
<div className="text-4xl font-extrabold text-primary mb-2">50+</div>
<div className="text-4xl font-extrabold text-primary mb-2">100+</div>
<div className="text-neutral-dark font-semibold">Employees</div>
</div>
<div className="bg-white p-8 rounded-2xl shadow-sm border border-neutral-100">
@@ -52,7 +52,7 @@ layout: "fullBleed"
</div>
</div>
<InteractiveGermanyMap isHero={true} badge="Nationwide Presence" title="Infrastructure for an entire country" description="Since 2023, we have proven in over 100 projects across Germany that we reliably implement infrastructure projects of any scale." />
<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." />
<CompanyTimeline />
@@ -63,37 +63,36 @@ layout: "fullBleed"
companies={[
{
title: "E-TIB GMBH",
description: "The company has fully specialized in cable civil engineering. The complete range of services for the construction of cable routes from a single source.",
description: "The complete range of services for the construction of cable routes from a single source.",
icon: "M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z",
url: "https://www.e-tib.com/",
backgroundImage: "/assets/photos/DJI_0243.JPG"
url: "/en/standorte/guben",
backgroundImage: "/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-54.jpg"
},
{
title: "E-TIB Ingenieurgesellschaft mbH",
description: "Our engineers plan the energy and telecommunications networks of the future for you - surveying and documentation included.",
icon: "M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4",
url: "https://www.etib-ing.com/",
backgroundImage: "/assets/photos/DSC01137.JPG"
backgroundImage: "/assets/photos/etib_ingenieure_tiefbau_solar_pv_planung_vermessung_gis-298.jpg"
},
{
title: "E-TIB Verwaltung GmbH",
description: "Central services, purchasing, finance, and management of real estate, properties, machinery, and equipment.",
icon: "M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4",
url: "/en/standorte/buelstedt",
backgroundImage: "/assets/photos/DJI_0048.JPG"
},
{
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",
backgroundImage: "/assets/photos/DSC08653.JPG"
url: "/en/standorte/kirchheilingen",
backgroundImage: "/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-47.jpg"
}
]}
/>
</div>
<CallToAction
title="Ready for Your Project?"
description="We are always looking for new challenges and strong partners. Contact us for a non-binding consultation on your project."
ctaLabel="Contact Us Now"
ctaHref="/en/contact"
/>
<CallToAction />

View File

@@ -8,8 +8,8 @@ layout: "fullBleed"
<HeroSection
badge="Core Competency"
title="Surveying & Documentation"
subtitle="Seamless and legally compliant recording of all construction phases"
backgroundImage={{ url: '/assets/photos/DSC08653.JPG' }}
subtitle="High-precision digital as-built documentation, 3D scans, and drone surveying for your line routes and facilities."
backgroundImage={{ url: '/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie_Vermessung_(24_von_99)_groß2.jpg' }}
alignment="center"
ctaLabel="Request a project"
ctaHref="/en/contact"

11
data/Orte 2023.txt Normal file
View File

@@ -0,0 +1,11 @@
PV-Anlage, 14797 Göhlsdorf
PV-Anlage, 24631 Langwedel
Windpark, 48346 Ostbevern
Windpark, 18249 Tarnow-Prüzen
Windpark, 24161 Felm
PV-Anlage, 25560 Agethorst
Windpark, 16866 Gumtow OT Schrepkow
Windpark, 21649 Regesbostel
PV-Anlage, 25361 Krempe
PV-Anlage, 25596 Nienbüttel
Windpark, 16845 Neustadt Dosse

4
data/Orte 2026.txt Normal file
View File

@@ -0,0 +1,4 @@
PV-Anlage, 03238 Sallgast
PV-Anlage, 19372 Rom
PV-Anlage, 15374 Eggersdorf
Batteriespeicher, 39443 Staßfurt OT Förderstedt

View File

@@ -12,76 +12,52 @@ export interface Location {
export const defaultLocations: Location[] = [
{
id: 'guben',
name: 'Guben (Hauptsitz)',
type: 'hq',
x: 85,
y: 41.1,
description: 'E-TIB GmbH Holding & Bohrtechnik GmbH',
details: ['Zentrale Steuerung', 'Kabelleitungstiefbau', 'Maschinenpark'],
},
{
id: 'buelstedt',
name: 'Bülstedt (Ingenieurgesellschaft)',
type: 'branch',
x: 37,
y: 25.33,
description: 'E-TIB Ingenieurgesellschaft mbH',
details: ['Planung & Projektierung', 'Vermessung', 'Dokumentation'],
},
{
id: 'spreewald',
name: 'Spreewald (FTTC)',
id: 'dettmannsdorf',
name: 'Dettmannsdorf (PV)',
type: 'project',
x: 81,
y: 36.99,
description: 'Breitbandausbau FTTC',
href: '/referenzen/spreewald',
x: 66.38,
y: 14.04,
description: 'Netzanbindung Solarpark',
},
{
id: 'bomlitz',
name: 'Bomlitz (FTTH)',
id: 'proetzel',
name: 'Prötzel (PV)',
type: 'project',
x: 78.84,
y: 32.5,
description: 'Kabeltrasse Solarpark',
},
{
id: 'ostbevern',
name: 'Ostbevern (Wind)',
type: 'project',
x: 26.64,
y: 39.84,
description: 'Netzanbindung Windpark',
},
{
id: 'petershagen',
name: 'Petershagen (Wind)',
type: 'project',
x: 36.26,
y: 35.79,
description: 'Netzanbindung Windpark',
},
{
id: 'ketzin',
name: 'Ketzin (Wind)',
type: 'project',
x: 72,
y: 34,
description: 'Netzanbindung Windpark',
},
{
id: 'jevenstedt',
name: 'Jevenstedt (Wind)',
type: 'project',
x: 43,
y: 28.76,
description: '88km Leitungstrasse (Tiefbau/HDD)',
href: '/referenzen/bomlitz',
},
{
id: 'forst',
name: 'Forst (Kabeltrasse)',
type: 'project',
x: 87,
y: 43.85,
description: 'Neubau MS-Kabeltrasse',
href: '/referenzen/forst',
},
{
id: 'eisenhuettenstadt',
name: 'Eisenhüttenstadt (Kabel)',
type: 'project',
x: 86,
y: 38.36,
description: 'Kabelverbindung U30 - T10',
href: '/referenzen/eisenhuettenstadt',
},
{
id: 'goerne',
name: 'Görne (PV-Anlage)',
type: 'project',
x: 65,
y: 32.19,
description: 'Einspeisung PV-Anlage (MS-Kabel)',
href: '/referenzen/goerne',
},
{
id: 'boerde',
name: 'Börde (FTTH-Ausbau)',
type: 'project',
x: 55,
y: 34.24,
description: '109km Leitungstrasse für Breitband',
href: '/referenzen/boerde',
y: 9,
description: 'Netzanbindung Windpark',
}
];
@@ -920,3 +896,4 @@ export const minorLocations: Location[] = [
description: 'pv',
},
];
export const projectLocations = [...defaultLocations, ...minorLocations];

174
lib/standorte-data.ts Normal file
View File

@@ -0,0 +1,174 @@
import { LucideIcon, MapPin, Building2, HardHat, Phone, Mail, Navigation } from 'lucide-react';
export interface ContactPerson {
name: string;
role: string;
phone: string;
email: string;
image?: string;
}
export interface StandortData {
id: string;
name: string;
shortName: string;
description: Record<'de' | 'en', string>;
address: {
street: string;
city: string;
};
contact: {
phone: string;
email: string;
};
coordinates: {
lat: number;
lng: number;
};
keyFeatures: Record<'de' | 'en', string[]>;
image: string;
gallery: string[];
type: 'hq' | 'branch';
}
export const standorteData: StandortData[] = [
{
id: 'guben',
name: 'E-TIB GmbH Holding & Bohrtechnik GmbH',
shortName: 'Guben (Hauptsitz)',
type: 'hq',
description: {
de: 'Unser Hauptsitz in Guben bildet das strategische und operative Zentrum der E-TIB Gruppe. Von hier aus steuern wir bundesweit Großprojekte im Kabelleitungstiefbau und koordinieren unseren hochmodernen Maschinenpark.',
en: 'Our headquarters in Guben forms the strategic and operational center of the E-TIB Group. From here, we manage large-scale civil engineering projects nationwide and coordinate our state-of-the-art machinery fleet.'
},
address: {
street: 'Gewerbestraße 22',
city: '03172 Guben'
},
contact: {
phone: '+49 (0) 3561 / 68577 33',
email: 'info@e-tib.com'
},
coordinates: {
lat: 51.942,
lng: 14.717
},
keyFeatures: {
de: [
'Zentrale strategische Steuerung',
'Kabelleitungstiefbau & Infrastruktur',
'Koordination Großmaschinenpark',
'Zentrales Projektmanagement'
],
en: [
'Central strategic management',
'Underground cable engineering & infrastructure',
'Coordination of heavy machinery',
'Central project management'
]
},
image: '/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-100.jpg',
gallery: [
'/assets/photos/DSC02114.jpg',
'/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-45.jpg'
]
},
{
id: 'kirchheilingen',
name: 'E-TIB Bohrtechnik GmbH',
shortName: 'Standort Thüringen',
type: 'branch',
description: {
de: 'Unser spezialisierter Standort für Horizontalspülbohrtechnik in Thüringen. Mit modernsten Bohranlagen realisieren wir grabenlose Leitungsverlegungen für komplexe Infrastrukturprojekte, umweltschonend und hocheffizient.',
en: 'Our specialized location for horizontal directional drilling in Thuringia. Utilizing state-of-the-art drilling rigs, we implement trenchless cable laying for complex infrastructure projects, environmentally friendly and highly efficient.'
},
address: {
street: 'Bahnhofstraße 180a',
city: '99947 Kirchheilingen'
},
contact: {
phone: '+49 (0) 3561 / 68577 33', // Placeholder, using central
email: 'info@e-tib.com'
},
coordinates: {
lat: 51.1852,
lng: 10.6865
},
keyFeatures: {
de: [
'Horizontalspülbohrtechnik (HDD)',
'Grabenlose Rohrverlegung',
'Felsbohrungen',
'Unterquerung von Gewässern & Straßen'
],
en: [
'Horizontal Directional Drilling (HDD)',
'Trenchless pipe laying',
'Rock drilling',
'Crossing underneath water bodies & roads'
]
},
image: '/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie_Vermessung_(247_von_80).jpg',
gallery: [
'/assets/photos/DSC02089.jpg',
'/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-6.jpg'
]
},
{
id: 'buelstedt',
name: 'E-TIB Ingenieurgesellschaft mbH',
shortName: 'Bülstedt (Ingenieurgesellschaft)',
type: 'branch',
description: {
de: 'Unsere Ingenieurgesellschaft in Bülstedt ist spezialisiert auf die hochpräzise Planung, Vermessung und Projektierung von Energie- und Telekommunikationsnetzen. Hier verschmelzen technische Expertise und modernes Datenmanagement.',
en: 'Our engineering firm in Bülstedt specializes in the high-precision planning, surveying, and project management of energy and telecommunication networks. This is where technical expertise and modern data management converge.'
},
address: {
street: 'Dorfstraße 1', // Placeholder
city: '27412 Bülstedt'
},
contact: {
phone: '+49 (0) 3561 / 68577 33', // Placeholder, using central
email: 'info@e-tib.com'
},
coordinates: {
lat: 53.2167,
lng: 9.15
},
keyFeatures: {
de: [
'Trassenplanung & Projektierung',
'Geodätische Vermessung (GPS/Tachymetrie)',
'As-Built Dokumentation (GIS/CAD)',
'Genehmigungsmanagement'
],
en: [
'Route planning & project management',
'Geodetic surveying (GPS/Tacheometry)',
'As-built documentation (GIS/CAD)',
'Permit management'
]
},
image: '/assets/photos/etib_ingenieure_tiefbau_solar_pv_planung_vermessung_gis-256.jpg',
gallery: [
'/assets/photos/etib_ingenieure_tiefbau_solar_pv_planung_vermessung_gis-294.jpg',
'/assets/photos/etib_ingenieure_tiefbau_solar_pv_planung_vermessung_gis-298.jpg'
]
}
];
export function getStandortById(id: string): StandortData | undefined {
return standorteData.find(s => s.id === id);
}
// Convert StandortData to the Location format required by the map
export const standorteLocations = standorteData.map(standort => ({
id: standort.id,
name: standort.shortName,
type: standort.type,
x: standort.id === 'kirchheilingen' ? 52 : standort.id === 'buelstedt' ? 37 : 85,
y: standort.id === 'kirchheilingen' ? 55 : standort.id === 'buelstedt' ? 25.33 : 41.1,
description: standort.name,
href: `/standorte/${standort.id}`,
details: standort.keyFeatures.de.slice(0, 3)
}));

1
login-result.html Normal file

File diff suppressed because one or more lines are too long

BIN
lychee Executable file

Binary file not shown.

View File

@@ -102,7 +102,7 @@
"office": "Hauptsitz Guben",
"address": "Gewerbestraße 22\n03172 Guben\nDeutschland",
"phone": "+49 (0) 3561 / 68577 33",
"email": "info@e-tib.com"
"email": "E-Mail"
},
"hours": {
"title": "Öffnungszeiten",
@@ -318,6 +318,13 @@
"timeoutError": "Anfrage hat zu lange gedauert. Bitte versuche es erneut.",
"genericError": "Ein Fehler ist aufgetreten."
},
"GrowthChart": {
"title": "Bewiesene Leistungsfähigkeit",
"subtitle": "Unsere verlässliche Baukapazität der letzten Jahre (in Metern)",
"kabel": "Kabelverlegung",
"hdd": "HDD Spülbohrung",
"offener": "Offener Tiefbau"
},
"ReferenceDetail": {
"backToOverview": "Zurück zur Übersicht",
"projectReference": "Projektreferenz",

View File

@@ -102,7 +102,7 @@
"office": "Headquarters Guben",
"address": "Gewerbestraße 22\n03172 Guben\nGermany",
"phone": "+49 (0) 3561 / 68577 33",
"email": "info@e-tib.com"
"email": "Email"
},
"hours": {
"title": "Opening Hours",
@@ -318,6 +318,13 @@
"timeoutError": "Request took too long. Please try again.",
"genericError": "An error occurred."
},
"GrowthChart": {
"title": "Proven Performance",
"subtitle": "Our reliable construction capacity of the last years (in meters)",
"kabel": "Cable Laying",
"hdd": "HDD Drilling",
"offener": "Open Trenching"
},
"ReferenceDetail": {
"backToOverview": "Back to Overview",
"projectReference": "Project Reference",

Some files were not shown because too many files have changed in this diff Show More