PeachPalette.kt

4.7 KB · raw

1package com.peachpasswords.ui.theme23import androidx.compose.runtime.Composable4import androidx.compose.runtime.staticCompositionLocalOf5import androidx.compose.ui.graphics.Color67/**8 * A resolved set of Peach colour tokens for one theme (dark or light).9 *10 * Composables read tokens from [peachColors] (i.e. [LocalPeachColors].current)11 * instead of the dark-only [PeachColors] object, so a surface re-colours when12 * the active theme changes. Field names mirror [PeachColors] exactly — the call13 * site migration is a pure `PeachColors.X` → `peachColors.X` substitution.14 *15 * Accent-derived tints (glow, border, dim …) are NOT stored here: they are the16 * `Color.peachGlow()` family in AccentColors.kt, computed from the current accent17 * at the call site so they re-derive whenever the user changes their accent.18 */19data class PeachPalette(20    // Backgrounds / surfaces21    val Bg: Color,22    val S1: Color,23    val S2: Color,24    val S3: Color,25    val SurfaceCard: Color,26    val SurfaceElevated: Color,27    val SettingsGroupBg: Color,28    // Text hierarchy29    val T0: Color,30    val T1: Color,31    val T2: Color,32    val T3: Color,33    val T4: Color,34    // Accent (the live runtime accent — same value LocalPeachAccent carries)35    val Accent: Color,36    // Semantic37    val Breach: Color,38    val BreachBg: Color,39    val BreachBorder: Color,40    val HealthOk: Color,41    val TotpTag: Color,42    val SyncOk: Color,43    val SyncBusy: Color,44    val SyncErr: Color,45    // Shell top fade46    val ShellTopSolid: Color,47    val ShellTopFade: Color,48    // Meta49    val isDark: Boolean,50)5152/**53 * The active palette. Provided by [PeachTheme]; reading it without a surrounding54 * theme is a programming error (every Peach surface lives under [PeachTheme]).55 */56val LocalPeachColors = staticCompositionLocalOf<PeachPalette> {57    error("No PeachPalette provided — wrap your composable in PeachTheme {}")58}5960/** Convenience accessor — use this everywhere instead of [PeachColors].* */61val peachColors: PeachPalette62    @Composable get() = LocalPeachColors.current6364/** Dark palette: the canonical tokens from [PeachColors], unchanged. */65fun peachDark(accent: Color = DEFAULT_ACCENT): PeachPalette = PeachPalette(66    Bg = PeachColors.Bg,67    S1 = PeachColors.S1,68    S2 = PeachColors.S2,69    S3 = PeachColors.S3,70    SurfaceCard = PeachColors.SurfaceCard,71    SurfaceElevated = PeachColors.SurfaceElevated,72    SettingsGroupBg = PeachColors.SettingsGroupBg,73    T0 = PeachColors.T0,74    T1 = PeachColors.T1,75    T2 = PeachColors.T2,76    T3 = PeachColors.T3,77    T4 = PeachColors.T4,78    Accent = accent,79    Breach = PeachColors.Breach,80    BreachBg = PeachColors.BreachBg,81    BreachBorder = PeachColors.BreachBorder,82    HealthOk = PeachColors.HealthOk,83    TotpTag = PeachColors.TotpTag,84    SyncOk = PeachColors.SyncOk,85    SyncBusy = PeachColors.SyncBusy,86    SyncErr = PeachColors.SyncErr,87    ShellTopSolid = PeachColors.ShellTopSolid,88    ShellTopFade = PeachColors.ShellTopFade,89    isDark = true,90)9192/**93 * Light palette. Tokens that exist in [PeachColorsLight] are copied verbatim.94 * Five semantic tokens have no light counterpart in PeachColorsLight; their95 * values are [INFERRED] — darker, fully-opaque variants chosen for contrast on96 * the warm parchment bg (#EFEEE9) rather than the dark singleton's translucent97 * forms, which wash out on a light surface.98 */99fun peachLight(accent: Color = DEFAULT_ACCENT): PeachPalette = PeachPalette(100    Bg = PeachColorsLight.Bg,101    S1 = PeachColorsLight.S1,102    S2 = PeachColorsLight.S2,103    S3 = PeachColorsLight.S3,104    SurfaceCard = PeachColorsLight.SurfaceCard,105    SurfaceElevated = PeachColorsLight.SurfaceElevated,106    SettingsGroupBg = PeachColorsLight.SettingsGroupBg,107    T0 = PeachColorsLight.T0,108    T1 = PeachColorsLight.T1,109    T2 = PeachColorsLight.T2,110    T3 = PeachColorsLight.T3,111    T4 = PeachColorsLight.T4,112    Accent = accent,113    Breach = PeachColorsLight.BreachText,            // light error already defined as BreachText114    BreachBg = PeachColorsLight.BreachBg,115    BreachBorder = Color(0x33B83C2E),                // [INFERRED] subtle red hairline on light116    HealthOk = Color(0xFF3A8A3A),                    // [INFERRED] darker green for light contrast117    TotpTag = Color(0xFF3A6AAA),                     // [INFERRED] darker blue for light contrast118    SyncOk = Color(0xFF3A7A3A),                      // [INFERRED] darker green for light contrast119    SyncBusy = Color(0xFF8A7020),                    // [INFERRED] darker amber for light contrast120    SyncErr = PeachColorsLight.BreachText,           // mirror Breach, as in the dark palette121    ShellTopSolid = Color(0xFFFFFFFF),               // [INFERRED] light top fades to white122    ShellTopFade = Color(0xF2EFEEE9),                // [INFERRED] over the parchment bg123    isDark = false,124)