| name | mobile-theme-parity |
| description | Cross-platform theme AND visual parity for apps/mobile — same theme IDs and design tokens as web, RN ThemeProvider, uit pref, and web-referenced screen layouts. Use when adding mobile styling, ThemeProvider, theme selector, design token imports, or building any mobile screen that has a web counterpart. |
Mobile theme + visual parity (web + mobile)
Mobile and web share supported theme IDs and semantic token values, not the same UI stack.
Mobile screens should also mirror the web app's visual design where a counterpart exists (see
§ Screen & visual parity below).
Supported themes
Same as web — from @podverse/ui / @podverse/design-tokens:
dark, light, dracula, violet, ember, dawn
Default when unset: dark (matches web :root / [data-ui-theme='dark']).
What mobile imports
| Allowed | Forbidden |
|---|
@podverse/design-tokens (RN-safe TS token maps) | @podverse/ui components |
UITheme, ALL_POSSIBLE_THEMES from design-tokens or @podverse/ui type re-export | SCSS, CSS custom properties at runtime |
Theme labels via i18n settings.ui_theme.* | Hardcoded hex colors in screens |
Pref storage
- Web:
localSettings cookie, key uit (apps/web/src/utils/localSettings/).
- Mobile: MMKV or AsyncStorage with same key semantics (
uit); full store in Track 16.1.
- Optional v1.1: honor
Appearance.getColorScheme() when uit unset; still default to dark.
Implementation pattern
apps/mobile/src/theme/
├── ThemeProvider.tsx # Context: uiTheme, setUITheme, token map
├── useTheme.ts # Hook for screens
└── createStyles.ts # Map design-tokens → StyleSheet factories
- Wrap app root (with nav shell, Track 7.11+).
- Wire
StatusBar style from active theme.
- Settings theme selector (Track 16.3): same ids as web
SettingsThemeSelector.tsx.
Token source of truth
SCSS in packages/ui/src/styles/_themes.scss and _variables-root.scss remains canonical for web/management-web.
When adding or changing theme-scoped tokens:
- Update SCSS in
packages/ui/src/styles/.
- Sync
@podverse/design-tokens RN export (see styles-source-of-truth skill).
- Update operator sample JSON if applicable (custom-themes-operator-sample-sync rule).
Screen & visual parity — reference the web app
When building any apps/mobile screen that has a web counterpart, look at the web app first
and mirror its information architecture and actions, adapted to React Native — as a
functional sketch, not final polish (master plan Ship bar + Track 23):
- Find the web source — the route client under
apps/web/src/app/<area>/ and/or the component
under apps/web/src/components/<Area>/. Cite it in the detail doc's Web parity references.
- Mirror the information hierarchy — header/hero, section order, list vs grid, row structure
(artwork + title + metadata + actions), selector/tab placement, and loading / empty / error
states. Match web semantics; do not invent a different IA. Pixel spacing may stay rough.
- Mirror action affordances (not just layout) — same primary controls as the web counterpart
(Play; Queue next/last; more-menu items; Subscribe/Unsubscribe). Adapt presentation (icon +
action sheet vs hover menu). Do not reuse unrelated i18n keys (e.g. queue copy for remove
feed). See DOCS-MOBILE-PROCESS-VISUAL-PARITY.md §4
and master-plan Track 9c. Which buttons exist matters; pixel polish waits for Track 23.
- Adapt, don't port — use RN primitives (
View, FlatList, Pressable, Image) and
StyleSheet factories from createStyles.ts; never import @podverse/ui or SCSS.
- Tokens only — all colors, spacing, and radii come from
@podverse/design-tokens via the
theme. No hardcoded hex in screens (enforced by this skill + mobile-react-native rule).
- Diverge only with reason — platform conventions (native back, pull-to-refresh, bottom sheets,
safe-area, tab bar) win over pixel-copying the web chrome. Note intentional divergences in the
detail doc.
- Hard stop — do not redesign the full player, add player-integrated transcripts, clip
authoring UI, or pixel DnD unless a master-plan step explicitly asks for that sketch (or
Track 23 brief). Prefer a working stub +
testID over thrashing on aesthetics.
Reference this section from screen detail docs (e.g. Tracks 8–9 home/browse screens) instead of
re-describing the rule per screen.
Deferred (operator / post-feature)
- Track 23 — operator screen-by-screen visual polish (agents apply briefs only).
- Player-integrated transcript chrome, clip authoring, pixel DnD — Track 21 deferrals.
- Operator remote custom themes (
NEXT_PUBLIC_CUSTOM_THEMES_URL) — web-only until mobile step lands.
- Brand logo variant by theme (web:
getBrandLogoSrc(uiTheme)).
Related