Index: src/routes/admin-users.js
===================================================================
--- src/routes/admin-users.js	(revision 05a6ca0062c5c8b2a5307b16fba39e6b5a745dd1)
+++ src/routes/admin-users.js	(revision 0c2228a9c4489c1c67d7c50a257243dee4569320)
@@ -98,22 +98,33 @@
   }
 
-  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);
+  // Cascade-verwijderen: de sites van deze user (+ posts/playlists/audio/leden/
+  // comments daaronder), z'n eigen content elders, en daarna de user zelf.
+  // Atomisch in een transactie — faalt er een FK, dan rolt alles terug.
+  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);
+    }
+    // Eigen content op andere sites + losse koppelingen.
+    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);
+  });
 
-  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.`
-    ));
+  try {
+    del();
+  } catch (e) {
+    console.error('[admin/users delete]', e.message);
+    return res.redirect('/admin/users?error=' + encodeURIComponent('Verwijderen mislukt (mogelijk gekoppelde data).'));
   }
 
-  // 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));
+  res.redirect('/admin/users?success=' + encodeURIComponent('Gebruiker verwijderd: ' + target.username));
 });
 
Index: src/views/pages/admin-users.ejs
===================================================================
--- src/views/pages/admin-users.ejs	(revision 05a6ca0062c5c8b2a5307b16fba39e6b5a745dd1)
+++ src/views/pages/admin-users.ejs	(revision 0c2228a9c4489c1c67d7c50a257243dee4569320)
@@ -74,7 +74,10 @@
             </form>
 
-            <% if (u.id !== user.id && (u.post_count + u.site_count === 0)) { %>
+            <% if (u.id !== user.id) { %>
+              <% var _warn = (u.post_count + u.site_count > 0)
+                   ? ('Dit verwijdert ook hun site + ' + u.post_count + ' post(s). ')
+                   : ''; %>
               <form method="post" action="/admin/users/<%= u.id %>/delete" class="ax-delete-form"
-                    onsubmit="return confirm('Verwijder gebruiker <%= u.username %>?')">
+                    onsubmit="return confirm('Gebruiker <%= u.username %> verwijderen? <%= _warn %>Dit kan niet ongedaan worden.')">
                 <button type="submit" class="ax-icon-btn ax-icon-btn-danger" aria-label="Verwijderen" title="Verwijderen">🗑</button>
               </form>
Index: src/views/partials/topnav.ejs
===================================================================
--- src/views/partials/topnav.ejs	(revision 05a6ca0062c5c8b2a5307b16fba39e6b5a745dd1)
+++ src/views/partials/topnav.ejs	(revision 0c2228a9c4489c1c67d7c50a257243dee4569320)
@@ -28,6 +28,7 @@
       <% } else if (typeof tenancy !== 'undefined' && tenancy === 'hub') { %>
         <%# Hub: de brand is de hub-naam en gaat naar de hub-home (volledige nav, geen
-            HTMX, zodat de headerloze overview correct rendert). %>
-        <a class="site-title" href="/" aria-label="Naar de hub-home"><%= (typeof hubTitle !== 'undefined' && hubTitle) ? hubTitle : 'Home' %></a>
+            HTMX, zodat de headerloze overview correct rendert). Eigen class want
+            .site-title is overal display:none. %>
+        <a class="nav-hub-home" href="/" aria-label="Naar de hub-home"><%= (typeof hubTitle !== 'undefined' && hubTitle) ? hubTitle : 'Home' %></a>
       <% } else if (site) { %>
         <a class="site-title" href="<%= _siteUrlBase %>/"
@@ -232,4 +233,13 @@
 }
 
+/* Hub-home brand is WÉL zichtbaar — de thuisknop op artiest-/hub-pagina's. */
+.masthead-brand .nav-hub-home {
+  display: inline-block; vertical-align: middle;
+  color: var(--ink); text-decoration: none;
+  font-family: var(--font-display, serif); font-weight: 700; font-size: 1.05rem;
+  transition: color 120ms;
+}
+.masthead-brand .nav-hub-home:hover { color: var(--accent); }
+
 /* On mobile, hide the entire masthead except for admin pages. The brand
    appears in the profile-header on content pages, and the bottom-tab
