Skip to content
The constitution

Design decisions, compiled.

Gridline's entire interface derives from one token file. This page imports lib/tokens.ts and renders it live — the documentation cannot drift from the product. If it's here, it ships. If it isn't, it doesn't.

20 color tokens · 10 type steps · 9 space steps · 4 shadows · 9 motion rules · 5 radii · 1 silhouette

01 — Color

One accent. Everything else is structure.

Graphite surfaces, hairlines, three text tiers and a single volt-green accent. Semantic state colors exist for meaning, never for decoration. Components reference tokens — raw hex is a lint error waiting to happen.

Surfaces

bg

--bg · #0A0E12

App canvas — the deepest graphite layer

surface

--surface · #10161D

Cards, panels, raised sections

surface-2

--surface-2 · #161E27

Inputs, nested wells, hover fills

surface-3

--surface-3 · #1C2732

Highest elevation — menus, active rows

Lines

line

--line · rgba(255,255,255,0.08)

Default hairline borders & dividers

line-strong

--line-strong · rgba(255,255,255,0.14)

Emphasised edges, focus-adjacent borders

Text

fg

--fg · #F2F5F7

Primary text & headings — 15:1 on canvas

fg-dim

--fg-dim · #9BA7B4

Body, secondary text — 7.7:1 on canvas

fg-faint

--fg-faint · #8593A3

Mono meta, captions, axis labels — ≥4.8:1 on every surface

Accent — the only brand color

accent

--accent · #2DE0A7

Volt-green. The single accent: CTAs, links, live state

accent-strong

--accent-strong · #22C08D

Accent hover / pressed — one shade deeper

accent-soft

--accent-soft · rgba(45,224,167,0.12)

Tinted backgrounds, badges, glow rings

on-accent

--on-accent · #052A20

Text/icons on a filled accent surface

Semantic states

success

--success · #2DE0A7

Online / healthy — shares the accent hue

warn

--warn · #F5B54A

Degraded, attention, non-blocking warnings

danger

--danger · #FF5C6A

Errors, faults, destructive actions

info

--info · #5B9DFF

Neutral information, secondary charts

warn-soft

--warn-soft · rgba(245,181,74,0.12)

12% tint — warn badge & panel fills

danger-soft

--danger-soft · rgba(255,92,106,0.12)

12% tint — danger badge & panel fills

info-soft

--info-soft · rgba(91,157,255,0.12)

12% tint — info badge & panel fills

source: lib/tokens.ts · rendered live — not screenshots

02 — Type

Three voices, ten steps.

Sora carries headlines, Inter carries prose, IBM Plex Mono carries data — numbers never render in a proportional face. Every step below is the real CSS, not a picture of it.

Grid intelligence

display-xl

60px / 1.04 · Sora 700 · -0.03em

Hero headline

Grid intelligence

display-lg

48px / 1.06 · Sora 700 · -0.025em

Page title

Grid intelligence

display-md

38px / 1.1 · Sora 700 · -0.02em

Section heading

Grid intelligence

display-sm

30px / 1.15 · Sora 600 · -0.015em

Sub-section

Grid intelligence

title

24px / 1.25 · Sora 600 · -0.01em

Card title

Grid intelligence

subtitle

20px / 1.35 · Sora 600 · -0.005em

Lead paragraph

Telemetry from every asset, one pane of glass.

body-lg

18px / 1.6 · Inter 400 · 0

Large body copy

Telemetry from every asset, one pane of glass.

body

16px / 1.6 · Inter 400 · 0

Default body

Telemetry from every asset, one pane of glass.

body-sm

14px / 1.55 · Inter 400 · 0

Secondary text, captions

FDR-27 · ONLINE · 99.98%

label

12px / 1.4 · Plex Mono 500 · 0.14em

Uppercase mono label

source: lib/tokens.ts · every step is the real CSS applied to real text

03 — Space, radius & elevation

A 4-point grid you can hear.

Spacing snaps to 4/8pt increments, corners come in five radii plus one 45° cut — the Gridline silhouette, reserved for actions — and elevation is four shadows, the last one the accent glow. Nothing in between, nothing improvised.

Spacing — 4/8pt rhythm

1

4px

2

8px

3

12px

4

16px

6

24px

8

32px

12

48px

16

64px

24

96px

Bars are true to size. If a gap isn't on this scale, it doesn't exist.

Radius & silhouette

sm · 6px

md · 10px

lg · 14px

xl · 20px

full · 9999px

cut · 10px

--cut45° corner-cut on primary / secondary / console actions — applied via the .u-cut utility. Rounded corners say "surface"; the 45° cut says "action".

Elevation

shadow-sm

Resting inputs, subtle lift

shadow-md

Cards, dropdowns

shadow-lg

Modals, popovers, hero panels

shadow-glow

Accent hover / focus emphasis

Four levels. The glow is the only colored shadow and only ever accent-tinted — elevation never invents new hues.

04 — Components

Every state, designed on purpose.

The same components that build Home, Platform, Pricing and About — with every state on the table. Hover, focus and press are live: try them. Each specimen lists where it ships.

Button

components/ui/Button.tsx

Intents — primary / secondary / console carry the corner-cut

event log — press an intent

Disabled

Loading

Sizes

ships on: every page · navbar · footer form · platform console

hover / focus / press are live — try them

Input

components/ui/Input.tsx

Labels are always visible — placeholders never carry meaning.

ships on: footer form — every page

focus is live — click into a field

Badge & Card

components/ui/Badge.tsx · Card.tsx

Badge — six tones

QueuedFeaturedOnlineDegradedFaultMaintenance

Card — resting vs interactive (hover it)

Resting

Surface, hairline, lg radius.

Interactive

Lift 2px + edge, 150ms.

ships on: every page

status is a state, not an animation — dots never blink

Tabs / segmented

components/ui/Tabs.tsx

Three options

Two options — pricing period

ships on: pricing (billing toggle) · this page

the pill morphs via shared layout — it never cuts

Stat

components/ui/Stat.tsx

0.00%fleet uptime
0msalert latency

ships on: home (scale band)

counts once on view · 900ms — data is content, not chrome

Accordion

components/ui/Accordion.tsx

Content reveal is layout by nature — everything else on the site moves with transform and opacity only, so it stays on the compositor.

ships on: pricing (FAQ)

the one sanctioned height animation — exit 160ms beats enter 240ms

05 — Motion

The motion constitution.

Motion is a system, not a mood. Three bands: what always happens, what happens on interaction, and what never happens. The demos replay the real curves with their real durations.

ALWAYS

Content enters fade-up

opacity 0→1, y 12→0 · 240ms · ease-out · staggered 40ms

ALWAYS

Respect prefers-reduced-motion

Transforms collapse to a plain fade; no parallax, no auto-play

ALWAYS

Exit faster than enter

Exits run ~66% of enter duration (160ms) so dismissals feel instant

ON-INTERACTION

Hover lift + glow

translateY -2px + accent ring · 150ms · only on pointer devices

ON-INTERACTION

Press scale

scale 0.98 on active for tactile feedback, restored on release

ON-INTERACTION

Layout morph

Toggles/tabs move via shared layoutId, never a cut

NEVER

No decorative infinite loops

Ambient motion lives in one sanctioned band — the hero scenes and the backdrop cube field (core float, grid pulse, drift particles, scroll cue) — everything else is event-driven

NEVER

No animating width/height/top/left

Movement is transform & opacity only — it stays on the compositor. Sole exception: disclosure containers (accordion) animate height, because content reveal is layout by nature

NEVER

No chrome slower than 400ms

UI transitions cap at 400ms. Data reveals (counters, charts) may take up to 1s — they are content, not chrome

fast 150ms · hover, press
base 240ms · enter
exit 160ms · exit
slow 400ms · ceiling

Enter · fade-up

content

240ms · cubic-bezier(0.22, 1, 0.36, 1)

Exit beats enter

dismissed

out 160ms cubic-bezier(0.4, 0, 1, 1) → in 240ms

Interaction · lift

live
hover me

150ms · cubic-bezier(0.4, 0, 0.2, 1)

06 — Do / Don't

Discipline, illustrated.

The judgement calls that keep five pages feeling like one product.

Color

Do

Semantic tokens, one accent. Volt-green means action or life — nothing else gets to be loud.

Don't

#7B2FF7 · #FF9900 · #FF2D95

Raw hex improvised per screen. If a color has no name, it has no job.

Motion

Do

opacity 0→1 · y 12→0 · once

Enter once: fade-up 240ms on view. Motion marks arrival, then gets out of the way.

Don't

animate-bounce · animate-pulse · marquee

Perpetual loops on chrome. If it moves forever, it is noise — the ambient band (hero scenes + backdrop cubes) is the single exception.

Data typography

Do

1,024.5 MW · 50.02 Hz

Numbers render in IBM Plex Mono with tabular figures — columns align, values don't wobble as they tick.

Don't

1,024.5 MW · 50.02 Hz

Proportional digits in tables and tickers. A 1 narrower than a 4 makes live data jitter.

Geometry

Do

The corner cut is the silhouette of action — and focus follows it as an inset ring, because outlines get clipped.

Don't

outline: 2px — clipped, invisible

A default outline on cut geometry. clip-path clips it to nothing — the keyboard user goes blind.

Hierarchy

Do

One primary action per screen. Everything else is secondary or ghost — the eye never has to arbitrate.

Don't

Competing primaries. Three loud buttons equals zero loud buttons.