Document: skeleton shimmer migration (43 files), EmptyState migration, text-destructive token migration, SearchPageResults/UserCard a11y. Co-authored-by: Cursor <cursoragent@cursor.com>
8.2 KiB
8.2 KiB
UI Quality Log
Suivi des leviers traités pour atteindre le niveau premium Discord/Spotify-like. Chaque entrée documente : levier, fichiers impactés, impact visuel, risques évités.
2025-02-08 — Session 1
Levier 1 : Contraste muted-foreground (WCAG AA+)
- Fichiers :
src/index.css(3 variables) - Changement : dark mode oklch(0.65 → 0.70), light mode oklch(0.45 → 0.42), sidebar-foreground synchronisé
- Impact : texte secondaire plus lisible sur toutes les surfaces (labels, timestamps, placeholders, sidebar nav items). Rapproche du ratio Spotify (~0.70) et Discord (~0.76).
- Risques évités : pas de régression de hiérarchie (delta foreground/muted reste 0.28, suffisant pour distinction visuelle)
Levier 2 : Migration text-[10px] → text-xs (23 composants)
- Fichiers : 23 composants (admin, marketplace, player, settings, chat, upload, etc.)
- Changement : remplacement de toutes les tailles arbitraires
text-[10px]partext-xs. Exceptions documentées : avatar xs, badge JSDoc. - Impact : typographie cohérente et conforme au design system sur toute l'app
- Risques évités : vérification que text-xs (0.75rem = 12px vs 10px) ne casse pas la densité des composants compacts
Levier 3 : Migration max-h-[XXvh] → tokens layout (15 composants)
- Fichiers : 15 composants (modales, panels, player, hero)
- Changement : toutes les hauteurs arbitraires viewport remplacées par
max-h-layout-modal*,max-h-layout-list,max-h-layout-drawer,h-layout-lyrics - Impact : système de hauteurs cohérent, modales qui respectent un contrat visuel
- Risques évités : tokens déjà définis et testés dans index.css avant usage
Levier 4 : Shell DashboardLayout + Header transparence
- Fichiers :
DashboardLayout.tsx,Header.tsx - Changement :
min-w-0(fix overflow),max-lg:ml-0(responsive),bg-transparent backdrop-blur-mdheader - Impact : header seamless type Spotify, meilleur scroll
- Risques évités : pas de modification des tokens — changements locaux aux composants
Levier 5 : Player sidebar-aware + synced lyrics
- Fichiers :
GlobalPlayer.tsx,PlayerExpanded.tsx,PlayerQueue.tsx,types.ts - Changement : positionnement player aligné sur sidebar, vue étendue avec lyrics synchronisées, queue repositionnée
- Impact : player qui ne chevauche plus la sidebar sur desktop, expérience lyrics type Spotify
- Risques évités : z-index vérifié, reduced-motion respecté
Levier 6 : Focus-visible rings (16 composants)
- Fichiers : 16 composants (TrackCard, ConversationItem, SelectOptionItem, etc.)
- Changement : ajout
focus-visible:ring-2 focus-visible:ring-ringsur éléments interactifs sans indicateur focus - Impact : navigation clavier fonctionnelle sur les contrôles manquants
- Risques évités : pattern cohérent avec les composants déjà couverts (Button, Sidebar)
Levier 7 : Arbitrary min-w → Tailwind scale (5 composants)
- Fichiers : AdminModerationView, PasswordStrengthIndicator, PlaylistFollowButton, FollowButton, collapsible
- Changement :
min-w-[Xpx]→min-w-NTailwind, exception documentée pour collapsible - Impact : cohérence du spacing system
- Risques évités : valeurs Tailwind les plus proches vérifées (140px → 36 = 144px, 100px → 24 = 96px, 80px → 20 = 80px)
Levier 8 : Unification scrollbar
- Fichiers :
global-effects.css,fixDisplayIssues.ts - Changement : suppression des définitions scrollbar dupliquées, index.css comme source unique
- Impact : scrollbar cohérente dans toute l'app (dev et prod)
- Risques évités : pas de conflit d'ordre de chargement CSS
Levier 9 : Nettoyage fixDisplayIssues.ts (719 → 70 lignes)
- Fichiers :
fixDisplayIssues.ts,aggressiveVisualFix.ts - Changement : suppression de l'injection CSS nucléaire, MutationObserver, setInterval. Conservation des outils diagnostic opt-in.
- Impact : dev mode fidèle à la prod (borders, backgrounds, éléments étroits visibles)
- Risques évités : vérification que le problème original (lignes verticales) est toujours corrigé à la source CSS
Levier 10 : PlaylistCard hover transition fix + focus-visible
- Fichiers :
PlaylistCard.tsx - Changement : suppression de
transition-opacityqui écrasait les transitions du Card (shadow, bg-color). Ajout focus-visible ring.ring-blue-500→ring-primary. - Impact : hover shadow animation fonctionne maintenant, navigation clavier accessible
- Risques évités : pas de changement de layout, seulement des transitions et ring
Levier 11 : Switch, Toast, LoadingSpinner → design system
- Fichiers :
switch.tsx,Toast.tsx,loading-spinner.tsx - Changement : dimensions arbitraires → Tailwind scale (
w-[44px]→w-11), couleurs hardcodées → tokens (bg-kodo-cyan→bg-primary,border-t-blue-600→border-t-primary) - Impact : composants alignés sur le design system, cohérence visuelle
- Risques évités : dimensions Tailwind exactement identiques aux px arbitraires
Levier 12 : Skeleton shimmer animation (premium loading)
- Fichiers :
skeleton.tsx,index.css - Changement : remplacement
animate-pulse(opacité simple) par overlay shimmer (gradient balayant).bg-kodo-steel/50→bg-muted/50. Respecteprefers-reduced-motion. - Impact : loading states perçus comme premium (pattern Spotify/Discord). Visible sur chaque page load et transition.
- Risques évités : shimmer via enfant overlay, pas de conflit avec les classes animate-pulse inline existantes
2026-02-08 — Session 2
Levier 13 : Migration inline skeletons → <Skeleton> shimmer (43 fichiers)
- Fichiers : 43 skeleton files across all major views (TrackDetailPage, LibraryPage, PlaylistDetailPage, DiscoverView, PlaybackDashboard, StudioView, MonitoringDashboard, UserProfilePage, SearchPage, ChatMessages, AudioPlayer, etc.)
- Changement : remplacement de tous les
<div className="... bg-muted animate-pulse">par<Skeleton>component avec shimmer premium - Impact : chaque état de chargement dans l'app utilise maintenant le shimmer premium au lieu du pulse basique. Perception de fluidité uniforme.
- Risques évités : layout identique (seules les classes bg-muted/animate-pulse retirées), props/structure inchangées
Levier 14 : Inline empty states → <EmptyState> component (6 composants)
- Fichiers : MarketplaceHome, MarketplaceViewGrid, ProfileViewTracksTab, ProfileViewPlaylistsTab, PurchasesViewList, SessionManagement, empty-state.tsx
- Changement : remplacement des "No X found" nus par EmptyState (icône + titre + description + action optionnelle). Tokens du composant EmptyState migrés :
text-white→text-foreground,text-kodo-content-dim→text-muted-foreground - Impact : les états vides sont maintenant des moments UX designés, pas des fallback bruts
- Risques évités : migration conservatrice — même texte, ajout d'icône contextuelle
Levier 15 : text-red-500 → text-destructive (11 composants)
- Fichiers : PlayerExpanded, PlayerQueue, WebhooksView, RolesPage, ChatPage, AdminDashboardStatCard, NotificationsViewItem/Header, AnalyticsViewTopTracks, AdminDashboardTabs, AdminDashboardHeader
- Changement : migration systématique de
text-red-500,bg-red-500/10,border-red-500/20etc. vers les équivalentsdestructivedu design system - Impact : les états d'erreur et destructifs s'adapteront au thème, cohérence du langage visuel
- Risques évités : tokens
destructivedéjà définis dans index.css, couleur visuellement identique
Levier 16 : Focus-visible + a11y SearchPageResults & UserCard
- Fichiers : SearchPageResults.tsx, UserCard.tsx
- Changement : ajout tabIndex/role/onKeyDown/focus-visible ring sur toutes les Cards interactives de SearchPageResults. Conversion des div/h3 cliquables de UserCard en
<button>sémantiques. Migration tokens couleur legacy. - Impact : navigation clavier complète dans la recherche, conformité a11y UserCard
- Risques évités : pas de changement de layout visuel, focus ring visible uniquement au clavier (focus-visible)