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.
Identified while implementing #12 (PR #110).
src/constants/colors.ts(Task 9, PR #110) derives its tokens from the web palette inapps/web/src/styles.css, which defines both a light set on:rootand a dark set underhtml.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'sapp.jsonhaduserInterfaceStyle: "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.html.tui-theme-darkvalues into a dark token set, choose how a screen reads them (useColorScheme()+ auseThemeColors()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 restoreuserInterfaceStyle: "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.useColorScheme(). Nothing is mocked beyond that.userInterfaceStyleis back to"automatic"with no light-on-dark mismatch on any Phase 1 screen.feat/mobile-dark-modePhase 1 scope decision: deliberately out. Filed so the
"light"pin inapp.jsonis traceable to a decision rather than looking like an oversight.