DESIGN: derived interaction-state mix ratios are a placeholder — per-brand colour review pending #75

Closed
opened 2026-07-30 12:37:40 +00:00 by ville · 1 comment
Member

Splitting the second half of the PROVISIONAL note above _derived_state_lines
(udg/generators/extract.py, ~line 99) out of #72. #72 is about the naming of the
derived vars; this is about their values.

Decision

One global derivation rule does not carry across brands. The current
DERIVED_STATES ratios — mix 88% / 78% / 90% / 85% toward #000, plus a 22%
focus glow — are accepted as a placeholder default, not as a house rule.
Nothing is blocked on it, so we ship as-is and revisit deliberately.

Why one rule doesn't carry

Compared the current output against alternatives across rituals, spelwork, tctd,
fux-capacity and peterswimm:

  • Swapping the mix target from #000 to a brand-owned dark changes almost
    nothing.
    These brands' darkest own colours are already near-black
    (#2B1810, #1A1A1A, #0A0A0A), and tctd's bg.surface is #000000.
    Distance from the base primary moves from ~26 to ~20 units — invisible. So
    "mix toward a brand colour instead of black" is not by itself the fix.
  • What actually moves the result is either raising the ratio (25% toward the
    brand dark gives a properly distinguishable hover) or mixing toward the
    brand's secondary hue, which shifts hue rather than only darkening.
  • But secondary-mixing only works when a brand's two colours are neighbours on
    the wheel.
    rituals (terracotta → mustard) and peterswimm read well.
    fux-capacity (red → blue) lands on #C9495D, a rosy half-tone that looks
    related to neither brand colour; tctd (yellow → white) just washes out.
  • A shipping brand already contradicts the rule's direction. pardner
    hand-authors primary-hover: #9C90EE against a #8275E6 base — its hover is
    lighter. The global rule darkens. So "hover darkens" is not currently a house
    rule, whatever the emitter assumes.

No new machinery needed

The per-brand mechanism already exists and pardner already uses it: author the
states as real DTCG tokens in the product's color.json and the emitter fills
only the gaps (_derived_state_lines skips any derived name already emitted as a
base var). pardner ends up with three hand-picked values plus a derived
--error-hover and --focus-glow. That is the intended shape.

So this issue is design work, not refactoring.

Open, for a later pass

  1. Which brands get hand-authored interaction states, and what the values are
    (5 brands × 3–5 states).
  2. What the global fallback should be for brands that don't author their own. If
    88/78/90/85-toward-#000 stays, it should be documented as the default
    rather than as the correct answer.
  3. Whether "hover darkens" is a house rule. It is not today — pardner breaks it.
    If it should be, pardner's values are wrong; if not, say so explicitly so the
    next person doesn't "fix" them.

Related: #72 (naming of the same vars — separate question, answered there).

Splitting the second half of the PROVISIONAL note above `_derived_state_lines` (`udg/generators/extract.py`, ~line 99) out of #72. #72 is about the *naming* of the derived vars; this is about their *values*. ## Decision One global derivation rule does not carry across brands. The current `DERIVED_STATES` ratios — mix 88% / 78% / 90% / 85% toward `#000`, plus a 22% focus glow — are accepted as a **placeholder default**, not as a house rule. Nothing is blocked on it, so we ship as-is and revisit deliberately. ## Why one rule doesn't carry Compared the current output against alternatives across rituals, spelwork, tctd, fux-capacity and peterswimm: - **Swapping the mix target from `#000` to a brand-owned dark changes almost nothing.** These brands' darkest own colours are already near-black (`#2B1810`, `#1A1A1A`, `#0A0A0A`), and tctd's `bg.surface` *is* `#000000`. Distance from the base primary moves from ~26 to ~20 units — invisible. So "mix toward a brand colour instead of black" is not by itself the fix. - **What actually moves the result** is either raising the ratio (25% toward the brand dark gives a properly distinguishable hover) or mixing toward the brand's *secondary* hue, which shifts hue rather than only darkening. - **But secondary-mixing only works when a brand's two colours are neighbours on the wheel.** rituals (terracotta → mustard) and peterswimm read well. fux-capacity (red → blue) lands on `#C9495D`, a rosy half-tone that looks related to neither brand colour; tctd (yellow → white) just washes out. - **A shipping brand already contradicts the rule's direction.** pardner hand-authors `primary-hover: #9C90EE` against a `#8275E6` base — its hover is *lighter*. The global rule darkens. So "hover darkens" is not currently a house rule, whatever the emitter assumes. ## No new machinery needed The per-brand mechanism already exists and pardner already uses it: author the states as real DTCG tokens in the product's `color.json` and the emitter fills only the gaps (`_derived_state_lines` skips any derived name already emitted as a base var). pardner ends up with three hand-picked values plus a derived `--error-hover` and `--focus-glow`. That is the intended shape. So this issue is design work, not refactoring. ## Open, for a later pass 1. Which brands get hand-authored interaction states, and what the values are (5 brands × 3–5 states). 2. What the global fallback should be for brands that don't author their own. If 88/78/90/85-toward-`#000` stays, it should be documented as *the default* rather than as the correct answer. 3. Whether "hover darkens" is a house rule. It is not today — pardner breaks it. If it should be, pardner's values are wrong; if not, say so explicitly so the next person doesn't "fix" them. Related: #72 (naming of the same vars — separate question, answered there).
Member

Wish completed — all requirements satisfied.

Wish completed — all requirements satisfied.
Sign in to join this conversation.
No description provided.