Every value in Bracket has a name. A colour that appears in a component and is not in this reference is a bug in that component.
Tokens exist in two layers. The primitive layer is a palette: --bk-blue-60, --bk-grey-10. Nothing in a component may read a primitive directly. The semantic layer says what a value is for: --bk-color-surface, --bk-color-text-muted. Components read only semantic tokens, which is what makes a theme a change of one file rather than a change of forty.
Naming
--bk-<category>-<role>-<modifier>
--bk-color-surface-raised
--bk-color-text-muted
--bk-space-4
--bk-radius-smFour rules, applied without exception:
- The prefix is always
bk. It is short because it is typed hundreds of times a day. - The category is one of
color,space,size,text,radius,border,shadow,z. - The role says what the value is for, never what it looks like.
--bk-color-text-muted, not--bk-color-text-grey. - The modifier is optional and always last:
-raised,-hover,-inverse,-strong.
Colour
Semantic colours only. Each one resolves to a different primitive in light and dark, and both pairs are checked for contrast on every build.
--bk-color-surface—grey-00light,grey-95dark. The page behind everything.--bk-color-surface-raised—grey-00light,grey-88dark. Cards, dialogs, menus. In light theme it is the same value as the page and is separated by a border instead.--bk-color-surface-sunken—grey-04light,grey-98dark. Wells, table headers, code blocks.--bk-color-text—grey-95light,grey-06dark. Body text, and the default for anything that does not say otherwise.--bk-color-text-muted—grey-60light,grey-45dark. Descriptions, captions, disabled labels. Never for anything a person has to read to complete a task.--bk-color-border—grey-16light,grey-78dark. Every one-pixel line in the system that is not a table rule.--bk-color-border-strong—grey-32light,grey-62dark. Table rules and separators that carry meaning.--bk-color-accent—blue-60light,blue-48dark. The single accent: links, focus ring, selection, the primary button.--bk-color-accent-hover—blue-68light,blue-40dark. Hover and active states on accent surfaces.--bk-color-danger—red-58light,red-50dark. Destructive actions and error text.--bk-color-warning—amber-52light,amber-46dark. Warnings that are not errors.--bk-color-success—green-52light,green-44dark. Confirmed, saved, passed.
There is one accent. Requests for a second have been declined three times; a system with two accents has no accent.
Space
A four-pixel scale, eleven steps. Every margin, padding and gap in every component is one of these values.
--bk-space-1— 4px. Between an icon and its label.--bk-space-2— 8px. Inside a small control.--bk-space-3— 12px. Between related lines of text.--bk-space-4— 16px. The default gap, and the one to reach for first.--bk-space-5— 24px. Padding inside a card.--bk-space-6— 32px. Between cards.--bk-space-7— 48px. Between groups in a form.--bk-space-8— 64px. Between sections of a page.--bk-space-9— 96px. Between major blocks on a marketing page.--bk-space-10— 128px. Rare, and only at the top of a page.--bk-space-11— 160px. Used twice in the whole system.
There is no --bk-space-0: zero is zero.
Type
One family, Kalder Mono, at six sizes and two weights. The measure is wide on purpose: this system is for dense product interfaces and reference pages, not for magazines.
token size line used for
--------------------------------------------------------------
--bk-text-xs 12px 16px table metadata, badges
--bk-text-sm 14px 20px secondary text, captions
--bk-text-base 16px 26px body, and the default everywhere
--bk-text-lg 20px 28px subheadings, lead paragraphs
--bk-text-xl 28px 34px section headings
--bk-text-2xl 40px 46px page headings, one per pageWeights are --bk-weight-regular (400) and --bk-weight-bold (600). There is no medium; adding one produced pairs nobody could tell apart in review.
Radius, border, elevation
token value note
--------------------------------------------------------------
--bk-radius-none 0 tables, code blocks, the sidebar
--bk-radius-sm 2px inputs, buttons, badges
--bk-radius-md 4px cards, dialogs, menus
--bk-radius-full 9999px avatars, and the one pill
--bk-border-width 1px the only border width
--bk-shadow-raised 0 1px 2px menus and dialogs, nothing elseRadii are small because the type is monospaced and a large radius next to a fixed-width grid reads as an accident. There is one shadow. Depth in Bracket is expressed with borders and surface colour; the shadow exists only for elements that float over content that is still visible underneath.
Consuming them
import '@kalder/bracket/tokens.css';
.summary {
background: var(--bk-color-surface-raised);
border: var(--bk-border-width) solid var(--bk-color-border);
border-radius: var(--bk-radius-md);
padding: var(--bk-space-5);
}The same values are published as @kalder/bracket/tokens.json for anything that is not CSS, and as a Figma variable collection generated by the same build. All three come from one source file, tokens/source.yaml, and cannot drift apart.