--- name: gametime-ux-exercise-steps description: memory note gametime-ux-exercise-steps metadata: type: project --- # GameTime — Exercice à plusieurs étapes (ticket #54, UX 2026-07-19) Conception UX pour ajouter des **séquences d'étapes** aux exercices, sans remplacer les mesures existantes `Temps / Répétitions / Score` au niveau de la série. ## Décision structurante Les étapes sont un **rythme interne de l'exercice**, pas un nouveau mode exclusif d'exécution. - Un exercice peut conserver toutes ses mesures de série existantes : `Temps`, `Répétitions`, `Score`. - La séquence d'étapes s'ajoute par-dessus ces mesures. - Si la mesure `Répétitions` est active au niveau de la série, elle représente le nombre de **passages complets dans la séquence**. - Si la mesure `Temps` est active au niveau de la série, elle représente une fenêtre globale ou une durée cible de série, indépendante des chronos d'étapes. - Le score de série reste disponible tel que déjà conçu, y compris score libre ou score chrono. Exemple validé par le besoin utilisateur : une série peut demander de répéter 10 fois la séquence `dribble gauche -> dribble droite`, ou d'enchaîner cette séquence pendant 10 minutes, ou les deux. ## A. Création / édition d'exercice Surface concernée : `ExerciseFormScreen`, section existante `Mesures disponibles`. Ajouter une nouvelle section après les mesures disponibles et leurs valeurs par défaut : ```text Séquence d'étapes [ ] Rythmer cet exercice avec des étapes ``` Texte d'aide quand désactivé : ```text Ajoute des étapes si l'exercice doit suivre un ordre précis pendant chaque série. ``` Quand activé : ```text Séquence d'étapes Chaque passage suit ces étapes dans l'ordre. Si la série suit des répétitions, une répétition correspond à un passage complet. [Ajouter une étape] ``` ### Limite d'étapes Recommandation UX MVP : limite dure à **8 étapes** par exercice. Raison : 5-6 étapes restent lisibles pendant l'effort ; 8 couvre les exercices complexes sans rendre la progression mobile trop dense. Si l'utilisateur atteint la limite : ```text Limite atteinte Un exercice peut contenir jusqu'à 8 étapes. ``` ### Liste des étapes dans le formulaire Chaque étape est une carte compacte réordonnable, style Court Blazer : surface plate, rayon 6 px, bordure, liseré supérieur crimson si ouverte/active. Carte repliée : ```text [drag] 1. Dribble main droite [modifier] Temps · 10 s [menu] ``` ou : ```text [drag] 3. Pompes [modifier] Répétitions · 10 [menu] ``` Actions accessibles : - poignée drag-and-drop pour réordonner ; - menu `...` avec `Monter`, `Descendre`, `Dupliquer`, `Supprimer` ; - bouton/icône `Modifier l'étape` ouvrant le détail. Ne pas dépendre uniquement du drag-and-drop : `Monter` / `Descendre` doivent exister pour l'accessibilité tactile. ### Détail d'étape Ouvrir un écran ou une bottom sheet haute `Modifier l'étape`. Recommandation : **écran dédié** si le formulaire principal est déjà long ; bottom sheet acceptable seulement si elle reste plein écran. Champs : ```text Nom de l'étape [ Dribble main droite ] ``` Validation : ```text Le nom de l'étape est obligatoire. ``` Type d'étape, exclusif : ```text Type d'étape (•) Temps ( ) Répétitions ``` Si `Temps` : ```text Durée par défaut (s) [ 10 ] ``` Validation : ```text Saisis une durée supérieure à 0. ``` Si `Répétitions` : ```text Répétitions par défaut [ 10 ] ``` Validation : ```text Saisis un nombre de répétitions supérieur à 0. ``` ### Score d'étape Chaque étape peut avoir un score optionnel. ```text Score d'étape [ ] Ajouter un score pour cette étape ``` Si activé : ```text Mode de score (•) Saisie libre ( ) Chrono intégré ``` Score libre : ```text Score à saisir [ Réussites ] Unité [ paniers ] Score par défaut [ 5 ] ``` Validation : - `Le libellé du score est obligatoire.` - `L'unité du score est obligatoire.` - `Saisis un score supérieur ou égal à 0.` Score chrono : ```text Objectif de chrono par défaut (optionnel) [ 00:12 ] ``` Validation seulement si rempli : ```text Saisis un objectif supérieur à 0. ``` Recommandation UX : autoriser le score chrono surtout sur les étapes à répétitions. Sur une étape de type `Temps`, si l'utilisateur choisit aussi `Score chrono`, afficher un avertissement non bloquant : ```text Cette étape utilise déjà un compte à rebours. Le score chrono ajoute un second temps mesuré ; garde-le seulement si tu veux enregistrer une performance distincte. ``` ### États et validations du formulaire exercice - Si `Rythmer cet exercice avec des étapes` est activé, il faut au moins une étape. - Message : `Ajoute au moins une étape ou désactive la séquence.` - Chaque étape doit avoir un nom, un type, et une cible par défaut strictement positive pour son type. - Supprimer une étape demande confirmation seulement si elle contient déjà des champs remplis ou un score configuré. - Pour un exercice déjà utilisé dans des programmes, conserver l'avertissement existant : les programmes existants restent inchangés. Les étapes doivent être snapshotées comme le reste de l'exercice. ## B. Exécution pendant une séance Surface concernée : écran d'exécution déjà structuré avec : header discret, bloc `SÉRIE X/Y`, nom d'exercice, bouton médias, inputs de mesures, actions de série. ### Placement du module séquence Si l'exercice a des étapes, ajouter un module `Séquence` entre le nom de l'exercice et les inputs de mesures de série. Structure générale : ```text 00:12 Programme 1/2 · Exercice 3/8 SÉRIE 2 / 4 Dribble combo [Voir médias] SÉQUENCE Passage 1 / 10 [1] [2] [3] [4] ÉTAPE 1 / 4 Dribble main droite 10 s 00:10 [Démarrer la séquence] Résultat de la série Passages réalisés : 0 / 10 Score : -- [Terminer la série] [Passer la série] ``` Si la série n'a pas la mesure `Répétitions` active : ```text Passage en cours ``` Si la série a `Répétitions` active : ```text Passage 1 / 10 ``` Le mot `Passage` est utilisé dans l'UI pour éviter de confondre les répétitions de série avec les répétitions internes d'une étape. ### Progression des étapes Afficher une progression compacte compatible 5-6 étapes et jusqu'à 8 : - chips carrées ou petits segments `1 2 3 4` ; - étape courante : fond primaire or, texte fond ; - étapes terminées : succès ou contour primaire ; - étapes passées : contour/texte secondaire ; - étapes à venir : surface neutre. Pour plus de 6 étapes, la rangée peut défiler horizontalement, mais le label `ÉTAPE X / Y` reste toujours visible. ### Étape chronométrée État initial si c'est la première étape active de la série : ```text ÉTAPE 1 / 4 Dribble main droite Objectif : 10 s 00:10 [Démarrer la séquence] [Passer l'étape] ``` Après démarrage : ```text 00:07 [Passer l'étape] ``` Style : - compte à rebours en Anton, 56-64 px, couleur primaire or ; - label et nom en Archivo ; - liseré crimson 2 px sur le panneau ; - dans les 3 dernières secondes, flash discret du liseré ou du fond du compteur en crimson, sans nuire à la lisibilité. Son : - à `3`, `2`, `1` : bip court à chaque seconde ; - à `0` : bip long ; - à `0`, passage automatique à l'étape suivante. Enchaînement : - Si l'étape suivante est aussi chronométrée, son compte à rebours démarre immédiatement, sans pause ni bouton intermédiaire. - Si l'étape suivante est à répétitions, l'écran affiche l'étape suivante et attend l'action utilisateur `Étape suivante`. - Si c'est la dernière étape et qu'un nouveau passage doit commencer, le premier chrono du passage suivant démarre immédiatement si la première étape est chronométrée. ### Étape à répétitions Affichage : ```text ÉTAPE 3 / 4 Pompes 10 RÉPÉTITIONS [Étape suivante] [Passer l'étape] ``` - Le nombre cible utilise Anton, couleur primaire or. - `Étape suivante` valide l'étape et avance. - Il n'y a pas de compteur manuel des répétitions internes au MVP : l'utilisateur confirme quand l'étape est faite. ### Score d'étape pendant l'exécution Si l'étape a un score libre : afficher un champ compact sous le bloc principal de l'étape : ```text Score de l'étape (paniers) [ ] ``` Si l'étape est chronométrée, le score libre ne bloque jamais l'enchaînement automatique. Si l'utilisateur ne l'a pas renseigné, il pourra le corriger via le plan de séance / détail de série. Si l'étape a un score chrono et que l'étape est à répétitions : afficher un petit module `Chrono score d'étape` avec `Démarrer / Arrêter / Réinitialiser`, même logique que le score chrono de série. Recommandation UX pour éviter la surcharge : ne pas afficher de second gros compteur si l'étape elle-même est déjà chronométrée. Dans ce cas, si le score chrono est configuré, afficher l'avertissement en configuration et, en exécution, garder le compteur d'étape prioritaire. ### Passage d'une répétition/passage à l'autre Quand la dernière étape d'un passage est validée ou terminée : - incrémenter `Passages réalisés` de 1 ; - si la série a une cible de répétitions et que la cible n'est pas atteinte, commencer le passage suivant ; - si le prochain passage commence par une étape chronométrée, démarrer immédiatement le chrono ; - si le prochain passage commence par une étape à répétitions, afficher l'étape et attendre `Étape suivante`. Quand la cible de passages est atteinte : ```text Séquence terminée 10 / 10 passages réalisés ``` Le bouton principal devient ou reste : ```text Terminer la série ``` La fin de séquence ne doit pas forcément clôturer la série automatiquement, car la série peut aussi avoir un score global, un chrono score global ou une correction à faire. L'utilisateur garde le contrôle via `Terminer la série`. Si la série a `Temps` mais pas `Répétitions`, la séquence boucle tant que l'utilisateur ne termine pas la série. Le temps de série reste indépendant ; à expiration, afficher un feedback `Temps de série terminé`, mais ne pas interrompre brutalement une étape en cours. ### Articulation avec les mesures de série existantes Quand un exercice a des étapes, renommer visuellement la mesure `Répétitions` de série en contexte : ```text Passages réalisés 0 / 10 ``` Ce compteur est alimenté automatiquement par les passages terminés, avec action secondaire `Corriger` si l'utilisateur doit ajuster. Les autres mesures de série restent dans un bloc `Résultat de la série`, sous le module séquence : - `Temps de série` si actif ; - `Passages réalisés` si répétitions actif ; - `Score de série` ou `Chrono score` si actif. Ce bloc peut être compact par défaut pour ne pas écraser la séquence, mais les champs nécessaires doivent rester accessibles sans changer d'écran. ### Skip / passer Renommer le bouton de série existant en contexte : ```text Passer la série ``` Dans le module séquence : ```text Passer l'étape ``` Menu secondaire recommandé : ```text Passer ce passage ``` Comportements : - `Passer l'étape` marque l'étape comme passée et avance à la suivante. Si un chrono d'étape tourne, confirmation : `Le chrono de cette étape sera arrêté.` - `Passer ce passage` marque les étapes restantes du passage comme passées, ne compte pas ce passage dans `Passages réalisés`, puis démarre le passage suivant si la série doit continuer. - `Passer la série` conserve le comportement existant : la série est passée sans résultat de série. Si une étape est en cours, demander confirmation : `La séquence en cours sera arrêtée.` ### Pause, reprise, fermeture d'app - Pause de séance met aussi en pause le chrono d'étape et les éventuels chronos score d'étape. - À la reprise, afficher l'étape courante avec son temps restant exact. - Si l'app est tuée pendant une étape chronométrée, la reprise doit restaurer le passage, l'étape et le temps restant. UX attend la même robustesse que `ActiveRestState`. - Si un chrono arrive à zéro pendant que l'app est en arrière-plan, à la réouverture afficher l'état recalculé : étape suivante ou passage suivant selon le temps écoulé. Si plusieurs étapes chronométrées se sont enchaînées, l'app peut avancer jusqu'à la première étape à répétitions ou jusqu'à la fin calculée du passage. ### Plan de séance / édition ponctuelle Dans le `Plan de séance`, une série avec étapes garde son état global `À faire / En cours / Terminée / Passée`, mais le détail de série doit pouvoir afficher les étapes enregistrées : ```text Série 2 / 4 Passages réalisés : 7 / 10 Passage 1 Étape 1 · Terminée · 10 s Étape 2 · Terminée · 10 reps Étape 3 · Passée ``` Édition ponctuelle d'une série passée/terminée : ne rejoue pas la séquence en mode interactif. Elle permet de corriger les résultats enregistrés : passages réalisés, score de série, scores d'étapes. La position courante de séance ne bouge pas. ## Exigences remontées à Architect - Les étapes doivent être snapshotées avec l'exercice dans les programmes/séances/historiques. - Chaque étape : position, nom, type `time` ou `reps`, cible par défaut > 0, score optionnel avec mode et valeurs par défaut selon les règles existantes. - L'état d'exécution doit suivre : passage courant, étape courante, états des étapes du passage, temps restant/accumulé des chronos d'étapes, scores d'étapes, et robustesse après pause/kill app. - Les résultats historiques doivent pouvoir stocker les résultats d'étapes par série et par passage, sans remplacer les résultats de série existants.