diff --git a/web/zebra-spaces.html b/web/zebra-spaces.html
index 8c9351a..9df1f42 100644
--- a/web/zebra-spaces.html
+++ b/web/zebra-spaces.html
@@ -973,10 +973,12 @@ async function sfuSubscribe(){
logLine('', 'sfu: unknown kind '+kind+' from '+shortHex(pubHex));
return;
}
- /* mic audio — set a small jitter-buffer hint so brief network jitter
- * doesn't cause audible drops. 100ms is enough to absorb typical
- * Wi-Fi micro-bursts without making conversation feel laggy. */
- try { ev.receiver.playoutDelayHint = 0.2; } catch(_){}
+ /* mic audio — 400ms jitter-buffer target. Mobile/Wi-Fi peak inter-
+ * arrival is 3-5x the smoothed jitter reported by getStats, so a
+ * smoothed 50ms means 150-250ms peaks. 400ms absorbs that and feels
+ * fine for music broadcasts; conversation gains ~quarter-second of
+ * delay which is well below noticeable. */
+ try { ev.receiver.playoutDelayHint = 0.4; } catch(_){}
const pubHex = sid;
/* cache stream by publisher pubkey so it survives the member's session
* uuid changing across leave/rejoin — see flushSfuStreams */
@@ -1572,9 +1574,9 @@ async function connectToPeer(uuid, weOffer){
let a = remoteAudio.get(uuid);
if (!a){ a = document.createElement('audio'); a.autoplay = true; document.body.appendChild(a); remoteAudio.set(uuid, a); }
a.srcObject = ev.streams[0] || new MediaStream([ev.track]);
- /* 100ms jitter buffer absorbs typical Wi-Fi micro-bursts without
- * adding perceptible conversation lag */
- try { ev.receiver.playoutDelayHint = 0.2; } catch(_){}
+ /* 400ms jitter buffer — Wi-Fi peak inter-arrival is multiples of
+ * the smoothed jitter, so a generous buffer absorbs the bursts */
+ try { ev.receiver.playoutDelayHint = 0.4; } catch(_){}
stopMeter(uuid); startMeter(uuid, a.srcObject);
};
pc.onicecandidate = (ev) => { /* using waitForIceGathering pattern, candidates ignored */ };
@@ -2071,8 +2073,8 @@ logLine('', 'ready — pick a handle, type a rendezvous code, enter the space');