- Player room connection lifted out of the /play route to an app-level hook
(usePlayerConnection in RootLayout), keyed by a persisted joinIntent — so a
player stays connected while browsing their sheet, the compendium, anywhere,
and a reload reconnects automatically.
- Header "● Live: CODE · Leave" badge (PlayerSessionBadge); leaving is explicit
(leaveRoom clears intent + disconnects). /play renders the table from the store.
- Realtime e2e: player navigates away, badge persists, returns to a synced table.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Players claim a seat (GM approves) and drive their own character live —
HP/slots/resources/conditions/dice broadcast to the table — via new seat
protocol messages and per-seat ownership enforced in RoomHub. GM persists
player edits (charactersRepo.update → liveQuery → rebroadcast). Offline dev:
"Share with player" encodes a claim link (src/lib/sync/playerLink.ts) → /player
imports the character locally for full-sheet editing, bundled back as an
offlineSnapshot on seat claim for GM review.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>