From c88d10be10773a2c1c6b76fefaade02f6204ac7f Mon Sep 17 00:00:00 2001 From: Jens Reinemann Date: Thu, 14 May 2026 02:05:05 +0200 Subject: [PATCH] feat(theme): add Material 3 custom dark theme with seed #4A6741 Color.kt: New file with M3 color tokens generated from olive green seed color #4A6741. Defines primary, secondary, tertiary, error, surface, and container colors for the dark color scheme. Theme.kt: Updated DarkColorScheme with all custom color tokens, changed default to darkTheme=true, status bar now uses surface color instead of primary for better edge-to-edge appearance. themes.xml: Changed splash theme parent from Material.Light to Material dark, added dark background/status/navigation bar colors matching the Compose surface color (#1A1C18). Closes #32 --- .../de/krisenvorrat/app/ui/theme/Color.kt | 63 +++++++++++++++++++ .../de/krisenvorrat/app/ui/theme/Theme.kt | 43 ++++++++++++- app/src/main/res/values/themes.xml | 8 ++- 3 files changed, 110 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/de/krisenvorrat/app/ui/theme/Color.kt diff --git a/app/src/main/java/de/krisenvorrat/app/ui/theme/Color.kt b/app/src/main/java/de/krisenvorrat/app/ui/theme/Color.kt new file mode 100644 index 0000000..2f5c971 --- /dev/null +++ b/app/src/main/java/de/krisenvorrat/app/ui/theme/Color.kt @@ -0,0 +1,63 @@ +package de.krisenvorrat.app.ui.theme + +import androidx.compose.ui.graphics.Color + +/** + * Material 3 color tokens generated from seed color #4A6741 (Olivgrün/Militärgrün). + * + * Generated using Material Theme Builder tonal palette algorithm. + * Dark theme is the primary usage. + */ + +// Primary +val md_theme_dark_primary = Color(0xFFA1D395) +val md_theme_dark_onPrimary = Color(0xFF0B3900) +val md_theme_dark_primaryContainer = Color(0xFF1E5110) +val md_theme_dark_onPrimaryContainer = Color(0xFFBCEFAF) + +// Secondary +val md_theme_dark_secondary = Color(0xFFBBCBB2) +val md_theme_dark_onSecondary = Color(0xFF273422) +val md_theme_dark_secondaryContainer = Color(0xFF3D4B37) +val md_theme_dark_onSecondaryContainer = Color(0xFFD7E8CD) + +// Tertiary +val md_theme_dark_tertiary = Color(0xFFA0D0CB) +val md_theme_dark_onTertiary = Color(0xFF003735) +val md_theme_dark_tertiaryContainer = Color(0xFF1E4E4C) +val md_theme_dark_onTertiaryContainer = Color(0xFFBBECE7) + +// Error +val md_theme_dark_error = Color(0xFFFFB4AB) +val md_theme_dark_onError = Color(0xFF690005) +val md_theme_dark_errorContainer = Color(0xFF93000A) +val md_theme_dark_onErrorContainer = Color(0xFFFFDAD6) + +// Background & Surface +val md_theme_dark_background = Color(0xFF1A1C18) +val md_theme_dark_onBackground = Color(0xFFE2E3DC) +val md_theme_dark_surface = Color(0xFF1A1C18) +val md_theme_dark_onSurface = Color(0xFFE2E3DC) + +// Surface Variant & Outline +val md_theme_dark_surfaceVariant = Color(0xFF424940) +val md_theme_dark_onSurfaceVariant = Color(0xFFC2C9BD) +val md_theme_dark_outline = Color(0xFF8C9388) +val md_theme_dark_outlineVariant = Color(0xFF424940) + +// Inverse +val md_theme_dark_inverseSurface = Color(0xFFE2E3DC) +val md_theme_dark_inverseOnSurface = Color(0xFF2F312C) +val md_theme_dark_inversePrimary = Color(0xFF336B25) + +// Scrim +val md_theme_dark_scrim = Color(0xFF000000) + +// Surface containers +val md_theme_dark_surfaceDim = Color(0xFF1A1C18) +val md_theme_dark_surfaceBright = Color(0xFF404F3D) +val md_theme_dark_surfaceContainerLowest = Color(0xFF0F120D) +val md_theme_dark_surfaceContainerLow = Color(0xFF222520) +val md_theme_dark_surfaceContainer = Color(0xFF262924) +val md_theme_dark_surfaceContainerHigh = Color(0xFF31342E) +val md_theme_dark_surfaceContainerHighest = Color(0xFF3C3F39) diff --git a/app/src/main/java/de/krisenvorrat/app/ui/theme/Theme.kt b/app/src/main/java/de/krisenvorrat/app/ui/theme/Theme.kt index 3823385..8337c40 100644 --- a/app/src/main/java/de/krisenvorrat/app/ui/theme/Theme.kt +++ b/app/src/main/java/de/krisenvorrat/app/ui/theme/Theme.kt @@ -10,12 +10,49 @@ import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.platform.LocalView import androidx.core.view.WindowCompat -private val DarkColorScheme = darkColorScheme() +private val DarkColorScheme = darkColorScheme( + primary = md_theme_dark_primary, + onPrimary = md_theme_dark_onPrimary, + primaryContainer = md_theme_dark_primaryContainer, + onPrimaryContainer = md_theme_dark_onPrimaryContainer, + secondary = md_theme_dark_secondary, + onSecondary = md_theme_dark_onSecondary, + secondaryContainer = md_theme_dark_secondaryContainer, + onSecondaryContainer = md_theme_dark_onSecondaryContainer, + tertiary = md_theme_dark_tertiary, + onTertiary = md_theme_dark_onTertiary, + tertiaryContainer = md_theme_dark_tertiaryContainer, + onTertiaryContainer = md_theme_dark_onTertiaryContainer, + error = md_theme_dark_error, + onError = md_theme_dark_onError, + errorContainer = md_theme_dark_errorContainer, + onErrorContainer = md_theme_dark_onErrorContainer, + background = md_theme_dark_background, + onBackground = md_theme_dark_onBackground, + surface = md_theme_dark_surface, + onSurface = md_theme_dark_onSurface, + surfaceVariant = md_theme_dark_surfaceVariant, + onSurfaceVariant = md_theme_dark_onSurfaceVariant, + outline = md_theme_dark_outline, + outlineVariant = md_theme_dark_outlineVariant, + inverseSurface = md_theme_dark_inverseSurface, + inverseOnSurface = md_theme_dark_inverseOnSurface, + inversePrimary = md_theme_dark_inversePrimary, + scrim = md_theme_dark_scrim, + surfaceDim = md_theme_dark_surfaceDim, + surfaceBright = md_theme_dark_surfaceBright, + surfaceContainerLowest = md_theme_dark_surfaceContainerLowest, + surfaceContainerLow = md_theme_dark_surfaceContainerLow, + surfaceContainer = md_theme_dark_surfaceContainer, + surfaceContainerHigh = md_theme_dark_surfaceContainerHigh, + surfaceContainerHighest = md_theme_dark_surfaceContainerHighest, +) + private val LightColorScheme = lightColorScheme() @Composable fun KrisenvorratTheme( - darkTheme: Boolean = false, + darkTheme: Boolean = true, content: @Composable () -> Unit ) { val colorScheme = if (darkTheme) DarkColorScheme else LightColorScheme @@ -23,7 +60,7 @@ fun KrisenvorratTheme( if (!view.isInEditMode) { SideEffect { val window = (view.context as Activity).window - window.statusBarColor = colorScheme.primary.toArgb() + window.statusBarColor = colorScheme.surface.toArgb() WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = !darkTheme } } diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 6b2dd5e..ab4dc96 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -1,4 +1,10 @@ -