{
  "contract_version": "gab_043_contract_v1",
  "gab_id": "GAB-043",
  "canonical_name": "CooldownTimer",
  "module_owner": "EdTechPlayKit",
  "renderer_key": "text_cta",
  "required_fields": [
    "gab_id",
    "cooldown_timer_id",
    "title",
    "body",
    "duration_seconds"
  ],
  "optional_fields": [
    "icon",
    "primary_cta",
    "cta_done_label",
    "accessibility"
  ],
  "field_types": {
    "cooldown_timer_id": "string — identifiant unique de l'instance de pause",
    "title": "string — titre affiché sous le ring (ex : 'Respire un instant')",
    "body": "string — texte de guidage affiché sous le titre",
    "duration_seconds": "number(>0, entier) — durée du compte à rebours en secondes",
    "icon": "string — emoji icône (défaut '⏳')",
    "primary_cta": "object{label:string, icon:string, action:string} — libellé CTA de démarrage",
    "cta_done_label": "string — libellé CTA une fois la pause terminée",
    "accessibility": "object{ring_aria_label:string, keyboard_navigable:boolean, prefers_reduced_motion:boolean}"
  },
  "constraints": [
    "duration_seconds doit être un nombre > 0 (entier recommandé pour le rendu).",
    "primary_cta.label est structurel (libellé du bouton) et vient du JSON.",
    "cta_done_label est affiché à la fin du compte à rebours sans rebuild HTML.",
    "La circumférence du ring (339 ≈ 2π×54) est calculée à partir du rayon SVG r=54 ; ne pas hardcoder dans l'instance."
  ],
  "blocked_conditions": [
    "title absent",
    "body absent",
    "duration_seconds invalide (absent, ≤0 ou non numérique)"
  ],
  "accessibility": [
    "ring_aria_label sur le SVG",
    "aria_live polite sur le compteur numérique",
    "focus_visible sur le bouton CTA",
    "prefers_reduced_motion (transitions raccourcies)",
    "keyboard_navigable"
  ],
  "qa_cases": [
    { "case": "instance conforme", "expected": "rendu complet, ring animé, CTA actif, 0 erreur" },
    { "case": "champ requis manquant (ex: title)", "expected": "BLOCKED listé dans le panel d'erreur" },
    { "case": "duration_seconds=3", "expected": "compte à rebours démarre à 3, ring se remplit, CTA se débloque à 0" },
    { "case": "cta_done_label personnalisé", "expected": "libellé du CTA change après la pause sans modifier le HTML" },
    { "case": "instance externe injectée via ENGINE.init(data)", "expected": "le rendu change sans modifier le HTML" },
    { "case": "responsive 375/768/1024", "expected": "aucun débordement horizontal" }
  ],
  "traceability": {
    "derived_from_core_gab": "GAB-043",
    "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)."
  }
}
