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
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
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
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
--cut — 45° 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.
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.
Enter a valid email — e.g. ops@utility.co
ships on: footer form — every page
focus is live — click into a field
Badge & Card
components/ui/Badge.tsx · Card.tsx
Badge — six tones
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
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
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.
Content enters fade-up
opacity 0→1, y 12→0 · 240ms · ease-out · staggered 40ms
Respect prefers-reduced-motion
Transforms collapse to a plain fade; no parallax, no auto-play
Exit faster than enter
Exits run ~66% of enter duration (160ms) so dismissals feel instant
Hover lift + glow
translateY -2px + accent ring · 150ms · only on pointer devices
Press scale
scale 0.98 on active for tactile feedback, restored on release
Layout morph
Toggles/tabs move via shared layoutId, never a cut
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
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
No chrome slower than 400ms
UI transitions cap at 400ms. Data reveals (counters, charts) may take up to 1s — they are content, not chrome
Enter · fade-up
240ms · cubic-bezier(0.22, 1, 0.36, 1)
Exit beats enter
out 160ms cubic-bezier(0.4, 0, 1, 1) → in 240ms
Interaction · lift
live150ms · cubic-bezier(0.4, 0, 0.2, 1)
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
Raw hex improvised per screen. If a color has no name, it has no job.
Motion
Do
Enter once: fade-up 240ms on view. Motion marks arrival, then gets out of the way.
Don't
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
Numbers render in IBM Plex Mono with tabular figures — columns align, values don't wobble as they tick.
Don't
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
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.