# GAB-311 · RevisionLearningIntro — « Intro de séance de révision »

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

## Pack (structure officielle par-GAB)
```
GAB-311/
  renderer.html            ← moteur intro séance révision (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
```

## Archétype
**Intro de séance** : pose le contrat de révision (objectif, durée, fatigue) avant de commencer. Gère le choix de mode (rappel ou examen) et le cas limite « aucun item ».

## Champs requis (instance, à plat)
`gab_id` · `session_id` · `title` · `body` · `mode_options[]{id,label,default}` · `contract_items[]{icon,label,detail}` · `primary_cta{label,action}` · `fallback_no_item`

Optionnels : `session_kind`, `ghost_cta{label,action}`, `panel_started_rappel`, `panel_started_examen`

## Ce qui vient du JSON vs HTML
- **JSON** : titre de séance, résumé, mode-row (labels + mode par défaut), items du contrat (icône, label, détail), libellé des boutons CTA, texte du panel de lancement, message fallback vide.
- **HTML** : structure mode-row, animation contrat (stagger par item), boutons structurels (primary/ghost), layout, panels ok/warn/bad.

## Garde-fous (child_safety)
- **Anti-invention** : le moteur n'invente jamais de contenu pédagogique. Contenu manquant → `_TODO` dans l'instance, jamais halluciné.
- **Fallback no-item** : le message d'absence de révision vient du JSON (`fallback_no_item`), jamais en dur.
- **Modes** : les libellés et l'état `default` viennent du JSON — le moteur ne fixe pas de mode par défaut hardcodé.
- **BLOCKED** si `title` absent / `mode_options` vide / `contract_items` vide / `fallback_no_item` absent.

## QA à vérifier
1. Modifier `title` / `body` / `contract_items` → rendu change sans toucher au HTML (critère d'or).
2. `mode_options:[]` → BLOCKED propre.
3. Clic mode examen → mode actif bascule, panel démarrage adapté.
4. CTA principal → contrat animé (stagger), bouton disabled, panel ok.
5. Ghost CTA → panel warn `fallback_no_item`.
6. Instance externe injectée via `ENGINE.init(ext)` → rendu change.
7. Responsive 375/768/1024 — aucun débordement horizontal.

## Source
`INDEX-300-revisionlearning-GAB-311-315-PLAYABLE.html` (stage `data-tpl="311"`, handlers `d311Mode`, `d311Start`, `d311Empty`).

## external_refs / dependencies
- **GAB-312** — RevisionLearningPriorityQueue : étape suivante de la séance (file de priorité des items).
- **GAB-313** — RevisionLearningSpacedRepetitionCard : révision item par item après le tri.
