# Story 3.7: Navigation mobile - Chemin Libre et Bottom Bar Status: review ## Story As a visiteur mobile, I want naviguer facilement avec une interface adaptée au tactile, so that l'expérience reste immersive sur petit écran. ## Acceptance Criteria 1. **Given** le visiteur est sur mobile (< 768px) **When** il accède à la navigation **Then** le "Chemin Libre" affiche les zones en cards verticales scrollables (`ZoneCard`) 2. **And** chaque `ZoneCard` affiche : illustration, nom de la zone, statut (visité/nouveau/verrouillé) 3. **And** une ligne décorative relie les cards visuellement (effet chemin) 4. **And** un tap sur une zone navigue vers la section correspondante 5. **And** la zone Contact affiche un cadenas si `contactUnlocked` est `false` 6. **Given** la bottom bar mobile est affichée **When** le visiteur interagit **Then** 3 icônes sont accessibles : Carte (ouvre le Chemin Libre), Progression (affiche le %), Paramètres 7. **And** les touch targets font au minimum 48x48px 8. **And** la bottom bar est fixe et toujours visible 9. **And** le narrateur s'affiche au-dessus de la bottom bar quand actif ## Tasks / Subtasks - [x] **Task 1: Créer le composant ZoneCard** (AC: #1, #2, #5) - [x] Créer `frontend/app/components/feature/ZoneCard.vue` - [x] Props : zone (MapZone), isVisited, isLocked, isCurrent - [x] Afficher illustration, nom traduit, statut visuel - [x] Icône cadenas si verrouillé - [x] Badge "Nouveau" si non visité - [x] Checkmark si visité - [x] **Task 2: Créer le composant CheminLibre** (AC: #1, #3, #4) - [x] Créer `frontend/app/components/feature/CheminLibre.vue` - [x] Afficher les 5 zones en cards verticales - [x] Ligne décorative reliant les cards (SVG ou CSS) - [x] Scroll vertical natif - [x] Gestion du tap pour navigation - [x] **Task 3: Créer le composant BottomBar** (AC: #6, #7, #8) - [x] Créer `frontend/app/components/layout/BottomBar.vue` - [x] 3 boutons : Carte, Progression, Paramètres - [x] Touch targets minimum 48x48px - [x] Position fixe en bas - [x] Variable CSS --bottom-bar-height pour le spacing - [x] **Task 4: Intégrer le drawer Chemin Libre** (AC: #1) - [x] Au tap sur Carte dans BottomBar, ouvrir le CheminLibre - [x] Le CheminLibre s'affiche en slide-up depuis le bas - [x] Overlay pour fermer en tapant à l'extérieur - [x] Handle de glissement pour fermer - [x] **Task 5: Intégrer le modal Progression** (AC: #6) - [x] Au tap sur Progression, afficher le détail - [x] Réutiliser le composant ProgressBar avec compact mode - [x] Afficher la liste des sections visitées/restantes - [x] **Task 6: Intégrer les paramètres** (AC: #6) - [x] Au tap sur Paramètres, ouvrir un drawer - [x] Options : langue, mode Express (lien CV), réinitialiser - [x] Consentement RGPD accessible - [x] **Task 7: Gérer le positionnement du narrateur** (AC: #9) - [x] Variable CSS --bottom-bar-height définie - [x] Le NarratorBubble utilise cette variable pour son bottom - [x] Pas de chevauchement entre narrateur et bottom bar - [x] **Task 8: Responsive design** - [x] BottomBar visible uniquement < 768px - [x] CheminLibre adapté aux petits écrans - [x] Safe-area-inset pour les appareils avec notch - [x] **Task 9: Tests et validation** - [x] Build validé sans erreurs - [x] Touch targets 48px minimum (min-w-12 min-h-12) - [x] Navigation entre zones fonctionnelle - [x] Drawer Chemin Libre avec slide-up animation - [x] Narrateur positionné au-dessus de la bottom bar ## Dev Notes ### Composant ZoneCard ```vue ``` ### Composant CheminLibre ```vue ``` ### Composant BottomBar ```vue ``` ### Composant ProgressDetail (pour le modal) ```vue ``` ### Composant SettingsDrawer ```vue ``` ### Clés i18n **fr.json :** ```json { "zone": { "locked": "Verrouillé", "visited": "Visité", "new": "À découvrir", "newBadge": "Nouveau" }, "cheminLibre": { "title": "Chemin Libre" }, "bottomBar": { "map": "Carte", "progress": "Progression", "settings": "Options" }, "settings": { "title": "Paramètres", "language": "Langue", "expressMode": "Mode Express", "expressModeDesc": "Navigation rapide sans aventure", "saveProgress": "Sauvegarder ma progression", "saveProgressDesc": "Permet de reprendre là où vous vous êtes arrêté", "reset": "Réinitialiser ma progression", "confirmReset": "Êtes-vous sûr de vouloir réinitialiser votre progression ?" } } ``` **en.json :** ```json { "zone": { "locked": "Locked", "visited": "Visited", "new": "To discover", "newBadge": "New" }, "cheminLibre": { "title": "Free Path" }, "bottomBar": { "map": "Map", "progress": "Progress", "settings": "Settings" }, "settings": { "title": "Settings", "language": "Language", "expressMode": "Express Mode", "expressModeDesc": "Quick navigation without adventure", "saveProgress": "Save my progress", "saveProgressDesc": "Allows you to resume where you left off", "reset": "Reset my progress", "confirmReset": "Are you sure you want to reset your progress?" } } ``` ### Variable CSS pour la Bottom Bar ```css /* frontend/app/assets/css/main.css ou variables.css */ :root { --bottom-bar-height: 64px; } /* Padding bottom pour le contenu principal sur mobile */ @media (max-width: 767px) { .main-content { padding-bottom: calc(var(--bottom-bar-height) + 1rem); } } ``` ### Dépendances **Cette story nécessite :** - Story 3.4 : ProgressBar composant - Story 3.5 : Store de progression - Story 3.2 : NarratorBubble (pour le positionnement) **Cette story prépare pour :** - Story 4.2 : Intro narrative (navigation mobile) - Epic 4 : Chemins narratifs (utilise la navigation) ### Project Structure Notes **Fichiers à créer :** ``` frontend/app/components/ ├── feature/ │ ├── ZoneCard.vue # CRÉER │ ├── CheminLibre.vue # CRÉER │ ├── ProgressDetail.vue # CRÉER │ └── SettingsDrawer.vue # CRÉER └── layout/ └── BottomBar.vue # CRÉER ``` **Fichiers à modifier :** ``` frontend/app/layouts/default.vue # AJOUTER BottomBar frontend/app/assets/css/main.css # AJOUTER variables CSS frontend/i18n/fr.json # AJOUTER traductions frontend/i18n/en.json # AJOUTER traductions ``` ### References - [Source: docs/planning-artifacts/epics.md#Story-3.7] - [Source: docs/planning-artifacts/ux-design-specification.md#Mobile-Navigation] - [Source: docs/planning-artifacts/ux-design-specification.md#Bottom-Bar] ### Technical Requirements | Requirement | Value | Source | |-------------|-------|--------| | Breakpoint mobile | < 768px | Epics | | Touch targets | 48x48px minimum | WCAG | | Bottom bar height | 64px | Décision technique | | Safe area | env(safe-area-inset-bottom) | iOS | ## Dev Agent Record ### Agent Model Used Claude Opus 4.5 (claude-opus-4-5-20251101) ### Debug Log References - Build validé sans erreurs bloquantes - Warning connu sur HeroType import dupliqué (non bloquant) ### Completion Notes List - ZoneCard utilise `emoji` de MapZone (pas `icon` comme dans la spec originale) - SettingsDrawer utilise un lien vers /resume au lieu d'un toggle expressMode - ProgressDetail réutilise ProgressBar avec mode compact - Toutes les transitions respectent prefers-reduced-motion - Safe-area-inset géré pour iOS devices ### Change Log | Date | Change | Author | |------|--------|--------| | 2026-02-04 | Story créée avec contexte complet | SM Agent | | 2026-02-07 | Implémentation complète | Dev Agent | ### File List **Fichiers créés :** - `frontend/app/components/feature/ZoneCard.vue` - `frontend/app/components/feature/CheminLibre.vue` - `frontend/app/components/feature/ProgressDetail.vue` - `frontend/app/components/feature/SettingsDrawer.vue` - `frontend/app/components/layout/BottomBar.vue` **Fichiers modifiés :** - `frontend/app/layouts/default.vue` - Ajout BottomBar et padding mobile - `frontend/app/layouts/adventure.vue` - Ajout BottomBar et padding mobile - `frontend/app/assets/css/main.css` - Variable CSS --bottom-bar-height - `frontend/i18n/fr.json` - Traductions zone, cheminLibre, bottomBar, settings - `frontend/i18n/en.json` - Traductions zone, cheminLibre, bottomBar, settings