Color
The SWSH palette and the roles that give it purpose, in dark and light.
SWSH Orange
#EE421BLight orange
#FFB78ADark orange
#2D0800Brand white
#EFEFEFLight gray
#DEDEDEGray
#A5A5A5Medium gray
#222222Dark gray
#101010Brand black
#040404The five ramps run from 50, the lightest step, to 950, the darkest, with 500 as the base. Each published brand hex is an exact anchor step; every other step is interpolated in OKLCH between its nearest anchors.
Red, green, and amber support status UI and have no brand source.
White and black alpha ramps use eight-digit hex; the last pair represents opacity. Judge them on their actual backdrop, not as opaque colors.
5%#FFFFFF0D10%#FFFFFF1A20%#FFFFFF3330%#FFFFFF4D40%#FFFFFF6650%#FFFFFF8060%#FFFFFF9970%#FFFFFFB380%#FFFFFFCC90%#FFFFFFE65%#0000000D10%#0000001A20%#0000003330%#0000004D40%#0000006650%#0000008060%#0000009970%#000000B380%#000000CC90%#000000E6True white and black are for logo variants and alpha bases. For surfaces, use a role such as bg.canvas or bg.surface rather than a primitive; the light theme’s bg.surface is the role that resolves to white.
A primitive says what a value is; a role says what it is for. Every role references a palette primitive through THEME_REFS.
bg.canvasblackbg.surfacegray[950]text.primarygray[100]text.mutedgray[400]accent.defaultorange[500]fill.raised.defaultgray[900]bg
Canvas, surfaces, and the scrim.
fill
Interactive surfaces with default, hover, and pressed states.
text
Primary, muted, disabled, and inks for named fills.
border
Subtle hairlines, default dividers, and strong emphasis.
accent
The brand orange.
status
Success, warning, and danger indicators.
tint
Soft tinted fills with a matching ink — badge tones and the card icon square.
Card and search surfaces
Card and web SearchResults/Root share getCardSurface from swshd/tokens: fill.raised.default in dark mode and bg.surface in light mode. Filled SearchBar/Field shares Input's interactive surface: fill.raised.hover at rest and fill.raised.pressed on hover or focus. Compose these parts without overriding their backgrounds.
Native search results and the full-screen search header use bg.canvas, matching the app background. Recent rows are transparent at rest; touch feedback encloses the query and its secondary action in one shared row. Selected items retain their selection fill.
Overlay frames
Dialogs, sheets, and alerts use OVERLAY_SURFACE_TOKENS from swshd/tokens. Their frame uses bg.elevated; a search card inside the frame still uses the shared card surface.
Rows on surfaces
Use fill.subtle on bg.surface for rows. fill.selected is the active row’s steady backdrop, not another hover state.
Disabled is not a color
Touchable applies opacity to disabled controls, so no fill has a disabled state. text.disabled is the ink for disabled text.
Every role, its primitive reference, and resolved color in the selected theme.
bg| Role | Primitive | Hex |
|---|---|---|
black | ||
gray[950] | ||
gray[950] | ||
black | ||
blackAlpha[50] |
fill| Role | Primitive | Hex |
|---|---|---|
gray[100] | ||
gray[200] | ||
gray[300] | ||
gray[900] | ||
gray[800] | ||
gray[700] | ||
transparent | ||
whiteAlpha[10] | ||
whiteAlpha[20] | ||
red[600] | ||
red[700] | ||
red[800] | ||
transparent | ||
whiteAlpha[5] | ||
whiteAlpha[10] | ||
gray[800] | ||
gray[800] | ||
gray[800] |
text| Role | Primitive | Hex |
|---|---|---|
gray[100] | ||
gray[400] | ||
white | ||
gray[600] | ||
gray[950] | ||
gray[950] | ||
gray[100] |
border| Role | Primitive | Hex |
|---|---|---|
gray[900] | ||
gray[800] | ||
gray[400] |
accent| Role | Primitive | Hex |
|---|---|---|
orange[500] | ||
orange[300] | ||
orange[950] |
status| Role | Primitive | Hex |
|---|---|---|
green[500] | ||
amber[500] | ||
red[500] |
tint| Role | Primitive | Hex |
|---|---|---|
orange[950] | ||
orange[300] | ||
green[950] | ||
green[400] | ||
amber[950] | ||
amber[500] | ||
red[950] | ||
red[400] |
Every role exists in both built-in themes. A nested provider can re-theme a subtree; custom themes use createSwshdTheme over a built-in base.
import SwshdThemeProvider from "swshd/ThemeProvider";
<SwshdThemeProvider theme="light">
<AlbumPreview />
</SwshdThemeProvider>Ratios cover the canvas inks, on-accent ink, and every fill state. Alpha fills are composited over their intended surface before they are graded.
| Pair | Ratio | Grade |
|---|---|---|
Aa text.primary on bg.canvas | 18.26:1 | AAA |
Aa text.muted on bg.canvas | 8.53:1 | AAA |
Aa text.onAccent on accent.default | 5.30:1 | AA |
Aa text.inverse on fill.inverse.default | 17.83:1 | AAA |
Aa text.inverse on fill.inverse.hover | 15.24:1 | AAA |
Aa text.inverse on fill.inverse.pressed | 11.39:1 | AAA |
Aa text.primary on fill.raised.default | 16.55:1 | AAA |
Aa text.primary on fill.raised.hover | 13.84:1 | AAA |
Aa text.primary on fill.raised.pressed | 9.16:1 | AAA |
Aa text.primary on fill.ghost.default composited over bg.canvas | 18.26:1 | AAA |
Aa text.primary on fill.ghost.hover composited over bg.canvas | 15.14:1 | AAA |
Aa text.primary on fill.ghost.pressed composited over bg.canvas | 10.99:1 | AAA |
Aa text.onDanger on fill.danger.default | 5.31:1 | AA |
Aa text.onDanger on fill.danger.hover | 7.74:1 | AAA |
Aa text.onDanger on fill.danger.pressed | 11.09:1 | AAA |
Aa text.primary on fill.subtle.default composited over bg.surface | 17.83:1 | AAA |
Aa text.primary on fill.subtle.hover composited over bg.surface | 16.42:1 | AAA |
Aa text.primary on fill.subtle.pressed composited over bg.surface | 14.50:1 | AAA |
Aa text.primary on fill.selected.default | 13.84:1 | AAA |
Aa text.primary on fill.selected.hover | 13.84:1 | AAA |
Aa text.primary on fill.selected.pressed | 13.84:1 | AAA |
colors.text.primaryUse a role.
#EE421BCopy a hex.
Fill buttons with their variant role.
Fill a button with SWSH Orange.
colors.bg.surfaceBuild surfaces from bg roles.
Use white or black as a surface.
import { useSwshdTheme } from "swshd/ThemeProvider";
import Text from "swshd/Text";
const { colors } = useSwshdTheme();
<Text variant="body-md" color={colors.text.primary}>
Share the whole night
</Text>