diff --git a/web/zebra-spaces.html b/web/zebra-spaces.html
index 401c837..9e317ce 100644
--- a/web/zebra-spaces.html
+++ b/web/zebra-spaces.html
@@ -683,9 +683,10 @@ await loadOrCreateIdentity();
myHandle = localStorage.getItem(HANDLE_KEY) || '';
$('handle').value = myHandle;
/* preferences that should outlive a reload — music-mode toggle and the
- * last-picked mic + camera deviceIds. They're applied here before any
- * device enumeration / mic acquisition so the very first getUserMedia
- * call uses the right device + constraints. */
+ * last-picked mic + camera deviceIds. Declared up here so the restore
+ * runs before their downstream `let` would put them in the temporal
+ * dead zone; downstream code now reads from these existing bindings. */
+let musicMode = false, micDeviceId = '', cameraDeviceId = '';
try { musicMode = localStorage.getItem(MUSIC_MODE_KEY) === '1'; } catch(_){}
try { micDeviceId = localStorage.getItem(MIC_DEV_KEY) || ''; } catch(_){}
try { cameraDeviceId = localStorage.getItem(CAM_DEV_KEY) || ''; } catch(_){}
@@ -730,7 +731,9 @@ const SFU_BASE = (new URLSearchParams(location.search).get('sfu')
let sfuPubPC = null, sfuPubPeerID = null;
let sfuSubPC = null, sfuSubPeerID = null, sfuSubEvents = null;
let sfuScreenPC = null, sfuScreenPeerID = null, sfuScreenStream = null;
-let sfuCameraPC = null, sfuCameraPeerID = null, sfuCameraStream = null, cameraDeviceId = '';
+let sfuCameraPC = null, sfuCameraPeerID = null, sfuCameraStream = null;
+/* cameraDeviceId is declared earlier so localStorage restore can write to it
+ * before the device-list refresh runs */
/* incoming screen/camera streams keyed by publisher pubkey hex (== streamID).
* Cleared when the corresponding publisher leaves (peer-left or boot). */
const screenStreams = new Map(); // pubHex -> MediaStream
@@ -1171,7 +1174,9 @@ async function refreshTurnCred(){
* zebra-audio carries over directly: re-acquire + replaceTrack on every
* live sender (now multiple senders, one per peer).
* ================================================================== */
-let micStream = null, audioCtx = null, musicMode = false, micDeviceId = '';
+let micStream = null, audioCtx = null;
+/* musicMode + micDeviceId declared earlier so localStorage restore can
+ * populate them before getMic() reads micConstraints() */
function micConstraints(){
/* music mode = high-fidelity broadcast: stereo, raw, 48kHz so we can
* push 256kbps Opus and let Opus's stereo modes carry music properly.
@@ -2174,8 +2179,8 @@ logLine('', 'ready — pick a handle, type a rendezvous code, enter the space');