color.
24 role tokens, and you never write a hex. you write a role, the theme decides what it means, and the same call site works in all three.
the two accents
two accents, not one. every place usva shows its own construction, a token name, a registry slug, the period in the wordmark, it uses the pair. what it is not for: decorating things at random. if both accents are on screen and neither means anything, you have spent the whole budget on nothing.
accentthe primary voice. one live control, one focal thing, per view.
accent-altthe paired second voice. the period in the wordmark, the other half of a two-series chart. never on its own.
three text tiers, and one hard rule
ink and muted both clear 4.5:1 on every surface, so anything a reader has to understand goes in one of them, units and placeholders and group labels included. faint sits near 2:1 on purpose, and may never be the only thing carrying a fact.
inkinformationalthis sentence is set in ink.
AA on every surface. anything a reader has to understand.
mutedinformationalthis sentence is set in muted.
AA too, and that is deliberate. secondary does not mean unreadable: units, placeholders, group labels all live here.
faintdecorativethis sentence is set in faint.
near 2:1 by design. a divider glyph, a dimmed icon behind content. it must never be the only thing carrying a piece of information.
read the faint line again. if you had to squint, that is the point: it is doing its job, and it is why nothing you need may ever be written in it. all 24 roles are in the table below.
all 24 roles, three themes
every swatch is live: each column is a real theme scope, painting the same class.
| role | kajo | sisu | savi | what it is for |
|---|---|---|---|---|
bg | #0a0613 | #0d0d11 | #e7dcc8 | the page ground. one per document. |
sunken | #0c0719 | #111117 | #d6cdb6 | below the ground: code blocks, wells, inset areas. |
surface | #100b1f | #15151c | #f1ead9 | a card, a panel, anything raised off the ground. |
surface-2 | #181328 | #1d1d28 | #faf4e5 | raised again. a row inside a card, a hovered cell. |
overlay | #0c0718 | #14141b | #f1ead9 | a dialog, a popover, a menu. it floats. |
scrim | rgba(10, 6, 19, 0.6) | rgba(13, 13, 17, 0.6) | rgba(58, 45, 32, 0.35) | the dimmed layer behind an overlay. |
inktext | #e6e3f2 | #ddddf0 | #33291d | primary text. AA on every surface role. |
mutedtext | #8b85a8 | #8282ab | #635544 | secondary text, and anything information bearing. still AA. |
faintdecorative | #4c4663 | #454565 | #96866c | decorative glyphs only. near 2:1 by design. |
on-accent | #0a0613 | #06140b | #f4efe2 | text and icons on an accent fill. |
on-sunken | #e6e3f2 | #ddddf0 | #2a1f14 | text inside a sunken well, usually code. |
on-tint | #a78bfa | #52c989 | #234f31 | text on an accent tint, not on the accent itself. |
accent | #a78bfa | #52c989 | #2f6a41 | the primary voice. the one live control. |
accent-2 | #8b5cf6 | #419648 | #234f31 | a supporting accent, for a second series or state. |
accent-alt | #52c989 | #74e3ad | #86562e | the paired second voice. the period in the wordmark. |
accent-tint | #2e254b | #203530 | #aec2a6 | a translucent accent fill you can put text on. |
accent-ink | #e6e3f2 | #ddddf0 | #33291d | accent used as text, contrast corrected for it. |
success | #52c989 | #4ad991 | #246e43 | it worked. |
warning | #e0b341 | #f0a84d | #81591f | it will not work for long. |
danger | #e0556b | #f06b6b | #a34238 | it broke, or it is about to. |
info | #6ea8fe | #5b8df6 | #3e6391 | neutral status, no alarm. |
border | #221c30 | #222228 | #d2c4a8 | the hairline. most separation is this. |
border-strong | #3a3350 | #34343d | #b6a37f | the edge you actually need to see. |
ring | #a78bfa | #52c989 | #2f6a41 | the focus ring. never removed, only restyled. |