docs(brand): canonical terracotta #C05734 + scope the dark-first rule to product surfaces #99

Merged
peterswimm merged 3 commits from feat/toilville-web-palette-tokens into main 2026-09-09 20:31:46 +00:00
Owner

Re-opens the content of #98, which got merged into #97's branch instead of
main and had its source branch deleted. #97 is now in main, so this targets
main directly and adds only the two terracotta commits.

Why

brand.primary had two values in circulation. Canonical DTCG says #C05734;
CLAUDE.md, the toilville-fse theme, the design-sync conventions and a pile of
generator fallbacks still said #CC5C37.

It is not cosmetic — white text passes on #C05734 (4.51:1) and fails on
#CC5C37 (4.07:1)
. The two website design files we just reviewed disagree
with each other for exactly this reason.

Corrected

  • CLAUDE.md — the <frontend_aesthetics> colour table + the skin.css example
  • README.md — the canonical ANSI 256 mapping table
  • .design-sync/conventions.toilville.md, .design-sync/remote-stage/tokens/colors.css
  • udg/products/wp-themes/toilville-fse/theme.jsonprimary, color-1, color-7
  • udg/products/rituals/bbs-style.yml — the mapping comment
  • udg/icon-registry/ICON_ISSUES_GITHUB.md
  • udg/generators/templates/extra.css — every var(--accent, …) fallback. This
    file already mixed both hexes line-to-line, so it is now uniform.

Left alone on purpose

  • Brand/specs/rituals/rituals-color-theme-light.md — the Rituals sidebar-bg
    genuinely is #CC5C37, a distinct token from brand.primary. Not drift.
  • docs/reviews/theme-alignment-strategy.md — historical record of this exact
    drift; rewriting it would erase the finding.

The ANSI 166 mapping is hardcoded config, not derived from the hex, so the
mapping is unaffected. (Neither hex is actually the nearest ANSI index — 166 is
a curated terminal choice.)

Also: scoping the dark-first rule

The approved toilville.com design is light-first, which CLAUDE.md listed as an
anti-pattern. Now scoped: product surfaces stay dark-cocoa-first;
marketing surfaces (toilville.com, deck.landing) are light-first by
design, with dark still available from the token layer's
prefers-color-scheme block.

Verification

  • just check — fully green
  • python -m pytest generator/tests/ — 161 passed
  • Rebuild touched only dist/*/artifact.html (extra.css is a generator template)

https://claude.ai/code/session_01Kbzfscp4w5enUrZxMnDt78

Re-opens the content of #98, which got merged into #97's branch instead of `main` and had its source branch deleted. #97 is now in `main`, so this targets `main` directly and adds only the two terracotta commits. ## Why `brand.primary` had two values in circulation. Canonical DTCG says `#C05734`; `CLAUDE.md`, the toilville-fse theme, the design-sync conventions and a pile of generator fallbacks still said `#CC5C37`. It is not cosmetic — **white text passes on `#C05734` (4.51:1) and fails on `#CC5C37` (4.07:1)**. The two website design files we just reviewed disagree with each other for exactly this reason. ## Corrected - `CLAUDE.md` — the `<frontend_aesthetics>` colour table + the skin.css example - `README.md` — the canonical ANSI 256 mapping table - `.design-sync/conventions.toilville.md`, `.design-sync/remote-stage/tokens/colors.css` - `udg/products/wp-themes/toilville-fse/theme.json` — `primary`, `color-1`, `color-7` - `udg/products/rituals/bbs-style.yml` — the mapping comment - `udg/icon-registry/ICON_ISSUES_GITHUB.md` - `udg/generators/templates/extra.css` — every `var(--accent, …)` fallback. This file already mixed both hexes line-to-line, so it is now uniform. ## Left alone on purpose - `Brand/specs/rituals/rituals-color-theme-light.md` — the Rituals **sidebar-bg** genuinely is `#CC5C37`, a distinct token from `brand.primary`. Not drift. - `docs/reviews/theme-alignment-strategy.md` — historical record of this exact drift; rewriting it would erase the finding. The ANSI `166` mapping is hardcoded config, not derived from the hex, so the mapping is unaffected. (Neither hex is actually the nearest ANSI index — 166 is a curated terminal choice.) ## Also: scoping the dark-first rule The approved toilville.com design is light-first, which `CLAUDE.md` listed as an anti-pattern. Now scoped: **product** surfaces stay dark-cocoa-first; **marketing** surfaces (toilville.com, `deck.landing`) are light-first by design, with dark still available from the token layer's `prefers-color-scheme` block. ## Verification - `just check` — fully green - `python -m pytest generator/tests/` — 161 passed - Rebuild touched only `dist/*/artifact.html` (extra.css is a generator template) https://claude.ai/code/session_01Kbzfscp4w5enUrZxMnDt78
`brand.primary` had two values in circulation. Canonical DTCG says #C05734;
CLAUDE.md, the toilville-fse theme, the design-sync conventions and several
generator fallbacks still said #CC5C37. It is not cosmetic — white text passes
on #C05734 (4.51:1) and fails on #CC5C37 (4.07:1).

Corrected: CLAUDE.md, README.md (ANSI table), .design-sync/{conventions,
remote-stage}, udg/products/wp-themes/toilville-fse/theme.json, rituals
bbs-style.yml, udg/icon-registry/ICON_ISSUES_GITHUB.md, and every --accent
fallback in udg/generators/templates/extra.css (which already mixed both).

Left alone on purpose:
  Brand/specs/rituals/rituals-color-theme-light.md — sidebar-bg genuinely is
    #CC5C37, a distinct token from brand.primary
  docs/reviews/theme-alignment-strategy.md — historical record of this drift

Also scopes the <frontend_aesthetics> dark-first rule: product surfaces stay
dark-cocoa-first, marketing surfaces (toilville.com, deck.landing) are
light-first by design.

Claude-Session: https://claude.ai/code/session_01Kbzfscp4w5enUrZxMnDt78
build: regenerate artifact.html for the extra.css terracotta fallbacks
Some checks failed
PR policy check / policy-gate (pull_request) Failing after 0s
Security Scans / Gitleaks secret scan (pull_request) Successful in 2m24s
Security Scans / Trivy filesystem scan (pull_request) Successful in 3m6s
Test Generator / lint-workflows (pull_request) Successful in 1m9s
UDG dist drift gate / dist/ matches dtcg + udg sources (pull_request) Successful in 40s
Test Generator / lint-prose (pull_request) Successful in 48s
Test Generator / test (pull_request) Successful in 5m39s
bbd44b79d4
Claude-Session: 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
Sign in to join this conversation.
No description provided.