Skip to main content
Cayuse Design System Lato · 4pt grid · WCAG 2.1 AA

Foundations

Color

Twenty raw UI colours, seven status colours, and 104 semantic aliases that map them onto interface roles. Products consume the aliases; the raw values exist only to feed them.

Figma source: ★ COLOR ↗

Brand

Cayuse blue #0076b6 is the root of the system. It is aliased once, as --primary-brand-color, and 14 further semantic tokens alias that — buttons, tabs, icons, tiles, pagination, navigation and breadcrumb links all resolve back to this single value. Changing the brand colour is a one-line edit.

--color-blue-300#0076b64.92:1 on white
--color-blue-400#005c8e7.19:1 on white
--color-blue-500#25327211.81:1 on white
--color-blue-200#44a3db2.80:1 on white
--color-blue-100#e1eaf8

Ratios are shown only for colours used as text or as non-text indicators. Surface tints such as blue/100 are measured against what sits on them, not against white — see the audit.

Note the ramp is not a lightness scale. blue/500 is a distinct navy used for links and the suite header, not a darker step of blue/300. Treat the five blues as five named colours that happen to share a family.

Neutrals

Five greys plus true black and white. #111111 — not #000000 — is the text colour.

--color-white#ffffff
--color-gray-100#f5f5f5
--color-gray-200#eeeeee
--color-gray-300#cccccc
--color-gray-400#888c8c3.40:1 on white
--color-gray-500#5e5e5e6.48:1 on white
--color-black#11111118.88:1 on white

The greys are role-separated, and mixing them up is the most common drift in the system:

  • gray-100 — filled surfaces: table headers, disabled input fields.
  • gray-200 — hairline cell borders, hover fills, disabled backgrounds.
  • gray-300 — container and menu borders. The default 1px line.
  • gray-400 — input borders and disabled text. Not a text colour for anything enabled — it measures 3.40:1 on white.
  • gray-500 — secondary text: captions, help text, separators.

Feedback colours

Error, success and warning each have a text, background and border token so a message can be built without picking values by hand.

--color-red-500#b312006.99:1 on white
--color-red-100#ffe8e6
--color-green-500#285d357.76:1 on white
--color-green-100#f8fdef
--color-yellow-300#fbb829
--color-yellow-200#fff8d8
--color-yellow-100#7d3d028.27:1 on white
RoleTextBackgroundBorderMeasured
Error--error-text--error-background--error-border5.97:1 ✔
Success--success-text--success-background--success-border7.49:1 ✔
Warning--color-yellow-100--color-yellow-200--color-yellow-3007.74:1 ✔
Warning has no semantic tokens

Error and success each have three semantics aliases. Warning has none — the Banner Alert’s warning variant reaches directly for --color-yellow-100/200/300, which is exactly the layer violation the system otherwise forbids. Adding warning/text, warning/background and warning/border to the Figma semantics collection would close the last gap.

Status ramp

Seven colours reserved for the Status Pill. They are deliberately separate from the UI palette: a pill is data, not chrome, and reusing interface blue for a workflow state makes both harder to read.

--color-status-blue#0747a68.53:1 on white
--color-status-green#0066447.04:1 on white
--color-status-orange#ff56303.17:1 on white
--color-status-yellow#ffc810
--color-status-light-blue#accdff
--color-status-gray#d4d4d5
--color-status-custom#33333312.63:1 on white

The Figma file assigns each colour a meaning. Honour it — the colour is the fast signal, the label is the accurate one:

ColourMeaningText token
GrayNot yet started. No user action required.--status-text-dark
Light blueIn progress, no action required from this user.--status-text-dark
BlueUnder review by another party.--status-text-light
YellowWaiting on someone else; informational.--status-text-dark
OrangeRequires the user’s immediate attention, or a waiting period.--status-text-dark — see audit
GreenComplete, approved, funded.--status-text-light
CustomProduct-specific state with no standard equivalent.--status-text-light

Contrast audit

Every ratio below is computed from the shipped token values at build time. The requirement column reflects which WCAG 2.1 AA rule applies: 4.5:1 for normal text (SC 1.4.3), 3:1 for large text and for non-text indicators such as focus rings and borders (SC 1.4.11).

Passing

CombinationForegroundBackgroundRequiresMeasured
Body text on white#111111#ffffff4.5:118.88:1 PASS
Caption / help text on white#5e5e5e#ffffff4.5:16.48:1 PASS
Brand blue text on white#0076b6#ffffff4.5:14.92:1 PASS
White on primary button#ffffff#0076b64.5:14.92:1 PASS
White on primary button, hovered#ffffff#005c8e4.5:17.19:1 PASS
Link (resting) on white#253272#ffffff4.5:111.81:1 PASS
Error text on error background#b31200#ffe8e64.5:15.97:1 PASS
Success text on success background#285d35#f8fdef4.5:17.49:1 PASS
Warning text on warning background#7d3d02#fff8d84.5:17.74:1 PASS
Input border on white (non-text)#888c8c#ffffff3:13.40:1 PASS
Status pill — black on yellow#111111#ffc8104.5:112.16:1 PASS
Status pill — black on light blue#111111#accdff4.5:111.63:1 PASS
Status pill — black on gray#111111#d4d4d54.5:112.75:1 PASS
Status pill — white on blue#ffffff#0747a64.5:18.53:1 PASS
Status pill — white on green#ffffff#0066444.5:17.04:1 PASS
Status pill — white on custom#ffffff#3333334.5:112.63:1 PASS

Failing — four open issues

CombinationForegroundBackgroundRequiresMeasured
Link hover on white#44a3db#ffffff4.5:12.80:1 FAIL
Focus ring against white (SC 1.4.11)#44a3db#ffffff3:12.80:1 FAIL
Secondary button text on its hover fill#0076b6#e1eaf84.5:14.06:1 FAIL
Status pill — white on orange#ffffff#ff56304.5:13.17:1 FAIL
1 · Link hover is less readable than link resting

--link-hover aliases blue/200, measuring 2.80:1 on white against the 4.5:1 requirement. The resting colour --link-default measures 11.81:1. Hovering a link therefore makes it harder to read — the opposite of what a hover state is for, and a failure a user cannot avoid because it triggers on pointer movement.

Suggested fix: re-alias link/hover to blue/400 (7.19:1) or blue/300 (4.92:1). Both darken on hover, which is the conventional direction.

2 · The focus ring does not meet non-text contrast

--focus-ring also aliases blue/200, at 2.80:1 against white. SC 1.4.11 requires 3:1 for focus indicators against adjacent colours. Since the ring appears on white surfaces throughout the product, keyboard focus is currently below threshold system-wide.

Suggested fix: re-alias focus/ring to blue/300 (4.92:1). This is the single highest-leverage token change available — one alias fixes focus visibility on every component at once.

3 · Secondary button text fails on its own hover fill

--button-secondary-text (#0076b6) on --button-secondary-hover-background (#e1eaf8) measures 4.06:1. Button labels are 14px bold, which is not “large text” under WCAG (that needs 18.66px bold or 24px regular), so 4.5:1 applies.

Suggested fix: darken the label to blue/400 on hover (5.93:1), or lighten the hover fill.

4 · Status pill orange must use dark text

White on status/Orange measures 3.17:1. Black on the same orange measures 5.96:1. Pill text is 12px bold — again not “large” — so the light-text pairing fails and the dark one passes comfortably.

Fix applied in this library: .cds-status-pill--orange uses --status-text-dark. The Figma component should be updated to match.