Skip to content

docs(theme): state contrast thresholds and check every palette - #641

Merged
wemra3 merged 7 commits into
mainfrom
docs/semantic-color-palette-contrast
Oct 28, 2026
Merged

wemra3 merged 7 commits into
mainfrom
docs/semantic-color-palette-contrast

Conversation

@wemra3

@wemra3 wemra3 commented Oct 25, 2026

Copy link
Copy Markdown
Contributor

Why

Three open points in tailor-inc/platform-planning#2208 and tailor-inc/platform-planning#1892 needed a decision: whether status colours follow the palette, whether the remaining literal values should read scale steps, and which contrast thresholds AppShell guarantees. This PR records the decisions. No colour value changes.

Closes tailor-inc/platform-planning#2213. Addresses tailor-inc/platform-planning#1892: the thresholds are stated and tested, and the known exceptions are listed below.

What

  • Decision record: new section "Update 2026-10-24".
    • Status colours are the same in every palette. cream and bloom keep inheriting the hue roles. The neutral roles still follow the palette.
    • --accent, the chart colours, the shadows and DocumentProgressCard keep literal values.
    • Contrast thresholds: 4.5:1 for text and 3:1 for non-text.
  • Styling guide: the thresholds, the palette rule and the known exceptions. One sentence on the chart colours.
  • semantic-contrast.test.ts: the same checks run for default, cream and bloom, in light and dark mode. A new test checks that the palette files are read, so the checks cannot fall back to the default palette without notice. Most of the diff in this file is indentation from the new describe.each.
  • Changeset: patch, because the usage guidance changes.

Known exceptions

These are listed in the styling guide:

  • text on surface-hover stays at the 4.2:1 floor. Choosing another step is a visible change for a later PR.
  • In cream and bloom, the main content area is transparent over the shell gradient. At the top of the bloom light gradient, text on surface is 4.49:1 for success and 4.48:1 for danger. The earlier figure in the decision record (4.16:1) was measured on --shell-gradient-base, which the gradient covers. The new section corrects it.
  • warning solid and indicator are 2.15:1 against a light card. They are used with a label.
  • The neutral intent is not checked.

Checks

  • No CSS file changes, so no token value changes.
  • fmt:check, lint, type-check, test (core: 3023 tests), docs:check and build pass.
  • The contrast test has 310 tests. I changed the bloom dark --card to red on purpose, and 17 tests failed. Then I restored it.
  • Note: vite.config.ts sets publicDir: "src/assets", so build copies the two test files in src/assets to dist/. A local test run after build runs them twice, and they are in the npm package. This PR does not change that.

🤖 Generated with Claude Code

Status colours stay the same in every palette, and --accent, the chart
colours, the shadows and DocumentProgressCard keep literal values. The
styling guide states the 4.5:1 text and 3:1 non-text thresholds with the
known exceptions, and semantic-contrast.test.ts runs for cream and bloom
as well as default. No colour values change.

Refs tailor-inc/platform-planning#2208, tailor-inc/platform-planning#1892

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@wemra3
wemra3 requested a review from a team as a code owner October 25, 2026 01:57
@wemra3
wemra3 requested review from IzumiSy and interacsean October 25, 2026 01:57
@github-actions

github-actions Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Code Metrics Report

main (bb54644) #641 (a1bc896) +/-
Coverage 89.5% 89.5% 0.0%
Test Execution Time 2m1s 3m29s +1m28s
Details
  |                     | main (bb54644) | #641 (a1bc896) |  +/-   |
  |---------------------|----------------|----------------|--------|
  | Coverage            |          89.5% |          89.5% |   0.0% |
  |   Files             |            236 |            236 |      0 |
  |   Lines             |           7504 |           7504 |      0 |
  |   Covered           |           6719 |           6719 |      0 |
- | Test Execution Time |           2m1s |          3m29s | +1m28s |

Code coverage of files in pull request scope (100.0% → 100.0%)

Files Coverage +/- Status
packages/core/package.json 100.0% 0.0% modified

Reported by octocov

@IzumiSy

IzumiSy commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

@wemra3

What do you think about using Vitest Browser Mode for these style checks? I tried it in a stacked follow-up in #652.

The main benefit I see is testing the published CSS under real browser conditions. Chromium handles variable resolution, inheritance, and cascade, rather than us approximating those rules with a custom parser. We can also check whether styles actually take effect, instead of only checking the generated class names or CSS declarations.

The CI runtime impact seems small, so this feels like a worthwhile trade-off for more realistic coverage and less custom test logic. Does this direction make sense to you, or do you see advantages to keeping these checks in Node?

…alette-contrast

# Conflicts:
#	docs-manifest.json
@wemra3

wemra3 commented Oct 27, 2026

Copy link
Copy Markdown
Contributor Author

@IzumiSy Yes, I think this direction makes sense. The browser resolves variables, inheritance and the cascade, so the tests check what consumers actually get, and we can delete the custom parser. I read #652, and the thresholds and exclusions are the same, so I am happy with it.

I merged main into #641 to fix a conflict in docs-manifest.json. #652 may need the same update.

@IzumiSy

IzumiSy commented Oct 28, 2026

Copy link
Copy Markdown
Contributor

@wemra3 Thanks. Then, let me merge #652 into this PR to see all changes in one 🙏

* test(theme): move style contracts to Vitest Browser Mode

* fix CI for browser style contracts

Co-authored-by: IzumiSy <982850+IzumiSy@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: IzumiSy <982850+IzumiSy@users.noreply.github.com>

@IzumiSy IzumiSy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks some updates needed in docs and decision about browser testing, but overall it's good to go.

Hiroki Uemura and others added 2 commits October 28, 2026 20:54
…alette-contrast

# Conflicts:
#	docs-manifest.json
The contrast checks moved to Vitest Browser Mode in #652. Update the styling
guide and the decision record, and record why the checks run in Chromium.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@wemra3
wemra3 merged commit 6b6e21c into main Oct 28, 2026
10 checks passed
@wemra3
wemra3 deleted the docs/semantic-color-palette-contrast branch October 28, 2026 12:37
wemra3 pushed a commit that referenced this pull request Oct 28, 2026
#641 removed semantic-contrast.test.ts and added the dist/** exclude, so
this PR now only moves theme-bridge.test.ts out of src/assets. Drop the
!dist/**/*.test.* guard in files: no test file is copied into dist/ now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants