eee9dc and 0d0a03 become () and (ground, ): tokens that keep their reasons, so designers, developers and language models can work from the same rules.

Bring your own design.

The rules don't make your design decisions for you. Your colors, sizes and type come from wherever you like: picked by eye, taken from a brand book or generated. Here the palette is . The book only decides what goes where: which color is ground, ink or accent, which size is the next step up. Change the inputs and every rule that reads them is worked out again.

No.TokenSourceValue
Drag the handles to reshape the scale from to .
No.TokenSourceValue

Rendered with book.render('svg', { interactive: true }). Point at a token to follow its references.

No.TokenRuleValue

One book for designers, developers and language models.

A hex code doesn't tell you why it was picked. A rule does, and each of them can read it in their own form. The sheets below are rendered from the same book as the sentence at the top of this page.

For developers

CSS custom properties

      

Tokens are plain, serializable data with no closures. A model can change darkest to mostVivid and explain the change, instead of making up a new hex code. The package ships a skill file that teaches agents to move an existing system onto rules.

What it is built on

You bring the values
Rules pick and mix the colors, sizes and type you give them; they don't make up their own. Make the primitives however you like, with a generator, a brand book or by eye, and write a plain value wherever a rule isn't what you mean.
Rules, not values
Selectors pick from a scope (darkest, closest, bestContrastWith). Transforms derive from a token (lighten, colorMix, ramp). A plain value is fine wherever a fixed value is what you mean.
Contrast built in
Pass readableOn to any color selector and it only considers colors that meet WCAG contrast on that surface. When nothing passes, you get an error instead of an unreadable color.
A dependency graph
Every reference is an edge. Changing a token re-resolves exactly what depends on it, and a write that would create a cycle is refused.
Scopes inherit
A button-danger scope extends button and overrides only its background. Relative references such as ref('.bg') resolve in the scope that inherits them.
Variations are books
Each theme, brand or breakpoint is a separate book built by the same function. Render one fully and the others as the differences from it.
One source, many outputs
CSS custom properties that keep var(), color-mix() and calc() live in the browser, resolved JSON, or W3C Design Tokens.

Start with one rule.

Install it, give it the colors you already have and replace one hand-picked value with the rule behind it. The code below is a whole book. The tour shows every function at work, the editor lets you write your own in the browser, and the article argues the case.

import {
  DesignBook, color, ref, darkest, bestContrastWith,
} from 'design-book';

const book = new DesignBook('site');
const ledger = book.addScope('ledger');
ledger.set('paper', color('#eee9dc'));
ledger.set('ink',   color('#22201c'));

const ui = book.addScope('ui');
ui.set('ground', darkest(ref('ledger')));
ui.set('ink',    bestContrastWith(ref('ui.ground'), ref('ledger')));

book.render('css-variables');
$ npm i design-book