Skip to content

docs: add comprehensive guide to color scales and contrast patterns#1361

Open
lukasoppermann wants to merge 7 commits intomainfrom
docs/color-scales-guide
Open

docs: add comprehensive guide to color scales and contrast patterns#1361
lukasoppermann wants to merge 7 commits intomainfrom
docs/color-scales-guide

Conversation

@lukasoppermann
Copy link
Copy Markdown
Collaborator

Overview

Added a new document explaining how Primer's color system works:

  • Base scales: Structure (13 steps 0-13), semantics, current scales, and file locations
  • Functional tokens: Why they exist, examples, and how they reference base scales
  • Contrast requirements: WCAG 2.1 AA rules, automated checking, common violations
  • Change propagation: How updates to base scales cascade through functional tokens and themes
  • Best practices: Guidelines for scale modifications to minimize reference updates

Why now?

This context is needed for evaluating design decisions (like PR #1340) and serves as reference material for future color system work.

Target audience

  • Designers evaluating color system changes
  • Developers updating tokens or building new themes
  • Contributors trying to understand the system's constraints

lukasoppermann and others added 3 commits April 17, 2026 14:35
Adds a lint script that detects when tokens are deleted or renamed
without being documented in src/tokens/removed/. Compares the current
working tree against the git merge-base with main to find token names
that disappeared.

Changes:
- scripts/checkRemovedTokens.ts: main lint script
- scripts/utilities/extractTokenNames.ts: token name extraction utility
- scripts/utilities/extractTokenNames.test.ts: unit tests (7 cases)
- package.json: lint:removed script, wired into npm run lint
- .github/workflows/ci.yml: fetch-depth: 0 for base branch access
- .husky/pre-commit: runs check against HEAD before each commit

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Rename color.json → removed.json as the single tracking file
- Add 310 missing removed/renamed tokens from full version history:
  - v7.11.2 → v7.15.7: color scales, ansi, prettylights, fgColor renames (170)
  - v7.15.7 → v8.0.0: color.scale → base.color, gray → neutral (105)
  - v8.0.0 → v9.0.0: data.*.color, fgColor.*.@ renames (28)
  - v9.0.0 → v10.0.0: diffBlob restructuring (11)
  - v10.0.0 → v10.4.0: motion, outline.focus, button changes (7)
  - v11.0.0 → v11.7.0: lineBoxHeight, shadow.floating.legacy (7)
- Document removal/rename process in token-authoring.md
- Total: 757 entries (447 existing + 310 new)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Document base scale structure (13 steps 0-13)
- Explain functional tokens and how they layer on base scales
- Detail WCAG 2.1 AA contrast requirements
- Show how changes propagate through themes
- Include best practices for scale modifications
- Link to relevant ADRs and scripts

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 29, 2026 12:00
@lukasoppermann lukasoppermann requested a review from a team as a code owner April 29, 2026 12:00
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 29, 2026

⚠️ No Changeset found

Latest commit: dcb8dd6

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds new documentation describing Primer’s color scales and contrast constraints, and also introduces tooling/CI changes to enforce documenting removed/renamed tokens.

Changes:

  • Added COLOR_SCALES.md guide covering base scales, functional tokens, and contrast checking.
  • Added a removed-token lint script (scripts/checkRemovedTokens.ts) plus token-name extraction utility + tests.
  • Consolidated removed token mappings into src/tokens/removed/removed.json, wired the check into npm run lint, and adjusted CI checkout depth.
Show a summary per file
File Description
COLOR_SCALES.md New documentation for color scales/contrast; currently has a few accuracy issues.
contributor-docs/agents/token-authoring.md Documents the new “removed/renamed tokens must be recorded” workflow.
scripts/checkRemovedTokens.ts New lint script to detect removed tokens vs base branch and require documentation.
scripts/utilities/extractTokenNames.ts Utility to extract dot-path token names from parsed token JSON5.
scripts/utilities/extractTokenNames.test.ts Unit tests for token-name extraction behavior.
src/tokens/removed/removed.json New consolidated registry of removed tokens and replacements.
src/tokens/removed/color.json Deleted in favor of the consolidated removed-token registry.
package.json Adds lint:removed to lint pipeline; adds Husky prepare hook.
package-lock.json Lockfile updates for new dev dependencies.
.husky/pre-commit Adds pre-commit hook invoking the removed-token check (currently ineffective).
.github/workflows/ci.yml Ensures full git history is available (fetch-depth 0).

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 10/11 changed files
  • Comments generated: 7

Comment thread .husky/pre-commit Outdated
Comment thread package.json
Comment on lines +38 to +41
"lint": "eslint '**/*.{js,ts,tsx,md,mdx}' --config eslint.config.mjs && npm run lint:tokens && npm run lint:removed",
"lint:fix": "eslint '**/*.{js,ts,tsx,md,mdx}' --fix --max-warnings=0 --config eslint.config.mjs",
"lint:tokens": "tsx ./scripts/validateTokenJson.ts",
"lint:removed": "tsx ./scripts/checkRemovedTokens.ts",
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

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

The PR description is scoped to adding a color-scales/contrast guide, but this diff also adds a new removed-token lint/check script, Husky hook wiring, and a CI checkout-depth change. Either update the PR description/title to reflect these additional behavioral/tooling changes or split them into a separate PR to keep review and rollout risk manageable.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@copilot Can you move those changes into a new PR and a different branch?

Comment thread COLOR_SCALES.md Outdated

### Scale Structure

Each base scale has **13 steps** (0–13):
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

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

“13 steps (0–13)” is inconsistent: 0 through 13 inclusive is 14 steps. The repo’s base scales (e.g. base.color.neutral) do include keys 013, so the text should say “14 steps (0–13)” (or adjust the range if that’s not intended).

Copilot uses AI. Check for mistakes.
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.

Fixed in 9a65447 — updated "13 steps (0–13)" to "14 steps (0–13)" and corrected all other "13 steps" count references in the file (theme table, FAQ section).

Comment thread COLOR_SCALES.md
Comment on lines +160 to +161
npm run build:tokens # Generates all token files
npm run check:contrast # Runs contrast test
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

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

The documented contrast command npm run check:contrast doesn’t exist in this repo (the script is validate:contrast). Update the doc to reference the actual package script name so readers can run the check successfully.

Suggested change
npm run build:tokens # Generates all token files
npm run check:contrast # Runs contrast test
npm run build:tokens # Generates all token files
npm run validate:contrast # Runs contrast test

Copilot uses AI. Check for mistakes.
Comment thread COLOR_SCALES.md Outdated
for (const file of files) {
try {
const content = fs.readFileSync(path.join(REMOVED_DIR, file), 'utf-8')
const parsed = JSON.parse(content)
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

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

collectDocumentedRemovals() reads both .json and .json5 files but uses JSON.parse(), which will fail for valid JSON5 (comments/trailing commas). Either restrict the scan to .json only or parse with json5.parse() for .json5 to avoid the removed-token lint becoming brittle as soon as someone adds a JSON5 file.

Suggested change
const parsed = JSON.parse(content)
const parsed = file.endsWith('.json5') ? json5.parse(content) : JSON.parse(content)

Copilot uses AI. Check for mistakes.
Comment on lines +129 to +139
const baseRef = getArg('--base') ?? process.env.BASE_REF ?? 'main'
const isCI = process.env.CI === 'true'

const baseCommit = getBaseCommit(baseRef)

if (!baseCommit) {
if (isCI) {
console.error(`❌ Could not find merge-base with "${baseRef}". Ensure the base branch is fetched.`)
process.exit(1)
}
console.log(`⏭️ Skipping removed token check: could not resolve base ref "${baseRef}"`)
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

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

Defaulting baseRef to main is likely to fail in GitHub Actions because actions/checkout typically fetches origin/main but does not create a local main ref. Consider defaulting to origin/main, using GITHUB_BASE_REF when present, and/or falling back to origin/${baseRef} when git merge-base fails, otherwise npm run lint will hard-fail in CI even when no tokens were removed.

Suggested change
const baseRef = getArg('--base') ?? process.env.BASE_REF ?? 'main'
const isCI = process.env.CI === 'true'
const baseCommit = getBaseCommit(baseRef)
if (!baseCommit) {
if (isCI) {
console.error(`❌ Could not find merge-base with "${baseRef}". Ensure the base branch is fetched.`)
process.exit(1)
}
console.log(`⏭️ Skipping removed token check: could not resolve base ref "${baseRef}"`)
const requestedBaseRef =
getArg('--base') ?? process.env.GITHUB_BASE_REF ?? process.env.BASE_REF ?? 'origin/main'
const isCI = process.env.CI === 'true'
const baseRefCandidates = [...new Set([
requestedBaseRef,
requestedBaseRef.startsWith('origin/') ? requestedBaseRef.slice('origin/'.length) : `origin/${requestedBaseRef}`,
])]
let baseRef: string | null = null
let baseCommit: string | null = null
for (const candidate of baseRefCandidates) {
baseCommit = getBaseCommit(candidate)
if (baseCommit) {
baseRef = candidate
break
}
}
if (!baseCommit) {
const attemptedRefs = baseRefCandidates.map(ref => `"${ref}"`).join(', ')
if (isCI) {
console.error(`❌ Could not find merge-base with any of: ${attemptedRefs}. Ensure the base branch is fetched.`)
process.exit(1)
}
console.log(`⏭️ Skipping removed token check: could not resolve base ref from ${attemptedRefs}`)

Copilot uses AI. Check for mistakes.
lukasoppermann and others added 2 commits April 29, 2026 14:31
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 29, 2026

@lukasoppermann I've opened a new pull request, #1362, to work on those changes. Once the pull request is ready, I'll request review from you.

Agent-Logs-Url: https://github.com/primer/primitives/sessions/55bdd2b5-fb9a-47e2-bcb5-62c9fecfb7e9

Co-authored-by: lukasoppermann <813754+lukasoppermann@users.noreply.github.com>
- Add contrast requirements (WCAG 2.1 AA rules)
- Document three semantic regions of neutral scale (light, transition, text)
- Explain the 7↔8 lightness break and its architectural importance
- Show contrast matrix for neutral steps vs. functional tokens
- Clarify why functional tokens anchor at specific steps
- Document why scale changes cascade and propose solutions
- Include practical examples of contrast patterns in use

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@lukasoppermann
Copy link
Copy Markdown
Collaborator Author

@copilot the new PR removes all the tooling changes, but I also need a second PR that include only the tooling changes.

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 29, 2026

@lukasoppermann I've opened a new pull request, #1363, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI added a commit that referenced this pull request Apr 29, 2026
…RemovedTokens issues

- Remove COLOR_SCALES.md: this file belongs in the docs PR (#1361), not the tooling PR
- Fix JSON5 parsing: use json5.parse() for .json5 files in collectDocumentedRemovals()
- Fix baseRef defaulting: default to 'origin/main' instead of 'main', try both
  origin/ prefixed and unprefixed variants, handle empty env vars with || operator
- Add GITHUB_BASE_REF support for GitHub Actions context
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.

4 participants