Docs / Format spec
Components
The components block maps named UI components to their exact visual properties. Each entry gives AI agents and the CLI a precise, token-resolved style rule — no guessing required.
Component keys use kebab-case. The name should match the component as it exists in your codebase or design file — this makes it easy for agents to apply the right style to the right element.
Allowed properties
Property
Type
Example
backgroundColorcolor | ref
"#FFFFFF" or "{colors.surface}"
textColorcolor | ref
"#0A0A0A" or "{colors.primary}"
borderColorcolor | ref
"#E5E5E5" or "{colors.neutral-200}"
borderWidthstring
"1px", "2px"
roundedstring | ref
"8px" or "{rounded.md}"
paddingstring | ref
"12px 24px" or "{spacing.md}"
fontSizestring
"14px", "1rem"
fontWeightnumber
400, 500, 600, 700
boxShadowstring
"0 2px 8px rgba(0,0,0,0.08)"
opacitynumber
0.5, 0.8
Naming conventions
Use the pattern component-variant for variants, and plain component for the default style. Consistent naming is what lets agents understand when to apply which rule.
Pattern
Example keys
Default component
button, card, input, badge
Named variant
button-primary, button-ghost, button-danger
State variant
input-error, input-disabled
Size variant
button-sm, button-lg
Example: buttons
components:
button-primary:
backgroundColor: "{colors.primary}"
textColor: "#FFFFFF"
rounded: "{rounded.full}"
padding: "12px 24px"
fontWeight: 600
fontSize: "14px"
button-secondary:
backgroundColor: "{colors.surface}"
textColor: "{colors.primary}"
borderColor: "{colors.primary}"
borderWidth: "1px"
rounded: "{rounded.full}"
padding: "12px 24px"
fontWeight: 600
button-ghost:
backgroundColor: "transparent"
textColor: "{colors.primary}"
rounded: "{rounded.full}"
padding: "12px 24px"
fontWeight: 500
button-danger:
backgroundColor: "{colors.error}"
textColor: "#FFFFFF"
rounded: "{rounded.full}"
padding: "12px 24px"
fontWeight: 600Example: cards and surfaces
components:
card:
backgroundColor: "{colors.surface}"
borderColor: "{colors.neutral-200}"
borderWidth: "1px"
rounded: "{rounded.lg}"
padding: "{spacing.lg}"
card-elevated:
backgroundColor: "{colors.surface}"
rounded: "{rounded.xl}"
padding: "{spacing.lg}"
boxShadow: "0 4px 24px rgba(0, 0, 0, 0.08)"
badge:
backgroundColor: "{colors.neutral-100}"
textColor: "{colors.neutral-700}"
rounded: "{rounded.full}"
padding: "4px 10px"
fontSize: "12px"
fontWeight: 500
badge-accent:
backgroundColor: "{colors.accent-soft}"
textColor: "{colors.accent}"
rounded: "{rounded.full}"
padding: "4px 10px"
fontSize: "12px"
fontWeight: 500Example: form inputs
components:
input:
backgroundColor: "{colors.surface}"
textColor: "{colors.primary}"
borderColor: "{colors.neutral-300}"
borderWidth: "1px"
rounded: "{rounded.md}"
padding: "10px 14px"
fontSize: "14px"
input-error:
backgroundColor: "{colors.surface}"
textColor: "{colors.primary}"
borderColor: "{colors.error}"
borderWidth: "1px"
rounded: "{rounded.md}"
padding: "10px 14px"
fontSize: "14px"WCAG AA check: For any component with both
textColor and backgroundColor, the linter automatically computes the contrast ratio. Ratios below 4.5:1 (normal text) or 3:1 (large text / bold ≥18px) will fail the lint check.Using components in prose
You can reference component names in the markdown body to give agents additional context — for example, in your Components or Do’s and Don’ts sections:
## Components
Use button-primary for the single highest-emphasis action per screen.
Use button-ghost for secondary actions in the same view.
Never place two button-primary elements side by side.
## Do's and Don'ts
Do: use card-elevated for modals and overlays.
Don't: use card for floating elements — use card-elevated with boxShadow.