skynet

Tokens

166 tokens, one source

Defined in W3C Design Tokens JSON under packages/ui/tokens. The build emits CSS custom properties (the names below with dots as hyphens, e.g. --color-text-accent), TypeScript, a Figma variables file, and the contrast report. Colour swatches below are rendered live in each theme.

Type roles

Fifteen roles replace eighteen sizes

type.display-xl · clamp(42px, 6.8vw, 84px) / 1.1 · 700 · -0.03em
Find real edge.
The landing hero.
type.display-lg · clamp(32px, 4.6vw, 52px) / 1.1 · 700 · -0.03em
Find real edge.
Page titles.
type.display-md · clamp(28px, 4.5vw, 40px) / 1.1 · 700 · -0.02em
Find real edge.
Section titles.
type.display-sm · clamp(22px, 3vw, 30px) / 1.1 · 700 · -0.02em
Find real edge.
Sub-section titles.
type.heading · 20px / 1.4 · 700 · -0.02em
Every signal is marked at close against a fixed source.
Card and panel headings.
type.body-lg · 16px / 1.6 · 400 · 0em
Every signal is marked at close against a fixed source.
Lead paragraphs.
type.body · 15px / 1.7 · 400 · 0em
Every signal is marked at close against a fixed source.
Running text.
type.body-sm · 13px / 1.6 · 400 · 0em
Every signal is marked at close against a fixed source.
Dense UI text, table cells.
type.label · 11px / 1.4 · 500 · 0.08em
Every signal is marked at close against a fixed source.
Form labels, table headers, stat captions.
type.eyebrow · 11px / 1.4 · 500 · 0.12em
Every signal is marked at close against a fixed source.
The mono line above a section title.
type.caption · 11px / 1.6 · 400 · 0.08em
Every signal is marked at close against a fixed source.
Notes under a control.
type.code · 13px / 1.6 · 400 · 0em
skynet verify --provider 299M…rpDh
Addresses, signatures, code.
type.data · 14px / 1.4 · 500 · 0em
+0.41 n=127
Numbers in tables and stats. Mono so columns align.
type.control · 16px / 1.4 · 400 · 0em
Every signal is marked at close against a fixed source.
Text typed into a field. 16px so iOS does not zoom.
type.button · 14px / 1.4 · 600 · 0em
Every signal is marked at close against a fixed source.
Button labels.
Semantic colour

Roles, themed

Each swatch shows the same role in dark and light. Tokens marked with a requirement are checked against it on every build; see Accessibility.

Tokens
TokenValue (dark / light)Description
color.surface.page
→ color.neutral.950
#0d0d0d#f5f5f5The page ground.
color.surface.raised
→ color.neutral.900
#1a1a1a#ffffffCards, inputs, table rows: one step above the page.
color.surface.sunken
→ color.neutral.850
#252525#e8e8e8Wells, code blocks, hover fills.
color.surface.overlay
→ color.neutral.900
#1a1a1a#ffffffMenus and popovers that float over content.
color.surface.scrim#000000a6#00000066Behind a modal dialog. Dims the page without hiding it.
color.text.primary
→ color.neutral.150
#e0e0e0#1a1a1aHeadings and body.
color.text.secondary
→ color.neutral.300
#c0c0c0#333333
color.text.muted
→ color.neutral.400
#a0a0a0#666666Captions, labels, supporting copy. Still body-text contrast: muted is a tone, not an excuse.
color.text.accent
→ color.green.300
#16ff9a#16ff9aAccent used as text: links, the italic word in a display heading.
color.text.link
→ color.green.300
#16ff9a#16ff9a
color.text.on-accent
→ color.neutral.1000
#000000#000000Text on the accent fill, e.g. the primary button label.
color.text.disabled
→ color.neutral.600
#666666#a0a0a0Disabled text is exempt from contrast minimums (WCAG 1.4.3); never the only cue.
color.accent.fill
→ color.green.300
#16ff9a#16ff9aThe brand fill: the same green in both themes. On light it sits near 1.2:1 against the page, so the boundary of anything filled with it is drawn by accent.edge, not by the fill.
color.accent.fill-hover
→ color.green.400
#12cc7a#12cc7a
color.accent.edge
→ color.green.300
#16ff9a#007a20The boundary of a filled accent control. Dark: the fill's own green, invisible. Light: a darker green so the edge clears 3:1 against the page (WCAG 1.4.11).
color.border.subtle#4a4a4a8c#d0d0d08cDecorative hairlines that divide sections. Exempt from 1.4.11 because they convey nothing on their own.
color.border.default
→ color.neutral.700
#4a4a4a#d0d0d0Card and table outlines. Decorative.
color.border.control
→ color.neutral.500
#767676#8a8a8aThe boundary of anything you can type into or toggle. 3:1 per WCAG 1.4.11.
color.border.focus
→ color.green.300
#16ff9a#16ff9aThe focus ring. 3:1 against whatever it sits on.
color.status.win
→ color.green.300
#16ff9a#16ff9a
color.status.loss
→ color.red.400
#ff4444#cc0000
color.status.pending
→ color.amber.400
#ffa500#a85a00
color.decor.pink
→ color.pink.400
#ff6b9d#e85a8aSecond colour on divider segments only. Never text.
Semantic roles, theme-independent
Tokens
TokenValueDescription
layout.gutter
→ space.500
20pxPage side padding.
layout.section
→ space.1600
64pxVertical gap between page sections.
layout.stack-sm
→ space.200
8px
layout.stack-md
→ space.400
16px
layout.stack-lg
→ space.800
32px
layout.measure
→ size.measure
680px
layout.container
→ size.container
1200px
layout.page-top
→ space.2000
80pxSpace above a page's title, below the site header.
layout.page-gap
→ space.2500
100pxSpace between a page header and the first section.
motion.hover
→ duration.fast
100msColour and border changes on hover and focus.
motion.reveal
→ duration.base
200msThings appearing: menus, status messages.
motion.ease
→ easing.standard
[0.2,0,0,1]
motion.exit
→ duration.fast
100msThings leaving. Shorter than reveal: attention is already moving on.
motion.press
→ duration.fast
100msPress feedback on buttons: the scale down and back.
focus.ring-width
→ border-width.thick
2px
focus.ring-offset
→ space.50
2px
shadow.overlay
→ shadow.overlay-dark
{"color":"#000000a6","offsetX":"0px","offsetY":"8px","blur":"24px","spread":"0px"}
shadow.raised
→ shadow.raised-dark
{"color":"#ffffff1f","offsetX":"0px","offsetY":"0px","blur":"0px","spread":"1px"}
Component tokens

Owned by one component each, and allowed to reference semantic tokens only.

Tokens
TokenValueDescription
button.height
→ size.control-md
40px
button.height-sm
→ size.control-sm
32px
button.radius
→ radius.md
6px
button.padding-x
→ space.500
20px
field.height
→ size.control-md
40px
field.radius
→ radius.md
6px
field.padding-x
→ space.300
12px
field.bg
→ color.surface.page
#0d0d0d#f5f5f5
field.border
→ color.border.control
#767676#8a8a8a
table.cell-padding-x
→ space.400
16px
table.cell-padding-y
→ space.300
12px
table.row-border
→ color.border.subtle
#4a4a4a8c#d0d0d08c
badge.radius
→ radius.sm
2px
badge.padding-x
→ space.150
6px
panel.radius
→ radius.md
6px
panel.padding
→ space.600
24px
panel.bg
→ color.surface.raised
#1a1a1a#ffffff
panel.border
→ color.border.default
#4a4a4a#d0d0d0
Primitives

Raw values. Never referenced by a component; the test suite checks. Groups: color, space, font, radius, border-width, duration, easing, shadow, size.

Tokens
TokenValueDescription
color.neutral.0#ffffff#ffffff
color.neutral.50#f5f5f5#f5f5f5
color.neutral.100#e8e8e8#e8e8e8
color.neutral.150#e0e0e0#e0e0e0
color.neutral.200#d0d0d0#d0d0d0
color.neutral.300#c0c0c0#c0c0c0
color.neutral.400#a0a0a0#a0a0a0
color.neutral.450#8a8a8a#8a8a8a
color.neutral.500#767676#767676
color.neutral.600#666666#666666
color.neutral.700#4a4a4a#4a4a4a
color.neutral.800#333333#333333
color.neutral.850#252525#252525
color.neutral.900#1a1a1a#1a1a1a
color.neutral.950#0d0d0d#0d0d0d
color.neutral.1000#000000#000000
color.green.300#16ff9a#16ff9aThe brand accent on dark.
color.green.400#12cc7a#12cc7a
color.green.600#00aa2e#00aa2eThe original light-theme accent. 2.8:1 on the light page, so it is no longer used for text.
color.green.700#008824#008824
color.green.800#007a20#007a20Darkened until it clears 4.5:1 on the light page and carries white text.
color.red.400#ff4444#ff4444
color.red.700#cc0000#cc0000
color.amber.400#ffa500#ffa500
color.amber.700#a85a00#a85a00The original #ff8800 is 2.4:1 on the light page.
color.pink.400#ff6b9d#ff6b9d
color.pink.600#e85a8a#e85a8a
space.00px
space.251px
space.502px
space.1004px
space.1506px
space.2008px
space.30012px
space.40016px
space.50020px
space.60024px
space.80032px
space.100040px
space.160064px
space.200080px
space.2500100px
font.family.sans["var(--font-sans)","-apple-system","BlinkMacSystemFont","Segoe UI","Roboto","sans-serif"]Inter, self-hosted by the app through next/font.
font.family.mono["var(--font-mono)","ui-monospace","SFMono-Regular","Menlo","monospace"]JetBrains Mono.
font.size.5010px
font.size.7511px
font.size.10012px
font.size.20013px
font.size.30014px
font.size.35015px
font.size.40016px
font.size.50020px
font.size.60024px
font.size.display-smclamp(22px, 3vw, 30px)
font.size.display-mdclamp(28px, 4.5vw, 40px)
font.size.display-lgclamp(32px, 4.6vw, 52px)
font.size.display-xlclamp(42px, 6.8vw, 84px)
font.weight.regular400
font.weight.medium500
font.weight.semibold600
font.weight.bold700
font.leading.tight1.1
font.leading.snug1.4
font.leading.normal1.6
font.leading.relaxed1.7
font.tracking.display-0.03em
font.tracking.tight-0.02em
font.tracking.normal0em
font.tracking.label0.08em
font.tracking.eyebrow0.12em
radius.none0px
radius.sm2px
radius.md6px
radius.lg10px
radius.full9999px
border-width.hairline1px
border-width.thick2px
duration.instant0ms
duration.fast100ms
duration.base200ms
duration.slow320ms
easing.standard[0.2,0,0,1]
shadow.overlay-dark{"color":"#000000a6","offsetX":"0px","offsetY":"8px","blur":"24px","spread":"0px"}
shadow.overlay-light{"color":"#0000002e","offsetX":"0px","offsetY":"8px","blur":"24px","spread":"0px"}
shadow.raised-dark{"color":"#ffffff1f","offsetX":"0px","offsetY":"0px","blur":"0px","spread":"1px"}
shadow.raised-light[{"color":"#0000000f","offsetX":"0px","offsetY":"0px","blur":"0px","spread":"1px"},{"color":"#0000000f","offsetX":"0px","offsetY":"1px","blur":"2px","spread":"-1px"},{"color":"#0000000a","offsetX":"0px","offsetY":"2px","blur":"4px","spread":"0px"}]
size.control-sm32px
size.control-md40px
size.control-lg48px
size.target-min24pxWCAG 2.2 target size (minimum), 2.5.8.
size.measure680pxLongest comfortable line of running text.
size.container1200px