Rendered, not swatched
Your palette on a real page.
This whole surface is painted from the tokens TEMPER derived for the Dark mode at the default notch. Change mode, notch, or vision in the rail and every element here moves with it. Here is an inline link, some inline code, and a bit of emphasis in running text, so the accent and text roles all show at once.
Type and hierarchy
A third-level heading
Primary body text sits on the base background and carries the bulk of the reading. It is judged against your contrast target in the audit below.
Secondary text carries supporting detail at a lower emphasis, still comfortably legible.
Tertiary and muted text for the quietest labels and captions.
A blockquote, offset by an accent border and a subtle tint, for a passage pulled out of the flow.
Actions
Tab into any control to see the focus ring.
Forms
Status and feedback
Data
| Name | Role | Status |
|---|---|---|
| Ada Lovelace | Owner | active |
| Bev Turing | Editor | invited |
| Cy Shannon | Viewer | new |
Cards and elevation
Resting card
A card on the surface role with a small shadow.
Raised card
The same, lifted with the medium shadow.
Code
:root {
--color-accent: #AF97FF;
--color-bg-base: #16151B;
--color-surface: #28272D;
}The audit
Every meaningful pairing, its measured WCAG contrast, and whether it clears its floor, across all four modes at the default notch and default vision. Text pairs against your target; focus and de-emphasized text against the 3:1 non-text floor; borders are decorative. Misses are named, not hidden.
No meaning by color alone. Some status colors read alike once color is gone (success and warning, success and danger, warning and danger), so each must also carry a label or an icon, never color alone. The vision-safe palettes above separate them by luminance if you would rather solve it in the palette.
All 52 judged pairings clear their floor at AA.
Light
| Pairing | Ratio | vs floor |
|---|---|---|
| Primary text | 15.95:1 | pass |
| Secondary text | 9.26:1 | pass |
| Primary on surface | 17.72:1 | pass |
| Secondary on surface | 10.29:1 | pass |
| Link | 7.51:1 | pass |
| Link on surface | 8.34:1 | pass |
| Button label | 6.00:1 | pass |
| Code | 13.95:1 | pass |
| Success | 7.02:1 | pass |
| Warning | 7.01:1 | pass |
| Danger | 6.98:1 | pass |
| Tertiary text | 6.37:1 | pass |
| Focus ring | 5.98:1 | pass |
| Border | 1.45:1 | decorative |
Soft Light
| Pairing | Ratio | vs floor |
|---|---|---|
| Primary text | 14.93:1 | pass |
| Secondary text | 8.66:1 | pass |
| Primary on surface | 20.13:1 | pass |
| Secondary on surface | 11.67:1 | pass |
| Link | 7.52:1 | pass |
| Link on surface | 10.13:1 | pass |
| Button label | 6.00:1 | pass |
| Code | 12.90:1 | pass |
| Success | 7.04:1 | pass |
| Warning | 6.98:1 | pass |
| Danger | 7.03:1 | pass |
| Tertiary text | 6.01:1 | pass |
| Focus ring | 6.01:1 | pass |
| Border | 1.45:1 | decorative |
Soft Dark
| Pairing | Ratio | vs floor |
|---|---|---|
| Primary text | 14.58:1 | pass |
| Secondary text | 8.47:1 | pass |
| Primary on surface | 11.84:1 | pass |
| Secondary on surface | 6.87:1 | pass |
| Link | 7.54:1 | pass |
| Link on surface | 6.12:1 | pass |
| Button label | 4.80:1 | pass |
| Code | 16.42:1 | pass |
| Success | 7.04:1 | pass |
| Warning | 7.01:1 | pass |
| Danger | 7.04:1 | pass |
| Tertiary text | 5.85:1 | pass |
| Focus ring | 6.01:1 | pass |
| Border | 1.46:1 | decorative |
Dark
| Pairing | Ratio | vs floor |
|---|---|---|
| Primary text | 16.01:1 | pass |
| Secondary text | 9.31:1 | pass |
| Primary on surface | 13.06:1 | pass |
| Secondary on surface | 7.59:1 | pass |
| Link | 7.51:1 | pass |
| Link on surface | 6.13:1 | pass |
| Button label | 4.80:1 | pass |
| Code | 17.29:1 | pass |
| Success | 7.01:1 | pass |
| Warning | 7.03:1 | pass |
| Danger | 7.02:1 | pass |
| Tertiary text | 6.42:1 | pass |
| Focus ring | 5.98:1 | pass |
| Border | 1.45:1 | decorative |
Export
The theme.css is a drop-in with no build step; the tokens.json is DTCG-shaped for interop. Both carry all four modes at the default notch and default vision. Copy or download from the rail.
/* TEMPER color tokens. Generated by the TEMPER color tool (color.polymathie.xyz).
Baked at the default notch, default vision. Mode switches at runtime; notch and vision are baked here.
Drop in after TEMPER's base theme; these override the color roles for the four
modes plus System. Regenerate from your brand rather than editing by hand. */
:root {
color-scheme: light;
--color-bg-base: #F3F2FB;
--color-bg-subtle: #EAE9F2;
--color-surface: #FFFFFF;
--color-surface-hover: #F5F4FD;
--color-surface-active: #EBE9F2;
--color-border: #CCCBD4;
--color-border-strong: #AAA9B1;
--color-text-primary: #18181B;
--color-text-secondary: #414044;
--color-text-tertiary: #58585D;
--color-text-on-accent: #FFFFFF;
--color-accent: #650ECF;
--color-accent-hover: #5300AD;
--color-accent-subtle: #DFD9FF;
--color-accent-solid: #7935E9;
--color-success: #255D34;
--color-success-subtle: #C9E7CE;
--color-warning: #704B00;
--color-warning-subtle: #F3DCBB;
--color-danger: #913327;
--color-danger-subtle: #FFD6CF;
--color-focus-ring: #732BE1;
--color-selection: #CFC5FF;
--color-code-bg: #E5E3EC;
--color-code-text: #18181B;
--color-table-stripe: #FAF9FF;
--color-overlay: rgba(2, 1, 3, 0.45);
--shadow-sm: 0 1px 2px rgba(23, 25, 27, 0.06);
--shadow-md: 0 4px 14px rgba(23, 25, 27, 0.10);
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme]),
[data-theme="system"] {
color-scheme: dark;
--color-bg-base: #16151B;
--color-bg-subtle: #100F15;
--color-surface: #28272D;
--color-surface-hover: #2E2D34;
--color-surface-active: #35343A;
--color-border: #34333A;
--color-border-strong: #4C4B52;
--color-text-primary: #F1F0F5;
--color-text-secondary: #BAB9BE;
--color-text-tertiary: #9A999F;
--color-text-on-accent: #FFFFFF;
--color-accent: #AF97FF;
--color-accent-hover: #C2B2FF;
--color-accent-subtle: #321267;
--color-accent-solid: #8749FB;
--color-success: #74AE80;
--color-success-subtle: #142B19;
--color-warning: #C59A56;
--color-warning-subtle: #342306;
--color-danger: #EC8474;
--color-danger-subtle: #431A14;
--color-focus-ring: #A07EFF;
--color-selection: #421388;
--color-code-bg: #0C0B11;
--color-code-text: #F1F0F5;
--color-table-stripe: #121117;
--color-overlay: rgba(2, 1, 3, 0.58);
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.42);
--shadow-md: 0 6px 20px rgba(0, 0, 0, 0.55);
}
}
[data-theme="light"] {
color-scheme: light;
--color-bg-base: #F3F2FB;
--color-bg-subtle: #EAE9F2;
--color-surface: #FFFFFF;
--color-surface-hover: #F5F4FD;
--color-surface-active: #EBE9F2;
--color-border: #CCCBD4;
--color-border-strong: #AAA9B1;
--color-text-primary: #18181B;
--color-text-secondary: #414044;
--color-text-tertiary: #58585D;
--color-text-on-accent: #FFFFFF;
--color-accent: #650ECF;
--color-accent-hover: #5300AD;
--color-accent-subtle: #DFD9FF;
--color-accent-solid: #7935E9;
--color-success: #255D34;
--color-success-subtle: #C9E7CE;
--color-warning: #704B00;
--color-warning-subtle: #F3DCBB;
--color-danger: #913327;
--color-danger-subtle: #FFD6CF;
--color-focus-ring: #732BE1;
--color-selection: #CFC5FF;
--color-code-bg: #E5E3EC;
--color-code-text: #18181B;
--color-table-stripe: #FAF9FF;
--color-overlay: rgba(2, 1, 3, 0.45);
--shadow-sm: 0 1px 2px rgba(23, 25, 27, 0.06);
--shadow-md: 0 4px 14px rgba(23, 25, 27, 0.10);
}
[data-theme="soft-light"] {
color-scheme: light;
--color-bg-base: #DEDDE5;
--color-bg-subtle: #D5D3DC;
--color-surface: #FFFFFF;
--color-surface-hover: #F5F4FD;
--color-surface-active: #EBE9F2;
--color-border: #BAB8C1;
--color-border-strong: #9A98A1;
--color-text-primary: #070709;
--color-text-secondary: #38383C;
--color-text-tertiary: #504F55;
--color-text-on-accent: #FFFFFF;
--color-accent: #5700B5;
--color-accent-hover: #42008D;
--color-accent-subtle: #CDC2FF;
--color-accent-solid: #7935E9;
--color-success: #165028;
--color-success-subtle: #B6D2BA;
--color-warning: #604000;
--color-warning-subtle: #DEC8A8;
--color-danger: #82241A;
--color-danger-subtle: #F5BEB5;
--color-focus-ring: #6713D1;
--color-selection: #BFAEFF;
--color-code-bg: #CFCED7;
--color-code-text: #070709;
--color-table-stripe: #E5E3EC;
--color-overlay: rgba(2, 1, 3, 0.45);
--shadow-sm: 0 1px 2px rgba(23, 25, 27, 0.06);
--shadow-md: 0 4px 14px rgba(23, 25, 27, 0.10);
}
[data-theme="soft-dark"] {
color-scheme: dark;
--color-bg-base: #26252C;
--color-bg-subtle: #201F25;
--color-surface: #35343A;
--color-surface-hover: #3A3940;
--color-surface-active: #414047;
--color-border: #403F46;
--color-border-strong: #58565E;
--color-text-primary: #FAFAFE;
--color-text-secondary: #C1C1C6;
--color-text-tertiary: #A1A0A6;
--color-text-on-accent: #FFFFFF;
--color-accent: #BDABFF;
--color-accent-hover: #D1C7FF;
--color-accent-subtle: #3E2276;
--color-accent-solid: #8749FB;
--color-success: #84BE8F;
--color-success-subtle: #213926;
--color-warning: #D5A966;
--color-warning-subtle: #423014;
--color-danger: #FD9483;
--color-danger-subtle: #522721;
--color-focus-ring: #AC92FF;
--color-selection: #4D2496;
--color-code-bg: #1C1B21;
--color-code-text: #FAFAFE;
--color-table-stripe: #222127;
--color-overlay: rgba(2, 1, 3, 0.58);
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.42);
--shadow-md: 0 6px 20px rgba(0, 0, 0, 0.55);
}
[data-theme="dark"] {
color-scheme: dark;
--color-bg-base: #16151B;
--color-bg-subtle: #100F15;
--color-surface: #28272D;
--color-surface-hover: #2E2D34;
--color-surface-active: #35343A;
--color-border: #34333A;
--color-border-strong: #4C4B52;
--color-text-primary: #F1F0F5;
--color-text-secondary: #BAB9BE;
--color-text-tertiary: #9A999F;
--color-text-on-accent: #FFFFFF;
--color-accent: #AF97FF;
--color-accent-hover: #C2B2FF;
--color-accent-subtle: #321267;
--color-accent-solid: #8749FB;
--color-success: #74AE80;
--color-success-subtle: #142B19;
--color-warning: #C59A56;
--color-warning-subtle: #342306;
--color-danger: #EC8474;
--color-danger-subtle: #431A14;
--color-focus-ring: #A07EFF;
--color-selection: #421388;
--color-code-bg: #0C0B11;
--color-code-text: #F1F0F5;
--color-table-stripe: #121117;
--color-overlay: rgba(2, 1, 3, 0.58);
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.42);
--shadow-md: 0 6px 20px rgba(0, 0, 0, 0.55);
}
{
"$description": "TEMPER-derived color tokens, four modes. DTCG-shaped; each mode is a group of color tokens. Baked at the default notch, default vision. Mode switches at runtime; notch and vision are baked here.",
"light": {
"color": {
"bg-base": {
"$type": "color",
"$value": "#F3F2FB"
},
"bg-subtle": {
"$type": "color",
"$value": "#EAE9F2"
},
"surface": {
"$type": "color",
"$value": "#FFFFFF"
},
"surface-hover": {
"$type": "color",
"$value": "#F5F4FD"
},
"surface-active": {
"$type": "color",
"$value": "#EBE9F2"
},
"border": {
"$type": "color",
"$value": "#CCCBD4"
},
"border-strong": {
"$type": "color",
"$value": "#AAA9B1"
},
"text-primary": {
"$type": "color",
"$value": "#18181B"
},
"text-secondary": {
"$type": "color",
"$value": "#414044"
},
"text-tertiary": {
"$type": "color",
"$value": "#58585D"
},
"text-on-accent": {
"$type": "color",
"$value": "#FFFFFF"
},
"accent": {
"$type": "color",
"$value": "#650ECF"
},
"accent-hover": {
"$type": "color",
"$value": "#5300AD"
},
"accent-subtle": {
"$type": "color",
"$value": "#DFD9FF"
},
"accent-solid": {
"$type": "color",
"$value": "#7935E9"
},
"success": {
"$type": "color",
"$value": "#255D34"
},
"success-subtle": {
"$type": "color",
"$value": "#C9E7CE"
},
"warning": {
"$type": "color",
"$value": "#704B00"
},
"warning-subtle": {
"$type": "color",
"$value": "#F3DCBB"
},
"danger": {
"$type": "color",
"$value": "#913327"
},
"danger-subtle": {
"$type": "color",
"$value": "#FFD6CF"
},
"focus-ring": {
"$type": "color",
"$value": "#732BE1"
},
"selection": {
"$type": "color",
"$value": "#CFC5FF"
},
"code-bg": {
"$type": "color",
"$value": "#E5E3EC"
},
"code-text": {
"$type": "color",
"$value": "#18181B"
},
"table-stripe": {
"$type": "color",
"$value": "#FAF9FF"
},
"overlay": {
"$type": "color",
"$value": "rgba(2, 1, 3, 0.45)"
}
}
},
"soft-light": {
"color": {
"bg-base": {
"$type": "color",
"$value": "#DEDDE5"
},
"bg-subtle": {
"$type": "color",
"$value": "#D5D3DC"
},
"surface": {
"$type": "color",
"$value": "#FFFFFF"
},
"surface-hover": {
"$type": "color",
"$value": "#F5F4FD"
},
"surface-active": {
"$type": "color",
"$value": "#EBE9F2"
},
"border": {
"$type": "color",
"$value": "#BAB8C1"
},
"border-strong": {
"$type": "color",
"$value": "#9A98A1"
},
"text-primary": {
"$type": "color",
"$value": "#070709"
},
"text-secondary": {
"$type": "color",
"$value": "#38383C"
},
"text-tertiary": {
"$type": "color",
"$value": "#504F55"
},
"text-on-accent": {
"$type": "color",
"$value": "#FFFFFF"
},
"accent": {
"$type": "color",
"$value": "#5700B5"
},
"accent-hover": {
"$type": "color",
"$value": "#42008D"
},
"accent-subtle": {
"$type": "color",
"$value": "#CDC2FF"
},
"accent-solid": {
"$type": "color",
"$value": "#7935E9"
},
"success": {
"$type": "color",
"$value": "#165028"
},
"success-subtle": {
"$type": "color",
"$value": "#B6D2BA"
},
"warning": {
"$type": "color",
"$value": "#604000"
},
"warning-subtle": {
"$type": "color",
"$value": "#DEC8A8"
},
"danger": {
"$type": "color",
"$value": "#82241A"
},
"danger-subtle": {
"$type": "color",
"$value": "#F5BEB5"
},
"focus-ring": {
"$type": "color",
"$value": "#6713D1"
},
"selection": {
"$type": "color",
"$value": "#BFAEFF"
},
"code-bg": {
"$type": "color",
"$value": "#CFCED7"
},
"code-text": {
"$type": "color",
"$value": "#070709"
},
"table-stripe": {
"$type": "color",
"$value": "#E5E3EC"
},
"overlay": {
"$type": "color",
"$value": "rgba(2, 1, 3, 0.45)"
}
}
},
"soft-dark": {
"color": {
"bg-base": {
"$type": "color",
"$value": "#26252C"
},
"bg-subtle": {
"$type": "color",
"$value": "#201F25"
},
"surface": {
"$type": "color",
"$value": "#35343A"
},
"surface-hover": {
"$type": "color",
"$value": "#3A3940"
},
"surface-active": {
"$type": "color",
"$value": "#414047"
},
"border": {
"$type": "color",
"$value": "#403F46"
},
"border-strong": {
"$type": "color",
"$value": "#58565E"
},
"text-primary": {
"$type": "color",
"$value": "#FAFAFE"
},
"text-secondary": {
"$type": "color",
"$value": "#C1C1C6"
},
"text-tertiary": {
"$type": "color",
"$value": "#A1A0A6"
},
"text-on-accent": {
"$type": "color",
"$value": "#FFFFFF"
},
"accent": {
"$type": "color",
"$value": "#BDABFF"
},
"accent-hover": {
"$type": "color",
"$value": "#D1C7FF"
},
"accent-subtle": {
"$type": "color",
"$value": "#3E2276"
},
"accent-solid": {
"$type": "color",
"$value": "#8749FB"
},
"success": {
"$type": "color",
"$value": "#84BE8F"
},
"success-subtle": {
"$type": "color",
"$value": "#213926"
},
"warning": {
"$type": "color",
"$value": "#D5A966"
},
"warning-subtle": {
"$type": "color",
"$value": "#423014"
},
"danger": {
"$type": "color",
"$value": "#FD9483"
},
"danger-subtle": {
"$type": "color",
"$value": "#522721"
},
"focus-ring": {
"$type": "color",
"$value": "#AC92FF"
},
"selection": {
"$type": "color",
"$value": "#4D2496"
},
"code-bg": {
"$type": "color",
"$value": "#1C1B21"
},
"code-text": {
"$type": "color",
"$value": "#FAFAFE"
},
"table-stripe": {
"$type": "color",
"$value": "#222127"
},
"overlay": {
"$type": "color",
"$value": "rgba(2, 1, 3, 0.58)"
}
}
},
"dark": {
"color": {
"bg-base": {
"$type": "color",
"$value": "#16151B"
},
"bg-subtle": {
"$type": "color",
"$value": "#100F15"
},
"surface": {
"$type": "color",
"$value": "#28272D"
},
"surface-hover": {
"$type": "color",
"$value": "#2E2D34"
},
"surface-active": {
"$type": "color",
"$value": "#35343A"
},
"border": {
"$type": "color",
"$value": "#34333A"
},
"border-strong": {
"$type": "color",
"$value": "#4C4B52"
},
"text-primary": {
"$type": "color",
"$value": "#F1F0F5"
},
"text-secondary": {
"$type": "color",
"$value": "#BAB9BE"
},
"text-tertiary": {
"$type": "color",
"$value": "#9A999F"
},
"text-on-accent": {
"$type": "color",
"$value": "#FFFFFF"
},
"accent": {
"$type": "color",
"$value": "#AF97FF"
},
"accent-hover": {
"$type": "color",
"$value": "#C2B2FF"
},
"accent-subtle": {
"$type": "color",
"$value": "#321267"
},
"accent-solid": {
"$type": "color",
"$value": "#8749FB"
},
"success": {
"$type": "color",
"$value": "#74AE80"
},
"success-subtle": {
"$type": "color",
"$value": "#142B19"
},
"warning": {
"$type": "color",
"$value": "#C59A56"
},
"warning-subtle": {
"$type": "color",
"$value": "#342306"
},
"danger": {
"$type": "color",
"$value": "#EC8474"
},
"danger-subtle": {
"$type": "color",
"$value": "#431A14"
},
"focus-ring": {
"$type": "color",
"$value": "#A07EFF"
},
"selection": {
"$type": "color",
"$value": "#421388"
},
"code-bg": {
"$type": "color",
"$value": "#0C0B11"
},
"code-text": {
"$type": "color",
"$value": "#F1F0F5"
},
"table-stripe": {
"$type": "color",
"$value": "#121117"
},
"overlay": {
"$type": "color",
"$value": "rgba(2, 1, 3, 0.58)"
}
}
}
}