Each card is a parent Sprite (white for face-up, blue for face-down) with
a Text2d child showing rank+suit (e.g. "AH", "10C", "KS"). Hearts and
diamonds render red; clubs and spades black. Face-down labels are hidden.
Tableau cards fan downward; other piles stack at the same position with a
small z-offset.
Sync runs in PostStartup for the initial deal and in Update after every
StateChangedEvent. To avoid a one-frame lag, downstream plugins run after
the new GameMutation system set.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
compute_layout is a pure function that maps window size to card size and
the 13 pile positions, with clamping at the 800x600 minimum and seven
tableau columns horizontally aligned with stock/waste (cols 0,1) and the
four foundations (cols 3,4,5,6). TablePlugin spawns a 2D camera, a felt
background sprite, and 13 translucent pile-marker sprites, and
repositions them on WindowResized. Plugin registers WindowResized
explicitly so it works under MinimalPlugins in tests.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Introduces the plumbing layer for Phase 3: GameStateResource wraps
solitaire_core::GameState, DragState tracks in-progress drags, and
SyncStatusResource holds runtime sync status. GamePlugin routes
Draw/Move/Undo/NewGame request events into GameState and emits
StateChangedEvent and GameWonEvent for downstream systems.
Also adds the Phase 3 implementation plan under docs/superpowers/plans/.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>