Nova v2.1

Tandem · Internal design system · maintained in the open

Nova is why Tandem
feels like one product.

v2.1 Shipped June 12, 2026 — motion tokens, dark elevation ramp, retuned danger scale.

I keep this page honest so design reviews can be short. Everything below is rendered from the tokens it documents — if the page looks right, the system is right.

01

Calm by default. The canvas stays neutral so color, when it appears, means something.

02

Tokens over taste. Every value on this page has a name; if it has a name, it ships.

03

Two themes, one source. Light and dark render from the same tokens — never forked.

01 · Color

Ten steps of iris, tuned by hand

Neutrals do the layout, primary is for action, semantic color is for meaning — never the other way around. Click any swatch to copy its hex.

primary / iris — buttons, links, focus rings. Text sits on 600+.

neutral / warm gray — canvas, borders, text. 50 is the page you’re reading.

semantic — status only. If it isn’t a state, it doesn’t get a semantic color.


02 · Typography

Inter for the interface, JetBrains Mono for anything you might paste

Eight stops, 16px root. Sizes come from the scale — if you think you need 22px, you actually need 20 or 24.

type/display56px · 3.5rem · lh 62px
weight 800 · ls −0.028em
Count what matters
type/h140px · 2.5rem · lh 46px
weight 700 · ls −0.022em
Weekly digest, rebuilt
type/h230px · 1.875rem · lh 38px
weight 700 · ls −0.018em
Invite your first teammate
type/h324px · 1.5rem · lh 32px
weight 600 · ls −0.012em
Notifications that respect focus
type/h420px · 1.25rem · lh 28px
weight 600 · ls −0.008em
Connected calendars sync every 15 minutes
type/body16px · 1rem · lh 26px
weight 400
Tandem puts every meeting, doc, and decision on one shared timeline, so nobody spends Monday reconstructing what happened on Friday. Body copy stays at 16 — smaller sizes are for metadata, not paragraphs.
type/caption13px · 0.8125rem · lh 18px
weight 500
Last synced 4 minutes ago · 3 calendars connected
type/code13.5px · 0.84375rem · lh 22px
weight 400 · JetBrains Mono
tandem sync --workspace tandem-hq --since 2026-06-12

03 · Spacing

A 4px grid, eight steps, zero exceptions

Steps, not opinions: if a gap isn’t on the scale, it’s a bug. Component padding lives at 2–4; section rhythm lives at 8–16.


04 · Components

Every component, both themes, one source

The two panes below render identical markup against the light and dark token sets. The toggle and tabs work — try them. Nothing here is hard-coded to a theme.


05 · Elevation

Four levels of lift

Shadow encodes hierarchy, not decoration. If you’re reaching for a fifth level, you want a new page — not a bigger shadow.

shadow/1

Resting cards, table rows on hover

0 1px 2px rgba(27,26,24,.06)
shadow/2

Dropdowns, popovers, pickers

0 2px 6px ·07 + 0 1px 2px ·05
shadow/3

Command palette, floating panels

0 6px 16px ·09 + 0 2px 5px ·05
shadow/4

Modals, full-screen takeovers

0 16px 40px ·14 + 0 4px 10px ·06

06 · Radius

Rounder means more interactive

Radius scales with the size of the surface: tight on controls, generous on containers, full on anything pill-shaped.

radius/sm

4px

Checkboxes, chips

radius/md

8px

Buttons, inputs

radius/lg

14px

Cards, panes

radius/xl

24px

Sheets, dialogs

radius/full

999px · shown at 64

Pills, avatars, switches


07 · Usage

Four calls we’ve already made

The fastest design reviews are the ones we never have. These come up every quarter, so they’re rules now.

Do
Save changesCancel

One primary action per view. Everything else is secondary or ghost — the eye should never have to choose between two loud buttons.

Don’t
SaveExportShare

Three primaries is zero primaries. When everything shouts, the actual next step disappears.

Do
Payment failedSynced

Status speaks semantic. Failure is danger, success is success — status color comes from the semantic set, always.

Don’t
Payment failedSynced

Brand-colored status reads as decoration. A failed payment in cheerful iris is a support ticket waiting to happen.

Do
Work emailname@company.com

Labels live above the field. The placeholder shows the format; the label survives after you start typing.

Don’t
Work email

Placeholder-as-label vanishes on first keystroke — and takes the user’s memory of the question with it.

Do

Rhythm from the scale. 8 inside a group, 24 between groups — related things sit close, unrelated things visibly apart.

Don’t

Off-scale gaps (5, 11, 15, 17…) destroy grouping — the heading floats between sections and belongs to neither.


08 · Motion

Motion is feedback, not decoration

Three durations, three curves — new in v2.1. Hover (or tap) a token to feel it on the dot.

Rule of thumb: anything under your cursor gets duration/fast; anything that moves other content gets duration/slow with ease/exit. With prefers-reduced-motion, all of these collapse to an instant cut — the page you’re reading does the same.