main repo

This commit is contained in:
Basilosaurusrex
2025-11-24 18:09:40 +01:00
parent b636ee5e70
commit f027651f9b
34146 changed files with 4436636 additions and 0 deletions

874
app/page.tsx Normal file
View File

@@ -0,0 +1,874 @@
"use client";
import { useCallback, useEffect, useRef, useState } from "react";
import { Button } from "@/components/ui/button";
import { Calendar, Cookie } from "lucide-react";
import { colors } from "@/lib/colors";
import ProtectedAppointmentBooking from "@/components/ProtectedAppointmentBooking";
import AppointmentStatus from "@/components/AppointmentStatus";
import PriceCalculator from "@/components/PriceCalculator";
import SpinningNumbers from "@/components/SpinningNumbers";
import GlassSurface from "@/components/GlassSurface";
import LogoLoop from "@/components/LogoLoop";
import PillNav from "@/components/PillNav";
import TimelineDemo from "@/components/ui/timeline-demo";
import { HoverEffect } from "@/components/ui/card-hover-effect";
import HeroScrollDemo from "@/components/ui/container-scroll-animation-demo";
import Link from 'next/link';
// Scroll animation hook
const useScrollAnimation = () => {
const [scrollY, setScrollY] = useState(0);
useEffect(() => {
const handleScroll = () => setScrollY(window.scrollY);
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
return scrollY;
};
// Intersection Observer hook for fade-in animations
const useInView = (threshold = 0.1) => {
const [isInView, setIsInView] = useState(false);
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) {
setIsInView(true);
}
},
{ threshold }
);
if (ref.current) {
observer.observe(ref.current);
}
return () => observer.disconnect();
}, [threshold]);
return [ref, isInView] as const;
};
// Cookie Button Component
const CookieButton = () => {
const [showBanner, setShowBanner] = useState(false);
const handleAccept = () => {
setShowBanner(false);
// Add cookie acceptance logic here
};
return (
<>
{/* Cookie Button */}
<button
onClick={() => setShowBanner(true)}
className="fixed bottom-6 left-6 z-50 w-14 h-14 rounded-full flex items-center justify-center shadow-lg transition-all duration-300 hover:scale-110"
style={{ backgroundColor: colors.secondary }}
>
<Cookie className="w-6 h-6 text-white" />
</button>
{/* Cookie Banner */}
{showBanner && (
<div className="fixed inset-0 bg-black/50 backdrop-blur-sm z-50 flex items-center justify-center p-4">
<div
className="max-w-md w-full p-6 rounded-3xl shadow-2xl"
style={{ backgroundColor: colors.background }}
>
<div className="flex items-center space-x-3 mb-4">
<Cookie className="w-6 h-6" style={{ color: colors.primary }} />
<h3 className="text-lg font-semibold" style={{ color: colors.primary }}>
Cookie-Einstellungen
</h3>
</div>
<p className="mb-6 text-sm" style={{ color: colors.secondary }}>
Wir verwenden Cookies, um Ihre Erfahrung zu verbessern. Durch die Nutzung unserer Website stimmen Sie unserer Datenschutzrichtlinie zu.
</p>
<div className="flex space-x-3">
<Button
onClick={handleAccept}
className="flex-1 rounded-full font-medium"
style={{
backgroundColor: colors.primary,
color: colors.background
}}
>
Akzeptieren
</Button>
<Button
onClick={() => setShowBanner(false)}
variant="outline"
className="flex-1 rounded-full"
style={{
borderColor: colors.secondary,
color: colors.secondary
}}
>
Ablehnen
</Button>
</div>
</div>
</div>
)}
</>
);
};
export default function AboutServicePage() {
const scrollY = useScrollAnimation();
const [heroRef, heroInView] = useInView();
const [servicesRef, servicesInView] = useInView();
const [processRef, processInView] = useInView();
const [pricingRef, pricingInView] = useInView();
const [aboutRef, aboutInView] = useInView();
const [contactRef, contactInView] = useInView();
const navWrapperRef = useRef<HTMLDivElement>(null);
const navInnerRef = useRef<HTMLDivElement>(null);
const [navOffset, setNavOffset] = useState(0);
const navOffsetRef = useRef(0);
const navExpandedRef = useRef(false);
const animationFrameRef = useRef<number | null>(null);
useEffect(() => {
navOffsetRef.current = navOffset;
}, [navOffset]);
useEffect(() => {
return () => {
if (animationFrameRef.current) {
cancelAnimationFrame(animationFrameRef.current);
}
};
}, []);
const animateOffset = useCallback((target: number) => {
if (!Number.isFinite(target)) return;
if (animationFrameRef.current) {
cancelAnimationFrame(animationFrameRef.current);
animationFrameRef.current = null;
}
const startValue = navOffsetRef.current;
const delta = target - startValue;
if (Math.abs(delta) < 0.5) {
navOffsetRef.current = target;
setNavOffset(target);
return;
}
const duration = 520;
const startTime = performance.now();
const easeOutCubic = (t: number) => 1 - Math.pow(1 - t, 3);
const step = (now: number) => {
const elapsed = now - startTime;
const progress = Math.min(elapsed / duration, 1);
const eased = easeOutCubic(progress);
const value = startValue + delta * eased;
navOffsetRef.current = value;
setNavOffset(value);
if (progress < 1) {
animationFrameRef.current = requestAnimationFrame(step);
} else {
animationFrameRef.current = null;
}
};
animationFrameRef.current = requestAnimationFrame(step);
}, []);
const calculateNavOffset = useCallback(
(mode: "animate" | "immediate" = "animate", expandedOverride?: boolean) => {
if (!navWrapperRef.current || !navInnerRef.current) return;
const expanded = expandedOverride ?? navExpandedRef.current;
const wrapperWidth = navWrapperRef.current.clientWidth;
const navWidth = navInnerRef.current.offsetWidth;
const offset = expanded ? Math.max(0, (wrapperWidth - navWidth) / 2) : 0;
if (!Number.isFinite(offset)) return;
if (mode === "immediate") {
navOffsetRef.current = offset;
setNavOffset(offset);
} else {
animateOffset(offset);
}
},
[animateOffset]
);
useEffect(() => {
calculateNavOffset("immediate", navExpandedRef.current);
const handleResize = () => calculateNavOffset("immediate", navExpandedRef.current);
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, [calculateNavOffset]);
useEffect(() => {
if (!navInnerRef.current || typeof ResizeObserver === "undefined") return;
const observer = new ResizeObserver(() => {
calculateNavOffset("immediate", navExpandedRef.current);
});
observer.observe(navInnerRef.current);
return () => observer.disconnect();
}, [calculateNavOffset]);
useEffect(() => {
const wrapper = navWrapperRef.current;
if (!wrapper) return;
const handleTransitionEnd = (event: TransitionEvent) => {
if (event.propertyName === "max-width" || event.propertyName === "width" || event.propertyName === "transform") {
calculateNavOffset(navExpandedRef.current ? "animate" : "immediate", navExpandedRef.current);
}
};
wrapper.addEventListener("transitionend", handleTransitionEnd);
return () => wrapper.removeEventListener("transitionend", handleTransitionEnd);
}, [calculateNavOffset]);
// Partner Logos für LogoLoop
const partnerLogos = [
{
node: (
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '8px' }}>
<svg viewBox="0 0 48 48" fill="none" width={96} height={96} xmlns="http://www.w3.org/2000/svg">
{/* Traefik - Reverse Proxy mit drei Punkten */}
<circle cx="16" cy="16" r="4" fill={colors.background}/>
<circle cx="24" cy="24" r="4" fill={colors.background}/>
<circle cx="32" cy="32" r="4" fill={colors.background}/>
<path d="M16 16L24 24M24 24L32 32" stroke={colors.background} strokeWidth="2" strokeLinecap="round"/>
<path d="M12 24L24 12L36 24" stroke={colors.background} strokeWidth="2" opacity="0.5"/>
</svg>
<span style={{ color: colors.background, fontSize: '14px', fontWeight: '600', whiteSpace: 'nowrap' }}>Traefik</span>
</div>
),
title: "Traefik",
href: "https://traefik.io"
},
{
node: (
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '8px' }}>
<svg viewBox="0 0 48 48" fill="none" width={96} height={96} xmlns="http://www.w3.org/2000/svg">
{/* Porkbun - Domain/Globe */}
<circle cx="24" cy="24" r="16" stroke={colors.background} strokeWidth="3"/>
<path d="M8 24C8 18 12 14 24 14C36 14 40 18 40 24C40 30 36 34 24 34C12 34 8 30 8 24Z" stroke={colors.background} strokeWidth="2"/>
<path d="M24 8C24 8 18 14 18 20C18 26 24 32 24 32" stroke={colors.background} strokeWidth="2"/>
</svg>
<span style={{ color: colors.background, fontSize: '14px', fontWeight: '600', whiteSpace: 'nowrap' }}>Porkbun</span>
</div>
),
title: "Porkbun",
href: "https://porkbun.com"
},
{
node: (
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '8px' }}>
<svg viewBox="0 0 48 48" fill="none" width={96} height={96} xmlns="http://www.w3.org/2000/svg">
{/* n8n - Workflow Nodes */}
<circle cx="16" cy="16" r="5" fill={colors.background}/>
<circle cx="32" cy="16" r="5" fill={colors.background}/>
<circle cx="16" cy="32" r="5" fill={colors.background}/>
<circle cx="32" cy="32" r="5" fill={colors.background}/>
<path d="M21 16L27 16M16 21L16 27M21 32L27 32" stroke={colors.background} strokeWidth="2" strokeLinecap="round"/>
</svg>
<span style={{ color: colors.background, fontSize: '14px', fontWeight: '600', whiteSpace: 'nowrap' }}>n8n</span>
</div>
),
title: "n8n",
href: "https://n8n.io"
},
{
node: (
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '8px' }}>
<svg viewBox="0 0 48 48" fill="none" width={96} height={96} xmlns="http://www.w3.org/2000/svg">
{/* Mistral AI - Wind/Wave */}
<path d="M8 24Q16 16 24 24T40 24" stroke={colors.background} strokeWidth="3" strokeLinecap="round" fill="none"/>
<path d="M10 28Q18 20 26 28T42 28" stroke={colors.background} strokeWidth="3" strokeLinecap="round" fill="none" opacity="0.7"/>
<circle cx="24" cy="24" r="2" fill={colors.background} opacity="0.5"/>
</svg>
<span style={{ color: colors.background, fontSize: '14px', fontWeight: '600', whiteSpace: 'nowrap' }}>Mistral AI</span>
</div>
),
title: "Mistral AI",
href: "https://mistral.ai"
},
{
node: (
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '8px' }}>
<svg viewBox="0 0 48 48" fill="none" width={96} height={96} xmlns="http://www.w3.org/2000/svg">
{/* Hetzner - Server/Cloud */}
<rect x="12" y="14" width="24" height="20" rx="2" stroke={colors.background} strokeWidth="3"/>
<path d="M16 20H32M16 24H32M16 28H28" stroke={colors.background} strokeWidth="2" strokeLinecap="round"/>
<circle cx="36" cy="18" r="3" fill={colors.background}/>
</svg>
<span style={{ color: colors.background, fontSize: '14px', fontWeight: '600', whiteSpace: 'nowrap' }}>Hetzner</span>
</div>
),
title: "Hetzner",
href: "https://www.hetzner.com"
},
{
node: (
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '8px' }}>
<svg viewBox="0 0 48 48" fill="none" width={96} height={96} xmlns="http://www.w3.org/2000/svg">
{/* Cursor - Code Editor */}
<rect x="12" y="12" width="24" height="24" rx="4" stroke={colors.background} strokeWidth="3"/>
<path d="M18 20L24 24L18 28" stroke={colors.background} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
<path d="M28 20L30 24L28 28" stroke={colors.background} strokeWidth="2" strokeLinecap="round"/>
</svg>
<span style={{ color: colors.background, fontSize: '14px', fontWeight: '600', whiteSpace: 'nowrap' }}>Cursor</span>
</div>
),
title: "Cursor AI",
href: "https://cursor.sh"
},
{
node: (
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '8px' }}>
<svg viewBox="0 0 48 48" fill="none" width={96} height={96} xmlns="http://www.w3.org/2000/svg">
{/* Appwrite - Database/Backend */}
<rect x="14" y="10" width="20" height="28" rx="2" stroke={colors.background} strokeWidth="3"/>
<path d="M14 18H34M14 24H34M14 30H28" stroke={colors.background} strokeWidth="2" strokeLinecap="round"/>
<circle cx="32" cy="14" r="2" fill={colors.background}/>
</svg>
<span style={{ color: colors.background, fontSize: '14px', fontWeight: '600', whiteSpace: 'nowrap' }}>Appwrite</span>
</div>
),
title: "Appwrite",
href: "https://appwrite.io"
}
];
const valueProps = [
{
title: "Zeitersparnis",
description: "Wir übernehmen den digitalen Teil, Sie konzentrieren sich aufs Geschäft",
link: "#zeitersparnis"
},
{
title: "Kompetenz & Erfahrung",
description: "Technisch stark, klar in der Umsetzung",
link: "#kompetenz-erfahrung"
},
{
title: "Maßgeschneiderte Lösungen",
description: "Keine Templates, sondern individuelle Umsetzung",
link: "#massgeschneiderte-loesungen"
},
{
title: "Stressfreies Webmanagement",
description: "Ein Ansprechpartner für alles",
link: "#stressfreies-webmanagement"
}
];
const navIsExpanded = scrollY > 40;
const previousNavState = useRef(navIsExpanded);
useEffect(() => {
const previous = previousNavState.current;
previousNavState.current = navIsExpanded;
navExpandedRef.current = navIsExpanded;
let raf1: number | null = null;
let raf2: number | null = null;
let timeoutId: number | null = null;
if (navIsExpanded) {
if (previous === false) {
raf1 = requestAnimationFrame(() => {
calculateNavOffset("animate", true);
});
raf2 = requestAnimationFrame(() => {
calculateNavOffset("animate", true);
});
timeoutId = window.setTimeout(() => {
calculateNavOffset("animate", true);
}, 320);
} else {
calculateNavOffset("immediate", true);
}
} else {
animateOffset(0);
}
return () => {
if (raf1 !== null) cancelAnimationFrame(raf1);
if (raf2 !== null) cancelAnimationFrame(raf2);
if (timeoutId !== null) window.clearTimeout(timeoutId);
};
}, [navIsExpanded, calculateNavOffset, animateOffset]);
return (
<>
<div className="min-h-screen overflow-hidden" style={{ backgroundColor: colors.background }}>
{/* Fixed Navigation mit PillNav */}
<div
className="fixed left-0 right-0 z-40 px-4 top-4 transition-all duration-500"
style={{
transitionTimingFunction: "cubic-bezier(0.22, 1, 0.36, 1)"
}}
>
<div
className="w-full mx-auto transition-all duration-500 ease-out"
style={{
maxWidth: navIsExpanded ? "72rem" : "38rem",
width: navIsExpanded ? "100%" : "96%"
}}
>
<GlassSurface
width="100%"
height="auto"
borderRadius={9999}
displace={2.0}
backgroundOpacity={0.3}
className="w-full transition-all duration-500 ease-out"
style={{
minHeight: '70px',
backgroundColor: `${colors.secondary}66`,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
padding: '0.5rem 1.5rem',
transition: 'backdrop-filter 0.45s ease'
}}
>
<div
ref={navWrapperRef}
className="relative w-full flex items-center justify-center transition-all duration-500"
style={{
transitionTimingFunction: "cubic-bezier(0.22, 1, 0.36, 1)"
}}
>
{/* PillNav mit den Nav-Links */}
<div
ref={navInnerRef}
className="inline-flex transition-all duration-500"
style={{
transform: navIsExpanded ? `translateX(-${navOffset}px)` : "translateX(0)",
transitionTimingFunction: "cubic-bezier(0.22, 1, 0.36, 1)"
}}
>
<PillNav
logo="/WebKlarLogo.png"
logoAlt="Webklar Logo"
items={[
{ label: 'Über uns', href: '#about' },
{ label: 'Leistungen', href: '#services' },
{ label: 'Unsere Abläufe', href: '#process' }
]}
activeHref="#"
baseColor={colors.secondary}
pillColor={colors.background}
hoveredPillTextColor={colors.background}
pillTextColor={colors.primary}
className="pill-nav-custom"
/>
</div>
{/* Kontakt-Button rechts */}
<div
className="hidden md:block absolute right-0 transition-all duration-500 overflow-hidden"
style={{
opacity: navIsExpanded ? 1 : 0,
maxWidth: navIsExpanded ? "200px" : "0px",
pointerEvents: navIsExpanded ? "auto" : "none",
transform: navIsExpanded ? "translateX(0)" : "translateX(16px)",
transitionTimingFunction: "cubic-bezier(0.22, 1, 0.36, 1)"
}}
>
<Link href="/kontakte">
<Button className="rounded-full text-sm font-semibold px-3 sm:px-5 py-1.5 shadow-lg hover:shadow-xl transition-all duration-300 hover:scale-105 btn-enhanced pulse-glow" style={{ backgroundColor: colors.primary, color: colors.background }}>
Kontakt
</Button>
</Link>
</div>
</div>
</GlassSurface>
</div>
</div>
{/* Background Video Hero Section */}
<section id="hero" className="relative h-screen flex items-center justify-center overflow-hidden">
{/* Video Background */}
<div className="absolute inset-0 z-0">
<video
autoPlay
muted
loop
playsInline
className="w-full h-full object-cover"
style={{ filter: 'blur(8px)' }}
>
<source src="/path/to/your/background-video.mp4" type="video/mp4" />
</video>
<div
className="absolute inset-0 backdrop-blur-sm"
style={{
background: `linear-gradient(135deg, ${colors.primary}CC, ${colors.secondary}CC)`
}}
></div>
</div>
<div ref={heroRef} className="relative z-20 px-4 sm:px-8 pt-24 sm:pt-28 pb-20 sm:pb-24 max-w-7xl mx-auto text-center">
<h1 className={`text-4xl sm:text-6xl md:text-8xl font-bold mb-6 sm:mb-8 transition-all duration-1000 ${
heroInView ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-10'
}`}>
<span style={{ color: colors.background }}>
webklar das Web maßgeschneidert auf Ihr Unternehmen
</span>
</h1>
<div className={`flex flex-wrap justify-center gap-2 sm:gap-4 mb-8 sm:mb-12 text-xs sm:text-sm mt-6 transition-all duration-1000 delay-300 ${
heroInView ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-10'
}`}>
{['Strategieberatung', 'UX/UI Design', 'Entwicklung', 'SEO & Support'].map((item) => (
<span
key={item}
className="px-3 sm:px-4 py-2 rounded-full backdrop-blur-sm border"
style={{
backgroundColor: `${colors.background}80`,
borderColor: colors.tertiary,
color: colors.primary
}}
>
{item}
</span>
))}
</div>
<div className={`flex flex-col sm:flex-row items-center justify-center gap-4 sm:gap-6 transition-all duration-1000 delay-500 ${
heroInView ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-10'
}`}>
<Button
onClick={() => document.getElementById('contact')?.scrollIntoView({ behavior: 'smooth' })}
className="w-full sm:w-auto px-6 sm:px-8 py-3 sm:py-4 rounded-full flex items-center justify-center space-x-3 text-base sm:text-lg font-semibold shadow-2xl hover:shadow-3xl transition-all duration-300 hover:scale-105 btn-enhanced hover-lift"
style={{
backgroundColor: colors.background,
color: colors.primary
}}
>
<Calendar className="w-5 sm:w-6 h-5 sm:h-6" />
<span>Kostenlosen Termin buchen</span>
</Button>
</div>
{/* Partner Tools */}
<div className="mt-8 sm:mt-12 px-4 sm:px-8">
<div style={{ position: 'relative', overflow: 'visible', maxWidth: '100%' }} className="logo-loop-container">
<div style={{ height: '180px', position: 'relative', width: '100%', paddingBottom: '30px', overflow: 'hidden' }} className="logo-loop-inner">
<LogoLoop
logos={partnerLogos}
speed={60}
direction="left"
logoHeight={140}
gap={100}
pauseOnHover
scaleOnHover
ariaLabel="Technology partners"
style={{ width: '100%' }}
/>
</div>
</div>
</div>
</div>
</section>
{/* About Section */}
<section
id="about"
ref={aboutRef}
className="relative px-4 sm:px-8 py-12 sm:py-20 rounded-t-[2rem] sm:rounded-t-[3rem] rounded-b-[2rem] sm:rounded-b-[3rem] mx-2 sm:mx-4 backdrop-blur-sm"
style={{ backgroundColor: `${colors.background}F0`, position: 'relative', zIndex: 10 }}
>
<div className="max-w-7xl mx-auto">
<div className="grid lg:grid-cols-2 gap-8 sm:gap-16 items-center">
{/* Links: Spinning Numbers */}
<div className="relative order-2 lg:order-1">
<SpinningNumbers />
</div>
{/* Rechts: Text im Zeitungsstil (mehrspaltig) */}
<div className={`order-1 lg:order-2 transition-all duration-1000 w-full flex flex-col justify-center ${
aboutInView ? 'opacity-100 translate-x-0' : 'opacity-0 translate-x-10'
}`}>
<h2 className="text-3xl sm:text-5xl md:text-6xl font-bold mb-6 sm:mb-8 leading-tight whitespace-nowrap" style={{ color: colors.primary }}>
<span className="inline-block">Worauf wir</span>{" "}
<span className="inline-block">Wert</span>{" "}
<span className="inline-block">legen</span>
</h2>
<div
className="text-xl sm:text-2xl md:text-3xl leading-relaxed"
style={{
color: colors.secondary,
width: '100%',
maxWidth: '100%',
columnCount: 1,
columnGap: '3rem',
columnFill: 'balance',
textAlign: 'justify'
}}
>
Sicherheit ist für uns keine Nebensache, sondern die Grundlage jeder Website. Wir setzen auf moderne Technologien, zertifizierte Partner und höchste Datenschutzstandards. Unsere Systeme sind darauf ausgelegt, Ausfälle zu vermeiden und langfristig stabile Ergebnisse zu liefern damit Ihre Online-Präsenz so zuverlässig ist wie Ihr Unternehmen selbst.
</div>
</div>
</div>
</div>
</section>
{/* Services Grid */}
<section
id="services"
ref={servicesRef}
className="relative px-4 sm:px-8 py-12 sm:py-20 rounded-t-[2rem] sm:rounded-t-[3rem] rounded-b-[2rem] sm:rounded-b-[3rem] mx-2 sm:mx-4 backdrop-blur-sm"
style={{ backgroundColor: colors.primary }}
>
<div className="max-w-7xl mx-auto">
<div className="text-center mb-12 sm:mb-16">
<h2 className={`text-3xl sm:text-5xl md:text-6xl font-bold mb-4 sm:mb-6 transition-all duration-1000 ${
servicesInView ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-10'
}`} style={{ color: colors.tertiary }}>
Unsere Leistungen
</h2>
<p className={`text-lg sm:text-xl transition-all duration-1000 delay-200 ${
servicesInView ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-10'
}`} style={{ color: colors.background }}>
Alles aus einer Hand für Ihren digitalen Erfolg
</p>
</div>
<div
className={`transition-all duration-1000 ${
servicesInView ? "opacity-100 translate-y-0" : "opacity-0 translate-y-10"
}`}
>
<HeroScrollDemo />
</div>
</div>
</section>
{/* Process Section */}
<section
id="process"
ref={processRef}
className="relative px-4 sm:px-8 py-12 sm:py-20 rounded-t-[2rem] sm:rounded-t-[3rem] rounded-b-[2rem] sm:rounded-b-[3rem] mx-2 sm:mx-4 backdrop-blur-sm"
style={{ backgroundColor: `${colors.background}F0` }}
>
<div className="max-w-6xl mx-auto">
<div className="text-center mb-12 sm:mb-16">
<h2 className={`text-3xl sm:text-5xl md:text-6xl font-bold mb-4 sm:mb-6 transition-all duration-1000 ${
processInView ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-10'
}`} style={{ color: colors.primary }}>
Unser Ablauf
</h2>
<p className={`text-lg sm:text-xl transition-all duration-1000 delay-200 ${
processInView ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-10'
}`} style={{ color: colors.secondary }}>
So läuft die Zusammenarbeit ab
</p>
</div>
<div
className="rounded-[32px] px-2 py-10 sm:px-6 sm:py-16 transition-all duration-700"
style={{
background: `linear-gradient(135deg, ${colors.background}F2, ${colors.background}E8)`
}}
>
<TimelineDemo />
</div>
</div>
</section>
{/* Pricing Section */}
<section
id="references"
ref={pricingRef}
className="relative px-4 sm:px-8 py-12 sm:py-20 rounded-t-[2rem] sm:rounded-t-[3rem] rounded-b-[2rem] sm:rounded-b-[3rem] mx-2 sm:mx-4 backdrop-blur-sm"
style={{ backgroundColor: `${colors.primary}F0` }}
>
<div className="max-w-4xl mx-auto text-center">
<div className="mb-12 sm:mb-16">
<h2 className={`text-3xl sm:text-5xl md:text-6xl font-bold mb-4 sm:mb-6 transition-all duration-1000 ${
pricingInView ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-10'
}`} style={{ color: colors.tertiary }}>
Faire Preise
</h2>
<p className={`text-lg sm:text-xl transition-all duration-1000 delay-200 ${
pricingInView ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-10'
}`} style={{ color: colors.background }}>
Transparent und flexibel
</p>
</div>
<div className={`p-8 sm:p-12 rounded-3xl shadow-2xl backdrop-blur-sm transition-all duration-1000 delay-300 ${
pricingInView ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-10'
}`} style={{ backgroundColor: `${colors.background}F0` }}>
<h3 className="text-2xl sm:text-3xl font-bold mb-6" style={{ color: colors.primary }}>
Individuelle Lösungen
</h3>
<p className="text-lg sm:text-xl mb-8 leading-relaxed" style={{ color: colors.secondary }}>
Unsere Preise richten sich nach dem Projektumfang und Ihren Anforderungen.
Gemeinsam finden wir eine Lösung, die zu Ihrem Budget passt transparent, fair und flexibel.
</p>
<PriceCalculator />
</div>
</div>
</section>
{/* Target Groups & Value Props */}
<section
className="relative px-4 sm:px-8 py-12 sm:py-20 rounded-t-[2rem] sm:rounded-t-[3rem] rounded-b-[2rem] sm:rounded-b-[3rem] mx-2 sm:mx-4 backdrop-blur-sm"
style={{ backgroundColor: `${colors.background}F0` }}
>
<div className="max-w-7xl mx-auto">
<div className="grid lg:grid-cols-2 gap-12 sm:gap-16">
{/* Target Groups */}
<div>
<h2 className="text-2xl sm:text-4xl font-bold mb-6 sm:mb-8" style={{ color: colors.primary }}>
Für wen wir arbeiten
</h2>
<p className="text-lg sm:text-xl leading-relaxed" style={{ color: colors.secondary }}>
Wir arbeiten mit Unternehmen, die ihre veraltete Website modernisieren oder ihre Zeit nicht mehr mit Technik und Support verschwenden wollen.
</p>
</div>
{/* Value Props */}
<div>
<h2 className="text-2xl sm:text-4xl font-bold mb-6 sm:mb-8" style={{ color: colors.primary }}>
Warum wir das tun
</h2>
<div
className="rounded-3xl border shadow-sm"
style={{
background: `linear-gradient(135deg, ${colors.background}F5, ${colors.tertiary}1A)`,
borderColor: `${colors.secondary}55`
}}
>
<div className="p-4 sm:p-8">
<HoverEffect
items={valueProps}
className="py-2"
/>
</div>
</div>
</div>
</div>
</div>
</section>
{/* Contact Section */}
<section
ref={contactRef}
id="contact"
className="relative px-4 sm:px-8 py-12 sm:py-20 rounded-t-[2rem] sm:rounded-t-[3rem] rounded-b-[2rem] sm:rounded-b-[3rem] mx-2 sm:mx-4 backdrop-blur-sm"
style={{ backgroundColor: colors.secondary }}
>
<div className="max-w-4xl mx-auto">
<div className="text-center mb-12 sm:mb-16">
<h2
className="text-3xl sm:text-5xl md:text-6xl font-bold mb-4 sm:mb-6"
style={{ color: colors.background }}
>
Lassen Sie uns sprechen
</h2>
<p
className="text-lg sm:text-xl opacity-90"
style={{ color: colors.background }}
>
Erzählen Sie uns von Ihrem Projekt
</p>
</div>
<div className={`transition-all duration-1000 ${
contactInView ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-10'
}`}>
<ProtectedAppointmentBooking />
</div>
</div>
</section>
{/* Footer */}
<footer
className="relative py-8 sm:py-12 border-t rounded-t-[2rem] sm:rounded-t-[3rem] mx-2 sm:mx-4 backdrop-blur-sm"
style={{
backgroundColor: `${colors.primary}F0`,
borderColor: colors.secondary
}}
>
<div className="max-w-7xl mx-auto px-4 sm:px-8">
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 gap-6 sm:gap-8">
<div className="col-span-1 sm:col-span-2">
<div
className="text-2xl sm:text-3xl font-bold mb-4 relative"
style={{ color: colors.tertiary }}
>
<span className="relative z-10">Webklar</span>
<div
className="absolute -inset-2 rounded-xl blur-sm opacity-20"
style={{ backgroundColor: colors.secondary }}
></div>
</div>
<p
className="mb-6 leading-relaxed text-sm sm:text-base"
style={{ color: colors.background }}
>
Ihr Partner für Web & Support. Moderne Websites. Klare Kommunikation. Persönlicher Support.
</p>
</div>
<div>
<h4 className="text-base sm:text-lg font-semibold mb-4" style={{ color: colors.tertiary }}>
Services
</h4>
<ul className="space-y-2 text-sm sm:text-base" style={{ color: colors.background }}>
{['Webdesign', 'E-Commerce', 'SEO', 'Hosting'].map((item) => (
<li key={item}>
<a href="#" className="hover:opacity-80 transition-opacity">{item}</a>
</li>
))}
</ul>
</div>
<div>
<h4 className="text-base sm:text-lg font-semibold mb-4" style={{ color: colors.tertiary }}>
Kontakt
</h4>
<ul className="space-y-2 text-sm sm:text-base" style={{ color: colors.background }}>
<li><Link href="/impressum" className="hover:opacity-80 transition-opacity">Impressum</Link></li>
<li><Link href="/datenschutz" className="hover:opacity-80 transition-opacity">Datenschutz</Link></li>
<li><Link href="/agb" className="hover:opacity-80 transition-opacity">AGB</Link></li>
<li><Link href="/kontakte" className="hover:opacity-80 transition-opacity">Kontakte</Link></li>
</ul>
</div>
</div>
<div
className="border-t mt-6 sm:mt-8 pt-6 sm:pt-8 text-center text-sm"
style={{
borderColor: colors.secondary,
color: colors.background
}}
>
<p>&copy; 2025 Webklar. Alle Rechte vorbehalten.</p>
</div>
</div>
</footer>
{/* Film Grain Effect */}
{/* Cookie Button */}
<CookieButton />
{/* Appointment Status */}
<AppointmentStatus />
</div>
</>
);
}