{
  "contract_version": "gab_223_contract_v1",
  "gab_id": "GAB-223",
  "canonical_name": "SmartSelectFormatChoice",
  "module_owner": "EdTechSmartSelect",
  "renderer_key": "text_cta",
  "required_fields": [
    "gab_id",
    "format_choice_id",
    "title",
    "recommended_format",
    "formats"
  ],
  "optional_fields": [
    "subtitle",
    "header_icon",
    "info_label",
    "a11y_note",
    "cta_secondary_label",
    "fallback_text_summary"
  ],
  "field_types": {
    "recommended_format": "enum['visual','exercise','memory','audio','interactive','story','game','mixed_session']",
    "formats": "array<{key:string, icon:string, label:string, description:string, available:boolean, info:string, cta_primary:string}>",
    "a11y_note": "string (HTML autorisé pour les balises <b>)"
  },
  "constraints": [
    "formats doit contenir au moins 2 entrées.",
    "recommended_format doit correspondre à un key existant dans formats[].",
    "Un format avec available:false est affiché grisé avec indicateur 🚫 — jamais masqué.",
    "info et cta_primary viennent du JSON — aucun texte en dur dans le moteur.",
    "SmartSelect refuse un format sans accessibilité (cf a11y_note)."
  ],
  "blocked_conditions": [
    "formats absent ou vide",
    "recommended_format absent",
    "format_choice_id absent"
  ],
  "accessibility": [
    "keyboard_navigable",
    "focus_visible",
    "prefers_reduced_motion",
    "fallback_text",
    "unavailable_format_signaled_visually_and_aria"
  ],
  "qa_cases": [
    { "case": "instance conforme", "expected": "rendu complet, format recommandé présélectionné, justification affichée, 0 erreur" },
    { "case": "champ requis manquant (formats vide)", "expected": "BLOCKED listant le champ" },
    { "case": "recommended_format absent", "expected": "BLOCKED — aucune présélection impossible" },
    { "case": "format available:false", "expected": "affiché grisé avec 🚫, clic ignoré (pas de sélection)" },
    { "case": "clic sur format disponible", "expected": "format sélectionné visuellement, info et CTA mis à jour depuis JSON" },
    { "case": "instance externe injectée via init(ext)", "expected": "le rendu change sans modifier le HTML" },
    { "case": "responsive 375/768/1024", "expected": "grille 2 colonnes sur mobile, 4 colonnes desktop, aucun débordement" }
  ],
  "traceability": {
    "derived_from_core_gab": "GAB-223",
    "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). Source : INDEX-300-smartselect-GAB-221-225-PLAYABLE.html, stage data-tpl='223', handlers fcPick/FC_FORMATS."
  }
}
