Symfony Twig theme (twig.default_path, FrameworkBundle template paths) is unrelated to UI Kernel themes (data-theme, ThemeRegistry). See Symfony Twig theming.
Built-in themes ship as W3C DTCG token files — not bespoke symfinity_ui_kernel.themes YAML:
config/
├── design-systems/chameleon.dtcg.yaml # platform semantic vocabulary (ghost alias, …)
└── themes/{lineage}/
├── theme.meta.yaml # palette recipe + variant registry
├── {variant}.dtcg.yaml # theme-layer semantic + appearance tokens
└── …
| File | Role |
|---|---|
theme.meta.yaml |
lineage, optional design_system_id, shared palette, variants[] with layer_file, tone, mode |
{variant}.dtcg.yaml |
theme layer — semantic colour aliases (color.primary → {color.blue.600}), spacing, radius, motion |
design-systems/{id}.dtcg.yaml |
design_system layer — cross-theme vocabulary extensions |
Each lineage SHOULD set design_system_id: chameleon in theme.meta.yaml (default when omitted). The registry loads config/design-systems/{id}.dtcg.yaml. Unknown ids fail at stack-build time with UnknownDesignSystemException.
Runtime resolution: base (OKLCH palette DTCG from generator) ⊕ design_system ⊕ theme → LayeredTokenResolver → --ui-* CSS.
ui-themer consumer themes (export YAML from symfinity/ui-themer) stay on the bespoke preset / tone / semantics schema via AuthoringThemeConfig — they do not register in config/themes/. See DTCG token core and the ui-themer boundary below.
| Id | Label | Notes |
|---|---|---|
default |
Balanced | Light neutral baseline |
default-dark |
Balanced dark | Dark neutral baseline |
semantic |
Semantic | Bootstrap-inspired semantic colours, roomy spacing |
semantic-dark |
Semantic dark | Dark semantic palette |
utility |
Utility | Tailwind-inspired slate/blue palette, compact spacing |
utility-dark |
Utility dark | Dark utility palette |
Set the active lineage in config:
symfinity_ui_kernel:
default_theme: semantic
default_variant: semanticBuilt-in themes map to one of two rhythm profiles:
| Profile | Spacing | Radius | Motion | Lineages |
|---|---|---|---|---|
| Semantic | Roomy | Rounded | 200ms | default, semantic pairs |
| Utility | Compact | Subtle | 150ms | utility pair |
Theme swap changes semantic role colours; layout rhythm follows the lineage profile.
The boot script (ui_kernel_theme_boot_script()) sets document.documentElement.dataset.theme before CSS paints. Pair light/dark ids per lineage (default / default-dark, etc.).
For prefers-color-scheme: auto, the bundle can sync with a server endpoint when configured. Without it, the client resolves light/dark from system preference using the configured lineage pair.
CssGenerator emits:
- Theme tokens (
--ui-color-*,--ui-space-*,--ui-radius-*, …) - Overlay tokens (
--ui-overlay-surface,--ui-overlay-border,--ui-overlay-shadow,--ui-backdrop-color,--ui-backdrop-blur) - Structural profile globals (breakpoints, z-index ladder, layout roles such as grid/stack)
Mono-based semantic colour refs follow the active theme tone (warm/cool/pure families) so text and surface roles stay coherent within a lineage.
It does not emit [data-ui-role] component rules. Install symfinity/ux-blocks-* tier packages for component CSS.
Consumer themes authored in ui-themer (export YAML) use AuthoringThemeConfig + ThemeTokenResolver — not the built-in DTCG catalog. ui-themer packs live outside config/themes/ and resolve through the authoring pipeline, not BuiltinDtcgThemeCatalog.
Override public --ui-* keys at deploy time without forking theme YAML:
symfinity_ui_kernel:
default_theme: semantic
user_tokens:
'--ui-color-primary': '#1a4fd6'
'--ui-color-secondary': '#6c757d'Unknown keys are rejected at merge time.
Adjust breakpoints or container widths via config (not user_tokens):
symfinity_ui_kernel:
system_profile:
breakpoints:
md: 800When caching generated CSS, include profile identity in your cache key alongside theme id and user token hash.
Built-in themes use system font stacks for --ui-font-family-sans and --ui-font-family-mono. Optional webfont loading via symfinity/font-manager: font-manager-pairing.md.