sw: bump cache to v4 and revalidate with conditional fetch
Stale-while-revalidate was hitting the browser HTTP cache on its
revalidation fetch, so the SW-cached copy kept refreshing from an
already-stale response for the full max-age window. Using `cache:
'no-cache'` sends If-None-Match / If-Modified-Since so the origin can
return 304 or fresh 200, and the SW picks up changes on the next load.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>