Skip to content

Theme: Use a perceptual five-step foreground scale - #82294

Draft
ciampo wants to merge 5 commits into
trunkfrom
codex/theme-anchored-foreground-scale
Draft

Theme: Use a perceptual five-step foreground scale#82294
ciampo wants to merge 5 commits into
trunkfrom
codex/theme-anchored-foreground-scale

Conversation

@ciampo

@ciampo ciampo commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

What?

Follow up to #82037. Alternative implementation to #81537.

Applies the pilot approach, Anchored state-skewed · relative chroma, to the production theme algorithm. It adds fgSurface5, separates resting and active foreground states, and makes strong active fills consistently darker than their resting fills. One shared fill foreground now meets the WCAG floor on both states.

It also adds a private Storybook pilot that compares the production candidate with an all-APCA scale and a role-specific hybrid across the same neutral, brand, and error ramps.

Why?

The four-step foreground scale did not leave a distinct state between resting text and the strong endpoint, especially in light themes. Strong active fills could also become lighter or darker depending on the seed, and some representative brand and error combinations produced active-state contrast warnings.

The pilot showed that an anchored, state-skewed scale creates a clearer state change without flattening vibrant accent seeds. The new comparison tests whether APCA or OKLab color difference should shape the rest of the ramp while WCAG remains the hard accessibility gate.

How?

  • Preserve compliant fgSurface1 and fgSurface2 colors and the former strong endpoint.
  • Use APCA to place fgSurface3 and fgSurface4 at 40% and 60% of the visible contrast range. WCAG ratios remain hard constraints.
  • Use the existing chroma taper for neutral ramps and Color.js gamut-relative OKLCH chroma for accent ramps.
  • Generate bgFill2 in the darker direction, then solve fgFill against both bgFill1 and bgFill2. The former pinned foreground lightness is released down to a serialization-safe 4.5:1 floor.
  • Regenerate the primitive tokens, static ramps, CSS, JavaScript, and Sass fallbacks.
  • Add repeatable benchmarks for the production change and the three Storybook approaches.
Performance

A local comparison against current trunk on Node 20.20.2 produced these median times from 30 samples:

Ramp workload Trunk This PR Difference
One background ramp 0.333 ms 0.667 ms +100.4%
One accent ramp 0.416 ms 1.916 ms +360.8%
One background plus six accent ramps 3.728 ms 13.317 ms +257.2%

The separate experiment benchmark measured one neutral, brand, and error ramp at 5.831 ms for the anchored candidate, 9.888 ms for all-APCA, and 15.870 ms for the role-specific hybrid.

These are uncached local calculations and do not enforce a timing threshold. ThemeProvider caches ramps by seed and skips calculation when no custom colors are supplied.

Testing Instructions

  1. Run npm run storybook:dev.
  2. Open Design System → Theme → Theme Provider → Perceptual Ramp Pilot → Comparison.
  3. Use the Approaches control to show or hide the anchored, all-APCA, and role-specific hybrid rows.
  4. Compare the neutral, brand, and error tables for Default light, Default dark, Ectoplasm, Middle-gray, Yellow, and Cyan. Confirm every row reports WCAG gates pass and the seed colors appear above each scale.
  5. Compare the resting and active buttons below each seed combination. Confirm the active fill is always darker and remains readable.
  6. Open Design System → Theme → Theme Provider → Color Scales → Sample Combinations. Confirm each section reports No warnings.
  7. Open Design System → Components → Button. Compare the brand and neutral examples at rest and while pressed.

Testing Instructions for Keyboard

Use Tab to reach the Previous steps and Next steps buttons above each ramp table. Activate them with Enter or Space and confirm the table scrolls horizontally. In the Button story, use Tab to move through the examples and Space or Enter to press them. Confirm focus and the darker active state remain visible.

Screenshots or screencast

The Perceptual Ramp Pilot Storybook story is the visual comparison surface for this draft experiment.

Use of AI Tools

OpenAI Codex helped implement the algorithm, generate tests and artifacts, run verification, and draft this description. The author reviewed the resulting code and behavior.

@github-actions github-actions Bot added [Package] Base styles /packages/base-styles [Package] Theme /packages/theme labels Sep 1, 2026
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown

🤖 PR meta 🤖

🏷️ Labels

This pull request needs exactly one label indicating its type, and has 0.

  • Required: any label starting with [Type].
  • Found: none.

Read more about Type labels in Gutenberg. If you cannot add labels yourself, a reviewer can do it for you.

📦 Bundle size

Size Change: +2.54 kB (+0.03%)

Total Size: 7.92 MB

📦 View Changed
Filename Size Change
build/modules/boot/index.min.js 57.5 kB +17 B (+0.03%)
build/scripts/block-editor/index.min.js 478 kB +30 B (+0.01%)
build/scripts/block-library/index.min.js 370 kB +7 B (0%)
build/scripts/components/index.min.js 266 kB +4 B (0%)
build/scripts/edit-site/index.min.js 378 kB +12 B (0%)
build/scripts/editor/index.min.js 582 kB -1 B (0%)
build/scripts/format-library/index.min.js 40.1 kB +16 B (+0.04%)
build/scripts/media-utils/index.min.js 200 kB +18 B (+0.01%)
build/scripts/patterns/index.min.js 12.4 kB +7 B (+0.06%)
build/scripts/theme/index.min.js 28.8 kB +2.06 kB (+7.72%) 🔍
build/styles/components/style-rtl.css 16.2 kB +14 B (+0.09%)
build/styles/components/style-rtl.min.css 13.7 kB +13 B (+0.09%)
build/styles/components/style.css 16.3 kB +14 B (+0.09%)
build/styles/components/style.min.css 13.7 kB +12 B (+0.09%)
build/styles/edit-site/style-rtl.css 21.8 kB +35 B (+0.16%)
build/styles/edit-site/style-rtl.min.css 17.9 kB +41 B (+0.23%)
build/styles/edit-site/style.css 21.8 kB +37 B (+0.17%)
build/styles/edit-site/style.min.css 17.9 kB +41 B (+0.23%)
build/styles/editor/style-rtl.css 31.6 kB +27 B (+0.09%)
build/styles/editor/style-rtl.min.css 27.1 kB +23 B (+0.08%)
build/styles/editor/style.css 31.7 kB +27 B (+0.09%)
build/styles/editor/style.min.css 27.1 kB +23 B (+0.08%)
build/styles/theme/design-tokens-rtl.css 3.07 kB +16 B (+0.52%)
build/styles/theme/design-tokens-rtl.min.css 1.51 kB +16 B (+1.07%)
build/styles/theme/design-tokens.css 3.07 kB +16 B (+0.52%)
build/styles/theme/design-tokens.min.css 1.51 kB +16 B (+1.07%)

7d3423f Run

⚡ Performance

Show the results

Client side metrics exclude the server response time.

front-end-block-theme

Metric e60e854 trunk % Change
timeToFirstByte 48.4 ms +11.36% -3.62% 49.35 ms +17.22% -3.44% -1.93%
largestContentfulPaint 76 ms +5.26% -5.26% 82 ms +9.76% -7.32% -7.32%
lcpMinusTtfb 27.15 ms +5.34% -7.55% 29 ms +20.69% -7.24% -6.38%
wpBeforeTemplate 22.91 ms +15.71% -5.5% 22.75 ms +22.24% -8.31% 0.7%
wpTemplate 21.84 ms +3.25% -2.43% 22.86 ms +5.69% -5.12% -4.46%
wpTotal 45.11 ms +9.18% -4.61% 45.93 ms +14.63% -3.31% -1.79%
wpMemoryUsage 7.54 MB +0% -0% 7.50 MB +0% -0% 0.46%
wpDbQueries 17 +0% -0% 17 +0% -0% 0%

front-end-classic-theme

Metric e60e854 trunk % Change
timeToFirstByte 38.5 ms +12.47% -3.64% 38.75 ms +10.97% -2.58% -0.65%
largestContentfulPaint 76 ms +7.89% -0% 76 ms +7.89% -0% 0%
lcpMinusTtfb 38.9 ms +3.47% -3.08% 38.2 ms +4.45% -4.06% 1.83%
wpBeforeTemplate 18.52 ms +16.47% -0.76% 18.85 ms +6.53% -2.33% -1.75%
wpTemplate 16.59 ms +3.44% -3.44% 16.86 ms +3.91% -3.14% -1.6%
wpTotal 35.76 ms +11.55% -3.75% 36.07 ms +10.15% -2.5% -0.86%
wpMemoryUsage 6.16 MB +0% -0% 6.12 MB +0% -0% 0.58%
wpDbQueries 14 +0% -0% 14 +0% -0% 0%

media-processing

Metric e60e854 trunk % Change
mediaProcessingJpeg 330.64 ms +0.96% -0.26% 337.27 ms +2.64% -1.39% -1.97%
mediaProcessingAvif 4963.93 ms +0.61% -0.27% 5020.87 ms +0.68% -1.06% -1.13%
mediaProcessingJpegToAvif 3494.19 ms +0.34% -1.16% 3509.75 ms +0.94% -0.31% -0.44%

media-upload

Metric e60e854 trunk % Change
jpegUploadProcessing 1399.91 ms +1.18% -0.28% 1396.61 ms +0.64% -0.37% 0.24%
pngUploadProcessing 189.01 ms +42.3% -6.11% 195.47 ms +25.58% -7.24% -3.3%
largeJpegUploadProcessing 1390.8 ms +0.29% -0.87% 1386.76 ms +1.3% -0.35% 0.29%
multipleImageUploadProcessing 1466.43 ms +2.23% -0.06% 1460.5 ms +0.85% -0.04% 0.41%

post-editor

Metric e60e854 trunk % Change
serverResponse 478.99 ms +1.83% -8.52% 478.99 ms +3.58% -8.24% 0%
firstPaint 228.24 ms +42.09% -12.03% 258.09 ms +8.02% -17.42% -11.57%
domContentLoaded 1353.69 ms +2.62% -1.32% 1379.48 ms +1.26% -0.82% -1.87%
loaded 1355.1 ms +2.6% -1.3% 1381.12 ms +1.25% -0.82% -1.88%
firstContentfulPaint 445.07 ms +6.22% -5.76% 458.43 ms +0.65% -4.4% -2.91%
firstBlock 3727.96 ms +0.51% -1.39% 3682.66 ms +0.56% -0.38% 1.23%
type 23.19 ms +10.18% -13.54% 22.18 ms +11.95% -19.48% 4.55%
typeWithoutInspector 24.87 ms +5.43% -19.98% 21.62 ms +13% -23.73% 15.03%
typeWithTopToolbar 28.13 ms +11.73% -19.73% 28.95 ms +10.81% -7.39% -2.83%
typeContainer 10.47 ms +5.73% -4.87% 10.43 ms +14.38% -4.51% 0.38%
focus 96.44 ms +23.98% -9.19% 95.14 ms +11.68% -5.6% 1.37%
firstFocus 198.29 ms +0% -0% 186.63 ms +0% -0% 6.25%
selectAll 612.46 ms +13.45% -0.96% 599.2 ms +3.13% -2.46% 2.21%
listViewOpen 73.05 ms +7.23% -7.54% 71.04 ms +15.13% -11.11% 2.83%
inserterOpen 26.12 ms +2.07% -9.76% 24.91 ms +8.67% -5.62% 4.86%
inserterHover 4.75 ms +8.63% -8.42% 4.77 ms +7.34% -7.55% -0.42%
inserterSearch 9.26 ms +3.24% -1.51% 8.15 ms +11.78% -2.58% 13.62%
loadPatterns 690.94 ms +1.42% -1.43% 669.03 ms +6.7% -1.04% 3.27%
wpTotal 467.88 ms +1.83% -8.94% 467.5 ms +3.71% -8.31% 0.08%
wpMemoryUsage 13.13 MB +0% -0% 13.10 MB +0% -0% 0.22%
wpDbQueries 54 +0% -1.85% 54 +0% -1.85% 0%

site-editor

Metric e60e854 trunk % Change
serverResponse 417.42 ms +5.73% -5.01% 438.68 ms +1.99% -6.61% -4.85%
firstPaint 252.19 ms +14.6% -8.41% 233.67 ms +4.75% -7.08% 7.93%
domContentLoaded 1421.53 ms +0.44% -1.07% 1410.68 ms +0.48% -1.1% 0.77%
loaded 1422.87 ms +0.44% -1.06% 1412.17 ms +0.46% -1.12% 0.76%
firstContentfulPaint 451.77 ms +1.81% -3.66% 437.47 ms +3.68% -2.04% 3.27%
firstBlock 4470.07 ms +0.49% -1.14% 4358.89 ms +0.66% -1.01% 2.55%
type 22.64 ms +16.25% -17.76% 22.18 ms +10.5% -15.51% 2.07%
navigate 112.17 ms +11.48% -1.36% 105.83 ms +5.57% -9.69% 5.99%
loadPatterns 1579.26 ms +8.77% -15.37% 1383.97 ms +4.38% -10% 14.11%
loadPages 1309.93 ms +8.53% -4.82% 1168.93 ms +4.5% -1.97% 12.06%
wpTotal 406.54 ms +5.68% -5.18% 427.73 ms +2.07% -6.79% -4.95%
wpMemoryUsage 12.02 MB +0% -0% 11.99 MB +0% -0% 0.31%
wpDbQueries 43 +2.33% -0% 43 +2.33% -0% 0%

7d3423f Run

@ciampo ciampo self-assigned this Sep 1, 2026
@ciampo
ciampo force-pushed the codex/theme-anchored-foreground-scale branch from 799893a to b03bf28 Compare September 1, 2026 17:59
@ciampo
ciampo force-pushed the codex/theme-anchored-foreground-scale branch from b03bf28 to d7ec500 Compare September 1, 2026 20:50
@ciampo
ciampo force-pushed the codex/theme-anchored-foreground-scale branch from d7ec500 to 7d3423f Compare September 1, 2026 20:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Package] Base styles /packages/base-styles [Package] Theme /packages/theme

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant