"use client"; import { useEffect, useId, useState, type ReactNode } from "react"; import { AnimatePresence, motion } from "motion/react"; import { Check, Menu, Plus, X } from "lucide-react"; import { Logo } from "./logo"; import { useReducedMotion } from "./motion"; /* ------------------------------------------------------------------ * * Eyebrow label pill * ------------------------------------------------------------------ */ const WASH = { amber: "bg-amber-soft/70 text-[#8a6d00] border-amber/30", sky: "bg-sky-wash/70 text-sky-ink border-sky-ink/15", mint: "bg-mint-wash/70 text-mint-ink border-mint-ink/15", peach: "bg-peach-wash/70 text-peach-ink border-peach-ink/15", } as const; export function Eyebrow({ children, wash = "amber", className = "", }: { children: ReactNode; wash?: keyof typeof WASH; className?: string; }) { return ( {children} ); } /* ------------------------------------------------------------------ * * Primary CTA — solid amber, the brand's one loud surface * ------------------------------------------------------------------ */ export function BrandButton({ children, href, type, className = "", disabled, }: { children: ReactNode; href?: string; type?: "button" | "submit"; className?: string; disabled?: boolean; }) { const reduced = useReducedMotion(); const classes = `group relative inline-flex items-center justify-center gap-2 overflow-hidden rounded-buttons px-[22px] py-[11px] text-body font-semibold text-ink shadow-amber transition-shadow duration-300 disabled:pointer-events-none disabled:opacity-55 ${className}`; const style = { background: "var(--gradient-amber)" }; const inner = ( <> {/* Sheen sweep on hover — the glass highlight passing over. */} {children} ); if (href) { return ( {inner} ); } return ( {inner} ); } /** Secondary: glass surface, navy text. */ export function GlassButton({ children, href, className = "", }: { children: ReactNode; href: string; className?: string; }) { const reduced = useReducedMotion(); return ( {children} ); } export function GhostLink({ children, href, className = "", }: { children: ReactNode; href: string; className?: string; }) { return ( {children} ); } /* ------------------------------------------------------------------ * * Floating glass nav * ------------------------------------------------------------------ */ const NAV_LINKS = [ { href: "#funktionen", label: "Funktionen" }, { href: "#einblick", label: "Einblick" }, { href: "#preis", label: "Preis" }, { href: "#faq", label: "FAQ" }, ]; export function Nav() { const [scrolled, setScrolled] = useState(false); const [open, setOpen] = useState(false); const reduced = useReducedMotion(); useEffect(() => { const onScroll = () => setScrolled(window.scrollY > 24); onScroll(); window.addEventListener("scroll", onScroll, { passive: true }); return () => window.removeEventListener("scroll", onScroll); }, []); useEffect(() => { if (!open) return; const onKey = (event: KeyboardEvent) => { if (event.key === "Escape") setOpen(false); }; window.addEventListener("keydown", onKey); return () => window.removeEventListener("keydown", onKey); }, [open]); return (
Login Auf die Warteliste
{open ? ( ) : null}
); } /* ------------------------------------------------------------------ * * Waitlist form * ------------------------------------------------------------------ */ export function WaitlistForm({ compact = false }: { compact?: boolean }) { const [email, setEmail] = useState(""); const [state, setState] = useState<"idle" | "sending" | "done">("idle"); const fieldId = useId(); const statusId = `${fieldId}-status`; // No backend is wired up yet — this validates and acknowledges locally. const onSubmit = (event: React.FormEvent) => { event.preventDefault(); if (state !== "idle") return; setState("sending"); window.setTimeout(() => setState("done"), 700); }; if (state === "done") { return (

Danke — du stehst auf der Liste. Wir melden uns per E-Mail.

); } return (
setEmail(event.target.value)} className="min-w-0 flex-1 bg-transparent px-4 py-2.5 text-body text-ink outline-none placeholder:text-slate-quiet" /> {state === "sending" ? "Moment…" : "Platz sichern"}

Du bekommst eine E-Mail, sobald dein Zugang bereit ist. Keine Verpflichtung, keine Zahlungsdaten.

); } /* ------------------------------------------------------------------ * * FAQ accordion * ------------------------------------------------------------------ */ export function Faq({ question, children, }: { question: string; children: ReactNode; }) { const [open, setOpen] = useState(false); const panelId = useId(); return (

{children}
); }