Foundations
Nine pages, each held to one bar: Every rule carries why it exists, and every number cites the token, not a hex. Every number beside a rule is the token build’s.
Illustration
Section titled “Illustration”The pictures that show how something works — a library of 3D objects, each picture drawn live for the web and still for a slide or a PDF. A section of its own, in four pages.
The token layers
Section titled “The token layers”A token name reads left to right, from the general to the particular. There are three tiers.
Primitives — 147 variables
Section titled “Primitives — 147 variables”tier 1 — the raw ramps. A name is a ramp and a number (color/blue/400), never a fancy word: nobody has to agree on what azure means.
Semantic — 131 variables
Section titled “Semantic — 131 variables”tier 2 — the job, not the colour. text/default, surface/card, border/focus. Every value here is a reference to tier 1, and npm test fails if one is a literal.
Accent — 18 variables, 4 modes
Section titled “Accent — 18 variables, 4 modes”tier 2, by mode — the same seventeen roles in four modes (blue, red, yellow, multicolor). Set data-accent on any element and its subtree re-resolves; that is how one library serves products with different accents.
Typography — 72 variables, 4 modes
Section titled “Typography — 72 variables, 4 modes”tier 2, by canvas — the type roles (display / headline / title / body / label, each large / medium / small) in four canvases: web-desktop, web-tablet, web-mobile and slide. A web page’s two section steps live here too — layout/page-section-gap and layout/page-section-gap-tight — one custom property each that the canvas re-sets, so a frame’s one mode sets its type and its spacing together.
Ground — 2 variables, 2 modes
Section titled “Ground — 2 variables, 2 modes”tier 2, by ground — a grey surface is one step darker than the ground it sits on: neutral/100 on the white page, neutral/200 on the product ground surface/card, where neutral/100 could not be told from the ground. Two roles in two modes (page, card); surface/sunken, the neutral KPI tile and the box of a segmented Tabs read them — and the Tabs’ box is the one exception, white on the product ground. Set data-ground="card" on the element that paints surface/card as the ground of a screen and everything grey on it follows; the parts of @pepperui/css that paint a ground themselves — a tinted Card, a Table, a Dialog, and every white container inside them — set it for what they hold.
CSS only — 14 values
Section titled “CSS only — 14 values”Values that are not Figma variables because Figma has no type for them (a blur radius, a container width, an opacity). They live in tokens.css and are documented with the reason: Figma has no variable type for these. They become effect styles or stay CSS-only.
That is 386 custom properties in tokens.css, and every one of them is rendered in the workshop — the generator fails if a property has no record.
Seven outputs, one source
Section titled “Seven outputs, one source”tokens/*.json is the only place a value is typed. npm run build writes:
| Output | For |
|---|---|
tokens.css |
any browser — the --pui-* custom properties |
_tokens.scss |
Sass consumers — MAFO’s _variables.scss theme |
tailwind.js |
a Tailwind v3 preset |
tailwind.css |
a Tailwind v4 @theme block — 167 keys |
shadcn.css |
the shadcn variable map — 32 names + 7 of our own |
figma.json |
the Figma variable import (Figma is authored from here) |
pepper_tokens.py |
Python — the deck’s PPTX exporter reads it |
DESIGN.md is the eighth, and packages/charts/dist/theme.json the ninth — the chart theme, on Data visualisation.
Pepper UI v1.5.0
The Mobupps design system. 386 tokens, 88 components, 65 pages in the workshop — every page of this site generated from the repository, so nothing here is typed twice.