Summary
Android's LitterAppTheme (apps/android/app/src/main/java/com/litter/android/ui/LitterTheme.kt) only maps 11 of the 36 Material3 color roles when building the ColorScheme. Every Material3 component that reads the remaining roles — ModalBottomSheet (60 uses), AlertDialog (31), OutlinedTextField (54), FilterChip (25), Switch (31), Slider (14), Card (50), Badge (50) — falls back to the baseline Material Design 3 surface palette (the stock purple-tinted surfaces) instead of the Litter theme tokens.
iOS is unaffected because SwiftUI views consume the LitterTheme tokens directly; there is no Material role layer to leave unset.
Why
The color scheme is built like this:
darkColorScheme(
primary = activeTheme.accentStrong,
onPrimary = activeTheme.textOnAccent,
secondary = activeTheme.textSecondary,
onSecondary = activeTheme.textPrimary,
background = activeTheme.background,
onBackground = activeTheme.textBody,
surface = activeTheme.surface,
onSurface = activeTheme.textBody,
error = activeTheme.danger,
onError = activeTheme.textOnAccent,
outline = activeTheme.border,
)
The other 25 roles (surfaceVariant, onSurfaceVariant, surfaceContainer*, outlineVariant, primaryContainer, secondaryContainer, tertiary*, errorContainer, inverse*, scrim) stay at darkColorScheme()/lightColorScheme() defaults, so Material3 components render the stock M3 surfaces.
Fix
Derive the full 36-role scheme from the existing Litter tokens using Google's official material-color-utilities (the engine behind the Material Theme Builder) as a build-time generator. See PR #312.
Summary
Android's
LitterAppTheme(apps/android/app/src/main/java/com/litter/android/ui/LitterTheme.kt) only maps 11 of the 36 Material3 color roles when building theColorScheme. Every Material3 component that reads the remaining roles —ModalBottomSheet(60 uses),AlertDialog(31),OutlinedTextField(54),FilterChip(25),Switch(31),Slider(14),Card(50),Badge(50) — falls back to the baseline Material Design 3 surface palette (the stock purple-tinted surfaces) instead of the Litter theme tokens.iOS is unaffected because SwiftUI views consume the
LitterThemetokens directly; there is no Material role layer to leave unset.Why
The color scheme is built like this:
darkColorScheme( primary = activeTheme.accentStrong, onPrimary = activeTheme.textOnAccent, secondary = activeTheme.textSecondary, onSecondary = activeTheme.textPrimary, background = activeTheme.background, onBackground = activeTheme.textBody, surface = activeTheme.surface, onSurface = activeTheme.textBody, error = activeTheme.danger, onError = activeTheme.textOnAccent, outline = activeTheme.border, )The other 25 roles (surfaceVariant, onSurfaceVariant, surfaceContainer*, outlineVariant, primaryContainer, secondaryContainer, tertiary*, errorContainer, inverse*, scrim) stay at
darkColorScheme()/lightColorScheme() defaults, so Material3 components render the stock M3 surfaces.Fix
Derive the full 36-role scheme from the existing Litter tokens using Google's official material-color-utilities (the engine behind the Material Theme Builder) as a build-time generator. See PR #312.