feat(tools): theme design audit + item 28 punch list (slice a)
All checks were successful
Check / eval (push) Successful in 3m0s

tools/audit-theme-design.py (report-only, maintainer-run): for every
themes/*.json it checks OKLCH lightness architecture (raised bg stack,
fg hierarchy), WCAG contrast beyond the guarded pairs, status-color
hue families, accent harmony, protanopia/deuteranopia
distinguishability (Machado matrices), and ANSI slot semantics the
greeter/tty now rely on. Ran it over all 21 palettes + a visual pass
over representative previews; findings curated identity-aware (lumon/
vantablack/white/hackerman exemptions are identity, not defects) into
the P1-P3 punch list now recorded in BACKLOG item 28: two palettes
with literally invisible subtext (summer-day, flexoki-light — the
item-25/27 trap at its source), two inverted bg stacks (miasma,
kanagawa), muted/warn floors, a systemic "status is never color-only"
rule, the light-theme ANSI convention decision, and bar grouping
rhythm notes.

Verified: V0 (py_compile; the tool is report-only, deliberately not a
checks.* gate until slice b adopts rules + exemptions).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Bernardo Magri
2026-07-05 18:45:56 +01:00
parent d1d6a09d9d
commit abc953ea84
3 changed files with 223 additions and 4 deletions

View File

@@ -49,14 +49,61 @@ Bernardo has offered image-expert models for designed graphics
(wallpapers, logos, glyphs, preview/branding art): an agent slice that
needs artwork must STOP and ask ("say the word") instead of shipping
programmer-art.
Slices: (a) the audit — render every theme (VM themed-screenshot
recipe or real captures), review against the rules above, append a
per-surface punch list to this item; (b) palette-level fixes + the
extended contrast/harmony checker; (c) per-surface polish slices;
Slices: (a) the audit (2026-07-05, iteration #31 — findings below);
(b) palette-level fixes + the extended contrast/harmony checker;
(c) per-surface polish slices;
(d) the whole-swap themes brought to the same bar. Visual work is
V3-bound by nature — screenshots are the review artifact, hardware
confirms.
**Audit findings (slice a — `tools/audit-theme-design.py` over all 21
palettes + visual pass over previews; identity-aware curation):**
- **P1 · invisible-secondary-text palettes:** summer-day and
flexoki-light have `subtext == base` (contrast 1.0 — literally
invisible) and `text == surface`. Items 25/27 fixed the *consumers*
(swaync/bar stopped using them); the palettes are still traps — any
new surface consuming subtext/surface re-trips. Fix the palettes:
real mid-tone subtext, raised surface.
- **P1 · inverted bg stacks:** miasma's surface is #000000 under a
much lighter base; kanagawa's surface (L .14) sits below base
(L .24). "Raised" surfaces render sunken/black. Retune.
- **P2 · muted floor:** muted-on-base < 2.0 on gruvbox (1.27),
everforest (1.55), lumon (1.68), nord (1.69), white (1.82), latte
(1.91), retro-82 (1.93) — dimmed workspaces/inactive items barely
render (visible on the lumon preview). Adopt ≥ 2.0 and retune.
- **P2 · warn barely reads:** warn-on-base ≈ 2.02.3 on rose-pine,
summer-day, latte, flexoki-light — this is the bar's 25%-battery
color. Floor 2.5 (or see the color-only rule below).
- **P2 · text-on-surface < 4.5:** ristretto 3.88, latte 4.39 (menus
and chips draw text on surface).
- **P3 · accentAlt-on-base < 3:** latte 2.34, summer-day 2.83.
- **Design rule (systemic, beats palette surgery): status is never
color-only.** good/warn collapse under protanopia on ~half the
themes and good/bad under deuteranopia (59 pair-findings) — that's
inherent to red/green/yellow, not fixable per-palette. Battery and
recording already carry glyph changes; sweep the remaining
color-only indicators (updates count, notification dot, VPN shield
states) for shape/glyph redundancy.
- **Identity exemptions, made explicit:** vantablack + white
(deliberately hueless statuses), lumon (all-blue), hackerman
(matrix green statuses), matte-black/retro-82 (off-family hues) are
identity, not defects — slice (b)'s checker gets a per-theme
exemption list instead of silently lowered floors.
- **ANSI / greeter notes:** latte, rose-pine and white ship
`ansi[0]` LIGHTER than `ansi[15]` — decide the light-theme ANSI
convention (terminals conventionally keep black dark) before the
greeter/tty theming ships to them. tokyo-night/summer-night
`ansi[7]-on-ansi[0]` ≈ 2.83.0 = the greeter's muted text; fine as
muted, watch on hardware.
- **Visual pass (480×270 previews — too small for type/spacing; the
deep per-surface pass needs 1080p captures):** the generated bar's
right cluster runs ~9 modules with uniform spacing — no grouping
rhythm (consider micro-gaps between tray/net · stats · toggles ·
battery/notify groups); latte's preview shows a DARK terminal on
the light desktop — verify ghostty consumes the latte palette (or
the preview is stale); summer-day's island-pill whole-swap bar and
lumon's globe identity are strong — preserve through any polish.
### 14. Automated lock bumps — confirm the first real run
Slices b+c shipped 2026-07-05 (`.gitea/workflows/bump.yml`): weekly
schedule (Mon 05:17 UTC) + `workflow_dispatch` as the security

View File

@@ -17,6 +17,30 @@ Template:
---
## 2026-07-05 — theme design audit (iteration #31, item 28 slice a)
- **Task:** BACKLOG NEXT#28 slice (a) — the design-theory audit
(human-requested; Bernardo asked to run it now).
- **Did:** tools/audit-theme-design.py (new, report-only): OKLCH
lightness architecture, extended WCAG pairs, status-hue families,
accent harmony, Machado protan/deutan simulation, ANSI slot
semantics — over all 21 palettes; plus a visual pass over 4
representative preview.png captures. Findings curated
identity-aware into a P1P3 punch list appended to item 28: 2
invisible-subtext palettes (summer-day, flexoki-light), 2 inverted
bg stacks (miasma, kanagawa), 7 muted-floor misses, warn-barely-
reads ×4, a systemic "status is never color-only" rule (CVD
collapse is inherent, glyph redundancy is the fix), explicit
identity exemptions, light-theme ANSI convention decision, bar
right-cluster grouping rhythm, latte dark-terminal verify.
- **Verified:** V0 (py_compile; report tool, not wired into checks).
Analysis is palette-math + thumbnail previews; per-surface
spacing/type audit needs 1080p captures (slice c prep).
- **Pending:** slice (b) — palette retunes + checker extension w/
exemption list; needs Bernardo's eye on the P1 retunes (visual
taste calls). Artwork needs none so far — no image-model ask yet.
- **Next suggestion:** slice (b) P1s (summer-day/flexoki subtext+
surface, miasma/kanagawa stacks) — small hex edits, big payoff.
## 2026-07-05 — greeter theming from the JSON (iteration #30, item 16)
- **Task:** BACKLOG NEXT#16 — tuigreet themed from theme-state.json at
system rebuild (the Plymouth model). Item deleted.