Every grid cell downloaded the full detail sprite. Generate a smaller
/sprites-grid/v1/ set at build time and let the grid ask for those first,
falling back through the existing detail URLs when a thumbnail is missing so
detail resolution is unchanged. The new prefix is versioned, so it can be cached
forever, and the service worker recognises it alongside the other sprite roots.
The placeholder is now an empty box rather than a spinner: a thousand spinners
cost layout work and announced nothing useful.
- Sprites are cached as they are viewed instead of bulk-downloaded after
every sign-in, in one shared cache that is never pruned and survives
sign-out and account changes, since sprites never change.
- A "Save all artwork for offline" link saves every remaining sprite on
request, shows the remaining size, and is hidden once all are saved.
- Page loads reuse an offline snapshot under 15 minutes old; edits,
retries and a new sign-in still sync immediately.
- An expired session no longer wipes offline data; only the Sign Out
button does.
Each sync created a new artwork cache and re-fetched every sprite with no-cors. Opaque responses are padded to several MB each for storage quota, so a Living Dex grew to tens of GB, syncs never finished, and the offline copy could fail to save.
Artwork now lives in one cache per user that is topped up with only missing sprites, fetched with CORS so they count at their real size, with a per-fetch timeout. The offline copy is committed before any artwork, legacy per-sync artwork caches are removed first, and sprites shown online are cached on first load. Also requests persistent storage.