makeover
Shared theme loading for the make-family apps. Parses theme metadata and color values from .toml files on disk, resolves them into intent-based tokens, and derives the rest perceptually (OKLab) with WCAG contrast checks.
The crate ships the theme set it loads, in themes/. Consumers get working themes from a clean checkout without depending on any sibling repo.
Used by MNW server, GoingsOn, Balanced Breakfast, audiofiles, and Alloy.
The crate ships 31 themes. bundled_themes_dir() hands back the directory; embedded_themes() hands back the same set as (id, toml_source) pairs with no filesystem path involved, for consumers that embed at compile time or bundle assets at build time.
Usage
use ;
use PathBuf;
// Set up theme directories (later entries override earlier ones)
let bundled = bundled_themes_dir.expect;
let custom = from;
let dirs = vec!;
// List available themes (sorted by name)
let themes = list_themes_from_dirs;
for t in &themes
// Load a specific theme by ID
let theme = load_theme.unwrap;
println!; // "Catppuccin Mocha"
println!; // "dark"
println!; // "#1e1e2e"
// Build-from-source fallback: the themes this crate ships
if let Some = bundled_themes_dir
Theme File Format
Colors are declared by intent (the role a color plays), not by hue. See themes/ for the 31 bundled themes.
[]
= "Nord" # Display name; falls back to the filename
= "dark" # "dark", "light", or "high-contrast" (default: "dark")
[] # Container backgrounds by elevation
= "#2e3440"
= "#3b4252"
= "#434c5e"
= "#3b4252"
[] # Text and ink by emphasis
= "#d8dee9"
= "#e5e9f0"
= "#616e88"
[] # Interactive / brand color
= "#81a1c1"
[] # State semantics
= "#bf616a"
= "#a3be8c"
= "#ebcb8b"
= "#88c0d0"
[]
= "#4c566a"
[] # Optional: tag and label colors
Derived tokens
Interactive states are not authored. resolve() derives hover, active,
selection, row striping, and contrast pairings perceptually in OKLab, so theme
files stay small and every consuming app derives them identically rather than
each recomputing its own.
intent_css_vars() renders a resolved theme as a :root { … } block for web
consumers; native consumers read RGB tuples off the same resolved tokens.
Theme ID
The theme ID is the filename without .toml (e.g., catppuccin-mocha.toml has ID catppuccin-mocha). IDs must contain only alphanumeric characters, hyphens, and underscores. Path traversal characters are rejected.
API
| Function | Description |
|---|---|
list_themes_from_dirs(dirs) |
Scan directories for .toml files, return sorted Vec<ThemeMeta> |
load_theme(dirs, id) |
Load a theme by ID, returning ThemeColors (metadata + color map) |
find_theme_path(dirs, id) |
Find the file path for a theme ID (highest-priority directory wins) |
parse_meta(id, table, is_custom) |
Parse [meta] from a TOML table into ThemeMeta |
extract_colors(table) |
Flatten color sections into a HashMap<String, String> |
validate_theme_id(id) |
Check that an ID contains only safe characters |
bundled_themes_dir() |
The themes/ directory this crate ships, for build-from-source fallback |
embedded_themes() |
The shipped themes as (id, toml_source) pairs, embedded at compile time (no path needed) |
parse_theme_str(id, source, is_custom) |
Parse a theme from a string, for use with embedded_themes() |
resolve(theme) |
Resolve authored intents into the full token set, deriving interactive states |
intent_css_vars(tokens) |
Render resolved tokens as a :root { … } CSS block |
Directory Priority
list_themes_from_dirs and load_theme accept a list of (PathBuf, bool) pairs. Later directories override earlier ones by theme ID. The bool marks whether the directory contains user-custom themes (is_custom on ThemeMeta).
Typical setup for a Tauri app:
- Bundled themes, packaged by the app or from
bundled_themes_dir()(is_custom = false) - User themes from an app data directory (is_custom = true)
License
MIT.
The themes in themes/ adapt palettes from third-party projects (Catppuccin, Dracula, Nord, gruvbox, Tokyo Night, Rosé Pine, and others). Each upstream, its license, and the exact copyright line that license requires reproducing are recorded in THIRD-PARTY-NOTICES.md, verified against the upstream LICENSE files themselves. Every adapted theme file also carries that information in a header comment, so credit travels with the file.
If an attribution is wrong or you would prefer your work not be included, write to info@makenot.work and it will be corrected or removed.