You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The A2UI theming model works in layers: agents send semantic hints only (usageHint: "h1", button primary/borderless), the catalog maps hints to styled components and owns the theming solution (on the web: --a2ui-* CSS variables with minimal specificity), and the host/platform overrides those tokens.
a2tea is the catalog implementation for terminals, and it already has the right skeleton: render.Styles + DefaultStyles() + WithStyles (#31), monochrome by construction so the host theme wins. This epic completes that story so a host like crush can map its full semantic palette onto surfaces:
complete the style token set (per-component slots + chrome glyphs — the terminal analog of the web catalog's CSS variables)
honor more semantic hints from the basic catalog
support lossless live restyling for hosts with runtime theme switching
Two invariants are not changing:
DefaultStyles() stays monochrome — no color SGR in default output (pinned by render/styles_test.go)
The consuming side (crush mapping its quickstyle palette onto these tokens, A2UI-over-MCP) is tracked in the crush fork — see docs/proposals/a2ui-mcp.md there.
Tracking epic for the styling/theming work proposed in
docs/proposals/styling-layers.md.Context
The A2UI theming model works in layers: agents send semantic hints only (
usageHint: "h1", buttonprimary/borderless), the catalog maps hints to styled components and owns the theming solution (on the web:--a2ui-*CSS variables with minimal specificity), and the host/platform overrides those tokens.a2tea is the catalog implementation for terminals, and it already has the right skeleton:
render.Styles+DefaultStyles()+WithStyles(#31), monochrome by construction so the host theme wins. This epic completes that story so a host like crush can map its full semantic palette onto surfaces:Two invariants are not changing:
DefaultStyles()stays monochrome — no color SGR in default output (pinned byrender/styles_test.go)createSurface.themestays a no-op, matching the spec (even the reference web basic catalog ignores it; design is open upstream in Consider renamingthemeon createSurface toconfigurationand removeprimaryColorfrom basic catalog a2ui-project/a2ui#1118)Issues
Bug (ship first, independent):
variant: "obscured"renders the value in cleartext #55 — TextFieldobscuredrenders the value in cleartextCore (in order):
Stylesinto a complete token set (slots +Glyphs)Surface.SetStylesfor lossless live restylingHint upgrades (parallel after #56):
variant: "primary"a visual identity via ButtonPrimary slots #58 —Button primaryvisual identity viaButtonPrimaryslotsvariantsize hint (icon/avatar vs feature/header placeholders) #60 — honor Imagevariantsize hint in placeholdersDocs:
Standing:
createSurface.themepolicy; watch upstream Consider renamingthemeon createSurface toconfigurationand removeprimaryColorfrom basic catalog a2ui-project/a2ui#1118Sequencing
variant: "obscured"renders the value in cleartext #55 (bug fix, independent of everything else)variant: "primary"a visual identity via ButtonPrimary slots #58/Optional per-level heading styles (H1–H5) #59/Honor Imagevariantsize hint (icon/avatar vs feature/header placeholders) #60 (parallelizable after Expand render.Styles into a complete token set (component slots + Glyphs) #56)The consuming side (crush mapping its
quickstylepalette onto these tokens, A2UI-over-MCP) is tracked in the crush fork — seedocs/proposals/a2ui-mcp.mdthere.