# Design-System (Theme-Basis, F6 / Issue #31) Stand: Basis. Konkrete Komponenten (Formularfelder, Banner, Spiel-Kachel usw.) folgen in U1. Code: `app/lib/core/theme/` (`app_theme.dart`, `app_spacing.dart`), Tests: `app/test/core/theme/`. ## Theme - Material 3, `AppTheme.light()` und `AppTheme.dark()`; `ShuffleApp` nutzt `ThemeMode.system`. - Farben: `ColorScheme.fromSeed` mit Seed `#4F46E5` (Indigo). Einzige Abweichung: `outline` ist etwas dunkler (hell `#6B6A7A`) bzw. heller (dunkel `#9A99AB`), damit Feldrahmen mindestens 3:1 erreichen. - Keine Farbwerte in Widgets: immer `Theme.of(context).colorScheme` und `textTheme` verwenden. ## Kontraste (WCAG 2.1 AA) Geprüft im Test `app_theme_test.dart` für Hell und Dunkel. Text mindestens 4.5:1, Bedienelemente (Rahmen, Fokusring, Fehlerrahmen) mindestens 3:1. | Paar | Hell | Dunkel | |---|---|---| | onSurface / surface | 16.3 | 14.4 | | onSurfaceVariant / surface | 8.9 | 10.9 | | onSurfaceVariant / Feldfüllung | 7.2 | 7.3 | | onPrimary / primary (Buttons) | 6.5 | 7.7 | | Fehlertext (error) / Feldfüllung | 5.0 | 7.3 | | SnackBar-Text / SnackBar-Fläche | 11.5 | 10.1 | | SnackBar-Aktion / SnackBar-Fläche | 7.7 | 5.0 | | Feldrahmen (outline) / Feldfüllung | 4.1 | 4.4 | | Fokusring (primary) / Feldfüllung | 5.0 | 7.2 | Regeln: Informationen nie nur über Farbe vermitteln (Fehler = Text + Rahmen + Icon). Neue Farbpaare müssen in den Test aufgenommen werden. Deaktivierte Elemente sind von der Kontrastpflicht ausgenommen. ## Touch-Ziele und Fokus - Mindestgröße 48 x 48 dp für alle Buttons und Icon-Buttons (`minimumSize`), `MaterialTapTargetSize.padded`, `VisualDensity.standard`. Nicht auf `compact` verkleinern. - Tastaturfokus (Web/Desktop): Buttons und Textfelder zeigen einen 3 dp breiten Rahmen in `primary`. - Icons ohne Text brauchen `tooltip` bzw. `Semantics(label: ...)`; Bilder ein Label oder `excludeSemantics`. - Text muss bis 200 % Skalierung ohne Abschneiden funktionieren (kein fixes Höhen-Layout für Text). ## Typografie Material-2021-Skala (`textTheme`), Farbe `onSurface`. Überschriften `headline*`/`title*`, Fließtext `bodyLarge/Medium`, Hinweise `bodySmall` (`onSurfaceVariant`). Schriftgrößen nie hart codieren. ## Abstände, Radien, Breakpoints (`app_spacing.dart`) | Token | Wert (dp) | |---|---| | `AppSpacing` xxs / xs / sm / md / lg / xl / xxl / xxxl | 2 / 4 / 8 / 12 / 16 / 24 / 32 / 48 | | `AppRadius` sm / md / lg / xl | 8 / 12 / 16 / 28 | | Breakpoints (`AppWidthClass`) | kompakt < 600, mittel 600-1023, groß >= 1024 | | `AppBreakpoints.maxContentWidth` | 560 (Formulare/Text auf breiten Bildschirmen begrenzen) | `AppSpacing.pagePadding(width)` liefert den Seitenrand je Breitenklasse (16 / 24 / 32). Web darf nicht wie eine gestreckte Handy-App wirken: Inhalt zentrieren und auf `maxContentWidth` begrenzen. ## Komponenten-Themes in der Basis FilledButton, ElevatedButton, OutlinedButton, TextButton, IconButton, Checkbox, InputDecoration (gefüllt, Rahmen 1 dp, Fokus 3 dp, Fehler 2 dp), Card, AppBar, Divider, SnackBar (schwebend, mit Schließen-Icon).