# How to choose brand colours and fonts: start from lightness

> Contrast depends on lightness, not hue, so choose lightness first. In OKLab lightness, white text reaches 4.5:1 on fills darker than 0.55 and near-black text on fills lighter than 0.61. Between those, neither passes. Build the palette as a ramp that skips that band, then choose fonts for x-height, licence scope and loading, not for serif or sans.

By LAIN, 3 Mar 2026. 11 min read. Category: Branding. Canonical: https://lainagency.com/resources/choosing-brand-colours-and-fonts

Most guides on choosing brand colours start with meaning (blue for trust, red for energy) and finish with a contrast checker. That order is backwards. Hue is a taste decision you can defend or change. Contrast is arithmetic, and it is decided by one property: lightness. Fix the lightness steps first and every colour you add later is readable by construction. This guide works in that order, using numbers we computed and checked.

## Contrast is a lightness problem
The WCAG contrast ratio is calculated from relative luminance only. Two colours of different hue and equal luminance measure 1:1 against each other: a red, #c3594a, and a green, #358a3c, score 1.00:1 although nobody would confuse them. Hue and chroma barely enter the formula.

Perceptual colour spaces make that usable. Oklab, published by Björn Ottosson in December 2020, was built so that lightness, chroma and hue are perceptually independent; its polar form is called OKLCH. We used its lightness L, from 0 to 1, to find thresholds that hold for every hue. For 36 hues in 10 degree steps and six chroma levels, from grey up to the edge of the sRGB gamut, we searched for the lightest or darkest colour that still reached each ratio.

| Target ratio | A colour against white passes if | A colour against #121212 passes if |
|---|---|---|
| 3:1 | L is 0.64 or below | L is 0.53 or above |
| 4.5:1 | L is 0.55 or below | L is 0.61 or above (0.63 if very saturated) |
| 7:1 | L is 0.45 or below | L is 0.74 or above |

This is our own calculation with WCAG 2 ratios, sRGB and hex rounding included, not a published standard. A ratio does not depend on which colour is the text, so the table works both ways round. Check borderline colours in a checker anyway.

## The mid-tone trap
The table hides a consequence. A fill between about 0.55 and 0.61 is too light for white text and too dark for #121212 text. The reason is simple: contrast with white is 1.05 divided by (Y plus 0.05), where Y is the fill's relative luminance, and contrast with #121212 is (Y plus 0.05) divided by 0.056. They cross at 4.33. So the best text colour on the worst mid-tone fill gives 4.33:1, whatever the hue. With pure black as the ink the crossing is 4.58, so the trap nearly closes; the darker your ink, the narrower it is.

![A row of greys from black to white with Aa on each, white text on the dark ones, near-black on the light ones and 4.3 in the band between them.](https://lainagency.com/images/blog-art/choosing-brand-colours-and-fonts-fig2.webp)

Real palettes land in it. The olive, #6b7a55, on the [Outverge](https://lainagency.com/works/outverge) project page has L 0.557: white text gives 4.63:1, pure black 4.54:1 and #121212 only 4.05:1. It works with two of the three inks. Your own mid-tone brand colour has the same problem. The fix is a small move: shifting lightness by 0.03 to 0.05 barely changes how a colour looks but changes which text works. Ink matters too. The [Fleetly](https://lainagency.com/works/fleetly) palette lists charcoal, #303030, for type, and with that ink the safe fills start at about L 0.70 to 0.72. Its signal orange, #ff752d (L 0.72), would carry charcoal text at 4.92:1; the panel white, #fcfcfd, on it would be 2.61:1.

## The 40 and 50 shortcut has a hole
Two design systems turn this into a rule of thumb. The US Web Design System numbers every colour on a 0 to 100 grade scale and says a difference of 40 or more reaches AA for large text, 50 or more reaches AA for normal text and 70 or more reaches AAA. Material's HCT colour code says a tone difference of 40 guarantees 3:1 and of 50 guarantees 4.5:1, where tone is CIE L*.

Computed exactly from L*, a gap of 38.5 gives 3:1, 50.5 gives 4.5:1 and 62.5 gives 7:1. So 40 is safe, 70 is conservative, and 50 is a hair short: tone 50 on white measures 4.48:1. Material's own contrast code allows a 0.04 shortfall in the ratio, while WCAG says computed values must not be rounded and 4.499 fails. In practice use a gap of 52 or more (4.82 at worst for whole tones), or check the pair. The two systems also measure lightness differently, so do not mix their numbers.

## A worked ramp
Here is a ramp for an invented brand, nova, at hue 200 (a teal), with lightness steps chosen first. Ratios are against white and against #121212.

| Step | L | Hex | White | #121212 |
|---|---|---|---|---|
| 1 | 0.96 | #e3f6f7 | 1.12 | 16.76 |
| 2 | 0.90 | #c4e6e7 | 1.33 | 14.11 |
| 3 | 0.82 | #9fced1 | 1.72 | 10.90 |
| 4 | 0.72 | #6db2b6 | 2.42 | 7.76 |
| 5 | 0.62 | #33969b | 3.51 | 5.33 |
| 6 | 0.55 | #118186 | 4.66 | 4.02 |
| 7 | 0.45 | #026266 | 7.14 | 2.62 |
| 8 | 0.35 | #034346 | 11.08 | 1.69 |
| 9 | 0.25 | #022729 | 15.85 | 1.18 |
| 10 | 0.17 | #001314 | 19.03 | 1.02 |

The ramp has no step between 0.55 and 0.62 on purpose. It gives the roles for free. Step 6 and darker are text on white, links, and buttons with a white label. Step 5 and lighter carry #121212 text. Interface parts such as borders and icons need 3:1 against what is next to them, and step 5, at 3.51, is the lightest that qualifies on white. Step 4, at 2.42, does not. The hex values come from clamping OKLCH to sRGB, so verify them in your own tool.

## What the ratio does not see
WCAG 2.2 AA is still the test you can be held to. WCAG 3 is a draft, its own text says the contrast algorithm is still to be decided, and APCA, the alternative many designers cite, is not part of it. Sources disagree on when APCA was dropped from the draft: Adrian Roselli dates its removal to early 2023, and one blog says April 2026. The earlier date is better documented. Use the WCAG 2 ratio for pass or fail, and if you want an extra check for dark mode, treat APCA as advice.

Two limits of the ratio matter for brands. Thin faces render lighter than the colour you specified because of anti-aliasing, so a pair at 4.5:1 is weaker at weight 300. And dark mode is not a mirror: from the table, a teal that works as text on white at L 0.55 needs about L 0.63 or more to work on #121212, so a brand needs two steps for the same role.

## Colour that is also yours
Treat colour meaning as a hypothesis, not a rule. Labrecque and Milne ran four studies, which mapped hues to brand personality dimensions, tested how saturation and brightness strengthen them, and reportedly found that colour supported purchase intent when it fitted the personality the brand claimed. We read the abstract only. The reading we take: associations exist, they depend on saturation and brightness as well as hue, and fit with the brand's personality matters more than a rule like "blue means trust".

Distinctiveness is the better test. The Ehrenberg-Bass approach asks how many buyers link an asset to the brand (fame) and whether they link it only to that brand (uniqueness). A colour famous across the whole category scores low on uniqueness. One secondary source reports thresholds of 70% fame and 60% uniqueness, but we could not confirm them on an Institute page. The practical move needs no survey: list the lead colour of eight competitors. If yours sits among them, lead with a neutral and give the colour a different job. Our [rebrand guide](https://lainagency.com/resources/when-to-rebrand) has the full asset test.

## A colour-blind check that needs only lightness
We applied the Machado, Oliveira and Fernandes (2009) deuteranopia model, severity 1.0, to the red and green above. Normally the two are 0.237 apart in Oklab. Simulated, they become #8e8248 and #827742, two near-identical olives only 0.039 apart. Darkening the green to #1f6a2a, which separates the pair by 0.13 of lightness, brings the simulated gap back to 0.14. Success and error colours need a clear lightness difference and an icon or word, not only different hues. See the [accessibility checklist](https://lainagency.com/resources/website-accessibility-checklist).

## Fonts: choose by what can be measured
**Serif or sans is a weak lever.** Arditi and Cho (2005) found serif size had no effect on reading speed, though critics note four participants. A study of online reading found no overall difference. One comparison of Lucida and Lucida Sans reported the sans read about 20% faster in rapid presentation at a small size, with the gap gone at a larger size, but that result is unpublished. What is solid is the method: compare fonts at equal x-height, not equal point size, and test the smallest size you will use.

**Read the licence for each place the font will appear.** Desktop licences generally forbid embedding with @font-face. Web licences are typically capped by monthly pageviews, and one foundry says a web licence belongs to the site owner and cannot be spread across an agency's clients. App licences cover software, not web text. Get written confirmation for website, app, email and video.

**Self-host.** On 20 January 2022 the Munich Regional Court (case 3 O 17493/20) awarded a visitor 100 euros because a site loaded Google Fonts from Google's servers, sending their IP address without consent. The court rejected legitimate interest because the fonts can be hosted locally. These are law-firm summaries of the ruling, not legal advice.

**Plan the swap.** With `font-display: swap` the fallback shows at once and the page can jump when the brand font arrives. `optional` gives the font about 100 ms and then keeps the fallback for that page view. You can reduce the jump with `size-adjust`, `ascent-override` and `descent-override` on a fallback face, which tools such as Capsize calculate. One source says you can skip the ascent and descent overrides if you set a line height on all text. Measure layout shift on your own pages to decide. Choose a fallback with a similar x-height and write it in the [brand guidelines](https://lainagency.com/resources/brand-guidelines-what-to-include). The [hierarchy guide](https://lainagency.com/resources/typography-hierarchy-in-graphic-design) covers sizes.

## Where it goes wrong
| What happens | Cause | How to spot it | Fix |
|---|---|---|---|
| The button label is unreadable | The fill sits in the mid-tone band, or is too light for white | Compute the pair | Move the fill by 0.03 to 0.05 L, or change the label colour |
| It passes in light mode and fails in dark | The thresholds are not mirrored (0.55 against 0.63) | Test the same colour on both grounds | Define a second step for dark |
| Success and error look the same | Equal lightness | Simulate deuteranopia | Separate by lightness, add icons |
| The font jumps or looks different in email | Different fallback metrics | Check layout shift and test email clients | Match x-height, state the fallback |
| A licence claim arrives | A desktop licence was used for the web | Read it per use | Buy the right scope |
| The brand looks like everyone else | Lead colour shared with the category | List competitors' colours | Lead with a different job for colour |

## A pass or fail checklist
- Every text and background pair has a computed, unrounded ratio of at least 4.5:1 (3:1 for large text and interface parts).
- No fill between L 0.55 and 0.61 carries text unchecked.
- Dark mode has its own steps.
- Success and error differ in lightness and carry an icon or word.
- Eight competitors' lead colours are listed.
- Fonts: two at most, a fallback with matched x-height, a licence that covers web, app and email, and self-hosted files.

Our palettes show the idea at work. On the [Ordin](https://lainagency.com/works/ordin) page, Noir and Cloud carry almost everything, and Citrine (#cfdc4e) is kept for data. It measures 12.96:1 on Noir and 1.30:1 on Cloud, so as text it only works on the dark base. [Verden](https://lainagency.com/works/verden) lists a lime, #dffea2, for action, and it measures 9.81:1 on the brand green, #00453e. If you want a palette built this way, [talk to us about a brand identity](https://lainagency.com/contact).

## Frequently asked questions

### How do I know if a brand colour works with white or black text?

Compute the ratio, or check its OKLab lightness. White text reaches 4.5:1 on fills darker than L 0.55, and near-black #121212 text on fills lighter than 0.61. Between those, neither passes and the best case is about 4.3:1. Our own calculation, so confirm in a checker.

### Why does my brand colour fail with both white and black text?

It is probably a mid-tone. The contrast with white falls as the colour gets lighter and the contrast with black falls as it gets darker, and the two cross at about 4.33:1 when the ink is #121212. Move the fill 0.03 to 0.05 in lightness, or use a darker ink.

### Is a tone difference of 50 enough for WCAG AA?

Almost. Material says a difference of 50 guarantees 4.5:1, but computed exactly, tone 50 on white is 4.48:1. WCAG does not allow rounding up. A gap of 52 or more is safe for whole tones. A gap of 40 reaches 3:1.

### Should a brand use serif or sans-serif fonts?

Choose for character and context, not legibility. Controlled studies found little reliable difference in reading speed once x-height and spacing are matched, with a possible small-size advantage for sans that rests on weak studies. Compare candidates at equal x-height at your smallest size, and check the licence.

### Can I load Google Fonts from Google on a website?

A Munich court ruled in January 2022 that doing so without consent, sending a visitor's IP address to Google, justified 100 euros in damages, because the fonts could be hosted locally. Self-hosting the files avoids the issue. Check the font licence allows it, and take legal advice for your situation.

### Does colour psychology tell me which brand colour to choose?

Only loosely. Research finds hues link to personality traits, and the effect depends on saturation and brightness and on how well the colour supports the brand's claimed personality. Competitors matter more: a colour famous across the whole category is not distinctive for you.

## Sources and fact check

Checked on 28 Oct 2026.

- [USWDS: Design tokens, color overview (grades and the magic number)](https://designsystem.digital.gov/design-tokens/color/overview/)
- [Material Color Utilities: hct.ts (tone and contrast guarantee)](https://raw.githubusercontent.com/material-foundation/material-color-utilities/main/typescript/hct/hct.ts)
- [Material Color Utilities: contrast.ts](https://raw.githubusercontent.com/material-foundation/material-color-utilities/main/typescript/contrast/contrast.ts)
- [W3C: Understanding Success Criterion 1.4.3 Contrast (Minimum)](https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html)
- [W3C: Understanding Success Criterion 1.4.11 Non-text Contrast](https://www.w3.org/WAI/WCAG22/Understanding/non-text-contrast.html)
- [Björn Ottosson: A perceptual color space for image processing](https://bottosson.github.io/posts/oklab/)
- [Adrian Roselli: WCAG3 Contrast as of April 2026](https://adrianroselli.com/2026/04/wcag3-contrast-as-of-april-2026.html)
- [Machado, Oliveira and Fernandes: A physiologically-based model for simulation of color vision deficiency](https://www.inf.ufrgs.br/~oliveira/pubs_files/CVD_Simulation/CVD_Simulation.html)
- [Labrecque and Milne: Exciting red and competent blue (Journal of the Academy of Marketing Science)](https://colab.ws/articles/10.1007/s11747-010-0245-y)
- [Ehrenberg-Bass Institute: distinctive asset measurement](https://assets.marketingscience.info/distinctive-asset-measurement.pdf)
- [Arditi and Cho: Serifs and font legibility (Vision Research, 2005)](https://pubmed.ncbi.nlm.nih.gov/16099015)
- [Readability research: an interdisciplinary approach (arXiv)](https://arxiv.org/pdf/2107.09615)
- [Fontspring: Desktop font license](https://www.fontspring.com/license/fontspring/desktop)
- [activeMind.legal: Ruling on Google Fonts (LG Munich, 20 January 2022)](https://www.activemind.legal/guides/ruling-google-fonts/)
- [DebugBear: Web font layout shift](https://debugbear.com/blog/web-font-layout-shift)

