diff --git a/zebra-report/zebra-spaces.html b/zebra-report/zebra-spaces.html
index cef736f..978325c 100644
--- a/zebra-report/zebra-spaces.html
+++ b/zebra-report/zebra-spaces.html
@@ -2632,6 +2632,13 @@ function handleRemoteSfuTrack(ev){
if (kind === 'screen' || kind === 'camera' || kind === 'game'){
logLine('', 'sfu ontrack: kind=' + kind + ' pub=' + pubHex +
' track=' + ev.track.kind + ' mute=' + ev.track.muted + ' state=' + ev.track.readyState);
+ /* Video receivers (screen / camera / game) match the audio receiver's
+ * playoutDelayHint so the picture stays in sync with the voice. The
+ * mic jitter buffer is 4s; without a matching hint on video, mouse
+ * clicks / mouth movement / keystrokes lead the voice by ~4s. Audio
+ * is more vital than video — video adapts to audio's delay, never
+ * the other way around. */
+ try { if (ev.receiver) ev.receiver.playoutDelayHint = RECV_PLAYOUT_DELAY_SEC; } catch(_){}
}
/* MSID-supplant safety: the SFU re-uses the same streamID
* (`shortPub-kind`) when a publisher supplants themselves. WebRTC
@@ -4124,16 +4131,17 @@ async function startStream(uuid, pubHex){
a = document.createElement('audio');
a.autoplay = true; a.controls = false;
a.preload = 'auto'; a.playsInline = true;
- /* start muted so autoplay is universally allowed (muted autoplay
- * has no gesture requirement on any browser). applyAudioMute()
- * unmutes the moment the user gesture lands (btn-mute click) AND
- * this peer's canonical path is set to 'dj' by the 'playing'
- * listener below. */
- a.muted = true;
document.body.appendChild(a);
streamAudio.set(uuid, a);
await applySinkTo(a);
}
+ /* Toggle click is itself a user gesture, so unmuted play is allowed
+ * without the muted-autoplay workaround. Older code muted-started and
+ * relied on applyAudioMute() to unmute later, but that hook is a
+ * no-op for non-listeners now — host/speaker self-monitor (and host
+ * DJ-mode on remote speakers) was playing silently. Unmute on every
+ * call so a reused element from a prior stop also re-monitors. */
+ try { a.muted = false; } catch(_){}
a.src = wantUrl;
const onPlaying = () => {
logLine('', 'stream on for '+pubHex.slice(0,12)+' — DJ mode (~2s delay, glitch-free)');
@@ -4940,8 +4948,8 @@ logLine('', 'ready — pick a handle, type a rendezvous code, enter the space');