# GAB-020 · SessionUnsupportedFeatureFallback — « Fallback capacité non disponible »

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

## Pack (structure officielle par-GAB)
```
GAB-020/
  renderer.html            ← moteur fallback capacité (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` · `primary_cta{label,action,icon?}` · `unsupported_feature{label,icon}` · `fallback_feature{label,icon}`

Optionnels : `confirm_message`

## Ce qui vient du JSON vs HTML
- **JSON** : titre (capacité manquante), corps (message rassurant + alternative), labels du swap visuel (feature OFF et ON), libellé + icône du CTA, message de confirmation post-clic.
- **HTML** : layout de la carte sky, composant swap visuel (off → on), bouton structurel, fallback BLOCKED.

## Archétype
GAB-020 est un **écran de dégradation gracieuse** (graceful degradation). Il ne signale pas une erreur mais propose une alternative immédiate quand une capacité matérielle/navigateur est absente (micro, caméra, API tiers). Ton : rassurant, positif, sans blocage.

## Garde-fous (child_safety)
- **Pas de message d'erreur alarmant** : `title` doit nommer la capacité manquante, pas crier "Erreur".
- **Alternative toujours proposée** : `fallback_feature` obligatoire — jamais un cul-de-sac.
- **BLOCKED** si `title`, `body`, `primary_cta`, `unsupported_feature` ou `fallback_feature` absent.

## Cas d'usage (depuis source INDEX-300)
**use_when :** capacité absente (micro, caméra, API) · navigateur/appareil non compatible · proposer une alternative gracieuse.
**do_not_use_when :** perte réseau temporaire (→ GAB-009) · erreur provider (→ GAB-011) · accès verrouillé (→ GAB-010).

## QA à vérifier
1. Modifier `title`/`body`/`primary_cta.label` → rendu change sans toucher au HTML (critère d'or).
2. Supprimer `primary_cta` → BLOCKED propre.
3. Clic CTA → `confirm_message` affiché, bouton désactivé.
4. `confirm_message` absent → feedback générique "Mode alternatif activé."
5. Responsive 375/768/1024.

## external_refs / dependencies
Aucune référence hors-lot. GAB-020 est autonome dans le lot `LOT-playengine-GAB-016-020`.

## Source
`INDEX-300-playengine-GAB-016-020-PLAYABLE.html` (stage `data-tpl="20"`, handler `peConfirm()`, styles `.unsup-*`).
