Docs
GitHub

Tokens

A design token is a named value that components reference instead of hard-coding: a color, a spacing step, a font size. Change the value once and everything pointing at it updates. In SINA, tokens are CSS custom properties, all prefixed --sina-.

Three tiers

Primitive value#4a5a3fa raw hex in theme.css
Semantic role--sina-color-primarywhat it means
Component token--sina-button-bgwhere it’s used
Change the value once; every component that points at the role updates.
  • Primitive: a raw value in theme.css, like a specific green.
  • Semantic: a role that gives the value meaning. --sina-color-primary means "the primary action color," whatever that happens to be.
  • Component: a token scoped to one component, like --sina-button-bg, which points at a semantic role.

You almost always reach for the semantic tier. It answers "what does this color mean," not "what hex is it." That's why a theme can re-value a role and every component follows.

The naming grammar

One rule, so you can read a name and know what it does:

  • A single dash joins the identity (category, role, property): --sina-color-text-muted, --sina-button-bg.
  • A double dash marks a leaf modifier (a scale step, variant, or state), and it always comes last: --sina-space--4, --sina-color-primary--hover, --sina-button-bg--primary--hover.

Read it like a sentence

--sina-button-bg--primary--hover = the button's background, primary variant, hover state. Identity first, modifiers last.

Color

Pick colors by role ("the primary action color"), never by hue ("the green one"). Click a swatch to copy its variable.

Every surface role has a -fg partner: the color guaranteed readable on it. Use primary for a button's background and primary-fg for its label, and contrast takes care of itself. The status roles work the same way:

Two rules are enforced by build guards: colors are authored hex-only in theme.css (#rrggbb, never rgb() / hsl() / named colors), and component CSS never writes a raw color, only var(--sina-*). Status colors like danger, plus the focus ring and secure-surface tint, are governance-locked. See the locked boundary.

The scales

Everything that isn't color is a small, fixed set of steps. Sticking to the steps keeps a UI rhythmic instead of arbitrary.

FamilyTokens
Space--sina-space--0--24 on a 4px base, half-steps --0_5 · --1_5 · --2_5
Text size--sina-text--xs · ui · sm · base · lg · xl · 2xl5xl
Weight / leading--sina-font-weight--regular…bold · --sina-leading--none…relaxed
Radius--sina-radius--none · xs · sm · md · lg · xl · 2xl · full
Shadow--sina-shadow--xs…xl · focus · focus-ring
Motion--sina-duration--instant…slow · --sina-ease--standard · out
Z-index--sina-z--base · dropdown · overlay · modal · toast

Reduced motion is automatic

Durations collapse to zero under prefers-reduced-motion at the token layer, so every component respects the setting with no per-component code.

How tokens reach components

Each component declares its own token layer, where --sina-button-bg--primary aliases --sina-color-primary, and its CSS consumes only that layer. So a theme re-values a semantic role once, and every component slot pointing at it updates. That indirection is the whole theming mechanism.