# Menu UX Redesign — July 2026 Status: PLANNING. Visual identity (Terminal / base16-eighties) is settled and out of scope — this is about **structure and interaction**, not colors or type. ## Diagnosis (from code survey, 2026-07-07) | Surface | Today | Pain | | --- | --- | --- | | Settings | One scrolling modal, 5 section labels, ~37 control rows, single Done | Scroll-hunting for any toggle; endless on the folded (cover) screen; every new feature (theme store, import) stretches it further | | Home | Modal launcher: stats strip, draw-mode row, difficulty rows, 6 equal mode cards, Cancel | No "Continue" primacy; deal options (draw/difficulty/winnable) crowd the mode choice; six cards weighted identically though Classic dominates play | | HUD menu | Popover with 7 destinations (Help, Modes, Stats, Achievements, Profile, Settings, Leaderboard) | "Modes" duplicates Home's job; flat list, no grouping; each item opens another modal — modal-on-modal navigation | | Global | Everything is a modal over the felt | No hierarchy; near-square unfolded Fold renders one narrow wasted column | ## Phase A — Settings tabs (highest pain, lowest risk) - Replace the single scroll with **tabs**: `Audio · Gameplay · Appearance · Accessibility · Account`. - *Appearance* = today's Cosmetic (card back, background, card theme, theme store, import). - *Accessibility* = extracted from Gameplay/Cosmetic: color-blind, high-contrast, reduce-motion, touch input mode, tooltip delay. - *Account* = Sync + Privacy merged. - Narrow screens: tab chips in a row under the header. Wide (aspect > ~1.2 — unfolded Fold, desktop): left rail, rows in two columns. - Only the active tab's rows are spawned → each tab is ≤ 8 rows and fits the cover screen without scrolling. - **Implementation constraint:** pure `ui.rs` re-layout + one `SettingsTab` resource. The `SettingsButton` enum, input handlers, and persistence are untouched, so the 25 settings tests and the ambiguity gate stay green. ## Phase B — Home becomes a real home - **Hierarchy, top to bottom:** 1. `Continue` card (only when a game is in progress) — mode, elapsed, score. 2. Hero `New Game` — one tap, reuses last mode + deal options. 3. Compact 2×3 mode grid (Classic, Daily, Zen, Challenge, Time Attack, Seed) — smaller cards, glyph + name + one-line description on wide only. 4. Stats strip moves to the bottom (or right pane when unfolded). - **Deal options** (draw 1/3, difficulty, winnable-only) move off the top level into a disclosure on the Classic card / New Game hero — they are Classic-mode concerns, not global ones. - Cancel becomes `Back to table` and only renders when a game exists. - Unfolded Fold / desktop: two panes — modes left, Continue + stats + daily/weekly right. ## Phase C — HUD menu consolidation - Drop `Modes` from the popover (Home owns mode selection; HUD's New-Game path opens Home). - Group the remaining six: **Play** (Home) · **You** (Profile, Stats, Achievements) · **Community** (Leaderboard) · **System** (Settings, Help) — section dividers in the existing popover, not a new widget. - Dismissal audit: Esc / scrim-tap / Done must behave identically on every modal (most already do via `ScrimDismissible`; sweep the stragglers). ## Phase D — Validation gates - Optional Stitch mockups (Terminal design-system asset `assets/0f1652274fea460585d0b331a9ddbb06`, project 593811793268308763) for Home + Settings before implementing Phase B. Phase A is safe to build straight in-engine. - Per-phase gates: full test suite, clippy `-D warnings`, ambiguity gate at 0, Android checklist (§15.3), on-device pass on the Fold 7 in BOTH postures. ## Sequencing & risk | Phase | Size | Risk | Depends on | | --- | --- | --- | --- | | A — Settings tabs | ~1 session | Low (layout-only) | — | | B — Home hierarchy | 1–2 sessions | Medium (touches launch flow) | D mockups if wanted | | C — Menu grouping | small | Low | B (Modes removal) | ## Phase E — "You" hub (reuses the Phase A tab component) Profile, Stats, Achievements, and the replay browser are four separate modals today, reached through the HUD popover one at a time. Fold them into ONE tabbed hub — `Profile · Stats · Achievements · Replays` — using the same tab widget Phase A builds for Settings. Cuts the HUD popover to four destinations and makes the tab component pay for itself twice. Existing per-screen systems keep their markers/handlers; only the outer shell changes (same trick as Phase A). ## Phase F — Mobile ergonomics (Fold-first) - **Bottom action bar** on touch: Undo, Hint, Draw within thumb reach at the bottom safe-area edge (via the existing `SafeAreaAnchoredBottom`), score-only band stays on top. Desktop keeps the current top band. Biggest one-handed-play win available; folded posture is tall and top-heavy today. - **Hold-to-repeat Undo** — press-and-hold steps back repeatedly (respecting the existing undo scoring penalty), instead of tap-tap-tap. - Both are additive; game stays fully playable with the top band alone (UI-first rule §3.3 satisfied). ## Phase G — Post-win flow Win summary today is a stats dump with a close. Give it an action hierarchy: **Play again** (same mode/options, primary) · **Share replay** (the upload already returns a share URL; surface it here with copy feedback) · **Watch replay** · quiet stats below. Rematch loop drops from 4 taps to 1. ## Phase H — Feedback polish (small, bundling candidates) - Unify queued vs. immediate toast styling (two subtly different styles exist today) and anchor both to one position; consider a 5-item toast history on the stats screen. - Theme-store modal: render the preview PNGs the server already serves (v1 is text-only rows). - Hint: optional ghost-motion preview of the suggested move instead of a static highlight (auto-disabled under reduce-motion). ## Phase I — Onboarding & discoverability The first-run onboarding exists, but everything learned after it is invisible: the radial menu (long-press/right-click), hint cycling, tap-to-toggle HUD chrome, hotkeys. Add **contextual one-time tips** — fired by the situation, not a tour (first stall → hint tip; first long-press-able stack → radial tip; each shows once, stored in Settings like `shown_achievement_onboarding` already is). Plus a one-shot **"What's new"** card on first launch after a version bump — ObtainX updates are silent today, so shipped features go unnoticed (nobody will find the theme store on their own). ## Phase J — Keyboard & focus completeness (desktop + web) `ui_focus` already gives deterministic Esc order and tab-walk (`FocusRow`/`Focusable`), and `KeyboardDragState` exists — but full keyboard-only play has never been audited end to end. Deliverables: every modal reachable/dismissable without a mouse, a visible focus ring styled to the Terminal system (current focus state is subtle), and a hotkey cheat-sheet overlay (hold `?`) generated from the actual bindings instead of the static Help text. Web build (Rhys) benefits most. ## Phase K — UI scale & touch-target accessibility All type sizes flow through `TYPE_*` tokens and layout through `compute_layout` — which makes a **UI scale setting** (90/100/115/130 %) cheap to wire and genuinely useful on the Fold's dense cover screen. Pair with: respect Android system font scale on first run (seed the setting from it), and a one-time audit that every interactive element meets the 44 px logical minimum in BOTH Fold postures (the pill buttons and picker swatches are the suspects). Lands in the Accessibility tab that Phase A creates. ## Phase L — Empty & loading states, standardized Async/empty surfaces each improvise today: leaderboard with no entries, stats with no games, replay browser with no replays, theme store loading/error (just added), sync status text. Define ONE pattern — glyph + one-line explanation + a single next-step action — as a `spawn_empty_state` helper in `ui_modal`, and sweep all five surfaces onto it. Small, mechanical, big perceived-quality win. ## Phase M — Sync transparency & data stewardship The sync layer returns `ConflictReport`s ("data is never silently discarded") — but no UI ever shows them; players can't tell what a merge did. Add: a post-sync summary line ("merged, 2 conflicts kept newer values" → tap for detail in the Account tab), a visible last-synced timestamp (exists as `SyncStatus::LastSynced`, barely surfaced), and local **data export/import** (zip of the JSON saves) for device migrations without a server. Closes the trust loop the server work opened. ## Roadmap tie-ins (already in flight elsewhere) - **Spider mode** (feat/spider-core, PR #157): Home's mode grid gains a 7th card once engine work lands — the 2×3 grid in Phase B should be designed as N-card flow from day one. Spider UI also needs positional card→entity keys (documented in spider.rs module docs). - **Show solution** (feat/solution-line, in flight): lands in the pause menu; Phase C's grouping should leave room for it under a "Game" cluster if the pause menu grows. ## Sequencing (updated) | Phase | Size | Risk | Depends on | | --- | --- | --- | --- | | A — Settings tabs | ~1 session | Low | — (DECIDED: tabs) | | E — "You" hub | ~1 session | Low | A's tab component | | C — Menu grouping | small | Low | E (popover shrinks) | | B — Home hierarchy | 1–2 sessions | Medium | D mockups if wanted | | F — Bottom action bar | ~1 session | Medium (input paths) | — | | G — Post-win flow | small | Low | — | | H — Feedback polish | small each | Low | — | | I — Onboarding & discoverability | ~1 session | Low | ships best after B/F land | | J — Keyboard & focus completeness | ~1 session | Low | A/E (fewer modals to audit) | | K — UI scale & touch targets | ~1 session | Medium (layout-wide) | A (Accessibility tab) | | L — Empty-state standardization | small | Low | — | | M — Sync transparency & export | ~1 session | Low–Medium | A (Account tab) | Suggested order: **A → E → C** (one arc: the tab component and the menu slimming), then **B**, then **F/G/H** as independent follow-ups. ## Open decisions 1. ~~Settings: tabs vs. sub-pages~~ — **DECIDED 2026-07-07: tabs.** 2. Deal options: disclosure on Classic card (proposed) vs. keep global row? 3. Time Attack + Seed: top-level cards (proposed, grid stays symmetric) vs. tucked under a "More" card? 4. Stitch mockups for Phase B, or iterate directly in-engine? 5. Phase F bottom bar: touch-only (proposed) or also desktop?