- AUDIT_UI_UX_VISUEL_COMPLET.md: comprehensive visual audit with structured analysis (shell, rhythm, typography, colors, components, motion) and Top 10 improvement roadmap - UI_UX_AUDIT_DISCORD_SPOTIFY_QUALITY.md: detailed gap analysis vs Discord/Spotify with phased action plan - A11Y_AUDIT.md: accessibility audit baseline - EMPTY_ERROR_PATTERNS.md: unified empty/error state pattern guide - codemod-typography-arbitrary.mjs: migration script for text-[10px] Co-authored-by: Cursor <cursoragent@cursor.com>
17 KiB
Audit UI/UX visuel complet — Qualité Discord/Spotify-like
Date : 8 février 2025
Rôle : Lead Frontend Engineer + Design Systems Architect + UX Reviewer
Référents : Discord (densité, sidebar, clarté), Spotify (rythme, listes, player), Linear, Notion
Source de vérité visuelle : Storybook (full layout), baselines visual-tests/, code shell et tokens.
Méthodologie : Analyse fondée sur le code du shell (DashboardLayout, Sidebar, Header, GlobalPlayer), les tokens (index.css, DESIGN_TOKENS.md, APP_SHELL.md), les rapports existants (UI_UX_AUDIT_DISCORD_SPOTIFY_QUALITY.md, VISUAL_AUDIT_REPORT.md) et l’analyse des assets dans visual-tests/baselines/. Les baselines actuelles (dashboard, library, header) décrivent des écrans de login lorsque l’app est capturée sans session ; pour une observation directe du shell complet, ouvrir Storybook sur App/Layouts/DashboardLayout → Dashboard – full layout (port 6006).
1. Résumé exécutif (10–15 lignes)
L’interface Veza se situe aujourd’hui entre produit soigné et produit premium. Le shell (sidebar, header, main, player) est structuré et tokenisé : largeurs, marges, z-index et transitions sont centralisés dans index.css et APP_SHELL.md. La hiérarchie typographique et le rythme des pages principales (Dashboard, cartes, listes) sont maîtrisés sur les vues authentifiées. Les écarts qui empêchent le niveau Discord/Spotify sont : (1) baselines visuelles qui reflètent souvent l’état login (redirection non authentifiée), donc peu de captures du shell complet ; (2) valeurs arbitraires restantes (modales, quelques vues) et typo (text-[10px]) ; (3) scrollbar et effets globaux définis à plusieurs endroits ; (4) patterns Error/Empty et focus-visible pas encore systématiques. Impression utilisateur : application moderne, dark theme cohérent, player et sidebar soignés ; la dernière couche de polish (micro-interactions, contraste secondaire, un seul système de scrollbar) manque pour atteindre le niveau “premium”.
2. Constats visuels majeurs (avec références)
2.1 Source des observations
- Storybook : stories
App/Layouts/DashboardLayout— Default (shell + placeholder), Dashboard – full layout, Playlists – full layout, Library – full layout, Settings, Profile. Viewport desktop, MSW actif. Recommandation : considérer Storybook comme source de vérité pour le shell et lancer les captures Playwright sur ces stories (pas seulement sur l’app avec auth). - Baselines actuelles (
visual-tests/baselines/) : les capturesdashboard-desktop-dark.png,header-desktop-dark.png,library-desktop-dark.pngdécrivent dans l’analyse des images des écrans de login (Welcome Back, Sign in, boutons sociaux). Cela indique soit une redirection login quand l’auth n’est pas disponible pendant la capture, soit un nommage à clarifier. Pour un audit shell complet, s’appuyer sur les stories full layout Storybook. - Code :
DashboardLayout.tsx,Sidebar.tsx,Header.tsx,GlobalPlayer.tsx,index.css(tokens shell),DESIGN_TOKENS.md,APP_SHELL.md.
2.2 Shell & structure globale
| Élément | Constat visuel / code | Niveau |
|---|---|---|
| Sidebar | Largeur tokenisée : 15rem (expanded), 5rem (collapsed). Classes w-sidebar-expanded, w-sidebar-collapsed, transition-shell. Sections (My Studio, Veza Network, Commerce, Library, System), labels en text-xs uppercase, items px-3 py-2 rounded-lg, indicateur actif sidebar-active-indicator. Densité proche Discord (liste de canaux). |
Correct à premium |
| Header | h-header (4rem), backdrop-blur-md, position left-header-expanded / left-header-collapsed selon sidebar. Recherche type Spotify (rounded-full, placeholder “What do you want to play?”). Badge “Online”, notifications, theme toggle, user menu. Rapport avec le main : pt-main dégage le header. |
Correct |
| Player | Barre flottante bottom-6, lg:left-main-expanded / lg:left-main-collapsed, rounded-2xl, backdrop-blur-2xl, barre de progression en haut, h-20 md:h-24. Animation d’entrée slide-in-from-bottom-4 fade-in duration-500, player-bar-entrance avec prefers-reduced-motion respecté. Poids visuel fort mais contenu principal reste prioritaire. |
Robuste |
| Alignement global | Main : pt-main, pb-main, px-4 md:px-8, max-w-layout-content mx-auto. Marges gauche lg:ml-main-expanded / lg:ml-main-collapsed. Grille cohérente. |
Correct |
Conclusion shell : niveau actuel correct à premium. Structure claire, tokens respectés, transitions fluides. La seule réserve : sur les captures “app” (non-Storybook), si l’utilisateur n’est pas authentifié, le shell n’est pas visible — d’où l’importance des stories full layout pour la régression visuelle.
2.3 Rythme visuel & spacing
- Dashboard :
space-y-6page,gap-4grille stats,gap-6grille activité. Cartes enCard variant="glass"avectransition-all duration-[var(--duration-normal)]. Padding contenup-6 pb-24. - Sidebar :
space-y-6entre sections,space-y-0.5entre items,px-3 py-2items,px-4 py-4header sidebar. - Tokens :
--layout-gap,--layout-gap-sm,--layout-gap-lgdocumentés. Échelle Tailwind utilisée (gap-2, gap-3, gap-4, p-3, p-4, etc.). - Où le rythme est maîtrisé : grilles Dashboard, espacement sidebar, padding main, espacement entre cartes.
- Où il peut casser la lecture : rapports arbitraires signalent encore des
gap-[Xpx]oup-[Xpx]dans certains composants (modales, vues métier) ; à migrer vers l’échelle ou tokens pour un rythme 100 % cohérent type Discord/Spotify.
2.4 Hiérarchie typographique
- Titres :
text-3xl font-display font-bold(Dashboard welcome),text-2xl font-bold(valeurs stats), sous-titrestext-sm/text-xs text-muted-foreground. - Sidebar : sections en
text-xs font-medium uppercase tracking-wider, itemstext-sm font-medium. - Player : titre piste
text-sm md:text-base font-display font-bold, artistetext-xs text-muted-foreground. - Reste de
text-[10px]: listé dansUI_UX_AUDIT_DISCORD_SPOTIFY_QUALITY.md(Navbar, Badge, Admin, MetadataForm, etc.) — à migrer verstext-xssauf exceptions documentées (ex. avatar xs). - Contraste principal / secondaire :
text-foregroundvstext-muted-foregroundutilisé ; à vérifier ratio AA surmuted-foreground(audit a11y recommandé).
2.5 Couleurs, contrastes, surfaces
- Fonds :
bg-background, sidebarbg-[var(--sidebar)], headerbg-transparent backdrop-blur-md, cartesvariant="glass", playerbg-black/80 border border-white/10. - Hover / focus :
hover:bg-sidebar-accent,hover:bg-white/5,focus-visible:ring-2 focus-visible:ring-primary/50sur Sidebar et Header. Carteshover:border-primary/50. - Impression : l’UI “respire” grâce au dark theme, aux espacements et au blur ; pas d’écrasement visuel. Profondeur par bordures légères et ombres sémantiques (shadow-card, shadow-player-hover).
2.6 Composants (qualité perçue)
| Composant | Classe | Commentaire |
|---|---|---|
| Sidebar (nav items, sections) | Robuste | États actif/hover/focus cohérents, transitions tokenisées. |
| Header (search, menu user) | Correct | Recherche lisible, menu dropdown ; focus-visible présent. |
| GlobalPlayer (barre, controls) | Robuste | Entrée animée, barre de progression, hover sur barre. |
| Cartes Dashboard (stats, activité) | Correct | Glass, hover border, pas de surcharge. |
| Boutons (primaire, ghost) | Correct | Focus ring, transitions. |
| Inputs (login/register vus en baselines) | Correct | Rounded-xl, contraste OK ; lien “Don’t have an account? Sign up” signalé en contraste faible dans les descriptions d’images → à renforcer. |
| Modales (max-h) | Fragile | Plusieurs max-h-[85vh] / max-h-[80vh] encore en dur → migrer vers tokens .max-h-layout-modal*. |
2.7 Micro-interactions & motion
- Présent :
transition-shell(sidebar),duration-[var(--duration-fast)]/--duration-normalsur Header, Sidebar, cartes, player. Animation d’entrée player (slide-in-from-bottom-4,fade-in).prefers-reduced-motion: reducedésactivetransition-shelletplayer-bar-entrance. - Où une animation apporte du sens : déjà en place sur le player (entrée, hover barre). À étendre : feedback hover/focus uniforme sur toutes les listes et cards cliquables ; loading states sur boutons (spinner) pour les actions async.
3. Points forts (à préserver absolument)
- Shell tokenisé : une seule source (
index.css) pour sidebar, header, main, player (largeurs, marges, offsets, z-index). Classes utilitaires.pt-main,.pb-main,.ml-main-expanded,.transition-shell, etc. - Layout primitives :
max-w-layout-content,min-h-layout-main,min-h-layout-page, tokens modales/lyrics documentés dans DESIGN_TOKENS.md et APP_SHELL.md. - Transitions et durées : variables
--duration-fast,--duration-normal,--duration-slow,--ease-out,--ease-in-oututilisées dans le shell et les composants critiques ; pas deduration-200en dur. - Ombres sémantiques :
.shadow-card,.shadow-modal,.shadow-tooltip,.shadow-player-thumb,.shadow-queue-item-current, etc. — cohérence et maintenabilité. - Sidebar : structure claire (sections, labels, indicateur actif), focus-visible et hover cohérents, transition expand/collapse fluide.
- GlobalPlayer : positionnement aligné sur la sidebar (lg:left-main-*), entrée animée, barre de progression toujours visible, reduced-motion respecté.
- Stories full layout : DashboardLayout avec Dashboard, Playlists, Library, Settings, Profile — référence visuelle et base pour tests de régression.
- Skeletons : présents sur de nombreuses vues (Library, Playlist, Track, Chat, Settings, Profile) pour états Loading.
- Règles et outillage : ESLint no-restricted-syntax sur valeurs arbitraires, script
report-arbitrary-values.mjs, procédure visual-tests documentée.
4. Points faibles critiques (ce qui empêche le niveau premium)
- Captures visuelles shell : les baselines “dashboard”, “library”, “header” peuvent montrer l’écran de login si l’app est capturée sans session. Le shell complet (sidebar + header + main + player) n’est pas garanti dans la régression actuelle. Impact : régressions layout shell non détectées.
- Valeurs arbitraires restantes : modales (
max-h-[85vh], etc.), quelques vues (LiveStreamDetailView, APIPlaygroundView, etc.), typotext-[10px]dans plusieurs fichiers. Impact : incohérence et maintenance difficile. - Scrollbar et effets globaux : définitions dans
index.css,global-effects.cssetfixDisplayIssues.ts— risque d’incohérence selon l’ordre de chargement. Impact : expérience variable, sentiment “bricolé”. - Contraste secondaire : texte “Don’t have an account? Sign up” et similaires (muted-foreground) signalés comme faible contraste dans les analyses d’images. Impact : accessibilité et lisibilité en dessous du niveau AA sur certains textes secondaires.
- Patterns Error / Empty : pas unifiés (toast vs bannière vs bloc inline ; messages et CTA empty hétérogènes). Impact : expérience incohérente en cas d’erreur ou liste vide.
- Focus-visible : pas sur tous les contrôles (Select, certaines listes, certaines cards). Impact : navigation clavier et a11y incomplètes.
- Réduction de mouvement : partielle (effets décoratifs) ; pas étendue à toutes les transitions du shell/player dans un seul bloc
prefers-reduced-motion. Impact : utilisateurs sensibles au motion pas toujours respectés.
5. Top 10 des améliorations à plus fort impact
| # | Amélioration | Impact visuel | Risque | Effort |
|---|---|---|---|---|
| 1 | Capturer le shell en Storybook : ajouter des tests Playwright qui ouvrent les stories DashboardLayout (Default, DashboardFullLayout) et capturent sidebar + header + main + player. Mettre à jour la doc visual-tests. | Élevé (régression shell détectée) | Faible | M |
| 2 | Unifier la scrollbar : une seule source (index.css ou global-effects) avec variables CSS ; retirer ou cantonner les injections dans fixDisplayIssues. | Élevé (cohérence perçue) | Moyen | S |
| 3 | Tokens modales : utiliser .max-h-layout-modal, .max-h-layout-modal-sm, etc. partout ; supprimer les max-h-[XXvh] dans les modales. |
Moyen (design system) | Faible | M |
| 4 | Contraste muted-foreground : mesurer et ajuster --muted-foreground (dark) pour ratio ≥ 4.5:1 ; corriger les liens secondaires (ex. “Sign up”). |
Élevé (lisibilité, a11y) | Faible | S |
| 5 | Pattern Error unifié : composant ou pattern (page vs liste vs formulaire) + usage systématique. | Moyen (cohérence) | Faible | M |
| 6 | Pattern Empty unifié : structure commune (titre, description, CTA) + style cohérent pour librairie vide, playlist vide, queue vide, recherche sans résultat. | Moyen (cohérence) | Faible | M |
| 7 | Focus-visible sur tous les contrôles : audit des éléments focusables (Select, listes, cards cliquables) et ajout du ring cohérent. | Élevé (a11y, clavier) | Faible | M |
| 8 | Migration text-[10px] → text-xs : avec exceptions documentées (avatar xs, etc.). | Moyen (typo cohérente) | Faible | S |
| 9 | Réduction de mouvement complète : étendre @media (prefers-reduced-motion: reduce) à toutes les transitions du shell et du player (sidebar, header, player bar). |
Moyen (a11y) | Faible | S |
| 10 | Micro-interactions : hover/focus explicites sur list items et cards cliquables ; loading spinner sur boutons d’action async. | Moyen (polish) | Faible | M |
6. Recommandations structurantes
6.1 Design system
- Consolider une seule définition des effets globaux (scrollbar, noise) et la documenter dans DESIGN_TOKENS.md.
- Documenter les exceptions typo (avatar xs, etc.) et les tokens modales/lyrics déjà en place.
- Ajouter un court guide “Empty state” et “Error handling” dans
docs/et les lier depuis DESIGN_TOKENS ou STORYBOOK_CONTRACT.
6.2 Layout
- Continuer à utiliser uniquement les classes shell tokenisées (
pt-main,pb-main,lg:ml-main-*,left-header-*,lg:left-main-*) ; pas de marges/padding en dur pour le shell. - Valider les breakpoints 320, 768, 1024, 1280 sur les stories full layout (grilles, listes, sidebar overlay).
6.3 Composants
- Classe chaque nouveau composant “feature” avec états Loading (skeleton), Error, Empty dans les stories (référence STORYBOOK_CONTRACT.md).
- Étendre l’usage des ombres sémantiques (shadow-card, shadow-modal) et éviter les
shadow-[...]arbitraires. - Boutons : feedback loading (spinner ou disabled) sur toutes les actions async.
6.4 Motion
- Utiliser uniquement les variables
--duration-*et--ease-*pour les transitions. - Centraliser la logique
prefers-reduced-motion: reduce(déjà partiellement en place) pour shell et player ; ne pas ajouter d’animations décoratives sans les désactiver en reduced-motion.
7. Verdict honnête
Aujourd’hui, cette UI est à environ 70–75 % d’une qualité Discord/Spotify-like.
- Shell et structure : 85 % — très proche (tokens, alignements, player).
- Rythme et spacing : 75 % — bon sur les pages principales ; reste des arbitraires et quelques incohérences.
- Typographie : 70 % — hiérarchie claire ; reste des
text-[10px]et contraste secondaire à renforcer. - Couleurs et surfaces : 80 % — thème cohérent, ombres sémantiques.
- Composants : 70 % — sidebar et player robustes ; modales et patterns Error/Empty à unifier.
- Motion : 75 % — transitions tokenisées et reduced-motion partiel ; micro-interactions à étendre.
Les 2–3 prochaines semaines ciblant : (1) captures shell Storybook + unification scrollbar, (2) tokens modales + contraste muted-foreground, (3) patterns Error/Empty et focus-visible, feront franchir le cap “produit premium” de façon visible et durable.
8. Références
docs/DESIGN_TOKENS.md— tokens layout, typo, ombres, transitions.docs/APP_SHELL.md— shell, variables CSS, classes utilitaires, responsive.docs/UI_UX_AUDIT_DISCORD_SPOTIFY_QUALITY.md— lacunes détaillées, phases A/B/C.visual-tests/README.md— procédure capture/compare/update.src/components/layout/DashboardLayout.stories.tsx— stories full layout.src/index.css— tokens shell,.transition-shell,.pt-main,.pb-main, etc.