Raft Design System

Foundations

Color

The surface, text, line and role colors, what each color means, and the contrast they guarantee.

Color in Raft works in two ways. Surfaces get less color from the outside in: the yellow frame, then the cream sidebar, then white paper where content sits. On top of that, each brand color has one fixed meaning, so a color on screen always tells the person something: who they are, what waits for them, or what a status is. A color that means none of these is removed.

Principles

  • Yellow goes on the frame only. The frame is on every screen but nobody reads it, so color there costs almost nothing. Everything people read (messages, lists, cards, the content of pushed pages) sits on paper. The frame is the desktop rail, the web top bar and the top bar of a phone's top-level pages; see Page structure.
  • Each color has one meaning. Yellow is you, pink is to do, cyan is this item, orange interrupts, red is irreversible. Status colors are fixed too; see Meanings of color.
  • A block of brand color is a sticker. It has a 1.5px ink edge and ink type on it, in both modes; see Stickers.
  • Notices are neutral. Toasts and tooltips are dark gray, not a brand color.

Tokens

Surfaces

Surfaces step down in color from the frame inward. In light mode layer-canvas, layer-card and layer-popover are all white and are told apart by lines; in dark mode they are told apart by lightness, each one lighter than the one beneath it.

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
TokenUse for
layer-frameThe frame: the top bar of a phone's top-level pages, the desktop rail, the web top bar
layer-sidebarThe desktop sidebar
layer-canvasPaper: the desktop main area, every phone screen
layer-cardRaised containers: cards, inset groups, inputs, the composer, the tab bar
layer-popoverPopups: menus, drawers, bottom sheets, dialogs, profile cards
fill-mutedSunken fills: tracks, inline code, skeletons, neutral tiles, reactions, thread previews
layer-codeCode blocks and command lines
layer-hudToasts and tooltips; text on it is foreground-on-hud and foreground-on-hud-muted
layer-backdropThe scrim behind centered overlays, modal drawers, bottom sheets and the lightbox

Fills are laid into or over a surface: the sunken fill and the pressed overlays (Pressed overlays).

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

Text and icons

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
TokenUse for
foregroundInk: body text, titles, control borders
foreground-mutedSecondary text: previews, descriptions, labels
foreground-hintTertiary text: times, IDs, group headings, placeholders
foreground-disabledDisabled text and icons
foreground-linkLinks in running text
danger-strongError text: the border and help text of an invalid input, a failed upload

Lines

There are three kinds of line, and each one means something. See Shape for their widths.

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
TokenMeaningUse for
line-hairlineInside contentList dividers, card outlines
line-seamBetween regionsRail and sidebar, a header and its content, the edge of a menu, drawer or dialog
line-strongThis is a controlThe 1.5px ink border of controls and the edge of stickers

Lines, secondary text and overlays are made from translucent steps of ink. Use the role tokens above; the steps are listed for reference.

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

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

Meanings of color

ColorRoleMeansUse for
YellowbrandYouThe frame, the selected item in navigation, an on switch, the location tile of the place you are in, a mention of you, search hits; your workspace (yellow on ink)
PinkattentionTo doAt most one primary button per screen; unread counts and attention dots
CyaninfoThis item, informationIn Progress, runtimes, external agents, progress bars; info-soft for the item singled out in content, an active filter, an info banner
OrangewarningInterruptsButtons that stop, leave or reset; warnings; Todo; the error presence light
ReddangerIrreversibleDelete buttons
LimesuccessDoneDone, online, success banners
Lavenderpalette-lavender-*—In Review, and people without a photo
StoneinactiveClosedClosed, offline
  • Use orange when something goes wrong: red is only for consequences that cannot be undone.
  • Use blue (foreground-link) only for links in running text.
  • Lime, lavender and stone only mark a status. Don't use them for anything else.

Statuses

Tasks and presence each have five colors, and they never change meaning. Task statuses are spelled Todo, In Progress, In Review, Done and Closed.

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
Task statusTokenPresence lightToken
Todo (orange)task-status-todoOnline (lime)presence-online
In Progress (cyan)task-status-in-progressBusy (yellow)presence-busy
In Review (lavender)task-status-in-reviewError (orange)presence-error
Done (lime)task-status-doneOffline (stone)presence-offline
Closed (stone)task-status-closedExternal agent (cyan)presence-external
TokenLightDark
presence-online
#a9d877
#a9d877
presence-busy
#ffd440
#ffd440
presence-error
#f8a16f
#f8a16f
presence-offline
#c0b9b1
#c0b9b1
presence-external
#27ccf3
#27ccf3
  • Put a status chip on its task-status-*-soft tint.
  • presence-busy has its own value instead of pointing at brand, so that a change of brand color doesn't change what busy looks like.
  • Presence lights never blink; see Motion.

Soft tints

A soft tint (*-soft) is a highlight, never a sticker: it has no border.

TintUse for
brand-softMenu highlight, the busy chip, text selection
info-softThe selected item in content, filters, info banners, runtime chips, thread references, a message inside a notification
attention-softChannel references, a reaction you added
success-softSuccess banners, the Done chip
warning-softWarning banners, the Todo chip, errors and warnings in notifications
danger-softDanger banners
task-status-in-review-softThe In Review chip
task-status-closed-softThe Closed chip

Pressed overlays

Hover and press lay a translucent overlay over a control instead of changing its fill; see States.

TokenOver
fill-pressedPaper-colored controls and content; hover uses it too
sticker-pressedStickers
fill-frame-pressedAnything on the frame

Stickers

A sticker is a block of brand color: avatars, the selected item, the location tile, the primary button, badges.

  • Give every block of brand color a 1.5px line-strong edge: stickers and paper are only 1.4:1 to 2.8:1 apart, so without an edge a sticker doesn't hold its shape.
  • Put ink type on a sticker (sticker-ink), never white, in both modes.
  • Don't invert stickers in dark mode. Sticker colors have the same value in both modes; dark mode adds the die-cut edge instead (see Dark mode).
  • Don't put a shadow on a control. The hard sticker shadow is only for brand illustration; see Elevation.
TokenLightDark
sticker-ink
#141111
#141111
sticker-paper
#ffffff
#ffffff
sticker-edge
#141111 / 0%
#fafaf7 / 35%
sticker-pressed
#141111 / 12%
#141111 / 12%

Contrast

  • foreground, foreground-muted and foreground-hint are at least 4.5:1 on every surface, every soft tint and every popup, in both modes. There are no exceptions to remember.
  • Ink on a sticker is at least 6.8:1.
  • line-seam is 3.0:1 on white and 2.8:1 on yellow.

Palette

The role tokens point at a small palette. Use the palette directly only where no role fits, such as lavender for people without a photo. The palette tokens are palette-<color>-<step>, with the bare utilities bg-palette-<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
  • Dark mode: what changes and what stays in dark mode.
  • States: the colors of hover, selection, unread and error.
  • Brand: how much brand color each kind of page may use.
  • Button: which button color to use for which action.