Index: src/views/pages/home.ejs
===================================================================
--- src/views/pages/home.ejs	(revision 7963a6e9c576b291e837823c55309d6bb470d2d9)
+++ src/views/pages/home.ejs	(revision b94c08ee93afe04552667726a69e8b5eb5629d16)
@@ -11,4 +11,5 @@
 
 const allPosts = [...pinnedPosts, ...posts];
+const _base = (typeof siteUrlBase !== 'undefined' && siteUrlBase) ? siteUrlBase : '';
 %>
 
@@ -26,7 +27,7 @@
       <% if (user && permissions.canCreatePost(user, site)) { %>
         <p style="margin-top:2rem">
-          <a class="btn" href="/posts/new"
-             hx-get="/posts/new?partial=1" hx-target="#pcms-main" hx-swap="innerHTML"
-             hx-push-url="/posts/new" hx-indicator="#pcms-loading">
+          <a class="btn" href="<%= _base %>/posts/new"
+             hx-get="<%= _base %>/posts/new?partial=1" hx-target="#pcms-main" hx-swap="innerHTML"
+             hx-push-url="<%= _base %>/posts/new" hx-indicator="#pcms-loading">
             Schrijf je eerste post →
           </a>
Index: src/views/pages/post.ejs
===================================================================
--- src/views/pages/post.ejs	(revision 7963a6e9c576b291e837823c55309d6bb470d2d9)
+++ src/views/pages/post.ejs	(revision b94c08ee93afe04552667726a69e8b5eb5629d16)
@@ -1,2 +1,8 @@
+<%
+// In hub-mode is de site bereikbaar onder /user/<slug>; alle site-scoped links
+// (tag, edit, delete, comments) moeten met die prefix anders vallen ze terug op
+// de primaire site → 404 / verkeerde site. In solo is _base = ''.
+const _base = (typeof siteUrlBase !== 'undefined' && siteUrlBase) ? siteUrlBase : '';
+%>
 <article class="container post-page">
   <% if (post.cover_image_url) { %>
@@ -30,8 +36,8 @@
     <div class="post-tags">
       <% post.tags.forEach(t => { %>
-        <a class="tag" href="/tag/<%= encodeURIComponent(t) %>"
-           hx-get="/tag/<%= encodeURIComponent(t) %>?partial=1"
+        <a class="tag" href="<%= _base %>/tag/<%= encodeURIComponent(t) %>"
+           hx-get="<%= _base %>/tag/<%= encodeURIComponent(t) %>?partial=1"
            hx-target="#pcms-main" hx-swap="innerHTML"
-           hx-push-url="/tag/<%= encodeURIComponent(t) %>"
+           hx-push-url="<%= _base %>/tag/<%= encodeURIComponent(t) %>"
            hx-indicator="#pcms-loading">#<%= t %></a>
       <% }); %>
@@ -43,12 +49,12 @@
     <aside class="post-actions">
       <% if (permissions.canEditPost(user, post, site)) { %>
-        <a href="/posts/<%= post.slug %>/edit" class="btn"
-           hx-get="/posts/<%= post.slug %>/edit?partial=1" hx-target="#pcms-main"
-           hx-push-url="/posts/<%= post.slug %>/edit" hx-indicator="#pcms-loading">
+        <a href="<%= _base %>/posts/<%= post.slug %>/edit" class="btn"
+           hx-get="<%= _base %>/posts/<%= post.slug %>/edit?partial=1" hx-target="#pcms-main"
+           hx-push-url="<%= _base %>/posts/<%= post.slug %>/edit" hx-indicator="#pcms-loading">
           ✏️ Edit
         </a>
       <% } %>
       <% if (permissions.canDeletePost(user, post, site)) { %>
-        <form method="post" action="/posts/<%= post.slug %>/delete" style="display:inline" onsubmit="return confirm('Delete this post?')">
+        <form method="post" action="<%= _base %>/posts/<%= post.slug %>/delete" style="display:inline" onsubmit="return confirm('Delete this post?')">
           <button type="submit" class="btn btn-danger">🗑 Delete</button>
         </form>
@@ -78,5 +84,5 @@
 
     <% if (!comments || !comments.length) { %>
-      <p class="comments-empty">No comments yet.<% if (!user) { %> <a href="/auth/login?next=<%= encodeURIComponent('/' + post.slug + '#comments') %>">Log in</a> to start the conversation.<% } %></p>
+      <p class="comments-empty">No comments yet.<% if (!user) { %> <a href="/auth/login?next=<%= encodeURIComponent(_base + '/' + post.slug + '#comments') %>">Log in</a> to start the conversation.<% } %></p>
     <% } else { %>
       <ol class="comments-list">
@@ -101,5 +107,5 @@
                 <% } %>
                 <% if (user && permissions.canDeleteComment(user, c, site)) { %>
-                  <form method="post" action="/comments/<%= c.id %>/delete" style="display:inline" onsubmit="return confirm('Delete this comment?')">
+                  <form method="post" action="<%= _base %>/comments/<%= c.id %>/delete" style="display:inline" onsubmit="return confirm('Delete this comment?')">
                     <button type="submit" class="comment-delete-btn">Delete</button>
                   </form>
@@ -109,5 +115,5 @@
               <!-- Inline reply form (hidden by default) -->
               <% if (user) { %>
-                <form method="post" action="/comments" class="comment-reply-form" hidden data-reply-form-for="<%= c.id %>">
+                <form method="post" action="<%= _base %>/comments" class="comment-reply-form" hidden data-reply-form-for="<%= c.id %>">
                   <input type="hidden" name="post_slug" value="<%= post.slug %>">
                   <input type="hidden" name="parent_comment_id" value="<%= c.id %>">
@@ -140,5 +146,5 @@
                         <div class="comment-actions">
                           <% if (user && permissions.canDeleteComment(user, r, site)) { %>
-                            <form method="post" action="/comments/<%= r.id %>/delete" style="display:inline" onsubmit="return confirm('Delete this comment?')">
+                            <form method="post" action="<%= _base %>/comments/<%= r.id %>/delete" style="display:inline" onsubmit="return confirm('Delete this comment?')">
                               <button type="submit" class="comment-delete-btn">Delete</button>
                             </form>
@@ -158,5 +164,5 @@
     <!-- Top-level comment form (only for logged-in users for now) -->
     <% if (user) { %>
-      <form method="post" action="/comments" class="comment-form">
+      <form method="post" action="<%= _base %>/comments" class="comment-form">
         <input type="hidden" name="post_slug" value="<%= post.slug %>">
         <label class="comment-form-label">
@@ -168,5 +174,5 @@
     <% } else { %>
       <p class="comments-login-cta">
-        <a href="/auth/login?next=<%= encodeURIComponent('/' + post.slug + '#comments') %>" class="btn">Log in to comment</a>
+        <a href="/auth/login?next=<%= encodeURIComponent(_base + '/' + post.slug + '#comments') %>" class="btn">Log in to comment</a>
       </p>
     <% } %>
Index: src/views/pages/search.ejs
===================================================================
--- src/views/pages/search.ejs	(revision 7963a6e9c576b291e837823c55309d6bb470d2d9)
+++ src/views/pages/search.ejs	(revision b94c08ee93afe04552667726a69e8b5eb5629d16)
@@ -1,6 +1,7 @@
+<% const _base = (typeof siteUrlBase !== 'undefined' && siteUrlBase) ? siteUrlBase : ''; %>
 <div class="container search-page">
   <h1>Search</h1>
 
-  <form method="get" action="/search" class="search-page-form">
+  <form method="get" action="<%= _base %>/search" class="search-page-form">
     <input
       type="search"
Index: src/views/partials/bottom-tab.ejs
===================================================================
--- src/views/partials/bottom-tab.ejs	(revision 7963a6e9c576b291e837823c55309d6bb470d2d9)
+++ src/views/partials/bottom-tab.ejs	(revision b94c08ee93afe04552667726a69e8b5eb5629d16)
@@ -59,7 +59,7 @@
   <% if (_canPost) { %>
     <a class="bottom-tab-item bottom-tab-fab<%= _active === 'create' ? ' is-active' : '' %>"
-       href="/posts/new"
-       hx-get="/posts/new?partial=1" hx-target="#pcms-main" hx-swap="innerHTML"
-       hx-push-url="/posts/new" hx-indicator="#pcms-loading"
+       href="<%= _siteUrlBase %>/posts/new"
+       hx-get="<%= _siteUrlBase %>/posts/new?partial=1" hx-target="#pcms-main" hx-swap="innerHTML"
+       hx-push-url="<%= _siteUrlBase %>/posts/new" hx-indicator="#pcms-loading"
        aria-label="Nieuwe post">
       <svg class="bottom-tab-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.25" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
Index: src/views/partials/profile-sheet.ejs
===================================================================
--- src/views/partials/profile-sheet.ejs	(revision 7963a6e9c576b291e837823c55309d6bb470d2d9)
+++ src/views/partials/profile-sheet.ejs	(revision b94c08ee93afe04552667726a69e8b5eb5629d16)
@@ -21,4 +21,6 @@
                  : (user.role === 'editor') ? 'redacteur'
                  : '';
+// Site-scoped link (post-aanmaken) heeft in hub de /user/<slug>-prefix nodig.
+const _base = (typeof siteUrlBase !== 'undefined' && siteUrlBase) ? siteUrlBase : '';
 %>
 
@@ -64,7 +66,7 @@
       <% if (_canPost) { %>
       <li role="none">
-        <a href="/posts/new" class="profile-sheet-item" role="menuitem" data-close-sheet
-           hx-get="/posts/new?partial=1" hx-target="#pcms-main" hx-swap="innerHTML"
-           hx-push-url="/posts/new" hx-indicator="#pcms-loading">
+        <a href="<%= _base %>/posts/new" class="profile-sheet-item" role="menuitem" data-close-sheet
+           hx-get="<%= _base %>/posts/new?partial=1" hx-target="#pcms-main" hx-swap="innerHTML"
+           hx-push-url="<%= _base %>/posts/new" hx-indicator="#pcms-loading">
           <svg class="psi-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"/></svg>
           <span class="psi-label">Nieuwe post</span>
