Index: src/routes/posts.js
===================================================================
--- src/routes/posts.js	(revision 1c338045489f4392395fa5c08a753b440ea2e416)
+++ src/routes/posts.js	(revision adb6291578046e2adec69d0fd51408d163b671ed)
@@ -998,5 +998,5 @@
   const candidates = isHub
     ? db.prepare(`
-        SELECT p.id, p.slug, p.title, p.cover_image_url, p.published_at, p.tags, p.nsfw, p.content_warning, s.slug AS site_slug
+        SELECT p.id, p.slug, p.title, p.cover_image_url, p.cover_video_url, p.published_at, p.tags, p.nsfw, p.content_warning, s.slug AS site_slug
         FROM posts p JOIN sites s ON s.id = p.site_id
         WHERE p.status = 'published' AND p.id != ?
@@ -1004,5 +1004,5 @@
       `).all(post.id)
     : db.prepare(`
-        SELECT id, slug, title, cover_image_url, published_at, tags, nsfw, content_warning
+        SELECT id, slug, title, cover_image_url, cover_video_url, published_at, tags, nsfw, content_warning
         FROM posts
         WHERE site_id = ? AND status = 'published' AND id != ?
Index: src/routes/tags.js
===================================================================
--- src/routes/tags.js	(revision 1c338045489f4392395fa5c08a753b440ea2e416)
+++ src/routes/tags.js	(revision adb6291578046e2adec69d0fd51408d163b671ed)
@@ -22,5 +22,5 @@
   try {
     posts = db.prepare(`
-      SELECT DISTINCT p.id, p.slug, p.title, p.excerpt, p.cover_image_url,
+      SELECT DISTINCT p.id, p.slug, p.title, p.excerpt, p.cover_image_url, p.cover_video_url,
                       p.published_at, u.username AS author_username
       FROM posts p, json_each(p.tags) j
@@ -35,5 +35,5 @@
     // Fall back to a LIKE match if json_each isn't available for some reason
     posts = db.prepare(`
-      SELECT p.id, p.slug, p.title, p.excerpt, p.cover_image_url,
+      SELECT p.id, p.slug, p.title, p.excerpt, p.cover_image_url, p.cover_video_url,
              p.published_at, u.username AS author_username
       FROM posts p JOIN users u ON u.id = p.author_id
Index: src/routes/types.js
===================================================================
--- src/routes/types.js	(revision 1c338045489f4392395fa5c08a753b440ea2e416)
+++ src/routes/types.js	(revision adb6291578046e2adec69d0fd51408d163b671ed)
@@ -21,5 +21,5 @@
 
   const posts = db.prepare(`
-    SELECT p.id, p.slug, p.title, p.excerpt, p.cover_image_url,
+    SELECT p.id, p.slug, p.title, p.excerpt, p.cover_image_url, p.cover_video_url,
            p.published_at, p.type, u.username AS author_username
     FROM posts p JOIN users u ON u.id = p.author_id
Index: src/routes/users.js
===================================================================
--- src/routes/users.js	(revision 1c338045489f4392395fa5c08a753b440ea2e416)
+++ src/routes/users.js	(revision adb6291578046e2adec69d0fd51408d163b671ed)
@@ -27,5 +27,5 @@
 
   const posts = db.prepare(`
-    SELECT p.id, p.slug, p.title, p.excerpt, p.cover_image_url, p.published_at
+    SELECT p.id, p.slug, p.title, p.excerpt, p.cover_image_url, p.cover_video_url, p.published_at
     FROM posts p
     WHERE p.author_id = ? AND p.site_id = ? AND p.status = 'published'
Index: src/views/pages/post.ejs
===================================================================
--- src/views/pages/post.ejs	(revision 1c338045489f4392395fa5c08a753b440ea2e416)
+++ src/views/pages/post.ejs	(revision adb6291578046e2adec69d0fd51408d163b671ed)
@@ -182,5 +182,5 @@
                hx-push-url="/<%= rp.slug %>" hx-indicator="#pcms-loading"<% } %>>
               <% if (rp.cover_image_url) { %>
-                <span class="post-related-cover<%= rp.nsfw ? ' nsfw-media' : '' %>" aria-hidden="true"><img class="post-related-img" src="<%= rp.cover_image_url %>" alt="" loading="lazy" decoding="async"><% if (rp.nsfw) { %><span class="nsfw-veil"><span class="nsfw-veil-label">🔞 <%= rp.content_warning || t('post.nsfw_warning') %></span><span class="nsfw-veil-btn"><%= t('post.nsfw_show') %></span></span><% } %></span>
+                <span class="post-related-cover<%= rp.nsfw ? ' nsfw-media' : '' %>" aria-hidden="true"><img class="post-related-img" src="<%= rp.cover_image_url %>" alt="" loading="lazy" decoding="async"<% if (rp.cover_video_url) { %> data-ios-mp4="<%= rp.cover_video_url %>"<% } %>><% if (rp.nsfw) { %><span class="nsfw-veil"><span class="nsfw-veil-label">🔞 <%= rp.content_warning || t('post.nsfw_warning') %></span><span class="nsfw-veil-btn"><%= t('post.nsfw_show') %></span></span><% } %></span>
               <% } else { %>
                 <span class="post-related-cover post-related-cover--empty<%= rp.nsfw ? ' nsfw-media' : '' %>" aria-hidden="true"><% if (rp.nsfw) { %><span class="nsfw-veil"><span class="nsfw-veil-label">🔞 <%= rp.content_warning || t('post.nsfw_warning') %></span><span class="nsfw-veil-btn"><%= t('post.nsfw_show') %></span></span><% } %></span>
Index: src/views/partials/post-card.ejs
===================================================================
--- src/views/partials/post-card.ejs	(revision 1c338045489f4392395fa5c08a753b440ea2e416)
+++ src/views/partials/post-card.ejs	(revision adb6291578046e2adec69d0fd51408d163b671ed)
@@ -52,5 +52,5 @@
            srcset="<%= thumb(post.cover_image_url, 320) %> 320w, <%= thumb(post.cover_image_url, 640) %> 640w, <%= thumb(post.cover_image_url, 1280) %> 1280w"
            sizes="(min-width: 768px) 120px, 100vw"
-           alt="" loading="lazy" decoding="async">
+           alt="" loading="lazy" decoding="async"<% if (post.cover_video_url) { %> data-ios-mp4="<%= post.cover_video_url %>"<% } %>>
       <% if (post.nsfw) { %><span class="nsfw-veil"><span class="nsfw-veil-label">🔞 <%= post.content_warning || t('post.nsfw_warning') %></span><span class="nsfw-veil-btn"><%= t('post.nsfw_show') %></span></span><% } %>
     </a>
Index: src/views/partials/post-tile.ejs
===================================================================
--- src/views/partials/post-tile.ejs	(revision 1c338045489f4392395fa5c08a753b440ea2e416)
+++ src/views/partials/post-tile.ejs	(revision adb6291578046e2adec69d0fd51408d163b671ed)
@@ -19,5 +19,5 @@
    <% if (_ext) { %>target="_blank" rel="noopener"<% } else { %>hx-get="<%= _href %>?partial=1" hx-target="#pcms-main" hx-swap="innerHTML" hx-push-url="<%= _href %>" hx-indicator="#pcms-loading"<% } %>>
 
-  <% if (_hasCover) { %><img class="grid-tile-img" src="<%= thumb(post.cover_image_url, 480) %>" alt="" loading="lazy" decoding="async"><% } %>
+  <% if (_hasCover) { %><img class="grid-tile-img" src="<%= thumb(post.cover_image_url, 480) %>" alt="" loading="lazy" decoding="async"<% if (post.cover_video_url) { %> data-ios-mp4="<%= post.cover_video_url %>"<% } %>><% } %>
 
   <% if (_typeLabel) { %>
