diff --git a/PROJECT.md b/PROJECT.md
index 01a73e9..0bbab80 100644
--- a/PROJECT.md
+++ b/PROJECT.md
@@ -5384,6 +5384,42 @@ rolling (seed 31337 found it).
**Not built:** the champion LEARNING whether the net works for him (Free Tennis's idea), a style for
classic's CPU, and a "DROP"/"LOB" word at contact.
+### The swing log comes back for every rally mode, and the gold ring is TIMED (2026-10-14, v365)
+Oliver: *"bitte bau nochmal die Funktion ein die protokolliert warum ich einen Ball nicht bekommen habe
+(ich glaube das war ein Tap aufs Scoreboard).. ich würde dir das gerne mal zum Debuggen geben."*
+- **The log existed but was gated on `G.mode === 'tennis'`.** The match runs as `'splatter'` under its
+ interlude, so the Climb, the cup and training logged nothing at all. `swingLog()` (tennis or
+ `rallyFeel`) now gates every site: whiff analysis, swing snapshots, closest approach, the HIT line.
+- What a line now carries:
+ - **HIT:** `q=0.82 drop left volley · tap 120ms · capped: …`, i.e. the shot asked for, the tap's
+ age (keyPressed's `lead`, stored as `P.tap`), and which cap took the quality down (volley below
+ the tape, dug-out drop, lobbed).
+ - **MISS:** the old early/late/wide/high/low reasons, plus "waited for the bounce" when the
+ let-it-bounce gate refused it. The snapshot reach now includes `matchReach`; without it a near
+ miss in the match read as wide.
+ - **WON/LOST:** every point names why (`logPoint`, called by both `pointTo` and `resolveInterlude`).
+ A point lost with no swing adds how close the ball came. The old PASSED entry folded into this
+ line; the ghost hand's pass streak keeps its old classic-only trigger.
+- The ring holds 200 entries. **Tap the scoreboard** to open the last nine. **Tap the open log** to
+ copy all of it (`copySwingLog`, main.js): a header with build, mode, opponent and style, then one
+ line per entry with its measured fields. It uses the clipboard, with the share sheet as fallback.
+ `render.logGeom` is the one geometry for drawing and hit test.
+- **The log's first catch: the gold ring was a DISTANCE** (2.7 m ± 0.5). That is right for the
+ ~20 m/s rally balls it was calibrated on, and too early for every slow ball steps 1-3 brought in:
+ moonballs, lobs, drops, deep balls braked by their bounce. A gold-ring tap on one missed "30 ms after
+ the window".
+ - `gameplay.ringCue` rolls the ball forward (the real bounce rule, reach, height band and
+ let-it-bounce gate) to the moment it enters the player's contact reach, measured against where
+ the auto-run is CARRYING him (`P.tgt`). Against where he stands, the cue jumped 50-180 ms a frame.
+ - Gold means a finger landing now centres that moment in the swing window (`ringBand` 0.35 of the
+ half-window, so the gold edge is q 0.65). The rings kiss at the sweet moment: a tap at the kiss
+ measured q 1.00 every time.
+ - Gold-tapping bot with a 100 ms lift: 92-98% returned at every style. The distance ring returned
+ 75% against THE BRUTE's topspin.
+ - `TUNE.ringTime 0` restores the distance ring for A/B.
+- Note: contact still fires on the first frame the ball is in reach, which right after a bounce is
+ often 15-25 cm off the grass. A visual half-volley, the old contact model; untouched.
+
# OPEN — leftovers, in rough priority order
Nothing here is broken; these are known gaps and unverified risks.
diff --git a/index.html b/index.html
index fd85b7d..0b8a461 100644
--- a/index.html
+++ b/index.html
@@ -1140,6 +1140,6 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
REC
-
+