diff --git a/web/zebra-spaces.html b/web/zebra-spaces.html
index 2205689..10af972 100644
--- a/web/zebra-spaces.html
+++ b/web/zebra-spaces.html
@@ -2118,6 +2118,38 @@ function detachListenerStream(uuid){
try { node.gain.disconnect(); } catch(_){}
listenerAudioNodes.delete(uuid);
}
+
+/* Smooth crossfade for the SFU worklet path. The worklet stays running
+ * (continues decoding samples at small CPU cost); only its GainNode
+ * value moves. We use Web Audio's linearRampToValueAtTime for click-
+ * free transitions — settings audio.volume directly causes audible
+ * zipper noise on Android.
+ *
+ * Called by:
+ * - mesh ontrack → ramp to 0 (mesh