| Age | Commit message (Collapse) | Author | Files | Lines |
|
`udt-ledstrip on|off` switches the strip, replaying the gradient when it
comes on; with no argument it still only replays the gradient, so a
wallpaper change leaves a strip the user switched off alone.
The last address is cached in ~/.cache/udt/ledstrip.json, because `off`
runs as the session ends and cannot wait up to 20 s for a broadcast.
From the cache a switch takes under half a second; discovery is the
fallback when the cached address fails.
hypr-theme calls it at login, on Hyprland's shutdown event, and around
suspend from hypridle.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
udt-ledstrip sends the window border's three hues to every Tuya
addressable strip in the tinytuya device list as a flow scene (DP 51,
dreamlight_scene_mode), so the strip moves with the wallpaper accent.
Fully local: it speaks protocol 3.5 itself with cryptography, finds the
strip by its UDP discovery broadcast, and reads the local key from
~/.config/udt/tuya/devices.json, written once by tinytuya's wizard.
DP 51's layout is undocumented and missing from the cloud spec; it was
read off the strip's status pushes while the app set scenes. Saturation
is floored at full because LEDs render pastel accents as white.
udt-accent starts it detached next to udt-keyboard; install.sh links it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
write_firefox reports a PIL or disk error instead of raising, so main()
still updates GRUB and the homepage and starts the helpers; a selftest
case covers a real image and a broken one under a temporary HOME.
An unknown option or a missing file was taken as the wallpaper and its
path written into SDDM's config and colors.json. Now --help prints the
usage and anything else that is not an existing file exits 2.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The ssh menu's banner, title plate and plated search bar move into
header.rasi, which ssh.rasi, list.rasi and grid.rasi import, so every
searchable menu gets the same header with its -p as the title. The
banner's @WPAPER@ now lives in header.rasi, so that file is generated
and ssh.rasi is linked again.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The prompt is lifted onto the card as a left-aligned "Screenshot:"
header with a camera glyph. confirm.rasi sets its own card children, so
the power menu's confirm step keeps its centred question and no header.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
rofi's ssh mode shows the alias only. blackpearl-sshmenu.sh now reads
~/.ssh/config itself and feeds dmenu two-line cards: the alias, then
"user · address" with the user only where the config sets one. ssh.rasi
lays them out 4x3 under an "SSH:" header lifted out of the inputbar.
The script moves into bin/ under the name hypr-theme's keybinding calls,
and install.sh links it and the theme like the other menus.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The confirm and screenshot menus split the monitor into two half-screen
buttons with a glyph sized from the monitor height. They are now a fixed
368px card centred on the scrim, two 150px buttons at 72pt, so the
scripts no longer compute a glyph size.
Glyphs in all three menus sat right of centre: common.rasi's element
spacing still reserved a gap for the hidden icon. Elements now hold
element-text only. The power menu's greeting ignored horizontal-align,
so spacers either side centre it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
quickshell's appearance shell was merged into its desktop process, whose
settings window now holds the appearance pages and the steps window. The
appearance IPC target kept its verbs there, so only the path changes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The new tab showed the wallpaper verbatim, so it read as a hole onto
the desktop. write_firefox now scales the wallpaper to 1920 wide and
applies a Gaussian blur (FIREFOX_BLUR, radius 24) with PIL before
saving it into FF Ultima's darknix.png slot. Saving through PIL also
makes the file a real PNG whatever the wallpaper's format.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Write background_<output>= into the SDDM theme config for every screen
wallp manages, read from wallp.conf's OUTPUT_H/OUTPUT_V and the saved
wall_h/wall_v. The greeter shows each monitor its own wallpaper instead
of the horizontal one on both. Missing wallp state writes no keys, so
the greeter falls back to the shared background.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The darknix.png symlink out of the profile left the new tab blank, even
after a restart: Firefox's sandbox does not follow it. udt-accent now
copies the wallpaper over the slot on every change instead, removing any
leftover link first so the copy cannot write through it into the
wallpaper. install.sh no longer makes the link.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Both sat on the scheme's fixed accent, on the grounds that nothing at boot
and nothing on the dashboard host can read the wallpaper. Neither needs to:
both are generated here, and both already carry the wallpaper itself, so a
wallpaper change already leaves them stale and raises their root steps.
Following the accent adds no step.
udt-accent rewrites the accent in the generated files before it starts
udt-grub and udt-homepage: the accent= value on theme.txt's '# udt:' line,
which grub-theme-udt's build reads for its PNG slices, and a single
--udt-accent line in homepage's custom.css that every accent rule now
reads. Sublime's rewrite moves onto the same helper, which also keeps the
file's mode rather than leaving it 0600.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
colorz returned cluster means, which averaged a small vivid element into
its surroundings, so a violet motif on a frame of pale skin came out as a
muddy red. signature_color() now reads the pixels of a 256px thumbnail
itself and scores each by chroma times its distance from the image's mean
colour. The top 2% vote by hue, neighbouring bands summed, and the most
vivid pixel near the peak is snapped. A pick under chroma 25 is a tint and
takes the fallback.
Dropping colorz also fixes two bugs. Its k-means seeds are random, so one
wallpaper could snap differently between runs. And it calls sys.exit() on
some images, which `except Exception` in main() does not catch, so
udt-accent died without writing and the previous accent stayed.
Over 314 wallpapers: no errors (colorz failed on 18), 25 fall back,
about 0.06s each. The selftest gains a small-vivid-patch case and a
grey-image case.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
udt-keyboard sets an Ajazz AK820 Pro to its "launch" effect in the
current accent through ak820-ctl, and does nothing without it.
udt-accent starts it detached on every run; --watch reapplies the
accent when the USB cable is plugged in, since the keyboard takes no
commands over its dongle or Bluetooth.
The firmware ignores a mode change unless the lights go off first and
settle, so it sends off, waits three seconds, then the mode. A lock
keeps a wallpaper change and a plug-in from interleaving the pairs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
btop gets a generated udt.theme and only the color_theme line of btop.conf
is rewritten. Joplin gets userchrome.css overriding the --joplin-* custom
properties most of its UI is built on, with !important since Joplin's own
:root block is injected later; a userchrome.css udt did not write is left
alone. Feishin 1.17 watches a Themes folder for JSON themes, so UDT.json
extends its built-in Catppuccin Mocha with the scheme's roles and reaches
a running Feishin live once selected.
All three use existing roles, so no scheme file changes. udt-appthemes
installs them next to Obsidian and Typora; the recap hint names btop and
Joplin among the apps that need a restart.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
udt-accent's docstrings and AGENTS.md still said colors.json was a fixed
Macchiato palette. It has been built from udt_colors.PALETTE, which
udt-palette generates per scheme, since schemes became switchable; the
live file carries candy-night's colours. The terminal likewise follows
the scheme, only never the wallpaper.
The stock ~/.config/waybar/ has been deleted, so the notes explaining why
install.sh leaves it alone now just record that it is gone.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Notification balloons carried the GRUB and homepage root commands, but a
balloon cannot stay open while its commands are pasted into a root shell.
bin/udt-steps NAME writes a consumer's pending steps to
~/.cache/udt/steps/NAME and pokes quickshell's appearance shell, which shows
one tab per file on DP-3. Empty stdin clears the tab, so producers report
on every run and a consumer that caught up drops out by itself.
udt-grub and udt-homepage now route through it. install.sh's SDDM block
checks what is installed and reports only the steps still missing, rather
than printing the full install on every run. udt-homepage remembers the
last staged pair, since udt-accent now also runs on icon switches, which
change neither file and would re-raise the finish steps for nothing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
GRUB's background is a wallpaper snapshot, but only install.sh rebuilt it,
so a wallpaper change left the /boot copy stale with no hint. udt-grub now
holds the build-and-print logic; install.sh runs it in the foreground and
udt-accent starts it detached next to udt-homepage. A stale installed theme
gets a notification carrying the root copy command. A flock serialises the
two runs install.sh triggers, since build swaps dist/udt in by rename.
AGENTS.md: udt-accent writes seven outputs (SDDM was missing), and names
the two detached helpers.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The GRUB theme titles its panel with the machine's pretty name, and on
Slackware nothing writes /etc/machine-info: hostnamectl is systemd's. This
sets the one key, keeping any others, and with no argument prints it.
The value is double-quoted with only \ and " escaped, the escapes systemd's
reader and the GRUB build's shlex agree on; control characters are refused.
It needs root and is never run by install.sh, which only suggests it in the
GRUB output while no name is set. tests/machine-name.sh checks the quoting
round-trip against shlex.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
theme.txt has no include, so udt-palette substitutes eight roles and the
scheme name into the sibling repo's theme.txt.in, conky-style. The accent is
the scheme's fixed one; nothing at boot can read the wallpaper.
install.sh runs that repo's build as the user and, only when it succeeds,
prints the root copy into /boot/grub/themes plus the one-time GRUB_THEME and
grub-mkconfig steps. External targets are now skipped whenever their template
is missing, not only when the repo is, so a sibling mid-setup cannot break an
install.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The rofi menus' launch scripts lived loose in ~/bin, so the themes were
tracked and the only things that open them were not. They now live in bin/
and are symlinked under the names hypr-theme's keybindings call.
neovim gets a generated colorscheme: catppuccin/nvim with all 26 palette
colours overridden from the active scheme, selected by rewriting only the
colorscheme line of init.vim. hypr-theme is linked as the whole of
~/.config/hypr, leaving a real directory there alone.
The qt-gtk templates were reference copies nothing installed. They now hold
theme keys only and ini_merge writes them into the live qt5ct, qt6ct and
gtk3 files key by key, keeping every other line; tests/ini-merge.sh checks
it. The stale kvantum.kvconfig template is gone, install.sh writes that file.
Fresh-machine fixes: settings.ini and ~/.config/gtk-4.0 are created when
missing instead of aborting under set -e, and conky is found as a sibling
checkout and skipped when absent, in udt-palette as well as install.sh.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The power menu's ground was a hardcoded rgba(36, 39, 58, 0.88),
Macchiato's base, so every other scheme drew its overlay with a
Macchiato tint. Each roles file now defines scrim as its own
background at 88% alpha, udt-palette emits it into palette.rasi, and
powermenu.rasi uses @scrim.
scrim is the first translucent palette entry, so udt-accent's QML
palette no longer drops the alpha pair: an opaque colour still goes
out as #rrggbb, a translucent one as QML's #aarrggbb.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
palette.rasi is what udt-accent forwards to quickshell as
udt-palette.qml, and the keybind reminder there draws the macropad's
orange, purple and blue keycaps. peach and mauve come from the peach
and highlight roles every scheme defines; mauve used to be added only
to waybar's compat list, which now reads it from ROFI_NAMES instead of
defining it twice.
The existing "blue" name carries the active-border role, magenta under
candy-night, so the terminal's blue goes out as termblue. The first
spelling, term_blue, made rofi reject palette.rasi and with it every
theme; AGENTS.md now says so next to the selftest.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The greeter drew the AccountsService icon while hyprlock and the rofi
powermenu draw ~/.user-icon.jpg, so one login showed two pictures.
udt-accent now writes that path as `avatar`, plus `avatarUser` naming
who it belongs to, into the generated theme.conf.user. Both stay empty
when the file is missing so the greeter keeps its fallback.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
kcalc rendered white under the dark Kvantum theme. Off Plasma,
KStyleManager forces Breeze unless kdeglobals names a widgetStyle, and
KColorSchemeManager applies BreezeLight unless kdeglobals names a colour
scheme; qt6ct never forwards the portal's prefer-dark to Qt.
Generate a udt.colors KColorScheme from the Kvantum roles, install it to
~/.local/share/color-schemes/, and point kdeglobals at it and at
kvantum-dark.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
bin/udt-homepage replaces install.sh's inline scp. It stages custom.css
and the current wallpaper, keeping the wallpaper's own extension, then
raises a desktop notification with the root commands that install both
and point settings.yaml at the new background. Plain root commands, not
sudo: the login user on that host has no sudo rights.
udt-accent starts it detached on every run, so it follows a wallpaper
change (wallp) as well as a scheme switch (install.sh) without holding
either up when the host is unreachable.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
udt-palette renders the scheme-level palette to
templates/hyprlock/hyprlock-palette.conf ($panel, $input_bg, $text,
$subtext, $fail); udt-accent writes the wallpaper accent gradient to
~/.cache/udt/hyprlock-border.conf as a hyprlang variable. The hyprlock
config sources both, so a scheme switch recolours the lock and a
wallpaper change recolours its border.
install.sh copies the palette and seeds the border from the committed
fallback on a fresh cache. Both selftests cover the new outputs.
|
|
find_icon merged all candidate names into one set and ranked across
them, so a later alternate name could beat the first name present, and
size directories spelled 48x48 or scalable were not parsed. Try the
names in order instead: the first with a match wins, and within a name
prefer -symbolic, then scalable, then the largest size directory.
Update the docstring and selftest comment to match, extend the selftest
with size and name-order cases.
Add the missing GPL-2.0-only SPDX line.
|
|
The greeter runs as the sddm user and cannot read the login user's
dconf, so udt-accent resolves the four FreeDesktop power icon names in
the icon theme gsettings reports and bakes absolute paths into the
generated sddm-theme.conf. An unresolved key stays empty and the
theme falls back to its bundled SVGs.
|
|
|
|
|
|
|
|
|
|
The conky dashboard target is an absolute path now that it lives in
another repo, and `out_dir / absolute` discards out_dir, a documented
pathlib behaviour.
For the default in-repo render that is correct: the file genuinely
belongs at that path. For a render aimed anywhere else it is not.
selftest renders every scheme to a temp dir to have rofi parse the
result, so the escaping target rewrote the live file each time,
silently leaving the user's rendered conky.conf set to whichever scheme
was probed last rather than the one they run. Confirmed with a sentinel
line: before the fix it vanished after a selftest, after it survives.
So an absolute target is honoured only when out_dir is the repo, and
rebased under out_dir otherwise. Rebasing unconditionally was the wrong
fix and was caught in testing: it sent the real render into a
home/danix/... tree inside this repo and stopped updating the live file
at all.
Verified both directions: selftest leaves the live file alone and
creates no stray tree, a real render still updates it, and all nine
schemes still pass.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
The Lua dashboard lives in conky-theme-udt now, so udt-palette renders
that repo's conky.conf.in instead of a local template and install.sh
links the Lua alongside the config.
gen_conky also substitutes critical, for the dashboard's error overlay:
conky reports a Lua fault as a blank window, so the dashboard catches
it and draws the message instead.
The old variables-and-execi template is deleted. Its hardware discovery
was not lost; the hwmon glob-by-name approach is carried into
lib/data.lua deliberately, since fixed indices drift across kernel
reorders.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
Twelve hexes were shades upstream computed from a palette colour rather than
taking one. They were left literal on the same reasoning as the neutral greys,
which was wrong: a grey is shading, but each of these paints one widget
surface in a colour that is supposed to be the theme's. Under any scheme but
Macchiato they stayed Macchiato, including the window close, minimise and
maximise hover fills.
They are substituted as @ROLE_PCT@ now, the percentage being that shade's
brightness relative to its base. shade() scales each channel and clamps, so it
keeps the relationship rather than the exact upstream value; closest on the
accent family, crudest on the reds, where upstream darkened toward saturation.
GTK4 carries ten of the twelve: the selected progress bar and the
selection-mode titlebar backdrop are GTK3-only widgets upstream.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
A placeholder with no matching role renders literally into the CSS and GTK
drops the declaration without an error. The stylesheets are 8500 lines each,
so nothing would catch it by eye.
Verified the assertion fires: renaming @ACCENT@ to @NOSUCHROLE@ in one asset
template fails the selftest, naming the file and the placeholder.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
70 new targets: the two stylesheets, the metatheme descriptor and 67 widget
assets. The assets are discovered from disk rather than listed, because they
arrive as a set from upstream and a hand-written list would miss one added by
a future refresh.
Substitution does the _RGB@ form before the bare @ROLE@: @FG@ is a prefix of
@FG_RGB@, so the other order would eat the start of the triple placeholder
and leave a literal "_RGB@" in the CSS.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
GTK's stylesheets write colours two ways: as a hex, and as a bare decimal
triple inside rgba(). The existing rgba() helper emits without spaces and
wraps the call itself, so neither form matches what the upstream theme
contains; rgb_triple emits just `r, g, b` and the template keeps the call.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
They lived in ~/.cache/wal because pywal owned that directory and udt-accent
was written alongside a pywal run. Nothing on this desktop invokes pywal any
more: the wal binary is unused, and udt-accent imports pywal.backends.colorz
as a quantisation library, which writes nothing. Sharing the cache only left
the ownership ambiguous.
colors.json is the one file that cannot move. pywalfox hardcodes
<cache>/wal/colors.json and honours only XDG_CACHE_HOME, which would relocate
every cache on the system, so udt-accent writes the real file to ~/.cache/udt
and install.sh symlinks the old path at it. ~/.cache/wal now holds that link
and nothing else.
Consumers repointed here: install.sh, udt-accent, launcher.rasi's @WPAPER@.
Outside the repo, wallp, Hyprland's look_and_feel.lua and quickshell's
shared/Theme.qml move with it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
dunst no longer runs on this desktop. notifyd owns
org.freedesktop.Notifications and the quickshell notifications shell
draws the balloons, reading the palette from ~/.cache/wal/udt-palette.qml
like every other quickshell component. So the whole dunst path was
generating a config nothing read.
It was also actively wrong. pywal rendered ~/.cache/wal/dunstrc from the
installed template, then wal.sh restarted dunst on it while @ACCENT@ was
still an unsubstituted placeholder, and udt-accent restarted it a second
time after substituting. Two restarts per wallpaper change, the first on
a broken config, for a daemon that could not claim the bus name anyway.
Removes gen_dunst and its TARGETS entry, write_dunst and DUNSTRC, the
install block, templates/dunstrc.in and the gitignore entry. The reload
table now lists quickshell, which needs no signal: it watches the
generated palette and re-reads it in place.
The [state] roles stay. They were never dunst-only; waybar module states
and conky warnings use the same four.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
The bar these roles existed for is gone. The stock one alternated module
backgrounds so it read as stripes, and carried a role for each: workspaces,
temperature, memory, cpu, time, date, tray, volume, backlight, battery, plus
charging. waybar-theme-udt draws every pill on main_bg, and its stylesheets
reference seven names in total, none of them a module. So all eleven had no
consumer left in any of the nine schemes.
They are deleted rather than renamed. Renaming them after the new bar's
modules would have invented consumers that do not exist: nothing reads a
"mail" or "launcher" colour, because the pills are deliberately uniform.
Re-adding one means a stylesheet that actually references it.
install.sh was still writing the theme into ~/.config/waybar/, which hyprland
no longer launches, so switching scheme recoloured a bar nobody sees while the
running one kept its old palette. It writes to ~/.config/waybar-udt/ now,
under the fixed name that bar imports, so there is no import to repoint.
The stock directory is left exactly as it was, and deliberately gets no new
theme: its stylesheets still ask for the per-module names, so writing one
there would leave it referencing colours that no longer exist.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
Two outputs, not one. The colour scheme themes the editor pane and tracks
the wallpaper accent; the theme themes the UI chrome and sits on the
scheme's fixed accent, because Sublime reads a theme once per window and a
moving accent would leave open windows disagreeing with new ones.
The colour scheme costs no new roles. Its scopes map onto the sixteen ANSI
slots every scheme already declares, so all nine satisfy it and the
identical-role-set selftest passes untouched.
The theme is an override layered over Material Behave rather than a theme
of its own: that theme hardcodes 419 rules of [r,g,b] literals with no
variables, so the chrome surfaces are restated and its geometry, icons and
animations are inherited. It installs under the name of the theme it
overrides, because Sublime merges .sublime-theme files by filename with
Packages/User last; under its own name it would never apply. It also has
to follow Material Behave's material_theme_contrast_mode block and carry
no settings gate, or contrast mode wins.
The accent is replaced by matching the variable's current value rather
than a placeholder: install.sh copies the file out of the repo, so after
the first wallpaper change there is no placeholder left to substitute.
udt-accent --selftest now covers that it stays idempotent.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
styles/main.css and styles/global.css are edited in place, not generated,
and reference nineteen colours by Catppuccin name: @surface1, @text,
@crust, @lavender and the rest. gen_waybar emitted only the role layer
plus the scheme's own palette names, which happen to include those names
under the four Catppuccin schemes and none of the other five.
Under tokyo-night every one of those references was undefined, GTK fell
back to a default, and the separators in main.css went from a dim
alpha(@surface1, 0.4) hairline to full brightness. The workspace
underline, the bluetooth, mail and breaktimer state colours and the
tooltip border were falling back the same way.
Emit them from roles, reusing the ROFI_NAMES table that exists because
rofi had this exact bug; mauve is the one name waybar uses that rofi
does not, and maps to the highlight role.
Verified across all nine schemes: every referenced name now resolves.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0176XsV85ByN2ee7HseUKcqA
|
|
The installer found vaults by scanning ~/Documents/Obsidian for .obsidian
directories, which cannot tell a vault from a leftover. That parent folder
holds an abandoned .obsidian from a vault that no longer exists, so the scan
found six vaults where Obsidian knows five, and the extra one got a snippet
and an edited appearance.json for something Obsidian never opens.
It now reads ~/.config/obsidian/obsidian.json, which is the list Obsidian
itself maintains, and only writes to a path that is both registered and still
has a .obsidian directory.
The stray directory has been restored to its previous contents.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015gbjA2bmswN8jyPDKzrvqe
|
|
Both expose a first-class, update-safe theming hook, which is what separates
them from the Electron apps that cannot be consumers: Signal, Discord and
Spotify ship closed bundles whose only theming route is patching a signed
asar that every update reverts.
Obsidian gets a CSS snippet rather than a theme, so it layers over whatever
theme a vault already uses instead of replacing the user's choice. Enabling it
means appending to enabledCssSnippets in each vault's appearance.json, which
bin/udt-appthemes does by reading the list and adding to it: rewriting the file
would have switched off the layout snippet one vault was already using.
Typora's theme is derived from the Dracula theme installed here, whose 350
rules all resolve through :root variables, so only that block is templated and
none of the layout is touched.
Verified across six vaults, nested ones included: the vault with an existing
snippet kept it, a vault with no appearance.json got a valid one, and three
consecutive installs leave exactly one udt entry.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015gbjA2bmswN8jyPDKzrvqe
|
|
Qt and GTK were the one part of the desktop the palette never reached: Kvantum
was pinned to a hand-installed catppuccin-macchiato-lavender directory, so
pcmanfm-qt and every other Qt app stayed Macchiato no matter which scheme was
selected.
A Kvantum theme is a .kvconfig of colours and a .svg of widget artwork with
colours baked into the paths, which looked like it needed redrawing. It did
not: the SVG carries only 27 distinct colours, 12 of them palette colours and
the rest neutral greys that are shading, not theme colour. Both files are now
templates with the 12 as placeholders, derived from the theme this desktop was
already running.
Installs to ~/.config/Kvantum/udt/ under one fixed name for every scheme, so a
switch needs no change to kvantum.kvconfig and leaves no stale theme behind.
Adds accent_dim and accent_bright roles for Kvantum's hover and pressed states.
Verified: no placeholders survive generation, the SVG still parses as XML, and
pcmanfm-qt picks up the new colours on restart. Qt reads a theme at startup
only, so running apps need restarting; AGENTS.md says so.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015gbjA2bmswN8jyPDKzrvqe
|
|
Adds Catppuccin Frappe and Mocha, which share Macchiato's colour names so
their role maps are the same mapping against different values, and Material
Ocean, Palenight and Darker, which bring their own names and their own maps.
Nine schemes now, all dark.
Material ships one accent per hue and three greys where the roles want five
depths, so each Material palette carries four interpolated shades, marked as
not upstream, and its bright_* terminal slots name the same colours as the
normal ones.
The selftest now renders every scheme to a temp directory and has rofi parse
every theme, not just check that roles resolve. Resolving was never the
property that mattered: the Tokyo Night breakage resolved fine and still
emitted a palette the themes could not use. Verified the check fails when a
name is removed.
Catppuccin Latte is deliberately absent. It is light, and that is not a role
remap: homepage is pinned theme: dark and the generated card overrides target
its dark-mode class.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015gbjA2bmswN8jyPDKzrvqe
|
|
Switching to tokyo-night broke every rofi launcher. The themes reference
Catppuccin spellings (@base, @text, @surface0), and gen_rofi emitted whatever
names the scheme happened to use, so under Tokyo Night the palette defined bg
and fg instead and rofi refused to parse a theme referencing colours that did
not exist.
The names the themes ask for are now filled from roles, the same way every
other consumer already worked. The spellings stay Catppuccin's because that is
what the themes were written against; only the values change per scheme.
Adds a selftest that collects every @name used in a colour property across the
themes and asserts the generator emits it. Verified it fails when a name is
removed, rather than passing vacuously, and all seven themes now parse under
all four schemes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015gbjA2bmswN8jyPDKzrvqe
|
|
The dashboard's custom.css was written by hand against Macchiato, so it would
have drifted the moment the desktop changed scheme. It is now generated from
the same roles as everything else and staged on the host by install.sh.
Adds four intermediate grey roles to every scheme. homepage wants a full
ten-step ramp where the other consumers want three depths, and without them
several steps collapsed onto the same colour, flattening the mid-tones.
The scp is deliberately soft: five second timeout, BatchMode, a warning rather
than a failure when the host is unreachable, so a laptop away from that network
still installs the local theme. It stages to ~/hp-stage only, because
/opt/homepage/config is root-owned; install.sh prints the sudo copy to finish.
Verified: the generated Macchiato stylesheet reproduces the deployed one
colour-for-colour, switching to tokyo-night propagates through to the staged
file, and a failing scp leaves install.sh exiting 0.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015gbjA2bmswN8jyPDKzrvqe
|