import Link from "next/link";
import type { ComponentPropsWithoutRef, ReactNode } from "react";
import { HexMark, HoneycombPattern } from "@/components/honeycomb";
export function Container({
id,
className = "",
children,
}: {
id?: string;
className?: string;
children: ReactNode;
}) {
return (
{children}
);
}
type ButtonVariant = "primary" | "secondary" | "ghost" | "inverted" | "accent";
// Signatur-Hover: der Knopf fuellt sich von unten wie ein Glas — beim
// Primaerknopf mit Honig, beim Sekundaerknopf mit Waldgruen. Umgesetzt als
// Hintergrund-Verlauf, dessen Hoehe waechst (kein Layout-Eigenschafts-
// Tweening, kein zusaetzliches Element).
const fillBase =
"bg-no-repeat bg-bottom bg-[length:100%_0%] hover:bg-[length:100%_100%] focus-visible:bg-[length:100%_100%] motion-reduce:transition-colors";
const buttonStyles: Record = {
primary: `${fillBase} bg-forest bg-[linear-gradient(var(--color-honey-dark),var(--color-honey-dark))] text-cream border border-forest hover:border-honey-dark`,
secondary: `${fillBase} bg-transparent bg-[linear-gradient(var(--color-forest),var(--color-forest))] text-forest border border-forest hover:text-cream focus-visible:text-cream`,
ghost: "bg-transparent text-ink border border-ink/20 hover:border-ink hover:bg-ink/[0.03]",
// Fuer dunkle Flaechen (Hero, Waldgruen-Abschnitte, Menue): Creme-Rahmen,
// fuellt sich mit Creme, Text wechselt auf Waldgruen.
inverted: `${fillBase} bg-transparent bg-[linear-gradient(var(--color-cream),var(--color-cream))] text-cream border border-cream hover:text-forest focus-visible:text-forest`,
// Hauptaktion auf dunklen Flaechen, wo Waldgruen im Grund verschwinden wuerde.
accent: `${fillBase} bg-honey-dark bg-[linear-gradient(var(--color-cream),var(--color-cream))] text-cream border border-honey-dark hover:text-forest hover:border-cream focus-visible:text-forest`,
};
const buttonBase =
"inline-flex items-center justify-center gap-2 px-7 py-3 text-sm tracking-wide-caps transition-[color,background-size,border-color,transform,box-shadow] duration-500 ease-[var(--ease-arrive)] hover:shadow-[0_10px_24px_-14px_rgba(36,53,43,0.55)] active:scale-[0.97] active:duration-100";
interface LinkButtonProps extends ComponentPropsWithoutRef {
variant?: ButtonVariant;
}
export function LinkButton({
variant = "primary",
className = "",
children,
...props
}: LinkButtonProps) {
return (
{children}
);
}
interface ButtonProps extends ComponentPropsWithoutRef<"button"> {
variant?: ButtonVariant;
}
export function Button({
variant = "primary",
className = "",
children,
...props
}: ButtonProps) {
return (
);
}
export function SectionHeading({
eyebrow,
title,
subtitle,
align = "left",
className = "",
level = "h2",
tone = "default",
}: {
eyebrow?: string;
title: string;
subtitle?: string;
align?: "left" | "center";
className?: string;
/** "h1" fuer Seiten, auf denen diese Komponente die einzige/primaere Ueberschrift ist (SEO-Heading-Hierarchie). Default h2, da die meisten Verwendungen einzelne Abschnitte innerhalb einer Seite mit eigenem h1 sind. */
level?: "h1" | "h2";
/** "inverted" fuer Abschnitte auf dunklem Grund (z.B. bg-forest) — steuert die Eyebrow-Farbe fuer ausreichenden Kontrast. */
tone?: "default" | "inverted";
}) {
const Heading = level;
return (
{eyebrow ? (
{eyebrow}
) : null}
{title}
{subtitle ? (
{subtitle}
) : null}
);
}
/**
* Bild mit versetztem Honigrahmen dahinter — gibt den Bildspalten der
* Startseite Tiefe, statt sie flach neben den Text zu legen. Der Rahmen
* weicht beim Hover etwas zurueck, das Bild bleibt ruhig.
*/
export function FramedMedia({
children,
side = "right",
className = "",
}: {
children: ReactNode;
/** Richtung, in die der Rahmen versetzt ist. */
side?: "left" | "right";
className?: string;
}) {
return (
{children}
);
}
/**
* Karte fuer die kurzen Formularseiten (Passwort, Zwei-Faktor, ...): hebt
* das Formular von der Flaeche ab, mit Wabenraster in der oberen Ecke als
* leiser Markengruss.
*/
export function FormPanel({ children, className = "" }: { children: ReactNode; className?: string }) {
return (