VERSION was stuck at raycer-v1 so mobile PWAs never picked up
the streak fix (cache-first served the stale stats.js forever).
- Bump to raycer-v2 → triggers install, purges old caches
- Switch same-origin assets from cache-first to network-first
so future deploys propagate immediately; cache is only used
as an offline fallback
- Simplify to a single SHELL_CACHE (no separate runtime cache)
- Cross-origin vendor assets (Dexie CDN) stay cache-first
currentStreak() was starting its backward walk from today, so if the
user hadn't checked in yet today the first lookup missed and it
returned 0 — even with a perfect streak on previous days.
Now when today's entry is absent and the goal is still active, the
count starts from yesterday instead. Once the goal window has closed
the original end-of-window anchor is preserved.
beforeinstallprompt fires asynchronously after renderLanding() runs,
so the click handler was never attached when the prompt arrived late.
Always attach the handler and check deferredInstallPrompt at click time.
- Landing page shows an "add to home screen" button when the browser
install prompt is available (Android/desktop) or on iOS Safari with
a share-menu hint; hidden when already running in standalone mode
- Last visited user route (/ray or /cer) is saved to Dexie meta and
restored on next open so the app reopens where you left off
- Active user in the topbar brand renders as a filled accent-color pill
- A 1px accent-color frame wraps the entire viewport while a user is active
Vanilla HTML/JS/CSS PWA with Dexie offline-first sync, Hono+SQLite backend,
served via nginx reverse-proxy. Two seed goals (no-sugar, no-social-media)
for users ray and cer.
Local dev runs at https://raycer.test via the shared Traefik proxy.
Production deploys to https://raycer.altweb.me on cool2026/personal via
docker-compose.coolify.yaml — see deploy/COOLIFY.md.