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.
14 KiB
14 KiB
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 for the full direction.
Top complaints from the original smoke test — all closed
- HUD too cluttered. ✅ Closed by
73cad7e— readouts now sit in a 4-tier vertical stack with progressive disclosure of penalty/bonus tiers. - 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 withscaled_duration(speed)helper.solitaire_engine/src/ui_modal.rs—spawn_modalscaffold +spawn_modal_header/spawn_modal_body_text/spawn_modal_actions/spawn_modal_buttonhelpers +ButtonVariantenum (Primary / Secondary / Tertiary) +paint_modal_buttonssystem.UiModalPluginregistered insolitaire_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:
- Run the game.
cargo run -p solitaire_app --features bevy/dynamic_linking. - HUD layout reads as 4 stacked tiers (Score / Mode / Penalty / Selection) with the new midnight-purple palette.
- 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 yellowDone/Closeprimary button. Hover/press states on every button. - Settings. Four sections (Audio / Gameplay / Cosmetic / Sync). Body scrolls within the modal on small windows;
Donebutton stays fixed at the bottom regardless of scroll. Card-back / Background pickers tint the selected swatch withSTATE_SUCCESS. - Confirm flow. Click
New Gamewhile a game is in progress — the abandon-current-game modal has real Cancel/Confirm buttons.Y/Enterand the yellow primary button start a new game;N/Escand the secondary button cancel. - 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 viaGlobalZIndex). - First-run onboarding. Delete
settings.json(or setfirst_run_complete = false) — three-slide flow shows: Welcome → How to play → Keyboard shortcuts. Navigate withNext/Backbuttons or→/←accelerators.Escskips on slide 0. - 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
Expressivecurve with per-card ±15° Z-rotation, screen shake driven by the newMOTION_WIN_SHAKE_*tokens.
- Slide a card to a pile — motion curves through
- Resize the window — cards still snap, no "snap-back-and-forth" jitter.
- Win modal — restyled with the design tokens: midnight-purple card, yellow
Play Againbutton.
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.