diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9f22bad6..bf8ed852 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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
diff --git a/app/src/main/java/com/papi/nova/ui/compose/NovaComposeTheme.kt b/app/src/main/java/com/papi/nova/ui/compose/NovaComposeTheme.kt
index 4df508fb..e1c46110 100644
--- a/app/src/main/java/com/papi/nova/ui/compose/NovaComposeTheme.kt
+++ b/app/src/main/java/com/papi/nova/ui/compose/NovaComposeTheme.kt
@@ -84,7 +84,7 @@ 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)
@@ -92,7 +92,7 @@ fun NovaComposeColors.librarySurfaces(theme: String): NovaLibrarySurfaces {
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)
@@ -100,7 +100,7 @@ fun NovaComposeColors.librarySurfaces(theme: String): NovaLibrarySurfaces {
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)
@@ -108,7 +108,7 @@ fun NovaComposeColors.librarySurfaces(theme: String): NovaLibrarySurfaces {
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)
@@ -123,7 +123,7 @@ 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)
@@ -131,7 +131,7 @@ fun NovaComposeColors.librarySurfaces(theme: String): NovaLibrarySurfaces {
selectedControl = accent.copy(alpha = when {
isHighContrast -> 0.34f
isMiami -> 0.22f
- isPortableChrome -> 0.20f
+ isPortableChrome -> 0.18f
isOled -> 0.22f
else -> 0.18f
}),
@@ -139,14 +139,14 @@ fun NovaComposeColors.librarySurfaces(theme: String): NovaLibrarySurfaces {
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)
@@ -162,14 +162,14 @@ 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,
@@ -177,7 +177,7 @@ fun NovaComposeColors.librarySurfaces(theme: String): NovaLibrarySurfaces {
isOled -> 0f
isHighContrast -> 0.28f
isMiami -> 0.68f
- isPortableChrome -> 0.32f
+ isPortableChrome -> 0.24f
isMaterialYou -> 0.42f
else -> 1f
}
diff --git a/app/src/main/res/values/colors_nova.xml b/app/src/main/res/values/colors_nova.xml
index 9040e8e5..2c037d97 100644
--- a/app/src/main/res/values/colors_nova.xml
+++ b/app/src/main/res/values/colors_nova.xml
@@ -55,31 +55,31 @@
#73FF5CAB
#22FF5CAB
-
- #FF98A6B5
- #FFB8C1CC
- #FFA7B2BE
- #FF7F8C9A
- #FFD6DDE5
- #FFEAF0F5
- #FFB8C1CC
- #FFB8C1CC
- #E6D6DDE5
- #FFE0E6EC
- #FFC8D1DC
- #FFD6DDE5
- #FFC7D1DD
- #FF7F8C9A
- #FF25313D
- #FF4F5D6B
- #FF667584
- #FF557395
- #22557395
- #33557395
- #22557395
- #FF315B45
- #FF315B45
- #FF557395
+
+ #FF7C8998
+ #FFA2ADBA
+ #FF8E9BAA
+ #FF667484
+ #FFC4CDD8
+ #FFD7DEE7
+ #FFA2ADBA
+ #FFA2ADBA
+ #E6C4CDD8
+ #FFCBD3DD
+ #FFB1BCC9
+ #FFC0CAD5
+ #FFAFBAC7
+ #FF667484
+ #FF1F2A35
+ #FF465464
+ #FF5A6877
+ #FF4B6686
+ #264B6686
+ #334B6686
+ #244B6686
+ #FF294F3D
+ #FF294F3D
+ #FF4B6686
#FFFFFFFF
#FF05070c
diff --git a/app/src/test/java/com/papi/nova/ui/NovaThemeManagerTest.kt b/app/src/test/java/com/papi/nova/ui/NovaThemeManagerTest.kt
index 61171da2..2dda102e 100644
--- a/app/src/test/java/com/papi/nova/ui/NovaThemeManagerTest.kt
+++ b/app/src/test/java/com/papi/nova/ui/NovaThemeManagerTest.kt
@@ -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)
diff --git a/app/src/test/java/com/papi/nova/ui/compose/NovaLibrarySurfacesTest.kt b/app/src/test/java/com/papi/nova/ui/compose/NovaLibrarySurfacesTest.kt
index 8901cedf..220b4622 100644
--- a/app/src/test/java/com/papi/nova/ui/compose/NovaLibrarySurfacesTest.kt
+++ b/app/src/test/java/com/papi/nova/ui/compose/NovaLibrarySurfacesTest.kt
@@ -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
@@ -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(