Design System
Work in progress. I'm adding components as I go, following patterns from what's already documented. Nothing here is set in stone yet.
Foundations
Design tokens that everything else builds on. Colors, typography, borders, interactions, breakpoints.
Colors
Color palette and CSS variables used throughout the website.
Background Colors
--background-color#181927--background-frostedrgba(24, 25, 39, 0.05)Surface Colors
--card-surface-raised#2d2d3b--card-surface#1c2638--card-surface-hover#313d50Text Colors
--color#e0e0e0--light-color#f6f5f7Color Scales
Each section uses a themed color palette. These override --accent-color and --secondary-accent-color at the section level.
--orange-bg--orange-tint--orange-cool-shift--orange-desaturated--orange-border--orange-lightest--orange-light--orange--orange-dark--orange-darker--orange-darkest--red-bg--red-tint--red-cool-shift--red-desaturated--red-border--red-lightest--red-light--red--red-dark--red-darker--red-darkest--green-bg--green-tint--green-cool-shift--green-desaturated--green-border--green-lightest--green-light--green--green-dark--green-darker--green-darkest--pink-bg--pink-tint--pink-cool-shift--pink-desaturated--pink-border--pink-lightest--pink-light--pink--pink-dark--pink-darker--pink-darkest--purple-bg--purple-tint--purple-cool-shift--purple-desaturated--purple-border--purple-lightest--purple-light--purple--purple-dark--purple-darker--purple-darkest--blue-bg--blue-tint--blue-cool-shift--blue-desaturated--blue-border--blue-lightest--blue-light--blue--blue-dark--blue-darker--blue-darkest--cyan-bg--cyan-tint--cyan-cool-shift--cyan-desaturated--cyan-border--cyan-lightest--cyan-light--cyan--cyan-dark--cyan-darker--cyan-darkest--yellow-bg--yellow-tint--yellow-cool-shift--yellow-desaturated--yellow-border--yellow-lightest--yellow-light--yellow--yellow-dark--yellow-darker--yellow-darkest--indigo-bg--indigo-tint--indigo-cool-shift--indigo-desaturated--indigo-border--indigo-lightest--indigo-light--indigo--indigo-dark--indigo-darker--indigo-darkest--teal-bg--teal-tint--teal-cool-shift--teal-desaturated--teal-border--teal-lightest--teal-light--teal--teal-dark--teal-darker--teal-darkestBorder Colors
--border-colorrgba(255, 255, 255, 0.1)--border-hover-colorrgba(255, 255, 255, 0.2)Usage
Import variables from @/styles/variables.css or use CSS custom properties directly in your styles.
Typography
Outfit, weights 100–800. Article typography is the baseline — hero uses oversized variants.
Headings
--h2-sizeArticle Title
clamp(24px, …, 30px)Heading 2
1.15emHeading 3
1emHeading 4
Body
--font-size · line-height: 1.7Body text. Longer line-height for reading comfort, em-based margins between paragraphs.
--subtitle-sizeSubtitle text
--button-font-sizeHero (oversized)
The hero section uses larger heading sizes for the landing page. These override the defaults.
--h1-sizeHero Title
--h2-sizeSection Title
--h3-sizeCard Title
Size Variables
| Variable | Value | Min | Max |
|---|---|---|---|
--h1-size | clamp(48px, 1.58rem + 5.05vw, 96px) | 48px | 96px |
--h2-size | clamp(42px, 2.21rem + 1.47vw, 56px) | 42px | 56px |
--h3-size | clamp(18px, 0.95rem + 0.63vw, 24px) | 18px | 24px |
--subtitle-size | clamp(20px, 1.19rem + 0.21vw, 22px) | 20px | 22px |
--font-size-lg | clamp(16px, 0.89rem + 0.42vw, 20px) | 16px | 20px |
--font-size | clamp(16px, 0.89rem + 0.21vw, 18px) | 16px | 18px |
--font-size-sm | clamp(14px, 0.78rem + 0.21vw, 16px) | 14px | 16px |
--font-size-xs | clamp(13px, 0.69rem + 0.42vw, 17px) | 13px | 17px |
--font-size-2xs | 12px | 12px | 12px |
--font-size-3xs | 11px | 11px | 11px |
--button-font-size | 15px | 15px | 15px |
Font Family
The website uses Outfit as the primary font family with weights from 100 to 800.
Borders
Border tokens and radius conventions.
Border Colors
--border-colorrgba(255, 255, 255, 0.1)--border-hover-colorrgba(255, 255, 255, 0.2)--border-ghost-colorrgba(255, 255, 255, 0.3)accent-color 35%Focus state bordersAccent Border Scales
Each color scale includes a --{color}-border token at 35% opacity, used for chromatic borders.
--orange-border--red-border--green-border--pink-border--purple-border--blue-border--cyan-borderRadius Scale
--radius-xs4px — Code blocks, diagram badges--radius-sm6px — Badges, tooltips, ghost links--radius-md8px — Small buttons, logo boxes, sidebar items--radius-lg12px — Buttons, tags, icon buttons, nav cards, form fields--radius-xl32px — Cards, spotlight9999px9999px — Full circle (spotlight glow)Common Patterns
| Pattern | Border | Radius |
|---|---|---|
| Card / Spotlight | 1px solid var(--border-color) | var(--radius-xl) |
| Button / Tag | 1px solid transparent | var(--radius-lg) |
| Form field | 2px solid var(--border-color) | var(--radius-lg) |
| Small button | none | var(--radius-md) |
| Badge / Ghost link | 1px solid var(--border-ghost-color) | var(--radius-sm) |
Interactions
Tokens for interactive states — transitions, opacity, borders, and shared patterns.
Transitions
--transition-base0.3s ease — general hover/focus--transition-fast0.2s ease — subtle interactions--transition-snap200ms — active/press states| Token | Value | Used by |
|---|---|---|
--transition-base | 0.3s ease | Button, Link, IconButton, BadgeLink, IconLink, .anime |
--transition-fast | 0.2s ease | NavCard, ArrowLink icons, tooltips |
--transition-snap | 200ms | Active/press state on buttons and links |
Opacity
--opacity-idleInteractive elements at rest--opacity-mutedSecondary content, subtitles1Hover state (full opacity)| Token | Value | Used by |
|---|---|---|
--opacity-idle | 0.8 | Link, BadgeLink, Button ghost |
--opacity-muted | 0.6 | NavCard subtitle, IconLink icon |
Letter Spacing
Used on ghost-styled elements — badges, ghost buttons — where bold + wide tracking gives a label-like feel without uppercase.
Ghost Pattern
Shared mixin from _ghost.scss — border, weight, spacing, hover accent
@use "@/styles/ghost" as *;
.my-element {
@include ghost;
// adds: transparent bg, ghost border, 700 weight,
// wide tracking, idle opacity, accent hover
}The mixin provides the visual identity. Layout (display, padding, height, radius) stays in the component.
All Tokens
| Token | Value | Category |
|---|---|---|
--transition-base | 0.3s ease | Transition |
--transition-fast | 0.2s ease | Transition |
--transition-snap | 200ms | Transition |
--opacity-idle | 0.8 | Opacity |
--opacity-muted | 0.6 | Opacity |
--border-ghost-color | rgba(255,255,255,0.3) | Border |
--letter-spacing-wide | 0.5px | Typography |
--radius-xs | 4px | Radius |
--radius-sm | 6px | Radius |
--radius-md | 8px | Radius |
--radius-lg | 12px | Radius |
--radius-xl | 32px | Radius |
Breakpoints
SCSS mixins from _breakpoints.scss. All mobile-first, triggered at max-width.
Scale
Mixins
| Mixin | Max Width | Typical Use |
|---|---|---|
@include mobile | 600px | Single column, compact spacing |
@include tablet | 900px | Stacked layouts, smaller typography |
@include desktop | 1100px | Sidebar collapse, grid adjustments |
@include wide | 1200px | Minor width tweaks |
@include ultrawide | 1368px | Max content width boundary |
Usage
@use "@/styles/breakpoints" as *;
.component {
display: grid;
grid-template-columns: 1fr 1fr;
@include tablet {
grid-template-columns: 1fr;
}
@include mobile {
padding: 16px;
}
}Import with @use "@/styles/breakpoints" as * to use mixins without a namespace prefix.