Index: src/views/shell.ejs
===================================================================
--- src/views/shell.ejs	(revision b31c119f550d2891a319fb2dc32de54376ff864e)
+++ src/views/shell.ejs	(revision 366c13c2c490f6a154586f546de8750b9d6d5978)
@@ -772,4 +772,17 @@
 })();
 
+// Light anti-grab friction: suppress the right-click menu on visual media (covers, images,
+// videos) so the art isn't one right-click away from "Save as". Friction, NOT protection —
+// the files are public and reachable via devtools/network. Middle/Ctrl-click (open in new
+// tab) still works; only the context menu is blocked. Delegated → covers htmx-swapped content.
+(function () {
+  if (window.__noMediaCtxWired) return; window.__noMediaCtxWired = true;
+  document.addEventListener('contextmenu', function (e) {
+    if (e.target.closest('img, video, .grid-tile, .post-list-cover, .post-cover, .tl-media-img')) {
+      e.preventDefault();
+    }
+  });
+})();
+
 // iOS animated-cover → video: an animated WebP is janky on iOS Safari, so on iOS we swap any
 // <img data-ios-mp4="…"> for a muted, looping, inline <video> (the WebP's matching MP4). Every
