# GAB-029 · EmptyStateBlock — « État vide transverse »

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

## Pack (structure officielle par-GAB)
```
GAB-029/
  renderer.html            ← moteur état vide (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` · `empty_state_id` · `title` · `body`
Optionnels : `icon`, `cta{label, icon?, action}`.

## Ce qui vient du JSON vs HTML
- **JSON** : icône, titre, corps, libellé et action du bouton CTA.
- **HTML** : layout centré, animation float, style dashed-border card, bouton structurel, slot slots.

## Archétype
`EmptyStateBlock` est un état vide **transverse** : utilisable dans n'importe quel contexte où une liste, une ressource ou un contenu est absent. Il guide l'utilisateur vers une première action via le CTA optionnel.

## Garde-fous (child_safety)
- **BLOCKED** si `title` absent OU `body` absent — le bloc n'a aucun sens sans ces deux champs.
- `icon` absent → bloc s'affiche sans illustration flottante (dégradation gracieuse, pas de BLOCKED).
- `cta` absent → bouton masqué (dégradation gracieuse).
- Ne pas confondre avec GAB-030 (erreur de chargement) ni ENG-012 (session vide moteur).

## QA à vérifier
1. Modifier `title`/`body` → rendu change sans toucher au HTML (critère d'or).
2. `title` absent → BLOCKED propre.
3. `body` absent → BLOCKED propre.
4. `cta` absent → bouton masqué, rendu fonctionnel.
5. `icon` absent → pas d'élément flottant, aucun débordement.
6. Clic CTA → panel confirmation avec `cta.action`.
7. Responsive 375/768/1024.

## external_refs / dependencies
- **do_not_use_when** erreur de chargement → GAB-030
- **do_not_use_when** session vide moteur → ENG-012
- **do_not_use_when** chargement en cours (pas d'état vide à afficher)

## Source
`INDEX-300-playkit-GAB-026-030-PLAYABLE.html` (stage `data-tpl="29"`, CSS `.empty-card`, handler générique `peConfirm`).
