# GAB-386 · MediaLearningMediaGallery — « Galerie de médias »

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

> ⚠️ **renderer_key à concevoir (pas de moteur kit)** : `media_viewer` n'a pas de moteur de référence dans le kit de conversion. Le renderer a été dérivé directement de l'écran source (`INDEX-300-medialearning-GAB-386-390-PLAYABLE.html`, stage `data-tpl="386"`, handlers `d386Pick` / `d386Fail`).

## Pack (structure officielle par-GAB)
```
GAB-386/
  renderer.html            ← moteur galerie (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` · `gallery_id` · `items[]{id,label,icon,source_rights,alt,order,broken}` · `pedagogical_order` · `broken_item_fallback`

Optionnels : `title`, `pagination`, `mobile_perf`.

## Ce qui vient du JSON vs HTML
- **JSON** : chaque item (label, icône, source_rights, alt, ordre, état cassé), message fallback item cassé, titre galerie.
- **HTML** : grille, sélection visuelle, affichage panel droits, logique broken/fallback, layout responsive.

## Garde-fous (child_safety)
- **Anti-invention** : les 4 items (gravure/carte/graphique/photo cassée) sont extraits tels quels du HTML source. Les champs `source_rights` et `alt` de l'item cassé (item-4) portent un `_TODO` explicite — ils n'ont pas de valeur connue dans la source.
- **Droits visibles** : chaque item affiche sa source et ses droits au clic — jamais masqués.
- **Broken item isolé** : un item cassé déclenche le fallback sans bloquer les autres items de la galerie.
- **BLOCKED** si `items` vide / `gallery_id` absent / `broken_item_fallback` absent.

## _TODO / contenus manquants (anti-invention)
- `item-4 source_rights` : droits de la photo cassée non renseignés dans le HTML source.
- `item-4 alt` : texte alternatif de la photo cassée non renseigné dans le HTML source.

## QA à vérifier
1. Modifier un `label`/`source_rights` → rendu change sans toucher au HTML (critère d'or).
2. `items:[]` → BLOCKED propre.
3. Clic item normal → panel OK avec droits + ordre.
4. Clic item broken → panel WARN avec fallback.
5. Responsive 375/768/1024.

## Source
`INDEX-300-medialearning-GAB-386-390-PLAYABLE.html` (stage `data-tpl="386"`, handlers `d386Pick`, `d386Fail`).

## external_refs / dependencies
Aucune dépendance externe hors-lot. Les GAB-387 à GAB-390 du même lot (Embed, Asset IA, Annotation, État vide) sont des gabarits indépendants dans `/LOT-medialearning-GAB-386-390/`.
