Index: src/routes/guardian.js
===================================================================
--- src/routes/guardian.js	(revision fcd696455474523785c5743fbe27829c039720d0)
+++ src/routes/guardian.js	(revision c6185fa8bf0039de95fa1be9afb9804d70c203af)
@@ -17,4 +17,5 @@
 import * as Guardianship from '../services/guardianship/index.js';
 import { t as i18nT, resolveLang } from '../services/i18n.js';
+import { injectCspNonce } from '../middleware/render.js';
 
 const router = express.Router();
@@ -63,4 +64,7 @@
   if (!site) return res.status(404).send('No site for this account.');
   const sites = db.prepare('SELECT slug, title FROM sites WHERE owner_id = ? ORDER BY id').all(req.session.user.id);
+  // This standalone PWA page is rendered directly (not through renderPage), so
+  // the CSP nonce must be injected here — otherwise strict-dynamic blocks
+  // guardian.js and the whole dashboard is dead (buttons do nothing).
   res.render('pages/guardian', {
     state: dashboardState(site, L),
@@ -69,4 +73,7 @@
     t: (k, v) => i18nT(L, k, v),
     cspNonce: res.locals.cspNonce,
+  }, (err, html) => {
+    if (err) { console.error('[guardian] render error', err); return res.status(500).send('Internal Server Error'); }
+    res.send(injectCspNonce(html, res.locals.cspNonce));
   });
 });
