/* components/melucio-a11y.css */
/* melucio-a11y.css — Seiten-Wirkungen des <melucio-a11y>-Menues.
 *
 * Im <head> der Seite einbinden (das Bedien-Panel selbst kommt aus
 * melucio-a11y.js / Shadow DOM). Diese Datei liefert die universellen Teile:
 *   1. die @font-face der beiden Lese-Schriften (self-hosted, DSGVO-konform),
 *   2. die :root[data-font] / :root[data-spacing] Variablen-Zuordnung.
 *
 * INTEGRATIONS-VERTRAG (das Projekt muss diese Variablen anwenden):
 *   html { font-family: var(--body-font, <eigener System-Stack>); }
 *   body { line-height: var(--read-lh, <eigener Default>);
 *          letter-spacing: var(--read-ls, normal); }
 *   html { font-size: calc(<Basis>px * var(--font-scale, 1)); }
 * Die High-Contrast-Palette (:root[data-contrast='high'] { --fg: ...; ... })
 * bleibt bewusst beim Projekt — jede Marke hat ihre eigene Palette.
 *
 * SCHRIFT-DATEIEN: die sechs woff2 unter /fonts/ selbst hosten. Quelle:
 *   npm i @fontsource/atkinson-hyperlegible @fontsource/opendyslexic
 *   und die woff2 nach public/fonts/ kopieren.
 */

/* Kein blaues Aufblitzen beim Antippen (Android-Tap-Hervorhebung).
   Steht bewusst AUCH hier, nicht nur in melucio-reset.css: manche Seiten
   (etwa reine Rechtsseiten wie Impressum oder Datenschutz, einzelne
   Demoseiten) laden weder Reset noch Site-CSS — diese Datei ist dort das
   einzige geteilte Stylesheet. Doppelt mit dem Reset ist die Regel folgenlos (gleicher Wert).
   Der sichtbare Fokusring kommt aus :focus-visible und bleibt unberuehrt. */
* {
  -webkit-tap-highlight-color: transparent;
}


@font-face {
  font-family: 'Atkinson Hyperlegible';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/atkinson-hyperlegible-latin-400-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Atkinson Hyperlegible';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/atkinson-hyperlegible-latin-400-italic.woff2') format('woff2');
}
@font-face {
  font-family: 'Atkinson Hyperlegible';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/atkinson-hyperlegible-latin-700-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'OpenDyslexic';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/opendyslexic-latin-400-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'OpenDyslexic';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/opendyslexic-latin-400-italic.woff2') format('woff2');
}
@font-face {
  font-family: 'OpenDyslexic';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/opendyslexic-latin-700-normal.woff2') format('woff2');
}

/* Lese-Schriftart umschaltbar. Default = unset (System-Stack des Projekts). */
:root[data-font='hyper'] {
  --body-font: 'Atkinson Hyperlegible', system-ui, sans-serif;
}
:root[data-font='dyslexic'] {
  --body-font: 'OpenDyslexic', system-ui, sans-serif;
}

/* Textabstand umschaltbar (Zeilenhoehe + Buchstabenabstand). */
:root[data-spacing='loose'] {
  --read-lh: 1.95;
  --read-ls: 0.02em;
}
:root[data-spacing='xloose'] {
  --read-lh: 2.2;
  --read-ls: 0.045em;
}

/* Bewegung aus (Schalter im Menue, data-motion="reduce" auf <html>).
   Greift auf jeder Seite, die diese Datei laedt, auch ohne eigene Regel.

   Bewusst Dauer 0.01ms statt "animation: none": Viele Seiten blenden
   Inhalte per Animation mit fill-mode forwards EIN (Startzustand
   unsichtbar). "none" liesse sie im Startzustand stehen, also unsichtbar;
   eine fast leere Dauer springt sofort in den Endzustand, und
   animationend/transitionend feuern weiterhin (Skripte, die darauf
   warten, bleiben nicht haengen). Wer die Animationen auf einer Seite ganz
   entfernen will, schreibt dort "animation: none" samt Endzustand.

   Die Systemeinstellung (prefers-reduced-motion) deckt diese Datei NICHT
   ab; das bleibt Sache der Seite (bei den Apps mit melucio-breakpoints.css
   steht dieselbe Regel dort unter der Media Query). */
html[data-motion='reduce'] {
  scroll-behavior: auto !important;
}
html[data-motion='reduce'] *,
html[data-motion='reduce'] *::before,
html[data-motion='reduce'] *::after {
  animation-duration: 0.01ms !important;
  animation-delay: 0s !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.01ms !important;
  transition-delay: 0s !important;
  scroll-behavior: auto !important;
}

/* components/melucio-tokens.css */
/* ============================================================================
   meluciolabs.de — Farbtoken fuer hell und dunkel, an EINER Stelle, dazu das
   Wenige, was jede der einundzwanzig Seiten davon ableitet: die Kopfzeile in
   drei Spalten und die Knoepfe darin. Das MENUE steht dagegen in
   melucio-nav.css, denn die Videoraum-Seiten haben keins und laden sie nicht.

   ANLASS (22.09.2026): Das Portfolio war die einzige eigene Seite ohne hellen
   Modus. Der Umschalter (components/melucio-theme-toggle.js) lag fertig im
   Ordner und war auf keiner der zwanzig Seiten eingebunden; melucio-site.css
   kannte nur eine dunkle Palette, und die Rechtsseiten trugen ihre Farben
   jede noch einmal in einem eigenen <style>.

   AUFBAU (CLAUDE.md, Punkt 20):
     1. Hell steht auf blankem :root.
     2. Dunkel steht ZWEIMAL — unter @media (prefers-color-scheme: dark),
        abgesichert mit :root:not([data-theme="light"]), und noch einmal
        unter :root[data-theme="dark"]. Nur so gewinnt der Umschalter in
        beide Richtungen.
   Keine Farbe hat ihre EINZIGE Definition in einem Media-Block; was im
   Media-Block steht, steht oben auf :root auch.

   Die beiden dunklen Bloecke sind wortgleich und muessen es bleiben.
   Nachgezaehlt wird das, nicht geglaubt:
       node apps/meluciolabs/_tools/pruefe-themebloecke.mjs
   (laeuft im PR-Check ueber tests-vor-merge.yml mit).

   LADEREIHENFOLGE: nach melucio-reset.css, vor melucio-site.css und vor dem
   <style> der Seite. Der Reset setzt --bg/--fg/--muted selbst, und sein
   html[data-theme="dark"] traegt dieselbe Spezifitaet wie :root[data-theme]
   hier — wer diese Datei davor laedt, bekommt im Dunkeln den Reset-Grauwert.
   ========================================================================= */

:root {
    color-scheme: light;

    /* ---- Flaechen ---- */
    --bg: #f6f6fb;
    --bg-card: #ffffff;
    /* Alias fuer die Rechtsseiten, die ihre Karte --surface nennen. */
    --surface: #ffffff;
    /* Zweite deckende Flaeche (Eingabeleiste in /ki-demo). */
    --surface-2: #eef0f7;

    /* ---- Schrift ---- */
    --text: #15151f;
    /* Gemessen auf --bg: 6,4:1. #888 (der dunkle Wert) kaeme hier auf 3,5:1
       und faellt fuer Fliesstext durch. */
    --text-muted: #55556a;
    /* Alias fuer die Rechtsseiten. */
    --muted: #55556a;
    /* Schrift auf einer gefuellten AKZENT-Flaeche (--accent). Kippt im hohen
       Kontrast mit, weil der Akzent dort seine Helligkeit wechselt. */
    --on-accent: #ffffff;
    /* Schrift und Symbole auf den MARKEN-VERLAEUFEN. Die Verlaeufe sind in
       beiden Fassungen dieselben Farben, also ist es auch diese Schrift —
       und sie darf im hohen Kontrast NICHT mitkippen. Genau das war am
       22.09.2026 abends der Fall: --on-accent wurde dort dunkel, und die
       Knopfschrift landete mit 2,93:1 auf dem dunklen Ende von --gradient-1,
       schlechter als die 3,66:1 vorher. */
    --on-gradient: #ffffff;
    /* Vier der fuenf Marken-Verlaeufe sind HELL, und weisse Symbole darauf
       sind kaum zu sehen. Gemessen 22.09.2026: weiss auf #43e97b 1,59:1,
       auf #38f9d7 1,34:1, auf #4facfe 2,41:1, auf #f093fb 2,03:1 — ein
       Symbol braucht 3:1 (WCAG 1.4.11). Dieselben Flaechen mit dunklem
       Symbol: 7,5 bis 13,3:1. Die Verlaeufe bleiben, das Zeichen darin
       wechselt. */
    --on-gradient-hell: #15151f;

    /* ---- Akzent ----
       Seit 25.09.2026 aus der Logo-Familie ([[marke-lila-nicht-gruen]]):
       #7C6AF5, hell #A99EF8, dunkel #6355D0. Vorher stand hier Indigo
       (#4f46e5), das neben dem Logo wie eine zweite Marke aussah. */
    --accent: #6355D0;
    /* Im Hellen ist der Hover-Ton DUNKLER, nicht heller: der helle Logo-Ton
       #A99EF8 traegt auf Weiss nicht. */
    --accent-hover: #4A36A8;
    /* Der Akzent als SCHRIFT, getrennt von --accent (CLAUDE.md, Punkt 20).
       Im Dunkeln misst #7C6AF5 auf dem Grund zu wenig fuer Fliesstext,
       deshalb dort der helle Logo-Ton. Als FLAECHE steht im Dunkeln
       #6a58e6 (Anfang des Knopf-Verlaufs): weisse Schrift darauf misst
       rund 5:1, auf #7C6AF5 nur 4,01:1 (Sprunglink, frontend-pruefer 25.09.). Fuer Raender und accent-color bleibt
       --accent richtig. */
    --accent-text: #5646C4;
    /* Markenlila als SCHRIFT (Abschnittsnummern der Rechtsseiten, 25.09.2026).
       Logo-Familie wie der Akzent, aber als eigene Stufe fuer Ziffern und
       Auszeichnungen; Messwerte stehen in melucio-recht.css. */
    --brand-text: #6355D0;

    /* ---- Akzent als Flaeche und Linie (halbdurchsichtig) ---- */
    --accent-fill-faint: rgba(99, 85, 208, 0.06);
    --accent-fill-soft: rgba(99, 85, 208, 0.09);
    --accent-fill-strong: rgba(99, 85, 208, 0.13);
    --accent-line-faint: rgba(99, 85, 208, 0.20);
    --accent-line-soft: rgba(99, 85, 208, 0.28);
    --accent-line-strong: rgba(99, 85, 208, 0.38);

    /* ---- Neutrale Linien und Flaechen ---- */
    --line: rgba(20, 20, 45, 0.10);
    --line-2: rgba(20, 20, 45, 0.13);
    --line-3: rgba(20, 20, 45, 0.18);
    /* Alias fuer die Rechtsseiten. */
    --border: rgba(20, 20, 45, 0.13);
    --surface-soft: rgba(20, 20, 45, 0.05);
    --surface-soft-hover: rgba(20, 20, 45, 0.09);
    --underline-soft: rgba(20, 20, 45, 0.30);

    /* ---- Kopfleiste, Untergrund-Schimmer, Overlay ---- */
    --header-bg: rgba(246, 246, 251, 0.85);
    --glow-1: rgba(124, 106, 245, 0.10);
    --glow-2: rgba(110, 116, 132, 0.08);
    --overlay: rgba(18, 18, 32, 0.55);

    /* ---- Schatten ---- */
    --shadow-card: 0 20px 60px rgba(20, 20, 45, 0.14);
    --shadow-card-sm: 0 20px 40px rgba(20, 20, 45, 0.12);
    --shadow-accent: 0 10px 30px rgba(63, 47, 158, 0.25);
    --shadow-drawer: 12px 0 40px rgba(20, 20, 45, 0.18);
    --shadow-pop: 0 6px 20px rgba(20, 20, 45, 0.12);
    --shadow-chat: 0 16px 48px rgba(20, 20, 45, 0.26);
    --shadow-cta: 0 8px 24px rgba(63, 47, 158, 0.28);

    /* ---- Zustandsfarben ----
       Gemessen auf --bg-card: --ok 5,0:1, --danger-text 6,5:1.
       #43e97b und #ef4444 (die dunklen Werte) kaemen auf 1,7:1 bzw. 3,8:1. */
    /* #15803d mass auf der eigenen 10%-Fuellung nur 4,39:1 — knapp
       daneben ist daneben. #166534 kommt dort auf 6,1:1. */
    --ok: #166534;
    --ok-soft: rgba(22, 101, 52, 0.10);
    --ok-line: rgba(22, 101, 52, 0.28);
    --danger-text: #b91c1c;
    /* Warnton. Gelb traegt auf Weiss nicht: #e6b800 (der dunkle Wert) misst
       dort 1,6:1, deshalb im Hellen ein Ocker. */
    --warn-text: #7a5c00;
    --warn-soft: rgba(122, 92, 0, 0.09);
    --warn-line: rgba(122, 92, 0, 0.28);

    /* ---- Verlaeufe ----
       Fuellungen mit weisser Schrift/Icon darauf; sie sind in beiden
       Fassungen gleich, weil ihr Untergrund der Verlauf selbst ist. */
    --gradient-1: linear-gradient(135deg, #6a58e6 0%, #3F2F9E 100%);
    --gradient-2: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
    --gradient-3: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
    --gradient-4: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
    --gradient-khai: linear-gradient(135deg, #5CB85C 0%, #38f9d7 100%);
    /* Verlauf als SCHRIFT (Wortmarke, Hero-Zeile) — der steht auf dem
       Seitengrund und braucht deshalb eine eigene, dunklere Fassung.
       #667eea auf Weiss misst 3,0:1 und liegt damit auf der Kante. */
    --gradient-text: linear-gradient(135deg, #6355D0 0%, #4A36A8 100%);

    /* ---- Fokusring ---- */
    --focus-ring: #4A36A8;

    /* ---- <melucio-a11y> ---- */
    --a11y-surface: #ffffff;
    --a11y-fg: #15151f;
    --a11y-fg-muted: #55556a;
    --a11y-line-strong: rgba(20, 20, 45, 0.22);
    --a11y-accent: #6355D0;
    --a11y-accent-strong: #4A36A8;
    --a11y-accent-soft: rgba(99, 85, 208, 0.12);
    --a11y-shadow: 0 12px 34px rgba(20, 20, 45, 0.22);

    /* ---- Hoher Kontrast (a11y-Menue, data-contrast='high') ---- */
    --hc-text: #000000;
    --hc-text-muted: #22222c;
    --hc-accent: #3F2F9E;
    /* Schrift auf der Akzentflaeche im hohen Kontrast. Im Dunkeln kippt der
       Akzent dort ins Helle (#aab2ff), und weisse Schrift darauf misst 2:1 —
       gemessen am Sprunglink und am Senden-Knopf von /ki-demo. */
    --hc-on-accent: #ffffff;
    --hc-accent-hover: #33257f;
    --hc-line: rgba(0, 0, 0, 0.42);
    /* Das Gruen der Haken und Plaketten. Im Hellen hing es als einziges im
       hohen Kontrast bei 6,12:1 fest, waehrend der Rest auf 14:1 sprang. */
    --hc-ok: #0a3d1e;

    /* ---- Startseite: Material aus dem Logo (25.09.2026) ----
       Das Logo ist ein Zahnrad aus Chrom mit lila Buchstaben. Lila bleibt
       die einzige Farbe; Strich und Zahnrad im Hero tragen das Metall. */
    --chrom: #8a8fa0;
    --zahnrad: rgba(110, 116, 132, 0.13);
    --protokoll-bg: rgba(99, 85, 208, 0.05);
    --protokoll-line: rgba(99, 85, 208, 0.22);
}

/* ===== DUNKEL, Block 1 von 2: System sagt dunkel und der Besucher hat
   nichts anderes gewaehlt. ================================================ */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        color-scheme: dark;
        --bg: #0e1014;
        --bg-card: #161a20;
        --surface: #161a20;
        --surface-2: #1b1f26;
        --text: #f2f3f5;
        --text-muted: #a4a9b4;
        --muted: #a4a9b4;
        --on-accent: #ffffff;
        --on-gradient: #ffffff;
        --on-gradient-hell: #15151f;
        --accent: #6a58e6;
        --accent-hover: #A99EF8;
        --accent-text: #A99EF8;
        --brand-text: #A99EF8;
        --accent-fill-faint: rgba(124, 106, 245, 0.08);
        --accent-fill-soft: rgba(124, 106, 245, 0.10);
        --accent-fill-strong: rgba(124, 106, 245, 0.15);
        --accent-line-faint: rgba(124, 106, 245, 0.18);
        --accent-line-soft: rgba(124, 106, 245, 0.26);
        --accent-line-strong: rgba(124, 106, 245, 0.32);
        --line: rgba(200, 210, 225, 0.07);
        --line-2: rgba(200, 210, 225, 0.10);
        --line-3: rgba(200, 210, 225, 0.15);
        --border: rgba(200, 210, 225, 0.11);
        --surface-soft: rgba(200, 210, 225, 0.05);
        --surface-soft-hover: rgba(200, 210, 225, 0.10);
        --underline-soft: rgba(200, 210, 225, 0.28);
        --header-bg: rgba(14, 16, 20, 0.82);
        --glow-1: rgba(124, 106, 245, 0.12);
        --glow-2: rgba(138, 143, 160, 0.08);
        --overlay: rgba(0, 0, 0, 0.80);
        --shadow-card: 0 20px 60px rgba(0, 0, 0, 0.30);
        --shadow-card-sm: 0 20px 40px rgba(0, 0, 0, 0.30);
        --shadow-accent: 0 10px 30px rgba(0, 0, 0, 0.45);
        --shadow-drawer: 12px 0 40px rgba(0, 0, 0, 0.50);
        --shadow-pop: 0 6px 20px rgba(0, 0, 0, 0.18);
        --shadow-chat: 0 16px 48px rgba(0, 0, 0, 0.60);
        --shadow-cta: 0 8px 24px rgba(0, 0, 0, 0.45);
        --ok: #43e97b;
        --ok-soft: rgba(67, 233, 123, 0.12);
        --ok-line: rgba(67, 233, 123, 0.25);
        --danger-text: #ff9494;
        --warn-text: #e6b800;
        --warn-soft: rgba(255, 193, 7, 0.08);
        --warn-line: rgba(255, 193, 7, 0.25);
        --gradient-1: linear-gradient(135deg, #6a58e6 0%, #3F2F9E 100%);
        --gradient-2: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
        --gradient-3: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
        --gradient-4: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
        --gradient-khai: linear-gradient(135deg, #5CB85C 0%, #38f9d7 100%);
        --gradient-text: linear-gradient(135deg, #A99EF8 0%, #C4B5FD 100%);
        --focus-ring: #A99EF8;
        --a11y-surface: #181c23;
        --a11y-fg: #ffffff;
        --a11y-fg-muted: #b9b9c6;
        --a11y-line-strong: rgba(255, 255, 255, 0.20);
        --a11y-accent: #6a58e6;
        --a11y-accent-strong: #C4B5FD;
        --a11y-accent-soft: rgba(124, 106, 245, 0.18);
        --a11y-shadow: 0 12px 34px rgba(0, 0, 0, 0.55);
        --hc-text: #ffffff;
        --hc-text-muted: #e8e8f0;
        --hc-accent: #C4B5FD;
        --hc-on-accent: #15151f;
        --hc-accent-hover: #ddd6fe;
        --hc-line: rgba(255, 255, 255, 0.34);
        /* Im Dunkeln misst --ok schon 12,1:1 — hier gibt es nichts zu heben. */
        --hc-ok: #43e97b;
        --chrom: #9aa0b0;
        --zahnrad: rgba(160, 166, 182, 0.11);
        --protokoll-bg: rgba(124, 106, 245, 0.07);
        --protokoll-line: rgba(124, 106, 245, 0.26);
    }
}

/* ===== DUNKEL, Block 2 von 2: der Besucher hat dunkel gewaehlt.
   Wortgleich zu Block 1 — siehe pruefe-themebloecke.mjs. ================== */
:root[data-theme="dark"] {
    color-scheme: dark;
    --bg: #0e1014;
    --bg-card: #161a20;
    --surface: #161a20;
    --surface-2: #1b1f26;
    --text: #f2f3f5;
    --text-muted: #a4a9b4;
    --muted: #a4a9b4;
    --on-accent: #ffffff;
    --on-gradient: #ffffff;
    --on-gradient-hell: #15151f;
    --accent: #6a58e6;
    --accent-hover: #A99EF8;
    --accent-text: #A99EF8;
    --brand-text: #A99EF8;
    --accent-fill-faint: rgba(124, 106, 245, 0.08);
    --accent-fill-soft: rgba(124, 106, 245, 0.10);
    --accent-fill-strong: rgba(124, 106, 245, 0.15);
    --accent-line-faint: rgba(124, 106, 245, 0.18);
    --accent-line-soft: rgba(124, 106, 245, 0.26);
    --accent-line-strong: rgba(124, 106, 245, 0.32);
    --line: rgba(200, 210, 225, 0.07);
    --line-2: rgba(200, 210, 225, 0.10);
    --line-3: rgba(200, 210, 225, 0.15);
    --border: rgba(200, 210, 225, 0.11);
    --surface-soft: rgba(200, 210, 225, 0.05);
    --surface-soft-hover: rgba(200, 210, 225, 0.10);
    --underline-soft: rgba(200, 210, 225, 0.28);
    --header-bg: rgba(14, 16, 20, 0.82);
    --glow-1: rgba(124, 106, 245, 0.12);
    --glow-2: rgba(138, 143, 160, 0.08);
    --overlay: rgba(0, 0, 0, 0.80);
    --shadow-card: 0 20px 60px rgba(0, 0, 0, 0.30);
    --shadow-card-sm: 0 20px 40px rgba(0, 0, 0, 0.30);
    --shadow-accent: 0 10px 30px rgba(0, 0, 0, 0.45);
    --shadow-drawer: 12px 0 40px rgba(0, 0, 0, 0.50);
    --shadow-pop: 0 6px 20px rgba(0, 0, 0, 0.18);
    --shadow-chat: 0 16px 48px rgba(0, 0, 0, 0.60);
    --shadow-cta: 0 8px 24px rgba(0, 0, 0, 0.45);
    --ok: #43e97b;
    --ok-soft: rgba(67, 233, 123, 0.12);
    --ok-line: rgba(67, 233, 123, 0.25);
    --danger-text: #ff9494;
    --warn-text: #e6b800;
    --warn-soft: rgba(255, 193, 7, 0.08);
    --warn-line: rgba(255, 193, 7, 0.25);
    --gradient-1: linear-gradient(135deg, #6a58e6 0%, #3F2F9E 100%);
    --gradient-2: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
    --gradient-3: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
    --gradient-4: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
    --gradient-khai: linear-gradient(135deg, #5CB85C 0%, #38f9d7 100%);
    --gradient-text: linear-gradient(135deg, #A99EF8 0%, #C4B5FD 100%);
    --focus-ring: #A99EF8;
    --a11y-surface: #181c23;
    --a11y-fg: #ffffff;
    --a11y-fg-muted: #b9b9c6;
    --a11y-line-strong: rgba(255, 255, 255, 0.20);
    --a11y-accent: #6a58e6;
    --a11y-accent-strong: #C4B5FD;
    --a11y-accent-soft: rgba(124, 106, 245, 0.18);
    --a11y-shadow: 0 12px 34px rgba(0, 0, 0, 0.55);
    --hc-text: #ffffff;
    --hc-text-muted: #e8e8f0;
    --hc-accent: #C4B5FD;
    --hc-on-accent: #15151f;
    --hc-accent-hover: #ddd6fe;
    --hc-line: rgba(255, 255, 255, 0.34);
    /* Im Dunkeln misst --ok schon 12,1:1 — hier gibt es nichts zu heben. */
    --hc-ok: #43e97b;
    --chrom: #9aa0b0;
    --zahnrad: rgba(160, 166, 182, 0.11);
    --protokoll-bg: rgba(124, 106, 245, 0.07);
    --protokoll-line: rgba(124, 106, 245, 0.26);
}

/* ===== Was aus den Token folgt — gilt fuer alle zwanzig Seiten ========== */

/* Kein fremdes Blau beim Markieren (CLAUDE.md, Punkt 5). */
/* melucio-reset.css faerbt jeden <a> mit `var(--primary, #5CB85C)`. Ohne
   gesetztes --primary trug das Portfolio also KHAI-Gruen in den Links — im
   Dunkeln unauffaellig (5,8:1), im Hellen mit 2,48:1 nicht mehr. Der Akzent
   der Marke ist lila ([[marke-lila-nicht-gruen]]), und --accent-text ist der
   Ton, der als SCHRIFT in beiden Fassungen traegt: --accent selbst misst im
   Dunkeln nur 4,13:1. */
:root { --primary: var(--accent-text); }

/* Farben und Schrift fuer <melucio-footer>. Ohne sie fiel der Baustein auf
   seine eigenen Vorgaben zurueck: Hover und Copyright-Link in KHAI-Gruen
   #5CB85C, Hintergrund #1A1A2E statt Graphit (design-berater 26.09.2026).
   Nur einmal auf :root, wie --primary: Die Werte sind Verweise, und die
   verwiesenen Token wechseln mit dem Theme und dem hohen Kontrast selbst.
   Gemessen stehen die Werte bei den Token: --muted auf --bg hell 6,4:1,
   --accent-text auf --bg hell 6,3:1, dunkel 7,5:1. */
:root {
    --mf-accent: var(--accent-text);
    --mf-bg: var(--bg);
    --mf-text: var(--muted);
    --mf-sep: var(--muted);
    --mf-border: var(--border);
    --mf-pill-hover: var(--accent-fill-faint);
    --mf-font: var(--body-font, 'Inter', -apple-system, BlinkMacSystemFont, sans-serif);
}

::selection { background: var(--accent); color: var(--on-accent); }

/* Hoher Kontrast aus dem a11y-Menue. Steht hier statt in jeder Seite, und
   greift auf beide Fassungen: die Werte kommen aus den Token oben. */
:root[data-contrast='high'] {
    --text-muted: var(--hc-text-muted);
    --muted: var(--hc-text-muted);
    --accent: var(--hc-accent);
    --accent-hover: var(--hc-accent-hover);
    --accent-text: var(--hc-accent);
    --brand-text: var(--hc-accent);
    --on-accent: var(--hc-on-accent);
    --line: var(--hc-line);
    --line-2: var(--hc-line);
    --line-3: var(--hc-line);
    --border: var(--hc-line);
    /* --on-gradient bleibt bewusst stehen: die Verlaeufe kippen nicht mit. */

    /* Der Schalter steht IM a11y-Menue — und liess ausgerechnet dieses Menue
       unveraendert (Davids Beobachtung 22.09.2026 an zwei Bildschirmfotos,
       auf denen "Normal" und "Hoch" gleich aussehen). Jetzt zieht es mit. */
    --a11y-fg: var(--hc-text);
    --a11y-fg-muted: var(--hc-text-muted);
    --a11y-line-strong: var(--hc-line);
    --a11y-accent: var(--hc-accent);
    --a11y-accent-strong: var(--hc-accent-hover);
    --ok: var(--hc-ok);
}
:root[data-contrast='high'] body { color: var(--hc-text); }

/* Im hohen Kontrast gibt es keine Verlaufsschrift. Ein Verlauf kann seine
   Helligkeit nicht wechseln; er bliebe stehen, waehrend alles um ihn herum
   auf 15:1 springt — und faellt dann als DIE dunkle Stelle auf. Gemessen im
   Dunkeln: der Verlauf haelt 3,04:1 am dunklen Ende, der Ersatz 9,84:1. */
:root[data-contrast='high'] .logo-text,
:root[data-contrast='high'] .hero h1 .gradient,
:root[data-contrast='high'] .page-h1 .gradient,
:root[data-contrast='high'] .lp-header .brand {
    background: none;
    -webkit-text-fill-color: var(--accent-text);
    color: var(--accent-text);
}

/* Das a11y-Menue holt seine Farben aus den Token, statt sie je Seite
   noch einmal fest zu setzen. */
melucio-a11y {
    --surface: var(--a11y-surface);
    --fg: var(--a11y-fg);
    --fg-muted: var(--a11y-fg-muted);
    --line-strong: var(--a11y-line-strong);
    --accent: var(--a11y-accent);
    --accent-strong: var(--a11y-accent-strong);
    --accent-soft: var(--a11y-accent-soft);
    --shadow: var(--a11y-shadow);
}

/* Die beiden Kreise rechts im Kopf sehen gleich aus: dieselbe Groesse,
   dieselbe Rahmen- und Symbolfarbe, dasselbe Hover. Bis zum 25.09.2026 trug
   der a11y-Kreis ein Lila-Symbol (--a11y-accent-strong) und einen
   kraeftigeren Rand (0.22 statt 0.18) als der Theme-Kreis daneben und wuchs
   bei groesserer Schrift mit, der Theme-Kreis nicht. Die Werte stehen EINMAL
   hier, beide Knoepfe lesen sie. Symbol in Textfarbe: so kraeftig wie der
   Text (gemessen 16,8:1 hell, 17,2:1 dunkel auf dem Kopf). */
:root {
    --kopf-kreis-rand: var(--line-3);
    --kopf-kreis-symbol: var(--text);
    --kopf-kreis-hover: var(--surface-soft-hover);
    --kopf-kreis-mass: 40px;
}
@media (pointer: coarse) {
    :root { --kopf-kreis-mass: 44px; }
}
@media (max-width: 479px) {
    :root { --kopf-kreis-mass: 36px; }
}
@media (max-width: 479px) and (pointer: coarse) {
    :root { --kopf-kreis-mass: 44px; }
}
melucio-a11y {
    --a11y-toggle-size: var(--kopf-kreis-mass);
    --a11y-toggle-color: var(--kopf-kreis-symbol);
    --a11y-toggle-border: var(--kopf-kreis-rand);
    --a11y-toggle-hover-border: var(--kopf-kreis-rand);
    --a11y-toggle-hover-bg: var(--kopf-kreis-hover);
}

/* Der Umschalter im Kopf: runder Knopf, Tap-Flaeche 44px in PIXELN
   (CLAUDE.md — die Wurzelschrift dieser Seite ist fliessend). */
melucio-theme-toggle {
    --theme-toggle-color: var(--kopf-kreis-symbol);
    --theme-toggle-border: var(--kopf-kreis-rand);
    --theme-toggle-hover-bg: var(--kopf-kreis-hover);
    /* In Pixeln, weil die Wurzelschrift dieser Seite fliessend ist; das
       Mass steht mit den Stufen oben unter --kopf-kreis-mass. */
    --theme-toggle-size: var(--kopf-kreis-mass);
}

/* Der Chat-Knopf (seit 17.10.2026 NICHT mehr im Kopf, Davids Vorgabe: Knopf-
   Stapel, Grundmuster 3). Er steht am Ende des <body> und sitzt als runder
   Knopf unten rechts, Nach-oben darueber; Stellung und Abstand liefert
   melucio-fab-stapel.css (.fab-stapel-chat). Hier nur Mass und Optik.
   Vorher stand er als eckiger Knopf neben dem Menue; mobil war der Kopf mit
   Menue, Chat, Lockup und zwei Kreisen zu eng.

   Zwei Formen im Kopf bleiben: links der abgerundete Eckknopf (Menue, fuehrt
   woandershin), rechts Kreise (a11y, Theme, aendern die Darstellung). Der
   Chat oeffnet ein Fenster ueber der Seite, ist also ein schwebender Knopf
   und kein Teil dieser Reihen.

   Mass: 46px (wie Nach-oben), am Finger nie unter 44. */
:root {
    --fab-rand: 20px;
    --fab-bot-h: 46px;
    --fab-luft: 10px;
}
@media (max-width: 480px) {
    :root { --fab-rand: 16px; }
}
.mlx-chat-trigger{display:inline-flex;align-items:center;justify-content:center;flex:none;cursor:pointer;padding:0}
.mlx-chat-trigger svg{width:22px;height:22px}
.mlx-chat-trigger.fab-stapel-chat {
    border: 1px solid var(--accent-text);
    background: var(--bg);
    color: var(--accent-text);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
    transition: background .18s ease, border-color .18s ease;
}
.mlx-chat-trigger.fab-stapel-chat:hover {
    background: var(--surface-soft-hover);
}
.mlx-chat-trigger.fab-stapel-chat:focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: 2px;
}
@media (prefers-reduced-motion:reduce){
    .mlx-chat-trigger.fab-stapel-chat { transition: none; }
}
.header-links .nav-toggle {
    width: 40px;
    height: 40px;
    border-radius: 12px;
    border: 1px solid var(--line-3);
    background: transparent;
    transition: background .18s ease, border-color .18s ease;
    /* Der Hamburger stand frei und zog sich mit margin:-10px wieder
       zusammen; im Rahmen wuerde dieses Minus die Nachbarn ueberlappen. */
    margin: 0;
    padding: 0;
    align-items: center;
}
.header-links .nav-toggle:hover {
    background: var(--surface-soft-hover);
    border-color: var(--accent-line-soft);
}
.header-links .nav-toggle:focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: 2px;
}
@media (prefers-reduced-motion:reduce){
    .header-links .nav-toggle { transition: none; }
}
/* ── Die Kopfzeile in drei Spalten ──────────────────────────────────────

   Links die Navigation (Menue), in der Mitte das Lockup, rechts die
   Darstellungs-Sachen (a11y, Theme, spaeter der Sprachwechsel). Genau die
   Aufteilung verlangt die CLAUDE.md unter Punkt 2, und das Portfolio hielt
   sich bis zum 22.09.2026 nicht daran: Der Hamburger stand rechts zwischen
   den Anzeige-Knoepfen. Vorbild ist die Topbar von M.d.Ae.

   `1fr auto 1fr` statt `justify-content: space-between`: So bleibt das
   Lockup wirklich mittig, egal wie viele Knoepfe links und rechts stehen.
   M.d.Ae. loest dieselbe Aufgabe mit einem `.topbar-spacer`, der von Hand
   mitwachsen muss — steht sein Kommentar daneben („Muss mit den Knoepfen
   mitwachsen, sonst sitzt das Logo aus der Mitte"). Mit dem Raster entfaellt
   die Pflege: Spalte 1 und 3 sind per Definition gleich breit, und die drei
   Zonen liegen fest auf ihrer Spalte. Eine Seite ohne Menue (die
   Videoraum-Seiten) braucht deshalb auch keinen Platzhalter.

   Die Schublade steht in .header-links direkt hinter dem Menueknopf (damit
   Tab nach dem Oeffnen in die Menuepunkte geht) und ist `position: fixed`;
   sie faellt damit aus der Knopfreihe heraus und belegt keinen Platz. Ab
   1024px loest melucio-nav.css die Gruppe auf und stellt sie ins Raster. */
.header-content,
.lp-header {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 12px;
}
.header-links {
    grid-column: 1;
    justify-self: start;
    display: flex;
    align-items: center;
    gap: 12px;
}
.header-content > .logo,
.lp-header > .logo {
    grid-column: 2;
    justify-self: center;
}
.header-controls {
    grid-column: 3;
    justify-self: end;
    display: flex;
    align-items: center;
    gap: 12px;
}
@media (max-width: 413px) {
    /* Enger ruecken, aber NICHT unter die Tap-Flaeche: die Knoepfe behalten
       ihre 44px am Finger, nur der Abstand dazwischen gibt nach. */
    .header-content,
    .lp-header { gap: 6px; }
    .header-links,
    .header-controls { gap: 6px; }
}

/* Tap-Flaechen der linken Gruppe. Gemessen am 22.09.2026 bei 375px mit
   Touch-Emulation: Menue 42x36, Chat 38x38 — beide unter den 44px, die die
   CLAUDE.md verlangt, und beide schon vorher so. Neben den 44px-Kreisen von
   a11y und Theme fiel es erst auf, als die vier Knoepfe in zwei Gruppen
   auseinandergingen. Untergrenze in PIXELN, nicht in rem: die Wurzelschrift
   dieser Seite ist fliessend und faellt auf schmalen Fenstern auf 15px. */
@media (pointer: coarse) {
    .header-links .nav-toggle {
        min-width: 44px;
        min-height: 44px;
    }
}
/* ── Das Lockup ─────────────────────────────────────────────────────────
   Stand bis zum 22.09.2026 in melucio-site.css, die sieben Rechtsseiten und
   die Videoraum-Seiten laden die aber nicht: Dort war das Logo blanker
   36px-Zahn ohne Wortmarke, waehrend die Hauptseiten Zahn plus Wortmarke
   zeigten. Beim Seitenwechsel auf dem Telefon sprang das sofort ins Auge
   (Davids Fund). Jetzt tragen alle einundzwanzig dasselbe. */
.logo {
    display: flex;
    align-items: center;
    gap: 12px;
    text-decoration: none;
}
.logo-img {
    height: 42px;
    width: auto;
    /* KEIN Rahmen, keine Kachel (Davids Vorgabe 06.09.2026): das Logo steht
       frei auf dem Grund. Fuer dunkle Flaechen liefert der Header die
       Silber-ML-Fassung (leite-ab.py, zweiter Master). */
}
.logo-text {
    font-size: 1.75rem;
    font-weight: 700;
    background: var(--gradient-text);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}
@media (max-width: 768px) {
    .logo { gap: 8px; }
    .logo-img { height: 34px; }
    .logo-text { font-size: 1.35rem; }
}
@media (max-width: 480px) {
    .logo-img { height: 30px; }
    .logo-text { font-size: 1.18rem; }
}
@media (max-width: 413px) {
    .logo { min-width: 0; }
    .logo-img { height: 26px; }
    .logo-text { font-size: 1rem; }
}
/* Unter 380px weicht die Wortmarke dem Symbol. Nachgerechnet bei 320px:
     nach den Seitenraendern bleiben 272px, und die vier Bedienknoepfe belegen
     davon 186 (44 + 44 + 38 + 42 plus dreimal 6 Abstand) — fuer das Lockup
     bleiben 86, und 26px Symbol plus Abstand lassen davon 52 fuer elf
     Buchstaben. Bis zum 22.09.2026 waren es drei Knoepfe und es ging knapp auf;
     mit dem Theme-Umschalter geht es nicht mehr. Der Name bleibt im alt-Text
     des Logos und damit im Zugaenglichkeitsbaum, die Tap-Flaeche des Links
     bleibt ueber .logo-img + Rand erhalten. */
@media (max-width: 359px) {
    .logo-text { display: none; }
}
/* Dasselbe, wenn die Kopfzeile nachgemessen nicht passt (navigation.js
   setzt kopf-eng, etwa bei vergroesserter Schrift aus dem a11y-Menue). */
:root.kopf-eng .logo-text { display: none; }

/* Die Rechtsseiten nennen ihr Lockup nicht immer .logo; der Link zur
   Startseite ist dort das einzige <a> im Kopf. */
.lp-header > a:not(.logo) {
    grid-column: 2;
    justify-self: center;
}

/* ── Die Icon-Kacheln ───────────────────────────────────────────────────
   Bis zum 22.09.2026 stand der Verlauf als style-Attribut an jeder Kachel,
   und das Zeichen darin war immer weiss. Auf den vier hellen Verlaeufen war
   es damit praktisch unsichtbar (1,34 bis 2,41:1). Mit einer Klasse je
   Verlauf steht beides beieinander: die Flaeche und das, was darauf traegt. */
.icon-violet { background: var(--gradient-1); color: var(--on-gradient); }
.icon-pink   { background: var(--gradient-2); color: var(--on-gradient-hell); }
.icon-blue   { background: var(--gradient-3); color: var(--on-gradient-hell); }
.icon-green  { background: var(--gradient-4); color: var(--on-gradient-hell); }
.icon-khai   { background: var(--gradient-khai); color: var(--on-gradient-hell); }
/* Eine Farbe statt fuenf (Startseite, 25.09.2026): ruhige lila Flaeche, das
   Zeichen in --accent-text. Den vollen Verlauf (.icon-violet) tragen nur die
   Kernleistungen; so entsteht Gewichtung ohne neue Farbe, und das KHAI-Gruen
   verschwindet von der Seite, auf der es nie hingehoerte. */
.icon-mono {
    background: var(--accent-fill-strong);
    color: var(--accent-text);
    box-shadow: inset 0 0 0 1px var(--accent-line-faint);
}

/* ── Seitenraender als Variablen (CLAUDE.md Punkt 4) ────────────────────
   Bis zum 25.09.2026 stand der Rand als Zahl an jeder Stelle: 24px im
   .container, im Kopf und in den Brotkrumen, 20px auf den Rechtsseiten.
   Gestaffelt wie in apps/widab-landing/src/styles/theme.css: Bilder am
   dichtesten an der Kante, Fliesstext dahinter, Karten leicht eingerueckt.
   "Enger" oder "weiter" ist damit eine Zeile.

   Verdrahtet ist bisher nur --gutter-text: Die Site hat keine Bilder, die
   naeher an der Kante stehen als der Text, und keine Karten, die gegen ihn
   eingerueckt sind — alles sitzt im .container. Die beiden anderen stehen
   bereit fuer das erste Element, das eine davon braucht, damit es dann
   keine eigene Zahl bekommt. */
:root {
    --gutter-media: 16px;
    --gutter-text: 24px;
    --gutter-card: 28px;
}
/* Abstands-Staffel, dieselben Stufen wie im geteilten Theme
   (packages/@meluciolabs/ui-components/src/theme/melucio-theme.css), das
   diese Site nicht laedt. In rem, damit sie mit der Schriftgroesse aus dem
   a11y-Menue mitwaechst. Erster Nutzer: die Teilen-Zeile (26.09.2026). */
:root {
    --spacing-xs: 0.25rem;
    --spacing-sm: 0.5rem;
    --spacing-md: 1rem;
    --spacing-lg: 1.5rem;
    --spacing-xl: 2rem;
    --spacing-2xl: 3rem;
}
@media (max-width: 479px) {
    :root {
        --gutter-media: 12px;
        --gutter-text: 20px;
        --gutter-card: 22px;
    }
}

/* ── Anker unter dem festen Kopf (CLAUDE.md Punkt 1) ───────────────────
   Ohne das verschwindet jedes Sprungziel unter der Leiste, zuletzt #stufen
   auf der Sicherheitspruefungs-Seite (Fullscan 25.09.2026). --header-h
   misst navigation.js am echten Kopf.

   Zwei Teile, die sich ADDIEREN: scroll-padding am <html> haelt die
   Kopfhoehe frei, fuer Anker UND fuer den Tastaturfokus (WCAG 2.4.11,
   beim Rueckwaerts-Tab lag der Link sonst unter der Leiste). Die [id]-Regel
   gibt nur noch die Luft von 0.8rem dazu. Standen beide mit voller
   Kopfhoehe da, landete ein Anker rund 110px unter dem Kopf (25.09.2026). */
html { scroll-padding-top: var(--header-h, 78px); }
[id] { scroll-margin-top: 0.8rem; }

/* ── Sprunglink (alle Seiten) ────────────────────────────────────────────
   Stand bis zum 25.09.2026 nur auf der Startseite, in melucio-site.css —
   die die Rechtsseiten gar nicht laden. Unsichtbar, bis er per Tastatur
   den Fokus bekommt; wer mit Tab navigiert, springt damit am Kopf vorbei. */
.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 200;
    padding: 10px 16px;
    background: var(--accent);
    color: var(--on-accent);
    border-radius: 0 0 8px 0;
    font-weight: 600;
    text-decoration: none;
}
.skip-link:focus { left: 0; }
/* Das Sprungziel bekommt den Fokus nur voruebergehend (tabindex="-1");
   ein Ring um den ganzen Inhalt waere nur Laerm. */
main:focus { outline: none; }

/* ── Links im Fliesstext sind unterstrichen ─────────────────────────────
   Nur ueber die Farbe erkennbar waren sie zum umgebenden Text 1,1:1
   (Fullscan 25.09.2026, WCAG 1.4.1). Gemeint sind Links MITTEN im Satz:
   ohne eigene Klasse, in Absatz, Aufzaehlung oder Tabelle. Knoepfe,
   Karten und Menues tragen eine Klasse oder stehen woanders. */
main p a:not([class]),
main li a:not([class]),
main dd a:not([class]),
main td a:not([class]) {
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 3px;
}

/* Nur fuer Vorlesehilfen (Live-Ansagen, Zusatzhinweise wie „oeffnet in
   neuem Fenster"). */
.visually-hidden {
    position: absolute !important;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* Teilen-Knopf am Seitenende (CLAUDE.md Punkt 12, assets/js/teilen.js).
   Der Abstand kommt aus der Abstands-Staffel oben, nicht als Zahl.
   `body .teilen-zeile` statt nur `.teilen-zeile`: Auf zwoelf der dreizehn
   Seiten traegt die Zeile auch `.container`, und dessen `padding: 0 …` in
   melucio-site.css (spaeter geladen, gleiche Spezifitaet) nahm ihr bis zum
   26.09.2026 jeden Abstand. Gemessen klebte der Knopf mobil 22px, am
   Desktop 38px unter den Knoepfen darueber und direkt auf dem Fuss. */
body .teilen-zeile {
    display: flex;
    justify-content: center;
    padding-top: var(--spacing-xl);
    padding-bottom: var(--spacing-xl);
}
.teilen-knopf {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 44px;
}

/* Nettopreis neben dem Bruttopreis (Davids Entscheid 25.09.2026: brutto
   vorn, netto direkt daneben, kaum kleiner, kein Umschalter). 2px unter der
   Umgebung und nie unter 14px; Farbe ist die Fliesstextfarbe --text-muted,
   ohne opacity, damit der Kontrast in hell und dunkel ueber 4,5:1 bleibt.
   Die Preisseite setzt dieselbe Regel in ihrem Erzeuger. */
.netto {
    color: var(--text-muted);
    font-size: max(14px, calc(1em - 2px));
    font-weight: 400;
    white-space: nowrap;
}

/* ── Ueberschriften-Schrift (alle Seiten) ────────────────────────────────
   Bricolage Grotesque, Davids Wahl vom 25.09.2026 aus vier Proben. Selbst
   gehostet, OFL (fonts/bricolage-grotesque-OFL.txt), nur latin: deckt
   Umlaute und ß ab, 41 kB. Stand zuerst nur in melucio-site.css, die die
   Rechtsseiten nicht laden; hier ist sie EINMAL definiert, und beide
   Stylesheets nutzen --heading-font. Fliesstext bleibt, was er war.
   Waehlt jemand im a11y-Menue eine Leseschrift (--body-font), gilt sie
   auch fuer Ueberschriften: var(--body-font, var(--heading-font)). */
@font-face {
    font-family: 'Bricolage Grotesque';
    font-style: normal;
    font-weight: 200 800;
    font-display: swap;
    src: url('/fonts/bricolage-grotesque-latin.woff2?v=202610201757') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
:root {
    --heading-font: 'Bricolage Grotesque', 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
}

/* Inter fuer den Fliesstext, self-hosted (latin + latin-ext, variable
   Staerke 300 bis 700). Stand bis zum 26.09.2026 nur in melucio-site.css,
   die Rechtsseiten, 404 und /v/termin nicht laden: deren Fliesstext lief
   deshalb in der Systemschrift (Kontroll-Rundgang 26.09.2026). Jetzt hier,
   EINMAL, wie Bricolage. Die Adressen samt ?v=202610201757 muessen wortgleich zu den
   preload-Zeilen im <head> der Seiten bleiben (seit 26.09.2026 inter-latin
   und bricolage-grotesque-latin, auf /preise nur inter-latin), sonst laedt der
   Browser die Datei doppelt. Der Deploy ersetzt ?v=202610201757 in HTML und CSS mit
   demselben Zeitstempel. */
@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 300 700;
    font-display: swap;
    src: url('/fonts/inter-latin-ext.woff2?v=202610201757') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 300 700;
    font-display: swap;
    src: url('/fonts/inter-latin.woff2?v=202610201757') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ── Aus melucio-breakpoints.css uebernommen (26.09.2026) ──────────────
   Die Seiten luden die geteilte Staffel als eigenes Stylesheet, genutzt
   wurde davon nichts: keine ihrer Klassen, keine ihrer Variablen (Suche
   ueber apps/meluciolabs). Wirksam waren nur die zwei globalen Bloecke
   hier unten, und die stehen jetzt in dieser Datei, die jede Seite ohnehin
   laedt. Ein render-blockierender Abruf weniger. Die Staffel bleibt die
   Quelle fuer Breakpoints
   (packages/@meluciolabs/ui-components/src/theme/melucio-breakpoints.css).

   Weniger Bewegung per Systemeinstellung: melucio-site.css hat dafuer
   einen eigenen, strengeren Block, die Rechtsseiten, 404 und /v/termin
   laden sie aber nicht. Dieselbe Regel wie der Schalter in
   melucio-a11y.css (data-motion), nur unter der Media Query. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}
@media print {
    body { background: white !important; color: black !important; }
}

/* components/melucio-fuss.css */
/* ══════════════════════════════════════════════════════════════════════
   Der statische Fuss: Rechtsseiten, 404, /ki-demo, /v/termin
   ══════════════════════════════════════════════════════════════════════

   Zwei <nav> mit Namen, "Seiten" und "Rechtliches", Widerruf und
   Kuendigung als Pillen, darunter das Copyright (26.09.2026, design-berater,
   von David freigegeben). Statisches HTML statt einer Komponente, weil die
   Seiten ohne Skript lesbar bleiben sollen und die Druckansicht den Fuss
   ohnehin weglaesst.

   SEIT 26.09.2026 AUF ALLEN SEITEN, auch den zwoelf Hauptseiten. Dort stand
   bis dahin <melucio-footer groups>, und die Links entstanden erst per
   Skript im Shadow-DOM: ohne JavaScript fehlten Impressum, Datenschutz,
   Kuendigung (§ 312k BGB) und Widerruf (§ 356a BGB) ganz
   (rechtstexte-pruefer 26.09.2026). Die Komponente leistete hier nichts,
   was dieser Fuss nicht auch kann; sie zu behalten und den Fuss als
   Rueckfall hineinzulegen haette dieselben Links zweimal gepflegt.
   Alle Seiten binden diese Datei im <head> ein, direkt nach melucio-nav.css.
   Die Gleichheit aller Fuesse prueft _tools/pruefe-kopf.mjs.

   Nichts davon steht in einem Modal: Impressum (§ 5 DDG), Kuendigung
   (§ 312k BGB), Widerruf (§ 356a BGB) und Datenschutz sind auf jeder
   Seite direkte Links.

   Stand vorher in drei Fassungen (melucio-recht.css, 404.html inline,
   Erzeuger von /v/termin inline), und /v/termin fehlte dabei der Link
   auf /barrierefreiheit (CLAUDE.md, Punkt 22). */

.lp-footer {
    max-width: 760px;
    width: 100%;
    margin: 0 auto;
    padding: 24px 0 40px;
    border-top: 1px solid var(--border);
    color: var(--muted);
    font-size: 0.875rem;
    text-align: center;
}
/* Auf den Hauptseiten laufen die Abschnitte ueber die ganze Breite; der
   Fuss tut es mit ihnen, wie vorher die Komponente (Linie vollbreit, Inhalt
   mittig). */
.lp-footer--seite { max-width: none; padding-top: 2rem; }
/* Nur der Copyright-Streifen weicht den schwebenden Knoepfen seitlich aus
   (CLAUDE.md, Punkt 6); die Linkzeilen bekommen 1rem, sonst bricht jede
   Zeile auf dem Telefon zweimal um. */
.lp-footer nav { padding-inline: 1rem; }
.lp-footer nav + nav::before {
    content: "";
    display: block;
    width: 40px;
    height: 1px;
    margin: 0.5rem auto;
    background: var(--border);
}
.fuss-zeile {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    column-gap: 4px;
}
.fuss-zeile + .fuss-zeile { margin-top: 0.25rem; }
.fuss-zeile > li { display: flex; align-items: center; }
.fuss-zeile a {
    padding: 2px 6px;
    color: var(--muted);
    text-decoration: none;
}
.fuss-zeile a:hover { color: var(--accent-text); text-decoration: none; }
.fuss-zeile.fuss-pillen { column-gap: 8px; row-gap: 8px; margin-top: 0.5rem; }
.fuss-zeile a,
.lp-footer a.fuss-pille { box-sizing: border-box; }
.lp-footer a.fuss-pille {
    position: relative;
    display: inline-flex;
    align-items: center;
    min-height: 32px;
    padding: 0 12px;
    border: 1px solid var(--accent-text);
    border-radius: 999px;
    color: var(--accent-text);
    font-size: 0.8125rem;
    font-weight: 600;
    white-space: nowrap;
}
.lp-footer a.fuss-pille:hover { background: var(--accent-fill-faint); }
/* Die Pillen fuehren ins Portal und oeffnen dort einen neuen Tab, wie im
   Web-Component; das wird angesagt (WCAG 3.2.5), gleicher Wortlaut. */
.fuss-neu {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}
/* Mittelpunkte nur mit Maus und genug Breite; am Finger stuende nach jedem
   Umbruch ein verwaister Punkt am Zeilenanfang. Der Alternativtext "" haelt
   den Punkt aus der Vorlesung heraus. */
@media (pointer: fine) and (min-width: 768px) {
    .fuss-zeile:not(.fuss-pillen) > li + li::before {
        content: "\00B7";
        content: "\00B7" / "";
        margin: 0 0.35rem 0 0.1rem;
    }
}
/* Tap-Flaeche am Finger 44px, in px statt rem (CLAUDE.md, Punkt 7). */
@media (pointer: coarse) {
    .fuss-zeile a {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-height: 44px;
        min-width: 44px;
    }
    .lp-footer a.fuss-pille { min-height: 44px; }
    /* Die Tap-Flaechen sind schon 44px hoch, sie tragen den Abstand. */
    .fuss-zeile + .fuss-zeile:not(.fuss-pillen) { margin-top: 0; }
}
/* Unter 360px (iPhone SE, Galaxy S8) passte die Rechtszeile mit vier
   Links nicht mehr und brach in zwei. Etwas kleiner statt eine Zeile mehr. */
@media (max-width: 359px) {
    .lp-footer nav { padding-inline: 0.5rem; }
    .fuss-zeile a { padding-inline: 4px; font-size: 0.8125rem; }
}
.lp-footer .lp-copy {
    color: var(--muted);
    margin: 0.75rem 0 0;
    padding-inline: max(1rem, calc(var(--fab-rand, 20px) + var(--fab-bot-h, 46px)));
    font-size: 0.8rem;
}
.lp-footer .lp-copy a { color: var(--accent-text); text-decoration: underline; }
@media (max-width: 480px) {
    .lp-footer { padding-block: 1.5rem; }
}
:root[data-contrast='high'] .lp-footer,
:root[data-contrast='high'] .lp-footer nav + nav::before { border-color: var(--hc-line); }
:root[data-contrast='high'] .lp-footer nav + nav::before { background: var(--hc-line); }
