Lumen is the design system that unifies the RSB identity across the sites in the RSB body of work. It is published here so you can see how it works — how the tokens, primitives, and components fit together, why the architecture is what it is, and where the rough edges are. This is a "here is how this works if you are curious" repository, not a design system offered for adoption. If something here is interesting, look around. If something could be better, tell me.
Lumen is a monorepo with three packages and one site.
The packages are the implementation of the design system. @rsb/tokens is the token catalog — the closed set of values for color, spacing, typography, and motion that everything else builds on. @rsb/primitives is a collection of headless Svelte 5 components that handle focus, keyboard, ARIA, and portal behavior without taking a position on visual style. @rsb/ui is the styled component catalog — the actual buttons, dialogs, menus, and layouts that appear on the sites.
The site lives at apps/lumen and is deployed to lumen.rsb.sh. It is both the development environment for the system and a public showcase of the identity — components are built and refined there before they appear on the production sites, and a visitor curious about how the RSB sites look and feel can see the answer there. The site consumes the packages through workspace links, so changes to a package are visible immediately in the dev environment without a publish cycle.
Documentation lives under docs/, organized into specs (per-token and per-component normative descriptions) and standards (the conventions for CSS, design, and how the pieces fit together). The specs are the source of truth — divergence between a spec and its implementation is a bug, not a difference of opinion.
Lumen is built as three layers because the three concerns are genuinely different, and conflating them produces design systems that are harder to maintain than they need to be.
The first layer is values. Design tokens are the atomic vocabulary of the system — the exact color of an accent, the exact rhythm of vertical spacing, the exact curve of a motion easing. These values are not negotiable per-component; they are the shared language that every component speaks. @rsb/tokens holds them. It exposes types for tokens and catalogs in TypeScript, but the values themselves live in CSS custom properties, emitted from the catalog into base.css, fonts.css, and theme files. The TypeScript surface is names; the CSS is the truth. Three gates validate every token: a regex grammar that the name must match, a category membership check against the catalog, and a prefix check that ensures the name belongs to its category.
The second layer is behavior. A button needs to handle keyboard focus correctly. A dialog needs to trap focus while open and restore it when closed. A menu needs to manage arrow keys, escape, and portal placement. These behaviors are independent of how things look, and treating them as separable concerns is what makes a design system durable. @rsb/primitives provides headless Svelte 5 components — wrappers over bits-ui — that get focus, keyboard handling, ARIA attributes, and portal behavior right without taking any position on visual style. A primitive component renders its children and manages its behavior; styling is left entirely to the layer above.
The third layer is presentation. This is where values meet behavior and become the things you actually see on a page — a Button, a Card, a Dialog, a navigation layout. @rsb/ui composes the primitives with the tokens and produces styled components. The composition is where the identity becomes visible: the same primitive button, wearing the RSB tokens, produces the RSB button. Wearing different tokens, it would produce a different button. The architecture makes this separation explicit so the identity is encoded in tokens, not scattered across component CSS.
The governance chain that connects principles to implementation runs in one direction: foundation principles describe the values Lumen serves; experience stories describe how those values feel in use; design principles translate the stories into specific commitments; tokens encode the commitments as values; implementation realizes the values in code. Each step is normative for the step below it. When a token changes, it is because a design principle changed. When a design principle changes, it is because an experience story revealed something the principles missed. The chain is the thing that keeps the system coherent as it grows.
The @rsb/* packages are published to GitHub Packages and consumed by the RSB sites from there. They are scoped to RSB and documented here for the curious, not offered as a general install target.
Per-component examples live at lumen.rsb.sh alongside the live showcase.
The monorepo uses Bun workspaces. To work on Lumen locally, clone the repository and install dependencies with bun install --frozen-lockfile. The development site can be run with bun run --cwd apps/lumen dev. The packages can be type-checked, linted, and tested with bun run check, bun run lint, and bun test from the repository root.
The standards under docs/standards/ describe the conventions for CSS, design, and the heuristics that guide implementation. They are worth reading before making changes to package code, because Lumen's coherence depends on those conventions being applied consistently.
Lumen is open to comments, suggestions, and pull requests. The work is published in part to be commented on — if you see something that could be clearer, more correct, or more elegant, I want to hear about it. Substantive contributions are welcome through the usual pull request flow; smaller observations are welcome as issues or discussions.
The code is licensed under MIT or Apache 2.0, at your option, consistent with the rest of the work at github.com/rsb.
- Live site: lumen.rsb.sh
- Other work: github.com/rsb