Skip to content

Mobile app is pinned to light mode — no dark palette exists #111

Description

@toruiwasa

Identified while implementing #12 (PR #110).

Field Contents
Goal The mobile app renders correctly for a user whose device is in dark mode, instead of being pinned to light.
Context src/constants/colors.ts (Task 9, PR #110) derives its tokens from the web palette in apps/web/src/styles.css, which defines both a light set on :root and a dark set under html.tui-theme-dark. Only the light half was ported: REQ-17 Phase 1 specifies the mobile UX in terms of behaviour ("amber banner", "red banner") and names no palette at all, so a second set would have been invented rather than designed. Task 7's app.json had userInterfaceStyle: "automatic", which with a light-only palette pairs dark system chrome with light screens — PR #110 pinned it to "light" so the app is at least internally consistent. The web app already ships a dark theme with a theme picker (theme.service.ts), so the tokens exist; what is missing is the decision and the plumbing.
Scope Port the html.tui-theme-dark values into a dark token set, choose how a screen reads them (useColorScheme() + a useThemeColors() hook is the smallest option; a context provider if a manual in-app picker is wanted, matching web), add dark equivalents for the two banner families that have no web counterpart, and restore userInterfaceStyle: "automatic". Open decision: follow the system setting only, or offer an in-app picker as web does. Open decision: whether alert/price colours (priceUp #34D399, priceDown #F87171) need dark-mode variants at all — the web app leaves them unchanged across themes.
Test boundary The token sets are pure data — assert both sets export the same key set, and that every value is a valid hex. Whichever hook or provider is added is the boundary: it is tested against a mocked useColorScheme(). Nothing is mocked beyond that.
Done when Switching the device to dark mode changes the rendered palette, and userInterfaceStyle is back to "automatic" with no light-on-dark mismatch on any Phase 1 screen.
Branch feat/mobile-dark-mode
Dependency #15 (Task 12) and #16 (Task 13) — there is little point theming screens that do not exist yet. Not a blocker for either.
Risk LOW — additive, and the app is consistent (if light-only) until it lands.

Phase 1 scope decision: deliberately out. Filed so the "light" pin in app.json is traceable to a decision rather than looking like an oversight.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    mobileExpo / React Native layertaskSDLC task unit — one issue per task-breakdown item

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions