Skip to content
.mdDesign.md Store

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
backgroundColor
color | ref
"#FFFFFF" or "{colors.surface}"
textColor
color | ref
"#0A0A0A" or "{colors.primary}"
borderColor
color | ref
"#E5E5E5" or "{colors.neutral-200}"
borderWidth
string
"1px", "2px"
rounded
string | ref
"8px" or "{rounded.md}"
padding
string | ref
"12px 24px" or "{spacing.md}"
fontSize
string
"14px", "1rem"
fontWeight
number
400, 500, 600, 700
boxShadow
string
"0 2px 8px rgba(0,0,0,0.08)"
opacity
number
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: 600

Example: 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: 500

Example: 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.