veza/apps/web/docs/AUDIT_UI_UX_VISUEL_COMPLET.md
senke e82560c547 docs: add UI/UX audit reports and design system documentation
- 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>
2026-02-08 22:49:40 +01:00

17 KiB
Raw Blame History

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 lanalyse des assets dans visual-tests/baselines/. Les baselines actuelles (dashboard, library, header) décrivent des écrans de login lorsque lapp est capturée sans session ; pour une observation directe du shell complet, ouvrir Storybook sur App/Layouts/DashboardLayoutDashboard full layout (port 6006).


1. Résumé exécutif (1015 lignes)

Linterface Veza se situe aujourdhui 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/DashboardLayoutDefault (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 lapp avec auth).
  • Baselines actuelles (visual-tests/baselines/) : les captures dashboard-desktop-dark.png, header-desktop-dark.png, library-desktop-dark.png décrivent dans lanalyse des images des écrans de login (Welcome Back, Sign in, boutons sociaux). Cela indique soit une redirection login quand lauth nest pas disponible pendant la capture, soit un nommage à clarifier. Pour un audit shell complet, sappuyer 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 dentré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 lutilisateur nest pas authentifié, le shell nest pas visible — doù limportance des stories full layout pour la régression visuelle.

2.3 Rythme visuel & spacing

  • Dashboard : space-y-6 page, gap-4 grille stats, gap-6 grille activité. Cartes en Card variant="glass" avec transition-all duration-[var(--duration-normal)]. Padding contenu p-6 pb-24.
  • Sidebar : space-y-6 entre sections, space-y-0.5 entre items, px-3 py-2 items, px-4 py-4 header sidebar.
  • Tokens : --layout-gap, --layout-gap-sm, --layout-gap-lg documenté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] ou p-[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-titres text-sm / text-xs text-muted-foreground.
  • Sidebar : sections en text-xs font-medium uppercase tracking-wider, items text-sm font-medium.
  • Player : titre piste text-sm md:text-base font-display font-bold, artiste text-xs text-muted-foreground.
  • Reste de text-[10px] : listé dans UI_UX_AUDIT_DISCORD_SPOTIFY_QUALITY.md (Navbar, Badge, Admin, MetadataForm, etc.) — à migrer vers text-xs sauf exceptions documentées (ex. avatar xs).
  • Contraste principal / secondaire : text-foreground vs text-muted-foreground utilisé ; à vérifier ratio AA sur muted-foreground (audit a11y recommandé).

2.5 Couleurs, contrastes, surfaces

  • Fonds : bg-background, sidebar bg-[var(--sidebar)], header bg-transparent backdrop-blur-md, cartes variant="glass", player bg-black/80 border border-white/10.
  • Hover / focus : hover:bg-sidebar-accent, hover:bg-white/5, focus-visible:ring-2 focus-visible:ring-primary/50 sur Sidebar et Header. Cartes hover:border-primary/50.
  • Impression : lUI “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 “Dont have an account? Sign up” signalé en contraste faible dans les descriptions dimages → à 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-normal sur Header, Sidebar, cartes, player. Animation dentrée player (slide-in-from-bottom-4, fade-in). prefers-reduced-motion: reduce désactive transition-shell et player-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)

  1. 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.
  2. 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.
  3. Transitions et durées : variables --duration-fast, --duration-normal, --duration-slow, --ease-out, --ease-in-out utilisées dans le shell et les composants critiques ; pas de duration-200 en dur.
  4. Ombres sémantiques : .shadow-card, .shadow-modal, .shadow-tooltip, .shadow-player-thumb, .shadow-queue-item-current, etc. — cohérence et maintenabilité.
  5. Sidebar : structure claire (sections, labels, indicateur actif), focus-visible et hover cohérents, transition expand/collapse fluide.
  6. GlobalPlayer : positionnement aligné sur la sidebar (lg:left-main-*), entrée animée, barre de progression toujours visible, reduced-motion respecté.
  7. Stories full layout : DashboardLayout avec Dashboard, Playlists, Library, Settings, Profile — référence visuelle et base pour tests de régression.
  8. Skeletons : présents sur de nombreuses vues (Library, Playlist, Track, Chat, Settings, Profile) pour états Loading.
  9. 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)

  1. Captures visuelles shell : les baselines “dashboard”, “library”, “header” peuvent montrer lécran de login si lapp est capturée sans session. Le shell complet (sidebar + header + main + player) nest pas garanti dans la régression actuelle. Impact : régressions layout shell non détectées.
  2. Valeurs arbitraires restantes : modales (max-h-[85vh], etc.), quelques vues (LiveStreamDetailView, APIPlaygroundView, etc.), typo text-[10px] dans plusieurs fichiers. Impact : incohérence et maintenance difficile.
  3. Scrollbar et effets globaux : définitions dans index.css, global-effects.css et fixDisplayIssues.ts — risque dincohérence selon lordre de chargement. Impact : expérience variable, sentiment “bricolé”.
  4. Contraste secondaire : texte “Dont have an account? Sign up” et similaires (muted-foreground) signalés comme faible contraste dans les analyses dimages. Impact : accessibilité et lisibilité en dessous du niveau AA sur certains textes secondaires.
  5. 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 derreur ou liste vide.
  6. Focus-visible : pas sur tous les contrôles (Select, certaines listes, certaines cards). Impact : navigation clavier et a11y incomplètes.
  7. 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 daction 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 lusage 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 danimations décoratives sans les désactiver en reduced-motion.

7. Verdict honnête

Aujourdhui, cette UI est à environ 7075 % dune 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 23 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.