Index: src/routes/admin-users.js
===================================================================
--- src/routes/admin-users.js	(revision 2165b6d3d57ceaa8b5d1f70491868482149470cf)
+++ src/routes/admin-users.js	(revision 7bc636b391c66ac399c33e54f7173a022c6a3cbd)
@@ -20,8 +20,5 @@
 const router = express.Router();
 
-// 'kijker' = read-only demo/audit account: may view everything (incl. admin panel),
-// but the global guard blocks all mutations. Replaces the old separate
-// 'kijk-modus' flag (readonly), which is now covered by this role.
-const VALID_ROLES = new Set(['kijker', 'member', 'admin', 'god']);
+const VALID_ROLES = new Set(['member', 'admin', 'god']);
 
 function godCount() {
@@ -32,5 +29,5 @@
 router.get('/', requireGod, (req, res) => {
   const users = db.prepare(`
-    SELECT u.id, u.username, u.email, u.role, u.created_at, u.avatar_url, u.readonly,
+    SELECT u.id, u.username, u.email, u.role, u.created_at, u.avatar_url,
            (SELECT COUNT(*) FROM posts p WHERE p.author_id = u.id) AS post_count,
            (SELECT COUNT(*) FROM sites s  WHERE s.owner_id  = u.id) AS site_count
@@ -40,5 +37,5 @@
 
   renderPage(req, res, 'pages/admin-users', {
-    pageTitleKey: 'admin.t_users',
+    pageTitle: 'Users',
     bodyClass: 'on-admin',
     users,
@@ -69,7 +66,5 @@
   }
 
-  // readonly=0: read-only status now lives entirely in the 'kijker' role, so
-  // on every role change we clear the legacy flag (no dual source of truth).
-  db.prepare('UPDATE users SET role = ?, readonly = 0, updated_at = CURRENT_TIMESTAMP WHERE id = ?')
+  db.prepare('UPDATE users SET role = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?')
     .run(newRole, userId);
   res.redirect('/admin/users?success=' + encodeURIComponent('Role updated'));
@@ -89,33 +84,22 @@
   }
 
-  // Cascade delete: this user's sites (+ posts/playlists/audio/members/
-  // comments under them), their own content elsewhere, then the user themselves.
-  // Atomic in a transaction — if any FK fails, everything rolls back.
-  const del = db.transaction(() => {
-    const sites = db.prepare('SELECT id FROM sites WHERE owner_id = ?').all(userId).map((s) => s.id);
-    for (const sid of sites) {
-      db.prepare('DELETE FROM comments WHERE post_id IN (SELECT id FROM posts WHERE site_id = ?)').run(sid);
-      db.prepare('DELETE FROM posts WHERE site_id = ?').run(sid);
-      db.prepare('DELETE FROM playlists WHERE site_id = ?').run(sid);
-      db.prepare('DELETE FROM audio_tracks WHERE site_id = ?').run(sid);
-      db.prepare('DELETE FROM site_members WHERE site_id = ?').run(sid);
-      db.prepare('DELETE FROM sites WHERE id = ?').run(sid);
-    }
-    // Own content on other sites + loose associations.
-    db.prepare('DELETE FROM comments WHERE post_id IN (SELECT id FROM posts WHERE author_id = ?)').run(userId);
-    db.prepare('DELETE FROM posts WHERE author_id = ?').run(userId);
-    db.prepare('DELETE FROM comments WHERE author_id = ?').run(userId);
-    db.prepare('DELETE FROM site_members WHERE user_id = ?').run(userId);
-    db.prepare('DELETE FROM users WHERE id = ?').run(userId);
-  });
+  const owned = db.prepare(`
+    SELECT
+      (SELECT COUNT(*) FROM posts WHERE author_id = ?) AS posts,
+      (SELECT COUNT(*) FROM sites WHERE owner_id  = ?) AS sites
+  `).get(userId, userId);
 
-  try {
-    del();
-  } catch (e) {
-    console.error('[admin/users delete]', e.message);
-    return res.redirect('/admin/users?error=' + encodeURIComponent('Verwijderen mislukt (mogelijk gekoppelde data).'));
+  if (owned.posts > 0 || owned.sites > 0) {
+    return res.redirect('/admin/users?error=' + encodeURIComponent(
+      `Cannot delete: user owns ${owned.sites} site(s) and ${owned.posts} post(s). Reassign or delete those first.`
+    ));
   }
 
-  res.redirect('/admin/users?success=' + encodeURIComponent('Gebruiker verwijderd: ' + target.username));
+  // Clean up dangling references
+  db.prepare('DELETE FROM site_members WHERE user_id = ?').run(userId);
+  db.prepare('DELETE FROM comments WHERE author_id = ?').run(userId);
+  db.prepare('DELETE FROM users WHERE id = ?').run(userId);
+
+  res.redirect('/admin/users?success=' + encodeURIComponent('User deleted: ' + target.username));
 });
 
