diff --git a/PROJECT.md b/PROJECT.md
index e685cff..fc5827c 100644
--- a/PROJECT.md
+++ b/PROJECT.md
@@ -456,19 +456,23 @@ creating the room could decide whether it is classic tennis or death match.. in
wounded opponent would show increased dynamic bleeding before exploding."* The VS second step is
three chips now (HOST — CLASSIC TENNIS / HOST — DEATH MATCH / JOIN WITH A CODE); the host's pick
rides the room (`?death=1` at creation, carried in the relay's start message), so the joiner never
-answers a question. On pairing BOTH phones rebuild the court into the zombie-tennis match — the
-same verdicts drive `resolveInterlude`/`matchPoint` instead of `pointTo`, so wounds, blood, the
-fall, the mop beat and the burst all come along unmodified. On each phone YOUR OPPONENT IS THE
-ZOMBIE: their lost points tear its wound stages (your win = their body comes apart), their won
-points draw your blood, and bleeding out sends `dead` — the other phone banks a NOT-dead match run
-and holds the win screen. Wired details: the same friend walks back on after each burst (`d.opp`
-frozen — the roster climb would hand them a new face; returns get an IT RISES AGAIN flash, not a
-repeated name card), racketAI and the early-decide are gated off (`!G.net` — you cannot predict a
-human's legs), match balls already passed through the body so no contact work was needed, and
-`gushProne()` in zombies.js is the asked-for bleed-out: LOW anchors around the corpse during the
-kill fall's prone hold (bleed() stays suppressed there — its standing-height anchors are the
-"blood fountains midair" bug), `TUNE.killGush` attempts per frame until the burst. #netd hosts a
-death room from a URL. 80 tests; the wound/blood/burst loop verified across two panes.
+answers a question. On pairing BOTH phones rebuild the court into the match machinery — the same
+verdicts drive `resolveInterlude`/`matchPoint` instead of `pointTo`, so blood, the mop beat and
+the scoring come along unmodified. **THE OPPONENT IS THE FRIEND, NOT A ROSTER BODY** (his retest:
+*"the opponent reads as zombie — it should be the normal opponent"*, and no SHAMBLER teaser
+card): nothing spawns, the living O carries the whole picture, and since the human sprite has no
+wound skins, **the score reads on him as BLOOD** — `bleedO()` in zombies.js opens an anchor per
+point taken off him this game and thickens the flow, love → game point, thin drops throughout
+(the settled rule: more emissions, never heavier drops). The game-winning point BURSTS him where
+he stands (`explode` — the human has no fall art, and procedural gore is the sanctioned fake),
+the mop beat runs over the gap, and IT RISES AGAIN returns him with the ramp reset. Their won
+points draw your blood; bleeding out sends `dead` — the other phone banks a NOT-dead match run
+and holds the win screen. Wired details: `d.opp` frozen (no roster climb — same friend every
+game), racketAI / the early-decide / the empty-court-regicide check all gated `!G.net`, the heal
+beat is a CARD in netplay (the modal froze this world while the other phone's kept moving), and
+`gushProne()` gives the SOLO deathmatch's kill fall the same bleed-out from prone-height anchors
+(bleed() stays suppressed there — standing anchors are the "blood fountains midair" bug). #netd
+hosts a death room from a URL. 79 tests; the blood-ramp/burst/return loop verified across panes.
## Session log: the far court, without spending the lens (2026-08-13)
diff --git a/index.html b/index.html
index 04105ae..baa70d7 100644
--- a/index.html
+++ b/index.html
@@ -494,6 +494,6 @@ if (location.hostname !== 'splatter-tennis.wuwi.one') {
-
+