~ knotless Search/
↑↓ move↵ open⇧↵ all results

chadtmiller.com/knotless

git that lives in your Atmosphere account

knotless.dev
1 collaborator

knotless 0.13.0 Latest 2 packages, 1 image

1
10

The pages colour by purpose, not hue: danger, success, attention, done and neutral

Merged
Merged chadtmiller.com asked to merge into main from chadtmiller.com/knotless:web/semantic-colours

What changes

tokens.css gains five role tokens, named as GitHub's Primer names them, each pointing at a hue the themes set:

rolehuefor
--success--greenopen, passed, added
--danger--redfailed, removed, dangerous
--attention--yellowwaiting, notices
--done--purplemerged
--neutral--grayclosed, skipped, drafts

The state aliases (--open, --merged, --closed-pull, --closed-issue, --running, --add, --rem) now point at the roles, not the hues, so the chain runs hue → role → state. In app.css, the 22 uses of --red for errors and danger now take --danger, the agent chat's tool mark takes --success, and drafts take --neutral. AGENTS.md says to take a role, never a hue.

Why

Design tokens are usually named in two layers: primitives name the value, semantic tokens name the purpose. Pages and themes should only touch the semantic layer, so a value can change without its name becoming wrong. The pages already had that for states but used --red directly everywhere else. This comes first for the themes pull, whose dev.knotless.theme palette names its colours by purpose (success, danger…); the pages should mean the same thing by them.

Three uses keep their hues on purpose:

  • the pressed star, yellow as an object rather than for a purpose
  • the green and red dots on Appearance's theme cards, which show the theme's hues

Theme blocks inside tokens.css (--unread: var(--red) and similar) also keep hues. A role token is declared on :root, so a theme set on an element inside the page would inherit it already worked out from <html>'s colours.

How it was checked

Every role is exactly the hue it replaces, so nothing should draw differently. node harness/contrast.mjs passes on all 8 themes. The shots check will confirm no page moved; none is named to move.

Shortcomings

harness/contrast.mjs's pairs still name hues (green on bg, on-solid on red). It checks the primitives the roles resolve to, so it still covers what's drawn.

🤖 Generated with Claude Code

Approved

This adds five role tokens (--success, --danger, --attention, --done, --neutral) to tokens.css, each aliasing a hue. It points the state aliases at the roles and swaps --red for --danger in app.css. The drafts and the agent chat mark also move to roles, and AGENTS.md gets the rule.

I found nothing that breaks. The roles sit in the :root, [data-theme='light'] block, so on <html> they resolve against whichever theme's hues are set there, and every theme sets its hues on <html>. Each swapped use resolves to the same value as before. A repo-wide search shows the --red uses left in app.css are the theme dot, and the ones left in tokens.css are the theme blocks. Both match what the description says it kept on purpose.

One small thing, not blocking: the AGENTS.md edit leaves one very long line where the paragraph was re-wrapped. Re-wrap it to match the lines around it.

Merged as 020d16b