Axel Kummerlöwe
Designsystem2026

Kante: ein Designsystem, das eine KI lesen kann

Was muss in einem Designsystem stehen, damit eine KI daraus genau die Komponenten baut, die ich will, und nicht die, die sie für wahrscheinlich hält? Ich habe ein System gebaut und es an echten Durchläufen gemessen.

Vier Einstellungs-Screens nebeneinander: Referenz, Durchlauf ohne System, Durchlauf mit System auf Opus und mit System auf Haiku. Alle sehen fast gleich aus.
Derselbe Screen viermal: die Referenz und drei KI-Durchläufe. Der Unterschied liegt nicht im Bild, sondern im Code darunter.
Art
Designsystem mit gemessenen KI-Durchläufen
Rolle
Konzept, Tokens, Spezifikationen, Prüfskripte, Referenz und Auswertung
Zeitraum
November 2026
Technik
Tokens im W3C-Format, Style Dictionary, Tailwind v4, Radix, Claude Code (Opus und Haiku)

Kurzfassung

Eine KI baut eine Oberfläche in Minuten. Ohne Vorgaben baut sie aber den Durchschnitt dessen, was sie kennt, und erfindet jeden Wert neu. Bei einer Marke mit eigener Sprache ist das kein Zeitgewinn, sondern Nacharbeit.

Ich habe Kante gebaut, ein bewusst kantiges System, und dieselbe Aufgabe dreimal von einer frischen KI-Sitzung lösen lassen: ohne System, mit System auf einem großen Modell und mit System auf einem kleinen. Ohne System fand die Prüfung 263 Werte, die an keinem Token hängen. Mit System waren es nach 2 Runden 0, auch auf dem kleinen Modell.

In Zahlen

263Befunde ohne System
0mit System nach 2 Runden (Opus)
0mit System auf dem kleinen Modell (Haiku)
4Lücken im System, die die Durchläufe aufgedeckt haben

Das Problem

Ohne System rät die KI, und sie rät ziemlich gut

Der Durchlauf ohne System bekam nur zwei Screenshots der Referenz. Das Ergebnis sieht auf den ersten Blick richtig aus. Das ist die eigentliche Gefahr: Niemand würde es im Review zurückweisen.

Darunter stehen 116 Farbwerte direkt im Code, 28 verschiedene. Kante hat 15. Die Tinte hat das Modell aus dem Bild geschätzt, als #141414 statt #111111, und für fast dieselbe graue Fläche gibt es zwei Werte, die sich um eine Stufe unterscheiden. Ändere ich im System eine Farbe, kommt davon nichts an.

runs/2026-11-11-baseline-r1/components/button.tsx

  primary: {
    rest: "border-[#8fb31a] bg-[#c8f031] text-[#141414]",
    hover: "enabled:hover:bg-[#b6dd22]",
    active: "enabled:active:bg-[#a3c81c] enabled:active:border-[#141414]",
    hoverStatic: "bg-[#b6dd22]",
    activeStatic: "bg-[#a3c81c] border-[#141414]",
  },
  secondary: {
    rest: "border-[#141414] bg-white text-[#141414]",
    hover: "enabled:hover:bg-[#ebebe6]",
    active: "enabled:active:bg-[#dcdcd5] enabled:active:shadow-[inset_0_0_0_1px_#141414]",
    hoverStatic: "bg-[#ebebe6]",
    activeStatic: "bg-[#dcdcd5] shadow-[inset_0_0_0_1px_#141414]",
  },
  danger: {
    rest: "border-[#141414] bg-white text-[#c0261c]",
    hover: "enabled:hover:bg-[#fbe7e4]",
    active: "enabled:active:bg-[#f5d3ce] enabled:active:shadow-[inset_0_0_0_1px_#c0261c]",
    hoverStatic: "bg-[#fbe7e4]",
    activeStatic: "bg-[#f5d3ce] shadow-[inset_0_0_0_1px_#c0261c]",
  },
};
Ausschnitt aus dem Button ohne System: jeder Zustand mit eigenen, geschätzten Farben.

Aufbau

Drei Ebenen, und die KI darf nur die mittlere benutzen

Alle Werte stehen als JSON im W3C-Format für Design-Tokens. Daraus erzeugt Style Dictionary CSS-Variablen, Tailwind-Klassen und eine lesbare Doku. Es gibt genau eine Quelle.

Die Basis-Ebene enthält rohe Werte wie ink.900. Die Bedeutungs-Ebene sagt, wofür ein Wert da ist: color.text.default. Die Komponenten-Ebene gibt es nur dort, wo eine Komponente wirklich abweicht. Die KI darf ausschließlich Bedeutungs- und Komponenten-Tokens verwenden. So sucht sie nach Zweck und nicht nach Aussehen.

Ein Token durch alle Ebenen

  1. Basisbase.color.ink.900#111111
  2. Bedeutungcolor.text.default#111111Body text, headings and labels on page, raised and sunken surfaces. Also text on status backgrounds.
  3. Bedeutungcolor.action.secondary.text#111111Label of secondary actions. Destructive secondary actions use text.danger instead.
  4. Codetext-ds-action-secondary-textreference/components/button.tsx
Die Farbe der Button-Beschriftung, von der Basis bis in den Code.

Token mit Zweck und Grenze

tokens/semantic/color.json

      "muted": {
        "$value": "{base.color.ink.500}",
        "$description": "Secondary text: hints, help text, metadata. Only on page and raised surfaces. Never on sunken surfaces or status backgrounds, the contrast is too low there.",
        "$extensions": {
          "de.axkl.pairs": [
            {
              "surface": "color.surface.page",
              "min": 4.5
            },
            {
              "surface": "color.surface.raised",
              "min": 4.5
            }
          ]
        }
      },
      "inverse": {
Jeder Bedeutungs-Token sagt, wofür er da ist und wo nicht. Erlaubte Farbpaare stehen als Daten daneben; der Build prüft sie auf WCAG AA.

Spezifikation als Daten

specs/button.json

  "states": [
    { "name": "default", "tokens": { "primary.bg": "color.action.primary.bg", "primary.text": "color.action.primary.text", "secondary.bg": "color.action.secondary.bg", "secondary.text": "color.action.secondary.text", "secondary.border": "color.action.secondary.border", "danger.text": "color.text.danger", "radius": "radius.control" } },
    { "name": "hover", "tokens": { "primary.bg": "color.action.primary.bg-hover", "secondary.bg": "color.action.secondary.bg-hover", "duration": "motion.quick" } },
    { "name": "focus", "tokens": { "outline": "color.border.focus" } },
    { "name": "active", "tokens": { "primary.bg": "color.action.primary.bg-hover", "secondary.bg": "color.action.secondary.bg-hover" } },
    { "name": "disabled", "tokens": { "bg": "color.surface.sunken", "text": "color.text.default", "border": "color.border.default" } }
  ],
  "a11y": {
    "role": "button",
    "keyboard": ["Enter and Space activate", "Tab moves focus"],
    "mustMatch": ["button[type]"]
  },
  "rules": [
    "At most one primary button per view.",
    "Danger is a secondary button with a text.danger label and the same outline; it never has a red background.",
    "An icon-only button needs aria-label.",
    "Disabled buttons use the disabled attribute, the disabled tokens and 50% opacity on the whole button.",
    "Focus ring: 2px outline in border.focus with 2px offset."
  ]
Jede Komponente hat eine JSON-Spezifikation mit Zuständen, Tokens, Barrierefreiheit und Verboten. Mensch und KI lesen dieselbe Quelle.

Harte Regeln in AGENTS.md

AGENTS.md

## Hard rules
1. No colour literals: no hex, rgb(), hsl(), oklch().
2. No px, rem or em values, neither in arbitrary Tailwind values (`h-[13px]`) nor in `style`.
3. No Tailwind palette colours (`bg-gray-100`, `text-blue-600`, `bg-white`, `text-black`).
4. Spacing only with `*-ds-*` utilities; never `p-4`, `gap-3`, `mt-6`.
5. Corners only `rounded-none`. No `rounded`, `rounded-md`, `rounded-full`.
6. No shadows. Elevation comes from borders.
7. Text only with `type-*` utilities; no `text-sm`, `font-bold`, `leading-*`, `tracking-*`.
8. Never reference `--ds-base-*` or `ds-base-*`.
9. Implement exactly the states each spec lists, with the tokens it names.
10. A spec's `rules` override your own taste.
11. No numeric size utilities (`size-5`, `w-10`, `h-6`, `size-4`). Control and icon sizes come from component tokens: `size-ds-checkbox-size`, `w-ds-switch-width`, `h-ds-switch-height`, `size-ds-switch-thumb`, `size-ds-icon-s`. `w-full`, `w-1/2` and `min-h-screen` are fine.

Die Anweisungsdatei ist kurz. Sie sagt, wo was liegt, und zählt Regeln auf, die ein Skript prüfen kann.

Entscheidungen

Was das System lesbar macht

  1. Eine Quelle, viele Ausgaben. Tokens stehen einmal als JSON. CSS, Tailwind-Klassen, Typen und Doku werden daraus erzeugt. Eine KI kann nichts lesen, was an zwei Stellen unterschiedlich steht.
  2. Namen nach Zweck, nicht nach Aussehen. color.text.muted statt grey-500. Wer nach dem Zweck sucht, findet den richtigen Token auch dann, wenn zwei Farben gleich aussehen.
  3. Grenzen in die Beschreibung. Jeder Token sagt, wo er nicht hingehört, etwa „nie auf eingesenkten Flächen“. Genau diese Sätze verhindern die typischen Fehlgriffe.
  4. Kontrast als Daten, nicht als Hoffnung. Erlaubte Text- und Flächenpaare stehen am Token. Liegt ein Paar unter WCAG AA, scheitert der Build.
  5. Fertige Textstile. type-heading-m statt Größe, Gewicht und Zeilenhöhe einzeln. Weniger Freiheitsgrade heißen weniger falsche Kombinationen.
  6. Regeln, die ein Skript prüfen kann. Jede harte Regel in AGENTS.md hat eine Prüfung. Was sich nicht prüfen lässt, steht in den Spezifikationen und nicht in der Anweisungsdatei.
  7. Fehler im System beheben, nie im Ergebnis. Wenn eine KI etwas falsch baut, ändere ich das System und lasse sie neu bauen. So wird jede Lücke einmal geschlossen und nicht bei jedem Prompt wieder.

Durchläufe

Gemessen statt behauptet

Jeder Durchlauf ist eine frische KI-Sitzung ohne Vorwissen, in einem eigenen Ordner. Die Aufgabe ist für alle gleich: acht Komponenten in allen Zuständen und ein Einstellungs-Screen daraus. Der Durchlauf mit System bekommt Tokens, Spezifikationen, Prüfskripte und AGENTS.md, aber nie die Referenz.

Gezählt wird per Skript: Werte, die an keinem Token hängen, Kontrastverstöße im gerenderten Ergebnis, fehlende Zustände und fehlende Pflicht-Attribute für Barrierefreiheit. Die Optik beurteile ich selbst.

In der ersten Runde blieben mit System 11 (Opus) und 4 (Haiku) Befunde. Ihre Ursachen lagen im System, nicht in den Modellen.

DurchlaufModellRundeGesamtFreie WerteKontrastZuständeBarrierefreiheit
ohne SystemOpus1263262001
mit SystemOpus11111000
mit System, kleinHaiku144000
mit SystemOpus200000
mit System, kleinHaiku200000

Was die erste Runde im System aufgedeckt hat

  1. 01

    Befund: Alle Durchläufe, und auch meine Referenz, setzten Checkbox, Switch und Icons mit Zahlen-Klassen wie size-5 oder h-6.

    Änderung am System: Komponenten-Tokens für diese Größen und eine neue Prüfregel. Alle Durchläufe der ersten Runde habe ich mit der strengeren Regel neu bewertet.

    Grund: Größen waren der einzige Bereich ohne Tokens. Die Spezifikation nannte Pixel als Text, also hat jedes Modell sie selbst übersetzt.

  2. 02

    Befund: Opus legte den Seitenabstand außerhalb der maximalen Spaltenbreite an. Der Inhalt wurde 64 px breiter.

    Änderung am System: Die Screen-Spezifikation sagt jetzt, dass die Spalte zentriert ist und den Abstand einschließt.

    Grund: Die Spezifikation ließ beide Lesarten zu.

  3. 03

    Befund: Die Beschreibung eines Textstils nannte h3, die Karten-Spezifikation verlangte die Ebene nach Gliederung. Beide Modelle lösten den Widerspruch unterschiedlich.

    Änderung am System: Eine Regel an einer Stelle: Die Ebene folgt der Gliederung.

    Grund: Zwei Quellen im System widersprachen sich.

  4. 04

    Befund: Haiku mischte im Dialog ein gesteuertes Radix-Element mit einer statischen Vorschau. Die Seite warf einen Fehler beim Laden.

    Änderung am System: Die Dialog-Spezifikation legt den Aufbau jetzt verbindlich fest.

    Grund: Sie verlangte nur „Radix Dialog“. Das Muster meiner Referenz stand nirgends.

Vier Einstellungs-Screens nebeneinander: Referenz, Durchlauf ohne System, Durchlauf mit System auf Opus und mit System auf Haiku. Alle sehen fast gleich aus.
Endstand: Referenz, ohne System, mit System auf Opus und auf Haiku.

System zum Anfassen

Die Referenz-Komponenten

Diese Komponenten sind die Referenz, gebaut nur aus Bedeutungs-Tokens. Sie lassen sich bedienen, auch per Tastatur.

Profile

Shown to everyone in the workspace.

Enter a full address, like name@example.com.

Preferences

A summary of activity every Monday.

Was ich gelernt habe

  • Die KI findet die Lücken. Jede Abweichung in der ersten Runde zeigte auf eine Stelle, an der das System mehrdeutig war oder schwieg. Die Durchläufe sind damit der beste Test für das System selbst.
  • Ein kleines Modell reicht, wenn das System trägt. Haiku mit System erreicht dasselbe Ergebnis wie Opus mit System. Das spart in der Praxis Zeit und Geld.
  • Der Unterschied ist nicht im Screenshot. Ohne System sieht das Ergebnis fast richtig aus. Wer nur auf Bilder schaut, merkt nicht, dass jeder Wert kopiert statt verknüpft ist.

Grenzen

  • Pro Variante gab es einen Durchlauf je Runde. Das zeigt eine Richtung, ist aber keine Statistik.
  • Die Prüfregel für Größen habe ich nach der ersten Runde verschärft. Damit die Zahlen vergleichbar bleiben, sind alle Durchläufe mit derselben Regel bewertet.
  • Fehler beim Laden der Seite zählt die Prüfung nicht. Ich habe sie für jeden Durchlauf einzeln geprüft und festgehalten.
  • Ein Agent hat kurz eine Hilfsdatei im gemeinsamen Elternordner der Durchläufe abgelegt. Er gibt an, dort nichts gelesen zu haben. Überprüfen lässt sich das nicht.

Was ich daraus mitnehme

Ein Designsystem für KI ist kein Styleguide mit mehr Text. Es ist eine Sammlung von Entscheidungen, die als Daten vorliegen und sich prüfen lassen. Dann baut auch ein kleines Modell, was ich meine.

Nächstes Projekt

Suchagenten

Side-Project