// design system / v0.1
The threesided
style guide.
How this site holds together — tokens, components, voice, and the accessibility commitments behind them. Adding a section? Start here.
/ 01 — palette
Colors.
Three accents on a near-black ground. Contrast ratios measured against
--void. Every text color hits at least WCAG AA at its
intended size.
-
--void
#0d0a1e
Background — primary
contrast: —
Used as page background. All foreground colors are measured against this.
-
--void-deep
#050316
Background — recessed
contrast: —
Footer wells, image placeholders, image-frame backings.
-
--void-soft
#1a1530
Background — raised
contrast: —
Subtle elevation behind cards or grouped content.
-
--ghost
#f0f0ff
Foreground — primary
contrast: 17.1 : 1
Body text + headings. AAA contrast on void.
-
--acid
#fff95b
Accent — tertiary
contrast: 17.4 : 1
Highlights + warnings. Prefer dark text ON acid (used in .tag--acid) rather than acid text on dark at body sizes.
-
--cyan
#00d9ff
Accent — secondary
contrast: 11.2 : 1
Links, info contexts, focus rings. AAA.
-
--muted
#b8b8d0
Foreground — secondary
contrast: 10.0 : 1
Supporting text, summaries, metadata. AAA.
-
--hot
#ff006e
Accent — primary
contrast: 5.0 : 1
Primary CTAs and intensity contexts. AA for normal text; keep ≥ 14px + bold or invert for anything smaller.
-
--dim
#7a7a95
Foreground — tertiary
contrast: 4.6 : 1
Footnotes, muted-context eyebrows. AA just above the 4.5 : 1 line — never under 14px and never load-bearing.
/ 02 — typography
Type scale.
Display + body in Space Grotesk.
Mono in IBM Plex Mono.
Sizes use clamp() for responsive scaling — fluid down to
mobile.
- Bleeding-edge.
- The receipts.
- Project title
- Section subhead text.
- Body paragraph text.
- // EYEBROW
/ 03 — components
Building blocks.
Tags, CTAs, and cards. Three accent variants where it makes sense — keep the rotation consistent across a section.
Tags
- // hot accent
- // cyan accent
- // acid accent
- // neutral
Use sparingly — one accent per logical group. Mono only.
Call-to-action
Primary is always --hot. Pair with a ghost variant on the same row when there are two paths.
Eyebrow + heading + body
// section eyebrow
Section heading goes here.
Section subhead in .body-lg. Caps line length at ~56ch for readability.
Default section pattern — eyebrow, h2, body-lg subhead. Hierarchy is always eyebrow → h2 → body-lg.
/ 04 — motion
Motion.
- Scroll-reveal everything once. Cards fade up on first viewport entry via IntersectionObserver, staggered when several land at once. After reveal they stay revealed.
- Hover is a permitted surface for showing more. Grayscale → full color on client chips. Card lifts and accent edges on hover. Never trigger a destructive action on hover.
- Easings are intentional.
--ease-out(cubic-bezier(0.16, 1, 0.3, 1)) for on-screen welcomes.--ease-snapfor state changes that need to feel decisive. -
prefers-reduced-motion: reduceis honored everywhere. Scroll reveals turn off, Three.js falls back to a static frame, transitions zero out.
/ 05 — voice + tone
How it sounds.
- Lead with the user benefit.
"Sub-second loads" beats "Vite + SWC bundler"
- One adjective max per noun phrase.
"Custom interactions" not "Custom, novel, delightful interactions"
- Sass with substance.
"Names on request" is fine. "The cool kids do it this way" is not.
- Mono for technical contexts only.
Eyebrows, tech tags, file names. Not body copy.
- Sentence case in headings.
"The receipts" — not "The Receipts" or "THE RECEIPTS".
/ 06 — accessibility
Commitments.
- WCAG 2.1 AA — text contrast measured and recorded in this guide.
- Semantic HTML first.
main,section,article,header,footerwith oneh1per page. - Skip link at the top of every page (focus the URL bar, tab once — it appears).
- Focus-visible on every interactive element (2px cyan outline, 3px offset).
- Reduced-motion respected globally and per-component.
- Decorative SVGs are
aria-hidden. Decorative images carryalt="". - Keyboard nav works without the 3D canvas (it's
tabindex="-1"+aria-hidden).
/ 07 — the rulebook
For future contributors.
The full design system lives in DESIGN.md at the repo root.
When extending the site — new section, new component, new page — start there.