TEMPER
The color tool · color.polymathie.xyz
Give it a brand color. TEMPER solves a full semantic palette across all four modes to verified contrast floors, shows you where every pairing lands against your target, and hands you a drop-in theme.css and a tokens.json. The palette is not picked; it is derived, so legibility is a property of the engine.
Brand
The primary color becomes the accent (its hue held at every background). An optional second color sets the neutral temperature. The target is the contrast floor the audit judges text against.
The derived palette
Every mode solved from the one brand color, at the middle notch, default vision.
Light
Soft Light
Soft Dark
Dark
The audit
Every meaningful pairing, its measured WCAG contrast, and whether it clears its floor: text pairs against your target, focus and de-emphasized text against the 3:1 non-text floor. Borders are shown as decorative and carry no floor. Misses are named, not hidden.
All 52 judged pairings clear their floor across the four modes at AA.
Light
| Pairing | Ratio | vs floor |
|---|---|---|
| Primary text | 15.95:1 | pass (≥4.5) |
| Secondary text | 9.26:1 | pass (≥4.5) |
| Primary on surface | 17.72:1 | pass (≥4.5) |
| Secondary on surface | 10.29:1 | pass (≥4.5) |
| Link | 7.51:1 | pass (≥4.5) |
| Link on surface | 8.34:1 | pass (≥4.5) |
| Button label | 6.00:1 | pass (≥4.5) |
| Code | 13.95:1 | pass (≥4.5) |
| Success | 7.02:1 | pass (≥4.5) |
| Warning | 7.01:1 | pass (≥4.5) |
| Danger | 6.98:1 | pass (≥4.5) |
| Tertiary text | 6.37:1 | pass (≥3) |
| Focus ring | 5.98:1 | pass (≥3) |
| Border | 1.45:1 | decorative |
Soft Light
| Pairing | Ratio | vs floor |
|---|---|---|
| Primary text | 14.93:1 | pass (≥4.5) |
| Secondary text | 8.66:1 | pass (≥4.5) |
| Primary on surface | 20.13:1 | pass (≥4.5) |
| Secondary on surface | 11.67:1 | pass (≥4.5) |
| Link | 7.52:1 | pass (≥4.5) |
| Link on surface | 10.13:1 | pass (≥4.5) |
| Button label | 6.00:1 | pass (≥4.5) |
| Code | 12.90:1 | pass (≥4.5) |
| Success | 7.04:1 | pass (≥4.5) |
| Warning | 6.98:1 | pass (≥4.5) |
| Danger | 7.03:1 | pass (≥4.5) |
| Tertiary text | 6.01:1 | pass (≥3) |
| Focus ring | 6.01:1 | pass (≥3) |
| Border | 1.45:1 | decorative |
Soft Dark
| Pairing | Ratio | vs floor |
|---|---|---|
| Primary text | 14.58:1 | pass (≥4.5) |
| Secondary text | 8.47:1 | pass (≥4.5) |
| Primary on surface | 11.84:1 | pass (≥4.5) |
| Secondary on surface | 6.87:1 | pass (≥4.5) |
| Link | 7.54:1 | pass (≥4.5) |
| Link on surface | 6.12:1 | pass (≥4.5) |
| Button label | 4.80:1 | pass (≥4.5) |
| Code | 16.42:1 | pass (≥4.5) |
| Success | 7.04:1 | pass (≥4.5) |
| Warning | 7.01:1 | pass (≥4.5) |
| Danger | 7.04:1 | pass (≥4.5) |
| Tertiary text | 5.85:1 | pass (≥3) |
| Focus ring | 6.01:1 | pass (≥3) |
| Border | 1.46:1 | decorative |
Dark
| Pairing | Ratio | vs floor |
|---|---|---|
| Primary text | 16.01:1 | pass (≥4.5) |
| Secondary text | 9.31:1 | pass (≥4.5) |
| Primary on surface | 13.06:1 | pass (≥4.5) |
| Secondary on surface | 7.59:1 | pass (≥4.5) |
| Link | 7.51:1 | pass (≥4.5) |
| Link on surface | 6.13:1 | pass (≥4.5) |
| Button label | 4.80:1 | pass (≥4.5) |
| Code | 17.29:1 | pass (≥4.5) |
| Success | 7.01:1 | pass (≥4.5) |
| Warning | 7.03:1 | pass (≥4.5) |
| Danger | 7.02:1 | pass (≥4.5) |
| Tertiary text | 6.42:1 | pass (≥3) |
| Focus ring | 5.98:1 | pass (≥3) |
| Border | 1.45:1 | decorative |
Export
Three ways out. The theme.css is a drop-in with no build step; the tokens.json is DTCG-shaped for interop. Copy for the quick paste, download for the file.
/* TEMPER color tokens. Generated by the TEMPER color tool (color.polymathie.xyz).
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.",
"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)"
}
}
}
}