WORK / CASE 01

UDS —
uDocz Design System

The design system all four uDocz products consume: 76 CSS components on two token layers. I design it, document it and maintain it.

Role
Design, architecture, governance
Reach
Consumed by 4 products
System
76 components · 2 token layers
Releases
4 · SemVer · changelog
The problem

Four products, four different ways to draw a button.

uDocz grew product by product: the B2C study experience, the institutions dashboard, the teacher suite embedded in the LMS, and the public-sector programs. Each one solved its interface on its own — auditing one of them I found over 50 one-off implementations and up to four variants of the same button living in production.

The real cost: every new screen re-decided things already decided, and every inconsistency was one more conversation in the engineering handoff.

HOVER OVER EACH BUTTON — THE FIRST FOUR RECONSTRUCT THE AUDIT; THE FIFTH IS THE SYSTEM'S
DEMO 01 — THE SAME BUTTON, FOUR TIMES (AND HOW IT ENDED UP) · INTERACTIVE
The architecture

Primitives and semantics: two token layers.

The system separates primitives (scaled palettes, 2px-base spacing, radii, elevation, typography) from semantics (text, surface, border, brand, feedback — named by role). Components consume semantics only; primitives just anchor the semantic layer.

That makes theming nearly free: dark mode and product variants are solved by re-pointing the semantic layer with one attribute. All 76 components inherit unchanged.

384 tokens in two layers; no component has a hardcoded color. NO COLOR OUTSIDE THE SYSTEM — EXCEPTIONS ARE DOCUMENTED INLINE
THEME PRODUCT
Activity report

Colegio San Agustín — 2026-S1

Up to date LTI 1.3
128 active students ▲ 12%

License expiring

The school's plan expires in 14 days. Renew to keep access.

CLICK ANY PIECE TO READ ITS TOKEN CHAIN — THE COMPONENT IS NEVER TOUCHED; THEME AND PRODUCT ONLY RE-POINT THE SEMANTIC LAYER
DEMO 02 — THE SYSTEM'S REAL COMPONENTS, ON THEIR REAL TOKENS · INTERACTIVE
HOVER ACROSS THE SCALE — 63 REAL PRIMITIVES; COMPONENTS CAN'T TOUCH THEM: ONLY THE SEMANTIC LAYER ANCHORS HERE
DEMO 03 — THE 7 PALETTES, WITH THEIR SEMANTIC ROLES RESOLVED LIVE · INTERACTIVE
The governance

Nine written contribution rules.

Every change to the system goes through nine documented rules. The four that do the most work:

  • The system defines appearance and behavior, not application logic. If a component needs JS, the system documents the behavior and each product implements it.
  • Nothing gets removed without a migration plan. A breaking change is a major release with the way out documented.
  • No style patches. I inherited 11 exceptions that forced styles over the system; 2 remain, each with its reason documented.
  • New components don't enter the system directly. They're born in the product that needs them, following the system's conventions, and get promoted once they serve more than one product — renaming nothing.

In v0.4.0 that mechanism promoted 49 components at once, from the B2C staging into the system, without breaking a single consumer: from 27 to 76.

RELEASE V0.3.1 → V0.4.0 COMPONENTS: 27/76
THE V0.4.0 PROMOTION, RECONSTRUCTED FROM THE REAL CHANGELOG — THE NAMES ARE THE REAL ONES
DEMO 04 — FROM 27 TO 76 IN ONE PLANNED MOVE, BATCH BY BATCH
Accessibility

WCAG 2.2 AA, every fix in the changelog.

Audited and fixed, dated and versioned:

  • Info text went from 3.1:1 contrast to 7.2:1 — from failing AA to passing AAA. The demo below computes it live on the real hex values.
  • Focus indicator added to 21 of 27 components that lacked it.
  • Screen readers audited component by component: navigation, dialogs, alerts and states announced.
  • prefers-reduced-motion respected; no touch target below 44×44.
  • In dark, brand and accent move up one stop of the scale to hold contrast.
BEFORE — UP TO V0.2

Your license expires in 14 days. Renew to keep access.

--color-blue-400 · · ✗ FAILS AA
AFTER — V0.3

Your license expires in 14 days. Renew to keep access.

--color-blue-600 · · ✓ AAA
NAVIGATE WITH TAB — THE FOCUS RING REACHED 21 COMPONENTS THAT LACKED IT
THE RATIO IS COMPUTED LIVE ON THE REAL HEX VALUES — AND THE DEMO FOLLOWS THE SITE THEME: IN DARK IT SHOWS WHY THE OVERRIDE RE-POINTS THE TOKEN
DEMO 05 — CONTRAST MEASURED LIVE, AND VISIBLE FOCUS · INTERACTIVE
The state

Today: the suite's source of truth.

76 components with usage documentation (when to use it, when not to, anatomy, do's and don'ts), 76 isolated preview pages, 40 custom icons and 4 releases with a changelog. When design and production disagree, the system is the reference — and if the system is wrong, it gets fixed with a version.

The prototypes of all four products consume these same tokens: whatever gets approved in a prototype is already inside the system.

SHOWCASE CATALOG: 76 COMPONENTS · LIVE HERE: 6
Variants --primary --outline --ghost
Sizes and states --sm --md disabled
PICK A COMPONENT — WHAT RENDERS IS THE SYSTEM'S REAL CSS, AND THE READER SHOWS ITS API
DEMO 06 — THE SHOWCASE, IN THE PORTFOLIO'S SHELL: REAL COMPONENTS, LIVE · INTERACTIVE
In progress

A design system is never finished.

v0.4.0 left open work, tracked in the changelog:

  • Refactoring the forced styles that came in from staging. The promotion brought 11 !important declarations, a resource the system's own rules forbid because it makes it unpredictable which style wins. Nine turned out to be unnecessary and are already gone; the two that remain are a documented exception: the only way a mobile adjustment can win over styles the JS writes inline.
  • Dark mode verification, component by component. It was completed when the system had 27; the 49 promoted ones inherit the dark theme from the semantic layer, and their one-by-one review is in progress.
  • Behavior lives in each product, by decision. The system ships styles and structure, not JS: keyboard navigation in a modal or how a toast announces itself is implemented by each consumer, and the docs fix exactly what falls on each side.