BridgeHandbookDraft
For agents
Menu
Draft

Interaction states

Hover, focus, pressed, disabled, loading and selected.

Every control's states

These states look the same across every component. A new component uses the same treatment, not its own.

StateWhat it looks likeHow
HoverFills darken a step; quiet controls gain a light fill; links underline.-hover tokens, --surface-tertiary, 150ms color transition
Focus (keyboard)A 2px ring with a 2px gap, blue (red on danger controls). Mouse clicks draw nothing.focus-visible:ring-2 ring-offset-2
PressedShrinks to 98% while held.active:scale-[0.98]
Active / onA filled background on a toggle or chip; the label stays readable.--surface-tertiary with --text-primary, aria-pressed
Disabled30% opacity, no pointer. Say why nearby when you can.disabled:opacity-30
Loading (action running)A spinner in the control; it can't be pressed again.loading prop, aria-busy
Not ready (data loading)A skeleton of the same size and shape.ButtonSkeleton, row and cell skeletons
ErrorRed border or text plus a message that says what to do.--error, --danger-text, aria-invalid

Loading, empty and error

A card never disappears because its data is missing. Loading, failed and empty are three bodies inside the same card frame (icon, title, hint stay put), and a failure offers Retry. Content that arrives late never pushes other content down: its space is reserved from the first paint by a skeleton of the same height. The full pattern is on Loading, empty and error. A selected row is tinted (see Selection and bulk actions).

Rules

The frame stays

A card never disappears because its data is missing. Loading, empty and failed are three bodies inside the same frame (icon, title and hint stay put), and a failure offers Try again. Returning null on error deletes the feature from the page: the person can't tell broken from empty.

Focus always shows

Every control shows a visible ring when reached by keyboard (focus-visible). Never remove an outline without drawing a ring in its place.

Known gaps

Where Bridge OS code differs from this page today. Follow the page, not the gap.

  • Bridge OS still has about 300 hand-made buttons, each with its own hover and disabled look, until they move to Button.

Sources

  • Bridge OS components.md → Button (states, loading vs ButtonSkeleton), FilterChip, ConfirmDialog (busy).
  • Bridge OS DESIGN.md → principles 6 and 7 (cards keep their frame; no layout shift).
  • Package button.tsx (the states as built).