Molecules
Stable groups of atoms that do one local job.
Segmented control
Switches between two or three mutually exclusive modes in place.
Example markup
Usage
Keep labels short and of similar length. For four or more options, use a regular select.
Keyboard
A native radio group keeps arrow keys, focus and the announcement of the selected value.
| Root | .segmented |
|---|---|
| Control | input[type="radio"] inside label |
| States | checked, disabled |
Disclosure
Keeps secondary content one click away without a modal.
More details
The content sits in the normal flow and needs no extra script.
Example markup
Usage
Use it for help text and extra settings. Never hide a critical warning in a closed block.
Keyboard
Native details and summary respond to Enter and Space without JavaScript.
| Root | .disclosure |
|---|---|
| Content | .disclosure__body |
| State | open |
Field
Groups the label, control, hint and error into one vertical stack.
A short rule for filling it in.
Example markup
Error
On error, set aria-invalid="true" on the control and link the message with aria-describedby.
Hint
The hint explains the rule before the user types. An empty hint or error takes no space.
| Parts | .field__label, .field__hint, .field__error |
|---|---|
| State | aria-invalid, aria-describedby |
Radio group
One required choice from a short set of visible options.
Example markup
Usage
All options are visible at once. For a long set, use a select.
Keyboard
A shared name ties the group together. fieldset and legend give it an accessible name.
| Group | .check-group |
|---|---|
| Control | input[type="radio"] |
Breadcrumbs
Shows where the current page sits in a stable hierarchy.
Example markup
Usage
Use them only for real nesting. Navigation history needs a different pattern.
Accessibility
Give the navigation a name. The current level stays plain text with aria-current="page".
| Root | .breadcrumbs |
|---|---|
| Current | aria-current="page" |
Tabs
Switch between several equal panels in one context.
First panel content.
Second panel content.
Page sections · tabs--page
Deploys
All services, last 24 hours.
Summary across all services.
Services and their versions.
Deploy log for the period.
Example markup
Usage
Panels must be equal in rank. For sequential stages, use the Steps component.
Tabs that split the whole page into sections get .tabs--page and go right after .workspace-head. The strip runs edge to edge on the header fill with no line between them, and the first label lines up with the heading.
Keyboard
Arrow keys switch tabs, Home and End jump to the ends. Tab moves focus into the active panel.
| Root | .tabs, data-tabs |
|---|---|
| Roles | tablist, tab, tabpanel |
| Links | aria-controls, aria-labelledby |
| Variants | .tabs--page right after .workspace-head |
Pagination
Moves between pages of a large set and shows the current position.
Example markup
Usage
Keep filters and sorting when the page changes. A short set needs no pagination.
Accessibility
Give the navigation a name. The current link uses aria-current="page".
| Page | .pagination__page |
|---|---|
| Position | .pagination__status |
Steps
Position in a short linear process: done, current and upcoming.
- 01Setup
- 02Review
- 03Done
Example markup
Usage
Keep three to five stable stages. Detailed subtasks do not become separate steps.
Accessibility
The current item gets aria-current="step". Color alone never carries the state.
| Root | .steps |
|---|---|
| States | data-state="done| |
Code block
Local source code with a file label and a copy button.
<!-- Weekly summary -->
<section class="section" id="summary">
<h2>Week in review</h2>
<p data-count="12">12 tasks closed</p>
</section>/* Gap from the scale, 1 px border */
.summary { gap: var(--space-4); border: 1px solid var(--line); }Example markup
Usage
The label names the source. Do not use the monospace font for ordinary values and metadata.
Mechanics
The button points at the pre block with a selector in data-copy="#id". After copying, copy.js sets aria-pressed="true" and shows the second label in the same cell, so the button keeps its width.
code-highlight.js colors HTML, CSS, JavaScript, JSON and shell commands offline. Set the language with class="language-css" on code. Without it, the script guesses the language from the text.
| Root | .code-block |
|---|---|
| Button | .code-block__copy |
| Hook | data-copy="#id" |
| State | aria-pressed |
| Language | class="language-html", language-css, language-js, language-json, language-shell |
| Script | copy.js, code-highlight.js |
Notice
A message, warning or next step inside the current flow.
Example markup
Variants
OK, warning and error report a state. .notice--action replaces a separate accent callout.
Accessibility
Spell out the message type in words. An urgent error can get role="alert".
| Variants | .notice--ok, .notice--warn, .notice--error, .notice--action |
|---|---|
| Parts | __mark, __title, __actions |
Progress
Shows a known share of completed work, or just that work is still going.
Example markup
Usage
Repeat known progress as a number. The indeterminate mode never makes up a percentage.
Motion
The animation stops when reduced motion is on. The label still tells the state.
| Parts | __head, __track, __fill |
|---|---|
| Value | --value |
| Indeterminate | .progress--indeterminate |
Empty state
Explains why there is no result and which action can create one.
Example markup
Usage
Tell an empty set apart from a loading error. Show the action only when the user can change the state.
Accessibility
Do not move focus automatically after the area updates. Announce content that appears asynchronously through a live region.
| Root | .empty-state |
|---|---|
| Heading | direct child strong |