Skip to main content

max / makeover-layout

Write the three-tone convention into the header content is active, content-secondary is inactive but usable, content-muted is inert. Settled 2026-08-16 out of e2408b2f, and it belongs here because the description is what names the intents. content-muted is the one with a claim in it: State::Disabled resolves to it, so a live control wearing it tells the user it will not answer, and the user's response to that is to stop trying. The sortable-but-unsorted heading and the unchosen radio option are the two sites that read as dead lists that way.
Wiki
three-tone-convention
Author: Max Johnson <me@maxj.phd> · 2026-08-16 19:00 UTC
Signed with PGP, not checked
Commit: 2794cd90f95fb6e9473afcef0bfa21759df4a451
Parent: 71cf089
2 files changed, +26 insertions, -1 deletion
M Cargo.toml +1 -1
@@ -1,6 +1,6 @@
1 1 [package]
2 2 name = "makeover-layout"
3 - version = "0.27.0"
3 + version = "0.27.1"
4 4 edition = "2024"
5 5 # One copy of this vocabulary per dependency graph, enforced by cargo rather
6 6 # than by remembering. Two versions of a description layer in one build means
M src/lib.rs +25
@@ -312,6 +312,31 @@
312 312 //! stroke", "focus cue", "wants focus". "Caret" is a different thing — the text
313 313 //! cursor inside a field — and keeps its name.
314 314 //!
315 + //! # The three tones, and what a colour claims
316 + //!
317 + //! One rule, settled 2026-08-16, for how colour says whether a thing can be
318 + //! used. Every renderer answers to it, and it is stated here because the
319 + //! description is what names the intents.
320 + //!
321 + //! | the thing | intent |
322 + //! |-----------|--------|
323 + //! | active, emphasised, the thing itself | `content` |
324 + //! | inactive but usable: it still answers a press | `content-secondary` |
325 + //! | inert: disabled, or not a control at all | `content-muted` |
326 + //!
327 + //! `content-muted` is the one with a claim in it. [`State::Disabled`] resolves
328 + //! to it, so a live control wearing it is telling the user it will not answer —
329 + //! and being wrong about that is worse than being quiet, because the user's
330 + //! response is to stop trying. A sortable column heading that was never sorted,
331 + //! and every unchosen option in a radio group, both read as dead lists that way;
332 + //! those are the two this rule was written out of. What is legitimately muted is
333 + //! a caption, a hint, a placeholder, a meter's reading, an axis label: text that
334 + //! was never going to answer anything.
335 + //!
336 + //! The three are one ramp and not three colours. `makeover`'s `Emphasis` derives
337 + //! the quieter two from the ink, so "one step back" means the same distance in
338 + //! every theme and a renderer cannot land between them by picking its own.
339 + //!
315 340 //! # Where the description stops
316 341 //!
317 342 //! The rule is that a member is added when an app needs a fact the vocabulary