Design system
Three brands, one codebase
Every component asks for a colour by its role, never by its value. Each brand answers in its own colours, and a test on every pull request checks that every text colour reads on every surface it sits on. If one drops below WCAG AA, the change cannot ship.
The house brand. Soft 18px corners, a serif for titles.
Online course
Musicality from the ground up
Hear the structure of a song before you dance it: phrases, breaks and the moment the music changes.
12 lessons · 3 h 40 min
Beginner friendlySolo practiceSpanish + English
Counting the phraseWatched · Lesson 1 · 9 min
Where the break landsWatched · Lesson 2 · 14 min
Timing on the oneUp next · Lesson 3 · 12 min
What CI checks
Every text role on every ground
Small text needs 4.5:1. The same numbers run as a test on every pull request.
| Role | Page | Surface | Accent tint |
|---|---|---|---|
| Ink | Aa17.7:1 | Aa18.1:1 | Aa16.4:1 |
| Text | Aa12.7:1 | Aa13.0:1 | Aa11.8:1 |
| Muted | Aa5.5:1 | Aa5.7:1 | Aa5.1:1 |
| Faint text | Aa5.5:1 | Aa5.7:1 | Aa5.1:1 |
| Accent text | Aa5.2:1 | Aa5.4:1 | Aa4.8:1 |
The same component, three times
One component, no props for colour. Only the custom properties around it change.
Timing on the oneUp next · Lesson 3 · 12 min
Cream & Gold
Timing on the oneUp next · Lesson 3 · 12 min
Slate
Timing on the oneUp next · Lesson 3 · 12 min
Violet