The rules behindevery screen.
Relay looks like a terminal on purpose. This is the system that keeps it consistent: what each token is for, how it moves, what it does for accessibility and where it still falls short. Everything below is rendered with the real components and tokens.
01
Principles
- 01
Data is typography.
Numbers, ids, timestamps and error text are set in mono. Prose and headings stay in sans. The two faces do different jobs, so a reader can tell data from explanation at a glance. see it
- 02
Two signals for every state.
Healthy, syncing, failed and never-synced each have an icon and a word as well as a colour. Nothing depends on telling red from green. see it
- 03
One accent, kept for the next action.
Terracotta marks what to press or where you are: the primary button, the active tab, the caret. It is never decoration, so it stays rare enough to mean something. see it
- 04
Detail on demand.
Tooltips, drawers and modals hold what most people don't need most of the time. The page stays quiet, and the long error is one click away instead of truncated in a row. see it
- 05
Motion explains.
Things move to show where they came from or where they went. A drawer slides from the edge it lives on. Nothing bounces to fill silence. see it
02
Colour
Warm neutrals and a single terracotta accent, dark first. Dark is the designed identity. Light is a functional fallback for a light system preference. Elevation is a lighter surface plus a hairline border, never a shadow or a blur.
| Live | Token | Role | Dark | Light |
|---|---|---|---|---|
| background | Page ground | #141210 | #faf7f2 | |
| surface | Cards, windows, header. One step lighter than the ground | #1c1916 | #ffffff | |
| foreground | Body text and strong UI | #f2ede7 | #1c1712 | |
| muted | Secondary text, labels, icons | #948b81 | #7a6f63 | |
| accent | The next action, and where you are | #d97757 | #c2410c | |
| accent-foreground | Text on accent fills | #141210 | #faf7f2 | |
| success | Healthy, answered | #4ade80 | #15803d | |
| danger | Error, refused, destructive | #f87171 | #b91c1c |
border is the foreground colour at 10% opacity in both themes, so hairlines follow the theme instead of being a fixed grey.
| Pair | Dark | Light |
|---|---|---|
| foreground on background | 16.06:1 AA | 16.64:1 AA |
| muted on background | 5.58:1 AA | 4.59:1 AA |
| muted on surface | 5.22:1 AA | 4.90:1 AA |
| accent on background | 5.99:1 AA | 4.85:1 AA |
| accent-foreground on accent | 5.99:1 AA | 4.85:1 AA |
| success on background | 10.72:1 AA | 4.69:1 AA |
| danger on background | 6.76:1 AA | 6.05:1 AA |
03
Type
Two families and no more. Geist Sans for prose, headings and UI labels. JetBrains Mono for data and meta labels. Display sizes get tight tracking. Uppercase labels get loose tracking.
Aa
Geist Sans · 400 500 600
Aa
JetBrains Mono · 400 500 600
Display
clamp 2.5–8.5rem · 600 · −0.04em · sans
Cited answers
Heading
1.9–3.5rem · 600 · −0.035em · sans
Staying up to date
Body
16px · 400 · 1.625 leading · 62–66ch · sans
Relay reads your Drive, Gmail, Calendar and Sheets, then answers with a link to the exact passage.
UI label
12–14px · 500 · sans
Sync Gmail now
Data
12–14px · 400–600 · mono · tabular figures
6,267ms 0.412 9/21/2026, 8:50 AM
Meta label
11–12px · uppercase · +0.08–0.12em · mono
Per-surface sync lag
04
Shape & space
Everything has a 4px radius, with 2px for very small parts like checkboxes. Circles are reserved for status dots. Spacing runs on a 4px grid: tight inside an app screen, generous on the public site, with vertical gaps that vary by how related two sections are instead of repeating one number.
4px · rounded
Cards, buttons, inputs, windows
2px · rounded-sm
Checkboxes, chart parts, tiny controls
full · rounded-full
Status dots and window dots only
elevation without shadows
background
surface
hover / selected · foreground at 5%
05
Components
These are the real components from the app, not screenshots. Toggle, hover and open them.
- use
- One primary per view. Name the action: Sync Gmail now, not Submit.
- avoid
- Two accent buttons side by side. A destructive action styled as primary.
- use
- Immediate state changes, like auto-sync. It states its own value in text.
- avoid
- A pill switch with only colour and position to say on or off.
- use
- Every state gets an icon and a word as well as a colour.
- avoid
- A bare red or green dot that means nothing to a colour-blind reader.
- use
- Tooltips for secondary detail only. Chips for things you can open.
- avoid
- Putting the one thing people must read inside a tooltip.
- use
- Modal to confirm or warn. Drawer for one item's detail or a small workflow.
- avoid
- A modal that hides information people need to compare.
- use
- A visible border and a prompt glyph, so it reads as a place to type.
- avoid
- A borderless field that relies on placeholder text alone.
Query volume
18%167
06
Motion
Animate transform and opacity only, since those run on the compositor and never trigger layout. Enter slower than you exit. Never linear, except a blinking caret and a spinner. Everything obeys prefers-reduced-motion.
Same distance, same 1.2 seconds. Linear starts and stops like a machine. cubic-bezier(0.16, 1, 0.3, 1) leaves fast and settles slowly, which is how things with weight move.
Lists arrive one after another so the eye can follow. Past about 80ms per item it starts to feel slow. Under 30ms it reads as a single block.
click the track
Springs for things you move yourself: the nav underline (stiffness 500, damping 40) and the drawer (380, 38). Critically damped, so nothing wobbles.
| What | Timing | Animates | Why |
|---|---|---|---|
| Tooltip in | 120ms | opacity + 4px | Fast: it answers a hover |
| Hover lift | 150–200ms | translateY(−1px) | A hint of pressability, not a jump |
| Message enter | 180ms | opacity + 6px | Ease-out, so the reply arrives and stays |
| Drawer | spring 380/38 | translateX from the edge | Slides from where it lives |
| Nav indicator | spring 500/40 | layout, shared element | Follows you between tabs |
| Section reveal | 600–750ms | opacity + 14px, or a masked line | Only on the public site |
| List stagger | 30–60ms/item | same as the item | Long enough to follow, short enough to finish |
07
Accessibility
What is in place, and, listed just as plainly, what isn't yet.
in place
- Focus is always visible: the browser outline by default, an accent ring or border on custom controls
- Icon-only buttons carry an aria-label
- Switch, checkbox and dialog roles, with Esc closing overlays
- Nav uses aria-current for the active page
- Status is never colour alone: icon plus word
- prefers-reduced-motion respected in JavaScript and CSS
- On the public site: landmarks, a skip link, and captioned tables with row and column headers
- Text contrast measured above, both themes
known gaps
- Modal and Drawer close on Esc and backdrop click but do not trap focus or return it to the trigger
- Some dense controls are under 44px: the send button is 40px, citation chips about 28px
- Charts have hover tooltips but no text alternative such as a data table
- Native date inputs keep the browser's own styling and picker
- 11px mono labels pass contrast but are small
08
Voice
Say what happened and what to do next. Name the action on the button. Sentence case for prose, lowercase mono for data labels. Skip the words that could be on any product page.
Error 500
Gmail is rate-limited. Wait a minute and sync again.
Submit
Sync Gmail now
Unlock seamless insights
Ask a question, get a cited answer
Oops! Something went wrong
Nothing in your sources supports an answer, so Relay won't guess.