# Schéma canonique — Templates JSON Fidulia

> Tout template de la bibliothèque Fidulia respecte ce schéma.
> Produit par : Agent Veille (50) → validé par Agent Design System (21) → exécuté par Agent Graphiste (31).
> Bibliothèque stockée dans : `Contexte/Design-System/Templates/`

---

## Schéma complet

```json
{
  "template_id": "string — identifiant kebab-case unique (ex: carousel-autorite-cgp)",
  "version": "string — YYYY-MM-DD de la dernière mise à jour",
  "type": "carousel | banniere | post-image | citation-visuelle | infographie | cover-newsletter",
  "niche": ["cgp", "avocat", "expert-comptable", "notaire", "medecin", "generaliste"],
  "positionnement": "autorite | proximite | innovant",
  "slides_count": "integer — nombre de slides (carrousels uniquement, sinon 1)",

  "palette": {
    "primary": "#hex — couleur dominante (fond principal)",
    "secondary": "#hex — couleur secondaire (accents structurels)",
    "accent": "#hex — couleur signal (chiffres, mots-clés, ~5% de la composition)",
    "background": "#hex — fond de base",
    "text_main": "#hex — texte principal",
    "text_muted": "#hex — sous-titres, légendes"
  },

  "typography": {
    "title_font": "string — nom exact du serif de titres. Défaut Fidulia : Playfair Display (Variable Font locale).",
    "title_font_url": "string — URL Google Fonts OU chemin depuis la racine projet (ex: Contexte/Design-System/Fonts/PlayfairDisplay-VF.ttf).",
    "body_font": "string — nom exact du sans-serif du corps. Défaut Fidulia : Raleway.",
    "body_font_url": "string",
    "display_font": "string — nom exact du sans-serif géométrique des CHIFFRES display (KPIs, stats-hero, chiffre-fort de slides). Défaut Fidulia : League Spartan. Règle : dès qu'un chiffre est mis en avant, c'est display_font.",
    "display_font_url": "string",
    "title_weight": "integer — Playfair 400 | 500 | 600 | 700. Éviter 900 (le poids max de Playfair est déjà très dense).",
    "title_transform": "none — les titres serif ne se mettent PAS en MAJUSCULES. Uppercase réservé aux kickers en Raleway Bold.",
    "title_tracking": "string — ex: -0.01em pour titres, -0.02em pour chiffres display",
    "scale": {
      "display": "integer px — chiffre display en League Spartan (KPI hero)",
      "title": "integer px — H1/H2 en Playfair Display",
      "subtitle": "integer px — sous-titre ou chute en Playfair Italic",
      "body": "integer px — corps en Raleway",
      "caption": "integer px — légende/source en Raleway"
    }
  },

  "dimensions": {
    "width_px": "integer — largeur en px (référence 2x Retina)",
    "height_px": "integer — hauteur en px",
    "ratio": "string — ex: 1:1 | 4:5 | 4:1",
    "safe_zone_px": "integer — marge de sécurité sur chaque bord"
  },

  "slides": [
    {
      "position": "integer — 1-based",
      "role": "hook | contenu | transition | cta | couverture",
      "layout": "titre-centre | titre-gauche | titre-image | chiffre-hero | liste-puces | split-50-50 | full-image-overlay",
      "background_variant": "primary | secondary | light | dark | image",
      "zones": ["titre", "sous-titre", "corps", "chiffre", "visuel", "kicker", "cta", "numero"],
      "regles": "string — contrainte spécifique à cette slide (ex: max 8 mots pour le titre)"
    }
  ],

  "composants": {
    "border_radius": "integer px",
    "card_background": "#hex",
    "divider_color": "#hex",
    "icon_style": "filaire | plein | duotone",
    "icon_library": "Lucide | Phosphor | Heroicons"
  },

  "usage": {
    "contexte": "string — quand utiliser ce template",
    "niche_ideale": "string — pour quelle profession ce template est le plus adapté",
    "ton": "string — ex: pédagogique, assertif, narratif",
    "exemples_contenu": ["string — ex: '5 erreurs LinkedIn des CGP'"]
  },

  "nano_banana": {
    "style": "string — photorealistic | editorial illustration | 3D render | minimalist",
    "ambiance": ["adjectif1", "adjectif2", "adjectif3"],
    "negative_prompt": "string — ce qu'on exclut systématiquement"
  },

  "source": "string — origine du template (blog, exemple LinkedIn, veille Agent 50, etc.)",
  "statut": "proposition | validé | actif | archivé"
}
```

---

## Valeurs autorisées — champs enum

### `type`
| Valeur | Format LinkedIn | Dimensions référence |
|---|---|---|
| `carousel` | Carrousel natif | 1080×1350 px |
| `banniere` | Bannière profil | 1584×396 px |
| `post-image` | Image de post | 1080×1350 px (4:5) |
| `citation-visuelle` | Image portrait | 1080×1350 px (4:5) |
| `infographie` | Portrait | 1080×1350 px |
| `cover-newsletter` | Cover LinkedIn Newsletter | 1200×627 px |

### `slides[].layout`
| Valeur | Description visuelle |
|---|---|
| `titre-centre` | Titre centré, fond uni — slide de hook ou transition |
| `titre-gauche` | Titre aligné gauche, espace pour visuels à droite |
| `titre-image` | Titre sur overlay d'une image plein fond |
| `chiffre-hero` | Grand chiffre occupant 60% de la slide |
| `liste-puces` | 3–5 points courts avec icônes ou numéros |
| `split-50-50` | Colonne gauche texte / colonne droite chiffre ou icône |
| `full-image-overlay` | Image plein fond avec texte superposé |

### `slides[].role`
| Valeur | Description |
|---|---|
| `hook` | Slide 1 — accroche, promesse, titre fort |
| `contenu` | Slides 2 à N-2 — développement, 1 idée par slide |
| `transition` | Slide intermédiaire de respiration visuelle |
| `cta` | Dernière slide — appel à l'action, contact |
| `couverture` | Bannière ou post-image (format non-carrousel) |

---

## Exemple complet — `carousel-autorite-cgp`

```json
{
  "template_id": "carousel-autorite-cgp",
  "version": "2026-06-05",
  "type": "carousel",
  "niche": ["cgp", "expert-comptable"],
  "positionnement": "autorite",
  "slides_count": 8,

  "palette": {
    "primary": "#0C132A",
    "secondary": "#1F2937",
    "accent": "#D70459",
    "background": "#0C132A",
    "text_main": "#FFFFFF",
    "text_muted": "#D1D5DB"
  },

  "typography": {
    "title_font": "Playfair Display",
    "title_font_url": "Contexte/Design-System/Fonts/PlayfairDisplay-VF.ttf",
    "body_font": "Raleway",
    "body_font_url": "Contexte/Design-System/Fonts/Raleway-VF.ttf",
    "display_font": "League Spartan",
    "display_font_url": "Contexte/Design-System/Fonts/LeagueSpartan-VF.ttf",
    "title_weight": 700,
    "title_transform": "none",
    "title_tracking": "-0.01em",
    "scale": {
      "display": 150,
      "title": 80,
      "subtitle": 38,
      "body": 30,
      "caption": 24
    }
  },

  "dimensions": {
    "width_px": 1080,
    "height_px": 1350,
    "ratio": "4:5",
    "safe_zone_px": 80
  },

  "slides": [
    {
      "position": 1,
      "role": "hook",
      "layout": "titre-centre",
      "background_variant": "primary",
      "zones": ["kicker", "titre", "sous-titre"],
      "regles": "Titre max 8 mots. Kicker en magenta uppercase. Sous-titre en text_muted 38px."
    },
    {
      "position": 2,
      "role": "contenu",
      "layout": "chiffre-hero",
      "background_variant": "primary",
      "zones": ["chiffre", "corps", "numero"],
      "regles": "Chiffre en accent (#D70459) 150px. Corps en white 30px max 20 mots. Numéro de slide en haut à droite en text_muted."
    },
    {
      "position": 3,
      "role": "contenu",
      "layout": "liste-puces",
      "background_variant": "primary",
      "zones": ["titre", "corps", "numero"],
      "regles": "Max 4 puces. Icônes filaires Lucide en magenta. Titre en white 80px."
    },
    {
      "position": 4,
      "role": "transition",
      "layout": "titre-centre",
      "background_variant": "secondary",
      "zones": ["titre"],
      "regles": "Slide de respiration. 1 phrase max 6 mots. Fond #1F2937 (secondary) pour rompre le rythme."
    },
    {
      "position": 5,
      "role": "contenu",
      "layout": "split-50-50",
      "background_variant": "primary",
      "zones": ["titre", "chiffre", "corps", "numero"],
      "regles": "Gauche : titre + corps. Droite : chiffre en display + légende en caption."
    },
    {
      "position": 6,
      "role": "contenu",
      "layout": "liste-puces",
      "background_variant": "primary",
      "zones": ["titre", "corps", "numero"],
      "regles": "Idem slide 3."
    },
    {
      "position": 7,
      "role": "contenu",
      "layout": "titre-gauche",
      "background_variant": "light",
      "zones": ["titre", "corps", "numero"],
      "regles": "Slide light (#FFFFFF fond) pour rythmer. Texte en #0C132A. Accent magenta sur mots-clés uniquement."
    },
    {
      "position": 8,
      "role": "cta",
      "layout": "titre-centre",
      "background_variant": "primary",
      "zones": ["titre", "cta", "kicker"],
      "regles": "Titre = question ouverte ou appel direct. CTA en pill magenta. Kicker = nom du compte LinkedIn en caption."
    }
  ],

  "composants": {
    "border_radius": 12,
    "card_background": "#1F2937",
    "divider_color": "#D70459",
    "icon_style": "filaire",
    "icon_library": "Lucide"
  },

  "usage": {
    "contexte": "Post pédagogique à forte valeur informative, sujet de fond (conformité, méthode, erreurs à éviter)",
    "niche_ideale": "CGP indépendant, Expert-comptable",
    "ton": "assertif, pédagogique, autorité bienveillante",
    "exemples_contenu": [
      "5 erreurs LinkedIn des CGP qui plombent leur crédibilité",
      "Ce que dit vraiment l'AMF sur la communication LinkedIn",
      "3 signaux qui montrent qu'un prospect est prêt à être contacté"
    ]
  },

  "nano_banana": {
    "style": "minimalist editorial",
    "ambiance": ["sobre", "professionnel", "confiant"],
    "negative_prompt": "text, logos, watermarks, handshakes, suits in conference rooms, generic stock photo, AI artifacts, oversaturation, pastel colors"
  },

  "source": "DS Fidulia 2026 — template de référence agence",
  "statut": "actif"
}
```

---

## Système modulaire — famille "liste" (4 à 20 items)

> Introduit le 27/07/2026 à partir des wireframes SVG fournis par Fabien (`list-4/1.svg` et `2.svg`).
> Couvre les infographies "liste numérotée" (N items de même poids, format 1080×1350).

### Principe : header et footer à hauteur FIXE, jamais en %

Contrainte posée par Fabien : le header et le footer ne bougent jamais, quel que soit le nombre d'items.

| Zone | Hauteur fixe | Contenu |
|---|---|---|
| Header | **216px** | kicker + titre + sous-titre, centrés verticalement |
| Corps | **972px** (= 1350 − 216 − 162) | N items, en bandes empilées ou en grille |
| Footer | **162px** | handle + source, centrés verticalement |

### Deux familles de layout par taille N

- **Empilée** (`liste-empilee-N`) : N bandes pleine largeur, fond alterné secondary/primary, numéro d'ordre League Spartan en accent. Lecture strictement séquentielle. Contenu : numéro + titre + description.
- **Grille** (`liste-grille-[cols]x[rows]`) : cases de taille égale, fond secondary, bordure arrondie. Lecture non-linéaire par blocs. Contenu : **icône Lucide + titre + description courte** (pas de numéro — décision Fabien 27/07/2026).

### Seuil empilée vs grille

Au-delà de 6–8 items, une bande pleine largeur devient trop fine (< 130px) pour rester lisible. **La variante empilée est réservée à 4, 6 et 8 items.** Au-delà, seule la variante grille est proposée.

### Table des grilles retenues (cols × rows, convention = colonnes puis lignes)

Grille choisie par proximité avec `ideal_cols = round(√(N × 1080/972))`, en préférant le diviseur de N le plus proche.

| N | Empilée | Grille (cols×rows) | Taille de case approx. |
|---|---|---|---|
| 4 | ✅ liste-empilee-4 | 2×2 | 464×450 |
| 6 | ✅ liste-empilee-6 | 3×2 | ~300×450 |
| 8 | ✅ liste-empilee-8 *(à produire)* | 2×4 | ~464×219 |
| 10 | ❌ | 2×5 | ~464×172 |
| 12 | ❌ | 4×3 | ~245×304 |
| 14 | ❌ | 2×7 | ~464×119 — case dense, description à raccourcir davantage |
| 16 | ❌ | 4×4 | ~245×219 |
| 18 | ❌ | 3×6 | ~304×139 |
| 20 | ❌ | 5×4 | ~178×219 |

**Statut au 27/07/2026** : 4 (empilée + grille) et 6 (empilée + grille) produits et livrés en `statut: "proposition"`. Les tailles 8 à 20 suivent la même mécanique (header/footer fixes, palette et typo identiques, densité de contenu qui s'allège avec la hauteur de case — voir règle ci-dessous) et seront produites à la demande une fois le système validé sur 4 et 6.

### Règle de densité de contenu selon la hauteur de case (variante grille)

| Hauteur de case | Contenu |
|---|---|
| ≥ 300px | Icône + titre (max 6 mots) + description (max 12 mots, 2 lignes) |
| 150–300px | Icône + titre (max 5 mots) + description courte (max 8-10 mots, 1 ligne) |
| < 150px | Icône + titre seul (max 4 mots), pas de description |

### Nommage

`infographie-liste-empilee-[N]-generaliste.json` / `infographie-liste-grille-[cols]x[rows]-generaliste.json`

### Relation avec `infographie-bento-2x2-generaliste`

Un template proche existe déjà pour 4 items en grille 2×2 (`infographie-bento-2x2-generaliste`, créé le 20/07/2026 à partir du même wireframe source). Il reste distinct de `infographie-liste-grille-2x2-generaliste` : le bento assume des cases **totalement indépendantes** (aucune notion de liste), tandis que la famille "liste" assume un contenu conçu à l'origine comme une liste numérotée, simplement présentée en blocs plutôt qu'en bandes. Choisir le bento si le contenu n'a jamais été une liste ; choisir liste-grille sinon.

---

## Nommage des fichiers

```
Contexte/Design-System/Templates/
├── SCHEMA.md                          ← ce fichier
├── carousel-autorite-cgp.json         ← template actif
├── carousel-proximite-generaliste.json
├── citation-visuelle-finance.json
├── banniere-autorite-cgp.json
└── ...
```

Convention : `[type]-[positionnement]-[niche].json`

---

*Source : DS Fidulia · Consommateurs : Agents 21 (Design System) et 31 (Graphiste)*
