veza/apps/web/visual-tests/PHASE2_COMPARATIVE_REPORT.md
senke 39b2b642d2 feat(web): UI premium Discord/Spotify-like — tokens, shadows, focus, layout
Plan UI premium 6–8 semaines (design system, shell, Storybook, a11y):

- Design system: DESIGN_TOKENS.md, APP_SHELL.md, FULL_LAYOUT_PAGE.md. Single source
  for layout/shell (index.css), shadows (design-system.css), durations/easing.
- Tokens: shadow-cover-depth, shadow-gold-glow, shadow-fab-glow; layout max-height
  (max-h-layout-drawer, max-h-layout-panel, max-h-layout-list). All duration-200/300/500
  replaced by --duration-fast/normal/slow. Arbitrary shadows replaced by token classes.
- Shell & player: Sidebar, Header, GlobalPlayer, MiniPlayer, PlayerQueue, PlayerControls,
  AudioPlayer use tokens; focus-visible on Sidebar, PlayerQueue, DropdownMenuTrigger/Item,
  TabsTrigger. Typography: text-[10px]/[9px] → text-xs where applicable.
- ESLint: no-restricted-syntax (warn) for w-/h-/rounded-/shadow-/text-/spacing arbitrary.
- Scripts: report-arbitrary-values.mjs, capture/compare/generate visual; visual-complete.spec.ts.
- Stories full layout: Dashboard, Playlists, Library, Settings, Profile in DashboardLayout.stories.
- .cursorrules + README: DESIGN_TOKENS, APP_SHELL, visual commands, no arbitrary without justification.
- apps/web/.gitignore: e2e test artifacts (test-results-visual, playwright-report-visual).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 17:15:58 +01:00

285 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Phase 2 — Analyse comparative visuelle (Discord × Spotify)
**Contexte** : Baselines Veza en conditions contrôlées (1280×720, dark, reduced motion).
**Métriques Veza** : déduites du code (composants, `index.css`, Tailwind).
**Métriques Discord/Spotify** : reverse-engineering communautaire et documentation publique ; lorsquaucune valeur px nest disponible, la méthode de mesure sur capture de référence est indiquée.
**Aucune modification de code ou de tokens** : phase analytique uniquement.
---
## 1. Référents par écran
| Écran Veza | Fichier baseline | Équivalent Discord | Équivalent Spotify |
|------------|------------------|--------------------|---------------------|
| Login | `login-desktop.png` | N/A (Discord desktop = app native) | Login web (desktop) |
| Register | `register-desktop.png` | N/A | Inscription web |
| Dashboard | `dashboard-desktop.png` | Vue principale (canal actif + liste messages) | Home / Search (zone centrale) |
| Sidebar | `sidebar-desktop.png` | Liste serveurs + liste canaux (channel list) | Left nav (Home, Search, Library) |
| Playlists (liste) | `playlists-desktop.png` | Liste canaux (texte) / liste DMs | Liste playlists / liste titres |
| Library | `library-desktop.png` | — | Your Library (grille/liste) |
| 404 | `404-desktop.png` | Page erreur / lien mort | Page non trouvée |
---
## 2. Analyse par écran
### 2.1 Login (`login-desktop.png`)
**Référent** : Spotify login (desktop web) — formulaire centré, fond sombre, un seul CTA.
#### Métriques déduites du code (Veza)
- **Typographie** : Titre de page (non présent dans LoginForm ; dépend du layout) ; labels/inputs via `FloatingInput` ; bouton `text-sm font-medium` (14px), CTA avec `font-bold tracking-wide` (button primary). Pas de titre explicite dans le formulaire dans le snippet — à confirmer sur baseline.
- **Spacing** : `space-y-8` entre blocs (32px), `space-y-4` dans le groupe champs (16px). Champs espacés 16px verticalement.
- **Conteneur** : Formulaire `w-full` ; conteneur centré dépend du layout parent (AuthLayout).
- **Bouton** : `h-10` (40px), `rounded-full`, `rounded-xl` sur le CTA login (override dans le form).
#### Comparaison Spotify login (pratiques courantes)
- **Typographie** : Titre principal lisible (souvent 2428px), sous-texte plus petit (1416px). Ratio titre/corps marqué.
- **Spacing** : Espacement vertical généreux entre champs (2024px) ; padding du conteneur 3240px.
- **Densité** : Une seule colonne, peu déléments ; pas de surcharge.
#### Diagnostic
| Critère | Veza (code) | Spotify (référence) | Écart |
|---------|-------------|----------------------|--------|
| Espacement vertical entre champs | 16px (space-y-4) | 2024px typique | Veza plus serré ; risque de sensation "compact" |
| Espacement entre sections | 32px (space-y-8) | Souvent 3240px | Proche |
| Hauteur bouton principal | 40px (h-10) | ~4048px | Proche |
| Radius bouton | full / xl | Souvent 2428px (pill) | Cohérent |
**Verdict** : Densité **légèrement sur-dense** par rapport à un login type Spotify (espacement entre champs). Hiérarchie à vérifier sur capture : titre de page vs labels vs lien "Forgot password" (taille, contraste).
**Écarts précis** :
- Lespacement vertical entre champs (16px) est inférieur aux ~2024px courants sur login Spotify, ce qui réduit la respiration du formulaire.
- Si le titre de page est absent ou en petit, la hiérarchie "titre > sous-titre > champs > CTA" est faible.
---
### 2.2 Register (`register-desktop.png`)
Même référent que login (formulaire dinscription web).
#### Métriques Veza (code)
- Même système que login : `space-y-8` / `space-y-4`, boutons et inputs partagés.
- Formulaire plus long (plus de champs) → plus de scroll.
#### Diagnostic
- **Densité** : Identique au login ; si le nombre de champs est élevé, 16px entre champs peut donner une liste étouffée.
- **Hiérarchie** : Sections (étapes ou blocs) doivent se distinguer par un espacement ou un titre ; à vérifier sur baseline.
**Verdict** : Même problème potentiel que login (spacing entre champs). Risque **moyen** si beaucoup de champs sans séparation visuelle.
---
### 2.3 Dashboard (`dashboard-desktop.png`)
**Référents** : Discord = zone canal + liste messages ; Spotify = Home (cartes, sections).
#### Métriques déduites du code (Veza)
- **Conteneur** : `space-y-6 p-6 pb-24` → 24px entre sections, 24px padding, 96px en bas (player).
- **Titre** : `text-3xl font-display font-bold` (30px) + sous-texte `text-muted-foreground` (p = leading-relaxed).
- **Grille cartes** : `grid gap-4 md:grid-cols-2 lg:grid-cols-4` → 16px entre cartes, 4 colonnes en large.
- **Cartes** : Card + CardHeader/CardContent ; pas de padding explicite dans le snippet — dépend de `card.tsx`.
#### Comparaison Discord (zone principale)
- **Densité** : Élevée ; messages serrés (padding vertical ~48px par message), scroll long.
- **Hiérarchie** : Nom dutilisateur / heure en petit ; contenu en corps ; contraste typographique fort.
#### Comparaison Spotify Home
- **Densité** : Moyenne ; sections avec titres (ex. 24px), cartes horizontales scrollables, espacement vertical entre sections ~2432px.
- **Rythme** : Répétition section titre + carrousel ; padding latéral marqué.
#### Diagnostic
| Critère | Veza (code) | Discord | Spotify Home |
|---------|-------------|---------|--------------|
| Padding zone principale | 24px (p-6) | ~16px | ~2432px |
| Espacement entre sections | 24px (space-y-6) | — | 2432px |
| Espacement entre cartes | 16px (gap-4) | — | 1624px |
| Titre page | 30px (text-3xl) | — | 2428px section |
**Verdict** : **Ni sous-dense ni sur-dense** pour un dashboard type "command center". Hiérarchie à valider sur capture : le titre avec gradient (Welcome back, {name}) doit dominer ; les cartes stats ne doivent pas rivaliser en poids visuel (couleurs, ombres).
**Écarts précis** :
- Les stats utilisent des couleurs vives (cyan, lime, destructive, magenta) et des ombres (drop-shadow) : risque de **concurrence visuelle** avec le titre et entre cartes.
- `space-y-6` (24px) entre blocs est cohérent avec Spotify ; à confirmer que le premier bloc (titre + sous-titre) est bien séparé du bloc cartes.
---
### 2.4 Sidebar (`sidebar-desktop.png`)
**Référents** : Discord = liste serveurs (icônes) + liste canaux (texte) ; Spotify = left nav (icônes + labels).
#### Métriques déduites du code (Veza)
- **Dimensions** : Ouverte `w-64` (256px), fermée `lg:w-20` (80px). Position `left-6 bottom-6 top-20` → 24px gauche/bas, 80px haut (sous header).
- **Header** : `px-4 py-4` (16px), `gap-3` (12px). Logo 32×32px. Titre `text-sm font-semibold`, sous-texte `text-xs text-muted-foreground`.
- **Sections** : `space-y-6` (24px entre groupes), `px-3 py-2` (12px/8px), labels `text-xs font-medium uppercase tracking-wider mb-2 px-3`.
- **Items** : `px-3 py-2` (12px/8px), `space-y-0.5` (2px entre items), `text-sm font-medium`. Hauteur approximative par item : 8+8+line-height(14px) ≈ 3640px.
- **Radius** : `rounded-xl` sur laside (12px avec --radius 0.5rem + 4px).
#### Comparaison Discord (reverse-engineering communautaire)
- **Liste canaux** : Largeur étendue **240px**, collapsed **72px**.
- **Items** : Hauteur ditem ~3240px ; padding horizontal ~812px ; texte canal en 1416px.
- **Sections** : Séparation nette ; labels en petit, uppercase ou titre court.
#### Comparaison Spotify (pratiques courantes)
- **Left nav** : Largeur variable (resizable) ; collapsed = icônes seules (~5672px), étendu ~200280px.
- **Items** : Hauteur ~4048px ; icône + label ; peu ditems visibles sans scroll.
- **Rythme** : Espacement vertical régulier ; pas de surcharge.
#### Diagnostic
| Critère | Veza (code) | Discord | Spotify |
|---------|-------------|---------|---------|
| Largeur ouverte | 256px (w-64) | 240px | ~200280px |
| Largeur fermée | 80px (w-20) | 72px | ~5672px |
| Padding horizontal items | 12px (px-3) | ~812px | ~1216px |
| Padding vertical item | 8px (py-2) | ~68px | ~1012px |
| Espacement entre items | 2px (space-y-0.5) | ~02px | ~04px |
| Espacement entre sections | 24px (space-y-6) | ~1624px | ~816px |
| Taille label section | 12px (text-xs) | ~1112px | ~1112px |
| Taille item | 14px (text-sm) | ~14px | ~14px |
**Verdict** : **Densité et largeur dans la fourchette** Discord/Spotify. Points à valider sur capture : alignement icônetexte (gap-3 = 12px), contraste item actif vs inactif, et **incohérences de mise en page** (valeurs en dur : `left-6`, `top-20`, `bottom-6`, `z-[95]` non issues de tokens).
**Écarts précis** :
- La sidebar Veza fait **256px** ouverte contre **240px** Discord : 16px de plus, pas bloquant mais à aligner sur un token si on vise la même densité que Discord.
- `space-y-0.5` (2px) entre items donne une liste très serrée ; Discord/Spotify sont souvent dans la même gamme ; à confirmer que la ligne de base du texte ne touche pas litem suivant.
- **Alignements** : Le header utilise `gap-3`, les items `gap-3` (icônetexte) ; vérifier sur capture que les icônes des items sont alignées verticalement avec le titre "System Hub" (grille implicite).
---
### 2.5 Playlists — liste dense (`playlists-desktop.png`)
**Référents** : Discord = liste de canaux texte ; Spotify = liste de playlists ou liste de titres.
#### Métriques déduites du code (Veza)
- **Vue liste** : `flex flex-col gap-2 sm:gap-3` → 8px (mobile) / 12px (desktop) entre lignes.
- **PlaylistTrackItem** : `p-2 sm:p-3` (8px / 12px), `gap-2 sm:gap-4` (8px / 16px). Titre `text-sm sm:text-base` (14px / 16px), secondaire `text-xs sm:text-sm` (12px / 14px). Hauteur de ligne ≈ 12+12+20 (line-height) ≈ 44px (sm) ou 12+12+~24 ≈ 48px avec text-base.
- **Vue grille** : `grid gap-4`, `grid-cols-2 md:grid-cols-3 lg:grid-cols-4`. PlaylistCard avec `aspect-square` pour la cover.
- **Espacement global** : `space-y-4` entre toolbar et liste.
#### Comparaison Spotify (liste titres / playlists)
- **Liste titres** : Hauteur de ligne souvent ~4856px ; padding horizontal ~16px ; titre 1416px, secondaire 1214px.
- **Liste playlists** : Cartes ou lignes ; espacement régulier (gap 1624px).
#### Comparaison Discord (liste canaux)
- **Items** : Hauteur ~3240px ; texte 14px ; padding serré.
- **Densité** : Élevée pour afficher beaucoup de canaux.
#### Diagnostic
| Critère | Veza (code) | Spotify (liste) | Discord (canaux) |
|---------|-------------|-----------------|------------------|
| Padding vertical ligne | 812px (p-2/p-3) | ~1216px | ~610px |
| Espacement entre lignes | 812px (gap-2/gap-3) | ~04px (liste) | ~02px |
| Taille titre ligne | 1416px | 1416px | ~14px |
| Taille secondaire | 1214px | 1214px | ~12px |
| Hauteur approximative ligne | ~4448px | ~4856px | ~3240px |
**Verdict** : **Légèrement plus compact** que Spotify (padding et gap plus faibles), **proche** de Discord en densité. Pour une "liste dense" type Spotify, augmenter le padding vertical des lignes (p-3 → p-4) et/ou le gap entre lignes (gap-3 → gap-4) rapprocherait du rythme Spotify sans changer la structure.
**Écarts précis** :
- Litem de liste fait environ **4448px** de hauteur (p-2/p-3 + texte) contre **4856px** typique Spotify, ce qui donne une liste plus serrée.
- En vue grille, `gap-4` (16px) est cohérent ; vérifier sur capture que les cartes ne semblent pas collées (ratio cover/titre cohérent).
---
### 2.6 Library (`library-desktop.png`)
**Référent** : Spotify "Your Library" (grille ou liste dalbums/playlists).
#### Métriques Veza (code)
- Même composants que playlists (PlaylistList, grille/liste) ; écran library peut réutiliser des vues liste ou grille selon le code.
- Si grille : `gap-4`, colonnes 2/3/4 ; si liste : même métriques que playlists.
**Verdict** : Aligner sur le même diagnostic que Playlists (densité, hauteur de ligne, gap). **Cohérence** entre Library et Playlists à confirmer sur baselines (mêmes tokens, pas décart visuel entre les deux écrans).
---
### 2.7 404 (`404-desktop.png`)
**Référent** : Page erreur minimale (Spotify / Discord : message + CTA).
#### Points à vérifier sur baseline
- Hiérarchie : message principal > explication > bouton.
- Densité : centré, pas trop vide (min-h-layout-page-sm = 400px).
- Contraste : texte lisible sur fond dark.
- Composant : KodoEmptyState ou équivalent (icône, titre, description, action).
**Verdict** : Pas de référent métrique strict ; **qualité** = lisibilité et un seul CTA clair. À valider en Phase 3 avec une capture.
---
## 3. Synthèse transverse
### 3.1 Règles implicites Discord (extraites)
1. **Densité élevée avec contraste typographique fort** : Beaucoup déléments visibles (canaux, messages) ; différenciation par taille (labels petits, contenu en corps) et poids (gras pour noms), pas par espacement excessif.
2. **Sidebar à largeur fixe et prévisible** : 72px (collapsed) / 240px (étendu) ; peu de variation. Hiérarchie visuelle par sections (serveurs vs canaux) et par état actif/hover.
3. **Alignements stricts** : Icônes et texte alignés sur une grille ; pas de décalage entre zones équivalentes (même padding gauche pour tous les items de même niveau).
### 3.2 Règles implicites Spotify (extraites)
1. **Densité modérée, rythme vertical régulier** : Espacement entre sections et entre lignes cohérent (1624px) ; moins ditems visibles que Discord mais lecture plus confortable.
2. **Sidebar resizable avec états clairs** : Collapsed = icônes seules ; étendu = icône + label ; transition nette. Pas de demi-mesure visuelle.
3. **Hiérarchie par taille et contraste secondaire** : Titres de section 24px ou équivalent ; corps 1416px ; secondaire (métadonnées) plus petit et plus terne ; peu de couleurs vives en dehors des covers et CTAs.
### 3.3 Ce que lapp actuelle fait déjà bien
- **Sidebar** : Largeur et structure (sections, items, collapsed) dans la fourchette Discord/Spotify ; tokens sémantiques (sidebar-primary, sidebar-accent) présents.
- **Dashboard** : Padding et espacement entre blocs (p-6, space-y-6, gap-4) proches de Spotify Home.
- **Formulaires auth** : Structure space-y-8 / space-y-4 et boutons (h-10, rounded-full) cohérents avec des patterns courants.
- **Listes** : Typo (text-sm / text-xs) et structure (titre + secondaire) alignées avec les référents.
### 3.4 Ce qui éloigne structurellement des référents
- **Spacing formulaires** : 16px entre champs (space-y-4) plus serré que le 2024px type Spotify login → sensation plus dense.
- **Liste playlists** : Lignes ~4448px et gap 812px plus compacts que Spotify (~4856px, 04px gap) → liste plus "Discord" que "Spotify".
- **Dashboard** : Multiplicité de couleurs vives et ombres sur les cartes → risque de concurrence visuelle avec le titre ; Discord/Spotify limitent les couleurs vives à des zones précises (accents, états).
- **Sidebar** : Valeurs en dur (left-6, top-20, bottom-6, z-[95], w-64) non issues de tokens → incohérence potentielle et maintenance difficile ; Discord/Spotify sappuient sur des variables de layout.
- **Alignements** : Non audités pixel-perfect sur les captures ; ruptures de grille ou padding incohérents entre zones équivalentes restent possibles.
---
## 4. Tableau de synthèse (ordre de traitement Phase 3)
| Écran | Problème principal | Type | Impact perçu |
|-------|--------------------|------|--------------|
| Login | Espacement vertical entre champs trop faible (16px vs 2024px) | Spacing | Moyen |
| Register | Idem login ; risque détouffement si nombreux champs | Spacing | Moyen |
| Dashboard | Concurrence visuelle cartes (couleurs + ombres) vs titre | Hiérarchie | Fort |
| Sidebar | Valeurs en dur (position, z-index, w-64) ; 256px vs 240px Discord | Spacing / Alignement | Moyen |
| Playlists (liste) | Hauteur de ligne et gap plus compacts que Spotify | Spacing / Densité | Moyen |
| Library | Cohérence avec Playlists (mêmes tokens) | Alignement | Faible |
| 404 | À valider sur capture (lisibilité, CTA unique) | Hiérarchie / Contraste | Faible |
---
## 5. Ordre recommandé pour la Phase 3
1. **Sidebar** : Remplacer les valeurs en dur par des tokens (largeur, positions, z-index) ; optionnellement aligner la largeur ouverte sur 240px si cible Discord.
2. **Login / Register** : Augmenter lespacement vertical entre champs (nouveau token ou space-y-5 / space-y-6) ; une seule catégorie à la fois, puis capture + pixelmatch.
3. **Dashboard** : Réduire la concurrence visuelle des cartes (ombres ou couleurs) pour renforcer la hiérarchie titre > cartes ; vérifier contrastes.
4. **Playlists (liste)** : Ajuster padding vertical des lignes et/ou gap entre lignes pour se rapprocher du rythme Spotify ; mesurer sur baseline après correction.
5. **Library** : Sassurer que les mêmes tokens que Playlists sont utilisés ; pas de dérive visuelle.
6. **404** : Validation visuelle et contraste ; corrections mineures si besoin.
---
**Fin du rapport Phase 2.** Aucune modification de code ou de tokens na été effectuée ; les corrections seront appliquées en Phase 3, une catégorie à la fois, avec capture et diff pixelmatch pour chaque changement.