Zum Inhalt
← Buttons

Button-System und Übersicht

Button-System eines Marburger Interface-Büros: fünf Typen, sieben Zustände, Tokens mit live gerechnetem Kontrast, eine Galerie aller 24 Button-Muster des Fundus zum Anfassen und die Zuordnung der 21 Rezepte.

Grundvariante für helle Kundenseiten und als Styleguide-Vorlage.

Eine Design-System-Seite für Buttons. Sie legt die Hierarchie fest (primär, sekundär, tertiär als Text, Icon-Button, Gefahr), nennt die Tokens für Höhe, Radius, Innenabstand, Abstand sowie Kurve und Dauer je Zustand und zeigt alle Zustände an echten Knöpfen: Ruhe, Hover, Fokus, Druck, deaktiviert, Laden, Erfolg. Dazu die Regeln für Trefferfläche (44 px) und Kontrast, eine Galerie aller Button-Muster des Fundus als Live-Beispiele und eine Tabelle, welcher Button-Typ zu welchem Rezept passt.

Buttons sind das häufigste Bedienelement einer Seite. Als System aus wenigen Tokens sprechen sie überall dieselbe Sprache: Die Hauptaktion ist sofort erkennbar, Zustände sind vorhersehbar, und neue Seiten erben das Verhalten. Große Design-Systeme und Studios behandeln Buttons deshalb als Satz aus Typen, Tokens und Zuständen, nicht als Einzeleffekte.

Wann einsetzen

Vor jedem Website-Bau als Werkzeug: Tokens aus dem Rezept setzen, dann ein Button-Muster als Haupttyp und höchstens eines als Zweittyp aus der Rezept-Tabelle wählen. Als Vorlage für eine eigene Komponentenseite, wenn mehrere Leute an einer Kundenseite bauen.

Wann nicht

Nicht als sichtbare Galerie auf einer Kundenseite: Die Übersicht ist Werkzeug, keine Sektion. Nicht mehrere Button-Muster auf einer Seite mischen. Nie mehr als eine primäre Handlung je Ansicht. Keine Muster, die das Rezept unter „nicht verwenden“ führt.

Varianten

  • hell: neutrale Systemseite auf hellem Grund, Signalton Ultramarin
  • dunkel: dieselben Tokens für dunkle Oberflächen, helle Primärfläche mit dunklem Text, eigene Gefahr- und Erfolgsfarbe
  • rezepte: dieselben fünf Typen in den Tokens von Studio-Bühne, Manufaktur-Stille und Fahrschule; der Umschalter setzt die Welt für die ganze Seite, Token-Tabellen und Kontraste rechnen mit

Umsetzung

Alle Buttons lesen dieselben Custom Properties: --b-h-s/m/l, --b-px-s/m/l, --b-radius, --b-kante, --b-schrift, Farben je Typ (--p-*, --s-*, --t-*, --i-*, --g-*, deaktiviert --d-*, Erfolg --ok-*) und Bewegung je Zustand (--dauer-*, --kurve-*). Jeder Typ mappt seine Farben auf --bg, --fg, --kante und deren -h- und -d-Stufen; die Zustandsregeln sind für alle Typen gleich. Hover nur in @media (hover: hover), Fokus über :focus-visible mit outline, Druck über :active und scale. Deaktiviert über aria-disabled="true", damit der Knopf fokussierbar bleibt und per aria-describedby sagt, warum. Laden mit aria-busy und role=status; Ruhe-, Lade- und Erfolgslabel liegen in einer Grid-Zelle, damit die Breite nie springt. Kleine Knöpfe bekommen über ::after mit negativem inset 44 px Trefferfläche. <button> für Handlungen, <a> für Ziele. Ein Rezept überschreibt nur Tokens am :root.

Robust umsetzen

Telefon. Ohne Hover entfällt der Hover-Zustand, Druck und Fokus bleiben. Alle Knöpfe mindestens 44 px tastbar, die Hauptaktion im Formular auf dem Telefon volle Breite und zuerst. Breite Tabellen werden zu Karten oder scrollen in einem eigenen Bereich.

Ohne Bewegung. Keine Wege und kein Skalieren: Druck wird zur Farbänderung, Label wechseln ohne Weg, der Spinner steht und der Text „Wird gesendet“ trägt den Zustand, das Häkchen erscheint ohne Zeichnen. Farbwechsel bleiben.

Barrierefrei. WCAG 1.4.3: Label in jedem Zustand mindestens 4,5 : 1, auch deaktiviert und im Ladezustand; gedämpft über eine eigene Textfarbe, nie über Deckkraft. 1.4.11: Kante sekundärer Buttons und Fokusring mindestens 3 : 1. 2.4.7: Fokus sichtbar, im Kontrastmodus Highlight. 2.5.8: mindestens 24 px, hier 44 px. 4.1.2: Icon-Buttons mit aria-label und Tooltip, Umschalter mit aria-pressed, Menü mit aria-expanded, Laden mit aria-busy und role=status. Gefahr-Buttons nicht nur über Rot: Verb nennt die Folge, Rückfrage mit Fokus auf „Behalten“, danach Rückgängig. Kontrastmodus: Rahmen in ButtonText, deaktiviert in GrayText.

Code

<!DOCTYPE html>
<!--
  Button-System und Übersicht
  Fundus · Buttons · https://cecodesign.de/lab/fundus/buttons/button-system-uebersicht/
  Eigenständige Datei. Bilder liegen hier unter bilder/ – eigene einsetzen.
-->
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Button-System und Übersicht · Fundus-Demo</title>
<script>document.documentElement.classList.add('js');if(matchMedia('(prefers-reduced-motion: reduce)').matches)document.documentElement.classList.add('reduziert')</script>
<style>
@font-face { font-family: 'Schibsted Grotesk'; src: url('https://cdn.jsdelivr.net/fontsource/fonts/schibsted-grotesk:vf@latest/latin-wght-normal.woff2') format('woff2-variations'); font-weight: 400 900; font-display: swap; }
@font-face { font-family: 'Geist Mono'; src: url('https://cdn.jsdelivr.net/fontsource/fonts/geist-mono:vf@latest/latin-wght-normal.woff2') format('woff2-variations'); font-weight: 100 900; font-display: swap; }
@font-face { font-family: 'TikTok Sans'; src: url('https://cdn.jsdelivr.net/fontsource/fonts/tiktok-sans:vf@latest/latin-wdth-normal.woff2') format('woff2-variations'); font-weight: 300 900; font-stretch: 75% 150%; font-display: swap; }
@font-face { font-family: 'Bodoni Moda'; src: url('https://cdn.jsdelivr.net/fontsource/fonts/bodoni-moda:vf@latest/latin-opsz-normal.woff2') format('woff2-variations'); font-weight: 400 900; font-style: normal; font-display: swap; }
@font-face { font-family: 'Instrument Sans'; src: url('https://cdn.jsdelivr.net/fontsource/fonts/instrument-sans:vf@latest/latin-wght-normal.woff2') format('woff2-variations'); font-weight: 400 700; font-display: swap; }
@font-face { font-family: 'Bricolage Grotesque'; src: url('https://cdn.jsdelivr.net/fontsource/fonts/bricolage-grotesque:vf@latest/latin-opsz-normal.woff2') format('woff2-variations'); font-weight: 200 800; font-display: swap; }
@font-face { font-family: 'Atkinson Hyperlegible Next'; src: url('https://cdn.jsdelivr.net/fontsource/fonts/atkinson-hyperlegible-next:vf@latest/latin-wght-normal.woff2') format('woff2-variations'); font-weight: 200 800; font-display: swap; }

/* ===================== Seite (Quermaß) ===================== */
:root {
  --grund: #f2f3f5; --flaeche: #ffffff; --flaeche-2: #e7e9ed; --text: #121419; --leise: #4d525c; --linie: rgb(18 20 25 / .12); --linie-2: rgb(18 20 25 / .24);
  --signal: #2a33e0; --signal-schrift: #2a33e0; --markierung: #d0108a;
  --rand: clamp(18px, 4.2vw, 56px);
  --mono: 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  --sans: 'Schibsted Grotesk', system-ui, sans-serif;
  --ui: cubic-bezier(0.2, 0, 0, 1);
  --expo: cubic-bezier(0.16, 1, 0.3, 1);

  /* ---------- System-Tokens: Maß ---------- */
  --b-h-s: 36px; --b-h-m: 44px; --b-h-l: 52px;
  --b-px-s: 14px; --b-px-m: 20px; --b-px-l: 26px;
  --b-gap: 8px; --b-abstand: 12px;
  --b-radius: 10px; --b-radius-icon: 10px;
  --b-kante: 1px;
  --b-schrift: 'Schibsted Grotesk', system-ui, sans-serif; --b-gewicht: 600; --b-groesse-s: 14px; --b-groesse-m: 15px; --b-groesse-l: 16px; --b-laufweite: 0em; --b-versal: none;
  --b-fokus: #121419; --b-fokus-breite: 2px; --b-fokus-versatz: 3px;
  --b-druck: .97;
  /* ---------- System-Tokens: Farbe je Typ ---------- */
  --p-bg: #2a33e0; --p-bg-h: #1d24b8; --p-bg-d: #161c94; --p-fg: #ffffff; --p-fg-h: #ffffff; --p-kante: #2a33e0; --p-kante-h: #1d24b8;
  --s-bg: #ffffff; --s-bg-h: #e7e9ed; --s-bg-d: #dcdfe4; --s-fg: #121419; --s-fg-h: #121419; --s-kante: #7d818a; --s-kante-h: #121419;
  --t-bg: #ffffff; --t-bg-h: #e7e9ed; --t-bg-d: #dcdfe4; --t-fg: #121419; --t-fg-h: #121419;
  --i-bg: #e7e9ed; --i-bg-h: #dcdfe4; --i-bg-d: #cfd3da; --i-fg: #121419; --i-fg-h: #121419; --i-kante: #e7e9ed; --i-kante-h: #dcdfe4;
  --g-bg: #b3261e; --g-bg-h: #8f1d17; --g-bg-d: #741712; --g-fg: #ffffff; --g-fg-h: #ffffff; --g-kante: #b3261e; --g-kante-h: #8f1d17;
  --d-bg: #e3e5e9; --d-fg: #5d626c; --d-kante: #b9bdc5;
  --ok-bg: #1d6b45; --ok-fg: #ffffff;
  /* ---------- System-Tokens: Bewegung je Zustand ---------- */
  --dauer-hover: 150ms; --kurve-hover: cubic-bezier(0.2, 0, 0, 1);
  --dauer-fokus: 120ms; --kurve-fokus: cubic-bezier(0.2, 0, 0, 1);
  --dauer-druck-ein: 100ms; --kurve-druck-ein: cubic-bezier(0.45, 0.02, 0.09, 0.98);
  --dauer-druck-aus: 500ms; --kurve-druck-aus: linear(0, 0.044, 0.155, 0.307, 0.476, 0.643, 0.795, 0.923, 1.023, 1.095, 1.139, 1.16, 1.162, 1.15, 1.129, 1.102, 1.075, 1.048, 1.025, 1.006, 0.991, 0.981, 0.976, 0.973, 0.974, 0.977, 0.981, 0.985, 0.99, 0.994, 0.997, 1, 1.002, 1.003, 1.004, 1.004, 1.004, 1.004, 1.003, 1.002, 1);
  --dauer-label: 150ms; --kurve-label: cubic-bezier(0.16, 1, 0.3, 1);
  --dauer-spinner: 700ms;
  --dauer-haken: 300ms;
}
:root[data-v="dunkel"] {
  --grund: #0f1013; --flaeche: #17191e; --flaeche-2: #22252c; --text: #eef0f3; --leise: #a5abb6; --linie: rgb(238 240 243 / .12); --linie-2: rgb(238 240 243 / .26);
  --signal: #9aa2ff; --signal-schrift: #aab1ff; --markierung: #ff6ec7;
  --b-fokus: #eef0f3;
  --p-bg: #9aa2ff; --p-bg-h: #b8beff; --p-bg-d: #cdd1ff; --p-fg: #0b0c10; --p-fg-h: #0b0c10; --p-kante: #9aa2ff; --p-kante-h: #b8beff;
  --s-bg: #17191e; --s-bg-h: #22252c; --s-bg-d: #2c3038; --s-fg: #eef0f3; --s-fg-h: #ffffff; --s-kante: #6c727e; --s-kante-h: #eef0f3;
  --t-bg: #17191e; --t-bg-h: #22252c; --t-bg-d: #2c3038; --t-fg: #eef0f3; --t-fg-h: #ffffff;
  --i-bg: #22252c; --i-bg-h: #2c3038; --i-bg-d: #363a44; --i-fg: #eef0f3; --i-fg-h: #ffffff; --i-kante: #22252c; --i-kante-h: #2c3038;
  --g-bg: #ff8a80; --g-bg-h: #ffa79f; --g-bg-d: #ffc0ba; --g-fg: #0f1013; --g-fg-h: #0f1013; --g-kante: #ff8a80; --g-kante-h: #ffa79f;
  --d-bg: #22252c; --d-fg: #9aa0aa; --d-kante: #3a3e47;
  --ok-bg: #6fd6a0; --ok-fg: #0f1013;
  color-scheme: dark;
}
/* Rezept-Welten: dieselben Komponenten, nur andere Tokens */
.welt--buehne, :root[data-v="rezepte"][data-welt="buehne"] {
  --b-h-s: 40px; --b-h-m: 48px; --b-h-l: 56px; --b-px-s: 18px; --b-px-m: 24px; --b-px-l: 30px;
  --b-radius: 999px; --b-radius-icon: 999px; --b-kante: 1.5px;
  --b-schrift: 'TikTok Sans', system-ui, sans-serif; --b-gewicht: 600; --b-groesse-s: 14px; --b-groesse-m: 16px; --b-groesse-l: 17px; --b-laufweite: -0.01em; --b-versal: none;
  --b-fokus: #0b0b0b; --b-druck: .96;
  --p-bg: #ff5a1f; --p-bg-h: #0b0b0b; --p-bg-d: #0b0b0b; --p-fg: #0b0b0b; --p-fg-h: #ffffff; --p-kante: #ff5a1f; --p-kante-h: #0b0b0b;
  --s-bg: #f2f2f2; --s-bg-h: #0b0b0b; --s-bg-d: #0b0b0b; --s-fg: #0b0b0b; --s-fg-h: #ffffff; --s-kante: #0b0b0b; --s-kante-h: #0b0b0b;
  --t-bg: #f2f2f2; --t-bg-h: #e2e2e2; --t-bg-d: #d6d6d6; --t-fg: #0b0b0b; --t-fg-h: #0b0b0b;
  --i-bg: #0b0b0b; --i-bg-h: #ff5a1f; --i-bg-d: #ff5a1f; --i-fg: #ffffff; --i-fg-h: #0b0b0b; --i-kante: #0b0b0b; --i-kante-h: #ff5a1f;
  --g-bg: #f2f2f2; --g-bg-h: #b3261e; --g-bg-d: #8f1d17; --g-fg: #a3201a; --g-fg-h: #ffffff; --g-kante: #a3201a; --g-kante-h: #b3261e;
  --d-bg: #e2e2e2; --d-fg: #555555; --d-kante: #bdbdbd;
  --ok-bg: #0b0b0b; --ok-fg: #ffffff;
  --dauer-hover: 400ms; --kurve-hover: cubic-bezier(0.16, 1, 0.3, 1); --dauer-label: 400ms;
  --welt-grund: #f2f2f2; --welt-text: #0b0b0b; --welt-leise: #555555; --welt-titel: 'TikTok Sans', system-ui, sans-serif;
}
.welt--manufaktur, :root[data-v="rezepte"][data-welt="manufaktur"] {
  --b-h-s: 40px; --b-h-m: 48px; --b-h-l: 52px; --b-px-s: 18px; --b-px-m: 26px; --b-px-l: 30px;
  --b-radius: 0px; --b-radius-icon: 0px; --b-kante: 1px;
  --b-schrift: 'Instrument Sans', system-ui, sans-serif; --b-gewicht: 500; --b-groesse-s: 11px; --b-groesse-m: 12px; --b-groesse-l: 12.5px; --b-laufweite: 0.08em; --b-versal: uppercase;
  --b-fokus: #8f7244; --b-fokus-breite: 1px; --b-fokus-versatz: 5px; --b-druck: 1;
  --p-bg: #23282f; --p-bg-h: #3a414b; --p-bg-d: #11151a; --p-fg: #ffffff; --p-fg-h: #ffffff; --p-kante: #23282f; --p-kante-h: #3a414b;
  --s-bg: #ffffff; --s-bg-h: #f4f4f2; --s-bg-d: #e9e9e6; --s-fg: #23282f; --s-fg-h: #23282f; --s-kante: #7c8188; --s-kante-h: #23282f;
  --t-bg: #ffffff; --t-bg-h: #f4f4f2; --t-bg-d: #e9e9e6; --t-fg: #23282f; --t-fg-h: #23282f;
  --i-bg: #ffffff; --i-bg-h: #f4f4f2; --i-bg-d: #e9e9e6; --i-fg: #23282f; --i-fg-h: #23282f; --i-kante: #7c8188; --i-kante-h: #23282f;
  --g-bg: #ffffff; --g-bg-h: #8a1f17; --g-bg-d: #6e1912; --g-fg: #8a1f17; --g-fg-h: #ffffff; --g-kante: #8a1f17; --g-kante-h: #8a1f17;
  --d-bg: #f4f4f2; --d-fg: #5f646b; --d-kante: #c9cbcd;
  --ok-bg: #23282f; --ok-fg: #ffffff;
  --dauer-hover: 250ms; --kurve-hover: cubic-bezier(0.25, 1, 0.5, 1); --dauer-label: 250ms;
  --welt-grund: #ffffff; --welt-text: #23282f; --welt-leise: #5f646b; --welt-titel: 'Bodoni Moda', Georgia, serif;
}
.welt--fahrschule, :root[data-v="rezepte"][data-welt="fahrschule"] {
  --b-h-s: 40px; --b-h-m: 48px; --b-h-l: 56px; --b-px-s: 16px; --b-px-m: 22px; --b-px-l: 28px;
  --b-radius: 14px; --b-radius-icon: 14px; --b-kante: 2px;
  --b-schrift: 'Bricolage Grotesque', system-ui, sans-serif; --b-gewicht: 700; --b-groesse-s: 15px; --b-groesse-m: 16px; --b-groesse-l: 18px; --b-laufweite: 0em; --b-versal: none;
  --b-fokus: #142b50; --b-fokus-breite: 3px; --b-fokus-versatz: 4px; --b-druck: .95;
  --p-bg: #ffd60a; --p-bg-h: #ffe14d; --p-bg-d: #f0c400; --p-fg: #142b50; --p-fg-h: #142b50; --p-kante: #142b50; --p-kante-h: #142b50;
  --s-bg: #ffffff; --s-bg-h: #eef0d8; --s-bg-d: #e3e6c6; --s-fg: #142b50; --s-fg-h: #142b50; --s-kante: #142b50; --s-kante-h: #142b50;
  --t-bg: #f8f8ec; --t-bg-h: #eef0d8; --t-bg-d: #e3e6c6; --t-fg: #142b50; --t-fg-h: #142b50;
  --i-bg: #142b50; --i-bg-h: #213f70; --i-bg-d: #0b1a33; --i-fg: #ffffff; --i-fg-h: #ffffff; --i-kante: #142b50; --i-kante-h: #213f70;
  --g-bg: #ffffff; --g-bg-h: #b3261e; --g-bg-d: #8f1d17; --g-fg: #a3201a; --g-fg-h: #ffffff; --g-kante: #a3201a; --g-kante-h: #b3261e;
  --d-bg: #e3e4d4; --d-fg: #3f4a5e; --d-kante: #b8bba3;
  --ok-bg: #1d6b45; --ok-fg: #ffffff;
  --dauer-hover: 400ms; --kurve-hover: cubic-bezier(0.34, 1.56, 0.64, 1); --dauer-label: 300ms;
  --welt-grund: #f8f8ec; --welt-text: #142b50; --welt-leise: #3f4a5e; --welt-titel: 'Bricolage Grotesque', system-ui, sans-serif;
}

* { box-sizing: border-box; margin: 0; }
html { background: var(--grund); color: var(--text); font-family: var(--sans); font-size: 16px; line-height: 1.5; -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
:root:has(:focus-visible) { scroll-behavior: auto; }
.reduziert { scroll-behavior: auto; }
body { min-height: 100svh; overflow-x: clip; }
a { color: inherit; }
:focus-visible { outline: 2px solid var(--b-fokus); outline-offset: 3px; }
.mono, .label { font-family: var(--mono); font-size: 11px; font-weight: 500; letter-spacing: .14em; text-transform: uppercase; line-height: 1.3; }
.label { color: var(--leise); }
.nur-sr { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.rahmen { padding-inline: var(--rand); max-width: 1440px; margin-inline: auto; }

/* ---------- Pult (in der Seite, nicht fest) ---------- */
.pult { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 18px; padding: 10px var(--rand); border-bottom: 1px solid var(--linie); background: var(--flaeche-2); color: var(--leise); }
.pult__gruppe { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; }
.pult__gruppe > span { margin-right: 6px; }
.pult button { font: inherit; letter-spacing: inherit; text-transform: inherit; color: var(--leise); background: none; border: 1px solid transparent; border-radius: 999px; padding: 6px 10px; min-height: 30px; cursor: pointer; transition: background-color 150ms var(--ui), color 150ms var(--ui); }
.pult button:hover { background: rgb(127 127 127 / .14); color: var(--text); }
.pult button[aria-pressed="true"] { background: var(--text); color: var(--grund); }
.pult output { margin-left: auto; }

/* ---------- Kopf ---------- */
.kopf { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px 28px; padding-block: 20px; border-bottom: 1px solid var(--linie); }
.marke { display: flex; align-items: baseline; gap: 12px; text-decoration: none; }
.marke b { font-weight: 800; font-size: 21px; letter-spacing: -0.03em; }
.marke b i { font-style: normal; color: var(--signal-schrift); }
.kopf nav ul { display: flex; flex-wrap: wrap; gap: 4px 20px; list-style: none; padding: 0; }
.kopf nav a { text-decoration: none; display: inline-flex; align-items: center; min-height: 44px; color: var(--leise); }
.kopf nav a:hover { color: var(--text); text-decoration: underline; text-underline-offset: .3em; }
.kopf nav a span { color: var(--text); margin-right: 6px; }

/* ---------- Hero ---------- */
.held { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); gap: clamp(28px, 5vw, 80px); align-items: end; padding-block: clamp(36px, 6vw, 84px) clamp(36px, 5vw, 64px); }
.held__text .label { display: flex; gap: 14px; margin-bottom: 26px; }
.held h1 { font-weight: 750; font-size: clamp(2.4rem, 1rem + 4.4vw, 4.9rem); line-height: .96; letter-spacing: -0.045em; text-wrap: balance; }
.held h1 > * { display: block; }
.held h1 em { font-style: normal; color: var(--leise); font-weight: 500; }
.held__intro { margin-top: 26px; max-width: 34em; font-size: clamp(1rem, .95rem + .3vw, 1.15rem); color: var(--leise); text-wrap: pretty; }
.held__fakten { display: flex; flex-wrap: wrap; gap: 10px 28px; margin-top: 30px; padding: 0; list-style: none; }
.held__fakten li { display: grid; gap: 2px; }
.held__fakten b { font-size: 1.6rem; font-weight: 700; letter-spacing: -0.03em; line-height: 1.1; font-variant-numeric: tabular-nums; }

/* Spezimen */
.spezimen { position: relative; background: var(--flaeche); border: 1px solid var(--linie); border-radius: 18px; padding: clamp(18px, 2.4vw, 28px); display: grid; gap: 22px; }
.spezimen__kopf { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.spezimen__feld { position: relative; display: grid; place-items: center; min-height: 190px; border-radius: 12px;
  background-color: var(--grund);
  background-image: linear-gradient(var(--linie) 1px, transparent 1px), linear-gradient(90deg, var(--linie) 1px, transparent 1px);
  background-size: 22px 22px; background-position: -1px -1px; }
.mass { position: absolute; inset: 0; pointer-events: none; }
.mass__h, .mass__p { position: absolute; font-family: var(--mono); font-size: 10.5px; letter-spacing: .08em; color: var(--markierung); white-space: nowrap; }
.spezimen__zustaende { display: flex; flex-wrap: wrap; gap: 6px; padding: 0; list-style: none; }
.spezimen__zustaende li { font-family: var(--mono); font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase; padding: 6px 9px; border-radius: 999px; border: 1px solid var(--linie-2); color: var(--leise); transition: background-color 150ms var(--ui), color 150ms var(--ui), border-color 150ms var(--ui); }
.spezimen__zustaende li.ist-an { background: var(--text); color: var(--grund); border-color: var(--text); }
.spezimen__werte { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; border-top: 1px solid var(--linie); padding-top: 16px; }
.spezimen__werte div { display: grid; gap: 4px; min-width: 0; }
.spezimen__werte output { font-family: var(--mono); font-size: 12.5px; color: var(--text); overflow-wrap: anywhere; }

/* Rezept-Welten im Hero */
.welten { display: none; }
:root[data-v="rezepte"] .welten { display: block; padding-bottom: clamp(36px, 5vw, 64px); }
:root[data-v="rezepte"] .spezimen { display: none; }
:root[data-v="rezepte"] .held { grid-template-columns: minmax(0, 1fr); padding-bottom: 28px; }
:root[data-v="rezepte"] .held h1 { font-size: clamp(2.1rem, 1rem + 3vw, 3.6rem); }
:root[data-v="rezepte"] .held { padding-top: clamp(28px, 4vw, 52px); }
:root[data-v="rezepte"] .held__fakten { display: none; }
:root[data-v="rezepte"] .held__intro { margin-top: 16px; }
.welten__wahl { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; margin-bottom: 18px; }
.welten__wahl [role=group] { display: inline-flex; flex-wrap: wrap; padding: 4px; gap: 4px; border-radius: 999px; background: var(--flaeche-2); }
.welten__wahl button { font: 600 14px/1 var(--sans); min-height: 40px; padding: 0 16px; border-radius: 999px; border: 0; background: none; color: var(--leise); cursor: pointer; transition: background-color 150ms var(--ui), color 150ms var(--ui); }
.welten__wahl button[aria-pressed="true"] { background: var(--flaeche); color: var(--text); box-shadow: 0 1px 2px rgb(0 0 0 / .1); }
.welten__raster { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
.welt { position: relative; background: var(--welt-grund); color: var(--welt-text); border-radius: 16px; padding: 22px 20px 22px; display: grid; gap: 14px; align-content: start; border: 1px solid rgb(0 0 0 / .1); transition: box-shadow 250ms var(--ui); }
.welt.ist-aktiv { box-shadow: 0 0 0 2px var(--grund), 0 0 0 4px var(--text); }
.welt__kopf { display: grid; gap: 4px; }
.welt__kopf h3 { font-family: var(--welt-titel); font-weight: 600; font-size: 1.45rem; letter-spacing: -0.02em; line-height: 1.1; }
.welt--manufaktur .welt__kopf h3 { font-weight: 500; letter-spacing: 0; }
.welt__kopf span { font-family: var(--mono); font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: var(--welt-leise); }
.welt__knoepfe { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.welt__notiz { font-family: var(--mono); font-size: 10.5px; letter-spacing: .04em; color: var(--welt-leise); line-height: 1.5; }

/* ---------- Abschnitte ---------- */
.abschnitt { padding-block: clamp(48px, 7vw, 104px); border-top: 1px solid var(--linie); }
.abschnitt__kopf { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr); gap: 16px 48px; margin-bottom: clamp(26px, 4vw, 48px); align-items: end; }
.abschnitt__kopf h2 { font-weight: 720; font-size: clamp(1.9rem, 1.2rem + 2.4vw, 3.2rem); line-height: 1; letter-spacing: -0.035em; }
.abschnitt__kopf h2 .label { display: block; margin-bottom: 14px; letter-spacing: .14em; }
.abschnitt__kopf p { color: var(--leise); max-width: 40em; text-wrap: pretty; }

/* ---------- Button-Komponente ---------- */
.k { --_h: var(--b-h-m); --_px: var(--b-px-m); --_fs: var(--b-groesse-m);
  --bg: var(--p-bg); --bg-h: var(--p-bg-h); --bg-d: var(--p-bg-d); --fg: var(--p-fg); --fg-h: var(--p-fg-h); --kante: var(--p-kante); --kante-h: var(--p-kante-h);
  position: relative; display: inline-grid; grid-auto-flow: column; align-items: center; justify-content: center; gap: var(--b-gap);
  min-height: var(--_h); min-width: var(--_h); padding: 0 var(--_px); border-radius: var(--b-radius);
  border: var(--b-kante) solid var(--kante); background-color: var(--bg); color: var(--fg);
  font-family: var(--b-schrift); font-weight: var(--b-gewicht); font-size: var(--_fs); line-height: 1.1; letter-spacing: var(--b-laufweite); text-transform: var(--b-versal);
  text-decoration: none; cursor: pointer; user-select: none; -webkit-tap-highlight-color: transparent; white-space: nowrap;
  outline: 0 solid var(--b-fokus); outline-offset: 0;
  transition: background-color var(--dauer-hover) var(--kurve-hover), color var(--dauer-hover) var(--kurve-hover), border-color var(--dauer-hover) var(--kurve-hover),
    outline-width var(--dauer-fokus) var(--kurve-fokus), outline-offset var(--dauer-fokus) var(--kurve-fokus), scale var(--dauer-druck-aus) var(--kurve-druck-aus);
}
.k::after { content: ''; position: absolute; inset: min(0px, calc((var(--_h) - 44px) / 2)); border-radius: inherit; }
.k--s { --_h: var(--b-h-s); --_px: var(--b-px-s); --_fs: var(--b-groesse-s); }
.k--l { --_h: var(--b-h-l); --_px: var(--b-px-l); --_fs: var(--b-groesse-l); }
.k--sekundaer { --bg: var(--s-bg); --bg-h: var(--s-bg-h); --bg-d: var(--s-bg-d); --fg: var(--s-fg); --fg-h: var(--s-fg-h); --kante: var(--s-kante); --kante-h: var(--s-kante-h); }
.k--tertiaer { --bg: transparent; --bg-h: var(--t-bg-h); --bg-d: var(--t-bg-d); --fg: var(--t-fg); --fg-h: var(--t-fg-h); --kante: transparent; --kante-h: transparent; --_px: calc(var(--b-px-m) * .6);
  text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: .28em; }
.k--tertiaer.k--s { --_px: calc(var(--b-px-s) * .6); }
.k--tertiaer.k--l { --_px: calc(var(--b-px-l) * .6); }
.k--icon { --bg: var(--i-bg); --bg-h: var(--i-bg-h); --bg-d: var(--i-bg-d); --fg: var(--i-fg); --fg-h: var(--i-fg-h); --kante: var(--i-kante); --kante-h: var(--i-kante-h); padding: 0; width: var(--_h); border-radius: var(--b-radius-icon); }
.k--gefahr { --bg: var(--g-bg); --bg-h: var(--g-bg-h); --bg-d: var(--g-bg-d); --fg: var(--g-fg); --fg-h: var(--g-fg-h); --kante: var(--g-kante); --kante-h: var(--g-kante-h); }
.k--voll { width: 100%; }
.k svg { width: 1.15em; height: 1.15em; flex: none; }
.k--icon svg { width: 20px; height: 20px; }
.k path, .k circle, .k line, .k polyline { vector-effect: non-scaling-stroke; }

/* Zustände (echte Pseudoklassen plus .ist-… für Matrix und Vorführung) */
.k.ist-hover { background-color: var(--bg-h); color: var(--fg-h); border-color: var(--kante-h); }
.k--tertiaer.ist-hover { text-decoration-thickness: 2px; }
@media (hover: hover) {
  .k:hover:not([aria-disabled="true"], [aria-busy="true"], .ist-erfolg) { background-color: var(--bg-h); color: var(--fg-h); border-color: var(--kante-h); }
  .k--tertiaer:hover:not([aria-disabled="true"]) { text-decoration-thickness: 2px; }
}
.k:focus-visible, .k.ist-fokus { outline-width: var(--b-fokus-breite); outline-offset: var(--b-fokus-versatz); }
.k:active:not([aria-disabled="true"], [aria-busy="true"]), .k.ist-druck { background-color: var(--bg-d); color: var(--fg-h); border-color: var(--kante-h); scale: var(--b-druck);
  transition: background-color 60ms linear, color 60ms linear, border-color 60ms linear, scale var(--dauer-druck-ein) var(--kurve-druck-ein); }
.k[aria-disabled="true"], .k.ist-aus { background-color: var(--d-bg); color: var(--d-fg); border-color: var(--d-kante); border-style: dashed; cursor: not-allowed; text-decoration: none; }
.k--tertiaer[aria-disabled="true"], .k--tertiaer.ist-aus { background-color: transparent; border-color: transparent; text-decoration: underline dashed 1px; }
.k[aria-busy="true"], .k.ist-laden { cursor: progress; }
.k.ist-erfolg { background-color: var(--ok-bg); color: var(--ok-fg); border-color: var(--ok-bg); text-decoration: none; }

/* Label-Stapel: alle Beschriftungen in einer Zelle, Breite = längste, nichts springt */
.k__stapel { display: grid; place-items: center; }
.k__stapel > * { grid-area: 1 / 1; display: inline-flex; align-items: center; gap: var(--b-gap); transition: opacity var(--dauer-label) var(--kurve-label), translate var(--dauer-label) var(--kurve-label); }
.k__laden, .k__ok { opacity: 0; translate: 0 .45em; }
.k.ist-laden .k__ruhe, .k.ist-erfolg .k__ruhe { opacity: 0; translate: 0 -.45em; }
.k.ist-laden .k__laden, .k.ist-erfolg .k__ok { opacity: 1; translate: 0 0; }
.k__dreh { width: 1em; height: 1em; border-radius: 50%; border: 2px solid currentColor; border-right-color: transparent; animation: drehen var(--dauer-spinner) linear infinite; animation-play-state: paused; }
.k.ist-laden .k__dreh { animation-play-state: running; }
@keyframes drehen { to { rotate: 1turn; } }
.k__haken path { stroke-dasharray: 1; stroke-dashoffset: 1; }
.k.ist-erfolg .k__haken path { stroke-dashoffset: 0; transition: stroke-dashoffset var(--dauer-haken) var(--expo) 80ms; }

/* Tooltip für Icon-Buttons */
.k[data-tipp]::before { content: attr(data-tipp); position: absolute; bottom: calc(100% + 8px); left: 50%; translate: -50% 4px; padding: 5px 8px; border-radius: 6px; background: var(--text); color: var(--grund);
  font: 500 11px/1.2 var(--mono); letter-spacing: .06em; text-transform: none; white-space: nowrap; opacity: 0; pointer-events: none; transition: opacity 120ms var(--ui) 0ms, translate 120ms var(--ui); z-index: 3; }
.k[data-tipp]:focus-visible::before { opacity: 1; translate: -50% 0; }
@media (hover: hover) { .k[data-tipp]:hover::before { opacity: 1; translate: -50% 0; transition-delay: 400ms; } }

/* Trefferflächen zeigen */
:root[data-treffer] .k::after, :root[data-treffer] [data-ziel] { outline: 1px dashed var(--markierung); outline-offset: 0; }
:root[data-treffer] .k::after { background: color-mix(in srgb, var(--markierung) 10%, transparent); }

/* ---------- Hierarchie ---------- */
.typen { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 1px; background: var(--linie); border: 1px solid var(--linie); border-radius: 16px; overflow: hidden; }
.typ { background: var(--flaeche); padding: 22px 20px 24px; display: grid; gap: 16px; align-content: start; }
.typ h3 { font-size: 1.15rem; font-weight: 700; letter-spacing: -0.02em; display: flex; justify-content: space-between; gap: 8px; align-items: baseline; }
.typ h3 span { font-family: var(--mono); font-size: 10.5px; font-weight: 500; letter-spacing: .1em; color: var(--leise); }
.typ__groessen { display: grid; justify-items: start; gap: 12px; min-height: 172px; align-content: center; }
.typ__groessen.icons { grid-auto-flow: column; justify-content: start; align-items: center; }
.typ p { font-size: .94rem; color: var(--leise); text-wrap: pretty; }
.typ p b { color: var(--text); font-weight: 600; }

.kontexte { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); gap: 14px; margin-top: 14px; }
.kontext { background: var(--flaeche); border: 1px solid var(--linie); border-radius: 16px; padding: clamp(18px, 2.4vw, 28px); display: grid; gap: 18px; align-content: start; }
.kontext__titel { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.formular { display: grid; gap: 14px; }
.feld { display: grid; gap: 6px; }
.feld label, .feld .feld__name { font-size: .88rem; font-weight: 600; }
.feld input, .feld select, .feld textarea { font: inherit; font-size: 1rem; color: var(--text); background: var(--grund); border: 1px solid var(--s-kante); border-radius: 8px; padding: 10px 12px; min-height: 44px; width: 100%; }
.feld textarea { min-height: 84px; resize: vertical; }
.zeile2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.haken { display: flex; gap: 10px; align-items: flex-start; font-size: .94rem; min-height: 44px; padding-top: 10px; cursor: pointer; }
.haken input { width: 20px; height: 20px; margin-top: 1px; accent-color: var(--p-bg); flex: none; }
.aktionen { display: flex; flex-wrap: wrap; gap: var(--b-abstand); align-items: center; padding-top: 6px; border-top: 1px solid var(--linie); padding-top: 18px; }
.aktionen .k--primaer { margin-left: auto; }
.hinweis { font-size: .86rem; color: var(--leise); }
.hinweis.ist-betont { color: var(--g-fg-text, var(--text)); font-weight: 600; }
.status { font-family: var(--mono); font-size: 11.5px; letter-spacing: .06em; color: var(--leise); min-height: 1.4em; }
.liste-projekte { display: grid; gap: 0; padding: 0; list-style: none; border-top: 1px solid var(--linie); }
.liste-projekte li { display: flex; align-items: center; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--linie); min-height: 68px; flex-wrap: wrap; }
.liste-projekte li > div:first-child { flex: 1 1 160px; min-width: 0; }
.liste-projekte b { display: block; font-weight: 600; }
.liste-projekte small { color: var(--leise); font-size: .84rem; }
.werkzeuge { display: flex; gap: 6px; }
.bestaetigung { display: grid; gap: 12px; padding: 16px; border-radius: 12px; background: var(--grund); border: 1px solid var(--linie-2); }
.bestaetigung[hidden] { display: none; }
.bestaetigung p { font-size: .94rem; }
.bestaetigung .reihe { display: flex; flex-wrap: wrap; gap: 10px; }

/* ---------- Tokens ---------- */
.tokens { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr); gap: 14px; }
.tafel { background: var(--flaeche); border: 1px solid var(--linie); border-radius: 16px; padding: clamp(16px, 2.2vw, 26px); min-width: 0; }
.tafel h3 { font-size: 1.05rem; font-weight: 700; letter-spacing: -0.01em; margin-bottom: 14px; display: flex; justify-content: space-between; gap: 10px; flex-wrap: wrap; align-items: baseline; }
.ttab-huelle { overflow-x: auto; }
.ttab { width: 100%; border-collapse: collapse; font-size: .9rem; }
.ttab th, .ttab td { text-align: left; padding: 9px 8px 9px 0; border-bottom: 1px solid var(--linie); vertical-align: top; }
.ttab th { font-family: var(--mono); font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase; font-weight: 500; color: var(--leise); }
.ttab td:first-child, .ttab code { font-family: var(--mono); font-size: 12px; }
.ttab td.wert { font-family: var(--mono); font-size: 12px; color: var(--text); overflow-wrap: anywhere; }
.ttab tr:last-child td { border-bottom: 0; }
.kurve { width: 46px; height: 32px; display: block; }
.kurve path { fill: none; stroke: var(--signal); stroke-width: 1.6; }
.kurve line { stroke: var(--linie-2); stroke-width: 1; }
.treffer-bild { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; margin-top: 18px; }
.treffer-bild figure { display: grid; gap: 8px; justify-items: center; padding: 18px 8px 12px; background: var(--grund); border-radius: 12px; }
.treffer-bild figcaption { font-family: var(--mono); font-size: 10.5px; letter-spacing: .06em; color: var(--leise); text-align: center; }
.treffer-bild .bsp { position: relative; display: grid; place-items: center; width: 116px; height: 60px; }
.treffer-bild .zone { position: absolute; border: 1px dashed var(--markierung); background: color-mix(in srgb, var(--markierung) 9%, transparent); border-radius: 6px; }
.treffer-bild .knopf-bsp { position: relative; background: var(--p-bg); border-radius: 8px; }

/* ---------- Zustände-Matrix ---------- */
.matrix-huelle { overflow-x: auto; border: 1px solid var(--linie); border-radius: 16px; background: var(--flaeche); }
.matrix { display: grid; grid-template-columns: 112px repeat(7, minmax(132px, 1fr)); min-width: 1040px; }
.matrix > * { padding: 14px 12px; border-bottom: 1px solid var(--linie); border-right: 1px solid var(--linie); min-width: 0; }
.matrix > *:nth-child(8n) { border-right: 0; }
.matrix .kopfz { font-family: var(--mono); font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--leise); display: grid; gap: 4px; align-content: end; }
.matrix .kopfz small { letter-spacing: .02em; text-transform: none; font-size: 10.5px; }
.matrix .typz { font-weight: 700; font-size: .92rem; display: flex; align-items: center; }
.zelle { display: grid; justify-items: center; gap: 10px; padding-block: 22px 12px !important; }
.zelle output { font-family: var(--mono); font-size: 10.5px; letter-spacing: .04em; color: var(--leise); }
.zelle output b { color: var(--text); font-weight: 600; }
.matrix > :nth-last-child(-n + 8) { border-bottom: 0; }
.regeln { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; margin-top: 14px; }
.regel { background: var(--flaeche); border: 1px solid var(--linie); border-radius: 16px; padding: 18px 18px 20px; display: grid; gap: 8px; align-content: start; }
.regel b { font-size: 1.6rem; font-weight: 750; letter-spacing: -0.03em; line-height: 1; font-variant-numeric: tabular-nums; }
.regel p { font-size: .92rem; color: var(--leise); }

/* ---------- Galerie ---------- */
.filter { display: flex; flex-wrap: wrap; gap: 12px 24px; align-items: center; margin-bottom: 22px; }
.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chips button { font: 500 13px/1 var(--sans); min-height: 36px; padding: 0 13px; border-radius: 999px; border: 1px solid var(--linie-2); background: var(--flaeche); color: var(--text); cursor: pointer; position: relative; transition: background-color 150ms var(--ui), color 150ms var(--ui); }
.chips button::after { content: ''; position: absolute; inset: -4px 0; }
.chips button[aria-pressed="true"] { background: var(--text); color: var(--grund); border-color: var(--text); }
.filter label { display: inline-flex; flex-wrap: wrap; gap: 6px 10px; align-items: center; font-size: .9rem; max-width: 100%; }
.filter select { min-width: 0; width: min(100%, 22rem); font: inherit; font-size: .95rem; min-height: 44px; padding: 0 36px 0 12px; border-radius: 10px; border: 1px solid var(--s-kante); background: var(--flaeche); color: var(--text); max-width: 100%; }
.filter output { margin-left: auto; }
.galerie { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr)); gap: 14px; padding: 0; list-style: none; }
.karte { display: grid; grid-template-rows: auto 1fr; background: var(--flaeche); border: 1px solid var(--linie); border-radius: 16px; overflow: hidden; transition: border-color 150ms var(--ui), box-shadow 150ms var(--ui); }
.karte[hidden] { display: none; }
.karte.ist-empfohlen { border-color: var(--text); box-shadow: 0 0 0 1px var(--text); }
.karte.ist-ausgeschlossen .karte__buehne { filter: grayscale(1); }
.karte__buehne { position: relative; display: grid; place-items: center; min-height: 190px; padding: 18px; overflow: hidden; isolation: isolate; }
.karte__info { display: grid; gap: 8px; padding: 16px 18px 18px; border-top: 1px solid var(--linie); align-content: start; }
.karte__info h3 { font-size: 1rem; font-weight: 700; letter-spacing: -0.01em; line-height: 1.25; }
.karte__info p { font-size: .88rem; color: var(--leise); text-wrap: pretty; }
.karte__info .karte__var { font-family: var(--mono); font-size: 11px; letter-spacing: .02em; color: var(--leise); }
.karte__fuss { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 6px 12px; margin-top: 4px; }
.tags { display: flex; flex-wrap: wrap; gap: 4px; padding: 0; list-style: none; }
.tags li { font-family: var(--mono); font-size: 10px; letter-spacing: .08em; text-transform: uppercase; padding: 3px 7px; border-radius: 4px; background: var(--flaeche-2); color: var(--leise); }
.karte__link { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; font-weight: 600; font-size: .9rem; text-decoration: underline; text-underline-offset: .25em; text-decoration-thickness: 1px; }
.karte__link:hover { text-decoration-thickness: 2px; }
.marke-rezept { display: none; font-family: var(--mono); font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; padding: 4px 8px; border-radius: 4px; justify-self: start; }
.ist-empfohlen .marke-rezept--ja { display: inline-block; background: var(--text); color: var(--grund); }
.ist-ausgeschlossen .marke-rezept--nein { display: inline-block; border: 1px dashed var(--linie-2); color: var(--text); }

/* ---------- Rezept-Tabelle ---------- */
.rtab-huelle { background: var(--flaeche); border: 1px solid var(--linie); border-radius: 16px; overflow: hidden; }
.rtab { width: 100%; border-collapse: collapse; font-size: .92rem; }
.rtab th, .rtab td { text-align: left; vertical-align: top; padding: 14px 14px; border-bottom: 1px solid var(--linie); }
.rtab thead th { font-family: var(--mono); font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase; font-weight: 500; color: var(--leise); background: var(--flaeche-2); }
.rtab tbody tr:last-child > * { border-bottom: 0; }
.rtab th[scope=row] { font-weight: 700; width: 22%; }
.rtab th[scope=row] small, .rtab td small { display: block; font-family: var(--mono); font-weight: 400; font-size: 10.5px; letter-spacing: .04em; color: var(--leise); margin-top: 4px; }
.rtab td.stim { width: 16%; color: var(--leise); }
.rtab td.mus { width: 24%; }
.rtab td.mus a { display: inline-flex; align-items: center; min-height: 32px; font-family: var(--mono); font-size: 12px; text-underline-offset: .25em; }
.rtab td.mus ul { list-style: none; padding: 0; display: grid; gap: 2px; }
.rtab td.mus i { font-style: normal; font-family: var(--mono); font-size: 11px; color: var(--leise); margin-left: 4px; }
.rtab td.warum { color: var(--text); text-wrap: pretty; }
.rtab tr.ist-gewaehlt > * { background: color-mix(in srgb, var(--signal) 9%, var(--flaeche)); }

/* ---------- Fuß ---------- */
.fuss { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 12px 30px; padding-block: 34px 44px; border-top: 1px solid var(--linie); color: var(--leise); font-size: .9rem; }

/* ===================== Galerie-Nachbauten (schlank) ===================== */
.g-glas-bild { position: absolute; inset: 0; z-index: -1;
  background: radial-gradient(60% 70% at 78% 18%, #ffe3bd 0 14%, rgb(255 227 189 / 0) 52%),
    repeating-linear-gradient(90deg, rgb(255 244 228 / .0) 0 26px, rgb(255 244 228 / .16) 26px 30px),
    linear-gradient(168deg, #b89574 0%, #7d5f47 42%, #3e3a37 100%); }
.g-glas-bild::after { content: ''; position: absolute; left: 8%; right: 30%; bottom: 0; height: 34%; background: linear-gradient(#5b4a3c, #2e2925); border-radius: 6px 6px 0 0; }
.g-glas { position: relative; min-height: 52px; padding: 0 22px; border-radius: 999px; border: 6px solid transparent; background: rgb(254 242 227 / .16) padding-box; color: #2b2421; font: 600 15px/1 var(--sans); cursor: pointer;
  -webkit-backdrop-filter: blur(12px) saturate(1.6); backdrop-filter: blur(12px) saturate(1.6); box-shadow: inset 1.5px 1.5px 0 rgb(255 255 255 / .78), inset -1px -1px 0 rgb(255 255 255 / .28), 0 10px 30px -12px rgb(0 0 0 / .45); transition: scale 250ms var(--expo), background-color 150ms var(--ui); }
.g-glas span { position: relative; display: block; padding: 12px 18px; margin: 0 -16px; border-radius: 999px; background: rgb(254 242 227 / .62); box-shadow: 0 0 5px 2px rgb(254 242 227 / .62); }
@media (hover: hover) { .g-glas:hover span { background: rgb(254 242 227 / .74); } }
.g-glas:active { scale: .97; }
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) { .g-glas span { background: rgb(254 242 227 / .9); } }
@media (prefers-reduced-transparency: reduce) { .g-glas { backdrop-filter: none; -webkit-backdrop-filter: none; background: #fef2e3; } .g-glas span { background: #fef2e3; box-shadow: none; } }

.g-pfeil { position: relative; display: inline-flex; align-items: center; gap: 14px; min-height: 48px; padding: 4px 4px 4px 22px; border-radius: 999px; background: #e1e3e3; color: #231f20; font: 600 15px/1 var(--sans); text-decoration: none; isolation: isolate; overflow: hidden; }
.g-pfeil::before { content: ''; position: absolute; inset: 0; background: #231f20; clip-path: circle(20px at calc(100% - 24px) 50%); transition: clip-path 175ms cubic-bezier(0.5, 0, 0.75, 0); z-index: -1; }
.g-pfeil__kreis { display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%; color: #ffffff; }
.g-pfeil__text { transition: color 125ms linear; }
.g-pfeil:is(:hover, :focus-visible, .ist-an)::before { clip-path: circle(150% at calc(100% - 24px) 50%); transition: clip-path 250ms cubic-bezier(0.25, 1, 0.5, 1); }
.g-pfeil:is(:hover, :focus-visible, .ist-an) .g-pfeil__text { color: #ffffff; }
.g-pfeil:focus-visible { outline: 2px solid #0022ff; outline-offset: 3px; }

.g-taste { position: relative; border: 0; padding: 0; background: transparent; cursor: pointer; outline-offset: 6px; font: 700 16px/1 'Bricolage Grotesque', var(--sans); }
.g-taste__schatten, .g-taste__kante { position: absolute; inset: 0; border-radius: 14px; }
.g-taste__schatten { background: rgb(20 43 80 / .32); filter: blur(2px); translate: 0 2px; transition: translate 600ms cubic-bezier(0.3, 0.7, 0.4, 1); }
.g-taste__kante { background: linear-gradient(to left, #0b1a33 0%, #142b50 8%, #142b50 92%, #0b1a33 100%); }
.g-taste__front { position: relative; display: block; padding: 18px 26px; border-radius: 14px; background: #ffd60a; color: #142b50; box-shadow: inset 0 0 0 2px #142b50; translate: 0 -4px; transition: translate 600ms cubic-bezier(0.3, 0.7, 0.4, 1); }
@media (hover: hover) { .g-taste:hover .g-taste__front { translate: 0 -6px; transition: translate 250ms cubic-bezier(0.3, 0.7, 0.4, 1.5); } .g-taste:hover .g-taste__schatten { translate: 0 4px; transition: translate 250ms cubic-bezier(0.3, 0.7, 0.4, 1.5); } }
.g-taste:active .g-taste__front, .g-taste.ist-an .g-taste__front { translate: 0 -2px; transition: translate 34ms linear; }
.g-taste:active .g-taste__schatten, .g-taste.ist-an .g-taste__schatten { translate: 0 1px; transition: translate 34ms linear; }
.g-taste:focus-visible { outline: 3px solid #142b50; }

.g-kontur { position: relative; min-height: 52px; padding: 0 30px; border: 1px solid rgb(35 40 47 / .55); background: #ffffff; color: #23282f; font: 500 12px/1 'Instrument Sans', var(--sans); letter-spacing: .08em; text-transform: uppercase; cursor: pointer; transition: background-color 125ms linear; }
.g-kontur svg { position: absolute; inset: -1px; width: calc(100% + 2px); height: calc(100% + 2px); overflow: visible; pointer-events: none; }
.g-kontur rect { width: calc(100% - 1.5px); height: calc(100% - 1.5px); fill: none; stroke: #23282f; stroke-width: 1.5; stroke-dasharray: 1 1; stroke-dashoffset: 1; transition: stroke-dashoffset 310ms cubic-bezier(0.7, 0, 0.84, 0); }
.g-kontur:is(:hover, :focus-visible, .ist-an) rect { stroke-dashoffset: 0; transition: stroke-dashoffset 480ms cubic-bezier(0.16, 1, 0.3, 1); }
.g-kontur:active { background: rgb(35 40 47 / .06); }
.g-kontur:focus-visible { outline: 1px solid #8f7244; outline-offset: 5px; }

.g-gruppe { display: flex; gap: 2px; width: min(100%, 330px); }
.g-gruppe button { flex: 1 1 0; display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-height: 48px; padding: 0 12px; border: 0; border-radius: 8px; background: #e7e3da; color: #1a1a17; font: 600 14px/1 var(--sans); cursor: pointer;
  transition: flex-grow 250ms var(--expo), border-radius 220ms var(--expo), background-color 150ms var(--ui), color 150ms var(--ui); }
.g-gruppe button:first-child { border-radius: 24px 8px 8px 24px; }
.g-gruppe button:last-child { border-radius: 8px 24px 24px 8px; }
.g-gruppe button:active, .g-gruppe button.ist-druck { flex-grow: 1.2; border-radius: 4px; transition-duration: 150ms; }
.g-gruppe button[aria-pressed="true"] { background: #1a1a17; color: #f5f4f1; border-radius: 24px; }
.g-gruppe button svg { width: 0; height: 16px; transition: width 220ms var(--expo); }
.g-gruppe button[aria-pressed="true"] svg { width: 16px; }
.g-gruppe button:focus-visible { outline: 2px solid #1a1a17; outline-offset: 3px; }

.g-zust { position: relative; display: inline-grid; place-items: center; min-height: 50px; padding: 0 26px; border: 0; border-radius: 12px; background: #2a5a3f; color: #fff; font: 600 15px/1 var(--sans); cursor: pointer; transition: background-color 200ms cubic-bezier(0.42, 0, 0.58, 1), scale 150ms cubic-bezier(0.42, 0, 0.58, 1); }
.g-zust > span { grid-area: 1 / 1; display: inline-flex; gap: 8px; align-items: center; transition: opacity 200ms cubic-bezier(0.42, 0, 0.58, 1), scale 200ms cubic-bezier(0.42, 0, 0.58, 1); }
.g-zust .z-laden, .g-zust .z-ok { opacity: 0; scale: .9; }
.g-zust.ist-laden .z-ruhe, .g-zust.ist-ok .z-ruhe { opacity: 0; scale: .9; }
.g-zust.ist-laden .z-laden, .g-zust.ist-ok .z-ok { opacity: 1; scale: 1; }
.g-zust.ist-ok { background: #3d8a5f; }
@media (hover: hover) { .g-zust:hover { background: #1f4a33; } }
.g-zust:active { scale: .97; }
.g-zust .k__dreh { animation-duration: 600ms; animation-play-state: running; }
.g-zust:focus-visible { outline: 2px solid #2a5a3f; outline-offset: 3px; }

.g-druck { min-height: 50px; padding: 0 26px; border: 0; border-radius: 999px; background: #121419; color: #fff; font: 600 15px/1 var(--sans); cursor: pointer; box-shadow: 0 10px 22px -12px rgb(0 0 0 / .5);
  transition: scale 500ms linear(0, 0.044, 0.155, 0.307, 0.476, 0.643, 0.795, 0.923, 1.023, 1.095, 1.139, 1.16, 1.162, 1.15, 1.129, 1.102, 1.075, 1.048, 1.025, 1.006, 0.991, 0.981, 0.976, 0.973, 0.974, 0.977, 0.981, 0.985, 0.99, 0.994, 0.997, 1, 1.002, 1.003, 1.004, 1.004, 1.004, 1.004, 1.003, 1.002, 1), box-shadow 500ms var(--expo); }
.g-druck:active, .g-druck.ist-an { scale: .96; box-shadow: 0 3px 6px -3px rgb(0 0 0 / .5); transition: scale 100ms cubic-bezier(0.45, 0.02, 0.09, 0.98), box-shadow 100ms linear; }
.g-druck:focus-visible { outline: 2px solid #121419; outline-offset: 3px; }

.g-halten { position: relative; overflow: hidden; min-height: 52px; padding: 0 24px; border: 1px solid #0b0b09; border-radius: 999px; background: #fcfcfc; color: #0b0b09; font: 600 15px/1 var(--sans); cursor: pointer; isolation: isolate; touch-action: none; -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
.g-halten::before { content: ''; position: absolute; inset: 0; background: #0b0b09; transform-origin: left; scale: var(--p, 0) 1; z-index: -1; }
.g-halten span { transition: color 150ms var(--ui); }
.g-halten .h-voll { position: absolute; inset: 0; display: grid; place-items: center; color: #fcfcfc; clip-path: inset(0 calc(100% - var(--p, 0) * 100%) 0 0); }
.g-halten.ist-ok { background: #0b0b09; }
.g-halten.ist-ok .h-voll { clip-path: none; }
.g-halten:focus-visible { outline: 2px solid #0b0b09; outline-offset: 3px; }

.g-kopie { display: flex; align-items: center; gap: 4px; padding: 4px 4px 4px 16px; border-radius: 12px; background: #fff; border: 1px solid #d9dbe0; max-width: 100%; }
.g-kopie code { font: 500 13.5px/1 var(--mono); color: #121419; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.g-kopie button { position: relative; display: inline-grid; place-items: center; min-height: 44px; padding: 0 12px; border: 0; border-radius: 9px; background: #eef0f3; color: #121419; font: 600 13.5px/1 var(--sans); cursor: pointer; flex: none; }
.g-kopie button > span { grid-area: 1 / 1; display: inline-flex; gap: 6px; align-items: center; transition: opacity 200ms var(--expo), filter 200ms var(--expo), scale 200ms var(--expo); }
.g-kopie .c-ok { opacity: 0; filter: blur(4px); scale: .6; }
.g-kopie button.ist-ok .c-ruhe { opacity: 0; filter: blur(4px); scale: .6; }
.g-kopie button.ist-ok .c-ok { opacity: 1; filter: none; scale: 1; }
.g-kopie button svg { width: 16px; height: 16px; }
.g-kopie .k__haken path { stroke-dasharray: 1; stroke-dashoffset: 1; }
.g-kopie button.ist-ok .k__haken path { stroke-dashoffset: 0; transition: stroke-dashoffset 300ms var(--expo) 100ms; }
.g-kopie button:focus-visible { outline: 2px solid #121419; outline-offset: 2px; }

.g-magnet { display: grid; place-items: center; width: 108px; height: 108px; border-radius: 50%; border: 0; background: #1c1d22; color: #fff; font: 600 14px/1 var(--sans); cursor: pointer; will-change: translate; }
.g-magnet span { display: block; will-change: translate; }
.g-magnet:focus-visible { outline: 2px solid #1c1d22; outline-offset: 4px; }

.g-fuell { position: relative; display: inline-flex; align-items: center; gap: 10px; min-height: 52px; padding: 0 26px; border: 1.5px solid #1a1a1a; border-radius: 999px; background: transparent; color: #1a1a1a; font: 600 15px/1 var(--sans); cursor: pointer; overflow: hidden; }
.g-fuell__fl { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; gap: 10px; background: #fb6100; color: #1a1a1a; clip-path: circle(0px at var(--x, 50%) var(--y, 50%)); pointer-events: none; }
.g-fuell.ist-voll .g-fuell__fl { clip-path: circle(var(--r, 200px) at var(--x, 50%) var(--y, 50%)); transition: clip-path 600ms var(--expo); }
.g-fuell.ist-raus .g-fuell__fl { transition: clip-path 600ms var(--expo); }
.g-fuell:focus-visible { outline: 2px solid #1a1a1a; outline-offset: 3px; }
.g-fuell:focus-visible .g-fuell__fl { clip-path: circle(150% at 50% 50%); }

.g-form { position: relative; min-height: 56px; padding: 0 34px 0 30px; border: 0; background: transparent; color: #0b0b0b; font: 600 15px/1 'TikTok Sans', var(--sans); cursor: pointer; isolation: isolate; }
.g-form::before { content: ''; position: absolute; inset: 0; background: #ff5a1f; z-index: -1; clip-path: polygon(0 0, 100% 0, 100% 50%, 100% 100%, 0 100%, 0 50%); transition: clip-path 400ms cubic-bezier(0.2, 1, 0.8, 1); }
.g-form span { display: inline-block; transition: translate 400ms cubic-bezier(0.2, 1, 0.8, 1); }
.g-form:is(:hover, :focus-visible, .ist-an)::before { clip-path: polygon(0 0, calc(100% - 26px) 0, 100% 50%, calc(100% - 26px) 100%, 0 100%, 18px 50%); }
.g-form:is(:hover, :focus-visible, .ist-an) span { translate: 8px 0; }
.g-form:focus-visible { outline: 2px solid #0b0b0b; outline-offset: 4px; }

.g-goo { position: relative; display: inline-grid; place-items: center; border: 0; border-radius: 999px; background: #0b0b0b; padding: 0; cursor: pointer; color: #fff; font: 600 15px/1 'TikTok Sans', var(--sans); }
.g-goo__form { position: absolute; inset: 0; filter: url(#g-goo); }
.g-goo__form i { position: absolute; background: #0b0b0b; border-radius: 999px; }
.g-goo__form .pille { inset: 0; }
.g-goo__form .tropfen { width: 44px; height: 44px; top: 6px; right: 6px; transition: translate 600ms cubic-bezier(0.16, 1, 0.3, 1); }
.g-goo__text { position: relative; display: block; padding: 20px 76px 20px 28px; }
.g-goo__icon { position: absolute; top: 6px; right: 6px; width: 44px; height: 44px; display: grid; place-items: center; transition: translate 600ms cubic-bezier(0.16, 1, 0.3, 1); }
.g-goo__icon svg { width: 18px; height: 18px; }
.g-goo:is(:hover, :focus-visible, .ist-an) .tropfen, .g-goo:is(:hover, :focus-visible, .ist-an) .g-goo__icon { translate: 58px 0; }
.g-goo:focus-visible { outline: 2px solid #0b0b0b; outline-offset: 4px; border-radius: 999px; }

.g-roll { display: inline-flex; align-items: center; min-height: 52px; padding: 0 26px; border: 0; border-radius: 999px; background: #0b0b0b; color: #f2f2f2; font: 600 16px/1.2 'TikTok Sans', var(--sans); cursor: pointer; }
.g-roll__maske { display: inline-flex; overflow: hidden; height: 1lh; }
.g-roll__z { display: inline-block; position: relative; white-space: pre; transition: translate 800ms cubic-bezier(0.16, 1, 0.3, 1); transition-delay: calc(var(--i) * 12ms); }
.g-roll__z::after { content: attr(data-z); position: absolute; left: 0; top: 100%; }
.g-roll:is(:hover, :focus-visible, .ist-an) .g-roll__z { translate: 0 -100%; }
.g-roll:focus-visible { outline: 2px solid #0b0b0b; outline-offset: 3px; }

.g-squash { display: inline-flex; align-items: center; gap: 12px; min-height: 52px; padding: 0 22px 0 26px; border: 0; border-radius: 12px; background: #293e3a; color: #f0ece0; font: 600 15px/1 var(--sans); cursor: pointer; }
.g-squash svg { width: 24px; height: 24px; overflow: visible; }
.g-squash .schaft { transform-box: fill-box; transform-origin: left center; transition: scale 200ms cubic-bezier(0.5, 1, 0.89, 1); }
.g-squash .spitze { transition: translate 200ms cubic-bezier(0.5, 1, 0.89, 1); }
.g-squash:is(:hover, :focus-visible, .ist-an) .schaft { scale: 1.6 1; }
.g-squash:is(:hover, :focus-visible, .ist-an) .spitze { translate: 5px 0; }
.g-squash:focus-visible { outline: 2px solid #293e3a; outline-offset: 3px; }

@property --winkel { syntax: '<angle>'; inherits: false; initial-value: 0deg; }
.g-ring { --ring: linear-gradient(180deg, #b9c5ff 0%, #5d6a9a 100%); min-height: 52px; padding: 0 28px; border: 1.5px solid transparent; border-radius: 999px; background: linear-gradient(#141414, #141414) padding-box, var(--ring) border-box; color: #ffffff; font: 600 15px/1 var(--sans); cursor: pointer; }
.g-ring:is(:hover, :focus-visible, .ist-an) { --ring: conic-gradient(from var(--winkel), #3a3f55 0% 55%, #7491ff 72%, #e6ebff 84% 88%, #3a3f55 98% 100%); animation: g-drehen 3000ms linear infinite; }
@keyframes g-drehen { to { --winkel: 360deg; } }
.g-ring:focus-visible { outline: 2px solid #141414; outline-offset: 3px; }

.g-korn { position: relative; min-height: 52px; padding: 0 28px; border: 0; border-radius: 10px; overflow: hidden; isolation: isolate; color: #fff; font: 600 15px/1 var(--sans); cursor: pointer;
  background-color: #2b4a38; background-image: linear-gradient(100deg, #2b4a38, #4b6b3a 55%, #2b4a38); background-size: 200% 100%; transition: background-position 600ms var(--expo); }
.g-korn::before { content: ''; position: absolute; inset: 0; z-index: -1; opacity: .55; mix-blend-mode: overlay; background-size: 160px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); }
.g-korn span { position: relative; }
.g-korn:is(:hover, .ist-an) { background-position: 100% 0; }
.g-korn:focus-visible { outline: 2px solid #2b4a38; outline-offset: 3px; }

.g-porz { min-height: 52px; padding: 0 28px; border: 0; border-radius: 14px; background: linear-gradient(#fbf9f6, #efebe5); color: #121010; font: 600 15px/1 var(--sans); cursor: pointer;
  box-shadow: inset 0 1px 0 0 rgb(255 255 255 / .9), 0 0 0 1px rgb(18 16 16 / .1), 0 1px 2px rgb(18 16 16 / .08), 0 10px 20px -10px rgb(18 16 16 / .3); transition: translate 180ms cubic-bezier(0, 0, 0.58, 1), box-shadow 180ms cubic-bezier(0, 0, 0.58, 1); }
.g-porz:active, .g-porz.ist-an { translate: 0 2px; box-shadow: inset 0 1px 2px 0 rgb(18 16 16 / .14), 0 0 0 1px rgb(18 16 16 / .12), 0 1px 1px rgb(18 16 16 / .06); transition-duration: 100ms; }
.g-porz:focus-visible { outline: 2px solid #121010; outline-offset: 3px; }

.g-herz { position: relative; display: grid; place-items: center; width: 52px; height: 52px; border-radius: 50%; border: 1px solid #d9d4cc; background: #fff; color: #3b2f2f; cursor: pointer; }
.g-herz svg { width: 24px; height: 24px; }
.g-herz path { fill: transparent; stroke: currentColor; stroke-width: 1.8; transition: fill 150ms var(--ui); }
.g-herz[aria-pressed="true"] { color: #c0392b; border-color: #c0392b; }
.g-herz[aria-pressed="true"] path { fill: currentColor; }
.g-herz[aria-pressed="true"] svg { animation: g-pop 350ms cubic-bezier(0.2, 0, 0, 1); }
.g-herz::before { content: ''; position: absolute; inset: -1px; border-radius: 50%; border: 2px solid #c0392b; opacity: 0; pointer-events: none; }
.g-herz.ist-burst::before { animation: g-ring 400ms cubic-bezier(0, 0, 0.58, 1); }
@keyframes g-pop { 0% { scale: 0; } 40% { scale: 1.25; } 100% { scale: 1; } }
@keyframes g-ring { 0% { scale: 1; opacity: .9; } 100% { scale: 1.6; opacity: 0; border-width: .5px; } }
.g-herz:focus-visible { outline: 2px solid #3b2f2f; outline-offset: 3px; }
.g-herz-zeile { display: flex; align-items: center; gap: 14px; }
.g-herz-zeile small { font-family: var(--mono); font-size: 12px; color: #3b2f2f; }

.g-menue { display: inline-flex; align-items: center; gap: 12px; min-height: 48px; padding: 0 18px 0 16px; border: 1px solid #231f20; border-radius: 999px; background: #fff; color: #231f20; font: 600 14px/1.2 var(--sans); cursor: pointer; }
.g-menue__icon { position: relative; width: 18px; height: 12px; }
.g-menue__icon i { position: absolute; left: 0; right: 0; height: 1.5px; background: currentColor; transition: translate 400ms var(--expo), rotate 400ms var(--expo); }
.g-menue__icon i:first-child { top: 2px; } .g-menue__icon i:last-child { bottom: 2px; }
.g-menue[aria-expanded="true"] .g-menue__icon i:first-child { translate: 0 3.25px; rotate: 45deg; }
.g-menue[aria-expanded="true"] .g-menue__icon i:last-child { translate: 0 -3.25px; rotate: -45deg; }
.g-menue__label { display: grid; overflow: hidden; height: 1lh; }
.g-menue__label span { grid-area: 1 / 1; transition: translate 400ms var(--expo), visibility 0s linear 0s; }
.g-menue__label span:last-child { translate: 0 100%; visibility: hidden; transition-delay: 0s, 400ms; }
.g-menue[aria-expanded="true"] .g-menue__label span:first-child { visibility: hidden; transition-delay: 0s, 400ms; }
.g-menue[aria-expanded="true"] .g-menue__label span:last-child { visibility: visible; transition-delay: 0s, 0s; }
.g-menue[aria-expanded="true"] .g-menue__label span:first-child { translate: 0 -100%; }
.g-menue[aria-expanded="true"] .g-menue__label span:last-child { translate: 0 0; }
.g-menue:focus-visible { outline: 2px solid #231f20; outline-offset: 3px; }

.g-kuend { display: grid; gap: 10px; justify-items: center; text-align: center; width: 100%; }
.g-kuend p { font-size: .85rem; color: #3a3a3a; max-width: 28ch; }
.g-kuend .reihe { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
.g-kuend button { min-height: 44px; padding: 0 18px; border-radius: 8px; font: 600 14px/1 var(--sans); cursor: pointer; }
.g-kuend .eins { border: 1.5px solid #1a1a1a; background: #fff; color: #1a1a1a; }
.g-kuend .zwei { border: 0; background: #b3261e; color: #fff; }
.g-kuend .ab { border: 0; background: none; color: #1a1a1a; text-decoration: underline; text-underline-offset: .25em; }
.g-kuend button:focus-visible { outline: 2px solid #1a1a1a; outline-offset: 2px; }
.g-kuend [hidden] { display: none; }

.g-fok-reihe { display: flex; flex-wrap: wrap; justify-content: center; gap: 14px; }
.g-fok { min-height: 48px; padding: 0 20px; border: 1.5px solid #0b0b09; border-radius: 8px; background: #ffffff; color: #0b0b09; font: 600 15px/1 var(--sans); cursor: pointer; outline: 0 solid #0b0b09; transition: background-color 160ms cubic-bezier(0.165, 0.84, 0.44, 1), box-shadow 160ms cubic-bezier(0.165, 0.84, 0.44, 1); }
.g-fok:focus-visible, .g-fok.ist-fokus { background: #ffdd00; box-shadow: inset 0 -4px 0 #0b0b09; outline: 2px solid #0b0b09; outline-offset: 2px; }

.g-pixel { position: relative; overflow: hidden; min-height: 52px; padding: 0 28px; border: 1.5px solid #0b0b0b; border-radius: 0; background: #efede9; color: #0b0b0b; font: 600 15px/1 var(--sans); cursor: pointer; isolation: isolate; }
.g-pixel__raster { position: absolute; inset: 0; display: grid; grid-template-columns: repeat(auto-fill, 8px); grid-auto-rows: 8px; z-index: -1; }
.g-pixel__raster i { background: #0b0b0b; opacity: 0; transition: opacity 0s linear var(--d, 0ms); }
.g-pixel.ist-voll .g-pixel__raster i, .g-pixel:focus-visible .g-pixel__raster i { opacity: 1; }
.g-pixel__text { position: relative; transition: color 0s linear 0ms; }
.g-pixel.ist-voll .g-pixel__text, .g-pixel:focus-visible .g-pixel__text { color: #ffffff; transition-delay: 240ms; }
.g-pixel:focus-visible .g-pixel__text { transition-delay: 0ms; }
.g-pixel:focus-visible { outline: 2px solid #0b0b0b; outline-offset: 3px; }

.g-ecke { min-height: 52px; padding: 0 30px; border: 0; border-radius: 14px; background: #2a3a8f; color: #ffffff; font: 600 15px/1 var(--sans); cursor: pointer; transition: background-color 300ms cubic-bezier(0.37, 0, 0.63, 1), border-radius 300ms cubic-bezier(0.37, 0, 0.63, 1); }
.g-ecke:is(:hover, :focus-visible, .ist-an) { background: #1f2c70; border-radius: 22px; }
@supports (corner-shape: squircle) {
  .g-ecke { border-radius: 18px; corner-shape: bevel; transition: background-color 300ms cubic-bezier(0.37, 0, 0.63, 1), corner-shape 300ms cubic-bezier(0.37, 0, 0.63, 1); }
  .g-ecke:is(:hover, :focus-visible, .ist-an) { border-radius: 18px; corner-shape: squircle; }
}
.g-ecke:focus-visible { outline: 2px solid #2a3a8f; outline-offset: 3px; }

/* ---------- Telefon und schmal ---------- */
@media (max-width: 1100px) {
  .typen { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .regeln { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 900px) {
  .held, .abschnitt__kopf, .kontexte, .tokens { grid-template-columns: minmax(0, 1fr); }
  .welten__raster { grid-template-columns: minmax(0, 1fr); }
  .rtab thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .rtab, .rtab tbody, .rtab tr, .rtab th, .rtab td { display: block; width: auto !important; }
  .rtab tr { padding: 16px 16px; border-bottom: 1px solid var(--linie); }
  .rtab tbody tr:last-child { border-bottom: 0; }
  .rtab th, .rtab td { padding: 4px 0; border: 0; }
  .rtab td[data-th]::before { content: attr(data-th); display: block; font-family: var(--mono); font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: var(--leise); margin-top: 8px; }
}
@media (max-width: 640px) {
  .typen { grid-template-columns: minmax(0, 1fr); }
  .typ__groessen { min-height: 0; }
  .regeln { grid-template-columns: minmax(0, 1fr); }
  .spezimen__werte { grid-template-columns: minmax(0, 1fr); }
  .zeile2 { grid-template-columns: minmax(0, 1fr); }
  .aktionen .k--primaer { margin-left: 0; order: -1; width: 100%; }
  .aktionen > .k { flex: 1 1 auto; }
  .filter output, .pult output { margin-left: 0; }
  .treffer-bild { grid-template-columns: minmax(0, 1fr); }
  .kopf nav ul { gap: 0 16px; }
}
@media (max-width: 360px) {
  .k { white-space: normal; text-align: center; }
  .held h1 { font-size: 2.2rem; }
}
@media (hover: none) {
  .pult button { padding: 10px 12px; }
}

/* ---------- Vorschau ---------- */
.vorschau body { overflow: hidden; }
.vorschau .pult, .vorschau main > .abschnitt, .vorschau .fuss, .vorschau .held__fakten { display: none; }
.vorschau .held { padding-block: 40px 30px; }
.vorschau:root[data-v="rezepte"] .held__intro { display: none; }
.vorschau:root[data-v="rezepte"] .held { padding-block: 32px 22px; }
.vorschau .kopf nav { display: none; }

/* ---------- Reduzierte Bewegung ---------- */
.reduziert .k { transition-property: background-color, color, border-color, outline-width, outline-offset; scale: none !important; }
.reduziert .k__stapel > * { translate: none !important; }
.reduziert .k__dreh { animation: none; border-right-color: currentColor; border-style: dotted; }
.reduziert .k.ist-erfolg .k__haken path { transition: none; }
.reduziert :is(.g-pfeil, .g-taste, .g-kontur, .g-gruppe, .g-zust, .g-druck, .g-kopie, .g-fuell, .g-form, .g-goo, .g-roll, .g-squash, .g-korn, .g-porz, .g-herz, .g-menue, .g-glas) *,
.reduziert .g-pixel__raster i { transition-delay: 0ms !important; }
.reduziert :is(.g-ecke, .g-fok, .g-pfeil, .g-taste, .g-kontur, .g-gruppe button, .g-zust, .g-druck, .g-fuell, .g-form, .g-goo, .g-roll, .g-squash, .g-korn, .g-porz, .g-herz, .g-menue, .g-glas, .g-ring),
.reduziert .g-pfeil::before, .reduziert .g-form::before { transition-duration: .01ms !important; animation: none !important; }
.reduziert .g-taste__front, .reduziert .g-taste__schatten { translate: 0 -2px !important; }
.reduziert .g-taste__schatten { translate: 0 1px !important; }
.reduziert :is(.g-druck, .g-zust, .g-glas, .g-porz):active { scale: none; translate: none; }
.reduziert .g-gruppe button { flex-grow: 1 !important; }
.reduziert .g-roll__z, .reduziert .g-menue__label span { transition: none !important; }
.reduziert .g-ring { animation: none !important; }
.reduziert .g-goo .tropfen, .reduziert .g-goo__icon { translate: none !important; }
.reduziert .g-squash .schaft, .reduziert .g-squash .spitze { scale: none !important; translate: none !important; }
.reduziert .g-zust .k__dreh, .reduziert .g-kopie .k__dreh { animation: none; }
.reduziert .g-herz svg, .reduziert .g-herz::before { animation: none !important; }

/* Windows-Kontrastmodus */
@media (forced-colors: active) {
  button, [role=button], [role=tab], [role=switch], input, select, textarea { border: 1px solid ButtonText !important; }
  .k { border-style: solid; }
  .k:focus-visible, .k.ist-fokus { outline-color: Highlight; }
  .k[aria-disabled="true"] { color: GrayText; border-color: GrayText !important; }
  .g-pfeil::before, .g-fuell__fl, .g-form::before { forced-color-adjust: none; }
}

</style>
</head>
<body>
<svg width="0" height="0" style="position:absolute" aria-hidden="true" focusable="false">
  <defs>
    <filter id="g-goo" x="-20%" y="-60%" width="140%" height="220%" color-interpolation-filters="sRGB">
      <feGaussianBlur in="SourceGraphic" stdDeviation="8" result="b"/>
      <feColorMatrix in="b" mode="matrix" values="1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 19 -9" result="goo"/>
      <feComposite in="SourceGraphic" in2="goo" operator="atop"/>
    </filter>
  </defs>
</svg>

<div class="pult mono" role="group" aria-label="Demo-Steuerung">
  <div class="pult__gruppe" role="group" aria-label="Variante">
    <span>Variante</span>
    <button type="button" data-variante="hell" aria-pressed="true">Hell</button>
    <button type="button" data-variante="dunkel" aria-pressed="false">Dunkel</button>
    <button type="button" data-variante="rezepte" aria-pressed="false">Rezept-Welten</button>
  </div>
  <div class="pult__gruppe" role="group" aria-label="Hilfslinien">
    <button type="button" id="treffer-schalter" aria-pressed="false">Trefferflächen zeigen</button>
  </div>
  <output>System 2.3 · Stand 02.11.2026</output>
</div>

<header class="rahmen kopf">
  <a class="marke" href="#oben" aria-label="Quermaß, Interface-Systeme, zum Seitenanfang"><b>Quer<i>maß</i></b><span class="label">Interface-Systeme · Marburg</span></a>
  <nav aria-label="Kapitel">
    <ul class="mono">
      <li><a href="#hierarchie"><span>01</span>Hierarchie</a></li>
      <li><a href="#tokens"><span>02</span>Tokens</a></li>
      <li><a href="#zustaende"><span>03</span>Zustände</a></li>
      <li><a href="#galerie"><span>04</span>Galerie</a></li>
      <li><a href="#rezepte"><span>05</span>Rezepte</a></li>
    </ul>
  </nav>
</header>

<main id="oben">
  <section class="rahmen held" aria-labelledby="titel">
    <div class="held__text">
      <p class="label"><span>Komponente 04</span><span>Button</span></p>
      <h1 id="titel"><span>Fünf Typen.</span> <span>Sieben Zustände.</span> <em>Ein Satz Tokens.</em></h1>
      <p class="held__intro">Unser Button-System für Kundenseiten: Hierarchie, Maße, Bewegung je Zustand und die Regeln für Trefferfläche und Kontrast. Darunter alle Button-Muster des Fundus zum Ausprobieren und welches zu welchem Rezept passt.</p>
      <ul class="held__fakten">
        <li><b>44 px</b><span class="label">Trefferfläche</span></li>
        <li><b>4,5 : 1</b><span class="label">Label-Kontrast</span></li>
        <li><b>1</b><span class="label">Primärer je Ansicht</span></li>
        <li><b>28</b><span class="label">Rezepte zugeordnet</span></li>
      </ul>
    </div>

    <figure class="spezimen" aria-labelledby="sp-titel">
      <div class="spezimen__kopf">
        <p class="label" id="sp-titel">Spezimen · Primär · L</p>
        <p class="label">Zeigen, tabben, klicken</p>
      </div>
      <div class="spezimen__feld">
        <button class="k k--primaer k--l" id="spez" type="button">
          <span class="k__stapel">
            <span class="k__ruhe">Angebot anfragen <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
            <span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Wird gesendet</span>
            <span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Angefragt</span>
          </span>
        </button>
        <svg class="mass" id="mass" aria-hidden="true"></svg>
      </div>
      <ol class="spezimen__zustaende" aria-label="Zustände des Spezimens">
        <li data-z="ruhe" class="ist-an">Ruhe</li><li data-z="hover">Hover</li><li data-z="fokus">Fokus</li><li data-z="druck">Druck</li><li data-z="aus">Deaktiviert</li><li data-z="laden">Laden</li><li data-z="erfolg">Erfolg</li>
      </ol>
      <div class="spezimen__werte">
        <div><span class="label">Zustand</span><output id="w-zustand">Ruhe</output></div>
        <div><span class="label">Bewegung</span><output id="w-bewegung">keine</output></div>
        <div><span class="label">Kontrast</span><output id="w-kontrast">–</output></div>
      </div>
      <p class="nur-sr" role="status" id="spez-status"></p>
    </figure>
  </section>

  <section class="rahmen welten" aria-labelledby="welten-titel">
    <div class="welten__wahl">
      <h2 class="label" id="welten-titel">Dieselben Buttons in drei Rezepten</h2>
      <div role="group" aria-label="Rezept-Welt für die ganze Seite">
        <button type="button" data-welt="buehne" aria-pressed="true">Studio-Bühne</button>
        <button type="button" data-welt="manufaktur" aria-pressed="false">Manufaktur-Stille</button>
        <button type="button" data-welt="fahrschule" aria-pressed="false">Fahrschule</button>
      </div>
    </div>
    <div class="welten__raster">
      <article class="welt welt--buehne" data-welt-panel="buehne" aria-label="Studio-Bühne">
        <div class="welt__kopf"><h3>Studio-Bühne</h3><span>kreativstudio-buehne</span></div>
        <div class="welt__knoepfe">
          <button class="k k--primaer" type="button" data-demo-laden><span class="k__stapel"><span class="k__ruhe">Showreel ansehen</span><span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Einen Moment</span><span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Erledigt</span></span></button>
          <button class="k k--sekundaer" type="button">Projekt anfragen</button>
        </div>
        <div class="welt__knoepfe">
          <button class="k k--tertiaer" type="button">Später</button>
          <button class="k k--icon" type="button" aria-label="Teilen" data-tipp="Teilen"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 15V4M8 8l4-4 4 4M5 13v5a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-5"/></svg></button>
          <button class="k k--gefahr k--s" type="button">Termin absagen</button>
        </div>
        <p class="welt__notiz">Schwarz, Weiß, ein Signalton · Pille · 400 ms expo.out</p>
      </article>
      <article class="welt welt--manufaktur" data-welt-panel="manufaktur" aria-label="Manufaktur-Stille">
        <div class="welt__kopf"><h3>Manufaktur-Stille</h3><span>luxus-manufaktur-stille</span></div>
        <div class="welt__knoepfe">
          <button class="k k--primaer" type="button" data-demo-laden><span class="k__stapel"><span class="k__ruhe">Termin vereinbaren</span><span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Einen Moment</span><span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Erledigt</span></span></button>
          <button class="k k--sekundaer" type="button">Kollektion</button>
        </div>
        <div class="welt__knoepfe">
          <button class="k k--tertiaer" type="button">Später</button>
          <button class="k k--icon" type="button" aria-label="Teilen" data-tipp="Teilen"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 15V4M8 8l4-4 4 4M5 13v5a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-5"/></svg></button>
          <button class="k k--gefahr k--s" type="button">Termin absagen</button>
        </div>
        <p class="welt__notiz">Anthrazit, Weiß, Messing nur als Linie · eckig · 250 ms</p>
      </article>
      <article class="welt welt--fahrschule" data-welt-panel="fahrschule" aria-label="Fahrschule">
        <div class="welt__kopf"><h3>Fahrschule</h3><span>fahrschule-freundlich-buchbar</span></div>
        <div class="welt__knoepfe">
          <button class="k k--primaer" type="button" data-demo-laden><span class="k__stapel"><span class="k__ruhe">Jetzt anmelden</span><span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Einen Moment</span><span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Erledigt</span></span></button>
          <button class="k k--sekundaer" type="button">Preise ansehen</button>
        </div>
        <div class="welt__knoepfe">
          <button class="k k--tertiaer" type="button">Später</button>
          <button class="k k--icon" type="button" aria-label="Teilen" data-tipp="Teilen"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 15V4M8 8l4-4 4 4M5 13v5a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-5"/></svg></button>
          <button class="k k--gefahr k--s" type="button">Termin absagen</button>
        </div>
        <p class="welt__notiz">Creme, Navy, Kennzeichen-Gelb · 14 px · Überschwinger</p>
      </article>
    </div>
  </section>

  <!-- ===================== 01 Hierarchie ===================== -->
  <section class="rahmen abschnitt" id="hierarchie" aria-labelledby="h-hier">
    <div class="abschnitt__kopf">
      <h2 id="h-hier"><span class="label">01 · Hierarchie</span>Wer wie laut sein darf</h2>
      <p>Die Rangfolge entsteht über Fläche, Kante und Unterstrich, nicht über Größe. Je Ansicht gibt es genau eine primäre Handlung. Labels beginnen mit dem Verb und nennen die Folge: „Angebot senden“, nicht „OK“.</p>
    </div>
    <div class="typen">
      <article class="typ">
        <h3>Primär <span>p-*</span></h3>
        <div class="typ__groessen">
          <button class="k k--primaer k--l" type="button">Termin anfragen</button>
          <button class="k k--primaer" type="button">Termin anfragen</button>
          <button class="k k--primaer k--s" type="button">Termin anfragen</button>
        </div>
        <p><b>Eine je Ansicht.</b> Die Handlung, für die die Seite gebaut ist. Volle Fläche im Signalton.</p>
      </article>
      <article class="typ">
        <h3>Sekundär <span>s-*</span></h3>
        <div class="typ__groessen">
          <button class="k k--sekundaer k--l" type="button">Unterlagen laden</button>
          <button class="k k--sekundaer" type="button">Unterlagen laden</button>
          <button class="k k--sekundaer k--s" type="button">Unterlagen laden</button>
        </div>
        <p><b>Gleichwertige Alternative.</b> Fläche wie der Grund, Kante mindestens 3 : 1. Nie zwei primäre nebeneinander.</p>
      </article>
      <article class="typ">
        <h3>Tertiär <span>t-*</span></h3>
        <div class="typ__groessen">
          <button class="k k--tertiaer k--l" type="button">Abbrechen</button>
          <button class="k k--tertiaer" type="button">Mehr erfahren</button>
          <button class="k k--tertiaer k--s" type="button">Filter zurücksetzen</button>
        </div>
        <p><b>Nebenhandlung als Text.</b> Unterstrich statt Kante, Fläche erst beim Hover. Trefferfläche bleibt 44 px.</p>
      </article>
      <article class="typ">
        <h3>Icon <span>i-*</span></h3>
        <div class="typ__groessen icons">
          <button class="k k--icon k--l" type="button" aria-label="Teilen" data-tipp="Teilen"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 15V4M8 8l4-4 4 4M5 13v5a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-5"/></svg></button>
          <button class="k k--icon" type="button" aria-label="Duplizieren" data-tipp="Duplizieren"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2"/><path d="M16 8V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h2"/></svg></button>
          <button class="k k--icon k--s" type="button" aria-label="Mehr Optionen" data-tipp="Mehr Optionen"><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><circle cx="5.5" cy="12" r="1.7"/><circle cx="12" cy="12" r="1.7"/><circle cx="18.5" cy="12" r="1.7"/></svg></button>
        </div>
        <p><b>Nur vertraute Symbole.</b> Immer mit aria-label, Tooltip beim Verweilen und bei Fokus. Klein sichtbar, 44 px tastbar.</p>
      </article>
      <article class="typ">
        <h3>Gefahr <span>g-*</span></h3>
        <div class="typ__groessen">
          <button class="k k--gefahr k--l" type="button">Archiv löschen</button>
          <button class="k k--gefahr" type="button">Vertrag kündigen</button>
          <button class="k k--gefahr k--s" type="button">Eintrag entfernen</button>
        </div>
        <p><b>Folgen, die bleiben.</b> Verb nennt die Folge, danach eine Rückfrage. Nie nur über Rot unterscheiden.</p>
      </article>
    </div>

    <div class="kontexte">
      <article class="kontext" aria-labelledby="kx1">
        <div class="kontext__titel"><h3 id="kx1">Im Formular</h3><span class="label">primär · sekundär · tertiär · deaktiviert · laden</span></div>
        <form class="formular" id="anfrage" novalidate>
          <div class="zeile2">
            <div class="feld"><label for="f-name">Name</label><input id="f-name" name="name" autocomplete="name" value="Henrike Albers"></div>
            <div class="feld"><label for="f-mail">E-Mail</label><input id="f-mail" name="mail" type="email" autocomplete="email" value="albers@lahnwerk-moebel.de"></div>
          </div>
          <div class="feld"><label for="f-art">Projekt</label>
            <select id="f-art" name="art"><option>Website mit Shop</option><option>Designsystem für ein bestehendes Produkt</option><option>Barrierefreiheit prüfen und nachbessern</option></select></div>
          <label class="haken"><input type="checkbox" id="f-ok"> <span>Ich habe die Projektbedingungen gelesen.</span></label>
          <div class="aktionen">
            <button class="k k--tertiaer" type="reset">Abbrechen</button>
            <button class="k k--sekundaer" type="button" id="entwurf">Entwurf speichern</button>
            <button class="k k--primaer" type="submit" id="senden" aria-disabled="true" aria-describedby="senden-hinweis">
              <span class="k__stapel">
                <span class="k__ruhe">Angebot senden</span>
                <span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Wird gesendet</span>
                <span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Gesendet</span>
              </span>
            </button>
          </div>
          <p class="hinweis" id="senden-hinweis">Senden geht, sobald die Projektbedingungen bestätigt sind.</p>
          <p class="status" role="status" id="anfrage-status"></p>
        </form>
      </article>

      <article class="kontext" aria-labelledby="kx2">
        <div class="kontext__titel"><h3 id="kx2">In der Liste</h3><span class="label">icon · gefahr mit Rückfrage</span></div>
        <ul class="liste-projekte">
          <li><div><b>Lahnwerk Möbel</b><small>Shop · Entwurf 3 · geändert heute</small></div>
            <div class="werkzeuge"><button class="k k--icon k--s" type="button" aria-label="Teilen" data-tipp="Teilen"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 15V4M8 8l4-4 4 4M5 13v5a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-5"/></svg></button><button class="k k--icon k--s" type="button" aria-label="Duplizieren" data-tipp="Duplizieren"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2"/><path d="M16 8V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h2"/></svg></button></div></li>
          <li><div><b>Hofgut Elbenrod</b><small>Buchung · live seit 14.10.2026</small></div>
            <div class="werkzeuge"><button class="k k--icon k--s" type="button" aria-label="Teilen" data-tipp="Teilen"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 15V4M8 8l4-4 4 4M5 13v5a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-5"/></svg></button><button class="k k--icon k--s" type="button" aria-label="Duplizieren" data-tipp="Duplizieren"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2"/><path d="M16 8V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h2"/></svg></button></div></li>
          <li><div><b>Archiv 2019 bis 2022</b><small>27 Projekte · nur lesend</small></div>
            <div class="werkzeuge"><button class="k k--gefahr k--s" type="button" id="loeschen" aria-expanded="false" aria-controls="rueckfrage">Archiv löschen</button></div></li>
        </ul>
        <div class="bestaetigung" id="rueckfrage" hidden>
          <p><b>Archiv wirklich löschen?</b> 27 Projekte mit allen Dateien. Das lässt sich nicht rückgängig machen.</p>
          <div class="reihe">
            <button class="k k--sekundaer" type="button" id="behalten">Behalten</button>
            <button class="k k--gefahr" type="button" id="endgueltig">Endgültig löschen</button>
          </div>
        </div>
        <p class="status" role="status" id="liste-status"></p>
      </article>
    </div>
  </section>

  <!-- ===================== 02 Tokens ===================== -->
  <section class="rahmen abschnitt" id="tokens" aria-labelledby="h-tok">
    <div class="abschnitt__kopf">
      <h2 id="h-tok"><span class="label">02 · Tokens</span>Maß, Form, Bewegung</h2>
      <p>Die Werte unten liest die Seite direkt aus den CSS-Variablen der Komponente. Ein Rezept setzt nur diese Tokens neu, das Markup bleibt gleich. Unter „Rezept-Welten“ sieht man, wie sie sich ändern.</p>
    </div>
    <div class="tokens">
      <div class="tafel">
        <h3>Maß und Form <span class="label" data-welt-name>Quermaß</span></h3>
        <div class="ttab-huelle" role="region" aria-label="Tokens für Maß und Form" tabindex="0"><table class="ttab">
          <thead><tr><th scope="col">Token</th><th scope="col">Wert</th><th scope="col">Wofür</th></tr></thead>
          <tbody>
            <tr><td>--b-h-s / m / l</td><td class="wert" data-tok="--b-h-s,--b-h-m,--b-h-l"></td><td>Höhe der drei Größen</td></tr>
            <tr><td>--b-px-s / m / l</td><td class="wert" data-tok="--b-px-s,--b-px-m,--b-px-l"></td><td>Innenabstand links und rechts</td></tr>
            <tr><td>--b-gap</td><td class="wert" data-tok="--b-gap"></td><td>Abstand Icon zu Label</td></tr>
            <tr><td>--b-abstand</td><td class="wert" data-tok="--b-abstand"></td><td>Abstand zwischen Buttons</td></tr>
            <tr><td>--b-radius</td><td class="wert" data-tok="--b-radius"></td><td>Ecken, Icon-Button gleich</td></tr>
            <tr><td>--b-kante</td><td class="wert" data-tok="--b-kante"></td><td>Rahmenstärke aller Typen</td></tr>
            <tr><td>--b-schrift</td><td class="wert" data-tok="--b-schrift"></td><td>Schrift des Labels</td></tr>
            <tr><td>--b-groesse-s / m / l</td><td class="wert" data-tok="--b-groesse-s,--b-groesse-m,--b-groesse-l"></td><td>Schriftgröße je Größe</td></tr>
            <tr><td>--b-fokus-*</td><td class="wert" data-tok="--b-fokus-breite,--b-fokus-versatz"></td><td>Fokusring Breite und Versatz</td></tr>
            <tr><td>--b-druck</td><td class="wert" data-tok="--b-druck"></td><td>Skalierung beim Drücken</td></tr>
          </tbody>
        </table></div>
        <div class="treffer-bild" aria-label="Trefferflächen">
          <figure><div class="bsp"><span class="zone" style="width:88px;height:44px"></span><span class="knopf-bsp" style="width:80px;height:36px"></span></div><figcaption>S: 36 px sichtbar, 44 px tastbar</figcaption></figure>
          <figure><div class="bsp"><span class="zone" style="width:44px;height:44px"></span><span class="knopf-bsp" style="width:36px;height:36px;background:var(--i-bg-d)"></span></div><figcaption>Icon S: ::after inset −4 px</figcaption></figure>
          <figure><div class="bsp"><span class="zone" style="width:112px;height:44px"></span><span style="position:relative;font-size:13px;font-weight:600;text-decoration:underline;text-underline-offset:.25em">Mehr erfahren</span></div><figcaption>Tertiär: Text, Zone 44 px</figcaption></figure>
        </div>
      </div>
      <div class="tafel">
        <h3>Bewegung je Zustand <span class="label" data-welt-name>Quermaß</span></h3>
        <div class="ttab-huelle" role="region" aria-label="Bewegung je Zustand" tabindex="0"><table class="ttab">
          <thead><tr><th scope="col">Zustand</th><th scope="col">Was</th><th scope="col">Dauer</th><th scope="col">Kurve</th><th scope="col">Reduziert</th></tr></thead>
          <tbody>
            <tr><td>Hover</td><td>Fläche, Schrift, Kante</td><td class="wert" data-tok="--dauer-hover"></td><td class="wert" data-kurve="--kurve-hover"></td><td>bleibt (Farbe)</td></tr>
            <tr><td>Fokus</td><td>Ring wächst auf Versatz</td><td class="wert" data-tok="--dauer-fokus"></td><td class="wert" data-kurve="--kurve-fokus"></td><td>Ring ohne Übergang</td></tr>
            <tr><td>Druck ein</td><td>scale auf --b-druck</td><td class="wert" data-tok="--dauer-druck-ein"></td><td class="wert" data-kurve="--kurve-druck-ein"></td><td>nur Farbe</td></tr>
            <tr><td>Druck aus</td><td>Feder zurück</td><td class="wert" data-tok="--dauer-druck-aus"></td><td class="wert" data-kurve="--kurve-druck-aus"></td><td>nur Farbe</td></tr>
            <tr><td>Laden</td><td>Label tauscht, Spinner</td><td class="wert" data-tok="--dauer-label,--dauer-spinner"></td><td class="wert" data-kurve="--kurve-label"></td><td>Spinner steht, Text trägt</td></tr>
            <tr><td>Erfolg</td><td>Häkchen zeichnet sich</td><td class="wert" data-tok="--dauer-haken"></td><td class="wert" data-kurve="--kurve-label"></td><td>Häkchen sofort</td></tr>
            <tr><td>Deaktiviert</td><td>keine Bewegung</td><td class="wert">0 ms</td><td class="wert">–</td><td>–</td></tr>
          </tbody>
        </table></div>
      </div>
    </div>
  </section>

  <!-- ===================== 03 Zustände ===================== -->
  <section class="rahmen abschnitt" id="zustaende" aria-labelledby="h-zus">
    <div class="abschnitt__kopf">
      <h2 id="h-zus"><span class="label">03 · Zustände</span>Jeder Typ, jeder Zustand</h2>
      <p>Die Matrix friert alle Zustände ein. Unter jedem Knopf steht der Kontrast des Labels gegen seine Fläche, berechnet aus den Tokens. Deaktiviert heißt hier aria-disabled: Der Knopf bleibt fokussierbar und sagt, warum er nicht geht.</p>
    </div>
    <div class="matrix-huelle" role="region" aria-label="Zustände aller Button-Typen, waagerecht scrollbar" tabindex="0">
      <div class="matrix" id="matrix">
        <div class="kopfz" aria-hidden="true"></div>
        <div class="kopfz">Ruhe<small>Grundzustand</small></div>
        <div class="kopfz">Hover<small>nur mit Zeiger</small></div>
        <div class="kopfz">Fokus<small>:focus-visible</small></div>
        <div class="kopfz">Druck<small>:active</small></div>
        <div class="kopfz">Deaktiviert<small>aria-disabled</small></div>
        <div class="kopfz">Laden<small>aria-busy</small></div>
        <div class="kopfz">Erfolg<small>role=status</small></div>
        <div class="typz">Primär</div>
        <div class="zelle"><button class="k k--primaer" type="button" inert tabindex="-1"><span class="k__stapel"><span class="k__ruhe">Senden</span><span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Sendet</span><span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Gesendet</span></span></button><output data-fg="--p-fg" data-bg="--p-bg" data-art="text"></output></div>
        <div class="zelle"><button class="k k--primaer ist-hover" type="button" inert tabindex="-1"><span class="k__stapel"><span class="k__ruhe">Senden</span><span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Sendet</span><span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Gesendet</span></span></button><output data-fg="--p-fg-h" data-bg="--p-bg-h" data-art="text"></output></div>
        <div class="zelle"><button class="k k--primaer ist-fokus" type="button" inert tabindex="-1"><span class="k__stapel"><span class="k__ruhe">Senden</span><span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Sendet</span><span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Gesendet</span></span></button><output data-fg="--b-fokus" data-bg="--flaeche" data-art="ring"></output></div>
        <div class="zelle"><button class="k k--primaer ist-druck" type="button" inert tabindex="-1"><span class="k__stapel"><span class="k__ruhe">Senden</span><span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Sendet</span><span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Gesendet</span></span></button><output data-fg="--p-fg-h" data-bg="--p-bg-d" data-art="text"></output></div>
        <div class="zelle"><button class="k k--primaer ist-aus" type="button" inert tabindex="-1"><span class="k__stapel"><span class="k__ruhe">Senden</span><span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Sendet</span><span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Gesendet</span></span></button><output data-fg="--d-fg" data-bg="--d-bg" data-art="text"></output></div>
        <div class="zelle"><button class="k k--primaer ist-laden" type="button" inert tabindex="-1"><span class="k__stapel"><span class="k__ruhe">Senden</span><span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Sendet</span><span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Gesendet</span></span></button><output data-fg="--p-fg" data-bg="--p-bg" data-art="text"></output></div>
        <div class="zelle"><button class="k k--primaer ist-erfolg" type="button" inert tabindex="-1"><span class="k__stapel"><span class="k__ruhe">Senden</span><span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Sendet</span><span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Gesendet</span></span></button><output data-fg="--ok-fg" data-bg="--ok-bg" data-art="text"></output></div>
        <div class="typz">Sekundär</div>
        <div class="zelle"><button class="k k--sekundaer" type="button" inert tabindex="-1"><span class="k__stapel"><span class="k__ruhe">Speichern</span><span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Speichert</span><span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Gespeichert</span></span></button><output data-fg="--s-fg" data-bg="--s-bg" data-art="text"></output></div>
        <div class="zelle"><button class="k k--sekundaer ist-hover" type="button" inert tabindex="-1"><span class="k__stapel"><span class="k__ruhe">Speichern</span><span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Speichert</span><span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Gespeichert</span></span></button><output data-fg="--s-fg-h" data-bg="--s-bg-h" data-art="text"></output></div>
        <div class="zelle"><button class="k k--sekundaer ist-fokus" type="button" inert tabindex="-1"><span class="k__stapel"><span class="k__ruhe">Speichern</span><span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Speichert</span><span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Gespeichert</span></span></button><output data-fg="--b-fokus" data-bg="--flaeche" data-art="ring"></output></div>
        <div class="zelle"><button class="k k--sekundaer ist-druck" type="button" inert tabindex="-1"><span class="k__stapel"><span class="k__ruhe">Speichern</span><span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Speichert</span><span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Gespeichert</span></span></button><output data-fg="--s-fg-h" data-bg="--s-bg-d" data-art="text"></output></div>
        <div class="zelle"><button class="k k--sekundaer ist-aus" type="button" inert tabindex="-1"><span class="k__stapel"><span class="k__ruhe">Speichern</span><span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Speichert</span><span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Gespeichert</span></span></button><output data-fg="--d-fg" data-bg="--d-bg" data-art="text"></output></div>
        <div class="zelle"><button class="k k--sekundaer ist-laden" type="button" inert tabindex="-1"><span class="k__stapel"><span class="k__ruhe">Speichern</span><span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Speichert</span><span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Gespeichert</span></span></button><output data-fg="--s-fg" data-bg="--s-bg" data-art="text"></output></div>
        <div class="zelle"><button class="k k--sekundaer ist-erfolg" type="button" inert tabindex="-1"><span class="k__stapel"><span class="k__ruhe">Speichern</span><span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Speichert</span><span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Gespeichert</span></span></button><output data-fg="--ok-fg" data-bg="--ok-bg" data-art="text"></output></div>
        <div class="typz">Tertiär</div>
        <div class="zelle"><button class="k k--tertiaer" type="button" inert tabindex="-1"><span class="k__stapel"><span class="k__ruhe">Abbrechen</span><span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Bricht ab</span><span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Erledigt</span></span></button><output data-fg="--t-fg" data-bg="--flaeche" data-art="text"></output></div>
        <div class="zelle"><button class="k k--tertiaer ist-hover" type="button" inert tabindex="-1"><span class="k__stapel"><span class="k__ruhe">Abbrechen</span><span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Bricht ab</span><span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Erledigt</span></span></button><output data-fg="--t-fg-h" data-bg="--t-bg-h" data-art="text"></output></div>
        <div class="zelle"><button class="k k--tertiaer ist-fokus" type="button" inert tabindex="-1"><span class="k__stapel"><span class="k__ruhe">Abbrechen</span><span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Bricht ab</span><span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Erledigt</span></span></button><output data-fg="--b-fokus" data-bg="--flaeche" data-art="ring"></output></div>
        <div class="zelle"><button class="k k--tertiaer ist-druck" type="button" inert tabindex="-1"><span class="k__stapel"><span class="k__ruhe">Abbrechen</span><span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Bricht ab</span><span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Erledigt</span></span></button><output data-fg="--t-fg-h" data-bg="--t-bg-d" data-art="text"></output></div>
        <div class="zelle"><button class="k k--tertiaer ist-aus" type="button" inert tabindex="-1"><span class="k__stapel"><span class="k__ruhe">Abbrechen</span><span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Bricht ab</span><span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Erledigt</span></span></button><output data-fg="--d-fg" data-bg="--flaeche" data-art="text"></output></div>
        <div class="zelle"><button class="k k--tertiaer ist-laden" type="button" inert tabindex="-1"><span class="k__stapel"><span class="k__ruhe">Abbrechen</span><span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Bricht ab</span><span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Erledigt</span></span></button><output data-fg="--t-fg" data-bg="--flaeche" data-art="text"></output></div>
        <div class="zelle"><button class="k k--tertiaer ist-erfolg" type="button" inert tabindex="-1"><span class="k__stapel"><span class="k__ruhe">Abbrechen</span><span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Bricht ab</span><span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Erledigt</span></span></button><output data-fg="--ok-fg" data-bg="--ok-bg" data-art="text"></output></div>
        <div class="typz">Icon</div>
        <div class="zelle"><button class="k k--icon" type="button" inert tabindex="-1" aria-label="Teilen"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 15V4M8 8l4-4 4 4M5 13v5a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-5"/></svg></button><output data-fg="--i-fg" data-bg="--i-bg" data-art="text"></output></div>
        <div class="zelle"><button class="k k--icon ist-hover" type="button" inert tabindex="-1" aria-label="Teilen"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 15V4M8 8l4-4 4 4M5 13v5a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-5"/></svg></button><output data-fg="--i-fg-h" data-bg="--i-bg-h" data-art="text"></output></div>
        <div class="zelle"><button class="k k--icon ist-fokus" type="button" inert tabindex="-1" aria-label="Teilen"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 15V4M8 8l4-4 4 4M5 13v5a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-5"/></svg></button><output data-fg="--b-fokus" data-bg="--flaeche" data-art="ring"></output></div>
        <div class="zelle"><button class="k k--icon ist-druck" type="button" inert tabindex="-1" aria-label="Teilen"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 15V4M8 8l4-4 4 4M5 13v5a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-5"/></svg></button><output data-fg="--i-fg-h" data-bg="--i-bg-d" data-art="text"></output></div>
        <div class="zelle"><button class="k k--icon ist-aus" type="button" inert tabindex="-1" aria-label="Teilen"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 15V4M8 8l4-4 4 4M5 13v5a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-5"/></svg></button><output data-fg="--d-fg" data-bg="--d-bg" data-art="text"></output></div>
        <div class="zelle"><button class="k k--icon ist-laden" type="button" inert tabindex="-1" aria-label="Teilen"><i class="k__dreh" aria-hidden="true"></i></button><output data-fg="--i-fg" data-bg="--i-bg" data-art="text"></output></div>
        <div class="zelle"><button class="k k--icon ist-erfolg" type="button" inert tabindex="-1" aria-label="Teilen"><svg class="k__haken" style="width:20px;height:20px" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg></button><output data-fg="--ok-fg" data-bg="--ok-bg" data-art="text"></output></div>
        <div class="typz">Gefahr</div>
        <div class="zelle"><button class="k k--gefahr" type="button" inert tabindex="-1"><span class="k__stapel"><span class="k__ruhe">Löschen</span><span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Löscht</span><span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Gelöscht</span></span></button><output data-fg="--g-fg" data-bg="--g-bg" data-art="text"></output></div>
        <div class="zelle"><button class="k k--gefahr ist-hover" type="button" inert tabindex="-1"><span class="k__stapel"><span class="k__ruhe">Löschen</span><span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Löscht</span><span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Gelöscht</span></span></button><output data-fg="--g-fg-h" data-bg="--g-bg-h" data-art="text"></output></div>
        <div class="zelle"><button class="k k--gefahr ist-fokus" type="button" inert tabindex="-1"><span class="k__stapel"><span class="k__ruhe">Löschen</span><span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Löscht</span><span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Gelöscht</span></span></button><output data-fg="--b-fokus" data-bg="--flaeche" data-art="ring"></output></div>
        <div class="zelle"><button class="k k--gefahr ist-druck" type="button" inert tabindex="-1"><span class="k__stapel"><span class="k__ruhe">Löschen</span><span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Löscht</span><span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Gelöscht</span></span></button><output data-fg="--g-fg-h" data-bg="--g-bg-d" data-art="text"></output></div>
        <div class="zelle"><button class="k k--gefahr ist-aus" type="button" inert tabindex="-1"><span class="k__stapel"><span class="k__ruhe">Löschen</span><span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Löscht</span><span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Gelöscht</span></span></button><output data-fg="--d-fg" data-bg="--d-bg" data-art="text"></output></div>
        <div class="zelle"><button class="k k--gefahr ist-laden" type="button" inert tabindex="-1"><span class="k__stapel"><span class="k__ruhe">Löschen</span><span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Löscht</span><span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Gelöscht</span></span></button><output data-fg="--g-fg" data-bg="--g-bg" data-art="text"></output></div>
        <div class="zelle"><button class="k k--gefahr ist-erfolg" type="button" inert tabindex="-1"><span class="k__stapel"><span class="k__ruhe">Löschen</span><span class="k__laden" aria-hidden="true"><i class="k__dreh"></i>Löscht</span><span class="k__ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Gelöscht</span></span></button><output data-fg="--ok-fg" data-bg="--ok-bg" data-art="text"></output></div>
      </div>
    </div>
    <div class="regeln">
      <div class="regel"><span class="label">Trefferfläche</span><b>44 × 44 px</b><p>Sichtbar darf ein Knopf kleiner sein; ein ::after mit negativem inset macht ihn tastbar. WCAG 2.5.8 verlangt 24 px, wir nehmen 44.</p></div>
      <div class="regel"><span class="label">Label</span><b>≥ 4,5 : 1</b><p>In jedem Zustand, auch deaktiviert und im Ladezustand. Gedämpft über eine eigene Textfarbe, nie über Deckkraft.</p></div>
      <div class="regel"><span class="label">Kante und Fokus</span><b>≥ 3 : 1</b><p>Rahmen sekundärer Buttons und der Fokusring gegen den Grund. Fokus nie ersatzlos entfernen, im Kontrastmodus Systemfarben.</p></div>
      <div class="regel"><span class="label">Doppelklick</span><b>1 ×</b><p>Während des Ladens ignoriert der Knopf weitere Klicks (aria-busy). Der Server prüft trotzdem selbst.</p></div>
    </div>
  </section>

  <!-- ===================== 04 Galerie ===================== -->
  <section class="rahmen abschnitt" id="galerie" aria-labelledby="h-gal">
    <div class="abschnitt__kopf">
      <h2 id="h-gal"><span class="label">04 · Galerie</span>Alle Button-Muster im Fundus</h2>
      <p>Schlanke Nachbauten zum Anfassen, nicht die vollen Demos. Jede Karte führt zur Detailseite mit Messwerten, Varianten und Code. Wähle ein Rezept, um die passenden Muster hervorzuheben und ausgeschlossene zu markieren.</p>
    </div>
    <div class="filter">
      <div class="chips" role="group" aria-label="Nach Stimmung filtern">
        <button type="button" data-stimmung="" aria-pressed="true">Alle</button>
        <button type="button" data-stimmung="ruhig" aria-pressed="false">ruhig</button>
        <button type="button" data-stimmung="präzise" aria-pressed="false">präzise</button>
        <button type="button" data-stimmung="luxuriös" aria-pressed="false">luxuriös</button>
        <button type="button" data-stimmung="verspielt" aria-pressed="false">verspielt</button>
        <button type="button" data-stimmung="laut" aria-pressed="false">laut</button>
        <button type="button" data-stimmung="warm" aria-pressed="false">warm</button>
      </div>
      <label>Rezept <select id="rezept-wahl"><option value="">alle zeigen</option><option value="architektur-ruhiges-raster">Architektur: ruhiges Raster</option><option value="handwerk-werkstatt-klartext">Handwerk: Werkstatt und Klartext</option><option value="fahrschule-freundlich-buchbar">Fahrschule: freundlich und buchbar</option><option value="immobilien-diskret-hochwertig">Immobilien: diskret und hochwertig</option><option value="gastro-warm-appetitlich">Gastronomie: warm und einladend</option><option value="boutique-hotel-gastgeber">Boutique-Hotel: Gastgeber mit Haltung</option><option value="kreativstudio-buehne">Kreativstudio: Studio-Bühne</option><option value="freelancer-stille-visitenkarte">Freelancer: Stille Visitenkarte</option><option value="fotograf-film-bild-zuerst">Fotografie und Film: Bild zuerst</option><option value="mode-beauty-kollektion">Mode und Beauty: Kollektion und Ritual</option><option value="kultur-programm-haltung">Kultur: Programm und Haltung</option><option value="luxus-manufaktur-stille">Luxus und Manufaktur: Stille</option><option value="saas-produkt-praezise">SaaS &amp; KI: das Produkt zeigt sich selbst</option><option value="kanzlei-beratung-souveraen">Kanzlei &amp; Beratung: Haltung und Klarheit</option><option value="praxis-gesundheit-ruhig">Praxis &amp; Therapie: ruhig und zugewandt</option><option value="kurs-coaching-lernweg">Online-Kurs &amp; Coaching: klarer Lernweg</option><option value="d2c-produkt-zuerst">Onlineshop &amp; Produktmarke: Produkt zuerst</option><option value="verein-nonprofit-wirkung">Verein &amp; Non-Profit: Wirkung zeigen</option><option value="friseur-salon-handschrift">Salon: Handschrift und Termin</option><option value="fitness-studio-rhythmus">Studio: Rhythmus und Kursplan</option><option value="pflege-dienst-naehe">Pflegedienst: Nähe und Klartext</option><option value="musik-kuenstler-buehne">Musik und Kunst: Ära und Bühne</option><option value="industrie-b2b-mittelstand">Industrie-Mittelstand: Datenblatt und Fachperson</option><option value="kfz-werkstatt-autohaus">Kfz-Werkstatt und Autohaus: Festpreis, Termin, fertig</option><option value="arbeitgeber-karriere">Arbeitgeber: Einblick statt Floskel</option><option value="bestattung-wuerdig">Bestattung: würdig und klar</option><option value="eventlocation-hochzeit">Eventlocation: ein Tag, der in die Nacht geht</option><option value="weingut-hofladen-herkunft">Weingut und Hofladen: Herkunft zuerst</option></select></label>
      <output class="label" id="galerie-zahl" aria-live="polite"></output>
    </div>
    <ul class="galerie" id="galerie-liste">
      <li class="karte" data-id="glas-button" data-stimmung="ruhig präzise luxuriös" data-nr="0" data-var="">
        <div class="karte__buehne" style="background:transparent"><div class="g-glas-bild" aria-hidden="true"></div><button class="g-glas" type="button" data-ziel><span>Verfügbarkeit prüfen</span></button></div>
        <div class="karte__info">
          <span class="marke-rezept marke-rezept--ja">Empfohlen<span data-var></span></span>
          <span class="marke-rezept marke-rezept--nein">Im Rezept ausgeschlossen</span>
          <h3>Glas-Button</h3>
          <p>Frost über dem Foto: unscharfer Saum mit Lichtkante, dichter Kern unter dem Label. Ohne Unschärfe oder bei reduzierter Transparenz deckend.</p>
          <p class="karte__var">Varianten: frost · liquid · getoent · glanz</p>
          <div class="karte__fuss">
            <ul class="tags" aria-label="Stimmung"><li>ruhig</li><li>präzise</li><li>luxuriös</li></ul>
            <a class="karte__link" href="../../buttons/glas-button/index.html" aria-label="Detailseite: Glas-Button">Detailseite <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          </div>
          <span class="label">buttons / glas-button</span>
        </div>
      </li>
      <li class="karte" data-id="pfeil-icon-button" data-stimmung="ruhig präzise" data-nr="1" data-var="">
        <div class="karte__buehne" style="background:#ffffff"><a class="g-pfeil" href="#galerie" data-ziel><span class="g-pfeil__text">Projekte ansehen</span><span class="g-pfeil__kreis"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span></a></div>
        <div class="karte__info">
          <span class="marke-rezept marke-rezept--ja">Empfohlen<span data-var></span></span>
          <span class="marke-rezept marke-rezept--nein">Im Rezept ausgeschlossen</span>
          <h3>Pfeil-Icon-Button</h3>
          <p>Der Icon-Kreis wächst zur ganzen Pille, das Label wird weiß. Nur das Icon trägt die Bewegung.</p>
          <p class="karte__var">Varianten: kreis-expand · tausch · linie · seitenwechsel</p>
          <div class="karte__fuss">
            <ul class="tags" aria-label="Stimmung"><li>ruhig</li><li>präzise</li></ul>
            <a class="karte__link" href="../../buttons/pfeil-icon-button/index.html" aria-label="Detailseite: Pfeil-Icon-Button">Detailseite <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          </div>
          <span class="label">buttons / pfeil-icon-button</span>
        </div>
      </li>
      <li class="karte" data-id="tiefen-taste-3d" data-stimmung="verspielt laut" data-nr="2" data-var="">
        <div class="karte__buehne" style="background:#f8f8ec"><button class="g-taste" type="button" data-ziel><span class="g-taste__schatten"></span><span class="g-taste__kante"></span><span class="g-taste__front">Probestunde buchen</span></button></div>
        <div class="karte__info">
          <span class="marke-rezept marke-rezept--ja">Empfohlen<span data-var></span></span>
          <span class="marke-rezept marke-rezept--nein">Im Rezept ausgeschlossen</span>
          <h3>Tiefen-Taste (3D)</h3>
          <p>Front, Kante und Schatten als Stapel: Hover hebt auf −6 px mit Überschwinger, Druck setzt in 34 ms auf −2 px.</p>
          <p class="karte__var">Varianten: stapel · versatz-brutal · keycap · soft</p>
          <div class="karte__fuss">
            <ul class="tags" aria-label="Stimmung"><li>verspielt</li><li>laut</li></ul>
            <a class="karte__link" href="../../buttons/tiefen-taste-3d/index.html" aria-label="Detailseite: Tiefen-Taste (3D)">Detailseite <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          </div>
          <span class="label">buttons / tiefen-taste-3d</span>
        </div>
      </li>
      <li class="karte" data-id="kontur-button-zeichnen" data-stimmung="ruhig luxuriös" data-nr="3" data-var="">
        <div class="karte__buehne" style="background:#ffffff"><button class="g-kontur" type="button" data-ziel>Termin in der Werkstatt<svg aria-hidden="true"><rect x=".75" y=".75" pathLength="1"/></svg></button></div>
        <div class="karte__info">
          <span class="marke-rezept marke-rezept--ja">Empfohlen<span data-var></span></span>
          <span class="marke-rezept marke-rezept--nein">Im Rezept ausgeschlossen</span>
          <h3>Kontur, die sich zeichnet</h3>
          <p>Die Linie läuft bei Hover und Fokus einmal um den Knopf (pathLength 1, 480 ms), zurück mit Anlauf.</p>
          <p class="karte__var">Varianten: zeichnen · ecken · doppel · laufend</p>
          <div class="karte__fuss">
            <ul class="tags" aria-label="Stimmung"><li>ruhig</li><li>luxuriös</li></ul>
            <a class="karte__link" href="../../buttons/kontur-button-zeichnen/index.html" aria-label="Detailseite: Kontur, die sich zeichnet">Detailseite <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          </div>
          <span class="label">buttons / kontur-button-zeichnen</span>
        </div>
      </li>
      <li class="karte" data-id="button-gruppe-expressiv" data-stimmung="präzise verspielt" data-nr="4" data-var="">
        <div class="karte__buehne" style="background:#f5f4f1"><div class="g-gruppe" role="group" aria-label="Sorten filtern"><button type="button" aria-pressed="true" data-ziel><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12.5l4.5 4.5L19 7.5"/></svg>Samenfest</button><button type="button" aria-pressed="false" data-ziel><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12.5l4.5 4.5L19 7.5"/></svg>Bio</button><button type="button" aria-pressed="false" data-ziel><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12.5l4.5 4.5L19 7.5"/></svg>Balkon</button></div></div>
        <div class="karte__info">
          <span class="marke-rezept marke-rezept--ja">Empfohlen<span data-var></span></span>
          <span class="marke-rezept marke-rezept--nein">Im Rezept ausgeschlossen</span>
          <h3>Button-Gruppe expressiv</h3>
          <p>Verbundene Toggle-Gruppe: Druck macht breiter und eckiger, Auswahl macht rund und zeigt ein Häkchen.</p>
          <p class="karte__var">Varianten: toggle · einzeln · split</p>
          <div class="karte__fuss">
            <ul class="tags" aria-label="Stimmung"><li>präzise</li><li>verspielt</li></ul>
            <a class="karte__link" href="../../buttons/button-gruppe-expressiv/index.html" aria-label="Detailseite: Button-Gruppe expressiv">Detailseite <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          </div>
          <span class="label">buttons / button-gruppe-expressiv</span>
        </div>
      </li>
      <li class="karte" data-id="button-zustaende" data-stimmung="präzise verspielt" data-nr="5" data-var="">
        <div class="karte__buehne" style="background:#fff6e8"><button class="g-zust" type="button" data-ziel><span class="z-ruhe">Termin buchen</span><span class="z-laden" aria-hidden="true"><i class="k__dreh"></i>Wird gebucht</span><span class="z-ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Gebucht</span></button><p class="nur-sr" role="status"></p></div>
        <div class="karte__info">
          <span class="marke-rezept marke-rezept--ja">Empfohlen<span data-var></span></span>
          <span class="marke-rezept marke-rezept--nein">Im Rezept ausgeschlossen</span>
          <h3>Button-Zustandsfolge</h3>
          <p>Hover, Druck, Laden und Erfolg am selben Knopf, alle Labels liegen übereinander, nichts springt.</p>
          
          <div class="karte__fuss">
            <ul class="tags" aria-label="Stimmung"><li>präzise</li><li>verspielt</li></ul>
            <a class="karte__link" href="../../mikroanimationen/button-zustaende/index.html" aria-label="Detailseite: Button-Zustandsfolge">Detailseite <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          </div>
          <span class="label">mikroanimationen / button-zustaende</span>
        </div>
      </li>
      <li class="karte" data-id="druck-feedback" data-stimmung="verspielt" data-nr="6" data-var="">
        <div class="karte__buehne" style="background:#eef0f3"><button class="g-druck" type="button" data-ziel>In den Korb</button></div>
        <div class="karte__info">
          <span class="marke-rezept marke-rezept--ja">Empfohlen<span data-var></span></span>
          <span class="marke-rezept marke-rezept--nein">Im Rezept ausgeschlossen</span>
          <h3>Druck-Feedback</h3>
          <p>Einfedern 100 ms auf scale .96, zurück mit gedämpfter Feder (linear(), etwa 16 % Überschwinger).</p>
          
          <div class="karte__fuss">
            <ul class="tags" aria-label="Stimmung"><li>verspielt</li></ul>
            <a class="karte__link" href="../../mikroanimationen/druck-feedback/index.html" aria-label="Detailseite: Druck-Feedback">Detailseite <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          </div>
          <span class="label">mikroanimationen / druck-feedback</span>
        </div>
      </li>
      <li class="karte" data-id="hold-to-confirm" data-stimmung="präzise verspielt" data-nr="7" data-var="">
        <div class="karte__buehne" style="background:#fcfcfc"><button class="g-halten" type="button" data-ziel><span class="h-leer">Angebot annehmen · halten</span><span class="h-voll" aria-hidden="true">Angebot annehmen · halten</span></button><p class="nur-sr" role="status"></p></div>
        <div class="karte__info">
          <span class="marke-rezept marke-rezept--ja">Empfohlen<span data-var></span></span>
          <span class="marke-rezept marke-rezept--nein">Im Rezept ausgeschlossen</span>
          <h3>Gedrückt halten</h3>
          <p>Annehmen per Halten: Die Fläche füllt sich in 1,2 s, Loslassen spult dreimal so schnell zurück. Leertaste und Enter halten ebenso.</p>
          
          <div class="karte__fuss">
            <ul class="tags" aria-label="Stimmung"><li>präzise</li><li>verspielt</li></ul>
            <a class="karte__link" href="../../mikroanimationen/hold-to-confirm/index.html" aria-label="Detailseite: Gedrückt halten">Detailseite <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          </div>
          <span class="label">mikroanimationen / hold-to-confirm</span>
        </div>
      </li>
      <li class="karte" data-id="kopieren-feedback" data-stimmung="präzise verspielt" data-nr="8" data-var="">
        <div class="karte__buehne" style="background:#eef0f3"><div class="g-kopie"><code>post@quermass.de</code><button class="" type="button" data-ziel data-kopie="post@quermass.de"><span class="c-ruhe"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2"/><path d="M16 8V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h2"/></svg>Kopieren</span><span class="c-ok" aria-hidden="true"><svg class="k__haken" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path pathLength="1" d="M5 12.5l4.5 4.5L19 7.5"/></svg>Kopiert</span></button></div><p class="nur-sr" role="status"></p></div>
        <div class="karte__info">
          <span class="marke-rezept marke-rezept--ja">Empfohlen<span data-var></span></span>
          <span class="marke-rezept marke-rezept--nein">Im Rezept ausgeschlossen</span>
          <h3>Kopieren-Feedback</h3>
          <p>Bestätigung direkt am Knopf: Icon und Label tauschen mit Unschärfe, nach 2 s zurück; Ansage per role=status.</p>
          
          <div class="karte__fuss">
            <ul class="tags" aria-label="Stimmung"><li>präzise</li><li>verspielt</li></ul>
            <a class="karte__link" href="../../mikroanimationen/kopieren-feedback/index.html" aria-label="Detailseite: Kopieren-Feedback">Detailseite <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          </div>
          <span class="label">mikroanimationen / kopieren-feedback</span>
        </div>
      </li>
      <li class="karte" data-id="fokus-stil-system" data-stimmung="ruhig präzise" data-nr="9" data-var="">
        <div class="karte__buehne" style="background:#ffffff"><div class="g-fok-reihe"><button class="g-fok" type="button" data-ziel>Zurück</button><button class="g-fok ist-fokus" type="button" inert>Weiter zur Kasse</button></div></div>
        <div class="karte__info">
          <span class="marke-rezept marke-rezept--ja">Empfohlen<span data-var></span></span>
          <span class="marke-rezept marke-rezept--nein">Im Rezept ausgeschlossen</span>
          <h3>Fokus als Gestaltung</h3>
          <p>Fokus in der Markensprache, hier als Signalfläche: Gelb mit Unterkante, mindestens 3 : 1. Rechts eingefroren, links mit Tab live.</p>
          <p class="karte__var">Varianten: ring · doppel · signal</p>
          <div class="karte__fuss">
            <ul class="tags" aria-label="Stimmung"><li>ruhig</li><li>präzise</li></ul>
            <a class="karte__link" href="../../zugang/fokus-stil-system/index.html" aria-label="Detailseite: Fokus als Gestaltung">Detailseite <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          </div>
          <span class="label">zugang / fokus-stil-system</span>
        </div>
      </li>
      <li class="karte" data-id="magnetische-elemente" data-stimmung="luxuriös verspielt laut" data-nr="10" data-var="">
        <div class="karte__buehne" style="background:#e9e7e2"><button class="g-magnet" type="button" data-ziel data-magnet><span>Schreiben</span></button></div>
        <div class="karte__info">
          <span class="marke-rezept marke-rezept--ja">Empfohlen<span data-var></span></span>
          <span class="marke-rezept marke-rezept--nein">Im Rezept ausgeschlossen</span>
          <h3>Magnetischer Button</h3>
          <p>Der Knopf zieht sich zum Zeiger (Stärke 24 px), das Label folgt mit 12 px, zurück mit Feder. Nur mit Maus.</p>
          
          <div class="karte__fuss">
            <ul class="tags" aria-label="Stimmung"><li>luxuriös</li><li>verspielt</li><li>laut</li></ul>
            <a class="karte__link" href="../../hover/magnetische-elemente/index.html" aria-label="Detailseite: Magnetischer Button">Detailseite <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          </div>
          <span class="label">hover / magnetische-elemente</span>
        </div>
      </li>
      <li class="karte" data-id="fuellung-vom-eintrittspunkt" data-stimmung="ruhig präzise luxuriös verspielt" data-nr="11" data-var="basis">
        <div class="karte__buehne" style="background:#efedea"><button class="g-fuell" type="button" data-ziel data-fuell><span>Anfrage stellen</span><span class="g-fuell__fl" aria-hidden="true">Anfrage stellen</span></button></div>
        <div class="karte__info">
          <span class="marke-rezept marke-rezept--ja">Empfohlen<span data-var></span></span>
          <span class="marke-rezept marke-rezept--nein">Im Rezept ausgeschlossen</span>
          <h3>Füllung vom Eintrittspunkt</h3>
          <p>Die Fläche wächst als Kreis genau dort, wo der Zeiger eintritt, und zieht sich zum Austrittspunkt zurück (600 ms expo.out).</p>
          <p class="karte__var">Varianten: basis · pixel</p>
          <div class="karte__fuss">
            <ul class="tags" aria-label="Stimmung"><li>ruhig</li><li>präzise</li><li>luxuriös</li></ul>
            <a class="karte__link" href="../../hover/fuellung-vom-eintrittspunkt/index.html" aria-label="Detailseite: Füllung vom Eintrittspunkt">Detailseite <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          </div>
          <span class="label">hover / fuellung-vom-eintrittspunkt</span>
        </div>
      </li>
      <li class="karte" data-id="fuellung-vom-eintrittspunkt" data-stimmung="ruhig präzise luxuriös verspielt" data-nr="12" data-var="pixel">
        <div class="karte__buehne" style="background:#efede9"><button class="g-pixel" type="button" data-ziel data-pixel><span class="g-pixel__raster" aria-hidden="true"></span><span class="g-pixel__text">Tickets sichern</span></button></div>
        <div class="karte__info">
          <span class="marke-rezept marke-rezept--ja">Empfohlen<span data-var></span></span>
          <span class="marke-rezept marke-rezept--nein">Im Rezept ausgeschlossen</span>
          <h3>Füllung vom Eintrittspunkt · Pixel</h3>
          <p>Variante pixel: Zellen von 8 px füllen sich in sechs Stufen zu 80 ms vom Eintrittspunkt aus, ohne Kurve, nur Takt.</p>
          <p class="karte__var">Varianten: pixel</p>
          <div class="karte__fuss">
            <ul class="tags" aria-label="Stimmung"><li>ruhig</li><li>präzise</li><li>luxuriös</li></ul>
            <a class="karte__link" href="../../hover/fuellung-vom-eintrittspunkt/index.html" aria-label="Detailseite: Füllung vom Eintrittspunkt · Pixel">Detailseite <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          </div>
          <span class="label">hover / fuellung-vom-eintrittspunkt</span>
        </div>
      </li>
      <li class="karte" data-id="clip-path-form-hover" data-stimmung="verspielt laut warm" data-nr="13" data-var="basis">
        <div class="karte__buehne" style="background:#f2f2f2"><button class="g-form" type="button" data-ziel><span>Showreel 2026</span></button></div>
        <div class="karte__info">
          <span class="marke-rezept marke-rezept--ja">Empfohlen<span data-var></span></span>
          <span class="marke-rezept marke-rezept--nein">Im Rezept ausgeschlossen</span>
          <h3>Form-Morph (Pfeil)</h3>
          <p>Die Fläche morpht per clip-path vom Rechteck zur Pfeilspitze, das Label rückt 8 px nach.</p>
          <p class="karte__var">Varianten: basis · gooey</p>
          <div class="karte__fuss">
            <ul class="tags" aria-label="Stimmung"><li>verspielt</li><li>laut</li><li>warm</li></ul>
            <a class="karte__link" href="../../hover/clip-path-form-hover/index.html" aria-label="Detailseite: Form-Morph (Pfeil)">Detailseite <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          </div>
          <span class="label">hover / clip-path-form-hover</span>
        </div>
      </li>
      <li class="karte" data-id="clip-path-form-hover" data-stimmung="verspielt laut warm" data-nr="14" data-var="gooey">
        <div class="karte__buehne" style="background:#f2f2f2"><button class="g-goo" type="button" data-ziel><span class="g-goo__form" aria-hidden="true"><i class="pille"></i><i class="tropfen"></i></span><span class="g-goo__text">Kontakt aufnehmen</span><span class="g-goo__icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span></button></div>
        <div class="karte__info">
          <span class="marke-rezept marke-rezept--ja">Empfohlen<span data-var></span></span>
          <span class="marke-rezept marke-rezept--nein">Im Rezept ausgeschlossen</span>
          <h3>Form-Morph · Gooey</h3>
          <p>Variante gooey: Ein Tropfen löst sich aus der Pille und wird zur Icon-Blase (SVG-Filter aus Blur und Farbmatrix).</p>
          <p class="karte__var">Varianten: gooey</p>
          <div class="karte__fuss">
            <ul class="tags" aria-label="Stimmung"><li>verspielt</li><li>laut</li><li>warm</li></ul>
            <a class="karte__link" href="../../hover/clip-path-form-hover/index.html" aria-label="Detailseite: Form-Morph · Gooey">Detailseite <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          </div>
          <span class="label">hover / clip-path-form-hover</span>
        </div>
      </li>
      <li class="karte" data-id="text-roll-hover" data-stimmung="ruhig editorial präzise verspielt" data-nr="15" data-var="">
        <div class="karte__buehne" style="background:#f2f2f2"><button class="g-roll" type="button" data-ziel aria-label="Projekte ansehen"><span class="g-roll__maske" aria-hidden="true"><span class="g-roll__z" style="--i:0" data-z="P">P</span><span class="g-roll__z" style="--i:1" data-z="r">r</span><span class="g-roll__z" style="--i:2" data-z="o">o</span><span class="g-roll__z" style="--i:3" data-z="j">j</span><span class="g-roll__z" style="--i:4" data-z="e">e</span><span class="g-roll__z" style="--i:5" data-z="k">k</span><span class="g-roll__z" style="--i:6" data-z="t">t</span><span class="g-roll__z" style="--i:7" data-z="e">e</span><span class="g-roll__z" style="--i:8" data-z=" "> </span><span class="g-roll__z" style="--i:9" data-z="a">a</span><span class="g-roll__z" style="--i:10" data-z="n">n</span><span class="g-roll__z" style="--i:11" data-z="s">s</span><span class="g-roll__z" style="--i:12" data-z="e">e</span><span class="g-roll__z" style="--i:13" data-z="h">h</span><span class="g-roll__z" style="--i:14" data-z="e">e</span><span class="g-roll__z" style="--i:15" data-z="n">n</span></span></button></div>
        <div class="karte__info">
          <span class="marke-rezept marke-rezept--ja">Empfohlen<span data-var></span></span>
          <span class="marke-rezept marke-rezept--nein">Im Rezept ausgeschlossen</span>
          <h3>Text-Roll beim Hover</h3>
          <p>Das Label liegt doppelt in einer Zeilenmaske, eine Zeichenwelle rollt die Kopie herein (12 ms Versatz, 800 ms).</p>
          
          <div class="karte__fuss">
            <ul class="tags" aria-label="Stimmung"><li>ruhig</li><li>editorial</li><li>präzise</li></ul>
            <a class="karte__link" href="../../schrift-animationen/text-roll-hover/index.html" aria-label="Detailseite: Text-Roll beim Hover">Detailseite <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          </div>
          <span class="label">schrift-animationen / text-roll-hover</span>
        </div>
      </li>
      <li class="karte" data-id="icon-squash-stretch" data-stimmung="verspielt warm" data-nr="16" data-var="">
        <div class="karte__buehne" style="background:#f0ece0"><button class="g-squash" type="button" data-ziel>Tisch reservieren<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path class="schaft" d="M5 12h8"/><path class="spitze" d="M9 8l4 4-4 4"/></svg></button></div>
        <div class="karte__info">
          <span class="marke-rezept marke-rezept--ja">Empfohlen<span data-var></span></span>
          <span class="marke-rezept marke-rezept--nein">Im Rezept ausgeschlossen</span>
          <h3>Icon-Squash-and-Stretch</h3>
          <p>Der Pfeil streckt sich: Schaft wird länger, die Spitze rückt vor (200 ms quad.out). Wirkt gezeichnet statt mechanisch.</p>
          
          <div class="karte__fuss">
            <ul class="tags" aria-label="Stimmung"><li>verspielt</li><li>warm</li></ul>
            <a class="karte__link" href="../../mikroanimationen/icon-squash-stretch/index.html" aria-label="Detailseite: Icon-Squash-and-Stretch">Detailseite <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          </div>
          <span class="label">mikroanimationen / icon-squash-stretch</span>
        </div>
      </li>
      <li class="karte" data-id="verlaufs-rahmen" data-stimmung="präzise laut" data-nr="17" data-var="">
        <div class="karte__buehne" style="background:#f4f6fa"><button class="g-ring" type="button" data-ziel>Platz sichern</button></div>
        <div class="karte__info">
          <span class="marke-rezept marke-rezept--ja">Empfohlen<span data-var></span></span>
          <span class="marke-rezept marke-rezept--nein">Im Rezept ausgeschlossen</span>
          <h3>Verlaufsrahmen · Button</h3>
          <p>Variante button: Ein Lichtstreif läuft um die Pille, aber nur bei Hover und Fokus; sonst steht eine ruhige Lichtkante.</p>
          <p class="karte__var">Varianten: button</p>
          <div class="karte__fuss">
            <ul class="tags" aria-label="Stimmung"><li>präzise</li><li>laut</li></ul>
            <a class="karte__link" href="../../glas-material/verlaufs-rahmen/index.html" aria-label="Detailseite: Verlaufsrahmen · Button">Detailseite <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          </div>
          <span class="label">glas-material / verlaufs-rahmen</span>
        </div>
      </li>
      <li class="karte" data-id="grain-noise-overlay" data-stimmung="editorial filmisch warm" data-nr="18" data-var="">
        <div class="karte__buehne" style="background:#f5f4f1"><button class="g-korn" type="button" data-ziel><span>In den Warenkorb · 24 €</span></button></div>
        <div class="karte__info">
          <span class="marke-rezept marke-rezept--ja">Empfohlen<span data-var></span></span>
          <span class="marke-rezept marke-rezept--nein">Im Rezept ausgeschlossen</span>
          <h3>Grain · Button</h3>
          <p>Variante button: körniger Verlauf auf der Kaufbox-Fläche. Deckende Grundfarbe als Rückfall, Korn per feTurbulence-Kachel.</p>
          <p class="karte__var">Varianten: button</p>
          <div class="karte__fuss">
            <ul class="tags" aria-label="Stimmung"><li>editorial</li><li>filmisch</li><li>warm</li></ul>
            <a class="karte__link" href="../../glas-material/grain-noise-overlay/index.html" aria-label="Detailseite: Grain · Button">Detailseite <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          </div>
          <span class="label">glas-material / grain-noise-overlay</span>
        </div>
      </li>
      <li class="karte" data-id="neo-skeuomorph-taktile-ui" data-stimmung="präzise luxuriös verspielt" data-nr="19" data-var="">
        <div class="karte__buehne" style="background:#e9e4dc"><button class="g-porz" type="button" data-ziel>Probe bestellen</button></div>
        <div class="karte__info">
          <span class="marke-rezept marke-rezept--ja">Empfohlen<span data-var></span></span>
          <span class="marke-rezept marke-rezept--nein">Im Rezept ausgeschlossen</span>
          <h3>Taktile Taste (Porzellan)</h3>
          <p>Lichtkante oben, Haarlinie, gestaffelte Schatten; beim Drücken sinkt der Knopf 2 px ein.</p>
          
          <div class="karte__fuss">
            <ul class="tags" aria-label="Stimmung"><li>präzise</li><li>luxuriös</li><li>verspielt</li></ul>
            <a class="karte__link" href="../../glas-material/neo-skeuomorph-taktile-ui/index.html" aria-label="Detailseite: Taktile Taste (Porzellan)">Detailseite <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          </div>
          <span class="label">glas-material / neo-skeuomorph-taktile-ui</span>
        </div>
      </li>
      <li class="karte" data-id="corner-shape-eckenformen" data-stimmung="präzise verspielt" data-nr="20" data-var="">
        <div class="karte__buehne" style="background:#f4f6fa"><button class="g-ecke" type="button" data-ziel>Kurs buchen</button></div>
        <div class="karte__info">
          <span class="marke-rezept marke-rezept--ja">Empfohlen<span data-var></span></span>
          <span class="marke-rezept marke-rezept--nein">Im Rezept ausgeschlossen</span>
          <h3>Eckenform per corner-shape</h3>
          <p>Der Knopf wechselt beim Hover von Fase zu Squircle (corner-shape, 300 ms). Ohne Unterstützung bleibt eine normale Rundung.</p>
          <p class="karte__var">Varianten: basis · formen</p>
          <div class="karte__fuss">
            <ul class="tags" aria-label="Stimmung"><li>präzise</li><li>verspielt</li></ul>
            <a class="karte__link" href="../../mikroanimationen/corner-shape-eckenformen/index.html" aria-label="Detailseite: Eckenform per corner-shape">Detailseite <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          </div>
          <span class="label">mikroanimationen / corner-shape-eckenformen</span>
        </div>
      </li>
      <li class="karte" data-id="like-herz-burst" data-stimmung="verspielt warm" data-nr="21" data-var="">
        <div class="karte__buehne" style="background:#faf7f2"><div class="g-herz-zeile"><button class="g-herz" type="button" aria-pressed="false" aria-label="Wohnung merken" data-ziel><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 20s-7-4.4-7-10a4 4 0 0 1 7-2.6A4 4 0 0 1 19 10c0 5.6-7 10-7 10z"/></svg></button><small><span data-herz-zahl>2</span> gemerkt</small></div></div>
        <div class="karte__info">
          <span class="marke-rezept marke-rezept--ja">Empfohlen<span data-var></span></span>
          <span class="marke-rezept marke-rezept--nein">Im Rezept ausgeschlossen</span>
          <h3>Merken mit Herz</h3>
          <p>Icon-Button mit aria-pressed: Das Herz springt mit Überschwinger, ein Ring zerstreut sich, der Zähler zählt.</p>
          
          <div class="karte__fuss">
            <ul class="tags" aria-label="Stimmung"><li>verspielt</li><li>warm</li></ul>
            <a class="karte__link" href="../../mikroanimationen/like-herz-burst/index.html" aria-label="Detailseite: Merken mit Herz">Detailseite <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          </div>
          <span class="label">mikroanimationen / like-herz-burst</span>
        </div>
      </li>
      <li class="karte" data-id="menue-icon-und-label-morph" data-stimmung="editorial präzise verspielt" data-nr="22" data-var="">
        <div class="karte__buehne" style="background:#ffffff"><button class="g-menue" type="button" data-ziel aria-expanded="false"><span class="g-menue__icon" aria-hidden="true"><i></i><i></i></span><span class="g-menue__label"><span>Menü</span><span aria-hidden="true">Schließen</span></span></button></div>
        <div class="karte__info">
          <span class="marke-rezept marke-rezept--ja">Empfohlen<span data-var></span></span>
          <span class="marke-rezept marke-rezept--nein">Im Rezept ausgeschlossen</span>
          <h3>Menü-Button-Morph</h3>
          <p>Zwei Linien werden zum X, das Label rollt von „Menü“ zu „Schließen“; aria-expanded trägt den Zustand.</p>
          
          <div class="karte__fuss">
            <ul class="tags" aria-label="Stimmung"><li>editorial</li><li>präzise</li><li>verspielt</li></ul>
            <a class="karte__link" href="../../navigation/menue-icon-und-label-morph/index.html" aria-label="Detailseite: Menü-Button-Morph">Detailseite <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          </div>
          <span class="label">navigation / menue-icon-und-label-morph</span>
        </div>
      </li>
      <li class="karte" data-id="widerruf-und-kuendigung-schaltflaeche" data-stimmung="präzise" data-nr="23" data-var="">
        <div class="karte__buehne" style="background:#f7f7f7"><div class="g-kuend"><div class="stufe1"><button class="eins" type="button" data-ziel>Verträge hier kündigen</button></div><div class="stufe2" hidden><p>Abo „Gartenkiste“ zum 31.12.2026 kündigen?</p><div class="reihe"><button class="ab" type="button" data-ziel>Abbrechen</button><button class="zwei" type="button" data-ziel>jetzt kündigen</button></div></div><div class="stufe3" hidden><p role="status">Kündigung eingegangen. Bestätigung per E-Mail (Demo).</p><button class="ab" type="button" data-ziel>Zurücksetzen</button></div></div></div>
        <div class="karte__info">
          <span class="marke-rezept marke-rezept--ja">Empfohlen<span data-var></span></span>
          <span class="marke-rezept marke-rezept--nein">Im Rezept ausgeschlossen</span>
          <h3>Kündigungs-Button</h3>
          <p>Pflicht-Button in zwei Stufen: „Verträge hier kündigen“ führt zur Bestätigung „jetzt kündigen“. Gefahrfarbe erst im zweiten Schritt.</p>
          <p class="karte__var">Varianten: richtig</p>
          <div class="karte__fuss">
            <ul class="tags" aria-label="Stimmung"><li>präzise</li></ul>
            <a class="karte__link" href="../../sektionen/widerruf-und-kuendigung-schaltflaeche/index.html" aria-label="Detailseite: Kündigungs-Button">Detailseite <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></a>
          </div>
          <span class="label">sektionen / widerruf-und-kuendigung-schaltflaeche</span>
        </div>
      </li>
    </ul>
  </section>

  <!-- ===================== 05 Rezepte ===================== -->
  <section class="rahmen abschnitt" id="rezepte" aria-labelledby="h-rez">
    <div class="abschnitt__kopf">
      <h2 id="h-rez"><span class="label">05 · Rezepte</span>Rezept → passender Button-Typ</h2>
      <p>Ein Haupttyp, höchstens ein zweiter. Die Wahl folgt aus Stimmung, Animationsstil und den Ausschlüssen des Rezepts. Was ein Rezept unter „nicht verwenden“ führt, taucht hier nie auf.</p>
    </div>
    <div class="rtab-huelle">
      <table class="rtab">
        <caption class="nur-sr">Zuordnung der 28 Rezepte zu Button-Mustern mit Begründung</caption>
        <thead><tr><th scope="col">Rezept</th><th scope="col">Stimmung · Bewegung</th><th scope="col">Button-Muster</th><th scope="col">Warum</th></tr></thead>
        <tbody>
          <tr data-rezept="architektur-ruhiges-raster">
            <th scope="row">Architektur: ruhiges Raster<small>architektur-ruhiges-raster</small></th>
            <td class="stim" data-th="Stimmung · Bewegung">ruhig, präzise, zurückhaltend<small>token-swiss-knackig</small></td>
            <td class="mus" data-th="Button-Muster"><ul><li><a href="../../buttons/pfeil-icon-button/index.html">pfeil-icon-button</a><i>?v=linie</i></li><li><a href="../../buttons/kontur-button-zeichnen/index.html">kontur-button-zeichnen</a><i>?v=ecken</i></li></ul></td>
            <td class="warum" data-th="Warum">Ruhig und sachlich, token-swiss-knackig: Bewegung nur im kleinen Pfeil oder in der Kontur, keine Fläche, die aufspringt. Projektfotos tragen die Farbe.</td>
          </tr>
          <tr data-rezept="handwerk-werkstatt-klartext">
            <th scope="row">Handwerk: Werkstatt und Klartext<small>handwerk-werkstatt-klartext</small></th>
            <td class="stim" data-th="Stimmung · Bewegung">bodenständig, vertrauenswürdig, materialnah<small>token-tech-praezise</small></td>
            <td class="mus" data-th="Button-Muster"><ul><li><a href="../../hover/fuellung-vom-eintrittspunkt/index.html">fuellung-vom-eintrittspunkt</a><i>?v=basis</i></li><li><a href="../../buttons/kontur-button-zeichnen/index.html">kontur-button-zeichnen</a><i>?v=ecken</i></li></ul></td>
            <td class="warum" data-th="Warum">Ein Signalton nur für Anfrage und Anruf: Die Füllung macht ihn beim Zeigen satt. Nebenwege wie Leistungen und Referenzen bekommen eine Kontur mit Eckklammern. Magnet ist ausgeschlossen (Agentur-Geste).</td>
          </tr>
          <tr data-rezept="fahrschule-freundlich-buchbar">
            <th scope="row">Fahrschule: freundlich und buchbar<small>fahrschule-freundlich-buchbar</small></th>
            <td class="stim" data-th="Stimmung · Bewegung">freundlich, ermutigend, klar<small>token-federnd-verspielt</small></td>
            <td class="mus" data-th="Button-Muster"><ul><li><a href="../../buttons/tiefen-taste-3d/index.html">tiefen-taste-3d</a><i>?v=stapel</i></li><li><a href="../../mikroanimationen/button-zustaende/index.html">button-zustaende</a></li></ul></td>
            <td class="warum" data-th="Warum">Freundlich und ermutigend, token-federnd-verspielt: Die Taste federt nur am Button, nicht in Formularfeldern. Die Anmeldung zeigt Laden und Erfolg. Halten-zum-Bestätigen ist ausgeschlossen.</td>
          </tr>
          <tr data-rezept="immobilien-diskret-hochwertig">
            <th scope="row">Immobilien: diskret und hochwertig<small>immobilien-diskret-hochwertig</small></th>
            <td class="stim" data-th="Stimmung · Bewegung">seriös, hochwertig, ruhig<small>token-editorial-langsam</small></td>
            <td class="mus" data-th="Button-Muster"><ul><li><a href="../../buttons/pfeil-icon-button/index.html">pfeil-icon-button</a><i>?v=tausch</i></li><li><a href="../../mikroanimationen/button-zustaende/index.html">button-zustaende</a></li></ul></td>
            <td class="warum" data-th="Warum">Seriös, token-editorial-langsam: dunkle Pille, nur der Pfeil bewegt sich. „Bewertung anfragen“ bestätigt sich ruhig am Knopf. Keine Tiefe, kein Glanz.</td>
          </tr>
          <tr data-rezept="gastro-warm-appetitlich">
            <th scope="row">Gastronomie: warm und einladend<small>gastro-warm-appetitlich</small></th>
            <td class="stim" data-th="Stimmung · Bewegung">warm, einladend, persönlich<small>token-editorial-langsam</small></td>
            <td class="mus" data-th="Button-Muster"><ul><li><a href="../../buttons/pfeil-icon-button/index.html">pfeil-icon-button</a><i>?v=tausch</i></li><li><a href="../../mikroanimationen/druck-feedback/index.html">druck-feedback</a></li></ul></td>
            <td class="warum" data-th="Warum">Warm und einladend, meist mobil: „Tisch reservieren“ als ruhige Pille, nur der Pfeil tauscht. Tippen muss sich gut anfühlen, darum antwortet der Knopf mit spürbarem Druck. Kein Effekt, der vom Essen ablenkt.</td>
          </tr>
          <tr data-rezept="boutique-hotel-gastgeber">
            <th scope="row">Boutique-Hotel: Gastgeber mit Haltung<small>boutique-hotel-gastgeber</small></th>
            <td class="stim" data-th="Stimmung · Bewegung">gastfreundlich, entspannt, hochwertig<small>token-luxus-weich</small></td>
            <td class="mus" data-th="Button-Muster"><ul><li><a href="../../buttons/pfeil-icon-button/index.html">pfeil-icon-button</a><i>?v=tausch</i></li><li><a href="../../buttons/glas-button/index.html">glas-button</a><i>?v=frost</i></li></ul></td>
            <td class="warum" data-th="Warum">Die Fotos tragen die Stimmung: Buchen und Formulare als Pille in der Hausfarbe mit tauschendem Pfeil, Glas nur über dem Hero-Foto. Magnet ist ausgeschlossen, Bewegung bleibt ruhig (token-luxus-weich).</td>
          </tr>
          <tr data-rezept="kreativstudio-buehne">
            <th scope="row">Kreativstudio: Studio-Bühne<small>kreativstudio-buehne</small></th>
            <td class="stim" data-th="Stimmung · Bewegung">laut, selbstbewusst, kinematisch<small>token-editorial-langsam</small></td>
            <td class="mus" data-th="Button-Muster"><ul><li><a href="../../buttons/pfeil-icon-button/index.html">pfeil-icon-button</a><i>?v=kreis-expand</i></li><li><a href="../../schrift-animationen/text-roll-hover/index.html">text-roll-hover</a></li></ul></td>
            <td class="warum" data-th="Warum">Laut und selbstbewusst, Schwarz-Weiß plus ein Signalton: Der Kreis wird beim Kontakt-CTA zur Signalfläche, Text-Roll ist die Signatur in Navigation und Links. Kein Glow.</td>
          </tr>
          <tr data-rezept="freelancer-stille-visitenkarte">
            <th scope="row">Freelancer: Stille Visitenkarte<small>freelancer-stille-visitenkarte</small></th>
            <td class="stim" data-th="Stimmung · Bewegung">ruhig, präzise, persönlich<small>token-tech-praezise</small></td>
            <td class="mus" data-th="Button-Muster"><ul><li><a href="../../buttons/pfeil-icon-button/index.html">pfeil-icon-button</a><i>?v=seitenwechsel</i></li><li><a href="../../mikroanimationen/kopieren-feedback/index.html">kopieren-feedback</a></li></ul></td>
            <td class="warum" data-th="Warum">Ruhig und präzise, Graustufen: Konturpille mit wanderndem Kreis, „E-Mail kopieren“ bestätigt sich am Knopf. Magnet und Cursor-Effekte sind ausgeschlossen.</td>
          </tr>
          <tr data-rezept="fotograf-film-bild-zuerst">
            <th scope="row">Fotografie und Film: Bild zuerst<small>fotograf-film-bild-zuerst</small></th>
            <td class="stim" data-th="Stimmung · Bewegung">zurückhaltend, filmisch, kuratiert<small>token-kinetisch-inout</small></td>
            <td class="mus" data-th="Button-Muster"><ul><li><a href="../../buttons/kontur-button-zeichnen/index.html">kontur-button-zeichnen</a><i>?v=zeichnen</i></li><li><a href="../../buttons/pfeil-icon-button/index.html">pfeil-icon-button</a><i>?v=linie</i></li></ul></td>
            <td class="warum" data-th="Warum">Bild zuerst: Buttons bleiben Kontur oder Textlink, damit keine Fläche Farbe ins Bild wirft. Grain und Filter sind ausgeschlossen, weil sie fremde Textur über Werke legen.</td>
          </tr>
          <tr data-rezept="mode-beauty-kollektion">
            <th scope="row">Mode und Beauty: Kollektion und Ritual<small>mode-beauty-kollektion</small></th>
            <td class="stim" data-th="Stimmung · Bewegung">kuratiert, ruhig, warm<small>token-luxus-weich</small></td>
            <td class="mus" data-th="Button-Muster"><ul><li><a href="../../buttons/glas-button/index.html">glas-button</a><i>?v=getoent</i></li><li><a href="../../schrift-animationen/text-roll-hover/index.html">text-roll-hover</a></li></ul></td>
            <td class="warum" data-th="Warum">Kuratiert und ruhig: getöntes Glas über dem Kampagnenbild, im Shop leise Text-Rollen in Light/Regular. Warenkorb-Flug und Konfetti sind ausgeschlossen.</td>
          </tr>
          <tr data-rezept="kultur-programm-haltung">
            <th scope="row">Kultur: Programm und Haltung<small>kultur-programm-haltung</small></th>
            <td class="stim" data-th="Stimmung · Bewegung">sachlich, grafisch, zugänglich<small>token-swiss-knackig</small></td>
            <td class="mus" data-th="Button-Muster"><ul><li><a href="../../hover/fuellung-vom-eintrittspunkt/index.html">fuellung-vom-eintrittspunkt</a><i>?v=pixel</i></li><li><a href="../../buttons/kontur-button-zeichnen/index.html">kontur-button-zeichnen</a><i>?v=ecken</i></li></ul></td>
            <td class="warum" data-th="Warum">Grafisch und sachlich, token-swiss-knackig: Pixel-Füllung im Takt statt Überschwinger (die sind ausgeschlossen), Eckklammern wie Passermarken für Nebenaktionen.</td>
          </tr>
          <tr data-rezept="luxus-manufaktur-stille">
            <th scope="row">Luxus und Manufaktur: Stille<small>luxus-manufaktur-stille</small></th>
            <td class="stim" data-th="Stimmung · Bewegung">luxuriös, präzise, ruhig<small>token-toggle-asymmetrisch</small></td>
            <td class="mus" data-th="Button-Muster"><ul><li><a href="../../buttons/kontur-button-zeichnen/index.html">kontur-button-zeichnen</a><i>?v=doppel</i></li><li><a href="../../buttons/pfeil-icon-button/index.html">pfeil-icon-button</a><i>?v=tausch</i></li></ul></td>
            <td class="warum" data-th="Warum">Luxuriös und still, Messing nur als Linie: Die Kontur zeichnet sich, eine Fläche gibt es nur für die Hauptaktion. Magnet und Schimmer sind ausgeschlossen.</td>
          </tr>
          <tr data-rezept="saas-produkt-praezise">
            <th scope="row">SaaS &amp; KI: das Produkt zeigt sich selbst<small>saas-produkt-praezise</small></th>
            <td class="stim" data-th="Stimmung · Bewegung">präzise, technisch, ruhig<small>token-tech-praezise</small></td>
            <td class="mus" data-th="Button-Muster"><ul><li><a href="../../buttons/button-gruppe-expressiv/index.html">button-gruppe-expressiv</a><i>?v=split</i></li><li><a href="../../mikroanimationen/kopieren-feedback/index.html">kopieren-feedback</a></li></ul></td>
            <td class="warum" data-th="Warum">Das Produkt zeigt sich selbst, token-tech-praezise: Gruppen und Split-Button wie in der App, Kopieren für Befehle und Schlüssel. Magnet und Glitzer sind ausgeschlossen.</td>
          </tr>
          <tr data-rezept="kanzlei-beratung-souveraen">
            <th scope="row">Kanzlei &amp; Beratung: Haltung und Klarheit<small>kanzlei-beratung-souveraen</small></th>
            <td class="stim" data-th="Stimmung · Bewegung">seriös, souverän, klar<small>token-swiss-knackig</small></td>
            <td class="mus" data-th="Button-Muster"><ul><li><a href="../../buttons/pfeil-icon-button/index.html">pfeil-icon-button</a><i>?v=linie</i></li><li><a href="../../mikroanimationen/button-zustaende/index.html">button-zustaende</a></li></ul></td>
            <td class="warum" data-th="Warum">Seriös und zurückhaltend: Textlink mit Stripe-Pfeil für Rechtsgebiete, das Kontaktformular zeigt Laden und Eingang ohne Show. Magnet und Custom-Cursor sind ausgeschlossen.</td>
          </tr>
          <tr data-rezept="praxis-gesundheit-ruhig">
            <th scope="row">Praxis &amp; Therapie: ruhig und zugewandt<small>praxis-gesundheit-ruhig</small></th>
            <td class="stim" data-th="Stimmung · Bewegung">ruhig, vertrauensvoll, warm<small>token-tech-praezise</small></td>
            <td class="mus" data-th="Button-Muster"><ul><li><a href="../../mikroanimationen/button-zustaende/index.html">button-zustaende</a></li><li><a href="../../buttons/pfeil-icon-button/index.html">pfeil-icon-button</a><i>?v=linie</i></li></ul></td>
            <td class="warum" data-th="Warum">Ruhig und zugänglich, Kontrast vor Effekt: „Termin anfragen“ bestätigt sich klar, Behandlungen führen per Textlink weiter. Magnet und Grain sind ausgeschlossen.</td>
          </tr>
          <tr data-rezept="kurs-coaching-lernweg">
            <th scope="row">Online-Kurs &amp; Coaching: klarer Lernweg<small>kurs-coaching-lernweg</small></th>
            <td class="stim" data-th="Stimmung · Bewegung">klar, ermutigend, persönlich<small>token-federnd-verspielt</small></td>
            <td class="mus" data-th="Button-Muster"><ul><li><a href="../../buttons/tiefen-taste-3d/index.html">tiefen-taste-3d</a><i>?v=stapel</i></li><li><a href="../../glas-material/verlaufs-rahmen/index.html">verlaufs-rahmen</a><i>?v=button</i></li></ul></td>
            <td class="warum" data-th="Warum">Ermutigend und klar, token-federnd-verspielt: Die Taste lädt zum Klicken ein, der Lichtlauf um „Platz sichern“ läuft nur bei Hover und Fokus. Kein Countdown-Druck.</td>
          </tr>
          <tr data-rezept="d2c-produkt-zuerst">
            <th scope="row">Onlineshop &amp; Produktmarke: Produkt zuerst<small>d2c-produkt-zuerst</small></th>
            <td class="stim" data-th="Stimmung · Bewegung">sympathisch, direkt, hochwertig<small>token-toggle-asymmetrisch</small></td>
            <td class="mus" data-th="Button-Muster"><ul><li><a href="../../buttons/button-gruppe-expressiv/index.html">button-gruppe-expressiv</a><i>?v=split</i></li><li><a href="../../glas-material/grain-noise-overlay/index.html">grain-noise-overlay</a><i>?v=button</i></li></ul></td>
            <td class="warum" data-th="Warum">Sympathisch und direkt: Split-Button für „In den Warenkorb“ mit Nebenformen, körnige Fläche für die Kaufbox. Produktfotos bleiben unverfälscht.</td>
          </tr>
          <tr data-rezept="verein-nonprofit-wirkung">
            <th scope="row">Verein &amp; Non-Profit: Wirkung zeigen<small>verein-nonprofit-wirkung</small></th>
            <td class="stim" data-th="Stimmung · Bewegung">engagiert, glaubwürdig, nahbar<small>token-kinetisch-inout</small></td>
            <td class="mus" data-th="Button-Muster"><ul><li><a href="../../mikroanimationen/button-zustaende/index.html">button-zustaende</a></li><li><a href="../../hover/fuellung-vom-eintrittspunkt/index.html">fuellung-vom-eintrittspunkt</a><i>?v=basis</i></li></ul></td>
            <td class="warum" data-th="Warum">Glaubwürdig und sparsam: „Jetzt spenden“ zeigt Laden und Dank am Knopf, die Füllung kostet nichts. Hochglanz wie Glas und Holo passt nicht zu Spendengeld.</td>
          </tr>
          <tr data-rezept="friseur-salon-handschrift">
            <th scope="row">Salon: Handschrift und Termin<small>friseur-salon-handschrift</small></th>
            <td class="stim" data-th="Stimmung · Bewegung">stilbewusst, persönlich, warm<small>token-studio-signatur</small></td>
            <td class="mus" data-th="Button-Muster"><ul><li><a href="../../hover/fuellung-vom-eintrittspunkt/index.html">fuellung-vom-eintrittspunkt</a><i>?v=basis</i></li><li><a href="../../hover/clip-path-form-hover/index.html">clip-path-form-hover</a><i>?v=basis</i></li></ul></td>
            <td class="warum" data-th="Warum">Stilbewusst und warm, ein Lackrot nur für „Termin buchen“: Füllung vom Eintrittspunkt, als Akzent die Pfeil-Form. Magnet und SVG-Verzerrung sind ausgeschlossen.</td>
          </tr>
          <tr data-rezept="fitness-studio-rhythmus">
            <th scope="row">Studio: Rhythmus und Kursplan<small>fitness-studio-rhythmus</small></th>
            <td class="stim" data-th="Stimmung · Bewegung">energisch, direkt, motivierend<small>token-brutal-hart</small></td>
            <td class="mus" data-th="Button-Muster"><ul><li><a href="../../buttons/tiefen-taste-3d/index.html">tiefen-taste-3d</a><i>?v=versatz-brutal</i></li><li><a href="../../hover/fuellung-vom-eintrittspunkt/index.html">fuellung-vom-eintrittspunkt</a><i>?v=pixel</i></li></ul></td>
            <td class="warum" data-th="Warum">Energisch, token-brutal-hart: harter Versatz und Pixel-Füllung im Takt, die Limette als Fläche. Verlaufsrahmen und Glow sind ausgeschlossen (Gym-Klischee).</td>
          </tr>
          <tr data-rezept="pflege-dienst-naehe">
            <th scope="row">Pflegedienst: Nähe und Klartext<small>pflege-dienst-naehe</small></th>
            <td class="stim" data-th="Stimmung · Bewegung">nah, verlässlich, klar<small>token-toggle-asymmetrisch</small></td>
            <td class="mus" data-th="Button-Muster"><ul><li><a href="../../mikroanimationen/button-zustaende/index.html">button-zustaende</a></li><li><a href="../../buttons/pfeil-icon-button/index.html">pfeil-icon-button</a><i>?v=linie</i></li></ul></td>
            <td class="warum" data-th="Warum">Nah und verlässlich, viele ältere Leser: große Knöpfe, Laden und Bestätigung in Worten, Wege zu Leistungen als Textlink mit Pfeil. Kein Glas (Kontrast), kein Magnet.</td>
          </tr>
          <tr data-rezept="musik-kuenstler-buehne">
            <th scope="row">Musik und Kunst: Ära und Bühne<small>musik-kuenstler-buehne</small></th>
            <td class="stim" data-th="Stimmung · Bewegung">laut, experimentell, eigenständig<small>token-brutal-hart</small></td>
            <td class="mus" data-th="Button-Muster"><ul><li><a href="../../buttons/tiefen-taste-3d/index.html">tiefen-taste-3d</a><i>?v=versatz-brutal</i></li><li><a href="../../buttons/kontur-button-zeichnen/index.html">kontur-button-zeichnen</a><i>?v=laufend</i></li></ul></td>
            <td class="warum" data-th="Warum">Laut und eckig wie ein Plakat, token-brutal-hart: Die harte Taste gilt nur für die eine Haupthandlung („Anhören“, „Tickets“). Termine und Downloads bekommen die laufende Kontur. Glas und Lichtrahmen sind ausgeschlossen, neben Dither oder Marmor wären sie ein zweiter Effekt.</td>
          </tr>
          <tr data-rezept="industrie-b2b-mittelstand">
            <th scope="row">Industrie-Mittelstand: Datenblatt und Fachperson<small>industrie-b2b-mittelstand</small></th>
            <td class="stim" data-th="Stimmung · Bewegung">präzise, sachlich, belastbar<small>token-swiss-knackig</small></td>
            <td class="mus" data-th="Button-Muster"><ul><li><a href="../../mikroanimationen/button-zustaende/index.html">button-zustaende</a></li><li><a href="../../buttons/kontur-button-zeichnen/index.html">kontur-button-zeichnen</a><i>?v=ecken</i></li></ul></td>
            <td class="warum" data-th="Warum">Sachlich wie ein Datenblatt: „Anfrage senden“ zeigt Laden und Eingang mit Vorgangsnummer, Nebenwege wie Datenblatt und Download als Kontur mit Eckklammern. Glas, Lichtrahmen und Magnet sind ausgeschlossen (SaaS-Glanz, Agentur-Geste).</td>
          </tr>
          <tr data-rezept="kfz-werkstatt-autohaus">
            <th scope="row">Kfz-Werkstatt und Autohaus: Festpreis, Termin, fertig<small>kfz-werkstatt-autohaus</small></th>
            <td class="stim" data-th="Stimmung · Bewegung">bodenständig, schnell, klar<small>token-toggle-asymmetrisch</small></td>
            <td class="mus" data-th="Button-Muster"><ul><li><a href="../../buttons/tiefen-taste-3d/index.html">tiefen-taste-3d</a><i>?v=stapel</i></li><li><a href="../../buttons/pfeil-icon-button/index.html">pfeil-icon-button</a><i>?v=tausch</i></li></ul></td>
            <td class="warum" data-th="Warum">Schnell und bodenständig: Die Tiefen-Taste gibt es nur für „Termin buchen“, höchstens einmal je Ansicht. Alle anderen Knöpfe bleiben flach mit tauschendem Pfeil. Glas über Hallenfotos und Magnet sind ausgeschlossen.</td>
          </tr>
          <tr data-rezept="arbeitgeber-karriere">
            <th scope="row">Arbeitgeber: Einblick statt Floskel<small>arbeitgeber-karriere</small></th>
            <td class="stim" data-th="Stimmung · Bewegung">ehrlich, nahbar, konkret<small>token-federnd-verspielt</small></td>
            <td class="mus" data-th="Button-Muster"><ul><li><a href="../../hover/fuellung-vom-eintrittspunkt/index.html">fuellung-vom-eintrittspunkt</a><i>?v=basis</i></li><li><a href="../../buttons/pfeil-icon-button/index.html">pfeil-icon-button</a><i>?v=linie</i></li></ul></td>
            <td class="warum" data-th="Warum">Ehrlich und nahbar, meist am Handy: Klatschmohn mit Füllung vom Eintrittspunkt nur für „Bewerben“. Links zu Stellen als Textlink mit Pfeil. Magnet und die Ecken-Signatur der Pflege sind ausgeschlossen.</td>
          </tr>
          <tr data-rezept="bestattung-wuerdig">
            <th scope="row">Bestattung: würdig und klar<small>bestattung-wuerdig</small></th>
            <td class="stim" data-th="Stimmung · Bewegung">ruhig, würdig, klar<small>token-luxus-weich</small></td>
            <td class="mus" data-th="Button-Muster"><ul><li><a href="../../mikroanimationen/button-zustaende/index.html">button-zustaende</a></li><li><a href="../../buttons/pfeil-icon-button/index.html">pfeil-icon-button</a><i>?v=linie</i></li></ul></td>
            <td class="warum" data-th="Warum">Ruhig und würdig: „Rückruf anfordern“ zeigt Laden und Bestätigung in Worten, ohne Überschwingen. Weitere Wege als Textlink mit Pfeil, keine Pille. Druck-Feedback, Herz und Magnet sind ausgeschlossen, weil sie verspielt wirken.</td>
          </tr>
          <tr data-rezept="eventlocation-hochzeit">
            <th scope="row">Eventlocation: ein Tag, der in die Nacht geht<small>eventlocation-hochzeit</small></th>
            <td class="stim" data-th="Stimmung · Bewegung">festlich, emotional, großzügig<small>token-studio-signatur</small></td>
            <td class="mus" data-th="Button-Muster"><ul><li><a href="../../hover/fuellung-vom-eintrittspunkt/index.html">fuellung-vom-eintrittspunkt</a><i>?v=basis</i></li><li><a href="../../buttons/kontur-button-zeichnen/index.html">kontur-button-zeichnen</a><i>?v=doppel</i></li></ul></td>
            <td class="warum" data-th="Warum">Festlich über Licht und Schrift: Mohnrot mit Füllung vom Eintrittspunkt nur für die Haupthandlung (Anfragen, Datum übernehmen), Nebenwege als Messing-Doppelkontur. Glas, Herz und Magnet sind ausgeschlossen.</td>
          </tr>
          <tr data-rezept="weingut-hofladen-herkunft">
            <th scope="row">Weingut und Hofladen: Herkunft zuerst<small>weingut-hofladen-herkunft</small></th>
            <td class="stim" data-th="Stimmung · Bewegung">bodenständig, klar, warm<small>token-luxus-weich</small></td>
            <td class="mus" data-th="Button-Muster"><ul><li><a href="../../mikroanimationen/button-zustaende/index.html">button-zustaende</a></li><li><a href="../../buttons/kontur-button-zeichnen/index.html">kontur-button-zeichnen</a><i>?v=ecken</i></li></ul></td>
            <td class="warum" data-th="Warum">Herkunft zuerst, eckig wie ein Etikett: Buntsandstein gefüllt nur für Kaufen und Tickets, mit Laden und „Im Warenkorb“ am Knopf. Nebenwege als Kontur mit Eckklammern wie Passermarken. Das Herz ist ausgeschlossen.</td>
          </tr>
        </tbody>
      </table>
    </div>
  </section>
</main>

<footer class="rahmen fuss">
  <p><b>Quermaß</b> · Büro für Interface-Systeme · Marburg an der Lahn</p>
  <p class="mono">Button-System 2.3 · Stand 02.11.2026 · Werkzeug, keine Kundensektion</p>
</footer>

<script>
(() => {
  const root = document.documentElement;
  const $ = (s, el = document) => el.querySelector(s);
  const $$ = (s, el = document) => [...el.querySelectorAll(s)];
  const reduziert = () => root.classList.contains('reduziert');
  const REZEPTE = {"architektur-ruhiges-raster": {"ja": [["pfeil-icon-button", "linie"], ["kontur-button-zeichnen", "ecken"]], "nein": []}, "handwerk-werkstatt-klartext": {"ja": [["fuellung-vom-eintrittspunkt", "basis"], ["kontur-button-zeichnen", "ecken"]], "nein": ["magnetische-elemente"]}, "fahrschule-freundlich-buchbar": {"ja": [["tiefen-taste-3d", "stapel"], ["button-zustaende", ""]], "nein": ["hold-to-confirm"]}, "immobilien-diskret-hochwertig": {"ja": [["pfeil-icon-button", "tausch"], ["button-zustaende", ""]], "nein": []}, "gastro-warm-appetitlich": {"ja": [["pfeil-icon-button", "tausch"], ["druck-feedback", ""]], "nein": []}, "boutique-hotel-gastgeber": {"ja": [["pfeil-icon-button", "tausch"], ["glas-button", "frost"]], "nein": ["magnetische-elemente"]}, "kreativstudio-buehne": {"ja": [["pfeil-icon-button", "kreis-expand"], ["text-roll-hover", ""]], "nein": []}, "freelancer-stille-visitenkarte": {"ja": [["pfeil-icon-button", "seitenwechsel"], ["kopieren-feedback", ""]], "nein": ["magnetische-elemente"]}, "fotograf-film-bild-zuerst": {"ja": [["kontur-button-zeichnen", "zeichnen"], ["pfeil-icon-button", "linie"]], "nein": ["grain-noise-overlay"]}, "mode-beauty-kollektion": {"ja": [["glas-button", "getoent"], ["text-roll-hover", ""]], "nein": []}, "kultur-programm-haltung": {"ja": [["fuellung-vom-eintrittspunkt", "pixel"], ["kontur-button-zeichnen", "ecken"]], "nein": []}, "luxus-manufaktur-stille": {"ja": [["kontur-button-zeichnen", "doppel"], ["pfeil-icon-button", "tausch"]], "nein": ["magnetische-elemente"]}, "saas-produkt-praezise": {"ja": [["button-gruppe-expressiv", "split"], ["kopieren-feedback", ""]], "nein": ["magnetische-elemente"]}, "kanzlei-beratung-souveraen": {"ja": [["pfeil-icon-button", "linie"], ["button-zustaende", ""]], "nein": ["magnetische-elemente"]}, "praxis-gesundheit-ruhig": {"ja": [["button-zustaende", ""], ["pfeil-icon-button", "linie"]], "nein": ["magnetische-elemente", "grain-noise-overlay"]}, "kurs-coaching-lernweg": {"ja": [["tiefen-taste-3d", "stapel"], ["verlaufs-rahmen", "button"]], "nein": []}, "d2c-produkt-zuerst": {"ja": [["button-gruppe-expressiv", "split"], ["grain-noise-overlay", "button"]], "nein": []}, "verein-nonprofit-wirkung": {"ja": [["button-zustaende", ""], ["fuellung-vom-eintrittspunkt", "basis"]], "nein": []}, "friseur-salon-handschrift": {"ja": [["fuellung-vom-eintrittspunkt", "basis"], ["clip-path-form-hover", "basis"]], "nein": ["magnetische-elemente"]}, "fitness-studio-rhythmus": {"ja": [["tiefen-taste-3d", "versatz-brutal"], ["fuellung-vom-eintrittspunkt", "pixel"]], "nein": ["verlaufs-rahmen", "magnetische-elemente"]}, "pflege-dienst-naehe": {"ja": [["button-zustaende", ""], ["pfeil-icon-button", "linie"]], "nein": ["magnetische-elemente"]}, "musik-kuenstler-buehne": {"ja": [["tiefen-taste-3d", "versatz-brutal"], ["kontur-button-zeichnen", "laufend"]], "nein": ["glas-button", "verlaufs-rahmen"]}, "industrie-b2b-mittelstand": {"ja": [["button-zustaende", ""], ["kontur-button-zeichnen", "ecken"]], "nein": ["verlaufs-rahmen", "glas-button", "magnetische-elemente"]}, "kfz-werkstatt-autohaus": {"ja": [["tiefen-taste-3d", "stapel"], ["pfeil-icon-button", "tausch"]], "nein": ["glas-button", "magnetische-elemente"]}, "arbeitgeber-karriere": {"ja": [["fuellung-vom-eintrittspunkt", "basis"], ["pfeil-icon-button", "linie"]], "nein": ["corner-shape-eckenformen", "magnetische-elemente"]}, "bestattung-wuerdig": {"ja": [["button-zustaende", ""], ["pfeil-icon-button", "linie"]], "nein": ["druck-feedback", "like-herz-burst", "magnetische-elemente"]}, "eventlocation-hochzeit": {"ja": [["fuellung-vom-eintrittspunkt", "basis"], ["kontur-button-zeichnen", "doppel"]], "nein": ["glas-button", "like-herz-burst", "magnetische-elemente"]}, "weingut-hofladen-herkunft": {"ja": [["button-zustaende", ""], ["kontur-button-zeichnen", "ecken"]], "nein": ["like-herz-burst"]}};
  const WELTNAME = { buehne: 'Studio-Bühne', manufaktur: 'Manufaktur-Stille', fahrschule: 'Fahrschule' };

  /* ---------- Tokens lesen, Kontrast rechnen ---------- */
  const tok = (name, el = root) => getComputedStyle(el).getPropertyValue(name).trim();
  function farbe(wert) {
    if (!wert || wert === 'transparent') return null;
    let m = wert.match(/^#([0-9a-f]{3}|[0-9a-f]{6})$/i);
    if (m) { let h = m[1]; if (h.length === 3) h = h.replace(/./g, c => c + c); return [0, 2, 4].map(i => parseInt(h.slice(i, i + 2), 16)); }
    m = wert.match(/rgba?\(([^)]+)\)/);
    if (m) return m[1].split(/[\s,/]+/).slice(0, 3).map(Number);
    return null;
  }
  const lum = rgb => { const f = c => { c /= 255; return c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4; }; return 0.2126 * f(rgb[0]) + 0.7152 * f(rgb[1]) + 0.0722 * f(rgb[2]); };
  function kontrast(fgName, bgName, el = root) {
    const a = farbe(tok(fgName, el)), b = farbe(tok(bgName, el)) || farbe(tok('--flaeche', el));
    if (!a || !b) return null;
    const [x, y] = [lum(a), lum(b)].sort((p, q) => q - p);
    return (x + 0.05) / (y + 0.05);
  }
  const zahl = k => (Math.floor(k * 10) / 10).toLocaleString('de-DE', { minimumFractionDigits: 1, maximumFractionDigits: 1 }) + ' : 1';

  /* Kurve als kleine Grafik */
  function kurvenPunkte(str) {
    let m = str.match(/cubic-bezier\(([^)]+)\)/);
    if (m) {
      const [x1, y1, x2, y2] = m[1].split(',').map(Number), pts = [];
      for (let i = 0; i <= 32; i++) { const t = i / 32, u = 1 - t; pts.push([3 * u * u * t * x1 + 3 * u * t * t * x2 + t ** 3, 3 * u * u * t * y1 + 3 * u * t * t * y2 + t ** 3]); }
      return pts;
    }
    m = str.match(/linear\(([^)]+)\)/);
    if (m) {
      const teile = m[1].split(',').map(s => s.trim().split(/\s+/)), n = teile.length;
      return teile.map((t, i) => [t[1] ? parseFloat(t[1]) / 100 : i / (n - 1), parseFloat(t[0])]);
    }
    if (/linear/.test(str)) return [[0, 0], [1, 1]];
    return null;
  }
  function kurvenSvg(str) {
    const p = kurvenPunkte(str);
    if (!p) return '';
    const ys = p.map(q => q[1]), lo = Math.min(0, ...ys), hi = Math.max(1, ...ys), W = 46, H = 32, pad = 3;
    const sx = x => pad + x * (W - 2 * pad), sy = y => H - pad - (y - lo) / (hi - lo) * (H - 2 * pad);
    const d = p.map((q, i) => (i ? 'L' : 'M') + sx(q[0]).toFixed(1) + ' ' + sy(q[1]).toFixed(1)).join(' ');
    return `<svg class="kurve" viewBox="0 0 ${W} ${H}" aria-hidden="true"><line x1="${pad}" x2="${W - pad}" y1="${sy(1)}" y2="${sy(1)}"/><line x1="${pad}" x2="${W - pad}" y1="${sy(0)}" y2="${sy(0)}"/><path d="${d}"/></svg>`;
  }
  const kurzKurve = s => /linear\(/.test(s) ? 'linear() Feder, ~16 % Überschwinger' : s.replace(/\s+/g, ' ');

  function fuelleTokens() {
    $$('td[data-tok]').forEach(td => {
      td.textContent = td.dataset.tok.split(',').map(n => {
        let w = tok(n);
        if (n === '--b-schrift') w = w.split(',')[0].replace(/['"]/g, '');
        return w;
      }).join(' / ');
    });
    $$('td[data-kurve]').forEach(td => { const s = tok(td.dataset.kurve); td.innerHTML = kurvenSvg(s) + '<span>' + kurzKurve(s) + '</span>'; });
    const name = root.dataset.v === 'rezepte' ? WELTNAME[root.dataset.welt] : (root.dataset.v === 'dunkel' ? 'Quermaß dunkel' : 'Quermaß hell');
    $$('[data-welt-name]').forEach(e => { e.textContent = name; });
  }
  function fuelleMatrix() {
    $$('#matrix output[data-fg]').forEach(o => {
      const k = kontrast(o.dataset.fg, o.dataset.bg);
      if (!k) { o.textContent = ''; return; }
      const ring = o.dataset.art === 'ring', ok = ring ? k >= 3 : k >= 4.5;
      o.innerHTML = (ring ? 'Ring ' : '') + '<b>' + zahl(k) + '</b> ' + (ok ? (ring ? '≥ 3' : 'AA') : 'zu wenig');
    });
  }

  /* ---------- Maßlinien am Spezimen ---------- */
  const spez = $('#spez'), mass = $('#mass');
  function masse() {
    if (!spez || !mass || !spez.offsetParent) return;
    const feld = spez.parentElement, W = feld.clientWidth, H = feld.clientHeight;
    const x = spez.offsetLeft, y = spez.offsetTop, w = spez.offsetWidth, h = spez.offsetHeight;
    const px = parseFloat(tok('--b-px-l')) || 0, rad = tok('--b-radius');
    mass.setAttribute('viewBox', `0 0 ${W} ${H}`);
    mass.setAttribute('width', W); mass.setAttribute('height', H);
    const c = 'var(--markierung)', lx = x - 14, by = y + h + 14;
    mass.innerHTML = `<g stroke="${c}" stroke-width="1" fill="none">
      <line x1="${lx}" x2="${lx}" y1="${y}" y2="${y + h}"/><line x1="${lx - 4}" x2="${lx + 4}" y1="${y}" y2="${y}"/><line x1="${lx - 4}" x2="${lx + 4}" y1="${y + h}" y2="${y + h}"/>
      <line x1="${x}" x2="${x + px}" y1="${by}" y2="${by}"/><line x1="${x}" x2="${x}" y1="${by - 4}" y2="${by + 4}"/><line x1="${x + px}" x2="${x + px}" y1="${by - 4}" y2="${by + 4}"/>
      <line x1="${x}" x2="${x + w}" y1="${y - 14}" y2="${y - 14}" stroke-dasharray="2 3"/></g>
      <g fill="${c}" font-family="Geist Mono, monospace" font-size="10.5" letter-spacing=".06em">
      <text x="${lx - 8}" y="${y + h / 2 + 4}" text-anchor="end">${Math.round(h)}</text>
      <text x="${x + px + 6}" y="${by + 4}">${Math.round(px)} innen</text>
      <text x="${x + w}" y="${y - 20}" text-anchor="end">r ${rad.replace('px', '')} · ${Math.round(w)} breit</text></g>`;
  }

  /* ---------- Spezimen-Zustände ---------- */
  const FOLGE = ['ruhe', 'hover', 'fokus', 'druck', 'aus', 'laden', 'erfolg'];
  const ZNAME = { ruhe: 'Ruhe', hover: 'Hover', fokus: 'Fokus', druck: 'Druck', aus: 'Deaktiviert', laden: 'Laden', erfolg: 'Erfolg' };
  const ms = n => tok(n);
  function zustandsWerte(z) {
    switch (z) {
      case 'hover': return [`Farbe ${ms('--dauer-hover')} · ${kurzKurve(tok('--kurve-hover'))}`, kontrast('--p-fg-h', '--p-bg-h')];
      case 'fokus': return [`Ring ${tok('--b-fokus-breite')}, Versatz ${tok('--b-fokus-versatz')} · ${ms('--dauer-fokus')}`, kontrast('--b-fokus', '--grund'), 'ring'];
      case 'druck': return [`scale ${tok('--b-druck')} · ${ms('--dauer-druck-ein')} ein, ${ms('--dauer-druck-aus')} Feder`, kontrast('--p-fg-h', '--p-bg-d')];
      case 'aus': return ['keine · aria-disabled', kontrast('--d-fg', '--d-bg')];
      case 'laden': return [`Label ${ms('--dauer-label')} · Spinner ${ms('--dauer-spinner')} linear`, kontrast('--p-fg', '--p-bg')];
      case 'erfolg': return [`Häkchen ${ms('--dauer-haken')} · hält 1800ms`, kontrast('--ok-fg', '--ok-bg')];
      default: return ['keine', kontrast('--p-fg', '--p-bg')];
    }
  }
  let spezZ = 'ruhe';
  function zeigeWerte(z) {
    spezZ = z;
    $$('.spezimen__zustaende li').forEach(li => li.classList.toggle('ist-an', li.dataset.z === z));
    const [bew, k, art] = zustandsWerte(z);
    $('#w-zustand').textContent = ZNAME[z];
    $('#w-bewegung').textContent = bew;
    $('#w-kontrast').textContent = k ? (art === 'ring' ? 'Ring ' : 'Label ') + zahl(k) : '–';
  }
  function setzeKlassen(btn, z) {
    btn.classList.remove('ist-hover', 'ist-fokus', 'ist-druck', 'ist-laden', 'ist-erfolg', 'ist-aus');
    btn.removeAttribute('aria-busy');
    if (btn === spez) btn.removeAttribute('aria-disabled');
    if (z === 'ruhe') return;
    if (z === 'aus') { btn.setAttribute('aria-disabled', 'true'); return; }
    btn.classList.add('ist-' + z);
    if (z === 'laden') btn.setAttribute('aria-busy', 'true');
  }

  /* echte Bedienung des Spezimens */
  let spezLauf = 0;
  if (spez) {
    spez.addEventListener('pointerenter', () => { if (spezZ === 'ruhe' && matchMedia('(hover: hover)').matches) zeigeWerte('hover'); });
    spez.addEventListener('pointerleave', () => { if (spezZ === 'hover' || spezZ === 'druck') zeigeWerte(spez.matches(':focus-visible') ? 'fokus' : 'ruhe'); });
    spez.addEventListener('focus', () => { if (spez.matches(':focus-visible') && spezZ === 'ruhe') zeigeWerte('fokus'); });
    spez.addEventListener('blur', () => { if (spezZ === 'fokus') zeigeWerte('ruhe'); });
    spez.addEventListener('pointerdown', () => { if (spezZ !== 'laden' && spezZ !== 'erfolg') zeigeWerte('druck'); });
    spez.addEventListener('click', e => {
      if (!e.isTrusted) return;
      if (spez.getAttribute('aria-busy') === 'true' || spez.classList.contains('ist-erfolg')) return;
      const lauf = ++spezLauf;
      setzeKlassen(spez, 'laden'); zeigeWerte('laden'); $('#spez-status').textContent = 'Anfrage wird gesendet.';
      setTimeout(() => {
        if (lauf !== spezLauf) return;
        setzeKlassen(spez, 'erfolg'); zeigeWerte('erfolg'); $('#spez-status').textContent = 'Anfrage gesendet.';
        setTimeout(() => { if (lauf !== spezLauf) return; setzeKlassen(spez, 'ruhe'); zeigeWerte('ruhe'); }, 1800);
      }, 1400);
    });
  }

  /* ---------- Varianten und Welten ---------- */
  const VARIANTEN = ['hell', 'dunkel', 'rezepte'];
  let v = new URLSearchParams(location.search).get('v');
  if (!VARIANTEN.includes(v)) v = 'hell';
  function aktualisieren() { fuelleTokens(); fuelleMatrix(); masse(); zeigeWerte(spezZ); }
  function setzeVariante(nv, url) {
    v = nv; root.dataset.v = nv;
    if (!root.dataset.welt) root.dataset.welt = 'buehne';
    $$('[data-variante]').forEach(b => b.setAttribute('aria-pressed', String(b.dataset.variante === nv)));
    if (url) { const u = new URL(location.href); u.searchParams.set('v', nv); history.replaceState(history.state, '', u); }
    requestAnimationFrame(aktualisieren);
  }
  function setzeWelt(w) {
    root.dataset.welt = w;
    $$('.welten__wahl [data-welt]').forEach(b => b.setAttribute('aria-pressed', String(b.dataset.welt === w)));
    $$('[data-welt-panel]').forEach(p => p.classList.toggle('ist-aktiv', p.dataset.weltPanel === w));
    requestAnimationFrame(aktualisieren);
  }
  $$('[data-variante]').forEach(b => b.addEventListener('click', () => setzeVariante(b.dataset.variante, true)));
  $$('.welten__wahl [data-welt]').forEach(b => b.addEventListener('click', () => setzeWelt(b.dataset.welt)));
  $('#treffer-schalter').addEventListener('click', e => {
    const an = !root.hasAttribute('data-treffer');
    root.toggleAttribute('data-treffer', an); e.currentTarget.setAttribute('aria-pressed', String(an));
  });

  /* Lade-Knöpfe in den Welten */
  $$('[data-demo-laden]').forEach(btn => {
    btn.addEventListener('click', () => {
      if (btn.getAttribute('aria-busy') === 'true' || btn.classList.contains('ist-erfolg')) return;
      setzeKlassen(btn, 'laden');
      setTimeout(() => { setzeKlassen(btn, 'erfolg'); setTimeout(() => setzeKlassen(btn, 'ruhe'), 1800); }, 1400);
    });
  });

  /* ---------- Formular ---------- */
  const senden = $('#senden'), fOk = $('#f-ok'), hinweis = $('#senden-hinweis'), aStatus = $('#anfrage-status');
  function sendenFrei() {
    const frei = fOk.checked;
    senden.setAttribute('aria-disabled', String(!frei));
    hinweis.textContent = frei ? 'Wir antworten innerhalb von zwei Werktagen.' : 'Senden geht, sobald die Projektbedingungen bestätigt sind.';
    hinweis.classList.remove('ist-betont');
  }
  fOk.addEventListener('change', sendenFrei);
  $('#anfrage').addEventListener('submit', e => {
    e.preventDefault();
    if (senden.getAttribute('aria-disabled') === 'true') { hinweis.classList.add('ist-betont'); aStatus.textContent = 'Bitte zuerst die Projektbedingungen bestätigen.'; fOk.focus(); return; }
    if (senden.getAttribute('aria-busy') === 'true' || senden.classList.contains('ist-erfolg')) return;
    setzeKlassen(senden, 'laden'); aStatus.textContent = 'Angebot wird gesendet …';
    setTimeout(() => {
      setzeKlassen(senden, 'erfolg'); aStatus.textContent = 'Angebot gesendet. Antwort innerhalb von zwei Werktagen.';
      setTimeout(() => setzeKlassen(senden, 'ruhe'), 1800);
    }, 1400);
  });
  $('#anfrage').addEventListener('reset', () => { setTimeout(() => { sendenFrei(); aStatus.textContent = 'Eingaben verworfen.'; }); });
  $('#entwurf').addEventListener('click', () => {
    aStatus.textContent = 'Entwurf gespeichert um ' + new Date().toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit' }) + ' Uhr.';
  });

  /* ---------- Gefahr mit Rückfrage ---------- */
  const loeschen = $('#loeschen'), rueck = $('#rueckfrage'), lStatus = $('#liste-status');
  const archivZeile = loeschen.closest('li'), archivOriginal = archivZeile.innerHTML;
  function rueckfrage(auf) { rueck.hidden = !auf; $('#loeschen').setAttribute('aria-expanded', String(auf)); if (auf) $('#behalten').focus(); }
  function bindeLoeschen() {
    const btn = $('#loeschen');
    btn.addEventListener('click', () => rueckfrage(rueck.hidden));
  }
  bindeLoeschen();
  $('#behalten').addEventListener('click', () => { rueckfrage(false); $('#loeschen').focus(); lStatus.textContent = 'Archiv bleibt erhalten.'; });
  $('#endgueltig').addEventListener('click', () => {
    rueck.hidden = true;
    archivZeile.innerHTML = '<div><b>Archiv gelöscht</b><small>27 Projekte entfernt · 10 Sekunden rückgängig machbar</small></div><div class="werkzeuge"><button class="k k--tertiaer k--s" type="button" id="rueckgaengig">Rückgängig</button></div>';
    lStatus.textContent = 'Archiv gelöscht.';
    const r = $('#rueckgaengig'); r.focus();
    r.addEventListener('click', () => {
      archivZeile.innerHTML = archivOriginal; bindeLoeschen();
      const neu = $('#loeschen'); neu.setAttribute('aria-expanded', 'false'); neu.focus();
      lStatus.textContent = 'Archiv wiederhergestellt.';
    });
  });

  /* ---------- Galerie: Nachbauten ---------- */
  const status = (el, t) => { const s = el.closest('.karte__buehne').querySelector('[role=status]'); if (s) s.textContent = t; };
  $$('.g-zust').forEach(btn => btn.addEventListener('click', () => {
    if (btn.classList.contains('ist-laden') || btn.classList.contains('ist-ok')) return;
    btn.classList.add('ist-laden'); btn.setAttribute('aria-busy', 'true'); status(btn, 'Termin wird gebucht.');
    setTimeout(() => { btn.classList.replace('ist-laden', 'ist-ok'); btn.removeAttribute('aria-busy'); status(btn, 'Termin gebucht.');
      setTimeout(() => btn.classList.remove('ist-ok'), 1800); }, 1400);
  }));
  $$('[data-kopie]').forEach(btn => { let t; btn.addEventListener('click', () => {
    try { navigator.clipboard && navigator.clipboard.writeText(btn.dataset.kopie).catch(() => {}); } catch (e) {}
    btn.classList.add('ist-ok'); status(btn, 'E-Mail-Adresse kopiert.');
    clearTimeout(t); t = setTimeout(() => btn.classList.remove('ist-ok'), 2000);
  }); });
  $$('.g-herz').forEach(btn => btn.addEventListener('click', () => {
    const an = btn.getAttribute('aria-pressed') !== 'true', z = btn.parentElement.querySelector('[data-herz-zahl]');
    btn.setAttribute('aria-pressed', String(an));
    z.textContent = String(+z.textContent + (an ? 1 : -1));
    btn.classList.remove('ist-burst'); void btn.offsetWidth; if (an) btn.classList.add('ist-burst');
  }));
  $$('.g-menue').forEach(btn => btn.addEventListener('click', () => btn.setAttribute('aria-expanded', String(btn.getAttribute('aria-expanded') !== 'true'))));
  $$('.g-gruppe button').forEach(btn => btn.addEventListener('click', () => btn.setAttribute('aria-pressed', String(btn.getAttribute('aria-pressed') !== 'true'))));
  $$('.g-kuend').forEach(k => {
    const [s1, s2, s3] = ['.stufe1', '.stufe2', '.stufe3'].map(s => k.querySelector(s));
    const zeige = (s, f) => { [s1, s2, s3].forEach(x => { x.hidden = x !== s; }); if (f) f.focus(); };
    s1.querySelector('button').addEventListener('click', () => zeige(s2, s2.querySelector('.zwei')));
    s2.querySelector('.ab').addEventListener('click', () => zeige(s1, s1.querySelector('button')));
    s2.querySelector('.zwei').addEventListener('click', () => zeige(s3, s3.querySelector('button')));
    s3.querySelector('button').addEventListener('click', () => zeige(s1, s1.querySelector('button')));
  });

  /* Halten zum Bestätigen */
  $$('.g-halten').forEach(btn => {
    let p = 0, richtung = 0, last = 0, raf = 0, fertig = false, gehalten = false;
    const leer = btn.querySelector('.h-leer'), voll = btn.querySelector('.h-voll'), TEXT = leer.textContent;
    function tick(t) {
      const dt = Math.min(50, t - (last || t)); last = t;
      p = Math.max(0, Math.min(1, p + richtung * dt / 1200 * (richtung < 0 ? 3 : 1)));
      btn.style.setProperty('--p', p.toFixed(4));
      if (p >= 1 && !fertig) { fertig = true; richtung = 0; btn.classList.add('ist-ok'); leer.textContent = voll.textContent = 'Angenommen'; status(btn, 'Angebot angenommen.');
        setTimeout(() => { fertig = false; p = 0; btn.style.setProperty('--p', 0); btn.classList.remove('ist-ok'); leer.textContent = voll.textContent = TEXT; }, 2000); }
      if ((richtung > 0 && p < 1) || (richtung < 0 && p > 0)) raf = requestAnimationFrame(tick); else raf = 0;
    }
    const start = () => { if (fertig) return; gehalten = true; richtung = 1; last = 0; if (!raf) raf = requestAnimationFrame(tick); };
    const stopp = () => { if (fertig || !gehalten) return; gehalten = false; richtung = -1; last = 0; if (!raf) raf = requestAnimationFrame(tick); if (p < 1) status(btn, 'Zum Annehmen 1,2 Sekunden gedrückt halten.'); };
    btn.addEventListener('pointerdown', e => { btn.setPointerCapture && btn.setPointerCapture(e.pointerId); start(); });
    ['pointerup', 'pointercancel', 'lostpointercapture'].forEach(t => btn.addEventListener(t, stopp));
    btn.addEventListener('keydown', e => { if ((e.key === ' ' || e.key === 'Enter') && !e.repeat) { e.preventDefault(); start(); } });
    btn.addEventListener('keyup', e => { if (e.key === ' ' || e.key === 'Enter') { e.preventDefault(); stopp(); } });
    btn.addEventListener('contextmenu', e => e.preventDefault());
    btn._halten = { start, stopp };
  });

  /* Magnet */
  const feinZeiger = matchMedia('(hover: hover) and (pointer: fine)');
  $$('[data-magnet]').forEach(btn => {
    const label = btn.querySelector('span'); let ziel = [0, 0], ist = [0, 0], raf = 0, zeit = 0;
    function lauf(t) {
      const dt = zeit ? t - zeit : 16.7; zeit = t;
      const f = 1 - Math.pow(0.9, dt / 16.667);
      ist = ist.map((w, i) => w + (ziel[i] - w) * f);
      btn.style.translate = `${ist[0].toFixed(2)}px ${ist[1].toFixed(2)}px`;
      label.style.translate = `${(ist[0] * .5).toFixed(2)}px ${(ist[1] * .5).toFixed(2)}px`;
      if (Math.abs(ist[0] - ziel[0]) + Math.abs(ist[1] - ziel[1]) > .05) raf = requestAnimationFrame(lauf); else { raf = 0; zeit = 0; }
    }
    const setze = z => { ziel = z; if (!raf) raf = requestAnimationFrame(lauf); };
    btn._magnet = setze;
    btn.addEventListener('pointermove', e => {
      if (!feinZeiger.matches || reduziert()) return;
      const r = btn.getBoundingClientRect();
      setze([((e.clientX - r.left) / r.width - .5) * 24 * 2, ((e.clientY - r.top) / r.height - .5) * 24 * 2]);
    });
    btn.addEventListener('pointerleave', () => setze([0, 0]));
  });

  /* Füllung vom Eintrittspunkt */
  $$('[data-fuell]').forEach(btn => {
    function rein(x, y) {
      const r = btn.getBoundingClientRect();
      const rad = Math.max(Math.hypot(x, y), Math.hypot(r.width - x, y), Math.hypot(x, r.height - y), Math.hypot(r.width - x, r.height - y)) + 2;
      btn.classList.remove('ist-voll', 'ist-raus');
      btn.style.setProperty('--x', x + 'px'); btn.style.setProperty('--y', y + 'px'); btn.style.setProperty('--r', rad + 'px');
      void btn.offsetWidth; btn.classList.add('ist-voll');
    }
    function raus(x, y) { btn.style.setProperty('--x', x + 'px'); btn.style.setProperty('--y', y + 'px'); btn.classList.add('ist-raus'); btn.classList.remove('ist-voll'); }
    btn._fuell = { rein, raus };
    btn.addEventListener('pointerenter', e => { const r = btn.getBoundingClientRect(); rein(e.clientX - r.left, e.clientY - r.top); });
    btn.addEventListener('pointerleave', e => { const r = btn.getBoundingClientRect(); raus(e.clientX - r.left, e.clientY - r.top); });
  });

  /* Pixel-Füllung */
  $$('[data-pixel]').forEach(btn => {
    const raster = btn.querySelector('.g-pixel__raster'); let zellen = [], spalten = 0;
    function bauen() {
      const w = btn.clientWidth, h = btn.clientHeight; spalten = Math.ceil(w / 8); const reihen = Math.ceil(h / 8);
      if (zellen.length === spalten * reihen) return;
      raster.innerHTML = '<i></i>'.repeat(spalten * reihen); zellen = [...raster.children];
    }
    function stufen(x, y) {
      bauen();
      const pos = zellen.map((z, i) => [(i % spalten) * 8 + 4, Math.floor(i / spalten) * 8 + 4]);
      const max = Math.max(...pos.map(([a, b]) => Math.hypot(a - x, b - y))) || 1;
      zellen.forEach((z, i) => { const s = Math.max(0, Math.min(5, Math.round(Math.hypot(pos[i][0] - x, pos[i][1] - y) / max * 5 + (Math.random() - .5) * 1.4))); z.style.setProperty('--d', (reduziert() ? 0 : s * 80) + 'ms'); });
    }
    btn._pixel = { rein: (x, y) => { stufen(x, y); btn.classList.add('ist-voll'); }, raus: (x, y) => { stufen(x, y); btn.classList.remove('ist-voll'); } };
    btn.addEventListener('pointerenter', e => { const r = btn.getBoundingClientRect(); btn._pixel.rein(e.clientX - r.left, e.clientY - r.top); });
    btn.addEventListener('pointerleave', e => { const r = btn.getBoundingClientRect(); btn._pixel.raus(e.clientX - r.left, e.clientY - r.top); });
    bauen();
  });

  /* ---------- Galerie: Filter ---------- */
  const karten = $$('.karte'), zahlOut = $('#galerie-zahl'), wahl = $('#rezept-wahl');
  let stimmung = '';
  function filtern() {
    const r = REZEPTE[wahl.value];
    let sichtbar = 0, ja = 0, nein = 0;
    karten.forEach(k => {
      const passt = !stimmung || k.dataset.stimmung.split(' ').includes(stimmung);
      k.hidden = !passt;
      let emp = false, aus = false, varText = '';
      if (r) {
        const treffer = r.ja.find(([id, vv]) => id === k.dataset.id && (!k.dataset.var || !vv || k.dataset.var === vv));
        if (treffer) { emp = true; varText = treffer[1] ? ' · ' + treffer[1] : ''; }
        aus = r.nein.includes(k.dataset.id);
      }
      k.classList.toggle('ist-empfohlen', emp); k.classList.toggle('ist-ausgeschlossen', aus);
      k.querySelector('[data-var]').textContent = varText;
      k.style.order = emp ? -1 : (aus ? 1 : 0);
      if (passt) { sichtbar++; if (emp) ja++; if (aus) nein++; }
    });
    $$('.rtab tr[data-rezept]').forEach(tr => tr.classList.toggle('ist-gewaehlt', tr.dataset.rezept === wahl.value));
    zahlOut.textContent = r ? `${sichtbar} Muster · ${ja} empfohlen · ${nein} ausgeschlossen` : `${sichtbar} Muster`;
  }
  $$('.chips [data-stimmung]').forEach(b => b.addEventListener('click', () => {
    stimmung = b.dataset.stimmung;
    $$('.chips [data-stimmung]').forEach(x => x.setAttribute('aria-pressed', String(x === b)));
    filtern();
  }));
  wahl.addEventListener('change', filtern);

  /* ---------- Vorführung ---------- */
  const DAUER = { ruhe: 900, hover: 1100, fokus: 1100, druck: 650, aus: 1000, laden: 1400, erfolg: 1500 };
  const WELTEN = ['buehne', 'manufaktur', 'fahrschule'];
  let uhr = 0, schritt = 0, laeuft = false;
  function vorfuehrSchritt() {
    const z = FOLGE[schritt % FOLGE.length];
    if (v === 'rezepte') {
      $$('[data-welt-panel]').forEach(p => {
        setzeKlassen(p.querySelector('.k--primaer'), z === 'fokus' || z === 'aus' ? (z === 'aus' ? 'ruhe' : 'fokus') : z);
        const s = p.querySelector('.k--sekundaer'); setzeKlassen(s, z === 'hover' ? 'hover' : (z === 'druck' ? 'druck' : 'ruhe'));
      });
      if (z === 'ruhe' && schritt > 0) setzeWelt(WELTEN[(WELTEN.indexOf(root.dataset.welt) + 1) % WELTEN.length]);
    }
    setzeKlassen(spez, z); zeigeWerte(z);
    schritt++;
    uhr = setTimeout(vorfuehrSchritt, DAUER[z]);
  }
  function alleZurueck() {
    clearTimeout(uhr); spezLauf++;
    [spez, ...$$('[data-welt-panel] .k')].forEach(b => setzeKlassen(b, 'ruhe'));
    zeigeWerte('ruhe');
  }
  function neustart() { alleZurueck(); schritt = 0; masse(); }
  function vorfuehren() { neustart(); laeuft = true; uhr = setTimeout(vorfuehrSchritt, 400); }
  function pause() { clearTimeout(uhr); laeuft = false; }
  function weiter() { if (!laeuft) { laeuft = true; uhr = setTimeout(vorfuehrSchritt, 200); } }
  ['pointerdown', 'keydown'].forEach(t => document.addEventListener(t, e => {
    if (laeuft && e.isTrusted && !root.classList.contains('vorschau') && !e.target.closest('fundus-pult-knopf')) { pause(); alleZurueck(); }
  }));

  /* Start */
  setzeVariante(v, false);
  setzeWelt(root.dataset.welt || 'buehne');
  filtern();
  if (document.fonts && document.fonts.ready) document.fonts.ready.then(masse);
  if (window.ResizeObserver && spez) new ResizeObserver(masse).observe(spez.parentElement);
  addEventListener('load', masse);

})();

</script>
</body>
</html>