Index: src/views/pages/post.ejs
===================================================================
--- src/views/pages/post.ejs	(revision 2165b6d3d57ceaa8b5d1f70491868482149470cf)
+++ src/views/pages/post.ejs	(revision 7bc636b391c66ac399c33e54f7173a022c6a3cbd)
@@ -1,28 +1,6 @@
-<%
-// In hub mode the site is accessible under /user/<slug>; all site-scoped links
-// (tag, edit, delete, comments) must carry that prefix otherwise they fall back
-// to the primary site → 404 / wrong site. In solo mode _base = ''.
-const _base = (typeof siteUrlBase !== 'undefined' && siteUrlBase) ? siteUrlBase : '';
-%>
-<article class="container post-page<%= post.nsfw ? ' nsfw-gate' : '' %>">
-
-  <%# Navigation across ALL posts — ABOVE the post (shared partial). %>
-  <%- include('../partials/post-nav', { newerPost: newerPost, olderPost: olderPost }) %>
-
-  <% if (post.nsfw) { %>
-    <div class="nsfw-banner">
-      <span class="nsfw-banner-icon">🔞</span>
-      <span class="nsfw-banner-text"><%= post.content_warning || t('post.nsfw_warning') %></span>
-      <button type="button" class="nsfw-banner-btn nsfw-reveal"><%= t('post.nsfw_show') %></button>
-    </div>
-  <% } %>
-
+<article class="container post-page">
   <% if (post.cover_image_url) { %>
     <figure class="post-cover">
-      <img src="<%= post.cover_image_url %>" alt="<%= post.cover_alt || '' %>"<% if (post.cover_video_url) { %> data-ios-mp4="<%= post.cover_video_url %>"<% } %>>
-    </figure>
-  <% } else if (post.cover_video_url) { %>
-    <figure class="post-cover">
-      <video src="<%= post.cover_video_url %>" poster="<%= thumb(post.cover_video_url, 1280) %>" controls loop muted playsinline preload="metadata"></video>
+      <img src="<%= post.cover_image_url %>" alt="">
     </figure>
   <% } %>
@@ -49,34 +27,11 @@
   </div>
 
-  <% if (typeof poll !== 'undefined' && poll) { %>
-    <section class="poll" aria-label="<%= t('poll.aria') %>">
-      <% poll.options.forEach(function(o){ var _lead = poll.total > 0 && o.count === Math.max.apply(null, poll.options.map(function(x){return x.count;})); %>
-        <div class="poll-opt<%= _lead ? ' is-lead' : '' %>">
-          <div class="poll-bar" style="width:<%= o.pct %>%"></div>
-          <span class="poll-name"><%= o.name %></span>
-          <span class="poll-pct"><%= o.pct %>%</span>
-        </div>
-      <% }); %>
-      <div class="poll-meta">
-        <span><%= poll.voters %> <%= poll.voters === 1 ? t('poll.voter_one') : t('poll.voter_many') %></span>
-        <span aria-hidden="true">·</span>
-        <% if (poll.closed) { %>
-          <span><%= t('poll.closed') %></span>
-        <% } else if (poll.endTime) { %>
-          <span><%= t('poll.closes') %> <%= new Date(poll.endTime).toLocaleString() %></span>
-        <% } %>
-        <% if (poll.multiple) { %><span aria-hidden="true">·</span><span><%= t('poll.multiple') %></span><% } %>
-      </div>
-      <p class="poll-note"><%= t('poll.fedi_only') %></p>
-    </section>
-  <% } %>
-
   <% if (post.tags && post.tags.length > 0) { %>
     <div class="post-tags">
       <% post.tags.forEach(t => { %>
-        <a class="tag" href="<%= _base %>/tag/<%= encodeURIComponent(t) %>"
-           hx-get="<%= _base %>/tag/<%= encodeURIComponent(t) %>?partial=1"
+        <a class="tag" href="/tag/<%= encodeURIComponent(t) %>"
+           hx-get="/tag/<%= encodeURIComponent(t) %>?partial=1"
            hx-target="#pcms-main" hx-swap="innerHTML"
-           hx-push-url="<%= _base %>/tag/<%= encodeURIComponent(t) %>"
+           hx-push-url="/tag/<%= encodeURIComponent(t) %>"
            hx-indicator="#pcms-loading">#<%= t %></a>
       <% }); %>
@@ -84,31 +39,16 @@
   <% } %>
 
-  <div class="post-share" style="margin:1.25rem 0;display:flex;align-items:center;gap:.6rem;flex-wrap:wrap">
-    <button type="button" class="btn post-share-btn" data-share data-share-title="<%= post.title %>">🔗 <%= t('post.share') %></button>
-    <%# Interact via the fediverse — for VISITORS (reply/like/boost from their own
-        server). Same flow as the CTA in the fediverse section; hidden for the
-        owner/admin (their own post) and when AP is off. %>
-    <% if (post.status === 'published' && (typeof apEnabled === 'undefined' || apEnabled) && (typeof canManageSite === 'undefined' || !canManageSite)) { %>
-      <% var _shareAbsUrl = (typeof ogOrigin !== 'undefined' && ogOrigin ? ogOrigin : '') + (typeof _base !== 'undefined' && _base ? _base : '') + '/' + post.slug; %>
-      <button type="button" class="btn fedi-remote-reply-btn" data-fedi-uri="<%= _shareAbsUrl %>" data-fedi-ph="<%= t('fedi.remote_ph') %>">
-        <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="17 1 21 5 17 9"/><path d="M3 11V9a4 4 0 0 1 4-4h14"/><polyline points="7 23 3 19 7 15"/><path d="M21 13v2a4 4 0 0 1-4 4H3"/></svg>
-        <%= t('fedi.remote_interact') %>
-      </button>
-    <% } %>
-    <span class="post-share-feedback" id="post-share-feedback" style="color:var(--accent);font-size:.85rem" hidden><%= t('post.share_copied') %></span>
-  </div>
-
   <!-- Inline admin actions: only visible if user has permission -->
   <% if (user && (permissions.canEditPost(user, post, site) || permissions.canDeletePost(user, post, site))) { %>
     <aside class="post-actions">
       <% if (permissions.canEditPost(user, post, site)) { %>
-        <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">
+        <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">
           ✏️ Edit
         </a>
       <% } %>
       <% if (permissions.canDeletePost(user, post, site)) { %>
-        <form method="post" action="<%= _base %>/posts/<%= post.slug %>/delete" style="display:inline" data-confirm="Delete this post?">
+        <form method="post" action="/posts/<%= post.slug %>/delete" style="display:inline" onsubmit="return confirm('Delete this post?')">
           <button type="submit" class="btn btn-danger">🗑 Delete</button>
         </form>
@@ -117,38 +57,140 @@
   <% } %>
 
-  <!-- Fediverse interactions — single place: ⭐ like (clickable) + 🔁/💬 counts + reply -->
-  <% var _fedi = (typeof fediverse !== 'undefined' && fediverse) ? fediverse : { thread: [], likeCount: 0, announceCount: 0 }; %>
-  <% if (post.status === 'published' && (typeof apEnabled === 'undefined' || apEnabled)) { %>
-    <section class="post-fediverse post-comments" id="fediverse">
-      <h2 class="comments-heading"><%= t('fedi.heading') %></h2>
-      <div class="fedi-stats">
-        <span class="fedi-stat" title="<%= t('fedi.likes') %>">
-          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
-          <span><%= _fedi.likeCount %></span>
-        </span>
-        <span class="fedi-stat" title="<%= t('fedi.boosts') %>">
-          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="17 1 21 5 17 9"/><path d="M3 11V9a4 4 0 0 1 4-4h14"/><polyline points="7 23 3 19 7 15"/><path d="M21 13v2a4 4 0 0 1-4 4H3"/></svg>
-          <span><%= _fedi.announceCount %></span>
-        </span>
-        <span class="fedi-stat" title="<%= t('fedi.replies') %>">
-          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
-          <span><%= (_fedi.thread || []).length %></span>
-        </span>
-      </div>
-      <% if (_fedi.thread && _fedi.thread.length) { %>
-        <ol class="comments-list">
-          <% _fedi.thread.forEach(function(n){ %>
-            <li class="comment"><%- include('../partials/fedi-node', { n: n, t: t, canManageSite: (typeof canManageSite !== 'undefined' ? canManageSite : false), _base: _base, siteAvatar: (typeof siteAvatar !== 'undefined' ? siteAvatar : null), formatDateTime: formatDateTime, postSlug: post.slug }) %></li>
-          <% }); %>
-        </ol>
-      <% } %>
-      <%# The "Interact via the fediverse" button for visitors now lives next to
-          the Share button at the top of the post (single, prominent place). %>
-    </section>
-  <% } %>
-  <%# Het remote-reply-veld zit in assets/js/mod/post.js. Inline script hier wordt
-    door de CSP geweigerd zodra je deze pagina via een link binnen de site opent
-    -- zie shaer-0i6. %>
-
+  <!-- Comments -->
+  <section class="post-comments" id="comments">
+    <h2 class="comments-heading">
+      <%= totalComments %> comment<%= totalComments === 1 ? '' : 's' %>
+    </h2>
+
+    <% if (typeof currentPath === 'string' && currentPath && currentPath.indexOf('/' + post.slug) === 0) { %>
+      <% /* If the URL has ?pending=1, the previous submit landed in the queue */ %>
+    <% } %>
+    <script>
+      (function() {
+        if (location.search.indexOf('pending=1') !== -1) {
+          var s = document.createElement('div');
+          s.className = 'comments-pending-flash';
+          s.textContent = 'Your comment is awaiting moderation. It will appear once an admin approves it.';
+          document.currentScript.parentNode.insertBefore(s, document.currentScript);
+        }
+      })();
+    </script>
+
+    <% 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>
+    <% } else { %>
+      <ol class="comments-list">
+        <% comments.forEach(function(c) { %>
+          <li class="comment" id="comment-<%= c.id %>">
+            <div class="comment-avatar">
+              <% if (c.author_avatar) { %>
+                <img src="<%= c.author_avatar %>" alt="">
+              <% } else { %>
+                <span><%= c.author_username.charAt(0).toUpperCase() %></span>
+              <% } %>
+            </div>
+            <div class="comment-body">
+              <div class="comment-meta">
+                <a class="comment-author" href="/users/<%= encodeURIComponent(c.author_username) %>"><%= c.author_username %></a>
+                <span class="comment-time" title="<%= c.created_at %>"><%= formatDateTime(c.created_at) %></span>
+              </div>
+              <div class="comment-content"><%= c.content %></div>
+              <div class="comment-actions">
+                <% if (user) { %>
+                  <button type="button" class="comment-reply-btn" data-reply-to="<%= c.id %>">Reply</button>
+                <% } %>
+                <% if (user && permissions.canDeleteComment(user, c, site)) { %>
+                  <form method="post" action="/comments/<%= c.id %>/delete" style="display:inline" onsubmit="return confirm('Delete this comment?')">
+                    <button type="submit" class="comment-delete-btn">Delete</button>
+                  </form>
+                <% } %>
+              </div>
+
+              <!-- Inline reply form (hidden by default) -->
+              <% if (user) { %>
+                <form method="post" action="/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 %>">
+                  <textarea name="content" rows="3" maxlength="4000" placeholder="Reply to <%= c.author_username %>…" required></textarea>
+                  <div class="comment-reply-form-actions">
+                    <button type="submit" class="btn btn-primary">Reply</button>
+                    <button type="button" class="btn comment-cancel-reply">Cancel</button>
+                  </div>
+                </form>
+              <% } %>
+
+              <!-- Replies (1 level deep) -->
+              <% if (c.replies && c.replies.length) { %>
+                <ol class="comment-replies">
+                  <% c.replies.forEach(function(r) { %>
+                    <li class="comment comment-reply" id="comment-<%= r.id %>">
+                      <div class="comment-avatar">
+                        <% if (r.author_avatar) { %>
+                          <img src="<%= r.author_avatar %>" alt="">
+                        <% } else { %>
+                          <span><%= r.author_username.charAt(0).toUpperCase() %></span>
+                        <% } %>
+                      </div>
+                      <div class="comment-body">
+                        <div class="comment-meta">
+                          <a class="comment-author" href="/users/<%= encodeURIComponent(r.author_username) %>"><%= r.author_username %></a>
+                          <span class="comment-time"><%= formatDateTime(r.created_at) %></span>
+                        </div>
+                        <div class="comment-content"><%= r.content %></div>
+                        <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?')">
+                              <button type="submit" class="comment-delete-btn">Delete</button>
+                            </form>
+                          <% } %>
+                        </div>
+                      </div>
+                    </li>
+                  <% }); %>
+                </ol>
+              <% } %>
+            </div>
+          </li>
+        <% }); %>
+      </ol>
+    <% } %>
+
+    <!-- Top-level comment form (only for logged-in users for now) -->
+    <% if (user) { %>
+      <form method="post" action="/comments" class="comment-form">
+        <input type="hidden" name="post_slug" value="<%= post.slug %>">
+        <label class="comment-form-label">
+          <span>Add a comment as <strong><%= user.username %></strong></span>
+          <textarea name="content" rows="3" maxlength="4000" placeholder="Share your thoughts…" required></textarea>
+        </label>
+        <button type="submit" class="btn btn-primary">Post comment</button>
+      </form>
+    <% } else { %>
+      <p class="comments-login-cta">
+        <a href="/auth/login?next=<%= encodeURIComponent('/' + post.slug + '#comments') %>" class="btn">Log in to comment</a>
+      </p>
+    <% } %>
+  </section>
+
+  <!-- Reply form toggle -->
+  <script>
+  (function() {
+    document.querySelectorAll('.comment-reply-btn').forEach(function(btn) {
+      btn.addEventListener('click', function() {
+        var id = btn.dataset.replyTo;
+        var form = document.querySelector('[data-reply-form-for="' + id + '"]');
+        if (form) {
+          form.hidden = !form.hidden;
+          if (!form.hidden) form.querySelector('textarea').focus();
+        }
+      });
+    });
+    document.querySelectorAll('.comment-cancel-reply').forEach(function(btn) {
+      btn.addEventListener('click', function() {
+        btn.closest('.comment-reply-form').hidden = true;
+      });
+    });
+  })();
+  </script>
 
   <%# ── Related posts (3-card grid) ─────────────────────────────
@@ -158,15 +200,17 @@
   <% if (relatedPosts && relatedPosts.length > 0) { %>
     <section class="post-related" aria-labelledby="related-heading">
-      <h2 class="post-related-heading" id="related-heading"><%= t('related.title') %></h2>
+      <h2 class="post-related-heading" id="related-heading">Gerelateerde posts</h2>
       <ul class="post-related-grid">
         <% relatedPosts.forEach(function(rp) { %>
           <li class="post-related-card">
-            <a href="<%= rp._urlBase || '' %>/<%= rp.slug %>"<% if (!rp._urlBase) { %>
+            <a href="/<%= rp.slug %>"
                hx-get="/<%= rp.slug %>?partial=1" hx-target="#pcms-main"
-               hx-push-url="/<%= rp.slug %>" hx-indicator="#pcms-loading"<% } %>>
+               hx-push-url="/<%= rp.slug %>" hx-indicator="#pcms-loading">
               <% if (rp.cover_image_url) { %>
-                <span class="post-related-cover<%= rp.nsfw ? ' nsfw-media' : '' %>" aria-hidden="true"><img class="post-related-img" src="<%= rp.cover_image_url %>" alt="" loading="lazy" decoding="async"<% if (rp.cover_video_url) { %> data-ios-mp4="<%= rp.cover_video_url %>"<% } %>><% if (rp.nsfw) { %><span class="nsfw-veil"><%- include('../partials/nsfw-veil', { cw: rp.content_warning }) %></span><% } %></span>
+                <span class="post-related-cover"
+                      style="background-image: url('<%= rp.cover_image_url %>')"
+                      aria-hidden="true"></span>
               <% } else { %>
-                <span class="post-related-cover post-related-cover--empty<%= rp.nsfw ? ' nsfw-media' : '' %>" aria-hidden="true"><% if (rp.nsfw) { %><span class="nsfw-veil"><%- include('../partials/nsfw-veil', { cw: rp.content_warning }) %></span><% } %></span>
+                <span class="post-related-cover post-related-cover--empty" aria-hidden="true"></span>
               <% } %>
               <span class="post-related-meta">
@@ -181,9 +225,80 @@
   <% } %>
 
+  <%# ── Pinned navigation (only when current post is pinned) ───
+      Two card-style links: "Vorige vastgepinde" / "Volgende vastgepinde".
+      Edge-of-stack states show "← BOVENAAN — Nieuwste post" or the equivalent
+      for the bottom. Layout mirrors v9 exactly. %>
+  <% if (post.pinned) { %>
+    <nav class="post-pinned-nav" aria-label="Pinned navigation">
+      <%# LEFT card: post one step UP the pinned stack (towards #1).
+          Uses prevPinnedPost which now means "smaller rank". %>
+      <% if (prevPinnedPost) { %>
+        <a class="post-pinned-card post-pinned-card--prev" href="/<%= prevPinnedPost.slug %>"
+           hx-get="/<%= prevPinnedPost.slug %>?partial=1" hx-target="#pcms-main"
+           hx-push-url="/<%= prevPinnedPost.slug %>" hx-indicator="#pcms-loading">
+          <span class="post-pinned-arrow" aria-hidden="true">←</span>
+          <span class="post-pinned-body">
+            <span class="post-pinned-label">📌 Vorige vastgepinde</span>
+            <span class="post-pinned-title"><%= prevPinnedPost.title %></span>
+            <span class="post-pinned-cta">Lees deze post →</span>
+          </span>
+        </a>
+      <% } else if (pinnedTopOfStack) { %>
+        <span class="post-pinned-card post-pinned-card--edge">
+          <span class="post-pinned-edge-label">— BOVENAAN —</span>
+          <span class="post-pinned-edge-title">Nieuwste post</span>
+        </span>
+      <% } %>
+
+      <%# RIGHT card: post one step DOWN the pinned stack (away from #1).
+          Uses nextPinnedPost which now means "larger rank". %>
+      <% if (nextPinnedPost) { %>
+        <a class="post-pinned-card post-pinned-card--next" href="/<%= nextPinnedPost.slug %>"
+           hx-get="/<%= nextPinnedPost.slug %>?partial=1" hx-target="#pcms-main"
+           hx-push-url="/<%= nextPinnedPost.slug %>" hx-indicator="#pcms-loading">
+          <span class="post-pinned-arrow" aria-hidden="true">→</span>
+          <span class="post-pinned-body">
+            <span class="post-pinned-label">📌 Volgende vastgepinde</span>
+            <span class="post-pinned-title"><%= nextPinnedPost.title %></span>
+            <span class="post-pinned-cta">← Lees deze post</span>
+          </span>
+        </a>
+      <% } else if (pinnedBottomOfStack) { %>
+        <span class="post-pinned-card post-pinned-card--edge">
+          <span class="post-pinned-edge-label">— ONDERAAN —</span>
+          <span class="post-pinned-edge-title">Oudste post</span>
+        </span>
+      <% } %>
+    </nav>
+  <% } %>
+
+  <%# ── Chronological prev/next (kept for non-pinned posts) ──────
+      For pinned posts the pinned-nav above replaces this. Non-pinned
+      regular posts still get the simple older/newer pair. %>
+  <% if (!post.pinned && (prevPost || nextPost)) { %>
+    <nav class="post-nav">
+      <% if (prevPost) { %>
+        <a class="post-nav-prev" href="/<%= prevPost.slug %>"
+           hx-get="/<%= prevPost.slug %>?partial=1" hx-target="#pcms-main"
+           hx-push-url="/<%= prevPost.slug %>" hx-indicator="#pcms-loading">
+          <span class="post-nav-label">← Older</span>
+          <span class="post-nav-title"><%= prevPost.title %></span>
+        </a>
+      <% } else { %><span></span><% } %>
+      <% if (nextPost) { %>
+        <a class="post-nav-next" href="/<%= nextPost.slug %>"
+           hx-get="/<%= nextPost.slug %>?partial=1" hx-target="#pcms-main"
+           hx-push-url="/<%= nextPost.slug %>" hx-indicator="#pcms-loading">
+          <span class="post-nav-label">Newer →</span>
+          <span class="post-nav-title"><%= nextPost.title %></span>
+        </a>
+      <% } %>
+    </nav>
+  <% } %>
 </article>
 <style>
-.post-page { max-width: 720px; margin: 0.5rem auto 2rem; padding: 0 1rem; }
+.post-page { max-width: 720px; margin: 2rem auto; padding: 0 1rem; }
 .post-cover { margin: 0 0 2rem; border-radius: 8px; overflow: hidden; }
-.post-cover img, .post-cover video { width: 100%; height: auto; display: block; }
+.post-cover img { width: 100%; height: auto; display: block; }
 .post-header { margin-bottom: 2rem; }
 .post-title { font-family: var(--font-display, serif); font-size: 2.5rem; line-height: 1.1; margin: 0 0 1rem; }
@@ -194,25 +309,4 @@
 .post-content { font-family: var(--font-body, serif); font-size: 1.1rem; line-height: 1.7; color: var(--ink); }
 .post-content p { margin: 1.2em 0; }
-/* Poll (a hosted AS2 Question) — display-only; voting happens from the fediverse. */
-.poll { margin: 1.75rem 0; display: flex; flex-direction: column; gap: .5rem; }
-.poll-opt { position: relative; display: flex; align-items: center; gap: .5rem; padding: .55rem .75rem; border: 1px solid var(--line, rgba(128,128,128,.25)); border-radius: 8px; overflow: hidden; font-size: .98rem; }
-.poll-bar { position: absolute; inset: 0 auto 0 0; background: color-mix(in srgb, var(--accent) 18%, transparent); z-index: 0; transition: width .3s ease; }
-.poll-opt.is-lead .poll-bar { background: color-mix(in srgb, var(--accent) 30%, transparent); }
-.poll-name { position: relative; z-index: 1; flex: 1; color: var(--ink); }
-.poll-opt.is-lead .poll-name { font-weight: 600; }
-.poll-pct { position: relative; z-index: 1; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
-.poll-meta { display: flex; flex-wrap: wrap; gap: .4rem; font-size: .85rem; color: var(--ink-muted); }
-.poll-note { font-size: .8rem; color: var(--ink-muted); margin: .1rem 0 0; }
-.like-btn {
-  display: inline-flex; align-items: center; gap: 0.45rem;
-  padding: 0.4rem 0.85rem; border: 1px solid var(--rule); border-radius: 999px;
-  background: var(--paper-2); color: var(--ink); font: inherit; font-size: 0.95rem;
-  cursor: pointer; text-decoration: none; transition: border-color 120ms, color 120ms, background 120ms;
-}
-.like-btn:hover { border-color: var(--accent); }
-.like-btn .like-heart { font-size: 1.1rem; line-height: 1; }
-.like-btn.is-liked { border-color: var(--accent); color: var(--accent); }
-.like-btn.is-liked .like-heart { color: var(--accent); }
-.like-btn .like-count { font-variant-numeric: tabular-nums; }
 .post-content h2 { font-family: var(--font-display, serif); font-size: 1.6rem; margin: 2rem 0 1rem; }
 .post-content h3 { font-family: var(--font-display, serif); font-size: 1.3rem; margin: 1.5rem 0 0.75rem; }
@@ -226,4 +320,10 @@
 .tag:hover { background: var(--accent); color: white; }
 .post-actions { display: flex; gap: 0.5rem; margin: 2rem 0; padding: 1rem; background: var(--paper-2); border-radius: 6px; flex-wrap: wrap; }
+.post-nav { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-top: 3rem; padding-top: 2rem; border-top: 1px solid var(--rule); }
+.post-nav-prev, .post-nav-next { display: flex; flex-direction: column; padding: 1rem; background: var(--paper-2); border-radius: 6px; text-decoration: none; color: var(--ink); }
+.post-nav-next { text-align: right; align-items: flex-end; }
+.post-nav-label { font-size: 0.8rem; color: var(--ink-muted); margin-bottom: 0.25rem; }
+.post-nav-title { font-weight: 500; }
+@media (max-width: 600px) { .post-nav { grid-template-columns: 1fr; } }
 
 /* ============================================================
@@ -290,6 +390,4 @@
   gap: 0.5rem;
   align-items: baseline;
-  flex-wrap: wrap;
-  row-gap: 0.1rem;
   font-size: 0.85rem;
   margin-bottom: 0.3rem;
@@ -298,8 +396,4 @@
 .comment-author:hover { color: var(--accent); }
 .comment-time { color: var(--ink-muted, var(--ink-soft)); }
-.comment-meta .fedi-handle { overflow-wrap: anywhere; }
-@media (max-width: 560px) {
-  .comment-meta .comment-time { flex-basis: 100%; font-size: 0.78rem; color: var(--ink-faint, var(--ink-muted)); }
-}
 .comment-content {
   white-space: pre-wrap;
@@ -314,10 +408,5 @@
   gap: 0.5rem;
   margin-top: 0.4rem;
-  flex-wrap: wrap;
-  align-items: center;
-}
-.fedi-owner-react { display: inline; }
-.fedi-owner-reply { display: inline-block; }
-.fedi-owner-reply[open] { flex-basis: 100%; }
+}
 .comment-reply-btn, .comment-delete-btn {
   background: none;
@@ -334,23 +423,4 @@
 .comment-delete-btn:hover { color: #c33; }
 
-/* Owner comment-action icons — same visual language as the News feed, compact (30px). */
-.fedi-cact { width: 30px; height: 30px; flex: 0 0 30px; border-radius: 50%; padding: 0; box-sizing: border-box;
-  display: inline-flex; align-items: center; justify-content: center; list-style: none;
-  border: 1px solid color-mix(in srgb, var(--ink, #000) 14%, transparent);
-  background: color-mix(in srgb, var(--ink, #000) 3%, transparent);
-  color: var(--ink-soft, #888); cursor: pointer; -webkit-tap-highlight-color: transparent;
-  transition: background .12s, border-color .12s, transform .1s; }
-.fedi-cact::-webkit-details-marker { display: none; }
-.fedi-cact svg { width: 15px; height: 15px; display: block; }
-.fedi-cact:active { transform: scale(.9); }
-.fedi-cact-like svg { color: #e8b04b; }
-.fedi-cact-like:hover { background: color-mix(in srgb, #e8b04b 15%, transparent); border-color: color-mix(in srgb, #e8b04b 50%, transparent); }
-.fedi-cact-like.is-on { background: color-mix(in srgb, #e8b04b 18%, transparent); border-color: color-mix(in srgb, #e8b04b 60%, transparent); }
-.fedi-cact-boost svg { color: #2fa85a; }
-.fedi-cact-boost:hover { background: color-mix(in srgb, #2fa85a 15%, transparent); border-color: color-mix(in srgb, #2fa85a 50%, transparent); }
-.fedi-cact-boost.is-on { background: color-mix(in srgb, #2fa85a 18%, transparent); border-color: color-mix(in srgb, #2fa85a 60%, transparent); }
-.fedi-cact-reply svg { color: var(--accent, #06c); }
-.fedi-cact-reply:hover { background: color-mix(in srgb, var(--accent, #888) 14%, transparent); border-color: color-mix(in srgb, var(--accent, #888) 50%, transparent); }
-
 .comment-replies {
   margin-top: 1rem;
@@ -380,5 +450,4 @@
   resize: vertical;
   min-height: 70px;
-  max-height: 200px;
   padding: 0.65rem 0.85rem;
   border: 1px solid var(--rule);
@@ -393,13 +462,4 @@
 .comment-form button { align-self: flex-start; }
 .comment-reply-form-actions { display: flex; gap: 0.5rem; }
-/* Show the reply form only AFTER clicking REPLY. The display:flex above would
-   otherwise override the [hidden] attribute → form was always open. */
-.comment-reply-form[hidden] { display: none; }
-.fedi-owner-reply summary { list-style: none; cursor: pointer; }
-.fedi-owner-reply summary::-webkit-details-marker { display: none; }
-.fedi-owner-reply[open] summary { margin-bottom: .45rem; }
-/* DELETE button is inside a <form>; display:contents makes it a direct flex-sibling
-   of REPLY → pixel-perfect alignment + equal gap. */
-.comment-actions form { display: contents; }
 
 .comments-login-cta { margin-top: 1.5rem; text-align: center; }
@@ -447,10 +507,7 @@
 .post-related-cover {
   display: block;
-  position: relative;
-  overflow: hidden;
   aspect-ratio: 16 / 10;
   background: var(--paper-2) center/cover no-repeat;
 }
-.post-related-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
 .post-related-cover--empty {
   background-image: linear-gradient(135deg,
