Index: src/middleware/auth.js
===================================================================
--- src/middleware/auth.js	(revision 42081fbe4c4537789651ecf5cfece97f7b562c43)
+++ src/middleware/auth.js	(revision 8afbdd6572a947bce4726d5aa0d0aa0d6c7e5067)
@@ -37,7 +37,18 @@
 }
 
+// Een 'kijker' mag ALLES bekijken (incl. Beheer) maar NIETS wijzigen. De
+// schrijf-blokkade zit in de globale guard in server.js; deze helper bepaalt
+// alleen "is dit een alleen-lezen account?". `readonly` is de legacy-vlag die
+// we nog meenemen zodat niet-gemigreerde demo-accounts geblokkeerd blijven.
+export function isViewer(user) {
+  return !!user && (user.role === 'kijker' || !!user.readonly);
+}
+
 export function requireGod(req, res, next) {
   if (!req.session?.user) return loginRedirect(req, res);
-  if (req.session.user.role !== 'god') {
+  const role = req.session.user.role;
+  // god beheert; een kijker mág het Beheer-paneel zien (alleen-lezen) — de
+  // globale guard 403't elke write, dus dit geeft enkel kijk-toegang.
+  if (role !== 'god' && role !== 'kijker') {
     return res.status(403).send('God role required');
   }
@@ -52,5 +63,5 @@
   if (!req.session?.user) return loginRedirect(req, res);
   const u = req.session.user;
-  if (u.role === 'god') return next();
+  if (u.role === 'god' || u.role === 'kijker') return next(); // kijker = alleen-lezen kijk-toegang
   const site = res.locals.site;
   if (site && site.owner_id === u.id) return next();
@@ -62,5 +73,5 @@
   if (!req.session?.user) return loginRedirect(req, res);
   const u = req.session.user;
-  if (u.role === 'god') return next();
+  if (u.role === 'god' || u.role === 'kijker') return next(); // kijker = alleen-lezen kijk-toegang
   const site = db.prepare('SELECT owner_id FROM sites WHERE slug = ?').get(req.params.slug);
   if (site && site.owner_id === u.id) return next();
Index: src/middleware/render.js
===================================================================
--- src/middleware/render.js	(revision 42081fbe4c4537789651ecf5cfece97f7b562c43)
+++ src/middleware/render.js	(revision 8afbdd6572a947bce4726d5aa0d0aa0d6c7e5067)
@@ -15,4 +15,5 @@
 import db from '../config/database.js';
 import PermissionsService from '../services/PermissionsService.js';
+import { isViewer } from './auth.js';
 import { getSetting } from '../services/SettingsService.js';
 import { PLATFORMS as PLATFORMS_CATALOG } from '../services/PlatformIcons.js';
@@ -51,8 +52,14 @@
     : null;
 
+  // Kijker-modus: alles bekijken mag, niets wijzigen. Views gebruiken canMutate
+  // om schrijf-knoppen (posten, opslaan, verwijderen) te verbergen/uit te zetten.
+  const _isViewer = isViewer(_u);
+
   // Common locals
   const locals = {
     user: _u,
     userOwnsSite,
+    isViewer: _isViewer,
+    canMutate: !_isViewer,
     siteOwnerAvatar,
     site: _site,
@@ -65,5 +72,5 @@
     formatDate,
     formatDateTime,
-    pageTitle: data.pageTitle || (data.site && data.site.title) || 'PrutCMS',
+    pageTitle: data.pageTitle || (data.site && data.site.title) || 'Klonkt Hub Beta',
     bodyClass: data.bodyClass || 'on-home',
     socialDescr: data.socialDescr || '',
