The studio foundation.
A minimal, editorial system. A near-neutral canvas, one forest-green accent, and a single typeface working hard. Everything below is driven by design tokens — flip the theme to watch the whole page re-resolve from one attribute.
A near-neutral canvas, used in proportion
Near-white paper, near-black ink, and a neutral grey ramp do almost all the work. The forest-green accent appears rarely — for calls to action, links, focus, and the occasional mark. It deepens in light and turns vivid in dark. Swatches render live from the tokens.
Core & accent
Neutral ramp
Status
One typeface, hierarchy from weight & scale
Geist for display and text; Geist Mono for labels, eyebrows, and code. Hierarchy comes from size, weight, and tight tracking on the display roles — not from many families. The scale is responsive (resize to see it shift).
A 4px baseline, generous at the top
Controls use the lower steps; editorial layouts lean on 900–1100 for section rhythm. Whitespace is a material, not leftover.
Intent names over the raw scale
The same 4px scale, named by what it does: inset pads inside a
surface, stack gaps blocks vertically, inline gaps items in
a row. Components reach for intent, not numbers — nothing new is invented, each
token just points at a --gok-space-* step.
Inset · padding inside a surface
Stack · vertical gap between blocks
Inline · horizontal gap in a row
--gok-space-section (64px) sets the padding within a
section; --gok-space-section-gap (128px) the rhythm between
major divisions — the editorial breathing room this page is built on.
Breakpoints, containers & a 12-column grid
Width does two jobs, kept separate: a narrow reading measure for text, and a wide canvas for layout and media. Resize the window — the readout tracks the active breakpoint, and the auto grid reflows with no media query.
Active breakpoint: —12-column grid · .gok-grid
Auto grid · .gok-grid.gok-grid--auto
Crisp corners
Small, restrained radii. The pill is reserved for tags and avatars.
Hairline by default
A tidy three-step scale beside radius. The hairline (1px) is the editorial divider already used for these section rules; heavier weights mark emphasis and selection. Components read a token instead of inventing a width.
Quiet & precise
Precise curve to enter, dynamic curve to exit. No bounce. Click a row to preview the easing. Transition durations stay sub-300ms; ambient/looping durations (spinners, shimmer) run in seconds. Reduced-motion collapses every transition duration to zero — the ambient loops slow or freeze themselves instead.
| Token | Value | Use | Preview |
|---|---|---|---|
duration-instant | 100ms | Hover / colour micro-states | |
duration-fast | 150ms | Chevrons, checks, small reveals | |
duration-moderate | 220ms | Popovers, menus, tabs | |
duration-slow | 300ms | Modal / drawer / toast | |
duration-loop | 1.2s | Ambient — one full spin (spinner, button pending) | |
duration-shimmer | 1.8s | Ambient — a highlight sweep (skeleton) | |
duration-pulse | 1.6s | Ambient — a breathing cycle (pulse loaders) | |
ease-precise | enter | Snaps into place, no settle | |
ease-dynamic | exit | Accelerates away | |
ease-standard | both | Symmetric micro-states |
Soft, restrained depth
Three levels by how far a surface sits above the page.
One model for interaction states
Disabled dims a whole control; hover, focus, and pressed are the alpha of an ink wash composed over a surface — one consistent system instead of one-off colours. The scrim is the modal backdrop, composed straight from its opacity token.
State-layer washes · ink over a surface
Disabled & scrim
A z-index scale, so layers never fight
Overlapping surfaces stack in a deliberate, shared order — components read a
named token (--gok-z-*) instead of inventing a number. The higher
tier sits on top. The sticky topbar above already uses
--gok-z-sticky.