fjord-uiv0.1.0 / generation 1, "sounding"

Tokens

Generation 1, "sounding". One cold neutral ramp at oklch hue 245, read from opposite ends for light and dark, so the two schemes are one ramp rather than two hand-tuned palettes (COLOR-1). Every value here is public API: renaming one is a breaking change, and revaluing one is a CHANGELOG entry naming the old and new values, the reason, the blast radius and the invariant that governed the decision.

Light

colour

Every text token clears 4.5:1 against every surface it is permitted to sit on, and every meaningful boundary clears 3:1, with an empty exception list. The structural hairlines deliberately do NOT: a rule that encodes nothing has no floor, and the moment it encodes something it becomes --fj-mark. tests/contrast.rs asserts all of it against these values, parsed out of tokens.css rather than copied.

bg
surface
surface-sunk
rule
rule-strong
mark
ink
ink-2
muted
faint
primary
primary-half
primary-wash
select-wash
accent
accent-wash
add
add-wash
del
del-wash

type

Eight steps, and the whole hierarchy of a page lives inside them. The ladder is compressed on purpose (COLOR-8), so size, weight, tracking and position carry what an unconstrained palette would have carried in value.

size-1eyebrow, pill, kbd, column label. Uppercase.
size-2date, size, count, gutter number, keyhint
size-3nav, tab, button, commit subject, diff code
size-4base: row primary, names, clone command, prose
size-5sub-heading, lede
size-6section title
size-7page title
size-8display: 404, empty-state headline

weight and tracking

TYPE-5: weight does hierarchy at small sizes, size does it at large ones, never both at once.

weight-normal400 / body, data, prose
weight-medium500 / a row's primary name, a lede's emphasis
weight-strong600 / eyebrows, the wordmark
track-labelRepositories
track-capsread replica

what a forge actually reads

The worst case for a monospace is a page of shas, paths and refs, and it is fjord's normal case. 0/O, 1/l/I and rn/m have to be distinguishable at 11px.

disambiguation0O 1lI rn m {} [] () <> && || => != ->
object ids22b34a3 e6d13d5 fc626a9 0eedb7b b0d8188
pathssrc/views/layout.rs / deploy/provision-tailwind.sh

the full contract

Every token name in fjord_ui_core::tokens::ALL, in declaration order.

--fj-bg
--fj-surface
--fj-surface-sunk
--fj-rule
--fj-rule-strong
--fj-mark
--fj-ink
--fj-ink-2
--fj-muted
--fj-faint
--fj-primary
--fj-primary-fg
--fj-primary-half
--fj-primary-wash
--fj-select-wash
--fj-accent
--fj-accent-wash
--fj-add
--fj-add-wash
--fj-del
--fj-del-wash
--fj-hunk
--fj-hunk-wash
--fj-mod
--fj-destructive
--fj-destructive-fg
--fj-ring
--fj-ring-width
--fj-ring-offset
--fj-shadow-1
--fj-shadow-2
--fj-highlight
--fj-unit
--fj-space-0
--fj-space-1
--fj-space-2
--fj-space-3
--fj-space-4
--fj-space-5
--fj-space-6
--fj-space-7
--fj-row
--fj-row-tall
--fj-rail
--fj-node
--fj-node-merge
--fj-container
--fj-prose
--fj-hairline
--fj-marker
--fj-radius
--fj-mono
--fj-prose-family
--fj-size-1
--fj-size-2
--fj-size-3
--fj-size-4
--fj-size-5
--fj-size-6
--fj-size-7
--fj-size-8
--fj-leading-tight
--fj-leading-body
--fj-leading-code
--fj-track-tight
--fj-track-none
--fj-track-label
--fj-track-caps
--fj-weight-normal
--fj-weight-medium
--fj-weight-strong
--fj-dur-1
--fj-dur-2
--fj-dur-3
--fj-ease
--fj-ease-out
--fj-stagger
Dark

colour

Every text token clears 4.5:1 against every surface it is permitted to sit on, and every meaningful boundary clears 3:1, with an empty exception list. The structural hairlines deliberately do NOT: a rule that encodes nothing has no floor, and the moment it encodes something it becomes --fj-mark. tests/contrast.rs asserts all of it against these values, parsed out of tokens.css rather than copied.

bg
surface
surface-sunk
rule
rule-strong
mark
ink
ink-2
muted
faint
primary
primary-half
primary-wash
select-wash
accent
accent-wash
add
add-wash
del
del-wash

type

Eight steps, and the whole hierarchy of a page lives inside them. The ladder is compressed on purpose (COLOR-8), so size, weight, tracking and position carry what an unconstrained palette would have carried in value.

size-1eyebrow, pill, kbd, column label. Uppercase.
size-2date, size, count, gutter number, keyhint
size-3nav, tab, button, commit subject, diff code
size-4base: row primary, names, clone command, prose
size-5sub-heading, lede
size-6section title
size-7page title
size-8display: 404, empty-state headline

weight and tracking

TYPE-5: weight does hierarchy at small sizes, size does it at large ones, never both at once.

weight-normal400 / body, data, prose
weight-medium500 / a row's primary name, a lede's emphasis
weight-strong600 / eyebrows, the wordmark
track-labelRepositories
track-capsread replica

what a forge actually reads

The worst case for a monospace is a page of shas, paths and refs, and it is fjord's normal case. 0/O, 1/l/I and rn/m have to be distinguishable at 11px.

disambiguation0O 1lI rn m {} [] () <> && || => != ->
object ids22b34a3 e6d13d5 fc626a9 0eedb7b b0d8188
pathssrc/views/layout.rs / deploy/provision-tailwind.sh

the full contract

Every token name in fjord_ui_core::tokens::ALL, in declaration order.

--fj-bg
--fj-surface
--fj-surface-sunk
--fj-rule
--fj-rule-strong
--fj-mark
--fj-ink
--fj-ink-2
--fj-muted
--fj-faint
--fj-primary
--fj-primary-fg
--fj-primary-half
--fj-primary-wash
--fj-select-wash
--fj-accent
--fj-accent-wash
--fj-add
--fj-add-wash
--fj-del
--fj-del-wash
--fj-hunk
--fj-hunk-wash
--fj-mod
--fj-destructive
--fj-destructive-fg
--fj-ring
--fj-ring-width
--fj-ring-offset
--fj-shadow-1
--fj-shadow-2
--fj-highlight
--fj-unit
--fj-space-0
--fj-space-1
--fj-space-2
--fj-space-3
--fj-space-4
--fj-space-5
--fj-space-6
--fj-space-7
--fj-row
--fj-row-tall
--fj-rail
--fj-node
--fj-node-merge
--fj-container
--fj-prose
--fj-hairline
--fj-marker
--fj-radius
--fj-mono
--fj-prose-family
--fj-size-1
--fj-size-2
--fj-size-3
--fj-size-4
--fj-size-5
--fj-size-6
--fj-size-7
--fj-size-8
--fj-leading-tight
--fj-leading-body
--fj-leading-code
--fj-track-tight
--fj-track-none
--fj-track-label
--fj-track-caps
--fj-weight-normal
--fj-weight-medium
--fj-weight-strong
--fj-dur-1
--fj-dur-2
--fj-dur-3
--fj-ease
--fj-ease-out
--fj-stagger