Was macht Ahmed UI Craft?
Sprachmodelle driften zum statistischen Durchschnitt des Webs: Inter, ein purpurfarbener Verlauf, drei identische runde Karten, ein Emoji pro Funktion. Diese Ausgabe ist auf den ersten Blick erkennbar und signalisiert dem Benutzer, dass niemand eine Entscheidung getroffen hat. Diese Fähigkeit erzwingt, dass Entscheidungen getroffen, als Tokens festgehalten und überprüft werden, bevor du etwas übergibst.
Befolge den Arbeitsablauf der Reihe nach. Jeder Schritt existiert, weil das Überspringen der Grund für generische UI ist.
Schritt 0 – Lies das Projekt, bevor du designst
Schau nach, bevor du erfindest. Prüfe in dieser Reihenfolge:
- Framework:
package.json(next, react, vue, svelte, astro) oder reines.html. - Styling:
tailwind.config.*oder@import "tailwindcss"/@theme(Tailwind v4),*.module.css, styled-components oder reines CSS. - Vorhandene Tokens: Suche nach
--color-,--space-,@theme,theme.extend. - Komponentenbibliothek:
components/ui/+components.json(shadcn/ui),@mui/material, Radix, Headless UI, Vuetify.
Warum: Eine schöne Komponente, die die vorhandenen Tokens und die Bibliothek des
Projekts ignoriert, ist ein Rückschritt, keine Verbesserung. Wenn das Projekt bereits
ein Designsystem hat, arbeite darin: erweitere seine Tokens, gestalte seine Primitiven
neu (bei shadcn/ui bearbeite die CSS-Variablen in globals.css und die Komponentendateien,
wickle sie nicht ein). Bringe assets/tokens.css nur ein, wenn kein System zum
Erweitern vorhanden ist.
Wenn nichts existiert, verwende standardmäßig: semantisches HTML + CSS-Custom-Properties
aus assets/tokens.css, gemappt in Tailwind, wenn Tailwind vorhanden ist.
Schritt 1 – Design Thinking (vor jedem Code)
Schreibe vier kurze Zeilen, in Gedanken oder in der Antwort:
- Zweck: Welche Aufgabe erfüllt dieser Bildschirm? (z.B. „einen Teamleiter davon überzeugen, eine Testversion zu starten")
- Zielgruppe: Wer schaut, auf welchem Gerät, in welcher Stimmung? (z.B. „Betriebsingenieure, Desktop, schnelles Scannen")
- Ton: Drei Adjektive. (z.B. „präzise, ruhig, dicht")
- Alleinstellungsmerkmal: Eine Sache, an die sich jemand erinnert, nachdem er den Tab geschlossen hat.
Das Alleinstellungsmerkmal muss konkret und sichtbar sein, nicht „sauber und modern". Gute Beispiele: „Preise in einer riesigen, komprimierten Ziffer, die von Rand zu Rand reicht"; „jede Karte hat eine feine Linie und eine Mono-Indexnummer wie ein Datenblatt"; „die Hero-Überschrift ist in einer serifenbetonten Kursiven auf einer cremefarbenen Papierstruktur gesetzt".
Warum: Wenn du das Alleinstellungsmerkmal nicht benennen kannst, wird die Ausgabe der Durchschnitt sein, weil der Durchschnitt das ist, was das Modell produziert, wenn nichts es wegzieht.
Wenn der Benutzer eine Marke, einen Screenshot oder eine bestehende Website angegeben hat, stammt der Ton von dort. Gib einer etablierten Marke keine neue Richtung vor.
Schritt 2 – Lege eine ästhetische Richtung fest
Wähle eine Richtung und wende sie überall an: Schriftart, Farbe, Radius, Schatten, Bewegung, Bilder und Kopierrhythmus. Gemischte Richtungen wirken wie Unentschlossenheit.
| Richtung | Schriftart | Farbe | Form und Tiefe | Bewegung |
|---|---|---|---|---|
| Editorial | Serifenbetonte Display-Schrift, humanistische Grundschrift | Papier-Cremeweiß, Tinte, ein starker Akzent | Feine Linien, nahezu kein Radius, keine Schatten | Langsame Überblendungen, keine beim Scrollen |
| Brutalistisch | Schwere Grotesk oder Mono, riesige Größen | Reines Schwarz/Weiß + eine laute Farbe | 0 Radius, dicke Rahmen, harte Offset-Schatten | Sofort, knackig |
| Weich / organisch | Runde oder weiche Serifen-Display-Schrift | Warm getönte neutrale Töne, gedämpfter erdiger Akzent | Großer Radius nur bei Containern, diffuse Schatten | Federnd, sanft |
| Industrial / technisch | Kondensiert oder Grotesk + Mono | Dunkles Neutral, Signal-Akzent (Bernstein, Limette, Cyan) | Kleiner Radius, 1px Rahmen, Gitternetzlinien sichtbar | Schnell, linear-artig |
| Luxuriös | Hochkontrast-Serife, weite Tracking-Versalien | Fast schwarz, Creme, metallischer oder tiefer Juwelen-Akzent | Großzügiger Weißraum, dünne Rahmen | Langsam, lange Easingkurven |
| Verspielt | Klobige Display-Schrift, freundliche Sans | Zwei gesättigte Farben, die absichtlich kollidieren | Aufkleberformen, Offset-Schatten | Hüpfende Überschwinger |
Jede Zeile hat eine vorgefertigte Voreinstellung in assets/directions/ (Schriftarten, kontrastgeprüfte helle und dunkle
Palette, Radius, Schatten, Bewegung) und eine Liste von charakteristischen Merkmalen in references/directions.md.
Lade die Voreinstellung nach tokens.css, verwende mindestens zwei ihrer charakteristischen Merkmale und verschiebe
ihre Farbtöne in Richtung der Marke. Schweizer Minimalismus ist die siebte Voreinstellung.
Regeln für die Wahl:
- Leite sie aus Schritt 1 ab, nicht aus Gewohnheit. Ein Dashboard für SREs ist nicht „luxuriös".
- Nenne sie in deiner Antwort („Richtung: Industrial / technisch"), damit der Benutzer frühzeitig umlenken kann.
- Wenn der Benutzer etwas Langweiliges verlangt („einfach, sauber"), wähle trotzdem: „Schweizer Minimalismus" ist eine Richtung (strenges Raster, eine Grotesk, Schwarz + eine Farbe, keine Dekoration).
Schritt 3 – Definiere zuerst die Tokens
Bevor du eine einzige Komponente schreibst, definiere Tokens für: Farbe, Schriftart, Abstand,
Radius, Schatten, Bewegung, Z-Index. Beginne mit assets/tokens.css: behalte die Namen,
ersetze die Werte.
Die Startwerte (Fraunces + Instrument Sans, Papier-Neutraltöne, Zinnoberrot-Akzent)
sind ein Platzhalter, kein Stil. Bevor du Komponenten schreibst, ändere mindestens die
Schriftkombination (aus references/typography.md, passend zu deiner Richtung), den
Akzentfarbton und den Farbton, in den die Neutraltöne getönt sind. Warum: In Tests führten
unveränderte Start-Tokens dazu, dass ein Anmeldeformular und eine Preisseite für
unzusammenhängende Produkte identisch aussahen. Das ist eine neue Standardeinstellung,
was das Problem ist, das diese Fähigkeit beheben soll. Behalte sie nur, wenn die Richtung
wirklich warmherzig, redaktionell mit einem rot-orangen Akzent ist.
Der schnellste Weg zu einer neuen, barrierefreien Palette: generiere sie, dann füge sie über die Farb-Tokens in Block 2 ein.
node scripts/palette.mjs --hue 250 --accent 130 --dark-first # Schiefer-Neutraltöne, Limetten-Akzent
--hue tönt die Neutraltöne (verwende den Markenfarbton), --accent ist der Akzentfarbton. Jedes
Text-/Hintergrund-Paar wird so gelöst, dass es WCAG AA in Hell und Dunkel besteht, bevor es
ausgegeben wird.
Für Dunkel-zuerst-Richtungen (Monitoring-Dashboards, Entwickler-Tools, luxuriöse Nacht-
Themes) setze :root { color-scheme: dark; } damit Dunkel der Standard ist und Hell nur
optional.
Warum: Tokens machen die Richtung durchsetzbar. Ein hartcodiertes #6366f1 oder 13px
in einer Komponente ist eine isolierte Entscheidung, und zwanzig davon lassen die
UI abdriften. Mit Tokens sind Dark Mode, Theming und spätere Umgestaltungen Änderungen
in einer Datei.
Regeln:
- Zwei Ebenen: rohe Palette (
--ink-900,--clay-500) und semantische Tokens (--color-text,--color-accent,--color-surface). Komponenten verwenden nur semantische Tokens. - Keine magischen Zahlen in Komponenten. Jede Farbe, Größe, Abstand, Radius, Schatten,
Dauer und Z-Index stammt von einem Token. Ausnahmen:
0,1pxfeine Linien,100%und1fr. - Dark Mode: jede semantische Farbe ist
light-dark(HELL, DUNKEL), sodass beide Themes in einer Deklaration leben und Komponenten sich nie ändern. Siehereferences/color-and-theming.md.
Tailwind: Mache die Tokens zum Theme, sodass bg-surface, text-text-muted,
font-display und rounded-md existieren und bg-indigo-500 nicht.
- v4: Der zweite Block in
assets/tokens.cssverwendet bereits Tailwinds Namensräume (--color-*,--font-*,--text-*,--radius-*,--shadow-*,--ease-*). Ändere das:rootdieses Blocks in@themeund füge--color-*: initial;als erste Zeile hinzu, um die Standardpalette zu entfernen. Behalte Block 3 (color-scheme) als reines CSS. Utilities lösenlight-dark()pro Theme auf, da sievar(--color-*)referenzieren. Schreibe nicht@theme inline { --color-x: var(--color-x) }; eine Variable, die ihren eigenen Namen referenziert, ist ein Kreislauf und löst sich zu nichts auf. - v3: Setze in
tailwind.configtheme.colors(nichtextend) auf{ surface: "var(--color-surface)", ... }und erweiterefontFamily,borderRadius,boxShadowauf die gleiche Weise.
Schritt 4 – Entwickle Mobile-First, mit jedem Zustand
Schreibe Basisstile für eine 360px-Ansichtsbreite, füge dann min-width-Media oder
Container-Queries hinzu. Warum: Es ist einfacher, Platz hinzuzufügen, als ihn wegzunehmen, und
die meisten Layout-Fehler (horizontaler Scrollbalken, gequetschte Tabellen) treten nur bei
kleinen Breiten auf.
Jedes interaktive Element wird mit allen seinen Zuständen ausgeliefert. Fehlende Zustände sind der häufigste Grund, warum sich eine UI unfertig anfühlt.
| Zustand | Was er zeigen muss |
|---|---|
| Standard | Das ruhende Design |
| Hover | Subtile Änderung (Farbe oder Schatten), nur unter @media (hover: hover) |
| focus-visible | Ein deutlich sichtbarer Ring, niemals entfernt |
| active | Gedrückt-Rückmeldung (dunkler, oder translateY(1px)) |
| deaktiviert | Geringerer Kontrast + cursor: not-allowed, und das echte disabled-Attribut |
| laden | Spinner oder Skelett, aria-busy="true", Breite springt nicht |
| fehler | Nachrichtentext nahe dem Feld, nicht nur ein roter Rand |
| leer | Eine echte Nachricht und eine nächste Aktion, niemals eine leere Box |
Verwende zuerst semantisches HTML: <button> für Aktionen, <a href> für Navigation,
<label for> für jedes Eingabefeld, <dialog> für Modals, <table> für tabellarische
Daten, Landmarken (<header> <nav> <main> <footer>). Füge ARIA nur hinzu, wenn HTML
kein natives Äquivalent hat. Warum: Native Elemente bringen Tastaturverhalten und
Screenreader-Semantik kostenlos mit; ARIA ist ein Versprechen, das du dann implementieren musst.
Schreibe echten Text. Platzhaltertext („Lorem ipsum", „Funktion 1", „Max Mustermann") versteckt Layout-Probleme und lässt das Ergebnis wie eine Vorlage aussehen. Verwende spezifische, plausible Inhalte, die zum Zweck aus Schritt 1 passen.
Schritt 5 – Prüfe, bevor du auslieferst
Führe scripts/audit.md aus: bash scripts/audit.sh <geänderte Dateien> (Musterprüfungen plus
Token-Kontrast), dann, wenn Playwright verfügbar ist oder der Benutzer der Installation zustimmt,
node scripts/browser-check.mjs <Seite> und sieh dir die gespeicherten Screenshots an. Behebe, was fehlschlägt. Verhältnisse,
die in Kommentaren geschrieben sind, sind Behauptungen, keine Messungen; berechne sie. Melde die Arbeit nicht als
erledigt mit bekannten Fehlern; wenn etwas nicht behoben werden kann (zum Beispiel eine Markenfarbe, die den
Kontrast nicht erfüllt), sage es explizit.
Multi-Agent-Modus (wenn ein Unteragenten-Tool verfügbar ist)
Der Hauptagent führt immer die Schritte 0-4 selbst aus: Denken und Bauen benötigen den gleichen Kontext, und eine Aufteilung geht verloren, was Schritt 0 gefunden hat. Verwende Unteragenten nur an zwei Punkten:
-
Richtungsvorschläge (Schritt 2, nur bei offenen Briefings). Wenn es keine Marke, keinen Screenshot oder kein bestehendes Designsystem gibt, starte 2-3 Unteragenten parallel. Gib jedem die Zeilen aus Schritt 1 und weise jedem eine andere Richtung aus der Tabelle zu. Sage jedem, er solle zuerst seinen Abschnitt von
references/directions.mdundreferences/typography.mdlesen, und gib jedem die Richtungen der anderen Agenten, damit sie diese vermeiden. Jeder gibt nur zurück: Richtung, Schriftpaar, Akzent- + Neutralfarbton, Alleinstellungsmerkmal, zwei charakteristische Merkmal. Lehne einen Vorschlag ab, der das Schriftpaar, den Akzentfarbton oder das Alleinstellungsmerkmal eines anderen wiederverwendet oder die Startwerte vontokens.cssbeibehält. Wähle einen aus (oder zeige dem Benutzer die Optionen), dann fahre allein fort. Warum: Ein Agent konvergiert zum Durchschnitt; erzwungene unterschiedliche Startpunkte tun dies nicht. Überspringe dies, wenn die Marke bereits die Richtung vorgibt. -
Unabhängige Überprüfung (Schritt 5, immer bei neuen Seiten oder Bildschirmen). Nachdem deine eigene Prüfung bestanden ist, starte einen neuen Unteragenten, der den Code nicht geschrieben hat. Gib ihm die geänderten Dateien, die Zeilen aus Schritt 1 und die gewählte Richtung, und bitte ihn:
references/anti-patterns.mdlesen,scripts/audit.shausführen und jede Stelle auflisten, an der die UI generisch aussieht, einen Zustand vermissen lässt oder die Richtung bricht. Er stuft jeden Befund als Blocker / Schwerwiegend / Geringfügig ein und bearbeitet nichts. Behebe jeden Blocker und jede schwerwiegende Sache, führescripts/audit.sherneut aus, und liste nicht behobene geringfügige Mängel in der Antwort auf. Ein Prüfdurchlauf, keine Schleife. Warum: Der Ersteller beurteilt das Ergebnis danach, was es beabsichtigt hat, nicht nach dem, was auf dem Bildschirm ist.
Kein Unteragenten-Tool: Führe beide Durchläufe selbst durch, der Reihe nach. Lies für die Überprüfung die Dateien noch einmal, als hätte sie jemand anderes geschrieben.
Qualitätsregeln (und warum)
Typografie
- Verwende für Display-Text nicht standardmäßig Inter, Roboto, Arial, Helvetica oder system-ui. Vermeide auch die neueren KI-Standards: Poppins, Montserrat, Space Grotesk, DM Sans. Warum: Diese werden von jeder generierten Seite verwendet, also signalisieren sie „generiert".
- Kombiniere eine Display-Schrift mit einer Grundschrift, die sich in der Struktur unterscheidet (Serife + Sans, kondensiert + breit, Grotesk + Mono). Maximal zwei Familien, plus optional eine Mono.
- Verwende eine modulare Skala mit fließenden Größen (
clamp()), und mache die größte Überschrift deutlich größer als den Fließtext. Zaghaftes Hierarchie (32px über 16px) wirkt unfertig. - Fließtext: mindestens 16px, Zeilenhöhe 1,5-1,7, Maß 60-75 Buchstaben. Dichte Dashboards können 12-14px für Metadaten und Tabellenzellen verwenden, niemals für Absätze oder Eingabefelder.
Farbe
- Eine dominante Farbe trägt die Marke; ein scharfer Akzent ist für die primäre Aktion und Schlüsseldaten reserviert. Neutrale Töne machen die meiste Arbeit. Ungefähr 60/30/10. Warum: Eine gleichmäßig verteilte Fünf-Farben-Palette hat keinen Brennpunkt, also wirkt nichts als wichtig.
- Töne deine Neutraltöne in Richtung des Markenfarbtons, anstatt reines Grau zu verwenden.
- Keine Lila-zu-Blau- oder Lila-auf-Weiß-Verläufe, es sei denn, die Marke ist wirklich lila.
- Textkontrast mindestens 4,5:1 (3:1 für 24px+ oder 18,66px+ fetten Text und für UI-Komponentengrenzen und Fokusringe).
Layout und Form
- Vermeide das identische Drei- oder Vier-Karten-Raster. Variiere Größe und Gewichtung: ein hervorgehobenes Element über zwei Spalten, eine Liste neben einem großen Bild, eine asymmetrische Aufteilung.
- Der Radius folgt der Richtung und ist pro Ebene konsistent. Setze nicht
rounded-2xlauf alles; kleine Steuerelemente bekommen einen kleinen Radius oder keinen. - Kein horizontaler Scrollbalken bei 320px. Verwende
min-width: 0auf Flex/Grid-Kindern,overflow-wrap: anywherefür lange Zeichenfolgen und Scrollcontainer für breite Tabellen. - Berührungsziele mindestens 44x44px (Polsterung zählt).
Symbole und Bilder
- Keine Emojis als Symbole. Verwende einen Symbolsatz (Lucide, Phosphor, Heroicons, Tabler) mit einer Strichstärke oder Inline-SVG. Warum: Emojis werden pro Betriebssystem unterschiedlich gerendert, können nicht mit Tokens eingefärbt werden und werden von Screenreadern angesagt („Rakete").
- Dekorative Symbole erhalten
aria-hidden="true"; Nur-Symbol-Schaltflächen erhalten einaria-label.
Bewegung
- Animieren nur
transformundopacity(plusfiltersparsam). Warum: Andere Eigenschaften lösen bei jedem Frame Layout oder Neuanstrich aus und ruckeln auf Low-End-Telefonen. - Dauern von Tokens: 120-200ms für UI-Rückmeldung, 250-400ms für eintretende Elemente.
- Respektiere
prefers-reduced-motion: entferne Bewegung, halte Überblendungen kurz oder sofort.
Zugänglichkeit
- Der gesamte semantische Inhalt ist bei Verwendung von CSS
display: noneunsichtbar und nicht nur visuell versteckt. Verwendearia-hiddenfür dekorative Elemente. - Alle Formulareingaben haben ein zugehöriges
<label>, auch wenn es visuell versteckt ist. - Keine
tabindex-Werte über 0. Verwende die logische Fokusreihenfolge mit Quellenreihenfolge. - Fehlermeldungen sind programmatisch mit der Eingabe verknüpft (über
aria-describedby). - Seiten haben genau einen
<h1>, der den Hauptinhalt beschreibt.
Leistung und Zustellbarkeit
- Keine Render-blockierenden Ressourcen für das erste Paint. Schriftarten werden mit
font-display: swapund optionalempreloadgeladen. - Bilder und SVGs haben
widthundheightgesetzt, um Layoutverschiebungen zu vermeiden. - Die Ausgabe besteht aus einer einzelnen HTML-Datei, es sei denn, das Framework erfordert eine Aufteilung. Keine externen Abhängigkeiten außer dem Schriftarten-CDN.
Kontext und Konsequenzen
„Generische UI ist ein Vertrauensverlust. Der Benutzer weiß vielleicht nicht, warum, aber er fühlt, dass niemand aufgepasst hat." — Jeder Schritt existiert, um dieses Gefühl zu verhindern.
Wenn du diese Regeln aus einer vermeintlichen Abkürzung heraus überspringst, wird die Ausgabe den Durchschnitt der Trainingsdaten widerspiegeln, nicht den Design-Briefing. Das Durchsetzen der Regeln dauert länger beim Schreiben, spart aber Zeit beim Überarbeiten und liefert eine Arbeit, die nicht durch „sieht generisch aus" zurückgewiesen wird.