ryan spohn

Design system

A living reference for the system this site is built on, built in the open as proof of craft. Four token modules (type, spacing, color, motion), then the execute layer: how the system is run, the decisions behind it, and one component documented end to end.

Open the live control panel, tune any token, and watch the whole site respond. “Copy CSS” gives you a paste-ready :root block. The same controls open from anywhere via the design control in the nav.


Typography

One fluid ramp per role. The clamp min anchors a tight ~1.2 scale at 320px; the max anchors a more dramatic ~1.333 scale at 1440px. Lyon (serif) for display & titles, Founders Grotesk (grotesque) for reading & UI, Founders X-Condensed for labels.

The typefaces

The system runs on two typefaces chosen for character. Both Lyon and Founders Grotesk are revivals. Setting one against the other gives the site its editorial voice and keeps a clear division of labor: Lyon speaks (titles, leads, quotes), Founders works (display structure, reading, UI).

Lyon

serif · Commercial Type (opens in new tab)

Kai Bernau, 2009. A contemporary serif drawn from Robert Granjon’s 16th-century Renaissance punchcutting, reworked for modern editorial use.

Founders Grotesk

sans · Klim Type Foundry (opens in new tab)

Kris Sowersby, 2012. A grotesque that reaches back past Helvetica to the rougher early-20th-century faces, keeping a directness that later sans-serifs standardized away.

Display / hero42→88px · lh 1 · -0.025em
Building products people trust
Page title (H1)40→76px · lh 1.05 · -0.025em
Selected work
Feature card title26→44px · lh 1.1 · -0.015em
Drive, modernized
Section title (H2)26→36px · lh 1.12 · -0.015em
How I work
Sub-item title (H3)22→28px · lh 1.2 · -0.01em
Lead with the problem
Standfirst / lead23→30px · lh 1.32 · 0em
A design leader and maker who ships the work, not just the strategy.
Body21→24px · lh 1.4 · 0em
This portfolio is hand-built rather than assembled from a template, so the system underneath gets the same care as the work it presents. Design and code stay one source of truth, and the whole thing is kept deliberately simple.
Pull-quote21→24px · lh 1.6 · 0em
“He reframed the problem before anyone had written a line of code.”
Secondary / meta16→17px · lh 1.45 · 0em
Design Manager · Enterprise SaaS · 2021 — Present
Eyebrow (caps)16→18px · lh 1.15 · 0.08em
Selected work
Micro label (caps)14→15px · lh 1.15 · 0.1em
Role
Fine print12px · lh 1.4 · 0em
© 2026 Ryan Spohn. All rights reserved.

Color

An accented neutral: a near-neutral paper field, near-black ink, and a single oxblood accent. These are the primitives — surface, ink, accent, and status — that the semantic aliases (card, primary, ring, the *-foreground pairs) track. The accent family is one OKLCH hue (~25°) stepped in lightness. Full taxonomy, OKLCH coordinates, and the WCAG/APCA contrast audit are in DESIGN-SYSTEM.md.

--background#F4F4F2
paper surface
--foreground#1A1A1A
primary ink, headings
--medium#515150
soft body
--muted#6E6E6A
meta, captions, labels
--accent#7A1F1F
oxblood: links, accents
--accent-hover#5C1717
button hover (accent, darker)
--bg-inverse#1A1A1A
dark surface (cards, sections)
--ink-inverse#EAE8E2
text on dark surfaces
--ink-inverse-medium#A7A5A0
soft body on dark
--ink-inverse-muted#888680
captions on dark
--accent-inverse#D8766F
oxblood on dark (lightness lift)
--status-production#3F7332
shipped / production
--status-development#284B6D
in development

Spacing

One named step set (Option A): an 8px grid with a 4px half-step, growing ~geometrically (×1.33–1.5 per step) so every value is a multiple of 8 and the workhorse 16 / 24 survive. Bars render at true size. Section rhythm (--page-gap, --gap-section), the reading measure, and the golden-ratio proportions are fluid or compound, so they live in DESIGN-SYSTEM.md rather than on a slider.

--space-3xshairline nudges, icon gaps (the half-step)
4px
--space-2xstight inline gaps
8px
--space-xslabel / value pairs, small gaps
12px
--space-smdefault element gap
16px
--space-mdcomfortable gap, card padding
24px
--space-lggroup spacing
32px
--space-xlsub-section
48px
--space-2xlsection
64px
--space-3xlmajor section
96px
--space-4xlpage-level
128px

Motion

An ordered duration ramp (80–800ms) on three named easing roles. Each specimen replays a move on the standard ease so you can read the speed; the three eases are shown side by side for curve comparison. CSS --motion-* is canonical; the component transition vars (--card-*, --layer-*, --btn-*) alias it and animation-tokens.ts mirrors it for GSAP. Full rationale in DESIGN-SYSTEM.md (Motion).

--motion-instantpress / tap feedback
80ms
--motion-fasthover, release, dialog close, micro
150ms
--motion-basestandard UI: card lift-in, dialog open
200ms
--motion-moderaterest-settle, opacity fades
300ms
--motion-slowentrance / reveal transform
400ms
--motion-deliberatelarge, deliberate transitions
800ms
Easing roles (at --motion-deliberate)
standard
spring
settle

Component: the button

One component documented end to end rather than a shallow gallery. The button is a composition, not a prop-driven widget: a real <a>/<button> carrying .btn-interactive (the motion behavior), one geometry (36px tall, 4px radius, a cap-trimmed label + a 34px icon box), and one of three fills. Hover to feel the asymmetric timing; press for the 80ms scale.

Outlinesecondary / quieter CTA
Filled darkprimary action on a light page
Filled oxbloodloudest, brand-forward, used sparingly

Operating model

How a system is governed and evolved is what separates a design system from a style guide, and it is what most portfolios omit. This is an honest, lightweight model for a one-person site: governance is centralized but real (trap sheets, do-not rules, enforced two-layer aliasing, a multi-agent workflow); token changes are the versioned surface, with deprecations migrated rather than left to rot; adoption is measured by token coverage and the absence of off-scale values. Every heavier mechanism (RFCs, federation, semver tags) is named as a deliberate non-goal.

TypographyGoverned
ColorGoverned
SpacingTokenized → governing
MotionTokenized
Shape / radiusGoverned (one token)
ComponentsDocumented (one exemplar)

Decisions & non-goals

A rationalized “no” is the strongest systems-thinking evidence available. The high-signal subset of the register:

Single 4px radius, no scaleThe single token is the rationale; an editorial surface needs no scale.
Flat cards, no elevationEditorial register; hairlines and type carry hierarchy, not shadows.
No dark modeOne light oxblood-on-paper palette; the inverse pair gives dark surfaces without a second theme.
AA across the board, AAA only where freeDon't darken secondary text to chase 7:1; it flattens the editorial hierarchy.
Single accent (oxblood)Accented-neutral; one hue carries all emphasis, kept under ~10% of the page.
Golden ratio only on visible proportionsImage crops and the featured split, not the spacing scale, where grid cleanliness wins.
One button geometry, three fillsRestraint; fill encodes emphasis, no size axis.
No component library at scaleOne exemplar proves the API thinking; a library would be over-indexing for a six-page site.
No baseline grid; rhythm on the 8px gridFluid type slides the line box 29→34px, so no fixed baseline holds; the scale is commensurate with the line box (32 ≈ 1 line) instead.