260 lines
11 KiB
Markdown
260 lines
11 KiB
Markdown
|
|
# V0.801 Release Scope — UX/UI Polish, Accessibilité & PWA
|
|||
|
|
|
|||
|
|
**Statut** : Planifié
|
|||
|
|
**Phase** : 8 (Polish & Scale — Lot 1)
|
|||
|
|
**Prérequis** : v0.703 (taguée)
|
|||
|
|
**Date cible** : TBD
|
|||
|
|
**Estimation** : ~3 sprints (15 jours ouvrés)
|
|||
|
|
**Précédente** : [v0.703](archive/V0_703_RELEASE_SCOPE.md)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 1. Objectif
|
|||
|
|
|
|||
|
|
Première version de la Phase 8. Améliore l'expérience utilisateur avec les **thèmes avancés** (contraste élevé, compact, accents personnalisables), l'**accessibilité WCAG AA** (clavier, screen reader, ARIA), et le **renforcement PWA** (offline, add-to-home-screen, background playback). Ces améliorations touchent l'ensemble de l'interface sans modifier les fonctionnalités métier.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 2. État actuel (post-v0.703)
|
|||
|
|
|
|||
|
|
| Composant | État | Détail |
|
|||
|
|
|-----------|------|--------|
|
|||
|
|
| **Thème clair/sombre** | ✅ Livré | ThemeProvider, toggle dans Settings |
|
|||
|
|
| **Thème auto (système)** | ✅ Livré | prefers-color-scheme détecté |
|
|||
|
|
| **Contraste élevé** | ❌ Absent | Pas de mode high contrast |
|
|||
|
|
| **Mode compact/confortable** | ❌ Absent | Layout unique, pas de densité configurable |
|
|||
|
|
| **Couleur d'accent** | ❌ Absent | Couleur primary fixe dans design tokens |
|
|||
|
|
| **Navigation clavier** | ⚠️ Partiel | Certains composants focusables, pas systématique |
|
|||
|
|
| **Screen reader (ARIA)** | ⚠️ Partiel | Labels manquants sur boutons icônes, tables, modales |
|
|||
|
|
| **Focus visible** | ⚠️ Partiel | Outline CSS basique, pas toujours visible |
|
|||
|
|
| **Taille de police ajustable** | ❌ Absent | Tailles fixes dans design tokens |
|
|||
|
|
| **prefers-reduced-motion** | ❌ Absent | Animations non conditionnées |
|
|||
|
|
| **PWA Service Worker** | ⚠️ Partiel | SW de base, pas d'offline caching |
|
|||
|
|
| **Add-to-home-screen** | ❌ Absent | Pas de manifest complet ni prompt |
|
|||
|
|
| **Background playback** | ❌ Absent | Audio s'arrête en background mobile |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 3. Lots
|
|||
|
|
|
|||
|
|
### Lot UX1 — Thèmes avancés
|
|||
|
|
|
|||
|
|
**Objectif** : Offrir des options de personnalisation visuelle complètes.
|
|||
|
|
|
|||
|
|
| # | Tâche | Fichiers impactés | Effort |
|
|||
|
|
|---|-------|--------------------|--------|
|
|||
|
|
| UX1-01 | Mode contraste élevé — palette high-contrast dans index.css, toggle dans SettingsAppearance | `apps/web/src/index.css`, `apps/web/src/components/settings/SettingsAppearance.tsx` | M |
|
|||
|
|
| UX1-02 | Mode compact/confortable — réduire spacing/padding/gap de 25% en mode compact, CSS variables | `apps/web/src/index.css`, ThemeProvider | M |
|
|||
|
|
| UX1-03 | Couleur d'accent personnalisable — color picker dans Settings, CSS variable `--color-primary`, persistence localStorage | `apps/web/src/components/settings/SettingsAppearance.tsx`, ThemeProvider | M |
|
|||
|
|
| UX1-04 | Persistence des préférences — stocker theme, contrast, density, accent dans localStorage + compte utilisateur (PUT /users/me/preferences) | `apps/web/src/stores/`, backend | M |
|
|||
|
|
| UX1-05 | Migration backend — ajout colonne `preferences JSONB` sur users | `migrations/118_users_preferences.sql` | S |
|
|||
|
|
| UX1-06 | Tests — theme toggle, accent change, compact mode rendering | Tests | S |
|
|||
|
|
|
|||
|
|
### Lot UX2 — Accessibilité WCAG AA
|
|||
|
|
|
|||
|
|
**Objectif** : Atteindre la conformité WCAG AA sur tous les composants critiques.
|
|||
|
|
|
|||
|
|
| # | Tâche | Fichiers impactés | Effort |
|
|||
|
|
|---|-------|--------------------|--------|
|
|||
|
|
| UX2-01 | Audit a11y — lister tous les composants UI avec aria-label manquant, focus trap incomplet, contraste insuffisant | Audit doc | M |
|
|||
|
|
| UX2-02 | Navigation clavier complète — tabindex, Enter/Space handlers sur tous les composants interactifs (Button, Card, Menu, Tab, Modal) | `apps/web/src/components/ui/` | L |
|
|||
|
|
| UX2-03 | ARIA labels — ajouter aria-label sur boutons icônes, aria-describedby sur forms, role sur régions | `apps/web/src/components/` | M |
|
|||
|
|
| UX2-04 | Focus visible amélioré — focus-visible ring distinct (2px solid, offset), skip-to-content link | `apps/web/src/index.css`, layout | S |
|
|||
|
|
| UX2-05 | Taille de police ajustable — slider dans Settings (14px–20px), CSS variable `--font-size-base`, scale proportionnel | `apps/web/src/index.css`, Settings | M |
|
|||
|
|
| UX2-06 | prefers-reduced-motion — conditionner toutes les animations/transitions CSS, respecter l'OS preference | `apps/web/src/index.css` | S |
|
|||
|
|
| UX2-07 | Contraste WCAG AA — vérifier ratio 4.5:1 sur tous les textes, ajuster les couleurs secondaires si nécessaire | `apps/web/src/index.css` | M |
|
|||
|
|
| UX2-08 | Tests a11y — axe-core intégré dans Storybook (addon-a11y), 0 violations critiques | `apps/web/.storybook/` | M |
|
|||
|
|
|
|||
|
|
### Lot UX3 — PWA & Mobile
|
|||
|
|
|
|||
|
|
**Objectif** : Améliorer l'expérience mobile avec offline, installation, et background playback.
|
|||
|
|
|
|||
|
|
| # | Tâche | Fichiers impactés | Effort |
|
|||
|
|
|---|-------|--------------------|--------|
|
|||
|
|
| UX3-01 | Manifest PWA complet — icons (192, 512, maskable), theme_color, background_color, display: standalone, shortcuts | `apps/web/public/manifest.json` | S |
|
|||
|
|
| UX3-02 | Service worker offline — cache app shell, pages visitées, fallback offline page | `apps/web/src/sw.ts` ou vite-plugin-pwa | M |
|
|||
|
|
| UX3-03 | Add-to-home-screen prompt — beforeinstallprompt handler, bouton "Install App" dans Settings | `apps/web/src/hooks/usePWAInstall.ts`, Settings | M |
|
|||
|
|
| UX3-04 | Background playback mobile — Audio element persist, page visibility API, prevent sleep (WakeLock API) | `apps/web/src/features/player/hooks/` | M |
|
|||
|
|
| UX3-05 | Tests PWA — Lighthouse PWA score, offline fallback, install prompt | Tests | S |
|
|||
|
|
|
|||
|
|
### Lot QA1 — Tests & Release
|
|||
|
|
|
|||
|
|
| # | Tâche | Fichiers impactés | Effort |
|
|||
|
|
|---|-------|--------------------|--------|
|
|||
|
|
| QA1-01 | Smoke test v0.801 | `docs/SMOKE_TEST_V0801.md` | S |
|
|||
|
|
| QA1-02 | Mise à jour PROJECT_STATE, FEATURE_STATUS, CHANGELOG | `docs/` | S |
|
|||
|
|
| QA1-03 | Rétrospective, archivage, placeholder v0.802, tag | `docs/`, Git | S |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 4. Hors scope v0.801
|
|||
|
|
|
|||
|
|
| Élément | Version cible |
|
|||
|
|
|---------|---------------|
|
|||
|
|
| Cloud Storage avancé | v0.802 |
|
|||
|
|
| Gear warranty tracking | v0.802 |
|
|||
|
|
| OpenAPI/Swagger | v0.803 |
|
|||
|
|
| GDPR compliance complet | v0.803 |
|
|||
|
|
| Wishlists marketplace | v0.901 |
|
|||
|
|
| Layouts personnalisables (drag & drop modules) | v2.0 |
|
|||
|
|
| Thèmes communautaires | v2.0 |
|
|||
|
|
| Mode dyslexie-friendly | v2.0 |
|
|||
|
|
| Transcriptions vidéo auto | v2.0 |
|
|||
|
|
| Sous-titres auto-générés | v2.0 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 5. Détail technique
|
|||
|
|
|
|||
|
|
### 5.1 Design tokens contraste élevé
|
|||
|
|
|
|||
|
|
```css
|
|||
|
|
[data-contrast="high"] {
|
|||
|
|
--color-foreground: #000000;
|
|||
|
|
--color-background: #ffffff;
|
|||
|
|
--color-muted: #4a4a4a;
|
|||
|
|
--color-border: #000000;
|
|||
|
|
--color-primary: #0000cc;
|
|||
|
|
--color-destructive: #cc0000;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.dark[data-contrast="high"] {
|
|||
|
|
--color-foreground: #ffffff;
|
|||
|
|
--color-background: #000000;
|
|||
|
|
--color-muted: #cccccc;
|
|||
|
|
--color-border: #ffffff;
|
|||
|
|
--color-primary: #6666ff;
|
|||
|
|
--color-destructive: #ff6666;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5.2 Mode compact
|
|||
|
|
|
|||
|
|
```css
|
|||
|
|
[data-density="compact"] {
|
|||
|
|
--spacing-unit: 0.75;
|
|||
|
|
--font-size-base: 13px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[data-density="comfortable"] {
|
|||
|
|
--spacing-unit: 1;
|
|||
|
|
--font-size-base: 15px;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5.3 Couleur d'accent
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
function applyAccentColor(hue: number) {
|
|||
|
|
document.documentElement.style.setProperty('--color-primary', `hsl(${hue}, 70%, 50%)`);
|
|||
|
|
document.documentElement.style.setProperty('--color-primary-foreground', `hsl(${hue}, 70%, 98%)`);
|
|||
|
|
localStorage.setItem('veza-accent-hue', String(hue));
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5.4 prefers-reduced-motion
|
|||
|
|
|
|||
|
|
```css
|
|||
|
|
@media (prefers-reduced-motion: reduce) {
|
|||
|
|
*, *::before, *::after {
|
|||
|
|
animation-duration: 0.01ms !important;
|
|||
|
|
animation-iteration-count: 1 !important;
|
|||
|
|
transition-duration: 0.01ms !important;
|
|||
|
|
scroll-behavior: auto !important;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5.5 Background Playback (WakeLock)
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
async function requestWakeLock() {
|
|||
|
|
if ('wakeLock' in navigator) {
|
|||
|
|
try {
|
|||
|
|
const lock = await navigator.wakeLock.request('screen');
|
|||
|
|
return lock;
|
|||
|
|
} catch (e) {
|
|||
|
|
// WakeLock denied — battery saver, etc.
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 6. Fichiers impactés (récapitulatif)
|
|||
|
|
|
|||
|
|
### Backend (nouveau)
|
|||
|
|
|
|||
|
|
| Fichier | Action |
|
|||
|
|
|---------|--------|
|
|||
|
|
| `migrations/118_users_preferences.sql` | Nouveau — colonne preferences JSONB |
|
|||
|
|
|
|||
|
|
### Backend (modifier)
|
|||
|
|
|
|||
|
|
| Fichier | Action |
|
|||
|
|
|---------|--------|
|
|||
|
|
| `internal/models/user.go` | Ajout champ Preferences |
|
|||
|
|
| `internal/handlers/user_handler.go` | PUT /users/me/preferences |
|
|||
|
|
|
|||
|
|
### Frontend (nouveau)
|
|||
|
|
|
|||
|
|
| Fichier | Action |
|
|||
|
|
|---------|--------|
|
|||
|
|
| `apps/web/src/hooks/usePWAInstall.ts` | Nouveau — beforeinstallprompt handler |
|
|||
|
|
| `apps/web/src/hooks/useReducedMotion.ts` | Nouveau — prefers-reduced-motion hook |
|
|||
|
|
|
|||
|
|
### Frontend (modifier)
|
|||
|
|
|
|||
|
|
| Fichier | Action |
|
|||
|
|
|---------|--------|
|
|||
|
|
| `apps/web/src/index.css` | Design tokens contrast, compact, accent, reduced-motion, font-size |
|
|||
|
|
| `apps/web/src/components/settings/SettingsAppearance.tsx` | Toggle contrast, density, color picker, font size slider |
|
|||
|
|
| `apps/web/src/components/ui/` | ARIA labels, focus handlers, keyboard nav |
|
|||
|
|
| `apps/web/public/manifest.json` | PWA manifest complet |
|
|||
|
|
| `apps/web/src/features/player/hooks/` | WakeLock, background playback |
|
|||
|
|
| `apps/web/.storybook/` | addon-a11y |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 7. Critères d'acceptation
|
|||
|
|
|
|||
|
|
- [ ] Mode contraste élevé activable dans Settings, couleurs WCAG AA ratio 4.5:1
|
|||
|
|
- [ ] Mode compact réduit spacing de 25%, confortable par défaut
|
|||
|
|
- [ ] Couleur d'accent personnalisable via color picker, persistée
|
|||
|
|
- [ ] Navigation clavier complète (Tab, Enter, Space, Escape) sur tous les composants UI
|
|||
|
|
- [ ] ARIA labels sur tous les boutons icônes, modales, formulaires
|
|||
|
|
- [ ] Focus visible ring distinct, skip-to-content link
|
|||
|
|
- [ ] Taille de police ajustable (14px–20px) via slider Settings
|
|||
|
|
- [ ] prefers-reduced-motion respecté (animations désactivées)
|
|||
|
|
- [ ] axe-core 0 violations critiques dans Storybook
|
|||
|
|
- [ ] PWA installable (manifest complet, icons, display standalone)
|
|||
|
|
- [ ] Offline : app shell cachée, page fallback
|
|||
|
|
- [ ] Background playback mobile avec WakeLock
|
|||
|
|
- [ ] Tag v0.801 créé
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 8. Risques
|
|||
|
|
|
|||
|
|
| Risque | Mitigation |
|
|||
|
|
|--------|------------|
|
|||
|
|
| Accent color casse le contraste | Validation ratio contraste automatique sur selection |
|
|||
|
|
| ARIA labels verbeux sur screen reader | Tester avec VoiceOver/NVDA réels |
|
|||
|
|
| Service worker cache stale | Cache-first + network fallback avec versioning |
|
|||
|
|
| WakeLock non supporté partout | Feature detection, fallback gracieux |
|
|||
|
|
| Compact mode casse des layouts | Tests visuels sur résolutions critiques (320px, 768px, 1920px) |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 9. Références
|
|||
|
|
|
|||
|
|
- [RETROSPECTIVE_V0703.md](RETROSPECTIVE_V0703.md)
|
|||
|
|
- [V0_703_RELEASE_SCOPE.md](archive/V0_703_RELEASE_SCOPE.md)
|
|||
|
|
- [SCOPE_CONTROL.md](SCOPE_CONTROL.md)
|
|||
|
|
- [DESIGN_TOKENS.md](apps/web/docs/DESIGN_TOKENS.md)
|
|||
|
|
- [WCAG 2.1 AA Guidelines](https://www.w3.org/WAI/WCAG21/quickref/?levels=aaa)
|
|||
|
|
- [Web App Manifest](https://developer.mozilla.org/en-US/docs/Web/Manifest)
|
|||
|
|
- [Screen Wake Lock API](https://developer.mozilla.org/en-US/docs/Web/API/Screen_Wake_Lock_API)
|