feat(tokens): marketing palette - warm neutral ramp, product accents, space 9-11 #100

Merged
peterswimm merged 1 commit from feat/toilville-web-palette-tokens into fix/terracotta-canonical-c05734 2026-09-09 20:31:48 +00:00
Owner

Stacked on #99. Base is
fix/terracotta-canonical-c05734.

Promotes the colour families the approved toilville.com design actually needs,
so the site can be built from tokens instead of the 508 raw hex literals
the Claude Design export carried (82% of them off-palette).

New tokens

Token Light Dark On white
neutral.warm-ink #2E2A27 #E8E2DE 14.22:1
neutral.warm-body #4A443F #C9C1BC 9.59:1
neutral.warm-muted #6E6864 #A9A09B 5.49:1
accent.spelwork #3A5987 #8FA6C9 7.10:1
accent.rituals #A6432B #D98874 6.07:1

Plus spelwork-container / rituals-container tints, and space 9/10/11
(80/96/120px) — the design builds page rhythm above the old 64px ceiling.

Not promoted: the design's muted greys #9C9591 (2.95:1) and #A8A8A8
(2.38:1) fail AA. neutral.warm-muted is the passing replacement for that role.

Why baseline, not a product override

My original plan said "product override with color_inherits_baseline: false".
That was wrong on two counts, and I changed course:

  1. color_inherits_baseline: true is a merge (baseline ⊕ product), not
    "no overrides" — so flipping toilville to false would have forced it to
    re-declare the entire palette.
  2. toilville is the only product that inherits baseline. Every other product
    is already self-contained. So a baseline addition has exactly the same
    blast radius as a toilville override would — while keeping toilville's
    documented role as the pure grammar (dist/toilville == baseline).

Net: no divergence, so no RATIONALE.yml entry is owed. Other products see
only the three additive space tokens (non-colour tiers always inherit).

Gating

Added to wcag.py _PAIRS as text-on-surface, and verified they genuinely
fire — I temporarily set neutral.warm-muted to #CCCCCC and the gate caught
it at 1.6:1.

Deliberately not gated as white-on-fill: the dark values are light by design
(readable on #121212), so white-on-fill would fail there. A fill must use the
light value or carry its own ink token, the way #96 paired
accent.consent-text with text.on-consent. Noted in a comment at the pairs.

extract.py SHORT_ALIAS extended — toilville is css_var_style: short, so
new baseline tokens need an alias to get a friendly var name.

Verification

  • just check — fully green
  • pytest generator/tests/ tools/wp_theme_ingestor/test_*.py — 262 passed
  • dist/toilville/skin.css carries all 7 new colour vars in light + dark
  • Other products' diffs are the 3 space tokens only

Open question for ville

accent.spelwork / accent.rituals are named for the products they represent
on the marketing site. If you'd rather they read as pure palette
(accent.blue / accent.sienna), say so — trivial rename now, annoying later.

https://claude.ai/code/session_01Kbzfscp4w5enUrZxMnDt78

**Stacked on #99.** Base is `fix/terracotta-canonical-c05734`. Promotes the colour families the approved toilville.com design actually needs, so the site can be built from tokens instead of the **508 raw hex literals** the Claude Design export carried (82% of them off-palette). ## New tokens | Token | Light | Dark | On white | |---|---|---|---| | `neutral.warm-ink` | `#2E2A27` | `#E8E2DE` | 14.22:1 | | `neutral.warm-body` | `#4A443F` | `#C9C1BC` | 9.59:1 | | `neutral.warm-muted` | `#6E6864` | `#A9A09B` | 5.49:1 | | `accent.spelwork` | `#3A5987` | `#8FA6C9` | 7.10:1 | | `accent.rituals` | `#A6432B` | `#D98874` | 6.07:1 | Plus `spelwork-container` / `rituals-container` tints, and space `9/10/11` (80/96/120px) — the design builds page rhythm above the old 64px ceiling. **Not promoted:** the design's muted greys `#9C9591` (2.95:1) and `#A8A8A8` (2.38:1) fail AA. `neutral.warm-muted` is the passing replacement for that role. ## Why baseline, not a product override My original plan said "product override with `color_inherits_baseline: false`". That was wrong on two counts, and I changed course: 1. `color_inherits_baseline: true` is a **merge** (baseline ⊕ product), not "no overrides" — so flipping toilville to `false` would have forced it to re-declare the entire palette. 2. **toilville is the only product that inherits baseline.** Every other product is already self-contained. So a baseline addition has *exactly* the same blast radius as a toilville override would — while keeping toilville's documented role as the pure grammar (`dist/toilville` == baseline). Net: no divergence, so **no `RATIONALE.yml` entry is owed**. Other products see only the three additive space tokens (non-colour tiers always inherit). ## Gating Added to `wcag.py _PAIRS` as **text-on-surface**, and verified they genuinely fire — I temporarily set `neutral.warm-muted` to `#CCCCCC` and the gate caught it at 1.6:1. Deliberately **not** gated as white-on-fill: the dark values are light by design (readable on `#121212`), so white-on-fill would fail there. A fill must use the light value or carry its own ink token, the way #96 paired `accent.consent-text` with `text.on-consent`. Noted in a comment at the pairs. `extract.py` `SHORT_ALIAS` extended — toilville is `css_var_style: short`, so new baseline tokens need an alias to get a friendly var name. ## Verification - `just check` — fully green - `pytest generator/tests/ tools/wp_theme_ingestor/test_*.py` — 262 passed - `dist/toilville/skin.css` carries all 7 new colour vars in light + dark - Other products' diffs are the 3 space tokens only ## Open question for ville `accent.spelwork` / `accent.rituals` are named for the products they represent on the marketing site. If you'd rather they read as pure palette (`accent.blue` / `accent.sienna`), say so — trivial rename now, annoying later. https://claude.ai/code/session_01Kbzfscp4w5enUrZxMnDt78
feat(tokens): marketing palette — warm neutral ramp, product accents, space 9-11
Some checks failed
PR policy check / policy-gate (pull_request) Failing after 0s
Security Scans / Gitleaks secret scan (pull_request) Successful in 31s
Security Scans / Trivy filesystem scan (pull_request) Successful in 35s
UDG dist drift gate / dist/ matches dtcg + udg sources (pull_request) Successful in 14s
Test Generator / test (pull_request) Successful in 3m18s
Test Generator / lint-workflows (pull_request) Successful in 18s
Test Generator / lint-prose (pull_request) Successful in 20s
7b5c1ebb5d
Promotes the colour families the approved toilville.com design actually needs,
so the site can be built from tokens instead of the 508 raw hex literals the
Claude Design export carried.

New (Brand/UDG/dtcg/color.json):
  neutral.warm-ink     #2E2A27 / #E8E2DE   14.22:1 on white
  neutral.warm-body    #4A443F / #C9C1BC    9.59:1
  neutral.warm-muted   #6E6864 / #A9A09B    5.49:1
  accent.spelwork      #3A5987 / #8FA6C9    7.10:1   developer-portal identity
  accent.rituals       #A6432B / #D98874    6.07:1   product identity
  + spelwork-container / rituals-container tints

The design's muted greys #9C9591 (2.95:1) and #A8A8A8 (2.38:1) are NOT
promoted — they fail AA. neutral.warm-muted is the passing replacement.

Space scale gains 9/10/11 (80/96/120px); the design uses page rhythm above the
old 64px ceiling.

Why baseline and not a product override: toilville is the ONLY product with
color_inherits_baseline: true, so a baseline addition has exactly the same
blast radius as a toilville override would — while keeping toilville's
documented role as the pure grammar (its dist == baseline). No divergence, so
no RATIONALE entry is owed. Every other product is self-contained and sees only
the three additive space tokens.

Gated in wcag.py as text-on-surface. Deliberately NOT gated as white-on-fill:
the dark values are light by design (readable on #121212), so a fill needs the
light value or its own ink token, the way #96 paired accent.consent-text with
text.on-consent.

extract.py SHORT_ALIAS extended — toilville is css_var_style: short, so new
baseline tokens need an alias to get a friendly var name.

Claude-Session: https://claude.ai/code/session_01Kbzfscp4w5enUrZxMnDt78
peterswimm merged commit f6691fec9d into fix/terracotta-canonical-c05734 2026-09-09 20:31:48 +00:00
peterswimm deleted branch feat/toilville-web-palette-tokens 2026-09-09 20:31:49 +00:00
Sign in to join this conversation.
No description provided.