Skip to content

Axes — tone · appearance · variant

Styling axes are named by what they mean, and every component reaches for the same names. That's what makes the API predictable: you never have to guess whether variant="danger" exists (it doesn't — color intent is always tone).

tone

Color intent

From the shared vocabulary neutral · brand · info · success · warning · danger · discovery (plus component-specific tones like Stat's positive/negative). Color intent is never expressed through an axis named variant.

<Badge tone="danger" />

appearance

Fill / surface treatment

How the color is applied to the surface: solid · soft · outline · ghost · subtle · framed, and friends.

<Alert tone="warning" appearance="soft" />

variant

Kind / structure

Reserved for structural axes — line|bar, arc|needle, dot|icon — that swap geometry, not color or fill. Two exceptions are sanctioned in the lint: Button's variant is its action-emphasis (fill) axis with color intent still on tone, and Tabs' variant (underline|pill|enclosed) swaps indicator geometry.

<Sparkline variant="bar" />

look

Bundled visual language

A lint-sanctioned Stepper-only one-off (filled | outline): a bundled indicator visual language, deliberately distinct from Badge-style fill appearance. No other component may declare a look axis.

<Stepper look="outline" />

tone × appearance, rendered

The same component (Badge) across every tone, under four appearances. Tone carries the intent; appearance carries the fill.

solid
neutralbrandinfosuccesswarningdanger
soft
neutralbrandinfosuccesswarningdanger
outline
neutralbrandinfosuccesswarningdanger
subtle
neutralbrandinfosuccesswarningdanger

Every enum axis also reflects to a matching data-<axis> attribute (data-tone, data-appearance, data-variant) so styling and testing can target semantics, not class soup. See it applied on any component page under Appearance browse the roster →

These names aren't a convention you can opt out of: a metadata lint fails the build if a color axis is called variant, or a fill axis is misnamed. The structural variant axes and the Stepper look one-off are individually allowlisted there — a new one requires a doctrine review, not just a new prop.