# GTK3 and GTK4 Generated from the palette, installed as `~/.themes/udt`. One fixed name for every scheme, like Kvantum: the name is referenced by gsettings and by the GTK4 symlink, so a per-scheme name would mean rewriting both on every switch and leaving stale themes behind. Derived from `catppuccin/gtk` v1.0.3, which is **archived upstream**. Forking it is deliberate: it is the theme this desktop already ran, and it will not track future GTK4/libadwaita changes. Replacing it means replacing these templates, not editing a consumer. ## What is substituted Colours appear in two forms and both are replaced: the hex (`#b7bdf8`) and the bare decimal triple GTK writes inside `rgba()` (`183, 189, 248`). Substitution is whole-file, not confined to the `@define-color` block at the tail, because the 8400 lines above it hardcode palette colours too. That was measured, not assumed: 338 occurrences in GTK3 and 328 in GTK4 sit outside the block. `#eff1f5` is upstream's foreground, which is Latte `text`, a near-white it pairs with a Macchiato background. It maps to the `fg` role so GTK text matches rofi, kitty and waybar rather than being brighter than all of them. The generator replaces `@ROLE_RGB@` before `@ROLE@`, because `@FG@` is a prefix of `@FG_RGB@` and the other order would eat the start of the triple placeholder and leave a literal `_RGB@` in the CSS. ## What is left alone Neutral greys and upstream's derived tints: `#3e4152`, `#2e3143`, the `rgba(0, 0, 0, ...)` shadows, `#ffffff`, and the `*_500`/`*_700`/`*_900` Material swatch constants, which ship with every build and are not theme colour. Same rule as the Kvantum SVG: shading is not palette. Two decimal-triple values are mapped anyway, because they are semantic rather than shading: `17, 17, 27` (Latte crust, used as text on the accent) becomes `bg_deep`, and `182, 106, 119` (a darkened red on the close button) becomes `critical`. ## Derived tints Twelve hexes are shades upstream computed from a palette colour rather than taking one, and each paints exactly one widget surface. Leaving them literal, which is the right rule for the neutral greys, left twelve Macchiato-tinted spots on every other scheme, including the window close, minimise and maximise hover fills. They are substituted as `@ROLE_PCT@`, where the percentage is that shade's brightness relative to its base, measured off the Macchiato theme these came from. | Was | Paints | Now | | --- | --- | --- | | `#a0a8f6` | infobar hover | `accent` at 93% | | `#bfc5f8` | selected progress bar (GTK3 only) | `accent` at 103% | | `#d3d7fb` | selection-mode titlebar backdrop (GTK3 only) | `accent` at 109% | | `#e5e8fd` | check and radio, checked and hovered | `accent` at 118% | | `#eea2ae` / `#ea7183` / `#e55267` | infobar, window close active | `critical` at 110/92/79% | | `#eedbb5` / `#eaca89` / `#e5bd6b` | infobar, window minimise active | `warning` at 105/94/86% | | `#b8e0ad` / `#80ca68` | infobar, window maximise active | `success` at 109/81% | `shade()` scales each channel and clamps at 255, so it keeps the relationship rather than reproducing the upstream value exactly. It is closest on the accent family and crudest on the reds, where upstream darkened toward saturation and a flat channel scale darkens toward grey. That is a deliberate ceiling: these are low-traffic surfaces, and a per-tint hand-tuned value for nine schemes would be 108 numbers to maintain. `#e5e8fd` is read as the accent pushed near-white rather than as `fg`, which it is numerically closer to, because it backs a checked-and-hovered check box whose glow is already an accent tint. ## Assets 67 SVGs, carrying only three palette colours: `bg`, `bg_alt` and the accent, the last in 36 of them. The upstream `gtk-3.0/assets` and `gtk-4.0/assets` directories are byte-identical, so one templated set is rendered and copied into both. They are discovered from disk by the generator rather than listed, because they arrive as a set from upstream and a hand-written list would silently miss one added by a future refresh. ## Gotchas - **GTK3 takes its theme name from gsettings on Wayland**, not `settings.ini`. The file is written too, but gsettings wins; it was once pinned to `Breeze`, silently overriding the file for who knows how long. - **GTK4 ignores `gtk-theme-name` entirely.** Its stylesheet is imported by `~/.config/gtk-4.0/gtk.css` through the `theme` symlink. - **`gtk-dark.css` must exist** alongside `gtk.css`. Apps request one or the other depending on the prefer-dark setting; upstream ships them identical. - **GTK apps only reread a theme at startup**, like Qt. A running app keeps the old colours, which is why the accent here is the fixed fallback rather than the wallpaper-tracking one. - **A placeholder with no matching role renders literally** and GTK drops the declaration with no error. `udt-palette --selftest` asserts every placeholder in these templates maps to a role, because 8500 lines is too much to eyeball.