Skip to content

feat(mobile): draw the app's own screens in the web UI's colours - #759

Merged
Medformatik merged 2 commits into
mainfrom
feat/mobile-native-theme
Nov 3, 2026
Merged

Medformatik merged 2 commits into
mainfrom
feat/mobile-native-theme

Conversation

@Medformatik

@Medformatik Medformatik commented Nov 3, 2026 •

Copy link
Copy Markdown
Collaborator

What changed and why

The few screens the shell draws itself had their own blue palette: the loading and error overlays, the recovery screen and the location disclosure. So did the Android notification tint, the adaptive-icon background and the dark splash. In front of the green web UI they looked like a different product.

The colours now live in @openmapx/core/theme. The web's MUI theme and theme-color tags are built from it, so the web looks the same as before. The shell derives its light and dark palettes from the same values, plus the 8 px corner radius and the medium button-label weight:

  • Primary buttons use the primary colour with its contrast text.
  • Secondary buttons are outlined, with a half-opacity primary border and a primary label, as MUI draws them.
  • Body text uses the secondary text colour.
  • Light pages are white like the web's full-screen dialogs. Dark pages use the web's #1C1C1C, which the dark splash now matches.

The native screens still use the system font, not Plus Jakarta Sans.

Before (dark) After (dark) After (light)
Location disclosure with blue buttons on a near-black background The same disclosure with a green primary button, green outlined buttons and the web's dark grey background Light disclosure on white with a dark-green primary button

Android splash logo

Android 12 and later draw the splash image on a 288 dp canvas and crop it to a 192 dp circle. The splash used the square, edge-to-edge logo at 180 dp, so the circle cut off its corners and edges. Android now gets its own splash image: the full logo at 148 dp on a transparent 288 dp canvas, small enough that its rounded corners stay inside the circle. iOS does not crop and keeps the existing image.

Before: logo cut by the circle After: the whole logo
Dark splash with the logo cropped into a rough circle Dark splash showing the full rounded-square logo

Related work

Last of four stacked PRs. It is based on #758 (native navigation), which is based on #757 and #756.

Verification

  • Pixel (Android 17), in both dark and light system appearance: the disclosure matches the web theme. The foreground-service notification is tinted #207E23, and the generated Android resources use the new splash and icon-background colours.
  • apps/mobile: jest (new palette test), tsc, biome, assert-generated, and expo config resolving the shared colours.
  • Web: vitest project (including themeColor), tsc. Full node vitest project for the new core module.
  • Splash: recorded cold starts on the Pixel before and after. The generated splashscreen_logo drawable keeps every opaque pixel within 372 px of the centre of its 1152 px canvas (the circle's radius is 384 px).
  • Not checked: iOS.

Release and upgrade impact

Product impact: ordinary

No package release: the new @openmapx/core/theme module is imported only by the web app and the mobile shell; extension-cli builds byte-identical dist output with and without this change.

@Medformatik Medformatik added the javascript Pull requests that update javascript code label Nov 3, 2026
@Medformatik Medformatik self-assigned this Nov 3, 2026
@Medformatik
Medformatik force-pushed the feat/mobile-native-navigation branch from 8a75857 to ad03646 Compare November 3, 2026 22:11
Base automatically changed from feat/mobile-native-navigation to main November 3, 2026 22:25
The native loading, error, recovery and permission screens, the Android notification tint, the adaptive icon background and the splash used a blue palette of their own, so they looked like a different product in front of the green web UI.

The colours now live in @openmapx/core/theme. The web's MUI theme and theme-color tags are built from it, and the shell derives its light and dark palettes, button radius and label weight from the same values.
Android 12 and later draw the splash image on a 288 dp canvas and crop it to a 192 dp circle. The splash used the square, edge-to-edge app logo at 180 dp, so the circle cut off its corners and edges.

Android now gets its own splash image: the full logo at 148 dp on a transparent 288 dp canvas, small enough that its rounded corners stay inside the circle. iOS, which does not crop, keeps the existing image.
@Medformatik
Medformatik force-pushed the feat/mobile-native-theme branch from a629a03 to 48d58e4 Compare November 3, 2026 22:25
@Medformatik
Medformatik merged commit 2989f4b into main Nov 3, 2026
29 checks passed
@Medformatik
Medformatik deleted the feat/mobile-native-theme branch November 3, 2026 22:39
@github-actions github-actions Bot locked and limited conversation to collaborators Nov 3, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

javascript Pull requests that update javascript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant