Summary
Add a {component}.css emitter to specs-cli that projects a validated component contract into a CSS file with one class per anatomy element, custom properties mapped from token paths, and [data-variant=...] / [data-state=...] selectors for every variant configuration.
RFC
This emitter is specified in RFC 001: Component Dictionary — emitter group styling, priority high, complexity medium.
One class per anatomy element, custom properties from token paths, [data-state=...] selectors per variant. Lossless for the deterministic ruleset.
Sketch
rfc/001-component-dictionary/sketches/button.css
The sketch shows:
- Root element class with custom properties aliasing token vars (
--bg, --fg, --border, etc.)
- Base layout rules (display, gap, padding, color, border-radius)
[data-variant=...] attribute selectors overriding custom properties per variant
[data-state=...] selectors for interactive states (hover, pressed, disabled)
- Per-slot element classes sized from anatomy dimensions
Identifier casing reuses config.format.keys; per-emitter keys override is available (CSS forces kebab regardless of root config). See cli-reference.md for the options.css.keys config field.
Acceptance criteria
Summary
Add a
{component}.cssemitter tospecs-clithat projects a validated component contract into a CSS file with one class per anatomy element, custom properties mapped from token paths, and[data-variant=...]/[data-state=...]selectors for every variant configuration.RFC
This emitter is specified in RFC 001: Component Dictionary — emitter group
styling, priority high, complexity medium.Sketch
rfc/001-component-dictionary/sketches/button.cssThe sketch shows:
--bg,--fg,--border, etc.)[data-variant=...]attribute selectors overriding custom properties per variant[data-state=...]selectors for interactive states (hover, pressed, disabled)Identifier casing reuses
config.format.keys; per-emitterkeysoverride is available (CSS forces kebab regardless of root config). Seecli-reference.mdfor theoptions.css.keysconfig field.Acceptance criteria
stylinggroup[data-variant=...]selectors for each prop value that modifies styling[data-state=...]selectors for interactive statesconfig.format.keys(default kebab for CSS)