Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Unreleased

- Deepens the PSP / Portable Chrome theme into a sleeker smoked-graphite handheld shell with less washed-out white.
- Adds a PSP / Portable Chrome Nova theme matching the Polaris dim Moonlight-grey early-2000s silver palette, including settings/theme-picker entries and restrained Compose library surfaces.

## 1.1.3 - 2026-06-12
Expand Down
22 changes: 11 additions & 11 deletions app/src/main/java/com/papi/nova/ui/compose/NovaComposeTheme.kt
Original file line number Diff line number Diff line change
Expand Up @@ -84,31 +84,31 @@ fun NovaComposeColors.librarySurfaces(theme: String): NovaLibrarySurfaces {
backgroundScrim = when {
isOled -> Color.Transparent
isMiami -> window.copy(alpha = 0.60f)
isPortableChrome -> Color.Black.copy(alpha = 0.20f)
isPortableChrome -> Color.Black.copy(alpha = 0.28f)
isHighContrast -> Color.Black.copy(alpha = 0.72f)
isMaterialYou -> window.copy(alpha = 0.28f)
else -> window.copy(alpha = 0.56f)
},
panel = when {
isOled -> dialog.copy(alpha = 0.88f)
isMiami -> dialog.copy(alpha = 0.82f)
isPortableChrome -> dialog.copy(alpha = 0.90f)
isPortableChrome -> dialog.copy(alpha = 0.94f)
isHighContrast -> dialog.copy(alpha = 0.96f)
isMaterialYou -> card.copy(alpha = 0.76f)
else -> dialog.copy(alpha = 0.64f)
},
panelBorder = when {
isOled -> divider.copy(alpha = 0.78f)
isMiami -> accent.copy(alpha = 0.18f)
isPortableChrome -> divider.copy(alpha = 0.62f)
isPortableChrome -> divider.copy(alpha = 0.70f)
isHighContrast -> divider.copy(alpha = 0.92f)
isMaterialYou -> divider.copy(alpha = 0.46f)
else -> divider.copy(alpha = 0.44f)
},
tile = when {
isOled -> card.copy(alpha = 0.90f)
isMiami -> card.copy(alpha = 0.82f)
isPortableChrome -> card.copy(alpha = 0.88f)
isPortableChrome -> card.copy(alpha = 0.92f)
isHighContrast -> card.copy(alpha = 0.98f)
isMaterialYou -> card.copy(alpha = 0.78f)
else -> card.copy(alpha = 0.74f)
Expand All @@ -123,30 +123,30 @@ fun NovaComposeColors.librarySurfaces(theme: String): NovaLibrarySurfaces {
control = when {
isOled -> card.copy(alpha = 0.78f)
isMiami -> card.copy(alpha = 0.76f)
isPortableChrome -> card.copy(alpha = 0.84f)
isPortableChrome -> card.copy(alpha = 0.88f)
isHighContrast -> card.copy(alpha = 1f)
isMaterialYou -> card.copy(alpha = 0.70f)
else -> card.copy(alpha = 0.72f)
},
selectedControl = accent.copy(alpha = when {
isHighContrast -> 0.34f
isMiami -> 0.22f
isPortableChrome -> 0.20f
isPortableChrome -> 0.18f
isOled -> 0.22f
else -> 0.18f
}),
focusRing = accent,
focusHalo = accent.copy(alpha = when {
isHighContrast -> 0.36f
isMiami -> 0.28f
isPortableChrome -> 0.20f
isPortableChrome -> 0.16f
isOled -> 0.24f
else -> 0.18f
}),
mediaPlaceholder = when {
isOled -> Color(0xFF08080C)
isMiami -> Color(0xFF2C1734)
isPortableChrome -> Color(0xFFB8C1CC)
isPortableChrome -> Color(0xFFA2ADBA)
isHighContrast -> Color(0xFF111827)
isMaterialYou -> card.copy(alpha = 1f)
else -> divider.copy(alpha = 1f)
Expand All @@ -162,22 +162,22 @@ fun NovaComposeColors.librarySurfaces(theme: String): NovaLibrarySurfaces {
focusedArtworkAlpha = when {
isOled -> 0.10f
isMiami -> 0.26f
isPortableChrome -> 0.16f
isPortableChrome -> 0.12f
isMaterialYou -> 0.18f
else -> 0.24f
},
focusedArtworkScrim = Color.Black.copy(alpha = when {
isOled -> 0.82f
isMiami -> 0.76f
isPortableChrome -> 0.64f
isPortableChrome -> 0.70f
else -> 0.72f
}),
particlesEnabled = !isOled,
particleAlpha = when {
isOled -> 0f
isHighContrast -> 0.28f
isMiami -> 0.68f
isPortableChrome -> 0.32f
isPortableChrome -> 0.24f
isMaterialYou -> 0.42f
else -> 1f
}
Expand Down
50 changes: 25 additions & 25 deletions app/src/main/res/values/colors_nova.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,31 +55,31 @@
<color name="nova_miami_accent_glow">#73FF5CAB</color>
<color name="nova_miami_ripple">#22FF5CAB</color>

<!-- Portable Chrome - Moonlight-grey early-2000s silver with restrained status accents. -->
<color name="nova_portable_void">#FF98A6B5</color>
<color name="nova_portable_deep">#FFB8C1CC</color>
<color name="nova_portable_twilight">#FFA7B2BE</color>
<color name="nova_portable_storm">#FF7F8C9A</color>
<color name="nova_portable_silver">#FFD6DDE5</color>
<color name="nova_portable_ice">#FFEAF0F5</color>
<color name="nova_portable_bg_primary">#FFB8C1CC</color>
<color name="nova_portable_bg_window">#FFB8C1CC</color>
<color name="nova_portable_bg_card">#E6D6DDE5</color>
<color name="nova_portable_bg_elevated">#FFE0E6EC</color>
<color name="nova_portable_bg_input">#FFC8D1DC</color>
<color name="nova_portable_dialog_bg">#FFD6DDE5</color>
<color name="nova_portable_context_bg">#FFC7D1DD</color>
<color name="nova_portable_divider">#FF7F8C9A</color>
<color name="nova_portable_text_primary">#FF25313D</color>
<color name="nova_portable_text_secondary">#FF4F5D6B</color>
<color name="nova_portable_text_muted">#FF667584</color>
<color name="nova_portable_accent">#FF557395</color>
<color name="nova_portable_accent_surface">#22557395</color>
<color name="nova_portable_accent_glow">#33557395</color>
<color name="nova_portable_ripple">#22557395</color>
<color name="nova_portable_success">#FF315B45</color>
<color name="nova_portable_streaming">#FF315B45</color>
<color name="nova_portable_online">#FF557395</color>
<!-- Portable Chrome / PSP - smoked graphite handheld chrome with restrained status accents. -->
<color name="nova_portable_void">#FF7C8998</color>
<color name="nova_portable_deep">#FFA2ADBA</color>
<color name="nova_portable_twilight">#FF8E9BAA</color>
<color name="nova_portable_storm">#FF667484</color>
<color name="nova_portable_silver">#FFC4CDD8</color>
<color name="nova_portable_ice">#FFD7DEE7</color>
<color name="nova_portable_bg_primary">#FFA2ADBA</color>
<color name="nova_portable_bg_window">#FFA2ADBA</color>
<color name="nova_portable_bg_card">#E6C4CDD8</color>
<color name="nova_portable_bg_elevated">#FFCBD3DD</color>
<color name="nova_portable_bg_input">#FFB1BCC9</color>
<color name="nova_portable_dialog_bg">#FFC0CAD5</color>
<color name="nova_portable_context_bg">#FFAFBAC7</color>
<color name="nova_portable_divider">#FF667484</color>
<color name="nova_portable_text_primary">#FF1F2A35</color>
<color name="nova_portable_text_secondary">#FF465464</color>
<color name="nova_portable_text_muted">#FF5A6877</color>
<color name="nova_portable_accent">#FF4B6686</color>
<color name="nova_portable_accent_surface">#264B6686</color>
<color name="nova_portable_accent_glow">#334B6686</color>
<color name="nova_portable_ripple">#244B6686</color>
<color name="nova_portable_success">#FF294F3D</color>
<color name="nova_portable_streaming">#FF294F3D</color>
<color name="nova_portable_online">#FF4B6686</color>
<color name="nova_portable_on_accent">#FFFFFFFF</color>
<!-- High Contrast — brighter copy, firm outlines, and blue focus for readability. -->
<color name="nova_hc_bg_primary">#FF05070c</color>
Expand Down
13 changes: 13 additions & 0 deletions app/src/test/java/com/papi/nova/ui/NovaThemeManagerTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,19 @@ class NovaThemeManagerTest {
assertEquals(context.getColor(R.color.nova_portable_divider), NovaThemeManager.getDividerColor(context))
}

@Test
fun portableChromePaletteUsesSmokedPspGraphiteInsteadOfWashedSilver() {
NovaThemeManager.setTheme(context, NovaThemeManager.THEME_PORTABLE_CHROME)

assertEquals(0xFFA2ADBA.toInt(), context.getColor(R.color.nova_portable_bg_window))
assertEquals(0xE6C4CDD8.toInt(), context.getColor(R.color.nova_portable_bg_card))
assertEquals(0xFFC0CAD5.toInt(), context.getColor(R.color.nova_portable_dialog_bg))
assertEquals(0xFF667484.toInt(), context.getColor(R.color.nova_portable_divider))
assertEquals(0xFF1F2A35.toInt(), context.getColor(R.color.nova_portable_text_primary))
assertEquals(0xFF4B6686.toInt(), NovaThemeManager.getAccentColor(context))
assertEquals(0xFF294F3D.toInt(), context.getColor(R.color.nova_portable_success))
}

@Test
fun miamiThemeResolvesSemanticColors() {
NovaThemeManager.setTheme(context, NovaThemeManager.THEME_MIAMI)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,19 @@ class NovaLibrarySurfacesTest {
}

@Test
fun portableChromeLibrarySurfacesUseDimSilverPanelsAndSubduedParticles() {
fun portableChromeLibrarySurfacesUseSmokedGraphiteShellAndSubduedParticles() {
val portableColors = portableChromeColors()

val portableChrome = portableColors.librarySurfaces(NovaThemeManager.THEME_PORTABLE_CHROME)

assertTrue(portableChrome.particlesEnabled)
assertEquals(portableColors.accent, portableChrome.focusRing)
assertTrue(portableChrome.panel.alpha >= 0.86f)
assertTrue(portableChrome.panelBorder.alpha >= 0.56f)
assertTrue(portableChrome.particleAlpha in 0.20f..0.45f)
assertTrue(portableChrome.focusHalo.alpha < 0.24f)
assertEquals(Color(0xFFB8C1CC), portableChrome.mediaPlaceholder)
assertTrue(portableChrome.backgroundScrim.alpha >= 0.24f)
assertTrue(portableChrome.panel.alpha >= 0.92f)
assertTrue(portableChrome.panelBorder.alpha >= 0.68f)
assertTrue(portableChrome.particleAlpha in 0.16f..0.28f)
assertTrue(portableChrome.focusHalo.alpha < 0.18f)
assertEquals(Color(0xFFA2ADBA), portableChrome.mediaPlaceholder)
}

@Test
Expand Down Expand Up @@ -95,17 +96,17 @@ class NovaLibrarySurfacesTest {
}

private fun portableChromeColors(): NovaComposeColors = NovaComposeColors(
window = Color(0xFFB8C1CC),
card = Color(0xE6D6DDE5),
dialog = Color(0xFFD6DDE5),
badge = Color(0x33557395),
divider = Color(0xFF7F8C9A),
accent = Color(0xFF557395),
accentSurface = Color(0x22557395),
window = Color(0xFFA2ADBA),
card = Color(0xE6C4CDD8),
dialog = Color(0xFFC0CAD5),
badge = Color(0x334B6686),
divider = Color(0xFF667484),
accent = Color(0xFF4B6686),
accentSurface = Color(0x264B6686),
warning = Color(0xFFFBBF24),
textPrimary = Color(0xFF25313D),
textSecondary = Color(0xFF4F5D6B),
textMuted = Color(0xFF667584),
textPrimary = Color(0xFF1F2A35),
textSecondary = Color(0xFF465464),
textMuted = Color(0xFF5A6877),
onAccent = Color.White
)
private fun miamiColors(): NovaComposeColors = NovaComposeColors(
Expand Down
Loading