Webzenia · design system

Foundations

The tokens everything is built from

Every value below resolves from @webzenia/tokens at runtime — primitive scales, semantic tokens, type, spacing, elevation, and motion. Nothing here is hand-typed; the swatches render the live token.

Colour

Two layers: primitive scales (raw oklch) and semantic tokens (what components consume). Components reference semantics only — never primitives. The brand hue is 262.236°.

Neutral scale

neutral-0oklch(1 0 0)
neutral-50oklch(.985 .004 250)
neutral-100oklch(.975 .006 250)
neutral-200oklch(.94 .006 250)
neutral-300oklch(.88 .008 250)
neutral-400oklch(.80 .008 250)
neutral-500oklch(.66 .010 250)
neutral-600oklch(.58 .010 250)
neutral-650oklch(.48 .010 250)
neutral-700oklch(.34 .010 250)
neutral-800oklch(.22 .008 250)
neutral-850oklch(.195 .007 250)
neutral-900oklch(.185 .006 250)
neutral-950oklch(.18 .012 250)
neutral-975oklch(.16 .005 250)
neutral-1000oklch(0 0 0)

Brand · blue scale

blue-50oklch(.97 .025 262)
blue-100oklch(.94 .05 262)
blue-200oklch(.88 .08 262)
blue-300oklch(.82 .11 262)
blue-400oklch(.74 .15 262)
blue-450oklch(.698 .148 262)
blue-500oklch(.622 .204 262)
blue-600oklch(.528 .217 262)
blue-700oklch(.46 .21 262)
blue-800oklch(.38 .18 262)
blue-900oklch(.30 .14 262)
blue-950oklch(.22 .09 262)

Status

success-500oklch(.62 .17 145)
error-500oklch(.62 .22 27)
warning-500oklch(.74 .16 75)
info-500oklch(.62 .19 240)

Semantic · surface

surface-base
surface-card
surface-elevated

Semantic · text

text-default
text-muted
text-accent
text-inverse

Semantic · border

border-faint
border-subtle
border-divider
border-default
border-strong
border-accent

Semantic · accent

accent-default
accent-fill
accent-hover
accent-emphasis

Semantic · status

success
error
warning
info
Blue budget: blue is the scarce accent — ≤ a few bursts per page (foundations/color-hierarchy.md). Default to monochrome; spend blue on the one thing that must be seen.

Typography

Role-based. Components render via <Text role='…'>, never inline font-size/weight. 142 roles exist, namespaced per surface; the reusable core is shown here.

Families

Ag
Söhne Display — H1/H2
Ag
Söhne — body 400/500
Ag
Domaine Display — hero H1
Ag
Söhne Mono — metadata/data-viz

Roles

display-xlDisplay XL
display-lDisplay L
section.h2

Section heading H2

section.h3

Section heading H3

section.h4

Section heading H4

section.subhead

Section subhead — supporting line under a heading.

body-large

Body large — the workhorse paragraph role for readable prose.

stat.number38%
mono-eyebrowmono · eyebrow
mono-tinymono · tiny

Spacing

A bespoke 25-step scale (--space-step-0 … 24). Components use step tokens for micro-spacing, semantic layout tokens for structure. Never raw px.

--space-step-1
--space-step-2
--space-step-3
--space-step-4
--space-step-5
--space-step-6
--space-step-7
--space-step-8
--space-step-9
--space-step-10
--space-step-11
--space-step-12
--space-step-13
--space-step-14
--space-step-15
--space-step-16
--space-step-17
--space-step-18
--space-step-19
--space-step-20

Radius

rounded-full reserved for pills/avatars; cards and panels use the rectangle scale.

--radius-1
--radius-2
--radius-3
--radius-4
--radius-5
--radius-6
--radius-7
--radius-8
--radius-10

Elevation · shadow

Solid content cards use a flat resting shadow; glow is a rare focal device (≤1 per page).

dark-cardcard resting elevation
dark-elevatedelevated / hover
glow-subtlesubtle focal glow
glow-primarybrand glow (rare, ≤1/page)

Glassmorphism · blur

Glass is for navigation, modals, and ambient decoration only — content cards are solid. Performance ceiling: blur() ≤ 16px (mid-range Android).

.glass-card · --blur-glass

Motion

Durations + easings. All motion wraps useReducedMotion() — Indian low-end devices often have battery-saver on.

120msinstant
140msmicro
150msfast
200msbase
200mspress
260msexpand
300msslow
320msmodal
360msfaq
500msslower
ease-defaultcubic-bezier(.16, 1, .3, 1)
ease-outcubic-bezier(0, 0, .2, 1)
ease-incubic-bezier(.4, 0, 1, 1)
ease-springcubic-bezier(.34, 1.56, .64, 1)