Theming
A department changes the theme by overriding custom properties. No component code changes, and no recompile — unlike systems that theme at Sass compile time, one build can serve many departments.
:root {
--gov-primary: #005ea8;
--gov-primary-hover: #004f8f;
}
Components consume semantic tokens and never repeat raw values, so they do not care which blue is selected.
Density
Administrative software is read all day. Density is a mode set once on a container, never a prop threaded through every component:
<div data-gov-density="compact"> ... </div>
Two tokens that are easy to get wrong
Focus is not derived from the primary color
A navy focus ring on a navy primary button is invisible. Yellow alone does not solve it
either — #ffdd00 is about 1.1:1 against a white page. The ring is two-tone: a
yellow band inside a dark one, so whichever surface it lands on, one of its edges carries the
contrast.
If you re-theme --gov-focus, check it against every surface it can land on,
including your primary button.
There are two border tokens
A decorative table rule and the edge of a text input have different jobs. WCAG 2.2 requires 3:1 for the latter (SC 1.4.11) and nothing for the former.
| Token | Use |
|---|---|
--gov-border | Decoration: table rules, dividers, card edges |
--gov-border-strong | Interactive control edges: inputs, secondary buttons |
Collapsing them into one light grey is among the most common ways a design system quietly fails that criterion.
Internationalization
Two defaults that feel neutral and are not:
- Line-height is floored at 1.4. Devanagari matras sit above and below the baseline and clip at the ~1.2 heading line-height most design systems use. Bengali, Tamil and Gurmukhi behave the same way.
- Only logical CSS properties are used —
padding-inline,border-inline-start— so components mirror correctly underdir="rtl"without a second set of rules.