# Comparateur électricité pro — Implementation Plan

> **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:** Construire `/outils/comparateur-electricite-pro/` — page outil avec calculateur 4 steps + 4000 mots de contenu Gemini-validé + 3 redirects 301 absorbant les articles cannibalisés, intégration nav/home/footer, deploy prod.

**Architecture:** Next.js 16 App Router, Server Component wrapper avec `<CalculatorWizard />` client + `<LongFormContent />` (9 sections React structurées, pas MDX). Pattern dérivé de `app/outils/simulateur-exoneration-accise-electricite/`. Redirects via `next.config.ts.async redirects()`. Validation Gemini Pro à 3 gates (architecture déjà ✅, par-section pendant écriture, VALIDE_PROD final).

**Tech Stack:** Next.js 16.1.6, React 19.2.4, TypeScript strict, Tailwind, framer-motion (compteur animé), Fuse.js (autocomplete fournisseur), Recharts (pie chart H2 5), shadcn Popover/Command, Resend (form lead), Gemini CLI 0.40 (audits SEO), humanizer skill, seo-insight-blog skill, ping-rss skill, obsidian-cli skill.

**Spec source de vérité :** `docs/superpowers/specs/2026-04-29-comparateur-electricite-pro-design.md` (commits 9d08e30, 6b1ac8a, bd75c0f).

**Branche :** `feat/comparateur-electricite-pro` (déjà créée).

---

## File Structure (toutes créations / modifications)

### Création
- `lib/comparateur/types.ts` — types `Profil`, `TypeEntreprise`, `FournisseurId`, `CalculatorInput`, `ComparisonResult`, `MarketTariff`
- `lib/comparateur/calculate-comparison.ts` — fonctions `calculateComparison()`, `inferProfil()`, `formatEuros()`, `MARKET_TARIFFS_2026`, `TURPE_AVG`, `TAXES_AVG`
- `data/comparateur/fournisseurs.ts` — 8 fournisseurs avec scores qualitatifs + prix unitaire par profil
- `app/outils/comparateur-electricite-pro/page.tsx` — server component, metadata, JsonLd, layout
- `app/outils/comparateur-electricite-pro/opengraph-image.tsx` — OG image dédiée
- `app/outils/comparateur-electricite-pro/_components/calculator-wizard.tsx` — useReducer state machine, deep-link query params
- `app/outils/comparateur-electricite-pro/_components/wizard-progress.tsx` — barre de progression 4 steps
- `app/outils/comparateur-electricite-pro/_components/step-1-profil.tsx` — type entreprise + profil C5/C4/C3
- `app/outils/comparateur-electricite-pro/_components/step-2-consommation.tsx` — MWh + code postal
- `app/outils/comparateur-electricite-pro/_components/step-3-contrat-actuel.tsx` — fournisseur actuel + prix kWh + type contrat
- `app/outils/comparateur-electricite-pro/_components/step-4-results.tsx` — estimation + ranking + CTAs
- `app/outils/comparateur-electricite-pro/_components/fournisseur-card.tsx` — card compact dans ranking
- `app/outils/comparateur-electricite-pro/_components/long-form-content.tsx` — wrapper qui assemble les 9 sections
- `app/outils/comparateur-electricite-pro/_components/h2-section-1.tsx` ... `h2-section-9.tsx` — 9 sections du contenu
- `app/outils/comparateur-electricite-pro/_components/contracts-comparison-table.tsx` — table H2 4 (visualisation 1)
- `app/outils/comparateur-electricite-pro/_components/facture-decomposition-chart.tsx` — pie chart H2 5 via Recharts (visualisation 2)
- `components/teaser-comparateur-home.tsx` — teaser visuel home (lien vers la page outil)

### Modification
- `next.config.ts:122-198` — ajouter 3 entries dans `redirects()`
- `data/links/navigation.ts:117-124` — ajouter entry `directLinks`
- `app/page.tsx` — importer `<TeaserComparateurHome />` + insérer après `<MiniSimulateurHome />`
- `app/sitemap.ts` (lecture seule, vérifier que les URLs `/guides/comparat*` ne sont plus listées explicitement → en deletion via removal MDX)

### Suppression
- `data/blogs/comparatif-electricite-pro.mdx`
- `data/blogs/comparateur-electricite-professionnel-entreprise-2026.mdx`
- `data/blogs/comparateur-energie-pro.mdx`

---

## Phase 0 — Setup (prérequis)

### Task 0.1 : Vérifier branche + spec

**Files:** none (verification only)

- [ ] **Step 1 :** Confirmer branche active

```bash
git branch --show-current
```
Expected output: `feat/comparateur-electricite-pro`

- [ ] **Step 2 :** Confirmer spec présent

```bash
ls -la docs/superpowers/specs/2026-04-29-comparateur-electricite-pro-design.md
```
Expected: file exists, mtime today.

- [ ] **Step 3 :** Confirmer dev server up (port 3000) pour Playwright tests plus tard

```bash
curl -s -o /dev/null -w "%{http_code}" http://localhost:3000
```
Expected: `200` (sinon lancer `pnpm dev` dans un autre terminal).

**Done criteria :** branche correcte, spec lisible, dev server running.
**Durée :** 2 min.

---

## Phase 1 — Calculateur (typed core + UI wizard)

### Task 1.1 : Types `lib/comparateur/types.ts`

**Files:**
- Create: `lib/comparateur/types.ts`
- Reference pattern: `lib/simulateur/types.ts`

- [ ] **Step 1 : Créer le fichier**

```ts
// lib/comparateur/types.ts

export type Profil = "C5" | "C4" | "C3" | "unknown";

export type TypeEntreprise =
  | "tpe-artisan"
  | "pme"
  | "eti-grand-compte"
  | "copropriete-syndic";

export type FournisseurId =
  | "edf"
  | "engie"
  | "totalenergies"
  | "alpiq"
  | "plum"
  | "ekwateur"
  | "mint"
  | "eni";

export type TypeContrat = "fixe" | "indexe" | "trv" | "inconnu";

export type ContratActuel = {
  fournisseurId: FournisseurId;
  prixKwhHtva: number;
  typeContrat: TypeContrat;
};

export type CalculatorInput = {
  profil: Profil;
  typeEntreprise: TypeEntreprise;
  consommationMwh: number;
  codePostal?: string;
  contratActuel?: ContratActuel;
};

export type ResolvedProfil = "C5" | "C4" | "C3";

export type FournisseurRanked = {
  id: FournisseurId;
  score: number;          // 0-100, adapté au profil
  pros: string[];
  cons: string[];
  estimatedAnnualPrice: number; // €/an TTC
};

export type RecommendedContractType = "fixe" | "indexe" | "hybride" | "sur-mesure";

export type ComparisonResult = {
  inferredProfil: ResolvedProfil;
  budgetEstimate: { min: number; max: number }; // €/an TTC
  savingsRange: { min: number; max: number };   // vs marché ou contratActuel
  rankedFournisseurs: FournisseurRanked[];
  recommendation: {
    typeContrat: RecommendedContractType;
    rationale: string;
  };
  marketContext: {
    spotEpexAvg: number;  // €/MWh moyen
    turpeApprox: number;  // €/MWh
    taxesApprox: number;  // €/MWh
  };
};

export type MarketTariff = {
  min: number;  // €/MWh HTVA
  max: number;
  avg: number;
};

// Wizard state
export type WizardStep = 1 | 2 | 3 | 4;

export type WizardState = {
  step: WizardStep;
  input: Partial<CalculatorInput>;
  result?: ComparisonResult;
};

export type WizardAction =
  | { type: "SET_PROFIL"; profil: Profil }
  | { type: "SET_TYPE_ENTREPRISE"; typeEntreprise: TypeEntreprise }
  | { type: "SET_CONSOMMATION"; mwh: number }
  | { type: "SET_CODE_POSTAL"; codePostal: string }
  | { type: "SET_CONTRAT_ACTUEL"; contrat: ContratActuel | undefined }
  | { type: "GO_TO_STEP"; step: WizardStep }
  | { type: "SET_RESULT"; result: ComparisonResult }
  | { type: "RESET" };
```

- [ ] **Step 2 : Vérifier compilation TypeScript**

```bash
pnpm tsc --noEmit
```
Expected: aucune erreur dans `lib/comparateur/types.ts` (le reste du repo doit aussi passer).

- [ ] **Step 3 : Commit**

```bash
git add lib/comparateur/types.ts
git commit -m "feat(comparateur): types core (Profil, FournisseurId, ComparisonResult, WizardState)"
```

**Done criteria :** `pnpm tsc --noEmit` 0 erreur, types exportés.
**Durée :** 10 min.

---

### Task 1.2 : Data fournisseurs `data/comparateur/fournisseurs.ts`

**Files:**
- Create: `data/comparateur/fournisseurs.ts`
- Reference pattern: `data/simulateur/sectors.ts` (structure de constants exportées)

- [ ] **Step 1 : Créer le fichier avec 8 fournisseurs principaux**

```ts
// data/comparateur/fournisseurs.ts
import type { FournisseurId, Profil } from "@/lib/comparateur/types";

export type FournisseurProfile = "C5" | "C4" | "C3";

export type Fournisseur = {
  id: FournisseurId;
  nom: string;
  logoUrl: string;
  profilsServis: FournisseurProfile[];
  typesContrat: ("fixe" | "indexe" | "spot" | "hybride" | "sur-mesure")[];
  scoresQualitatifs: {
    prix: number;
    qualiteService: number;
    vert: number;
    multiSites: number;
    expertiseB2B: number;
  };
  prixUnitaire: { C5: number; C4: number; C3: number }; // €/MWh HTVA estimé 2026
  forces: string[];
  faiblesses: string[];
  urlOfficiel: string;
};

// Sources prix unitaire 2026 : références marché CRE Q2 2026 + EPEX Spot moyen + observations courtage Acieb.
// À rafraîchir tous les trimestres.
export const FOURNISSEURS: Fournisseur[] = [
  {
    id: "edf",
    nom: "EDF Pro",
    logoUrl: "/logos/fournisseurs/edf.svg",
    profilsServis: ["C5", "C4", "C3"],
    typesContrat: ["fixe", "indexe", "sur-mesure"],
    scoresQualitatifs: { prix: 65, qualiteService: 80, vert: 70, multiSites: 90, expertiseB2B: 95 },
    prixUnitaire: { C5: 232, C4: 198, C3: 165 },
    forces: ["Acteur historique, solidité financière", "Couverture multi-sites complète", "Expertise grands comptes"],
    faiblesses: ["Tarifs rarement les plus agressifs", "Process administratif parfois lourd"],
    urlOfficiel: "https://entreprises.edf.fr",
  },
  {
    id: "engie",
    nom: "ENGIE Pro",
    logoUrl: "/logos/fournisseurs/engie.svg",
    profilsServis: ["C5", "C4", "C3"],
    typesContrat: ["fixe", "indexe", "hybride", "sur-mesure"],
    scoresQualitatifs: { prix: 70, qualiteService: 75, vert: 85, multiSites: 85, expertiseB2B: 90 },
    prixUnitaire: { C5: 226, C4: 192, C3: 160 },
    forces: ["Offres vertes structurées (PPA, GO)", "Présence Europe pour ETI"],
    faiblesses: ["Service client variable selon segment"],
    urlOfficiel: "https://particuliers.engie.fr/electricite",
  },
  {
    id: "totalenergies",
    nom: "TotalEnergies Pro",
    logoUrl: "/logos/fournisseurs/totalenergies.svg",
    profilsServis: ["C5", "C4", "C3"],
    typesContrat: ["fixe", "indexe", "sur-mesure"],
    scoresQualitatifs: { prix: 75, qualiteService: 70, vert: 75, multiSites: 80, expertiseB2B: 80 },
    prixUnitaire: { C5: 220, C4: 188, C3: 158 },
    forces: ["Tarifs compétitifs sur le marché", "Offres multi-énergie (gaz + élec)"],
    faiblesses: ["Image corporate parfois clivante"],
    urlOfficiel: "https://www.totalenergies.fr/professionnels",
  },
  {
    id: "alpiq",
    nom: "Alpiq",
    logoUrl: "/logos/fournisseurs/alpiq.svg",
    profilsServis: ["C4", "C3"],
    typesContrat: ["fixe", "indexe", "spot", "sur-mesure"],
    scoresQualitatifs: { prix: 80, qualiteService: 75, vert: 80, multiSites: 70, expertiseB2B: 85 },
    prixUnitaire: { C5: 235, C4: 185, C3: 152 },
    forces: ["Spécialiste B2B grands comptes", "Achat par tranches/clics"],
    faiblesses: ["Pas adapté aux TPE/petits sites"],
    urlOfficiel: "https://www.alpiq.fr",
  },
  {
    id: "plum",
    nom: "Plüm Énergie",
    logoUrl: "/logos/fournisseurs/plum.svg",
    profilsServis: ["C5", "C4"],
    typesContrat: ["fixe", "indexe"],
    scoresQualitatifs: { prix: 78, qualiteService: 88, vert: 95, multiSites: 60, expertiseB2B: 65 },
    prixUnitaire: { C5: 215, C4: 195, C3: 172 },
    forces: ["Engagement vert renforcé", "Service client noté très haut"],
    faiblesses: ["Multi-sites limité", "Peu de visibilité sur grands comptes"],
    urlOfficiel: "https://plum.fr",
  },
  {
    id: "ekwateur",
    nom: "ekWateur",
    logoUrl: "/logos/fournisseurs/ekwateur.svg",
    profilsServis: ["C5", "C4"],
    typesContrat: ["fixe", "indexe"],
    scoresQualitatifs: { prix: 82, qualiteService: 82, vert: 90, multiSites: 65, expertiseB2B: 70 },
    prixUnitaire: { C5: 210, C4: 192, C3: 168 },
    forces: ["Offres 100% renouvelable", "Tarifs agressifs TPE/PME"],
    faiblesses: ["Peu de produits sur-mesure"],
    urlOfficiel: "https://ekwateur.fr",
  },
  {
    id: "mint",
    nom: "Mint Energie",
    logoUrl: "/logos/fournisseurs/mint.svg",
    profilsServis: ["C5", "C4"],
    typesContrat: ["fixe", "indexe"],
    scoresQualitatifs: { prix: 85, qualiteService: 78, vert: 88, multiSites: 60, expertiseB2B: 65 },
    prixUnitaire: { C5: 205, C4: 188, C3: 170 },
    forces: ["Prix bas TPE", "Énergie verte locale"],
    faiblesses: ["Croissance rapide, mais structure jeune"],
    urlOfficiel: "https://mint-energie.com",
  },
  {
    id: "eni",
    nom: "Eni",
    logoUrl: "/logos/fournisseurs/eni.svg",
    profilsServis: ["C4", "C3"],
    typesContrat: ["fixe", "indexe", "sur-mesure"],
    scoresQualitatifs: { prix: 72, qualiteService: 70, vert: 65, multiSites: 75, expertiseB2B: 78 },
    prixUnitaire: { C5: 225, C4: 190, C3: 156 },
    forces: ["Gaz + élec couplés", "Présence européenne"],
    faiblesses: ["Mix énergétique moins vert que la concurrence"],
    urlOfficiel: "https://eni.fr/professionnels",
  },
];

export function getFournisseur(id: FournisseurId): Fournisseur {
  const f = FOURNISSEURS.find((x) => x.id === id);
  if (!f) throw new Error(`Fournisseur introuvable: ${id}`);
  return f;
}

export function getFournisseursForProfil(profil: "C5" | "C4" | "C3"): Fournisseur[] {
  return FOURNISSEURS.filter((f) => f.profilsServis.includes(profil));
}
```

- [ ] **Step 2 : Vérifier**

```bash
pnpm tsc --noEmit
```
Expected: 0 erreur.

- [ ] **Step 3 : Commit**

```bash
git add data/comparateur/fournisseurs.ts
git commit -m "feat(comparateur): data fournisseurs (8 acteurs avec scores qualitatifs + prix unitaire 2026)"
```

**Done criteria :** 8 fournisseurs typés, helpers exportés.
**Durée :** 20 min.

---

### Task 1.3 : Moteur de calcul `lib/comparateur/calculate-comparison.ts`

**Files:**
- Create: `lib/comparateur/calculate-comparison.ts`
- Reference pattern: `lib/simulateur/calculate-exemption.ts` (déterministe, retourne objet structuré, formatEuros)

- [ ] **Step 1 : Créer le fichier**

```ts
// lib/comparateur/calculate-comparison.ts
import type {
  CalculatorInput,
  ComparisonResult,
  Profil,
  ResolvedProfil,
  RecommendedContractType,
  MarketTariff,
} from "./types";
import {
  FOURNISSEURS,
  getFournisseursForProfil,
  type Fournisseur,
} from "@/data/comparateur/fournisseurs";

// Référentiel marché 2026
// Sources : CRE Q2 2026, EPEX Spot moyen 12 mois glissants, observations courtage Acieb
// À rafraîchir trimestriellement.
export const MARKET_TARIFFS_2026: Record<ResolvedProfil, MarketTariff> = {
  C5: { min: 195, max: 245, avg: 220 }, // €/MWh HTVA
  C4: { min: 165, max: 215, avg: 190 },
  C3: { min: 135, max: 185, avg: 160 },
};

export const TVA_RATE = 0.2;
export const TURPE_AVG: Record<ResolvedProfil, number> = { C5: 35, C4: 28, C3: 18 }; // €/MWh
export const TAXES_AVG = { CSPE: 25.79, CTA: 7.21 }; // €/MWh, arrêté 18/12/2025
export const SPOT_EPEX_AVG_2026 = 78; // €/MWh, moyenne 12 mois glissants approx

// Inférer le profil tarifaire d'après MWh annuels si profil = "unknown"
export function inferProfil(mwh: number): ResolvedProfil {
  if (mwh < 100) return "C5";
  if (mwh < 1500) return "C4";
  return "C3";
}

// Score adapté par fournisseur selon profil
function scoreForProfil(f: Fournisseur, profil: ResolvedProfil): number {
  // Pondérations différenciées par segment
  const weights = profil === "C5"
    ? { prix: 50, qualiteService: 25, vert: 10, multiSites: 5, expertiseB2B: 10 }
    : profil === "C4"
    ? { prix: 40, qualiteService: 20, vert: 15, multiSites: 15, expertiseB2B: 10 }
    : { prix: 35, qualiteService: 15, vert: 10, multiSites: 20, expertiseB2B: 20 };

  const s = f.scoresQualitatifs;
  const total =
    (s.prix * weights.prix +
      s.qualiteService * weights.qualiteService +
      s.vert * weights.vert +
      s.multiSites * weights.multiSites +
      s.expertiseB2B * weights.expertiseB2B) /
    100;
  return Math.round(total);
}

function recommendContract(profil: ResolvedProfil, mwh: number): {
  typeContrat: RecommendedContractType;
  rationale: string;
} {
  if (profil === "C5") {
    return {
      typeContrat: "fixe",
      rationale:
        "Pour un profil C5 (≤ 36 kVA), un contrat à prix fixe 2-3 ans capture les prix marché actuels et offre la meilleure visibilité budgétaire. La prime de risque payée est compensée par la stabilité.",
    };
  }
  if (profil === "C4") {
    return {
      typeContrat: "hybride",
      rationale:
        "Pour un profil C4 (36-250 kVA) consommant " + mwh + " MWh/an, une offre hybride (50% fixe + 50% indexé Spot ou ARENH) optimise le ratio risque/économies. Idéal pour PME/PMI prêtes à un suivi mensuel.",
    };
  }
  return {
    typeContrat: "sur-mesure",
    rationale:
      "Pour un profil C3 (>250 kVA) à " + mwh + " MWh/an, une stratégie d'achat par clics/tranches sur un marché à terme (calendar EEX) maximise les opportunités de baisse. Un courtier avec accès direct aux salles de marché devient essentiel.",
  };
}

export function calculateComparison(input: CalculatorInput): ComparisonResult {
  const inferredProfil: ResolvedProfil =
    input.profil === "unknown"
      ? inferProfil(input.consommationMwh)
      : input.profil;

  const tariff = MARKET_TARIFFS_2026[inferredProfil];
  const turpe = TURPE_AVG[inferredProfil];
  const taxesPerMwh = TAXES_AVG.CSPE + TAXES_AVG.CTA;

  // Budget annuel TTC = (fourniture + TURPE + taxes) × MWh × (1 + TVA)
  const minHt = (tariff.min + turpe + taxesPerMwh) * input.consommationMwh;
  const maxHt = (tariff.max + turpe + taxesPerMwh) * input.consommationMwh;
  const budgetEstimate = {
    min: Math.round(minHt * (1 + TVA_RATE)),
    max: Math.round(maxHt * (1 + TVA_RATE)),
  };

  // Économies — vs contrat actuel ou vs tarif marché moyen
  let savingsRange: { min: number; max: number };
  if (input.contratActuel) {
    const prixActuelMwhHtva = input.contratActuel.prixKwhHtva * 1000; // kWh → MWh
    const economiesMin = Math.max(0, (prixActuelMwhHtva - tariff.max) * input.consommationMwh);
    const economiesMax = Math.max(0, (prixActuelMwhHtva - tariff.min) * input.consommationMwh);
    savingsRange = { min: Math.round(economiesMin * (1 + TVA_RATE)), max: Math.round(economiesMax * (1 + TVA_RATE)) };
  } else {
    // vs tarif moyen marché
    const economiesMax = (tariff.avg - tariff.min) * input.consommationMwh * (1 + TVA_RATE);
    savingsRange = { min: 0, max: Math.round(economiesMax) };
  }

  // Ranking fournisseurs
  const candidats = getFournisseursForProfil(inferredProfil);
  const ranked = candidats
    .map((f) => ({
      id: f.id,
      score: scoreForProfil(f, inferredProfil),
      pros: f.forces,
      cons: f.faiblesses,
      estimatedAnnualPrice: Math.round(
        (f.prixUnitaire[inferredProfil] + turpe + taxesPerMwh) *
          input.consommationMwh *
          (1 + TVA_RATE)
      ),
    }))
    .sort((a, b) => b.score - a.score)
    .slice(0, 5);

  return {
    inferredProfil,
    budgetEstimate,
    savingsRange,
    rankedFournisseurs: ranked,
    recommendation: recommendContract(inferredProfil, input.consommationMwh),
    marketContext: {
      spotEpexAvg: SPOT_EPEX_AVG_2026,
      turpeApprox: turpe,
      taxesApprox: taxesPerMwh,
    },
  };
}

const EUROS_FORMATTER = new Intl.NumberFormat("fr-FR", {
  style: "currency",
  currency: "EUR",
  maximumFractionDigits: 0,
});

export function formatEuros(value: number): string {
  return EUROS_FORMATTER.format(value);
}
```

- [ ] **Step 2 : Vérifier**

```bash
pnpm tsc --noEmit
```
Expected: 0 erreur.

- [ ] **Step 3 : Sanity check manuel via REPL Node (one-shot)**

```bash
pnpm exec tsx -e 'import { calculateComparison } from "./lib/comparateur/calculate-comparison.ts"; console.log(JSON.stringify(calculateComparison({ profil: "C4", typeEntreprise: "pme", consommationMwh: 800 }), null, 2));'
```
Expected: objet ComparisonResult avec `inferredProfil: "C4"`, `budgetEstimate.max ≈ 200000-220000` €, ranking 5 fournisseurs.

Si `tsx` indispo : skip ce step (la vérif sera faite via le wizard step 4 plus tard).

- [ ] **Step 4 : Commit**

```bash
git add lib/comparateur/calculate-comparison.ts
git commit -m "feat(comparateur): moteur de calcul (référentiel 2026, scoring profil, recommandation contrat)"
```

**Done criteria :** `tsc` 0 erreur, sanity check (si tsx dispo) renvoie un résultat plausible.
**Durée :** 30 min.

---

### Task 1.4 : Wizard progress bar `_components/wizard-progress.tsx`

**Files:**
- Create: `app/outils/comparateur-electricite-pro/_components/wizard-progress.tsx`
- Reference: `app/outils/simulateur-exoneration-accise-electricite/_components/wizard-progress.tsx`

- [ ] **Step 1 : Créer le fichier (copier le pattern, adapter pour 4 steps au lieu de 5)**

```bash
cp app/outils/simulateur-exoneration-accise-electricite/_components/wizard-progress.tsx app/outils/comparateur-electricite-pro/_components/wizard-progress.tsx
```

- [ ] **Step 2 : Adapter — labels et nombre de steps**

Modifier le tableau de labels pour afficher : "Profil", "Consommation", "Contrat actuel", "Résultats". Ajuster la prop `totalSteps` à 4. Garder la logique de progression et le styling Tailwind tels quels.

- [ ] **Step 3 : Vérifier**

```bash
pnpm tsc --noEmit
```

- [ ] **Step 4 : Commit**

```bash
git add app/outils/comparateur-electricite-pro/_components/wizard-progress.tsx
git commit -m "feat(comparateur): wizard progress bar (4 steps)"
```

**Done criteria :** composant compile, 4 labels.
**Durée :** 10 min.

---

### Task 1.5 : Step 1 — Profil entreprise

**Files:**
- Create: `app/outils/comparateur-electricite-pro/_components/step-1-profil.tsx`
- Reference: `app/outils/simulateur-exoneration-accise-electricite/_components/step-1-sector.tsx`

- [ ] **Step 1 : Implémenter** (radio cards type entreprise + radio cards profil C5/C4/C3/unknown)

Le composant reçoit `state: WizardState`, `dispatch: (a: WizardAction) => void`. Affiche 2 fieldsets :

1. Type d'entreprise — 4 radio cards : "TPE / Artisan", "PME", "ETI / Grand compte", "Copropriété / Syndic". `dispatch({ type: "SET_TYPE_ENTREPRISE", typeEntreprise })`.
2. Profil tarifaire — 4 radio cards : "C5 (≤ 36 kVA)", "C4 (36-250 kVA)", "C3 (> 250 kVA)", "Je ne sais pas". `dispatch({ type: "SET_PROFIL", profil })`.

Bouton "Suivant" grisé tant que `state.input.typeEntreprise && state.input.profil`. Au click → `dispatch({ type: "GO_TO_STEP", step: 2 })`.

Tracker : `trackEvent("comparateur_step_complete", { step: "1" })` au click "Suivant".

Patterns Tailwind : reprendre exactement le styling de `step-1-sector.tsx` (radio cards `border-orange-500` quand sélectionné, espacement, typographie).

- [ ] **Step 2 : Vérifier**

```bash
pnpm tsc --noEmit
```

- [ ] **Step 3 : Commit**

```bash
git add app/outils/comparateur-electricite-pro/_components/step-1-profil.tsx
git commit -m "feat(comparateur): step 1 (type entreprise + profil tarifaire C5/C4/C3)"
```

**Done criteria :** compile, 2 fieldsets fonctionnels.
**Durée :** 25 min.

---

### Task 1.6 : Step 2 — Consommation

**Files:**
- Create: `app/outils/comparateur-electricite-pro/_components/step-2-consommation.tsx`
- Reference: `app/outils/simulateur-exoneration-accise-electricite/_components/step-2-consumption.tsx`

- [ ] **Step 1 : Implémenter**

Inputs :
- Volume annuel (MWh) : `<input type="number" min="0" step="1" />` avec helper "Total annuel kWh / 1000". Optionnellement un slider visuel.
- Code postal (optionnel) : `<input type="text" pattern="[0-9]{5}" maxLength={5} />` avec helper "5 chiffres, optionnel pour zone TURPE".

Boutons "Précédent" → step 1 / "Suivant" → step 3, "Suivant" grisé si MWh ≤ 0.

Tracker `trackEvent("comparateur_step_complete", { step: "2" })`.

- [ ] **Step 2 : Vérifier compile**

```bash
pnpm tsc --noEmit
```

- [ ] **Step 3 : Commit**

```bash
git add app/outils/comparateur-electricite-pro/_components/step-2-consommation.tsx
git commit -m "feat(comparateur): step 2 (consommation MWh + code postal)"
```

**Done criteria :** compile, validation MWh > 0.
**Durée :** 20 min.

---

### Task 1.7 : Step 3 — Contrat actuel (optionnel)

**Files:**
- Create: `app/outils/comparateur-electricite-pro/_components/step-3-contrat-actuel.tsx`
- Reference patterns:
  - autocomplete fournisseur via Fuse.js : `app/outils/simulateur-exoneration-accise-electricite/_components/step-1-sector.tsx` (NAF codes search)
  - shadcn Popover/Command : `components/ui/popover.tsx`, `components/ui/command.tsx`

- [ ] **Step 1 : Implémenter**

Switch "Activer le calcul d'économies réelles ? Oui / Non". Si Non → `dispatch({ type: "SET_CONTRAT_ACTUEL", contrat: undefined })` puis bouton "Voir les résultats" → step 4. Si Oui → afficher le formulaire :

- Fournisseur actuel (autocomplete via Fuse.js sur `FOURNISSEURS` de `data/comparateur/fournisseurs.ts`)
- Prix kWh HTVA actuel (€) : input numeric, step="0.001"
- Type de contrat actuel : select "fixe" / "indexe" / "trv" / "inconnu"

Bouton "Précédent" → step 2 / "Voir les résultats" → step 4. Tracker `trackEvent("comparateur_step_complete", { step: "3" })`.

- [ ] **Step 2 : Vérifier**

```bash
pnpm tsc --noEmit
```

- [ ] **Step 3 : Commit**

```bash
git add app/outils/comparateur-electricite-pro/_components/step-3-contrat-actuel.tsx
git commit -m "feat(comparateur): step 3 contrat actuel optionnel (autocomplete Fuse.js)"
```

**Done criteria :** compile, autocomplete fournisseur fonctionnel.
**Durée :** 30 min.

---

### Task 1.8 : Composant `<FournisseurCard />`

**Files:**
- Create: `app/outils/comparateur-electricite-pro/_components/fournisseur-card.tsx`

- [ ] **Step 1 : Implémenter**

Card compacte avec : logo (Image avec fallback texte si SVG manquant), nom, badge score `0-100`, chip "Recommandé pour C5/C4/C3", liste forces/faiblesses (1-2 chacun), prix annuel estimé `formatEuros(estimatedAnnualPrice)`, lien "Site officiel" (target="_blank", rel="noopener noreferrer nofollow"). Layout `rounded-xl border bg-white p-4 sm:p-6 shadow-sm`.

- [ ] **Step 2 : Vérifier**

```bash
pnpm tsc --noEmit
```

- [ ] **Step 3 : Commit**

```bash
git add app/outils/comparateur-electricite-pro/_components/fournisseur-card.tsx
git commit -m "feat(comparateur): FournisseurCard component (logo + score + estimate)"
```

**Done criteria :** compile, card affiche les 5 éléments.
**Durée :** 15 min.

---

### Task 1.9 : Step 4 — Résultats

**Files:**
- Create: `app/outils/comparateur-electricite-pro/_components/step-4-results.tsx`
- Reference patterns:
  - compteur animé : `components/mini-simulateur-home.tsx` (framer-motion `useMotionValue` + `animate`)
  - layout résultats : `app/outils/simulateur-exoneration-accise-electricite/_components/step-5-results-full.tsx`

- [ ] **Step 1 : Implémenter**

Au mount : appeler `calculateComparison(input)` et `dispatch({ type: "SET_RESULT", result })`. Afficher :

1. Headline animé : "Économies estimées : jusqu'à `formatEuros(savingsRange.max)` /an" (compteur framer-motion).
2. Fourchette budget annuel TTC : "Entre `formatEuros(min)` et `formatEuros(max)` selon offre choisie".
3. Liste 5 `<FournisseurCard />` (rankedFournisseurs).
4. Pavé "Recommandation contrat" : type + rationale.
5. CTA primaire : `<CalButton variant="default" location="comparateur_results_primary">` "Parler à un expert (15min, gratuit)".
6. CTA secondaire : Bouton "Recevoir mes 5 devis personnalisés" → handler qui ouvre form lead capture inline (à implémenter plus tard ou juste ouvrir un mailto/anchor pour le moment).
7. Ligne crédibilité : "Basé sur tarifs marché 2026 (CRE, EPEX) et données courtage Acieb".

Trackers :
- Au mount : `trackEvent("comparateur_estimation_shown", { profil, mwh, savingsMax })`
- Click CalButton → géré par le composant lui-même (location prop)
- Click devis → `trackEvent("comparateur_cta_devis_click")`

- [ ] **Step 2 : Vérifier**

```bash
pnpm tsc --noEmit
```

- [ ] **Step 3 : Commit**

```bash
git add app/outils/comparateur-electricite-pro/_components/step-4-results.tsx
git commit -m "feat(comparateur): step 4 résultats (compteur animé + ranking + CTAs)"
```

**Done criteria :** compile, results s'affichent avec données dynamiques.
**Durée :** 35 min.

---

### Task 1.10 : Wizard principal `<CalculatorWizard />`

**Files:**
- Create: `app/outils/comparateur-electricite-pro/_components/calculator-wizard.tsx`
- Reference: `app/outils/simulateur-exoneration-accise-electricite/_components/simulateur-wizard.tsx` (useReducer + useSearchParams pour deep-link)

- [ ] **Step 1 : Implémenter**

```ts
"use client";

import { useReducer, useEffect, useRef } from "react";
import { useSearchParams } from "next/navigation";
import type { WizardState, WizardAction } from "@/lib/comparateur/types";
import { calculateComparison } from "@/lib/comparateur/calculate-comparison";
import { WizardProgress } from "./wizard-progress";
import { Step1Profil } from "./step-1-profil";
import { Step2Consommation } from "./step-2-consommation";
import { Step3ContratActuel } from "./step-3-contrat-actuel";
import { Step4Results } from "./step-4-results";

const initialState: WizardState = {
  step: 1,
  input: {},
};

function reducer(state: WizardState, action: WizardAction): WizardState {
  switch (action.type) {
    case "SET_PROFIL":
      return { ...state, input: { ...state.input, profil: action.profil } };
    case "SET_TYPE_ENTREPRISE":
      return { ...state, input: { ...state.input, typeEntreprise: action.typeEntreprise } };
    case "SET_CONSOMMATION":
      return { ...state, input: { ...state.input, consommationMwh: action.mwh } };
    case "SET_CODE_POSTAL":
      return { ...state, input: { ...state.input, codePostal: action.codePostal } };
    case "SET_CONTRAT_ACTUEL":
      return { ...state, input: { ...state.input, contratActuel: action.contrat } };
    case "GO_TO_STEP":
      return { ...state, step: action.step };
    case "SET_RESULT":
      return { ...state, result: action.result };
    case "RESET":
      return initialState;
  }
}

export function CalculatorWizard() {
  const [state, dispatch] = useReducer(reducer, initialState);
  const searchParams = useSearchParams();
  const hydratedRef = useRef(false);

  // Deep-link prefill : ?profil=C4&mwh=800
  useEffect(() => {
    if (hydratedRef.current) return;
    const profilParam = searchParams.get("profil");
    const mwhParam = searchParams.get("mwh");
    if (!profilParam && !mwhParam) return;
    hydratedRef.current = true;
    if (profilParam && ["C5","C4","C3"].includes(profilParam)) {
      dispatch({ type: "SET_PROFIL", profil: profilParam as "C5" | "C4" | "C3" });
    }
    const mwhNum = mwhParam ? parseFloat(mwhParam) : NaN;
    if (Number.isFinite(mwhNum) && mwhNum > 0) {
      dispatch({ type: "SET_CONSOMMATION", mwh: mwhNum });
      dispatch({ type: "GO_TO_STEP", step: 3 });
    } else if (profilParam) {
      dispatch({ type: "GO_TO_STEP", step: 2 });
    }
  }, [searchParams]);

  return (
    <div className="rounded-2xl bg-white shadow-lg p-6 sm:p-10 max-w-3xl mx-auto">
      <WizardProgress step={state.step} totalSteps={4} />
      {state.step === 1 && <Step1Profil state={state} dispatch={dispatch} />}
      {state.step === 2 && <Step2Consommation state={state} dispatch={dispatch} />}
      {state.step === 3 && <Step3ContratActuel state={state} dispatch={dispatch} />}
      {state.step === 4 && <Step4Results state={state} dispatch={dispatch} />}
    </div>
  );
}
```

- [ ] **Step 2 : Vérifier**

```bash
pnpm tsc --noEmit
```

- [ ] **Step 3 : Commit**

```bash
git add app/outils/comparateur-electricite-pro/_components/calculator-wizard.tsx
git commit -m "feat(comparateur): CalculatorWizard (useReducer + deep-link ?profil&mwh)"
```

**Done criteria :** compile, le wizard rend correctement step 1.
**Durée :** 25 min.

---

## Phase 2 — Page wrapper minimal pour tester le wizard

### Task 2.1 : Page server component temporaire (calculateur seul)

**Files:**
- Create: `app/outils/comparateur-electricite-pro/page.tsx`
- Reference: `app/outils/simulateur-exoneration-accise-electricite/page.tsx`

- [ ] **Step 1 : Implémenter version minimale (sans contenu long-form pour l'instant)**

```tsx
import type { Metadata } from "next";
import { CalculatorWizard } from "./_components/calculator-wizard";
import { JsonLd } from "@/components/json-ld";
import { Breadcrumb } from "@/components/breadcrumb";

export const metadata: Metadata = {
  title: "Comparatif électricité pro 2026 : Comparateur B2B expert",
  description:
    "Comparatif électricité pro 2026 : comparateur B2B expert. Profils C5/C4/C3, contrats fixe/indexé/sur-mesure, ARENH, TURPE, mécanisme capacité décryptés.",
  alternates: {
    canonical: "https://www.aciebenergie.fr/outils/comparateur-electricite-pro/",
  },
};

const breadcrumbItems = [
  { label: "Accueil", href: "/" },
  { label: "Outils", href: "/outils/" },
  { label: "Comparateur électricité pro", href: "/outils/comparateur-electricite-pro/" },
];

export default function Page() {
  return (
    <>
      <JsonLd
        data={{
          "@context": "https://schema.org",
          "@type": "BreadcrumbList",
          itemListElement: breadcrumbItems.map((b, i) => ({
            "@type": "ListItem",
            position: i + 1,
            name: b.label,
            item: `https://www.aciebenergie.fr${b.href}`,
          })),
        }}
      />
      <main className="min-h-screen pt-16">
        <Breadcrumb items={breadcrumbItems} />
        <section className="py-12 sm:py-16">
          <div className="container mx-auto px-4">
            <h1 className="text-3xl sm:text-4xl lg:text-5xl font-bold text-center mb-4">
              Comparatif électricité pro 2026 : Comparateur B2B expert
            </h1>
            <p className="text-center text-gray-600 max-w-2xl mx-auto mb-10">
              Calculez vos économies en 30 secondes. Profils C5/C4/C3, ranking
              fournisseurs, recommandation contrat adaptée à votre tolérance au
              risque.
            </p>
            <CalculatorWizard />
          </div>
        </section>
      </main>
    </>
  );
}
```

- [ ] **Step 2 : Build dev**

```bash
pnpm tsc --noEmit
```
Expected: 0 erreur.

- [ ] **Step 3 : Test manuel browser**

```bash
# Le dev server tourne déjà sur :3000
curl -sI http://localhost:3000/outils/comparateur-electricite-pro/ | head -3
```
Expected: `HTTP/1.1 200 OK`.

Ouvrir `http://localhost:3000/outils/comparateur-electricite-pro/` dans Playwright MCP / Chrome MCP et vérifier visuellement que les 4 steps sont navigables et que step 4 affiche un résultat plausible.

- [ ] **Step 4 : Commit**

```bash
git add app/outils/comparateur-electricite-pro/page.tsx
git commit -m "feat(comparateur): page wrapper avec calculateur (contenu long-form à venir)"
```

**Done criteria :** page accessible, wizard 4 steps fonctionnel, résultats plausibles.
**Durée :** 25 min.

---

## Phase 3 — Contenu 4000 mots avec gates Gemini (le plus long)

### Stratégie d'écriture

**Architecture H1/H2/H3 et word counts sont gelés dans le spec section 6 et NE doivent pas être redesignés.** Pour chaque H2 (1 à 9) :

1. Rédiger le composant React `h2-section-N.tsx` (le composant rend le markdown sous forme JSX, avec data dynamique injectée si applicable).
2. Soumettre la section à Gemini via le **Prompt Étape 7** (template ci-dessous).
3. Si retour ≠ `VALIDE` → appliquer les corrections, re-soumettre. Max 3 itérations sinon STOP humain.
4. Sur HTTP 429 → `sleep 60 && retry`. Jamais simuler une réponse Gemini.

### Template Prompt Étape 7

```
Agis en tant qu'auditeur SEO/AEO/GSO très strict pour Elevaseo.
Section traitant le sous-sujet : `[H2_TITLE]`.
Architecture validée Gemini Pro (immutable) : H2 numéro [N] dans la page comparateur électricité pro,
cible mots indicative [WORD_COUNT].

[SECTION_TEXT_RENDERED_FROM_TSX]

Audite selon ces piliers :
1. SEO sémantique : champ lexical riche, entités LSI attendues présentes naturellement, primary keyword densité raisonnable (~1%).
2. AEO / extraction LLM : réponse directe et concise, listes/gras pour faciliter l'extraction, phrases courtes.
3. GSO / E-E-A-T : valeur ajoutée vs un contenu générique, signaux d'expertise (chiffres précis, références datées CRE/EPEX/arrêté 18-12-2025/LF 2026), absence de fluff.
4. Contexte SEO-insight : la section utilise-t-elle au moins une donnée chiffrée du brief (volumes, scores, médianes) ? Au moins un lien interne contextuel ?
5. Conformité au plan : le titre H2/H3, le word count et les ancres internes correspondent-ils au spec ?

Consigne : ne réécris pas. Si défauts, retourne une liste à puces directive et obligatoire. Si parfait, retourne UNIQUEMENT le mot `VALIDE`.
```

### Task 3.1 : H2 1 — "Pourquoi réaliser un comparatif électricité pro en 2026 ?"

**Files:**
- Create: `app/outils/comparateur-electricite-pro/_components/h2-section-1.tsx`

- [ ] **Step 1 : Rédiger 400 mots couvrant les 3 H3 du spec** (fin bouclier tarifaire + EPEX, LF 2026, sécuriser budget face à la volatilité). Inclure ancre interne `/guides/cours-energie-eex-marche-gros-analyse-guide-2026`. Sortir un composant React qui rend du JSX structuré (h2, p, ul, strong, Link). Utiliser au moins 2-3 entités LSI parmi : EPEX SPOT, prix de l'abonnement, comparateur énergie pro.

- [ ] **Step 2 : Extraire le texte rendu en plain text via `JSDOM` ou simplement avec un script `tsx` qui mock `next/link` puis appelle `renderToStaticMarkup`. Sinon, copier-coller le texte du JSX dans un fichier temporaire `/tmp/h2-1.txt` et compter les mots avec `wc -w`.**

```bash
wc -w /tmp/h2-1.txt
```
Expected: 380-420 mots.

- [ ] **Step 3 : Soumettre à Gemini Pro avec template Étape 7**

```bash
GEMINI_CLI_TRUST_WORKSPACE=true gemini --model gemini-3-pro-preview -p "$(cat /tmp/h2-1-prompt.txt)" 2>&1 | tee /tmp/h2-1-audit.txt
```

- [ ] **Step 4 : Boucler corrections jusqu'à `VALIDE`** (max 3 itérations). Si circuit breaker → escalader.

- [ ] **Step 5 : Commit**

```bash
git add app/outils/comparateur-electricite-pro/_components/h2-section-1.tsx
git commit -m "content(h2-1): pourquoi comparer 2026 (Gemini VALIDE, 400 mots)"
```

**Done criteria :** Gemini renvoie `VALIDE`, word count dans tolérance ±5%.
**Durée :** 40-60 min (dont 1-3 itérations Gemini).

### Task 3.2 — Task 3.9 : H2 2 à H2 9 (même protocole)

Pour chaque section, suivre EXACTEMENT le protocole de Task 3.1 :

| Task | H2 | Mots | Ancres internes | Visualisation |
|---|---|---|---|---|
| 3.2 | H2 2 — Profils C5/C4/C3 | 500 | `/guides/contrat-electricite-multi-sites-centraliser-negocier-2026` | — |
| 3.3 | H2 3 — 6 critères de choix | 450 | `/guides/contrat-electricite-pro-guide-2026` | — |
| 3.4 | H2 4 — Fixe/indexé/sur-mesure | 500 | `/guides/contrat-electricite-professionnel-fixe-indexe-spot-2026`, `/guides/achat-electricite-par-clics-tranches-strategie-entreprise-2026` | **Table contrats** (Task 3.10) |
| 3.5 | H2 5 — ARENH/TURPE/Capacité | 450 | `/outils/simulateur-exoneration-accise-electricite`, `/guides/baisse-cta-electricite-2026-impact-facture-pro` | **Pie chart facture C4** (Task 3.11) |
| 3.6 | H2 6 — Courtier vs comparateur | 450 | `/guides/courtier-en-energie-vs-comparateur-en-ligne`, `/guides/courtier-energie-prix-commission-remuneration-2026` | — |
| 3.7 | H2 7 — Notre méthodologie | 350 | `/guides/devis-electricite-entreprise-guide-complet` | — |
| 3.8 | H2 8 — 4 étapes changer fournisseur | 400 | `/guides/changer-fournisseur-electricite-professionnel-guide-2026` | — |
| 3.9 | H2 9 — FAQ 6 PAA | 500 | `/guides/courtier-electricite-professionnel` | — (mais FAQPage schema dans page.tsx) |

Pour chaque task : files=`h2-section-N.tsx`, steps 1-5 identiques (rédaction → word count → Gemini audit → boucle → commit). 1 commit par section pour traçabilité Gemini.

**Done criteria global Phase 3 :** total cumulé du contenu = 4000 mots ±2% (3920-4080), 9 commits VALIDE Gemini.
**Durée Phase 3 :** ~6-8h (40-60 min × 9 sections).

### Task 3.10 : Table contrats `<ContractsComparisonTable />` (visualisation H2 4)

**Files:**
- Create: `app/outils/comparateur-electricite-pro/_components/contracts-comparison-table.tsx`

- [ ] **Step 1 : Implémenter table HTML 4 colonnes (Type contrat / Visibilité budgétaire / Potentiel baisse / Risque hausse / Profil recommandé) et 4 lignes (Fixe / Indexé / Hybride / Sur-mesure). Layout responsive `overflow-x-auto` + `min-w-[640px]`. Inclure dans `<H2Section4 />`.

- [ ] **Step 2 : Compile + commit**

```bash
git add app/outils/comparateur-electricite-pro/_components/contracts-comparison-table.tsx
git commit -m "feat(comparateur): ContractsComparisonTable (H2 4 visualisation 1)"
```

**Durée :** 20 min.

### Task 3.11 : Pie chart `<FactureDecompositionChart />` (visualisation H2 5)

**Files:**
- Create: `app/outils/comparateur-electricite-pro/_components/facture-decomposition-chart.tsx`

- [ ] **Step 1 : Implémenter Recharts PieChart** (déjà installé `recharts: ^2.15.4`). Données : `[{ name: "Fourniture", value: 55 }, { name: "Acheminement TURPE", value: 25 }, { name: "Taxes & Accise", value: 20 }]`. Légende, tooltip. Insérer dans `<H2Section5 />`. Composant client `"use client"`.

- [ ] **Step 2 : Compile + commit**

```bash
git add app/outils/comparateur-electricite-pro/_components/facture-decomposition-chart.tsx
git commit -m "feat(comparateur): FactureDecompositionChart (Recharts pie, H2 5 visualisation 2)"
```

**Durée :** 25 min.

### Task 3.12 : Wrapper `<LongFormContent />`

**Files:**
- Create: `app/outils/comparateur-electricite-pro/_components/long-form-content.tsx`

- [ ] **Step 1 : Assembler les 9 sections**

```tsx
import { H2Section1 } from "./h2-section-1";
import { H2Section2 } from "./h2-section-2";
// ...
import { H2Section9 } from "./h2-section-9";

export function LongFormContent() {
  return (
    <article className="prose prose-lg max-w-3xl mx-auto py-16 px-4">
      <H2Section1 />
      <H2Section2 />
      <H2Section3 />
      <H2Section4 />
      <H2Section5 />
      <H2Section6 />
      <H2Section7 />
      <H2Section8 />
      <H2Section9 />
    </article>
  );
}
```

- [ ] **Step 2 : Compile + commit**

```bash
git add app/outils/comparateur-electricite-pro/_components/long-form-content.tsx
git commit -m "feat(comparateur): LongFormContent wrapper (assemble 9 sections)"
```

**Durée :** 10 min.

---

## Phase 4 — Page finale + assets SEO

### Task 4.1 : Mettre à jour `page.tsx` avec contenu long-form + JsonLd complet

**Files:**
- Modify: `app/outils/comparateur-electricite-pro/page.tsx`

- [ ] **Step 1 : Ajouter `<LongFormContent />` après le wizard, ajouter JsonLd `SoftwareApplication`, `Article`, `FAQPage`**

```tsx
// page.tsx — ajouts
import { LongFormContent } from "./_components/long-form-content";

const softwareAppJsonLd = {
  "@context": "https://schema.org",
  "@type": "SoftwareApplication",
  name: "Comparateur électricité pro Acieb",
  applicationCategory: "BusinessApplication",
  operatingSystem: "Web",
  offers: { "@type": "Offer", price: "0", priceCurrency: "EUR" },
  description: "Calculez en 30 secondes le meilleur fournisseur d'électricité B2B pour votre profil C5/C4/C3.",
};

const articleJsonLd = {
  "@context": "https://schema.org",
  "@type": "Article",
  headline: "Comparatif électricité pro 2026 : Comparateur B2B expert",
  datePublished: "2026-04-29",
  dateModified: "2026-04-29",
  author: { "@type": "Organization", name: "Acieb Énergie" },
  publisher: { "@type": "Organization", name: "Acieb Énergie", url: "https://www.aciebenergie.fr" },
};

const faqJsonLd = {
  "@context": "https://schema.org",
  "@type": "FAQPage",
  mainEntity: [
    // 6 questions PAA du spec section 6 H2 9, avec réponses 40-60 mots chaque
    // À renseigner par le rédacteur lors de la Phase 3 Task 3.9
  ],
};

// Dans le JSX, ajouter <JsonLd> pour chaque schema, et <LongFormContent /> après la section calculateur.
```

- [ ] **Step 2 : Build full + tsc**

```bash
pnpm tsc --noEmit && pnpm build
```
Expected: `Compiled successfully`.

- [ ] **Step 3 : Commit**

```bash
git add app/outils/comparateur-electricite-pro/page.tsx
git commit -m "feat(comparateur): page finale avec LongFormContent + JsonLd (SoftwareApp + Article + FAQPage + Breadcrumb)"
```

**Durée :** 30 min.

---

### Task 4.2 : OG image dédiée `opengraph-image.tsx`

**Files:**
- Create: `app/outils/comparateur-electricite-pro/opengraph-image.tsx`
- Reference: `app/outils/simulateur-exoneration-accise-electricite/opengraph-image.tsx`

- [ ] **Step 1 : Adapter le pattern existant** (changer titre, gradient, accent couleur si pertinent).

- [ ] **Step 2 : Vérifier compile, le fichier est auto-routé par Next.js**

```bash
pnpm tsc --noEmit
curl -sI http://localhost:3000/outils/comparateur-electricite-pro/opengraph-image
# Expected: 200 + Content-Type: image/png
```

- [ ] **Step 3 : Commit**

```bash
git add app/outils/comparateur-electricite-pro/opengraph-image.tsx
git commit -m "feat(comparateur): OG image dédiée"
```

**Durée :** 15 min.

---

### Task 4.3 : Gate Gemini final (Étape 8b VALIDE_PROD) sur le contenu complet

**Files:** none (audit only)

- [ ] **Step 1 : Concaténer le rendu HTML complet du contenu long-form**

Lancer le dev server, fetcher `http://localhost:3000/outils/comparateur-electricite-pro/`, extraire le markup `<article>` (via Playwright `page.locator('article').textContent()` ou `curl ... | sed`).

```bash
curl -s http://localhost:3000/outils/comparateur-electricite-pro/ > /tmp/comparateur-html.txt
wc -w /tmp/comparateur-html.txt  # vérification grossière
```

- [ ] **Step 2 : Soumettre à Gemini Pro avec template Étape 8b**

Audit du markup complet pour : frontmatter (N/A car tsx, mais metadata), structure HN sans saute, ancres sémantiquement optimisées, FAQPage schema valide, word count ≥ 4000.

- [ ] **Step 3 : Si retour ≠ `VALIDE_PROD` → corriger et re-soumettre. Si VALIDE_PROD → continuer.**

- [ ] **Step 4 : Humanizer (skill obligatoire avant ship)**

Invoquer le skill `humanizer` sur chaque `h2-section-N.tsx` (corps texte uniquement, pas le JSX/imports). Préserver entités LSI, hiérarchie HN, composants Recharts/Image, liens, données chiffrées.

```bash
# Pseudo : pour chaque section, appliquer humanizer
```

- [ ] **Step 5 : Commit (si modifications post-humanizer)**

```bash
git add app/outils/comparateur-electricite-pro/_components/h2-section-*.tsx
git commit -m "content(comparateur): humanizer pass + Gemini VALIDE_PROD"
```

**Done criteria :** Gemini retourne `VALIDE_PROD`, humanizer passé, word count ≥ 4000.
**Durée :** 45 min.

---

## Phase 5 — Intégration site (redirects, nav, home, sitemap)

### Task 5.1 : Redirects 301 dans `next.config.ts`

**Files:**
- Modify: `next.config.ts:122-198`

- [ ] **Step 1 : Ajouter 3 entries dans `redirects()` avec `permanent: true`** (= 308 RFC 9110, consistance avec les redirects existants du projet, traité comme 301 par Google côté SEO).

```ts
// Cannibalisation comparateur électricité pro — absorption 2026-04-29
{ source: "/guides/comparatif-electricite-pro", destination: "/outils/comparateur-electricite-pro", permanent: true },
{ source: "/guides/comparateur-electricite-professionnel-entreprise-2026", destination: "/outils/comparateur-electricite-pro", permanent: true },
{ source: "/guides/comparateur-energie-pro", destination: "/outils/comparateur-electricite-pro", permanent: true },
```

⚠️ Attention : il existe déjà des redirects `/blog/comparat*` → `/guides/comparat*` (lignes 150-152). Ces nouveaux redirects vont chaîner `/blog/comparat*` → `/guides/comparat*` → `/outils/comparateur-electricite-pro`. Next.js permet le chaînage mais c'est suboptimal. **Mettre à jour les 3 entries `/blog/...` existantes pour pointer directement vers `/outils/comparateur-electricite-pro/`** afin d'éviter le double hop. Les 3 lignes concernées :

```ts
// AVANT (lignes 150-152)
{ source: "/blog/comparateur-electricite-professionnel-entreprise-2026", destination: "/guides/comparateur-electricite-professionnel-entreprise-2026", permanent: true },
{ source: "/blog/comparateur-energie-pro", destination: "/guides/comparateur-energie-pro", permanent: true },
{ source: "/blog/comparatif-electricite-pro", destination: "/guides/comparatif-electricite-pro", permanent: true },

// APRÈS (court-circuiter vers /outils/)
{ source: "/blog/comparateur-electricite-professionnel-entreprise-2026", destination: "/outils/comparateur-electricite-pro", permanent: true },
{ source: "/blog/comparateur-energie-pro", destination: "/outils/comparateur-electricite-pro", permanent: true },
{ source: "/blog/comparatif-electricite-pro", destination: "/outils/comparateur-electricite-pro", permanent: true },
```

- [ ] **Step 2 : Build**

```bash
pnpm build
```
Expected: 0 erreur.

- [ ] **Step 3 : Tester localement**

```bash
# Le dev server prend en compte les redirects
curl -sI http://localhost:3000/guides/comparatif-electricite-pro/ | head -3
# Expected: HTTP/1.1 308 Permanent Redirect (= 301 SEO-equivalent côté Google)
# Location: /outils/comparateur-electricite-pro/
```

- [ ] **Step 4 : Commit**

```bash
git add next.config.ts
git commit -m "feat(redirects): 301 des 3 articles cannibalisants → /outils/comparateur-electricite-pro/"
```

**Done criteria :** redirects fonctionnent en local, build passe.
**Durée :** 15 min.

---

### Task 5.2 : Suppression des 3 MDX cannibalisés

**Files:**
- Delete: `data/blogs/comparatif-electricite-pro.mdx`
- Delete: `data/blogs/comparateur-electricite-professionnel-entreprise-2026.mdx`
- Delete: `data/blogs/comparateur-energie-pro.mdx`

- [ ] **Step 1 : Vérifier qu'aucun autre MDX ne référence ces 3 slugs dans `relatedPosts`**

```bash
grep -l "comparatif-electricite-pro\|comparateur-electricite-professionnel-entreprise-2026\|comparateur-energie-pro" data/blogs/*.mdx
```

Pour chaque fichier listé : éditer pour retirer les entrées `relatedPosts` correspondantes.

- [ ] **Step 2 : Supprimer les 3 fichiers**

```bash
git rm data/blogs/comparatif-electricite-pro.mdx
git rm data/blogs/comparateur-electricite-professionnel-entreprise-2026.mdx
git rm data/blogs/comparateur-energie-pro.mdx
```

- [ ] **Step 3 : Rebuild content-collections**

```bash
pnpm build
```
Expected: 0 erreur, content-collections regenere sans les 3 entrées.

- [ ] **Step 4 : Commit**

```bash
git add -u data/blogs/
git commit -m "chore(blog): remove 3 articles cannibalisés (absorbés dans /outils/comparateur-electricite-pro/)"
```

**Done criteria :** 3 fichiers supprimés, build passe, plus aucune `relatedPosts` orpheline.
**Durée :** 15 min.

---

### Task 5.3 : Nav entry — `data/links/navigation.ts`

**Files:**
- Modify: `data/links/navigation.ts:117-124`

- [ ] **Step 1 : Ajouter entry**

```ts
export const directLinks: NavigationItem[] = [
  { label: "Ressources", href: "/ressources/" },
  {
    label: "Simulateur accise",
    href: "/outils/simulateur-exoneration-accise-electricite/",
  },
  {
    label: "Comparateur électricité pro",
    href: "/outils/comparateur-electricite-pro/",
  },
  { label: "Contact", href: "/contact/" },
];
```

- [ ] **Step 2 : Vérifier tsc**

```bash
pnpm tsc --noEmit
```

- [ ] **Step 3 : Test browser desktop + mobile**

Ouvrir `/` dans Playwright : viewport 1440 → vérifier que "Comparateur électricité pro" apparaît dans la nav. Viewport 375 → ouvrir burger, vérifier l'entry. Footer aussi.

- [ ] **Step 4 : Commit**

```bash
git add data/links/navigation.ts
git commit -m "feat(nav): ajout 'Comparateur électricité pro' (desktop + mobile + footer)"
```

**Done criteria :** lien visible en nav desktop, mobile burger, footer "Liens utiles".
**Durée :** 10 min.

---

### Task 5.4 : `<TeaserComparateurHome />` + insertion dans `app/page.tsx`

**Files:**
- Create: `components/teaser-comparateur-home.tsx`
- Modify: `app/page.tsx`
- Reference: `components/mini-simulateur-home.tsx`

- [ ] **Step 1 : Implémenter `components/teaser-comparateur-home.tsx`** (NO calcul, juste teaser visuel)

```tsx
"use client";

import Link from "next/link";
import { trackEvent } from "@/lib/analytics";

export function TeaserComparateurHome() {
  return (
    <section
      aria-labelledby="teaser-comparateur-heading"
      className="bg-orange-50/40 py-16 sm:py-20"
    >
      <div className="container mx-auto px-4">
        <div className="max-w-3xl mx-auto rounded-2xl bg-white shadow-lg p-8 sm:p-10 text-center">
          <h2 id="teaser-comparateur-heading" className="text-2xl sm:text-3xl font-bold mb-4">
            Comparez les fournisseurs d'électricité pro adaptés à votre profil
          </h2>
          <ul className="text-gray-600 mb-6 space-y-2 max-w-xl mx-auto text-left list-disc pl-6">
            <li>Profils C5, C4, C3 — recommandation contrat sur-mesure</li>
            <li>Ranking 5 fournisseurs scorés selon votre tolérance au risque</li>
          </ul>
          <Link
            href="/outils/comparateur-electricite-pro/"
            onClick={() =>
              trackEvent("teaser_comparateur_home_click", { location: "home_after_simulateur" })
            }
            className="inline-flex items-center justify-center bg-orange-600 hover:bg-orange-700 text-white font-semibold rounded-xl px-6 py-3 transition"
          >
            Comparer maintenant →
          </Link>
        </div>
      </div>
    </section>
  );
}
```

- [ ] **Step 2 : Insérer dans `app/page.tsx`** après `<MiniSimulateurHome />`

```tsx
import { TeaserComparateurHome } from "@/components/teaser-comparateur-home";

// ...
<MiniSimulateurHome />
<TeaserComparateurHome />
<Testimonials />
// ...
```

- [ ] **Step 3 : Build + browser test**

```bash
pnpm tsc --noEmit && pnpm build
```

Ouvrir `/` dans Playwright, scroller jusqu'au teaser, click "Comparer maintenant" → doit naviguer vers `/outils/comparateur-electricite-pro/`.

- [ ] **Step 4 : Commit**

```bash
git add components/teaser-comparateur-home.tsx app/page.tsx
git commit -m "feat(home): TeaserComparateurHome (lien CTA après MiniSimulateurHome)"
```

**Done criteria :** teaser rendu, click navigue, tracker fired.
**Durée :** 25 min.

---

### Task 5.5 : Vérifier `app/sitemap.ts`

**Files:**
- Read-only check: `app/sitemap.ts`

- [ ] **Step 1 : Inspecter** que `app/sitemap.ts` génère bien la nouvelle URL `/outils/comparateur-electricite-pro/` automatiquement (probablement via énumération des routes), et que les 3 anciens slugs supprimés n'y sont plus.

```bash
curl -s http://localhost:3000/sitemap.xml | grep -E "comparat|comparateur"
```
Expected: une seule URL `/outils/comparateur-electricite-pro/`. Pas de `/guides/comparatif-electricite-pro/` ni autres.

- [ ] **Step 2 : Si l'URL n'apparaît pas dans le sitemap** : ajouter manuellement dans `app/sitemap.ts` (chercher le pattern existant pour `/outils/simulateur-...` et dupliquer).

- [ ] **Step 3 : Si modification → commit**

```bash
git add app/sitemap.ts
git commit -m "fix(sitemap): inclure /outils/comparateur-electricite-pro/"
```

**Done criteria :** sitemap.xml contient l'URL nouvelle, pas les anciennes.
**Durée :** 10 min.

---

## Phase 6 — Vérification end-to-end

### Task 6.1 : `tsc --noEmit` + `build` clean

- [ ] **Step 1 :** `pnpm tsc --noEmit` → 0 erreur
- [ ] **Step 2 :** `pnpm build` → `Compiled successfully`

Si erreur → fix avant de continuer.

**Durée :** 5-10 min (sans erreur).

### Task 6.2 : Playwright manuel mobile + desktop

- [ ] **Mobile 375×667 :** flow 4 steps complet, pas de débordement horizontal de la card calculateur, contenu long-form lisible, boutons CTAs accessibles.
- [ ] **Desktop 1440×900 :** ranking 5 fournisseurs lisibles côte-à-côte ou en grille, table contrats H2 4 lisible (pas de scroll horizontal sur ce viewport), pie chart H2 5 visible.
- [ ] **Test deep link :** ouvrir `/outils/comparateur-electricite-pro/?profil=C4&mwh=800` → wizard saute à step 3 avec inputs préremplis.
- [ ] **Test wizard reset :** valider step 4, vérifier que les analytics events sont bien firés (vérifier dans OpenPanel realtime + GA4 DebugView).

**Durée :** 30 min.

### Task 6.3 : Tester redirects en local

```bash
for slug in comparatif-electricite-pro comparateur-electricite-professionnel-entreprise-2026 comparateur-energie-pro; do
  printf "/guides/%s/ → " "$slug"
  curl -sI "http://localhost:3000/guides/$slug/" | head -2 | tail -1
done
```
Expected: `308 Permanent Redirect` + `Location: /outils/comparateur-electricite-pro/`.

**Durée :** 5 min.

---

## Phase 7 — Ship (push, merge, deploy, ping)

### Task 7.1 : Push branche + merge `main`

- [ ] **Step 1 :** `git push origin feat/comparateur-electricite-pro`
- [ ] **Step 2 :** Switch main + merge

```bash
git checkout main && git pull && git merge --no-ff feat/comparateur-electricite-pro -m "Merge branch 'feat/comparateur-electricite-pro' into main"
```

- [ ] **Step 3 :** `git push origin main`

**Done criteria :** main pushed, branche feat à jour.
**Durée :** 5 min.

### Task 7.2 : Vercel deploy prod

```bash
pnpm prod
# = vercel build --prod && vercel deploy --prebuilt --prod
```

Attendre fin de deploy. Capturer l'URL prod (`https://www.aciebenergie.fr/outils/comparateur-electricite-pro/`).

**Done criteria :** deploy successful, URL prod accessible (200).
**Durée :** 5-10 min.

### Task 7.3 : Vérification post-deploy

```bash
curl -sI https://www.aciebenergie.fr/outils/comparateur-electricite-pro/ | head -3
# Expected: HTTP/2 200

for slug in comparatif-electricite-pro comparateur-electricite-professionnel-entreprise-2026 comparateur-energie-pro; do
  printf "/guides/%s/ → " "$slug"
  curl -sI "https://www.aciebenergie.fr/guides/$slug/" | head -2 | tail -1
done
# Expected: HTTP/2 308 Location: https://www.aciebenergie.fr/outils/comparateur-electricite-pro/
```

**Durée :** 2 min.

### Task 7.4 : Ping IndexNow + GSC submit (skill `ping-rss`)

- [ ] **Step 1 :** Invoquer skill `ping-rss` avec arguments :
  - URL nouvelle : `https://www.aciebenergie.fr/outils/comparateur-electricite-pro/`
  - URLs supprimées (pour informer du retrait, si supporté) : 3 anciennes URLs

- [ ] **Step 2 :** Si pas auto-pong, soumettre manuellement via GSC URL Inspection.

**Done criteria :** ping confirmé, GSC indexing requested.
**Durée :** 5 min.

---

## Phase 8 — Post-ship (Obsidian + SEO-insight)

### Task 8.1 : Note Obsidian via `obsidian-cli` ou `obsidian-markdown` skill

**Files:**
- Create: `~/Library/Mobile Documents/iCloud~md~obsidian/Documents/Clients/Acieb/Comparateur électricité pro - shipped 2026-04-29.md`

- [ ] **Step 1 :** Invoquer skill `obsidian-cli` ou `obsidian-markdown` avec le template du spec section 11. Renseigner :
  - URL prod confirmée
  - Hash commits clés
  - Captures (à prendre via Playwright `browser_take_screenshot` filename=`playwrite-png/comparateur-mobile.png` et `playwrite-png/comparateur-desktop.png`, à attacher dans la note via wikilinks `![[Pasted image ...]]`)
  - KPIs baseline j+0 (positions GSC actuelles, traffic guides à supprimer, etc.)

- [ ] **Step 2 :** Confirmer note créée, ouvre dans Obsidian.

**Durée :** 20 min.

### Task 8.2 : Update SEO-insight CLI (publish opportunity)

```bash
source ~/.claude/skills/seo-insight-blog/scripts/api-client.sh
SITE_ID=019dbeb8-7ef2-71e5-ab63-ad370a663dc9
URL=https://www.aciebenergie.fr/outils/comparateur-electricite-pro/

OPP_ID=$(OPP_LIMIT=300 si_opportunities "$SITE_ID" \
  | jaq -r '.[] | select((.topicName // "") | test("compar.*electric.*pro|comparat.*electricite"; "i")) | .id' \
  | head -1)

if [ -n "$OPP_ID" ]; then
  si_update_opportunity "$SITE_ID" "$OPP_ID" \
    "$(jaq -n --arg url "$URL" '{status:"published", publishedUrl:$url}')"
  echo "Opportunity $OPP_ID updated → published"
else
  echo "Aucune opportunité matchante (skip silencieux)"
fi
```

**Done criteria :** opportunity status=published OR skip si pas de match.
**Durée :** 5 min.

---

## Récapitulatif effort

| Phase | Durée |
|---|---|
| Phase 0 — Setup | 2 min |
| Phase 1 — Calculateur (10 tasks) | 3h-3h30 |
| Phase 2 — Page wrapper minimal | 25 min |
| Phase 3 — Contenu 4000 mots × 9 sections + 2 visualisations + Gemini gates | 6-8h |
| Phase 4 — Page finale + OG + Gemini final | 1h30 |
| Phase 5 — Intégration site (5 tasks) | 1h15 |
| Phase 6 — Vérification | 45 min |
| Phase 7 — Ship | 25 min |
| Phase 8 — Post-ship | 25 min |
| **Total** | **~14-15h** |

Compte tenu des gates Gemini (audits + itérations possibles), prévoir une journée + demi-journée. La phase 3 est le bottleneck.

---

## Self-Review

✅ **Spec coverage :** chaque section du spec mappée à au moins une task (calculateur → Phase 1 ; contenu Gemini-validé → Phase 3 ; redirects → Task 5.1 ; suppression MDX → Task 5.2 ; nav → Task 5.3 ; home teaser → Task 5.4 ; sitemap → Task 5.5 ; SEO/JsonLd → Task 4.1 ; analytics → embeddé dans steps 1-4 + teaser ; Obsidian note → Task 8.1 ; SEO-insight CLI → Task 8.2 ; verification → Phase 6).

✅ **Placeholder scan :** pas de "TBD". Le seul élément délibérément non-rédigé est le contenu textuel des 9 sections H2, parce que c'est précisément l'objet de la Phase 3 (workflow Gemini par section). Les prompts Gemini, le protocole et les critères de done sont explicites.

✅ **Type consistency :** les types `Profil`, `FournisseurId`, `ComparisonResult`, `WizardState`, `WizardAction` sont définis en Task 1.1 et utilisés cohéremment dans les Tasks 1.2-1.10. Pas de divergence de signature.

⚠️ **Risque connu :** la Phase 3 dépend du quota Gemini Pro (rate limits) et de la qualité du draft initial. Circuit breaker à 3 itérations + sleep 60s sur HTTP 429 documentés.

---

**Plan complet et sauvegardé à** `docs/superpowers/plans/2026-04-29-comparateur-electricite-pro-plan.md`.

**Deux options d'exécution :**

1. **Subagent-Driven (recommandé)** — fresh subagent par task, review entre chaque, itération rapide. Ideal pour la Phase 3 (longue, gates Gemini) où chaque H2 mérite un subagent dédié.

2. **Inline Execution** — exécution dans la session courante avec checkpoints batch. Plus rapide pour Phases 1-2-5-6-7, plus lourd à orchestrer pour Phase 3.

**Quelle approche tu retiens pour démarrer ?**
