Design system — foundations
The TED OS design system is built as a neutral foundation plus per-surface skins. Each surface keeps its own hue and icons; the foundation stays neutral and reusable.
Foundation vs. skin
| Package | What |
|---|---|
@tedos/ui | The neutral foundation — palette + type scale — icon- and accent-agnostic. Carries no surface hue. |
@tedos/admin-ui | The admin skin — the admin's tokens (@theme layer), shell, components/ui primitives, shared screen views, plus the admin's Cian + HugeIcons. |
A surface's hue lives in its skin, never in the foundation — "one core, many hues". The console
adds its own ink token layer on top of @tedos/admin-ui. See Color scope.
Semantic tokens only
Color, radius, shadow, and font always come from tokens — never raw hex in components. The
admin's @theme layer exposes surfaces (canvas / surface / elevated / sunken), borders,
text, accent + status tones, a radius scale (xs … pill), shadows, and the font tokens.
When a surface skin (e.g. a white-label client, or the console) overrides the base surface tokens, it must re-declare the short alias tokens too — overriding only the underlying token leaves the alias-based utilities resolving to the light base, producing light-on-light content. (A real incident; the rule is now part of the conventions.)
No arbitrary size values
Arbitrary pixel values (text-[13px], w-[820px], rounded-[10px], …) are banned. If a needed
size does not exist in the scale or tokens, that is a design decision routed to the Designer to
add as a token — never invented inline.
Icons
All UI icons use HugeIcons (@hugeicons/react + @hugeicons/core-free-icons). Hand-drawn
inline SVGs for UI icons are not allowed. Brand marks (the seed mark, the phyllotaxis field) are
the exception — those stay bespoke.
The four mandatory states
Every interactive surface ships four states: loading (skeletal, layout-matched), empty, error (inline), and success. A happy-path-only component is incomplete.
Shared screen views
Presentational screen bodies are extracted into the design-system package so every consumer — the operator admin and white-label client apps — renders the same view. The views are data-in-props and pure: no data fetching, no app seams inside. The hosting app reads via its own seam and passes data + state + routing hrefs as props; routing stays app-owned. This is what makes the white-label client pattern (see Comprender) cheap.
Where the source of truth lives
The pixel-exact reference lives in the project's Paper design files; the token layer and the
written conventions live in the repo (knowledge/ + the design-system package). On a conflict, the
latest decision wins. See Grid System v2 and Color scope.