Ton: ein Designsystem gegen den KI-Mittelwert
Eine KI baut Oberflächen schnell, aber sie baut den Durchschnitt. Ich wollte wissen, ob ein Designsystem sie davon abhalten kann, ohne dass ich jedes Ergebnis nacharbeite. Ton ist meine Antwort: warm, weich, mit Federn und Klang.

- Art
- Designsystem mit Prüfungen in Build und Tests
- Rolle
- Konzept, Tokens, Feder-Löser, Klang, Spezifikationen, Prüfskripte und Referenz
- Zeitraum
- November 2026
- Technik
- Tokens im W3C-Format, OKLCH, CSS linear(), Tailwind v4, Radix, Web Audio, Figtree
Kurzfassung
KI-Oberflächen sehen oft gleich aus: lila Verlauf, Glas, Inter, drei gleiche Karten. Das ist kein Zufall. Ein Modell schreibt das Wahrscheinlichste, und das Wahrscheinlichste ist der Mittelwert dessen, was es gesehen hat.
Ton ist mein zweites System nach Kante. Es ist bewusst taktil: Flächen aus Lehm und Ocker, weiche Schatten, Körnung, Bewegung mit Federn und leise Klänge. Die Regeln stehen nicht nur in einer Anweisungsdatei. Der Token-Build und ein Prüfskript in den Tests prüfen sie.
Das Problem
Der Mittelwert sieht nach nichts aus
Links steht ein Screen, wie ihn eine KI ohne Vorgaben gern baut. Ich habe ihn selbst nachgebaut, mit allem, was dazugehört. Rechts steht derselbe Inhalt in Ton.
Der linke Screen ist nicht falsch. Er ist nur austauschbar. Jede Marke, die so aussieht, sieht aus wie alle anderen.
Firing on Thursday
Twelve pieces are glazed and waiting for the kiln. Book a shelf before Wednesday noon.
Shelves free
3 of 8
Peak
1240 °C
Slow cool
On
Twelve pieces are glazed and waiting for the kiln. Book a shelf before Wednesday noon.
Regelwerk
Regeln, die geprüft werden
Eine Verbotsliste in einer Textdatei hilft wenig, wenn niemand sie prüft. In Ton gibt es dafür zwei Stellen. Der Token-Build bricht ab, wenn ein Farbpaar zu wenig Kontrast hat, eine Fläche im falschen Farbton liegt oder eine Feder zu lange zum Einschwingen braucht. Ein Scan in den Tests prüft den Code der Referenz auf Verläufe, Glas, feste Zeiten, bestimmte Schriften und Rahmen.
Alle Ausschnitte hier liest die Seite beim Bauen aus den echten Dateien. Ändert sich eine Datei, ändert sich die Seite.
Harte Regeln in AGENTS.md
design-system-ton/AGENTS.md
## Hard rules
1. No colour literals: no hex, rgb(), hsl(), oklch().
2. No Tailwind palette colours, no `bg-white`, no `text-black`.
3. No gradients on surfaces.
4. No glass: no `backdrop-blur`, no semi-transparent surfaces over content.
5. No `duration-*`, no `ease-linear`, `ease-in`, `ease-out` or `ease-in-out`, no `transition: … s`. Motion only with `ease-ton-*` or `useSpring`.
6. No typefaces other than the system typeface (Figtree via `font.family.base`); explicitly no Inter, Inter Tight, Roboto, and no monospace.
7. No borders and no 1px lines for structure; structure comes from surface, shadow, spacing and font weight.
8. No `rounded-none`; corners only through `rounded-ton-*`.
9. No base tokens.
10. Sound only through the sound engine and only for events a spec names.Eine Feder als Token
design-system-ton/tokens/semantic/motion.json
"press": {
"$value": { "mass": 1, "stiffness": 2000, "damping": 54 },
"$description": "Press feedback. Under-damped on purpose so the surface visibly rebounds; settles inside 250 ms.",
"$extensions": { "de.axkl.ton": { "role": "press" } }
}Was der Build daraus macht
design-system-ton/build/tokens.css
--ton-motion-spring-press-easing: linear(0, 0.0122 1.5625%, 0.0456 3.125%, 0.1581 6.25%, 0.4661 12.5%, 0.7566 18.75%, 0.87 21.875%, 0.9579 25%, 1.0211 28.125%, 1.062 31.25%, 1.0924 37.5%, 1.0525 50%, 1.0054 62.5%, 0.9915 75%, 1);
--ton-motion-spring-press-duration: 231ms;Der Token-Build scheitert an einer lila Fläche
design-system-ton/build/failure-sample.txt
Ton token gates failed:
Gate 1: --ton-color-text-muted on --ton-color-surface-raised has contrast 3.41, needs 4.5 (oklch(40% 0.035 45) on oklch(70% 0.1 290))
Gate 1: --ton-color-text-danger on --ton-color-surface-raised has contrast 3.88, needs 4.5 (oklch(38% 0.12 28) on oklch(70% 0.1 290))
Gate 1: --ton-color-text-success on --ton-color-surface-raised has contrast 2.64, needs 4.5 (oklch(45% 0.06 150) on oklch(70% 0.1 290))
Gate 2: surface --ton-color-surface-raised is oklch(70% 0.1 290), hue 290 with chroma 0.1 falls in the violet band 270-320
Gate 6: semantic colour --ton-color-surface-raised is "oklch(70% 0.1 290)", it must reference another token with var(--ton-…)Farbe und Material
Warme Flächen, gerechnet statt geschätzt
Alle Farben sind in OKLCH angelegt. Der Raum ist so gebaut, dass gleiche Helligkeitswerte auch annähernd gleich hell wirken. Das macht Abstufungen planbar.
Jede Textfarbe nennt die Flächen, auf denen sie stehen darf. Der Kontrast unten wird beim Bauen der Seite aus den Tokens gerechnet, nicht abgetippt.
Surfaces
- surface.baseoklch(84% 0.035 68)
- surface.raisedoklch(88% 0.025 70)
- surface.sunkenoklch(76% 0.075 72)
- surface.accentoklch(44% 0.13 28)
- action.primary.bgoklch(44% 0.13 28)
- action.primary.bg-pressedoklch(38% 0.12 28)
Text on its allowed surfaces, contrast calculated from the tokens
- text.defaultoklch(26% 0.03 40)
- 9.55 : 1on surface.base, needs 4.5
- 10.89 : 1on surface.raised, needs 4.5
- 7.23 : 1on surface.sunken, needs 4.5
- text.mutedoklch(40% 0.035 45)
- 5.69 : 1on surface.base, needs 4.5
- 6.48 : 1on surface.raised, needs 4.5
- text.on-accentoklch(88% 0.025 70)
- 5.76 : 1on surface.accent, needs 4.5
- 5.76 : 1on action.primary.bg, needs 4.5
- 7.38 : 1on action.primary.bg-pressed, needs 4.5
- text.dangeroklch(38% 0.12 28)
- 6.47 : 1on surface.base, needs 4.5
- 7.38 : 1on surface.raised, needs 4.5
- text.successoklch(45% 0.06 150)
- 5.02 : 1on surface.raised, needs 4.5
- action.primary.textoklch(88% 0.025 70)
- 5.76 : 1on action.primary.bg, needs 4.5
- 7.38 : 1on action.primary.bg-pressed, needs 4.5
- focusoklch(26% 0.03 40)
- 9.55 : 1on surface.base, needs 3
- 10.89 : 1on surface.raised, needs 3
- 7.23 : 1on surface.sunken, needs 3
Derselbe Verlauf, zwei Farbräume
surface.accent → text.success
Bewegung
Federn statt fester Zeiten
Die meisten Oberflächen bewegen sich mit einer festen Dauer und einer festen Kurve, etwa 0,3 Sekunden ease-in-out. Das wirkt glatt, aber nicht nach Material. Ton beschreibt Bewegung als Feder: Masse, Steifigkeit, Dämpfung.
Daraus folgen zwei Werte. Die Eigenfrequenz ω₀ = √(k/m) sagt, wie schnell die Feder schwingen will. Der Dämpfungsgrad ζ = c / (2·√(k·m)) sagt, wie stark sie gebremst wird. Liegt ζ unter 1, schwingt sie mit ω_d = ω₀·√(1−ζ²) nach.
Viele Teams nehmen dafür Motion, früher Framer Motion. Ton nutzt bewusst keine Bibliothek. Der Build rechnet die Federn für CSS vor, und für Ziehen und Loslassen gibt es einen kleinen Hook.
Solid: the spring. Dashed: 0.3 s ease-in-out. Time runs to the right.
- ω₀ = √(k/m)
- 7.75 rad/s
- ζ = c / (2·√(k·m))
- 0.581
- ω_d = ω₀·√(1−ζ²)
- 6.30 rad/s
- Settles in
- 1378 ms
- CSS output
- linear() with 16 points, 1378 ms
Layout
Dichte und Leere statt drei gleicher Karten
Das Bento ist absichtlich ungleich: ein dichter Cluster, eine leere Spalte und eine große Karte. Die Schale bricht aus ihr heraus und liegt auf einer eigenen Ebene. Sie bewegt sich leicht gegen Zeiger und Scrollen.
Mit reduzierter Bewegung bleibt sie stehen. Die Karte „Wet clay“ lässt sich ziehen, auch mit den Pfeiltasten.
Firing on Thursday
Twelve pieces are glazed and waiting for the kiln. Book a shelf before Wednesday noon.
Leave the lids off until the glaze is dry to the touch.
Klang
Klang nur auf Wunsch
Ton klingt leise: ein gedämpfter Klick, zwei steigende Töne für Erfolg, ein tiefer Ton für Fehler. Alles entsteht aus Oszillatoren, Rauschen und Filtern. Es gibt keine Audiodateien.
Klang ist aus, bis du ihn einschaltest. Erst danach, bei der nächsten Geste, entsteht der Audio-Kontext. Der Klang wiederholt nur, was du auch siehst.
Eine Media Query für reduzierten Klang gibt es nicht. prefers-reduced-sound ist ein oft genannter Wunsch, aber kein Standard. Deshalb ist Klang hier standardmäßig aus und bleibt es, bis du ihn ausdrücklich einschaltest.
Not clicked yet. Sound is off.
Grenzen
Was Ton nicht leistet
- Eine Verbotsliste allein erzeugt nur einen neuen Mittelwert. Weiche Flächen, Bento und herausragende 3D-Objekte sind selbst auf dem Weg zum Standard. Was hilft, ist eine Richtung, die aus der Marke kommt, und Prüfungen, die sie halten.
- Ich habe mit Ton keine KI-Durchläufe gemessen. Wie gut eine KI mit einem solchen System arbeitet, habe ich bei Kante gemessen.
- Die Prüfungen finden Werte und Muster im Code. Ob eine Seite gut gestaltet ist, entscheidet kein Skript.
- Klang lässt sich nicht automatisch an Vorlieben anpassen, weil Browser dafür keine Einstellung kennen.
Was ich daraus mitnehme
Mit KI gestalte ich weniger einzelne Screens und mehr die Regeln, nach denen sie entstehen. Ton war dafür mein Übungsfeld. Jede Entscheidung, die als Token oder Prüfung vorliegt, hält der Build fest. Ich muss sie dann nicht in jedem Ergebnis neu einfordern.
Nächstes Projekt
