Index: src/middleware/render.js
===================================================================
--- src/middleware/render.js	(revision d7526bda1a7c629688e73f463847832f685c3381)
+++ src/middleware/render.js	(revision e951b7c4efb52daa3b8964b528fd3f604de85365)
@@ -19,5 +19,5 @@
 import { getSetting } from '../services/SettingsService.js';
 import { isPremium as isPremiumInstance, premiumEnabled, premiumUnlocked } from '../services/PatreonService.js';
-import { unreadCount as notifUnreadCount } from '../services/NotificationService.js';
+import ActivityPubService from '../services/ActivityPubService.js';
 import { audioEnabled as audioFeatureEnabled } from '../config/features.js';
 import { PLATFORMS as PLATFORMS_CATALOG } from '../services/PlatformIcons.js';
@@ -118,5 +118,5 @@
     langs: LANGS.map((c) => ({ code: c, name: LANG_NAMES[c], active: c === _lang })),
     timezone: getSetting('timezone') || '',
-    notifUnread: _u ? notifUnreadCount(_u.id) : 0,
+    notifUnread: (canManageFedi && _site) ? ActivityPubService.countUnseenNotifications(_site.slug) : 0,
     userOwnsSite,
     canSeeBeheer,
Index: src/routes/posts.js
===================================================================
--- src/routes/posts.js	(revision d7526bda1a7c629688e73f463847832f685c3381)
+++ src/routes/posts.js	(revision e951b7c4efb52daa3b8964b528fd3f604de85365)
@@ -581,4 +581,5 @@
   const site = res.locals.site;
   const items = site ? ActivityPubService.getNotifications(site.slug, 80) : [];
+  if (site) ActivityPubService.markNotificationsSeen(site.slug); // viewing = seen → clears the bell badge
   renderPage(req, res, 'pages/fedi-notifications', { pageTitle: 'Meldingen', bodyClass: 'on-special', items });
 });
Index: src/services/ActivityPubService.js
===================================================================
--- src/services/ActivityPubService.js	(revision d7526bda1a7c629688e73f463847832f685c3381)
+++ src/services/ActivityPubService.js	(revision e951b7c4efb52daa3b8964b528fd3f604de85365)
@@ -169,4 +169,21 @@
   } catch { /* non-fatal */ }
   return out;
+}
+
+// Notifications "seen" tracking → a real bell badge. Stored per site in app_settings.
+export function markNotificationsSeen(slug) {
+  try {
+    db.prepare("INSERT INTO app_settings (key, value, updated_at) VALUES (?, ?, CURRENT_TIMESTAMP) ON CONFLICT(key) DO UPDATE SET value = excluded.value, updated_at = CURRENT_TIMESTAMP")
+      .run(`fedi_notif_seen:${slug}`, new Date().toISOString());
+  } catch { /* non-fatal */ }
+}
+export function countUnseenNotifications(slug) {
+  try {
+    const row = db.prepare('SELECT value FROM app_settings WHERE key = ?').get(`fedi_notif_seen:${slug}`);
+    const seen = row ? Date.parse(row.value) : 0;
+    let n = 0;
+    for (const it of getNotifications(slug, 50)) { if (Date.parse(it.created_at) > seen) n++; }
+    return n;
+  } catch { return 0; }
 }
 
@@ -919,4 +936,4 @@
   getNotifications, listBlocks, isBlockedAny, blockTarget, unblock,
   deliverWithRetry, enqueueDelivery, processDeliveryQueue, startDeliveryWorker,
-  getReplyUris,
+  getReplyUris, markNotificationsSeen, countUnseenNotifications,
 };
Index: src/views/partials/topnav.ejs
===================================================================
--- src/views/partials/topnav.ejs	(revision d7526bda1a7c629688e73f463847832f685c3381)
+++ src/views/partials/topnav.ejs	(revision e951b7c4efb52daa3b8964b528fd3f604de85365)
@@ -103,4 +103,5 @@
            hx-get="/meldingen?partial=1" hx-target="#pcms-main" hx-swap="innerHTML" hx-push-url="/meldingen" 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><% } %>
         </a>
       <% } %>
