Qeetrix

Colour

Semantic colour roles for text, surfaces, borders, actions and feedback, and the palette behind them.

Build with the semantic roles. Each one has a meaning and a value for each theme, and every text and surface pair the roles are designed for meets WCAG AA contrast. Colour is authored in OKLCH.

The Tailwind column gives each colour's utility with bg-; the same name works with text-, border- and the other colour utilities. Roles without a utility of their own are used through the variable.

Text

RoleLightDarkCSS variableTailwind
primaryoklch(0.16 0.001 60)oklch(0.958 0.003 60)--qx-color-text-primary—
secondaryoklch(0.4 0.002 60)oklch(0.857 0.003 60)--qx-color-text-secondary—
tertiaryoklch(0.49 0.003 60)oklch(0.72 0.003 60)--qx-color-text-tertiary—
placeholderoklch(0.49 0.003 60)oklch(0.72 0.003 60)--qx-color-text-placeholder—
disabledoklch(0.72 0.003 60)oklch(0.49 0.003 60)--qx-color-text-disabled—
inverseoklch(1 0 0)oklch(0.16 0.001 60)--qx-color-text-inverse—
brandoklch(0.53 0.165 38)oklch(0.77 0.156 54.793)--qx-color-text-brandbg-brand
linkoklch(0.53 0.165 38)oklch(0.77 0.156 54.793)--qx-color-text-linkbg-link
link-hoveroklch(0.47 0.145 36)oklch(0.842 0.103 57.312)--qx-color-text-link-hoverbg-link-hover
successoklch(0.522 0.118 159.971)oklch(0.77 0.135 157.802)--qx-color-text-successbg-success-text
warningoklch(0.522 0.109 77.44)oklch(0.77 0.14 85.394)--qx-color-text-warningbg-warning-text
dangeroklch(0.522 0.189 21.633)oklch(0.77 0.136 19.102)--qx-color-text-dangerbg-destructive-text
infooklch(0.522 0.138 247.265)oklch(0.77 0.128 242.204)--qx-color-text-infobg-info-text
on-brandoklch(1 0 0)oklch(1 0 0)--qx-color-text-on-brand—
on-subtleoklch(0.16 0.001 60)oklch(0.958 0.003 60)--qx-color-text-on-subtle—
on-feedbackoklch(1 0 0)oklch(0.11 0 0)--qx-color-text-on-feedback—
on-feedback-strongoklch(1 0 0)oklch(1 0 0)--qx-color-text-on-feedback-strongbg-on-feedback-strong
on-warning-strongoklch(0.16 0.001 60)oklch(0.16 0.001 60)--qx-color-text-on-warning-strongbg-on-warning-strong

Surface

RoleLightDarkCSS variableTailwind
canvasoklch(0.985 0.002 60)oklch(0.16 0.001 60)--qx-color-surface-canvasbg-canvas
defaultoklch(1 0 0)oklch(0.185 0.001 60)--qx-color-surface-defaultbg-surface
elevatedoklch(1 0 0)oklch(0.21 0.001 60)--qx-color-surface-elevatedbg-surface-elevated
overlayoklch(1 0 0)oklch(0.235 0.001 60)--qx-color-surface-overlaybg-surface-overlay
sunkenoklch(0.958 0.003 60)oklch(0.135 0.001 60)--qx-color-surface-sunkenbg-surface-sunken
subtleoklch(0.974 0.0025 60)oklch(0.21 0.001 60)--qx-color-surface-subtlebg-surface-subtle
interactiveoklch(0.958 0.003 60)oklch(0.268 0.001 60)--qx-color-surface-interactivebg-surface-interactive
interactive-hoveroklch(0.937 0.003 60)oklch(0.3 0.0015 60)--qx-color-surface-interactive-hoverbg-surface-interactive-hover
interactive-activeoklch(0.912 0.003 60)oklch(0.34 0.0015 60)--qx-color-surface-interactive-activebg-surface-interactive-active
brand-subtleoklch(0.952 0.03 61.16)color-mix(in oklab, oklch(1 0 0) 7%, transparent)--qx-color-surface-brand-subtlebg-brand-subtle
brand-subtle-hoveroklch(0.93 0.044 60.391)color-mix(in oklab, oklch(1 0 0) 10%, transparent)--qx-color-surface-brand-subtle-hoverbg-brand-subtle-hover
brand-subtle-activeoklch(0.906 0.06 59.551)color-mix(in oklab, oklch(1 0 0) 13%, transparent)--qx-color-surface-brand-subtle-activebg-brand-subtle-active
railoklch(0.974 0.0025 60)oklch(0.135 0.001 60)--qx-color-surface-rail—
inverseoklch(0.21 0.001 60)oklch(0.958 0.003 60)--qx-color-surface-inverse—

Border

RoleLightDarkCSS variableTailwind
defaultoklch(0.912 0.003 60)oklch(0.268 0.001 60)--qx-color-border-default—
subtleoklch(0.937 0.003 60)oklch(0.235 0.001 60)--qx-color-border-subtlebg-border-subtle
strongoklch(0.857 0.003 60)oklch(0.34 0.0015 60)--qx-color-border-strongbg-border-strong
controloklch(0.61 0.003 60)oklch(0.61 0.003 60)--qx-color-border-controlbg-control
control-hoveroklch(0.49 0.003 60)oklch(0.72 0.003 60)--qx-color-border-control-hoverbg-control-hover
focusedoklch(0.585 0.1835 40)oklch(0.77 0.156 54.793)--qx-color-border-focused—
hoveroklch(0.49 0.003 60)oklch(0.72 0.003 60)--qx-color-border-hover—
brandoklch(0.585 0.1835 40)oklch(0.77 0.156 54.793)--qx-color-border-brandbg-border-brand
dangeroklch(0.6 0.209 20.837)oklch(0.635 0.215 20.48)--qx-color-border-danger—
successoklch(0.842 0.105 157.172)oklch(0.6 0.137 159.289)--qx-color-border-success—
warningoklch(0.842 0.109 87.703)oklch(0.6 0.124 79.942)--qx-color-border-warning—
infooklch(0.842 0.087 240.735)oklch(0.6 0.153 245.673)--qx-color-border-info—

Action

RoleLightDarkCSS variableTailwind
primaryoklch(0.585 0.1835 40)oklch(0.585 0.1835 40)--qx-color-action-primary—
primary-hovercolor-mix(in oklab, oklch(0.585 0.1835 40), oklch(0.53 0.165 38))color-mix(in oklab, oklch(0.585 0.1835 40), oklch(0.53 0.165 38))--qx-color-action-primary-hover—
primary-activeoklch(0.53 0.165 38)oklch(0.53 0.165 38)--qx-color-action-primary-active—

Feedback

RoleLightDarkCSS variableTailwind
successoklch(0.522 0.118 159.971)oklch(0.77 0.135 157.802)--qx-color-feedback-success—
warningoklch(0.522 0.109 77.44)oklch(0.77 0.14 85.394)--qx-color-feedback-warning—
erroroklch(0.522 0.189 21.633)oklch(0.77 0.136 19.102)--qx-color-feedback-error—
infooklch(0.522 0.138 247.265)oklch(0.77 0.128 242.204)--qx-color-feedback-info—
success-subtleoklch(0.952 0.036 156.21)color-mix(in oklab, oklch(0.68 0.15 158.589) 15%, transparent)--qx-color-feedback-success-subtlebg-success-subtle
warning-subtleoklch(0.952 0.037 91.23)color-mix(in oklab, oklch(0.705 0.144 83.309) 12%, transparent)--qx-color-feedback-warning-subtlebg-warning-subtle
error-subtleoklch(0.952 0.023 17.245)color-mix(in oklab, oklch(0.635 0.215 20.48) 15%, transparent)--qx-color-feedback-error-subtlebg-destructive-subtle
info-subtleoklch(0.952 0.025 238.49)color-mix(in oklab, oklch(0.64 0.16 244.857) 15%, transparent)--qx-color-feedback-info-subtlebg-info-subtle
success-strongoklch(0.522 0.118 159.971)oklch(0.522 0.118 159.971)--qx-color-feedback-success-strongbg-success-strong
warning-strongoklch(0.77 0.14 85.394)oklch(0.77 0.14 85.394)--qx-color-feedback-warning-strongbg-warning-strong
error-strongoklch(0.522 0.189 21.633)oklch(0.522 0.189 21.633)--qx-color-feedback-error-strongbg-destructive-strong
info-strongoklch(0.522 0.138 247.265)oklch(0.522 0.138 247.265)--qx-color-feedback-info-strongbg-info-strong

Focus, selection and overlay

RoleLightDarkCSS variableTailwind
ringoklch(0.585 0.1835 40)oklch(0.77 0.156 54.793)--qx-color-focus-ring—
RoleLightDarkCSS variableTailwind
backgroundcolor-mix(in oklab, oklch(0.686 0.1855 47.1629) 20%, transparent)color-mix(in oklab, oklch(0.686 0.1855 47.1629) 32%, transparent)--qx-color-selection-background—
RoleLightDarkCSS variableTailwind
scrimcolor-mix(in oklab, oklch(0.11 0 0) 40%, transparent)color-mix(in oklab, oklch(0.11 0 0) 62%, transparent)--qx-color-overlay-scrim—

Palette

The primitive ramps the roles are built from. They're published in @qeetrix/ui/tokens.css for design tooling, but not in styles.css: build with the roles above. Hover a step for its variable and value.

qeet

50

100

150

200

300

400

500

550

600

700

800

900

950

graphite

0

25

50

100

150

200

300

400

450

500

600

700

750

800

825

875

900

925

950

975

1000

neutral

0

50

100

200

300

400

500

600

700

800

850

900

950

1000

danger

50

100

200

300

400

500

600

700

800

900

950

success

50

100

200

300

400

500

600

700

800

900

950

warning

50

100

200

300

400

500

600

700

800

900

950

info

50

100

200

300

400

500

600

700

800

900

950