# Leadity Vertrag für Filter und Form-Controls

Status: nach vollständigem Figma-Re-Audit der Form-Page vom 23. Juli 2026 neu strukturiertes Prüfpaket 6. `DESIGN.md` bleibt die kanonische Regelquelle. Aktionen, Overlays, Chips und Datentabellen übernehmen ihre jeweiligen Paketverträge.

Fokus, Tastatur, Zustandsbindung, Fehlerkommunikation, Trefferflächen und Reduced Motion folgen zusätzlich `interaction-accessibility-contract.md`.
Foundation-Bereiche, die 760-px-Komponentengrenze, feste Controlmaße und kompakter Reflow folgen zusätzlich `responsive-overflow-contract.md`.

## Quellen und Entscheidungsrang

- Form-Page `2855:5675` mit den aktiven Sections RadioButton `4904:6787`, Checkbox `4904:6788`, ToggleSwitch `4904:13109`, Editor `7729:1214`, InputText `4951:7428`, Select `4951:7427`, Password `7505:1103`, Slider `7627:665`, TextArea `4951:15356`, Search `5457:7013`, ListBox `6235:21440`, Yearpicker `7504:1109`, Multiselect `8128:8122`, Select with Chip `8562:2081`, InputGroup `10235:2929`, InputDate `10315:29875` und Language-select `10807:894`.
- Feld-Primitives: InputText `5623:4420`/`.inputtext` `5629:5339`/Floating `8076:22034`, Textarea `4951:7101`/`.textarea` `5414:23971`/Floating `7877:7816`, Password `7514:9040`/Strength `7505:4007`, Search `5457:6900`, Slider `7627:671`/Part `7627:732`, InputGroup `10236:2959`/Content `10234:2486` und InputDate `11168:775`.
- Select-Familie: Select `4951:7120`/Part `2864:8781`/Floating `4951:7112`, Dropdown-Option `5076:6078`, Dropdown-Liste `5076:6085`, Dropdown mit Liste `5076:6090`, Floating Select mit Liste `5707:489`, Liste mit Suche `10604:2131`, Multiselect-Liste `11539:943`, Multiselect-Option `11539:971`, Select-with-Button `8128:8123` und Select-with-Chip `8562:2082`.
- Eigenständige Auswahlmodelle: ListBox `8289:53231`/Option `8330:1220`, Yearpicker Open `7504:1429`, Language Select `10807:870`/Country Flags `10807:874`, Radio `2085:157`/Small `3222:14685`/With Label `5144:22182`/Optionlist `5418:13408`, Checkbox `2091:238`/Small `3222:14663`/With Label `5144:22193` und Toggle `4142:4693`/With Label `6392:11890`.
- Editor `7729:1270`, Editor-Schritt `7729:11056` und Editor-Beispiele `8124:1112`. Die Schrittkomposition gehört zum Paket Task Surfaces; das Form-Paket stellt ausschließlich die Editor-Basis bereit.
- Beispiele `5144:21509` und Examples Form Fields `11935:936` dienen als Beleg für zulässige Kompositionen, nicht als eigenständige Primitives.
- Filter Card `8944:57444`, Filterelemente `8944:57266`, `8944:57269` und `8944:57272`, Filter-Popover `8944:57473` und Filterkomposition `10359:6902`.
- Produktive Vue-/PrimeVue-Komponenten: `BaseFilterCard`, `BaseFilterPopover`, `BaseFilterElement`, neue Core-/Experimental-Field-Wrapper, `BaseDatePicker`, `BaseFilterSearchBar`, `PrimeRadioButton` und `BaseToggleSwitch`.
- Ausführbare OpenDesign-Komponenten: Registry und Renderer in `ui_kits/app/component-registry.js`.
- Foundations, Aktionen, Cards, Overlays und Chips aus den bestehenden Workspace-Verträgen.

Bei Konflikten gilt: belegte Produktkomponente vor Einzelinstanz; freigegebene Paketentscheidung vor Legacy-Komponente. Deprecated Controls sind Migrationsbelege, keine Zielstruktur.

## 1. Gemeinsame Feldschale

| Variante | Höhe | Verwendung |
|---|---:|---|
| Standard | 40 px | Search, kompakte Inputs und Selects |
| Floating Label | 56 px | reguläre Formularfelder mit dauerhaft sichtbarem Label |
| Top Label | insgesamt 36 px Labelbereich | Textarea und ausdrücklich oberhalb beschriftete Felder |
| Textarea | mindestens 136 px | mehrzeilige fachliche Eingaben; Höhe bleibt inhalts- beziehungsweise kontextabhängig |

- Weißer Hintergrund, 1 px `neutral-40`, Radius 4 px und 12 px horizontaler Innenabstand.
- Feldwerte verwenden Roboto 16/400. Top Labels verwenden Roboto 16/600. Ein leeres Floating Label steht mit Roboto 16/400 vertikal zentriert; bei Wert, Fokus in einer Texteingabe, Readonly oder Error wechselt es auf Roboto 14/400 bei 3 px oberem Abstand. Leere Filter-Selects, Multiselects und DatePicker bleiben auch im belegten Open-State vertikal zentriert und werden nicht allein durch `focus-within` zum Filled-State.
- Floating Labels besitzen weißen Hintergrund und 4 px horizontalen Innenabstand. Readonly und Disabled übernehmen beide den Hintergrund ihrer gemeinsamen `neutral-10`-Feldfläche; das Label darf in keinem Select, InputText oder Textarea als weißer Ausschnitt sichtbar bleiben.
- Placeholder unterstützen das Label und ersetzen es nicht. Ein Placeholder allein genügt nur bei eindeutig zugänglich benannten Suchfeldern.
- InputText leitet fachlich notwendige native Eingabehinweise wie `inputmode` aus seinen Props an das innere Eingabefeld weiter; Verbraucher ersetzen dafür nicht die registrierte Feldschale.
- Fokus verwendet den globalen 2-px-Indikator in `neutral-80` mit 2 px Offset. Ein Feldzustand darf nicht nur über Farbe vermittelt werden.
- Fehler kombinieren Error-Kontur, Error-Inhaltsfarbe, sichtbare Fehlermeldung, `aria-invalid="true"` und `aria-describedby`. Der Error-Message-Wrapper aus Figma `5623:4439` verwendet `s2`/4 px Innenabstand oben und unten; der sichtbare Fehlertext beginnt dadurch 4 px unter der Feldschale. Eine Fehlermeldung bleibt initial vollständig verborgen und erscheint erst nach ausgelöster Validierung bei ungültigem Wert.
- Pflichtfelder zeigen einen zugänglichen Pflichtstatus. Ein sichtbarer Stern ist Ergänzung, nicht alleinige Semantik. Im Default übernimmt der Stern die aktuelle Labelfarbe; erst der validierte Error-Zustand färbt Label und Stern gemeinsam mit `state/error/text`.
- `readonly` und `disabled` verwenden beide `neutral-10` mit `neutral-40`-Kontur. Readonly bleibt fokussier- und kopierbar, behält normalen Werttext und zeigt rechts das freigegebene 16-px-Icon `fa-light fa-pen-slash` mit `s4` Innenabstand; bei Select ersetzt es das Chevron. Auch native Readonly-Selects bleiben fokussierbar, lassen aber keine Wertänderung zu. Disabled ist nicht interaktiv, verwendet `text/light` für Wert und Icon und zeigt kein Pen-Slash. Readonly ist von Empty/Filled unabhängig: leer bleibt das 16/400-Label zentriert, gefüllt steht es 14/400 oben.
- Textareas dürfen vertikal vergrößert werden, wenn der Kontext dies zulässt. Der alte Runtime-Baustein `BaseTextarea.vue` bleibt deprecated.
- Die in Figma vorhandene Left-Label-Variante ist ohne belegten Einsatzbereich gesperrt. Zulässig sind Floating, Top und None; None benötigt weiterhin einen eindeutigen zugänglichen Namen.
- Textarea-Höhen werden getrennt gelesen: 136 px Basisschale, 153 px Floating-Komposition und 172 px Top-Komposition einschließlich Labelbereich.

Kanonische Klassen: `.leadity-field`, `.leadity-field-label`, `.leadity-control`, `.leadity-textarea`, `.leadity-field-help` und `.leadity-field-error`.

### Kompositionsabstände zwischen Feldern

- Standardfelder mit Floating Label verwenden horizontal und vertikal `s4`/12 px. Zusammengehörige Gruppen aus Floating-Label-Feldern verwenden horizontal und vertikal `s6`/24 px.
- Standardfelder mit Static beziehungsweise Top Label verwenden horizontal `s4`/12 px und vertikal `s5`/16 px.
- Radio- und Checkbox-Optionen mit Label verwenden horizontal `s5`/16 px und vertikal `s0`/0 px. Ihre wirksamen Trefferflächen und zugänglichen Labels bleiben davon unberührt.
- Mehrere Toggle Switches mit Label verwenden horizontal `s6`/24 px.
- Zwischen einer Formularfeldgruppe und einem eigenständigen Template-Block auf einer TaskPage gilt vertikal `s7`/32 px. Innerhalb des Template-Blocks gelten dessen eigene Komponentenabstände.
- Freie Pixelwerte für Layout-Gaps, Margins oder Padding sind unzulässig; belegte Feld- und Controlmaße bleiben intrinsische Komponentenwerte.

## 2. Checkbox, Radio und Toggle

### Checkbox

- Die ausführbare Primitive ist `checkbox`/`<leadity-checkbox>` in der zentralen Registry. Sichtbares Label, Metatext und icon-only Auswahl werden über Props konfiguriert; Verbraucher zeichnen kein eigenes Checkbox-Markup.
- Zweck: unabhängige Mehrfachauswahl, bestätigte Formularwerte und Teilselektion.
- Größen: 20 px Standard, 16 px kompakt; 2 px Kontur.
- Pflichtzustände: `unchecked`, `checked`, `mixed`, Hover, Focus, Disabled und Error.
- Das native Input bleibt die semantische und fokussierbare Quelle; seine sichtbare 20-px-Schale wird kontrolliert gezeichnet, damit die Figma-Matrix browserübergreifend stabil bleibt. Ein gemischter Zustand setzt zusätzlich die DOM-Eigenschaft `indeterminate`. Der 10 × 2 px große Mixed-Strich beziehungsweise seine kompakte 8 × 2 px Variante wird über `top: 50%`, `left: 50%` und `translate(-50%, -50%)` geometrisch in der jeweiligen Schale zentriert; feste Pixeloffsets sind unzulässig. Die 16-px-Gesamtauswahl im Multiselect verwendet dieselbe kompakte Zentrierungslogik.
- Die sichtbare Controlfläche darf 16/20 px groß sein; die effektive Trefferfläche bleibt mindestens 40 px.
- Der Error-Zustand ist nur unchecked belegt. Checked+Error, Mixed+Error und weitere nicht belegte Kombinationen werden nicht als Referenzvarianten erfunden.

### Radio

- Die ausführbare Primitive ist `radio`/`<leadity-radio>`. Gruppen verwenden das Registry-Composite `choiceGroup`; alle Optionen teilen den fachlichen Namen, sofern eine Referenzmatrix nicht ausdrücklich eine getrennte Beispielgruppe kennzeichnet.
- Zweck: genau eine Option aus einer kleinen, gleichzeitig verständlichen Gruppe.
- Zwei bis sieben Optionen werden sichtbar als Radio-Gruppe dargestellt; ab acht Optionen wird ein Select verwendet.
- Größen: 20 px Standard, 16 px kompakt. Gruppe und jedes Radio besitzen eine sichtbare Beschriftung.
- Pfeiltastenverhalten nativer Radio-Gruppen bleibt erhalten; eigene Button-Segmente ersetzen keine Radiosemantik.
- Das native Radio bleibt innerhalb der Primitive erhalten. Eigene Roving-Tabindex- oder Button-Logik ist nicht zulässig.

### Toggle

- Zweck: unmittelbar wirksamer binärer Zustand ohne separate Speichern-Aktion.
- Sichtbare Spur 28 × 14 px innerhalb einer mindestens 40 × 40 px großen Trefferfläche.
- Off: Spur `neutral-40` mit weißem Griff; Hover `neutral-50`. On: Spur `neutral-80` mit `neutral-10`-Griff; Hover `neutral-100` mit weißem Griff. Disabled verwendet `neutral-40` mit positionsabhängigem Griff in `neutral-100` und keine pauschale Opacity.
- Toggle verwendet `role="switch"` und ein synchrones `aria-checked`. Das sichtbare Label beschreibt den Zustand fachlich; „An/Aus“ ist kein ausreichender Ersatz.
- Checkbox und Toggle sind nicht austauschbar: Sobald eine separate Bestätigung erforderlich ist, wird eine Checkbox verwendet.

## 3. Select, Multiselect und Listen

- Select übernimmt die 40/56-px-Feldschale; Optionen sind mindestens 40 px hoch. Das Chevron wird relativ zur tatsächlichen Triggerhöhe vertikal zentriert und verwendet keine feste y-Position, damit Standard- und Floating-Label-Varianten dieselbe optische Achse behalten.
- Jede Select- und Multiselect-Liste übernimmt dynamisch exakt die aktuelle Breite ihres besitzenden Controls. Listen verwenden `width`, `min-width` und `max-width` mit 100 Prozent sowie `border-box`; feste oder inhaltsgetriebene Listenbreiten sind unzulässig. Dadurch wachsen und schrumpfen Standard-, Floating-, Search-, Grouped-, Language-, Filter- und Composite-Varianten ohne eigene Breitenlogik mit ihrem Trigger. DatePicker- und Yearpicker-Popover bleiben eigenständige Interaktionsmodelle mit ihren belegten Maßen.
- Native Selects sind ausschließlich als unsichtbare Formular-Proxies oder in ausdrücklich abweichend belegten produktiven Adaptern zulässig. Komponentenreferenz, kanonische Templates und alle Controls mit dokumentiertem Leadity-OpenState verwenden den kontrollierten Registry-Renderer mit Combobox-/Listbox-Semantik, `aria-expanded`, `aria-controls`, `aria-selected`, Pfeiltasten, Enter, Escape und Type-ahead.
- Multiselect besitzt in der Figma-Basis 343 px Breite, folgt im Produkt jedoch der verfügbaren Komponentenbreite. Seine Liste bleibt stets genauso breit wie der Trigger und besitzt `neutral-40`-Kontur, 4 px Radius und Overflow Clip. Die Suche verwendet 12 px seitlich/oben, 8 px unten, 40 px Höhe, Radius 4 und `shadow-default`.
- Optionen verwenden 12 px horizontal, 8 px vertikal, 20-px-Checkbox und `s3`/8 px Gap. Gruppenüberschriften sind Roboto 16/600. Belegt sind Default und „With subline“. Die 16-px-Gesamtauswahl und die rechtsstehende Suche gehören ausschließlich zur separat belegten Filter-Multiselect-Variante; der allgemeine 343-px-Multiselect besitzt keine Gesamtauswahlzeile.
- Das Listenmuster liegt innerhalb der äußeren Combobox-/Listbox-Semantik und unterstützt Pfeiltasten, Enter, Escape, Type-ahead und synchrones `aria-selected`.
- Ausgewählte Werte werden als zugängliche Anzahl, Kurztext oder Chips aus Paket 5 ausgegeben. Die Feldschale erfindet keine zweite Chipfamilie.
- `ListBox` ist zusätzlich als registrierte eigenständige 216-px-Komponente freigegeben. Sie besitzt optionale Suche, Radius `md`/8 px, `shadow-default`, 40-px-Optionen und die Zustände Default, Hover, Selected und Group. Selected verwendet `neutral-80` mit `neutral-10`-Text; Dropdown-Selected bleibt davon getrennt auf `neutral-10`.
- `Select with Chip` ist ein Registry-Composite aus Controlled Select und der echten Paket-5-Icon-Chip-Primitive. Es bildet Ausstehend/Pending, Bereit/Ready, Entwurf/Draft, Risiko/Risk, Fehler/Error und Nicht berücksichtigt/Not Considered mit deutschem zugänglichem Namen, Icon und semantischer Fläche ab.
- `Language Select` ist ein Registry-Composite aus realem Flaggenasset und Controlled Select, keine neue Feldschale. Seine Liste entspricht der aktuellen 110-px-Triggerbreite und darf nicht auf Inhaltsbreite wachsen. Es verwendet den generischen kontrollierten Select-OpenState als transparent dokumentierte Ableitung; ein eigener Language-OpenState ist in Figma nicht belegt und sichtbare native Browser-UI bleibt ausgeschlossen.
- `Select with Button` ist ein Registry-Composite aus Controlled Select und der bestehenden benannten 40-px-Secondary-IconButton-Basisschale. Die Aktion verwendet im Ruhezustand `neutral-10`, im Hover `neutral-20`, das Icon `fa-light fa-pen` und erscheint ausschließlich im belegten Filled-Zustand. Die transparente Inline-Aktion aus Search und Password ist für diesen freistehenden IconButton unzulässig.
- Die Filtervarianten aus Figma `8944:57275` verwenden kontrollierte Open-States statt browserabhängiger nativer Dropdowns: Der Trigger ist 280 px breit; die Liste übernimmt diese Breite über den gemeinsamen 100-Prozent-Vertrag und steht mit `s3`/8 px vertikalem Abstand. Der Single-Select „Delegiert“ verwendet 40-px-Optionszeilen für „Ja“ und „Nein“.
- Die Filter-Multiselects verwenden eine `neutral-40`-konturierte 280-px-Liste mit Radius 4 und `s3`/8 px Innenpadding. Die erste 40-px-Zeile kombiniert eine 16-px-Gesamtauswahl-Checkbox, `s3` Abstand und die Suchschale. Gruppenüberschriften und Optionen sind 32 px hoch; Optionen kombinieren eine 16-px-Checkbox, `s3` Abstand und Roboto 16/24. Verantwortlichkeit gruppiert nach „MainUser“, „MultiUser“ und „ReportingUser“ und besitzt einen 340-px-Open-Container; Bearbeitungsstatus zeigt „Ausstehend“, „In Bearbeitung“, „In Prüfung“ und „Abgeschlossen“ ohne Gruppenheadline in einem 188-px-Open-Container.
- Das Öffnen eines leeren Filter-Multiselects fokussiert die Suche nicht automatisch. Der Trigger behält den Empty-State; Suche und Optionen bleiben über Tab beziehungsweise Pfeiltasten erreichbar. Gesamtauswahl, Einzelcheckboxen, Anzahl, Proxywert, `aria-selected` und `aria-expanded` bleiben synchron.

## 4. Spezialisierte Felder

### Search

- Die ausführbare Primitive ist `search`/`<leadity-search>`. Standard und Outline sind Varianten derselben Registry-Komponente; Verbraucher liefern Label, Wert, Placeholder und optionale Datenattribute.
- Echtes `type="search"`, sichtbares Suchicon, eindeutiger zugänglicher Name und benannte Reset-Aktion bei Inhalt. Native Browser-Cancel-Controls wie `::-webkit-search-cancel-button` und `::-ms-clear` werden unterdrückt, damit im Filled- und Hover-State ausschließlich die kontrollierte Leadity-Reset-Aktion erscheint.
- Die Hauptvariante ist eine weiße, 40 px hohe Pill mit `shadow-default`; Empty verwendet `text/light` für Placeholder und Suchicon, Filled beziehungsweise Active `text/default`. Das 16-px-Suchicon sitzt links mit `s6`/24 px Abstand zur Feldkante; der Text beginnt nach weiteren `s3`/8 px bei `s8`/48 px. Die Search-State-Matrix `5457:6900` belegt zusätzlich eine pillenförmige Outline-Variante mit `neutral-40`-Kontur, Full-Radius und `shadow-default`, einschließlich Filled und Reset. Dropdown-, ListBox- und Multiselect-Suchen verwenden davon getrennt die rechteckige Outline-Ableitung mit Radius 4 und ohne Schatten; die Filter-Multiselect-Suche behält zudem ihre separat belegte rechtsstehende Iconposition.
- Belegte Zustände sind Empty, Active, Filled und Reset. Die Komponentenreferenz zeigt Default auf `neutral-10`, damit die weiße Pill und ihr sehr leichter Schatten wahrnehmbar bleiben, sowie rechteckige Dropdown-Outline und pillenförmige Outline Filled als getrennte Varianten.
- Reset leert das Feld, stellt den Fokus wieder her und löst dieselbe Ergebnisaktualisierung wie eine manuelle Eingabe aus. Die effektive Trefferfläche bleibt 40 px, ihre sichtbare Darstellung jedoch transparent: Default/Hover wechseln ausschließlich die 16-px-Iconfarbe von `text/light` zu `text/default`; eine kreisförmige Hoverfläche ist unzulässig.

### Datepicker und Yearpicker

- Gemeinsame Feldschale mit Kalendericon und eindeutigem Datumsformat.
- InputDate besitzt eine 56-px-Floating-Variante mit 16-px-Kalendericon und eine 40-px-Standardvariante ohne sichtbares Label. Das Kalendericon wird in beiden Triggerhöhen über `top: 50%` und `translateY(-50%)` geometrisch vertikal zentriert; ein fester y-Offset ist unzulässig. Die Filtervariante verwendet ein kontrolliertes 280-px-Kalenderpopover mit `s3`/8 px Abstand, deutschem Monats-/Datumsformat, Monatsnavigation, Wochentagszeile und zugänglichem Datumsraster. Datepicker unterstützt Tastaturbedienung, aktuelles Datum, Auswahl, Pfeiltasten und Escape-Schließen; der Empty-Open-State bleibt zentriert.
- Yearpicker ist eine registrierte Primitive ausschließlich für Jahresauswahl und ersetzt auch die globale Header-Jahresauswahl. Sein 16-px-Kalendericon übernimmt die gemeinsame Feldgeometrie des DatePickers: 11 px rechts und mit `top: 50%` plus `translateY(-50%)` vertikal zentriert. Es steht nicht im Textfluss hinter dem Jahreswert. Die separate Header-Variante behält ihr Chevron im zentrierten Inline-Trigger. Das Popover ist 280 px breit, hat `neutral-40`-Kontur, Radius `md`/8 px, `s4`-Padding, `s3`-Rasterabstand und `shadow-floating`. Ein Dekadenheader mit zwei runden 40-px-Chevron-Aktionen steuert ein 2×5-Jahresraster. Jeder Jahresbutton behält aus Zugänglichkeitsgründen eine mindestens 40 px hohe Trefferfläche; die Popoverhöhe darf dafür gegenüber dem 280×221-px-Figma-Frame wachsen.

### Password

- Die ausführbare Primitive ist `password`/`<leadity-password>`. Feld, Sichtbarkeitsaktion, Stärkeanzeige und Kriterienliste gehören gemeinsam dieser Komponente; Verbraucher zeichnen keinen Teilbaum nach.
- Sichtbarkeit wird über eine benannte Iconaktion mit synchronem `aria-pressed` umgeschaltet. Wie beim Search-Reset bleibt deren 40-px-Trefferfläche unsichtbar; Hover verändert ausschließlich die Farbe des 16-px-Eye-Icons.
- Stärke erscheint bei Fokus in einem 440-px-Popover mit `neutral-40`-Kontur, Radius 8, 12 px Padding/Gaps und `shadow-floating`. Der Balken ist 12 px hoch.
- Stärke wird mit „Schwach“, „Mittel“ und „Stark“ sowie vier Kriterien kommuniziert: mindestens 10 Zeichen, Zahl, Großbuchstabe und Kleinbuchstabe. Ein Sonderzeichen ist keine Pflicht.
- Schwach verwendet Error, Mittel Warning und Stark Success. Farbe ist nie das einzige Signal.

### Slider

- Die ausführbare Primitive ist `slider`/`<leadity-slider>`. Single, Range Partially und Range Complete sind Props derselben Komponente; Feld, Track und native Range-Inputs werden ausschließlich in ihrem Renderer erzeugt.
- Für kontinuierliche Werte oder Bereiche, etwa Zeiträume. Wenige diskrete Fachoptionen verwenden Radio oder Select.
- Der Slider zeigt gemäß Figma eine einzelne 440-px-InputText-Komposition oberhalb, 16 px Abstand, einen 4-px-Track und 16-px-Griffe. Belegt sind Single, Range Partially und Range Complete. Der aktive Bereich ist `neutral-100`, der inaktive Bereich `neutral-40`; Griffe sind weiß mit `stroke-medium`. Minimum und Maximum bleiben programmatisch gebunden und können einander nicht überkreuzen.
- Tastaturbedienung nativer Range-Inputs bleibt erhalten.

### InputGroup

- Die ausführbare Primitive ist `inputGroup`/`<leadity-input-group>`. Start- und End-Addon sind optionale statische Props; das Hauptfeld besitzt genau ein Label.
- Gesamtbreite 520 px mit einer 56-px-Floating-Hauptschale. Linke und rechte Addons sind weiß, besitzen eigene `neutral-40`-Konturen, 12 px Innenabstand und ausschließlich an den Außenkanten Radius 4.
- Statische Einheiten und Präfixe bleiben Text. Interaktive Addons sind echte Buttons mit zugänglichem Namen.
- Die Gruppe besitzt genau ein fachliches Label; Addons erzeugen keine konkurrierenden Feldlabels.

### Editor

- Der Editor besteht aus einer weißen, mit `neutral-40` konturierten Basisschale, Toolbar und editierbarer Fläche. Die belegte Ausgangsgröße ist 1061 × 267 px und wird responsiv auf `max-width: 100%` begrenzt.
- Die Toolbar enthält benannte Aktionen für Fett, Kursiv, Unterstrichen, geordnete Liste, ungeordnete Liste, Link und Formatierung entfernen. Aktive Formatierungen verwenden `aria-pressed`.
- Die sieben Toolbaricons verwenden ausschließlich die komponentenspezifische Registry-Gruppe `light-18-editor` aus Figma `7729:1270`. Die 18-px-Größe gilt nicht für andere Formcontrols.
- Die editierbare Fläche besitzt einen eindeutigen zugänglichen Namen, sichtbaren Fokus und erhält keine alleinige Placeholder-Beschriftung.
- Die fachliche `texteditor-step`-Komposition mit Card, Projektmanagement-Metadaten und Aktionen wird ausschließlich im Paket Task Surfaces dokumentiert.

## 5. Filter Card

- Struktureller Eigentümer ist `filterCard` aus der Komponenten-Registry. Die Card komponiert `select`, `filterPopover` und dynamische `filterElement`-Instanzen; sie zeichnet deren internes DOM nicht selbst nach.
- Eigenständige weiße Large Card unterhalb der Header Card: 32 px Padding, 20 px Radius und `shadow-default`.
- Stabile Reihenfolge: „Alle Filter“, Schnellfilter, Sortierung, aktive Filterelemente und Gesamt-Reset.
- Schnellfilter sind runde 32-px-Small-Secondary-Buttons mit Full-Radius, Roboto 14/400, 8 px Gruppenabstand, 12 px horizontalem Innenabstand und mindestens 40 px effektiver Trefferfläche. Ein gesetzter Schnellfilter bleibt visuell `neutral-10`; seine konkrete Auswahl erscheint als reguläres aktives Filterelement in der Bottom-Zone. Er wird weder zur Primary-Fläche noch zu einer zweiten Chipfamilie.
- Sortierung besteht aus einem 18 × 16 px großen Icon, 12 px Abstand und einem exakt 260 px breiten, 40 px hohen Select; sie ist kein Filterchip. Breite und Controlgröße schrumpfen beim Umbruch nicht. Lange Auswahltexte bleiben einzeilig und werden innerhalb des Selects mit Ellipsis abgeschnitten.
- Aktive Filter sind 320 px breit: 280-px-Floating-Feld, 8 px Abstand und separate runde 32-px-Entfernen-Aktion. Unset zeigt ein zentriertes Label 16/400; Set und Multiple zeigen Label 14/400 plus Wert 16/400. Multiple fasst als „n ausgewählt“ zusammen. Sie sind keine Statuschips.
- Aktive Filter verwenden 24 px horizontalen und 12 px vertikalen Abstand. Der 159 px breite Small-Secondary-Reset steht rechts in derselben Bottom-Zone und ist mit 12 px unterem Innenoffset auf die Filterfelder ausgerichtet.
- „Alle zurücksetzen“ wird nur bei mindestens einem gesetzten Filter gezeigt.
- Varianten ohne Sortierung entfernen den gesamten rechten Sortierblock und reservieren dort keinen Leerraum.
- Bei schmalerer Kartenbreite umbrechen Schnellfilter und aktive Filter intrinsisch. In der belegten 936-px-Variante bleiben 260-px-Sortierung und 320-px-Filtermodule unverändert; nur die Zeilenanzahl wächst.
- Filter verändern ausschließlich den nachfolgenden Content und die explizit als filterabhängig benannten Statuswerte.
- Filterzustand, Zähler, aktive Elemente und Ergebnisdarstellung stammen aus einer gemeinsamen Datenquelle.

## 6. Filter-Popover

- Struktureller Eigentümer ist `filterPopover` aus der Komponenten-Registry. Zulässige Kinder sind `multiselect`, `datePicker`, `select`, `toggle` und `filterRemove`.
- „Alle Filter“ öffnet standardmäßig das Filter-Popover, kein Modal.
- Desktopbreite 688 px, viewportgebunden auf kleineren Screens; 16 px Padding, 8 px Radius und `shadow-floating`.
- Zwei 280-px-Spalten mit 24 px Abstand. Die linke Spalte trägt die Überschrift „Projektmanagement-Filter“ und enthält „Verantwortliche Person“, „Bearbeitungsstatus“, „Fällig bis“ und „Delegiert“. Die rechte Spalte trägt „Inhaltliche Filter“ und enthält „Nachhaltigkeitsdimension“.
- Das Popover besitzt keinen eigenen Header, Close-X oder Aktionsfooter. Alle fünf Kriterien sind 56-px-Floating-Selects und wirken unmittelbar.
- Bei unzureichender Breite stehen die Spalten untereinander; horizontaler Scroll ist ausgeschlossen.
- „Gesetzte Filter merken“ verwendet einen Toggle, weil die Präferenz unmittelbar aktualisiert wird.
- Trigger bindet `aria-expanded` und `aria-controls`. Light Dismiss und Escape geben den Fokus an den Trigger zurück.
- Das geöffnete Popover bleibt bei Seiten- und Containerscroll über die gemeinsame Overlay-Positionierung an „Alle Filter“ verankert. Seine Schale erzeugt keinen eigenen Clipping-Kontext; Select-, Multiselect- und DatePicker-Layer dürfen über die Popover-Unterkante hinausragen.
- Das Popover darf vorhandene Schnellfilter nicht duplizieren. Es enthält zusätzliche Filterkriterien und synchronisiert bei jeder Änderung dieselbe Zustandsquelle.
- Verantwortliche Person und Bearbeitungsstatus unterstützen Mehrfachauswahl mit Checkbox, Suche, gruppierten beziehungsweise statusbezogenen Optionen und der Zusammenfassung „n ausgewählt“. „Fällig bis“ verwendet den Datepicker; „Delegiert“ ist eine Einzelauswahl mit „Ja“ und „Nein“. Ein gesetzter Wert zeigt die 32-px-Entfernen-Aktion, ein leerer Zustand reserviert ihre Geometrie ohne sichtbare Aktion.
- Für die Open-State-Matrix gelten die sichtbaren Figma-Nodes `8944:57286`, `8944:57348`, `8944:57363` und `8944:57408`. Ein Open-State verändert weder `data-field-state="empty"` noch die Labelposition; nur eine reale Auswahl erzeugt Filled beziehungsweise Multiple.
- Ein Modal bleibt ausschließlich für ausdrücklich umfangreiche, mehrabschnittige Filteraufgaben zulässig.

## 7. Formular- und Filterverhalten

- Eine primäre Aktion pro Entscheidungskontext. Sekundäre Aktionen verwenden auf Weiß `secondary`, auf grauem Canvas `secondaryLight`.
- Validierung läuft bei relevanter Eingabe und spätestens beim Absenden. Der erste fehlerhafte Control erhält Fokus.
- Dynamische Ergebnis- oder Filtermeldungen verwenden eine höfliche Live-Region; sie ersetzen keine sichtbaren Zustände.
- Formulare werden nicht allein durch Platzhalter, Farbe oder Icons erklärt.
- Mobile Layouts stapeln Felder, Filterspalten und Aktionen. Kein Control erzeugt bei 360 px horizontalen Seitenscroll. Belegte feste Breiten bleiben auf regulären Breiten stabil; unterhalb der dokumentierten kompakten Grenze wechselt der Komponentenvertrag auf die verfügbare Breite.
- `prefers-reduced-motion` reduziert rein dekorative Übergänge; Zustandswechsel bleiben unmittelbar verständlich.

### Dateiupload und verknüpfte Inhalte

- Uploads verwenden ein echtes Datei-Input. Eine Drag-and-drop-Zone besitzt immer eine Tastaturalternative.
- Die Zustände leer, läuft und abgeschlossen sind sichtbar; Fortschritt wird zugänglich über `aria-valuenow` oder einen gleichwertigen Status kommuniziert.
- Entfernen-Aktionen besitzen einen zugänglichen Namen. Dateitypen verwenden freigegebene Registry-Icons; unbekannte Typen das generische Datei-Icon.
- Kompakte Uploads sind für Tabellen und dichte Layouts vorgesehen, die vollständige Variante für Formulare und Dialoge.
- Bereits vorhandene KPI, Maßnahmen, Aktivitäten, Ziele oder Links werden als verknüpfte Inhalte referenziert und nicht erneut hochgeladen.

## 8. Ausführbare Referenz und Integration

- Registry und Renderer: `../ui_kits/app/component-registry.js`; die Feldbasis registriert `inputText` und `textArea`, die Select-Familie komponiert `select` aus `dropdownOption` und `search`, Paket 2 registriert Dropdown-/Listenkomponenten, Paket 3 Checkbox, Radio und ChoiceGroup. Paket 4 ergänzt `search`, `password`, `slider` und `inputGroup`; InputDate bleibt `datePicker`. Die Editor-Basis ist als `editor` registriert.
- Styles: `../ui_kits/app/filter-form-controls.css`.
- Verhalten: `../ui_kits/app/filter-form-controls.js`.
- Interaktive Zustandsreferenz: `../ui_kits/components/filter-form-controls.html`.
- Template 2 und seine Preview verwenden Filter Card plus Filter-Popover.
- Komponentenreferenz, Template 2, Preview und Paket-8-Kompositionsreferenz instanziieren ausschließlich `<leadity-filter-card>`; internes Filter- und Popover-Markup wird nicht in Verbraucherdateien kopiert.
- Template 3 und seine Ziel-Preview binden ihre fachlichen Felder und Toggles an dieselbe Feldschale; das neutrale Template bleibt inhaltlich unbelegt.
- Globale Berichtsjahre sowie reine Basis- und Zieljahre verwenden den Yearpicker, nicht freie Zahleneingaben oder native Jahres-Selects.
- Die Komponentenreferenz gliedert sich sichtbar in: Eingabefelder und Beschriftungsvarianten; Auswahlcontrols; Select-Anwendungsfälle; Dropdown-Listen und Open States; Datum, Jahr, ListBox und Sprache; Spezialfelder und Editor; Filterkompositionen. Jede Familie nennt Figma-Quelle, kanonischen Vertrag und produktnahe Verwendungen; fachliche Kompositionen werden verlinkt statt lokal dupliziert.
- Alle allgemeinen Beispiele sind fachlich neutral. Modulbegriffe wie Berichtsstandard oder ESRS werden ausschließlich in den besitzenden Modul-Previews verwendet und definieren keine globale Form-Control-Rolle.
- Die neutrale Kategorie-Auswahl, die Filter-Sortierung und InputDate verwenden kontrollierte Registry-Renderer. Language Select verwendet denselben generischen Controlled-Select-OpenState und ergänzt ihn um ein reales Flaggenasset; dies ist eine abgeleitete Implementierung und kein behaupteter eigener Figma-OpenState.
- Komponentenreferenz, DataTable-Spaltenauswahl, DataTable-Zeilenauswahl, TaskList, TaskListCard und BulkActionsBar verwenden die registrierte Checkbox-Primitive. Fachliche Data-/Task-Selektoren bleiben auf dem inneren nativen Input erhalten; Geometrie und Zustände stammen ausschließlich aus der Primitive.
- Search, Password, Slider und InputGroup werden in der Komponentenreferenz ausschließlich als Registry-Instanzen mit Props ausgegeben. Der Verhaltenslayer bindet Reset, Sichtbarkeit, Stärke und Werteabgleich, erzeugt aber kein sichtbares Spezialfeld-Markup.

## 9. Verworfen oder ersetzt

- Radio-Grenze 2–5 wird durch 2–7 ersetzt.
- Toggle-Farben gelten nicht länger als offen; eine Legacy-Bindung an `neutral-120` wird nicht kanonisiert.
- Toggle-Frame `3166:12427` ist ausdrücklich OUTDATED und darf weder als Zielkomponente noch als Tokenquelle verwendet werden.
- Sichtbare native Language-Select-OpenStates, lokale Statuschip-Ersatzflächen, Plus-Aktionen im Select-with-Button sowie lokale ListBox-/Yearpicker-Renderer sind verworfen.
- Rohe Checkbox-/Radio-Unterbäume in HTML-Verbrauchern, lokale Data-/Task-Auswahlgeometrien, Div-basierte Ersatzsemantik und Radio-SelectButtons sind verworfen.
- Rohe Search-, Password-, Slider- oder InputGroup-Unterbäume, parallele Spezialfeld-Renderer, zwei separate sichtbare Range-Wertfelder und eine zweite InputDate-Implementierung sind verworfen.
- Die Figma-Rohwerte 6 px ListBox-Radius sowie 10/14 px freie Abstände erzeugen keine neuen Tokens; sie werden auf `radius-md` und die vorhandene Spacing-Skala abgebildet.
- Left Label bleibt gesperrt, bis ein konkreter produktiver Einsatzbereich belegt und freigegeben ist.
- Das bisherige Filter-Modal in Template 2 wird durch das 688-px-Popover ersetzt.
- Einfache `.filter-chip`-Pills ersetzen keine aktiven 56-px-Filterelemente.
- Isolierte Feld-CSS-Regeln in Produktpreviews werden nicht als paralleler Vertrag fortgeführt.
- Deprecated Runtime-Controls bleiben Migrationshilfen und sind keine Quelle für neue HTML-Komponenten.
