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.
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.
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.
| Role | Text | Background | Border | Measured |
|---|---|---|---|---|
| Error | --error-text | --error-background | --error-border | 5.97:1 ✔ |
| Success | --success-text | --success-background | --success-border | 7.49:1 ✔ |
| Warning | --color-yellow-100 | --color-yellow-200 | --color-yellow-300 | 7.74:1 ✔ |
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.
The Figma file assigns each colour a meaning. Honour it — the colour is the fast signal, the label is the accurate one:
| Colour | Meaning | Text token |
|---|---|---|
| Gray | Not yet started. No user action required. | --status-text-dark |
| Light blue | In progress, no action required from this user. | --status-text-dark |
| Blue | Under review by another party. | --status-text-light |
| Yellow | Waiting on someone else; informational. | --status-text-dark |
| Orange | Requires the user’s immediate attention, or a waiting period. | --status-text-dark — see audit |
| Green | Complete, approved, funded. | --status-text-light |
| Custom | Product-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
| Combination | Foreground | Background | Requires | Measured |
|---|---|---|---|---|
| Body text on white | #111111 | #ffffff | 4.5:1 | 18.88:1 PASS |
| Caption / help text on white | #5e5e5e | #ffffff | 4.5:1 | 6.48:1 PASS |
| Brand blue text on white | #0076b6 | #ffffff | 4.5:1 | 4.92:1 PASS |
| White on primary button | #ffffff | #0076b6 | 4.5:1 | 4.92:1 PASS |
| White on primary button, hovered | #ffffff | #005c8e | 4.5:1 | 7.19:1 PASS |
| Link (resting) on white | #253272 | #ffffff | 4.5:1 | 11.81:1 PASS |
| Error text on error background | #b31200 | #ffe8e6 | 4.5:1 | 5.97:1 PASS |
| Success text on success background | #285d35 | #f8fdef | 4.5:1 | 7.49:1 PASS |
| Warning text on warning background | #7d3d02 | #fff8d8 | 4.5:1 | 7.74:1 PASS |
| Input border on white (non-text) | #888c8c | #ffffff | 3:1 | 3.40:1 PASS |
| Status pill — black on yellow | #111111 | #ffc810 | 4.5:1 | 12.16:1 PASS |
| Status pill — black on light blue | #111111 | #accdff | 4.5:1 | 11.63:1 PASS |
| Status pill — black on gray | #111111 | #d4d4d5 | 4.5:1 | 12.75:1 PASS |
| Status pill — white on blue | #ffffff | #0747a6 | 4.5:1 | 8.53:1 PASS |
| Status pill — white on green | #ffffff | #006644 | 4.5:1 | 7.04:1 PASS |
| Status pill — white on custom | #ffffff | #333333 | 4.5:1 | 12.63:1 PASS |
Failing — four open issues
| Combination | Foreground | Background | Requires | Measured |
|---|---|---|---|---|
| Link hover on white | #44a3db | #ffffff | 4.5:1 | 2.80:1 FAIL |
| Focus ring against white (SC 1.4.11) | #44a3db | #ffffff | 3:1 | 2.80:1 FAIL |
| Secondary button text on its hover fill | #0076b6 | #e1eaf8 | 4.5:1 | 4.06:1 FAIL |
| Status pill — white on orange | #ffffff | #ff5630 | 4.5:1 | 3.17:1 FAIL |
--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.
--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.
--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.
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.