package com.peachpasswords.ui.theme import androidx.compose.runtime.Composable import androidx.compose.runtime.staticCompositionLocalOf import androidx.compose.ui.graphics.Color /** * A resolved set of Peach colour tokens for one theme (dark or light). * * Composables read tokens from [peachColors] (i.e. [LocalPeachColors].current) * instead of the dark-only [PeachColors] object, so a surface re-colours when * the active theme changes. Field names mirror [PeachColors] exactly — the call * site migration is a pure `PeachColors.X` → `peachColors.X` substitution. * * Accent-derived tints (glow, border, dim …) are NOT stored here: they are the * `Color.peachGlow()` family in AccentColors.kt, computed from the current accent * at the call site so they re-derive whenever the user changes their accent. */ data class PeachPalette( // Backgrounds / surfaces val Bg: Color, val S1: Color, val S2: Color, val S3: Color, val SurfaceCard: Color, val SurfaceElevated: Color, val SettingsGroupBg: Color, // Text hierarchy val T0: Color, val T1: Color, val T2: Color, val T3: Color, val T4: Color, // Accent (the live runtime accent — same value LocalPeachAccent carries) val Accent: Color, // Semantic val Breach: Color, val BreachBg: Color, val BreachBorder: Color, val HealthOk: Color, val TotpTag: Color, val SyncOk: Color, val SyncBusy: Color, val SyncErr: Color, // Shell top fade val ShellTopSolid: Color, val ShellTopFade: Color, // Meta val isDark: Boolean, ) /** * The active palette. Provided by [PeachTheme]; reading it without a surrounding * theme is a programming error (every Peach surface lives under [PeachTheme]). */ val LocalPeachColors = staticCompositionLocalOf { error("No PeachPalette provided — wrap your composable in PeachTheme {}") } /** Convenience accessor — use this everywhere instead of [PeachColors].* */ val peachColors: PeachPalette @Composable get() = LocalPeachColors.current /** Dark palette: the canonical tokens from [PeachColors], unchanged. */ fun peachDark(accent: Color = DEFAULT_ACCENT): PeachPalette = PeachPalette( Bg = PeachColors.Bg, S1 = PeachColors.S1, S2 = PeachColors.S2, S3 = PeachColors.S3, SurfaceCard = PeachColors.SurfaceCard, SurfaceElevated = PeachColors.SurfaceElevated, SettingsGroupBg = PeachColors.SettingsGroupBg, T0 = PeachColors.T0, T1 = PeachColors.T1, T2 = PeachColors.T2, T3 = PeachColors.T3, T4 = PeachColors.T4, Accent = accent, Breach = PeachColors.Breach, BreachBg = PeachColors.BreachBg, BreachBorder = PeachColors.BreachBorder, HealthOk = PeachColors.HealthOk, TotpTag = PeachColors.TotpTag, SyncOk = PeachColors.SyncOk, SyncBusy = PeachColors.SyncBusy, SyncErr = PeachColors.SyncErr, ShellTopSolid = PeachColors.ShellTopSolid, ShellTopFade = PeachColors.ShellTopFade, isDark = true, ) /** * Light palette. Tokens that exist in [PeachColorsLight] are copied verbatim. * Five semantic tokens have no light counterpart in PeachColorsLight; their * values are [INFERRED] — darker, fully-opaque variants chosen for contrast on * the warm parchment bg (#EFEEE9) rather than the dark singleton's translucent * forms, which wash out on a light surface. */ fun peachLight(accent: Color = DEFAULT_ACCENT): PeachPalette = PeachPalette( Bg = PeachColorsLight.Bg, S1 = PeachColorsLight.S1, S2 = PeachColorsLight.S2, S3 = PeachColorsLight.S3, SurfaceCard = PeachColorsLight.SurfaceCard, SurfaceElevated = PeachColorsLight.SurfaceElevated, SettingsGroupBg = PeachColorsLight.SettingsGroupBg, T0 = PeachColorsLight.T0, T1 = PeachColorsLight.T1, T2 = PeachColorsLight.T2, T3 = PeachColorsLight.T3, T4 = PeachColorsLight.T4, Accent = accent, Breach = PeachColorsLight.BreachText, // light error already defined as BreachText BreachBg = PeachColorsLight.BreachBg, BreachBorder = Color(0x33B83C2E), // [INFERRED] subtle red hairline on light HealthOk = Color(0xFF3A8A3A), // [INFERRED] darker green for light contrast TotpTag = Color(0xFF3A6AAA), // [INFERRED] darker blue for light contrast SyncOk = Color(0xFF3A7A3A), // [INFERRED] darker green for light contrast SyncBusy = Color(0xFF8A7020), // [INFERRED] darker amber for light contrast SyncErr = PeachColorsLight.BreachText, // mirror Breach, as in the dark palette ShellTopSolid = Color(0xFFFFFFFF), // [INFERRED] light top fades to white ShellTopFade = Color(0xF2EFEEE9), // [INFERRED] over the parchment bg isDark = false, )