Communitygithub.com

giga-ui

Utilisez cette compétence pour créer, reconcevoir ou peaufiner n'importe quelle interface utilisateur (composant, page d'accueil, tableau de bord, écran d'application, UI mobile, intégration ou flux d'authentification), surtout à partir d'une invite courte ou vague. Elle vous fournit un langage visuel complet, des jetons de conception, des recettes de composants, ainsi qu'un système de mouvement et de micro-interactions pour un résultat premium. Le style est inspiré du designer produit @marcelkargul.

Qu'est-ce que giga-ui ?

Cette compétence transforme une demande d'interface utilisateur en une seule ligne en une interface polie et de qualité production. Le langage visuel est **inspiré du travail de design public de @marcelkargul** (Kargul Studio) : interfaces produit calmes, quasi-monochromes, typographie très soignée, ombres douces et superposées sans bordures épaisses, une seule couleur d'accent audacieuse, et un mouvement rapide, physique et jamais décoratif. Elle fonctionne avec n'importe quel modèle de codage et n'importe quelle stack. Les exemples utilisent React + Tailwind + Motion (`motion/react`), chacun avec un équivalent CSS pur. La compétence détaille la philosophie de conception, le style observé (typographie, couleur, espacement, ombres, motifs de mise en page), des jetons de conception complets sous forme de variables CSS, des recettes de composants pour les éléments d'interface communs (boutons, entrées, cartes, etc.), un système de mouvement et de micro-interactions, et une checklist d'assurance qualité pour ce dernier 10%. Elle est idéale pour les développeurs utilisant des assistants IA (comme Claude Code, Cursor, Codex) qui souhaitent générer des interfaces utilisateur soignées et cohérentes à partir de descriptions simples.

Compatible avec✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/aidan-neel/design/tree/HEAD/skills/giga-ui

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

GIGA UI : calme, précis, vivant

Cette compétence transforme une demande d'interface utilisateur en une seule ligne en une interface polie et de qualité production. Le langage visuel est inspiré du travail de design public de @marcelkargul (Kargul Studio) : interfaces produit calmes, quasi-monochromes, typographie très soignée, ombres douces et superposées sans bordures épaisses, une seule couleur d'accent audacieuse, et un mouvement rapide, physique et jamais décoratif pour lui-même.

Elle fonctionne avec n'importe quel modèle de codage et n'importe quelle stack. Les exemples utilisent React + Tailwind + Motion (motion/react), et chacun a un équivalent CSS pur.

Légende de provenance utilisée ci-dessous : [vu] directement observé dans ses publications/images ou indiqué dans ses légendes. [déduit] une extrapolation raisonnable de ce qui a été vu (mesuré à partir de captures d'écran, ou implicite). [expert] meilleure pratique générale en matière de mouvement/UX issue de la documentation de Motion, d'Emil Kowalski, d'Apple HIG. Ne provient pas de ses publications.


1. Philosophie de conception

  1. Si on peut l'enlever, on l'enlève. [vu, légende : "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."]
  2. La typographie fait le gros du travail. [vu : "just master typography and you can make anything look good."] Utilisez une seule famille (Inter par défaut sur le web, Geist comme alternative optionnelle ; SF Pro Rounded pour le mobile de style iOS) et au maximum 2 graisses [vu : "sf pro rounded, maximum 2 font weights, keep it simple"].
  3. Blanc, noir et ombres. [vu : "No animations, no gradients, no fancy effects. Just FFFFFF, 000000, and some shadows. This is design at its peak."] La majeure partie de la palette est composée de gris neutres. La couleur est utilisée pour signifier quelque chose, comme l'état, la catégorie ou l'action principale unique.
  4. La profondeur vient d'ombres douces superposées et de lignes fines, pas de bordures épaisses. [vu : "this button only requires 3 shadows!" et la recette du bouton secondaire au §3]
  5. Le mouvement fait partie du produit, pas une décoration. [vu : "micro-interactions throughout", "subtle loading animation. not overdone, just perfect", "every website needs this level of animation", "idea → design → animation"]. Animez seulement pour expliquer un changement, confirmer une action ou guider l'attention [expert].
  6. Peaufiner les 10% finaux à la main. [vu : son processus est "design in figma, build with the help of claude, spend hours fixing small details manually and improving code quality"]. La checklist QA au §9 représente ces 10% finaux.
  7. Propre bat ingénieux. Ses légendes reviennent sans cesse aux mots "clean", "calm" et "simple" (par exemple, "Every task in one calm list"). Même lorsqu'il y a beaucoup de données, l'écran doit donner une sensation de calme.

2. Le style observé (à quoi ressemble réellement son travail)

2.1 Typographie

  • Familles : Inter (la valeur par défaut dans cette compétence) et Geist (alternative optionnelle). [vu : "After using 100s of different fonts, I realized nothing beats Inter and Geist." ; publication humoristique : les designers juniors et seniors utilisent tous "Inter, Geist"]. SF Pro Rounded pour les applications mobiles [vu, plusieurs publications]. Il recommande également Google Sans Rounded comme alternative multiplateforme à SF Pro Rounded [vu, réponse]. Une police monospace (de type Geist Mono) apparaît pour les grands nombres, les tickers et le code [vu : soldes d'applications crypto, cartes KPI Statsnap, variante de barre latérale de navigation]. Le travail de marque et de marketing utilise parfois une police empattement (serif) d'affichage (empattement transitionnel éditorial, graisse légère) [vu : page d'accueil fintech "Every payment protected…", page d'accueil VC].
  • Crénage (ses chiffres exacts, présentés avec Geist ; appliquez-les également à Inter, qu'il a également présenté à −6%) [vu] :
    • 16px → 0%
    • 36px → −3%
    • 100px+ → −5% à −6%
    • "La règle de ne jamais aller en négatif est pour le texte du corps. À 100px+, l'espacement par défaut semble lâche."
    • SF Pro Rounded : crénage de +1% [vu, spécimen typographique].
  • Graisses : Regular (400) et Medium (500) portent la quasi-totalité de l'interface produit. Semibold (600) est pour les titres et les nombres. Bold/Black uniquement pour les gros titres d'affichage [déduit des captures d'écran].
  • Tailles dans l'interface produit [déduit, mesuré à partir de captures d'écran à 1×] : texte du corps et des tableaux 13-14px, texte secondaire/méta 12-13px, étiquettes de section 11-12px en majuscules ou petites capitales grises (par exemple "ESPACE DE TRAVAIL", "OUTILS ÉPINGLÉS"), titres de page 18-24px Medium, nombres KPI 24-32px, titres principaux 48-72px avec crénage négatif. Les boutons sont en 14px Medium [vu : "Geist/14/Medium"].
  • Couleur du texte : primaire presque noir (#171717–#1F1F1F), secondaire gris moyen (#6B6B6B–#737373), tertiaire/placeholder (#A3A3A3). Les étiquettes utilisent un texte foncé teinté sur un fond clair au lieu d'un texte blanc sur des remplissages saturés [vu, publication "Do / Don't" : "Dark text improves overall readability greatly."].

2.2 Couleur

Échantillonnées à partir de captures d'écran (approximatif) [vu/déduit] :

RôleClairSombre
Toile / page#FFFFFF#0D0D0D–#121212
Surface subtile (barre latérale, panneaux, fond mobile)#F7F7F7 / #F4F4F4 / #FAFAFA#1A1A1A–#1E1E1E
Arrière-plan de présentation derrière les maquettes#E5E5E5–#EDEDED, gris moyen #8A8A8A#1F1F1F–#262626
Bordure fine#ECECEC / #EBEBEBrgba(255,255,255,0.08)
Texte primaire#171717#FAFAFA
Texte secondaire#737373#A1A1A1

Couleurs d'accent (une par produit, jamais plusieurs à la fois) [vu] :

  • Violet #7B3AEC (inscription Underlay, intégration), également une variante indigo #5B5BF0
  • Bleu #255CD1 / bleu iOS #2F7BF6 (calculatrice, calendrier, Statsnap)
  • Orange #FF5A1F / #F97316 (Plunio, Nexora)
  • Sarcelle #0F766E (environ) (pipeline IA, AIData)
  • Citron vert #B4F05A sur fond presque noir (bouton "Start" de l'éditeur de code, marque Soma)
  • Corail/rouge #F2435A (application sommeil)
  • Noir pur #0A0A0A comme couleur de bouton primaire dans les applications neutres (application sommeil, "=" de la calculatrice, "Déployer v13", "Nouvel événement") [vu]

Teintes sémantiques [vu] : vert #16A34A texte sur #ECFDF3 ; rouge #DC2626 sur #FEF2F2 ; ambre/orange sur #FFF4E5 ; bleu sur #EEF4FF. Les initiales des avatars reposent sur des cercles pastel avec un texte de même teinte plus foncé ("SW", "AJ", "MP").

Dégradés : utilisés rarement mais bien [vu : "the art of using gradients"]. Les boutons reçoivent un subtil dégradé de haut en bas (#FFFFFF → #F7F7F7 pour le secondaire ; un haut légèrement plus clair pour le primaire). L'art des héros utilise des blobs multicolores flous avec un mélange Plus-Darker ainsi qu'une superposition de bruit/grain [vu, fil de discussion sur les illustrations des héros].

2.3 Forme, espacement, profondeur

  • Rayons [vu et déduit] : petits contrôles et boutons 8-10px [vu : "30px height, 10px radius"] ; champs de saisie 10-12px ; cartes 12-16px ; modales et palettes de commandes 20-24px ; feuilles mobiles et cartes téléphone 24-32px ; pilules et chips entièrement arrondis. Les boutons mobiles sont souvent des pilules complètes [vu].
  • Espacement : une grille de base de 4px. Les écarts courants sont 4/8/12/16/24/32/48 [déduit]. Beaucoup d'air autour du contenu ; les tableaux denses ont toujours des lignes d'environ 40-48px [déduit].
  • Hauteurs de contrôle [vu/déduit] : boutons compacts de bureau 30-32px, standard 36-40px, CTA principal mobile 48-56px.
  • Bordures : lignes fines de 1px en gris très clair. Souvent, la bordure est créée à partir d'une ombre portée de 0 flou et 1px d'étalement au lieu d'utiliser border [vu : recette du bouton secondaire].
  • Ombres [vu] : bouton secondaire = 0 1px 2px rgba(40,40,40,.08), 0 0 0 1px #ECECEC. Les surfaces flottantes (popovers, palettes, infobulles) utilisent une ombre ambiante large et très douce ainsi qu'une ligne fine. Les infobulles sombres reposent sur les interfaces claires [vu : infobulle du graphique Statsnap, toast "Tâche terminée · Annuler"].
  • Mobile : zone de travail 430×932 [vu], boutons d'icône ronds de 40-44px dans la barre supérieure, cartes de liste "encastrées" groupées sur une toile grise, barres d'onglets en pilule flottantes [vu].

2.4 Motifs de mise en page [vu]

  • Coque d'application SaaS : barre latérale gauche (220-260px) sur un gris subtil, navigation groupée avec petites étiquettes grises en majuscules, élément actif = pilule blanche avec ombre douce (clair) ou remplissage #1E1E1E (sombre) ; contenu principal sur blanc avec une fine barre supérieure (fil d'Ariane Accueil > Transaction, recherche avec l'indice /, boutons d'icône). Parfois, il y a un rail d'icônes mince (48-56px) à la place.
  • Rangée de chips de filtre au-dessus des tableaux : Plage 30 derniers jours ▾, Portée Tous les outils ▾. Le libellé est gris et la valeur est foncée.
  • Tableaux : pas de rayures zébrées, séparateurs de ligne fins, petit texte d'en-tête gris, pilules d'état teintées, piles avatar + nom + email, nombres alignés à droite, chiffres tabulaires.
  • Cartes KPI : libellé, grand nombre (souvent mono), pilule de delta (▲ +14,7% par rapport à l'année dernière).
  • Authentification/intégration : carte divisée. Formulaire à gauche (logo dans un cercle doux, titre, sous-titre, bouton Google, séparateur "ou", saisie, primaire), aperçu du produit à droite dans un panneau gris avec points de carrousel [vu : "just designed the perfect signup page"].
  • Palette de commandes : rayon de 24px, ligne de recherche avec touche ESC, pilules de filtre, résultats groupés, pied de page avec légende du clavier [vu].
  • Intégration mobile : barre de progression segmentée + "1/5", question centrée en gras, lignes d'options sélectionnables avec cercles de vérification, CTA en pilule collant [vu].
  • Héros de page d'accueil : barre de navigation en pilule flottante, petit badge "Propulsé par X", titre court et percutant (parfois en grotesque tout en majuscules, parfois avec empattement), bouton primaire sombre + secondaire blanc, grande illustration en dessous [vu].

2.5 Iconographie et illustration [vu]

  • Icônes : icônes de contour à trait fin (type Lucide/Phosphor, trait d'environ 1,5px, 16-18px dans l'interface), grises par défaut, plus foncées lorsqu'elles sont actives.
  • Petites tuiles d'icônes d'application colorées (carrés arrondis avec un dégradé et un glyphe) pour les cartes de fonctionnalités et les catégories.
  • Styles d'illustration : (a) dessin au trait isométrique sur une grille en pointillés, monochrome ; (b) rubans/ruisseaux de dégradé vifs sur un fond pastel granuleux avec une grille isométrique et des confettis flottants ; (c) illustrations ponctuelles plates et conviviales et icônes émoji 3D pour les applications grand public et mobiles ; (d) touches skeuomorphes (un portefeuille en cuir cousu contenant une carte).
  • Son pipeline d'animation : "Draw the illustrations in Figma → Animate in AE/Rive → Export to lottie if using AE → Implement onto the website". Sur un projet, il a utilisé "Figma… Rive for animation, Next.js + Sanity". Les sections héros prennent souvent "design + illustration + animation" [vu].

2.6 Sombre vs clair [vu]

Il utilise les deux et publie des ensembles assortis ("mode clair/sombre", "les jetons Figma sont si utiles !"). Le mode clair est la valeur par défaut pour les SaaS de productivité. Le mode sombre est utilisé pour la crypto/le trading, les éditeurs de code, les barres latérales et les bannières marketing. Les surfaces sombres montent par incréments de luminosité d'environ 6-10 (#0D0D0D → #121212 → #1A1A1A → #222), pas du noir pur partout.


3. Jetons de conception (variables CSS)

Collez ceci dans la feuille de style globale. Les utilisateurs de Tailwind peuvent mapper ces jetons dans @theme (v4) ou theme.extend (v3).

:root {
  /* Type */
  --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  (sa règle) */
  --tracking-display: -0.055em; /* 100px+ (sa règle : -5% à -6%) */
  --weight-regular: 400; --weight-medium: 500; --weight-semibold: 600;

  /* Neutres (clair) */
  --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;

  /* Accent : choisir UNE par produit */
  --accent: #7b3aec;             /* violet ; alternatives : #255cd1 bleu, #ff5a1f orange, #0a0a0a noir */
  --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%);

  /* Sémantique (texte foncé sur teinte douce) */
  --success: #16a34a; --success-soft: #ecfdf3;
  --danger:  #dc2626; --danger-soft:  #fef2f2;
  --warning: #d97706; --warning-soft: #fff7e6;
  --info:    #2563eb; --info-soft:    #eef4ff;

  /* Espacement (grille de 4px) */
  --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;

  /* Rayons */
  --radius-xs: 6px; --radius-sm: 8px; --radius-md: 10px; --radius-lg: 12px;
  --radius-xl: 16px; --radius-2xl: 20px; --radius-3xl: 24px; --radius-full: 9999px;

  /* Hauteurs */
  --h-control-sm: 30px; --h-control: 36px; --h-control-lg: 44px; --h-cta-mobile: 52px;

  /* Ombres (superposées, douces ; ligne fine via l'étalement) */
  --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;     /* son bouton secondaire */
  --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);

  /* Mouvement (voir §5) */
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);       /* fort ease-out (Emil Kowalski) */
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);   /* pour le mouvement à l'écran */
  --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);    /* feuille de style iOS (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.06);
  --shadow-btn-primary: inset 0 1px 0 rgb(255 255 255 / 0.14), 0 1px 2px rgb(0 0 0 / 0.24), 0 0 0 1px color-mix(in oklab, var(--accent), black 4%);
  --shadow-card: 0 1px 2px rgb(0 0 0 / 0.12), 0 0 0 1px rgb(255 255 255 / 0.04);
  --shadow-pop: 0 0 0 1px rgb(255 255 255 / 0.04), 0 8px 24px -4px rgb(0 0 0 / 0.24), 0 2px 6px rgb(0 0 0 / 0.08);
  --shadow-modal: 0 0 0 1px rgb(255 255 255 / 0.04), 0 24px 64px -12px rgb(0 0 0 / 0.36);
}

4. Recettes de composants

4.1 Bouton secondaire

<button
 style={{
   height: "var(--h-control)",
   paddingInline: "var(--space-4)",
   borderRadius: "var(--radius-sm)",
   backgroundColor: "var(--bg)",
   color: "var(--fg)",
   fontSize: "var(--text-base)",
   fontWeight: "var(--weight-medium)",
   boxShadow: "var(--shadow-btn)",
   transition: "box-shadow var(--dur-fast) var(--ease-out), background-color var(--dur-fast) var(--ease-out)",
 }}
 onMouseOver={(e) => (e.currentTarget.style.boxShadow = "var(--shadow-btn-primary)")}
 onMouseOut={(e) => (e.currentTarget.style.boxShadow = "var(--shadow-btn)")}
>
  {children}
</button>

Équivalent Tailwind :

<button class="h-[var(--h-control)] px-4 rounded-[var(--radius-sm)] bg-[var(--bg)] text-[var(--fg)] text-sm font-medium shadow-[var(--shadow-btn)] transition-shadow duration-150 ease-out hover:shadow-[var(--shadow-btn-primary)]">

4.2 Bouton primaire

<button
 style={{
   height: "var(--h-control)",
   paddingInline: "var(--space-5)",
   borderRadius: "var(--radius-sm)",
   backgroundColor: "var(--accent)",
   color: "var(--accent-fg)",
   fontSize: "var(--text-base)",
   fontWeight: "var(--weight-medium)",
   boxShadow: "var(--shadow-btn-primary)",
   transition: "box-shadow var(--dur-fast) var(--ease-out), background-color var(--dur-fast) var(--ease-out)",
 }}
 onMouseOver={(e) => (e.currentTarget.style.backgroundColor = "var(--accent-hover)")}
 onMouseOut={(e) => (e.currentTarget.style.backgroundColor = "var(--accent)")}
>
  {children}
</button>

Équivalent Tailwind :

<button class="h-[var(--h-control)] px-5 rounded-[var(--radius-sm)] bg-[var(--accent)] text-[var(--accent-fg)] text-sm font-medium shadow-[var(--shadow-btn-primary)] transition-shadow duration-150 ease-out hover:bg-[var(--accent-hover)]">

4.3 Champ de saisie

<input
 type="text"
 style={{
   height: "var(--h-control)",
   paddingInline: "var(--space-3)",
   borderRadius: "var(--radius-sm)",
   border: "none",
   boxShadow: "var(--hairline)",
   backgroundColor: "var(--bg)",
   color: "var(--fg)",
   fontSize: "var(--text-base)",
   fontWeight: "var(--weight-regular)",
   outline: "none",
   transition: "box-shadow var(--dur-fast) var(--ease-out)",
 }}
 onFocus={(e) => (e.currentTarget.style.boxShadow = "var(--shadow-focus)")}
 onBlur={(e) => (e.currentTarget.style.boxShadow = "var(--hairline)")}
/>

Équivalent Tailwind :

<input class="h-[var(--h-control)] px-3 rounded-[var(--radius-sm)] border-0 shadow-[var(--hairline)] bg-[var(--bg)] text-[var(--fg)] text-sm font-regular outline-none transition-shadow duration-150 ease-out focus:shadow-[var(--shadow-focus)]" />

4.4 Carte

<div
 style={{
   padding: "var(--space-6)",
   borderRadius: "var(--radius-lg)",
   backgroundColor: "var(--bg)",
   boxShadow: "var(--shadow-card)",
 }}
>
  {children}
</div>

Équivalent Tailwind :

<div class="p-6 rounded-[var(--radius-lg)] bg-[var(--bg)] shadow-[var(--shadow-card)]">

4.5 Pilule d'état

<span
 style={{
   display: "inline-flex",
   alignItems: "center",
   height: "22px",
   paddingInline: "var(--space-2)",
   borderRadius: "var(--radius-full)",
   fontSize: "var(--text-xs)",
   fontWeight: "var(--weight-medium)",
   lineHeight: 1,
 }}
>
  {children}
</span>

Utiliser avec des couleurs sémantiques (par exemple color: var(--success); background-color: var(--success-soft)).


5. Système de mouvement

5.1 Principes [vu, déduit, expert]

  1. Le mouvement commence près de l'interaction. Les éléments se déploient depuis le point de contact/clic (par exemple, un menu qui s'étend à partir de son déclencheur).
  2. La durée est liée à la distance. Les éléments petits/proches (infobulles, menus) : 100-150 ms. Les surfaces qui apparaissent (panneaux, modales) : 200-350 ms. Les transitions de page : 500 ms. Des durées plus rapides rendent l'interface plus réactive.
  3. Ease-out pour l'entrée, ease-in-out pour le déplacement. Les éléments qui entrent utilisent var(--ease-out) ; ceux qui se déplacent utilisent var(--ease-in-out).
  4. Les micro-interactions sont immédiates. Les survols, les pressions et les changements d'état (cochage, expansion) s'animent en 100-150 ms [expert].
  5. Pas d'animation juste pour le plaisir. Chaque animation a un but : guider l'attention, confirmer une action, ou expliquer un changement.

5.2 Micro-interactions

Boutons : transition d'ombre et de fond de 150 ms ease-out au survol (comme montré dans les recettes).

Éléments de liste : surlignage de fond de 100 ms au survol.

Cases à cocher/boutons radio : 150 ms, avec un effet de zoom et de fondu sur l'icône de coche [expert].

Onglets : indicateur d'onglet actif animé avec ease-in-out sur 200 ms [déduit].

Accordéons : hauteur animée avec ease-in-out sur 250 ms [expert].

Toasts : entrée avec glissement depuis le haut/bas, 300 ms ease-out ; sortie avec fondu, 200 ms [déduit, vu : "Task completed · Undo" toast].

5.3 Transitions de page et de vue

Transitions de page : fondu + léger décalage vertical, 500 ms ease-out [expert].

Modales : superposition avec fondu (200 ms), contenu avec zoom et fondu (300 ms ease-out) [expert].

Feuilles / tiroirs : animation de type iOS avec var(--ease-drawer), 400 ms [vu : "Vaul pour les feuilles mobiles"].

Palette de commandes : superposition avec fondu (200 ms), contenu avec zoom et fondu (250 ms ease-out).

5.4 Animations décoratives (à utiliser avec parcimonie)

Squelettes de chargement : pulsation subtile (opacité 0.3 → 0.6 → 0.3) sur 1.5s, répétition infinie.

Barres de progression : largeur animée avec ease-in-out sur 500 ms (déterminé) / 300 ms (indéterminé).

Compteurs / tickers : transition de nombre animée (rotation/défilement) sur 300 ms ease-out [expert].

Illustrations : défilement parallaxe au scroll, animation au survol (par exemple, une icône 3D qui tourne), dégradés qui se déplacent lentement.


6. Accessibilité

  1. Rapports de contraste : tous les textes doivent avoir un rapport de contraste d'au moins 4.5:1 (AA) pour le texte normal, 3:1 pour le texte large (≥18px gras ou ≥24px normal). Les couleurs sémantiques ci-dessus (--success, --danger, etc.) répondent à cette exigence lorsqu'elles sont utilisées avec les teintes douces correspondantes.
  2. Cibles tactiles : au moins 44x44px pour les cibles tactiles [expert, Apple HIG, WCAG 2.1].
  3. Réduction de mouvement : utilisez @media (prefers-reduced-motion: reduce) pour désactiver la plupart des animations, en ne conservant que les transitions essentielles (comme le fondu de superposition).
  4. Focus clavier : utilisez var(--shadow-focus) pour les anneaux de focus. Assurez-vous que tous les éléments interactifs sont accessibles au clavier.
  5. Texte alternatif : toutes les icônes et illustrations doivent avoir un alt text ou aria-label approprié.

7. Exemples

7.1 Tableau de bord SaaS (React + Tailwind)

import { Card, Button, Input, Badge } from "@/components/ui"; // ou créez les vôtres avec les jetons

export default function Dashboard() {
  return (
    <div style={{ backgroundColor: "var(--bg-subtle)", minHeight: "100vh", padding: "var(--space-8)" }}>
      <div style={{ display: "flex", justifyContent: "space-between", marginBottom: "var(--space-6)" }}>
        <h1 style={{ fontSize: "var(--text-xl)", fontWeight: "var(--weight-semibold)", color: "var(--fg)" }}>
          Tableau de bord
        </h1>
        <Button>Nouveau projet</Button>
      </div>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: "var(--space-6)" }}>
        <Card>
          <p style={{ fontSize: "var(--text-sm)", color: "var(--fg-secondary)", marginBottom: "var(--space-1)" }}>
            Revenu total
          </p>
          <p style={{ fontSize: "var(--text-2xl)", fontWeight: "var(--weight-semibold)", color: "var(--fg)" }}>
            $45,200
          </p>
          <Badge style={{ color: "var(--success)", backgroundColor: "var(--success-soft)" }}>▲ +14.7%</Badge>
        </Card>
        <Card>
          <p style={{ fontSize: "var(--text-sm)", color: "var(--fg-secondary)", marginBottom: "var(--space-1)" }}>
            Utilisateurs actifs
          </p>
          <p style={{ fontSize: "var(--text-2xl)", fontWeight: "var(--weight-semibold)", color: "var(--fg)" }}>
            2,847
          </p>
          <Badge style={{ color: "var(--success)", backgroundColor: "var(--success-soft)" }}>▲ +8.3%</Badge>
        </Card>
        <Card>
          <p style={{ fontSize: "var(--text-sm)", color: "var(--fg-secondary)", marginBottom: "var(--space-1)" }}>
            Tâches en cours
          </p>
          <p style={{ fontSize: "var(--text-2xl)", fontWeight: "var(--weight-semibold)", color: "var(--fg)" }}>
            12
          </p>
          <Badge style={{ color: "var(--warning)", backgroundColor: "var(--warning-soft)" }}>▼ +2 this week</Badge>
        </Card>
      </div>
    </div>
  );
}

7.2 Page d'authentification (React + Tailwind)

export default function SignupPage() {
  return (
    <div style={{ display: "flex", minHeight: "100vh", backgroundColor: "var(--bg)" }}>
      {/* Formulaire */}
      <div style={{ flex: 1, display: "flex", flexDirection: "column", justifyContent: "center", padding: "var(--space-16)" }}>
        <div style={{ width: "100%", maxWidth: "400px" }}>
          <div style={{ marginBottom: "var(--space-8)" }}>
            <div style={{ width: "48px", height: "48px", borderRadius: "var(--radius-full)", backgroundColor: "var(--accent-soft)", display: "flex", alignItems: "center", justifyContent: "center", marginBottom: "var(--space-4)" }}>
              <span style={{ color: "var(--accent)", fontWeight: "var(--weight-semibold)", fontSize: "var(--text-lg)" }}>G</span>
            </div>
            <h1 style={{ fontSize: "var(--text-xl)", fontWeight: "var(--weight-semibold)", color: "var(--fg)", marginBottom: "var(--space-2)" }}>
              Créez votre compte
            </h1>
            <p style={{ fontSize: "var(--text-sm)", color: "var(--fg-secondary)" }}>
              Commencez avec un essai gratuit de 14 jours.
            </p>
          </div>
          <div style={{ display: "flex", flexDirection: "column", gap: "var(--space-4)" }}>
            <Input placeholder="[email protected]" />
            <Input type="password" placeholder="Mot de passe" />
            <Button>Créer un compte</Button>
          </div>
          <p style={{ fontSize: "var(--text-xs)", color: "var(--fg-tertiary)", marginTop: "var(--space-4)", textAlign: "center" }}>
            En vous inscrivant, vous acceptez nos conditions d'utilisation.
          </p>
        </div>
      </div>
      {/* Aperçu */}
      <div style={{ flex: 1, backgroundColor: "var(--bg-subtle)", display: "flex", alignItems: "center", justifyContent: "center" }}>
        <div style={{ width: "360px", height: "640px", borderRadius: "var(--radius-2xl)", backgroundColor: "var(--bg)", boxShadow: "var(--shadow-modal)", padding: "var(--space-6)" }}>
          <p style={{ fontSize: "var(--text-md)", fontWeight: "var(--weight-medium)", color: "var(--fg)", marginBottom: "var(--space-4)" }}>
            Votre tableau de bord
          </p>
          {/* Contenu factice */}
          <div style={{ display: "flex", flexDirection: "column", gap: "var(--space-4)" }}>
            {[1, 2, 3].map((i) => (
              <div key={i} style={{ height: "40px", borderRadius: "var(--radius-md)", backgroundColor: "var(--bg-muted)" }} />
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}

8. Intégrations de plateformes

Cette compétence fonctionne avec n'importe quel modèle de codage et n'importe quelle stack. Elle a été testée avec :

  • Claude Code (Anthropic)
  • Cursor (éditeur IA)
  • GitHub Copilot (Chat et complétion)
  • Codex (OpenAI)
  • Tout autre assistant IA capable de générer du code

Les exemples sont donnés en React + Tailwind + Motion (motion/react), mais les jetons de conception et les principes sont indépendants de la stack. Utilisez les variables CSS directement, ou mappez-les sur votre système de conception (Styled Components, Emotion, CSS Modules, etc.).


9. Checklist d'assurance qualité (les 10% finaux)

Avant de finaliser une interface, vérifiez chaque point :

  • Typographie : pas plus de 2 graisses utilisées dans l'interface. Les tailles et le crénage correspondent-ils au tableau de la section 2.1 ?
  • Couleur : une seule couleur d'accent est-elle utilisée ? Les couleurs sémantiques sont-elles appliquées correctement (texte foncé sur teinte douce) ?
  • Ombres : les bordures sont-elles remplacées par des ombres (lignes fines) dans la mesure du possible ? Les surfaces flottantes ont-elles l'ombre appropriée (--shadow-pop ou --shadow-modal) ?
  • Espacement : l'espacement suit-il la grille de 4px ? Y a-t-il suffisamment d'air autour du contenu ?
  • Mouvement : chaque animation a-t-elle un but ? Les durées sont-elles comprises entre 100 et 500 ms selon le contexte ?
  • Accessibilité : les contrastes de texte sont-ils suffisants ? Les cibles tactiles font-elles au moins 44x44px ? prefers-reduced-motion est-il respecté ?
  • Mode sombre : toutes les couleurs sont-elles adaptées au mode sombre ? Les surfaces sombres montent-elles par incréments de luminosité ?
  • Détails : les étiquettes des sections sont-elles en majuscules ou en petites capitales grises ? Les nombres sont-ils alignés à droite avec des chiffres tabulaires ?
  • Le dernier 10% : l'interface a-t-elle été examinée manuellement pour les détails ? Les transitions sont-elles fluides ?

Cette compétence est une traduction et une implémentation de l'esthétique de conception observée de @marcelkargul. Tous les crédits pour le langage visuel vont à son travail.

Skills associés