diff --git a/README.md b/README.md index 7639b56..0a4a904 100644 --- a/README.md +++ b/README.md @@ -129,7 +129,8 @@ 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`). Persisted to `localStorage`, no flash on reload. + `dracula`, `valentine`, `ocean`). 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/ocean.css b/assets/css/themes/ocean.css new file mode 100644 index 0000000..546c322 --- /dev/null +++ b/assets/css/themes/ocean.css @@ -0,0 +1,14 @@ +/* Ocean — deep navy water, foam-pale ink, teal + coral pops. + Concatenated after main.css (see baseof.html). */ +:root[data-theme="ocean"] { + --bg: #0b1e2d; --fg: #dceef5; --muted: #5c8aa3; --border: #1c3a4f; + --accent: #22b8cf; --accent-fg: #06232e; --selection: #1e4a5f; --code: #ffa94d; + --c-red: #ff6b6b; --c-orange: #ffa94d; --c-yellow: #ffd93d; --c-green: #38d9a9; + --c-cyan: #22d3ee; --c-blue: #4dabf7; --c-purple: #9775fa; --c-pink: #f783ac; + /* sets: cool water surfaces, coral console for contrast */ + --link: var(--c-cyan); + --pill: var(--c-green); --pill-fg: var(--bg); + --row: var(--c-blue); --row-fg: var(--bg); + --term: var(--c-pink); --term-fg: var(--bg); + --focus: var(--c-orange); +} diff --git a/assets/js/console.js b/assets/js/console.js index 5cb147e..715f5e2 100644 --- a/assets/js/console.js +++ b/assets/js/console.js @@ -70,7 +70,7 @@ 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"]; + var modes = ["light", "dark", "auto", "paper", "dracula", "valentine", "ocean"]; if (sub === "list") { return { lines: modes.map(function (m) { return { text: " " + m }; }) }; } @@ -341,6 +341,7 @@ assert.strictEqual(run("theme set dark", {}).theme, "dark"); 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.ok(/usage: theme set/.test(run("theme set purple", {}).lines[0].text)); assert.ok(/dark/.test(run("theme list", {}).lines[1].text)); assert.ok(/Subcommands/.test(run("theme", {}).lines[4].text)); diff --git a/assets/js/tunes.js b/assets/js/tunes.js index de1c15b..988ba6c 100644 --- a/assets/js/tunes.js +++ b/assets/js/tunes.js @@ -52,6 +52,28 @@ 47, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0] + }, + // D whole-tone, sine lead — no eighth-note rests, a continuous rippling + // current instead of a beat-driven melody. Whole-tone (no semitones) is + // the classic "underwater" scale (Debussy, water-level video game themes) + // since it has no leading tone pulling anywhere — it just drifts. One + // swelling 8-bar wave: rises to a crest in bar 5, recedes back to the + // tonic to loop. Bass pedal follows the same swell (D, up to the tritone + // G#, back to D) rather than outlining a chord progression. + ocean: { + bpm: 78, wave: "sine", + lead: [62, 64, 66, 64, 62, 60, 58, 60, + 64, 66, 68, 66, 64, 62, 60, 62, + 66, 68, 70, 68, 66, 64, 62, 64, + 68, 70, 72, 70, 68, 66, 64, 66, + 70, 72, 74, 76, 74, 72, 70, 68, + 68, 66, 64, 62, 64, 66, 68, 70, + 64, 62, 60, 58, 60, 62, 64, 66, + 62, 60, 58, 56, 54, 52, 50, 50], + bass: [38, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, + 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] } }; if (typeof module !== "undefined" && module.exports) module.exports = TUNES;