Raft Design System

Foundations

Tokens

Every token group with its values in both modes, how token names are built, where tokens.json lives and how foundation.css is generated from it, and how to move off the deprecated names.

A token is a named value: a color, a shadow, a size. Components and products use the name, never the value, so a value can change in one place and every screen follows in both modes. This page is the reference for every token. The rules for choosing between tokens belong to the foundation that owns each group, linked from each section below.

Principles

  • One source. Every token in tokens.json is written once there. foundation.css is generated from it, and nothing else defines a token value.
  • Names say the role, not the color. attention, not pink; layer-canvas, not white. A token keeps its name when its value changes, and the dark value lives under the same name.
  • Use the role token before the palette. Reach for palette-* only where no role fits; see Color.
  • A value used three times becomes a token. A one-off value can stay inline, as an ink step or an oklch() literal; on its third use, add a token.

Where tokens live

FileWhat it holds
packages/ui/src/tokens.jsonThe source for colors, shadows, the focus ring and the metric tokens, in the Design Tokens Community Group format (2025.10). Published as @botiverse/raft-ui/tokens.json for tools outside CSS.
packages/ui/src/foundation.cssGenerated from tokens.json: every token as a CSS custom property, for light mode, dark mode and the system setting. Published as @botiverse/raft-ui/foundation.css for plain CSS.
packages/ui/src/styles.cssThe Tailwind entry. It imports foundation.css, maps tokens to utilities (bg-layer-canvas, text-foreground-muted, shadow-float) and defines the tokens that exist only as Tailwind theme values: radii, type styles and ease-slide.
packages/ui/src/fonts.cssThe font families: Space Grotesk, Space Mono and the Chinese fallbacks.

An app that uses Tailwind imports @botiverse/raft-ui/styles.css. A page without Tailwind imports @botiverse/raft-ui/foundation.css and reads the custom properties: var(--layer-canvas).

How foundation.css is generated

packages/ui/scripts/build-tokens.mjs reads tokens.json and writes foundation.css. Never edit foundation.css by hand.

sh
vp run @botiverse/raft-ui#build:tokens          # write src/foundation.css
node packages/ui/scripts/build-tokens.mjs --check   # exit 1 if it is out of date
  • Change a value in tokens.json, run build:tokens, and commit both files. A test (foundation.generated.test.ts) fails when foundation.css doesn't match tokens.json.
  • A token's path becomes its property name: {layer.canvas} is --layer-canvas. $root names the group itself: {foreground.$root} is --foreground. A reference ("{palette.cyan.800}") becomes var(--palette-cyan-800).
  • The format has no field for modes, so tokens.json adds an extension, build.botiverse.raft:
FieldMeaning
modes.darkThe dark-mode value. A token without it has the same value in both modes
scope: "root"A value that doesn't change with the mode, such as the palette: declared once on :root
scope: "every-mode"An alias of a token that changes with the mode: declared again in each mode scope, so it resolves against that mode's value
css: trueA value kept as a CSS expression that the format has no type for: color-mix(), a shadow with several layers
static: trueA deprecated alias of a value that doesn't change with the mode

The generated file has, in order:

  1. the palette, on :where(:root);
  2. light mode, on :where(:root) and .light;
  3. dark mode, on .dark;
  4. dark mode again under @media (prefers-color-scheme: dark) for a root without .light or .dark, so the page has the right colors before the app sets a class;
  5. the aliases declared in every mode, then the deprecated names.

A .light element inside a dark page is a light island, for a preview or a portal; the dark: variant in styles.css follows the nearest mode class. See Dark mode.

Token grammar

Names are built from a few parts, so a name you haven't seen tells you what it is for.

KindPatternExamples
Neutral roles{role}(-{purpose})(-{intensity})layer-canvas, foreground-hint, line-seam, fill-pressed, foreground-on-hud
Color roles{family}(-{slot})brand, brand-soft, danger-strong, info-muted
Ink stepsink-{alpha}ink-8, ink-40
Palettepalette-{color}-{step}palette-yellow-400, palette-lavender-800
Statusestask-status-{status}(-soft|-strong), presence-{state}task-status-in-review-soft, presence-busy
Stickerssticker-{part}sticker-ink, sticker-edge, sticker-pressed
Shadowselevation-{level}, focus-ringelevation-float, elevation-sticker
Metrics{part}-{property}field-font-size, card-title-line-height

Neutral roles. The role is one of four:

  • foreground-*: text and icons;
  • layer-*: a surface, in the order things stack (frame, sidebar, canvas, card, popover);
  • line-*: a line;
  • fill-*: a fill laid into or over a surface.

The purpose says where the token is used: frame, sidebar, canvas, card, popover, code, hud, on-frame, on-hud, link, field. Intensity runs from the bare name down to -muted, then -hint for text, and from -hairline through -seam to -strong for lines.

Color roles. The family is one of brand, attention, info, success, warning, danger or inactive. The slot says which shade:

SlotIs
bare (info)The solid color: a sticker's fill
-strongA deep shade, readable as text
-mutedA strong tint
-softA pale tint, without a border; see Soft tints
-foregroundText on the solid color, where a family has its own
-hover, -activeThe pair a solid fill takes on hover and press. A family has both or neither
-50 to -950The numbered ramp. Only brand and attention have one

Opacity. Every layer token is opaque except layer-backdrop, the scrim. fill-muted and fill-strong are opaque. fill-pressed, fill-frame-pressed and sticker-pressed are translucent: they are overlays laid on top of a control (Pressed overlays).

Utilities. A Tailwind utility is the property's prefix and the token name: bg-layer-card, text-foreground-muted, border-line-strong. Shadows are named apart: shadow-float for elevation-float, shadow-sticker for elevation-sticker, shadow-focus for focus-ring. The numbered palette steps are only custom properties, not utilities; the bare bg-palette-yellow and its siblings are the exception.

Token groups

Each block below is generated from tokens.json and shows the light and dark values.

Palette

The raw colors the roles point at. The rules for using them directly are in Color.

TokenLightDark
palette-yellow-50
#fff9ed
#fff9ed
palette-yellow-100
#fff6e3
#fff6e3
palette-yellow-200
#ffe9b9
#ffe9b9
palette-yellow-300
#ffdf91
#ffdf91
palette-yellow-400
#ffd441
#ffd441
palette-yellow-500
#d3ad03
#d3ad03
palette-yellow-600
#a78802
#a78802
palette-yellow-700
#7a6300
#7a6300
palette-yellow-800
#534300
#534300
palette-yellow-900
#2d2300
#2d2300
palette-yellow-950
#1c1500
#1c1500
palette-lavender-50
#f7f6fc
#f7f6fc
palette-lavender-100
#efecf9
#efecf9
palette-lavender-200
#dcd7f2
#dcd7f2
palette-lavender-300
#ccc4ec
#ccc4ec
palette-lavender-400
#bbafe6
#bbafe6
palette-lavender-500
#9d8ada
#9d8ada
palette-lavender-600
#7f62cb
#7f62cb
palette-lavender-700
#6341b0
#6341b0
palette-lavender-800
#442b7c
#442b7c
palette-lavender-900
#251548
#251548
palette-lavender-950
#170c31
#170c31
palette-pink-50
#fff0f4
#fff0f4
palette-pink-100
#ffe1e8
#ffe1e8
palette-pink-200
#fec1d2
#fec1d2
palette-pink-300
#fea0bc
#fea0bc
palette-pink-400
#fe7da8
#fe7da8
palette-pink-500
#fe2f8b
#fe2f8b
palette-pink-600
#d4086f
#d4086f
palette-pink-700
#9f0551
#9f0551
palette-pink-800
#700238
#700238
palette-pink-900
#42011e
#42011e
palette-pink-950
#2f0014
#2f0014
palette-cyan-50
#ecf9ff
#ecf9ff
palette-cyan-100
#d7f2fe
#d7f2fe
palette-cyan-200
#a9e6fe
#a9e6fe
palette-cyan-300
#68dafd
#68dafd
palette-cyan-400
#28ccf3
#28ccf3
palette-cyan-500
#1ea6c6
#1ea6c6
palette-cyan-600
#15849f
#15849f
palette-cyan-700
#0e6276
#0e6276
palette-cyan-800
#06414f
#06414f
palette-cyan-900
#02252f
#02252f
palette-cyan-950
#01161c
#01161c
palette-orange-50
#fef5f1
#fef5f1
palette-orange-100
#fde6de
#fde6de
palette-orange-200
#fbd1c0
#fbd1c0
palette-orange-300
#f9b899
#f9b899
palette-orange-400
#f8a16f
#f8a16f
palette-orange-500
#dd7e34
#dd7e34
palette-orange-600
#ad6127
#ad6127
palette-orange-700
#83481a
#83481a
palette-orange-800
#5b310f
#5b310f
palette-orange-900
#331905
#331905
palette-orange-950
#220e02
#220e02
palette-lime-50
#f1fde9
#f1fde9
palette-lime-100
#dcfac1
#dcfac1
palette-lime-200
#c0f588
#c0f588
palette-lime-300
#b4e67f
#b4e67f
palette-lime-400
#a9d877
#a9d877
palette-lime-500
#8ab261
#8ab261
palette-lime-600
#6b8b4a
#6b8b4a
palette-lime-700
#506836
#506836
palette-lime-800
#344522
#344522
palette-lime-900
#1c2711
#1c2711
palette-lime-950
#101808
#101808
palette-red-50
#fef1f0
#fef1f0
palette-red-100
#fddedd
#fddedd
palette-red-200
#fbbdb9
#fbbdb9
palette-red-300
#fa9991
#fa9991
palette-red-400
#f97264
#f97264
palette-red-500
#eb4423
#eb4423
palette-red-600
#bb3419
#bb3419
palette-red-700
#8e2510
#8e2510
palette-red-800
#621708
#621708
palette-red-900
#3e0b03
#3e0b03
palette-red-950
#280501
#280501
palette-stone-50
#f7f6f5
#f7f6f5
palette-stone-100
#efedeb
#efedeb
palette-stone-200
#e0dcd7
#e0dcd7
palette-stone-300
#d2cbc2
#d2cbc2
palette-stone-400
#c0b9b1
#c0b9b1
palette-stone-500
#9d9891
#9d9891
palette-stone-600
#7b7671
#7b7671
palette-stone-700
#5d5955
#5d5955
palette-stone-800
#3e3b38
#3e3b38
palette-stone-900
#23211f
#23211f
palette-stone-950
#141312
#141312
palette-cream-50
#fffdf9
#fffdf9
palette-cream-100
#fffcf5
#fffcf5
palette-cream-200
#fffaef
#fffaef
palette-cream-300
#f9eccf
#f9eccf
palette-cream-400
#ebd38f
#ebd38f
palette-cream-500
#d2b100
#d2b100
palette-cream-600
#a78c00
#a78c00
palette-cream-700
#7c6800
#7c6800
palette-cream-800
#554500
#554500
palette-cream-900
#312700
#312700
palette-cream-950
#191300
#191300

Text and icons

foreground and its tiers, and the text colors for the frame and the HUD. Usage and contrast: Color, Typography.

TokenLightDark
foreground
#141111
#e5e5e2
foreground-muted
#141111 / 68%
#c4c4c1
foreground-hint
#141111 / 62%
#9e9e9b
foreground-disabled
#141111 / 30%
#636360
foreground-inverse
#ffffff
#1b1b19
foreground-on-hud
#f3f3f5
#e5e5e2
foreground-on-hud-mutedSecondary text on the HUD: the shortcut in a tooltip, the detail line of a toast.
#f3f3f5 / 70%
#c4c4c1foreground-muted
foreground-on-frame
#141111sticker-ink
#e5e5e2
foreground-on-frame-muted
#564919
#9e9e9b
foreground-on-frame-active
#141111sticker-ink
#141111sticker-ink
foreground-link
#1447e6
#8ec5ff
foreground-active
#141111foreground
#e5e5e2foreground
foreground-hover
#141111foreground
#e5e5e2foreground

Surfaces

Usage: Color.

TokenLightDark
layer-canvas
#ffffff
#1b1b19
layer-sidebar
#fffaef
#0d0d0b
layer-popover
#ffffff
#292927
layer-backdrop
#000000 / 65%
#000000 / 60%
layer-card
#ffffff
#242422
layer-hud
#252429
#292927
layer-frame
#ffd440
#0d0d0b
layer-frame-active
#ffffff
#ffd440
layer-code
#ffffff
#0a0c10

Fills

Usage: Color and Pressed overlays.

TokenLightDark
fill-muted
#f3f3f3
#32322f
fill-strong
#eaeaea
#3a3a37
fill-frame-pressed
#141111 / 12%
#fafaf7 / 8%
fill-pressed
#141111 / 8%
#fafaf7 / 8%

Lines

Usage and widths: Color, Shape.

TokenLightDark
line-strong
#141111
#e5e5e2
line-seam
#141111 / 45%
#fafaf7 / 26%
line-hairline
#141111 / 15%
#fafaf7 / 10%
line-frame-active
#141111sticker-ink
#141111sticker-ink
line-field
#141111line-strong
#e5e5e2line-strong
line-field-hover
#141111line-strong
#e5e5e2line-strong

Ink steps

Translucent steps of ink that lines, secondary text and overlays are made from. Use the role tokens; reach for an ink step only for a one-off wash.

TokenLightDark
ink-2
#141111 / 2%
#fafaf7 / 2%
ink-4
#141111 / 4%
#fafaf7 / 4%
ink-6
#141111 / 6%
#fafaf7 / 6%
ink-8
#141111 / 8%
#fafaf7 / 8%
ink-10
#141111 / 10%
#fafaf7 / 10%
ink-16
#141111 / 16%
#fafaf7 / 16%
ink-20
#141111 / 20%
#fafaf7 / 20%
ink-30
#141111 / 30%
#fafaf7 / 30%
ink-40
#141111 / 40%
#fafaf7 / 40%
ink
#141111
#fafaf7

Color roles

What each color means: Meanings of color.

TokenLightDark
brand-50
#fff9edpalette-yellow-50
#fff9edpalette-yellow-50
brand-100
#fff6e3palette-yellow-100
#fff6e3palette-yellow-100
brand-200
#ffe9b9palette-yellow-200
#ffe9b9palette-yellow-200
brand-300
#ffdf91palette-yellow-300
#ffdf91palette-yellow-300
brand-400
#ffd440
#ffd440
brand-500
#d3ad03palette-yellow-500
#d3ad03palette-yellow-500
brand-600
#a78802palette-yellow-600
#a78802palette-yellow-600
brand-700
#7a6300palette-yellow-700
#7a6300palette-yellow-700
brand-800
#534300palette-yellow-800
#534300palette-yellow-800
brand-900
#2d2300palette-yellow-900
#2d2300palette-yellow-900
brand-950
#1c1500palette-yellow-950
#1c1500palette-yellow-950
brand-strong
#564919
#ffd440
brand-soft
#fff0bd
#876f1f / 16%
brand-edge
#141111sticker-ink
#141111sticker-ink
brand-glow
#ffd440
#ffd440
brand-hoverPressing a sticker lays sticker-pressed (12% ink) over its colour.
color-mix(in srgb, var(--brand-400) 88%, var(--sticker-ink))
color-mix(in srgb, var(--brand-400) 88%, var(--sticker-ink))
brand-active
color-mix(in srgb, var(--brand-400) 88%, var(--sticker-ink))brand-hover
color-mix(in srgb, var(--brand-400) 88%, var(--sticker-ink))brand-hover
TokenLightDark
attention-50
#fff0f4palette-pink-50
#fff0f4palette-pink-50
attention-100
#ffe1e8palette-pink-100
#ffe1e8palette-pink-100
attention-200
#fec1d2palette-pink-200
#fec1d2palette-pink-200
attention-300
#fea0bcpalette-pink-300
#fea0bcpalette-pink-300
attention-400
#ff99c3
#ff99c3
attention-500
#fe7da8palette-pink-400
#fe7da8palette-pink-400
attention-600
#d4086fpalette-pink-600
#d4086fpalette-pink-600
attention-700
#9f0551palette-pink-700
#9f0551palette-pink-700
attention-800
#700238palette-pink-800
#700238palette-pink-800
attention-900
#42011epalette-pink-900
#42011epalette-pink-900
attention-950
#2f0014palette-pink-950
#2f0014palette-pink-950
attention-strong
#c00064
#ffacc7
attention-soft
#ffd6e2
#d0457c / 16%
attention-hover
color-mix(in srgb, var(--attention-400) 88%, var(--sticker-ink))
color-mix(in srgb, var(--attention-400) 88%, var(--sticker-ink))
attention-active
color-mix(in srgb, var(--attention-400) 88%, var(--sticker-ink))attention-hover
color-mix(in srgb, var(--attention-400) 88%, var(--sticker-ink))attention-hover
TokenLightDark
infoEvery solid is a sticker: ink type on the colour in both modes.
#27ccf3
#27ccf3
info-strong
#06414fpalette-cyan-800
#6ccdea
info-muted
#a9e6fepalette-cyan-200
#007592 / 28%
info-soft
#d7f2fe
#005f7a / 18%
info-hover
color-mix(in srgb, var(--info) 88%, var(--sticker-ink))
color-mix(in srgb, var(--info) 88%, var(--sticker-ink))
info-active
color-mix(in srgb, var(--info) 88%, var(--sticker-ink))info-hover
color-mix(in srgb, var(--info) 88%, var(--sticker-ink))info-hover
TokenLightDark
success
#a9d877
#a9d877
success-foreground
#141111sticker-ink
#141111sticker-ink
success-strong
#344522palette-lime-800
#b7e18c
success-muted
#c0f588palette-lime-200
#0c7d43 / 28%
success-soft
#dcfac1
#167641 / 18%
TokenLightDark
warning
#f8a16f
#f8a16f
warning-foreground
#141111sticker-ink
#141111sticker-ink
warning-strong
#5b310fpalette-orange-800
#ffaf76
warning-muted
#fbd1c0palette-orange-200
#ac571d / 28%
warning-soft
#fde6de
#9e511e / 18%
warning-hover
color-mix(in srgb, var(--warning) 88%, var(--sticker-ink))
color-mix(in srgb, var(--warning) 88%, var(--sticker-ink))
warning-active
color-mix(in srgb, var(--warning) 88%, var(--sticker-ink))warning-hover
color-mix(in srgb, var(--warning) 88%, var(--sticker-ink))warning-hover
TokenLightDark
dangerdanger = the destructive sticker (red fill, ink type); danger-strong is the error ink for invalid fields and destructive menu items.
#f97264
#f97264
danger-foreground
#141111sticker-ink
#141111sticker-ink
danger-strong
#b5321a
#f8a49d
danger-muted
#fbbdb9palette-red-200
#d33c30 / 30%
danger-soft
#fddedd
#c93126 / 18%
danger-hover
color-mix(in srgb, var(--danger) 88%, var(--sticker-ink))
color-mix(in srgb, var(--danger) 88%, var(--sticker-ink))
danger-active
color-mix(in srgb, var(--danger) 88%, var(--sticker-ink))danger-hover
color-mix(in srgb, var(--danger) 88%, var(--sticker-ink))danger-hover
TokenLightDark
inactive
#c0b9b1
#c0b9b1
inactive-foreground
#141111sticker-ink
#141111sticker-ink
inactive-soft
#e0dcd7
#32322f

Statuses

Task statuses and presence lights: Statuses.

TokenLightDark
task-status-todo
#f8a16f
#ff6900
task-status-todo-soft
#fde6de
#9e511e / 18%
task-status-todo-strong
#5b310fpalette-orange-800
#ffaf76
task-status-in-progress
#27ccf3
#27ccf3
task-status-in-progress-soft
#d7f2fe
#005f7a / 18%
task-status-in-progress-strong
#06414fpalette-cyan-800
#6ccdea
task-status-in-review
#bbafe6
#9d8ada
task-status-in-review-soft
#efecf9
#6853a0 / 24%
task-status-in-review-strong
#442b7cpalette-lavender-800
#ccc4ecpalette-lavender-300
task-status-done
#a9d877
#20c16b
task-status-done-soft
#dcfac1
#167641 / 18%
task-status-done-strong
#344522palette-lime-800
#6ed892
task-status-closed
#c0b9b1
#8f8f8d
task-status-closed-soft
#e0dcd7
#32322f
task-status-closed-strong
#3e3b38palette-stone-800
#9e9e9b
TokenLightDark
presence-online
#a9d877
#a9d877
presence-busy
#ffd440
#ffd440
presence-error
#f8a16f
#f8a16f
presence-offline
#c0b9b1
#c0b9b1
presence-external
#27ccf3
#27ccf3

Stickers

Usage: Stickers.

TokenLightDark
sticker-ink
#141111
#141111
sticker-paper
#ffffff
#ffffff
sticker-edge
#141111 / 0%
#fafaf7 / 35%
sticker-pressed
#141111 / 12%
#141111 / 12%

Shadows and the focus ring

Usage: Elevation, Accessibility.

TokenLightDark
elevation-floatControls never cast a shadow; only overlays float.
0 1px 0 oklch(0.1813 0.005 17.62 / 0.039), 0 12px 32px -12px oklch(0.1813 0.005 17.62 / 0.322)
0 0 0 1px oklch(0.9843 0.004 106.47 / 0.078), 0 16px 40px -12px oklch(0 0 0 / 0.8)
elevation-sticker
4px 4px 0 oklch(0.1813 0.005 17.62)
4px 4px 0 oklch(0 0 0)
TokenLightDark
focus-ring
0 0 0 2px oklch(1 0 0), 0 0 0 4px oklch(0.1813 0.005 17.62)
0 0 0 2px oklch(0.2213 0.0038 106.71), 0 0 0 4px oklch(0.9211 0.004 106.48)

Metrics

The type metrics a field and a card title share with the parts laid out beside them. Usage: Typography.

TokenLightDark
field-font-size16px16px
field-font-weight400400
field-line-height24px24px
TokenLightDark
card-title-font-size16px16px
card-title-font-weight600600
card-title-line-height24px24px

Tokens defined in styles.css

These are Tailwind theme values in styles.css, not entries in tokens.json, so they have no generated table.

TokensOwner
radius-sticker, radius-chip, radius-control, radius-container, radius-dialogShape
text-hero to text-label, text-mono-meta, text-mono-codeTypography
ease-slideMotion
font-sans, font-heading, font-monoTypography

Deprecated names

Earlier names are kept as aliases until raft-ui 1.0, in the deprecated group of tokens.json. Each one points at the token to use instead, so old code keeps working while it moves.

TokenLightDark
layer-panel#fffffflayer-canvas#1b1b19layer-canvas
layer-inset#f3f3f3fill-muted#32322ffill-muted
layer-canvas-muted#fffaeflayer-sidebar#0d0d0blayer-sidebar
layer-hud-foreground#f3f3f5foreground-on-hud#e5e5e2foreground-on-hud
foreground-strong#141111foreground#e5e5e2foreground
foreground-icon#141111 / 68%foreground-muted#c4c4c1foreground-muted
foreground-placeholder#141111 / 62%foreground-hint#9e9e9bforeground-hint
line#141111 / 45%line-seam#fafaf7 / 26%line-seam
line-muted#141111 / 15%line-hairline#fafaf7 / 10%line-hairline
primary-50#fff9edbrand-50#fff9edbrand-50
primary-100#fff6e3brand-100#fff6e3brand-100
primary-200#ffe9b9brand-200#ffe9b9brand-200
primary-300#ffdf91brand-300#ffdf91brand-300
primary-400#ffd440brand-400#ffd440brand-400
primary-500#d3ad03brand-500#d3ad03brand-500
primary-600#a78802brand-600#a78802brand-600
primary-700#7a6300brand-700#7a6300brand-700
primary-800#534300brand-800#534300brand-800
primary-900#2d2300brand-900#2d2300brand-900
primary-950#1c1500brand-950#1c1500brand-950
primary-strong#564919brand-strong#ffd440brand-strong
primary-soft#fff0bdbrand-soft#876f1f / 16%brand-soft
primary-edge#141111brand-edge#141111brand-edge
primary-glow#ffd440brand-glow#ffd440brand-glow
primary-hovercolor-mix(in srgb, var(--brand-400) 88%, var(--sticker-ink))brand-hovercolor-mix(in srgb, var(--brand-400) 88%, var(--sticker-ink))brand-hover
primary-activecolor-mix(in srgb, var(--brand-400) 88%, var(--sticker-ink))brand-activecolor-mix(in srgb, var(--brand-400) 88%, var(--sticker-ink))brand-active
accent-50#fff0f4attention-50#fff0f4attention-50
accent-100#ffe1e8attention-100#ffe1e8attention-100
accent-200#fec1d2attention-200#fec1d2attention-200
accent-300#fea0bcattention-300#fea0bcattention-300
accent-400#ff99c3attention-400#ff99c3attention-400
accent-500#fe7da8attention-500#fe7da8attention-500
accent-600#d4086fattention-600#d4086fattention-600
accent-700#9f0551attention-700#9f0551attention-700
accent-800#700238attention-800#700238attention-800
accent-900#42011eattention-900#42011eattention-900
accent-950#2f0014attention-950#2f0014attention-950
accent-strong#c00064attention-strong#ffacc7attention-strong
accent-soft#ffd6e2attention-soft#d0457c / 16%attention-soft
accent-hovercolor-mix(in srgb, var(--attention-400) 88%, var(--sticker-ink))attention-hovercolor-mix(in srgb, var(--attention-400) 88%, var(--sticker-ink))attention-hover
accent-activecolor-mix(in srgb, var(--attention-400) 88%, var(--sticker-ink))attention-activecolor-mix(in srgb, var(--attention-400) 88%, var(--sticker-ink))attention-active
theme-shadow-xs
0 0 #0000
0 0 #0000
theme-shadow-sm
0 0 #0000
0 0 #0000
theme-shadow-md
0 0 #0000
0 0 #0000
theme-shadow-lg0 1px 0 oklch(0.1813 0.005 17.62 / 0.039), 0 12px 32px -12px oklch(0.1813 0.005 17.62 / 0.322)elevation-float0 0 0 1px oklch(0.9843 0.004 106.47 / 0.078), 0 16px 40px -12px oklch(0 0 0 / 0.8)elevation-float
theme-shadow-xl0 1px 0 oklch(0.1813 0.005 17.62 / 0.039), 0 12px 32px -12px oklch(0.1813 0.005 17.62 / 0.322)elevation-float0 0 0 1px oklch(0.9843 0.004 106.47 / 0.078), 0 16px 40px -12px oklch(0 0 0 / 0.8)elevation-float
theme-shadow-float0 1px 0 oklch(0.1813 0.005 17.62 / 0.039), 0 12px 32px -12px oklch(0.1813 0.005 17.62 / 0.322)elevation-float0 0 0 1px oklch(0.9843 0.004 106.47 / 0.078), 0 16px 40px -12px oklch(0 0 0 / 0.8)elevation-float
theme-shadow-sticker4px 4px 0 oklch(0.1813 0.005 17.62)elevation-sticker4px 4px 0 oklch(0 0 0)elevation-sticker
theme-focus-ring0 0 0 2px oklch(1 0 0), 0 0 0 4px oklch(0.1813 0.005 17.62)focus-ring0 0 0 2px oklch(0.2213 0.0038 106.71), 0 0 0 4px oklch(0.9211 0.004 106.48)focus-ring
color-brutal-yellow-50#fff9edpalette-yellow-50#fff9edpalette-yellow-50
color-brutal-yellow-100#fff6e3palette-yellow-100#fff6e3palette-yellow-100
color-brutal-yellow-200#ffe9b9palette-yellow-200#ffe9b9palette-yellow-200
color-brutal-yellow-300#ffdf91palette-yellow-300#ffdf91palette-yellow-300
color-brutal-yellow-400#ffd441palette-yellow-400#ffd441palette-yellow-400
color-brutal-yellow-500#d3ad03palette-yellow-500#d3ad03palette-yellow-500
color-brutal-yellow-600#a78802palette-yellow-600#a78802palette-yellow-600
color-brutal-yellow-700#7a6300palette-yellow-700#7a6300palette-yellow-700
color-brutal-yellow-800#534300palette-yellow-800#534300palette-yellow-800
color-brutal-yellow-900#2d2300palette-yellow-900#2d2300palette-yellow-900
color-brutal-yellow-950#1c1500palette-yellow-950#1c1500palette-yellow-950
color-brutal-purple-50#f7f6fcpalette-lavender-50#f7f6fcpalette-lavender-50
color-brutal-purple-100#efecf9palette-lavender-100#efecf9palette-lavender-100
color-brutal-purple-200#dcd7f2palette-lavender-200#dcd7f2palette-lavender-200
color-brutal-purple-300#ccc4ecpalette-lavender-300#ccc4ecpalette-lavender-300
color-brutal-purple-400#bbafe6palette-lavender-400#bbafe6palette-lavender-400
color-brutal-purple-500#9d8adapalette-lavender-500#9d8adapalette-lavender-500
color-brutal-purple-600#7f62cbpalette-lavender-600#7f62cbpalette-lavender-600
color-brutal-purple-700#6341b0palette-lavender-700#6341b0palette-lavender-700
color-brutal-purple-800#442b7cpalette-lavender-800#442b7cpalette-lavender-800
color-brutal-purple-900#251548palette-lavender-900#251548palette-lavender-900
color-brutal-purple-950#170c31palette-lavender-950#170c31palette-lavender-950
color-brutal-pink-50#fff0f4palette-pink-50#fff0f4palette-pink-50
color-brutal-pink-100#ffe1e8palette-pink-100#ffe1e8palette-pink-100
color-brutal-pink-200#fec1d2palette-pink-200#fec1d2palette-pink-200
color-brutal-pink-300#fea0bcpalette-pink-300#fea0bcpalette-pink-300
color-brutal-pink-400#fe7da8palette-pink-400#fe7da8palette-pink-400
color-brutal-pink-500#fe2f8bpalette-pink-500#fe2f8bpalette-pink-500
color-brutal-pink-600#d4086fpalette-pink-600#d4086fpalette-pink-600
color-brutal-pink-700#9f0551palette-pink-700#9f0551palette-pink-700
color-brutal-pink-800#700238palette-pink-800#700238palette-pink-800
color-brutal-pink-900#42011epalette-pink-900#42011epalette-pink-900
color-brutal-pink-950#2f0014palette-pink-950#2f0014palette-pink-950
color-brutal-cyan-50#ecf9ffpalette-cyan-50#ecf9ffpalette-cyan-50
color-brutal-cyan-100#d7f2fepalette-cyan-100#d7f2fepalette-cyan-100
color-brutal-cyan-200#a9e6fepalette-cyan-200#a9e6fepalette-cyan-200
color-brutal-cyan-300#68dafdpalette-cyan-300#68dafdpalette-cyan-300
color-brutal-cyan-400#28ccf3palette-cyan-400#28ccf3palette-cyan-400
color-brutal-cyan-500#1ea6c6palette-cyan-500#1ea6c6palette-cyan-500
color-brutal-cyan-600#15849fpalette-cyan-600#15849fpalette-cyan-600
color-brutal-cyan-700#0e6276palette-cyan-700#0e6276palette-cyan-700
color-brutal-cyan-800#06414fpalette-cyan-800#06414fpalette-cyan-800
color-brutal-cyan-900#02252fpalette-cyan-900#02252fpalette-cyan-900
color-brutal-cyan-950#01161cpalette-cyan-950#01161cpalette-cyan-950
color-brutal-orange-50#fef5f1palette-orange-50#fef5f1palette-orange-50
color-brutal-orange-100#fde6depalette-orange-100#fde6depalette-orange-100
color-brutal-orange-200#fbd1c0palette-orange-200#fbd1c0palette-orange-200
color-brutal-orange-300#f9b899palette-orange-300#f9b899palette-orange-300
color-brutal-orange-400#f8a16fpalette-orange-400#f8a16fpalette-orange-400
color-brutal-orange-500#dd7e34palette-orange-500#dd7e34palette-orange-500
color-brutal-orange-600#ad6127palette-orange-600#ad6127palette-orange-600
color-brutal-orange-700#83481apalette-orange-700#83481apalette-orange-700
color-brutal-orange-800#5b310fpalette-orange-800#5b310fpalette-orange-800
color-brutal-orange-900#331905palette-orange-900#331905palette-orange-900
color-brutal-orange-950#220e02palette-orange-950#220e02palette-orange-950
color-brutal-lime-50#f1fde9palette-lime-50#f1fde9palette-lime-50
color-brutal-lime-100#dcfac1palette-lime-100#dcfac1palette-lime-100
color-brutal-lime-200#c0f588palette-lime-200#c0f588palette-lime-200
color-brutal-lime-300#b4e67fpalette-lime-300#b4e67fpalette-lime-300
color-brutal-lime-400#a9d877palette-lime-400#a9d877palette-lime-400
color-brutal-lime-500#8ab261palette-lime-500#8ab261palette-lime-500
color-brutal-lime-600#6b8b4apalette-lime-600#6b8b4apalette-lime-600
color-brutal-lime-700#506836palette-lime-700#506836palette-lime-700
color-brutal-lime-800#344522palette-lime-800#344522palette-lime-800
color-brutal-lime-900#1c2711palette-lime-900#1c2711palette-lime-900
color-brutal-lime-950#101808palette-lime-950#101808palette-lime-950
color-brutal-red-50#fef1f0palette-red-50#fef1f0palette-red-50
color-brutal-red-100#fddeddpalette-red-100#fddeddpalette-red-100
color-brutal-red-200#fbbdb9palette-red-200#fbbdb9palette-red-200
color-brutal-red-300#fa9991palette-red-300#fa9991palette-red-300
color-brutal-red-400#f97264palette-red-400#f97264palette-red-400
color-brutal-red-500#eb4423palette-red-500#eb4423palette-red-500
color-brutal-red-600#bb3419palette-red-600#bb3419palette-red-600
color-brutal-red-700#8e2510palette-red-700#8e2510palette-red-700
color-brutal-red-800#621708palette-red-800#621708palette-red-800
color-brutal-red-900#3e0b03palette-red-900#3e0b03palette-red-900
color-brutal-red-950#280501palette-red-950#280501palette-red-950
color-brutal-stone-50#f7f6f5palette-stone-50#f7f6f5palette-stone-50
color-brutal-stone-100#efedebpalette-stone-100#efedebpalette-stone-100
color-brutal-stone-200#e0dcd7palette-stone-200#e0dcd7palette-stone-200
color-brutal-stone-300#d2cbc2palette-stone-300#d2cbc2palette-stone-300
color-brutal-stone-400#c0b9b1palette-stone-400#c0b9b1palette-stone-400
color-brutal-stone-500#9d9891palette-stone-500#9d9891palette-stone-500
color-brutal-stone-600#7b7671palette-stone-600#7b7671palette-stone-600
color-brutal-stone-700#5d5955palette-stone-700#5d5955palette-stone-700
color-brutal-stone-800#3e3b38palette-stone-800#3e3b38palette-stone-800
color-brutal-stone-900#23211fpalette-stone-900#23211fpalette-stone-900
color-brutal-stone-950#141312palette-stone-950#141312palette-stone-950
color-brutal-cream-50#fffdf9palette-cream-50#fffdf9palette-cream-50
color-brutal-cream-100#fffcf5palette-cream-100#fffcf5palette-cream-100
color-brutal-cream-200#fffaefpalette-cream-200#fffaefpalette-cream-200
color-brutal-cream-300#f9eccfpalette-cream-300#f9eccfpalette-cream-300
color-brutal-cream-400#ebd38fpalette-cream-400#ebd38fpalette-cream-400
color-brutal-cream-500#d2b100palette-cream-500#d2b100palette-cream-500
color-brutal-cream-600#a78c00palette-cream-600#a78c00palette-cream-600
color-brutal-cream-700#7c6800palette-cream-700#7c6800palette-cream-700
color-brutal-cream-800#554500palette-cream-800#554500palette-cream-800
color-brutal-cream-900#312700palette-cream-900#312700palette-cream-900
color-brutal-cream-950#191300palette-cream-950#191300palette-cream-950
secondary-50#f7f6f5palette-stone-50#f7f6f5palette-stone-50
secondary-100#efedebpalette-stone-100#efedebpalette-stone-100
secondary-200#e0dcd7palette-stone-200#e0dcd7palette-stone-200
secondary-300#d2cbc2palette-stone-300#d2cbc2palette-stone-300
secondary-400#c0b9b1palette-stone-400#c0b9b1palette-stone-400
secondary-500#9d9891palette-stone-500#9d9891palette-stone-500
secondary-600#7b7671palette-stone-600#7b7671palette-stone-600
secondary-700#5d5955palette-stone-700#5d5955palette-stone-700
secondary-800#3e3b38palette-stone-800#3e3b38palette-stone-800
secondary-900#23211fpalette-stone-900#23211fpalette-stone-900
secondary-950#141312palette-stone-950#141312palette-stone-950

The renames follow a few patterns:

text
primary-*                  ->  brand-*
accent-*                   ->  attention-*
color-brutal-{color}-{n}   ->  palette-{color}-{n}   (purple -> lavender)
secondary-{n}              ->  palette-stone-{n}
layer-panel                ->  layer-canvas
layer-canvas-muted         ->  layer-sidebar
layer-inset                ->  fill-muted
layer-hud-foreground       ->  foreground-on-hud
foreground-strong          ->  foreground
foreground-icon            ->  foreground-muted
foreground-placeholder     ->  foreground-hint
line                       ->  line-seam
line-muted                 ->  line-hairline
theme-shadow-float/lg/xl   ->  elevation-float       (utility: shadow-float)
theme-shadow-sticker       ->  elevation-sticker     (utility: shadow-sticker)
theme-focus-ring           ->  focus-ring            (utility: shadow-focus)
theme-shadow-xs/sm/md      ->  none: controls cast no shadow, drop the class

The codemod

raft-ui ships a codemod that rewrites the old names in Tailwind utilities (bg-…, hover:border-…/50) and in CSS custom properties (var(--…)):

sh
node node_modules/@botiverse/raft-ui/codemods/token-names.mjs <dir-or-file>... [--dry]
  • It rewrites .ts, .tsx, .js, .jsx, .mjs, .cjs, .css and .html files, and skips node_modules, dist and build. --dry lists the files it would change.
  • It renames references and leaves declarations alone, so running it twice is safe.
  • Review the result by hand. A guard that forbade an old name (a lint rule, a test, an allowlist) now forbids the new one, and a pattern built from parts, such as a regular expression over class names, keeps the old name.
  • The docs never use a deprecated name: scripts/check-docs.mjs fails a page that does.

Changing a token

  • Add or change a value only in tokens.json, then regenerate foundation.css in the same change.
  • Give a new token a name that follows the grammar above, and add its utility to styles.css if components need one.
  • Rename a token by keeping the old name in the deprecated group, pointing at the new one, and adding the rename to the codemod. Remove aliases only in a major version.
  • When a text, surface or tint value changes, recheck the contrast guarantees in Color for both modes.
  • Update the foundation page that owns the token in the same pull request (Authoring).
  • Color: what each color token is for, and the contrast it guarantees.
  • Typography: the type styles and the metric tokens.
  • Elevation: shadows and the focus ring.
  • Dark mode: what changes between the modes.