diff --git a/index.html b/index.html
index ca20e5e..9c4dc3b 100644
--- a/index.html
+++ b/index.html
@@ -3,7 +3,7 @@
-
+
+
+
-
+
+
+
+
0 trains dispatched
@@ -297,8 +441,10 @@
const dispatcher = document.querySelector("#dispatcher");
const hero = document.querySelector("#hero");
+ const themeButton = document.querySelector("#theme");
const muteButton = document.querySelector("#mute");
const counter = document.querySelector("#counter");
+ const themeMeta = document.querySelector('meta[name="theme-color"]');
const choo = new Audio("./public/choo-choo.mp3");
choo.preload = "auto";
@@ -308,6 +454,9 @@
let lastLane = -1;
let lastDirection = "rtl";
let muted = localStorage.getItem("wtc:muted") === "1";
+ let theme =
+ localStorage.getItem("wtc:theme") ||
+ (window.matchMedia("(prefers-color-scheme: dark)").matches ? "night" : "day");
function pick(items) {
return items[Math.floor(Math.random() * items.length)];
@@ -320,6 +469,19 @@
localStorage.setItem("wtc:muted", muted ? "1" : "0");
}
+ function syncThemeButton() {
+ const isNight = theme === "night";
+ document.documentElement.dataset.theme = theme;
+ themeButton.textContent = isNight ? "☀️" : "🌙";
+ themeButton.setAttribute(
+ "aria-label",
+ isNight ? "Use day mode" : "Use night mode",
+ );
+ themeButton.setAttribute("aria-pressed", String(isNight));
+ themeMeta.setAttribute("content", isNight ? "#09111f" : "#fbfbfa");
+ localStorage.setItem("wtc:theme", theme);
+ }
+
function updateCounter() {
const noun = count === 1 ? "train" : "trains";
counter.textContent = `${count} ${noun} dispatched`;
@@ -404,16 +566,33 @@
syncMuteButton();
});
+ themeButton.addEventListener("click", (event) => {
+ event.stopPropagation();
+ theme = theme === "night" ? "day" : "night";
+ syncThemeButton();
+ });
+
window.addEventListener("keydown", (event) => {
+ const isButtonKey =
+ (event.code === "Space" || event.code === "Enter") &&
+ event.target instanceof HTMLElement &&
+ event.target.closest("button");
+
+ if (isButtonKey) return;
+
if (event.code === "Space" || event.code === "Enter") {
event.preventDefault();
dispatchTrain();
} else if (event.key === "m" || event.key === "M") {
muted = !muted;
syncMuteButton();
+ } else if (event.key === "n" || event.key === "N") {
+ theme = theme === "night" ? "day" : "night";
+ syncThemeButton();
}
});
+ syncThemeButton();
syncMuteButton();
updateCounter();