Index: src/views/pages/admin.ejs
===================================================================
--- src/views/pages/admin.ejs	(revision 7eee4495b816d92c1498fd902970e1140a6a46dc)
+++ src/views/pages/admin.ejs	(revision eefd30286365ba17e55cb461eb4f00242982db11)
@@ -55,5 +55,5 @@
     <% } %>
     <% if (typeof apEnabled === 'undefined' || apEnabled) { %>
-      <a href="/newspaper" class="btn">🌐 <%= t('tl.title') %></a>
+      <a href="/news" class="btn">🌐 <%= t('tl.title') %></a>
       <a href="/notifications" class="btn">🔔 <%= t('notif.title') %></a>
       <a href="/fediverse" class="btn">🐘 <%= t('admin.b_fediverse') %></a>
Index: src/views/pages/following.ejs
===================================================================
--- src/views/pages/following.ejs	(revision 7eee4495b816d92c1498fd902970e1140a6a46dc)
+++ src/views/pages/following.ejs	(revision eefd30286365ba17e55cb461eb4f00242982db11)
@@ -9,5 +9,5 @@
   </div>
 
-  <form method="post" action="/newspaper/follow" class="tl-follow">
+  <form method="post" action="/news/follow" class="tl-follow">
     <input type="text" name="handle" placeholder="@naam@server.social of site.com" autocomplete="off" spellcheck="false" required>
     <button type="submit" class="btn btn-primary"><%= t('tl.follow_btn') %></button>
@@ -26,9 +26,9 @@
             <% if (f.status === 'pending') { %><span class="tl-pending"><%= t('tl.pending') %></span><% } %>
           </span>
-          <form method="post" action="/newspaper/autoboost" class="tl-foll-ab" title="<%= t('tl.autoboost_hint') %>">
+          <form method="post" action="/news/autoboost" class="tl-foll-ab" title="<%= t('tl.autoboost_hint') %>">
             <input type="hidden" name="actor_uri" value="<%= f.actor_uri %>">
             <label><input type="checkbox" name="auto_boost" value="1" <%= f.auto_boost ? 'checked' : '' %> onchange="this.form.submit()"> ✨ <%= t('tl.autoboost') %></label>
           </form>
-          <form method="post" action="/newspaper/unfollow"><input type="hidden" name="actor_uri" value="<%= f.actor_uri %>"><button type="submit" class="tl-unfollow"><%= t('tl.unfollow') %></button></form>
+          <form method="post" action="/news/unfollow"><input type="hidden" name="actor_uri" value="<%= f.actor_uri %>"><button type="submit" class="tl-unfollow"><%= t('tl.unfollow') %></button></form>
         </li>
       <% }); %>
Index: src/views/pages/news.ejs
===================================================================
--- src/views/pages/news.ejs	(revision eefd30286365ba17e55cb461eb4f00242982db11)
+++ src/views/pages/news.ejs	(revision eefd30286365ba17e55cb461eb4f00242982db11)
@@ -0,0 +1,165 @@
+<div class="tl-wrap">
+  <%- include('../partials/fedi-tabs', { active: 'feed' }) %>
+  <h1 class="tl-title"><%= t('tl.title') %></h1>
+  <p class="tl-lead"><%= t('tl.lead') %></p>
+  <% if (typeof success !== 'undefined' && success) { %><div class="alert alert-success"><%= success %></div><% } %>
+  <% if (typeof error !== 'undefined' && error) { %><div class="alert alert-error"><%= error %></div><% } %>
+
+  <% if (!timeline || !timeline.length) { %>
+    <div class="tl-empty">
+      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><line x1="8.59" y1="13.51" x2="15.42" y2="17.49"/><line x1="15.41" y1="6.51" x2="8.59" y2="10.49"/></svg>
+      <p><%= t('tl.empty') %></p>
+    </div>
+  <% } else { %>
+    <ol class="tl-feed">
+      <% timeline.forEach(function(p){ %>
+        <li class="tl-item">
+          <div class="tl-head">
+            <span class="tl-avatar"><% if (p.author_icon) { %><img src="<%= p.author_icon %>" alt="" loading="lazy"><% } else { %><%= (p.author_name || '?').charAt(0).toUpperCase() %><% } %></span>
+            <span class="tl-id">
+              <a class="tl-author" href="<%= p.author_url || p.author_uri %>" target="_blank" rel="nofollow noopener"><%= p.author_name %></a>
+              <span class="tl-handle"><%= p.author_handle %></span>
+            </span>
+            <% if (p.published || p.created_at) { %><time class="tl-time"><%= formatDateTime(p.published || p.created_at) %></time><% } %>
+          </div>
+
+          <div class="tl-content"><%- p.content %></div>
+
+          <%
+            var media = []; try { media = JSON.parse(p.media_json || '[]'); } catch (e) { media = []; }
+            var imgs = media.filter(function(m){ return m && m.url && (!m.type || /^image\//.test(m.type)); });
+            var vids = media.filter(function(m){ return m && m.url && m.type && /^video\//.test(m.type); });
+            var auds = media.filter(function(m){ return m && m.url && m.type && /^audio\//.test(m.type); });
+          %>
+          <% if (imgs.length) { %>
+            <div class="tl-media">
+              <% imgs.forEach(function(m){ %>
+                <a class="tl-media-img" href="<%= m.url %>" target="_blank" rel="noopener"><img src="<%= m.url %>" alt="" loading="lazy" decoding="async"></a>
+              <% }); %>
+            </div>
+          <% } %>
+          <% vids.forEach(function(m){ %><video class="tl-media-video" src="<%= m.url %>" controls preload="metadata" playsinline></video><% }); %>
+          <% auds.forEach(function(m){ %><audio class="tl-media-audio" src="<%= m.url %>" controls preload="none"></audio><% }); %>
+
+          <% if (p.embedHtml) { %><div class="tl-embed"><%- p.embedHtml %></div><% } %>
+
+          <% if (p.url) { %><a class="tl-orig" href="<%= p.url %>" target="_blank" rel="nofollow noopener"><%= t('tl.view_original') %></a><% } %>
+
+          <div class="tl-actions">
+            <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>
+            <% } else { %>
+            <form method="post" action="/news/boost" 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" title="<%= t('fedi.boosts') %>" aria-label="<%= t('fedi.boosts') %>"><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>
+            <% } %>
+            <button type="button" class="tl-act tl-act-reply fedi-remote-reply-btn" data-fedi-uri="<%= p.id %>" data-fedi-ph="<%= t('fedi.remote_ph') %>" title="<%= t('fedi.remote_reply') %>" aria-label="<%= t('fedi.remote_reply') %>"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="9 17 4 12 9 7"/><path d="M20 18v-2a4 4 0 0 0-4-4H4"/></svg></button>
+            <form method="post" action="/blocking/add" class="tl-act-form" onsubmit="return confirm('<%= t('tl.block') %>?');"><input type="hidden" name="target" value="<%= p.author_uri %>"><button type="submit" class="tl-act tl-act-block" title="<%= t('tl.block') %>" aria-label="<%= t('tl.block') %>"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"/><line x1="4.9" y1="4.9" x2="19.1" y2="19.1"/></svg></button></form>
+          </div>
+        </li>
+      <% }); %>
+    </ol>
+  <% } %>
+</div>
+
+<style>
+  .tl-wrap { max-width: 640px; margin: 1rem auto 3rem; padding: 0 1rem; }
+  .tl-title { margin: 0 0 .15rem; font-size: clamp(1.5rem, 4vw, 1.8rem); }
+  .tl-lead { color: var(--ink-soft, #888); margin: 0 0 1.5rem; }
+  .tl-empty { text-align: center; color: var(--ink-soft, #888); margin: 3rem auto; }
+  .tl-empty svg { width: 44px; height: 44px; color: color-mix(in srgb, var(--accent, #888) 60%, transparent); margin: 0 auto .75rem; display: block; }
+
+  .tl-feed { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 1rem; }
+  .tl-item { padding: 1.1rem 1.15rem; border-radius: 16px;
+    border: 1px solid color-mix(in srgb, var(--ink, #000) 8%, transparent);
+    background: color-mix(in srgb, var(--ink, #000) 2.5%, transparent);
+    transition: border-color .15s ease, box-shadow .15s ease; }
+  .tl-item:hover { border-color: color-mix(in srgb, var(--accent, #888) 32%, transparent);
+    box-shadow: 0 2px 14px color-mix(in srgb, var(--ink, #000) 6%, transparent); }
+
+  .tl-head { display: flex; align-items: center; gap: .65rem; margin: 0 0 .65rem; }
+  .tl-avatar { flex: 0 0 44px; width: 44px; height: 44px; border-radius: 50%; overflow: hidden;
+    display: inline-flex; align-items: center; justify-content: center; font-weight: 700; font-size: 1.1rem;
+    background: color-mix(in srgb, var(--accent, #888) 22%, transparent); color: var(--accent, #555);
+    box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent, #888) 18%, transparent); }
+  .tl-avatar img { width: 100%; height: 100%; object-fit: cover; background: #fff; }
+  .tl-id { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.25; }
+  .tl-author { font-weight: 700; color: var(--ink, inherit); text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
+  .tl-author:hover { text-decoration: underline; }
+  .tl-handle { color: var(--ink-soft, #888); font-size: .82rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
+  .tl-time { color: var(--ink-soft, #999); font-size: .78rem; flex: 0 0 auto; align-self: flex-start; white-space: nowrap; }
+
+  .tl-content { line-height: 1.55; overflow-wrap: anywhere; }
+  .tl-content p { margin: .4rem 0; } .tl-content p:first-child { margin-top: 0; } .tl-content p:last-child { margin-bottom: 0; }
+  .tl-content a { color: var(--accent, #06c); }
+  .tl-content img { max-width: 100%; height: auto; border-radius: 10px; background: #fff; }
+
+  /* Always show the FULL image at its natural ratio — never cropped, no letterbox. */
+  .tl-media { display: flex; flex-direction: column; gap: .4rem; margin: .75rem 0 0; }
+  .tl-media-img { display: block; border-radius: 12px; overflow: hidden; background: #fff; }
+  .tl-media-img img { width: 100%; height: auto; display: block; }
+
+  .tl-media-video, .tl-media-audio { width: 100%; margin: .75rem 0 0; border-radius: 12px; display: block; }
+  .tl-media-video { max-height: 480px; background: #000; }
+
+  .tl-embed { margin: .75rem 0 0; border-radius: 12px; overflow: hidden; background: var(--paper-2, #111); }
+  .tl-embed-frame { width: 100%; border: 0; display: block; aspect-ratio: 16 / 9; }
+  .tl-embed-spotify { aspect-ratio: auto; height: 152px; }
+  .tl-embed-sc { aspect-ratio: auto; height: 166px; }
+  .tl-embed-klonkt { aspect-ratio: auto; height: 180px; background: var(--paper, #fff); }
+  .tl-embed-bandcamp { aspect-ratio: auto; height: 470px; }
+  .tl-embed-apple { aspect-ratio: auto; height: 175px; }
+
+  .tl-orig { display: inline-block; margin: .7rem 0 0; font-size: .82rem; color: var(--accent, #06c); text-decoration: none; }
+  .tl-orig:hover { text-decoration: underline; }
+
+  /* Uniform circular action buttons with coloured icons (no emoji). */
+  .tl-actions { display: flex; gap: .5rem; margin-top: .9rem; align-items: center; }
+  .tl-act-form { margin: 0; display: inline-flex; }
+  .tl-act { width: 36px; height: 36px; flex: 0 0 36px; border-radius: 50%; padding: 0; box-sizing: border-box;
+    display: inline-flex; align-items: center; justify-content: center;
+    border: 1px solid color-mix(in srgb, var(--ink, #000) 12%, transparent);
+    background: color-mix(in srgb, var(--ink, #000) 3%, transparent);
+    color: var(--ink-soft, #888); cursor: pointer; -webkit-tap-highlight-color: transparent;
+    transition: background .12s, border-color .12s, transform .1s; }
+  .tl-act svg { width: 18px; height: 18px; display: block; }
+  .tl-act:active { transform: scale(.9); }
+  .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-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); }
+  .tl-act-boost.is-on { background: color-mix(in srgb, #2fa85a 18%, transparent); border-color: color-mix(in srgb, #2fa85a 60%, transparent); }
+  .tl-act-reply svg { color: var(--accent, #06c); }
+  .tl-act-reply:hover { background: color-mix(in srgb, var(--accent, #888) 14%, transparent); border-color: color-mix(in srgb, var(--accent, #888) 50%, transparent); }
+  .tl-act-block svg { color: #e0524d; }
+  .tl-act-block:hover { background: color-mix(in srgb, #d9534f 14%, transparent); border-color: color-mix(in srgb, #d9534f 50%, transparent); }
+</style>
+
+<script>
+(function(){
+  if (window.__fediRemoteWired) return; window.__fediRemoteWired = true;
+  var current = null, currentBtn = null;
+  function close(){ if (current) { current.remove(); current = null; currentBtn = null; } }
+  function go(raw, uri){ var d=(raw||'').trim().replace(/^@?[^@\s]*@/,'').replace(/^https?:\/\//i,'').replace(/\/.*$/,'').trim(); if(d){ try{ localStorage.setItem('pcmsFediServer', d); }catch(e){} location.href='https://'+d+'/authorize_interaction?uri='+encodeURIComponent(uri||''); } }
+  function place(f, b){ var r=b.getBoundingClientRect(); f.style.top=(r.bottom+window.scrollY+6)+'px'; f.style.left=Math.max(8, Math.min(r.left+window.scrollX, window.scrollX+window.innerWidth-340))+'px'; }
+  document.addEventListener('click', function(e){
+    if (e.target.closest && e.target.closest('.fedi-remote-cancel')) { close(); return; }
+    if (current && e.target.closest && e.target.closest('.fedi-remote-form')) return;
+    var b = e.target.closest && e.target.closest('.fedi-remote-reply-btn');
+    if (b) {
+      e.preventDefault();
+      if (currentBtn === b) { close(); return; }
+      close();
+      var f = document.createElement('form'); f.className='fedi-remote-form'; f.dataset.uri = b.getAttribute('data-fedi-uri')||'';
+      f.innerHTML = '<input type="text" autocomplete="off" spellcheck="false"><button type="submit" class="btn btn-primary fedi-remote-go" aria-label="ok">&rarr;</button><button type="button" class="fedi-remote-cancel" aria-label="x">&times;</button>';
+      var _inp = f.querySelector('input'); _inp.placeholder = b.getAttribute('data-fedi-ph') || 'mastodon.social';
+      try{ var _sv = localStorage.getItem('pcmsFediServer'); if(_sv) _inp.value = _sv; }catch(e){}
+      document.body.appendChild(f); place(f, b); current=f; currentBtn=b; _inp.focus(); _inp.select();
+      return;
+    }
+    if (current) close();
+  });
+  document.addEventListener('submit', function(e){ var f=e.target.closest && e.target.closest('.fedi-remote-form'); if(!f) return; e.preventDefault(); go(f.querySelector('input').value, f.dataset.uri); });
+  document.addEventListener('keydown', function(e){ if (e.key === 'Escape') close(); });
+  window.addEventListener('scroll', close, true);
+})();
+</script>
Index: src/views/pages/newspaper.ejs
===================================================================
--- src/views/pages/newspaper.ejs	(revision 7eee4495b816d92c1498fd902970e1140a6a46dc)
+++ 	(revision )
@@ -1,165 +1,0 @@
-<div class="tl-wrap">
-  <%- include('../partials/fedi-tabs', { active: 'feed' }) %>
-  <h1 class="tl-title"><%= t('tl.title') %></h1>
-  <p class="tl-lead"><%= t('tl.lead') %></p>
-  <% if (typeof success !== 'undefined' && success) { %><div class="alert alert-success"><%= success %></div><% } %>
-  <% if (typeof error !== 'undefined' && error) { %><div class="alert alert-error"><%= error %></div><% } %>
-
-  <% if (!timeline || !timeline.length) { %>
-    <div class="tl-empty">
-      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><line x1="8.59" y1="13.51" x2="15.42" y2="17.49"/><line x1="15.41" y1="6.51" x2="8.59" y2="10.49"/></svg>
-      <p><%= t('tl.empty') %></p>
-    </div>
-  <% } else { %>
-    <ol class="tl-feed">
-      <% timeline.forEach(function(p){ %>
-        <li class="tl-item">
-          <div class="tl-head">
-            <span class="tl-avatar"><% if (p.author_icon) { %><img src="<%= p.author_icon %>" alt="" loading="lazy"><% } else { %><%= (p.author_name || '?').charAt(0).toUpperCase() %><% } %></span>
-            <span class="tl-id">
-              <a class="tl-author" href="<%= p.author_url || p.author_uri %>" target="_blank" rel="nofollow noopener"><%= p.author_name %></a>
-              <span class="tl-handle"><%= p.author_handle %></span>
-            </span>
-            <% if (p.published || p.created_at) { %><time class="tl-time"><%= formatDateTime(p.published || p.created_at) %></time><% } %>
-          </div>
-
-          <div class="tl-content"><%- p.content %></div>
-
-          <%
-            var media = []; try { media = JSON.parse(p.media_json || '[]'); } catch (e) { media = []; }
-            var imgs = media.filter(function(m){ return m && m.url && (!m.type || /^image\//.test(m.type)); });
-            var vids = media.filter(function(m){ return m && m.url && m.type && /^video\//.test(m.type); });
-            var auds = media.filter(function(m){ return m && m.url && m.type && /^audio\//.test(m.type); });
-          %>
-          <% if (imgs.length) { %>
-            <div class="tl-media">
-              <% imgs.forEach(function(m){ %>
-                <a class="tl-media-img" href="<%= m.url %>" target="_blank" rel="noopener"><img src="<%= m.url %>" alt="" loading="lazy" decoding="async"></a>
-              <% }); %>
-            </div>
-          <% } %>
-          <% vids.forEach(function(m){ %><video class="tl-media-video" src="<%= m.url %>" controls preload="metadata" playsinline></video><% }); %>
-          <% auds.forEach(function(m){ %><audio class="tl-media-audio" src="<%= m.url %>" controls preload="none"></audio><% }); %>
-
-          <% if (p.embedHtml) { %><div class="tl-embed"><%- p.embedHtml %></div><% } %>
-
-          <% if (p.url) { %><a class="tl-orig" href="<%= p.url %>" target="_blank" rel="nofollow noopener"><%= t('tl.view_original') %></a><% } %>
-
-          <div class="tl-actions">
-            <form method="post" action="/newspaper/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="/newspaper/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>
-            <% } else { %>
-            <form method="post" action="/newspaper/boost" 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" title="<%= t('fedi.boosts') %>" aria-label="<%= t('fedi.boosts') %>"><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>
-            <% } %>
-            <button type="button" class="tl-act tl-act-reply fedi-remote-reply-btn" data-fedi-uri="<%= p.id %>" data-fedi-ph="<%= t('fedi.remote_ph') %>" title="<%= t('fedi.remote_reply') %>" aria-label="<%= t('fedi.remote_reply') %>"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="9 17 4 12 9 7"/><path d="M20 18v-2a4 4 0 0 0-4-4H4"/></svg></button>
-            <form method="post" action="/blocking/add" class="tl-act-form" onsubmit="return confirm('<%= t('tl.block') %>?');"><input type="hidden" name="target" value="<%= p.author_uri %>"><button type="submit" class="tl-act tl-act-block" title="<%= t('tl.block') %>" aria-label="<%= t('tl.block') %>"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"/><line x1="4.9" y1="4.9" x2="19.1" y2="19.1"/></svg></button></form>
-          </div>
-        </li>
-      <% }); %>
-    </ol>
-  <% } %>
-</div>
-
-<style>
-  .tl-wrap { max-width: 640px; margin: 1rem auto 3rem; padding: 0 1rem; }
-  .tl-title { margin: 0 0 .15rem; font-size: clamp(1.5rem, 4vw, 1.8rem); }
-  .tl-lead { color: var(--ink-soft, #888); margin: 0 0 1.5rem; }
-  .tl-empty { text-align: center; color: var(--ink-soft, #888); margin: 3rem auto; }
-  .tl-empty svg { width: 44px; height: 44px; color: color-mix(in srgb, var(--accent, #888) 60%, transparent); margin: 0 auto .75rem; display: block; }
-
-  .tl-feed { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 1rem; }
-  .tl-item { padding: 1.1rem 1.15rem; border-radius: 16px;
-    border: 1px solid color-mix(in srgb, var(--ink, #000) 8%, transparent);
-    background: color-mix(in srgb, var(--ink, #000) 2.5%, transparent);
-    transition: border-color .15s ease, box-shadow .15s ease; }
-  .tl-item:hover { border-color: color-mix(in srgb, var(--accent, #888) 32%, transparent);
-    box-shadow: 0 2px 14px color-mix(in srgb, var(--ink, #000) 6%, transparent); }
-
-  .tl-head { display: flex; align-items: center; gap: .65rem; margin: 0 0 .65rem; }
-  .tl-avatar { flex: 0 0 44px; width: 44px; height: 44px; border-radius: 50%; overflow: hidden;
-    display: inline-flex; align-items: center; justify-content: center; font-weight: 700; font-size: 1.1rem;
-    background: color-mix(in srgb, var(--accent, #888) 22%, transparent); color: var(--accent, #555);
-    box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent, #888) 18%, transparent); }
-  .tl-avatar img { width: 100%; height: 100%; object-fit: cover; background: #fff; }
-  .tl-id { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.25; }
-  .tl-author { font-weight: 700; color: var(--ink, inherit); text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
-  .tl-author:hover { text-decoration: underline; }
-  .tl-handle { color: var(--ink-soft, #888); font-size: .82rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
-  .tl-time { color: var(--ink-soft, #999); font-size: .78rem; flex: 0 0 auto; align-self: flex-start; white-space: nowrap; }
-
-  .tl-content { line-height: 1.55; overflow-wrap: anywhere; }
-  .tl-content p { margin: .4rem 0; } .tl-content p:first-child { margin-top: 0; } .tl-content p:last-child { margin-bottom: 0; }
-  .tl-content a { color: var(--accent, #06c); }
-  .tl-content img { max-width: 100%; height: auto; border-radius: 10px; background: #fff; }
-
-  /* Always show the FULL image at its natural ratio — never cropped, no letterbox. */
-  .tl-media { display: flex; flex-direction: column; gap: .4rem; margin: .75rem 0 0; }
-  .tl-media-img { display: block; border-radius: 12px; overflow: hidden; background: #fff; }
-  .tl-media-img img { width: 100%; height: auto; display: block; }
-
-  .tl-media-video, .tl-media-audio { width: 100%; margin: .75rem 0 0; border-radius: 12px; display: block; }
-  .tl-media-video { max-height: 480px; background: #000; }
-
-  .tl-embed { margin: .75rem 0 0; border-radius: 12px; overflow: hidden; background: var(--paper-2, #111); }
-  .tl-embed-frame { width: 100%; border: 0; display: block; aspect-ratio: 16 / 9; }
-  .tl-embed-spotify { aspect-ratio: auto; height: 152px; }
-  .tl-embed-sc { aspect-ratio: auto; height: 166px; }
-  .tl-embed-klonkt { aspect-ratio: auto; height: 180px; background: var(--paper, #fff); }
-  .tl-embed-bandcamp { aspect-ratio: auto; height: 470px; }
-  .tl-embed-apple { aspect-ratio: auto; height: 175px; }
-
-  .tl-orig { display: inline-block; margin: .7rem 0 0; font-size: .82rem; color: var(--accent, #06c); text-decoration: none; }
-  .tl-orig:hover { text-decoration: underline; }
-
-  /* Uniform circular action buttons with coloured icons (no emoji). */
-  .tl-actions { display: flex; gap: .5rem; margin-top: .9rem; align-items: center; }
-  .tl-act-form { margin: 0; display: inline-flex; }
-  .tl-act { width: 36px; height: 36px; flex: 0 0 36px; border-radius: 50%; padding: 0; box-sizing: border-box;
-    display: inline-flex; align-items: center; justify-content: center;
-    border: 1px solid color-mix(in srgb, var(--ink, #000) 12%, transparent);
-    background: color-mix(in srgb, var(--ink, #000) 3%, transparent);
-    color: var(--ink-soft, #888); cursor: pointer; -webkit-tap-highlight-color: transparent;
-    transition: background .12s, border-color .12s, transform .1s; }
-  .tl-act svg { width: 18px; height: 18px; display: block; }
-  .tl-act:active { transform: scale(.9); }
-  .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-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); }
-  .tl-act-boost.is-on { background: color-mix(in srgb, #2fa85a 18%, transparent); border-color: color-mix(in srgb, #2fa85a 60%, transparent); }
-  .tl-act-reply svg { color: var(--accent, #06c); }
-  .tl-act-reply:hover { background: color-mix(in srgb, var(--accent, #888) 14%, transparent); border-color: color-mix(in srgb, var(--accent, #888) 50%, transparent); }
-  .tl-act-block svg { color: #e0524d; }
-  .tl-act-block:hover { background: color-mix(in srgb, #d9534f 14%, transparent); border-color: color-mix(in srgb, #d9534f 50%, transparent); }
-</style>
-
-<script>
-(function(){
-  if (window.__fediRemoteWired) return; window.__fediRemoteWired = true;
-  var current = null, currentBtn = null;
-  function close(){ if (current) { current.remove(); current = null; currentBtn = null; } }
-  function go(raw, uri){ var d=(raw||'').trim().replace(/^@?[^@\s]*@/,'').replace(/^https?:\/\//i,'').replace(/\/.*$/,'').trim(); if(d){ try{ localStorage.setItem('pcmsFediServer', d); }catch(e){} location.href='https://'+d+'/authorize_interaction?uri='+encodeURIComponent(uri||''); } }
-  function place(f, b){ var r=b.getBoundingClientRect(); f.style.top=(r.bottom+window.scrollY+6)+'px'; f.style.left=Math.max(8, Math.min(r.left+window.scrollX, window.scrollX+window.innerWidth-340))+'px'; }
-  document.addEventListener('click', function(e){
-    if (e.target.closest && e.target.closest('.fedi-remote-cancel')) { close(); return; }
-    if (current && e.target.closest && e.target.closest('.fedi-remote-form')) return;
-    var b = e.target.closest && e.target.closest('.fedi-remote-reply-btn');
-    if (b) {
-      e.preventDefault();
-      if (currentBtn === b) { close(); return; }
-      close();
-      var f = document.createElement('form'); f.className='fedi-remote-form'; f.dataset.uri = b.getAttribute('data-fedi-uri')||'';
-      f.innerHTML = '<input type="text" autocomplete="off" spellcheck="false"><button type="submit" class="btn btn-primary fedi-remote-go" aria-label="ok">&rarr;</button><button type="button" class="fedi-remote-cancel" aria-label="x">&times;</button>';
-      var _inp = f.querySelector('input'); _inp.placeholder = b.getAttribute('data-fedi-ph') || 'mastodon.social';
-      try{ var _sv = localStorage.getItem('pcmsFediServer'); if(_sv) _inp.value = _sv; }catch(e){}
-      document.body.appendChild(f); place(f, b); current=f; currentBtn=b; _inp.focus(); _inp.select();
-      return;
-    }
-    if (current) close();
-  });
-  document.addEventListener('submit', function(e){ var f=e.target.closest && e.target.closest('.fedi-remote-form'); if(!f) return; e.preventDefault(); go(f.querySelector('input').value, f.dataset.uri); });
-  document.addEventListener('keydown', function(e){ if (e.key === 'Escape') close(); });
-  window.addEventListener('scroll', close, true);
-})();
-</script>
