Index: src/views/partials/topnav.ejs
===================================================================
--- src/views/partials/topnav.ejs	(revision 2165b6d3d57ceaa8b5d1f70491868482149470cf)
+++ src/views/partials/topnav.ejs	(revision 7bc636b391c66ac399c33e54f7173a022c6a3cbd)
@@ -9,14 +9,12 @@
 // Desktop (≥768px):
 //   - Full v9 masthead: brand left, action row right
-//     (Archief / Search / Install / Theme / User-menu).
+//     (Archief / Search / Install / Theme / Prutter / User-menu).
 //   - bottom-tab is hidden via CSS, so all nav must live here.
 
 const _siteUrlBase = (typeof siteUrlBase !== 'undefined' && siteUrlBase) ? siteUrlBase : '';
 const _isAdmin     = typeof bodyClass !== 'undefined' && bodyClass.indexOf('on-admin') >= 0;
-// Fediverse pages (on-special) get the same top-nav "back to site" treatment as admin.
-const _isSpecial   = typeof bodyClass !== 'undefined' && bodyClass.indexOf('on-special') >= 0;
 const _hasSearch   = !site || site.show_search === undefined || site.show_search;
-const _canPost     = user && (typeof canMutate === 'undefined' || canMutate)
-                     && permissions && permissions.canCreatePost && permissions.canCreatePost(user, site);
+const _hasPrutter  = user && site && site.enable_prutter;
+const _canPost     = user && permissions && permissions.canCreatePost && permissions.canCreatePost(user, site);
 %>
 
@@ -26,8 +24,12 @@
     <!-- Brand block (always visible) -->
     <div class="masthead-brand">
-      <% if (_isAdmin || _isSpecial) { %>
-        <a href="<%= _siteUrlBase %>/" class="nav-link nav-link-admin"><%= t('nav.back_to_site') %></a>
+      <% if (_isAdmin) { %>
+        <a href="<%= _siteUrlBase %>/" class="nav-link nav-link-admin">← Terug naar site</a>
+      <% } else if (site) { %>
+        <a class="site-title" href="<%= _siteUrlBase %>/"
+           hx-get="<%= _siteUrlBase %>/?partial=1" hx-target="#pcms-main" hx-swap="innerHTML"
+           hx-push-url="<%= _siteUrlBase %>/" hx-indicator="#pcms-loading"><%= site.title %></a>
       <% } else { %>
-        <a class="site-title" href="/">Klonkt</a>
+        <a class="site-title" href="/">PrutFolio</a>
       <% } %>
     </div>
@@ -47,5 +49,5 @@
     <nav class="top-nav top-nav-desktop" aria-label="Hoofdnavigatie">
 
-      <% if (!_isAdmin && !_isSpecial) { %>
+      <% if (!_isAdmin) { %>
         <a class="nav-link" href="<%= _siteUrlBase %>/archive"
            hx-get="<%= _siteUrlBase %>/archive?partial=1" hx-target="#pcms-main"
@@ -53,10 +55,10 @@
            hx-indicator="#pcms-loading">
           <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 8v13H3V8"/><rect x="1" y="3" width="22" height="5" rx="1"/><line x1="10" y1="12" x2="14" y2="12"/></svg>
-          <span class="nav-label"><%= t('nav.archive') %></span>
+          <span class="nav-label">Archief</span>
         </a>
       <% } %>
 
       <% if (_hasSearch) { %>
-        <button type="button" class="nav-btn" id="search-toggle" aria-label="<%= t('nav.search') %>" title="<%= t('nav.search') %>">
+        <button type="button" class="nav-btn" id="search-toggle" aria-label="Zoeken" title="Zoeken">
           <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="11" cy="11" r="7"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
         </button>
@@ -71,27 +73,7 @@
       </button>
 
-      <% if (typeof langs !== 'undefined' && langs && langs.length > 1) {
-           var _curLang = (langs.find(function(l){ return l.active; }) || { code: 'nl' }).code;
-           var _langR = (typeof currentPath !== 'undefined' && currentPath) ? currentPath : '/';
-      %>
-        <details class="lang-menu">
-          <summary class="nav-btn lang-toggle" aria-label="<%= t('nav.language') %>" title="<%= t('nav.language') %>">
-            <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
-            <span class="lang-code"><%= _curLang.toUpperCase() %></span>
-            <svg class="lang-caret" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="6 9 12 15 18 9"/></svg>
-          </summary>
-          <div class="lang-dropdown" role="menu">
-            <% langs.forEach(function(l){ %>
-              <a class="lang-item<%= l.active ? ' is-active' : '' %>" role="menuitem" href="/lang/<%= l.code %>?r=<%= encodeURIComponent(_langR) %>"><span class="lang-item-code"><%= l.code.toUpperCase() %></span><%= l.name %></a>
-            <% }); %>
-          </div>
-        </details>
-      <% } %>
-
-      <% if (user && typeof canManageFedi !== 'undefined' && canManageFedi && apEnabled) { %>
-        <a class="nav-btn nav-notif" href="/notifications" aria-label="<%= t('notif.title') %>" title="<%= t('notif.title') %>"
-           hx-get="/notifications?partial=1" hx-target="#pcms-main" hx-swap="innerHTML" hx-push-url="/notifications" hx-indicator="#pcms-loading">
-          <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M18 8a6 6 0 0 0-12 0c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/></svg>
-          <% if (typeof notifUnread !== 'undefined' && notifUnread > 0) { %><span class="notif-badge"><%= notifUnread > 9 ? '9+' : notifUnread %></span><% } %>
+      <% if (_hasPrutter) { %>
+        <a class="nav-btn" href="<%= _siteUrlBase %>/prutter" aria-label="Prutter (DMs)" title="Prutter">
+          <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" 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>
         </a>
       <% } %>
@@ -101,5 +83,5 @@
           <summary class="nav-btn user-toggle" aria-label="Gebruikersmenu">
             <% if (user.avatar_url) { %>
-              <img class="user-avatar user-avatar-img" src="<%= avatar(user.avatar_url, 128) %>" alt="">
+              <img class="user-avatar user-avatar-img" src="<%= user.avatar_url %>" alt="">
             <% } else { %>
               <span class="user-avatar"><%= user.username.charAt(0).toUpperCase() %></span>
@@ -109,5 +91,5 @@
             <div class="user-dropdown-header">
               <% if (user.avatar_url) { %>
-                <img class="udh-avatar" src="<%= avatar(user.avatar_url, 128) %>" alt="">
+                <img class="udh-avatar" src="<%= user.avatar_url %>" alt="">
               <% } else { %>
                 <span class="udh-avatar udh-avatar-fallback"><%= user.username.charAt(0).toUpperCase() %></span>
@@ -116,5 +98,5 @@
                 <span class="udh-name"><%= user.username %></span>
                 <% if (user.role === 'god') { %>
-                  <span class="udh-role">God</span>
+                  <span class="udh-role">Admin</span>
                 <% } else if (user.role === 'admin' || user.role === 'moderator') { %>
                   <span class="udh-role"><%= user.role.charAt(0).toUpperCase() + user.role.slice(1) %></span>
@@ -123,32 +105,20 @@
             </div>
             <div class="user-dropdown-list">
-              <a href="/account" role="menuitem" class="udi"
-                 hx-get="/account?partial=1" hx-target="#pcms-main" hx-swap="innerHTML"
-                 hx-push-url="/account" hx-indicator="#pcms-loading">
+              <a href="/account" role="menuitem" class="udi">
                 <svg class="udi-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
-                <span><%= t('nav.account') %></span>
+                <span>Account</span>
               </a>
-              <% if (typeof canSeeBeheer !== 'undefined' && canSeeBeheer) { %>
-                <a href="/admin" role="menuitem" class="udi"
-                   hx-get="/admin?partial=1" hx-target="#pcms-main" hx-swap="innerHTML"
-                   hx-push-url="/admin" hx-indicator="#pcms-loading">
+              <% if (user.role === 'god' || user.role === 'admin') { %>
+                <a href="/admin" role="menuitem" class="udi">
                   <svg class="udi-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 3h7v7H3z"/><path d="M14 3h7v7h-7z"/><path d="M14 14h7v7h-7z"/><path d="M3 14h7v7H3z"/></svg>
-                  <span><%= t('nav.admin') %></span>
+                  <span>Beheer</span>
                 </a>
               <% } %>
               <% if (_canPost) { %>
-                <a href="<%= _siteUrlBase %>/posts/new" role="menuitem" class="udi"
-                   hx-get="<%= _siteUrlBase %>/posts/new?partial=1" hx-target="#pcms-main" hx-swap="innerHTML"
-                   hx-push-url="<%= _siteUrlBase %>/posts/new" hx-indicator="#pcms-loading">
+                <a href="/posts/new" role="menuitem" class="udi"
+                   hx-get="/posts/new?partial=1" hx-target="#pcms-main" hx-swap="innerHTML"
+                   hx-push-url="/posts/new" hx-indicator="#pcms-loading">
                   <svg class="udi-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-4 12.5-12.5z"/></svg>
-                  <span><%= t('nav.new_post') %></span>
-                </a>
-              <% } %>
-              <% if (typeof canManageFedi !== 'undefined' && canManageFedi && apEnabled) { %>
-                <a href="/news" role="menuitem" class="udi"
-                   hx-get="/news?partial=1" hx-target="#pcms-main" hx-swap="innerHTML"
-                   hx-push-url="/news" hx-indicator="#pcms-loading">
-                  <svg class="udi-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><line x1="8.59" y1="13.51" x2="15.42" y2="17.49"/><line x1="15.41" y1="6.51" x2="8.59" y2="10.49"/></svg>
-                  <span><%= t('nav.fediverse') %></span>
+                  <span>Nieuwe post</span>
                 </a>
               <% } %>
@@ -158,5 +128,5 @@
               <a href="/auth/logout" role="menuitem" class="udi udi-danger">
                 <svg class="udi-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/></svg>
-                <span><%= t('nav.logout') %></span>
+                <span>Uitloggen</span>
               </a>
             </div>
@@ -164,8 +134,6 @@
         </details>
       <% } else { %>
-        <a class="nav-link" href="/auth/login"
-           hx-get="/auth/login?partial=1" hx-target="#pcms-main" hx-swap="innerHTML"
-           hx-push-url="/auth/login" hx-indicator="#pcms-loading">
-          <span class="nav-label"><%= t('nav.login') %></span>
+        <a class="nav-link" href="/auth/login">
+          <span class="nav-label">Inloggen</span>
         </a>
       <% } %>
@@ -176,23 +144,61 @@
 
 <!-- Search overlay (shared by mobile bottom-tab + desktop top-nav) -->
-<%# De teksten staan op het element dat ze gebruikt, niet in het script: een
-    module is een statisch bestand en kan geen vertaling interpoleren. %>
-<div id="search-overlay" class="search-overlay" hidden data-suggest="<%= _siteUrlBase %>/search/suggest" data-action="<%= _siteUrlBase %>/search"
-     data-i18n="<%= JSON.stringify({ posts: t('search.section_posts'), tracks: t('search.section_tracks'), events: t('search.section_events'), pages: t('search.section_pages'), all: t('search.suggest_all'), none: t('search.suggest_empty') }) %>">
+<div id="search-overlay" class="search-overlay" hidden>
   <div class="container">
     <form class="search-overlay-form" method="get" action="<%= _siteUrlBase %>/search">
-      <input type="search" name="q" placeholder="<%= t('search.placeholder') %>" autocomplete="off">
-      <button type="submit" class="nav-btn" aria-label="<%= t('search.button') %>">
+      <input type="search" name="q" placeholder="Zoeken in posts…" autocomplete="off">
+      <button type="submit" class="nav-btn" aria-label="Zoeken">
         <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="11" cy="11" r="7"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
       </button>
-      <button type="button" class="nav-btn" id="search-close" aria-label="<%= t('imed.cancel') %>">
+      <button type="button" class="nav-btn" id="search-close" aria-label="Sluiten">
         <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
       </button>
     </form>
-    <div id="search-suggest" class="search-suggest" data-lenis-prevent></div>
   </div>
 </div>
 
-<%# Het script van de topnav staat in assets/js/mod/chrome.js (shaer-bqr). %>
+<script>
+(function() {
+  // Theme toggle (works for both mobile + desktop buttons)
+  function toggleTheme() {
+    const cur = document.documentElement.getAttribute('data-theme') || 'dark';
+    const next = cur === 'dark' ? 'light' : 'dark';
+    document.documentElement.setAttribute('data-theme', next);
+    try { localStorage.setItem('pcms-theme', next); } catch (e) {}
+  }
+  // Theme toggle — event delegation so it works for ANY button with the
+  // matching ids, even ones rendered later in the page (footer is below
+  // topnav in source order, so getElementById would have returned null
+  // when this IIFE ran).
+  document.body.addEventListener('click', function(e) {
+    const btn = e.target.closest(
+      '#theme-toggle, #theme-toggle-mobile, #theme-toggle-footer'
+    );
+    if (btn) toggleTheme();
+  });
+
+  // Search overlay
+  const overlay = document.getElementById('search-overlay');
+  document.getElementById('search-toggle')?.addEventListener('click', function() {
+    if (overlay) {
+      overlay.hidden = false;
+      const inp = overlay.querySelector('input');
+      if (inp) inp.focus();
+    }
+  });
+  document.getElementById('search-close')?.addEventListener('click', function() {
+    if (overlay) overlay.hidden = true;
+  });
+  document.addEventListener('keydown', function(e) {
+    if (e.key === 'Escape' && overlay && !overlay.hidden) overlay.hidden = true;
+  });
+
+  // Close user dropdown on outside click
+  document.addEventListener('click', function(e) {
+    const open = document.querySelector('.user-menu[open]');
+    if (open && !open.contains(e.target)) open.removeAttribute('open');
+  });
+})();
+</script>
 
 <style>
@@ -222,15 +228,4 @@
 }
 
-/* Hub-home brand IS visible — the home button on artist/hub pages. */
-.masthead-brand .nav-hub-home {
-  display: inline-flex; align-items: center; justify-content: center;
-  width: 40px; height: 40px;
-  color: var(--ink); text-decoration: none;
-  border-radius: 8px;
-  transition: color 120ms, background 120ms;
-}
-.masthead-brand .nav-hub-home:hover { color: var(--accent); background: var(--paper-2); }
-.masthead-brand .nav-hub-home svg { width: 22px; height: 22px; }
-
 /* On mobile, hide the entire masthead except for admin pages. The brand
    appears in the profile-header on content pages, and the bottom-tab
@@ -239,8 +234,4 @@
 @media (max-width: 767px) {
   body:not(.on-admin) .masthead { display: none; }
-  /* The masthead is gone on mobile, so it can't carry the iOS safe-area top inset
-     (env() resolves to 0 in the home-screen PWA; --ios-safe-top is set by JS in shell).
-     Pad the body instead so the profile-header clears the Dynamic Island / notch. */
-  body:not(.on-admin) { padding-top: var(--ios-safe-top, 0px); }
 }
 
@@ -349,8 +340,7 @@
   min-width: 220px;
   padding: .35rem;
-  /* Frosted glass: transparent + heavy blur so the frosted effect is clearly visible. */
-  background: color-mix(in srgb, var(--paper) 60%, transparent);
-  backdrop-filter: blur(34px) saturate(190%);
-  -webkit-backdrop-filter: blur(34px) saturate(190%);
+  background: color-mix(in srgb, var(--paper) 92%, transparent);
+  backdrop-filter: blur(14px) saturate(180%);
+  -webkit-backdrop-filter: blur(14px) saturate(180%);
   border: 1px solid var(--rule);
   border-radius: 12px;
@@ -466,24 +456,3 @@
   display: inline-flex; align-items: center; justify-content: center;
 }
-/* Live-resultaten dropdown */
-.search-suggest { margin-top: .6rem; max-height: 60vh; overflow-y: auto; display: flex; flex-direction: column; gap: .25rem; }
-.search-suggest:empty { display: none; }
-.ss-group { padding: .25rem 0; }
-.ss-title { font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--ink-soft, var(--ink-muted)); padding: .35rem .25rem .2rem; }
-.ss-item { display: block; padding: .55rem .6rem; border-radius: 8px; color: var(--ink); text-decoration: none; font-size: .95rem; }
-.ss-item:hover { background: var(--paper-2); color: var(--accent); }
-.ss-item.ss-noclick { opacity: .7; cursor: default; }
-.ss-sub { color: var(--ink-soft, var(--ink-muted)); font-size: .85em; }
-.ss-empty { padding: .8rem .6rem; color: var(--ink-soft, var(--ink-muted)); font-size: .9rem; }
-.ss-all { display: block; margin-top: .35rem; padding: .55rem .6rem; border-top: 1px solid var(--rule); color: var(--accent); font-weight: 600; text-decoration: none; font-size: .9rem; }
-.ss-all:hover { text-decoration: underline; }
-/* Notification bell + unread badge */
-.nav-notif { position: relative; }
-.notif-badge {
-  position: absolute; top: 1px; right: 1px;
-  min-width: 16px; height: 16px; padding: 0 4px; box-sizing: border-box;
-  display: inline-flex; align-items: center; justify-content: center;
-  background: #e0245e; color: #fff; font-size: 10px; font-weight: 700;
-  border-radius: 999px; line-height: 1; pointer-events: none;
-}
 </style>
