Index: src/views/pages/admin-site-edit.ejs
===================================================================
--- src/views/pages/admin-site-edit.ejs	(revision 598f09038f721164997d5a888801e65d93c1acb2)
+++ src/views/pages/admin-site-edit.ejs	(revision 48481cd4312d157017474ea7e2b0d723b63ac73c)
@@ -196,8 +196,19 @@
     <fieldset>
       <legend><%= t('asite.feed_view') %></legend>
+      <%# Twee vragen, en ze zijn niet hetzelfde: WELKE tweede weergave je site
+          aanbiedt naast Grid, en waarin hij opent. %>
+      <label>
+        <span><%= t('asite.feed_alt') %></span>
+        <select name="feed_alt_view">
+          <% var _a = ['timeline','auto'].indexOf(site.feed_alt_view) >= 0 ? site.feed_alt_view : 'reader'; %>
+          <option value="reader"   <%= _a === 'reader'   ? 'selected' : '' %>><%= t('asite.feed_alt_reader') %></option>
+          <option value="timeline" <%= _a === 'timeline' ? 'selected' : '' %>><%= t('asite.feed_alt_timeline') %></option>
+          <option value="auto"     <%= _a === 'auto'     ? 'selected' : '' %>><%= t('asite.feed_alt_auto') %></option>
+        </select>
+      </label>
       <label>
         <span><%= t('asite.feed_default') %></span>
         <select name="feed_view_default">
-          <option value="reader" <%= site.feed_view_default !== 'grid' ? 'selected' : '' %>><%= t('asite.feed_reader') %></option>
+          <option value="reader" <%= site.feed_view_default !== 'grid' ? 'selected' : '' %>><%= t('asite.feed_alt_' + _a) %></option>
           <option value="grid"     <%= site.feed_view_default === 'grid' ? 'selected' : '' %>><%= t('asite.feed_grid') %></option>
         </select>
Index: src/views/pages/home.ejs
===================================================================
--- src/views/pages/home.ejs	(revision 598f09038f721164997d5a888801e65d93c1acb2)
+++ src/views/pages/home.ejs	(revision 48481cd4312d157017474ea7e2b0d723b63ac73c)
@@ -67,4 +67,10 @@
 <% if (typeof readerItems !== 'undefined' && readerItems && readerItems.length) { %>
 <section class="feed-reader" aria-label="<%= t('switch.reader') %>">
+  <%# Terug naar boven. Staat IN de HTML en niet in JavaScript, zodat hij er ook
+      is als de module niet laadt -- dan doet hij niets, maar hij springt ook niet
+      opeens in beeld. Verschijnt pas als je ver genoeg bent (mod/read.js). %>
+  <button type="button" id="read-top" class="read-top" aria-label="<%= t('read.to_top') %>" title="<%= t('read.to_top') %>">
+    <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="12" y1="19" x2="12" y2="5"/><polyline points="5 12 12 5 19 12"/></svg>
+  </button>
   <div class="read-stream" id="read-stream" data-base="<%= _base %>">
     <% readerItems.forEach(function(it) { %>
Index: src/views/partials/view-switcher.ejs
===================================================================
--- src/views/partials/view-switcher.ejs	(revision 598f09038f721164997d5a888801e65d93c1acb2)
+++ src/views/partials/view-switcher.ejs	(revision 48481cd4312d157017474ea7e2b0d723b63ac73c)
@@ -23,4 +23,22 @@
   var _leesUit = _bc.indexOf('on-cirkel') >= 0;
   var _gridStandaard = (typeof site !== 'undefined' && site && site.feed_view_default === 'grid');
+  // Welke tweede weergave biedt deze site aan? Bij 'auto' tekenen we ZE ALLEBEI
+  // en laat de CSS er per viewport een zien -- Lezen op mobiel, Tijdlijn op
+  // desktop. Dat scheelt een resize-afhandeling en een knop die van naam
+  // verspringt terwijl je kijkt.
+  var _alt = (typeof site !== 'undefined' && site && site.feed_alt_view) || 'reader';
+  if (['reader', 'timeline', 'auto'].indexOf(_alt) < 0) _alt = 'reader';
+  var _tweede = _alt === 'auto' ? ['reader', 'timeline'] : [_alt];
+  // De tijdlijn WERKT wel in de cirkel -- dat is er zelfs de natuurlijke vorm.
+  // Alleen Lezen kan daar niet, want dat zijn berichten van anderen.
+  var _dood = function (v) { return v === 'reader' && _leesUit; };
+  // Staat er GEEN levende tweede knop, dan is Grid het enige dat overblijft en
+  // hoort die aan te staan. Bij een tijdlijn-site is dat in de cirkel niet zo:
+  // daar werkt de tijdlijn gewoon.
+  var _alleenGrid = _tweede.every(_dood);
+  var _icoon = {
+    reader: '<path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/>',
+    timeline: '<line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/>',
+  };
 %>
 <div class="view-switcher-wrap">
@@ -49,16 +67,18 @@
     <div class="view-switcher" role="tablist" aria-label="Weergave">
 
-      <%# Lezen is de standaardweergave sinds Tijdlijn weg is: hele berichten,
-          één per scherm. De chronologische lijst bestaat nog wel als opmaak
-          (.feed-timeline, ook op de cirkel en het archief), maar is geen KEUZE
-          meer -- daar was Lezen de betere vorm van. %>
-      <button type="button" class="view-switch-btn" data-view="reader" role="tab"
-              <%- _leesUit ? 'disabled aria-disabled="true" tabindex="-1" title="' + t('switch.reader_solo_only') + '"' : '' %>
-              aria-selected="<%= (!_leesUit && !_neutral && !_gridStandaard) ? 'true' : 'false' %>">
-        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/></svg>
-        <span><%= t('switch.reader') %></span>
+      <%# De tweede weergave naast Grid. Welke dat is, staat in de instellingen
+          van de site (feed_alt_view). Bij 'auto' staan ze er allebei en kiest
+          een mediaquery; vandaar de klasse vs-alleen-*. %>
+      <% _tweede.forEach(function (v) { %>
+      <button type="button" class="view-switch-btn<%= _alt === 'auto' ? ' vs-alleen-' + (v === 'reader' ? 'mobiel' : 'desktop') : '' %>"
+              data-view="<%= v %>" role="tab"
+              <%- _dood(v) ? 'disabled aria-disabled="true" tabindex="-1" title="' + t('switch.reader_solo_only') + '"' : '' %>
+              aria-selected="<%= (!_dood(v) && !_neutral && !_gridStandaard) ? 'true' : 'false' %>">
+        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><%- _icoon[v] %></svg>
+        <span><%= t('switch.' + v) %></span>
       </button>
+      <% }); %>
       <button type="button" class="view-switch-btn" data-view="grid" role="tab"
-              aria-selected="<%= (!_neutral && (_leesUit || _gridStandaard)) ? 'true' : 'false' %>">
+              aria-selected="<%= (!_neutral && (_alleenGrid || _gridStandaard)) ? 'true' : 'false' %>">
         <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/></svg>
         <span><%= t('switch.grid') %></span>
Index: src/views/shell.ejs
===================================================================
--- src/views/shell.ejs	(revision 598f09038f721164997d5a888801e65d93c1acb2)
+++ src/views/shell.ejs	(revision 48481cd4312d157017474ea7e2b0d723b63ac73c)
@@ -222,5 +222,5 @@
 
 <!-- v9 stylesheet (full palette system) -->
-<link rel="stylesheet" href="/assets/css/style.css?v=72">
+<link rel="stylesheet" href="/assets/css/style.css?v=77">
 <script>
 /* iOS safe-area, built by hand. env(safe-area-inset-top) resolves to 0 on this iOS in
@@ -345,5 +345,5 @@
 </head>
 
-<body class="<%= bodyClass || 'on-home' %> has-bottom-tab" data-js="chrome<%= (typeof pageJs !== 'undefined' && pageJs) ? ' ' + pageJs : '' %>" data-feed-view="<%- _e(safeSite.feed_view_default === 'grid' ? 'grid' : 'reader') %>" data-grid-cols="3" data-site-base="<%- _e((typeof siteUrlBase !== 'undefined' && siteUrlBase) ? siteUrlBase : '') %>">
+<body class="<%= bodyClass || 'on-home' %> has-bottom-tab" data-js="chrome<%= (typeof pageJs !== 'undefined' && pageJs) ? ' ' + pageJs : '' %>" data-feed-view="<%- _e(safeSite.feed_view_default === 'grid' ? 'grid' : (["timeline","auto"].indexOf(safeSite.feed_alt_view) >= 0 ? safeSite.feed_alt_view : "reader")) %>" data-feed-alt="<%- _e(["timeline","auto"].indexOf(safeSite.feed_alt_view) >= 0 ? safeSite.feed_alt_view : "reader") %>" data-grid-cols="3" data-site-base="<%- _e((typeof siteUrlBase !== 'undefined' && siteUrlBase) ? siteUrlBase : '') %>">
 
 <% if (typeof isViewer !== 'undefined' && isViewer) { %>
@@ -505,5 +505,5 @@
   // Eén nummer voor de hele map. Te vaak bumpen kost één download; te weinig
   // bumpen kost een bugfix die nooit aankomt.
-  var MOD_V = 4;
+  var MOD_V = 13;
 
   // name -> 1 (aan het laden) of de module-namespace (geladen). Een module
@@ -559,4 +559,5 @@
   // 'pcms-feed-view' en wordt hier nergens geschreven, zodat je thuiskomt in de
   // weergave die je achterliet.
+  var CIRKEL_SLEUTEL = 'pcms-cirkel-view';
   function opCirkel() { return body.classList.contains('on-cirkel'); }
 
@@ -565,14 +566,37 @@
     try {
       if (opCirkel()) {
-        body.dataset.feedView = 'grid';   // de enige mogelijkheid daar
+        // Lezen kan hier niet -- dat zijn berichten van ANDEREN, van hun servers,
+        // en "het hele stuk" hebben wij niet in handen. De knop staat er wel maar
+        // dood. Een TIJDLIJN kan hier juist bij uitstek: dat is de natuurlijke
+        // vorm van een cirkel.
+        //
+        // Beschikbaar, niet verplicht. Dit dwong eerst 'timeline' af zodra de
+        // site geen Lezen-site was, en dan kon je in de cirkel geen Grid meer
+        // kiezen. Nu is Grid de landing en is Tijdlijn een keuze ernaast.
+        var altC = body.dataset.feedAlt || 'reader';
+        var tijdlijnHier = altC === 'timeline'
+          || (altC === 'auto' && window.matchMedia('(min-width: 768px)').matches);
+        var magC = tijdlijnHier ? ['grid', 'timeline'] : ['grid'];
+        // Een EIGEN geheugen, en niet dat van solo. Twee redenen: hier kun je
+        // alleen uit Grid en Tijdlijn kiezen, dus een solo-keuze 'reader' zegt
+        // hier niets; en andersom mag een tuimeling hier je thuisweergave niet
+        // veranderen -- dan kom je thuis in iets anders dan je achterliet.
+        // (Dit geheugen stond er eerder al, verdween toen de cirkel nog maar een
+        // mogelijkheid had, en is nu weer nodig omdat Tijdlijn een echte keuze is.)
+        var vC = null;
+        try { vC = localStorage.getItem(CIRKEL_SLEUTEL); } catch (e) { /* geen opslag */ }
+        body.dataset.feedView = magC.indexOf(vC) >= 0 ? vC : 'grid';
         return;
       }
       var v = localStorage.getItem('pcms-feed-view');
-      // 'timeline' bestaat niet meer als keuze, maar staat nog in de localStorage
-      // van iedereen die hier eerder was. Zonder deze vertaling zou zo iemand een
-      // weergave houden die nergens meer een knop heeft: de pil helemaal grijs, en
-      // een feed die niet is wat hij koos. Lezen is waar Tijdlijn in opging.
-      if (v === 'timeline') v = 'reader';
-      if (v === 'grid' || v === 'reader') body.dataset.feedView = v;
+      // 'timeline' is sinds 20-8 weer een geldige keuze, maar alleen op een site
+      // die hem AANBIEDT. Wie de tijdlijn koos op de ene site en daarna een
+      // Lezen-site bezoekt, moet daar niet op een weergave landen die er geen
+      // knop heeft: dan staat de pil grijs en is de feed niet wat hij koos.
+      // Vandaar de toets tegen wat deze site biedt, in plaats van een vaste
+      // vertaling naar 'reader'.
+      var alt = body.dataset.feedAlt || 'reader';
+      var mag = alt === 'auto' ? ['grid', 'reader', 'timeline'] : ['grid', alt];
+      if (mag.indexOf(v) >= 0) body.dataset.feedView = v;
     } catch (e) { /* geen opslag: de server-standaard blijft staan */ }
   }
@@ -647,5 +671,8 @@
       // veranderen: die moet je terugvinden zoals je hem achterliet.
       try {
-        if (!opCirkel()) localStorage.setItem('pcms-feed-view', view);
+        // De cirkel heeft zijn eigen geheugen, zodat een keuze daar je
+        // thuisweergave niet aanraakt en andersom.
+        if (opCirkel()) localStorage.setItem(CIRKEL_SLEUTEL, view);
+        else localStorage.setItem('pcms-feed-view', view);
       } catch(_) {}
       syncAria();
