Index: src/views/pages/post-edit.ejs
===================================================================
--- src/views/pages/post-edit.ejs	(revision dcff893dc8dca9f4ca7461cb1ad2445167d326aa)
+++ src/views/pages/post-edit.ejs	(revision 837fc9c1dc50db6b6a042e84da63ed9989edf2fa)
@@ -237,4 +237,8 @@
           <input type="checkbox" name="noindex" value="1" <%= post.noindex ? 'checked' : '' %>>
           <span>🚫 <%= t('pedit.noindex_label') %></span>
+        </label>
+        <label class="pe-checkbox">
+          <input type="checkbox" name="nsfw" value="1" <%= post.nsfw ? 'checked' : '' %>>
+          <span>🔞 <%= t('pedit.nsfw_label') %></span>
         </label>
         <% if (typeof premiumUnlocked === 'undefined' || premiumUnlocked) { %>
Index: src/views/pages/post.ejs
===================================================================
--- src/views/pages/post.ejs	(revision dcff893dc8dca9f4ca7461cb1ad2445167d326aa)
+++ src/views/pages/post.ejs	(revision 837fc9c1dc50db6b6a042e84da63ed9989edf2fa)
@@ -5,8 +5,16 @@
 const _base = (typeof siteUrlBase !== 'undefined' && siteUrlBase) ? siteUrlBase : '';
 %>
-<article class="container post-page">
+<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"><%= t('post.nsfw_warning') %></span>
+      <button type="button" class="nsfw-banner-btn nsfw-reveal"><%= t('post.nsfw_show') %></button>
+    </div>
+  <% } %>
 
   <% if (post.cover_image_url) { %>
