Build
Tokens
Every value of the brand as a named role, light and dark. How they are named, how to use them — on the web, in Swift, in token tools — and the complete table.
A token is a name for a decision. --flaeche-karte says what a colour is for. The value behind it may change, the name stays. Components know only names, never values.
Names
Tokens are named in German, by design. Each name describes a role, never a step on a scale: „Karte“ (card), not „Beige 200“.
| Level | Examples | Used by |
|---|---|---|
| Base colours | --grund, --karte, --tinte, --rosa, --gelb, --blau | only the semantic roles |
| Semantic roles | --flaeche-seite, --text-koerper, --linie-haar, --rand-offen, --akzent | components and pages |
| Component roles | --knopf-primaer-flaeche, --knopf-inaktiv-text, --leiste-ort-zeiger | one component and its states |
| People | --person-1 to --person-8, --person-linie-1 to --person-linie-8, --person-text | sticky notes, avatars, lanes |
| Sizes | --raum-2, --karte-innen, --ziel-finger, --radius-karte, --strich-haar | spacing, targets, shape |
| Type | --schrift-titel, --grad-karten-titel, --gewicht-text-fest, --laufweite-titel | typography |
| Motion | --dauer-kurz, --verlauf-ruhig | transitions |
A component reaches for a semantic role whenever one exists. Using --grund directly is allowed, but --flaeche-seite says more.
A few words you will meet in names:
| German | English | German | English |
|---|---|---|---|
| grund | ground | raum | space |
| karte | card | ziel | target |
| flaeche | surface | schrift | typeface |
| tinte | ink | grad | size |
| linie | line | gewicht | weight |
| rand | outline | dauer | duration |
| knopf | button | verlauf | easing |
| hell | light | dunkel | dark |
Light and dark
Dark mode redefines the roles; it is not a second design. It hangs on one attribute on the root element:
<html data-modus="dunkel">
The roles then take different values. No component asks which mode is on. Person notes, pink, yellow and blue stay light surfaces at night. Text on them uses --person-text, --text-auf-gelb, --text-auf-blau or --text-auf-rosa, which stay dark.
With reduced motion every duration is 0 ms. tokens/motion.css emits that as its own block for prefers-reduced-motion.
The files
| File | Contents | For |
|---|---|---|
/tokens/tokens.json | every token resolved: name, CSS variable, light, dark, alias, meaning | agents, scripts, checks |
/tokens/tokens.dtcg.json | the source in W3C format, all sets in one file | token tools, Style Dictionary |
/tokens/tokens.css | CSS variables light and dark, type, space, shape, motion | any web surface |
/tokens/fonts.css | @font-face for the four fonts, served locally | web, together with the font files |
/tokens/tailwind.css | Tailwind v4 theme: the same roles as utilities | Next.js with Tailwind |
/tokens/Tokens.swift | AlbertFarbe, AlbertRaum, AlbertSchrift, AlbertForm, AlbertBewegung | SwiftUI |
/regeln.json | rules that are not values: words, registers, limits | copy and checks |
On the web
Inside the monorepo everything comes from the workspace package. Order matters: tokens first, then component states.
// app/layout.tsx
import "@hey-albert/design-system/styles.css";
With Tailwind, import the theme after Tailwind. It switches off Tailwind’s own colours, shadows and radii.
@import "tailwindcss";
@import "@hey-albert/design-system/tailwind/theme.css";
@import "@hey-albert/design-system/tailwind/shadcn.css";
Then you have bg-grund, text-tinte, rounded-karte, p-raum-2, h-ziel-finger and font-schrift-titel. The dark: variant follows data-modus.
Outside the monorepo: download tokens.css and fonts.css, put the font files from the package next to them and include both files.
In Swift
Copy Tokens.swift into the target or add it to a Swift package. Colours are dynamic and follow the system appearance.
Text("Felix · Handball")
.foregroundStyle(AlbertFarbe.textKoerper)
.padding(AlbertRaum.karteInnen)
.background(AlbertFarbe.flaecheKarte, in: RoundedRectangle(cornerRadius: AlbertForm.radiusKarte))
In token tools
tokens.dtcg.json follows the W3C Design Tokens Community Group format. Tools such as Tokens Studio read it directly. Themes live in $themes: Hell (light) uses farben-hell, Dunkel (dark) layers farben-dunkel on top. $metadata sets the order of the sets.
All tokens
Clicking a name copies var(--name). Meanings are given in German, as in the source.
Colour
| Token | Light | Dark | Meaning |
|---|---|---|---|
#F8F2E7 | #14110D | Seitenhintergrund, warmes Creme | |
#EEE8DD | #2A2620 | Standardkarte (Termin), beige | |
#FBF7EE | #201C17 | Tagesreiter, Menüs, Badges auf Karten, Suchfeld | |
#EDE6D8 | #322D26 | Segment-Regler inaktiv, sekundäre Knöpfe | |
#171717 | #0B0A08 | Leiste, primäre Knöpfe, heutiger Tag, aktive Auswahl | |
#2C2C2C | #2C2C2C | Schwarz unter dem Zeiger (Knopf, Kreis, heutiger Reiter) | |
#3A3A3A | #3A3A3A | Schwarz beim Drücken | |
#1A1A1A | #F4EFE6 | Fließtext, Titel | |
#6E6A63 | #A9A297 | Zweittext, Zeiten, Beschriftungen | |
#D8D0BF | #3D372E | Haarlinien 1 px, Ränder von Feldern und Kreisen | |
#F3B8DF | #F3B8DF | Akzent: Plus, Jetzt-Zeit, aktiver Ort, Zähler, Lupe | |
#F7CDE8 | #F7CDE8 | Zustands-Pillen, Tageskreis mit Offenem | |
#F5D95C | #F5D95C | Familie und Rituale, Alberts Vorschlag (iPhone), Zahlen | |
#E4C63A | #E4C63A | Formen auf gelben Karten | |
#BFD9A6 | #BFD9A6 | Bewertung: gut (HQ) | |
#F5D95C → gelb | #F5D95C | Bewertung: Potenzial (HQ) | |
#EBA7A0 | #EBA7A0 | Bewertung: schwach (HQ) | |
#2B2A25 | #2B2A25 | ||
#BFCDF0 | #BFCDF0 | Fahrten | |
#9DB1E3 | #9DB1E3 | Formen auf blauen Karten | |
#B8467F | #F09CC6 | nur gestrichelter Rand für „ohne Zuständigen“ | |
#4A4530 | #4A4530 | Zweittext auf gelben Flächen | |
#F4EFE6 | #F4EFE6 | Text und Zeichen auf Schwarz | |
#C9A0BD | #B98CAD | gedämpftes Rosa-Grau für den Sonntag |
| Token | Light | Dark | Meaning |
|---|---|---|---|
#F8F2E7 → grund | #14110D | ||
#FBF7EE → hell | #201C17 | was schwebt: Menü, Reiter, Feld | |
#EEE8DD → karte | #2A2620 | Termin | |
#BFCDF0 → blau | #BFCDF0 | Fahrt | |
#F5D95C → gelb | #F5D95C | Familie und Ritual | |
transparent | transparent | Vorschlag: gestrichelt, ohne Füllung | |
#171717 → schwarz | #0B0A08 | ||
rgba(26, 26, 26, 0.32) | rgba(0, 0, 0, 0.56) | dämpft, was dahinter liegt | |
rgba(244, 239, 230, 0.08) | rgba(244, 239, 230, 0.08) | Ort in der Leiste unter dem Zeiger | |
rgba(244, 239, 230, 0.14) | rgba(244, 239, 230, 0.14) | aktiver Ort in der Leiste unter dem Zeiger |
| Token | Light | Dark | Meaning |
|---|---|---|---|
#1A1A1A → tinte | #F4EFE6 | ||
#1A1A1A → tinte | #F4EFE6 | ||
#6E6A63 → grau | #A9A297 | ||
#F4EFE6 → leistentext | #F4EFE6 | ||
#9A948B | #8C857A | ||
#4A4530 → auf-gelb | #4A4530 | ||
#1A1A1A → tinte | #1A1A1A | ||
#4A4F63 | #4A4F63 | Zweittext auf blauen Flächen (Fahrt) | |
#1A1A1A → tinte | #1A1A1A | ||
#A29B8F | #7A7469 | gerechnet, keine Deckkraft |
| Token | Light | Dark | Meaning |
|---|---|---|---|
#D8D0BF → linie | #3D372E | ||
#C2B8A2 | #524A3D | Kontur 1,5 px statt 1 px | |
#E4DDCE | #2B2620 | gerechnet, keine Deckkraft | |
#1A1A1A → tinte | #F4EFE6 | gestrichelte Jetzt-Achse | |
#6E6A63 → grau | #A9A297 | gestrichelt grau: Vorschlag von Albert | |
#B8467F → offen | #F09CC6 | gestrichelt: ohne Zuständigen | |
#B8467F → offen | #F09CC6 | :focus-visible Ring |
| Token | Light | Dark | Meaning |
|---|---|---|---|
#F3B8DF → rosa | #F3B8DF | Akzent und „jetzt“ – nie Fehler | |
#F7CDE8 → rosa-hell | #F7CDE8 | ||
#B8467F → offen | #F09CC6 | ||
#BFCDF0 → blau | #BFCDF0 | ||
#9DB1E3 → blau-dunkel | #9DB1E3 | ||
#F5D95C → gelb | #F5D95C | ||
#E4C63A → gelb-dunkel | #E4C63A | ||
#EEE8DD → karte | #2A2620 |
| Token | Light | Dark | Meaning |
|---|---|---|---|
#171717 → schwarz | #F4EFE6 | ||
#2C2C2C → schwarz-zeiger | #E2DACD | Druck macht die Fläche nicht dunkler, sondern die Schrift ruhiger | |
#3A3A3A → schwarz-druck | #CFC6B7 | ||
#F4EFE6 → leistentext | #171717 | ||
#EDE6D8 → knopf-zweit | #322D26 | ||
#1A1A1A → tinte | #F4EFE6 | ||
#E9E2D4 | #2B2620 | ||
#A29B8F → text-inaktiv | #7A7469 |
| Token | Light | Dark | Meaning |
|---|---|---|---|
#D5F5C2 | #D5F5C2 | Anna - Mint | |
#A8E5E5 | #A8E5E5 | Tobias - Türkis | |
#F6D0FF | #F6D0FF | Felix - Flieder | |
#FFD6A5 | #FFD6A5 | Lena - Pfirsich | |
#AEBAFF | #AEBAFF | Sofia - Himmel | |
#C7EFD0 | #C7EFD0 | frei | |
#FFC9C9 | #FFC9C9 | frei | |
#E3DCA8 | #E3DCA8 | frei | |
#1A1A1A → tinte | #1A1A1A | ||
#8FCF6E | #A6DE87 | ||
#62BFBF | #7FD6D6 | ||
#D28FE8 | #E4A8F5 | ||
#E0A55F | #F0BE7C | ||
#7B8BE0 | #9AA8F0 | ||
#7FC993 | #98DBAA | ||
#E08F8F | #F0A8A8 | ||
#B7AE6A | #CFC57F |
Type
| Token | Light | Meaning |
|---|---|---|
| Ag | "Bricolage Grotesque", "Helvetica Neue", system-ui, sans-serif | |
| Ag | Inter, system-ui, -apple-system, sans-serif | |
| Ag | "Roboto Mono", ui-monospace, "SF Mono", monospace | |
| Ag | "Reenie Beanie", "Bradley Hand", cursive |
| Token | Light | Meaning |
|---|---|---|
800 | ||
400 | ||
500 | ||
600 |
| Token | Light | Meaning |
|---|---|---|
40px | „Guten Morgen, Anna.“ auf dem Mac | |
30px | dieselbe Zeile auf dem iPhone | |
34px | Zahl-Kachel: 8,7 h | |
22px | Logo in der Leiste | |
17px | ||
14.5px | Kartentitel | |
14px | ||
12px | Zweitzeile, Zeiten | |
11px | ||
10px | Wochentag im Tagesreiter |
| Token | Light | Meaning |
|---|---|---|
-0.03em | eng, wie in den Screensets | |
0em | ||
0.08em |
| Token | Light | Meaning |
|---|---|---|
1.02 | ||
1.2 | ||
1.45 |
| Token | Light | Meaning |
|---|---|---|
"tnum" 1, "lnum" 1 | Zahlen und Zeiten: tabellarische Ziffern |
Space
| Token | Light | Meaning |
|---|---|---|
4px | ||
8px | ||
16px | ||
24px | ||
32px | ||
40px | ||
48px | ||
64px |
| Token | Light | Meaning |
|---|---|---|
12px | ||
8px | ||
32px | ||
20px |
| Token | Light | Meaning |
|---|---|---|
28px | ||
44px | ||
56px |
| Token | Light | Meaning |
|---|---|---|
220px | ||
72px | ||
64px | ||
768px | ab hier ist es ein Tisch, kein Handy (nur Tailwind-Breakpoint, nicht in spacing.css) |
Shape
| Token | Light | Meaning |
|---|---|---|
16px | Karten und Menüs | |
12px | Tagesreiter, kleine Karten | |
24px | iPhone-Leiste | |
22px | Mac-Block | |
999px | Pillen, Kreise, Knöpfe |
| Token | Light | Meaning |
|---|---|---|
1px | ||
1.5px | Kontur wird stark, statt Schatten | |
1.5px | ||
5px 4px |
| Token | Light | Meaning |
|---|---|---|
0.3deg | was liegt, ist leicht gekippt | |
0deg | was schwebt, steht gerade |
| Token | Light | Meaning |
|---|---|---|
none | nicht verhandelbar | |
2px | ||
2px |
Motion
| Token | Light | Meaning |
|---|---|---|
120ms | ||
200ms | ||
300ms |
| Token | Light | Meaning |
|---|---|---|
cubic-bezier(0.2, 0, 0.2, 1) | ||
cubic-bezier(0.4, 0, 0.6, 1) |
| Token | Light | Meaning |
|---|---|---|
0ms | ||
0ms | ||
0ms |