#6 Pull-to-refresh genuinely broken: the indicator lived INSIDE the scroller (so it
scrolled away unseen) and only became visible after ~96px while the trigger fired at
70 — and preventDefault was deferred until the pull passed 10px, by which point
iOS/Chrome had already claimed the gesture. Indicator now mounts on the list's
non-scrolling parent with the branded loader, the gesture is claimed immediately, and
the trigger is reachable. Works on Android + iOS.
#4 ⋮ More now TOGGLES (it used to remove then instantly rebuild, so it never closed).
#3 "Ringing…" is centred over the tile with the avatar/name dimmed behind it.
#2 Meeting bar fits the screen on mobile: one row of controls sized to the viewport,
room code on its own line, safe-area padding.
#5 Search box in the in-call Add-people tab.
#1 Speaker control: setSinkId (the only web API for audio output) is NOT implemented in
Android Chrome or iOS Safari — the OS owns the route there, and iOS forces loudspeaker
whenever a mic track is live. Rather than ship a button that silently does nothing, it
now only renders where output switching actually works. Real speaker/earpiece/Bluetooth
switching on phones needs the native (Capacitor) audio plugin.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>