"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 { BackgroundBeams } from "@/components/ui/background-beams"; 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(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 */} {/* Cookie Banner */} {showBanner && (

Cookie-Einstellungen

Wir verwenden Cookies, um Ihre Erfahrung zu verbessern. Durch die Nutzung unserer Website stimmen Sie unserer Datenschutzrichtlinie zu.

)} ); }; 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(null); const navInnerRef = useRef(null); const [navOffset, setNavOffset] = useState(0); const navOffsetRef = useRef(0); const navExpandedRef = useRef(false); const animationFrameRef = useRef(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: (
{/* Traefik - Reverse Proxy mit drei Punkten */} Traefik
), title: "Traefik", href: "https://traefik.io" }, { node: (
{/* Porkbun - Domain/Globe */} Porkbun
), title: "Porkbun", href: "https://porkbun.com" }, { node: (
{/* n8n - Workflow Nodes */} n8n
), title: "n8n", href: "https://n8n.io" }, { node: (
{/* Mistral AI - Wind/Wave */} Mistral AI
), title: "Mistral AI", href: "https://mistral.ai" }, { node: (
{/* Hetzner - Server/Cloud */} Hetzner
), title: "Hetzner", href: "https://www.hetzner.com" }, { node: (
{/* Cursor - Code Editor */} Cursor
), title: "Cursor AI", href: "https://cursor.sh" }, { node: (
{/* Appwrite - Database/Backend */} Appwrite
), 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 ( <>
{/* Fixed Navigation mit PillNav */}
{/* PillNav mit den Nav-Links */}
{/* Kontakt-Button rechts */}
{/* Background Video Hero Section */}
{/* Video Background */}

webklar – das Web maßgeschneidert auf Ihr Unternehmen

{['Strategieberatung', 'UX/UI Design', 'Entwicklung', 'SEO & Support'].map((item) => ( {item} ))}
{/* Partner Tools */}
{/* About Section */}
{/* Links: Spinning Numbers */}
{/* Rechts: Text im Zeitungsstil (mehrspaltig) */}

Worauf wir{" "} Wert{" "} legen

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.
{/* Services Grid */}

Unsere Leistungen

Alles aus einer Hand für Ihren digitalen Erfolg

{/* Process Section */}

Unser Ablauf

So läuft die Zusammenarbeit ab

{/* Pricing Section */}

Faire Preise

Transparent und flexibel

Individuelle Lösungen

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.

{/* Target Groups & Value Props */}
{/* Target Groups */}

Für wen wir arbeiten

Wir arbeiten mit Unternehmen, die ihre veraltete Website modernisieren oder ihre Zeit nicht mehr mit Technik und Support verschwenden wollen.

{/* Value Props */}

Warum wir das tun

{/* Contact Section */}

Lassen Sie uns sprechen

Erzählen Sie uns von Ihrem Projekt

{/* Footer */}
Webklar

Ihr Partner für Web & Support. Moderne Websites. Klare Kommunikation. Persönlicher Support.

Services

    {['Webdesign', 'E-Commerce', 'SEO', 'Hosting'].map((item) => (
  • {item}
  • ))}

Kontakt

  • Impressum
  • Datenschutz
  • AGB
  • Kontakte

© 2025 Webklar. Alle Rechte vorbehalten.

{/* Film Grain Effect */} {/* Cookie Button */} {/* Appointment Status */}
); }