docs(android): build contract for admin theming and navigation parity (M12) #111
Reference in New Issue
Block a user
No description provided.
Delete Branch "docs/android-theming-nav-plan"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What & why
The website merged runtime admin theming, brand assets and nav overrides to
main(website#126 / docs#109). The Android app reads exactly one field of it —brand.accent— and renders a hardcodedAPP_MENU, so an admin who re-skins the site from Admin → Appearance and restructures the header from Admin → Navigation sees none of it on the phone.This adds
docs/android/THEMING_AND_NAV.mdas the design of record for M12, plus thePLAN.md§9 entry that anchors it — mirroring how the website side kept its build contract separate from its plan.Plan only. No app code, no backend work. Everything the app will consume is already live on
website/main:GET /public/settingsgainedtheme(the full resolved token map) andnav_public, itsbrandblock now returns effective values, andGET /api/v1/settings/navserves the admin/player overrides to any authenticated account.The points that shaped it
runic-gatewaypreset, value for value — M5 was drawn from the sametheme.cssthe preset was later extracted from. So the website's governing invariant ("an untouched instance renders as before") carries over as a testableColorSchemeequality assertion, not an approximation.Shapescame from the M5 mockup and genuinely differ (medium12dp vs--radius-card10px); a literal mapping would restyle the untouched app the day this ships, and copying the app's scale into the server would be a second source of truth.MenuAccessandMenuEntry.featurestill run after the merge, sohidden: falsecannot un-hide what a role or the shard's visibility config withholds — the same boundary the website's §7 draws.theme_visualandbrand_assetsride along in the same payload as the resolvedthemeandbrand. Re-deriving a palette from those raw rows would be a secondresolveThemeTokensin Kotlin, guaranteed to drift. The app models neither.Two things measured rather than assumed
Color.ktmigration is one file and seven constants.ThemeComponents.kt's other seven imports are semantic pill colors that stay fixed;ShardComponents.kt's two are semantic as well. Nothing else in the app reaches pastMaterialTheme.colorScheme— the M5 design premise paying off, and most of why this milestone is affordable.nav_playerreaches two app rows andnav_admintwo (/player,/account,/admin,/admin/moderation). The sidebar's other ~18 rows are admin configuration the app excludes, and two of the app's four staff entries are aggregates with no single web row. Hence label-and-hidden-only, and hence that phase is scheduled last and marked optional — dropping it costs nothing phases 0–6 depend on.Shape of the build
Nine phases into a fresh
edgeinAndroid-app/anddocs/, reachingmainas oneedge→mainmerge — the same shape the website side used. Phase 0 (contract + appearance store) carries a hard rule: it must change nothing on screen.How it was tested
Documentation only — nothing to build or run. Every claim about current behavior was checked against the code rather than from memory:
ui/theme/Color.ktmapping, value by value, againstserver/src/config/themePresets.js;ui.theme.Shard*import surface (two files, sixteen imports, seven themable);Shapesvs the web radius tokens, which is what forced the ratio decision;themePresets.jsFONT_OPTIONS;NAVarray inSiteHeader.jsxand the player/admin navs againstAPP_MENU/Routes.kt, which is where the unmapped rows came from;getPublic()insettings.model.jsand the/api/v1/settingsrouter group for the wire shapes.Checklist
AI-assisted contributions (required)
Claude Code (Opus 5). I have reviewed and understand every change, and take responsibility for it. AI-authored commits are marked with aCo-Authored-Bytrailer.License
docs(android): build contract for admin theming & navigation parity (M12)to docs(android): build contract for admin theming and navigation parity (M12)