Skip to content

Color schemes: per-scheme duotone overrides (prototype, stacked on #80698) - #80746

Draft
MaggieCabrera wants to merge 1 commit into
try/theme-json-color-schemesfrom
try/dark-mode-duotone
Draft

Color schemes: per-scheme duotone overrides (prototype, stacked on #80698)#80746
MaggieCabrera wants to merge 1 commit into
try/theme-json-color-schemesfrom
try/dark-mode-duotone

Conversation

@MaggieCabrera

@MaggieCabrera MaggieCabrera commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

What / Why

Technical prototype for discussion — not ready to merge. Stacked on #80698. Extends the color scheme data model to duotone presets, so filtered images switch with the rest of the palette.

How it works

A scheme override in settings.color.dark.duotone or settings.color.light.duotone:

  1. Injects wp-duotone-{slug}--{scheme} when the base preset is used.
  2. Points --wp--preset--duotone--{slug} to that filter inside the same prefers-color-scheme and data-scheme gates as Dark/light mode support for themes on theme.json  #80698.

Overrides match by slug. Custom per-block duotones remain fixed across schemes.

Testing

Automated

npm run wp-env-test start
npm run wp-env-test -- run --env-cwd=wp-content/plugins/gutenberg \
  wordpress vendor/bin/phpunit -c phpunit.xml.dist --filter WP_Duotone_Gutenberg_Test

Manual

Use either theme from WordPress/community-themes#266:

  1. Switch between its light and dark controls.
  2. Confirm the Portrait image recolors with the palette and Signal gradient.
  3. In DevTools, confirm --wp--preset--duotone--portrait points to the matching scheme filter.
  4. Repeat in the Site Editor canvas.
Citrus DaylightElectric Dusk
Portrait duotone in the light scheme Portrait duotone in the dark scheme

Questions for reviewers

  1. Is a per-scheme SVG filter the right mechanism, or should duotone move to CSS-native filters first?
  2. Should custom per-block duotones remain out of scope?

See docs/how-to-guides/themes/theme-json-dark-scheme.md.

@MaggieCabrera
MaggieCabrera force-pushed the try/dark-mode-duotone branch from 8619be1 to ac8bece Compare July 27, 2026 20:13
@MaggieCabrera MaggieCabrera added [Type] Technical Prototype Offers a technical exploration into an idea as an example of what's possible No Core Sync Required Indicates that any changes do not need to be synced to WordPress Core labels Jul 28, 2026
@MaggieCabrera
MaggieCabrera force-pushed the try/dark-mode-duotone branch from ac8bece to c543763 Compare July 28, 2026 14:26
Extends the scheme model to duotone, so duotone-filtered images recolor
with the scheme instead of staying fixed (a light-tinted duotone left
unchanged on a dark layout would otherwise break the design).

Unlike palette/gradients, a duotone preset resolves to an injected SVG
filter referenced through --wp--preset--duotone--<slug>. A scheme override
(settings.color.light.duotone / settings.color.dark.duotone, matched by
slug) injects an additional filter (id wp-duotone-<slug>--<scheme>) and
redefines that custom property under the scheme gate, so blocks flip
automatically. Variant filters are only injected when the base preset is
used.

Presets only; custom per-block duotones remain a documented limitation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Copilot AI 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.

Pull request overview

Technical prototype extending the theme.json color-scheme override model to duotone presets, so --wp--preset--duotone--{slug} can switch under the same prefers-color-scheme / data-scheme gates as palette and gradients.

Changes:

  • Add settings.color.dark.duotone / settings.color.light.duotone to the theme.json schema and reference docs.
  • Emit per-scheme duotone variant SVG filters (wp-duotone-{slug}--{scheme}) and gated CSS custom-property overrides when a base preset is used.
  • Update theme.json documentation to describe duotone overrides in the scheme model.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
schemas/json/theme.json Adds schema support for `settings.color.(dark
lib/class-wp-duotone-gutenberg.php Generates scheme-variant duotone SVG filters and gated --wp--preset--duotone--* overrides.
docs/reference-guides/theme-json-reference/theme-json-living.md Updates the theme.json reference to include duotone under dark/light overrides.
docs/how-to-guides/themes/theme-json-dark-scheme.md Documents how scheme duotone overrides work and what remains out of scope.

Comment on lines +1158 to +1161
$scheme_css = self::get_scheme_global_styles_presets();
if ( '' !== $scheme_css ) {
wp_add_inline_style( 'global-styles', $scheme_css );
}
Comment on lines +810 to +818
private static function get_scheme_duotone_overrides() {
if ( isset( self::$scheme_duotone_overrides ) ) {
return self::$scheme_duotone_overrides;
}

self::$scheme_duotone_overrides = array();
$settings = gutenberg_get_global_settings();

foreach ( array( 'light', 'dark' ) as $scheme ) {
Comment on lines +866 to +876
self::$used_svg_filter_data[ $variant_filter_id ] = array(
'slug' => $slug . '--' . $scheme,
'colors' => $overrides[ $scheme ][ $slug ],
);

// Record the variant so its gated custom-property override is emitted.
self::$used_scheme_duotone_presets[ $variant_filter_id ] = array(
'scheme' => $scheme,
'slug' => $slug,
'filter' => self::get_filter_url( $variant_filter_id ),
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

No Core Sync Required Indicates that any changes do not need to be synced to WordPress Core [Type] Technical Prototype Offers a technical exploration into an idea as an example of what's possible

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants