# GAB-156 · GameLevelSelect — « Sélection de niveau »

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

## Pack (structure officielle par-GAB)
```
GAB-156/
  renderer.html            ← moteur sélection de niveau (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` · `level_select_id` · `title` · `levels[]{id, stars, label, description}` · `primary_cta{label_idle, label_selected_prefix}`

Optionnels : `_note_dev`, `renderer_key`.

## Ce qui vient du JSON vs HTML
- **JSON** : titre hero, chaque niveau (stars emoji, label, description), libellé idle du CTA, préfixe du libellé après sélection.
- **HTML** : grille CSS, états `selected`, CTA désactivé jusqu'à sélection, responsive, layout.

## Archétype et use_when
- Utilisé **avant un mini-jeu** pour que l'élève choisisse sa difficulté (2 à 4 niveaux).
- Ne pas utiliser pour un choix de scénario narratif (→ GAB-049) ni pour un choix de problématique (→ GAB-148).
- Si un seul niveau disponible (pas de variante), ce gabarit est superflu.

## Garde-fous (child_safety)
- Les descriptions de difficulté doivent refléter la réalité du jeu (ex : "Chrono serré" = vraie contrainte côté moteur).
- `primary_cta.label_selected_prefix` concaténé avec `level.label` forme le libellé final ; s'assurer que la combinaison est grammaticalement correcte en français.
- BLOCKED si `levels` vide, `title` absent, ou `primary_cta.label_idle` absent.

## QA à vérifier
1. Modifier un `label` ou une `description` → rendu change sans toucher au HTML (critère d'or).
2. `levels:[]` → BLOCKED propre.
3. Clic sur un niveau → bouton CTA activé avec le bon libellé.
4. Clic sur un second niveau → sélection bascule correctement.
5. Responsive 375/768/1024 : 1 colonne sur mobile.

## Source
`INDEX-300-gamelearning-GAB-156-160-PLAYABLE.html` (stage `data-tpl="156"`, handler `lsPick`).

## Références hors-lot (external_refs / dependencies)
- **GAB-049** (ScenarioChoice) : alternative pour choix de scénario narratif.
- **GAB-148** (ProblematicsChoice) : alternative pour choix de problématique.
- **PlayKit / Gamification** : le niveau sélectionné ici est transmis au moteur de jeu qui l'utilise pour calibrer les paramètres (chrono, nb erreurs max, etc.).
