# GAB-387 · MediaLearningExternalEmbed — « Embed externe »

**Archétype / renderer_key :** `text_cta` (cartographie) · **module :** EdTechMediaLearning
**Critère validé :** changer le JSON change les libellés et messages sans modifier le HTML. ✅ check.py 12/12.

## Pack (structure officielle par-GAB)
```
GAB-387/
  renderer.html            ← moteur embed externe sous consentement (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` · `embed_id` · `provider_label` · `blocked_message` · `consent_cta_label` · `fallback_cta_label` · `consent_panel_message` · `fallback_panel_message`

Optionnels : `title`, `consent_success_label`, `minors_warning`, `revocable_consent`, `embed_url`, `provider_policy_url`.

## Ce qui vient du JSON vs HTML
- **JSON** : tous les libellés (bouton consentement, bouton fallback), le message de blocage, le message post-accord, le message fallback, le libellé fournisseur.
- **HTML** : layout carte, boutons structurels, panneau de réponse, animations, états disabled.

## Garde-fous (child_safety)
- **Consentement obligatoire** : aucun chargement tiers sans clic explicite de l'élève.
- **minors_warning:true** : signale que le tracking est interdit pour les mineurs — à renforcer côté serveur.
- **Fallback interne toujours disponible** : si refus ou échec embed, alternative sans fournisseur tiers.
- **BLOCKED** si l'un des 8 champs requis est absent.
- **Révocabilité** : `revocable_consent:true` = l'accord peut être retiré (à implémenter côté host).

## _TODO / Contenus manquants du source HTML
- `embed_url` : l'URL de l'embed tiers n'est pas présente dans le source playable — placeholder `_TODO`.
- `provider_policy_url` : l'URL de la politique du fournisseur n'est pas présente dans le source playable — placeholder `_TODO`.

Ces deux champs sont optionnels dans le schéma et ne bloquent pas le rendu de démo. Ils doivent être renseignés dans chaque instance réelle de production.

## QA à vérifier
1. Modifier `blocked_message` → rendu change sans toucher au HTML (critère d'or). 2. Clic « Autoriser le chargement » → panel ok, bouton désactivé « ✓ Autorisé ». 3. Clic « Voir l'alternative interne » → panel note, pas de ressource tierce. 4. `embed_id` absent → BLOCKED propre. 5. Responsive 375/768/1024.

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

## external_refs / dependencies
- **GAB-386** (MediaLearningMediaGallery) : galerie interne — ne pas utiliser GAB-387 pour une galerie interne.
- **GAB-390** (MediaLearningMediaEmptyState) : si l'embed est définitivement indisponible, basculer sur GAB-390.
