Index: src/assets/css/style.css
===================================================================
--- src/assets/css/style.css	(revision 77019faadc6c4bbe9563d212ee9184e36f3ce3d1)
+++ src/assets/css/style.css	(revision d9f60f46de1c9dfcf43052988e97abac89cdbe38)
@@ -2510,6 +2510,10 @@
     margin: 0 auto;
     /* De onderrand loopt achter de vaste tabbalk door; deze padding houdt de
-       TEKST erboven. */
-    padding: 2rem 1.2rem 4rem;
+       TEKST erboven. De BOVENmarge is verdubbeld (Robin, 21-8: 2rem -> 4rem):
+       na een snap staat de scheidingslijn op de bovenrand, en de tekst
+       daaronder krijgt meer lucht. MOET GELIJK BLIJVEN aan scroll-margin-top
+       op .read-anker hieronder -- lopen die uit elkaar, dan landt de lijn niet
+       meer precies op de bovenrand. */
+    padding: 4rem 1.2rem 4rem;
     box-sizing: border-box;
 }
@@ -2536,11 +2540,12 @@
     height: 0;
     scroll-snap-align: start;
-    /* Het anker staat BINNEN de padding van het artikel, dus 2rem onder de
-       streep. Zonder deze correctie landt de snap 32px te laag en staat de
-       scheidingslijn net boven beeld -- gemeten: 733 waar 700 hoort.
+    /* Het anker staat BINNEN de padding van het artikel, dus een padding-top
+       onder de streep. Zonder deze correctie landt de snap net zoveel te laag
+       en staat de scheidingslijn boven beeld -- gemeten: 733 waar 700 hoort.
        scroll-margin verschuift alleen het SNAPPUNT en niet de opmaak, dus het
        anker blijft waar het staat en de uitlijning klopt met de lijn.
-       Blijft in de pas met de padding-top van .read-post hierboven. */
-    scroll-margin-top: 2rem;
+       GELIJK aan de padding-top van .read-post hierboven; die ging 21-8 van
+       2rem naar 4rem, dus deze ook. */
+    scroll-margin-top: 4rem;
 }
 /* HET LAATSTE BERICHT SNAPT OOK (Robin, 21-8). Dat kon eerst niet: zijn
Index: src/assets/js/mod/read.js
===================================================================
--- src/assets/js/mod/read.js	(revision 77019faadc6c4bbe9563d212ee9184e36f3ce3d1)
+++ src/assets/js/mod/read.js	(revision d9f60f46de1c9dfcf43052988e97abac89cdbe38)
@@ -413,16 +413,36 @@
   // kandidaat beoordeelt: zonder deze omleiding houdt de zone vooruit op bij de
   // helft van de afstand tussen twee berichten, hoe groot je de drempel ook zet.
+  //
+  // DE REGEL, in Robins woorden (21-8): "enkel bij downscrollen, aan de
+  // onderkant van elke post, snappen naar de lijn tussen de posts" -- en geen
+  // snap op een bericht dat al voorbij is gescrold. Drie voorwaarden dus:
+  //   1. de laatste echte beweging ging omlaag,
+  //   2. het doel ligt VOOR je (een punt achter je slaan we over),
+  //   3. het ligt binnen de vangzone -- die begint rond de voet van het bericht.
+  // Het doel zelf blijft de bovenkant van het volgende bericht: dat IS de lijn
+  // ertussen, en dat is het essentiële.
+  //
+  // DE ZONE IS EEN GETAL, geen '55%'. Die string kwam ongewijzigd uit de opties
+  // en werd hier met een getal vergeleken -- altijd onwaar, dus deze terugval
+  // heeft nooit gewerkt en alleen het doel dat lenis zelf koos kwam erdoor.
+  const vangZone = () => 0.55 * window.innerHeight;
+  // Lenis' eigen `direction` is het teken van de snelheid, en die is bij het
+  // afvuren van de (gedebouncede) snap alweer nul. Daarom onthouden we de
+  // laatste richting die er echt was.
+  let laatsteRichtingOmlaag = true;
+  lenis.on('scroll', () => {
+    if (Math.abs(lenis.velocity) > 0.05) laatsteRichtingOmlaag = lenis.velocity > 0;
+  });
   const echtGaNaar = snap.goTo.bind(snap);
   snap.goTo = (index) => {
+    if (!laatsteRichtingOmlaag) return;   // omhoog: nooit vangen
     const punten = snap.computeSnaps();   // zelfde volgorde als goTo intern gebruikt
     const nu = lenis.scroll;
-    const doel = punten[index];
-    if (doel && doel.value > nu + 2) { echtGaNaar(index); return; }
     let vooruit = -1;
     punten.forEach((punt, i) => {
       if (punt.value > nu + 2 && (vooruit < 0 || punt.value < punten[vooruit].value)) vooruit = i;
     });
-    if (vooruit < 0) return;
-    if (punten[vooruit].value - nu <= snap.distanceThreshold) echtGaNaar(vooruit);
+    if (vooruit < 0) return;              // niets meer voor je: vrij uitscrollen
+    if (punten[vooruit].value - nu <= vangZone()) echtGaNaar(vooruit);
   };
   // Native snappen uit: twee mechanismen op dezelfde scroller vechten.
Index: src/views/shell.ejs
===================================================================
--- src/views/shell.ejs	(revision 77019faadc6c4bbe9563d212ee9184e36f3ce3d1)
+++ src/views/shell.ejs	(revision d9f60f46de1c9dfcf43052988e97abac89cdbe38)
@@ -222,5 +222,5 @@
 
 <!-- v9 stylesheet (full palette system) -->
-<link rel="stylesheet" href="/assets/css/style.css?v=104">
+<link rel="stylesheet" href="/assets/css/style.css?v=105">
 <script>
 /* iOS safe-area, built by hand. env(safe-area-inset-top) resolves to 0 on this iOS in
@@ -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 = 47;
+  var MOD_V = 48;
 
   // name -> 1 (aan het laden) of de module-namespace (geladen). Een module
