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
- 01Hardcoded hex values in components. The most common drift point. One
bg-[#fff]and your dark mode is broken. Lint for it. - 02Too 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.
- 03No 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. - 04Tokens 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
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.
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.
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.