Crash fix:
- restoreBackup (file + cloud pull) now validates each row through its Zod
schema, backfilling new fields — an older backup no longer lands characters
missing feats/concentration/etc and crashing the sheet. + test.
pf2e parity (closing feature gaps vs 5e):
- +9 missing classes (Animist, Exemplar, Gunslinger, Inventor, Kineticist,
Magus, Psychic, Summoner, Thaumaturge) with data + class tips.
- the wizard now enriches pf2e classes with their caster ability, so pf2e
spellcasters get the Spells step + "Caster" tag like 5e.
- editable Perception rank and spellcasting proficiency on the pf2e sheet
(fixes wrong initiative / spell DC at higher levels); rank-10 spell slots.
- pf2e monster resistances/weaknesses/immunities now apply in combat (flat
amounts: resistance subtracts, weakness adds, 'all' matches any type). + tests.
Glyph purge (finishing the emoji→Lucide migration): replaced ~40 leftover
text-glyphs (✕ − + ✦ 🤫 ⬆ ⬇ ☑ ☐ ▶ ◀ ‹ › ★ ↻ ▸ ↑ ●) with Lucide icons across
Modal (every dialog), the sheet sections, dice, settings, player panels, world
pages, map editor, roll tray, and session UI.
Gate: 293 unit + e2e green; tsc + build clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- character.portrait + mapToken.image (data URLs, Dexie v10, additive).
- src/lib/img/resize.ts: center-crop + downscale helper (160px tokens / 256px
portraits) keeping IndexedDB + wire payloads small.
- Portrait uploader on the character sheet; token icon uploader in the map token
modal (falls back to the linked character's portrait). Palette PC entries show
the portrait thumbnail.
- Tokens render the image clipped to the circle (HP ring + condition badge on top).
- Realtime: generalized the image channel to many images (map bg + token/portrait
icons), deduped by content and resent on reconnect. Player tokens/party carry an
imageId resolved from the session image cache; party panel shows portraits.
- Also: fix the encounter-picker dropdown text being clipped (drop fixed height).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- PWA registerType autoUpdate + skipWaiting/clientsClaim/cleanupOutdatedCaches so
a fresh deploy reaches browsers without a manual hard-reload (the old 'prompt'
served the stale cached bundle, hiding shipped fixes like the polygon outline).
- MapCanvas: always mount the outer container so the ResizeObserver binds even when
the map image arrives late over WebSocket — fixes the networked player view
showing the map at 100% instead of fit ("3x magnified").
- TokenPalette: encounter picker for planned AND active encounters (was active-only),
with per-encounter "+ All" and counts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Render maps at natural resolution inside a CSS-transform world layer (zoom,
pan, fit-to-view) instead of shrinking to maxWidth — large maps are now usable.
Pure viewport math in src/lib/map/viewport.ts (unit-tested). New TokenPalette
places party PCs / active-encounter combatants / blanks in one click with dup
detection; tokens gain optional combatantId (Dexie v9) for live encounter HP.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>