Was macht GIGA UI: ruhig, präzise, lebendig?
Dieser Skill verwandelt eine einzeilige UI-Anforderung in eine ausgefeilte, produktionsreife Oberfläche. Die visuelle Sprache ist inspiriert von den öffentlichen Design-Arbeiten von @marcelkargul (Kargul Studio): ruhige, fast monochrome Produkt-UIs, sehr sorgfältige Typografie, weiche, geschichtete Schatten anstelle von schweren Rahmen, eine selbstbewusste Akzentfarbe und Bewegungen, die schnell, physikalisch und niemals um ihrer selbst willen dekorativ sind.
Er funktioniert mit jedem Coding-Modell und jedem Stack. Die Beispiele verwenden React + Tailwind + Motion (motion/react), und jedes hat eine reines-CSS-Entsprechung.
Die unten verwendete Herkunftslegende: [gesehen] direkt in seinen Beiträgen/Bildern beobachtet oder in seinen Bildunterschriften angegeben. [erschlossen] eine vernünftige Extrapolation aus dem Gesehenen (anhand von Screenshots gemessen oder impliziert). [Experte] allgemeine Motion/UX-Best-Practice aus der Motion-Dokumentation, von Emil Kowalski, Apple HIG. Nicht aus seinen Beiträgen.
1. Design-Philosophie
- Wenn es entfernt werden kann, entferne es. [gesehen, Bildunterschrift: „every screen. every component. every frame. if it doesn't need to be there, it shouldn't be. simple is always hard, but simple always wins."]
- Typografie trägt die Hauptlast. [gesehen: „just master typography and you can make anything look good."] Verwende eine Schriftfamilie (standardmäßig Inter im Web, Geist als optionale Alternative; SF Pro Rounded für iOS-artiges Mobile) und maximal 2 Schriftstärken [gesehen: „sf pro rounded, maximum 2 font weights, keep it simple"].
- Weiß, Schwarz und Schatten. [gesehen: „No animations, no gradients, no fancy effects. Just FFFFFF, 000000, and some shadows. This is design at its peak."] Der Großteil der Palette besteht aus neutralen Grautönen. Farbe wird für Bedeutung verwendet, wie Status, Kategorie oder die eine primäre Aktion.
- Tiefe entsteht durch weiche, geschichtete Schatten und hauchdünne Linien, nicht durch dicke Rahmen. [gesehen: „this button only requires 3 shadows!" und das Secondary-Button-Rezept in §3]
- Bewegung ist Teil des Produkts, keine Dekoration. [gesehen: „micro-interactions throughout", „subtle loading animation. not overdone, just perfect", „every website needs this level of animation", „idea → design → animation"]. Animieren nur, um eine Änderung zu erklären, eine Aktion zu bestätigen oder die Aufmerksamkeit zu lenken [Experte].
- Die letzten 10 % von Hand ausarbeiten. [gesehen: sein Prozess ist „design in figma, build with the help of claude, spend hours fixing small details manually and improving code quality"]. Die QA-Checkliste in §9 sind diese letzten 10 %.
- Sauber schlägt clever. Seine Bildunterschriften kehren immer wieder zu den Wörtern „clean", „calm" und „simple" zurück (z. B. „Every task in one calm list"). Selbst wenn es eine große Datenmenge gibt, sollte der Bildschirm ruhig wirken.
2. Der beobachtete Stil (wie seine Arbeit tatsächlich aussieht)
2.1 Typografie
- Schriftfamilien: Inter (die Standardeinstellung in diesem Skill) und Geist (optionale Alternative). [gesehen: „After using 100s of different fonts, I realized nothing beats Inter and Geist."; Scherzbeitrag: Junior- und Senior-Designer verwenden beide „Inter, Geist"]. SF Pro Rounded für mobile Apps [gesehen, mehrere Beiträge]. Er empfiehlt auch Google Sans Rounded als plattformübergreifende Alternative zu SF Pro Rounded [gesehen, Antwort]. Eine Monospace (ähnlich Geist Mono) wird für große Zahlen, Ticker und Code verwendet [gesehen: Krypto-App-Balances, Statsnap-KPI-Karten, Sidebar-Navigation]. Marken- und Marketingarbeiten verwenden manchmal eine Serifen-Display-Schrift (redaktionelle Übergangsserife, helle Schriftstärke) [gesehen: Fintech-Landing „Every payment protected…", VC-Landing-Page].
- Tracking (seine genauen Zahlen, demonstriert mit Geist; auf Inter anwenden, das er ebenfalls bei −6 % demonstriert hat) [gesehen]:
- 16px → 0%
- 36px → −3%
- 100px+ → −5% bis −6%
- „Die ‚Never-go-negative‘-Regel gilt für Fließtext. Bei 100px+ wirkt der Standardabstand locker."
- SF Pro Rounded: +1 % Buchstabenabstand [gesehen, Schriftspezimen].
- Schriftstärken: Regular (400) und Medium (500) tragen fast die gesamte Produkt-UI. Semibold (600) ist für Überschriften und Zahlen. Bold/Black nur für große Display-Headlines [erschlossen aus Screenshots].
- Größen in der Produkt-UI [erschlossen, gemessen an Screenshots bei 1×]: Fließtext und Tabellentext 13–14px, sekundär/Meta 12–13px, Abschnittsbeschriftungen 11–12px in Großbuchstaben oder Kapitälchen in Grau (z. B. „WORKSPACE", „PINNED TOOLS"), Seitentitel 18–24px Medium, KPI-Zahlen 24–32px, Hero-Headlines 48–72px mit negativem Tracking. Buttons sind 14px Medium [gesehen: „Geist/14/Medium"].
- Textfarbe: primär nahe Schwarz (#171717–#1F1F1F), sekundär Mittelgrau (#6B6B6B–#737373), tertiär/Platzhalter (#A3A3A3). Tags verwenden dunkel getönten Text auf hellem Farbton anstelle von weißem Text auf gesättigten Flächen [gesehen: „Do / Don't"-Beitrag: „Dark text improves overall readability greatly."].
2.2 Farbe
Aus Screenshots entnommen (ungefähr) [gesehen/erschlossen]:
| Rolle | Hell | Dunkel |
|---|---|---|
| Leinwand / Seite | #FFFFFF | #0D0D0D–#121212 |
| Dezente Fläche (Sidebar, Panels, Mobile-HG) | #F7F7F7 / #F4F4F4 / #FAFAFA | #1A1A1A–#1E1E1E |
| Präsentationshintergrund hinter Mockups | #E5E5E5–#EDEDED, Mittelgrau #8A8A8A | #1F1F1F–#262626 |
| Hauchdünne Linie | #ECECEC / #EBEBEB | rgba(255,255,255,0.08) |
| Primärtext | #171717 | #FAFAFA |
| Sekundärtext | #737373 | #A1A1A1 |
Akzente (einer pro Produkt, niemals mehrere auf einmal) [gesehen]:
- Violett
#7B3AEC(Underlay-Anmeldung, Onboarding), auch eine Indigo-#5B5BF0-Variante - Blau
#255CD1/ iOS-Blau#2F7BF6(Rechner, Kalender, Statsnap) - Orange
#FF5A1F/#F97316(Plunio, Nexora) - Teal
#0F766E-artig (AI-Pipeline, AIData) - Lime
#B4F05Aauf nahezu Schwarz (Code-Editor-„Start"-Button, Soma-Marke) - Koralle/Rot
#F2435A(Schlaf-App) - Reines Schwarz
#0A0A0Aals primäre Button-Farbe in neutralen Apps (Schlaf-App, Rechner „=", „Deploy v13", „New event") [gesehen]
Semantische Farbtöne [gesehen]: grün #16A34A-Text auf #ECFDF3; rot #DC2626 auf #FEF2F2; bernstein/orange auf #FFF4E5; blau auf #EEF4FF. Avatar-Initialen sitzen auf Pastellkreisen mit dunklerem, gleichfarbigem Text („SW", „AJ", „MP").
Verläufe: selten, aber wirkungsvoll eingesetzt [gesehen: „the art of using gradients"]. Buttons erhalten einen dezenten Verlauf von oben nach unten (#FFFFFF → #F7F7F7 für sekundär; ein etwas helleres oben für primär). Hero-Artwork verwendet verschwommene, mehrfarbige Blobs mit Plus-Darker-Blending plus einer Rauschen/Korn-Überlagerung [gesehen: Hero-Illustrations-Thread].
2.3 Form, Abstand, Tiefe
- Radien [gesehen und erschlossen]: kleine Steuerelemente und Buttons 8–10px [gesehen: „30px height, 10px radius"]; Eingabefelder 10–12px; Karten 12–16px; Modals und Befehlspaletten 20–24px; mobile Blätter und Telefonkarten 24–32px; Pillen und Chips vollständig abgerundet. Mobile Buttons sind oft vollständige Pillen [gesehen].
- Abstände: ein 4px-Basisraster. Übliche Abstände sind 4/8/12/16/24/32/48 [erschlossen]. Viel Luft um den Inhalt; dichte Tabellen erhalten dennoch ~40–48px Zeilen [erschlossen].
- Steuerelementhöhen [gesehen/erschlossen]: kompakte Desktop-Buttons 30–32px, Standard 36–40px, mobiler primärer CTA 48–56px.
- Rahmen: 1px hauchdünne Linien in sehr hellem Grau. Oft wird der Rahmen aus einem unscharfen 1px-Spread-Schatten anstelle von
bordergemacht [gesehen: Secondary-Button-Rezept]. - Schatten [gesehen]: Secondary-Button =
0 1px 2px rgba(40,40,40,.08), 0 0 0 1px #ECECEC. Schwebende Oberflächen (Popovers, Paletten, Tooltips) verwenden einen großen, sehr weichen Umgebungsschatten plus eine hauchdünne Linie. Dunkle Tooltips liegen über hellen UIs [gesehen: Statsnap-Chart-Tooltip, „Task completed · Undo"-Toast]. - Mobil: Artboard 430×932 [gesehen], runde 40–44px Icon-Buttons in der oberen Leiste, gruppierte „Inset"-Listenkarten auf grauer Leinwand, schwebende Pillen-Tab-Leisten [gesehen].
2.4 Layoutmuster [gesehen]
- SaaS-App-Shell: linke Seitenleiste (220–260px) auf dezentem Grau, gruppierte Navigation mit kleinen, grauen Großbuchstaben-Labels, aktives Element = weiße Pille mit weichem Schatten (hell) oder
#1E1E1E-Füllung (dunkel); Hauptinhalt auf Weiß mit einer dünnen oberen Leiste (BreadcrumbHome > Transaction, Suche mit/-Hinweis, Icon-Buttons). Manchmal gibt es stattdessen eine schmale Icon-Leiste (48–56px). - Filter-Chip-Reihe über Tabellen:
Bereich Letzte 30 Tage ▾,Bereich Alle Tools ▾. Das Label ist grau und der Wert ist dunkel. - Tabellen: keine Zebrastreifen, hauchdünne Zeilentrennlinien, kleine graue Kopfzeilentexte, getönte Status-Pillen, Avatar + Name + E-Mail-Stapel, rechtsbündige Zahlen, tabellarische Ziffern.
- KPI-Karten: Label, große Zahl (oft Monospace), Delta-Pille (
▲ +14,7 % vs. letztes Jahr). - Auth/Onboarding: geteilte Karte. Formular auf der linken Seite (Logo in einem weichen Kreis, Titel, Untertitel, Google-Button, „oder"-Trennlinie, Eingabe, primär), Produktvorschau auf der rechten Seite in einem grauen Panel mit Karussell-Punkten [gesehen: „just designed the perfect signup page"].
- Befehlspalette: 24px Radius, Suchzeile mit
ESC-Taste, Filter-Pillen, gruppierte Ergebnisse, Tastaturkürzel-Fußzeile [gesehen]. - Mobiles Onboarding: segmentierte Fortschrittsleiste + „1/5", zentrierte fette Frage, auswählbare Optionszeilen mit Kreis-Checks, klebriger Pillen-CTA [gesehen].
- Landing-Heroes: schwebende Pillen-Navbar, kleines „Backed with X"-Badge, kurze, knackige Headline (manchmal in Großbuchstaben grotesk, manchmal eine Serife), dunkler primärer + weißer sekundärer Button, große Illustration darunter [gesehen].
2.5 Ikonografie und Illustration [gesehen]
- Icons: dünnstrichige Outline-Icons (Lucide/Phosphor-ähnlich, ~1,5px Strich, 16–18px in der UI), standardmäßig grau, dunkler bei Aktivierung.
- Kleine farbige App-Icon-Kacheln (abgerundete Quadrate mit einem Verlauf und einer Glyphe) für Feature-Karten und Kategorien.
- Illustrationsstile: (a) isometrische Strichzeichnungen auf einem gepunkteten Raster, monochrom; (b) leuchtende Verlaufsbänder/-ströme auf einem körnigen Pastellhintergrund mit einem isometrischen Raster und schwebendem Konfetti; (c) freundliche, flach schattierte Spot-Illustrationen und 3D-artige Emoji-Icons für Consumer- und Mobile-Apps; (d) skeuomorphe Details (eine genähte Lederbrieftasche, die eine Karte hält).
- Seine Animationspipeline: „Draw the illustrations in Figma → Animate in AE/Rive → Export to lottie if using AE → Implement onto the website". Bei einem Projekt verwendete er „Figma… Rive for animation, Next.js + Sanity". Hero-Bereiche bestehen oft aus „design + illustration + animation" [gesehen].
2.6 Dunkel vs. Hell [gesehen]
Er verwendet beide und liefert passende Sets („light/dark mode", „figma tokens are so useful!"). Hell ist der Standard für Produktivitäts-SaaS. Dunkel wird für Krypto/Handel, Code-Editoren, Sidebars und Marketing-Banner verwendet. Dunkle Oberflächen steigen in ~6–10 Hellstufen (#0D0D0D → #121212 → #1A1A1A → #222), nicht durchgehend reines Schwarz.
3. Design-Tokens (CSS-Variablen)
Füge dies in das globale Stylesheet ein. Tailwind-Benutzer können diese in @theme (v4) oder theme.extend (v3) abbilden.
:root {
/* Schrift */
--font-sans: "Inter", "Geist", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
--font-mono: ui-monospace, "Geist Mono", "SF Mono", Menlo, monospace;
--font-rounded: "SF Pro Rounded", ui-rounded, "Google Sans Rounded", var(--font-sans);
--text-xs: 12px; --text-sm: 13px; --text-base: 14px; --text-md: 16px;
--text-lg: 18px; --text-xl: 24px; --text-2xl: 32px; --text-3xl: 48px;
--text-4xl: 64px; --text-5xl: 96px;
--tracking-body: 0; /* <= 16px */
--tracking-tight: -0.01em;/* 18–24px */
--tracking-title: -0.03em;/* ~36px (seine Regel) */
--tracking-display: -0.055em; /* 100px+ (seine Regel: -5% bis -6%) */
--weight-regular: 400; --weight-medium: 500; --weight-semibold: 600;
/* Neutrale (hell) */
--bg: #ffffff;
--bg-subtle: #f7f7f7;
--bg-muted: #f0f0f0;
--bg-backdrop: #e8e8e8;
--border: #ececec;
--border-strong: #e0e0e0;
--fg: #171717;
--fg-secondary: #737373;
--fg-tertiary: #a3a3a3;
--fg-inverse: #ffffff;
/* Akzent: EINEN pro Produkt auswählen */
--accent: #7b3aec; /* Violett; Alternativen: #255cd1 blau, #ff5a1f orange, #0a0a0a schwarz */
--accent-hover: color-mix(in oklab, var(--accent), black 8%);
--accent-soft: color-mix(in oklab, var(--accent), white 90%);
--accent-fg: #ffffff;
--ring: color-mix(in oklab, var(--accent), transparent 65%);
/* Semantisch (dunkler Text auf hellem Farbton) */
--success: #16a34a; --success-soft: #ecfdf3;
--danger: #dc2626; --danger-soft: #fef2f2;
--warning: #d97706; --warning-soft: #fff7e6;
--info: #2563eb; --info-soft: #eef4ff;
/* Abstände (4px-Raster) */
--space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px;
--space-5: 20px; --space-6: 24px; --space-8: 32px; --space-10: 40px;
--space-12: 48px; --space-16: 64px; --space-24: 96px;
/* Radien */
--radius-xs: 6px; --radius-sm: 8px; --radius-md: 10px; --radius-lg: 12px;
--radius-xl: 16px; --radius-2xl: 20px; --radius-3xl: 24px; --radius-full: 9999px;
/* Höhen */
--h-control-sm: 30px; --h-control: 36px; --h-control-lg: 44px; --h-cta-mobile: 52px;
/* Schatten (geschichtet, weich; hauchdünne Linie via Spread) */
--hairline: 0 0 0 1px var(--border);
--shadow-xs: 0 1px 2px rgb(40 40 40 / 0.08);
--shadow-btn: 0 1px 2px rgb(40 40 40 / 0.08), 0 0 0 1px #ececec; /* sein Secondary-Button */
--shadow-btn-primary: inset 0 1px 0 rgb(255 255 255 / 0.18), 0 1px 2px rgb(0 0 0 / 0.16), 0 0 0 1px color-mix(in oklab, var(--accent), black 12%);
--shadow-card: 0 1px 2px rgb(0 0 0 / 0.04), 0 0 0 1px var(--border);
--shadow-pop: 0 0 0 1px rgb(0 0 0 / 0.06), 0 8px 24px -4px rgb(0 0 0 / 0.10), 0 2px 6px rgb(0 0 0 / 0.04);
--shadow-modal: 0 0 0 1px rgb(0 0 0 / 0.06), 0 24px 64px -12px rgb(0 0 0 / 0.18);
--shadow-focus: 0 0 0 3px var(--ring);
/* Motion (siehe §5) */
--ease-out: cubic-bezier(0.23, 1, 0.32, 1); /* starkes Ease-Out (Emil Kowalski) */
--ease-in-out: cubic-bezier(0.77, 0, 0.175, 1); /* für Bewegungen auf dem Bildschirm */
--ease-drawer: cubic-bezier(0.32, 0.72, 0, 1); /* iOS-ähnliches Blatt (Vaul) */
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
--dur-instant: 100ms; --dur-fast: 150ms; --dur-base: 200ms;
--dur-moderate: 250ms; --dur-slow: 350ms; --dur-page: 500ms;
}
[data-theme="dark"], .dark {
--bg: #0d0d0d;
--bg-subtle: #141414;
--bg-muted: #1c1c1c;
--bg-backdrop: #0a0a0a;
--border: rgb(255 255 255 / 0.08);
--border-strong: rgb(255 255 255 / 0.14);
--fg: #fafafa;
--fg-secondary: #a1a1a1;
--fg-tertiary: #6b6b6b;
--shadow-btn: inset 0 1px 0 rgb(255 255 255 / 0.06), 0 0 0 1px rgb(255 255 255 / 0.08);
--shadow-btn-primary: inset 0 1px 0 rgb(255 255 255 / 0.12), 0 0 0 1px color-mix(in oklab, var(--accent), black 20%), 0 1px 4px rgb(0 0 0 / 0.4);
--shadow-card: 0 1px 2px rgb(0 0 0 / 0.12), 0 0 0 1px rgb(255 255 255 / 0.06);
--shadow-pop: 0 0 0 1px rgb(255 255 255 / 0.06), 0 8px 24px -4px rgb(0 0 0 / 0.4), 0 2px 6px rgb(0 0 0 / 0.2);
--shadow-modal: 0 0 0 1px rgb(255 255 255 / 0.06), 0 24px 64px -12px rgb(0 0 0 / 0.6);
}
4. Komponenten-Rezepte
Jedes Rezept folgt seinem beobachteten Stil. Verwende die Tokens aus §3.
4.1 Primary-Button
<button
style={{
height: "var(--h-control)",
padding: "0 var(--space-5)",
border: 0,
borderRadius: "var(--radius-md)",
background: "var(--accent)",
color: "var(--accent-fg)",
fontSize: "var(--text-sm)",
fontWeight: "var(--weight-medium)",
letterSpacing: "var(--tracking-body)",
boxShadow: "var(--shadow-btn-primary)",
cursor: "pointer",
transition: "box-shadow var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out)",
}}
>
Aktion
</button>
Hover: box-shadow zur nächsten Stufe hochschalten: weniger innenliegende Hervorhebung, mehr Tiefe. transform: scale(0.97).
Pressed/Active: Schatten entfernen, Skalierung auf 0.96.
Disabled: Opazität auf 0.5, cursor: not-allowed.
4.2 Secondary-Button
<button
style={{
height: "var(--h-control)",
padding: "0 var(--space-5)",
border: 0,
borderRadius: "var(--radius-md)",
background: "var(--bg)",
color: "var(--fg)",
fontSize: "var(--text-sm)",
fontWeight: "var(--weight-medium)",
boxShadow: "var(--shadow-btn)",
cursor: "pointer",
transition: "box-shadow var(--dur-fast) var(--ease-out)",
}}
>
Sekundär
</button>
Dies ist sein Rezept: 3 Schatten (unscharfer Umgebungsschatten + hauchdünne Linie). Der Hover verdunkelt die hauchdünne Linie auf #E0E0E0. Klick entfernt den Umgebungsschatten.
4.3 Text-Input
<div style={{ display: "flex", flexDirection: "column", gap: "var(--space-1)" }}>
<label style={{ fontSize: "var(--text-sm)", color: "var(--fg-secondary)" }}>
Label
</label>
<input
style={{
height: "var(--h-control)",
padding: "0 var(--space-3)",
border: 0,
borderRadius: "var(--radius-sm)",
background: "var(--bg)",
boxShadow: "var(--shadow-xs), var(--hairline)",
fontSize: "var(--text-sm)",
color: "var(--fg)",
outline: "none",
transition: "box-shadow var(--dur-fast) var(--ease-out)",
}}
placeholder="Platzhalter"
/>
</div>
Fokus: box-shadow: var(--shadow-focus), var(--hairline).
Disabled: opacity: 0.5, cursor: not-allowed.
Fehler: var(--danger-soft)-Hintergrund, var(--danger)-Ring.
4.4 Karte
<div
style={{
borderRadius: "var(--radius-xl)",
background: "var(--bg)",
padding: "var(--space-6)",
boxShadow: "var(--shadow-card)",
display: "flex",
flexDirection: "column",
gap: "var(--space-4)",
}}
>
<h3 style={{ fontSize: "var(--text-lg)", fontWeight: "var(--weight-medium)" }}>
Kartentitel
</h3>
<p style={{ fontSize: "var(--text-sm)", color: "var(--fg-secondary)", lineHeight: 1.5 }}>
Karteninhalt
</p>
</div>
4.5 Dialog/Modal
<div
style={{
position: "fixed",
inset: 0,
display: "flex",
alignItems: "center",
justifyContent: "center",
background: "color-mix(in oklab, black, transparent 40%)",
}}
>
<div
style={{
borderRadius: "var(--radius-2xl)",
background: "var(--bg)",
padding: "var(--space-8)",
boxShadow: "var(--shadow-modal)",
maxWidth: 480,
width: "100%",
display: "flex",
flexDirection: "column",
gap: "var(--space-6)",
}}
>
<h2 style={{ fontSize: "var(--text-xl)", fontWeight: "var(--weight-medium)" }}>
Modaltitel
</h2>
<p style={{ fontSize: "var(--text-sm)", color: "var(--fg-secondary)" }}>
Inhalt
</p>
<div style={{ display: "flex", justifyContent: "flex-end", gap: "var(--space-3)" }}>
<button style={{ /* Secondary-Button-Style */ }}>Abbrechen</button>
<button style={{ /* Primary-Button-Style */ }}>Bestätigen</button>
</div>
</div>
</div>
5. Motion und Mikrointeraktionen
5.1 Timing und Easings
| Kontext | Dauer | Easing |
|---|---|---|
| Hover, Fokus, kleine Zustandswechsel (Toggle, Like) | --dur-fast (150 ms) | --ease-out |
| Einblenden von Elementen, Erscheinen von Dialogen | --dur-base (200 ms) | --ease-out |
| Aufdecken von Drawer/Sheet/Modal | --dur-moderate (250 ms) | --ease-drawer |
| Seitenübergänge, Layout-Shifts | --dur-slow (350 ms) | --ease-in-out |
| Seiteneingang (Page-Enter) | --dur-page (500 ms) | --ease-standard |
5.2 Mikrointeraktions-Rezepte
Button-Interaktionen
- Scale-Down bei
:active:transform: scale(0.97). - Klick-Welle (Ripple): Überlagere ein absolut positioniertes Element, das von der Mitte ausgehend skaliert und ausgeblendet wird. Dauer:
--dur-fast.
Hover-Karten Leichte Anhebung (Y-Translation) + verdunkelte hauchdünne Linie + erweiterter Schatten:
<div
onMouseEnter={(e) => {
e.currentTarget.style.transform = "translateY(-2px)";
e.currentTarget.style.boxShadow = "0 1px 4px rgba(0,0,0,0.08), 0 0 0 1px #D0D0D0";
}}
// ...
>
Listen-Elemente (Fade + Slide)
Beim Filtern: ausgehende Elemente erhalten opacity: 0 + translateY(-8px), eingehende opacity: 0 + translateY(8px). Dauer: --dur-moderate.
Fortschrittsbalken
Weicher Fortschritt mit --ease-out. Keine abrupten Sprünge.
Toast-Benachrichtigungen
- Erscheinen: Von oben hereingleiten (
translateY(-16px) → 0) + Einblenden. - Verschwinden: Ausblenden + nach oben gleiten.
- Dauer:
--dur-moderate.
Skelett-Ladezustand
Pulsierender Hintergrund var(--bg-subtle) mit einem sanften Farbwechsel (Shimmer-Effekt). Vermeide große, sich wiederholende Animationen. Verwende einen dezenten, einmaligen Durchlauf.
6. Seitenstrukturen (Layouts)
6.1 SaaS-App-Bildschirm
+------------------------------------------+
| Seitenleiste (220–260px, dezent grau) | Hauptinhalt (weiß) |
| | Top-Leiste (Breadcrumb + Suche) |
| Gruppe 1 | Filterzeile |
| Element | Tabelle / KPI-Karten / Inhalt |
| Element (aktiv = weiße Pille) | |
| Gruppe 2 | |
| Element | |
| Benutzerbereich (unten) | |
+------------------------------------------+
6.2 Mobile Auth / Onboarding
+---------------------------+
| [Zurück] [1/5] |
| |
| Logo (weicher Kreis) |
| |
| Fette, zentrierte Frage|
| |
| () Option 1 |
| () Option 2 |
| () Option 3 |
| |
| [Klebriger Pillen-CTA] |
+---------------------------+
7. Dunkelmodus-Anpassungen
- Hintergrund: Kein reines Schwarz. Verwende
#0D0D0Dfür die Leinwand,#141414für dezent,#1C1C1Cfür gedämpft. - Rahmen:
rgba(255, 255, 255, 0.08)für hauchdünne Linien. - Schatten: Umkehrung. Helle Elemente erhalten einen inneren Schatten; Schwebeelemente werden durch hellere Ränder definiert.
- Akzente: Behalte denselben Farbton bei, erwäge aber eine hellere Variante für besseren Kontrast (
color-mix(in oklab, var(--accent), white 20%)). - Text:
#FAFAFAfür primär,#A1A1A1für sekundär.
8. Beispiel (React + Tailwind v4 + Motion)
// app/page.tsx
"use client";
import { motion } from "motion/react";
export default function Page() {
return (
<div className="min-h-screen bg-[var(--bg-subtle)] flex items-center justify-center p-8">
<motion.div
initial={{ opacity: 0, y: 12 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.25, ease: [0.23, 1, 0.32, 1] }}
className="bg-[var(--bg)] rounded-[var(--radius-2xl)] p-8 shadow-[var(--shadow-modal)] max-w-sm w-full space-y-6"
>
<div className="flex items-center gap-4">
<div className="w-12 h-12 rounded-[var(--radius-lg)] bg-[var(--accent-soft)] flex items-center justify-center">
<span className="text-[var(--accent)] font-[var(--weight-semibold)] text-[var(--text-md)]">K</span>
</div>
<div>
<h2 className="text-[var(--text-lg)] font-[var(--weight-medium)] text-[var(--fg)]">
Willkommen
</h2>
<p className="text-[var(--text-sm)] text-[var(--fg-secondary)]">
Los geht‘s
</p>
</div>
</div>
<input
placeholder="Deine E-Mail"
className="w-full h-[var(--h-control)] px-[var(--space-3)] bg-[var(--bg)] rounded-[var(--radius-sm)] text-[var(--text-sm)] text-[var(--fg)] placeholder:text-[var(--fg-tertiary)] shadow-[var(--shadow-xs),var(--hairline)] outline-none focus:shadow-[var(--shadow-focus),var(--hairline)] transition-shadow duration-150 ease-[var(--ease-out)]"
/>
<button className="w-full h-[var(--h-control)] bg-[var(--accent)] text-[var(--accent-fg)] rounded-[var(--radius-md)] text-[var(--text-sm)] font-[var(--weight-medium)] shadow-[var(--shadow-btn-primary)] hover:brightness-110 active:scale-[0.97] transition-all duration-150 ease-[var(--ease-out)]">
Fortfahren
</button>
<p className="text-[var(--text-xs)] text-[var(--fg-tertiary)] text-center">
Mit dem Fortfahren stimmst du unseren Bedingungen zu.
</p>
</motion.div>
</div>
);
}
9. QA-Checkliste (die letzten 10 %)
Führe diese Prüfungen durch, bevor du den Code als abgeschlossen betrachtest:
Typografie
- Wird die primäre Schriftfamilie geladen und angewendet?
- Sind die Schriftstärken auf 2 pro Schriftart begrenzt (Regular + Medium/Semibold)?
- Sind die Buchstabenabstände gemäß §2.1 eingestellt (negativ für Titel, positiv für SF Pro Rounded)?
- Haben alle Texte einen ausreichenden Kontrast (mindestens AA, vorzugsweise AAA)?
- Sind sekundäre Texte in
#737373(hell) /#A1A1A1(dunkel) gehalten?
Layout und Abstand
- Folgt das Layout einem 4px-Raster?
- Gibt es mindestens
--space-6(24px) zwischen Inhaltsabschnitten? - Sind die Steuerelementhöhen konsistent (30/36/44/52px je nach Kontext)?
- Sind die Radien konsistent (10px für Buttons, 16px für Karten, 24px für Modals)?
Farbe und Akzente
- Wird genau eine Akzentfarbe verwendet (keine mehrfarbigen Buttons oder Links)?
- Sind semantische Farben (Erfolg, Fehler, Warnung) als dunkler Text auf hellem Farbton umgesetzt (kein weißer Text auf gesättigtem Hintergrund)?
- Existiert und funktioniert der Dunkelmodus ordnungsgemäß?
- Sind hauchdünne Linien
#ECECEC(hell) /rgba(255,255,255,0.08)(dunkel)?
Schatten und Tiefe
- Werden geschichtete Schatten anstelle von dicken
border-Werten verwendet? - Haben primäre Buttons einen inneren Schatten nach oben (Hervorhebung)?
- Haben schwebende Oberflächen (Popover, Tooltips) einen großen, weichen Schatten + hauchdünne Linie?
Motion
- Sind Hover- und Fokus-Übergänge vorhanden (Skalierung, Schattenwechsel)?
- Sind Animationen kurz (150–350 ms) und verwenden sie die angegebenen Easings?
- Sind Seitenübergänge glatt (Fade + Slide)?
- Sind alle Animationen deaktiviert, wenn
prefers-reduced-motion: reducegesetzt ist?
Barrierefreiheit
- Sind alle Buttons und Eingabefelder fokussierbar und haben einen sichtbaren Fokusring (
--shadow-focus)? - Haben Icons und Bilder geeignete
alt-Texte? - Sind Formular-Labels mit Eingabefeldern verknüpft?
- Sind die Touch-Ziele auf Mobilgeräten mindestens 44×44px?
10. Weiterführende Literatur
- Motion-Dokumentation – die Animationsbibliothek hinter den Beispielen
- Emil Kowalskis Design-Artikel – Easings, Mikrointeraktionen
- Apple Human Interface Guidelines – Motion, Layout
- Rive – Tool, das Kargul für komplexe Animationen verwendet
- Vaul – Drawer-Komponente, deren Easing referenziert wird
- Lucide-Icons – Icons im beobachteten Stil