Form controls
Fields sit a hair below the page: white, a strong edge, and a recessed inset. Every field looks the same whether you type, choose or search, and every one is 40px tall.
Input
A single line of text. Use Field for its label, hint and error.
| Part | Tokens | Notes |
|---|---|---|
| Height | 40px · h-5 | Matches a default button, so toolbars line up. |
| Edge | border-border-strong | #8A919C, 3:1 against white. |
| Depth | bg-raised · inset-shadow-recessed | A hair below the page. |
| Hover | border-muted-foreground | The edge darkens; nothing moves. |
| Focus | border-ring · ring-[3px] ring-ring/25 | A cyan edge and a soft halo instead of an outline. |
| Invalid | aria-invalid · border-destructive | Pair it with an error message in Field. |
Textarea
Several lines: notes on a detail, a description. It grows with its text from 80px.
| Part | Tokens | Notes |
|---|---|---|
| Height | min-h-10 · field-sizing-content | 80px, then grows. |
| Look | Same as Input | Edge, inset, focus and invalid are shared. |
NativeSelect
A short list of known choices, like a discipline or a project. The browser’s own menu keeps it fast and accessible on every device.
| Part | Tokens | Notes |
|---|---|---|
| Chevron | CaretDown · 16px | Right inset 16px; the text stops before it. |
| Look | Same as Input | One field look for every field. |
SearchField
A field with a magnifier that filters what is on the page. SearchTrigger looks like one but opens the command palette, and shows its shortcut.
| Part | Tokens | Notes |
|---|---|---|
| Icon | MagnifyingGlass · 16px | Inside the left padding. |
| Clear | Esc or the clear button | Appears once there is text. |
| Kbd | h-3 · rounded · border-border | The shortcut, in the system’s own words: Ctrl K or ⌘K. |
Field
The frame around a control: label above, the control, then a hint or an error. The error replaces the hint, in the same place.
| Part | Tokens | Notes |
|---|---|---|
| Label | text-sm font-medium | Sentence case, no colon. |
| Hint | 13/16 · text-muted-foreground | The format or the consequence. |
| Error | 13/16 · text-danger-foreground | Say what to type, not that it was wrong. |
| Gap | gap-1 · 8px | Between label, control and message. |
Switch
An on/off setting that takes effect at once, like approving a detail for use. If the change needs a save button, use a checkbox in a form instead.
| Part | Tokens | Notes |
|---|---|---|
| Track | 24 × 40 · rounded-full | Off bg-border-strong, on bg-primary. |
| Thumb | 16px · bg-raised · shadow-edge | A raised part on the track, 4px from each end. |
| Label | Beside the track | Name the setting, not the state. |
SegmentedControl
Two to four mutually exclusive views of the same list, like All, In review and Approved. The track is recessed; the selected segment is raised.
| Part | Tokens | Notes |
|---|---|---|
| Track | h-5 · bg-muted · inset-shadow-recessed | A 1px border and a 3px inset, so 32px items sit centred. |
| Selected | bg-raised · shadow-edge · ring-edge | Raised on the track; ink text. |
| Others | text-muted-foreground | Ink on hover. |
RadioGroup
One choice from a few, each with enough to say that it needs a row. RadioCard is the whole row as the target: an ink edge and a pressed inset when chosen.
| Part | Tokens | Notes |
|---|---|---|
| Radio | 16px · rounded-full · border-border-strong | Checked: an ink dot. |
| RadioCard | rounded · border-border · bg-raised · p-2 | Hover border-input; checked border-foreground and inset-shadow-selected. |