diff --git a/web/zebra-spaces.html b/web/zebra-spaces.html
index b67d5e8..d4a1e37 100644
--- a/web/zebra-spaces.html
+++ b/web/zebra-spaces.html
@@ -484,15 +484,15 @@
* the pubkey, never wrap a handle mid-word. */
.member {
display: grid;
- /* extra 1.4rem column for the per-speaker stream toggle — lives on the
- * top row next to the mic icon so it never wraps + never adds row
- * height (the original 3-row layout is preserved). Single-char button
- * (○ / ◉) keeps the column tight. */
- grid-template-columns: 5.5rem minmax(0, 1fr) 1.4rem 1.4rem 5rem;
+ /* 4 columns: badge, handle/pub/acts, mic, meter. The per-speaker
+ * stream toggle column ('strm') was removed 2026-06-05 — the
+ * adaptive worklet handles wiggle absorption automatically, no
+ * manual buffered-HTTP fallback button needed. */
+ grid-template-columns: 5.5rem minmax(0, 1fr) 1.4rem 5rem;
grid-template-areas:
- "badge handle mic strm meter"
- "badge pub pub pub pub"
- "badge acts acts acts acts";
+ "badge handle mic meter"
+ "badge pub pub pub"
+ "badge acts acts acts";
align-items: center; gap: 0.35rem 0.55rem; padding: 0.35rem 0;
border-bottom: 1px dotted #ccc; font-size: 0.85rem;
}
@@ -500,19 +500,8 @@
.member > .handle { grid-area: handle; }
.member > .pub-short { grid-area: pub; }
.member > .mic { grid-area: mic; }
- .member > .stream-toggle { grid-area: strm; justify-self: center; }
.member > .meter { grid-area: meter; }
.member > .mod-actions { grid-area: acts; }
- /* single-char stream toggle: ○ when off, ◉ when on. Keep the button
- * compact so it fits the 1.4rem column without forcing the row taller. */
- .stream-toggle {
- font-size: 0.95rem; line-height: 1; padding: 0.1rem 0.3rem;
- background: transparent; border: 1px solid #888; cursor: pointer;
- color: inherit;
- }
- .stream-toggle.on { background: #000; color: #fff; border-color: #000; }
- html.theme-dark .stream-toggle { border-color: #aaa; }
- html.theme-dark .stream-toggle.on { background: #fff; color: #000; border-color: #fff; }
.member:last-child { border-bottom: none; }
.badge {
font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.05em;
@@ -5950,18 +5939,6 @@ function stopStream(uuid){
}
} catch(_){}
}
-function toggleStreamFor(uuid, pubHex){
- if (streamMode.has(pubHex)){
- streamMode.delete(pubHex);
- stopStream(uuid);
- ddNoteManualToggle(pubHex, false);
- } else {
- streamMode.add(pubHex);
- startStream(uuid, pubHex);
- ddNoteManualToggle(pubHex, true);
- }
- renderRoom();
-}
/* selfListenerMode — a speaker/cohost/host who wants to consume the
* room via the buffered HTTP Ogg/Opus path instead of the live WebRTC
@@ -6147,22 +6124,11 @@ function renderRoom(){
* every speaker row grow a third sub-row of mod-actions even for
* non-mods (just-self-monitor self-rows), which fox flagged as
* causing vertical scroll. Single-char glyph keeps the column 1.4rem. */
- let streamEl = null;
- /* Per-row stream toggle. The ONLY row that gets one is SELF — and
- * only when we can speak (host/cohost/speaker). The button flips
- * THIS viewer's whole audio path from the live WebRTC mesh to the
- * buffered HTTP Ogg/Opus broadcast tap (the listener-quality
- * stream). selfListenerMode is global, so the ◉/○ glyph reflects
- * that flag rather than streamMode of any single pubHex. */
- if (canSpeak(m.role) && m.uuid === myUUID && canSpeak(myRole)){
- streamEl = document.createElement('button');
- streamEl.className = 'stream-toggle' + (selfListenerMode ? ' on' : '');
- streamEl.textContent = selfListenerMode ? '◉' : '○';
- streamEl.title = selfListenerMode
- ? 'listening on the buffered HTTP stream — click to rejoin the live WebRTC mesh (also unmutes is via the mic button)'
- : 'switch yourself to the listener stream (buffered, ~2s behind) — auto-mutes your mic';
- streamEl.onclick = () => roomMachines.selfListener.send('TOGGLE');
- }
+ /* The per-row stream toggle (○/◉ for self-listener mode) was
+ * removed 2026-06-05. The adaptive worklet with predictive
+ * grow + self-calibrating floor now absorbs wiggles
+ * automatically; there's no scenario where a user needs to
+ * manually flip onto the buffered HTTP path. */
if (isMod(myRole) && m.uuid !== myUUID){
if (m.role === 'listener'){
const b = document.createElement('button'); b.className='small invert';
@@ -6215,11 +6181,6 @@ function renderRoom(){
acts.appendChild(actsRemoval);
row.appendChild(badge); row.appendChild(handle); row.appendChild(pub);
row.appendChild(micEl);
- /* stream toggle (when rendered) goes between mic and meter so it
- * lands in the `strm` grid column on the top row. If absent the
- * column collapses to its 1.4rem track width (small whitespace
- * gap, no row-height change). */
- if (streamEl) row.appendChild(streamEl);
row.appendChild(meter); row.appendChild(acts);
wrap.appendChild(row);
}
@@ -6887,8 +6848,8 @@ logLine('', 'ready — pick a handle, type a rendezvous code, enter the space');