a ratchet on hardcoded colour, and the docs to match
The three previous attempts at this job died of endlessness, not difficulty. Nothing stopped the next component arriving with its own `text-emerald-400` while an old one was being fixed, so the number never fell for long. `bun run check:theme` counts palette classes per directory against a committed baseline. It does not care what the number is, only which way it moves. 942 across 21 directories today. Every directory can be paid down independently and none can quietly regrow — which turns an infinite job into a finite one. A baseline rather than a ban, deliberately: a rule forbidding palette classes outright fails on its first run, and a check nobody can make pass is a check everybody turns off. Proven by adding one `text-emerald-400` and watching it fail with the directory, the delta, and what to use instead. ── Documentation, which is part of the work rather than after it ── `src/workspaces/theme/README.md` is new and is the contract: how to write a theme, all 84 declarations by family, why colours are unwrapped HSL triplets while surfaces are complete CSS values, why assets are quoted paths, and the rules for components. Start from Plain, not from Duck — every value you change is then one you decided about. `plugins/EXTRACTING-A-PLUGIN.md` gains a rule beside the others: a plugin never hardcodes a colour, and pays its debt down DURING the extraction. The counts are named there — Soulseek 313, Invoices 95, Wallet 68 — because "some colours" does not convey that it is two thirds of the platform's total. The kickoff prompt says the same thing in the form a fresh agent will meet it. That is what makes the plugin exemption safe rather than a way of losing the work: the ratchet stops covering a directory the moment it leaves, so the rule has to travel with it. `THEMES-NOTES.md` rewritten to match reality — it still listed done things as open. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -82,3 +82,17 @@ still open.
|
||||
Then update `plugins/EXTRACTING-A-PLUGIN.md`: add what this extraction taught, and correct anything it
|
||||
told you that turned out to be wrong. The runbook is the thing that makes the next one cheaper, and it is
|
||||
only worth that if each extraction leaves it more accurate than it found it.
|
||||
|
||||
|
||||
## Colour is part of the job
|
||||
|
||||
The feature you are extracting almost certainly hardcodes Tailwind palette classes — `text-emerald-400`,
|
||||
`bg-zinc-800`, `border-red-500/30`. Replace them with semantic tokens as you go: `text-success`,
|
||||
`bg-muted`, `border-destructive`, `bg-busy/15`. They follow the theme; a palette number does not.
|
||||
|
||||
Read `src/workspaces/theme/README.md` for the contract and `src/workspaces/components/Data/tone.ts` for the
|
||||
closed set of state tones. `bun run check:theme` counts what is left.
|
||||
|
||||
Do it during the extraction rather than after. You are already rewriting every import in these files, and
|
||||
once the directory leaves the platform the ratchet stops covering it.
|
||||
|
||||
|
||||
@@ -37,6 +37,22 @@ file is **refused at discovery, by name**. Non-compliance is unrepresentable, no
|
||||
of any sort. The platform's answer is uniform; what a grant _means_ — whose rows a member sees, whether a
|
||||
resource is shared or per-user — is the plugin's own job, in its own queries.
|
||||
|
||||
**A plugin never hardcodes a colour.** Every colour comes from a semantic token — `bg-destructive`,
|
||||
`text-muted-foreground`, `bg-busy/15`, `border-border` — and never from Tailwind's palette
|
||||
(`text-emerald-400`, `bg-zinc-800`, `border-red-500/30`). Palette classes do not follow the theme, so a
|
||||
plugin using them looks wrong under every theme but the one its author happened to have. The contract is
|
||||
`src/workspaces/theme/README.md`; the closed set of state tones is `components/Data/tone.ts`.
|
||||
|
||||
Pay this down **as part of the extraction**, not afterwards. You are already rewriting the imports, and the
|
||||
counts are not small: Soulseek carries 313 palette classes, Invoices 95, Wallet 68, Jellyfin 48, Photos 47,
|
||||
Transmission 41. Left alone, an extraction exports its colour debt into a repository nobody will revisit —
|
||||
and the platform's own ratchet (`bun run check:theme`) stops covering it the moment the directory leaves.
|
||||
|
||||
Two shortcuts that are not shortcuts. `text-white` and `bg-black/60` are fine ONLY over media — a video, a
|
||||
photograph — where they sit on someone's content rather than on a themed surface; everywhere else they are
|
||||
palette classes like any other. And a colour that carries no state (a brand accent, a chart series) belongs
|
||||
in the plugin's own variables, declared once, not sprinkled as literals.
|
||||
|
||||
**Say `permissions`, never the other word.** It already means three things in this codebase.
|
||||
|
||||
**The manifest holds only what a directory listing cannot say.** Identity facts and human choices:
|
||||
|
||||
Reference in New Issue
Block a user