# GAB-203 · PlayEngineMixedActivityStepper — « Stepper multi-format »

**Archétype / renderer_key :** `text_cta` (cartographie) · **module :** EdTechPlayEngine
**Critère validé :** changer le JSON change le stepper sans modifier le HTML. ✅ check.py 12/12.

## Pack (structure officielle par-GAB)
```
GAB-203/
  renderer.html            ← moteur stepper (ne pas modifier par instance)
  instance.example.json    ← SOURCE DE VÉRITÉ (contenu réel, à plat)
  schema.contract.json     ← contrat de validation
  README-contract.md       ← ce fichier
```

## Champs requis (instance, à plat)
`gab_id` · `stepper_id` · `title` · `steps[]` · `progress_label` · `primary_cta`

Optionnels : `initial_step_index`, `back_cta`, `skip_cta`, `skip_blocked_message`.

## Structure d'une étape (steps[])
Chaque objet step porte : `index`, `emoji`, `title`, `sub`, `mod_class`, `mod_label`, `module_owner`, `skippable`.

## Ce qui vient du JSON vs HTML
- **JSON** : liste des étapes, libellés (emoji/title/sub), module_owner par étape, règle skippable, libellés des boutons (back/skip/next), message de blocage skip.
- **HTML** : stepper-row, barre de progression, contrôles, mise en page, chips de module, animations.

## Garde-fous (child_safety)
- **PlayEngine orchestre, ne possède pas** : module_owner est toujours explicite dans chaque step — jamais implicite.
- **BLOCKED** si `steps` vide/absent, `stepper_id` absent, ou `title` absent.
- **skip refusé si `skippable:false`** : le moteur affiche `skip_blocked_message` et bloque la navigation.
- **0 écriture XP/badge/reward** : ce gabarit n'attribue rien, délègue à PlayKit.

## QA à vérifier
1. Modifier `title` d'une step → rendu change sans toucher au HTML.
2. `steps:[]` → BLOCKED propre.
3. Step `skippable:false` → clic skip → message bloquant 2,2s.
4. Step `skippable:true` → clic skip → avance d'une étape.
5. Injection via `ENGINE.init(extInstance)` → rendu change dynamiquement.
6. Responsive 375/768/1024 — stepper-row scrollable sans débordement.

## Dépendances (external_refs / dependencies)
Ce gabarit est autonome (pas de dépendance vers d'autres GAB de ce lot).
Il est typiquement précédé de GAB-201 (session intro) et suivi de GAB-205 (session end summary).
Les étapes référencées (`module_owner`) sont résolues par GAB-204 (ProviderBridge) — composant architectural externe à ce GAB.

## Source
`INDEX-300-playengine-composite-GAB-201-205-PLAYABLE.html` (stage `data-tpl="203"`, handlers `stGo/stMove/stSkip/stRender`, constante `ST_STEPS`).
