Icon Studio
Designs application icons from the house palettes: pick a Material Symbols glyph or some text, a foreground colour and a background treatment, and see every combination your choices allow side by side.

Provenance
The original icon studio was lost in the data-loss incident, and unlike the Android clients there was no artefact to decompile — an egui binary was not sitting on a phone somewhere. So this is a rebuild from two things that did survive:
- its inputs — the palettes, which are still live (see below);
- its outputs — the icons it produced, which ship inside the five
cbz*Android apps.
That second point is what keeps this honest. tests/reproduce.rs renders a
background with the reconstructed code and compares it against
ic_icon_background.png taken from the installed cbzauth APK. The originals
turn out to be an even two-tone diagonal split of the Casabeza brand colours
with a hairline boundary — roughly one blended pixel per row — and the tests
assert exactly that, so a change that turns the split into a soft gradient
fails rather than quietly drifting.
What is attested, and what is not
| Feature | Evidence |
|---|---|
| Diagonal split background | Attested — all five shipped cbz icons use it |
| Material Symbols foreground | Attested — shipped icons are Symbols Rounded, outlined |
| Text foreground | Attested — cbznumerics ships “1234” |
| Casabeza + neiam palettes | Attested — recovered from the APK and live in dms |
| Solid, gradients, stripes, checks, dots, rays, wedge | Invented — described as “gradients, patterns and other things”, but no shipped icon uses them |
| Sub-banner | Invented — described, but no shipped icon has one, so the layout is a guess |
The invented parts are reasonable, not recovered. Treat them as a starting point rather than as the tool you remember.
Palettes
Nothing is retyped by hand. tools/regen_palettes.py writes
src/palette/generated.rs from:
- neiam — the daisyUI themes in
dms/assets/f/css/style.css(her,afterdark,forest,sky,clays,stones,dark,light), converted from OKLCH to sRGB with the same transform the Android clients use; - Casabeza — the exact values recovered from the cbzauth APK after the loss, carried in the script.
tools/regen_palettes.py # refresh after dms changes
tools/regen_palettes.py --check # non-zero if stale, for CI
The Android themes and the dms themes agree exactly on primary and accent;
Android’s backgrounds are deliberately darker (L 0.18 against 0.35). Both are
offered.
Fonts
Vendored in assets/:
- Material Symbols Rounded, outlined and filled, from
egui_material_icons(MIT), with the.codepointstable parsed at startup so the icon list and the rasteriser cannot disagree about what a name means; - B612 regular and bold, the face the cbz apps ship in
res/font, used for text marks and sub-banners. Rendering text through the Symbols font lands on.notdef, which is why text needs its own face.
Running
cargo run # the studio
cargo test # including the comparison against shipped icons
cargo run --example reproduce_cbz # re-render the five cbz icons
cargo run --example showcase # every background generator
Export writes ic_icon, ic_icon_background and ic_icon_foreground across
mipmap-mdpi through mipmap-xxxhdpi (108–432px), matching the layout the
cbz apps use.
Design notes
Rendering is tiny-skia and ab_glyph, deliberately independent of egui: the
preview, the grid and the exported PNG all go through render::render_composed,
so what you see is what lands on disk, and the renderer can be tested
headlessly. Grid cells are cached by content hash — the cartesian product gets
large quickly, and it is capped at 240 cells for that reason.