Skip to content
Design system

One language.

Foundations, components, and the way they move.

1

Foundations

Color

Ink for structure. Blue responds. Steel holds state.

NeutralSurface · text · line
SteelState · evidence · fill
LunetraResponds · links only

Type

Eleven roles. Optima for voice, Geist for the rest. Caps only in eyebrow and label.

display60One language.
chapter36Section heading
cardTitle24Card headline
voice24An editorial moment
lead18The line under a headline
body16Reading copy, capped at 68ch
blockTitle16Sub-head in a block
eyebrow13Selected work
meta13Lead designer · 2025
label12Design challenge
chip13Proof chip

Layout

Whitespace is the hierarchy.

8xs
16sm
24related
32eyebrow
48content
64block
96hero-meta
120section

Shape

Radius is materiality. Tone before shadow before line.

Chip4px
Control · card8px
Media (max)12px
Statuspill
restshadow
raisedshadow
floatingshadow
hairline1px

Motion

Only when it names a moment.

  • --duration-instant100ms · opacity snap, icon nudge
  • --duration-fast200ms · hover, arrow reveal, color
  • --duration-base300ms · crossfade, collapsible
  • --duration-slow550ms · scroll entrance only
Default--ease-out-soft
Entrance--ease-apple
Spring (rare)--ease-spring
2

Components

Actions

One primary per view. All 8px.

PrimaryctaPrimary
SecondaryctaSecondary
Disabled:disabled
TertiaryctaTertiary
ExternalCtaGhostLink

Read the case study.

InlinectaInline

Labels

Plain text marks. Chips are evidence.

Selected work
Eyebrowroles.eyebrow
~25% faster onboardingReusable AI system
Proofroles.chip
ShippedDraft
Statuspill

Surfaces

Tone and spacing, not borders.

Defaultraised
Accentn-100
Highlightsteel sweep
Darkn-950

Loading

Hold the shape of what is coming.

SkeletonSkeleton
Carousel arrowCarouselArrow
3

Interaction

Language

Four motions, repeated everywhere.

Line · A line grows to mark where you are.Nav rulerCase outlineInline linkSection tick
Sweep · Fill travels toward where you're going.PaginationNav link gradientHighlight card
Press · Things give a little when pressed.ButtonsRail arrowsCards
Unblur · New content settles in, never pops.Streamed wordsCrossfadesNotices

Principles

Every microinteraction has four parts.

  1. 01TriggerRespond on press, not release.
  2. 02RulesInterruptible. Start from where it is.
  3. 03FeedbackTransform + opacity. Under 300ms.
  4. 04LoopsExit faster than enter. Reduced motion settles.

Feedback

The interface answers the moment you act.

Press · Press to tryscale 0.98 · on pointer-down
Arrow nudge · HovertranslateX · gradient · 200ms
Focus · Tab2px ring · offset 2 · steel

Tokens start in .

Hover card · Try it: hover220ms delay · dismissible
Something on my end dropped that.

 

Retry · Clickin voice · one retry
Rail arrows · Clickscale 0.96 · disabled at ends

Disclosure

Quiet by default. Detail on request.

Expand · Clickheight + opacity · reduced motion = instant
4

AI

Rules

Calm about uncertainty.

  1. Thinking ≠ frozenRetry after 20s
  2. Words, not charactersAnnounce once
  3. Footing in wordsNever a percentage
  4. Unsure ≠ brokenOne quiet retry
  5. Acts when askedHuman checkpoint

States

Thinking, answering, unsure, broken.

I start with the decision someone has to make, then design the fewest states that get them there.

3 · settled
Lifecycle · Replayword unblur 150ms · aria-live once
Trust · Opengrounded · considered · tentative
This is taking longer than usual on my end.

 

I have got this switched off at the moment, so it cannot answer right now.

 

Stalled · Click20s silence · in voice
Something on my end dropped that.

 

Error · Clickrequest broke · one retry

Gaps

Needed, not shipped.

  • No grounded answer
  • Stop mid-stream
  • Partial-stream failure
  • Out of scope
  • Retry exhausted
  • Accept · edit · reject