diff --git a/index.html b/index.html
index e5429c8..fcda781 100644
--- a/index.html
+++ b/index.html
@@ -239,10 +239,15 @@ Events Resolved: 0
Save GameCtrl+S
Export SaveE
Import SaveI
+Mute SoundM
+High ContrastC
This Help? or /
Click WRITE CODE fast for combo bonuses! 10x=ops, 20x=knowledge, 30x+=bonus code
-
+
+
+
+
diff --git a/js/main.js b/js/main.js
index 3070bd0..1a7bb6b 100644
--- a/js/main.js
+++ b/js/main.js
@@ -97,7 +97,11 @@ try {
if (localStorage.getItem('the-beacon-muted') === '1') {
_muted = true;
const btn = document.getElementById('mute-btn');
- if (btn) { btn.textContent = '🔇'; btn.classList.add('muted'); }
+ if (btn) {
+ btn.textContent = '🔇';
+ btn.classList.add('muted');
+ btn.setAttribute('aria-label', 'Sound muted, click to unmute');
+ }
}
} catch(e) {}
@@ -117,7 +121,10 @@ try {
if (localStorage.getItem('the-beacon-contrast') === '1') {
document.body.classList.add('high-contrast');
const btn = document.getElementById('contrast-btn');
- if (btn) btn.classList.add('active');
+ if (btn) {
+ btn.classList.add('active');
+ btn.setAttribute('aria-label', 'High contrast on, click to disable');
+ }
}
} catch(e) {}
diff --git a/js/tutorial.js b/js/tutorial.js
index 75008c4..c4d311a 100644
--- a/js/tutorial.js
+++ b/js/tutorial.js
@@ -249,3 +249,12 @@ function startTutorial() {
// Small delay so the page renders first
setTimeout(() => renderTutorialStep(0), 300);
}
+
+function resetTutorial() {
+ try {
+ localStorage.removeItem(TUTORIAL_KEY);
+ } catch (e) {
+ // silent fail
+ }
+ startTutorial();
+}
diff --git a/tests/test_issue_57_polish.py b/tests/test_issue_57_polish.py
new file mode 100644
index 0000000..c6b57fb
--- /dev/null
+++ b/tests/test_issue_57_polish.py
@@ -0,0 +1,36 @@
+import pathlib
+import re
+import unittest
+
+ROOT = pathlib.Path(__file__).resolve().parents[1]
+INDEX_HTML = (ROOT / 'index.html').read_text(encoding='utf-8')
+TUTORIAL_JS = (ROOT / 'js' / 'tutorial.js').read_text(encoding='utf-8')
+MAIN_JS = (ROOT / 'js' / 'main.js').read_text(encoding='utf-8')
+
+
+class TestIssue57Polish(unittest.TestCase):
+ def test_help_overlay_lists_mute_and_contrast_shortcuts(self):
+ self.assertIn('Mute Sound', INDEX_HTML)
+ self.assertRegex(INDEX_HTML, r'>M<')
+ self.assertIn('High Contrast', INDEX_HTML)
+ self.assertRegex(INDEX_HTML, r'>C<')
+
+ def test_help_overlay_has_replay_tutorial_button(self):
+ self.assertRegex(
+ INDEX_HTML,
+ r'id="replay-tutorial-btn"[^>]*onclick="resetTutorial\(\)"',
+ 'Expected help overlay to expose a replay tutorial button.',
+ )
+
+ def test_reset_tutorial_clears_flag_and_restarts_walkthrough(self):
+ self.assertRegex(TUTORIAL_JS, r'function\s+resetTutorial\s*\(')
+ self.assertIn("localStorage.removeItem(TUTORIAL_KEY)", TUTORIAL_JS)
+ self.assertIn('startTutorial()', TUTORIAL_JS)
+
+ def test_restore_mute_and_contrast_labels_match_saved_state(self):
+ self.assertIn("btn.setAttribute('aria-label', 'Sound muted, click to unmute')", MAIN_JS)
+ self.assertIn("btn.setAttribute('aria-label', 'High contrast on, click to disable')", MAIN_JS)
+
+
+if __name__ == '__main__':
+ unittest.main()