Design rules

Beaket UI is an Ink & Instrument design system — a printed page you can press. These rules explain why things look the way they do — and what to preserve when you customize.

No decoration

No gradients. No border-radius (except Radio). No blur shadows. No opacity for styling. If it's a border, show the border. If it's a shadow, make it structural.

Accent is state, not decoration

Accent is scarce. It marks what is happening now; it is not a permanent synonym for “interactive.” At rest, pressables rely on neutral material — an ink fill, border, label, or geometry — and carry no standing accent edge. Raised surfaces keep a quiet grey offset shadow.

State precedence

The highest-priority state wins within a visual channel:

PriorityStateVisual channel
1Keyboard focus2px outer outline on pressables; cap-off edge on writing fields. Invalid focus uses danger instead of accent.
2Open ownership / active engagementGrown offset edge on an overlay owner; 2px inset leading rule on the active menu row.
3Hover intentThin offset edge on edged pressables, or a neutral tint/text change where an edge would be too dense.
4Current selectionFaint lens fill and neutral rim, or ink fill plus position/indicator. Selection never borrows the focus outline.
5Persistent affordanceNeutral border, ink surface, label, and geometry only.
6Content navigationAccent text and hover underline for links; muted-to-ink text for breadcrumb ancestors.

Only spatially distinct channels may stack. An outer keyboard-focus outline may surround an open-owner offset edge or a selected fill. Competing marks in one channel do not stack: open replaces the hover edge, press drops the edge while the control translates, invalid focus replaces the accent focus color, and selection never adds a focus outline. Disabled controls remove interaction edges and focus treatment.

Dense state composition

This server-rendered specimen pins the same outer outline used by focus-visible around an open owner. Its grown offset edge remains visible, while navigation, tabs, the checkbox, and pagination keep their own selection fills or indicators. The cues coexist because they occupy different channels.

Keyboard focus + open owner
Neutral at rest
Selected option

Component families

Pressables

Edged buttons and interactive cards are neutral at idle. Hover reveals the thin shadow-offset-action edge; an open overlay owner holds the grown shadow-offset-action-hover edge. Press drops the edge and translates the control by 1px. Ghost and link buttons use tint or underline instead of an edge. Disabled controls use a dashed muted boundary and disabled surface/text, with no edge or focus treatment.

Writing fields and invalid state

Input and Textarea stay quiet at rest. Focus caps the field with a static action edge instead of an outer outline. Invalid focus replaces that accent edge with danger; it does not layer both colors. Read-only focus keeps the neutral surface shade. The caret uses accent and text selection uses the accent tint.

Native choices and lens controls

Checkbox, Switch, and Radio keep a neutral chassis. Hover may reveal a thin edge, while checked state uses ink fill plus a check, thumb position, or dot — never an accent focus look. Pagination holds the current key down with ink fill. Navigation and Tabs are fused lens controls: the current cell gets a faint accent lens and neutral rim, while the strip itself has no standing edge.

Menus and selects

A Select trigger is field-surfaced and quiet at idle and hover. While open it holds the grown edge; keyboard focus may still use the spatially separate outer outline. Menu and Select rows mark keyboard navigation with an accent tint and 2px inset leading rule. An open submenu holds that cue, destructive rows replace it with danger, and disabled rows cannot receive it.

Links and breadcrumbs

Ordinary links use accent text and reveal an underline on hover. Breadcrumb is a trail, not a switcher: ancestors stay muted and darken on hover, the current page uses full ink, and only keyboard focus introduces accent.

One pattern, everywhere

Semantic variant names

Prefer danger for a destructive action or error state in Button, Badge and Alert. Existing names remain supported aliases with identical styling. Alert keeps its GitHub callout vocabulary, icons and default titles; use a custom title when the application needs different wording.

ComponentCanonical roleExisting alias
Buttondangerdestructive
Badgedangererror
Alertdangercaution
Alertinfonote
Alertsuccesstip
Alertaccentimportant

warning is already shared, as are success on Button and Badge and info on Badge. Aliases do not introduce new color styles: not every component exposes all six token roles, and Button's neutral primary is not an accent fill.

Pressables share outline-2 outline-border-focus outline-offset-2 for keyboard focus; writing fields use the cap-off edge. Disabled controls share border-dashed border-border-muted bg-bg-disabled text-fg-disabled. Preserve the channel and precedence when composing or customizing components.

Own it, keep it right

You own the code after installation. Every component accepts className — customize freely. But preserve touch targets (44px+), keyboard navigation, and ARIA attributes. The invisible quality matters most.