Skip to main content
BEEQ color system overview — light modeBEEQ color system overview — dark mode

BEEQ colors overview — a snapshot of some tokens from the color palette

Color in BEEQ serves communication, not decoration. The system gives every color a clear role — brand identity, feedback, hierarchy, or data — so interfaces stay consistent across products and themes.
Always reach for a mode role (--bq-text--primary, --bq-ui--brand, etc.) rather than a raw primitive value. Mode roles adapt automatically to the active theme and to light and dark mode. Primitives do not.For the main brand color on a fill, use --bq-ui--brand. --bq-brand is a root semantic: set it when you define a theme, and do not use it to style UI.

Color architecture

BEEQ resolves every color through four layers. Each layer only references the layer above it, so a change at the top flows through every role, component, and mode below. For example, the primary button fill in the BEEQ theme resolves like this:
BEEQ components only read mode roles and component variables — never primitives or root semantics directly. Mode roles in turn only reference root semantics, which is why rebranding the root layer is enough to restyle every component in both modes.

Color palette

The palette on this page is the root semantics layer — the colors each theme assigns to its intents, neutrals, and data series. Every color is shown for both built-in themes, and each swatch shows the primitive it points to — the hex codes are in Primitive color scales. To switch themes in your app, see Themes and modes.

Intent scale

BEEQ has six intents: brand, accent, info, success, warning, and danger. Every intent ships five steps, and each step has a single job: The base step is tuned to be recognizable as a fill, not to be readable as text, so text, icons, and strokes use -strong and -bright instead. Those steps reach 4.5:1 on neutral surfaces and on the matching -alt tint, and -bright also reaches APCA Lc 60, because WCAG 2 overrates light text on dark surfaces. When the base primitive already meets those targets, the step reuses it, so some swatches repeat: BEEQ brand-strong and accent-strong, and Endava warning-bright. Endava brand-strong, brand-bright, accent-strong, and accent-bright reuse Red Orange, so brand text, icons, and strokes match the brand fill as on endava.com. That’s a documented contrast exception.
  • Brand anchors primary actions, selection, and brand surfaces.
  • Accent is a secondary brand color for white-label themes. BEEQ components don’t use it; the Endava theme aliases it to brand.
  • Info communicates neutral, informational feedback. It’s a separate intent and never resolves through brand.
  • Success, warning, and danger communicate feedback states. Never use them for decoration or branding.

brand-light

var(--bq-iris-100)

brand

var(--bq-iris-600)

brand-dark

var(--bq-iris-950)

brand-strong

var(--bq-iris-600)

brand-bright

var(--bq-iris-300)

accent-light

var(--bq-purple-100)

accent

var(--bq-purple-600)

accent-dark

var(--bq-purple-950)

accent-strong

var(--bq-purple-600)

accent-bright

var(--bq-purple-300)

info-light

var(--bq-blue-100)

info

var(--bq-blue-600)

info-dark

var(--bq-blue-950)

info-strong

var(--bq-blue-700)

info-bright

var(--bq-blue-300)

success-light

var(--bq-teal-100)

success

var(--bq-teal-600)

success-dark

var(--bq-teal-950)

success-strong

var(--bq-teal-800)

success-bright

var(--bq-teal-400)

warning-light

var(--bq-gold-100)

warning

var(--bq-gold-600)

warning-dark

var(--bq-gold-950)

warning-strong

var(--bq-gold-800)

warning-bright

var(--bq-gold-400)

danger-light

var(--bq-red-100)

danger

var(--bq-red-600)

danger-dark

var(--bq-red-950)

danger-strong

var(--bq-red-700)

danger-bright

var(--bq-red-300)

Swatch names drop the --bq- prefix — for example, brand-strong is --bq-brand-strong. Each step has the same value in light and dark mode; the mode only changes which step a role uses, as shown in Mode roles.

Neutral

The neutral scale underpins surfaces, text, borders, and icons. --bq-white and --bq-black complete it. In the BEEQ theme the neutrals alias the grey primitives, and --bq-white and --bq-black are plain hex values with no primitive behind them; in the Endava theme they’re the Endava Solid Blue shades, --bq-neutral-950 is Solid Blue itself, and --bq-black is the slightly darker --bq-endava-grey-1000 (#14222C).

bq-white

#ffffff

bq-neutral-50

var(--bq-grey-50)

bq-neutral-100

var(--bq-grey-100)

bq-neutral-200

var(--bq-grey-200)

bq-neutral-300

var(--bq-grey-300)

bq-neutral-400

var(--bq-grey-400)

bq-neutral-500

var(--bq-grey-500)

bq-neutral-600

var(--bq-grey-600)

bq-neutral-700

var(--bq-grey-700)

bq-neutral-800

var(--bq-grey-800)

bq-neutral-900

var(--bq-grey-900)

bq-neutral-950

var(--bq-grey-950)

bq-neutral-1000

var(--bq-grey-1000)

bq-black

#060708

Data colors

A curated set of 12 distinct hues for charts, graphs, and data-driven visualizations. Use them in sequence — bq-data-01 first — to maintain legibility as more series are added. bq-data-01 always follows the theme’s brand color, and bq-data-11 and bq-data-12 reuse --bq-black and --bq-white.

bq-data-01

var(--bq-iris-600)

bq-data-02

var(--bq-purple-600)

bq-data-03

var(--bq-magenta-600)

bq-data-04

var(--bq-cyan-600)

bq-data-05

var(--bq-teal-600)

bq-data-06

var(--bq-orange-600)

bq-data-07

var(--bq-yellow-600)

bq-data-08

var(--bq-red-600)

bq-data-09

var(--bq-blue-600)

bq-data-10

var(--bq-grey-600)

bq-data-11

#060708

bq-data-12

#ffffff

The full primitive palette — all hue scales grouped by color — is available in the Primitive color scales reference section below.

Mode roles

Mode roles are the building blocks of every BEEQ component. They abstract the “what” (raw hex) from the “why” (intended role), so the same token resolves to the right value for the active theme and mode without manual overrides. Use the tabs to switch between the BEEQ and Endava themes. The swatches follow the current docs mode and show the primitive each role resolves to — click any swatch to copy the CSS custom property name. The tables list the root semantic each role points to, without the --bq- prefix, for both themes and modes.

Background

Use background tokens for page surfaces, cards, modals, drawers, and overlays.

--bq-background--primary

#ffffff

--bq-background--secondary

var(--bq-grey-100)

--bq-background--tertiary

var(--bq-grey-200)

--bq-background--alt

var(--bq-grey-300)

--bq-background--inverse

var(--bq-grey-900)

--bq-background--brand

var(--bq-iris-600)

--bq-background--overlay

var(--bq-grey-900)

UI elements

Use UI tokens for component fills — buttons, toggles, chips, selects, badges, and other small shapes.

--bq-ui--primary

#ffffff

--bq-ui--secondary

var(--bq-grey-100)

--bq-ui--tertiary

var(--bq-grey-500)

--bq-ui--inverse

var(--bq-grey-900)

--bq-ui--alt

var(--bq-grey-50)

--bq-ui--brand

var(--bq-iris-600)

--bq-ui--brand-alt

var(--bq-iris-100)

--bq-ui--accent

var(--bq-purple-600)

--bq-ui--accent-alt

var(--bq-purple-100)

--bq-ui--info

var(--bq-blue-600)

--bq-ui--info-alt

var(--bq-blue-100)

--bq-ui--success

var(--bq-teal-600)

--bq-ui--success-alt

var(--bq-teal-100)

--bq-ui--warning

var(--bq-gold-600)

--bq-ui--warning-alt

var(--bq-gold-100)

--bq-ui--danger

var(--bq-red-600)

--bq-ui--danger-alt

var(--bq-red-100)

Intent fills follow the same rule for every intent: {intent} is one of brand, accent, info, success, warning, or danger.

Text

Use text tokens for all typographic content — headings, body copy, labels, captions. Never apply a raw hex value to text.

--bq-text--primary

var(--bq-grey-800)

--bq-text--secondary

var(--bq-grey-600)

--bq-text--inverse

var(--bq-grey-50)

--bq-text--brand

var(--bq-iris-600)

--bq-text--accent

var(--bq-purple-600)

--bq-text--info

var(--bq-blue-700)

--bq-text--success

var(--bq-teal-800)

--bq-text--warning

var(--bq-gold-800)

--bq-text--danger

var(--bq-red-700)

On-color text

On-color tokens set the text and icon color on a solid intent fill. Each one is tuned to its --bq-ui--{intent} fill — white on dark fills, --bq-black on light fills — so the pair stays legible at rest, on hover, and when active.

--bq-text--on-brand

#ffffff

--bq-text--on-accent

#ffffff

--bq-text--on-info

#ffffff

--bq-text--on-success

#060708

--bq-text--on-warning

#060708

--bq-text--on-danger

#ffffff

Treat a fill and its on-color as a pair. If you override --bq-ui--{intent} or --bq-{intent}, check --bq-text--on-{intent} against the new fill and override it too when needed.

Icons

Use icon tokens for SVG fills. Pair each icon token with the text token of the same context — for example, --bq-icon--danger alongside --bq-text--danger. Icons need 3:1 against their surface.

--bq-icon--primary

var(--bq-grey-800)

--bq-icon--secondary

var(--bq-grey-600)

--bq-icon--inverse

var(--bq-grey-50)

--bq-icon--brand

var(--bq-iris-600)

--bq-icon--accent

var(--bq-purple-600)

--bq-icon--info

var(--bq-blue-700)

--bq-icon--success

var(--bq-teal-800)

--bq-icon--warning

var(--bq-gold-800)

--bq-icon--danger

var(--bq-red-700)

Stroke

Use stroke tokens for borders, dividers, and outlines.

--bq-stroke--primary

var(--bq-grey-200)

--bq-stroke--secondary

var(--bq-grey-600)

--bq-stroke--tertiary

var(--bq-grey-900)

--bq-stroke--inverse

#ffffff

--bq-stroke--alt

var(--bq-grey-50)

--bq-stroke--brand

var(--bq-iris-600)

--bq-stroke--brand-alt

var(--bq-iris-100)

--bq-stroke--accent

var(--bq-purple-600)

--bq-stroke--info

var(--bq-blue-700)

--bq-stroke--success

var(--bq-teal-800)

--bq-stroke--warning

var(--bq-gold-800)

--bq-stroke--danger

var(--bq-red-700)

States

State tokens drive hover, pressed, and focus feedback. They’re mode roles, so they follow the active theme and mode. Hover and active colors are derived where they’re used, by mixing the rest color with the state base at 20%:
BEEQ components work the same way: component variables hold the rest color, and the stylesheet applies the mix. Override the rest color and the hover and active states follow. A *-hover component variable only exists when the hover state starts from a different color than the rest state — for example, --bq-option--background-hover defaults to --bq-ui--secondary — and it holds that base role, not a pre-mixed value.

Usage rules

Every family has one job. Pairing tokens from the same row keeps contrast within the tested ranges.
Do
  • Use mode roles for all component and layout styling
  • Put --bq-text--on-{intent} on solid --bq-ui--{intent} fills
  • Use --bq-text--{intent} on neutral surfaces and -alt tints
  • Use data colors (data-01 → data-12) for all chart series
  • Check every custom color pair for contrast, including hover and active
Don’t
  • Hard-code hex values in component styles — always use a token
  • Put intent text (--bq-text--brand) on a solid intent fill
  • Use the brand color as a large background surface; it creates visual overload
  • Apply feedback colors (success, warning, danger) for decoration or branding
  • Rely on color alone to communicate state or meaning

Using colors in code

CSS custom properties

Every token is a native CSS custom property. Apply mode roles directly to any element:
Primitive values are available when you need a specific scale step — for example, building a gradient or a custom illustration:

Tailwind CSS

Add @beeq/tailwindcss to your project to use BEEQ’s mode roles as Tailwind utility classes. Tailwind v3 — add it as a preset in tailwind.config.ts:
Tailwind v4 — load it with @plugin in your CSS entry file:
@beeq/tailwindcss 1.16.2 and earlier fail with @plugin (b is not a function). On those versions, use @config "@beeq/tailwindcss"; instead.
If you also import beeq.css, add layer(base) to that import so the BEEQ reset doesn’t override Tailwind utilities. See Apps that use cascade layers.
Once set up, all mode roles are available as utility classes: Primitive hues are also available as standard Tailwind color utilities:
To apply a custom brand, override the CSS custom properties in your stylesheet — the utility classes resolve to whatever the CSS variables point to. See Theming and customization below.

Accessibility

Color alone must never be the only way information is communicated. Always pair color with text labels, icons, or patterns. BEEQ’s mode roles meet WCAG 2.1 Level AA contrast when you pair them as described in Usage rules. This applies to the built-in BEEQ and Endava themes in light and dark mode: BEEQ’s own test suite checks every pair below on every change.
Those tests don’t run in your app, so if you override colors, check your values against the same pairs and minimums — see the contrast checklist for custom brands.
Some pairs are deliberately outside these guarantees:
  • --bq-stroke--primary is decorative and --bq-stroke--secondary marks subtle or disabled borders, so neither carries the 3:1 non-text requirement. Use --bq-stroke--tertiary for borders that identify an interactive control.
  • In the BEEQ theme, dark-mode --bq-text--accent and --bq-text--danger reach APCA Lc 59.5 and 59.8 on --bq-ui--secondary, just under Lc 60. They still meet about 7:1.
  • In the Endava theme, --bq-text--secondary is only legible on primary and secondary surfaces. Don’t place it on --bq-background--tertiary or --bq-background--alt.
  • In the Endava theme, light-mode --bq-text--brand, --bq-icon--brand, --bq-stroke--brand, --bq-focus, and their accent versions are Red Orange (#FF5640), so they match the brand fill. Red Orange is 3.15:1 on --bq-background--primary and --bq-ui--primary, which meets 3:1 for icons, strokes, focus, and large text (24px, or 18.66px bold), but not 4.5:1 for regular text. On --bq-background--secondary and --bq-ui--secondary (2.61:1) and the brand tint --bq-ui--brand-alt (2.81:1), it falls below 3:1. If you need AA everywhere, override --bq-brand-strong with #C33600 (var(--bq-endava-orange-800)).
  • In the Endava theme, dark-mode --bq-text--brand and --bq-text--accent are Red Orange (#FF5640), as on endava.com. They meet 4.5:1 only on --bq-background--primary and --bq-ui--primary. On --bq-background--secondary, --bq-ui--secondary (3.40:1), and the brand tint --bq-ui--brand-alt (3.77:1), they meet AA for large text (24px, or 18.66px bold) only. If you need AA for regular text there, override --bq-brand-bright with #FF8979.
  • In the Endava theme, dark-mode --bq-text--success (#3DD17B) and --bq-text--warning (#F99C11) use the brand guide’s dark signal colours. They meet 4.5:1 on every dark surface but reach only APCA Lc 51–57. For APCA Lc 60, override --bq-success-bright with #6EDC9C and --bq-warning-bright with #FBBA58.
Endava brand fills are a large-text exception. White on Endava Red Orange (#FF5640) is 3.15:1, so --bq-text--on-brand and --bq-text--on-accent meet AA only for large text (24px, or 18.66px bold) and non-text UI. Keep labels on Endava brand fills large, or darken the fill for your app:
#D63B10 is the brand-contrast orange used on endava.com. White text on it reaches 4.67:1 at rest, and more on hover and active. For more contrast, use #C33600 (var(--bq-endava-orange-800), 5.46:1).
Verify custom color pairings with the WebAIM Contrast Checker or the APCA Contrast Calculator before shipping. For solid fills, check the hover and active mixes too.

Theming and customization

Designers: need to build a custom palette for a client project before applying it in Figma? See Building your color palette.
All BEEQ components read colors from CSS custom properties. Overriding those properties is the one universal mechanism for applying a custom brand — no library modifications needed, and it works regardless of your styling tool. BEEQ declares its theme and mode tokens inside :where(), so they have zero specificity and any plain selector in your stylesheet wins. Rebrand at the root layer and set the whole intent scale, plus the on-color for the new fill:
If your project also uses Tailwind, adding @beeq/tailwindcss makes your own utility classes (bg-brand, text-primary, etc.) resolve to the same tokens. The two approaches are independent and complementary — the Tailwind integration does not replace CSS overrides, it builds on top of them. For per-mode, per-section, and per-component overrides, and a contrast checklist for custom brands, see Custom theme.

Primitive color scales

The complete raw hue scales — grouped by color, not by meaning. Each step is available as var(--bq-{hue}-{scale}). Use these when tracing which raw value backs a root semantic or when defining a custom theme.

Blue

Corai

Cyan

Gold

Green

Grey

Indigo

Iris

Lime

Magenta

Orange

Purple

Red

Sky

Teal

Volcano

Yellow

The Endava theme draws from its own --bq-endava-* primitives, named after the Endava brand palette. Some scales only include the steps the theme uses.

Endava Orange

Endava Grey

Endava Positive

Endava Negative

Endava Info

Endava Warning


Resources

Custom theming

Full walkthrough for applying a custom brand, including light/dark mode token overrides.

GitHub — Theme source

Browse the full primitive palette, semantic tokens, and theme definitions.