Theming
Marchyo owns every themed surface itself, all derived from the Jylhis Design System: the desktop (GTK, Hyprland, the Quickshell shell, Waybar, Mako, Ghostty, fzf, bat, hyprlock, starship, the console, the Vicinae launcher, the Plymouth boot splash), Qt (through the GTK settings, QT_QPA_PLATFORMTHEME=gtk3), the TUI long tail (lazygit, k9s, ncspot, spotify-player, gdu), and Emacs (the design system’s own jylhis themes). Most surfaces restyle at runtime via marchyo theme set/next — no rebuild. There is no Stylix: marchyo retired it once every surface it covered had a marchyo-owned path.
The launcher is a slightly different case, and split by shell: with marchyo.shell.enable the in-shell launcher themes itself from the design tokens at runtime (the shell’s Color singleton — no registration needed), while the discrete stack’s Vicinae gets two real themes (jylhis-dark for dark, jylhis-light for light) generated from the design tokens and registered both, so the full color surface — text, inputs, buttons, list and grid selection, scrollbars, tooltips — is covered rather than just the background/accent basics. See Launcher.
Options
Section titled “Options”| Option | Type | Default | Description |
|---|---|---|---|
marchyo.theme.enable |
bool |
true |
Enable the theming system |
marchyo.theme.variant |
"dark" or "light" |
"dark" |
Theme variant preference |
marchyo.theme.scheme |
string or null |
null |
Override the base16 color scheme (a tinted-schemes catalog name) |
marchyo.theme.fontScale |
number (0.5–4.0) |
1.25 |
Global font-size multiplier applied to every text surface |
marchyo.theme.themes |
list of string or inline base16 theme |
["jylhis-dark" "jylhis-light"] |
Themes available for runtime switching (pre-built into the closure) |
marchyo.theme.followWallpaper |
bool |
false |
marchyo bg set / bg next also generate a matugen theme from the new wallpaper (details) |
marchyo.theme.wallpaper.enable |
bool |
true |
Enable the generated Marchyo grid wallpaper where supported |
marchyo.theme.wallpaper.package |
package |
pkgs.marchyo-wallpapers |
Package providing generated Marchyo wallpaper assets |
Basic usage
Section titled “Basic usage”marchyo.theme = { enable = true; variant = "dark";};Color schemes
Section titled “Color schemes”By default the theme is the Jylhis Design System palette, derived from its themes/jylhis.json:
| Variant | Palette |
|---|---|
"dark" |
Jylhis Dark (the “Negative” mode) |
"light" |
Jylhis Light (the “Print” mode) |
Both variants sit on a cool, near-neutral ground with a single bronze interactive accent, a benchmark-vermilion brand mark, and a structural contour blue used for linework only. Code colors are Emacs Modus Operandi (light) / Vivendi (dark), so syntax reads identically in every editor and terminal.
To use a different base16 scheme instead, set marchyo.theme.scheme to the name of a .yaml file in the tinted-theming/schemes catalog (the base16/ directory):
marchyo.theme = { variant = "dark"; scheme = "gruvbox-dark-medium"; # any tinted-schemes catalog name, e.g. "nord"};A base16 theme in runtime switching (a catalog or inline entry, or a matugen result) colours each design token from the slot that best matches its role:
| Slot | Tokens |
|---|---|
base00 |
bg |
base01 |
bg-subtle, accent-subtle |
base02 |
surface, selection-bg |
base03 |
text-faint, border, syn-comment |
base04 |
text-muted, border-strong |
base05 |
text |
base06 |
text-heading |
base07 |
surface-raised |
base08 |
status-err, destructive, syn-variable |
base09 |
accent, accent-hover, cursor, syn-number |
base0A |
status-warn |
base0B |
syn-string, status-ok |
base0C |
syn-type, syn-builtin |
base0D |
status-info, syn-function |
base0E |
syn-keyword |
base0F |
brand |
selection-bg, destructive and the extra syn-* tokens follow the slot the base16 styling guidelines name for that role (Selection Background, Diff Deleted, Variables, Integers, Support, Functions). contour, decorator, scrim and syn-docstring have no base16 role and keep the Jylhis hex. A matugen theme additionally takes border, border-strong and accent-subtle from Material’s outline_variant, outline and primary_container when matugen emits them.
Marchyo carries the design system’s three type roles across the system — the
fontconfig role mapping (modules/generic/fontconfig.nix), the GNOME interface
fonts Qt and GTK apps resolve (modules/home/jylhis-theme.nix), and every
surface that names a family directly. The defaults are:
| Role | Family | Package |
|---|---|---|
| Display / headings (serif) | Zilla Slab | pkgs.zilla-slab |
| Body (sansSerif) | Hanken Grotesk | pkgs.hanken-grotesk |
| Monospace | BlexMono Nerd Font (IBM Plex Mono, Nerd Font patched) | pkgs.nerd-fonts.blex-mono |
The Nerd Font patch of IBM Plex Mono is used for monospace because the desktop chrome — Waybar, Mako, hyprlock, Ghostty — needs the icon glyphs. To change the role mapping, override the fontconfig defaults:
fonts.fontconfig.defaultFonts.monospace = [ "JetBrainsMono Nerd Font" ];Font size
Section titled “Font size”marchyo.theme.fontScale is a single multiplier that resizes every text
surface at once — the interface fonts (GTK, Qt, Electron), the terminal, the
bar, notifications, the lock screen, the launcher, the TUI apps, and the TTY
console. It defaults to 1.25 (noticeably larger than upstream defaults).
Set it to 1.0 to restore the historical sizes, or higher for
HiDPI-at-distance or accessibility:
marchyo.theme.fontScale = 1.5; # everything ~50% largerEach surface scales from its own base size and rounds to a whole number, so the proportions between surfaces are preserved.
Runtime theme switching
Section titled “Runtime theme switching”marchyo.theme.themes lists the themes available for runtime switching — no rebuild needed. Each listed theme’s desktop assets (Waybar CSS, Mako config, Hyprland colors, Ghostty colors, wallpaper, GTK CSS + the dconf color-scheme, bat config, fzf colors, hyprlock colors, console palette, the k9s skin, lazygit, spotify-player and gdu colors, and a palette.json token map) are pre-built into the system closure so a switch is an instant symlink swap. The default list is the Jylhis pair; add any tinted-schemes catalog name to make it switchable:
marchyo.theme.themes = [ "jylhis-dark" "jylhis-light" "nord" "gruvbox-dark-hard"];Inline catalog themes
Section titled “Inline catalog themes”An entry can also be an inline base16 theme — the catalog contract — so you
can add an arbitrary palette (an omarchy colors.toml, a matugen result, your
own) without it living in any upstream catalog. Provide the sixteen
base00..base0F slots and a polarity; every runtime surface is derived from
them, and an optional wallpaper overrides the default grid:
marchyo.theme.themes = [ "jylhis-dark" { name = "kanagawa"; variant = "dark"; slots = { base00 = "#1f1f28"; base01 = "#2a2a37"; base02 = "#223249"; base03 = "#727169"; base04 = "#c8c093"; base05 = "#dcd7ba"; base06 = "#938aa9"; base07 = "#363646"; base08 = "#c34043"; base09 = "#ffa066"; base0A = "#dca561"; base0B = "#98bb6c"; base0C = "#7fb4ca"; base0D = "#7e9cd8"; base0E = "#957fb8"; base0F = "#d27e99"; }; # wallpaper = ./kanagawa.png; # optional; defaults to the Jylhis grid }];Runtime switching covers every surface except the Plymouth boot splash (it is
not on screen during a session) and ncspot (its theme sits inline in
config.toml, which has no include, so it follows the build-time
variant/scheme at rebuild). Qt follows the GTK swap: the session runs
QT_QPA_PLATFORMTHEME=gtk3, so Qt apps pick up the swapped gtk.css and dconf
color-scheme on next launch. The switch is ephemeral: the next activation
resets to the declarative default.
The TUI apps read their colours through the ~/.config/marchyo/current-theme
pointer. k9s restyles open sessions: marchyo theme relinks
~/.config/k9s/skins/jylhis.yaml at the new theme’s skin, and k9s watches its
skins directory. lazygit, spotify-player and gdu pick up the new theme the next
time they start. ~/.config/spotify-player/theme.toml and
~/.config/gdu/gdu.yaml link into the pointer, and lazygit loads
LG_CONFIG_FILE, which lists its main config.yml followed by the pointer’s
lazygit.yml (lazygit merges the files in order, so the theme overlay wins).
LG_CONFIG_FILE is a session variable, so it applies from the next login.
These TUI colours come from base16 slots: with marchyo.theme.scheme set, the
declarative theme’s files carry that scheme’s slots, as the build-time config
does. Off the desktop, and on Darwin, the TUI apps keep the build-time colours.
GTK apps follow a runtime switch on next launch (newly started apps read the
swapped ~/.config/gtk-{3,4}.0/gtk.css; libadwaita apps additionally restyle
live via the dconf color-scheme). Ghostty restyles open windows live too —
its runtime include names the Jylhis pair as a ghostty light/dark theme pair
(theme = dark:…,light:…), which ghostty resolves from the system
color-scheme, so the same dconf write that flips libadwaita apps recolors
running terminals. The Quickshell bar (marchyo.shell.enable)
recolors live as well — it reads the active theme’s palette through the same
pointer — and Super+Shift+L cycles the theme from the compositor.
Wallpaper
Section titled “Wallpaper”A generated Marchyo grid wallpaper is enabled by default wherever it is supported. To disable it, or to supply your own wallpaper asset package:
marchyo.theme.wallpaper = { enable = false; # skip the generated wallpaper # package = pkgs.my-wallpapers; # or swap in a different asset package};Wallpaper-derived theming (matugen)
Section titled “Wallpaper-derived theming (matugen)”marchyo theme generate <image> builds a colour scheme from a wallpaper with matugen and applies it live — no rebuild:
marchyo theme generate ~/Pictures/wall.jpg # let matugen pick the polaritymarchyo theme generate ~/Pictures/wall.jpg --light # force a light schememarchyo theme generate ~/Pictures/wall.jpg --dark # force a dark schememarchyo theme generate --revert # back to the declarative themematugen extracts a base16 palette from the image, which Marchyo maps through the same token slots the catalog schemes use. A generated theme restyles every surface a theme set does: the shell (bar, panels, toasts), the terminal (Ghostty), Hyprland window borders, Mako, Waybar, GTK (plus the dconf color-scheme), bat, fzf, the hyprlock fallback lock screen, the console palette (best-effort, as for every switch), k9s, lazygit, spotify-player, gdu, and the wallpaper itself.
The colours come from two files the build ships in the declarative variant’s theme dir: palette.json (every design token’s hex, syn-* included, and the token-to-base16-slot table) and templates/ (the Mako, Waybar and GTK configs with each colour as a token placeholder). theme generate fills each placeholder with the matugen slot for that token, and a token with no base16 slot keeps the build variant’s hex. For bat it writes a marchyo-generated.tmTheme into bat’s themes directory and runs bat cache --build.
Qt follows the runtime GTK swap on next launch (QT_QPA_PLATFORMTHEME=gtk3),
and starship styles through ANSI slot names, so it already recolors with the
terminal’s live palette. Only the Plymouth boot splash (not on screen during a
session) and ncspot keep the declarative theme until the next rebuild
(Runtime theme switching). Like marchyo bg, the generated theme is runtime-only: a rebuild (or --revert) resets to marchyo.theme.variant/scheme. Requires the desktop feature (matugen ships with it).
Follow the wallpaper
Section titled “Follow the wallpaper”An opt-in Material You mode makes the theme track the wallpaper. It is off by default; the Jylhis palette stays the declarative theme either way.
marchyo.theme.followWallpaper = true;With it set, every marchyo bg set <image> and marchyo bg next runs the theme generate path on the new image after setting it, with matugen picking the polarity as a bare theme generate <image> does. If generation fails (matugen missing, an unreadable image), the wallpaper still changes, the CLI prints a warning, and the command exits 0.
Both changes are recorded as runtime overrides, so marchyo runtime restore at login replays the wallpaper and the generated theme together. A failed generation leaves the theme override as it was, so restore replays the new wallpaper and whichever theme was live before. marchyo bg set --revert shows the active theme’s wallpaper, which under a generated theme is the image it came from; marchyo theme generate --revert and marchyo theme set return to a declarative theme as usual, and a rebuild resets everything.
Light mode
Section titled “Light mode”To use the light theme:
marchyo.theme = { variant = "light";};Shell appearance scale
Section titled “Shell appearance scale”With the Quickshell shell (marchyo.shell.enable = true), a set of
palette-independent axes adjust the shell’s geometry, corners, animation
speed, contrast, and overall shape without touching the colour palette.
The scale axes default neutral; the style axes (floatingBar,
surfaceAlpha) are Caelestia-inspired and default on.
marchyo.theme.appearance = { # floatingBar = false; # full-width strip bar instead of the floating pill # surfaceAlpha = 1.0; # opaque surfaces, no blur (default 0.85 glass) # cornerRadiusScale = 0.0; # square every corner (default 1.0) # uiScale = 1.2; # larger chrome without changing font size # animationSpeed = 2.0; # faster transitions (default 1.0) # highContrast = true; # thicker panel/notification borders};| Option | Type | Default | Description |
|---|---|---|---|
floatingBar |
bool |
true |
Detached rounded pill bar with gaps to the screen edges; false restores the full-width strip |
surfaceAlpha |
float |
0.85 |
Surface opacity; below 1 enables the Hyprland blur effect for the shell’s layer surfaces (glass look) |
cornerRadiusScale |
float |
1.0 |
Multiplier on corner radii (0.0 squares corners) |
uiScale |
float |
1.0 |
Geometry multiplier on top of fontScale, fonts unchanged |
animationSpeed |
float |
1.0 |
Animation speed (higher is faster) |
highContrast |
bool |
false |
Thicker separators for higher-contrast chrome |
With the shell on, Hyprland also turns on short compositor animations driven by
a snappy popin bezier: windows pop in, the shell’s panels, launcher, and OSD
pop in, the bar slides from its edge, and toasts and tooltips keep their own
QML transitions. Workspace switches and border colour changes stay instant.
With the shell off, compositor animations stay disabled.
Login greeter
Section titled “Login greeter”The greetd login greeter is built in the host’s marchyo.theme.variant, so a
light host shows a light login screen. It also follows the session theme:
every marchyo theme set, next, or generate writes the active theme’s
colours to /var/lib/marchyo/greeter/theme.json, and the greeter picks them up
at start and whenever the file changes. The directory is owned by root:users
with mode 1775, so session users can write their own marker but cannot
replace another user’s. The greeter accepts only #rrggbb values for colour
keys it already knows; a missing or invalid file falls back to the built-in
variant palette. A declarative rebuild does not touch the marker, so the
greeter keeps the last theme the CLI activated.