feat: contrast levels and custom color picker in appearance menu

Generate medium/high contrast schemes, add a custom swatch that builds a scheme
in the browser via lazy-loaded scheme.js, allow Theme Builder exports as palettes.
Drop the teal palette and spread the swatches across the menu width.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Andreas Reinhold / reini
2026-10-05 12:40:34 +02:00
co-authored by Claude Opus 5.5
parent b4eba7ae63
commit 6c271ffffe
8 changed files with 289 additions and 47 deletions
+14 -5
View File
@@ -48,9 +48,11 @@ the map, so run it after every Redmine update.
### Colors
Each user picks a mode (Auto / Light / Dark) and a color (Purple, Blue, Teal, Green, Orange) in the
Each user picks a mode (Auto / Light / Dark), a contrast level (Standard / Medium / High) and a color (Purple, Blue, Green, Orange) in the
**Appearance** section of the profile menu (top right; in the mobile menu at the bottom). The choice is
stored per browser (`localStorage`); Auto follows the operating system.
stored per browser (`localStorage`); Auto follows the operating system. The last (rainbow) swatch
lets users pick any color: `javascripts/scheme.js` is loaded on demand, generates the scheme in the
browser, and the generated CSS is stored with the choice, so later page loads don't need it.
The color roles are generated from one seed color per palette with `@material/material-color-utilities`
(scheme TonalSpot) into `tonalmine/stylesheets/palettes.css`:
@@ -58,12 +60,19 @@ The color roles are generated from one seed color per palette with `@material/ma
```sh
cd tools/palettes
npm install # once
npm run build # writes palettes.css
npm run build # writes palettes.css and javascripts/scheme.js
```
To add or change a palette, edit `PALETTES` in `tools/palettes/build_palettes.mjs` and in
`tonalmine/javascripts/theme.js` (the build fails if they differ), then rebuild. The only other
hard-coded colors are the select chevrons `images/arrow-drop-down*.svg` (one per mode).
`tonalmine/javascripts/theme.js` (the build fails if they differ), then rebuild.
To use a scheme from [Material Theme Builder](https://material-foundation.github.io/material-theme-builder/)
as-is: export it as Web (CSS), copy its `light.css` and `dark.css` into `tools/palettes/themes/<name>/`,
and also its `light-mc.css`, `light-hc.css`, `dark-mc.css` and `dark-hc.css` contrast files. Then add
`['<name>', '<seed>', 'themes/<name>']` to `PALETTES`. The roles are copied from the export; the seed
only tints the success/warning colors.
The only other hard-coded colors are the select chevrons `images/arrow-drop-down*.svg` (one per mode).
## License