Reference crypto subtle insecure origin

window.crypto.subtle only exists in secure contexts: https or localhost. Any page served over plain http from a LAN IP (e.g. Vite dev at http://192.168.86.50:<port>) gets crypto.subtle === undefined, so WebCrypto signing/hashing throws immediately while the same code passes every localhost test.

Hit 2026-07-02 in the justinkrystal.com fishing game: HMAC-signed leaderboard submits worked in Playwright (localhost) but silently failed on Justin's phone via the LAN dev URL. Fix: pure-JS HMAC-SHA256 fallback in games-src/src/fishing/hmac.ts (reusable), selected when globalThis.crypto?.subtle is missing, plus a visible error status instead of a silent catch.

Rule of thumb: any browser feature gated on secure contexts (WebCrypto, service workers, clipboard, geolocation) must be tested through the LAN IP, not just localhost, before calling it done. [Claude Code]