Index: src/config/database.js
===================================================================
--- src/config/database.js	(revision c7ecaf9d21f6baddcb99a2593e829187df0baacc)
+++ src/config/database.js	(revision 9d3485567cfa5e63e210609b3bb7ec38ec905976)
@@ -414,4 +414,5 @@
   // A timeline post you boosted (🔁) — also shown in the Cirkel (mixed by date).
   ensureColumn('ap_timeline', 'boosted', 'INTEGER DEFAULT 0');
+  ensureColumn('ap_timeline', 'liked', 'INTEGER DEFAULT 0'); // a feed post you liked (⭐) → toggle
 }
 
Index: src/routes/posts.js
===================================================================
--- src/routes/posts.js	(revision c7ecaf9d21f6baddcb99a2593e829187df0baacc)
+++ src/routes/posts.js	(revision 9d3485567cfa5e63e210609b3bb7ec38ec905976)
@@ -695,6 +695,20 @@
 router.post('/news/like', requireSiteManager, async (req, res) => {
   const site = res.locals.site;
-  if (site) { try { await ActivityPubService.sendInteraction(site, 'like', (req.body.note || '').toString(), (req.body.author || '').toString()); } catch (e) { /* ignore */ } }
+  const note = (req.body.note || '').toString();
+  if (site && note) {
+    try { await ActivityPubService.sendInteraction(site, 'like', note, (req.body.author || '').toString()); } catch (e) { /* ignore */ }
+    ActivityPubService.markLiked(site.slug, note);
+  }
   res.redirect('/news?success=' + encodeURIComponent('Geliket ⭐'));
+});
+
+router.post('/news/unlike', requireSiteManager, async (req, res) => {
+  const site = res.locals.site;
+  const note = (req.body.note || '').toString();
+  if (site && note) {
+    try { await ActivityPubService.sendInteraction(site, 'unlike', note, (req.body.author || '').toString()); } catch (e) { /* ignore */ }
+    ActivityPubService.unmarkLiked(site.slug, note);
+  }
+  res.redirect('/news?success=' + encodeURIComponent('Like ingetrokken'));
 });
 
Index: src/services/ActivityPubService.js
===================================================================
--- src/services/ActivityPubService.js	(revision c7ecaf9d21f6baddcb99a2593e829187df0baacc)
+++ src/services/ActivityPubService.js	(revision 9d3485567cfa5e63e210609b3bb7ec38ec905976)
@@ -1099,4 +1099,11 @@
   try { if (!_unmarkBoost) _unmarkBoost = db.prepare('UPDATE ap_timeline SET boosted = 0 WHERE slug = ? AND id = ?'); _unmarkBoost.run(slug, noteId); } catch { /* ignore */ }
 }
+let _markLike, _unmarkLike;
+export function markLiked(slug, noteId) {
+  try { if (!_markLike) _markLike = db.prepare('UPDATE ap_timeline SET liked = 1 WHERE slug = ? AND id = ?'); _markLike.run(slug, noteId); } catch { /* ignore */ }
+}
+export function unmarkLiked(slug, noteId) {
+  try { if (!_unmarkLike) _unmarkLike = db.prepare('UPDATE ap_timeline SET liked = 0 WHERE slug = ? AND id = ?'); _unmarkLike.run(slug, noteId); } catch { /* ignore */ }
+}
 export function boostedCount(slug) {
   try { if (!_boostedCount) _boostedCount = db.prepare('SELECT COUNT(*) AS n FROM ap_timeline WHERE slug = ? AND boosted = 1'); return _boostedCount.get(slug).n; } catch { return 0; }
@@ -1349,5 +1356,5 @@
   listOutbox, deliverOutboxDelete,
   webfingerResolve, followActor, resolveRemoteActor, unfollowActor, listFollowing, setAutoBoost, getTimeline, sendInteraction,
-  autoBoostCount, boostedCount, markBoosted, unmarkBoosted, getCirkelPosts, getCirkelMembers, selfHealTimeline,
+  autoBoostCount, boostedCount, markBoosted, unmarkBoosted, markLiked, unmarkLiked, getCirkelPosts, getCirkelMembers, selfHealTimeline,
   getNotifications, listBlocks, isBlockedAny, blockTarget, unblock,
   deliverWithRetry, enqueueDelivery, processDeliveryQueue, startDeliveryWorker,
Index: src/views/pages/news.ejs
===================================================================
--- src/views/pages/news.ejs	(revision c7ecaf9d21f6baddcb99a2593e829187df0baacc)
+++ src/views/pages/news.ejs	(revision 9d3485567cfa5e63e210609b3bb7ec38ec905976)
@@ -47,5 +47,9 @@
 
           <div class="tl-actions">
+            <% if (p.liked) { %>
+            <form method="post" action="/news/unlike" class="tl-act-form"><input type="hidden" name="note" value="<%= p.id %>"><input type="hidden" name="author" value="<%= p.author_uri %>"><button type="submit" class="tl-act tl-act-like is-on" title="<%= t('fedi.unlike_short') %>" aria-label="<%= t('fedi.unlike_short') %>"><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2.6l2.9 5.88 6.49.95-4.7 4.58 1.11 6.46L12 17.96l-5.8 3.06 1.1-6.46-4.69-4.58 6.49-.95z"/></svg></button></form>
+            <% } else { %>
             <form method="post" action="/news/like" class="tl-act-form"><input type="hidden" name="note" value="<%= p.id %>"><input type="hidden" name="author" value="<%= p.author_uri %>"><button type="submit" class="tl-act tl-act-like" title="<%= t('fedi.likes') %>" aria-label="<%= t('fedi.likes') %>"><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2.6l2.9 5.88 6.49.95-4.7 4.58 1.11 6.46L12 17.96l-5.8 3.06 1.1-6.46-4.69-4.58 6.49-.95z"/></svg></button></form>
+            <% } %>
             <% if (p.boosted) { %>
             <form method="post" action="/news/unboost" class="tl-act-form"><input type="hidden" name="note" value="<%= p.id %>"><input type="hidden" name="author" value="<%= p.author_uri %>"><button type="submit" class="tl-act tl-act-boost is-on" title="<%= t('tl.unboost') %>" aria-label="<%= t('tl.unboost') %>"><svg viewBox="0 0 24 24" 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></button></form>
@@ -126,4 +130,5 @@
   .tl-act-like svg { color: #e8b04b; }
   .tl-act-like:hover { background: color-mix(in srgb, #e8b04b 15%, transparent); border-color: color-mix(in srgb, #e8b04b 50%, transparent); }
+  .tl-act-like.is-on { background: color-mix(in srgb, #e8b04b 18%, transparent); border-color: color-mix(in srgb, #e8b04b 60%, transparent); }
   .tl-act-boost svg { color: #2fa85a; }
   .tl-act-boost:hover { background: color-mix(in srgb, #2fa85a 15%, transparent); border-color: color-mix(in srgb, #2fa85a 50%, transparent); }
