# Valid Component Token Properties in DESIGN.md: A Complete Guide to Variants and Hover States

> Learn valid component token properties in DESIGN.md including variants like hover states. Discover how to use literal values or token references for full design control.

- Repository: [Google Labs Code/design.md](https://github.com/google-labs-code/design.md)
- Tags: api-reference
- Published: 2026-07-03

---

**DESIGN.md supports eight valid component token properties—`backgroundColor`, `textColor`, `typography`, `rounded`, `padding`, `size`, `height`, and `width`—that accept either literal values or token references, while variants like hover states are defined using hyphenated suffixes (e.g., `button-primary-hover`) that override specific base properties while inheriting the rest.**

The [`google-labs-code/design.md`](https://github.com/google-labs-code/design.md/blob/main/google-labs-code/design.md) repository defines a strict schema for design tokens within its front-matter YAML. Understanding the valid component token properties in DESIGN.md and how variant states like hover or active are expressed is essential for building consistent, maintainable design systems that compile correctly through the CLI toolchain.

## Valid Component Token Properties

According to [`docs/spec.md`](https://github.com/google-labs-code/design.md/blob/main/docs/spec.md), the specification enforces a closed set of eight component-property tokens. Each property expects a specific type and may be expressed as a literal value or a reference to another token using curly brace syntax (e.g., `{colors.primary}`).

### The Eight Core Properties

The following table maps each valid property to its expected type and specification location:

| Property | Expected Type | Spec Reference |
|----------|---------------|----------------|
| `backgroundColor` | `<Color>` | [`docs/spec.md`](https://github.com/google-labs-code/design.md/blob/main/docs/spec.md#L22-L23) |
| `textColor` | `<Color>` | [`docs/spec.md`](https://github.com/google-labs-code/design.md/blob/main/docs/spec.md#L24-L25) |
| `typography` | `<Typography>` | [`docs/spec.md`](https://github.com/google-labs-code/design.md/blob/main/docs/spec.md#L26-L27) |
| `rounded` | `<Dimension>` | [`docs/spec.md`](https://github.com/google-labs-code/design.md/blob/main/docs/spec.md#L28-L29) |
| `padding` | `<Dimension>` | [`docs/spec.md`](https://github.com/google-labs-code/design.md/blob/main/docs/spec.md#L30-L31) |
| `size` | `<Dimension>` | [`docs/spec.md`](https://github.com/google-labs-code/design.md/blob/main/docs/spec.md#L32-L33) |
| `height` | `<Dimension>` | [`docs/spec.md`](https://github.com/google-labs-code/design.md/blob/main/docs/spec.md#L34-L35) |
| `width` | `<Dimension>` | [`docs/spec.md`](https://github.com/google-labs-code/design.md/blob/main/docs/spec.md#L36-L37) |

**Token references** allow values to reference global tokens defined elsewhere in the file, enabling single-source-of-truth updates across components.

## How Component Variants and Hover States Work

Variants in DESIGN.md follow a declarative inheritance model. Rather than defining state machines, you create separate component entries that override specific properties of a base component.

### Variant Naming Conventions

As documented in [`docs/spec.md`](https://github.com/google-labs-code/design.md/blob/main/docs/spec.md#L5-L6), variant keys append a state suffix to the base component name using hyphenation:

- `button-primary` (base)
- `button-primary-hover` (hover state)
- `button-primary-active` (active/pressed state)
- `button-primary-pressed` (alternative pressed state)

### Property Inheritance and Override Behavior

When the CLI exporter or consuming application resolves a component, it loads the base definition first, then overlays any matching variant properties. Unspecified properties in the variant automatically inherit from the base.

Consider this implementation from [`examples/totality-festival/DESIGN.md`](https://github.com/google-labs-code/design.md/blob/main/examples/totality-festival/DESIGN.md#L101-L110):

```yaml
components:
  button-primary:
    backgroundColor: "{colors.primary}"
    textColor: "{colors.on-primary}"
    typography: "{typography.label-md}"
    rounded: "{rounded.lg}"
    padding: 12px
    height: 48px

  button-primary-hover:
    backgroundColor: "{colors.primary-fixed}"

```

In this example, `button-primary-hover` only overrides `backgroundColor`. The consumer merges the maps, resulting in a component that retains the base typography, padding, and dimensions while swapping the background color to `{colors.primary-fixed}`.

## Practical Implementation Examples

### Defining Multi-State Components

Define comprehensive state coverage by chaining variant suffixes:

```yaml
components:
  button-primary:
    backgroundColor: "{colors.primary}"
    textColor: "{colors.on-primary}"
    typography: "{typography.label-md}"
    rounded: "{rounded.lg}"
    padding: 12px
    height: 48px

  button-primary-hover:
    backgroundColor: "{colors.primary-fixed}"

  button-primary-active:
    backgroundColor: "{colors.primary-80}"
    textColor: "{colors.on-primary-80}"

```

### Referencing Component Tokens

You can reference component properties within other components using dot notation:

```yaml
components:
  card-glass-level-2:
    backgroundColor: "rgba(52, 52, 58, 0.2)"
    rounded: "{rounded.xl}"
    padding: "{spacing.gutter}"
    typography: "{components.button-primary.typography}"

```

### Consuming Components via CLI

The parser in [`packages/cli/src/linter/spec-config.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/spec-config.ts) validates these structures during build. Access resolved components programmatically:

```typescript
import { parseDesign } from '@designmd/cli';

const design = await parseDesign('examples/totality-festival/DESIGN.md');
const btn = design.components['button-primary'];
const btnHover = design.components['button-primary-hover'];

// Merge base + hover (simplified resolution)
const hoverStyle = { ...btn, ...btnHover };
console.log(hoverStyle.backgroundColor); // → value of colors.primary-fixed

```

## Summary

- **Eight valid properties** define component tokens: `backgroundColor`, `textColor`, `typography`, `rounded`, `padding`, `size`, `height`, and `width`.
- **Values** may be literal (e.g., `12px`, `#ff0000`) or token references (e.g., `{colors.primary}`).
- **Variants** use hyphenated suffixes (`-hover`, `-active`, `-pressed`) appended to base component names.
- **Inheritance** works through map merging: variants override specific properties while inheriting unspecified ones from the base component.
- **Validation** occurs in [`packages/cli/src/linter/spec-config.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/spec-config.ts) against the schema defined in [`docs/spec.md`](https://github.com/google-labs-code/design.md/blob/main/docs/spec.md).

## Frequently Asked Questions

### What happens if a variant references a property not defined in the base component?

The variant simply adds that property to the resolved component. According to the [`docs/spec.md`](https://github.com/google-labs-code/design.md/blob/main/docs/spec.md) specification, variant maps may contain any subset of the eight valid component properties. If a property exists only in the variant, it becomes part of the final resolved style without requiring a base definition.

### Can I nest variant suffixes for complex states like hover-active?

The specification in [`docs/spec.md`](https://github.com/google-labs-code/design.md/blob/main/docs/spec.md#L5-L6) implies linear suffixes rather than nested combinations. For complex multi-state scenarios, define explicit combined keys such as `button-primary-hover-active` or rely on your consumer application to layer states programmatically. The DESIGN.md schema itself does not enforce hierarchical state inheritance beyond single-suffix variants.

### How does the CLI validate that my component properties are correct?

The linter in [`packages/cli/src/linter/spec-config.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/spec-config.ts) reads the canonical schema from [`docs/spec.md`](https://github.com/google-labs-code/design.md/blob/main/docs/spec.md) and validates component tokens during the build process. Tests in [`packages/cli/src/linter/spec-config.test.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/spec-config.test.ts) ensure that only the eight recognized properties are accepted and that token references resolve correctly. Invalid properties trigger linting errors before export.

### Are variant properties required to use the same value types as the base component?

Yes, type consistency is enforced. If `backgroundColor` expects a `<Color>` type in the base component, the variant's override must also resolve to a valid color value or reference. The schema validation ensures that overrides maintain type compatibility with the base property definitions.