fix dark/light theme toggle — was a dead button with no JS handler

Root cause: the [data-theme-toggle] button existed in ASW's baseof.html
but had no JavaScript attached to it — clicking it did nothing.

Fix:
- static/js/theme-toggle.js — click handler, localStorage persistence,
  prefers-color-scheme fallback, dynamic button icon + aria-label
- static/css/garden.css — full html[data-theme="light"] variable block
  (garden + ASW tokens) so light mode actually looks different from dark
- layouts/partials/head.html — include theme-toggle.js with defer

Light palette: near-white indigo bg (96%), dark indigo text (20%),
violet accents. ASW's @media (prefers-color-scheme) doesn't match
programmatic data-theme toggle, so garden.css provides duplicating
overrides on html[data-theme="light"].
This commit is contained in:
B.A. Baracus 2026-05-26 17:36:46 +02:00
parent 00fa25f436
commit 148d6c9126
Signed by: ba
GPG key ID: D52E9C8491872206
121 changed files with 295 additions and 0 deletions

View file

@ -44,11 +44,64 @@
--garden-wide-width: 80ch;
}
/* ── Light theme ─────────────────────────────────────────── */
/* Override garden's custom properties when theme is light.
ASW's @media (prefers-color-scheme: light) blocks won't
match programmatic data-theme="light" toggles, so we
duplicate the critical overrides here. */
html[data-theme="light"] {
--garden-bg: oklch(96% 0.015 270); /* near-white indigo */
--garden-surface: oklch(92% 0.02 270); /* light card bg */
--garden-border: oklch(80% 0.02 270); /* subtle border */
--garden-text: oklch(20% 0.025 270); /* dark indigo text */
--garden-text-dim: oklch(45% 0.03 270); /* secondary */
--garden-text-faint: oklch(60% 0.02 270); /* tertiary */
--surface: oklch(96% 0.015 270);
--surface-1: oklch(92% 0.02 270);
--surface-2: oklch(88% 0.02 270);
--surface-card: oklch(92% 0.02 270);
--surface-hover: oklch(88% 0.02 270);
--text: oklch(20% 0.025 270);
--text-2: oklch(30% 0.025 270);
--text-3: oklch(45% 0.03 270);
--text-dim: oklch(60% 0.02 270);
--border: oklch(80% 0.02 270);
--border-subtle: oklch(88% 0.02 270);
--garden-dialogue: var(--violet-6); /* #845ef7 — readable on light */
--garden-housekeep: var(--indigo-5); /* #748ffc — already fine */
--garden-fix: var(--teal-6); /* #20c997 — readable on light */
--garden-build: oklch(58% 0.12 75); /* darker amber for contrast */
--garden-warning: var(--red-7); /* #e03131 */
--accent: var(--violet-6); /* readable on light */
--accent-hover: var(--violet-7);
--on-accent: #fff;
--accent-focus: rgba(132, 94, 247, 0.25);
--accent-subtle: rgba(132, 94, 247, 0.08);
}
/* Light-mode adjustments for visual elements */
html[data-theme="light"] .fragment[open] {
background: color-mix(in srgb, var(--fragment-color) 8%, transparent);
}
html[data-theme="light"] pre {
background: var(--surface-2);
border-color: var(--border);
}
/* ── Base ──────────────────────────────────────────────────── */
html[data-theme="dark"] {
background-color: var(--garden-bg);
color: var(--garden-text);
}
html[data-theme="light"],
/* also handle the initial state before JS runs:
ASW baseof.html ships data-theme="dark" but JS may override
to "light" after DOMContentLoaded the default state here
ensures no flash of wrong background if prefers-color-scheme is light */
html:not([data-theme]) {
background-color: var(--garden-bg);
color: var(--garden-text);
}
/* Force body too — ASW sets background-color: var(--surface) */
body {
background-color: var(--garden-bg);