- Package: de.krisenvorrat.* -> de.bollwerk.* - Klassen: KrisenvorratApp/Database/Theme -> Bollwerk* - ApplicationId: de.bollwerk.app - Server: BOLLWERK_* Env-Vars, bollwerk HOCON-Config - Docker: bollwerk-server/db/backup Container-Namen - Room DB: bollwerk.db, SharedPrefs: bollwerk_secure_prefs - Export-Dateien: bollwerk_export/inventar - UI-Strings, HTML, Admin-UI: alle auf Bollwerk - Docs, Skills, README angepasst - Alle Tests gruen, Build erfolgreich
12 KiB
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, "Bollwerk"-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 "Bollwerk"-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 Bollwerk-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 "Bollwerk".
- ✅ 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
// 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 "Bollwerk"-Markenidentität bei jedem User
- ✅ Einfache Implementierung, geringer Wartungsaufwand
- ✅ Die grün/anthrazite Ästhetik wird IMMER angezeigt
B2 – Dynamic Color (Monet)
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 8–11 aus (>30% Marktanteil)
- ❌ Does not fit: "Bollwerk-Ästhetik" ist explizit gefordert
B3 – Hybrid
- ⚠️ Komplexität ohne echten Mehrwert für diesen Use Case
- ⚠️ Auf Android 12+ weicht die "Bollwerk"-Ä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.
// 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.
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-fontsDependency - ⚠️ 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.
// 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 Bollwerk-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 ("Bollwerk"-Ä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)