--- 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 qu’index.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.250–252), 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 d’ombres 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 d’espacement (`--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, l’ajouter dans index.css (ou design-system.css) et dans DESIGN_TOKENS.md, puis l’utiliser. - **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 < 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** : ``, `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). S’appuyer sur [STORYBOOK_CONTRACT](apps/web/docs/) ou équivalent s’il 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 d’aligner avec les captures visuelles. ### Livrable Semaine 3 - 2 à 3 nouvelles stories full layout (Library, Settings ou Profile). - Au moins 2–3 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 - S’assurer 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. 200–300 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 l’addon 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 à d’autres é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 - S’assurer 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 7–8 — 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 7–8 - 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 d’exé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 | | 7–8 | 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 d’arbitraire). FULL_LAYOUT_PAGE.md « Comment ajouter une page full layout ». | **Reste optionnel :** étendre stories Loading/Error/Empty sur d’autres 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.