From 4aa180d15a25b4551ce9b990984907dfa3566681 Mon Sep 17 00:00:00 2001 From: James Jiang Date: Fri, 31 Jul 2026 21:47:27 +1000 Subject: [PATCH] Add forest, winebar, and mono colour themes Three new console themes: forest (dark moss/rust), winebar (burgundy-led warm dark with olive and mustard pops, plus a jazzy I-vi-ii-V tune), and mono (zero-hue, syntax highlighting reads by weight not colour). Theme list reordered to auto/light/dark then alphabetical. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01CXUvHW2ZBJgqinhQ2YWMqs --- README.md | 6 +++--- assets/css/themes/forest.css | 14 ++++++++++++++ assets/css/themes/mono.css | 16 ++++++++++++++++ assets/css/themes/winebar.css | 15 +++++++++++++++ assets/js/console.js | 9 ++++++--- assets/js/tunes.js | 33 +++++++++++++++++++++++++++++++++ 6 files changed, 87 insertions(+), 6 deletions(-) create mode 100644 assets/css/themes/forest.css create mode 100644 assets/css/themes/mono.css create mode 100644 assets/css/themes/winebar.css diff --git a/README.md b/README.md index 0a4a904..4ca5dd2 100644 --- a/README.md +++ b/README.md @@ -128,9 +128,9 @@ the page works fully with JS off. Type `help` inside it for the full command list; the two with real content: - `theme set ` — switch theme. Modes: `light`, `dark`, `auto`, plus any - colour theme file under `assets/css/themes/*.css` (ships with `paper`, - `dracula`, `valentine`, `ocean`). Persisted to `localStorage`, no flash on - reload. + colour theme file under `assets/css/themes/*.css` (ships with `dracula`, + `forest`, `mono`, `ocean`, `paper`, `valentine`, `winebar`). + Persisted to `localStorage`, no flash on reload. - `music play` / `music stop` / `music volume <0-10>` — an 8-bit soundtrack synthesised live with WebAudio (no audio files), one tune per theme, keeps playing across page navigation. diff --git a/assets/css/themes/forest.css b/assets/css/themes/forest.css new file mode 100644 index 0000000..dcfe00d --- /dev/null +++ b/assets/css/themes/forest.css @@ -0,0 +1,14 @@ +/* Forest — deep moss-black dark, rust/amber pop, fern and clay accents. + Concatenated after main.css (see baseof.html). */ +:root[data-theme="forest"] { + --bg: #16211a; --fg: #e4e8d9; --muted: #75846a; --border: #2c3a25; + --accent: #c98a4b; --accent-fg: #16211a; --selection: #33452c; --code: #8fbf7a; + --c-red: #d97757; --c-orange: #c98a4b; --c-yellow: #d8c66a; --c-green: #8fbf7a; + --c-cyan: #5fae9d; --c-blue: #6d94ab; --c-purple: #9b82b3; --c-pink: #c97b93; + /* sets: fern pills, wildflower rows, clay terminal */ + --link: var(--c-cyan); + --pill: var(--c-green); --pill-fg: var(--bg); + --row: var(--c-purple); --row-fg: var(--bg); + --term: var(--c-red); --term-fg: var(--bg); + --focus: var(--c-yellow); +} diff --git a/assets/css/themes/mono.css b/assets/css/themes/mono.css new file mode 100644 index 0000000..64c4007 --- /dev/null +++ b/assets/css/themes/mono.css @@ -0,0 +1,16 @@ +/* Mono — zero hue anywhere, unlike the default light/dark's one rust accent. + The pop palette is 8 grey steps instead of 8 hues, so syntax highlighting + and mermaid diagrams read by weight, not colour — that's the point, not an + oversight. Concatenated after main.css (see baseof.html). */ +:root[data-theme="mono"] { + --bg: #ffffff; --fg: #000000; --muted: #737373; --border: #dddddd; + --accent: #000000; --accent-fg: #ffffff; --selection: #e0e0e0; --code: #000000; + --c-red: #262626; --c-orange: #333333; --c-yellow: #404040; --c-green: #4d4d4d; + --c-cyan: #595959; --c-blue: #666666; --c-purple: #737373; --c-pink: #808080; + /* sets: dark end of the grey scale so fill text stays legible */ + --link: var(--fg); + --pill: var(--c-orange); --pill-fg: #ffffff; + --row: var(--c-red); --row-fg: #ffffff; + --term: var(--fg); --term-fg: var(--bg); + --focus: var(--c-yellow); +} diff --git a/assets/css/themes/winebar.css b/assets/css/themes/winebar.css new file mode 100644 index 0000000..99863e1 --- /dev/null +++ b/assets/css/themes/winebar.css @@ -0,0 +1,15 @@ +/* Winebar — burgundy-led warm dark: olive (true olive, not drab khaki) ranks + second, mustard third, everything else kept muted so the three don't get + crowded out. Concatenated after main.css (see baseof.html). */ +:root[data-theme="winebar"] { + --bg: #241a1a; --fg: #ebdbb2; --muted: #8c7b6b; --border: #3a2a28; + --accent: #8c2f3f; --accent-fg: #ebdbb2; --selection: #4a2530; --code: #d1a537; + --c-red: #8c2f3f; --c-orange: #b3701c; --c-yellow: #d1a537; --c-green: #8a9440; + --c-cyan: #6d8f7a; --c-blue: #5f7d8c; --c-purple: #7a4a5c; --c-pink: #a15c68; + /* sets: burgundy console, olive links + pills + rows, mustard just focus */ + --link: var(--c-green); + --pill: var(--c-green); --pill-fg: var(--fg); + --row: var(--c-green); --row-fg: var(--fg); + --term: var(--c-red); --term-fg: var(--fg); + --focus: var(--c-yellow); +} diff --git a/assets/js/console.js b/assets/js/console.js index 715f5e2..97be020 100644 --- a/assets/js/console.js +++ b/assets/js/console.js @@ -69,8 +69,8 @@ case "theme": { var sub = (cmd.args[0] || "").toLowerCase(); - // base modes first, then colour palettes (see main.css) - var modes = ["light", "dark", "auto", "paper", "dracula", "valentine", "ocean"]; + // auto, light, dark, then colour palettes alphabetically (see main.css) + var modes = ["auto", "light", "dark", "dracula", "forest", "mono", "ocean", "paper", "valentine", "winebar"]; if (sub === "list") { return { lines: modes.map(function (m) { return { text: " " + m }; }) }; } @@ -342,8 +342,11 @@ assert.strictEqual(run("theme set dracula", {}).theme, "dracula"); assert.strictEqual(run("theme set valentine", {}).theme, "valentine"); assert.strictEqual(run("theme set ocean", {}).theme, "ocean"); + assert.strictEqual(run("theme set forest", {}).theme, "forest"); + assert.strictEqual(run("theme set winebar", {}).theme, "winebar"); + assert.strictEqual(run("theme set mono", {}).theme, "mono"); assert.ok(/usage: theme set/.test(run("theme set purple", {}).lines[0].text)); - assert.ok(/dark/.test(run("theme list", {}).lines[1].text)); + assert.ok(/dark/.test(run("theme list", {}).lines[2].text)); assert.ok(/Subcommands/.test(run("theme", {}).lines[4].text)); assert.strictEqual(run("music play", {}).music, "on"); assert.strictEqual(run("music stop", {}).music, "off"); diff --git a/assets/js/tunes.js b/assets/js/tunes.js index 00b7c3e..56a4023 100644 --- a/assets/js/tunes.js +++ b/assets/js/tunes.js @@ -80,6 +80,39 @@ 42, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0] + }, + // D minor pentatonic, mellow triangle lead — an unhurried 4-bar woodland + // loop, sparse like default/dracula (rests, not a filled-in line). + forest: { + bpm: 80, wave: "triangle", + lead: [62, 0, 65, 0, 69, 0, 65, 0, 62, 0, 60, 0, 65, 0, 69, 0, + 72, 0, 69, 0, 65, 0, 69, 0, 62, 0, 65, 0, 60, 0, 62, 0], + bass: [38, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0] + }, + // A I-vi-ii-V turnaround (the "rhythm changes" progression) — mellow + // triangle lead instead of square for a warmer combo tone, syncopated + // off-beat entrances instead of on-the-beat hits (no swing timing in the + // engine, so the swing has to come from where the rests fall), a + // chromatic blue-note resolution back to the tonic in bar 4. Bass keeps + // the oom-pah spacing (root + a jazzier 3rd/7th colour tone per bar, + // like paper's beats 1 and 3) rather than a continuous walk — the + // engine's long note-ring would turn a true walking bass into mush. + winebar: { + bpm: 92, wave: "triangle", + lead: [0, 69, 73, 0, 76, 0, 73, 69, 0, 66, 69, 0, 73, 0, 69, 66, + 0, 71, 74, 0, 78, 0, 74, 71, 0, 68, 71, 72, 0, 71, 69, 0], + bass: [45, 0, 0, 0, 49, 0, 0, 0, 42, 0, 0, 0, 52, 0, 0, 0, + 47, 0, 0, 0, 50, 0, 0, 0, 40, 0, 0, 0, 44, 0, 0, 0] + }, + // Bare octaves, no thirds — a stripped 4-bar loop, deliberately flat and + // undecorated to match the theme's zero-colour palette. + mono: { + bpm: 84, wave: "square", + lead: [60, 0, 0, 0, 60, 0, 0, 0, 65, 0, 0, 0, 65, 0, 0, 0, + 60, 0, 0, 0, 60, 0, 0, 0, 67, 0, 0, 0, 65, 0, 0, 0], + bass: [48, 0, 0, 0, 0, 0, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, + 48, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 53, 0, 0, 0] } }; if (typeof module !== "undefined" && module.exports) module.exports = TUNES;