- Regroup Redmine's "<strong>Label</strong>: value<br>" tooltip lines on first hover into a title block and a label/value grid (theme.js). - Style the issue link as a kicker, the subject as title-small, and the labels as a muted column next to aligned values. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tonalmine
Material Design 3 theme for Redmine 7.0.
Install
- Copy the
tonalmine/folder into<redmine>/themes/. - Restart Redmine (theme assets are compiled at boot).
- Select Tonalmine in Administration → Settings → Display → Theme.
Development
Requires Docker.
cd dev
docker compose up -d # Redmine 7.0.1 on http://localhost:3070
docker compose exec redmine bin/rails runner /seed/seed.rb # once: demo data, selects the theme
docker compose restart redmine # after every CSS change
Login: admin / admin.
The theme folder is bind-mounted into the container, so edits are picked up on restart.
Screenshots
cd e2e
npm install && npx playwright install chromium # once
node screenshots.mjs # all pages, light/dark × desktop/mobile → screenshots/
node screenshots.mjs issue # only pages whose name contains "issue"
node check-form-alignment.mjs # fails if a form label is not level with its field
node check-font-sizes.mjs # fails if any text is off the type scale (e.g. core 0.9em leftovers)
Icons
tonalmine/images/icons.svg replaces Redmine's icon sprite with Material Symbols Outlined.
It is generated from tools/icon_map.yml:
ruby tools/build_icons.rb
The script fails when Redmine's config/icon_source.yml (7.0-stable) has icon names that are missing from
the map, so run it after every Redmine update.
Colors
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. 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:
cd tools/palettes
npm install # once
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.
To use a scheme from 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
MIT, see LICENSE. Roboto (OFL 1.1) and Material Symbols (Apache 2.0) keep their own licenses.