# GAB-222 · SmartSelectLevelFit — « Niveau conseillé pour toi »

**Archétype / renderer_key :** `text_cta` (cartographie) · **module :** EdTechSmartSelect
**Critère validé :** changer le JSON change le niveau affiché, l'explication et le CTA sans modifier le HTML. ✅ check.py 12/12.

## Pack (structure officielle par-GAB)
```
GAB-222/
  renderer.html            ← moteur échelle 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_fit_id` · `selected_level` (enum 5 valeurs) · `levels[]` (5 paliers) · `reason`

Optionnels : `title`, `summary`, `safety_notice`, `secondary_cta_label`, `fallback_text_summary`.

## Ce qui vient du JSON vs HTML
- **JSON** : niveau sélectionné (`selected_level`), les 5 paliers (`levels[]{key,icon,label,description,explanation,cta_label}`), la justification (`reason`), le garde-fou (`safety_notice`), le libellé du bouton secondaire.
- **HTML** : échelle interactive (5 points cliquables), chip du niveau actif, bloc explication, bloc safety, boutons CTA — layout et comportement figés.

## Archétype
SmartSelectLevelFit choisit le **niveau de DÉPART** avant l'activité. C'est une couche de sélection pure, pas d'adaptation dynamique.

## Garde-fous (child_safety)
- **Distinction 222 vs 214** : GAB-222 = point d'entrée pré-activité. GAB-214 (AdaptiveDifficultyAdjuster) = adaptation pendant/après. Ne pas confondre.
- **Langage élève obligatoire** dans `reason` et `explanation` : jamais de scores bruts, jamais de logs.
- **BLOCKED** si `selected_level` absent / `levels` vides / `reason` absent.
- **Évaluation officielle** : ce gabarit ne s'affiche pas si session notée en cours (piloté par `safety_notice` + logique appelante).

## QA à vérifier
1. Modifier `selected_level` → palier actif, explication et CTA changent sans toucher au HTML (critère d'or).
2. `levels:[]` → BLOCKED propre.
3. `reason` absent → BLOCKED propre.
4. Clic palier → chip + explication + CTA se mettent à jour instantanément.
5. `init(ext)` avec instance externe → rendu piloté par ext.
6. Responsive 375/768/1024.

## external_refs / dependencies
- **GAB-214** (AdaptiveDifficultyAdjuster) : distinction explicite — GAB-214 adapte PENDANT/APRÈS l'activité, GAB-222 CHOISIT AVANT. `do_not_use_when` : AdaptiveDifficultyAdjuster déjà en cours.
- **GAB-225** (SmartSelectReasonCard) : peut s'afficher en complément de GAB-222 pour expliquer le choix du niveau (`reason_type: level`, `source: SmartSelectLevelFit (GAB-222)`).
- **Chaîne SmartSelect** : GAB-221 ContentMatch → **GAB-222 LevelFit** → GAB-223 FormatChoice → GAB-224 Fallback → GAB-225 ReasonCard.

## Source
`INDEX-300-smartselect-GAB-221-225-PLAYABLE.html` (stage `data-tpl="222"`, handlers `lfPick`, objet `LF_LEVELS`).
