/* ==========================================================================
   ESD KOMPONENTEN-CSS - die eine Heimat der Bedien-Elemente
   @esd-components-version: 1.0.0
   @stand: 2026-09-06
   @sot: knowledge/design-system.md v5.0 (§6.4, §8.2, §9, §9.6, §9.7, §11, §13.1)
   @paket: Frontend-Fundament Paket 4 (knowledge/ui-bibliothek-briefing.md)

   ZWECK
   Jedes Bedien-Element der Website existiert EINMAL, in allen Zustaenden, mit
   Tastatur- und Screenreader-Vertrag. Ein Button-Fix passiert einmal statt
   37-mal; ein Kunden-Theme bleibt ein Token-Tausch. Diese Datei aendert KEINEN
   Design-Wert - sie giesst die in der SoT entschiedenen Werte in Klassen.
   Fehlt ein Wert in der SoT, steht in der Quelldatei [MISSING: ...].

   LAUFORT (Briefing §2, Entscheid A)
   Global geladen wie tokens.css, DIREKT DANACH (esd-core, wp_enqueue_style,
   Abhaengigkeit esd-tokens). Diese Datei setzt selbst keine Token-Werte; sie
   LIEST tokens.css. Ohne tokens.css davor ist sie wirkungslos, nicht kaputt.

   SCOPE (nicht-invasiv bis zur Migration)
   Alle Selektoren sind mit :where(.esd-canvas) geschrieben - Spezifitaet wie
   eine einzelne Klasse. Eine noch nicht migrierte Seite, die `.esd-canvas .btn{}`
   oder `.inf-det{}` selbst definiert, GEWINNT weiter. Das ist gewollt und wird
   nicht bekaempft (kein !important, kein Spezifitaets-Trick): das Abraeumen der
   Seiten-Regeln passiert beim Anfassen der Seite. Dieselbe Philosophie wie
   tokens.css.

   LAYER-KONTEXT
   Die Komponenten lesen --ui-bg / --ui-text / --ui-text-2 / --ui-text-3 /
   --ui-line / --ui-line-2 / --ui-accent / --ui-field / --ui-focus. Gesetzt
   werden diese Namen vom Abschnitt `basis` (Datei 00-basis.html) je Ebene:
   .esd-canvas = Layer 0, .esd-layer-1/-2/-3, .esd-tone-light, .esd-layer-light-1.
   So bleibt "Karte in Karte" eine Klasse und kein Sonderfall.

   PFLEGE
   GENERIERT AUS website/components/ui/ - NICHT VON HAND EDITIEREN.
   Die Wahrheit lebt in den Einzeldateien (dort auch Zustands-Matrix,
   ARIA-Vertrag, Slot-Deklaration und Werkstatt-Lehren). Neu bauen mit:
       python website/components/ui/_assemble.py
   Wer einen Wert dreht, dreht ihn ZUERST in knowledge/design-system.md, dann
   in tokens.css, dann in der Komponenten-Datei - nie hier.

   ENTHALTEN (6): basis - button - field - card - accordion - sechead
   ========================================================================== */


/* ==========================================================================
   @esd-section: 00 - basis
   @sot: website/components/ui/00-basis.html
   ========================================================================== */
/* ===ui:basis CSS v1=== */
/* ==========================================================================
   LAYER-KONTEXTE
   Die Regel setzt NUR Variablen plus die Fliesstext-Farbe. Kein Hintergrund,
   keine Geometrie, kein Rand - sonst wuerden Bestandsseiten, die
   .esd-tone-light schon tragen, ihre eigene Flaeche verlieren.

   DIE RAISE-TREPPE (die Loesung fuer "Karte in Karte", ohne JS)
   Jeder Kontext exportiert vier Saetze:
     --ui-*        der Layer, auf dem der Inhalt JETZT sitzt
     --ui-raise-*  der naechste Layer  (= Grund einer Karte hier)
     --ui-raise2-* der uebernaechste   (= Grund einer Karte in der Karte)
     --ui-raise3-* der drittnaechste   (= Karte in Karte in Karte, dann Deckel)
   .esd-card (03-card) liest je nach Verschachtelungstiefe raise / raise2 /
   raise3 und schreibt daraus seinen eigenen --ui-*-Satz fuer die Kinder.
   WARUM VIER SAETZE statt einer Kette: CSS loest alle Custom Properties eines
   Elements gemeinsam auf. Schriebe eine Karte --ui-raise: var(--ui-raise2),
   laese ihr eigenes background: var(--ui-raise) bereits den neuen Wert - die
   Treppe kollabierte um eine Stufe. Absolute Slots kollidieren nicht, weil
   eine Karte NUR in den --ui-*-Satz schreibt und nur aus den raise-Saetzen
   liest. Tiefe 4 und tiefer bleibt auf Layer 3 (bzw. auf der hellen Insel auf
   layer-light-1) - dort endet die Treppe, tokens.css kennt keine weitere.

   CARBON-FELDREGEL (tokens.css Abschnitt 3): --ui-field ist immer der Grund
   der NAECHSTEN Stufe. Ein Eingabefeld auf Layer 1 traegt also Layer-2-Grund,
   sonst verschwindet es im Panel. --ui-field und --ui-raise sind deshalb
   wertgleich; sie stehen trotzdem getrennt, weil sie Verschiedenes meinen
   (Feld gegenueber Objekt) und ein Kunden-Theme sie trennen koennen muss.
   ========================================================================== */

/* --- A) Layer 0: die Buehne. Jede .esd-canvas-Seite startet hier. --- */
:where(.esd-canvas){
  --ui-bg:            var(--layer-0);
  --ui-text:          var(--layer-0-text);
  --ui-text-2:        var(--layer-0-text-2);
  --ui-text-3:        var(--layer-0-text-3);
  --ui-line:          var(--layer-0-line);
  --ui-line-2:        var(--layer-0-line-2);
  --ui-accent:        var(--layer-0-accent);
  --ui-field:         var(--layer-0-field);
  --ui-focus:         var(--layer-0-focus);

  --ui-raise:         var(--layer-1);
  --ui-raise-text:    var(--layer-1-text);
  --ui-raise-text-2:  var(--layer-1-text-2);
  --ui-raise-text-3:  var(--layer-1-text-3);
  --ui-raise-line:    var(--layer-1-line);
  --ui-raise-line-2:  var(--layer-1-line-2);
  --ui-raise-accent:  var(--layer-1-accent);
  --ui-raise-field:   var(--layer-1-field);
  --ui-raise-focus:   var(--layer-1-focus);

  --ui-raise2:        var(--layer-2);
  --ui-raise2-text:   var(--layer-2-text);
  --ui-raise2-text-2: var(--layer-2-text-2);
  --ui-raise2-text-3: var(--layer-2-text-3);
  --ui-raise2-line:   var(--layer-2-line);
  --ui-raise2-line-2: var(--layer-2-line-2);
  --ui-raise2-accent: var(--layer-2-accent);
  --ui-raise2-field:  var(--layer-2-field);
  --ui-raise2-focus:  var(--layer-2-focus);

  --ui-raise3:        var(--layer-3);
  --ui-raise3-text:   var(--layer-3-text);
  --ui-raise3-text-2: var(--layer-3-text-2);
  --ui-raise3-text-3: var(--layer-3-text-3);
  --ui-raise3-line:   var(--layer-3-line);
  --ui-raise3-line-2: var(--layer-3-line-2);
  --ui-raise3-accent: var(--layer-3-accent);
  --ui-raise3-field:  var(--layer-3-field);
  --ui-raise3-focus:  var(--layer-3-focus);

  color: var(--ui-text-2);
}

/* --- B) Layer 1: Panel auf der Buehne (.esd-dpanel-Ton) --- */
:where(.esd-canvas) .esd-layer-1{
  --ui-bg:            var(--layer-1);
  --ui-text:          var(--layer-1-text);
  --ui-text-2:        var(--layer-1-text-2);
  --ui-text-3:        var(--layer-1-text-3);
  --ui-line:          var(--layer-1-line);
  --ui-line-2:        var(--layer-1-line-2);
  --ui-accent:        var(--layer-1-accent);
  --ui-field:         var(--layer-1-field);
  --ui-focus:         var(--layer-1-focus);

  --ui-raise:         var(--layer-2);
  --ui-raise-text:    var(--layer-2-text);
  --ui-raise-text-2:  var(--layer-2-text-2);
  --ui-raise-text-3:  var(--layer-2-text-3);
  --ui-raise-line:    var(--layer-2-line);
  --ui-raise-line-2:  var(--layer-2-line-2);
  --ui-raise-accent:  var(--layer-2-accent);
  --ui-raise-field:   var(--layer-2-field);
  --ui-raise-focus:   var(--layer-2-focus);

  --ui-raise2:        var(--layer-3);
  --ui-raise2-text:   var(--layer-3-text);
  --ui-raise2-text-2: var(--layer-3-text-2);
  --ui-raise2-text-3: var(--layer-3-text-3);
  --ui-raise2-line:   var(--layer-3-line);
  --ui-raise2-line-2: var(--layer-3-line-2);
  --ui-raise2-accent: var(--layer-3-accent);
  --ui-raise2-field:  var(--layer-3-field);
  --ui-raise2-focus:  var(--layer-3-focus);

  --ui-raise3:        var(--ui-raise2);
  --ui-raise3-text:   var(--ui-raise2-text);
  --ui-raise3-text-2: var(--ui-raise2-text-2);
  --ui-raise3-text-3: var(--ui-raise2-text-3);
  --ui-raise3-line:   var(--ui-raise2-line);
  --ui-raise3-line-2: var(--ui-raise2-line-2);
  --ui-raise3-accent: var(--ui-raise2-accent);
  --ui-raise3-field:  var(--ui-raise2-field);
  --ui-raise3-focus:  var(--ui-raise2-focus);

  color: var(--ui-text-2);
}

/* --- C) Layer 2: Karte in Karte --- */
:where(.esd-canvas) .esd-layer-2{
  --ui-bg:            var(--layer-2);
  --ui-text:          var(--layer-2-text);
  --ui-text-2:        var(--layer-2-text-2);
  --ui-text-3:        var(--layer-2-text-3);
  --ui-line:          var(--layer-2-line);
  --ui-line-2:        var(--layer-2-line-2);
  --ui-accent:        var(--layer-2-accent);
  --ui-field:         var(--layer-2-field);
  --ui-focus:         var(--layer-2-focus);
  color: var(--ui-text-2);
}

/* --- D) Layer 3: hellste Karten-Stufe, die dritte Buehne (§1.6) --- */
:where(.esd-canvas) .esd-layer-3{
  --ui-bg:            var(--layer-3);
  --ui-text:          var(--layer-3-text);
  --ui-text-2:        var(--layer-3-text-2);
  --ui-text-3:        var(--layer-3-text-3);
  --ui-line:          var(--layer-3-line);
  --ui-line-2:        var(--layer-3-line-2);
  --ui-accent:        var(--layer-3-accent);   /* #4D9BFF statt --accent-lit, §1.6 Regel 2 */
  --ui-field:         var(--layer-3-field);
  --ui-focus:         var(--layer-3-focus);
  color: var(--ui-text-2);
}

/* Raise-Deckel dunkel: ab Layer 2 endet die Treppe auf Layer 3. */
:where(.esd-canvas) .esd-layer-2,
:where(.esd-canvas) .esd-layer-3{
  --ui-raise:         var(--layer-3);
  --ui-raise-text:    var(--layer-3-text);
  --ui-raise-text-2:  var(--layer-3-text-2);
  --ui-raise-text-3:  var(--layer-3-text-3);
  --ui-raise-line:    var(--layer-3-line);
  --ui-raise-line-2:  var(--layer-3-line-2);
  --ui-raise-accent:  var(--layer-3-accent);
  --ui-raise-field:   var(--layer-3-field);
  --ui-raise-focus:   var(--layer-3-focus);

  --ui-raise2:        var(--ui-raise);
  --ui-raise2-text:   var(--ui-raise-text);
  --ui-raise2-text-2: var(--ui-raise-text-2);
  --ui-raise2-text-3: var(--ui-raise-text-3);
  --ui-raise2-line:   var(--ui-raise-line);
  --ui-raise2-line-2: var(--ui-raise-line-2);
  --ui-raise2-accent: var(--ui-raise-accent);
  --ui-raise2-field:  var(--ui-raise-field);
  --ui-raise2-focus:  var(--ui-raise-focus);

  --ui-raise3:        var(--ui-raise);
  --ui-raise3-text:   var(--ui-raise-text);
  --ui-raise3-text-2: var(--ui-raise-text-2);
  --ui-raise3-text-3: var(--ui-raise-text-3);
  --ui-raise3-line:   var(--ui-raise-line);
  --ui-raise3-line-2: var(--ui-raise-line-2);
  --ui-raise3-accent: var(--ui-raise-accent);
  --ui-raise3-field:  var(--ui-raise-field);
  --ui-raise3-focus:  var(--ui-raise-focus);
}

/* --- E) helle Insel (= Layer light-0). Klasse existiert im Defense-Block
       §13 bereits; hier kommen NUR die Variablen dazu. --- */
:where(.esd-canvas) .esd-tone-light{
  --ui-bg:            var(--layer-light-0);
  --ui-text:          var(--layer-light-0-text);
  --ui-text-2:        var(--layer-light-0-text-2);
  --ui-text-3:        var(--layer-light-0-text-3);
  --ui-line:          var(--layer-light-0-line);
  /* [MISSING: --layer-light-0-line-2] siehe Kopf - vorlaeufig dieselbe Hairline */
  --ui-line-2:        var(--layer-light-0-line);
  --ui-accent:        var(--layer-light-0-accent);
  --ui-field:         var(--layer-light-0-field);
  --ui-focus:         var(--layer-light-0-focus);
  color: var(--ui-text-2);
}

/* --- F) Karte auf der hellen Insel (= Layer light-1) --- */
:where(.esd-canvas) .esd-layer-light-1{
  --ui-bg:            var(--layer-light-1);
  --ui-text:          var(--layer-light-1-text);
  --ui-text-2:        var(--layer-light-1-text-2);
  --ui-text-3:        var(--layer-light-1-text-3);
  --ui-line:          var(--layer-light-1-line);
  /* [MISSING: --layer-light-1-line-2] siehe Kopf */
  --ui-line-2:        var(--layer-light-1-line);
  --ui-accent:        var(--layer-light-1-accent);
  --ui-field:         var(--layer-light-1-field);
  --ui-focus:         var(--layer-light-1-focus);
  color: var(--ui-text-2);
}

/* Raise-Deckel hell: die helle Insel kennt genau eine Karten-Stufe. Eine
   Karte in der Karte bleibt deshalb auf layer-light-1 (Weiss auf Weiss mit
   Hairline) - das ist die dokumentierte Grenze, keine Nachlaessigkeit. */
:where(.esd-canvas) .esd-tone-light,
:where(.esd-canvas) .esd-layer-light-1{
  --ui-raise:         var(--layer-light-1);
  --ui-raise-text:    var(--layer-light-1-text);
  --ui-raise-text-2:  var(--layer-light-1-text-2);
  --ui-raise-text-3:  var(--layer-light-1-text-3);
  --ui-raise-line:    var(--layer-light-1-line);
  --ui-raise-line-2:  var(--layer-light-1-line);
  --ui-raise-accent:  var(--layer-light-1-accent);
  --ui-raise-field:   var(--layer-light-1-field);
  --ui-raise-focus:   var(--layer-light-1-focus);

  --ui-raise2:        var(--ui-raise);
  --ui-raise2-text:   var(--ui-raise-text);
  --ui-raise2-text-2: var(--ui-raise-text-2);
  --ui-raise2-text-3: var(--ui-raise-text-3);
  --ui-raise2-line:   var(--ui-raise-line);
  --ui-raise2-line-2: var(--ui-raise-line-2);
  --ui-raise2-accent: var(--ui-raise-accent);
  --ui-raise2-field:  var(--ui-raise-field);
  --ui-raise2-focus:  var(--ui-raise-focus);

  --ui-raise3:        var(--ui-raise);
  --ui-raise3-text:   var(--ui-raise-text);
  --ui-raise3-text-2: var(--ui-raise-text-2);
  --ui-raise3-text-3: var(--ui-raise-text-3);
  --ui-raise3-line:   var(--ui-raise-line);
  --ui-raise3-line-2: var(--ui-raise-line-2);
  --ui-raise3-accent: var(--ui-raise-accent);
  --ui-raise3-field:  var(--ui-raise-field);
  --ui-raise3-focus:  var(--ui-raise-focus);
}

/* WERKSTATT-LEHREN
   R7  Das Modell deckt eine der zwei Bestands-Treppen nicht ab (siehe
       GRENZEN im Kopf). Aufgefallen erst am Pilot, nicht in der Werkstatt:
       die Galerie stand auf --machine, wo alles stimmt. Wer ein Modell baut,
       misst es gegen den Bestand, nicht gegen die eigene Demo.
   R6  Werkstatt-Chrome und Ausliefer-CSS brauchen getrennte Marker. Die
       Regeln der esd-uidemo-Familie standen zuerst im CSS-Block und waeren
       jeder WordPress-Seite gelandet - eine Galerie-Klasse ist kein Produkt
       (Befund Agent C, W2 2026-09-06).
   R1  Eine Kontext-Klasse darf keinen Hintergrund setzen. .esd-tone-light
       existiert seit §13 auf Bestandsseiten MIT Hintergrund (per !important);
       ein zweiter Hintergrund von hier waere entweder wirkungslos oder haette
       beim Abraeumen des Defense-Blocks still die Flaeche uebernommen.
   R2  Die Raise-Treppe braucht absolute Slots, keine Kette. Der naheliegende
       Bau --ui-raise: var(--ui-raise2) auf .esd-card kollabiert, weil CSS alle
       Custom Properties eines Elements gemeinsam aufloest: das Element liest
       dann seinen eigenen neuen Wert (siehe Kopf).
   R3  --ui-field und --ui-raise sind wertgleich, aber nicht dasselbe. Sie
       zusammenzulegen haette ein Kunden-Theme daran gehindert, Felder anders
       zu fuehren als Objekte.
   R5  Eine Meta-/Label-Zeile ist Lesetext. Die tertiaere Stufe sah in der
       Werkstatt richtig aus und fiel im layout-audit mit 2,50 bis 3,42:1
       durch - das Auge taugt hier nicht als Messgeraet (W2, 2026-09-06).
   R4  Layer 1 ist seit dem Wert-Lock 2026-09-04 #17171c, nicht #131318. Die
       Kontrast-Matrix in tokens.css Abschnitt 10 rechnet die L1-Spalte noch
       gegen #131318 - gemeldet, hier gegen den gueltigen Wert gerechnet. */
/* ===/ui:basis CSS=== */


/* ==========================================================================
   @esd-section: 01 - button
   @sot: website/components/ui/01-button.html
   ========================================================================== */
/* ===ui:button CSS v1=== */
/* --------------------------------------------------------------------------
   ui:button v1 - Werte ausschliesslich aus tokens.css.
   Literale nur, wo die SoT sie woertlich nennt (@sot dahinter).
   [ALIAS] Die Alt-Namen .btn-primary/.btn-secondary/.btn-ghost (12 Seiten)
   laufen per :is()-Liste in jeder Modifier-Regel mit. Gemessen 2026-09-06:
   sie stehen im Bestand immer zusammen mit .btn, die Basisregel greift also.
   Das Drift-Gate (W3 component-drift-check.py) meldet sie, bis der Rollout
   sie abgebaut hat.

   WERKSTATT-LEHREN
   R1  Die 60%-Regel (#48) ist auf dem PRIMAER-Knopf nicht WCAG-faehig.
       Weiss auf --accent hat nur 4,83:1 - der Kopfraum ueber dem 4,50-Floor
       betraegt 4%. Gerechnet 2026-09-06: schon bei 94% Deckkraft steht das
       Label bei 4,44:1, bei den geforderten 60% bei 2,65:1. Auf secondary/
       ghost (off-white auf Nacht, 18,56:1) traegt dieselbe Regel muehelos
       (7,00:1). Deshalb hier: 60% als Basisregel wie in der SoT, und EINE
       ausdrueckliche Ausnahme fuer --primary/--on-visual-Fuellungen, wo der
       Ladezustand stattdessen ueber Status-Punkt + aria-busy + cursor:progress
       spricht. [TOBIAS-ENTSCHEID OFFEN] - eine Zeile zurueckzudrehen.
   R2  Ein Knopf-RAND braucht keine 3:1. Gerechnet: --ui-line auf L0 = 1,49:1.
       WCAG 1.4.11 verlangt Kontrast nur fuer das, was das Bedienelement
       IDENTIFIZIERT - beim Knopf ist das sein Label (18,56:1), nicht die
       Hairline. Beim FELD ist es umgekehrt (dort tut es die Box) - deshalb
       weicht 02-field an genau dieser Stelle bewusst von der Hairline ab.
   R3  Hover, Press und Ladezustand duerfen an einem toten Knopf nicht mehr
       feuern. Statt die Zustaende hinterher zu ueberschreiben, tragen die
       Hover-/Press-Regeln selbst eine :not()-Kette. Sonst gewinnt am Ende
       die Reihenfolge im Stylesheet, und das ist keine Regel, sondern Zufall.
   R4  §9 sagt "bei runden Zielen zusaetzlich border-radius: 8px". Das meint
       die Ring-FORM. Der Browser leitet den Outline-Radius aus dem
       Element-Radius ab, und der ist hier bereits --radius-pill; ein
       zusaetzliches border-radius:8px wuerde den Knopf umformen statt den
       Ring. --focus-radius gehoert deshalb an rechteckige Ziele (02-field).
   R8  Das Elementor-Kit schlaegt eine blosse Varianten-Klasse. Gemessen am
       Pilot (Staging, audit-briefing-erhalten). Die LIVE geholte Kit-Datei
       (curl, 2026-09-06) liest:
       `.elementor-kit-15 a{color:var( --e-global-color-accent );
       font-family:"Inter", Sans-serif;}` - Spezifitaet (0,1,1), eine Klasse
       plus ein Typ, --e-global-color-accent = #0066FF.
       ACHTUNG, eigener Fehler: Ich hatte hier zwischenzeitlich auf
       --e-global-color-71c70be (#0A84FF) "korrigiert" - das stand in der
       VERALTETEN Repo-Kopie website/html/live/Shop - ESD_files/post-15.css.
       Die Auftragsfassung war richtig, meine Korrektur falsch. Lehre:
       eine Kopie im Repo ist kein Beleg fuer den Live-Zustand (s. R10). Die Varianten-Regel stand als
       :where(.esd-canvas) :is(.btn--primary,.btn-primary) bei (0,1,0), weil
       :where() nichts beitraegt und :is() nur den Wert seines staerksten
       Arguments (eine Klasse) traegt. Ergebnis: blauer Text auf blauem Grund.
       Gift-/Clean-Probe 2026-09-06 gegen das LIVE geholte Kit: alte Form primary
       #0066FF auf #0066FF (1,0:1), Ghost auf #0066FF statt #3D8BFF; neue Form
       primary #FFFFFF auf #0066FF (4,83:1), Alias identisch, secondary
       #FAFAF7, ghost #3D8BFF. Deshalb tragen alle VARIANTEN-Regeln (Farbe,
       Rand, Grund von primary/secondary/ghost/on-visual samt Hover-, Press-,
       Disabled- und Lade-Zustand) jetzt `.btn` VOR der Varianten-Liste:
       .btn:is(.btn--primary,.btn-primary) = (0,2,0).
       Was das bewusst NICHT tut: es hebelt keine Seite aus. Eine gescopte
       Seiten-Regel .esd-canvas .btn--primary hat ebenfalls (0,2,0) und
       gewinnt weiter ueber die spaetere Position (31 Seiten, nicht-invasiv);
       ueberschrieben wird nur die ungescopte Form .btn--primary{} (0,1,0) -
       die verliert heute ohnehin gegen das Kit. Der Canvas-Scope bleibt als
       :where(.esd-canvas) stehen (traegt 0 bei), damit die Bibliothek nicht
       auf Woo-/Elementor-Flaechen ausserhalb der Canvas greift.
       BASIS-Regeln (.btn Masse, .btn__label, .btn__icon, :focus-visible,
       --small/--large/--block) bleiben bei :where(.esd-canvas) .btn.
   R9  GESCHLOSSEN 2026-09-06. Das Kit adressiert `a` und `button` als TYP -
       (0,1,1) - und schlaegt damit die Basis-Regeln der Bibliothek (0,1,0).
       Geloest mit einer schmalen GEGENREGEL bei ebenfalls (0,1,1)
       (:where() traegt 0, a/button ist Typ + .btn ist Klasse), die nur die
       gemessen betroffenen Felder traegt. Bei Gleichstand entscheidet die
       Dokument-Reihenfolge, und die ist deterministisch: Kit-CSS Index 23,
       components.css Index 40 von 45 (esd-core Prio 998, laedt nach allen
       Elementor-Dateien).
       -> ABHAENGIGKEIT, die das Ganze traegt: sollte components.css je VOR
          post-N.css landen, kippt die Gegenregel lautlos zurueck. Pruefschritt
          bei jeder Aenderung an der Ladereihenfolge oder am Kit:
          [...document.styleSheets].map(s=>s.href) im Browser, die
          components.css muss hinter der post-<id>.css stehen.
       GEMESSEN gegen das LIVE-Kit (curl staging, 2026-09-06), mit/ohne Kit,
       Reihenfolge Kit VOR components:
         <a class="btn">      font-family Inter (ESD-Kette) -> Inter, sans-serif
                              => optisch gleich, aber die ESD-Fallback-Kette
                                 faellt weg; Gegenregel als Versicherung
         <button class="btn"> font-family wie oben
                              padding-left 30,4px -> 24px (Kit .75em 1.5em
                                 gegen ESD .75em 1.9em) - sichtbar schmaler
         Ghost bleibt unberuehrt: .btn--ghost{padding-left:0} traegt (0,2,0).
         Radius, Schriftgewicht, Grund, Farbe und Rand sind LIVE kein Konflikt
         mehr (Kit steht auf 100px und 600, Farben deckt R8 ab).
       NICHT vorsorglich aufgenommen: border-radius. Live traegt das Kit
       100px, also kein Konflikt - aber es stand dort schon einmal auf 5px
       (Repo-Kopie). Aendert jemand den Kit-Radius, bricht die Pille an
       <button> erneut; dann gehoert border-radius hier hinein. Deshalb ist
       der Pruefschritt oben kein Formalismus.
       Der Bestand loeste dieselbe Klasse mit `color:#fff !important`
       (zahlungsarten/idee-check u.a.); das verbietet Briefing §2 - der
       Spezifitaets-Weg kommt ohne aus. Nebenbefund: die Kommentare dort
       nennen die Kit-Spezifitaet mit (0,2,0), richtig ist (0,1,1).
   R10 Eine Kopie im Repo ist kein Beleg fuer den Live-Zustand. Unter
       website/html/live/Shop - ESD_files/post-15.css liegt ein alter Abzug des
       Kits; er zeigt an `a` Trebuchet MS und an `button` border-radius 5px.
       LIVE steht dort Inter und 100px (Kit-Typografie-Fundament 2026-08-21).
       Ich habe zuerst gegen diesen Abzug gemessen und daraus zwei falsche
       Befunde gezogen (Schrift-Konflikt an `a`, Radius-Konflikt an `button`)
       sowie eine richtige Auftragsangabe "korrigiert". Regel daraus: Kit-,
       Theme- und Plugin-CSS fuer eine Messung IMMER frisch von der Quelle
       holen (curl der live ausgelieferten Datei) und das Fixture mit Datum
       versehen. Ein Abzug im Repo ist ein Fixture, kein Zeuge.
   -------------------------------------------------------------------------- */

/* --- Basis --- */
:where(.esd-canvas) .btn{
  box-sizing:border-box;
  display:inline-flex; align-items:center; justify-content:center; gap:.5em;
  min-height:var(--target-min);           /* §4 #27 / §13.1 Pkt. 8 */
  padding:.75em 1.9em;                    /* @sot §3.5 Chrome-Zeile, woertlich */
  border:1px solid transparent;
  border-radius:var(--radius-pill);
  background-color:transparent;
  color:var(--ui-text);
  font-family:var(--font-body);
  font-size:1rem;                         /* @sot §3.6 Button-Zeile; s. [MISSING] im Kopf */
  font-weight:var(--fw-semibold);
  line-height:1.25;                       /* mechanisch, s. [MISSING] im Kopf */
  letter-spacing:var(--track-body);
  text-align:center; text-decoration:none;
  cursor:pointer;
  white-space:normal;                     /* Langtext bricht um, statt zu ueberlaufen */
  overflow-wrap:break-word;
  text-wrap:balance;
  max-width:100%;
  -webkit-appearance:none; appearance:none;
  transition:background-color var(--dur-hover) var(--ease-out),
             border-color var(--dur-hover) var(--ease-out),
             color var(--dur-hover) var(--ease-out),
             box-shadow var(--dur-hover) var(--ease-out),
             opacity var(--dur-hover) var(--ease-out),
             transform var(--dur-hover) var(--ease-out);
}
:where(.esd-canvas) .btn__label{display:inline}
:where(.esd-canvas) .btn__icon{
  flex:0 0 auto; width:24px; height:24px;  /* 24er-Raster (§4); die Zielgroesse traegt der Knopf */
  color:currentColor; fill:none; stroke:currentColor;
  transition:transform var(--dur-hover) var(--ease-out);
}

/* --- Kit-Gegenregel (0,1,1) - NUR die zwei gemessenen Felder, s. Lehre R9 ---
   Das Elementor-Kit adressiert `a` und `button` als TYP und kommt damit auf
   (0,1,1); die Basis oben traegt (0,1,0) und verliert. Gegen das Kit reicht
   Gleichstand: bei gleicher Spezifitaet entscheidet die Dokument-Reihenfolge,
   und components.css laedt gemessen NACH dem Kit (Index 40 von 45 gegen 23).
   Bewusst NICHT (0,2,0): 22 Bestandsseiten definieren .btn{} ungescopt, davon
   21 mit Polster oder Radius - eine Basis auf (0,2,0) wuerde deren Knopfmasse
   live ueberschreiben (gezaehlt 2026-09-06). Gegen eine GESCOPTE Seiten-Regel
   .esd-canvas .btn (0,2,0) bleibt die Bibliothek weiter unterlegen.
   Getragen wird nur, was gegen das LIVE-Kit gemessen noetig ist. */
:where(.esd-canvas) a.btn,
:where(.esd-canvas) button.btn{
  font-family:var(--font-body);           /* Kit setzt Inter OHNE die ESD-Fallback-Kette */
}
:where(.esd-canvas) button.btn{
  padding:.75em 1.9em;                    /* Kit setzt .75em 1.5em - schmalere Pille */
}

/* --- Fokus (Pflicht auf JEDEM interaktiven Element, §9 #83 / §13.1 Pkt. 3) --- */
:where(.esd-canvas) .btn:focus-visible{
  outline:var(--focus-width) solid var(--ui-focus);
  outline-offset:var(--focus-offset);
}

/* --- Primary --- */
:where(.esd-canvas) .btn:is(.btn--primary,.btn-primary){
  background-color:var(--accent);
  border-color:var(--accent);
  color:#FFFFFF;                          /* @sot §9 "weisser Text" / §1.6 4,83:1 */
}
/* --- Secondary (Off-white-Outline auf Dunkel, §9) --- */
:where(.esd-canvas) .btn:is(.btn--secondary,.btn-secondary){
  background-color:transparent;
  border-color:var(--ui-line);
  color:var(--ui-text);
}
/* --- Secondary ueber einem Visual: opaker Panel-Grund statt Transparenz (§9) --- */
:where(.esd-canvas) .btn:is(.btn--secondary,.btn-secondary).btn--on-visual{
  background-color:var(--panel);
  border-color:var(--panel);
  color:var(--ink);
}
/* --- Ghost (Textlink-Optik mit Pfeil-Slot) --- */
:where(.esd-canvas) .btn:is(.btn--ghost,.btn-ghost){
  padding-left:0; padding-right:0;
  border-color:transparent; background-color:transparent;
  color:var(--ui-accent);
}

/* --- Groessen: nur die Schrift dreht, der em-Innenabstand folgt (§3.5) --- */
:where(.esd-canvas) .btn--small{font-size:var(--text-meta)}
:where(.esd-canvas) .btn--large{font-size:var(--text-lead)}
:where(.esd-canvas) .btn--block{display:flex; width:100%}

/* --- Hover (§9 #82; R3: die :not()-Kette haelt tote Knoepfe still) --- */
:where(.esd-canvas) .btn:not(:disabled):not([aria-disabled="true"]):not(.is-loading):hover{
  transform:translateY(-1px);             /* @sot §9 #82 "bewusst 1px" */
}
:where(.esd-canvas) .btn:is(.btn--primary,.btn-primary):not(:disabled):not([aria-disabled="true"]):not(.is-loading):hover{
  background-color:var(--accent-hover);
  border-color:var(--accent-hover);
  box-shadow:0 8px 24px var(--accent-glow);   /* @sot §9 #82, woertlich */
}
:where(.esd-canvas) .btn:is(.btn--secondary,.btn-secondary):not(:disabled):not([aria-disabled="true"]):not(.is-loading):hover{
  background-color:var(--glass-bg);           /* @sot §9 #82 nennt rgba(250,250,247,.05) woertlich;
                                                 --glass-bg traegt exakt diesen Wert. Genommen wird
                                                 nur die FARBE, nicht das Glas-Material (§2.2 kein
                                                 backdrop-filter) - so lebt der Wert weiter genau einmal. */
  border-color:var(--ui-text-2);              /* §9 nennt --text-secondary; --ui-text-2 loest
                                                 auf L0-L3 genau darauf auf */
}
:where(.esd-canvas) .btn:is(.btn--secondary,.btn-secondary).btn--on-visual:not(:disabled):not([aria-disabled="true"]):not(.is-loading):hover{
  background-color:var(--panel-hover);
  border-color:var(--panel-hover);
  box-shadow:var(--shadow-d-md);              /* der weisse Knopf loest sich vom Visual */
}
:where(.esd-canvas) .btn:is(.btn--ghost,.btn-ghost):not(:disabled):not([aria-disabled="true"]):not(.is-loading):hover{
  text-decoration:underline; text-underline-offset:.25em;
}
:where(.esd-canvas) .btn:is(.btn--ghost,.btn-ghost):not(:disabled):not([aria-disabled="true"]):not(.is-loading):hover .btn__icon{
  transform:translateX(3px);
}

/* --- Press (§8.2, Pflicht) --- */
:where(.esd-canvas) .btn:not(:disabled):not([aria-disabled="true"]):not(.is-loading):active{
  transform:scale(0.97);                  /* @sot §8.2, woertlich */
}

/* --- Deaktiviert (§9 #48) --- */
:where(.esd-canvas) .btn:disabled,
:where(.esd-canvas) .btn[aria-disabled="true"]{
  opacity:.45;                            /* @sot §9 #48, woertlich */
  cursor:not-allowed;
  box-shadow:none;
  transform:none;
}

/* --- Ladezustand (§9 #48) --- */
:where(.esd-canvas) .btn.is-loading{cursor:progress}
:where(.esd-canvas) .btn.is-loading .btn__label{opacity:.6}   /* @sot §9 #48, woertlich */
/* R1: Ausnahme fuer gefuellte Knoepfe - dort reisst 60% den Text-Floor (2,65:1). */
:where(.esd-canvas) .btn:is(.btn--primary,.btn-primary).is-loading .btn__label,
:where(.esd-canvas) .btn.btn--on-visual.is-loading .btn__label{opacity:1}
:where(.esd-canvas) .btn.is-loading::after{
  content:""; flex:0 0 auto;
  width:.5em; height:.5em; border-radius:var(--radius-pill);
  background-color:currentColor;
  animation:esd-btn-puls 900ms var(--ease-in-out) infinite alternate;
}
@keyframes esd-btn-puls{
  from{opacity:.35; transform:scale(.72)}
  to  {opacity:1;   transform:scale(1)}
}

/* --- Helle Insel: Ink-Outline statt Off-white (§9) --- */
:where(.esd-canvas) :is(.esd-tone-light,.esd-layer-light-1) .btn:is(.btn--secondary,.btn-secondary):not(.btn--on-visual){
  border-color:var(--ui-text-2);          /* --ink-2 auf Papier: 5,15:1 */
  color:var(--ui-text);
}
:where(.esd-canvas) :is(.esd-tone-light,.esd-layer-light-1) .btn:is(.btn--secondary,.btn-secondary):not(.btn--on-visual):not(:disabled):not([aria-disabled="true"]):not(.is-loading):hover{
  background-color:var(--paper-deep);
  border-color:var(--ui-text);
}

/* --- reduced-motion: Bewegung aus, Farbwechsel bleiben (§8.2 Pflichtzweig) --- */
@media (prefers-reduced-motion: reduce){
  :where(.esd-canvas) .btn{
    transition:background-color var(--dur-hover) var(--ease-out),
               border-color var(--dur-hover) var(--ease-out),
               color var(--dur-hover) var(--ease-out),
               box-shadow var(--dur-hover) var(--ease-out),
               opacity var(--dur-hover) var(--ease-out);
  }
  :where(.esd-canvas) .btn:not(:disabled):not([aria-disabled="true"]):not(.is-loading):hover,
  :where(.esd-canvas) .btn:not(:disabled):not([aria-disabled="true"]):not(.is-loading):active{
    transform:none;
  }
  :where(.esd-canvas) .btn__icon{transition:none}
  :where(.esd-canvas) .btn:is(.btn--ghost,.btn-ghost):not(:disabled):not([aria-disabled="true"]):not(.is-loading):hover .btn__icon{
    transform:none;
  }
  :where(.esd-canvas) .btn.is-loading::after{animation:none; opacity:1; transform:none}
}
/* ===/ui:button CSS=== */


/* ==========================================================================
   @esd-section: 02 - field
   @sot: website/components/ui/02-field.html
   ========================================================================== */
/* ===ui:field CSS v1=== */
/* --------------------------------------------------------------------------
   ui:field v1 - Werte ausschliesslich aus tokens.css.
   Literale nur, wo die SoT sie woertlich nennt (@sot dahinter) oder wo der
   Wert mechanisch ist (dann als solcher benannt).

   WERKSTATT-LEHREN
   F1  Beim FELD traegt die Box die Identifikation, nicht der Text - und
       genau deshalb reicht die Hairline dort nicht. Gerechnet 2026-09-06:
       die Carbon-Feldregel (Feldgrund = eine Layer-Stufe hoeher) ergibt
       #17171c auf #0d0d10 = 1,09:1, und der Hairline-Rand --ui-line (16%)
       kommt auf 1,49:1. Beides reisst die 3,00:1 aus WCAG 1.4.11, und
       WCAG 2.2 AA ist seit dem Frontend-Fundament-Entscheid 3a
       (Tobias 2026-09-04, §13.1) Hausstandard. §9 nennt an dieser Stelle
       kein Zahlenmass, sondern das Wort "Hairline" - deshalb gilt hier der
       Standard, nicht die Prosa. Gesetzt ist der naechsthoehere VORHANDENE
       Token, der den Floor schafft: --ui-text-3 auf Dunkel (3,39:1) und
       --ui-text-2 auf der hellen Insel (5,15/5,32:1; --ui-text-3 ist dort
       --ink-3 und schafft mit 2,54:1 nicht einmal 3,00). Kein neuer Wert,
       kein Literal - ein Token-Tausch je Buehne dreht es zurueck.
       Gegenprobe fuer den Knopf steht in 01-button, Lehre R2: dort ist es
       umgekehrt, weil das Label identifiziert.
   F2  Die Fehlermeldung steht in --ui-text, nicht in Rot. Gerechnet:
       --c-error auf der dritten Buehne (L3 #2C2C2E) = 4,09:1, also unter
       dem Text-Floor; auf der hellen Insel waeren es 3,13:1 und man
       muesste je Buehne auf --c-error-ink wechseln. Rot traegt hier den
       RAND und das Zeichen (beides Nicht-Text, Floor 3,00), der Satz
       traegt sich selbst. Nebeneffekt: die Regel "Farbe nie allein"
       (§1.3) ist damit nicht nur erfuellt, sondern erzwungen.
   F3  Das echte input-Element eines Hakens wird NICHT versteckt (display:none /
       visibility:hidden), sondern deckungsgleich unsichtbar ueber sein
       sichtbares Kaestchen gelegt. Nur so bleiben die native Roving-Logik
       der Radio-Gruppe, das Umschalten mit der Leertaste und die
       Klick-Flaeche erhalten - und der Fokus-Ring kann per
       :focus-visible + Geschwister auf das Kaestchen wandern.
   F4  Autofill ueberschreibt Grund und Schriftfarbe mit Browser-Werten und
       laesst sich nur ueber einen inset-Schatten zaehmen. Der 100px-Radius
       darin ist kein Design-Wert, sondern die Flaeche, die den Feldgrund
       sicher ueberdeckt.
   F6  box-sizing ist bei einem Kaestchen keine Kosmetik. Erste Messung
       2026-09-06: das 24er-Kaestchen kam mit Rand auf 26 x 26 und die
       Haken-Zeile auf 64 statt 44 - beide Male, weil width/min-height ohne
       border-box die INHALTS-Box meinen. Seither tragen .esd-field__choice
       und .esd-field__box border-box; nachgemessen 24 x 24 und 45 px hoch.
   F5  Der Platzhalter ist ein BEISPIEL, kein Label (forms.md Pkt. 3).
       Deshalb steht er in --ui-text-3 (3,42:1) - bewusst unter dem
       Text-Floor, weil dort nie Information liegt, die nicht auch im
       Label oder im Hinweis steht.
   F7  W2-Lehre: eine Galerie darf keine eigenen Klassen erfinden - der
       Marker-Block wandert in den Katalog, die Klassen des Standalone-
       Blocks nicht. Hier trug die Galerie .ui-page/.ui-grid; im Katalog
       stand die .esd-tone-light-Flaeche dadurch ohne Papier-Grund
       (gemessen 1,05:1 statt 16,31:1). Jetzt: Katalog-Chrome .ui-demo*
       (gespiegelt) + .esd-uidemo-grid aus 00-basis. Das Raster ist hier
       richtig, weil Felder ihre Spaltenbreite fuellen SOLLEN - bei
       Knoepfen ist es falsch (01-button, Lehre R6).
   -------------------------------------------------------------------------- */

/* --- Wrapper --- */
:where(.esd-canvas) .esd-field{
  display:block; margin:0 0 24px;   /* 24 = 8-Punkt-Raster (§4) */
}
:where(.esd-canvas) .esd-field:last-child{margin-bottom:0}

/* --- Label: SICHTBAR ueber dem Feld (forms.md Pkt. 3) --- */
:where(.esd-canvas) .esd-field__label{
  display:block; margin:0 0 8px;
  font-family:var(--font-body);
  font-size:var(--text-label);
  font-weight:var(--fw-medium);      /* tokens.css: --fw-medium ist die Label-Rolle */
  line-height:var(--lh-meta);
  letter-spacing:var(--track-meta);
  color:var(--ui-text);
}
/* Pflicht als TEXT, nicht als Sternchen und nicht ueber Farbe (WCAG 3.3.2) */
:where(.esd-canvas) .esd-field__req{
  margin-left:.4em;
  font-weight:var(--fw-normal);
  color:var(--ui-text-2);
}

/* --- Bedienelement --- */
:where(.esd-canvas) .esd-field__control{
  box-sizing:border-box;
  display:block; width:100%;
  min-height:var(--target-min);      /* §4 #27 / §13.1 Pkt. 8 */
  padding:.75em 1em;                 /* em, §3.5 Skalierungs-Regel */
  border:1px solid var(--ui-text-3); /* Lehre F1 - nicht --ui-line */
  border-radius:var(--radius-field); /* @sot §3.6 "Formularfeld: Radius 12px" */
  background-color:var(--ui-field);  /* Carbon-Feldregel, tokens.css Abschnitt 3 */
  color:var(--ui-text);
  font-family:var(--font-body);
  font-size:1rem;                    /* @sot §9.6 "1rem - Floor, nie darunter" (iOS-Zoom) */
  font-weight:var(--fw-normal);
  line-height:var(--lh-body);
  letter-spacing:var(--track-body);
  -webkit-appearance:none; appearance:none;
  transition:border-color var(--dur-hover) var(--ease-out),
             background-color var(--dur-hover) var(--ease-out),
             color var(--dur-hover) var(--ease-out);
}
:where(.esd-canvas) textarea.esd-field__control{
  min-height:120px;                  /* 8-Punkt-Raster (§4); s. [MISSING] im Kopf */
  resize:vertical;
}
:where(.esd-canvas) .esd-field__control::placeholder{
  color:var(--ui-text-3); opacity:1; /* Lehre F5 - Beispiel, nie Label-Ersatz */
}
:where(.esd-canvas) .esd-field__control:hover:not(:disabled):not([readonly]){
  border-color:var(--ui-text-2);
}
:where(.esd-canvas) .esd-field__control:focus-visible{
  outline:var(--focus-width) solid var(--ui-focus);
  outline-offset:var(--focus-offset);
  border-color:var(--ui-focus);
}

/* --- Auswahl: eigener Pfeil, gesetzter Grund (V-F19 Windows-Dark-Bug) --- */
:where(.esd-canvas) select.esd-field__control{
  background-color:var(--ui-field);
  color:var(--ui-text);
  padding-right:2.75em;              /* Platz fuer den Pfeil */
  cursor:pointer;
}
:where(.esd-canvas) select.esd-field__control option{
  background-color:var(--ui-field);
  color:var(--ui-text);
}
:where(.esd-canvas) .esd-field__select{position:relative; display:block}
:where(.esd-canvas) .esd-field__select:focus-within::after{
  border-right-color:var(--ui-focus);
  border-bottom-color:var(--ui-focus);
}
:where(.esd-canvas) .esd-field__select::after{
  content:""; position:absolute; right:1.15em; top:50%;
  width:8px; height:8px; margin-top:-6px;
  border-right:2px solid var(--ui-text-2);
  border-bottom:2px solid var(--ui-text-2);
  transform:rotate(45deg);
  pointer-events:none;
  transition:border-color var(--dur-hover) var(--ease-out);
}

/* --- Hinweis --- */
:where(.esd-canvas) .esd-field__hint{
  display:block; margin:8px 0 0;
  font-size:var(--text-meta);
  line-height:var(--lh-meta);
  color:var(--ui-text-2);            /* tragender Text, Floor §1.6 Regel 1 */
}

/* --- Meldung (Fehler und Erfolg) - Lehre F2 --- */
:where(.esd-canvas) .esd-field__msg{
  display:flex; align-items:flex-start; gap:.5em;
  margin:8px 0 0;
  font-size:var(--text-meta);
  line-height:var(--lh-meta);
  color:var(--ui-text);
}
:where(.esd-canvas) .esd-field__msg::before{
  content:"!";
  flex:0 0 auto;
  display:inline-flex; align-items:center; justify-content:center;
  width:1.35em; height:1.35em;
  border:1px solid currentColor; border-radius:var(--radius-pill);
  font-weight:var(--fw-semibold); font-size:.85em; line-height:1;
  color:var(--c-error);
}
:where(.esd-canvas) .esd-field__msg--success::before{
  content:"\2713";
  color:var(--c-live);
}

/* --- Fehlerzustand --- */
:where(.esd-canvas) .esd-field.is-error .esd-field__control,
:where(.esd-canvas) .esd-field__control[aria-invalid="true"]{
  border-color:var(--c-error);
}
/* --- Erfolgszustand --- */
:where(.esd-canvas) .esd-field.is-success .esd-field__control{
  border-color:var(--c-live);
}

/* --- Deaktiviert / nur lesbar (§9 #48) --- */
:where(.esd-canvas) .esd-field__control:disabled{
  opacity:.45; cursor:not-allowed;   /* @sot §9 #48, woertlich */
}
:where(.esd-canvas) .esd-field__control[readonly]{
  background-color:transparent;
  border-color:var(--ui-line);
  color:var(--ui-text-2);
  cursor:default;
}

/* --- Autofill zaehmen (Lehre F4) --- */
:where(.esd-canvas) .esd-field__control:-webkit-autofill,
:where(.esd-canvas) .esd-field__control:-webkit-autofill:hover,
:where(.esd-canvas) .esd-field__control:-webkit-autofill:focus{
  -webkit-box-shadow:0 0 0 100px var(--ui-field) inset;  /* 100px = Ueberdeckung, kein Design-Wert */
  -webkit-text-fill-color:var(--ui-text);
  caret-color:var(--ui-text);
}

/* --- Haken und Radio (Lehre F3) --- */
:where(.esd-canvas) .esd-field--choice{margin:0 0 16px}
:where(.esd-canvas) .esd-field__choice{
  box-sizing:border-box;
  position:relative;
  display:flex; align-items:flex-start; gap:12px;
  min-height:var(--target-min);      /* Trefferflaeche 44 (§13.1 Pkt. 8) */
  padding:10px 0;                    /* 44 - 24 Kaestchen = 20, also 10 oben/unten */
  cursor:pointer;
  font-family:var(--font-body);
  font-size:1rem;
  line-height:var(--lh-body);
  color:var(--ui-text);
}
/* Das echte Bedienelement bleibt im DOM und deckungsgleich ueber dem Kaestchen */
:where(.esd-canvas) .esd-field__input{
  position:absolute; left:0; top:10px;
  width:24px; height:24px; margin:0;
  opacity:0; cursor:pointer;
  -webkit-appearance:none; appearance:none;
}
:where(.esd-canvas) .esd-field__box{
  box-sizing:border-box;                    /* 24 heisst 24, auch mit Rand */
  flex:0 0 auto;
  position:relative;
  width:24px; height:24px;
  border:1px solid var(--ui-text-3);        /* Lehre F1 */
  border-radius:var(--radius-focus);        /* s. [MISSING] im Kopf */
  background-color:var(--ui-field);
  transition:background-color var(--dur-hover) var(--ease-out),
             border-color var(--dur-hover) var(--ease-out);
}
:where(.esd-canvas) .esd-field__box--radio{border-radius:var(--radius-pill)}
:where(.esd-canvas) .esd-field__box::after{
  content:""; position:absolute; inset:0;
  opacity:0;
  transition:opacity var(--dur-hover) var(--ease-out);
}
/* Haken als zwei Kanten eines gedrehten Rechtecks - reines CSS, kein Bild */
:where(.esd-canvas) .esd-field__box:not(.esd-field__box--radio)::after{
  left:8px; top:3px; right:auto; bottom:auto;
  width:6px; height:12px;
  border-right:2px solid #FFFFFF;           /* @sot §1.6 "Weiss auf #0066FF" 4,83:1 */
  border-bottom:2px solid #FFFFFF;
  transform:rotate(45deg);
}
:where(.esd-canvas) .esd-field__box--radio::after{
  inset:5px; border-radius:var(--radius-pill);
  background-color:#FFFFFF;                 /* @sot wie oben */
}
:where(.esd-canvas) .esd-field__input:checked + .esd-field__box{
  background-color:var(--accent);
  border-color:var(--accent);
}
:where(.esd-canvas) .esd-field__input:checked + .esd-field__box::after{opacity:1}
:where(.esd-canvas) .esd-field__choice:hover .esd-field__input:not(:disabled) + .esd-field__box{
  border-color:var(--ui-text-2);
}
:where(.esd-canvas) .esd-field__input:focus-visible + .esd-field__box{
  outline:var(--focus-width) solid var(--ui-focus);
  outline-offset:var(--focus-offset);
}
:where(.esd-canvas) .esd-field__input:disabled + .esd-field__box{
  opacity:.45;
}
:where(.esd-canvas) .esd-field__input:disabled ~ .esd-field__text{
  opacity:.45; cursor:not-allowed;
}

/* --- Gruppe: fieldset/legend statt Ueberschrift --- */
:where(.esd-canvas) .esd-field__group{
  margin:0 0 24px; padding:0; border:0;
}
:where(.esd-canvas) .esd-field__legend{
  padding:0; margin:0 0 8px;
  font-size:var(--text-label);
  font-weight:var(--fw-medium);
  letter-spacing:var(--track-meta);
  color:var(--ui-text);
}

/* --- Helle Insel: Rand und Statusfarben drehen mit (§1.6 Regel 2/3) --- */
:where(.esd-canvas) :is(.esd-tone-light,.esd-layer-light-1) .esd-field__control,
:where(.esd-canvas) :is(.esd-tone-light,.esd-layer-light-1) .esd-field__box{
  border-color:var(--ui-text-2);            /* Lehre F1: --ink-3 schafft dort nur 2,54:1 */
}
:where(.esd-canvas) :is(.esd-tone-light,.esd-layer-light-1) .esd-field.is-error .esd-field__control,
:where(.esd-canvas) :is(.esd-tone-light,.esd-layer-light-1) .esd-field__control[aria-invalid="true"]{
  border-color:var(--c-error-ink);          /* §1.6 Regel 3 */
}
:where(.esd-canvas) :is(.esd-tone-light,.esd-layer-light-1) .esd-field.is-success .esd-field__control{
  border-color:var(--c-live-ink);
}
:where(.esd-canvas) :is(.esd-tone-light,.esd-layer-light-1) .esd-field__msg::before{
  color:var(--c-error-ink);
}
:where(.esd-canvas) :is(.esd-tone-light,.esd-layer-light-1) .esd-field__msg--success::before{
  color:var(--c-live-ink);
}

/* --- reduced-motion: Farbwechsel bleiben, Rest steht (§8.2 Pflichtzweig) --- */
@media (prefers-reduced-motion: reduce){
  :where(.esd-canvas) .esd-field__control,
  :where(.esd-canvas) .esd-field__box{
    transition:border-color var(--dur-hover) var(--ease-out),
               background-color var(--dur-hover) var(--ease-out),
               color var(--dur-hover) var(--ease-out);
  }
  :where(.esd-canvas) .esd-field__box::after{transition:none}
}
/* ===/ui:field CSS=== */


/* ==========================================================================
   @esd-section: 03 - card
   @sot: website/components/ui/03-card.html
   ========================================================================== */
/* ===ui:card CSS v1=== */
/* ==========================================================================
   KARTE - Panel-Grammatik §2.7 auf dem Layer-Kontext aus 00-basis
   Die Karte liest --ui-raise-* (den naechsten Layer) und schreibt daraus den
   --ui-*-Satz fuer ihre Kinder. Verschachtelung siehe unten.
   ========================================================================== */
:where(.esd-canvas) .esd-card{
  /* @sot design-system.md §2.7 .esd-dpanel: padding clamp(24px,3vw,40px).
     Bewusst NICHT in em (§3.5 Chrome-Regel): die Karte ist ein Panel, kein
     Chrome-Element; §3.5 zielt auf Eyebrow/Chips/Buttons. */
  --esd-card-pad: clamp(24px, 3vw, 40px);

  /* Kinder erben den Karten-Layer */
  --ui-bg:     var(--ui-raise);
  --ui-text:   var(--ui-raise-text);
  --ui-text-2: var(--ui-raise-text-2);
  --ui-text-3: var(--ui-raise-text-3);
  --ui-line:   var(--ui-raise-line);
  --ui-line-2: var(--ui-raise-line-2);
  --ui-accent: var(--ui-raise-accent);
  --ui-field:  var(--ui-raise-field);
  --ui-focus:  var(--ui-raise-focus);

  position: relative;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  background: var(--ui-raise);
  border: 1px solid var(--ui-raise-line);
  border-radius: var(--radius-card);
  padding: var(--esd-card-pad);
  color: var(--ui-raise-text-2);
  font-family: var(--font-body);
  /* @sot §2.7: Top-Lichtkante rgba(255,255,255,.05) + Bodenschatten.
     Die Lichtkante steht als Literal in der SoT, ohne Token-Namen. */
  box-shadow: inset 0 1px 0 rgba(255,255,255,.05), var(--shadow-d-md);
}
:where(.esd-canvas) .esd-card *,
:where(.esd-canvas) .esd-card *::before,
:where(.esd-canvas) .esd-card *::after{ box-sizing: border-box; }

/* --- Verschachtelung: jede Stufe eine Ebene hoeher, Deckel Layer 3 ---
   Absolute Slots statt Kette, siehe 00-basis Kopf (R2). Tiefe 4 und tiefer
   trifft dieselbe Regel wie Tiefe 3 und bleibt damit auf Layer 3. */
:where(.esd-canvas) .esd-card .esd-card{
  --ui-bg:     var(--ui-raise2);
  --ui-text:   var(--ui-raise2-text);
  --ui-text-2: var(--ui-raise2-text-2);
  --ui-text-3: var(--ui-raise2-text-3);
  --ui-line:   var(--ui-raise2-line);
  --ui-line-2: var(--ui-raise2-line-2);
  --ui-accent: var(--ui-raise2-accent);
  --ui-field:  var(--ui-raise2-field);
  --ui-focus:  var(--ui-raise2-focus);
  background: var(--ui-raise2);
  border-color: var(--ui-raise2-line);
  color: var(--ui-raise2-text-2);
}
:where(.esd-canvas) .esd-card .esd-card .esd-card{
  --ui-bg:     var(--ui-raise3);
  --ui-text:   var(--ui-raise3-text);
  --ui-text-2: var(--ui-raise3-text-2);
  --ui-text-3: var(--ui-raise3-text-3);
  --ui-line:   var(--ui-raise3-line);
  --ui-line-2: var(--ui-raise3-line-2);
  --ui-accent: var(--ui-raise3-accent);
  --ui-field:  var(--ui-raise3-field);
  --ui-focus:  var(--ui-raise3-focus);
  background: var(--ui-raise3);
  border-color: var(--ui-raise3-line);
  color: var(--ui-raise3-text-2);
}

/* --- Helle Insel: dort gilt die helle Schatten-Treppe (§1.1), nicht die
       dunkle, und die weisse Top-Lichtkante hat nichts zu beleuchten. --- */
:where(.esd-canvas) .esd-tone-light .esd-card,
:where(.esd-canvas) .esd-layer-light-1 .esd-card{
  box-shadow: var(--shadow-md);
}

/* ==========================================================================
   SLOTS
   ========================================================================== */

/* Media - randlos oben in der Karte. Der negative Rand ist exakt der
   Innenabstand, damit das Bild an der Kartenkante sitzt (Content-Linie §11.1
   Regel 7 bleibt gewahrt, weil links/rechts derselbe Wert abgezogen wird). */
:where(.esd-canvas) .esd-card__media{
  display: block;
  margin: calc(var(--esd-card-pad) * -1) calc(var(--esd-card-pad) * -1) var(--space-element);
  border-radius: calc(var(--radius-card) - 1px) calc(var(--radius-card) - 1px) 0 0;
  overflow: hidden;
  background: var(--ui-raise-field);
  aspect-ratio: 16 / 9;   /* @sot knowledge/images.md § Mass-Register: Karte im Grid 16:9 */
}
:where(.esd-canvas) .esd-card__media > img,
:where(.esd-canvas) .esd-card__media > video{
  display: block; width: 100%; height: 100%; object-fit: cover;
}
:where(.esd-canvas) .esd-card__media--media-16-10{ aspect-ratio: 16 / 10; }  /* @sot images.md: USP-/Feature-Karte */
:where(.esd-canvas) .esd-card__media--media-1-1{ aspect-ratio: 1 / 1; }      /* @sot images.md: USP-Karte mobil */

/* Eyebrow - dieselben Regeln wie .esd-sechead__eyebrow (05-sechead, §3.1):
   Meta-Stufe, Gewicht 400, sentence case, kein Blau als Default. Farbe ist
   --ui-text-2 und nicht --text-tertiary, weil §13.1 Punkt 4 die Tertiaer-
   Stufe fuer tragenden Text ausdruecklich sperrt (2,50 bis 2,65:1). Die
   Zurueckhaltung kommt aus Groesse und Kleinschreibung, nicht aus zu wenig
   Kontrast. Begruendung ausfuehrlich im Kopf von 05-sechead.html. */
:where(.esd-canvas) .esd-card__eyebrow{
  margin: 0 0 8px;
  font-family: var(--font-body);
  font-size: var(--text-meta);
  font-weight: var(--fw-normal);
  letter-spacing: var(--track-meta);
  line-height: var(--lh-meta);
  color: var(--ui-text-2);
  text-transform: none;
}

/* Titel - H3-Rolle (§3.1). Karten-Ueberschriften bleiben deutlich unter der
   Sektions-H2 (§3.1 Sektions-/Karten-Kopf-Regeln). */
:where(.esd-canvas) .esd-card__title{
  margin: 0 0 12px;
  font-family: var(--font-heading);
  font-size: var(--text-title);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--track-title);
  line-height: var(--lh-title);
  color: var(--ui-text);
  text-wrap: balance;
}

:where(.esd-canvas) .esd-card__text{
  margin: 0 0 16px;
  max-width: var(--measure);
  font-size: var(--text-body);
  line-height: var(--lh-body);
  color: var(--ui-text-2);
}

/* Meta - Mikro-Zeile. Traegt nie Information, die nicht anderswo steht. */
:where(.esd-canvas) .esd-card__meta{
  margin: 0 0 16px;
  font-size: var(--text-meta);
  letter-spacing: var(--track-meta);
  line-height: var(--lh-meta);
  /* W2-Gate 2026-09-06: NICHT --ui-text-3. Die tertiaere Stufe reisst den
     Kontrast-Floor (2,50 bis 3,42:1) und §13.1 Punkt 4 sperrt sie fuer
     Lesetext. Eine Meta-Zeile IST Lesetext, kein Mikro-Signal. */
  color: var(--ui-text-2);
  font-variant-numeric: tabular-nums;   /* @sot §3.3 Zahlen in Inter */
}

/* Aktionen - nimmt .btn (01-button). margin-top:auto haelt sie unten, damit
   Karten einer Reihe auf einer Linie enden. */
:where(.esd-canvas) .esd-card__actions{
  display: flex; flex-wrap: wrap; gap: 12px;
  margin-top: auto; padding-top: 8px;
}

/* Badge - Slot oben rechts. Geometrie nach §9, Farbe bewusst neutral. */
:where(.esd-canvas) .esd-card__badge{
  position: absolute; top: 16px; right: 16px; z-index: 2;
  display: inline-flex; align-items: center;
  min-height: 24px;                 /* @sot tokens.css --target-min-wcag: Badge ist kein Ziel */
  padding: 4px 12px;
  border: 1px solid var(--ui-raise-line-2);
  border-radius: var(--radius-pill);
  background: var(--ui-raise-field);
  color: var(--ui-raise-text);
  /* @sot §9 Badge - Floor 12px gewinnt, Claude-Entscheid delegiert 2026-09-06.
     §9 nennt 10 bis 10,5px, aber aus dem Bestand erhoben, nicht entschieden;
     der mobile-guard-Floor (keine Schrift unter 12px) ist die haertere Regel.
     Fable zieht §9 in der SoT nach. */
  font-size: var(--text-meta);
  font-weight: var(--fw-semibold);  /* @sot §9: Gewicht 600 bis 700 */
  letter-spacing: .14em;            /* @sot §9 */
  text-transform: uppercase;        /* @sot §9 */
  line-height: 1;
}

/* Link - Pfeil-Textlink. In der statischen Karte ein normaler Link am Fuss;
   in .esd-card--link liegt er IM Titel und deckt die Karte ab. */
:where(.esd-canvas) .esd-card__link{
  position: relative;
  display: inline-flex; align-items: center; gap: 8px;
  min-height: var(--target-min);
  color: var(--ui-accent);
  text-decoration: none;
  font-size: var(--text-body);
  /* Nur Farbe - gap waere eine Layout-Property (§8.2 compositor-only).
     Die Pfeil-Bewegung laeuft ueber transform am ::after. */
  transition: color var(--dur-hover) var(--ease-out);
}
:where(.esd-canvas) .esd-card__link::after{
  content: "\2192";   /* Pfeil rechts. Kein Em-/En-Dash (§3.4). */
  display: inline-block;
  transition: transform var(--dur-hover) var(--ease-out);
}
:where(.esd-canvas) .esd-card__link:hover::after{ transform: translateX(4px); }
:where(.esd-canvas) .esd-card__link:active{ color: var(--ui-text); }
:where(.esd-canvas) .esd-card__link:focus-visible{
  outline: var(--focus-width) solid var(--ui-focus);
  outline-offset: var(--focus-offset);
  border-radius: var(--focus-radius);
}

/* ==========================================================================
   VARIANTE: klickbare Karte
   Ein <a class="esd-card__link"> im Titel deckt die Karte per ::before ab.
   Der Ring liegt auf der GANZEN Karte, nicht nur auf dem Wort - sonst
   markierte der Fokus eine andere Flaeche als der Klick trifft.
   ========================================================================== */
:where(.esd-canvas) .esd-card--link{
  transition: background-color var(--dur-hover) var(--ease-out),
              border-color var(--dur-hover) var(--ease-out);
}
:where(.esd-canvas) .esd-card--link .esd-card__title{ margin-bottom: 12px; }
:where(.esd-canvas) .esd-card--link .esd-card__title .esd-card__link{
  min-height: 0;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
}
/* Der Pfeil bleibt auf Body-Groesse. In Titel-Groesse (bis 40px) wirkt er wie
   ein zweites Objekt statt wie ein Hinweis - in der Werkstatt gesehen. */
:where(.esd-canvas) .esd-card--link .esd-card__title .esd-card__link::after{
  font-size: var(--text-body);
  align-self: center;
}
/* Die Abdeckung. ::before, weil ::after den Pfeil traegt. */
:where(.esd-canvas) .esd-card--link .esd-card__title .esd-card__link::before{
  content: ""; position: absolute; inset: 0; z-index: 1;
  border-radius: var(--radius-card);
}
/* Hover-Pop §2.7: eine Stufe hoeher plus betonte Kante. Kein Anheben - siehe
   [MISSING: Karten-Lift] im Kopf. */
:where(.esd-canvas) .esd-card--link:hover{
  background: var(--ui-raise2);
  border-color: var(--ui-raise-line-2);
}
:where(.esd-canvas) .esd-card .esd-card--link:hover{
  background: var(--ui-raise3);
  border-color: var(--ui-raise2-line-2);
}
:where(.esd-canvas) .esd-card--link:active{ background: var(--ui-raise); }
/* Fokus-Ring um die ganze Karte (:has ist seit 2023 in allen Zielbrowsern). */
:where(.esd-canvas) .esd-card--link:has(.esd-card__link:focus-visible){
  outline: var(--focus-width) solid var(--ui-raise-focus);
  outline-offset: var(--focus-offset);
}
/* Doppelring vermeiden - aber nur dort, wo :has wirklich greift. In einem
   Browser ohne :has bleibt der Ring am Wort und damit sichtbar. */
@supports selector(:has(*)){
  :where(.esd-canvas) .esd-card--link .esd-card__title .esd-card__link:focus-visible{
    outline-color: transparent;
  }
}

/* ==========================================================================
   VARIANTE: kompakt
   [TOBIAS-ENTSCHEID OFFEN] §2.7 beziffert nur die Voll-Fassung. Die Werte
   hier liegen auf dem 8pt-Raster (§4) und sind die naechstkleinere Stufe.
   ========================================================================== */
:where(.esd-canvas) .esd-card--compact{ --esd-card-pad: clamp(16px, 2vw, 24px); }

/* ==========================================================================
   VARIANTE: versenkt (.esd-dsunken-Grammatik §2.7)
   Nur dunkel - siehe [MISSING] im Kopf. Es werden ausschliesslich die vier
   Sunken-Rollen gesetzt, die tokens.css fuehrt; Akzent, Fokus, Feld und
   Mikro-Ton bleiben die des umgebenden Kontexts (auf Sunken messen sie
   praktisch dasselbe wie auf Layer 0).
   ========================================================================== */
:where(.esd-canvas) .esd-card--sunken{
  --ui-bg:     var(--layer-sunken);
  --ui-text:   var(--layer-sunken-text);
  --ui-text-2: var(--layer-sunken-text-2);
  --ui-line:   var(--layer-sunken-line);
  background: var(--layer-sunken);
  border-color: var(--layer-sunken-line);
  border-radius: var(--radius-inset);
  color: var(--layer-sunken-text-2);
  /* @sot §2.7 .esd-dsunken: inset 0 2px 10px rgba(0,0,0,.6),
     inset 0 -1px 0 rgba(255,255,255,.05) */
  box-shadow: inset 0 2px 10px rgba(0,0,0,.6), inset 0 -1px 0 rgba(255,255,255,.05);
}
:where(.esd-canvas) .esd-card--sunken .esd-card__media{
  border-radius: calc(var(--radius-inset) - 1px) calc(var(--radius-inset) - 1px) 0 0;
}

/* ==========================================================================
   ZUSTAND: laden
   ========================================================================== */
:where(.esd-canvas) .esd-card__skeleton{
  display: block; height: 12px; border-radius: var(--radius-focus);
  /* Nicht --ui-field: der Feld-Grund liegt nur 1,05 bis 1,22 ueber seiner
     Flaeche (Carbon-Feldregel) und war als Platzhalter praktisch unsichtbar
     - in der Werkstatt gemessen. --ui-line-2 ist der sichtbarste Token, der
     auf Dunkel UND auf der hellen Insel funktioniert. */
  background: var(--ui-line-2);
  margin-bottom: 12px;
  animation: esd-card-atmen 1600ms var(--ease-in-out) infinite;
}
:where(.esd-canvas) .esd-card__skeleton--titel{ height: 24px; width: 70%; }
:where(.esd-canvas) .esd-card__skeleton--kurz{ width: 45%; }
@keyframes esd-card-atmen{
  0%, 100%{ opacity: 1; }
  50%{ opacity: .55; }
}

/* ==========================================================================
   RASTER - Karten einer Reihe bleiben gleich hoch
   ========================================================================== */
:where(.esd-canvas) .esd-card-grid{
  display: grid;
  align-items: stretch;
  gap: var(--space-element);
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}

/* ==========================================================================
   reduced-motion (§8.2 - jede Animation hat ihren Zweig IN der Komponente)
   Der Pfeil bewegt sich nicht mehr und der Ladepuls steht still; die
   Farb-/Kanten-Uebergaenge bleiben als Zustands-Rueckmeldung erhalten, nur
   praktisch sofort. Abschalten allein waere zu wenig: ohne Rueckmeldung
   waere nicht mehr erkennbar, dass die Karte reagiert.
   ========================================================================== */
@media (prefers-reduced-motion: reduce){
  :where(.esd-canvas) .esd-card--link{
    transition: background-color 1ms var(--ease-out), border-color 1ms var(--ease-out);
  }
  :where(.esd-canvas) .esd-card__link{
    transition: color 1ms var(--ease-out);
  }
  :where(.esd-canvas) .esd-card__link::after{ transition: none; }
  :where(.esd-canvas) .esd-card__link:hover::after{ transform: none; }
  :where(.esd-canvas) .esd-card__skeleton{ animation: none; opacity: .8; }
}

/* WERKSTATT-LEHREN
   R1  Die Karte setzt ihren Kinder-Layer UND ihre eigene Flaeche aus
       --ui-raise-*. Beide aus derselben Quelle zu speisen ist der Grund,
       warum "Karte in Karte" ohne Sonderfall funktioniert.
   R2  Der Pfeil braucht ::after, die Klickflaeche ::before. Wer beides auf
       ::after legt, verliert entweder den Pfeil oder die Abdeckung - in der
       Werkstatt zuerst passiert.
   R3  Der Fokus-Ring gehoert auf die Karte, nicht auf das Wort. Ein Ring um
       drei Woerter bei einer Klickflaeche von 340x260px ist irrefuehrend.
       Ohne :has-Unterstuetzung faellt er auf das Wort zurueck, nie weg.
   R4  Das Media-Element bekommt seinen negativen Rand aus derselben Variable
       wie das padding. Mit zwei getrennten clamp-Werten waere die Kante bei
       jeder Viewport-Breite anders verrutscht.
   R7  Die Karte setzt stillschweigend voraus, dass ihre Sektion im
       Layer-Modell sitzt. Gemessener Fall (Pilot audit-briefing-erhalten,
       2026-09-06): die Seite gruendet sechs Sektionen auf --bg-primary, den
       Alias auf --elev-0 #1A1A1A. Eine .esd-card bekaeme dort --ui-raise =
       --layer-1 #17171c - Luminanz 0,00879 gegen 0,01033, die Karte waere
       also DUNKLER als ihr Grund und drehte §2.1 ("eine Karte sitzt nie auf
       demselben Ton wie ihr Grund, hoehere Ebene heller") um. Ursache ist
       nicht die Komponente, sondern dass zwei Herkunfts-Treppen
       nebeneinander leben (00-basis Kopf, Abschnitt GRENZEN). Deshalb steht
       die Voraussetzung jetzt als erste Einbau-Regel - vor der Migration
       pruefen, nicht danach.
   R6  Die §9-Badge-Groesse (10 bis 10,5px) war aus dem Bestand ERHOBEN, nicht
       entschieden - der 12px-Floor des mobile-guard ist die haertere Regel und
       gewinnt. Eine erhobene Zahl ist kein Entscheid (W2, 2026-09-06).
   R5  Auf Layer 3 und auf der hellen Insel aendert der Hover nur die Kante -
       darueber gibt es keine Stufe mehr (--panel-hover ist in tokens.css
       wertgleich mit --panel). Das ist die dokumentierte Obergrenze. */
/* ===/ui:card CSS=== */


/* ==========================================================================
   @esd-section: 04 - accordion
   @sot: website/components/ui/04-accordion.html
   ========================================================================== */
/* ===ui:accordion CSS v1=== */
/* ==========================================================================
   ui:accordion - Aufklapp-Liste auf nativem <details>
   sot: knowledge/design-system.md 6.4 / 8.2 / 9.7 / 13.1
   regel: kein JS. Werte nur aus Tokens. Layer-Token --ui-* setzt 00-basis.
   ========================================================================== */

/* --- Liste ------------------------------------------------------------ */
/* R3: Scroll-Anker sperren - sonst haelt Chrome beim Aufklappen ein Element
   weiter unten fest und scrollt die Seite mit (9.7 Scroll-Regel). */
:where(.esd-canvas) .esd-acc{
  box-sizing: border-box;
  overflow-anchor: none;
  max-width: var(--measure);          /* Anatomie inf-det (44em) in Token-Form */
  border-top: 1px solid var(--ui-line);
  border-bottom: 1px solid var(--ui-line);
}
/* Liste sitzt in einem Behaelter, der schon eine Kante hat. */
:where(.esd-canvas) .esd-acc--flush{
  border-top: 0;
  border-bottom: 0;
}

/* --- Item ------------------------------------------------------------- */
:where(.esd-canvas) .esd-acc__item{
  overflow-anchor: none;
}
:where(.esd-canvas) .esd-acc__item + .esd-acc__item{
  border-top: 1px solid var(--ui-line);
}

/* --- Titel-Zeile ------------------------------------------------------ */
/* R4: flex-start, damit der Winkel bei zweizeiligem Titel oben bleibt.
   Die 44px-Zielgroesse kommt aus dem Innenabstand, min-height ist der Boden. */
:where(.esd-canvas) .esd-acc__summary{
  box-sizing: border-box;             /* R7 - sonst addiert min-height die Polster */
  display: flex;
  align-items: flex-start;
  gap: .75em;
  min-height: var(--target-min);
  padding: .75em 0;
  cursor: pointer;
  color: var(--ui-text);
  font-family: inherit;
  font-size: var(--text-body);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-body);
  letter-spacing: var(--track-body);
  -webkit-tap-highlight-color: transparent;
}
/* R1: das Default-Dreieck stirbt an drei Stellen. */
:where(.esd-canvas) .esd-acc__summary{ list-style: none }
:where(.esd-canvas) .esd-acc__summary::-webkit-details-marker{ display: none }
:where(.esd-canvas) .esd-acc__summary::marker{ content: "" }

/* Ueberschrift-Fassung: die Semantik kommt vom Tag, die Optik von der Zeile. */
:where(.esd-canvas) .esd-acc__h{
  margin: 0;
  font-family: inherit;
  font-size: inherit;
  font-weight: inherit;
  line-height: inherit;
  letter-spacing: inherit;
  color: inherit;
}

/* --- Winkel (CSS-Icon aus currentColor) -------------------------------- */
/* R2: --ui-text-2, nicht die Tertiaer-Stufe: der Winkel ist ein
   Bedienelement (3:1-Boden) und reisst ihn auf der hellen Insel. */
:where(.esd-canvas) .esd-acc__summary::after{
  content: "";
  flex: none;
  align-self: flex-start;
  box-sizing: border-box;
  width: .62em;
  height: .62em;
  margin-left: auto;
  margin-top: .4em;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  color: var(--ui-text-2);
  transform: rotate(45deg);
  transform-origin: 50% 50%;
  transition: transform var(--dur-hover) var(--ease-out),
              color var(--dur-hover) var(--ease-out);
}
:where(.esd-canvas) .esd-acc__summary:hover::after{
  color: var(--ui-accent);
}
:where(.esd-canvas) .esd-acc__item[open] > .esd-acc__summary::after{
  transform: rotate(-135deg);
  color: var(--ui-accent);
}

/* --- Fokus ------------------------------------------------------------- */
:where(.esd-canvas) .esd-acc__summary:focus-visible{
  outline: var(--focus-width) solid var(--ui-focus);
  outline-offset: var(--focus-offset);
  border-radius: var(--focus-radius);
}

/* --- Panel ------------------------------------------------------------- */
:where(.esd-canvas) .esd-acc__panel{
  overflow-anchor: none;
  padding: 0 0 1.2em;
  color: var(--ui-text-2);
  font-size: var(--text-body);
  line-height: var(--lh-body);
}
:where(.esd-canvas) .esd-acc__panel > :first-child{ margin-top: 0 }
:where(.esd-canvas) .esd-acc__panel > :last-child{ margin-bottom: 0 }
:where(.esd-canvas) .esd-acc__panel strong,
:where(.esd-canvas) .esd-acc__panel b{ color: var(--ui-text) }
:where(.esd-canvas) .esd-acc__panel a{
  color: var(--ui-accent);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* --- Reduced Motion (8.2 / 13.1 Pkt. 9): Endzustand sofort ------------- */
/* html.rm ist derselbe Knoten wie :root.rm - der Umschalter im Katalog.
   Kein !important noetig: html.rm hebt die Spezifitaet ueber die Basis-Regel. */
@media (prefers-reduced-motion: reduce){
  :where(.esd-canvas) .esd-acc__summary::after{ transition: none }
}
html.rm :where(.esd-canvas) .esd-acc__summary::after{ transition: none }
/* ===/ui:accordion CSS=== */


/* ==========================================================================
   @esd-section: 05 - sechead
   @sot: website/components/ui/05-sechead.html
   ========================================================================== */
/* ===ui:sechead CSS v1=== */
/* ==========================================================================
   SEKTIONSKOPF
   Der Wrapper setzt keine Breite (die kommt aus dem Breiten-Register der
   Sektion, §11.1) und keinen Hintergrund. Er staffelt nur die drei Rollen.
   ========================================================================== */
:where(.esd-canvas) .esd-sechead{
  display: block;
  box-sizing: border-box;
  margin: 0 0 var(--space-element);
  text-align: left;
  font-family: var(--font-body);
}

/* Eyebrow - Meta-Stufe, Gewicht 400, sentence case, kein Blau als Default.
   Farbe --ui-text-2, Begruendung im Kopf ([SoT-WIDERSPRUCH]). */
:where(.esd-canvas) .esd-sechead__eyebrow{
  margin: 0 0 12px;
  font-family: var(--font-body);
  font-size: var(--text-meta);
  font-weight: var(--fw-normal);
  letter-spacing: var(--track-meta);
  line-height: var(--lh-meta);
  color: var(--ui-text-2);
  text-transform: none;   /* sentence case - Versalien sind die gestrichene Fassung */
}
/* Begruendungspflichtiger Modifier, siehe Kopf. */
:where(.esd-canvas) .esd-sechead__eyebrow--accent{ color: var(--ui-accent); }

/* Titel - H2-Rolle §3.1 */
:where(.esd-canvas) .esd-sechead__title{
  margin: 0;
  font-family: var(--font-heading);
  font-size: var(--text-headline);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--track-headline);
  line-height: var(--lh-headline);
  color: var(--ui-text);
  text-wrap: balance;   /* @sot §3.3 */
}

/* Lead - eigene Rolle, bis 800px (§3.3) */
:where(.esd-canvas) .esd-sechead__lead{
  margin: 24px 0 0;
  max-width: var(--measure-lead);
  font-size: var(--text-lead);
  font-weight: var(--fw-normal);
  letter-spacing: var(--track-lead);
  line-height: var(--lh-lead);
  color: var(--ui-text-2);
  text-wrap: pretty;    /* @sot §3.3 */
}

/* Meta - optionale Mikro-Zeile unter dem Lead */
:where(.esd-canvas) .esd-sechead__meta{
  margin: 16px 0 0;
  max-width: var(--measure);
  font-size: var(--text-meta);
  letter-spacing: var(--track-meta);
  line-height: var(--lh-meta);
  /* W2-Gate 2026-09-06: NICHT --ui-text-3. Die tertiaere Stufe reisst den
     Kontrast-Floor (2,50 bis 3,42:1) und §13.1 Punkt 4 sperrt sie fuer
     Lesetext. Eine Meta-Zeile IST Lesetext, kein Mikro-Signal. */
  color: var(--ui-text-2);
  font-variant-numeric: tabular-nums;   /* @sot §3.3 */
}

/* --- Modifier: zentriert --- */
:where(.esd-canvas) .esd-sechead--center{ text-align: center; }
:where(.esd-canvas) .esd-sechead--center .esd-sechead__lead,
:where(.esd-canvas) .esd-sechead--center .esd-sechead__meta{
  margin-left: auto; margin-right: auto;
}

/* --- Modifier: Hero. Macht Eyebrow-Regel 2 unumgehbar.
       Kein Groessen-Override, siehe [MISSING: --lh-display] im Kopf. --- */
:where(.esd-canvas) .esd-sechead--hero .esd-sechead__eyebrow{ display: none; }

/* WERKSTATT-LEHREN
   R1  Der Eyebrow ist ein <p>, kein <span> in der Ueberschrift. Im <h2>
       verschmilzt er mit dem Ueberschriften-Text und steht danach in jeder
       Ueberschriften-Liste eines Screenreaders.
   R2  --hero blendet den Eyebrow aus, statt ihn nur zu verbieten. Eine Regel,
       die nur im Kopf steht, wird beim naechsten Guss uebersehen; eine, die
       das Element unsichtbar macht, faellt sofort auf.
   R3  Der Kopf setzt keine max-width auf sich selbst. Sonst haette er die H2
       im Wide-Register (§11.1) eingeschnuert - genau der Fehler, den §11.1
       als Anlass nennt ("der Inhalt ist ja Box").
   R5  Auch die Meta-Zeile lief zuerst auf der tertiaeren Stufe - derselbe
       Fehler wie beim Eyebrow, nur unbemerkt, weil dort keine SoT-Zeile
       widersprach. Erst layout-audit.py hat ihn gezeigt (W2, 2026-09-06).
   R4  Die Farbe des Eyebrows ist der einzige Punkt, an dem diese Komponente
       von einer SoT-Zeile abweicht - mit ausgeschriebener Begruendung und
       gerechneten Zahlen im Kopf. Still abweichen waere der Fehler gewesen,
       still gegen den Kontrast-Floor bauen aber auch. */
/* ===/ui:sechead CSS=== */
