From 9a3d7f38761a5b1ed55a5dd9b7d2c498b38ef4c1 Mon Sep 17 00:00:00 2001 From: funman300 Date: Fri, 1 May 2026 21:24:09 +0000 Subject: [PATCH] docs: refresh SESSION_HANDOFF for session 6 + UX-iteration direction Captures today's six commits (theme loader fix, exit-warn silence, two font-warn rounds, HUD band, action fade), updates HEAD/test counts, records that the player redirected from "cut v0.11.0 / package" to "keep iterating on UX," and lists the new four-item UX punch list (unlock foundations, drop shadows, drop highlighting, stock badge). Resume prompt is rewritten so a fresh agent on a different machine picks up cleanly: notes GitHub is the canonical remote (Gitea drift caused commits to silently miss the alex machine earlier in session), flags that the in-progress save format will invalidate when (1) lands, and explicitly defers the release-prep items. Co-Authored-By: Claude Opus 4.7 (1M context) --- SESSION_HANDOFF.md | 176 ++++++++++++++++++--------------------------- 1 file changed, 68 insertions(+), 108 deletions(-) diff --git a/SESSION_HANDOFF.md b/SESSION_HANDOFF.md index d2e5c9b..79f80c0 100644 --- a/SESSION_HANDOFF.md +++ b/SESSION_HANDOFF.md @@ -1,159 +1,119 @@ # Solitaire Quest — UX Overhaul Session Handoff -**Last updated:** 2026-05-01 — Phases 3, 4, 5 + the seven CARD_PLAN phases all shipped. v0.1.0 tagged locally. Bundled card art + runtime SVG theme system + in-Settings theme picker all live. Remaining work is desktop packaging and a player-side smoke test of the new theme. +**Last updated:** 2026-05-01 (session 6) — Six commits landed today on top of `v0.10.0`: four bug fixes surfaced by the player's first end-to-end smoke test of the embedded-theme path, plus a HUD-band layout reservation and an auto-fade for the action button bar. Direction has shifted from "cut a release" to "keep iterating on UX." ## Status at pause -- **HEAD:** `924a1e2`. v0.1.0 tag created locally (push pending interactive credentials). -- **Working tree:** clean after the post-Phase cleanup pass. +- **HEAD:** `c4970b1`. **Pushed to GitHub** (`origin = https://github.com/funman300/Rusty_Solitare.git`). +- **Working tree:** clean. (`CARD_PLAN.md` is untracked but intentionally so — it's a plan doc, not source.) - **Build:** `cargo clippy --workspace --all-targets -- -D warnings` clean. -- **Tests:** **960 passed / 0 failed / 9 ignored** across the workspace. +- **Tests:** **962 passed / 0 failed / 9 ignored** across the workspace. +- **Tags on origin:** `v0.9.0`, `v0.10.0`. Local-only stale tag `v0.1.0` (points at a doc commit far behind HEAD — safe to `git tag -d v0.1.0`). ## Where we are -Phase 3 (design tokens + modal scaffold) and Phase 4 (release polish) shipped earlier. Phase 5 — running the binary end-to-end and fixing what broke — landed nine more commits today: a layout fit fix so tableau columns stop spilling off-screen, a three-pronged resize-lag fix, persisted window geometry, splash skip on subsequent launches, achievement tooltips, a code-quality sweep, client-side sync round-trip tests, and a hit-test fix so dragging a card no longer requires aiming for the bottom strip. +The card-theme system, HUD restructure, and modal scaffold are all complete. Today's session was a player-smoke-test pass that surfaced four bugs (theme assets not loading, an exit-time false-warn, two flavours of usvg font-substitution noise) plus two cosmetic wins (HUD crowding the cards, action buttons cluttering the play surface even when idle). All shipped. -Polish is essentially complete; the remaining work is tagging v0.1.0 and desktop packaging. +The player explicitly said **the direction is more UX iteration, not release prep** — so the v0.11.0 cut and desktop packaging are deferred until they say otherwise. ### Design direction (unchanged) - **Tone:** Balatro — chunky readable type, theatrical hierarchy, satisfying micro-interactions. - **Palette:** Midnight Purple base + Balatro yellow primary + warm magenta secondary. -- See [memory/project_ux_overhaul_2026-04.md](.claude/projects/-home-manage-Rusty-Solitare/memory/project_ux_overhaul_2026-04.md) for full direction. +- See `~/.claude/projects/-home-manage-Rusty-Solitare/memory/project_ux_overhaul_2026-04.md` (auto-memory; on a different machine, recreate this fresh from the README + ARCHITECTURE.md). -## Phase 3 (shipped) +### Canonical remote -- `solitaire_engine/src/ui_theme.rs` — every design token: colours, type scale, spacing scale, radius rungs, z-index hierarchy, motion durations. -- `solitaire_engine/src/ui_modal.rs` — `spawn_modal` scaffold + button-variant helpers + `paint_modal_buttons` system. -- All 12 overlays migrated to the modal scaffold with real Primary/Secondary/Tertiary buttons (no more Y/N debug prompts). -- HUD restructured into a 4-tier vertical stack with progressive disclosure. -- Animation upgrades: `SmoothSnap` slide curves, scoped settle bounce, deal jitter, win-cascade rotation. +`github.com/funman300/Rusty_Solitare` is the canonical repo. Earlier in this session a self-hosted Gitea remote (`git.aleshym.co/funman300/Rusty_Solitare`) was the source of truth on one machine, which caused commits to silently not reach the machine running the game. **Always push to GitHub.** -## Phase 4 (shipped 2026-04-30) +## Session 6 (shipped 2026-05-01) | Area | Commit | What landed | |---|---|---| -| Workspace lint | `9bfca92` | Test-only clippy warnings under `--all-targets` resolved. | -| App / window | `5f5aba8` | WM_CLASS, centered-on-primary window, panic hook → `crash.log`. | -| Modal animation | `71999e1` | `ModalEntering` + ease-out scrim fade and 0.96→1.0 card scale. | -| Score feedback | `dcfa976` | `ScorePulse` triangular 1.0→1.1→1.0; floating "+N" for jumps ≥ threshold. | -| Hit targets | `b082bd6` | `ICON_BUTTON_PX` 28 → 32; sync status reads "local only". | -| Microcopy | `abeb4e5` | Help "Close" → "Done"; final onboarding CTA → "Let's play". | -| Empty states | `65d595a` | First-launch em-dash zero-stats grid + welcome line on Profile. | -| Leaderboard | `1384365` | Idle/Loaded/Error enum; local-only guard. | -| Credits | `fd7fb7b`, `f866299` | CREDITS.md added; README links it. | -| Home | `c1bde18` | Home repurposed as Mode Launcher with level-5 lock state. | -| Focus rings (Phase 1) | `1278952` | Tab/Shift-Tab/Enter on every modal button; auto-focus primary. | -| Focus rings (Phase 2) | `51d3454` | HUD action bar (hover-gated) and Home mode cards. | -| Focus rings (Phase 3) | `b78a493` | Settings: icon buttons, swatches, toggles; arrow-key `FocusRow`; auto-scroll. | -| Achievement tests | `2e080d0` | Integration coverage for `draw_three_master` and `zen_winner`. | -| Microcopy | `0c86cac` | "New game" / "Forfeit" replace "Yes, abandon" / "Yes, forfeit". | -| Tooltip infra | `54d3497` | `Tooltip(Cow<'static, str>)` component + hover-delay overlay. | -| HUD tooltips | `220e3f0` | 10 readouts + 6 action buttons. | -| Settings tooltips | `74597a8` | Volume, toggles, swatches, Sync Now. | -| Popover tooltips | `dbe6c60` | Modes and Menu rows. | -| Splash | `5d57b67` | Branded splash overlay (300ms fade-in / ~1s hold / 300ms fade-out). | -| Doc-rot | `73e210b` | ARCHITECTURE.md `bevy_kira_audio` references → `kira`. | -| Doc | `de52c8a`, `60a8036` | Mid-session and end-of-Phase-4 SESSION_HANDOFF refreshes. | +| Theme loader | `ab1d098` | `AssetPath::resolve` (concatenates) → `resolve_embed` (RFC 1808 sibling resolution). Was producing paths like `…/theme.ron/hearts_4.svg` and failing to load every face SVG. | +| Sync exit log | `9a9026e` | `push_on_exit` now silently no-ops on `LocalOnlyProvider`'s `UnsupportedPlatform` instead of warn-spamming "sync push on exit failed" every shutdown. Mirrors the pull path's existing handling. | +| Font warn (filter) | `78cf30e` | Initial fix: populated usvg fontdb with system fonts + LogPlugin filter. Insufficient on its own (warnings still fired). Superseded by next commit. | +| Font warn (resolver) | `efa063f` | Custom `usvg::FontResolver.select_font` appends `Family::SansSerif` and `Family::Serif` to every query so unmatched named families (Arial on Linux) silently fall through to whatever sans-serif fontconfig points at. Reverts the LogPlugin filter. | +| HUD band | `2c72e1f` | `layout::HUD_BAND_HEIGHT = 64` reserved at top; `top_y` shifts down. Translucent `BG_HUD_BAND` strip painted via `hud_plugin::spawn_hud_band`. Cards no longer crowd the action buttons / score text. | +| Action fade | `c4970b1` | `HudActionFade` resource + cursor-tracked auto-hide. Buttons fade out when cursor is below `HUD_BAND_HEIGHT + 32 px`, fade back in when it returns. Lerp at 6/sec ≈ 167 ms transition. Applied in `Last` schedule so paint_action_buttons can't clobber. | -## Phase 5 (shipped 2026-05-01) +## Open punch list — UX iteration (current direction) -Smoke test surfaced three issues: window-resize lag, tableau columns clipped below viewport, hit-target offset on cards. All fixed, plus four bonus polish items. +The player's request, in priority order they've expressed: -| Area | Commit | What landed | -|---|---|---| -| Layout fit | `8dda954` | `card_height` constrained by vertical budget; worst-case 13-card column always fits. | -| Resize perf | `1719fda` | In-place sprite/text mutation + 50ms `ResizeThrottle` (was full re-spawn per pixel). | -| Resize stall | `59316de` | `PresentMode::AutoNoVsync` eliminates the X11/Wayland vsync stall during drag. | -| Window geometry | `6e7705b` | `WindowGeometry` persisted to settings.json; debounced save on resize/move. | -| Achievements | `7448225` | Tooltips on rows: reward shown when unlocked, condition + reward when locked, secrets stay cryptic. | -| Lint sweep | `4b9d008` | 33 pedantic warnings cleared (`map_unwrap_or`, `uninlined_format_args`, `match_same_arms`). | -| Sync tests | `3ef4ecb` | Five client-side round-trip integration tests via in-process axum + mock keyring. | -| Splash | `912b08c` | Splash skipped on subsequent launches via existing `first_run_complete` flag. | -| Hit test | `902560c` | `card_position` mirrors face-down fan step (0.12) for accurate AABB on tableau columns. | +1. **Unlock foundations** — currently `PileType::Foundation(Suit)` pre-assigns each foundation to a fixed suit (the slots show "C / D / H / S" placeholders). Player wants any Ace to land in any empty foundation; the slot then claims that suit until empty again. Cleanest path: change variant to `Foundation(u8)` (slot 0–3) and track the claimed suit as runtime state on `Pile`. Touches ~80 call sites in `solitaire_core` + `solitaire_engine`. Does NOT cross `solitaire_sync` (PileType is not transmitted), so no API break. **One-time invalidation of in-progress `game_state.json` saves on first launch after upgrade.** +2. **Card drop shadows against the felt** — cards currently read as flat stickers. Subtle 2-3 px shadow under each card, slightly stronger when picked up. "Make the play surface feel physical." +3. **Drop-target highlighting during drag** — when the player is holding a card, legal target piles glow / lift slightly. Highest gameplay-feel win in this list. Currently drops feel guess-y because there's no preview. +4. **Stock-pile remaining-count badge** — small "·N" chip on the corner of the stock so the player knows how many cards remain before a recycle. Currently they recycle blind. -## Open punch list for v1 +## Open punch list — release prep (deferred per player) -1. **Player smoke-test of the new theme system.** Launch - `cargo run -p solitaire_app --features bevy/dynamic_linking` and - confirm: (a) hayeah card faces render correctly, (b) the - midnight-purple `back.svg` shows on face-down cards, (c) the - "Card Theme" picker appears in Settings → Cosmetic with at least - the "Default" chip, (d) clicking the chip is a no-op (already - selected) without errors. -2. **Push the v0.1.0 tag** — `git push origin v0.1.0` once you're - happy with the smoke-test outcome. Tag exists locally; not yet on - origin. -3. **Desktop packaging** per ARCHITECTURE.md §17. The Arch PKGBUILD - exists in `/home/manage/solitaire-quest-pkgbuild/` (separate repo, - no remote yet — `git remote add origin ` and push to your - gitea / AUR when ready). Still pending: app icon, macOS .icns + - notarisation cert, Windows .ico + Authenticode cert, AppImage - recipe. +These are still on the table but the player has explicitly deferred them in favour of more UX work: -### Optional, deferred +1. **Cut `v0.11.0`** — meaningful slice since `v0.10.0`: full card-theme system (CARD_PLAN phases 1–7 + theme picker + hayeah art), HUD overhaul (band + fade), and the four bug fixes from session 6. (`git tag -d v0.1.0` first to clean up the stale local tag.) +2. **README + CHANGELOG refresh** — README was last touched at `a6b8348` before the Settings picker shipped; doesn't mention card themes or the auto-fade. +3. **Desktop packaging** per `ARCHITECTURE.md §17`. The Arch PKGBUILD exists in `/home/manage/solitaire-quest-pkgbuild/` (separate repo, no remote yet). Pending: app icon, macOS .icns + notarisation cert, Windows .ico + Authenticode cert, AppImage recipe. + +### Optional, deferred (lower priority than the four UX items above) - Animated focus ring (currently a static overlay; could pulse on focus change). - Achievement onboarding pass — show first-time players the achievement panel after their first win. - Mode-switch keyboard shortcut from inside the Mode Launcher (today only mouse opens it). -- Runtime aspect-ratio fidelity for the bundled hayeah cards: the SVG - source is ~1.45 height/width while the engine layout assumes 1.4. - Cards display ~3% squashed vertically; either widen the layout or - letterbox the SVGs to match. Cosmetic-only; not blocking. +- Runtime aspect-ratio fidelity: hayeah SVGs are ~1.45 h/w; engine layout assumes 1.4. Cards render ~3 % squashed vertically. Cosmetic. ## Card-theme system (CARD_PLAN.md, fully shipped) -Seven phases landed across `b8fb3fb` → `924a1e2`. End-to-end flow: +Seven phases landed across `b8fb3fb` → `924a1e2`. End-to-end: -- **Bundled default theme** ships in the binary via `embedded://` — - 52 hayeah/playing-cards-assets SVGs (MIT) + a midnight-purple - `back.svg` (original work). -- **User themes** live under `themes://` rooted at - `solitaire_engine::assets::user_theme_dir()`. Drop a directory - containing a valid `theme.ron` + 53 SVG files there and it - appears in the registry on next launch. -- **Importer** at `solitaire_engine::theme::import_theme(zip)` - validates an archive (20 MB cap, zip-slip rejection, manifest - validation, every referenced SVG round-tripped through the - rasteriser) and atomically unpacks it into the user themes dir. -- **Picker UI** in Settings → Cosmetic offers one chip per - registered theme; selection persists to `settings.json` as - `selected_theme_id` and propagates to live card sprites via - `react_to_settings_theme_change` → - `sync_card_image_set_with_active_theme` → `StateChangedEvent`. +- **Bundled default theme** ships in the binary via `embedded://` — 52 hayeah/playing-cards-assets SVGs (MIT) + a midnight-purple `back.svg` (original work). +- **User themes** live under `themes://` rooted at `solitaire_engine::assets::user_theme_dir()`. Drop a directory containing `theme.ron` + 53 SVG files; appears in the registry on next launch. +- **Importer** at `solitaire_engine::theme::import_theme(zip)` validates an archive (20 MB cap, zip-slip rejection, manifest validation, every SVG round-tripped through the rasteriser) and atomically unpacks. +- **Picker UI** in Settings → Cosmetic — one chip per registered theme; selection persists to `settings.json` as `selected_theme_id` and propagates to live sprites via `react_to_settings_theme_change` → `sync_card_image_set_with_active_theme` → `StateChangedEvent`. ## Resume prompt ``` -You are a senior Rust + Bevy developer finishing v1 of Solitaire -Quest. Working directory: /home/manage/Rusty_Solitare. Branch: -master. The polish phase is complete; the remaining work is release -prep, not new features. +You are a senior Rust + Bevy developer iterating on UX for Solitaire +Quest. Working directory: . +Branch: master. Current direction is UX iteration, NOT release prep — +the player explicitly deferred v0.11.0 and packaging in favour of more +gameplay-feel work. -State: HEAD=902560c, fully pushed to origin. Working tree clean. +State: HEAD=c4970b1, fully pushed to GitHub +(origin = https://github.com/funman300/Rusty_Solitare.git). +Working tree clean apart from untracked CARD_PLAN.md (intentional). Build: cargo clippy --workspace --all-targets -- -D warnings clean. -Tests: 906 passed / 0 failed. +Tests: 962 passed / 0 failed / 9 ignored. READ FIRST (in order, before doing anything): - 1. SESSION_HANDOFF.md — full state and punch list + 1. SESSION_HANDOFF.md — full state, session 6 changelog, punch list 2. CLAUDE.md — hard rules (UI-first, no panics, etc.) - 3. ARCHITECTURE.md §15, §17 — platform targets, deployment guide - 4. ~/.claude/projects/-home-manage-Rusty-Solitare/memory/MEMORY.md - — saved feedback / project context + 3. ARCHITECTURE.md — crate responsibilities + data flow + 4. ~/.claude/projects//memory/MEMORY.md + — saved feedback / project context (machine-local; + may be missing on a fresh machine) -PUNCH LIST (in priority order): - 1. Confirm or fill the xCards upstream URL in CREDITS.md (one-line - edit; not a release blocker). - 2. Tag v0.1.0 once the user signs off. - 3. Desktop packaging: icon hookup, platform bundles (.ico/.icns/ - AppImage), signing. Needs artwork and certs from the user. +PUNCH LIST — UX iteration, in priority order the player expressed: + 1. Unlock foundations: any Ace lands in any empty slot, slot claims + that suit until emptied. Refactor PileType::Foundation(Suit) → + Foundation(u8). ~80 call sites. Invalidates in-progress saves. + Does NOT cross solitaire_sync. + 2. Card drop shadows against the felt. + 3. Drop-target highlighting during drag (highest gameplay-feel win). + 4. Stock-pile remaining-count badge. + +DEFERRED (do not start without explicit direction): + - Cut v0.11.0, README/CHANGELOG refresh, desktop packaging. WORKFLOW NOTES: - Commits use: - git -c user.name=funman300 -c user.email=root@vscode.infinity commit -m "..." + git -c user.name=funman300 -c user.email=root@vscode.infinity \ + commit -m "..." - Sub-agents stage + verify only; orchestrator commits. - - Every commit must pass build / clippy / test. + - Every commit must pass build / clippy / test before pushing. + - Push to GitHub (origin) — that is the canonical remote. -OPEN AT THE START: ask which punch-list item to start on. Don't pick -unilaterally — release-readiness ordering is the user's call. +OPEN AT THE START: ask which punch-list item to start on. The player +prefers being asked over you picking unilaterally; (1) is the largest +in code-touch and they may want to scope it first. ```