Index: src/routes/circle.js
===================================================================
--- src/routes/circle.js	(revision b960185313553c71926ce884e75d5e5dc2775115)
+++ src/routes/circle.js	(revision 7917407ebdec315512ca9badca18040596ab36f6)
@@ -1,5 +1,6 @@
 /**
- * Publieke Cirkel-feed: /cirkel
- * Toont de gecachte publieke posts uit je cirkel als statische kaarten.
+ * Cirkel-feed + lokale lees-pagina.
+ *   GET /cirkel        -> overzicht (zelfde timeline/grid-view als de home)
+ *   GET /cirkel/:id    -> losse remote-post in eigen chrome (blijf op je site)
  * Alleen actief als tenancy === 'circle' (anders next() -> postsRoutes/404).
  * Zie docs/cirkels-v1-spec.md §5c.
@@ -19,11 +20,16 @@
   try { return s ? JSON.parse(s) : []; } catch { return []; }
 }
+function mediaImage(media_json) {
+  const media = safeJson(media_json).map((m) => ({ ...m, url: safeUrl(m.url) })).filter((m) => m.url);
+  return media.find((m) => m.type === 'image') || null;
+}
 
+// ── Overzicht ────────────────────────────────────────────────
 router.get('/cirkel', (req, res, next) => {
   if (getTenancy() !== 'circle') return next();
 
   const rows = db.prepare(`
-    SELECT p.id, p.published, p.title, p.summary, p.url, p.media_json,
-           a.name AS actor_name, a.url AS actor_url, a.avatar AS actor_avatar
+    SELECT p.id, p.published, p.title, p.summary, p.media_json,
+           a.name AS actor_name
     FROM remote_posts p
     JOIN remote_actors a ON a.id = p.actor_id
@@ -33,14 +39,10 @@
 
   const posts = rows.map((r) => {
-    const media = safeJson(r.media_json)
-      .map((m) => ({ ...m, url: safeUrl(m.url) }))
-      .filter((m) => m.url);
-    const image = media.find((m) => m.type === 'image') || null;
-    // Vorm de remote-post naar het lokale post-shape zodat post-card/post-tile
-    // (dezelfde timeline/grid-view als de home) 'm renderen. external_url maakt
-    // de partials extern-linkend (naar de bron) i.p.v. lokaal/htmx.
+    const image = mediaImage(r.media_json);
     return {
       id: r.id,
-      slug: encodeURIComponent(r.id),
+      // Lokale lees-pagina -> de kaart blijft op de eigen site (post-card linkt
+      // lokaal + htmx, GEEN external_url).
+      slug: 'cirkel/' + encodeURIComponent(r.id),
       title: r.title || '(zonder titel)',
       excerpt: r.summary || '',
@@ -52,7 +54,5 @@
       pinned: 0,
       status: 'published',
-      external_url: safeUrl(r.url),
       source_name: r.actor_name || 'Onbekend',
-      source_url: safeUrl(r.actor_url),
     };
   });
@@ -61,3 +61,36 @@
 });
 
+// ── Losse remote-post (lokaal lezen) ─────────────────────────
+router.get('/cirkel/:id', (req, res, next) => {
+  if (getTenancy() !== 'circle') return next();
+
+  const row = db.prepare(`
+    SELECT p.id, p.published, p.title, p.summary, p.url, p.media_json,
+           a.name AS actor_name, a.url AS actor_url, a.avatar AS actor_avatar
+    FROM remote_posts p
+    JOIN remote_actors a ON a.id = p.actor_id
+    WHERE p.id = ?
+  `).get(req.params.id);
+
+  if (!row) return next();
+
+  const image = mediaImage(row.media_json);
+  const post = {
+    title: row.title || '(zonder titel)',
+    body: row.summary || '',          // platte tekst (gesanitized bij ingest)
+    published: row.published,
+    image: image ? image.url : null,
+    sourceName: row.actor_name || 'Onbekend',
+    sourceUrl: safeUrl(row.actor_url),
+    sourceAvatar: safeUrl(row.actor_avatar),
+    originalUrl: safeUrl(row.url),
+  };
+
+  renderPage(req, res, 'pages/circle-post', {
+    pageTitle: post.title,
+    bodyClass: 'on-cirkel-post',
+    post,
+  });
+});
+
 export default router;
Index: src/views/pages/circle-post.ejs
===================================================================
--- src/views/pages/circle-post.ejs	(revision 7917407ebdec315512ca9badca18040596ab36f6)
+++ src/views/pages/circle-post.ejs	(revision 7917407ebdec315512ca9badca18040596ab36f6)
@@ -0,0 +1,46 @@
+<article class="container cirkel-post">
+  <p class="cirkel-post-back">
+    <a href="/cirkel" hx-get="/cirkel?partial=1" hx-target="#pcms-main" hx-swap="innerHTML"
+       hx-push-url="/cirkel" hx-indicator="#pcms-loading">&larr; Cirkel</a>
+  </p>
+
+  <header class="cirkel-post-head">
+    <div class="cirkel-post-src">
+      <% if (post.sourceAvatar) { %><img class="cirkel-post-avatar" src="<%= post.sourceAvatar %>" alt=""><% } %>
+      <span>via
+        <% if (post.sourceUrl) { %><a href="<%= post.sourceUrl %>" target="_blank" rel="noopener"><%= post.sourceName %></a>
+        <% } else { %><%= post.sourceName %><% } %>
+      </span>
+      <% if (post.published) { %><span class="cirkel-post-date">&middot; <%= post.published.slice(0, 10) %></span><% } %>
+    </div>
+    <h1 class="cirkel-post-title"><%= post.title %></h1>
+  </header>
+
+  <% if (post.image) { %>
+    <img class="cirkel-post-cover" src="<%= post.image %>" alt="" loading="lazy">
+  <% } %>
+
+  <div class="cirkel-post-body"><%= post.body %></div>
+
+  <% if (post.originalUrl) { %>
+    <p class="cirkel-post-readmore">
+      <a href="<%= post.originalUrl %>" target="_blank" rel="noopener">Lees verder bij <%= post.sourceName %> &rarr;</a>
+    </p>
+  <% } %>
+</article>
+
+<style>
+.cirkel-post { max-width: 720px; margin: 2rem auto; }
+.cirkel-post-back a { color: var(--ink-muted); text-decoration: none; font-size: .85rem; }
+.cirkel-post-back a:hover { color: var(--accent); }
+.cirkel-post-head { margin: 1rem 0 1.25rem; }
+.cirkel-post-src { display: flex; align-items: center; gap: .45rem; font-size: .85rem; color: var(--ink-muted); margin-bottom: .5rem; }
+.cirkel-post-src a { color: var(--ink-muted); }
+.cirkel-post-src a:hover { color: var(--accent); }
+.cirkel-post-avatar { width: 24px; height: 24px; border-radius: 50%; object-fit: cover; }
+.cirkel-post-title { font-family: var(--font-display, serif); font-size: 1.9rem; line-height: 1.15; margin: 0; }
+.cirkel-post-cover { width: 100%; border-radius: var(--radius); margin: 0 0 1.5rem; display: block; }
+.cirkel-post-body { font-size: 1.05rem; line-height: 1.7; white-space: pre-wrap; color: var(--ink); }
+.cirkel-post-readmore { margin-top: 2rem; padding-top: 1.25rem; border-top: 1px solid var(--rule); }
+.cirkel-post-readmore a { color: var(--accent); text-decoration: none; font-weight: 600; }
+</style>
