Index: src/assets/css/style.css
===================================================================
--- src/assets/css/style.css	(revision 108fd5f46564e7ff64ccbbe2464e388d7aef4325)
+++ src/assets/css/style.css	(revision 3cd1aaa2ceb0be58bb1991721a4e9ecec58ce19e)
@@ -2028,10 +2028,4 @@
     margin-bottom: 1.5rem;
 }
-/* Hub-landing (body.on-hub): verberg de site-chrome. In hub-modus staan masthead
-   + view-switcher altijd in de DOM (zodat htmx tussen hub-home en artiest-sites
-   kan schakelen zonder full-reload); hier toggelen we hun zichtbaarheid. De
-   hub-home heeft z'n eigen kop/nav in de content. */
-body.on-hub .masthead,
-body.on-hub .view-switcher-wrap { display: none !important; }
 .view-switcher {
     display: flex;
Index: src/middleware/render.js
===================================================================
--- src/middleware/render.js	(revision 108fd5f46564e7ff64ccbbe2464e388d7aef4325)
+++ src/middleware/render.js	(revision 3cd1aaa2ceb0be58bb1991721a4e9ecec58ce19e)
@@ -122,5 +122,18 @@
       }).replace(/[-￿]/g, (ch) => '\\u' + ch.charCodeAt(0).toString(16).padStart(4, '0'));
       res.setHeader('HX-Trigger-After-Settle', triggerJson);
-      return res.send(pageContent);
+      // Site-chrome out-of-band mee-renderen, zodat de kop (topnav/profielkop/
+      // view-switcher) bij navigatie ALTIJD bij de nieuwe pagina/artiest hoort —
+      // terwijl de audioplayer (los in document.body) blijft leven (geen
+      // verspringen). htmx vervangt #pcms-chrome via hx-swap-oob. Niet kritisch:
+      // faalt 't, dan blijft de oude chrome staan (geen crash).
+      let oobChrome = '';
+      try {
+        oobChrome = await ejs.renderFile(
+          path.join(VIEWS_DIR, 'partials', 'chrome.ejs'),
+          { ...locals, oob: true },
+          { async: false },
+        );
+      } catch (e) { /* chrome-OOB overslaan */ }
+      return res.send(pageContent + oobChrome);
     }
 
Index: src/views/partials/chrome.ejs
===================================================================
--- src/views/partials/chrome.ejs	(revision 3cd1aaa2ceb0be58bb1991721a4e9ecec58ce19e)
+++ src/views/partials/chrome.ejs	(revision 3cd1aaa2ceb0be58bb1991721a4e9ecec58ce19e)
@@ -0,0 +1,21 @@
+<%
+// Site-chrome (topnav + profielkop + view-switcher) in één vaste slot #pcms-chrome.
+//
+// Waarom een slot: bij htmx-navigatie verversen we deze hele chrome out-of-band
+// (oob=true), zodat de kop ALTIJD bij de nieuwe pagina/artiest hoort — terwijl de
+// audioplayer (los in document.body, buiten dit slot) blijft leven → geen
+// verspringen. Op de hub-landing (bareChrome) is het slot leeg: hero = de header.
+//
+// Wordt zowel door shell.ejs (oob niet gezet) als door render.js bij partials
+// (oob=true) gerenderd. bareChrome-logica staat hier zodat beide identiek zijn.
+var _isAdmin = typeof bodyClass === 'string' && bodyClass.indexOf('on-admin') >= 0;
+var bareChrome = (typeof bodyClass === 'string' && (bodyClass.indexOf('on-hub') >= 0 || bodyClass.indexOf('on-auth') >= 0))
+   || ((typeof tenancy !== 'undefined' && tenancy === 'hub') && !siteUrlBase && !_isAdmin);
+%>
+<div id="pcms-chrome"<% if (typeof oob !== 'undefined' && oob) { %> hx-swap-oob="true"<% } %>>
+<% if (!bareChrome) { %>
+  <%- include('topnav') %>
+  <%- include('profile-header') %>
+  <% if (!_isAdmin) { %><%- include('view-switcher') %><% } %>
+<% } %>
+</div>
Index: src/views/shell.ejs
===================================================================
--- src/views/shell.ejs	(revision 108fd5f46564e7ff64ccbbe2464e388d7aef4325)
+++ src/views/shell.ejs	(revision 3cd1aaa2ceb0be58bb1991721a4e9ecec58ce19e)
@@ -263,30 +263,10 @@
 <% } %>
 
-<%# Geen shell-chrome (masthead/profile-header/view-switcher/bottom-tab) op:
-    - de hub-overview (on-hub): standalone landing, begint met de hero;
-    - auth-pagina's (on-auth): focus-schermen voor in-/uitloggen.
-    Die chrome hoort bij een Klonkt-site en verschijnt dus op /user/-pagina's. %>
-<% var _isHub  = (typeof tenancy !== 'undefined' && tenancy === 'hub'); %>
-<% var _onAuth = (typeof bodyClass === 'string' && bodyClass.indexOf('on-auth') >= 0); %>
-<% var bareChrome = (typeof bodyClass === 'string' && (bodyClass.indexOf('on-hub') >= 0 || bodyClass.indexOf('on-auth') >= 0))
-     || (_isHub && !siteUrlBase && !isAdminPage); %>
-<%# In HUB-modus de chrome ALTIJD renderen (CSS verbergt 'm op de hub-landing via
-    body.on-hub) zodat htmx tussen hub-home en artiest-sites kan schakelen zónder
-    full-reload → de audioplayer blijft leven, geen verspringen. profile-header
-    self-hidet als er geen site is. Solo/circle: ongewijzigd (!bareChrome). %>
-<% var renderChrome = _isHub ? !_onAuth : !bareChrome; %>
-
-<% if (renderChrome) { %>
-  <%- include('partials/topnav') %>
-  <%- include('partials/profile-header') %>
-<% } %>
-
-<%# View switcher — visible on every non-admin page. On feed pages
-    (home, archive, tag, type, user) it toggles the visual layout;
-    on non-feed pages (post, account, search, auth) it navigates to /
-    in the chosen view. Click logic is in shell.ejs at the bottom. %>
-<% if (!isAdminPage && renderChrome) { %>
-  <%- include('partials/view-switcher') %>
-<% } %>
+<%# Site-chrome (topnav + profielkop + view-switcher) in één vaste slot #pcms-chrome.
+    Bij htmx-navigatie wordt dit slot out-of-band ververst (zie chrome.ejs +
+    render.js), zodat de kop ALTIJD bij de nieuwe pagina/artiest hoort terwijl de
+    audioplayer (los in document.body) blijft leven → geen verspringen. Op de
+    hub-landing is het slot leeg: de hero is daar de header. %>
+<%- include('partials/chrome') %>
 
 <%# hx-history-elt scopes HTMX history snapshots to #pcms-main only, so
@@ -360,8 +340,4 @@
     PAGE_CLASSES.forEach(function(c) { document.body.classList.remove(c); });
     document.body.classList.add(firstClass);
-    // 'on-hub' is een modifier náást de page-class: apart toggelen zodat de
-    // hub-chrome (topnav/view-switcher) via CSS mee-schakelt bij htmx-navigatie
-    // tussen hub-home (on-hub) en artiest-sites (geen on-hub).
-    document.body.classList.toggle('on-hub', /(^|\s)on-hub(\s|$)/.test(String(next)));
   });
 })();
