pointermove-Handler in controls.js; verwaiste window._helpPanel2Open/SetOpen-Globals in astroviewer.html (nirgendwo gelesen); unbenutzte Imports DEG, STAR_R_SCALE (aus utils.js), _applyRoll (aus camera.js), getCmpSysId1/2 (aus compare.js), _resolvePlaceholders und _applyScriptVars (aus recorder.js, werden direkt in actions.js importiert). Trailing Backslash im Kommentar entfernt. Header-Kommentar in controls.js um fehlende Exports ergänzt.updatePanelButtons war nicht im Context-Objekt von registerControlsContext() registriert – der Aufruf in applyCompareButtonStates(false) lief daher auf einen leeren Stub. In astroviewer.html nachgetragen.applyCompareButtonStates(false) restauriert alle Button-Opacities auf den vor-Compare-Zustand (inkl. surfaceBtn auf aktiv), ruft aber danach kein updateSurfaceBtnState() auf. Fix direkt in applyCompareButtonStates() – nach dem Restore wird updatePanelButtons() aufgerufen, das den Surface-Button-State auf Basis des tatsächlichen focusTgt neu setzt.saveCamState() speicherte focusTgt nicht mit – nach dem Restore zeigte focusTgt noch auf das vor dem Compare-Start fokussierte Objekt (z.B. einen Planeten), obwohl die Kamera zurück auf das Root-Objekt (Stern/Schwerpunkt) zeigt. focusTgt wird jetzt in saveCamState/restoreCamState mitgeführt und nach dem Restore der Surface-Button-State neu berechnet.endComparison() rief nach dem Button-Restore kein updateSurfaceBtnState() auf. Wird jetzt via updatePanelButtons() nachgeholt.updateSysNavButtons() deaktiviert diese Buttons per HTML-disabled-Attribut, das Help-Panel prüfte aber nur opacity/pointer-events. Beides wird jetzt berücksichtigt. Außerdem löst updateSysNavButtons() nun selbst einen Help-Panel-Refresh aus.applySurfaceButtonStates() dimmmt diese vier Buttons beim Eintreten in den Surface-Modus und gibt sie beim Verlassen wieder frei.compare.js schloss sie explizit beim Start und restaurierte sie beim Exit – beides entfernt. Die Panels bleiben jetzt beim Compare-Modus-Wechsel in ihrem aktuellen Zustand._updateSurfaceBtnState() löste keinen Help-Panel-Refresh aus. Wrapper in astroviewer.html erweitert.?-Button blieb aktiv (grün). Ursache: compare.js ruft window._helpPanelSetOpen direkt auf statt den astroviewer-Wrapper der den Button-State synct. Der Monkey-Patch in panels.js synchronisiert jetzt helpBtn2 selbst.rgba(160,160,160,0.45)), aktive Funktionen bleiben grün. Die Erkennung basiert auf dem bestehenden Disable-Mechanismus (opacity: 0.30 / pointer-events: none). Das Panel wird automatisch aktualisiert bei Wechsel in/aus Overview, Compare-Modus und Playback (Start und Stop).tracks.json unterstützen jetzt neben Regex auch Hash-basierte Zuweisung im Format hash:M:B (M = Modulo, B = Bucket 0..M-1). Der djb2-Hash des System-Keys wird modulo M berechnet – trifft er auf Bucket B, wird der Track gespielt. Dadurch gleichmäßige Verteilung auf alle Systeme unabhängig vom Anfangsbuchstaben (Gliese-Cluster kein Problem mehr). Die 8 System-Tracks wurden von Buchstaben-Regex auf hash:8:0 bis hash:8:7 umgestellt.set-volume 0 deaktiviert war. Ursache: navigate-system und focus-object riefen audioOnSystemChanged/audioOnObjectFocused auf bevor set-volume ausgeführt wurde – Audio war zu diesem Zeitpunkt noch enabled. Fix: stopAudio() setzt jetzt einen internen Suppress-Flag, der alle automatischen Track-Starts blockiert bis set-volume Audio explizit wieder einschaltet.