# GAB-210 · PlayEngineUnsupportedModuleFallback — « Fallback module non supporté »

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

## Pack (structure officielle par-GAB)
```
GAB-210/
  renderer.html            ← moteur fallback (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` · `fallback_id` · `title` · `body` · `module_owner` · `fallback_reason` · `step_status` · `primary_cta{label,action}`

Optionnels : `module_ref`, `distinction_items[]`, `skip_cta{label,label_disabled,action}`.

## Ce qui vient du JSON vs HTML
- **JSON** : titre du bloc, corps du message, module_owner (source de vérité doctrinaire), ref, raison du fallback, step_status (pilote skip), libellés des boutons, distinctions doctrinaires.
- **HTML** : carte pointillée coral, chaîne de responsabilité 204→210, grille détails, bloc distinctions, boutons structurels, layout, fallback BLOCKED.

## Archétype
Affiché par PlayEngine quand un bloc d'une session composite rencontre un `module_owner` inconnu ou non allowlisté par GAB-204 (ProviderBridge). Fait partie de la **couche résilience** PlayEngine (vague 12B, GAB-206 à GAB-210).

## Règle doctrinaire step_status
- `step_status = 'optional'` → bouton skip **activé** (`skip_cta.label`)
- `step_status = 'mandatory'` → bouton skip **désactivé** (`skip_cta.label_disabled`, `disabled=true`)

## Garde-fous (child_safety)
- **BLOCKED** si `title`, `body`, `module_owner`, `fallback_reason`, `step_status` ou `primary_cta` absent.
- **Anti-confusion** : ce GAB ne remplace pas SessionAccessGate (accès refusé) ni ErrorFallbackBlock (erreur serveur) — distinctions explicites dans `distinction_items`.
- **module_owner = source de vérité** (jamais "provider" — renommage doctrinaire vague 12B).

## QA à vérifier
1. Modifier `title`/`body`/`module_owner` → rendu change sans toucher au HTML (critère d'or).
2. `step_status:'mandatory'` → bouton skip désactivé + `label_disabled` affiché.
3. Champ requis absent → BLOCKED propre lisible.
4. `distinction_items:[]` ou absent → bloc distinctions masqué.
5. Responsive 375/768/1024.

## Source
`INDEX-300-playengine-composite-GAB-206-210-PLAYABLE.html` (bloc `data-tpl="210"`, handlers `ufToggle`, `peConfirm`).

## external_refs / dependencies
- **GAB-204** (ProviderBridge) : parsing + allowlist en amont — ce GAB est affiché quand GAB-204 détecte un module non supporté.
- **SessionAccessGate** : route alternative si accès refusé (non couvert par GAB-210).
- **ErrorFallbackBlock** : route alternative si erreur serveur globale (non couvert par GAB-210).
