470 lines
14 KiB
Markdown
470 lines
14 KiB
Markdown
|
|
# SKILL — Sliding Design System (Pernod Ricard)
|
|||
|
|
|
|||
|
|
Ce skill décrit le **design system « PR Editorial »** et le format de données
|
|||
|
|
que consomme le moteur de rendu `render_engine_v2.py` pour produire des
|
|||
|
|
présentations PowerPoint au format Pernod Ricard.
|
|||
|
|
|
|||
|
|
**Périmètre de ce skill : design et production uniquement.** Il ne traite pas
|
|||
|
|
de la structuration narrative, de la rédaction ou de la rhétorique. Il répond
|
|||
|
|
à une seule question : *comment produire un fichier YAML valide qui, passé au
|
|||
|
|
moteur, génère un PPTX conforme à la charte Pernod Ricard.*
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 1. Principe de fonctionnement
|
|||
|
|
|
|||
|
|
Le moteur prend en entrée un fichier **YAML** décrivant une liste de slides.
|
|||
|
|
Chaque slide déclare un `layout` (parmi 21) et les champs de contenu de ce
|
|||
|
|
layout. Le moteur applique automatiquement la charte (couleurs, polices,
|
|||
|
|
grille, centrage vertical). Tu n'as jamais à spécifier de couleur, de police
|
|||
|
|
ou de position en mode standard : tu fournis le contenu, le moteur compose.
|
|||
|
|
|
|||
|
|
Commande de rendu :
|
|||
|
|
```bash
|
|||
|
|
python3 render_engine_v2.py presentation.yaml sortie.pptx \
|
|||
|
|
--theme theme_v2.yaml --components components_v2.yaml --layouts layouts_v2.yaml
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Structure générale du YAML :
|
|||
|
|
```yaml
|
|||
|
|
slides:
|
|||
|
|
- layout: cover_split
|
|||
|
|
titre: "..."
|
|||
|
|
- layout: kpi_grid
|
|||
|
|
titre: "..."
|
|||
|
|
items: [...]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 2. La charte (appliquée automatiquement)
|
|||
|
|
|
|||
|
|
Tu n'écris jamais ces valeurs en mode standard ; elles sont là pour information.
|
|||
|
|
|
|||
|
|
**Couleurs**
|
|||
|
|
| Token | Hex | Usage |
|
|||
|
|
|---|---|---|
|
|||
|
|
| navy | `#061033` | dominant — fonds sombres, titres |
|
|||
|
|
| navy_light | `#10204D` | cercles décoratifs sur fond sombre |
|
|||
|
|
| coral | `#F4795B` | accent UNIQUE — chiffres, badges, lignes |
|
|||
|
|
| glacier | `#8FA9D0` | sous-titres sur fond sombre, 3e couleur |
|
|||
|
|
| slate | `#46505A` | 2e couleur de cycle |
|
|||
|
|
| card | `#F4F1EC` | fond des cartes (gris chaud) |
|
|||
|
|
| card_alt | `#EAF0F8` | variante froide |
|
|||
|
|
| body | `#2B3440` | texte courant sur fond clair |
|
|||
|
|
| muted | `#8A93A0` | légendes, sources |
|
|||
|
|
|
|||
|
|
**Polices** : Cambria (titres, chiffres) / Calibri (corps).
|
|||
|
|
**Format slide** : 33,87 × 19,05 cm (16:9).
|
|||
|
|
**Règle d'accent** : le corail est rare. Un seul élément corail dominant par slide ; le navy domine.
|
|||
|
|
**Rythme sandwich** : ouverture, transitions et clôture sur fond sombre (navy) ; contenu sur fond clair.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 3. Les 21 layouts standards
|
|||
|
|
|
|||
|
|
Chaque layout liste ses champs **requis** (obligatoires) et **optionnels**.
|
|||
|
|
`titre` doit être une formulation affirmative (le message du slide), pas un label.
|
|||
|
|
|
|||
|
|
### Ouverture / Clôture / Structure
|
|||
|
|
|
|||
|
|
**cover_split** — couverture (fond sombre)
|
|||
|
|
Requis : `titre` · Optionnel : `sous_titre`
|
|||
|
|
```yaml
|
|||
|
|
- layout: cover_split
|
|||
|
|
titre: "Titre de la présentation"
|
|||
|
|
sous_titre: "Tagline en une phrase"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**section_divider** — transition de section (fond sombre, numéro auto)
|
|||
|
|
Requis : `titre`
|
|||
|
|
```yaml
|
|||
|
|
- layout: section_divider
|
|||
|
|
titre: "Nom de la section"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**end_slide** — clôture (fond sombre)
|
|||
|
|
Requis : `message`
|
|||
|
|
```yaml
|
|||
|
|
- layout: end_slide
|
|||
|
|
message: "Phrase de conclusion"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Synthèse / Message
|
|||
|
|
|
|||
|
|
**executive_summary** — synthèse situation/complication/résolution
|
|||
|
|
Requis : `titre, situation, complication, resolution`
|
|||
|
|
```yaml
|
|||
|
|
- layout: executive_summary
|
|||
|
|
titre: "Le So What en une phrase affirmative"
|
|||
|
|
situation: "État des lieux factuel"
|
|||
|
|
complication: "Le problème ou la tension"
|
|||
|
|
resolution: "La réponse proposée"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**key_message** — citation/message fort (fond sombre)
|
|||
|
|
Requis : `message` · Optionnel : `detail`
|
|||
|
|
```yaml
|
|||
|
|
- layout: key_message
|
|||
|
|
message: "Le message clé en une phrase forte."
|
|||
|
|
detail: "Sous-texte optionnel."
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Données
|
|||
|
|
|
|||
|
|
**big_stat** — un chiffre héro plein écran
|
|||
|
|
Requis : `titre, valeur` · Optionnel : `description, source`
|
|||
|
|
```yaml
|
|||
|
|
- layout: big_stat
|
|||
|
|
titre: "Titre affirmatif"
|
|||
|
|
valeur: "78%"
|
|||
|
|
description: "ce que le chiffre signifie"
|
|||
|
|
source: "Référence — 2026"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**kpi_grid** — 2 à 6 cartes KPI
|
|||
|
|
Requis : `titre, items`
|
|||
|
|
```yaml
|
|||
|
|
- layout: kpi_grid
|
|||
|
|
titre: "Titre affirmatif"
|
|||
|
|
items:
|
|||
|
|
- label: "Indicateur 1"
|
|||
|
|
valeur: "+13%"
|
|||
|
|
description: "Source ou contexte"
|
|||
|
|
- label: "Indicateur 2"
|
|||
|
|
valeur: "85%"
|
|||
|
|
description: "Source ou contexte"
|
|||
|
|
```
|
|||
|
|
Note : `valeur` est une chaîne. Les valeurs courtes (≤6 car.) s'affichent en
|
|||
|
|
très grand, les valeurs longues sont réduites automatiquement.
|
|||
|
|
|
|||
|
|
### Comparaison
|
|||
|
|
|
|||
|
|
**two_cols_text** — deux colonnes en cartes (gauche navy, droite corail)
|
|||
|
|
Requis : `titre, left, right`
|
|||
|
|
```yaml
|
|||
|
|
- layout: two_cols_text
|
|||
|
|
titre: "Titre affirmatif"
|
|||
|
|
left:
|
|||
|
|
titre: "Titre colonne gauche"
|
|||
|
|
bullets:
|
|||
|
|
- texte: "Premier point"
|
|||
|
|
- texte: "Deuxième point"
|
|||
|
|
right:
|
|||
|
|
titre: "Titre colonne droite"
|
|||
|
|
bullets:
|
|||
|
|
- texte: "Premier point"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**comparison_table** — tableau comparatif multi-critères
|
|||
|
|
Requis : `titre, headers, rows` (max ~5 colonnes, 8 lignes)
|
|||
|
|
```yaml
|
|||
|
|
- layout: comparison_table
|
|||
|
|
titre: "Titre affirmatif"
|
|||
|
|
headers: ["Critère", "Option A", "Option B"]
|
|||
|
|
rows:
|
|||
|
|
- label: "Premier critère"
|
|||
|
|
values: ["Valeur A", "Valeur B"]
|
|||
|
|
- label: "Deuxième critère"
|
|||
|
|
values: ["Valeur A", "Valeur B"]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**from_to_pairs** — transformation avant/après
|
|||
|
|
Requis : `titre, pairs` · Optionnel : `label_from, label_to` (max 5 paires)
|
|||
|
|
```yaml
|
|||
|
|
- layout: from_to_pairs
|
|||
|
|
titre: "Titre affirmatif"
|
|||
|
|
label_from: "SITUATION ACTUELLE"
|
|||
|
|
label_to: "SITUATION CIBLE"
|
|||
|
|
pairs:
|
|||
|
|
- from: "État de départ"
|
|||
|
|
to: "État cible"
|
|||
|
|
- from: "Autre point"
|
|||
|
|
to: "Autre cible"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Concept / Texte
|
|||
|
|
|
|||
|
|
**circular_diagram** — 3 à 6 cercles + légende
|
|||
|
|
Requis : `titre, segments`
|
|||
|
|
```yaml
|
|||
|
|
- layout: circular_diagram
|
|||
|
|
titre: "Titre affirmatif"
|
|||
|
|
segments:
|
|||
|
|
- label: "Concept 1"
|
|||
|
|
description: "Description courte"
|
|||
|
|
- label: "Concept 2"
|
|||
|
|
description: "Description courte"
|
|||
|
|
- label: "Concept 3"
|
|||
|
|
description: "Description courte"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**default_bullets** — liste de points (max 5)
|
|||
|
|
Requis : `titre, bullets`
|
|||
|
|
Le format « Mot-clé : explication » met le mot-clé en gras navy.
|
|||
|
|
```yaml
|
|||
|
|
- layout: default_bullets
|
|||
|
|
titre: "Titre affirmatif"
|
|||
|
|
bullets:
|
|||
|
|
- texte: "Mot-clé : explication du point"
|
|||
|
|
niveau: 1
|
|||
|
|
- texte: "Autre mot-clé : explication"
|
|||
|
|
niveau: 1
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Process / Planning
|
|||
|
|
|
|||
|
|
**numbered_steps** — étapes en cartes avec badge numéroté (2 à 5)
|
|||
|
|
Requis : `titre, steps`
|
|||
|
|
```yaml
|
|||
|
|
- layout: numbered_steps
|
|||
|
|
titre: "Titre affirmatif"
|
|||
|
|
steps:
|
|||
|
|
- numero: 1
|
|||
|
|
titre: "Première étape"
|
|||
|
|
description: "Ce que ça implique"
|
|||
|
|
- numero: 2
|
|||
|
|
titre: "Deuxième étape"
|
|||
|
|
description: "Ce que ça implique"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**process_arrow** — flux horizontal de 3 à 6 étapes (sans dates)
|
|||
|
|
Requis : `titre, steps`
|
|||
|
|
```yaml
|
|||
|
|
- layout: process_arrow
|
|||
|
|
titre: "Titre affirmatif"
|
|||
|
|
steps:
|
|||
|
|
- titre: "Étape 1"
|
|||
|
|
description: "Ce qui se passe"
|
|||
|
|
- titre: "Étape 2"
|
|||
|
|
description: "Ce qui se passe"
|
|||
|
|
- titre: "Étape 3"
|
|||
|
|
description: "Ce qui se passe"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**phases_timeline** — phases avec périodes
|
|||
|
|
Requis : `titre, phases`
|
|||
|
|
```yaml
|
|||
|
|
- layout: phases_timeline
|
|||
|
|
titre: "Titre affirmatif"
|
|||
|
|
phases:
|
|||
|
|
- label: "Mois 1-2"
|
|||
|
|
periode: "Ce qui se passe"
|
|||
|
|
- label: "Mois 3-8"
|
|||
|
|
periode: "Ce qui se passe"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**gantt_timeline** — Gantt par workstreams
|
|||
|
|
Requis : `titre, periods, workstreams` (max 3 workstreams, 4 tâches chacun)
|
|||
|
|
`start`/`end` = index dans `periods` (0-based).
|
|||
|
|
```yaml
|
|||
|
|
- layout: gantt_timeline
|
|||
|
|
titre: "Titre affirmatif"
|
|||
|
|
periods: ["Juin", "Juil", "Août", "Sept"]
|
|||
|
|
workstreams:
|
|||
|
|
- label: "Workstream 1"
|
|||
|
|
tasks:
|
|||
|
|
- label: "Tâche A"
|
|||
|
|
start: 0
|
|||
|
|
end: 2
|
|||
|
|
- label: "Workstream 2"
|
|||
|
|
tasks:
|
|||
|
|
- label: "Tâche B"
|
|||
|
|
start: 1
|
|||
|
|
end: 3
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**yearly_timeline** — frise chronologique
|
|||
|
|
Requis : `titre, milestones` (max 6, `actif: true` met le jalon en corail)
|
|||
|
|
```yaml
|
|||
|
|
- layout: yearly_timeline
|
|||
|
|
titre: "Titre affirmatif"
|
|||
|
|
milestones:
|
|||
|
|
- annee: "2024"
|
|||
|
|
label: "Premier jalon"
|
|||
|
|
- annee: "2025"
|
|||
|
|
label: "Deuxième jalon"
|
|||
|
|
- annee: "2026"
|
|||
|
|
label: "Jalon courant"
|
|||
|
|
actif: true
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Gouvernance / Organisation / Décision
|
|||
|
|
|
|||
|
|
**raci_table** — matrice RACI
|
|||
|
|
Requis : `titre, roles, tasks` (max 4 rôles, 8 tâches)
|
|||
|
|
Lettres : R (Responsable, corail), A (Autorité, navy), C (Consulté, slate), I (Informé, muted).
|
|||
|
|
```yaml
|
|||
|
|
- layout: raci_table
|
|||
|
|
titre: "Titre affirmatif"
|
|||
|
|
roles: ["Rôle 1", "Rôle 2", "Rôle 3"]
|
|||
|
|
tasks:
|
|||
|
|
- label: "Première activité"
|
|||
|
|
raci: ["A", "R", "C"]
|
|||
|
|
- label: "Deuxième activité"
|
|||
|
|
raci: ["A", "I", "R"]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**org_chart** — organigramme (max 3 niveaux)
|
|||
|
|
Requis : `titre, root`
|
|||
|
|
Les `children` peuvent être des objets `{label, children}` OU de simples
|
|||
|
|
chaînes. Max 4 enfants directs, 3 petits-enfants par enfant (au-delà, ça serre).
|
|||
|
|
```yaml
|
|||
|
|
- layout: org_chart
|
|||
|
|
titre: "Titre affirmatif"
|
|||
|
|
root:
|
|||
|
|
label: "Responsable racine"
|
|||
|
|
children:
|
|||
|
|
- label: "Manager 1"
|
|||
|
|
children:
|
|||
|
|
- "Équipe A"
|
|||
|
|
- "Équipe B"
|
|||
|
|
- label: "Manager 2"
|
|||
|
|
children:
|
|||
|
|
- "Équipe C"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**matrix_2x2** — matrice effort/impact
|
|||
|
|
Requis : `titre, items` · Optionnel : `axis_x, axis_y, quadrants` (max 8 items)
|
|||
|
|
`x` et `y` vont de 0 à 100.
|
|||
|
|
```yaml
|
|||
|
|
- layout: matrix_2x2
|
|||
|
|
titre: "Titre affirmatif"
|
|||
|
|
axis_x:
|
|||
|
|
label: "Effort"
|
|||
|
|
low: "Faible"
|
|||
|
|
high: "Élevé"
|
|||
|
|
axis_y:
|
|||
|
|
label: "Impact"
|
|||
|
|
low: "Faible"
|
|||
|
|
high: "Élevé"
|
|||
|
|
quadrants:
|
|||
|
|
top_left: "Gains rapides"
|
|||
|
|
top_right: "Projets stratégiques"
|
|||
|
|
bottom_left: "Déprioritiser"
|
|||
|
|
bottom_right: "À planifier"
|
|||
|
|
items:
|
|||
|
|
- label: "Initiative A"
|
|||
|
|
x: 30
|
|||
|
|
y: 80
|
|||
|
|
- label: "Initiative B"
|
|||
|
|
x: 70
|
|||
|
|
y: 75
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**recommendation_card** — carte de recommandation (sidebar navy)
|
|||
|
|
Requis : `titre, headline, bullets` · Optionnel : `numero, cta`
|
|||
|
|
```yaml
|
|||
|
|
- layout: recommendation_card
|
|||
|
|
numero: 1
|
|||
|
|
titre: "Nom court de la recommandation"
|
|||
|
|
headline: "TROIS DÉCISIONS À PRENDRE MAINTENANT"
|
|||
|
|
cta: "Décider en réunion du 30 juin"
|
|||
|
|
bullets:
|
|||
|
|
- texte: "Première décision précise"
|
|||
|
|
- texte: "Deuxième décision précise"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 4. Le flux libre (freeform) — composition sur mesure
|
|||
|
|
|
|||
|
|
Pour les slides qui ne rentrent dans aucun layout standard, utilise
|
|||
|
|
`layout: freeform`. La slide est composée de **blocs positionnés sur une
|
|||
|
|
grille 12 × 12** (colonnes 0-12, lignes 0-12). La charte reste **imposée** :
|
|||
|
|
les couleurs ne peuvent être que des tokens nommés (jamais de hex).
|
|||
|
|
|
|||
|
|
Règles de la grille :
|
|||
|
|
- `col` (0-12) = colonne de départ, `row` (0-12) = ligne de départ
|
|||
|
|
- `w` = largeur en colonnes, `h` = hauteur en lignes
|
|||
|
|
- Contraintes : `col + w ≤ 12` et `row + h ≤ 12`
|
|||
|
|
- Maximum 8 blocs par slide
|
|||
|
|
- `mode: light` (fond blanc) ou `mode: dark` (fond navy)
|
|||
|
|
- `footer: false` pour masquer le pied de page (affiché par défaut, même sur fond sombre)
|
|||
|
|
|
|||
|
|
Note : `freeform` est géré directement par le moteur de rendu et ne figure pas
|
|||
|
|
dans `layouts_v2.yaml`. Un validateur basé sur ce fichier peut donc le signaler
|
|||
|
|
comme « layout inconnu » — c'est sans effet, le rendu fonctionne normalement.
|
|||
|
|
|
|||
|
|
Types de blocs disponibles :
|
|||
|
|
| type | description | champs spécifiques |
|
|||
|
|
|---|---|---|
|
|||
|
|
| `title` / `heading` | titre serif | `size` (déf. 28), `align`, `color` |
|
|||
|
|
| `text` | texte courant (Calibri) | `size`, `bold`, `italic`, `serif`, `align`, `color` |
|
|||
|
|
| `stat` | grand chiffre serif corail | `size` (déf. 72), `align`, `color` |
|
|||
|
|
| `circle` | cercle plein (motif charte) | `color` (diamètre = min(w,h)) |
|
|||
|
|
| `badge` | cercle numéroté, texte blanc centré | `text`, `color` |
|
|||
|
|
| `card` | carte arrondie avec ombre | `color` (déf. card) |
|
|||
|
|
| `rect` | rectangle plein | `color`, `rounded` |
|
|||
|
|
| `line` | ligne / séparateur | `color`, `weight` (h:0 = horizontale) |
|
|||
|
|
|
|||
|
|
Tokens couleur autorisés : `navy, navy_light, coral, glacier, slate, card,
|
|||
|
|
white, body, muted`. Aucun hex.
|
|||
|
|
|
|||
|
|
Exemple — slide manifeste (fond sombre, grand chiffre + titre + accent) :
|
|||
|
|
```yaml
|
|||
|
|
- layout: freeform
|
|||
|
|
mode: dark
|
|||
|
|
blocks:
|
|||
|
|
- type: stat
|
|||
|
|
text: "3"
|
|||
|
|
col: 0.5
|
|||
|
|
row: 1
|
|||
|
|
w: 3
|
|||
|
|
h: 4
|
|||
|
|
size: 150
|
|||
|
|
color: coral
|
|||
|
|
align: center
|
|||
|
|
- type: title
|
|||
|
|
text: "trois convictions structurantes"
|
|||
|
|
col: 4
|
|||
|
|
row: 1.5
|
|||
|
|
w: 7.5
|
|||
|
|
h: 3
|
|||
|
|
size: 30
|
|||
|
|
color: white
|
|||
|
|
- type: line
|
|||
|
|
col: 4
|
|||
|
|
row: 4.5
|
|||
|
|
w: 7
|
|||
|
|
h: 0
|
|||
|
|
color: coral
|
|||
|
|
weight: 2
|
|||
|
|
- type: text
|
|||
|
|
text: "Le sous-texte en glacier, italique."
|
|||
|
|
col: 4
|
|||
|
|
row: 5
|
|||
|
|
w: 7.5
|
|||
|
|
h: 2
|
|||
|
|
size: 18
|
|||
|
|
italic: true
|
|||
|
|
color: glacier
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 5. Règles de production (à respecter pour un YAML valide)
|
|||
|
|
|
|||
|
|
1. **Layouts** : utiliser uniquement les 21 noms listés (+ `freeform`).
|
|||
|
|
2. **Champs requis** : chaque layout doit avoir tous ses champs requis, non vides.
|
|||
|
|
3. **Chaînes** : toujours entre guillemets. Échapper les guillemets internes.
|
|||
|
|
4. **Chiffres de contenu** (`valeur`, `stat`) : toujours des chaînes (`"78%"`).
|
|||
|
|
5. **Entiers de structure** (`numero`, `niveau`, `start`, `end`, `x`, `y`) : sans guillemets.
|
|||
|
|
6. **`titre`** : formulation affirmative (le message), jamais un label thématique.
|
|||
|
|
7. **Pas de syntaxe Markdown** dans les valeurs : pas de `**gras**`, pas de `#`.
|
|||
|
|
Le formatage est géré par le moteur, pas par le texte.
|
|||
|
|
8. **Champ optionnel absent** : l'omettre (ne pas mettre `null`).
|
|||
|
|
9. **Freeform** : respecter `col+w ≤ 12`, `row+h ≤ 12`, max 8 blocs, tokens charte uniquement.
|
|||
|
|
10. **Densité** : respecter les maxima par layout (ex. kpi_grid ≤ 6, bullets ≤ 5,
|
|||
|
|
org_chart ≤ 4 branches). Au-delà, le rendu se dégrade.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 6. Sortie attendue
|
|||
|
|
|
|||
|
|
Quand on te demande de produire une présentation au format Pernod Ricard,
|
|||
|
|
tu produis **uniquement le YAML** décrit ci-dessus — rien d'autre. Ce YAML
|
|||
|
|
est destiné à être passé tel quel à `render_engine_v2.py`. Pas de texte
|
|||
|
|
d'introduction, pas de commentaire, pas de Markdown autour : le YAML brut,
|
|||
|
|
directement exploitable.
|