{
  "contract_version": "gab_381_contract_v1",
  "gab_id": "GAB-381",
  "canonical_name": "MediaLearningIntro",
  "module_owner": "EdTechMediaLearning",
  "renderer_key": "media_viewer",
  "required_fields": [
    "gab_id",
    "media_intro_id",
    "media_type",
    "title",
    "source_info",
    "rights",
    "contract_items"
  ],
  "optional_fields": [
    "description",
    "alt_transcript",
    "no_autoplay",
    "cta_prepare_label",
    "cta_rights_label",
    "feedback_prepared",
    "feedback_rights",
    "minor_safety",
    "fallback"
  ],
  "field_types": {
    "media_type": "enum['video','audio','image','mixed']",
    "title": "string",
    "source_info": "string",
    "rights": "string",
    "alt_transcript": "string",
    "no_autoplay": "boolean",
    "contract_items": "array<{icon:string, label:string, detail:string}>",
    "cta_prepare_label": "string",
    "cta_rights_label": "string",
    "feedback_prepared": "string",
    "feedback_rights": "string",
    "minor_safety": "boolean",
    "fallback": "string"
  },
  "constraints": [
    "no_autoplay doit être true par défaut — jamais forcer la lecture automatique.",
    "contract_items doit contenir au minimum les items Source/droits, Accessibilité et No autoplay.",
    "media_type doit correspondre au média réellement exposé.",
    "rights doit être renseigné — un média sans droits explicites est BLOQUÉ.",
    "alt_transcript requis pour video et audio (accessibilité RGAA/WCAG 1.2)."
  ],
  "blocked_conditions": [
    "media_intro_id absent (BLOCKED)",
    "media_type absent (BLOCKED)",
    "rights absent (BLOCKED)",
    "contract_items vide ou absent (BLOCKED)"
  ],
  "accessibility": [
    "keyboard_navigable",
    "focus_visible",
    "prefers_reduced_motion",
    "no_autoplay_enforced",
    "alt_transcript_available",
    "fallback_text"
  ],
  "qa_cases": [
    { "case": "instance conforme", "expected": "rendu complet, contrat animé, 0 erreur" },
    { "case": "rights absent", "expected": "BLOCKED listant 'rights absent'" },
    { "case": "contract_items vide", "expected": "BLOCKED listant 'contract_items vide ou absent'" },
    { "case": "media_type absent", "expected": "BLOCKED listant 'media_type absent'" },
    { "case": "clic 'Vérifier & préparer le média'", "expected": "items contrat révélés, feedback_prepared affiché, bouton désactivé" },
    { "case": "clic 'Droits & source'", "expected": "feedback_rights affiché" },
    { "case": "instance externe injectée via init(ext)", "expected": "rendu change sans modifier le HTML" },
    { "case": "responsive 375/768/1024", "expected": "aucun débordement horizontal" }
  ],
  "traceability": {
    "derived_from_core_gab": "GAB-381",
    "note": "Ce schema VALIDE l'instance. Le contrat pédagogique complet (input_contract/validation_logic/feedback_scoring_logic) vit dans le CORE-GAB officiel, pas ici (évite la duplication)."
  }
}
