An OKLCH-based engine generates eleven-step color scales anchored on your exact brand hex, semantic roles for light and dark, a categorical chart palette, modular type, density-aware spacing, radius, shadow and motion tokens. APCA contrast scoring on every pair. Exports to 12 formats including Tokens Studio and a Figma Variables script.
A single token source for color, type, spacing, and shape, everywhere.
Sustained week-over-week growth, accelerating in the last sprint.
| Invoice | Customer | Amount | Status |
|---|---|---|---|
| INV-1842 | Acme Robotics | $2,400.00 | paid |
| INV-1841 | Helix Labs | $840.00 | pending |
| INV-1840 | Northwind | $1,200.00 | paid |
| INV-1839 | Linear Stage | $320.00 | overdue |
A single token source for color, type, spacing, and shape, everywhere.
Sustained week-over-week growth, accelerating in the last sprint.
| Invoice | Customer | Amount | Status |
|---|---|---|---|
| INV-1842 | Acme Robotics | $2,400.00 | paid |
| INV-1841 | Helix Labs | $840.00 | pending |
| INV-1840 | Northwind | $1,200.00 | paid |
| INV-1839 | Linear Stage | $320.00 | overdue |
Eleven-step OKLCH scales. Your primary is kept verbatim at step 600 and the curve bends through it; chroma tapers at the extremes and is trimmed only where sRGB runs out (◆). Click any swatch to copy its hex.
Light on top, dark below. Equal lightness and chroma across the set, hues spread from your primary and ordered so neighbouring series in a legend are never neighbouring hues.
APCA Lc score for each scale step against the light and dark surfaces. ≥75 passes body text, ≥60 passes large or bold, ≥45 passes non-text UI.
| Color | Surface | 50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 950 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| primary | Light surface | 0 | 0 | 13 | 28 | 47 | 66 | 78 | 86 | 94 | 99 | 102 |
| Dark surface | 104 | 98 | 88 | 72 | 51 | 33 | 21 | 12 | 0 | 0 | 0 | |
| accent | Light surface | 0 | 0 | 15 | 29 | 47 | 65 | 76 | 86 | 94 | 99 | 102 |
| Dark surface | 105 | 98 | 85 | 70 | 51 | 33 | 22 | 13 | 0 | 0 | 0 | |
| success | Light surface | 0 | 0 | 8 | 21 | 37 | 53 | 68 | 80 | 91 | 98 | 102 |
| Dark surface | 105 | 101 | 92 | 79 | 62 | 45 | 30 | 19 | 8 | 0 | 0 | |
| warning | Light surface | 0 | 0 | 17 | 37 | 53 | 69 | 79 | 87 | 95 | 100 | 102 |
| Dark surface | 104 | 97 | 83 | 62 | 45 | 30 | 19 | 11 | 0 | 0 | 0 | |
| danger | Light surface | 0 | 0 | 12 | 27 | 46 | 63 | 74 | 84 | 93 | 99 | 102 |
| Dark surface | 104 | 99 | 88 | 72 | 52 | 35 | 24 | 15 | 0 | 0 | 0 | |
| info | Light surface | 0 | 0 | 11 | 25 | 43 | 60 | 73 | 83 | 93 | 99 | 102 |
| Dark surface | 104 | 99 | 89 | 74 | 56 | 38 | 25 | 16 | 0 | 0 | 0 |
Pick any two colors; see APCA Lc and WCAG ratio. If the pair fails, jump to the nearest scale step that passes.
Tokens carry product gravity.
A single source for color, type, and spacing keeps the system honest.
Body copy reads at the tightest size your scale defines. Pick the foreground and background; the engine will tell you whether the pair holds up under APCA and WCAG, and which scale step would pass if it doesn't.
Smaller helper text. Used for labels, captions, metadata.
minor third ratio · 1.200 · base 16px
Token systems carry product gravity.
Designed once, applied everywhere.
One source of truth, many surfaces.
Composable. Themable. Exportable.
Sized by ratio, named by intent.
Tokens are the smallest contract between design and code.
A token system replaces ad-hoc values with a vocabulary. Adjust a single value at the source and the change propagates across every product surface.
Helper text, labels, captions.
Metadata · timestamps · footnotes
4px base × density factor · density: cozy
space-00pxspace-14pxspace-28pxspace-312pxspace-416pxspace-520pxspace-624pxspace-832pxspace-1040pxspace-1248pxspace-1664pxspace-2080pxspace-2496pxspace-0.52pxspace-1.56pxspace-2.510pxsubtle radius · balanced shadow
standard · 5 durations and 5 easings, exported as --duration-* and --ease-*. Press play to race the curves.
12 formats, all generated client-side. Nothing leaves your browser.
/* Generated by DesignSystems.one Token Generator */
/* https://www.designsystems.one/tools/token-generator */
:root {
/* ===== Colors ===== */
/* Primary */
--color-primary-50: #f9faff;
--color-primary-100: #eef1ff;
--color-primary-200: #d9dfff;
--color-primary-300: #b9c3ff;
--color-primary-400: #8e9aff;
--color-primary-500: #6668ff;
--color-primary-600: #4f46e5;
--color-primary-700: #3d2ec1;
--color-primary-800: #2b1497;
--color-primary-900: #1b006f;
--color-primary-950: #0c0041;
/* Accent */
--color-accent-50: #faffd3;
--color-accent-100: #f0f7a7;
--color-accent-200: #dce546;
--color-accent-300: #c3cc00;
--color-accent-400: #a2a800;
--color-accent-500: #7e8300;
--color-accent-600: #656900;
--color-accent-700: #4f5200;
--color-accent-800: #373a00;
--color-accent-900: #242600;
--color-accent-950: #121300;
/* Neutral */
--color-neutral-50: #fafafc;
--color-neutral-100: #f1f1f4;
--color-neutral-200: #e0e1e6;
--color-neutral-300: #c5c7ce;
--color-neutral-400: #a2a4ac;
--color-neutral-500: #7e8088;
--color-neutral-600: #64666d;
--color-neutral-700: #4e4f56;
--color-neutral-800: #36383d;
--color-neutral-900: #232428;
--color-neutral-950: #111115;
/* Success */
--color-success-50: #effff2;
--color-success-100: #d9fee1;
--color-success-200: #b5f7c6;
--color-success-300: #84e7a1;
--color-success-400: #4dcc7a;
--color-success-500: #00ab57;
--color-success-600: #008844;
--color-success-700: #006a34;
--color-success-800: #004a22;
--color-success-900: #003014;
--color-success-950: #001707;
/* Warning */
--color-warning-50: #fff9f1;
--color-warning-100: #ffecd3;
--color-warning-200: #ffd191;
--color-warning-300: #f2a618;
--color-warning-400: #ca8900;
--color-warning-500: #9f6b00;
--color-warning-600: #805500;
--color-warning-700: #664200;
--color-warning-800: #492f00;
--color-warning-900: #311e00;
--color-warning-950: #1b0f00;
/* Danger */
--color-danger-50: #fff8f7;
--color-danger-100: #ffeeeb;
--color-danger-200: #ffd8d3;
--color-danger-300: #ffb4ab;
--color-danger-400: #ff7b6f;
--color-danger-500: #ea3d38;
--color-danger-600: #c80b18;
--color-danger-700: #9f000d;
--color-danger-800: #720007;
--color-danger-900: #4d0003;
--color-danger-950: #2a0001;
/* Info */
--color-info-50: #f6fbff;
--color-info-100: #e8f4ff;
--color-info-200: #cbe6ff;
--color-info-300: #9ad0ff;
--color-info-400: #4ab0ff;
--color-info-500: #008cdd;
--color-info-600: #006fb1;
--color-info-700: #00578c;
--color-info-800: #003d64;
--color-info-900: #002743;
--color-info-950: #001324;
/* ===== Typography ===== */
--font-family-body: 'Figtree', system-ui, sans-serif;
--font-family-heading: 'Space Grotesk', system-ui, sans-serif;
--font-size-xs: 0.6944rem;
--font-size-sm: 0.8333rem;
--font-size-base: 1rem;
--font-size-lg: 1.2rem;
--font-size-xl: 1.44rem;
--font-size-2xl: 1.728rem;
--font-size-3xl: 2.0736rem;
--font-size-4xl: 2.4883rem;
--font-size-5xl: 2.986rem;
--font-size-6xl: 3.5832rem;
--line-height-xs: 1.5;
--line-height-sm: 1.5;
--line-height-base: 1.5;
--line-height-lg: 1.5;
--line-height-xl: 1.4;
--line-height-2xl: 1.2;
--line-height-3xl: 1.2;
--line-height-4xl: 1.2;
--line-height-5xl: 1.2;
--line-height-6xl: 1.2;
--letter-spacing-xs: 0;
--letter-spacing-sm: 0;
--letter-spacing-base: 0;
--letter-spacing-lg: -0.005em;
--letter-spacing-xl: -0.010em;
--letter-spacing-2xl: -0.015em;
--letter-spacing-3xl: -0.020em;
--letter-spacing-4xl: -0.025em;
--letter-spacing-5xl: -0.030em;
--letter-spacing-6xl: -0.030em;
/* ===== Spacing ===== */
--spacing-0: 0;
--spacing-1: 0.25rem;
--spacing-2: 0.5rem;
--spacing-3: 0.75rem;
--spacing-4: 1rem;
--spacing-5: 1.25rem;
--spacing-6: 1.5rem;
--spacing-8: 2rem;
--spacing-10: 2.5rem;
--spacing-12: 3rem;
--spacing-16: 4rem;
--spacing-20: 5rem;
--spacing-24: 6rem;
--spacing-32: 8rem;
--spacing-40: 10rem;
--spacing-48: 12rem;
--spacing-56: 14rem;
--spacing-64: 16rem;
--spacing-0_5: 0.125rem;
--spacing-1_5: 0.375rem;
--spacing-2_5: 0.625rem;
/* ===== Radius ===== */
--radius-none: 0;
--radius-sm: 0.125rem;
--radius-md: 0.25rem;
--radius-lg: 0.375rem;
--radius-xl: 0.625rem;
--radius-2xl: 1rem;
--radius-3xl: 1.5rem;
--radius-full: 9999px;
/* ===== Shadow ===== */
--shadow-sm: 0 1px 2px 0 rgba(35, 36, 40, 0.06);
--shadow-md: 0 4px 6px -1px rgba(35, 36, 40, 0.1), 0 2px 4px -2px rgba(35, 36, 40, 0.06);
--shadow-lg: 0 10px 15px -3px rgba(35, 36, 40, 0.1), 0 4px 6px -4px rgba(35, 36, 40, 0.06);
--shadow-xl: 0 20px 25px -5px rgba(35, 36, 40, 0.1), 0 8px 10px -6px rgba(35, 36, 40, 0.06);
--shadow-2xl: 0 25px 50px -12px rgba(35, 36, 40, 0.25);
/* ===== Motion ===== */
--duration-instant: 50ms;
--duration-fast: 120ms;
--duration-base: 200ms;
--duration-slow: 320ms;
--duration-slower: 500ms;
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
--ease-emphasized: cubic-bezier(0.3, 0, 0, 1);
--ease-decelerate: cubic-bezier(0, 0, 0, 1);
--ease-accelerate: cubic-bezier(0.3, 0, 1, 1);
--ease-linear: linear;
/* ===== Semantic aliases (light) ===== */
--color-bg: var(--color-neutral-50);
--color-bg-subtle: var(--color-neutral-100);
--color-bg-muted: var(--color-neutral-200);
--color-surface: #ffffff;
--color-surface-raised: #ffffff;
--color-fg: var(--color-neutral-900);
--color-fg-muted: var(--color-neutral-600);
--color-fg-subtle: var(--color-neutral-500);
--color-border: var(--color-neutral-200);
--color-border-strong: var(--color-neutral-300);
--color-ring: var(--color-primary-500);
--color-brand: var(--color-primary-600);
--color-brand-hover: var(--color-primary-700);
--color-brand-active: var(--color-primary-800);
--color-brand-subtle: var(--color-primary-50);
--color-brand-fg: #ffffff;
--color-accent: var(--color-accent-500);
--color-accent-hover: var(--color-accent-600);
--color-accent-subtle: var(--color-accent-50);
--color-accent-fg: #ffffff;
--color-success: var(--color-success-600);
--color-success-subtle: var(--color-success-50);
--color-success-fg: var(--color-success-800);
--color-warning: var(--color-warning-600);
--color-warning-subtle: var(--color-warning-50);
--color-warning-fg: var(--color-warning-800);
--color-danger: var(--color-danger-600);
--color-danger-subtle: var(--color-danger-50);
--color-danger-fg: var(--color-danger-800);
--color-info: var(--color-info-600);
--color-info-subtle: var(--color-info-50);
--color-info-fg: var(--color-info-800);
}
.dark, [data-theme="dark"] {
--color-bg: var(--color-neutral-950);
--color-bg-subtle: var(--color-neutral-900);
--color-bg-muted: var(--color-neutral-800);
--color-surface: var(--color-neutral-900);
--color-surface-raised: var(--color-neutral-800);
--color-fg: var(--color-neutral-50);
--color-fg-muted: var(--color-neutral-300);
--color-fg-subtle: var(--color-neutral-400);
--color-border: var(--color-neutral-800);
--color-border-strong: var(--color-neutral-700);
--color-ring: var(--color-primary-400);
--color-brand: var(--color-primary-300);
--color-brand-hover: var(--color-primary-200);
--color-brand-active: var(--color-primary-100);
--color-brand-subtle: var(--color-primary-950);
--color-brand-fg: #0a0a0a;
--color-accent: var(--color-accent-300);
--color-accent-hover: var(--color-accent-200);
--color-accent-subtle: var(--color-accent-950);
--color-accent-fg: #0a0a0a;
--color-success: var(--color-success-500);
--color-success-subtle: var(--color-success-950);
--color-success-fg: var(--color-success-300);
--color-warning: var(--color-warning-500);
--color-warning-subtle: var(--color-warning-950);
--color-warning-fg: var(--color-warning-300);
--color-danger: var(--color-danger-500);
--color-danger-subtle: var(--color-danger-950);
--color-danger-fg: var(--color-danger-300);
--color-info: var(--color-info-500);
--color-info-subtle: var(--color-info-950);
--color-info-fg: var(--color-info-300);
}
Pipe the same tokens into another tool — colors and harmony travel along.