Index: src/server.js
===================================================================
--- src/server.js	(revision a8b4f10c0a990c56c7d7d68d8488d9406448df7e)
+++ src/server.js	(revision fe9164f4c79349febdefb284f3101cd67d2f1eb3)
@@ -99,5 +99,5 @@
   contentSecurityPolicy: {
     directives: {
-      defaultSrc: ["'self'"],
+      defaultSrc: ["'none'"],
       // Strict CSP: a per-request nonce + 'strict-dynamic' (no 'unsafe-inline', no broad host
       // sources — securityheaders/Observatory flag those). Trusted (nonce'd) scripts may load
@@ -132,4 +132,10 @@
       // renderPage — it shows untrusted remote content next to the interact buttons.
       frameSrc: ["'self'", "https:"],
+      // default-src is 'none' (deny by default), so resource types that were implicitly covered
+      // by the old default-src 'self' must be listed explicitly: the PWA manifest and the
+      // service worker. (base-uri/form-action/frame-ancestors/object-src 'none' come from
+      // Helmet's defaults; img/style/connect/media/font/frame are set above.)
+      manifestSrc: ["'self'"],
+      workerSrc: ["'self'", "blob:"],
     },
   },
