Skip to content

Add AMOLED-style Black theme option#295

Merged
sjp4 merged 1 commit into
coredevices:masterfrom
ForeverFreed:feature/amoled-black-theme
Jul 20, 2026
Merged

Add AMOLED-style Black theme option#295
sjp4 merged 1 commit into
coredevices:masterfrom
ForeverFreed:feature/amoled-black-theme

Conversation

@ForeverFreed

@ForeverFreed ForeverFreed commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Add AMOLED black theme

Adds a third app theme — Black — alongside Light and Dark, for OLED screens where a true-black background costs no backlight power.
Also fixes some minor readability issues with the original Dark theme, which would have carried over to the new Black theme (see below).

What you get

A new "Black" option in the app theme picker. It's the existing Dark scheme with background, surface, and the lowest container role painted pure black.

The interesting part: the surface ladder

Material 3 gives every scheme a ladder of container colours (surfaceContainerLowestsurfaceContainerHighest) that components use to lift themselves off the page. A DropdownMenu, for example, paints itself surfaceContainer.

Both dark schemes had a broken ladder when I first implemented this:

  • surfaceContainer was set to the same colour as surface, so popups had almost no visible edge against the page behind them.
  • In the Dark scheme, surfaceContainerHighest was darker than the page above it, so elevation read inverted.
  • Everything left unnamed fell through to the M3 dark defaults, which are near-black — wrong against a #333333 page.

Both ladders now ascend cleanly. Because the scheme carries the difference, components separate themselves correctly with no per-component styling — which is why this PR deletes the == Grey menu special case in WatchesScreen rather than generalising it.

Light theme is deliberately untouched: it separates menus via shadow elevation, which works on white. Dark themes suppress shadows, which is exactly why M3 uses tonal elevation there instead.

Theme-carried isDark

CoreAppColorScheme now carries an isDark flag instead of callers testing == Grey. Two places were picking a dark asset by comparing against the Dark theme specifically, so Black got the wrong one: the Wispr Flow logo (rendered black-on-black) and the webview's prefers-color-scheme. Both now follow the flag.

Files

10 files, +121 / −51. The substance is in util/src/commonMain/kotlin/theme/Theme.kt; most of the rest is one- to three-line touches.

Testing

  • :composeApp:assembleDebug — passing
  • :util:testDebugUnitTest — passing, including new coverage asserting both dark ladders ascend and that menu containers clear the page colour

Not yet verified on iOS. The only iOS-side change is one deleted import in PebbleWebview.ios.kt (isDark became a member property, so it resolves without one). It could not be compiled locally: :util:compileKotlinIosSimulatorArm64 fails in libpebble3 on an unresolved LibPebbleSwift reference, which needs podInstall and reproduces on a clean checkout — pre-existing, unrelated to this change. Worth a build on macOS before merge.

Worth a look when reviewing

The Dark theme ladder fix restyles the shipped Dark theme, not just the new Black one. It was unavoidable — the ladder is what makes menus work without per-component styling, so leaving Dark broken would have meant keeping the special case. Surfaces in Dark will look slightly different: containers now sit lighter than the page rather than darker.

Screenshots

Old vs. New Dark Theme, and New Black Theme

AI Disclosure

I used Claude (Sonnet 5 and Opus 4.8) to work on this feature. I am very new to Kotlin (but not coding in general), so using AI to help build out a maintainable new theme like this seemed appropriate. I am fully open to hearing out any changes you'd like to see before this is merged.

@ForeverFreed ForeverFreed changed the title Added an AMOLED-Style Black theme to the app. Add AMOLED-style Black theme option Jul 15, 2026
@ForeverFreed
ForeverFreed force-pushed the feature/amoled-black-theme branch from 2de6686 to 0f00bb1 Compare July 19, 2026 23:46
Adds a third app theme, Black, alongside Light and Dark, for OLED screens
where a true-black background costs no backlight power.

The scheme is a variant of the existing dark scheme with background, surface
and the lowest container role painted pure black. Getting there meant fixing
the M3 surface container ladders on both dark schemes: greyScheme had
surfaceContainer set to the same colour as surface, and surfaceContainerHighest
sitting *darker* than the page above it, so elevation read inverted and popups
had no visible edge against their background. Both schemes now ascend cleanly
from lowest to highest.

That ladder is what components use to separate themselves from the page --
DropdownMenu paints itself surfaceContainer -- so no per-component styling is
needed. The old `== Grey` menu special case in WatchesScreen is removed rather
than generalised. Light theme is left alone: it separates menus via shadow
elevation, which dark themes suppress.

Also switches the Wispr logo and webview colour-scheme checks from an equality
test against Grey to a theme-carried isDark flag, so Black picks the dark
variant too.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@ForeverFreed
ForeverFreed force-pushed the feature/amoled-black-theme branch from 9e1e3a7 to f0e1f67 Compare July 20, 2026 03:32
@sjp4
sjp4 merged commit af97174 into coredevices:master Jul 20, 2026
3 checks passed
@ericmigi

Copy link
Copy Markdown
Contributor

thanks @ForeverFreed! Keep in mind that as things change, we might not check them on this theme. If you notice any problems, please feel free to send another PR or mention the problem here.

@ForeverFreed

Copy link
Copy Markdown
Contributor Author

thanks @ForeverFreed! Keep in mind that as things change, we might not check them on this theme. If you notice any problems, please feel free to send another PR or mention the problem here.

Thanks @ericmigi! I finally got my PT2 just today and can't wait to continue making this project the best it can be!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants