feat: overhaul competence pages, unify brand colors, and polish site integrity
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 23s
Build & Deploy / 🧪 QA (push) Failing after 1m8s
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

- Rewrote all 5 competence pages (Kabeltiefbau, Bohrtechnik, Glasfaser, Planung, Vermessung) with factual data from references
- Unified brand colors: replaced toxic neon green with brand-aligned teal (#10a379)
- Fixed ReferencesSlider injection in dynamic MDX pages
- Enhanced Footer with icon parity, improved branding placement, and unified hover effects
- Refined Header with 3D micro-animations and improved dropdown visibility
- Fixed localized tracking API (rewrites for /stats/api/send)
- Resolved ReferenceErrors in InteractiveGermanyMap and Header state management
- Cleaned reference titles and truncated metadata in lists
This commit is contained in:
2026-05-15 21:07:25 +02:00
parent 4dcd5f511a
commit 843d61cd5d
47 changed files with 1125 additions and 690 deletions

View File

@@ -165,6 +165,13 @@ export default async function Page(props: { params: Promise<{ locale: string; sl
const pageMdxComponents = {
...mdxComponents,
InteractiveGermanyMap: (props: any) => <InteractiveGermanyMap locations={enrichedLocations} {...props} />,
HomeReferencesSlider: (props: any) => <HomeReferencesSlider {...props} references={references.map(r => ({
id: r.slug,
slug: r.slug,
title: r.frontmatter.title,
category: r.frontmatter.category || 'Projekt',
image: r.frontmatter.featuredImage
}))} />,
};
return (

View File

@@ -3,8 +3,9 @@
import { useEffect } from 'react';
import { useTranslations } from 'next-intl';
import { getAppServices } from '@/lib/services/create-services';
import { Container, Button, Heading } from '@/components/ui';
import Scribble from '@/components/Scribble';
import { Button, Heading } from '@/components/ui';
import { Terminal, Activity, AlertTriangle, RefreshCw, Home, ShieldAlert } from 'lucide-react';
import { motion } from 'framer-motion';
export default function Error({
error,
@@ -16,6 +17,9 @@ export default function Error({
const t = useTranslations('Error');
useEffect(() => {
// Force standard solid header
document.body.setAttribute('data-header-variant', 'standard');
// Treat "Failed to find Server Action" as a deployment sync issue and reload
if (error?.message?.includes('Failed to find Server Action')) {
window.location.reload();
@@ -30,64 +34,131 @@ export default function Error({
digest: error?.digest,
});
// Force solid header
document.body.setAttribute('data-force-solid-header', 'true');
return () => {
document.body.removeAttribute('data-force-solid-header');
document.body.removeAttribute('data-header-variant');
};
}, [error]);
return (
<>
<div className="relative min-h-[80vh] flex flex-col items-center justify-center overflow-hidden bg-[#050B14] py-24 px-4 mt-16">
{/* Deep Tech Grid Background */}
<div className="absolute inset-0 bg-[linear-gradient(to_right,#8080800a_1px,transparent_1px),linear-gradient(to_bottom,#8080800a_1px,transparent_1px)] bg-[size:40px_40px] [mask-image:radial-gradient(ellipse_60%_50%_at_50%_50%,#000_70%,transparent_100%)] pointer-events-none" />
{/* Glowing Orb */}
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-96 h-96 bg-red-500/20 blur-[120px] rounded-full pointer-events-none" />
<div className="relative min-h-screen flex flex-col items-center justify-center overflow-hidden bg-[#050B14] py-24 px-4">
{/* Industrial Blueprint Background */}
<div className="absolute inset-0 opacity-[0.03] pointer-events-none">
<div className="absolute inset-0 bg-[linear-gradient(to_right,#ffffff_1px,transparent_1px),linear-gradient(to_bottom,#ffffff_1px,transparent_1px)] bg-[size:100px_100px]" />
<div className="absolute inset-0 bg-[linear-gradient(to_right,#ffffff_1px,transparent_1px),linear-gradient(to_bottom,#ffffff_1px,transparent_1px)] bg-[size:20px_20px]" />
</div>
<div className="relative z-10 w-full max-w-2xl mx-auto">
<div className="group relative bg-[#050B14]/80 backdrop-blur-xl rounded-[2.5rem] p-12 md:p-16 border border-white/10 shadow-2xl overflow-hidden text-center">
{/* Inner Shimmer */}
<div className="absolute inset-0 bg-gradient-to-br from-white/[0.05] to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-700 pointer-events-none" />
<div className="relative mb-8">
<h1 className="text-8xl md:text-9xl font-heading font-black text-transparent bg-clip-text bg-gradient-to-b from-white to-white/20 drop-shadow-[0_0_30px_rgba(255,255,255,0.1)]">
{/* Decorative Technical Annotations */}
<div className="absolute inset-0 pointer-events-none overflow-hidden select-none">
<div className="absolute top-40 left-10 text-[10px] font-mono text-primary/30 uppercase tracking-[0.2em] rotate-90 origin-left">
System_Core_Access :: Restricted
</div>
<div className="absolute bottom-40 right-10 text-[10px] font-mono text-primary/30 uppercase tracking-[0.2em] -rotate-90 origin-right">
Protocol_Failure :: Type_500
</div>
<div className="absolute top-1/4 right-20 w-32 h-px bg-primary/20" />
<div className="absolute top-1/4 right-20 w-px h-32 bg-primary/20" />
</div>
{/* Background Glow */}
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[600px] h-[600px] bg-red-500/10 blur-[150px] rounded-full pointer-events-none animate-pulse" />
<div className="relative z-10 w-full max-w-4xl mx-auto flex flex-col items-center">
{/* The "Broken" Machine Visual */}
<div className="relative mb-12">
<motion.div
initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1 }}
className="relative"
>
<h1 className="text-[12rem] md:text-[18rem] font-heading font-black leading-none select-none">
<span className="relative inline-block text-transparent bg-clip-text bg-gradient-to-b from-white to-white/5 drop-shadow-[0_0_50px_rgba(255,255,255,0.1)]">
500
</h1>
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-full h-1 bg-red-500/40 blur-md skew-y-[-10deg]" />
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-full h-px bg-red-500 skew-y-[-10deg] shadow-[0_0_15px_rgba(239,68,68,1)]" />
{/* Glitch Layers */}
<span className="absolute inset-0 text-red-500/30 translate-x-[2px] -translate-y-[1px] mix-blend-screen animate-pulse pointer-events-none">500</span>
<span className="absolute inset-0 text-blue-500/30 -translate-x-[2px] translate-y-[1px] mix-blend-screen animate-pulse pointer-events-none">500</span>
</span>
</h1>
{/* Warning Overlay */}
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 flex flex-col items-center">
<motion.div
animate={{
opacity: [0.4, 1, 0.4],
scale: [0.95, 1.05, 0.95]
}}
transition={{ duration: 2, repeat: Infinity }}
className="p-4 rounded-2xl bg-red-500/20 border border-red-500/40 backdrop-blur-md shadow-[0_0_30px_rgba(239,68,68,0.3)]"
>
<ShieldAlert className="w-12 h-12 text-red-500" />
</motion.div>
</div>
</motion.div>
</div>
<div className="grid grid-cols-1 md:grid-cols-12 gap-8 w-full items-start">
{/* Main Content */}
<div className="md:col-span-7 text-center md:text-left">
<div className="inline-flex items-center gap-3 px-4 py-2 mb-6 rounded-lg bg-red-500/10 border border-red-500/20 text-[10px] font-mono uppercase tracking-widest text-red-400">
<Activity className="w-4 h-4 animate-pulse" />
CRITICAL_SYSTEM_OVERRIDE :: ACTIVE
</div>
<div className="inline-flex items-center gap-3 px-4 py-1.5 mb-6 rounded-full bg-red-500/10 border border-red-500/20 text-xs font-bold uppercase tracking-wider text-red-400">
<span className="w-2 h-2 rounded-full bg-red-500 animate-[ping_2s_infinite] shadow-[0_0_10px_rgba(239,68,68,0.8)]" />
SYSTEM PROTOCOL: CRITICAL ERROR
</div>
<Heading level={2} className="text-2xl md:text-3xl font-bold mb-4 text-white">
<Heading level={1} className="text-3xl md:text-5xl font-bold mb-6 text-white leading-tight">
{t('title')}
</Heading>
<p className="text-white/60 mb-10 max-w-md text-lg mx-auto leading-relaxed">
<p className="text-white/50 mb-10 max-w-lg text-lg leading-relaxed">
{t('description')}
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center">
<Button onClick={() => reset()} variant="primary" className="shadow-[0_0_20px_rgba(var(--color-primary),0.3)]">
<div className="flex flex-col sm:flex-row gap-4 justify-center md:justify-start">
<Button
onClick={() => reset()}
variant="primary"
className="group h-14 px-10 shadow-[0_0_30px_rgba(var(--color-primary),0.2)] hover:shadow-primary/40 transition-all"
>
<RefreshCw className="w-5 h-5 mr-3 group-hover:rotate-180 transition-transform duration-700" />
{t('tryAgain')}
</Button>
<Button href="/" variant="outline" className="border-white/20 text-white hover:bg-white/5">
<Button
href="/"
variant="outline"
className="h-14 px-8 border-white/10 text-white hover:bg-white/5"
>
<Home className="w-5 h-5 mr-3" />
{t('goHome')}
</Button>
</div>
</div>
{/* Decorative Base Line */}
<div className="w-full flex justify-center mt-12 opacity-50">
<div className="w-px h-24 bg-gradient-to-t from-red-500/50 to-transparent" />
{/* Technical Log Terminal */}
<div className="md:col-span-5">
<div className="bg-black/40 backdrop-blur-xl border border-white/10 rounded-2xl overflow-hidden shadow-2xl">
<div className="bg-white/5 px-4 py-2 border-b border-white/10 flex items-center justify-between">
<div className="flex gap-1.5">
<div className="w-2.5 h-2.5 rounded-full bg-red-500/50" />
<div className="w-2.5 h-2.5 rounded-full bg-yellow-500/50" />
<div className="w-2.5 h-2.5 rounded-full bg-green-500/50" />
</div>
<div className="text-[10px] font-mono text-white/30 tracking-wider">TERMINAL_OUTPUT</div>
</div>
<div className="p-6 font-mono text-xs leading-relaxed overflow-hidden h-[240px]">
<div className="text-primary/70 mb-1 animate-[fade-in_0.5s_ease-out_forwards]">[SYSTEM] Initializing recovery protocol...</div>
<div className="text-red-500/80 mb-1 animate-[fade-in_0.5s_ease-out_0.5s_forwards] opacity-0">[ERROR] Connection timeout at node 0x7F</div>
<div className="text-white/40 mb-1 animate-[fade-in_0.5s_ease-out_1s_forwards] opacity-0">[INFO] Request ID: {error?.digest || '0xDEADBEEF'}</div>
<div className="text-white/40 mb-1 animate-[fade-in_0.5s_ease-out_1.5s_forwards] opacity-0">[INFO] Timestamp: {new Date().toISOString()}</div>
<div className="text-white/40 mb-1 animate-[fade-in_0.5s_ease-out_2s_forwards] opacity-0">[INFO] Trace: {error?.message?.slice(0, 40)}...</div>
<div className="text-primary/70 mt-4 animate-[pulse_1.5s_infinite] opacity-0 animate-[fade-in_0.5s_ease-out_2.5s_forwards]">_ Waiting for user input...</div>
</div>
<div className="bg-red-500/10 p-3 flex items-center gap-3">
<Terminal className="w-4 h-4 text-red-400" />
<div className="text-[10px] font-bold text-red-400 uppercase tracking-tighter">Status: Handshake_Failed</div>
</div>
</div>
</div>
</div>
</div>
</>
</div>
);
}

View File

@@ -1,70 +1,145 @@
import { getTranslations } from 'next-intl/server';
import { Container, Button, Heading } from '@/components/ui';
import Scribble from '@/components/Scribble';
'use client';
import { useEffect } from 'react';
import { useTranslations } from 'next-intl';
import { Button, Heading } from '@/components/ui';
import { Terminal, Search, Home, Mail, Activity, Cpu } from 'lucide-react';
import { motion } from 'framer-motion';
import ClientNotFoundTracker from '@/components/analytics/ClientNotFoundTracker';
export default async function NotFound() {
console.log('--- NOT FOUND RENDERED ---');
const t = await getTranslations('Error.notFound');
export default function NotFound() {
const t = useTranslations('Error.notFound');
// Suggested URL logic removed along with Payload CMS
let suggestedUrl = null;
let suggestedLang = null;
useEffect(() => {
// Force standard solid header
document.body.setAttribute('data-header-variant', 'standard');
return () => {
document.body.removeAttribute('data-header-variant');
};
}, []);
return (
<>
<script dangerouslySetInnerHTML={{ __html: `document.body.setAttribute('data-force-solid-header', 'true');` }} />
<div className="relative min-h-screen flex flex-col items-center justify-center overflow-hidden bg-[#050B14] py-24 px-4">
<ClientNotFoundTracker path="" />
<div className="relative min-h-[80vh] flex flex-col items-center justify-center overflow-hidden bg-[#050B14] py-24 px-4 mt-16">
{/* Deep Tech Grid Background */}
<div className="absolute inset-0 bg-[linear-gradient(to_right,#8080800a_1px,transparent_1px),linear-gradient(to_bottom,#8080800a_1px,transparent_1px)] bg-[size:40px_40px] [mask-image:radial-gradient(ellipse_60%_50%_at_50%_50%,#000_70%,transparent_100%)] pointer-events-none" />
{/* Glowing Orb */}
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-96 h-96 bg-primary/20 blur-[120px] rounded-full pointer-events-none" />
{/* Industrial Blueprint Background */}
<div className="absolute inset-0 opacity-[0.03] pointer-events-none">
<div className="absolute inset-0 bg-[linear-gradient(to_right,#ffffff_1px,transparent_1px),linear-gradient(to_bottom,#ffffff_1px,transparent_1px)] bg-[size:100px_100px]" />
<div className="absolute inset-0 bg-[linear-gradient(to_right,#ffffff_1px,transparent_1px),linear-gradient(to_bottom,#ffffff_1px,transparent_1px)] bg-[size:20px_20px]" />
</div>
<div className="relative z-10 w-full max-w-2xl mx-auto">
<div className="group relative bg-[#050B14]/80 backdrop-blur-xl rounded-[2.5rem] p-12 md:p-16 border border-white/10 shadow-2xl overflow-hidden text-center">
{/* Inner Shimmer */}
<div className="absolute inset-0 bg-gradient-to-br from-white/[0.05] to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-700 pointer-events-none" />
<div className="relative mb-8">
<h1 className="text-8xl md:text-9xl font-heading font-black text-transparent bg-clip-text bg-gradient-to-b from-white to-white/20 drop-shadow-[0_0_30px_rgba(255,255,255,0.1)]">
{/* Decorative Technical Annotations */}
<div className="absolute inset-0 pointer-events-none overflow-hidden select-none">
<div className="absolute top-40 left-10 text-[10px] font-mono text-primary/30 uppercase tracking-[0.2em] rotate-90 origin-left">
Discovery_Service :: Failure
</div>
<div className="absolute bottom-40 right-10 text-[10px] font-mono text-primary/30 uppercase tracking-[0.2em] -rotate-90 origin-right">
Address_Resolution :: 0x404
</div>
<div className="absolute top-1/4 left-20 w-32 h-px bg-primary/20" />
<div className="absolute top-1/4 left-20 w-px h-32 bg-primary/20" />
</div>
{/* Background Glow */}
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[600px] h-[600px] bg-primary/10 blur-[150px] rounded-full pointer-events-none animate-pulse" />
<div className="relative z-10 w-full max-w-4xl mx-auto flex flex-col items-center">
{/* 404 Visual */}
<div className="relative mb-12">
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
className="relative"
>
<h1 className="text-[12rem] md:text-[18rem] font-heading font-black leading-none select-none">
<span className="relative inline-block text-transparent bg-clip-text bg-gradient-to-b from-white to-white/5 drop-shadow-[0_0_50px_rgba(var(--color-primary),0.15)]">
404
</h1>
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-full h-1 bg-primary/40 blur-md skew-y-[-10deg]" />
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-full h-px bg-primary skew-y-[-10deg] shadow-[0_0_15px_rgba(var(--color-primary),1)]" />
{/* Glitch Layers */}
<span className="absolute inset-0 text-primary/30 translate-x-[2px] -translate-y-[1px] mix-blend-screen animate-pulse pointer-events-none">404</span>
<span className="absolute inset-0 text-blue-500/20 -translate-x-[2px] translate-y-[1px] mix-blend-screen animate-pulse pointer-events-none">404</span>
</span>
</h1>
{/* Search Scan Overlay */}
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 flex flex-col items-center">
<motion.div
animate={{
scale: [1, 1.1, 1],
opacity: [0.5, 1, 0.5]
}}
transition={{ duration: 3, repeat: Infinity }}
className="p-5 rounded-full bg-primary/20 border border-primary/40 backdrop-blur-md shadow-[0_0_40px_rgba(var(--color-primary),0.3)]"
>
<Search className="w-10 h-10 text-primary" />
</motion.div>
</div>
</motion.div>
</div>
<div className="grid grid-cols-1 md:grid-cols-12 gap-12 w-full items-start">
{/* Main Content */}
<div className="md:col-span-7 text-center md:text-left">
<div className="inline-flex items-center gap-3 px-4 py-2 mb-6 rounded-lg bg-primary/10 border border-primary/20 text-[10px] font-mono uppercase tracking-widest text-primary">
<Cpu className="w-4 h-4 animate-spin-slow" />
OBJECT_NOT_FOUND :: SCAN_COMPLETE
</div>
<div className="inline-flex items-center gap-3 px-4 py-1.5 mb-6 rounded-full bg-red-500/10 border border-red-500/20 text-xs font-bold uppercase tracking-wider text-red-400">
<span className="w-2 h-2 rounded-full bg-red-500 animate-pulse shadow-[0_0_10px_rgba(239,68,68,0.8)]" />
SYSTEM PROTOCOL: NOT FOUND
</div>
<Heading level={2} className="text-2xl md:text-3xl font-bold mb-4 text-white">
<Heading level={1} className="text-3xl md:text-5xl font-bold mb-6 text-white leading-tight">
{t('title')}
</Heading>
<p className="text-white/60 mb-10 max-w-md text-lg mx-auto leading-relaxed">
<p className="text-white/50 mb-10 max-w-lg text-lg leading-relaxed">
{t('description')}
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center">
<Button href="/" variant="primary" className="shadow-[0_0_20px_rgba(var(--color-primary),0.3)]">
<div className="flex flex-col sm:flex-row gap-4 justify-center md:justify-start">
<Button
href="/"
variant="primary"
className="group h-14 px-10 shadow-[0_0_30px_rgba(var(--color-primary),0.2)] hover:shadow-primary/40 transition-all"
>
<Home className="w-5 h-5 mr-3" />
{t('cta')}
</Button>
<Button href="/kontakt" variant="outline" className="border-white/20 text-white hover:bg-white/5">
<Button
href="/kontakt"
variant="outline"
className="h-14 px-8 border-white/10 text-white hover:bg-white/5"
>
<Mail className="w-5 h-5 mr-3" />
Support kontaktieren
</Button>
</div>
</div>
{/* Decorative Base Line */}
<div className="w-full flex justify-center mt-12 opacity-50">
<div className="w-px h-24 bg-gradient-to-t from-primary to-transparent" />
{/* Technical Log Terminal */}
<div className="md:col-span-5">
<div className="bg-black/40 backdrop-blur-xl border border-white/10 rounded-2xl overflow-hidden shadow-2xl">
<div className="bg-white/5 px-4 py-2 border-b border-white/10 flex items-center justify-between">
<div className="flex gap-1.5">
<div className="w-2.5 h-2.5 rounded-full bg-primary/50" />
<div className="w-2.5 h-2.5 rounded-full bg-white/20" />
<div className="w-2.5 h-2.5 rounded-full bg-white/10" />
</div>
<div className="text-[10px] font-mono text-white/30 tracking-wider">DISCOVERY_LOG</div>
</div>
<div className="p-6 font-mono text-xs leading-relaxed overflow-hidden h-[220px]">
<div className="text-primary/70 mb-1">[SCAN] Initializing sector sweep...</div>
<div className="text-white/40 mb-1">[INFO] Indexing available nodes...</div>
<div className="text-primary/50 mb-1 animate-pulse">[INFO] Searching for: {typeof window !== 'undefined' ? window.location.pathname : 'unknown_resource'}</div>
<div className="text-red-400/80 mb-1 mt-4">[WARN] Resource 404: Not found in current branch</div>
<div className="text-white/30 mb-1">[INFO] Redirecting to fallback_strategy...</div>
<div className="text-primary/70 mt-4 animate-[pulse_1.5s_infinite]">_ Ready for manual redirect...</div>
</div>
<div className="bg-primary/10 p-3 flex items-center gap-3">
<Activity className="w-4 h-4 text-primary" />
<div className="text-[10px] font-bold text-primary uppercase tracking-tighter">Status: Resolution_Failed</div>
</div>
</div>
</div>
</div>
</div>
</>
</div>
);
}

View File

@@ -18,19 +18,20 @@ import JsonLd from '@/components/JsonLd';
import { Button } from '@/components/ui/Button';
import { Heading } from '@/components/ui/Heading';
import { getAllReferences } from '@/lib/references';
const mdxComponents = {
const mdxComponents = (references: any[]) => ({
HomeHero,
HomeSubCompanyTiles,
HomeCompetenceBentoGrid,
HomeReferencesSlider,
HomeReferencesSlider: (props: any) => <HomeReferencesSlider {...props} references={props.references || references} />,
FaqBlock,
CertificatesBlock,
HeroSection,
JsonLd,
Button,
Heading,
};
});
export async function generateMetadata(props: any): Promise<Metadata> {
const { locale } = await props.params;
@@ -54,6 +55,16 @@ export default async function Home(props: any) {
setRequestLocale(locale);
const mdx = await getMdxContent(locale, 'home');
const allReferences = await getAllReferences(locale);
// Transform ReferenceData to the format expected by ReferencesSlider
const sliderReferences = allReferences.map(ref => ({
id: ref.slug,
title: ref.frontmatter.title,
slug: ref.slug,
category: ref.frontmatter.location, // Using location as category if not specified
image: ref.frontmatter.featuredImage
})).slice(0, 6);
if (!mdx) {
notFound();
@@ -61,7 +72,7 @@ export default async function Home(props: any) {
return (
<main>
<MDXRemote source={mdx.content} components={mdxComponents} />
<MDXRemote source={mdx.content} components={mdxComponents(sliderReferences)} />
</main>
);
}

View File

@@ -70,10 +70,17 @@ export default async function ReferenceDetail(props: { params: Promise<{ locale:
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="list-none mb-8 space-y-3 text-base md:text-lg text-text-secondary font-medium max-w-3xl" {...props} />,
ul: (props: any) => <ul className="grid grid-cols-1 md:grid-cols-2 gap-4 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="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" {...props} />
<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>
),
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} />,

View File

@@ -116,19 +116,19 @@ export default async function ReferenzenOverview(props: { params: Promise<{ loca
</h3>
{/* Technical Meta Data */}
<div className="grid grid-cols-[1fr_1fr] gap-4 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 pr-16 md:pr-20 relative z-10">
<div className="min-w-0">
<span className="block text-[10px] uppercase tracking-widest text-neutral-400 font-bold mb-1">Kunde</span>
<span className="flex items-center gap-1.5 text-sm font-semibold text-neutral-700">
<Briefcase className="w-3.5 h-3.5 text-primary shrink-0" />
<span className="truncate">{ref.frontmatter.client}</span>
<span className="flex items-start gap-2 text-sm font-semibold text-neutral-700 leading-tight">
<Briefcase className="w-3.5 h-3.5 text-primary shrink-0 mt-[2px]" />
<span className="line-clamp-2">{ref.frontmatter.client}</span>
</span>
</div>
<div className="min-w-0">
<span className="block text-[10px] uppercase tracking-widest text-neutral-400 font-bold mb-1">Zeitraum</span>
<span className="flex items-center gap-1.5 text-sm font-semibold text-neutral-700">
<Calendar className="w-3.5 h-3.5 text-primary shrink-0" />
<span className="truncate">{ref.frontmatter.dateString || new Date(ref.frontmatter.date).getFullYear()}</span>
<span className="flex items-start gap-2 text-sm font-semibold text-neutral-700 leading-tight">
<Calendar className="w-3.5 h-3.5 text-primary shrink-0 mt-[2px]" />
<span className="line-clamp-2">{ref.frontmatter.dateString || new Date(ref.frontmatter.date).getFullYear()}</span>
</span>
</div>
</div>