Protocol Theme (createSurface.theme)
Besides injecting a full A2UITheme with provideA2UI({ theme }), you can attach a theme object on the v0.9 createSurface message to override primary color and font for a single Surface.
<A2UISurface> reads that payload and sets CSS variables on the Surface root:
| Field | Effect |
|---|---|
primaryColor | Builds a full --p-* ramp |
font | Sets --font-family / --font-family-flex |
This matches the Surface Theme example in the examples app: surface-theme-example.json.
Live Preview
The two panels share the same component tree and differ only in createSurface.theme.primaryColor / font (rose vs blue):
Message Example
{
"version": "v0.9",
"createSurface": {
"surfaceId": "example-surface-theme-rose",
"catalogId": "https://a2ui.org/specification/v0_9/basic_catalog.json",
"theme": {
"primaryColor": "#e11d48",
"font": "Georgia, 'Times New Roman', serif"
}
}
}Follow up with updateComponents / updateDataModel on the same surfaceId. The preview (and the examples app) also create a second Surface with primaryColor: "#2563eb" for comparison.
vs App-Level Theme
| Layer | Entry | Scope |
|---|---|---|
| App theme | provideA2UI({ theme }) | App-wide: utility classes + additionalStyles |
| Surface theme | createSurface.theme | --p-* / font on one Surface |
They can stack: the app theme maps components to tokens; the protocol theme overrides the primary ramp on that Surface.
If Button does not follow primaryColor
The default theme hardcodes additionalStyles.Button.background as a gradient, which overrides color-bgc-p30 (var(--p-30)). To let Button pick up primaryColor, set:
Button: {
...defaultTheme.additionalStyles?.Button,
background: undefined,
}The preview above and the examples Surface Theme page already do this.
Try It in Examples
cd packages/vue-renderer
npm run devOpen Surface Theme in the nav. Implementation:
Related
- Custom Theme (app-level) —
A2UITheme/additionalStyles - Core Concepts · Theme