veza/name Plan UI premium 6.txt
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

306 lines
20 KiB
Text
Raw Permalink 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.

---
name: Plan UI premium 6-8 semaines
overview: "Plan détaillé sur 6 à 8 semaines pour porter le frontend Veza au niveau \"Discord/Spotify-like\" : renforcement du design system (tokens, ombres, typo), harmonisation rythme/hiérarchie, consolidation Storybook, animations, tests visuels et accessibilité, extension du shell à Library/Profile/Settings, et automatisation (lint, scripts ciblés). S'appuie sur la base déjà en place (shell tokenisé, full layout stories, visual-tests)."
todos: []
isProject: false
---
# Plan UI premium — 6 à 8 semaines (Discord/Spotify-like)
## État des lieux (déjà en place)
- **Shell** : [DashboardLayout.tsx](apps/web/src/components/layout/DashboardLayout.tsx), [Header.tsx](apps/web/src/components/layout/Header.tsx), [Sidebar.tsx](apps/web/src/components/layout/Sidebar.tsx) utilisent les tokens de [index.css](apps/web/src/index.css) (header, main, sidebar). Doc : [APP_SHELL.md](apps/web/docs/APP_SHELL.md).
- **Stories full layout** : [DashboardLayout.stories.tsx](apps/web/src/components/layout/DashboardLayout.stories.tsx) — Default (placeholder), DashboardFullLayout, PlaylistsFullLayout.
- **Visual tests** : [visual-tests/](apps/web/visual-tests/) avec baselines, current, diffs, reports ; PHASE1/2/3 présents.
- **Tokens existants** : layout/shell et sidebar dans index.css ; spacing dans [design-tokens.css](apps/web/src/styles/design-tokens.css) ; shadows dans [design-system.css](apps/web/src/styles/design-system.css) (`--shadow-sm` à `--shadow-soft`). Duplication à trancher : design-system.css définit `--sidebar-width: 280px`, `--header-height: 64px` alors quindex.css utilise 15rem / 4rem.
- **ESLint** : règles déjà en place pour tailles de texte arbitraires, spacing arbitraire (gap/p/m/…), couleurs Tailwind par défaut, usage du composant Button. Pas encore de règle pour `w-[...]`, `h-[...]`, `rounded-[...]`, `shadow-[...]`.
- **Docs** : [SPACING_GUIDE.md](apps/web/docs/SPACING_GUIDE.md), nombreux audits (TYPOGRAPHY, SPACING_AUDIT, etc.).
---
## Semaine 1 — Design system : tokens et cohérence
**Objectif** : Une seule source de vérité pour layout/shell/shadows ; zéro valeur arbitraire dans les composants partagés du shell et des UI de base.
### 1.1 Unifier et documenter les tokens
- **Conflit layout** : Dans [design-system.css](apps/web/src/styles/design-system.css) (l.250252), supprimer ou aligner `--sidebar-width`, `--header-height`, `--header-height-tall` sur les variables de [index.css](apps/web/src/index.css) pour éviter deux sources (index.css fait autorité pour le shell).
- **Palette dombres sémantiques** : Dans index.css (ou design-system.css si centralisé), ajouter des tokens dédiés et les documenter :
- `--shadow-card` (ex. réutiliser `--shadow-soft` ou `--shadow-md` selon hiérarchie),
- `--shadow-modal` (ex. `--shadow-xl`),
- `--shadow-tooltip` (ex. `--shadow-md`).
Créer les classes utilitaires `.shadow-card`, `.shadow-modal`, `.shadow-tooltip` dans index.css (layer utilities) et les utiliser dans [card.css](apps/web/src/styles/card.css), modals, tooltips.
- **Documentation** : Créer ou étendre [docs/DESIGN_TOKENS.md](apps/web/docs/DESIGN_TOKENS.md) avec :
- Tableau des variables despacement (`--layout-gap`, `--layout-gap-sm`, `--layout-gap-lg`, + référence à design-tokens.css),
- Couleurs (référence à index.css + COLOR_USAGE.md),
- Typographie : tailles, line-heights, font-weight (extraire de index.css / Tailwind et lister),
- Ombres : sm, md, lg, xl, soft + card/modal/tooltip.
### 1.2 Audit et remplacement des valeurs en dur (shell + UI de base)
- **Périmètre** : [Sidebar.tsx](apps/web/src/components/layout/Sidebar.tsx), [Header.tsx](apps/web/src/components/layout/Header.tsx), [GlobalPlayer.tsx](apps/web/src/features/player/components/GlobalPlayer.tsx), [MiniPlayer.tsx](apps/web/src/components/player/MiniPlayer.tsx), puis [button.tsx](apps/web/src/components/ui/button.tsx), [card.tsx](apps/web/src/components/ui/card.tsx), [dialog](apps/web/src/components/ui/dialog/), [tooltip](apps/web/src/components/ui/tooltip/).
- **Actions** : Remplacer toute valeur arbitraire (ex. `shadow-[...]`, `w-[...]`, `h-[...]`, `gap-[3px]`, `rounded-[...]`) par un token ou une classe du design system. Si un token manque, lajouter dans index.css (ou design-system.css) et dans DESIGN_TOKENS.md, puis lutiliser.
- **Livrable** : DESIGN_TOKENS.md à jour ; shell + composants UI listés sans valeurs arbitraires ; baselines visual-tests inchangées (vérification par capture + diff).
### 1.3 Règle ESLint anti-arbitraire (width, height, rounded, shadow)
- Dans [eslint.config.js](apps/web/eslint.config.js), ajouter une entrée `no-restricted-syntax` (warn) pour les classes Tailwind arbitraires :
- `w-[...]`, `min-w-[...]`, `max-w-[...]` (exceptions possibles : `max-w-layout-content` déjà en token),
- `h-[...]`, `min-h-[...]`, `max-h-[...]`,
- `rounded-[...]`,
- `shadow-[...]` (hors cas documentés avec eslint-disable).
- Documenter les exceptions (ex. SVG, composants tiers) dans DESIGN_TOKENS.md ou un fichier dédié.
---
## Semaine 2 — Harmonisation rythme et hiérarchie
**Objectif** : Marges/gaps cohérents, hiérarchie typographique claire, comportement responsive du shell vérifié.
### 2.1 Marges et gaps
- Vérifier que léchelle Tailwind (ou tokens `--layout-gap*`) est respectée dans :
- Pages pilotes : [DashboardPage](apps/web/src/features/dashboard/pages/DashboardPage.tsx), [PlaylistListPage](apps/web/src/features/playlists/pages/PlaylistListPage.tsx), [LibraryPage](apps/web/src/features/library/pages/library-page/LibraryPage.tsx).
- Composants listes/cartes : DataList, cards de dashboard, items de playlist.
- Remplacer les écarts constatés (ex. `gap-[7px]` ou valeurs non scale) par des classes scale (gap-2, gap-3, gap-4, etc.) ou tokens.
### 2.2 Grid et flex responsive
- Documenter dans [APP_SHELL.md](apps/web/docs/APP_SHELL.md) les breakpoints utilisés (lg pour sidebar/main/header) et le comportement attendu (overlay &lt; lg, fixe ≥ lg).
- Vérifier visuellement (ou via tests Playwright) que Sidebar, Header et Main se comportent correctement sur 320px, 768px, 1024px, 1280px.
### 2.3 Typographie et hiérarchie
- Définir dans DESIGN_TOKENS.md une échelle claire : titre page (ex. text-2xl/3xl), sous-titre (text-lg/xl), label (text-sm), body (text-base), caption (text-xs). Vérifier que les composants réutilisables (StatCard, list items, cards) utilisent cette échelle.
- Réduire la concurrence visuelle sur le Dashboard : atténuer ombres ou couleurs secondaires des cartes (une seule catégorie de correction par itération, cf. Phase 3 visuelle déjà décrite dans les rapports).
### Livrable Semaine 2
- APP_SHELL.md mis à jour (breakpoints, comportement).
- DESIGN_TOKENS.md complété (typographie, hiérarchie).
- Rapport court listant les fichiers modifiés pour margins/gaps/typo.
---
## Semaine 3 — Consolidation Storybook (laboratoire QA UI)
**Objectif** : Full layout pour tous les écrans critiques ; variants Loading/Error/Empty et états interactifs.
### 3.1 Full layout stories
- Dans [DashboardLayout.stories.tsx](apps/web/src/components/layout/DashboardLayout.stories.tsx) (ou fichier dédié selon préférence), ajouter :
- **LibraryFullLayout** : `<DashboardLayout><LibraryPage /></DashboardLayout>`, `initialEntries: ['/library']`, handlers MSW pour library/tracks.
- **SettingsFullLayout** (ou **ProfileFullLayout**) : même principe pour Settings ou Profile selon priorité produit.
- Vérifier les handlers dans [handlers.ts](apps/web/src/mocks/handlers.ts) pour éviter loading infini (library, settings, profile).
### 3.2 Variants réalistes par composant
- Pour les composants critiques (ex. DataList, StatCard, PlaylistTrackItem, formulaires Login/Register) : ajouter ou compléter les stories **Loading** (Skeletons), **Error**, **Empty** (si liste/data). Sappuyer sur [STORYBOOK_CONTRACT](apps/web/docs/) ou équivalent sil existe.
- États interactifs : au moins une story avec hover/focus/disabled pour Button, Card, items de liste (playlist, library).
### 3.3 Décorateurs et viewport
- Confirmer que le décorateur global ([.storybook/decorators.tsx](apps/web/.storybook/decorators.tsx)) fournit ThemeProvider, QueryClient, Toast, AuthProvider, MemoryRouter. Utiliser uniquement `parameters.router.initialEntries` dans les stories full layout.
- Paramétrer un viewport cohérent (ex. 1280x720) pour les stories full layout afin daligner avec les captures visuelles.
### Livrable Semaine 3
- 2 à 3 nouvelles stories full layout (Library, Settings ou Profile).
- Au moins 23 composants avec Loading/Error/Empty et une story états interactifs.
- Build Storybook OK et vérification manuelle des stories.
---
## Semaine 4 — Animations et transitions
**Objectif** : Transitions douces et cohérentes (sidebar, boutons, modals, player) via tokens de durée/easing.
### 4.1 Tokens de transition
- Sassurer que [design-system.css](apps/web/src/styles/design-system.css) (ou index.css) expose bien `--duration-*` et `--ease-*`. Les documenter dans DESIGN_TOKENS.md.
- Créer si besoin des classes utilitaires (ex. `transition-shell`) pour la sidebar (width/opacity).
### 4.2 Sidebar
- Dans [Sidebar.tsx](apps/web/src/components/layout/Sidebar.tsx), appliquer une transition sur width/opacity avec une durée tokenisée (ex. `duration-normal` ou `--duration-normal`). Vérifier que le collapse/expand est fluide sans saut de layout.
### 4.3 Boutons et cartes
- Hover/focus : utiliser `transition-colors` ou `transition-all` avec durée courte (ex. 150ms). Uniformiser dans [button.tsx](apps/web/src/components/ui/button.tsx) et les cartes du dashboard.
### 4.4 Modals / drawers
- Fade + slide avec une durée unique (ex. 200300 ms) et easing cohérent. Vérifier [dialog](apps/web/src/components/ui/dialog/) et tout drawer existant.
### 4.5 Player
- [GlobalPlayer](apps/web/src/features/player/components/GlobalPlayer.tsx) et [MiniPlayer](apps/web/src/components/player/MiniPlayer.tsx) : transitions légères sur barre de progression et boutons (déjà partiellement en place ; aligner sur tokens).
### Livrable Semaine 4
- DESIGN_TOKENS.md mis à jour (durations, easings).
- Sidebar, boutons, modals, player utilisant les mêmes tokens de transition ; pas de régression visuelle (capture + diff).
---
## Semaine 5 — Tests visuels et audit UX
**Objectif** : Régression visuelle automatisée sur les stories full layout ; audit accessibilité et contrastes.
### 5.1 Régression visuelle
- Configurer Chromatic, Percy ou Playwright (snapshots) sur les stories **full layout** (Default, Dashboard, Playlists, Library, Settings/Profile). Si Playwright : ajouter un job ou script qui lance Storybook, capture les stories ciblées et compare aux baselines (ex. réutiliser [e2e/visual-complete.spec.ts](apps/web/e2e/visual-complete.spec.ts) et [scripts/generate-visual-report.mjs](apps/web/scripts/generate-visual-report.mjs)).
- Définir un seuil pixelmatch (ex. 0.1) et le documenter dans [visual-tests/README.md](apps/web/visual-tests/README.md).
### 5.2 Accessibilité
- Utiliser laddon a11y de Storybook sur les stories full layout et les composants critiques. Corriger les violations critiques (contraste, focus, labels).
- Vérifier la navigation au clavier (tab, Enter, Escape) sur Sidebar, Header, modals, player.
### 5.3 Cohérence focus / hover
- Vérifier que les états focus sont visibles et cohérents (ring, outline) sur tout le shell et les boutons/listes. Aligner sur les tokens (ring, border) du design system.
### Livrable Semaine 5
- Pipeline ou script de snapshots visuels sur full layout ; rapport de diff documenté.
- Rapport a11y (liste des violations et corrections appliquées).
- Mise à jour de visual-tests/README.md avec la procédure de validation visuelle.
---
## Semaine 6 — Extension du shell à dautres écrans
**Objectif** : Library, Profile, Settings (et autres écrans principaux) utilisent le même shell et les mêmes tokens ; validation par stories full layout.
### 6.1 Structure des pages
- Sassurer que Library, Profile, Settings sont rendus dans le même shell que Dashboard (même layout : DashboardLayout). Vérifier les routes dans [router](apps/web/src/router) et les wrappers de page.
- Appliquer les mêmes règles : pas de valeurs arbitraires ; spacing/typo/ombres depuis le design system.
### 6.2 Stories full layout
- Si pas déjà fait en Semaine 3, ajouter LibraryFullLayout, SettingsFullLayout, UserProfileFullLayout dans DashboardLayout.stories (ou fichiers dédiés) avec `initialEntries` et MSW adaptés.
### 6.3 Validation visuelle
- Capturer les écrans Library, Profile, Settings (visual:capture) et comparer aux baselines. Ajuster uniquement si les écarts sont voulus (puis mettre à jour les baselines avec justification).
### Livrable Semaine 6
- Tous les écrans principaux en full layout dans Storybook ; baselines à jour ; pas de régression.
---
## Semaine 78 — Automatisation et discipline long terme
**Objectif** : Lint strict sur les valeurs arbitraires ; scripts ciblés pour détecter les dérives ; pas de refactor massif risqué.
### 7.1 Lint
- Activer (ou durcir) la règle no-restricted-syntax pour `w-[...]`, `h-[...]`, `rounded-[...]`, `shadow-[...]` (passer en error sur les dossiers critiques si souhaité, ou garder en warn avec suivi).
- Ajouter une tâche CI (ou pre-commit) qui exécute ESLint sur les chemins concernés (src/components, src/features).
### 7.2 Scripts ciblés
- Script (ex. Node ou grep) qui liste les fichiers contenant des patterns arbitraires (`w-[`, `h-[`, `gap-[`, `p-[`, `m-[`, `rounded-[`, `shadow-[`) pour prioriser les migrations. Ne pas remplacer automatiquement : sortir un rapport (fichier, ligne, pattern) pour traitement manuel.
- Optionnel : script qui remplace des cas très simples et répétitifs (ex. `gap-[8px]` → `gap-2`) avec revue humaine obligatoire (PR dédiée, tests visuels).
### 7.3 Documentation et onboarding
- Mettre à jour [.cursorrules](apps/web/.cursorrules) ou README avec : usage obligatoire des tokens (référence DESIGN_TOKENS.md et APP_SHELL.md), commandes visual:capture / visual:compare / visual:update, et règle “pas de valeur arbitraire sans justification”.
- Court doc “Comment ajouter une nouvelle page full layout” (route, story, MSW, viewport).
### Livrable Semaine 78
- CI/lint configuré ; rapport des valeurs arbitraires restantes ; doc à jour. Éviter les scripts de remplacement global sur widths/heights/shadows sans revue contexte par contexte.
---
## Ordre dexécution et dépendances
```mermaid
flowchart LR
subgraph w1 [Semaine 1]
A1[Tokens unifiés]
A2[Audit shell + UI]
A3[ESLint anti-arbitraire]
end
subgraph w2 [Semaine 2]
B1[Marges gaps]
B2[Typo hiérarchie]
end
subgraph w3 [Semaine 3]
C1[Full layout stories]
C2[Variants Loading Error Empty]
end
subgraph w4 [Semaine 4]
D1[Transitions]
end
subgraph w5 [Semaine 5]
E1[Visual regression]
E2[A11y]
end
subgraph w6 [Semaine 6]
F1[Extension écrans]
end
subgraph w78 [Semaine 7-8]
G1[Lint CI]
G2[Scripts rapport]
end
A1 --> B1
A2 --> B1
A3 --> G1
B1 --> C1
B2 --> C1
C1 --> D1
D1 --> E1
E1 --> F1
F1 --> G1
```
---
## Fichiers clés à modifier (résumé)
| Semaine | Fichiers |
| ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | index.css, design-system.css, card.css, DESIGN_TOKENS.md (création/mise à jour), Sidebar.tsx, Header.tsx, GlobalPlayer.tsx, MiniPlayer.tsx, button.tsx, card.tsx, dialog, tooltip, eslint.config.js |
| 2 | APP_SHELL.md, DESIGN_TOKENS.md, DashboardPage, PlaylistListPage, LibraryPage, DataList, StatCard, composants listes |
| 3 | DashboardLayout.stories.tsx, handlers.ts, stories des composants (DataList, StatCard, etc.) |
| 4 | design-system.css ou index.css (tokens transition), Sidebar.tsx, button.tsx, card, dialog, GlobalPlayer, MiniPlayer |
| 5 | playwright ou Chromatic/Percy config, visual-tests/README.md, corrections a11y dans composants |
| 6 | Routes/pages Library, Profile, Settings, DashboardLayout.stories, baselines |
| 78 | eslint.config.js, script rapport arbitraires, .cursorrules ou README, doc “nouvelle page full layout” |
---
## Critères de succès globaux
- Aucune valeur arbitraire (w/h/gap/p/m/rounded/shadow) dans le shell et les composants UI de base sans token ou eslint-disable justifié.
- DESIGN_TOKENS.md et APP_SHELL.md sont la référence unique pour layout, espacements, ombres, typo, transitions.
- Chaque écran critique (Login, Register, Dashboard, Playlists, Library, Settings, Profile, 404) a une story full layout et une baseline visuelle.
- Régression visuelle détectée par outil (Playwright/Chromatic/Percy) sur les stories full layout.
- Audit a11y réalisé et violations critiques corrigées.
- Un nouvel engineer peut ajouter une page en suivant le doc sans introduire de valeurs arbitraires ni casser le shell.
---
## État d'avancement (mis à jour)
| Semaine | Statut | Détail |
|---------|--------|--------|
| **1** | ✅ Fait | Tokens unifiés (index.css source shell). Ombres sémantiques (shadow-card, shadow-modal, shadow-tooltip, shadow-cover-depth, shadow-gold-glow, shadow-fab-glow, etc.). DESIGN_TOKENS.md à jour. Shell + UI de base sans arbitraires (durations, ombres, layout max-height). ESLint no-restricted-syntax (warn) pour w-/h-/rounded-/shadow-/text-/spacing arbitraires. Script `report-arbitrary-values.mjs` + `npm run report:arbitrary`. |
| **2** | ✅ Fait | Marges/gaps via tokens et scale. APP_SHELL.md : breakpoints (320, 768, 1024, 1280), comportement responsive. DESIGN_TOKENS.md : typo (text-xs → caption), hiérarchie. Nombreux text-[10px] → text-xs. |
| **3** | ✅ Fait | Stories full layout : Default, DashboardFullLayout, PlaylistsFullLayout, LibraryFullLayout, SettingsFullLayout, ProfileFullLayout. Viewport desktop ; décorateurs (ThemeProvider, QueryClient, Toast, Auth, Router). FULL_LAYOUT_PAGE.md pour ajouter une page. Loading/Error/Empty sur certains composants (à étendre si besoin). |
| **4** | ✅ Fait | Tokens --duration-* et --ease-* documentés. transition-shell, Sidebar/button/card/dialog/player avec durances tokenisées. Ombres tokenisées partout (player, modals, FAB, gamification, etc.). |
| **5** | 🟡 En partie | Visual : visual-tests/README.md, seuil 0.1, commandes capture/compare/update ; e2e/visual-complete.spec.ts. A11y : focus-visible sur Sidebar, PlayerQueue, Button, DropdownMenuTrigger, DropdownMenuItem, TabsTrigger, etc. Addon a11y Storybook mentionné dans README. Rapport a11y formel (liste violations/corrections) à produire si souhaité. |
| **6** | ✅ Fait | Library, Profile, Settings dans le même shell (DashboardLayout). Stories full layout pour tous. DESIGN_TOKENS + APP_SHELL référence unique. |
| **7-8** | ✅ Fait | ESLint anti-arbitraire (warn). Script rapport arbitraires ; .cursorrules + README (DESIGN_TOKENS, APP_SHELL, visual, pas darbitraire). FULL_LAYOUT_PAGE.md « Comment ajouter une page full layout ». |
**Reste optionnel :** étendre stories Loading/Error/Empty sur dautres composants ; rapport a11y dédié (violations + corrections) ; durcir lint (error sur dossiers critiques) ou traiter les derniers `text-[10px]` / arbitraires signalés par le rapport.