534870a68a
Replaces the 3-line resume prompt with a senior-Rust-developer framing plus seven concrete next-direction tracks (A–G) covering the Home modal decision, window/release polish, sound, sync, achievements, release backlog, and UI/UX professional polish. Each track names specific files/tokens so the next session can act on a chosen direction without re-discovery.
213 lines
14 KiB
Markdown
213 lines
14 KiB
Markdown
# Solitaire Quest — UX Overhaul Session Handoff
|
||
|
||
**Last updated:** 2026-04-30 — Phase 3 complete. All 10 steps landed; ready for full smoke-test.
|
||
|
||
## Where we are
|
||
|
||
Phase 3 of the UX overhaul brief is **done**. The whole engine has been migrated to the `ui_theme` design-token system + `ui_modal` scaffold. Animation system upgraded. Final literal sweep landed. The work spans 17 commits this session, from the foundation (`e14852c`) through to the final sweep (`54e024c`).
|
||
|
||
### Design direction (already saved as project memory)
|
||
|
||
- **Tone:** Balatro — chunky readable type, theatrical hierarchy, satisfying micro-interactions.
|
||
- **Palette:** Midnight Purple base (`BG_BASE` `#1A0F2E` → `BG_ELEVATED` `#2D1B69` → `BG_ELEVATED_HI` `#3A2580` → `BG_ELEVATED_TOP` `#482F97`) + Balatro yellow primary accent (`ACCENT_PRIMARY` `#FFD23F`) + warm magenta secondary (`ACCENT_SECONDARY` `#FF6B9D`).
|
||
- See [memory/project_ux_overhaul_2026-04.md](.claude/projects/-home-manage-Rusty-Solitare/memory/project_ux_overhaul_2026-04.md) for the full direction.
|
||
|
||
### Top complaints from the original smoke test — all closed
|
||
|
||
1. **HUD too cluttered.** ✅ Closed by `73cad7e` — readouts now sit in a 4-tier vertical stack with progressive disclosure of penalty/bonus tiers.
|
||
2. **Y/N keyboard prompts feel like debug panels.** ✅ Closed across Confirm, GameOver, Pause, Forfeit, and Settings modals — every prompt now has real Primary/Secondary/Tertiary buttons with hover/press feedback.
|
||
|
||
## Foundation (done)
|
||
|
||
- **`solitaire_engine/src/ui_theme.rs`** — every design token: colours, 5-rung typography scale, 4-multiple spacing scale, three radius rungs, monotonically-ordered z-index hierarchy, motion durations with `scaled_duration(speed)` helper.
|
||
- **`solitaire_engine/src/ui_modal.rs`** — `spawn_modal` scaffold + `spawn_modal_header` / `spawn_modal_body_text` / `spawn_modal_actions` / `spawn_modal_button` helpers + `ButtonVariant` enum (Primary / Secondary / Tertiary) + `paint_modal_buttons` system. `UiModalPlugin` registered in `solitaire_app/src/main.rs`.
|
||
|
||
## Commits this session (Phase 3, latest first)
|
||
|
||
```
|
||
54e024c chore(engine): final literal-to-token sweep
|
||
3a01318 feat(engine): upgrade animations — curves, scoped settle, deal jitter, cascade rotation
|
||
79d3917 chore(data): derive Copy on AnimSpeed
|
||
ba019c0 feat(engine): convert SettingsPanel to modal scaffold + Done button
|
||
18d7c12 feat(engine): convert OnboardingPlugin to 3-slide modal flow
|
||
cb93bd9 fix(engine): pin modals via GlobalZIndex and surface forfeit-no-op toast
|
||
6723416 feat(engine): convert PauseScreen to modal + add ForfeitConfirmScreen
|
||
afb0879 docs: add SESSION_HANDOFF.md mid-overhaul checkpoint
|
||
3b619b8 feat(engine): convert HomeScreen to modal scaffold + Done button
|
||
37681cf feat(engine): convert LeaderboardScreen to modal scaffold + Done button
|
||
99064ce feat(engine): convert ProfileScreen to modal scaffold + Done button
|
||
de4dba6 feat(engine): convert AchievementsScreen to modal scaffold + Done button
|
||
75fc3aa feat(engine): convert StatsScreen to modal scaffold + Done button
|
||
deb034c feat(engine): convert HelpScreen to real-button modal with kbd-chip rows
|
||
242b5fe feat(engine): convert GameOverScreen to real-button modal
|
||
3f922ed feat(engine): convert ConfirmNewGameScreen to real-button modal
|
||
8da62bd feat(engine): add ui_modal primitive (scaffold + button variants)
|
||
73cad7e feat(engine): restructure HUD into 4-tier layout, adopt design tokens
|
||
e14852c feat(engine): add ui_theme.rs design-token module
|
||
```
|
||
|
||
**Test status:** `cargo build --workspace` clean, `cargo clippy --workspace -- -D warnings` clean, **819 tests pass / 0 failed / 8 ignored**.
|
||
|
||
## Smoke-test checklist
|
||
|
||
The whole overhaul is on disk. Worth running through once end-to-end:
|
||
|
||
1. **Run the game.** `cargo run -p solitaire_app --features bevy/dynamic_linking`.
|
||
2. **HUD layout** reads as 4 stacked tiers (Score / Mode / Penalty / Selection) with the new midnight-purple palette.
|
||
3. **Open every overlay** — `S` (Stats), `A` (Achievements), `P` (Profile), `O` (Settings), `L` (Leaderboard), `M` (Home), `F1` (Help). Each is a centred card on a uniform scrim with a yellow `Done` / `Close` primary button. Hover/press states on every button.
|
||
4. **Settings.** Four sections (Audio / Gameplay / Cosmetic / Sync). Body scrolls within the modal on small windows; `Done` button stays fixed at the bottom regardless of scroll. Card-back / Background pickers tint the selected swatch with `STATE_SUCCESS`.
|
||
5. **Confirm flow.** Click `New Game` while a game is in progress — the abandon-current-game modal has real Cancel/Confirm buttons. `Y/Enter` and the yellow primary button start a new game; `N/Esc` and the secondary button cancel.
|
||
6. **Pause + Forfeit.** Press `Esc` — pause modal shows real Resume / Forfeit buttons. Forfeit button opens a Cancel/Forfeit confirmation modal stacked above the pause modal (z-index ordered correctly via `GlobalZIndex`).
|
||
7. **First-run onboarding.** Delete `settings.json` (or set `first_run_complete = false`) — three-slide flow shows: Welcome → How to play → Keyboard shortcuts. Navigate with `Next` / `Back` buttons or `→` / `←` accelerators. `Esc` skips on slide 0.
|
||
8. **Animations.**
|
||
- Slide a card to a pile — motion curves through `SmoothSnap` (slight overshoot + settle), not linear lerp.
|
||
- Drop a card on a valid destination — only the moved cards bounce; the rest of the table stays still.
|
||
- Start a new game — deal stagger is no longer mechanically uniform; cards land with subtle ±10% timing variation.
|
||
- Win a game — cascade now uses `Expressive` curve with per-card ±15° Z-rotation, screen shake driven by the new `MOTION_WIN_SHAKE_*` tokens.
|
||
9. **Resize the window** — cards still snap, no "snap-back-and-forth" jitter.
|
||
10. **Win modal** — restyled with the design tokens: midnight-purple card, yellow `Play Again` button.
|
||
|
||
## Open follow-ups (not blockers)
|
||
|
||
- **Home / Help redundancy.** Home is still a kbd-reference modal that mostly duplicates Help. Three options: (1) keep as-is, (2) convert into a true mode launcher (Classic / Daily / Zen / Challenge / Time Attack cards, locked options visibly disabled below level 5), (3) drop entirely now that the action bar covers everything Home does. Worth asking the user which direction they want.
|
||
- **Forfeit countdown toast** is now superseded by the Forfeit modal (`6723416`). Confirm the toast path is no longer reachable when smoke-testing.
|
||
- **Sub-rung pixel sizes** (1 px borders, 64/80/110/150/160 px fixed widths, 28/36/50 px specific spacings) were intentionally left as literals during the step-10 sweep — they're below the smallest `SPACE_*` rung. If the design system grows a "fine" spacing tier in the future, those become candidates for migration.
|
||
|
||
## Resume prompt for the next session
|
||
|
||
```
|
||
You are a senior Rust + Bevy developer working toward a public release
|
||
of Solitaire Quest. Working directory: /home/manage/Rusty_Solitare.
|
||
Branch: master. Apply that lens to every decision: prefer shipping
|
||
quality (polish, packaging, defaults, credits, crash safety) over
|
||
greenfield features. If something is half-done, the question is
|
||
"finish for v1 or cut for v1?" not "what else can we add?".
|
||
|
||
State: HEAD=0066ca6. Phase 3 of the UX overhaul is shipped. cargo
|
||
build / clippy --workspace -- -D warnings / test --workspace all
|
||
green — 819 tests pass / 0 fail / 8 ignored.
|
||
|
||
READ FIRST (in order, before doing anything):
|
||
1. SESSION_HANDOFF.md — full state, smoke-test checklist, follow-ups
|
||
2. CLAUDE.md — hard rules (UI-first, no panics, etc.)
|
||
3. ARCHITECTURE.md §1, §15, §17 — design principles, platform
|
||
targets, deployment guide
|
||
4. ~/.claude/projects/-home-manage-Rusty-Solitare/memory/MEMORY.md
|
||
— saved feedback / project context
|
||
|
||
GATING SIGNAL — ASK FIRST, DON'T ASSUME:
|
||
Before proposing new work, ask: "Did the smoke-test (items 1-10 in
|
||
SESSION_HANDOFF.md) pass, or did anything regress?" If a regression
|
||
exists, fix it before opening any new thread.
|
||
|
||
LIKELY NEXT DIRECTIONS — surface for the user to choose, don't pick
|
||
unilaterally. All framed through "what does v1 release need?":
|
||
|
||
A. Home modal decision (open in SESSION_HANDOFF.md).
|
||
- keep as kbd-reference (duplicates Help — release-blocking
|
||
confusion?)
|
||
- repurpose as mode launcher (Classic / Daily / Zen / Challenge /
|
||
Time Attack cards, locked options below level 5)
|
||
- drop (action bar already covers every action)
|
||
|
||
B. Window + release polish — `solitaire_app/src/main.rs:34-48`
|
||
currently sets only title + resolution + min size. For public
|
||
release the window needs:
|
||
- app icon (taskbar / dock / alt-tab) — Bevy `Window::window_icon`
|
||
or platform `set_window_icon`; ship a .png/.ico asset.
|
||
- window class / app id (`Window::name`) so X11/Wayland and
|
||
Windows group taskbar entries correctly.
|
||
- persist size + position across launches (Settings already
|
||
saves to JSON; add `window_geometry` field).
|
||
- F11 (or a Settings toggle) wired to real fullscreen mode.
|
||
- centered default position on first launch (Bevy supports
|
||
`WindowPosition::Centered`).
|
||
- present_mode + vsync verification — make sure Linux/macOS
|
||
don't ship at uncapped 4000 fps.
|
||
- panic hook (`std::panic::set_hook`) that writes a crash
|
||
report next to the save files instead of silently exiting.
|
||
- macOS Info.plist / Windows .ico bundling — ARCHITECTURE.md
|
||
§17 currently only covers server deploy.
|
||
|
||
C. Sound-design audit. The scoped settle bounce (3a01318) means
|
||
audio_plugin.rs trigger sites may fire less often than before;
|
||
verify card_place / card_flip / card_invalid still feel right.
|
||
|
||
D. Sync flow end-to-end on a real second machine. Server
|
||
scaffolding exists but the register → push → pull → restore-on-
|
||
other-device round trip hasn't been exercised against the new
|
||
Settings sync section.
|
||
|
||
E. Achievement unlock completeness. ARCHITECTURE.md §11 lists 18.
|
||
The three hidden ones (speed_and_skill, comeback, zen_winner)
|
||
are most likely to be untested. For release, every advertised
|
||
achievement needs to actually fire.
|
||
|
||
F. Release-readiness backlog:
|
||
- README / store-page copy / screenshots
|
||
- LICENSE + third-party credits (xCards art, FiraMono, Bevy)
|
||
- SemVer + a v0.1.0 git tag
|
||
- itch.io / Steam packaging per platform (ARCHITECTURE.md §15)
|
||
- App signing — macOS notarization, Windows Authenticode,
|
||
Linux AppImage
|
||
- Telemetry / crash reporting — opt-in, off by default; or
|
||
confirm we ship without and rely on player reports
|
||
|
||
G. UI/UX professional polish — Phase 3 shipped the design system;
|
||
v1 wants the difference between "consistent" and "feels
|
||
intentional":
|
||
- Microcopy pass: every button label, empty state, error
|
||
message, and onboarding line reviewed for voice + clarity.
|
||
Pick one verb per concept ("Done" vs "Close" vs "OK") and
|
||
apply it everywhere.
|
||
- Empty / loading / error states: Leaderboard before any
|
||
scores, Stats before any games, Sync UI before login.
|
||
Today these are likely blank panels.
|
||
- Modal open/close animation: `MOTION_MODAL_SECS` token exists
|
||
in `ui_theme.rs:255` but isn't wired up — modals
|
||
appear/disappear instantly. Add scale-from-0.96 + scrim fade
|
||
per the token's doc comment.
|
||
- Tooltips on HUD readouts and settings labels. Bevy has no
|
||
built-in tooltip; build a small one. Hover a number to learn
|
||
what it counts.
|
||
- Accessibility: verify the AAA-contrast claim on
|
||
`ACCENT_PRIMARY` over `BG_BASE` (ui_theme.rs:65). Confirm
|
||
`AnimSpeed::Instant` disables every new animation (slide
|
||
curve, scoped settle, deal jitter, cascade rotation). Add
|
||
focus rings on `Button` entities for keyboard navigation.
|
||
- Typography choice: FiraMono is one weight, monospace for
|
||
everything. Consider shipping a second proportional face for
|
||
body + headings, keep mono for numerics (HUD score, timer).
|
||
Or commit to mono and lean into the "calm coder" feel — pick
|
||
deliberately and document the decision.
|
||
- Onboarding artwork: the 3 slides are text + buttons. For
|
||
release, stylised illustrations (or simple animated card
|
||
props on each slide) elevate the first-launch feel.
|
||
- Score-change feedback: floating "+N" numbers when score
|
||
jumps; pulse on the readout when value crosses a milestone.
|
||
`MOTION_SCORE_PULSE_SECS` is already a token.
|
||
- Splash / loading screen: today the window goes straight to
|
||
gameplay. A 1-2 second branded splash signals "real game"
|
||
vs "rust prototype".
|
||
- Hit-target audit: every interactive element ≥ 32 px on
|
||
desktop. Settings has 28 px icon buttons (`ICON_BUTTON_PX`
|
||
in settings_plugin.rs); revisit.
|
||
- Win-moment design: the cascade is good; consider a score-
|
||
breakdown reveal, streak callout, "share your time"
|
||
affordance for v1.
|
||
|
||
WORKFLOW NOTES:
|
||
- Commits use:
|
||
git -c user.name=funman300 -c user.email=root@vscode.infinity commit -m "..."
|
||
- Sub-agents can Edit/Write but CANNOT `git commit`. Brief them to
|
||
stage + verify only; orchestrator commits on their behalf.
|
||
See memory/feedback_agent_commit_limit.md.
|
||
- Remote push needs interactive credentials on git.aleshym.co; the
|
||
user runs `git push origin master` themselves.
|
||
- Every commit must pass build / clippy / test. Pause-and-verify
|
||
is the user's preferred cadence — one feature per commit.
|
||
|
||
OPEN AT THE START: ask (1) did smoke-test pass, (2) which of A–G to
|
||
pursue first. Do not assume.
|
||
```
|