Design system · v1.0
Facet
A design system for data-dense products. Thirty accessible components, live tokens, and its own light and dark themes, built from scratch.
- Accessible by default
- Token-driven
- Calm density
Ada Okafor
ada@facet.design
In use
The same primitives documented below, composed into one real screen. No mockups, this is the components running.
Team members
Manage who can access this workspace.
| Member | Role | Status |
|---|---|---|
AO Ada Okafor ada@facet.design | Admin | Active |
LM Leo Marsh leo@facet.design | Editor | Active |
PR Priya Raman priya@facet.design | Editor | Active |
SC Sam Cole sam@facet.design | Viewer | Invited |
No pending invitations
Invite a teammate and it will show up here.
Workspace settings would live here.
Color
Six ramps of eleven steps. Components never read raw hex; they read the semantic tokens below, which remap for light and dark.
Ink (brand)
50
faf9f7
100
f2f1ec
200
e6e4dd
300
d3d0c6
400
a8a498
500
7b7870
600
5b584f
700
43413a
800
2a2925
900
1a1916
950
0e0d0b
Bronze (signal)
50
faf6ec
100
f3e8cd
200
e7d3a0
300
d8bb74
400
c6a04e
500
ae863a
600
a07d36
700
7d612a
800
5a461f
900
3b2e15
950
241b0c
Success
50
ecfdf5
100
d1fae5
200
a7f3d0
300
6ee7b7
400
34d399
500
10b981
600
0f9d76
700
0b7a5c
800
0a6249
900
084c39
950
032b20
Warning
50
fdf8ec
100
faefcb
200
f5de93
300
f0c858
400
f0b530
500
d99b1c
600
b67b14
700
915e13
800
6f4816
900
4e3313
950
2b1a08
Danger
50
fdf2f1
100
fbe0de
200
f7c4c0
300
f19c95
400
f0736b
500
e0554c
600
c8443b
700
a5352e
800
832b26
900
631f1c
950
3a0f0d
Info
50
eff8fd
100
d8eefa
200
b0dcf4
300
7dc5eb
400
56b6e8
500
2f97cf
600
1f7fb5
700
1b6491
800
1b5375
900
164560
950
0e2c3e
--fc-bgPage background--fc-surfaceRaised surfaces, inputs--fc-fgPrimary text--fc-mutedSecondary text--fc-borderDividers, edges--fc-primaryBrand actions, focus--fc-successPositive status--fc-warningCaution status--fc-dangerDestructive, errors--fc-infoInformational statusTypography
One ramp, seven steps. Sizes in pixels, with line height, weight, and tracking fixed per step so text stays consistent across the system.
Display
32px / 1.1 / 600
Hero and page titles
Heading 1
24px / 1.2 / 600
Section titles
Heading 2
19px / 1.25 / 600
Sub-section titles
Heading 3
16px / 1.35 / 500
Card and group titles
Body
14px / 1.6 / 400
Default reading text
Small
13px / 1.55 / 400
Secondary text, help
Caption
12px / 1.5 / 400
Labels, meta, tags
Spacing
A 12-step scale in pixels. Every gap, padding, and margin snaps to a step, which keeps rhythm consistent without one-off values.
Radii
Five corner radii. Small for inputs and chips, medium for buttons and cards, large for surfaces, full for pills and avatars.
sm
6px
md
8px
lg
12px
xl
16px
full
9999px
Elevation
Four shadow tokens for lifting surfaces. Used sparingly: popovers use sm, dropdowns md, dialogs lg, and the highest layer xl.
shadow-sm
shadow-md
shadow-lg
shadow-xl
Motion
Three durations and one easing curve. Motion is functional, never decorative, and every transition is disabled under prefers-reduced-motion.
Iconography
A single-weight, 16px line set on a 16px grid. Icons are decorative by default (aria-hidden); when an icon is the only label, its control carries an aria-label.
Grid & breakpoints
A 12-column grid inside a 1240px max width, with a 24px gutter. Five breakpoints drive every responsive change.
sm640pxLarge phonemd768pxTabletlg1024pxLaptopxl1280pxDesktop2xl1536pxWideButtons & links
Five variants, three sizes, and every state. Real buttons: keyboard focusable, disabled and loading states expose aria-busy, focus rings meet contrast.
<Button variant="primary">Save changes</Button><Button size="sm|md|lg" /><Button loading /> · <Button disabled /><IconButton label="Search" /><Link external href="...">Docs</Link>Inputs & controls
Every control is labelled, keyboard operable, and states its errors with an icon and text, never color alone. Selection controls use roving tabindex, so each group is a single tab stop.
As it appears on your ID.
Enter a valid email address.
<Field label="Email"><Input /></Field>Markdown is supported.
<Field label="Notes"><Textarea /></Field><Select><option>…</option></Select>Start typing to filter the list.
<Combobox options={countries} /><Checkbox label="…" indeterminate /><RadioGroup options={plans} /><Switch checked={on} onChange={setOn} /><Slider value={v} onChange={setV} /><SegmentedControl options={views} />Alerts & status
Messages, live regions, and progress. Every status carries an icon and text, so meaning never rests on color. Tooltips answer to hover and keyboard. Motion respects reduced-motion.
Changes saved
Your profile is up to date. We synced it across every signed-in device.
Draft autosaved
We keep a copy as you type, so you can close this tab without losing work.
Storage almost full
You have used 92 percent of your plan. Archive old files to free up room.
Payment failed
We could not charge your card. Update your billing details to keep access.
<Alert tone="success" title="Saved">…</Alert><ToastDemo /><Tooltip label="Account"><button>…</button></Tooltip><Badge tone="success">Live</Badge><Tag onRemove={fn}>Design</Tag><Progress value={60} /> · <Progress indeterminate /><Skeleton className="h-4 w-40" />Dialogs & menus
Modal and non-modal layers built from scratch. Dialogs trap focus and lock scroll, Escape and outside clicks dismiss, and menus move focus with the arrow keys. No overlay library.
<Dialog open onClose={fn} title="Delete project" /><Drawer open onClose={fn} title="Settings" /><Popover trigger={<>Filters</>}>...</Popover><DropdownMenu label="Actions" items={items} />Tables & display
A sortable data table, cards, avatars, an accordion, and the small pieces that make dense screens legible. Sort state is announced through aria-sort, and every disclosure is keyboard operable.
AOAmara Okafor | Engineering | Active |
BCBen Carter | Design | Invited |
CWChen Wei | Product | Active |
DIDara Idris | Support | Suspended |
ERElena Ruiz | Design | Active |
FBFemi Bello | Engineering | Invited |
GLGrace Lin | Product | Active |
HAHassan Ali | Support | Active |
<Table columns={columns} rows={rows} sortable />Storage
Your team has used 48 GB of the 100 GB included on the current plan.
<Card title="Storage" footer={...} /><AvatarGroup max={4}>...</AvatarGroup><Accordion items={faqs} />No results
No members match that search. Try a different name or clear the filter.
<EmptyState title="No results" action={...} /><Kbd>⌘</Kbd><Kbd>K</Kbd>Accessibility
Not a claim, a property. Every pairing below is read live from the tokens, so it tracks the theme and can never drift. Every component is operable by keyboard alone.
Contrast, read live from the tokens
Body text
fg on bg
Secondary text
muted on bg
Text on surface
fg on surface
Primary button label
primary-fg on primary
Bronze signal
accent on bg · large/UI
Error text
danger on bg
Success indicator
success on bg · large/UI
Focus ring
ring on bg · large/UI
Keyboard
Reduced motion
Under prefers-reduced-motion, every transition and animation is reduced to near-zero. Nothing meaningful is conveyed by motion alone.
Color is never the only signal
Status always pairs a hue with an icon and text, like Error.