Index: src/middleware/render.js
===================================================================
--- src/middleware/render.js	(revision 4590e66b7458ade434bf5a870980abc09155b777)
+++ src/middleware/render.js	(revision e2ea5c49d99947fd02bdda292a25027f868b7225)
@@ -73,5 +73,8 @@
   // (Vary also applies to intermediate caches / Cloudflare.)
   res.setHeader('Vary', 'HX-Request');
-  if (isPartial) res.setHeader('Cache-Control', 'no-store');
+  // A full HTML page must always be revalidated so an online visitor gets the
+  // fresh site, never a heuristically-cached copy. no-cache (not no-store) still
+  // allows bfcache and conditional requests. Partials stay no-store (see above).
+  res.setHeader('Cache-Control', isPartial ? 'no-store' : 'no-cache');
 
   // Does this (non-god) user own a site? Determines whether they see an "Admin"
Index: src/server.js
===================================================================
--- src/server.js	(revision 4590e66b7458ade434bf5a870980abc09155b777)
+++ src/server.js	(revision e2ea5c49d99947fd02bdda292a25027f868b7225)
@@ -478,5 +478,5 @@
   res.set('Cache-Control', 'no-cache');
   res.send(`
-const CACHE_VERSION = 'pcms-v17-' + new Date().toISOString().split('T')[0];
+const CACHE_VERSION = 'pcms-v18-' + new Date().toISOString().split('T')[0];
 self.addEventListener('install', e => {
   e.waitUntil(caches.open(CACHE_VERSION).then(c => c.addAll(['/'])));
@@ -503,5 +503,9 @@
   try { if (new URL(e.request.url).origin !== self.location.origin) return; } catch (err) { return; }
   e.respondWith(
-    fetch(e.request).then(resp => {
+    // { cache: 'no-store' }: go to the network for the page, bypassing the browser's
+    // HTTP cache, so an online visitor ALWAYS gets the fresh site and never a
+    // heuristically-cached copy served through the SW. The cache is only a
+    // last-resort offline fallback (the .catch below).
+    fetch(e.request, { cache: 'no-store' }).then(resp => {
       // Network-first: always serve fresh when online. Also refresh the '/' offline
       // fallback with the homepage we just served, so a later cold start on a flaky or
