diff --git a/docs/superpowers/plans/2026-06-21-bilan-redesign.md b/docs/superpowers/plans/2026-06-21-bilan-redesign.md
new file mode 100644
index 0000000..034f597
--- /dev/null
+++ b/docs/superpowers/plans/2026-06-21-bilan-redesign.md
@@ -0,0 +1,1179 @@
+# Bilan Redesign — Plan d'implémentation
+
+> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
+
+**Goal:** Remplacer la mise en page plate et non hiérarchisée par une structure header-sticky + panneaux qui guide clairement le flux formateur (config → évaluation → synthèse/export).
+
+**Architecture:** Deux fichiers modifiés uniquement — `Bilan.jsx` (restructuration JSX + état toast) et `Bilan.css` (nouvelles classes de layout, suppression des anciennes). La logique métier (niveaux, drag & drop, PDF, OpenAI) reste intacte. Le test à chaque tâche est visuel : lancer le dev server et vérifier le rendu.
+
+**Tech Stack:** React 18, Vite 6, CSS pur (pas de framework CSS), Plus Jakarta Sans (Google Fonts), pdf-lib
+
+## Global Constraints
+
+- Ne jamais toucher à la logique métier (handlers, état des items, appels OpenAI, génération PDF)
+- Conserver toutes les variables CSS existantes dans `:root`
+- Conserver le responsive mobile (media query `max-width: 768px`)
+- Conserver le drag & drop et les level pills existants
+- Dev server : `npm run dev` (port 5173 par défaut)
+
+---
+
+## Fichiers touchés
+
+| Fichier | Action | Responsabilité |
+|---|---|---|
+| `src/components/Bilan.jsx` | Modifier | Restructuration JSX + remplacement état `status` par `toasts[]` |
+| `src/components/Bilan.css` | Modifier | Nouvelles classes layout, suppression `.bilan-wrapper/.bilan-container/.controls/.header/.status` |
+
+---
+
+### Task 1 : Système de toasts flottants
+
+**Remplace l'état `status` / `setStatus` par un tableau `toasts[]` avec auto-dismiss. Les notifications apparaissent en bas à droite, hors du flux de contenu.**
+
+**Files:**
+- Modify: `src/components/Bilan.jsx` (état, showStatus, JSX toasts, finally blocks)
+- Modify: `src/components/Bilan.css` (nouvelles classes `.toast-container`, `.toast`, `.toast-info/success/error`)
+
+**Interfaces:**
+- Consumes: —
+- Produces: `toasts` state, `showStatus(message, type, withProgress)` (même signature qu'avant), `dismissProgressToasts()` (appelé dans les blocs finally)
+
+---
+
+- [ ] **Étape 1 : Remplacer l'état `status` par `toasts` dans Bilan.jsx**
+
+Localiser ligne ~324 dans `src/components/Bilan.jsx`. Remplacer :
+
+```jsx
+const [status, setStatus] = useState(null);
+```
+
+par :
+
+```jsx
+const [toasts, setToasts] = useState([]);
+```
+
+- [ ] **Étape 2 : Supprimer le useEffect d'auto-dismiss (lignes ~355-362)**
+
+Supprimer entièrement ce bloc :
+
+```jsx
+useEffect(() => {
+ if (!status || status.withProgress) return;
+ const timeout = setTimeout(
+ () => setStatus(null),
+ status.type === "info" ? 3000 : 5000
+ );
+ return () => clearTimeout(timeout);
+}, [status]);
+```
+
+- [ ] **Étape 3 : Remplacer `showStatus` par la version toast**
+
+Localiser et remplacer le callback `showStatus` (ligne ~346) :
+
+```jsx
+const showStatus = useCallback((message, type = "info", withProgress = false) => {
+ const id = Date.now();
+ setToasts((prev) => [...prev, { id, message, type, withProgress }]);
+ if (!withProgress) {
+ setTimeout(() => {
+ setToasts((prev) => prev.filter((t) => t.id !== id));
+ }, type === "info" ? 3000 : 5000);
+ }
+}, []);
+```
+
+- [ ] **Étape 4 : Ajouter `dismissProgressToasts` après `showStatus`**
+
+```jsx
+const dismissProgressToasts = useCallback(() => {
+ setToasts((prev) => prev.filter((t) => !t.withProgress));
+}, []);
+```
+
+- [ ] **Étape 5 : Mettre à jour les blocs `finally` dans `generateAISummaryOpenAI`**
+
+Localiser le bloc `finally` de `generateAISummaryOpenAI` (ligne ~686). Remplacer :
+
+```jsx
+} finally {
+ setStatus((prev) => (prev ? { ...prev, withProgress: false } : prev));
+ setIsAiLoading(false);
+}
+```
+
+par :
+
+```jsx
+} finally {
+ dismissProgressToasts();
+ setIsAiLoading(false);
+}
+```
+
+- [ ] **Étape 6 : Mettre à jour le bloc `finally` dans `downloadPDF`**
+
+Localiser le bloc `finally` de `downloadPDF` (ligne ~912). Remplacer :
+
+```jsx
+} finally {
+ setStatus((prev) => (prev ? { ...prev, withProgress: false } : prev));
+}
+```
+
+par :
+
+```jsx
+} finally {
+ dismissProgressToasts();
+}
+```
+
+- [ ] **Étape 7 : Ajouter le JSX des toasts dans le return**
+
+Dans le `return` de `Bilan`, ajouter juste avant la fermeture de la div racine (peu importe laquelle pour l'instant) :
+
+```jsx
+
+ {toasts.map((toast) => (
+
+ {toast.withProgress ? (
+ <>
+
{toast.message}
+
+ >
+ ) : (
+
{toast.message}
+ )}
+
+ ))}
+
+```
+
+- [ ] **Étape 8 : Supprimer le JSX du statut inline existant**
+
+Dans le JSX du `return`, supprimer le bloc conditionnel `{status && (...)}` qui rend le statut à l'intérieur de `.evaluation-summary-section`. Localiser :
+
+```jsx
+{status && (
+
+ ...
+
+)}
+```
+
+et le supprimer entièrement.
+
+- [ ] **Étape 9 : Ajouter le CSS des toasts dans Bilan.css**
+
+Ajouter à la fin du fichier, avant les media queries :
+
+```css
+.toast-container {
+ position: fixed;
+ bottom: 24px;
+ right: 24px;
+ z-index: 1000;
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ max-width: 360px;
+ pointer-events: none;
+}
+
+.toast {
+ padding: 12px 16px;
+ border-radius: var(--radius-md);
+ font-size: 13.5px;
+ font-weight: 700;
+ font-family: var(--font-sans);
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.12), 0 1px 4px rgba(0, 0, 0, 0.06);
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ animation: toast-in 0.2s cubic-bezier(0.4, 0, 0.2, 1);
+}
+
+.toast-info {
+ background: var(--color-indigo-50);
+ border-left: 3px solid var(--color-indigo-500);
+ color: var(--color-indigo-700);
+}
+
+.toast-success {
+ background: #dcfce7;
+ border-left: 3px solid #10b981;
+ color: #15803d;
+}
+
+.toast-error {
+ background: #fee2e2;
+ border-left: 3px solid #ef4444;
+ color: #b91c1c;
+}
+
+.toast-progress {
+ width: 100%;
+ height: 3px;
+ background: rgba(0, 0, 0, 0.08);
+ border-radius: 999px;
+ overflow: hidden;
+}
+
+.toast-progress-bar {
+ width: 100%;
+ height: 100%;
+ background: currentColor;
+ opacity: 0.6;
+ animation: progress-stripes 1.5s linear infinite;
+}
+
+@keyframes toast-in {
+ from { opacity: 0; transform: translateY(10px); }
+ to { opacity: 1; transform: translateY(0); }
+}
+```
+
+- [ ] **Étape 10 : Vérifier visuellement**
+
+```bash
+npm run dev
+```
+
+Déclencher une action (ex : cliquer "Générer le Bilan"). Un toast doit apparaître en bas à droite et disparaître automatiquement. Aucun message de statut ne doit apparaître dans le corps de la page.
+
+- [ ] **Étape 11 : Commit**
+
+```bash
+git add src/components/Bilan.jsx src/components/Bilan.css
+git commit -m "feat: replace inline status with floating toast notifications"
+```
+
+---
+
+### Task 2 : App shell + Topbar sticky
+
+**Restructure le wrapper racine en `.app-shell` + `.app-topbar` (header sticky 64px) contenant logo, CP selector pill, titre, inputs identité et boutons d'action.**
+
+**Files:**
+- Modify: `src/components/Bilan.jsx` (nouvelle structure return, déplacement CP selector + identité + boutons dans topbar)
+- Modify: `src/components/Bilan.css` (nouvelles classes `.app-shell`, `.app-topbar`, `.topbar-*`, `.cp-select`, `.topbar-input`, `.btn-topbar-*`)
+
+**Interfaces:**
+- Consumes: `dismissProgressToasts` (Task 1), `toasts` state (Task 1)
+- Produces: structure `.app-shell > .app-topbar + .app-main` utilisée par les tâches 3, 4, 5
+
+---
+
+- [ ] **Étape 1 : Ajouter le CSS du app-shell et du topbar dans Bilan.css**
+
+Remplacer les règles `.bilan-wrapper` et `.bilan-container` existantes par :
+
+```css
+.app-shell {
+ min-height: 100vh;
+ background-color: #f8fafc;
+ background-image:
+ radial-gradient(circle at 10% 20%, rgba(98, 95, 255, 0.06) 0%, transparent 40%),
+ radial-gradient(circle at 90% 80%, rgba(139, 92, 246, 0.04) 0%, transparent 45%);
+ font-family: var(--font-sans);
+ color: var(--text-primary);
+ -webkit-font-smoothing: antialiased;
+}
+
+.app-topbar {
+ position: sticky;
+ top: 0;
+ z-index: 100;
+ height: 64px;
+ background: rgba(255, 255, 255, 0.97);
+ backdrop-filter: blur(12px);
+ -webkit-backdrop-filter: blur(12px);
+ border-bottom: 1px solid var(--border-slate-200);
+ box-shadow: 0 1px 8px rgba(0, 0, 0, 0.04);
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0 24px;
+ gap: 16px;
+}
+
+.topbar-left {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ flex-shrink: 0;
+}
+
+.topbar-logo {
+ height: 28px;
+ width: auto;
+ display: block;
+}
+
+.topbar-divider {
+ width: 1px;
+ height: 24px;
+ background: var(--border-slate-200);
+}
+
+.cp-select {
+ appearance: none;
+ -webkit-appearance: none;
+ background: var(--color-indigo-50);
+ color: var(--color-indigo-600);
+ border: 1px solid rgba(98, 95, 255, 0.2);
+ border-radius: 999px;
+ padding: 6px 28px 6px 12px;
+ font-size: 13px;
+ font-weight: 700;
+ font-family: var(--font-sans);
+ cursor: pointer;
+ outline: none;
+ background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg width='20' height='20' viewBox='0 0 20 20' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M5 7L10 12L15 7' stroke='%234f46e5' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
+ background-repeat: no-repeat;
+ background-position: right 8px center;
+ background-size: 14px;
+ transition: var(--transition);
+}
+
+.cp-select:hover {
+ background-color: var(--color-indigo-100);
+ border-color: var(--color-indigo-500);
+}
+
+.topbar-center {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 1px;
+ flex: 1;
+ min-width: 0;
+}
+
+.topbar-title {
+ font-size: 15px;
+ font-weight: 800;
+ color: var(--text-primary);
+ letter-spacing: -0.02em;
+ white-space: nowrap;
+}
+
+.topbar-subtitle {
+ font-size: 11px;
+ font-weight: 500;
+ color: var(--text-muted);
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ max-width: 100%;
+}
+
+.topbar-right {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ flex-shrink: 0;
+}
+
+.topbar-input {
+ width: 110px;
+ height: 36px;
+ padding: 0 12px;
+ border-radius: var(--radius-md);
+ border: 1px solid var(--border-slate-200);
+ background: #f8fafc;
+ color: var(--text-primary);
+ font-size: 13px;
+ font-weight: 500;
+ font-family: var(--font-sans);
+ outline: none;
+ transition: var(--transition);
+}
+
+.topbar-input::placeholder {
+ color: var(--text-muted);
+ font-weight: 400;
+}
+
+.topbar-input:focus {
+ border-color: var(--color-indigo-500);
+ background: #ffffff;
+ box-shadow: 0 0 0 3px rgba(98, 95, 255, 0.1);
+}
+
+.topbar-actions {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ padding-left: 12px;
+ border-left: 1px solid var(--border-slate-200);
+ margin-left: 4px;
+}
+
+.btn-topbar-secondary {
+ height: 36px;
+ padding: 0 14px;
+ border-radius: var(--radius-md);
+ border: 1px solid var(--border-slate-300);
+ background: #ffffff;
+ color: var(--text-secondary);
+ font-size: 13px;
+ font-weight: 700;
+ font-family: var(--font-sans);
+ cursor: pointer;
+ transition: var(--transition);
+ white-space: nowrap;
+ box-shadow: var(--shadow-flat);
+}
+
+.btn-topbar-secondary:hover {
+ border-color: var(--color-indigo-500);
+ color: var(--color-indigo-600);
+ box-shadow: 0 2px 8px rgba(98, 95, 255, 0.1);
+}
+
+.btn-topbar-primary {
+ height: 36px;
+ padding: 0 14px;
+ border-radius: var(--radius-md);
+ border: none;
+ background: linear-gradient(135deg, #6d28d9 0%, #a855f7 50%, #db2777 100%);
+ color: #ffffff;
+ font-size: 13px;
+ font-weight: 800;
+ font-family: var(--font-sans);
+ cursor: pointer;
+ transition: var(--transition);
+ white-space: nowrap;
+ box-shadow: 0 4px 14px rgba(168, 85, 247, 0.3);
+}
+
+.btn-topbar-primary:hover:not(:disabled) {
+ background: linear-gradient(135deg, #7c3aed 0%, #c084fc 50%, #ec4899 100%);
+ box-shadow: 0 6px 20px rgba(168, 85, 247, 0.45);
+ transform: translateY(-1px);
+}
+
+.btn-topbar-primary:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+ transform: none;
+}
+
+.btn-topbar-success {
+ height: 36px;
+ padding: 0 14px;
+ border-radius: var(--radius-md);
+ border: none;
+ background: linear-gradient(135deg, #10b981 0%, #059669 100%);
+ color: #ffffff;
+ font-size: 13px;
+ font-weight: 700;
+ font-family: var(--font-sans);
+ cursor: pointer;
+ transition: var(--transition);
+ white-space: nowrap;
+ box-shadow: 0 4px 14px rgba(16, 185, 129, 0.2);
+}
+
+.btn-topbar-success:hover {
+ background: linear-gradient(135deg, #059669 0%, #047857 100%);
+ box-shadow: 0 6px 18px rgba(16, 185, 129, 0.35);
+ transform: translateY(-1px);
+}
+
+.app-main {
+ max-width: 1240px;
+ margin: 0 auto;
+ padding: 32px 24px 64px;
+}
+```
+
+- [ ] **Étape 2 : Restructurer le JSX du return dans Bilan.jsx**
+
+Remplacer la div racine `` et son contenu jusqu'à la fermeture de `.bilan-container` (hors grille et section synthèse) par la nouvelle structure. Le return complet doit ressembler à :
+
+```jsx
+return (
+
+
+
+
+
+
setCurrentCp(event.target.value)}
+ >
+ {Object.keys(allDefaults).map((cp) => (
+ {cp}
+ ))}
+
+
+
+
+ {currentTitle.h1}
+ {currentTitle.h2}
+
+
+
+
+
+
+ {/* La toolbar critères (Task 3), la grille et la section synthèse viennent ici */}
+ {/* Conserver la grille .competences-grid et .evaluation-summary-section existantes pour l'instant */}
+
+
+
+ {toasts.map((toast) => (
+
+ {toast.withProgress ? (
+ <>
+
{toast.message}
+
+ >
+ ) : (
+
{toast.message}
+ )}
+
+ ))}
+
+
+);
+```
+
+**Important :** déplacer les éléments JSX de la grille `.competences-grid` et de `.evaluation-summary-section` à l'intérieur de `
`. Supprimer ` ` (watermark supprimé). Supprimer les anciens blocs `.controls.identity`, `.controls.actions` et `.header` du JSX (ils sont maintenant dans le topbar).
+
+- [ ] **Étape 3 : Vérifier visuellement**
+
+```bash
+npm run dev
+```
+
+Résultats attendus :
+- Header blanc sticky visible en haut (64px)
+- Logo Arinfo à gauche, CP selector pill indigo, titre du CP au centre
+- Inputs Prénom/Nom compacts à droite + boutons d'action visibles
+- En scrollant, le header reste fixé en haut
+- La grille de critères s'affiche dans la zone principale (même si encore sans toolbar)
+
+- [ ] **Étape 4 : Commit**
+
+```bash
+git add src/components/Bilan.jsx src/components/Bilan.css
+git commit -m "feat: add sticky app topbar with cp selector, identity inputs and action buttons"
+```
+
+---
+
+### Task 3 : Toolbar critères
+
+**Ajoute une barre fine (44px) sous le topbar contenant les actions de sélection groupée et l'ajout de critère. Supprime les anciens boutons/inputs équivalents du corps de page.**
+
+**Files:**
+- Modify: `src/components/Bilan.jsx` (ajout `.criteria-toolbar` dans ``, suppression des anciens `.controls.actions`)
+- Modify: `src/components/Bilan.css` (nouvelles classes `.criteria-toolbar`, `.btn-text`, `.toolbar-add-input`, `.btn-toolbar-add`)
+
+**Interfaces:**
+- Consumes: structure `.app-shell > .app-topbar + .app-main` (Task 2)
+- Produces: toolbar rendu dans `` avant la grille
+
+---
+
+- [ ] **Étape 1 : Ajouter le CSS de la toolbar dans Bilan.css**
+
+Ajouter après les classes `.app-main` :
+
+```css
+.criteria-toolbar {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ height: 44px;
+ padding: 0 4px;
+ margin-bottom: 20px;
+ gap: 16px;
+}
+
+.criteria-toolbar-left {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+}
+
+.btn-text {
+ background: none;
+ border: none;
+ padding: 4px 8px;
+ font-size: 12.5px;
+ font-weight: 600;
+ color: var(--text-muted);
+ cursor: pointer;
+ font-family: var(--font-sans);
+ transition: var(--transition);
+ border-radius: var(--radius-sm);
+ box-shadow: none;
+}
+
+.btn-text:hover {
+ color: var(--color-indigo-600);
+ background: var(--color-indigo-50);
+ transform: none;
+ box-shadow: none;
+}
+
+.toolbar-sep {
+ color: var(--border-slate-300);
+ font-size: 14px;
+ user-select: none;
+}
+
+.criteria-toolbar-right {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.toolbar-add-input {
+ height: 34px;
+ width: 240px;
+ padding: 0 12px;
+ border-radius: var(--radius-sm);
+ border: 1px solid var(--border-slate-200);
+ background: #ffffff;
+ color: var(--text-primary);
+ font-size: 13px;
+ font-family: var(--font-sans);
+ outline: none;
+ transition: var(--transition);
+ box-shadow: var(--shadow-flat);
+}
+
+.toolbar-add-input::placeholder {
+ color: var(--text-muted);
+}
+
+.toolbar-add-input:focus {
+ border-color: var(--color-indigo-500);
+ box-shadow: 0 0 0 3px rgba(98, 95, 255, 0.1);
+}
+
+.btn-toolbar-add {
+ height: 34px;
+ width: 34px;
+ border-radius: var(--radius-sm);
+ border: 1px solid var(--border-slate-300);
+ background: #ffffff;
+ color: var(--text-secondary);
+ font-size: 20px;
+ font-weight: 300;
+ font-family: var(--font-sans);
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: var(--transition);
+ box-shadow: var(--shadow-flat);
+ line-height: 1;
+ padding: 0;
+}
+
+.btn-toolbar-add:hover {
+ background: var(--color-indigo-50);
+ border-color: var(--color-indigo-500);
+ color: var(--color-indigo-600);
+ transform: none;
+ box-shadow: var(--shadow-flat);
+}
+```
+
+- [ ] **Étape 2 : Ajouter le JSX de la toolbar dans Bilan.jsx**
+
+Dans ``, ajouter en premier enfant (avant `.competences-grid`) :
+
+```jsx
+
+
+ handleToggleAll(true)}
+ >
+ Tout sélectionner
+
+ ·
+ handleToggleAll(false)}
+ >
+ Tout désélectionner
+
+
+
+ setNewCriterion(event.target.value)}
+ onKeyDown={(event) => event.key === "Enter" && handleAddCriterion()}
+ />
+
+ +
+
+
+
+```
+
+- [ ] **Étape 3 : Vérifier visuellement**
+
+```bash
+npm run dev
+```
+
+Résultats attendus :
+- Barre fine entre le topbar et la grille avec "Tout sélectionner · Tout désélectionner" à gauche
+- Input + bouton "+" à droite, alignés
+- Les deux actions fonctionnent (cocher/décocher tous)
+- Ajouter un critère via Enter ou clic "+" crée un item dans "À classer"
+
+- [ ] **Étape 4 : Commit**
+
+```bash
+git add src/components/Bilan.jsx src/components/Bilan.css
+git commit -m "feat: add criteria toolbar with selection controls and add-criterion input"
+```
+
+---
+
+### Task 4 : Layout interne des items en flex-row
+
+**Transforme le layout vertical de chaque `.competence-item` en ligne horizontale : checkbox → label (flex-grow) → level pills → bouton supprimer. Réduit la hauteur de page et améliore la densité.**
+
+**Files:**
+- Modify: `src/components/Bilan.css` (`.competence-item`, `.competence-label`, `.level-group`, `.remove-field-btn`)
+
+**Interfaces:**
+- Consumes: structure `.competence-item` existante dans le JSX (inchangée)
+- Produces: items en flex-row, visuellement plus compacts
+
+---
+
+- [ ] **Étape 1 : Modifier `.competence-item` pour flex-row**
+
+Localiser la règle `.competence-item` dans `Bilan.css` et remplacer par :
+
+```css
+.competence-item {
+ border: 1px solid var(--border-slate-200);
+ padding: 10px 12px;
+ border-radius: var(--radius-md);
+ cursor: grab;
+ background: #ffffff;
+ transition: var(--transition);
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ gap: 10px;
+ box-shadow: var(--shadow-card);
+ position: relative;
+}
+```
+
+- [ ] **Étape 2 : Modifier `.competence-label` pour occuper l'espace disponible**
+
+Localiser `.competence-item .competence-label` et remplacer par :
+
+```css
+.competence-item .competence-label {
+ flex: 1;
+ min-width: 0;
+ font-weight: 600;
+ color: var(--text-primary);
+ font-size: 13px;
+ cursor: pointer;
+ line-height: 1.4;
+ padding-right: 0;
+}
+```
+
+- [ ] **Étape 3 : Modifier `.level-group` pour s'intégrer inline**
+
+Localiser `.level-group` et remplacer par :
+
+```css
+.level-group {
+ display: flex;
+ flex-wrap: nowrap;
+ gap: 4px;
+ align-items: center;
+ flex-shrink: 0;
+ border-top: none;
+ padding-top: 0;
+ margin-top: 0;
+}
+```
+
+- [ ] **Étape 4 : Supprimer `.level-title` du JSX**
+
+Dans `Bilan.jsx`, dans le rendu de chaque item, localiser et supprimer la ligne :
+
+```jsx
+Niveau :
+```
+
+Ce label textuel prend de la place inutilement en layout row.
+
+- [ ] **Étape 5 : Modifier `.remove-field-btn` pour sortir du positionnement absolu**
+
+Remplacer la règle `.remove-field-btn` par :
+
+```css
+.remove-field-btn {
+ background: #fee2e2;
+ color: #ef4444;
+ border: 0 !important;
+ border-radius: 50% !important;
+ width: 20px !important;
+ height: 20px !important;
+ padding: 0 !important;
+ font-size: 12px !important;
+ cursor: pointer;
+ display: flex !important;
+ align-items: center !important;
+ justify-content: center !important;
+ flex-shrink: 0;
+ opacity: 0;
+ transform: scale(0.8);
+ transition: var(--transition);
+ box-shadow: none !important;
+ position: static;
+}
+```
+
+- [ ] **Étape 6 : Vérifier visuellement**
+
+```bash
+npm run dev
+```
+
+Résultats attendus :
+- Chaque item de critère est maintenant une seule ligne horizontale
+- Checkbox à gauche, label au centre (stretch), level pills (NA/EC/AC/MA) à droite
+- Le bouton × apparaît au hover, après les pills
+- La grille est sensiblement plus compacte
+
+- [ ] **Étape 7 : Commit**
+
+```bash
+git add src/components/Bilan.css src/components/Bilan.jsx
+git commit -m "feat: switch criteria items to horizontal flex-row layout"
+```
+
+---
+
+### Task 5 : Section divider + polish de la synthèse
+
+**Ajoute le séparateur visuel "Synthèse & Export", supprime le h3 redondant, améliore le header des cards de critères, et nettoie la section synthèse.**
+
+**Files:**
+- Modify: `src/components/Bilan.jsx` (ajout `.section-divider`, suppression `Synthèse & Observations `)
+- Modify: `src/components/Bilan.css` (`.section-divider`, amélioration `.competence-card h4`, loader inline)
+
+**Interfaces:**
+- Consumes: structure `.evaluation-summary-section` existante
+- Produces: séparateur visuel rendu, section synthèse sans titre redondant
+
+---
+
+- [ ] **Étape 1 : Ajouter le CSS du divider et polisher les card headers**
+
+Ajouter dans `Bilan.css` après les classes `.criteria-toolbar-*` :
+
+```css
+.section-divider {
+ display: flex;
+ align-items: center;
+ gap: 16px;
+ margin: 48px 0 32px;
+ color: var(--text-muted);
+ font-size: 11px;
+ font-weight: 700;
+ text-transform: uppercase;
+ letter-spacing: 0.08em;
+}
+
+.section-divider::before,
+.section-divider::after {
+ content: '';
+ flex: 1;
+ height: 1px;
+ background: var(--border-slate-200);
+}
+```
+
+Modifier `.competence-card h4` pour ajouter un fond coloré léger au header de chaque card :
+
+```css
+.competence-card h4 {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin: 0 -24px 0 -24px;
+ padding: 12px 24px;
+ font-size: 12px;
+ font-weight: 800;
+ color: var(--text-primary);
+ text-transform: uppercase;
+ letter-spacing: 0.06em;
+ border-radius: var(--radius-lg) var(--radius-lg) 0 0;
+ background: rgba(248, 250, 252, 0.8);
+ border-bottom: 1px solid var(--border-slate-200);
+}
+```
+
+- [ ] **Étape 2 : Ajouter le JSX du divider dans Bilan.jsx**
+
+Dans ``, avant `.evaluation-summary-section`, ajouter :
+
+```jsx
+
+ Synthèse & Export
+
+```
+
+- [ ] **Étape 3 : Supprimer le h3 redondant dans .evaluation-summary-section**
+
+Dans le JSX de `.evaluation-summary-section`, supprimer :
+
+```jsx
+Synthèse & Observations
+```
+
+- [ ] **Étape 4 : Supprimer le bloc `.ai-status-loader` du JSX (déjà remplacé par toasts)**
+
+Localiser et supprimer du JSX :
+
+```jsx
+{isAiLoading && (
+
+
+ Génération du résumé en cours…
+
+)}
+```
+
+- [ ] **Étape 5 : Vérifier visuellement**
+
+```bash
+npm run dev
+```
+
+Résultats attendus :
+- Ligne horizontale avec "Synthèse & Export" centré entre la grille et la section de synthèse
+- Headers des cards de critères ont un fond légèrement teinté
+- Pas de h3 redondant dans la section synthèse
+- Le loader inline a disparu (remplacé par toast en Task 1)
+
+- [ ] **Étape 6 : Commit**
+
+```bash
+git add src/components/Bilan.jsx src/components/Bilan.css
+git commit -m "feat: add section divider, polish card headers, remove redundant labels"
+```
+
+---
+
+### Task 6 : Nettoyage CSS final + responsive
+
+**Supprime toutes les classes CSS devenues inutilisées et adapte les media queries au nouveau layout.**
+
+**Files:**
+- Modify: `src/components/Bilan.css` (suppression `.bilan-wrapper`, `.bilan-container`, `.header`, `.controls`, `.logo-bg`, `.status`, `.back-btn`, `.ai-loader`, `.ai-status-loader`; mise à jour media queries)
+
+**Interfaces:**
+- Consumes: tout le CSS final des tasks 1–5
+- Produces: fichier CSS sans classes orphelines, responsive fonctionnel
+
+---
+
+- [ ] **Étape 1 : Supprimer les classes obsolètes de Bilan.css**
+
+Supprimer entièrement les blocs CSS suivants (ils ne sont plus référencés dans le JSX) :
+
+- `.bilan-wrapper` et `.logo-bg`
+- `.bilan-container`
+- `.header`, `.header h1`, `.header h2`
+- `.back-btn`, `.back-btn:hover`
+- `.controls`, `.controls.controls-select`, `.controls.controls-select label`, `.controls.identity input`, `.controls.actions input`, `.controls.actions button:last-of-type`, `.controls input`, `.controls select`
+- `.status`, `.status.info`, `.status.success`, `.status.error`, `.status .progress`, `.status .progress-bar`
+- `.ai-loader`
+- `.ai-status-loader`
+- `.bilan-container button`, `.bilan-container button:hover`, `.bilan-container button:disabled` (les boutons du topbar ont leurs propres classes)
+- `.bilan-container select`, `.bilan-container select option`
+- `.bilan-container textarea` (remplacé par les règles dans `.summary-inputs-panel` et `.summary-output-panel`)
+
+- [ ] **Étape 2 : Mettre à jour les media queries**
+
+Localiser le bloc `@media (max-width: 768px)` et le remplacer par :
+
+```css
+@media (max-width: 768px) {
+ .app-topbar {
+ height: auto;
+ flex-direction: column;
+ align-items: flex-start;
+ padding: 12px 16px;
+ gap: 10px;
+ }
+
+ .topbar-center {
+ align-items: flex-start;
+ }
+
+ .topbar-right {
+ flex-wrap: wrap;
+ gap: 8px;
+ }
+
+ .topbar-input {
+ width: 90px;
+ }
+
+ .topbar-actions {
+ border-left: none;
+ padding-left: 0;
+ margin-left: 0;
+ flex-wrap: wrap;
+ }
+
+ .app-main {
+ padding: 16px 16px 48px;
+ }
+
+ .criteria-toolbar {
+ flex-direction: column;
+ align-items: flex-start;
+ height: auto;
+ padding: 8px 0;
+ gap: 8px;
+ }
+
+ .toolbar-add-input {
+ width: 100%;
+ }
+
+ .criteria-toolbar-right {
+ width: 100%;
+ }
+
+ .summary-grid {
+ grid-template-columns: 1fr;
+ gap: 24px;
+ }
+
+ .competences-grid {
+ grid-template-columns: 1fr;
+ }
+
+ .competence-item {
+ flex-wrap: wrap;
+ }
+
+ .level-group {
+ flex-wrap: wrap;
+ margin-left: 28px;
+ }
+
+ .toast-container {
+ bottom: 12px;
+ right: 12px;
+ left: 12px;
+ max-width: none;
+ }
+}
+```
+
+- [ ] **Étape 3 : Vérification finale desktop**
+
+```bash
+npm run dev
+```
+
+Vérifier le workflow complet :
+1. Changer de CP → topbar se met à jour immédiatement
+2. Renseigner Prénom/Nom dans le topbar
+3. Cocher plusieurs critères + assigner des niveaux
+4. Cliquer "📝 Générer" → toast succès apparaît en bas à droite
+5. Cliquer "✨ Résumer avec l'IA" (sans clé) → toast erreur apparaît
+6. Le bouton "📄 PDF" apparaît dès qu'un critère est coché
+7. Ajouter un critère custom via la toolbar → apparaît dans "À classer"
+8. Drag & drop entre colonnes fonctionne toujours
+
+- [ ] **Étape 4 : Vérification mobile (DevTools, 375px)**
+
+Redimensionner à 375px. Vérifier :
+- Topbar passe en colonne, reste lisible
+- La grille passe en 1 colonne
+- La summary grid passe en 1 colonne
+- Les toasts s'affichent en bas en pleine largeur
+
+- [ ] **Étape 5 : Commit final**
+
+```bash
+git add src/components/Bilan.jsx src/components/Bilan.css
+git commit -m "chore: remove unused CSS classes and update responsive breakpoints"
+```
diff --git a/docs/superpowers/specs/2026-06-21-bilan-redesign-design.md b/docs/superpowers/specs/2026-06-21-bilan-redesign-design.md
new file mode 100644
index 0000000..3cbd00f
--- /dev/null
+++ b/docs/superpowers/specs/2026-06-21-bilan-redesign-design.md
@@ -0,0 +1,93 @@
+# Redesign Professionnel — Bilan d'Évaluation
+
+**Date :** 2026-06-21
+**Contexte :** Application React/Vite standalone utilisée par un formateur seul pour évaluer un apprenant (CP1–CP9), puis exporter un PDF.
+
+---
+
+## Problèmes identifiés
+
+1. Pas de hiérarchie visuelle — tout est au même niveau
+2. Workflow non évident — l'ordre des actions n'est pas guidé
+3. Aspect peu professionnel à montrer
+4. Actions importantes (Générer, IA, PDF) noyées en bas de page
+
+---
+
+## Architecture générale
+
+### Topbar sticky (64px)
+
+Structure en trois zones :
+
+- **Gauche :** logo Arinfo (32px hauteur) + séparateur + CP selector stylisé en pill indigo
+- **Centre :** titre dynamique `Bilan CPX — [sous-titre]` en font-weight 600, taille 15px
+- **Droite :** champs Prénom + Nom (inputs compacts, 36px, fond transparent) + trois boutons d'action principaux
+
+Boutons topbar (hiérarchie visuelle explicite) :
+- `📝 Générer` — style outline, secondaire
+- `✨ Résumer avec l'IA` — gradient violet→rose, bouton dominant
+- `📄 PDF` — gradient emerald, visible uniquement si `anySelected === true`
+
+Le topbar reste visible au scroll via `position: sticky; top: 0; z-index: 100`.
+
+### Toolbar critères (44px)
+
+Barre fine sous le topbar, fond `#f8fafc`, `border-bottom` subtile :
+- Gauche : liens texte "Tout sélectionner" / "Tout désélectionner"
+- Droite : input "Ajouter un critère…" + bouton `+` compact
+
+### Grille de critères
+
+Trois colonnes (Performance / Compétence / Connaissance), layout identique à l'existant avec amélioration du layout interne des items.
+
+**Header de card :** titre bucket uppercase + badge compteur sur fond coloré très léger (teinte propre à chaque bucket).
+
+**Layout interne d'un item :** passage de `flex-column` à `flex-row` :
+```
+[☐ checkbox] [label texte — flex-grow] [NA][EC][AC][MA] [× supprimer]
+```
+Cela rend les items plus denses, plus lisibles, et réduit la hauteur de page.
+
+### Section synthèse
+
+Séparée du reste par un divider visuel centré : `──── Synthèse & Export ────`
+
+Layout deux colonnes :
+- **Gauche :** notes formateur (textarea), tonalité (select), checkbox "insérer en tête", config API OpenAI (accordéon collapsible)
+- **Droite :** textarea bilan (monospace, `min-height: 380px`, hauteur libre)
+
+### Notifications de statut
+
+Les messages de statut (`success`, `error`, `info`) passent en **toast flottant** positionné `fixed` en bas à droite, avec disparition automatique. Ils ne s'insèrent plus dans le flux de contenu.
+
+---
+
+## Changements CSS
+
+- Ajout de `.app-topbar` (sticky header)
+- Ajout de `.criteria-toolbar`
+- Ajout de `.section-divider`
+- Modification de `.competence-item` : `flex-direction: row`, `align-items: center`
+- Modification de `.level-group` : suppression du `border-top`, intégration inline
+- Ajout de `.toast-container` + `.toast` (positionnement fixed)
+- Suppression des `.controls` génériques (remplacés par topbar et toolbar dédiés)
+
+---
+
+## Changements JSX
+
+- Le rendu passe de `.bilan-wrapper > .bilan-container` à `.app-shell > .app-topbar + .app-main`
+- Le `` CP selector, les inputs identité et les trois boutons d'action montent dans le topbar
+- La toolbar critères regroupe les boutons "Tout sélectionner/désélectionner" et le champ "Ajouter"
+- `showStatus` redirige vers un système de toast (état `toasts: []`, auto-retrait)
+- Le reste de la logique métier est inchangé
+
+---
+
+## Ce qui ne change pas
+
+- Logique métier complète (niveaux, drag & drop, génération PDF, appel OpenAI)
+- Les 3 colonnes de critères et leurs level pills
+- Les variables CSS existantes (couleurs, shadows, fonts)
+- La responsivité mobile (media queries à adapter)