A design tokens cheat sheet for solo founders
Color, type, spacing, radius, shadow, motion. The minimum-viable token system, the names that scale, and the file you can paste into your project this afternoon.
A design system at a 200-person company is a year-long project with a dedicated team. A design system at a one-person company is six files and an afternoon. The trap is that most solo founders either skip tokens entirely (every component invents its own values) or copy a Figma library template and inherit 800 unused variables.
This is the minimum-viable token set that scales from your first landing page to a real product UI without rework. Six categories, naming conventions that don't fall apart at year two, and a ready-to-paste structure.
The six token categories
1. Color
Three palettes: brand, neutral, semantic. Brand is one color with a 50–950 scale. Neutral is one gray with a 50–950 scale. Semantic is success, warning, danger, info — each with 50, 500, and 700, no more.
--brand-50: #f0f4ff;
--brand-500: #4f46e5; /* primary */
--brand-950: #0a0f2a;
--neutral-50: #fafafa;
--neutral-500: #737373;
--neutral-950: #0a0a0a;
--success-500: #16a34a;
--warning-500: #d97706;
--danger-500: #dc2626;
--info-500: #2563eb;Skip purple as a primary unless your product is genuinely about purple. Indigo, slate, and emerald are 2026's safer defaults; the model will reach for purple-500 every time you ask, override it once and you're done.
2. Typography
Two families. Four sizes. Three weights. That's the whole system.
--font-sans: 'Inter', system-ui, sans-serif;
--font-mono: 'Geist Mono', ui-monospace, monospace;
--text-xs: 12px;
--text-sm: 14px;
--text-base: 16px;
--text-lg: 20px;
--text-xl: 28px;
--text-2xl: 40px;
--text-3xl: 64px; /* hero */
--weight-regular: 400;
--weight-medium: 500;
--weight-semibold: 600;
--tracking-tight: -0.02em;
--tracking-tighter: -0.035em; /* hero headlines */The single biggest typography upgrade for a product UI is a tracking-tight token applied to every heading. It's the difference between "webpage" and "editorial."
3. Spacing
A 4px scale that doubles. Pick six values; if you need a seventh, you're decorating instead of structuring.
--space-1: 4px;
--space-2: 8px;
--space-3: 12px;
--space-4: 16px;
--space-6: 24px;
--space-8: 32px;
--space-12: 48px;
--space-16: 64px;
--space-24: 96px; /* section gaps */Resist the urge to add --space-5 or --space-10. The constraint is the value. The moment you add the in-between values, every component starts using them, and your visual rhythm dissolves.
4. Radius
Five values, used surgically. The defaults from most UI libraries (rounded-2xl on everything) are the single fastest way to make a product look like a template.
--radius-sm: 4px; /* inputs, badges */
--radius-md: 8px; /* buttons, cards */
--radius-lg: 12px; /* surfaces */
--radius-xl: 20px; /* hero card, big features */
--radius-full: 9999px; /* pills, avatars */5. Shadow
Three shadows. Subtle, lifted, floating. Anything more is decorative.
--shadow-sm: 0 1px 2px rgb(0 0 0 / 0.05);
--shadow-md: 0 4px 12px rgb(0 0 0 / 0.08), 0 1px 2px rgb(0 0 0 / 0.04);
--shadow-lg: 0 16px 40px rgb(0 0 0 / 0.12), 0 4px 12px rgb(0 0 0 / 0.06);Dark mode rule: shadows mostly disappear in dark UI. Replace with a subtle 1px top border (rgba(255,255,255,0.06)) for the same lifted-card feel.
6. Motion
Two durations, two easings. That's it.
--duration-fast: 120ms; /* hovers, focus rings */
--duration-slow: 240ms; /* layout, modals, sheets */
--ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
--ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);Anything slower than 240ms reads as sluggish on the second visit. Anything faster than 120ms reads as unresponsive. The two-value range covers 95% of product UI; reach for outliers only for hero animations and modal entrances.
Component variables, the second layer
Once tokens exist, build a thin layer of component variables on top. This is where light mode and dark mode actually live.
:root {
--bg: var(--neutral-50);
--surface: #ffffff;
--border: var(--neutral-200);
--text: var(--neutral-950);
--text-muted: var(--neutral-500);
--accent: var(--brand-500);
}
[data-theme="dark"] {
--bg: var(--neutral-950);
--surface: #0f0f0f;
--border: rgba(255,255,255,0.08);
--text: var(--neutral-50);
--text-muted: var(--neutral-400);
--accent: var(--brand-400); /* brighter in dark */
}The dark mode accent is one step lighter than the light mode accent. This is the single most-skipped detail that separates real dark modes from inverted ones.
Common mistakes
- 1.Hardcoded hex values in components. The most common drift point. One
bg-[#fff]and your dark mode is broken. Lint for it. - 2.Too many scale values. A 16-step neutral with five accent colors is overkill until you have an actual design team. Start with three scales of 11 values each; expand later if pain demands it.
- 3.No semantic layer. Using
--brand-500directly everywhere means changing the brand color requires touching every component. The second layer (--accent) is the abstraction that makes future-you grateful. - 4.Tokens with no documentation. A README at the top of your tokens file with one sentence per token category prevents the year-two question: "why does this exist?"
Ship one
The design foundations collection has the full token file above as a paste-ready CSS variables block, plus Tailwind config equivalents. Pair with the typography, spacing, and color deep-dives for the reasoning behind each scale.
keep reading →
- 01
Color systems for product teams that aren't design teams
Primary, neutrals, semantic colors, and how to ship a usable palette without hiring a brand consultant.
- 02
Typography for product UI is mostly about restraint
Two fonts, four sizes, and the tracking, leading, and weight choices that make product type feel premium.
- 03
Spacing systems that scale past the first screen
The 4px / 8px debate, the cases for both, and how to keep spacing consistent when your product grows to 200 screens.