Palette
Each flavor has 24 named colors: twelve neutrals and twelve accents. The names are the API; the values are tuned per flavor. Colors were designed in OKLCH, gamut-mapped, and frozen as hex, the canonical form. RGB and OKLCH below are derived from that hex, and every table on this page is generated from the published package at build time.
Neutrals, darkest to lightest on dark flavors: crust, mantle and base are backgrounds; surface0 to surface2 are raised fills; overlay0 to overlay2 are lines and icons; subtext0, subtext1 and text are text. Daybreak runs the background ramp the other way (crust darkest, base lightest). Accents are identical across the three dark flavors; Daybreak has a deeper set that stays readable on light backgrounds.
The last column is the WCAG contrast ratio against the flavor’s base. Ratios are truncated, never rounded up, and badges mark AAA (7:1), AA (4.5:1) and AA large text or UI (3:1). Backgrounds and hairlines sit below 3:1 by design.
The softest dark: plum ink with the lightest dark base, for long reading sessions.
| Swatch | Color | Hex | RGB | OKLCH | vs base |
|---|---|---|---|---|---|
Crust--sb-crustDeepest background: app chrome, HUD backdrop, code | #1f1424 | 31 20 36 | oklch(21.3% 0.035 314.9) | 1.18 | |
Mantle--sb-mantleSecondary background: sidebars, nav, inputs | #271b2c | 39 27 44 | oklch(24.5% 0.036 315.7) | 1.09 | |
Base--sb-baseMain background | #2f2235 | 47 34 53 | oklch(27.6% 0.039 314.9) | base | |
Surface 0--sb-surface-0Raised fill: cards, menus, popovers | #392c3e | 57 44 62 | oklch(31.5% 0.036 316.5) | 1.14 | |
Surface 1--sb-surface-1Hover fill | #433748 | 67 55 72 | oklch(35.6% 0.033 315.9) | 1.34 | |
Surface 2--sb-surface-2Active fill | #4d4152 | 77 65 82 | oklch(39.4% 0.032 316.0) | 1.56 | |
Overlay 0--sb-overlay-0Decorative hairlines | #615667 | 97 86 103 | oklch(47.0% 0.030 313.8) | 2.16 | |
Overlay 1--sb-overlay-1Component boundaries, input borders | #7c7182 | 124 113 130 | oklch(56.4% 0.029 313.8) | 3.24AA large | |
Overlay 2--sb-overlay-2Icons, strong borders, comments | #968d9b | 150 141 155 | oklch(65.6% 0.023 313.8) | 4.69AA | |
Subtext 0--sb-subtext-0Placeholders, tertiary text | #b8afbc | 184 175 188 | oklch(76.5% 0.021 315.6) | 7.06AAA | |
Subtext 1--sb-subtext-1Secondary text | #d3cdd6 | 211 205 214 | oklch(85.6% 0.014 314.7) | 9.61AAA | |
Text--sb-textPrimary text | #f1edf3 | 241 237 243 | oklch(95.1% 0.009 314.8) | 12.95AAA | |
Plasma--sb-plasmaBrand primary: links, focus | #fd65b2 | 253 101 178 | oklch(72.0% 0.200 351.8) | 5.48AA | |
Laser--sb-laserDanger, errors, deletions | #ff7379 | 255 115 121 | oklch(72.5% 0.171 19.8) | 5.69AA | |
Ember--sb-emberRose-coral: parameters, booleans | #f9ac85 | 249 172 133 | oklch(81.0% 0.105 47.6) | 8.04AAA | |
Sodium--sb-sodiumWarning; numbers and constants | #ffa73e | 255 167 62 | oklch(79.9% 0.154 66.4) | 7.74AAA | |
Halogen--sb-halogenLamp yellow: types, highlights | #f6e281 | 246 226 129 | oklch(90.9% 0.120 98.0) | 11.50AAA | |
Acid--sb-acidSuccess; strings | #a1ee54 | 161 238 84 | oklch(86.9% 0.199 132.1) | 10.61AAA | |
Coolant--sb-coolantAquamarine: operators, regex | #66e6ba | 102 230 186 | oklch(84.1% 0.131 167.8) | 9.70AAA | |
Frost--sb-frostIce blue: properties | #a8dcfc | 168 220 252 | oklch(86.9% 0.070 235.6) | 10.21AAA | |
Ion--sb-ionInfo; functions | #59a7ff | 89 167 255 | oklch(71.8% 0.150 253.0) | 5.99AA | |
Ultraviolet--sb-ultravioletSecondary; keywords | #b580ff | 181 128 255 | oklch(70.6% 0.184 301.1) | 5.35AA | |
Orchid--sb-orchidLilac-pink: storage, decorators | #efb2f2 | 239 178 242 | oklch(84.0% 0.109 324.9) | 8.79AAA | |
Chrome--sb-chromeSilver: neutral and metal badges | #bfc7dc | 191 199 220 | oklch(83.0% 0.031 269.1) | 8.86AAA |
Midnight
Section titled “Midnight”The default dark: saturated midnight indigo. Websites and docs start here.
| Swatch | Color | Hex | RGB | OKLCH | vs base |
|---|---|---|---|---|---|
Crust--sb-crustDeepest background: app chrome, HUD backdrop, code | #060918 | 6 9 24 | oklch(14.6% 0.033 271.7) | 1.10 | |
Mantle--sb-mantleSecondary background: sidebars, nav, inputs | #0b0f20 | 11 15 32 | oklch(17.5% 0.036 272.2) | 1.06 | |
Base--sb-baseMain background | #111629 | 17 22 41 | oklch(20.6% 0.039 271.5) | base | |
Surface 0--sb-surface-0Raised fill: cards, menus, popovers | #1b2034 | 27 32 52 | oklch(24.9% 0.039 272.6) | 1.11 | |
Surface 1--sb-surface-1Hover fill | #262c3f | 38 44 63 | oklch(29.6% 0.036 270.6) | 1.29 | |
Surface 2--sb-surface-2Active fill | #323749 | 50 55 73 | oklch(34.0% 0.032 272.5) | 1.51 | |
Overlay 0--sb-overlay-0Decorative hairlines | #474c5d | 71 76 93 | oklch(41.9% 0.029 272.2) | 2.10 | |
Overlay 1--sb-overlay-1Component boundaries, input borders | #626776 | 98 103 118 | oklch(51.5% 0.024 270.9) | 3.17AA large | |
Overlay 2--sb-overlay-2Icons, strong borders, comments | #7d818e | 125 129 142 | oklch(60.4% 0.020 272.1) | 4.61AA | |
Subtext 0--sb-subtext-0Placeholders, tertiary text | #a2a6b1 | 162 166 177 | oklch(72.5% 0.016 269.9) | 7.36AAA | |
Subtext 1--sb-subtext-1Secondary text | #c6c9d1 | 198 201 209 | oklch(83.6% 0.012 269.5) | 10.82AAA | |
Text--sb-textPrimary text | #ebedf2 | 235 237 242 | oklch(94.6% 0.007 268.5) | 15.31AAA | |
Plasma--sb-plasmaBrand primary: links, focus | #fd65b2 | 253 101 178 | oklch(72.0% 0.200 351.8) | 6.56AA | |
Laser--sb-laserDanger, errors, deletions | #ff7379 | 255 115 121 | oklch(72.5% 0.171 19.8) | 6.81AA | |
Ember--sb-emberRose-coral: parameters, booleans | #f9ac85 | 249 172 133 | oklch(81.0% 0.105 47.6) | 9.62AAA | |
Sodium--sb-sodiumWarning; numbers and constants | #ffa73e | 255 167 62 | oklch(79.9% 0.154 66.4) | 9.26AAA | |
Halogen--sb-halogenLamp yellow: types, highlights | #f6e281 | 246 226 129 | oklch(90.9% 0.120 98.0) | 13.76AAA | |
Acid--sb-acidSuccess; strings | #a1ee54 | 161 238 84 | oklch(86.9% 0.199 132.1) | 12.70AAA | |
Coolant--sb-coolantAquamarine: operators, regex | #66e6ba | 102 230 186 | oklch(84.1% 0.131 167.8) | 11.61AAA | |
Frost--sb-frostIce blue: properties | #a8dcfc | 168 220 252 | oklch(86.9% 0.070 235.6) | 12.22AAA | |
Ion--sb-ionInfo; functions | #59a7ff | 89 167 255 | oklch(71.8% 0.150 253.0) | 7.17AAA | |
Ultraviolet--sb-ultravioletSecondary; keywords | #b580ff | 181 128 255 | oklch(70.6% 0.184 301.1) | 6.40AA | |
Orchid--sb-orchidLilac-pink: storage, decorators | #efb2f2 | 239 178 242 | oklch(84.0% 0.109 324.9) | 10.52AAA | |
Chrome--sb-chromeSilver: neutral and metal badges | #bfc7dc | 191 199 220 | oklch(83.0% 0.031 269.1) | 10.60AAA |
Blackout
Section titled “Blackout”The deepest dark: near-black steel with the highest contrast, and the default for in-game HUDs drawn over game imagery.
| Swatch | Color | Hex | RGB | OKLCH | vs base |
|---|---|---|---|---|---|
Crust--sb-crustDeepest background: app chrome, HUD backdrop, code | #010205 | 1 2 5 | oklch(8.5% 0.015 262.0) | 1.04 | |
Mantle--sb-mantleSecondary background: sidebars, nav, inputs | #03050a | 3 5 10 | oklch(11.5% 0.015 261.3) | 1.02 | |
Base--sb-baseMain background | #060910 | 6 9 16 | oklch(14.0% 0.017 263.5) | base | |
Surface 0--sb-surface-0Raised fill: cards, menus, popovers | #0e131b | 14 19 27 | oklch(18.6% 0.018 259.7) | 1.06 | |
Surface 1--sb-surface-1Hover fill | #181d26 | 24 29 38 | oklch(23.0% 0.019 262.1) | 1.17 | |
Surface 2--sb-surface-2Active fill | #232831 | 35 40 49 | oklch(27.6% 0.018 262.2) | 1.34 | |
Overlay 0--sb-overlay-0Decorative hairlines | #393d46 | 57 61 70 | oklch(36.0% 0.016 266.5) | 1.83 | |
Overlay 1--sb-overlay-1Component boundaries, input borders | #5b5f67 | 91 95 103 | oklch(48.5% 0.014 264.4) | 3.10AA large | |
Overlay 2--sb-overlay-2Icons, strong borders, comments | #767a82 | 118 122 130 | oklch(57.9% 0.013 264.5) | 4.62AA | |
Subtext 0--sb-subtext-0Placeholders, tertiary text | #9da0a6 | 157 160 166 | oklch(70.5% 0.009 264.5) | 7.59AAA | |
Subtext 1--sb-subtext-1Secondary text | #c3c6cb | 195 198 203 | oklch(82.6% 0.008 260.7) | 11.62AAA | |
Text--sb-textPrimary text | #eef0f4 | 238 240 244 | oklch(95.5% 0.006 264.5) | 17.45AAA | |
Plasma--sb-plasmaBrand primary: links, focus | #fd65b2 | 253 101 178 | oklch(72.0% 0.200 351.8) | 7.28AAA | |
Laser--sb-laserDanger, errors, deletions | #ff7379 | 255 115 121 | oklch(72.5% 0.171 19.8) | 7.56AAA | |
Ember--sb-emberRose-coral: parameters, booleans | #f9ac85 | 249 172 133 | oklch(81.0% 0.105 47.6) | 10.68AAA | |
Sodium--sb-sodiumWarning; numbers and constants | #ffa73e | 255 167 62 | oklch(79.9% 0.154 66.4) | 10.29AAA | |
Halogen--sb-halogenLamp yellow: types, highlights | #f6e281 | 246 226 129 | oklch(90.9% 0.120 98.0) | 15.28AAA | |
Acid--sb-acidSuccess; strings | #a1ee54 | 161 238 84 | oklch(86.9% 0.199 132.1) | 14.10AAA | |
Coolant--sb-coolantAquamarine: operators, regex | #66e6ba | 102 230 186 | oklch(84.1% 0.131 167.8) | 12.89AAA | |
Frost--sb-frostIce blue: properties | #a8dcfc | 168 220 252 | oklch(86.9% 0.070 235.6) | 13.57AAA | |
Ion--sb-ionInfo; functions | #59a7ff | 89 167 255 | oklch(71.8% 0.150 253.0) | 7.96AAA | |
Ultraviolet--sb-ultravioletSecondary; keywords | #b580ff | 181 128 255 | oklch(70.6% 0.184 301.1) | 7.11AAA | |
Orchid--sb-orchidLilac-pink: storage, decorators | #efb2f2 | 239 178 242 | oklch(84.0% 0.109 324.9) | 11.68AAA | |
Chrome--sb-chromeSilver: neutral and metal badges | #bfc7dc | 191 199 220 | oklch(83.0% 0.031 269.1) | 11.77AAA |
Daybreak
Section titled “Daybreak”The light flavor: pale dawn lavender with a deeper accent set.
| Swatch | Color | Hex | RGB | OKLCH | vs base |
|---|---|---|---|---|---|
Crust--sb-crustDeepest background: app chrome, HUD backdrop, code | #e7e0e9 | 231 224 233 | oklch(91.5% 0.014 318.7) | 1.19 | |
Mantle--sb-mantleSecondary background: sidebars, nav, inputs | #f1eaf2 | 241 234 242 | oklch(94.5% 0.013 321.9) | 1.09 | |
Base--sb-baseMain background | #f9f5fa | 249 245 250 | oklch(97.5% 0.008 319.4) | base | |
Surface 0--sb-surface-0Raised fill: cards, menus, popovers | #ebe3ec | 235 227 236 | oklch(92.5% 0.015 322.3) | 1.16 | |
Surface 1--sb-surface-1Hover fill | #e0d7e1 | 224 215 225 | oklch(88.9% 0.017 322.7) | 1.29 | |
Surface 2--sb-surface-2Active fill | #d5ccd7 | 213 204 215 | oklch(85.6% 0.018 320.1) | 1.44 | |
Overlay 0--sb-overlay-0Decorative hairlines | #c4bac6 | 196 186 198 | oklch(80.1% 0.020 320.6) | 1.74 | |
Overlay 1--sb-overlay-1Component boundaries, input borders | #8d828f | 141 130 143 | oklch(62.1% 0.023 321.0) | 3.40AA large | |
Overlay 2--sb-overlay-2Icons, strong borders, comments | #776b7a | 119 107 122 | oklch(54.4% 0.027 319.5) | 4.67AA | |
Subtext 0--sb-subtext-0Placeholders, tertiary text | #635665 | 99 86 101 | oklch(47.1% 0.029 321.8) | 6.38AA | |
Subtext 1--sb-subtext-1Secondary text | #4d4050 | 77 64 80 | oklch(39.1% 0.031 319.9) | 8.99AAA | |
Text--sb-textPrimary text | #2a1d2d | 42 29 45 | oklch(25.4% 0.035 319.9) | 14.83AAA | |
Plasma--sb-plasmaBrand primary: links, focus | #c20072 | 194 0 114 | oklch(53.1% 0.218 355.2) | 5.50AA | |
Laser--sb-laserDanger, errors, deletions | #c51d28 | 197 29 40 | oklch(53.0% 0.200 25.1) | 5.43AA | |
Ember--sb-emberRose-coral: parameters, booleans | #a34942 | 163 73 66 | oklch(52.0% 0.121 26.6) | 5.42AA | |
Sodium--sb-sodiumWarning; numbers and constants | #9c5100 | 156 81 0 | oklch(51.6% 0.125 56.6) | 5.42AA | |
Halogen--sb-halogenLamp yellow: types, highlights | #796300 | 121 99 0 | oklch(50.7% 0.104 93.7) | 5.41AA | |
Acid--sb-acidSuccess; strings | #2d7304 | 45 115 4 | oklch(49.1% 0.150 138.1) | 5.46AA | |
Coolant--sb-coolantAquamarine: operators, regex | #00735b | 0 115 91 | oklch(49.5% 0.096 171.6) | 5.40AA | |
Frost--sb-frostIce blue: properties | #1c6b97 | 28 107 151 | oklch(50.3% 0.101 238.7) | 5.40AA | |
Ion--sb-ionInfo; functions | #0160d1 | 1 96 209 | oklch(51.3% 0.191 258.2) | 5.41AA | |
Ultraviolet--sb-ultravioletSecondary; keywords | #7c3ad3 | 124 58 211 | oklch(52.0% 0.219 297.9) | 5.72AA | |
Orchid--sb-orchidLilac-pink: storage, decorators | #9f37a7 | 159 55 167 | oklch(53.0% 0.191 324.8) | 5.44AA | |
Chrome--sb-chromeSilver: neutral and metal badges | #606477 | 96 100 119 | oklch(50.7% 0.031 275.9) | 5.42AA |
Use the values
Section titled “Use the values”import { flavors, flavorEntries, semanticRoles } from '@static-bloom/palette'import type { ColorName, FlavorName } from '@static-bloom/palette'
const midnight = flavors.midnightmidnight.colors.plasma.hex // '#fd65b2'midnight.colors.plasma.oklch // { l, c, h }midnight.colors[semanticRoles.primary].rgb // { r: 253, g: 101, b: 178 }
for (const flavor of flavorEntries) console.log(flavor.id, flavor.dark, flavor.onAccent)Each color carries name, label, order, accent, hex, rgb, hsl and oklch. Each flavor carries id, name, order, dark, colors and onAccent, the palette color used for text on solid accent fills. The package also exports colorNames, neutralNames, accentNames, syntaxRoles and the FlavorName, DarkFlavorName, ColorName, NeutralName, AccentName, Flavor and ColorFormat types. No color library is needed at runtime.
import palette from '@static-bloom/palette/palette.json' with { type: 'json' }
palette.flavors.daybreak.colors.base.hex // '#f9f5fa'The JSON holds the same data as the JavaScript exports, role maps included.
@import '@static-bloom/palette/css';
body { background: var(--sb-base); color: var(--sb-text);}palette.css declares --sb-<color> for all 24 colors in @layer theme, for Midnight on :root and for every [data-flavor] value, plus --sb-on-accent, --sb-flavor-dark (1 or 0) and color-scheme. Numeric suffixes are hyphenated: --sb-surface-0, --sb-overlay-1, --sb-subtext-0. To pin one flavor on :root, import its file instead:
@import '@static-bloom/palette/css/blackout.css';For components, prefer the semantic tokens from @static-bloom/css (Color roles) over raw palette variables.