Index: src/config/database.js
===================================================================
--- src/config/database.js	(revision e00c0e9397ee0864f97459b36a39ff5ad86a9e41)
+++ src/config/database.js	(revision fe97cc38d423c6b67d75cc07bab36c9ef2dd4f91)
@@ -347,4 +347,16 @@
     );
     CREATE INDEX IF NOT EXISTS idx_poll_votes_post ON poll_votes(post_id);
+    CREATE TABLE IF NOT EXISTS ap_mentions (
+      id INTEGER PRIMARY KEY AUTOINCREMENT,
+      slug TEXT NOT NULL,           -- our mentioned site/actor
+      object_uri TEXT NOT NULL,     -- the remote note that mentions us
+      note_url TEXT,                -- its human URL (open/interact)
+      actor_uri TEXT, actor_name TEXT, actor_handle TEXT, actor_icon TEXT, actor_url TEXT,
+      content TEXT,                 -- sanitized HTML snippet of the mentioning note
+      published TEXT,
+      created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
+      UNIQUE(slug, object_uri)
+    );
+    CREATE INDEX IF NOT EXISTS idx_ap_mentions_slug ON ap_mentions(slug, created_at);
     CREATE TABLE IF NOT EXISTS ap_reports (
       id INTEGER PRIMARY KEY AUTOINCREMENT,
Index: src/services/ActivityPubService.js
===================================================================
--- src/services/ActivityPubService.js	(revision e00c0e9397ee0864f97459b36a39ff5ad86a9e41)
+++ src/services/ActivityPubService.js	(revision fe97cc38d423c6b67d75cc07bab36c9ef2dd4f91)
@@ -660,4 +660,19 @@
 // ── HTTP Signatures + delivery ────────────────────────────────────
 const slugFromActorUrl = (url) => { const m = String(url || '').match(/\/ap\/users\/([^/?#]+)/); return m ? decodeURIComponent(m[1]) : null; };
+// Which of OUR sites are named in a note's Mention tags? Only hrefs on our own base count
+// (an /ap/users/<slug> path on a remote host is someone else's actor), and the slug must be
+// an existing site. Deduped.
+export function localMentionSlugs(tags, base) {
+  if (!base) return [];
+  const out = [], seen = new Set();
+  for (const t of (Array.isArray(tags) ? tags : (tags ? [tags] : []))) {
+    if (!t || t.type !== 'Mention' || typeof t.href !== 'string') continue;
+    if (!t.href.startsWith(base + '/ap/users/')) continue;
+    const slug = slugFromActorUrl(t.href);
+    if (!slug || seen.has(slug)) continue; seen.add(slug);
+    try { if (db.prepare('SELECT 1 FROM sites WHERE slug = ?').get(slug)) out.push(slug); } catch { /* ignore */ }
+  }
+  return out;
+}
 
 // Sign + POST an activity to a remote inbox (draft-cavage HTTP Signatures, RSA-SHA256).
@@ -1073,4 +1088,22 @@
         }
         console.log('[AP] timeline +', actorUri, 'x' + subs.length);
+      }
+    }
+    // Mentioned in a post that is NOT a reply to our content (a reply to us already returned
+    // above): store a mention notification for each of our actors named in the Mention tags.
+    // Requires our own base prefix on the tag href — /ap/users/<slug> on a REMOTE host is
+    // someone else's actor, not ours.
+    if (actorUri && !isLocalActor && o.id) {
+      const slugs = localMentionSlugs(o.tag, base);
+      if (slugs.length) {
+        const ai = actorInfo(await resolveActor(actorUri), actorUri);
+        const html = HtmlSanitizerService.sanitize(o.content || '');
+        for (const slug of slugs) {
+          try {
+            const r = db.prepare('INSERT OR IGNORE INTO ap_mentions (slug, object_uri, note_url, actor_uri, actor_name, actor_handle, actor_icon, actor_url, content, published, created_at) VALUES (?,?,?,?,?,?,?,?,?,?,CURRENT_TIMESTAMP)')
+              .run(slug, o.id, safeUrl(o.url) || null, actorUri, ai.name, ai.handle, ai.icon, ai.url, html, o.published || null);
+            if (r.changes) console.log('[AP] mention', actorUri, '→', slug);
+          } catch { /* ignore */ }
+        }
       }
     }
@@ -2161,4 +2194,9 @@
     }
   } catch { /* ignore */ }
+  try {
+    for (const r of db.prepare('SELECT object_uri, note_url, actor_uri, actor_name, actor_handle, actor_icon, actor_url, content, created_at FROM ap_mentions WHERE slug = ? ORDER BY created_at DESC LIMIT 50').all(slug)) {
+      out.push({ type: 'mention', name: r.actor_name, handle: r.actor_handle, url: r.actor_url || r.actor_uri, icon: r.actor_icon, content: stripLeadingMentions(r.content), note_url: r.note_url || r.object_uri, created_at: r.created_at });
+    }
+  } catch { /* ignore */ }
   out.sort((a, b) => new Date(b.created_at) - new Date(a.created_at));
   return out.slice(0, limit || 60);
@@ -2335,5 +2373,5 @@
   listOutbox, deliverOutboxDelete, deliverOutboxUpdate,
   webfingerResolve, followActor, resolveRemoteActor, unfollowActor, listFollowing, setAutoBoost, backfillFromOutbox, getTimeline, sendInteraction, voteOnPoll, voteOnRemotePoll,
-  parseOwnPoll, pollTally, ownPollView, deliverPollUpdate, maybeCrawlThread, sendReport,
+  parseOwnPoll, pollTally, ownPollView, deliverPollUpdate, maybeCrawlThread, sendReport, localMentionSlugs,
   autoBoostCount, boostedCount, markBoosted, unmarkBoosted, markLiked, unmarkLiked, getTimelineReaction, upsertBoostedNote, getCirkelPosts, getCirkelMembers, selfHealTimeline,
   getNotifications, listBlocks, isBlockedAny, blockTarget, unblock,
Index: src/services/i18n.js
===================================================================
--- src/services/i18n.js	(revision e00c0e9397ee0864f97459b36a39ff5ad86a9e41)
+++ src/services/i18n.js	(revision fe97cc38d423c6b67d75cc07bab36c9ef2dd4f91)
@@ -28,5 +28,5 @@
     'nav.language': 'Taal',
     'nav.notifications': 'Meldingen',
-    'notif.title': 'Meldingen', 'notif.empty': 'Nog geen meldingen.', 'notif.someone': 'Iemand', 'notif.followed': 'volgt je nu', 'notif.liked': 'likete je post', 'notif.boosted': 'boostte je post', 'notif.replied': 'reageerde op', 'notif.reported': 'rapporteerde je bij hun server', 'blk.title': 'Blokkeren', 'blk.lead': 'Blokkeer een account of een heel domein — hun reacties, likes en posts verdwijnen en nieuwe worden geweigerd.', 'blk.block_btn': 'Blokkeren', 'blk.empty': 'Niks geblokkeerd.', 'blk.unblock': 'Deblokkeren', 'tl.block': 'Blokkeer',
+    'notif.title': 'Meldingen', 'notif.empty': 'Nog geen meldingen.', 'notif.someone': 'Iemand', 'notif.followed': 'volgt je nu', 'notif.liked': 'likete je post', 'notif.boosted': 'boostte je post', 'notif.replied': 'reageerde op', 'notif.reported': 'rapporteerde je bij hun server', 'notif.mentioned': 'noemde je in een post', 'blk.title': 'Blokkeren', 'blk.lead': 'Blokkeer een account of een heel domein — hun reacties, likes en posts verdwijnen en nieuwe worden geweigerd.', 'blk.block_btn': 'Blokkeren', 'blk.empty': 'Niks geblokkeerd.', 'blk.unblock': 'Deblokkeren', 'tl.block': 'Blokkeer',
     'notif.reply': '{actor} reageerde op je reactie', 'notif.comment': '{actor} reageerde op je post', 'notif.like': '{actor} vindt je post leuk',
     'switch.agenda': 'Agenda',
@@ -959,5 +959,5 @@
     'nav.language': 'Language',
     'nav.notifications': 'Notifications',
-    'notif.title': 'Notifications', 'notif.empty': 'No notifications yet.', 'notif.someone': 'Someone', 'notif.followed': 'followed you', 'notif.liked': 'liked your post', 'notif.boosted': 'boosted your post', 'notif.replied': 'replied to', 'notif.reported': 'reported you to their server', 'blk.title': 'Blocking', 'blk.lead': 'Block an account or a whole domain — their replies, likes and posts disappear and new ones are refused.', 'blk.block_btn': 'Block', 'blk.empty': 'Nothing blocked.', 'blk.unblock': 'Unblock', 'tl.block': 'Block',
+    'notif.title': 'Notifications', 'notif.empty': 'No notifications yet.', 'notif.someone': 'Someone', 'notif.followed': 'followed you', 'notif.liked': 'liked your post', 'notif.boosted': 'boosted your post', 'notif.replied': 'replied to', 'notif.reported': 'reported you to their server', 'notif.mentioned': 'mentioned you in a post', 'blk.title': 'Blocking', 'blk.lead': 'Block an account or a whole domain — their replies, likes and posts disappear and new ones are refused.', 'blk.block_btn': 'Block', 'blk.empty': 'Nothing blocked.', 'blk.unblock': 'Unblock', 'tl.block': 'Block',
     'notif.reply': '{actor} replied to your comment', 'notif.comment': '{actor} commented on your post', 'notif.like': '{actor} liked your post',
     'switch.agenda': 'Agenda',
@@ -1881,5 +1881,5 @@
     'nav.language': 'Sprache',
     'nav.notifications': 'Benachrichtigungen',
-    'notif.title': 'Benachrichtigungen', 'notif.empty': 'Noch keine Benachrichtigungen.', 'notif.someone': 'Jemand', 'notif.followed': 'folgt dir jetzt', 'notif.liked': 'gefällt dein Beitrag', 'notif.boosted': 'teilte deinen Beitrag', 'notif.replied': 'antwortete auf', 'notif.reported': 'hat dich bei ihrem Server gemeldet', 'blk.title': 'Blockieren', 'blk.lead': 'Blockiere ein Konto oder eine ganze Domain — ihre Antworten, Likes und Beiträge verschwinden und neue werden abgelehnt.', 'blk.block_btn': 'Blockieren', 'blk.empty': 'Nichts blockiert.', 'blk.unblock': 'Entsperren', 'tl.block': 'Blockieren',
+    'notif.title': 'Benachrichtigungen', 'notif.empty': 'Noch keine Benachrichtigungen.', 'notif.someone': 'Jemand', 'notif.followed': 'folgt dir jetzt', 'notif.liked': 'gefällt dein Beitrag', 'notif.boosted': 'teilte deinen Beitrag', 'notif.replied': 'antwortete auf', 'notif.reported': 'hat dich bei ihrem Server gemeldet', 'notif.mentioned': 'hat dich in einem Beitrag erwähnt', 'blk.title': 'Blockieren', 'blk.lead': 'Blockiere ein Konto oder eine ganze Domain — ihre Antworten, Likes und Beiträge verschwinden und neue werden abgelehnt.', 'blk.block_btn': 'Blockieren', 'blk.empty': 'Nichts blockiert.', 'blk.unblock': 'Entsperren', 'tl.block': 'Blockieren',
     'notif.reply': '{actor} hat auf deinen Kommentar geantwortet', 'notif.comment': '{actor} hat deinen Beitrag kommentiert', 'notif.like': '{actor} gefällt dein Beitrag',
     'switch.agenda': 'Termine',
Index: src/views/pages/fedi-notifications.ejs
===================================================================
--- src/views/pages/fedi-notifications.ejs	(revision e00c0e9397ee0864f97459b36a39ff5ad86a9e41)
+++ src/views/pages/fedi-notifications.ejs	(revision fe97cc38d423c6b67d75cc07bab36c9ef2dd4f91)
@@ -7,5 +7,5 @@
     <ul class="nt-list">
       <% items.forEach(function(n){
-           var _ic = n.type === 'follow' ? 'follow' : (n.type === 'like' ? 'like' : (n.type === 'announce' ? 'boost' : (n.type === 'report' ? 'report' : 'reply')));
+           var _ic = n.type === 'follow' ? 'follow' : (n.type === 'like' ? 'like' : (n.type === 'announce' ? 'boost' : (n.type === 'report' ? 'report' : (n.type === 'mention' ? 'mention' : 'reply'))));
       %>
         <li class="nt-item nt-<%= _ic %>">
@@ -15,4 +15,5 @@
             <% } else if (_ic === 'follow') { %><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><line x1="19" y1="8" x2="19" y2="14"/><line x1="22" y1="11" x2="16" y2="11"/></svg>
             <% } else if (_ic === 'report') { %><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z"/><line x1="4" y1="22" x2="4" y2="15"/></svg>
+            <% } else if (_ic === 'mention') { %><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4"/><path d="M16 8v5a3 3 0 0 0 6 0v-1a10 10 0 1 0-3.92 7.94"/></svg>
             <% } else { %><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><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>
@@ -28,9 +29,11 @@
               <% } else if (n.type === 'announce') { %><%= t('notif.boosted') %>
               <% } else if (n.type === 'report') { %><%= t('notif.reported') %>
+              <% } else if (n.type === 'mention') { %><%= t('notif.mentioned') %>
               <% } else { %><%= t('notif.replied') %><% } %>
               <% if (n.post_slug) { %><a class="nt-post" href="/<%= n.post_slug %>"><%= n.post_title || n.post_slug %></a><% } %>
+              <% if (n.type === 'mention' && n.note_url) { %><a class="nt-post" href="<%= n.note_url %>" target="_blank" rel="nofollow noopener"><%= t('tl.view_original') %></a><% } %>
             </div>
             <% if (n.type === 'report' && n.content) { %><div class="nt-content"><%= n.content %></div>
-            <% } else if (n.type === 'reply' && n.content) { %><div class="nt-content"><%- n.content %></div><% } %>
+            <% } else if ((n.type === 'reply' || n.type === 'mention') && n.content) { %><div class="nt-content"><%- n.content %></div><% } %>
           </div>
         </li>
@@ -59,4 +62,5 @@
   .nt-follow .nt-icon, .nt-reply .nt-icon { background: color-mix(in srgb, var(--accent, #888) 16%, transparent); color: var(--accent, #06c); }
   .nt-report .nt-icon { background: color-mix(in srgb, #c0392b 16%, transparent); color: #c0392b; }
+  .nt-mention .nt-icon { background: color-mix(in srgb, #8e6cf0 16%, transparent); color: #8e6cf0; }
   .nt-body { flex: 1; min-width: 0; }
   .nt-line { display: flex; align-items: baseline; gap: .4rem; }
