* Decode webp in the shell
The background and the lock screen are drawn by Quickshell, so they
decode through Qt, which ships handlers for png, jpeg and gif but not
webp. QImageReader answers "Unsupported image format" and the layer
comes up blank. Any third-party theme shipping a .webp background hits
this today, even though every path that goes looking for a background
already globs the extension.
qt6-imageformats supplies the missing plugin for 71 KB downloaded. Its
one new dependency of substance, libwebp, is already on every machine
by way of libvips.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* Store theme backgrounds as webp
WebP codes both of the things these backgrounds are made of better than
the formats they were in: the photographs, where its lossy mode is worth
a third or more over JPEG at matched quality, and the flat art and dot
patterns, where its lossless mode undercuts an oxipng-packed PNG.
28 of them become lossless webp and decode bit-for-bit identically
(AE=0), so the dot patterns and flat-shaded pieces carry no quality
question at all. That includes 0-launch, whose alpha channel comes
through intact. The other 51 are photographs held to the same 38 dB
PSNR floor as the JPEG pass, landing between 38.0 and 54.6 dB. Every
image keeps its exact pixel dimensions, for 29.8 MB.
Each one is encoded from the original as it stands in quattro rather
than from the file the earlier commits produced, so nothing picks up a
second generation of loss on the way here.
13 stay JPEG. WebP is plainly larger for most of them, and three are
grainy enough that its filter smooths the grain instead of coding it:
PSNR plateaus near 34 dB however high the quality goes, well under the
floor.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
* Re-encode over-encoded theme backgrounds
Several backgrounds shipped at quality 95-100, which buys nothing visible
on a wallpaper but costs 20 MB. Re-encode those at quality 85, leaving
resolution untouched -- every file keeps its original pixel dimensions.
Only files stored above quality 90 are touched, and only when the result
saves at least 15% and stays above 38 dB PSNR against the original. The
34 backgrounds already stored at quality 85 or below are left alone
rather than pushed through another lossy generation for a few hundred KB.
osaka-jade/2-shaded-entrance is skipped for that reason: nothing clears
both bars. ristretto/2-coffee-beans is re-encoded at 90 instead of 85,
where 85 fell below the PSNR floor.
Theme backgrounds drop from 107 MB to 87 MB.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* Store nord's night-hawks background as a palette PNG
The file uses only 8 distinct colors but was saved as truecolor RGB,
costing 1.8 MB for an image an indexed palette stores in half the space.
Converting to a palette PNG is lossless: same dimensions, and zero pixels
differ from the original.
1782 KB -> 909 KB.
The other palette-eligible PNGs are already indexed, and re-compressing
them with ImageMagick only makes them bigger, so they are left alone.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* Recompress theme PNGs losslessly with oxipng
Every background PNG was left at its authoring tool's default deflate
settings. Running oxipng over them re-packs the same pixels: all 31 files
decode bit-for-bit identically (AE=0) at unchanged resolution, for 981 KB.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* Store photographic backgrounds as JPEG instead of PNG
Four backgrounds were shipped as PNG despite being photographs and
painterly illustrations, where lossless coding buys nothing the eye can
see. Re-encoding them at the same q85 used by the other backgrounds keeps
every pixel dimension and stays above 40 dB PSNR, for 3.3 MB.
The remaining PNGs stay PNG: JPEG is larger for the dot patterns and the
flat-shaded pieces, and 0-launch.png genuinely uses its alpha channel.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
---------
Co-authored-by: David Heinemeier Hansson <david@hey.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Both slots held #026fde, so strings and numbers rendered in one color
and syntax highlighting lost the distinction entirely. It mattered less
when the theme shipped its own nvim and vscode files; now that both
generate from this palette, the collision is visible everywhere.
The green slot takes a violet. Lupine's hues sit at 210, 214, 224, 267
and 301, leaving one real gap between blue and magenta, and that gap is
the only place a new color fits without either crowding an existing hue
or breaking the blues-and-purples character. Its bright variant becomes
a lavender, which suits a theme named for the flower. Nothing here reads
as green; the slot keeps its ANSI name, not its usual hue.
Yellow, orange and cyan remain close to each other. Pulling those apart
means either warm hues or a wider spread than the theme allows, which is
a bigger change than this one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018CC9kSQv8ZEogaxDoeKBzL
The JPEG drew the wordmark in #358fff on pure white, matching neither
the accent nor the background. Every other theme's omarchy wallpaper is
a flat two-color image: the theme's background behind its accent. Lupine
now follows that, so the wallpaper, the lock screen, and the focused
window border are all one blue.
Recolored from the shared wordmark rather than redrawn, so the glyphs
land on the same pixels as every other theme. JPEG was the wrong
container for two flat colors anyway; at one bit per pixel the PNG is
2KB against 71KB, with no ringing around the letters.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018CC9kSQv8ZEogaxDoeKBzL
Drops city, lavender-bloom, dusk-horizon, purple-mountains, lake-dawn,
and snowy-dawn, then renumbers the survivors so the sequence stays
contiguous. The remaining set is uniformly pale, which is what a light
theme needs; the cut ones were mid-tone or saturated enough that the
bar and window borders lost contrast against them.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018CC9kSQv8ZEogaxDoeKBzL
Rename the palette keys to the canonical background/foreground names the
resolver actually reads. The short bg/fg spellings were never aliased, so
every derived key was silently falling back.
Fill in the orange and brown slots too. Lupine is a deliberately cool,
near-monochrome blue palette, so both stay in family rather than
introducing warm hues the theme never had.
Drop neovim.lua and vscode.json. They pinned third-party extensions that
had to be installed separately; the generated templates cover both from
colors.toml alone.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018CC9kSQv8ZEogaxDoeKBzL
Convert the Lupine theme to the semantic color system introduced in the
quattro/Omarchy 4 line:
- Rewrite colors.toml from the old accent/foreground/background/color0-15
scheme to the semantic palette (mode, bg/fg ramp, named ANSI hues, and
bright_* variants). The chromatic palette is preserved exactly; only the
keys are renamed.
- Replace the empty light.mode marker with mode = "light".
- Drop the hand-shipped btop.theme and chromium.theme; both are now
generated from default/themed/*.tpl at theme-set time.
Selection now follows the convention used by the other light themes
(selection_foreground = bright_fg over a light selection background)
instead of the previous inverted dark selection bar.