Context
I’m building a new theme from scratch and adopted color_palette (following Horizon 4.0, which dropped color_scheme_group entirely). After a deep migration I hit a real architectural tradeoff and have some forward-looking questions.
The core tradeoff I ran into
color_scheme_group gave each scheme a complete, curated role bundle (background + text + primary/secondary button + input + border), guaranteed coherent by the designer. color_palette is intentionally flat — independent named colors with no role grouping. That’s cleaner as a single source of brand color, but it shifts a real responsibility onto the theme:
- When a merchant sets a custom background on a section, static elements inside it (buttons, inputs, sale price, swatches — not child blocks) no longer come from a coherent scheme. Their colors are global and were tuned against the page background, so they can clash on a custom background.
- Under schemes this was solved “for free” (each scheme carried its own button set). Under a flat palette it isn’t.
What I did (and want to validate)
- A global
:rootengine emitting--color-*tokens from the palette + global color settings. - A scoped per-element override snippet on
.color-custom-{id}that auto-derives foreground/border viacolor_brightness+color_contrast(WCAG), and adaptively re-derives button/input colors only when the global ones fail a 3:1 contrast against the custom background. - A planned per-block color override (the explicit control that per-scheme curation used to provide, relocated from scheme → block).
Pros I see
- Single source of brand color;
{{ settings.colors.x }}referenceable acrosscolor/color_backgrounddefaults. - Much better editing UX / onboarding; machine-friendly for AI / brand-kit flows.
Cons / costs
- Loss of per-scheme curated role bundles → the theme must reconstruct per-context contrast itself.
- More Liquid logic in the theme for what schemes gave declaratively.
Questions
- Intended end-state: for new themes, is the recommended model palette-only (no
color_scheme_group, like Horizon), or palette-as-source feeding scheme inputs as defaults? The docs say both “usecolor_paletteinstead” and “you can use a palette color as acolordefault”, which read slightly differently. - Per-element theming: with a flat palette, is auto-deriving per-section foreground/contrast (à la Horizon’s
contrast-override) the blessed pattern, or is Shopify planning a first-class primitive for per-section/per-element color so themes don’t each reinvent it? - Per-block overrides: is there a recommended pattern for letting a merchant override button/input colors at the block level from the palette?
- Longevity: is there any guidance confirming
color_scheme_groupremains supported long-term for existing themes? (Migration of thousands of live themes seems impractical, so I assume yes — but a confirmation would help theme authors commit.) - Palette-only capabilities: are there features that already (or will) work only with
color_palette— e.g. gradients, swatch propagation across pickers, AI / brand-kit color extraction? Knowing this helps weigh adoption. - Related known issue: palette colors not selectable inside
color_schemecolor inputs — is the fix tied to a broader direction here?
Thanks — keen to hear how other theme authors are approaching this, and any official steer.