docs: UI/Design-Entscheidungen dokumentiert (#3)

- Seed Color: #4A6741 (Olivgrün) für Dark Theme
- Fixed Custom Palette (kein Dynamic Color)
- Default Roboto M3 TypeScale
- Material Icons Extended

Closes #3
This commit is contained in:
Jens Reinemann 2026-05-13 15:01:30 +02:00
parent cf05c54a42
commit 5030ac929a
2 changed files with 336 additions and 0 deletions

View file

@ -0,0 +1,220 @@
# Technology Candidates UI/Design-Entscheidungen
Date: 2026-05-13
Requirements file: anforderungen-v1.md + Anforderungen/design/requirements.md
---
## Entscheidung A Farbwerte / Seed Color
### Candidate Table
| Name | Seed-Hex | Primär (Dark) | Charakter | M3-kompatibel | Lesbarkeit | Score |
|------|----------|----------------|-----------|---------------|------------|-------|
| A1 Forest Green | `#2E7D32` | `#6EC072` (tone 80) | Klassisch dunkelgrün, bekannt, klar | ✅ | ✅ | 8 |
| A2 Olivgrün / Militär | `#4A6741` | `#9CCB91` (tone 80) | Gedeckt, olivfarben, "Krisenvorrat"-Thema | ✅ | ✅ | 9 |
| A3 Dunkelgrün Pure | `#1B5E20` | `#54BA5B` (tone 80) | Sehr satt, fast schwarz-grün, industriell | ✅ | ✅ | 7 |
| A4 Waldgrün warm | `#3A5F3A` | `#8FCC8F` (tone 80) | Warm, natürlich, dezent | ✅ | ✅ | 8 |
> Material 3 erzeugt aus dem Seed automatisch: primary, secondary, tertiary, surface, background, error alle in Light + Dark. Anthrazit-Töne entstehen aus dem Low-Chroma-Neutral-Palette des Seeds.
### Details
#### A1 Forest Green (`#2E7D32`)
**Charakter:** Klassisches "Material Green 800". Klar erkennbar, professionell, gute Kontraste.
**Dark-Theme-Primary:** ~`#6EC072` mittelgrüner Akzent auf dunklem Hintergrund.
**Surfaces (Dark):** `#131A13` (Surface), `#1E251E` (SurfaceVariant) dezent dunkelgrüne Tönung.
- ✅ Must: Alle erfüllt
- ✅ Should: Erkennbarer Charakter, solide Kontraste
- ⚠️ Missing: Nicht maximale "Krisenvorrat"-Eigenständigkeit wirkt leicht wie Standard-Material-Grün
#### A2 Olivgrün / Militärgrün (`#4A6741`)
**Charakter:** Gedämpftes Oliv-Grün, militärische/Outdoor-Assoziation. Sehr gut zum Krisenvorrat-Kontext.
**Dark-Theme-Primary:** ~`#9CCB91` warmes, helles Olivgrün auf dunklem Hintergrund.
**Surfaces (Dark):** `#14191A` leicht grünlich-anthrazit, sehr angenehm für den Ausdruck "Krisenvorrat".
- ✅ Must: Alle erfüllt
- ✅ Should: Maximale thematische Eigenständigkeit, excellent Lesbarkeit
- ✅ Nice-to-Have: Ausgeprägte grüne Tönung der neutralen Flächen
#### A3 Dunkelgrün Pure (`#1B5E20`)
**Charakter:** Material Green 900 sehr dunkel, fast schwarz-grün. Dramatischer Effekt.
**Dark-Theme-Primary:** ~`#54BA5B` lebhaftes Grün, guter Kontrast.
**Surfaces (Dark):** Sehr dunkle Flächen mit kaum sichtbarer Grün-Tönung.
- ✅ Must: Alle erfüllt
- ⚠️ Should: Surfaces wirken fast wie reines Schwarz, verliert Eigenständigkeit
- ⚠️ Risiko: Wenig Differenzierung zwischen primärer Farbe und Surfaces
#### A4 Waldgrün warm (`#3A5F3A`)
**Charakter:** Warmer, natürlicher Grünton liegt zwischen A1 und A2.
- ✅ Must: Alle erfüllt
- ✅ Should: Gute Balance zwischen klar und charaktervoll
- ⚠️ Missing: Leicht ähnlich zu A1, keine starke Eigenständigkeit
---
## Entscheidung B Dynamic Color vs. Fixed Palette
### Candidate Table
| Option | Beschreibung | API-Anforderung | Markenkonsistenz | Wartungsaufwand | Score |
|--------|-------------|-----------------|------------------|-----------------|-------|
| B1 Fixed Palette (custom Theme) | Fest definierte Farben aus Theme Builder | Android 5+ (API 21) | ✅ Immer gleich | Niedrig | 9 |
| B2 Dynamic Color (wallpaper-basiert) | Monet-basiert, folgt dem Wallpaper | Android 12+ (API 31) | ❌ Variable | Niedrig | 3 |
| B3 Hybrid: Fixed + Optional Dynamic | Fixed Palette als Fallback, Dynamic ab API 31 | Android 5+ mit Opt-in | ⚠️ Variabel auf API 31+ | Mittel | 6 |
### Details
#### B1 Fixed Custom Palette ✅ **Empfohlen**
```kotlin
// In Theme.kt
val DarkColorScheme = darkColorScheme(
primary = Color(0xFF9CCB91), // aus M3 Theme Builder
onPrimary = Color(0xFF0D3B0A),
primaryContainer = Color(0xFF285226),
// ...
)
MaterialTheme(colorScheme = DarkColorScheme) { ... }
```
- ✅ Funktioniert auf allen Android-Versionen
- ✅ Konsistente "Krisenvorrat"-Markenidentität bei jedem User
- ✅ Einfache Implementierung, geringer Wartungsaufwand
- ✅ Die grün/anthrazite Ästhetik wird IMMER angezeigt
#### B2 Dynamic Color (Monet)
```kotlin
val colorScheme = if (Build.VERSION.SDK_INT >= 31) {
dynamicDarkColorScheme(LocalContext.current)
} else darkColorScheme(...)
```
- 🔴 Verliert grüne Ästhetik App sieht aus wie jede andere App
- 🔴 Schließt Android 811 aus (>30% Marktanteil)
- ❌ Does not fit: "Krisenvorrat-Ästhetik" ist explizit gefordert
#### B3 Hybrid
- ⚠️ Komplexität ohne echten Mehrwert für diesen Use Case
- ⚠️ Auf Android 12+ weicht die "Krisenvorrat"-Ästhetik ab
---
## Entscheidung C Typography-Stil
### Candidate Table
| Font | Dependency | Stil | Zahlen-Lesbarkeit | Compose-Support | Score |
|------|-----------|------|-------------------|-----------------|-------|
| C1 Roboto (System) | Keine | Sachlich, neutral | ✅ Exzellent | Native | 8 |
| C2 Inter (Google Fonts) | `ui-text-google-fonts` | Modern, clean | ✅ Sehr gut | Via GoogleFont API | 7 |
| C3 Roboto Condensed | `ui-text-google-fonts` | Kompakt, industriell | ✅ Sehr gut | Via GoogleFont API | 7 |
| C4 Source Sans 3 | `ui-text-google-fonts` | UI-optimiert, klar | ✅ Sehr gut | Via GoogleFont API | 7 |
| C5 Roboto (default M3 TypeScale) | Keine | M3-Standard | ✅ Exzellent | Native | 9 |
### Details
#### C5 Roboto (default Material 3 TypeScale) ✅ **Empfohlen**
Jetpack Compose Material 3 verwendet Roboto als Standard. Die M3-TypeScale (Display/Headline/Title/Body/Label × Large/Medium/Small) ist bereits optimal für Android konfiguriert.
**Keine zusätzliche Abhängigkeit, keine Netzwerk-Anfragen, kein APK-Overhead.**
```kotlin
// Kein Extra-Code nötig MaterialTheme verwendet M3-Standard automatisch
MaterialTheme(
typography = Typography(), // Default = Roboto + M3 TypeScale
...
)
```
- ✅ Alle Must-Haves erfüllt: Exzellente Lesbarkeit, zahlenfreundlich, M3-kompatibel
- ✅ Should: Sachliche, klare Anmutung passt zu "klar, funktional, industriell"
- ✅ Kein Google-Fonts-Netzwerkaufruf
- ⚠️ Nice-to-Have: Keine typografische Eigenständigkeit gegenüber Standard-Android
#### C2 Inter (Google Fonts)
Beliebt in modernen UI-Projekten, leicht breitere Buchstabenform als Roboto.
```kotlin
val interFamily = FontFamily(
Font(GoogleFont("Inter"), weight = FontWeight.Normal),
Font(GoogleFont("Inter"), weight = FontWeight.Bold)
)
```
- ✅ Slightly more distinct appearance
- ⚠️ Benötigt `androidx.compose.ui:ui-text-google-fonts` Dependency
- ⚠️ First-launch Netzwerkabruf (downloadable fonts) nicht Offline-First
#### C3 Roboto Condensed
- ✅ Passt gut zu "industriellem" Look
- ⚠️ Auf kleinen Screens kann Kondensierung die Lesbarkeit bei kleineren Schriftgraden reduzieren
---
## Entscheidung D Icon-Set
### Candidate Table
| Library | Icons | Compose-nativ | Dependency | Lizenz | APK-Impact | Score |
|---------|-------|---------------|------------|--------|------------|-------|
| D1 Material Icons Extended | ~900 | ✅ Nativ | `compose.material:material-icons-extended` | Apache 2.0 | ~3MB (ProGuard eliminiert unused) | 9 |
| D2 Lucide Icons (Compose) | ~1.400 | ✅ Nativ | `com.composables:icons-lucide` | ISC | ~4MB | 7 |
| D3 Phosphor for Compose | ~1.600 | ✅ Nativ | `com.composables:icons-phosphor` | MIT | ~5MB | 7 |
| D4 Custom SVG Icons | unbegrenzt | Via VectorDrawable | Kein | Eigen | Minimal | 4 |
### Details
#### D1 Material Icons Extended ✅ **Empfohlen**
Die offizielle Google-Icon-Bibliothek für Compose. Enthält alle benötigten Icons für diese App:
`Inventory2`, `Category`, `Place`, `Warning`, `DateRange`, `Edit`, `Delete`, `FileUpload`, `FileDownload`, `Settings`, `Search`, `Home`, `List`, `ShoppingCart`, `NotificationsActive`, `Add`, `Remove`, `MoreVert`, etc.
```kotlin
// In build.gradle.kts:
implementation("androidx.compose.material:material-icons-extended")
// Verwendung:
Icon(Icons.Outlined.Inventory2, contentDescription = "Inventar")
Icon(Icons.Filled.Warning, contentDescription = "Warnung")
```
- ✅ Alle Must-Haves erfüllt (native Compose, alle benötigten Icons vorhanden, Apache 2.0)
- ✅ Should: Material 3-konsistente visuelle Sprache Outlined + Filled + Round Styles
- ✅ ProGuard/R8 eliminiert unbenutzte Icons → APK-Impact minimal bei release builds
- ✅ Keine externe Abhängigkeit von Drittanbietern
- ⚠️ Nice-to-Have: Nicht maximale Eigenständigkeit (sehen wie Standard-Android aus)
#### D2 Lucide Icons
- ✅ Größere Auswahl, moderner Look
- ⚠️ Drittanbieter-Dependency, noch nicht so etabliert in Android-Community
- ⚠️ Nicht von Google maintained → Long-term Support-Risiko
#### D3 Phosphor
- ✅ Größte Auswahl, mehrere Styles (thin/light/regular/bold/fill/duotone)
- ⚠️ Drittanbieter, Community-maintained
- ⚠️ "Duotone"-Styles funktionieren in Compose nicht nativ
#### D4 Custom SVG Icons
- 🔴 Sehr hoher Aufwand (jedes Icon muss als VectorDrawable erstellt werden)
- Nur sinnvoll für wenige, besondere Brand-Icons
---
## Decision
Date: 2026-05-13
Decided by: User
### A Seed Color
**Gewählt:** `#4A6741` (Olivgrün / Militärgrün)
**Begründung:** Passt thematisch optimal zum Krisenvorrat-Kontext. Material 3 generiert daraus einen anthrazitgrünen Dark-Theme-Look mit dezenter Grün-Tönung der Surfaces.
**Alternativen:** `#2E7D32` (Forest Green, zu generisch), `#1B5E20` (zu dunkel), `#3A5F3A` (zu ähnlich zu Forest Green)
### B Dynamic Color
**Gewählt:** Fixed Custom Palette (B1)
**Begründung:** App-Identität ("Krisenvorrat"-Ästhetik) muss konsistent bleiben. Dynamic Color würde das grüne Branding überschreiben. Fixed Palette funktioniert auf allen Android-Versionen.
**Alternativen:** Dynamic Color (verliert Branding), Hybrid (unnötige Komplexität)
### C Typography
**Gewählt:** Default Roboto M3 TypeScale (C5)
**Begründung:** Null Overhead, exzellente Lesbarkeit für zahlen-/datenlastige Ansichten, sachlich-industrielle Anmutung. Eigenständigkeit kommt über die Farbwahl, nicht den Font.
**Alternativen:** Inter (Netzwerk-Dependency), Roboto Condensed (Lesbarkeitsverlust bei kleinen Graden)
### D Icon-Set
**Gewählt:** Material Icons Extended (D1)
**Begründung:** Native Compose-Integration, alle benötigten Icons vorhanden, von Google gepflegt, APK-Overhead durch R8 eliminiert.
**Alternativen:** Lucide (Drittanbieter-Risiko), Phosphor (Drittanbieter-Risiko), Custom SVG (zu aufwändig)

View file

@ -0,0 +1,116 @@
# Technology Requirements UI/Design-Entscheidungen
Date: 2026-05-13
Issue: #3
Author: Tech-Decision Workflow
---
## Kontext
Vor der Implementierung der ersten UI-Screens müssen vier visuelle Designentscheidungen getroffen werden, die direkt in die Compose-Theme-Datei einfließen. Die App ist eine native Android-App (Kotlin + Jetpack Compose + Material 3).
Übergeordnetes Design-Ziel laut Anforderungen (anforderungen-v1.md, Abschnitt 6):
- **Stil:** Klar, funktional, industriell
- **UI-Framework:** Material 3 Komponenten
- **Farbschema:** Dark Theme, Dunkelgrün / Anthrazit "Krisenvorrat-Ästhetik", gut lesbar
---
## Entscheidung A Konkrete Farbwerte (Seed Color für Dark Theme)
### Must-Have (Eliminatoren)
- Dark Theme als primäres Theme (nicht optional)
- Farbe vermittelt Seriosität und Funktionalität (kein grelles Grün, kein Hellblau)
- Kontrastverhältnis ≥ 4.5:1 auf dunklen Hintergründen (WCAG AA)
- Material 3 kompatibel (Seed-Color-basiertes Color Scheme)
### Should-Have
- "Waldgrün / Olivgrün / Militärgrün"-Anmutung (passt zum Thema Krisenvorrat)
- Anthrazit-Töne für Oberflächen (nicht reines Schwarz, nicht Hellgrau)
- Erkennbarer visueller Charakter App soll eigenständig aussehen
### Nice-to-Have
- Leichte grüne Tönung der neutralen Flächen (M3 erzeugt das automatisch aus dem Seed)
- Guter Look auch im Light Theme (falls später aktiviert)
### Constraints
- Platform: Android, Jetpack Compose, Material 3
- Tooling: Material Theme Builder (https://m3.material.io/theme-builder)
- Keine externen Design-Bibliotheken nur Compose-eigene Theme-Mechanismen
---
## Entscheidung B Material 3 Dynamic Color (Wallpaper-basiert) oder feste Palette?
### Must-Have
- Theme muss zuverlässig auf Android 8+ funktionieren (Projekt-minSdk ist noch nicht festgelegt, aber breite Kompatibilität erwünscht)
- Grün/Anthrazit-Ästhetik muss erkennbar bleiben nicht durch Wallpaper überschrieben
### Should-Have
- Kein Mehraufwand in der Wartung / Pflege
### Nice-to-Have
- Optionales Dynamic Color auf Android 12+ als "Bonus"
### Constraints
- Dynamic Color (Monet) erfordert API 31 (Android 12+) schließt Android 811 aus, wenn nicht separat gehandhabt
---
## Entscheidung C Typography-Stil
### Must-Have
- Exzellente Lesbarkeit auf kleinen Smartphone-Displays
- Gut geeignet für zahlenreiche Daten (Lagermengen, Preise, Datumsangaben)
- Material 3 TypeScale kompatibel (Display / Headline / Title / Body / Label)
### Should-Have
- Klare, sachliche Anmutung (nicht verspielt oder gerundet)
- Kein separates Google-Fonts-Netzwerkaufruf beim ersten Start (oder Fallback)
### Nice-to-Have
- Leichte typografische Eigenständigkeit gegenüber Standard-Android-Apps
- Variable-Font-Unterstützung (Roboto Flex o.ä.)
### Constraints
- Jetpack Compose / Material 3 TypeScale
- Kein unnötiger APK-Overhead durch komplexe Schriftarten
- Offline-First (Font darf nicht ausschließlich per Netzwerk geladen werden)
---
## Entscheidung D Icon-Set
### Must-Have
- Native Jetpack Compose Integration (kein SVG-Wrapping-Overhead)
- Alle benötigten Icons vorhanden: Inventar (Kiste/Box), Kategorie, Lagerort, Warnung, Ablaufdatum, Bearbeiten, Löschen, Import, Export, Einstellungen, Suche, Navigation
- Frei / Open Source (kein kommerzielles Lizenz-Risiko)
### Should-Have
- Konsistent mit Material 3 visueller Sprache
- Breite Icon-Auswahl (>500 Icons) für spätere Erweiterungen
### Nice-to-Have
- Mehrere Icon-Styles (Outlined, Filled, Rounded) für Variationsmöglichkeit
- Minimalistische, "industrielle" Icon-Ästhetik
### Constraints
- APK-Größe: bei Sideloading kein hartes Limit, aber ProGuard sollte unbenutzte Icons entfernen können
- Keine Abhängigkeit von externer Netzwerkressource zur Laufzeit