UI/UX

The principles every screen follows, the spacing and layout it sits on, and live examples of the @workspace/ui components. Toggle the theme in the header to check both modes.

Experience

People running a business use the product all day. It has to respond at once, never lose their work and behave the same way every time.

Principles

What every screen should do, whatever it shows.

Instant
A change shows the moment someone makes it, and the server catches up (optimistic updates). While something loads, show a skeleton of what's coming, never a blank page.
Never lose work
Editors autosave about a second after the last keystroke and say so. Nothing a person typed disappears because they navigated away.
One way to do each thing
An action works the same from a button, the command palette or a shortcut, because they all run the same operation. Learn it once.
Keyboard as well as pointer
⌘K reaches anything, and D switches theme. Every control is reachable by Tab, with a visible focus ring.
Say what happened
An error appears next to what caused it and says how to fix it. The change itself shows success. Add a toast only when the result is off-screen.
Shareable state
Open dialogs, tabs and filters live in the URL, so a link lands a colleague exactly where you are.

Patterns

Moments that come up again and again, handled the same way everywhere.

MomentDo thisWhy
Loading a viewA skeleton shaped like the contentThe layout doesn't jump when data lands.
Saving a changeApply it at once. If the server refuses, roll it back and show a toastNobody waits on the network after every edit.
Editing long textAutosave with a quiet saving/saved statusNo save button to forget.
DeletingConfirm with the item's name and "This can't be undone."A deliberate pause only where a mistake is permanent.
An empty listSay what will be here and offer the first stepSomeone looking at an empty list needs to know how to start.
A form errorInline, under the field, once it's been leftThe fix is next to the problem.

Accessibility

WCAG 2.2 AA, checked in both themes. It's the minimum, not a feature.

Do
  • Keep body text at 4.5:1 contrast and UI boundaries at 3:1.
  • Label every control, and give icon-only buttons an aria-label.
  • Keep focus visible, and return it where it was when a dialog closes.
  • Honour reduced motion, and make targets at least 24px.
Don't
  • Use colour alone to carry meaning.
  • Hide essential information in tooltips or on hover.
  • Trap focus outside dialogs, or remove outlines without a replacement.

Foundations

Tailwind's scale, kept small: five gaps, one radius family, five breakpoints.

Spacing

Reach for gap-4 first. Space with gap on the parent, not margins on children.

  • gap-1.50.375remLabel to input, icon to text
  • gap-30.75remTight groups: toolbar buttons, chips
  • gap-41remThe default: grids, cards, form fields
  • gap-82remRelated blocks within a section
  • gap-164remBetween the sections of a page
Do
  • Use the Tailwind scale, and these five steps before any other.
  • Design at 375px first. Nothing may scroll sideways on a phone.
Don't
  • Arbitrary values like p-[13px] to nudge something into place.
  • Nest max-width containers, or pad a card's children instead of the card.

Radii

Every radius is a multiple of --radius (0.45rem). Buttons and badges use rounded-2xl. Cards and dialogs go up to 24px.

rounded-sm4.3px
rounded-md5.8px
rounded-lg7.2px
rounded-xl10.1px
rounded-2xl13.0px
rounded-3xl15.8px
rounded-4xl18.7px

Breakpoints

Tailwind's defaults, mobile first: unprefixed classes are the phone layout.

PrefixFromWhat changes
None< 640pxOne column. Actions go full width.
sm640pxTwo-column grids.
md768pxPage padding grows, and the app sidebar stops being a sheet (useIsMobile).
lg1024pxThree columns. Secondary panels, like this table of contents, appear.
xl1280pxContent stops growing at max-w-screen-xl.

Page structure

The classes these guideline pages use.

RoleClasses
Page widthmx-auto w-full max-w-screen-xl
Reading widthmax-w-2xl (prose, descriptions)
Page paddingpx-4 py-8 md:px-8 md:py-12
Sectionsflex flex-col gap-16
Card gridsgrid gap-4 sm:grid-cols-2 lg:grid-cols-3

Actions

Everything a person presses. One primary action per view.

Button

Default (orange) for the one primary action. Outline or secondary for the rest, ghost in toolbars, and destructive only for what can't be undone.

Button sizes

Default (h-8) almost everywhere. Use sm and xs in dense rows, and lg only for a lone call to action.

Badge

Short status and counts. Secondary or outline by default, so the orange stays for what needs attention.

NewDraftProposal sentOverdue12

Button group

Related actions joined into one control.

Toggle group and segmented control

Toggle groups for formatting and multi-select. To switch between views, use the segmented control and nothing else.

Forms

React Hook Form and Zod do the work underneath. These are the controls on top.

Field and input

Every input sits in a Field with a label. Errors appear under their own field, never in a list at the bottom of the form.

As it should appear on proposals.

Input group

An input with an icon, prefix or unit attached.

%

Select and textarea

Select for one of a known list. Textarea for anything longer than a line.

Checkbox, radio, switch and slider

Checkboxes for independent options, radios for one of a few, switches for settings that apply at once.

Layout

The containers that hold content.

Card

Frosted glass with the orange top rule. Title in serif, description muted, actions in the footer.

Brand refresh
Northwind · due 14 March
x
7 of 11 tasks done
Pipeline value
£48,200

+12%vs last month

Tabs

Different views of the same thing. Keep labels to one or two words. Default (pill) tabs switch views inside a card or panel. Line tabs head a whole page or dialog, as in settings.

Default
The project at a glance.
Line
The project at a glance.

Accordion

Secondary detail a reader may not need. Never hide what they must read.

Item

A row in a list: media, title, description and actions.

Team

4 members, 1 pending invitation

SAR

Marketing

What the marketing site's sections are built from.

Section header

The words that open a section: eyebrow, heading, lead, then one or two actions. Every part is optional. The heading's size and its level in the page outline are set apart.

Planning

Plan the week in minutes

See every project's next step in one place, and move it with a drag.

Centred, and a size smaller

Drawn at heading 3, still an h2 in the outline.

Bento grid

Cards in mixed sizes. One column on a phone, two from 640px, three from 1024px. Small cards fill the gaps, so keep each card independent of its neighbours.

Mission Control
Large: two columns and two rows. The one thing the section is about.
Tasks
Default: one cell.
Chat
Default: one cell.
Planner
Wide: two columns, for something that reads across.
Proposals
Tall: two rows, for something that reads down.
Contacts
Default: one cell.

Media frame

The box every image, video and embed sits in. A fixed shape crops the media to cover it; original keeps the media's own shape.

Landscape, 16:9
Square, 1:1
Portrait, 4:5

Section backdrop

Brand artwork behind a section a page is built around (the hero, the pricing plans, the closing call to action): the glow, the dot field from Brain Space, or the dot-matrix Earth or Moon from Mission Control. Never on adjacent sections, and never two in view at once.

Glow

Dot field

Earth

Moon

Feedback

How the app tells people what's happening.

Alert

Inline, persistent messages about the thing in front of the reader. Always an icon, a title and what to do.

Toast

A short-lived confirmation of something that happened off-screen, or a failure. Name the thing and keep it to one sentence.

Skeleton and spinner

Skeletons, shaped like what's coming, for views and sections. A spinner only inside a button or inline, for an action in progress.

x

Empty

An empty list says what will be here and offers the first step.

No projects yet
Projects collect the tasks, files and notes for a piece of work.

Tooltip

Names an icon-only control. Never the only place information lives.

Copyright 2026 53 Degrees App LTD. Company number: 16727854. All rights reserved. Made with ♥ in Yorkshire 53.8008°N, 1.5491°W