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. 01Hardcoded hex values in components. The most common drift point. One bg-[#fff] and your dark mode is broken. Lint for it.
  2. 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.
  3. 03No semantic layer. Using --brand-500 directly everywhere means changing the brand color requires touching every component. The second layer (--accent) is the abstraction that makes future-you grateful.
  4. 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