// ============================================================
// STAGE PRÉPA LANDING — Stage intensif maths CPGE, 20 → 28 août 2026
// 20 h : 8 séances de cours (16 h) + 4 h d'analyse complète d'un sujet de prépa
// Route : /stage (zéro nav, hors site public) · 240 €
// Réutilise les globals de bac_maths_landing.jsx : useReveal, loadStripe,
// BmHeroAurora (scope Babel partagé — ne pas redéclarer).
// ============================================================

const { useState: useS5, useEffect: useE5, useRef: useR5 } = React;

// ---------- Constantes (préfixées SP_ pour éviter les collisions globales) ----------
const SP_PRICE = 240;

// Bandeau "Les prépas de nos élèves" — logos (ou lettrage si pas de logo)
const SP_PREPAS = [
  { img: "/assets/prepas/ginette.png", alt: "Sainte-Geneviève (Ginette)" },
  { img: "/assets/prepas/henri4.png", alt: "Lycée Henri-IV" },
  { img: "/assets/prepas/saint-louis.png", alt: "Lycée Saint-Louis" },
  { img: "/assets/prepas/llg.png", alt: "Lycée Louis-le-Grand" },
  { img: "/assets/prepas/janson.svg", alt: "Janson-de-Sailly" },
  { img: "/assets/prepas/stanislas-mono.png", alt: "Collège Stanislas" },
  { img: "/assets/prepas/pasteur-wordmark.png", alt: "Lycée Pasteur (Neuilly)" },
];

// ---------- Programme : les 9 séances (contenu validé) ----------
const SP_SEANCES = [
  {
    n: "Séance 1", date: "20 août", dow: "jeudi", slots: ["18h – 20h"], glyph: "∀",
    title: "Logique formelle et quantificateurs",
    sub: "Ensembles, quantificateurs et logique propositionnelle",
    items: [
      ["new", "Ensembles de nombres ℕ ⊂ ℤ ⊂ 𝔻 ⊂ ℚ ⊂ ℝ : inclusions strictes, chacune justifiée par un témoin (−1, ½, ⅓, √2)"],
      ["new", <>Application, image, antécédent et l'ensemble <span className="sp-mathcal">ℱ(A, B)</span></>],
      ["new", "Les quantificateurs ∀, ∃, ∃! comme symboles : montrer, utiliser et réfuter une proposition « ∀x ∈ E, P(x) »"],
      ["new", "Permutation des quantificateurs : pourquoi ∀x ∃y et ∃y ∀x ne disent pas la même chose"],
      ["new", "Négation mécanique d'une proposition à quantificateurs imbriqués"],
      ["new", "Connecteurs et tables de vérité, distributivité, lois de De Morgan pour nier un « et » ou un « ou »"],
      ["rev", "Opérations et composition des fonctions ; parité et imparité démontrées sur le graphe, pas constatées"],
    ],
  },
  {
    n: "Séance 2", date: "21 août", dow: "vendredi", slots: ["18h – 20h"], glyph: "⟹",
    title: "Raisonnements et démonstration",
    sub: "Contraposée, absurde, analyse-synthèse",
    items: [
      ["new", "Implication, réciproque, contraposée : les distinguer sans jamais hésiter"],
      ["new", "Négation d'une implication ; conditions nécessaire, suffisante, nécessaire et suffisante"],
      ["new", "Les trois façons de prouver P ⟹ Q — directe, par contraposée, par l'absurde — et comment choisir"],
      ["new", "Principe de contraposition démontré ; équivalence P ⟺ Q par double implication"],
      ["new", "Analyse-synthèse : condition nécessaire puis suffisante, la méthode qui résout les équations fonctionnelles"],
      ["rev", "Raisonnement par l'absurde, repris et formalisé : l'irrationalité de √2"],
    ],
  },
  {
    n: "Séance 3", date: "23 août", dow: "dimanche", slots: ["18h – 20h"], glyph: "ℕ",
    title: "Récurrences avancées",
    sub: "Double, forte, finie, finie descendante",
    items: [
      ["new", "Principe de récurrence démontré à partir du minimum d'une partie non vide de ℕ"],
      ["new", "Récurrence double, puis récurrence à p niveaux : adapter l'hérédité au nombre de rangs utilisés"],
      ["new", "Récurrence forte : quand l'hypothèse au seul rang n ne suffit plus"],
      ["new", "Récurrence finie et récurrence finie descendante"],
      ["new", "Reconnaître, à la lecture de l'énoncé, laquelle est attendue"],
      ["rev", "Rédaction : les trois temps d'une récurrence, sans raccourci toléré"],
    ],
  },
  {
    n: "Séance 4", date: "24 août", dow: "lundi", slots: ["18h – 20h"], glyph: "(uₙ)",
    title: "Suites",
    sub: "Arithmético-géométriques et récurrences linéaires d'ordre 2",
    items: [
      ["new", "Suites récurrentes linéaires d'ordre 2 et équation caractéristique r² = ar + b"],
      ["new", "Racine double ou deux racines distinctes : les deux formes du terme général"],
      ["new", "Démonstration complète du théorème, par récurrence double"],
      ["new", "Suites arithmético-géométriques : résolution par le point fixe"],
      ["rev", "Suites arithmétiques et géométriques : terme général et somme de termes démontrés"],
      ["rev", "Monotonie : étude du signe de uₙ₊₁ − uₙ, suites constantes et stationnaires"],
    ],
  },
  {
    n: "Séance 5", date: "25 août", dow: "mardi", slots: ["18h – 20h"], glyph: "Σ",
    title: "Sommes et produits",
    sub: "Les symboles Σ et Π : le langage calculatoire de la prépa",
    items: [
      ["new", "Le symbole Σ défini par récurrence : indice muet, bornes, convention de somme vide"],
      ["new", "Linéarité de la somme, relation de Chasles, découpage et regroupement selon la parité"],
      ["new", "Changement d'indice : la technique qui revient dans toutes les copies de sup"],
      ["new", "Sommes de référence démontrées, jamais admises : Σ k = n(n+1)/2, Σ k², somme géométrique"],
      ["new", "Sommes télescopiques : faire s'effondrer une somme de mille termes en une ligne"],
      ["new", "Factorisation de aⁿ − bⁿ et applications arithmétiques : montrer que 6 divise 7ⁿ − 1"],
      ["new", "Le symbole Π, la factorielle n! et les produits télescopiques"],
      ["new", "Sommes doubles : interversion des symboles, sommes rectangulaires et triangulaires"],
      ["new", "Coefficients binomiaux, triangle de Pascal et formule du binôme de Newton"],
    ],
  },
  {
    n: "Séance 6", date: "26 août", dow: "mercredi", slots: ["18h – 20h"], glyph: "𝒞ⁿ",
    title: "Continuité, dérivation et régularité",
    sub: "Dérivées n-ièmes, classes 𝒞ⁿ et 𝒞∞",
    items: [
      ["new", "Continuité définie par la limite — et pourquoi « sans lever le crayon » ne suffit pas"],
      ["new", "Dérivabilité et nombre dérivé ; dérivable ⟹ continue, avec le contre-exemple qui invalide la réciproque"],
      ["new", "Dérivées successives, dérivée n-ième et fonctions de classe 𝒞ⁿ puis 𝒞∞"],
      ["new", "Signe de la dérivée et variations sur un intervalle : tableau rigoureux — domaine, dérivabilité, puis signe"],
      ["new", "Périodicité : démonstration de l'invariance de la courbe par translation"],
      ["rev", "Dérivée d'une composée et opérations sur les dérivées"],
    ],
  },
  {
    n: "Séance 7", date: "27 août", dow: "jeudi", slots: ["10h – 12h"], glyph: "f⁻¹",
    title: "Bijection et fonctions réciproques",
    sub: "Théorème de la bijection, dérivée de f⁻¹, puissances réelles",
    items: [
      ["new", "Théorème des valeurs intermédiaires, puis théorème de la bijection sur un intervalle"],
      ["new", "Bijection réciproque f⁻¹ : existence, unicité, propriétés (f⁻¹ ∘ f = id)"],
      ["new", "Dérivée de la réciproque : (f⁻¹)′ = 1 ⁄ (f′ ∘ f⁻¹)"],
      ["new", "Symétrie des graphes de f et f⁻¹ par rapport à la première bissectrice, démontrée"],
      ["new", "Racines n-ièmes comme bijections réciproques, et dérivée de x^(1/n)"],
      ["new", "Le logarithme redéfini comme primitive de 1/x s'annulant en 1"],
      ["new", "Puissances réelles x^α = exp(α ln x) : définition et dérivation"],
      ["rev", "Croissances comparées, démontrées et non admises"],
    ],
  },
  {
    n: "Séance 8", date: "27 août", dow: "jeudi", slots: ["18h – 20h"], glyph: "(S)",
    title: "Systèmes linéaires et pivot de Gauss",
    sub: "La méthode qui ouvre l'algèbre linéaire de prépa",
    items: [
      ["new", "Équation linéaire à p inconnues, système de n équations : le vocabulaire exact"],
      ["new", "Opérations élémentaires sur les lignes et invariance de l'ensemble des solutions, démontrée"],
      ["new", "L'algorithme du pivot de Gauss, mené jusqu'à la forme échelonnée"],
      ["new", "Systèmes à paramètre : discuter selon les valeurs de a ∈ ℝ"],
      ["new", "Interprétation géométrique : intersection de droites et de plans"],
      ["new", "Ensemble des solutions : vide, point, droite, plan — et comment le décrire"],
    ],
  },
  {
    n: "Séance 9", date: "28 août", dow: "vendredi", slots: ["10h – 12h", "18h – 20h"], glyph: "□", max: true,
    title: "Analyse complète d'un sujet de prépa",
    intro: "Analyser un sujet, ce n'est pas le résoudre : c'est reconnaître, derrière chaque question, l'outil qu'elle appelle. Quatre heures pour installer cet arsenal — celui qui sépare l'élève qui bloque de celui qui voit où l'énoncé veut l'emmener. Le sujet, inspiré des devoirs donnés dans les meilleures prépas parisiennes, reste secret jusqu'au jour J.",
    items: [
      ["new", "Lecture structurelle d'un énoncé : hiérarchie des questions, résultats admis, dépendances implicites"],
      ["new", "Construction d'une fonction auxiliaire : ramener une inégalité à l'étude du signe d'une dérivée"],
      ["new", "Convexité : caractérisation par f″ ⩾ 0, position de la courbe par rapport à ses cordes et à ses tangentes, inégalité de Jensen"],
      ["new", "Hiérarchie des inégalités classiques : Jensen, Cauchy-Schwarz, Hölder, Minkowski"],
      ["new", "Équations fonctionnelles : équation de Cauchy, morphismes, points fixes et involutions"],
      ["new", "Analyse-synthèse : condition nécessaire puis suffisante, description exhaustive de l'ensemble des solutions"],
      ["new", "Injectivité, surjectivité, bijectivité employées comme leviers de démonstration"],
      ["new", "Suites définies implicitement par le théorème de la bijection ; suites croisées et suites homographiques"],
      ["new", "Stabilité d'un intervalle, point fixe attractif et théorème de la limite monotone"],
      ["new", "Récurrence forte et minimum d'une partie non vide de ℕ comme outil de démonstration"],
      ["new", "Théorème d'encadrement, majorations fines et passage à la limite dans une inégalité large"],
      ["new", "Rédaction : quantification correcte, disjonction de cas exhaustive, gestion des hypothèses"],
    ],
  },
];

const SP_OUTCOMES = [
  "Nier proprement une proposition à trois quantificateurs imbriqués.",
  "Choisir entre preuve directe, contraposée, absurde et analyse-synthèse.",
  "Rédiger une récurrence forte ou double sans hésiter sur l'initialisation.",
  "Résoudre une suite récurrente linéaire d'ordre 2 par l'équation caractéristique.",
  "Justifier la classe 𝒞ⁿ d'une fonction avant d'en calculer la dérivée n-ième.",
  "Appliquer le théorème de la bijection et dériver une réciproque.",
  <>Montrer qu'une fonction continue vérifiant <span className="sp-nowrap">f(x + y) = f(x) + f(y)</span> est nécessairement linéaire.</>,
  "Résoudre un système linéaire à paramètre par l'algorithme du pivot de Gauss.",
  <>Manipuler les symboles Σ et Π : changement d'indice, découpage, sommes et produits télescopiques.</>,
  <>Factoriser aⁿ − bⁿ et l'utiliser pour prouver une divisibilité comme <span className="sp-nowrap">6 | 7ⁿ − 1</span>.</>,
  "Attaquer un sujet long de prépa sans être pris au dépourvu.",
];

const SP_FAQ = [
  {
    q: "Je suis en vacances une partie du stage, est-ce un problème ?",
    a: "Non. Chaque séance est enregistrée et disponible en replay le soir même : tu rattrapes n'importe quelle séance le lendemain, où que tu sois. Le rythme est pensé pour l'été — 2 h par soir à 18 h, le reste de la journée est à toi. Beaucoup d'élèves suivent une partie en direct et une partie en replay.",
  },
  {
    q: "Est-ce trop difficile pour moi ?",
    a: "Le stage part du niveau terminale et monte marche par marche. Chaque notion est définie avant d'être utilisée, chaque théorème est démontré au tableau. Ce qui est exigeant, c'est le niveau d'arrivée — pas le niveau d'entrée. Si tu as eu ta spé maths, tu as tout ce qu'il faut pour suivre.",
  },
  {
    q: "Je ne connais pas encore ma prépa définitive, puis-je m'inscrire ?",
    a: "Oui. Logique, récurrences, suites, fonctions, bijection : ce socle ouvre la première année dans toutes les filières — MPSI, PCSI, PTSI, MP2I, BCPST, ECG comme prépa intégrée. Peu importe où tu seras affecté, ces trois chapitres t'attendent en septembre.",
  },
  {
    q: "Comment se déroulent les séances ?",
    a: "En direct via Whereby (visio professionnelle, sans compte à créer). Tu reçois le lien par mail après ton inscription. Tableau partagé, chat actif, questions à tout moment : Edgar démontre, tu interviens.",
  },
  {
    q: "Et si je rate une séance en direct ?",
    a: "Tous les lives sont enregistrés et accessibles sur ta plateforme personnelle de replays, tout au long de l'année. Tu peux revoir une démonstration autant de fois que nécessaire — y compris en septembre, quand ton cours de prépa passera sur ces chapitres.",
  },
  {
    q: "Que reçois-je après le paiement ?",
    a: "Immédiatement par mail : le lien Whereby pour les lives et le polycopié du stage en PDF. L'accès à ta plateforme de replays est débloqué dès la première séance et t'est envoyé par mail. Le sujet travaillé le 28 août et son corrigé rédigé te sont remis pendant le stage.",
  },
];

const SP_INCLUDED = [
  { label: "20 h de cours en direct", sub: "16 h de cours + 4 h d'analyse complète d'un sujet de prépa (du 20 au 28 août)" },
  { label: "Replays illimités", sub: "Chaque séance disponible le soir même, accès conservé pendant toute ta rentrée de prépa" },
  { label: "Polycopié du stage", sub: "Cours, exercices et démonstrations exigibles. Disponible dès ton inscription." },
  { label: "Un sujet de prépa + corrigé rédigé", sub: "Inspiré des devoirs des meilleures prépas parisiennes" },
  { label: "Feuille de route personnelle", sub: "Bilan individuel remis à la fin du stage pour attaquer septembre" },
];

// ---------- Petits composants motion ----------

// Count-up animé au reveal (rAF, ease-out)
function SpCountUp({ to, revealed, duration = 800 }) {
  const [val, setVal] = useS5(0);
  const started = useR5(false);
  useE5(() => {
    if (!revealed || started.current) return;
    started.current = true;
    if (window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
      setVal(to);
      return;
    }
    let raf;
    const t0 = performance.now();
    const tick = (t) => {
      const p = Math.min(1, (t - t0) / duration);
      setVal(Math.round(to * (1 - Math.pow(1 - p, 3))));
      if (p < 1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [revealed]);
  return <>{val}</>;
}

// CTA réutilisable inséré entre les sections
function SpCtaBlock({ onCta, note }) {
  return (
    <div className="sp-cta-block">
      <button className="sp-btn sp-btn-hero" onClick={onCta}>Réserver ma place</button>
      {note && <div className="sp-reassure">{note}</div>}
    </div>
  );
}

// ---------- Header sticky + barre CTA mobile ----------
function SpStickyChrome({ heroRef, onCta }) {
  const [shown, setShown] = useS5(false);
  useE5(() => {
    const el = heroRef.current;
    if (!el) return;
    const io = new IntersectionObserver(
      ([e]) => setShown(!e.isIntersecting),
      { threshold: 0, rootMargin: "-60px 0px 0px 0px" }
    );
    io.observe(el);
    return () => io.disconnect();
  }, []);
  return (
    <>
      <header className={`sp-topbar ${shown ? "is-shown" : ""}`} aria-hidden={!shown}>
        <img src="/assets/logo-cours-edgar.png" alt="Cours Edgar" className="sp-topbar-logo" />
      </header>
    </>
  );
}

// ---------- HERO ----------
function SpHero({ onCta, heroRef }) {
  // Bandeau prépas piloté en JS : translation modulaire au pixel près.
  // La position avance en continu et se recale d'exactement une période (1/3 de
  // la piste, 3 copies identiques) — raccord invisible, indépendant du navigateur,
  // des arrondis CSS (%) et de la taille d'écran. L'animation CSS est coupée inline.
  const marqueeRef = useR5(null);
  useE5(() => {
    const track = marqueeRef.current;
    if (!track) return;
    if (window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
    let offset = 0, last = null, raf = 0;
    const SPEED = 120; // px/s
    const step = (t) => {
      // Période = distance réelle entre copie 1 et copie 2, mesurée sur les
      // positions des enfants (offsetLeft), à CHAQUE frame. Surtout PAS la
      // largeur de la piste : quand les images se chargent après la première
      // mise en page, Chrome et Safari iOS gardent une largeur de piste
      // périmée (offsetWidth < scrollWidth) — c'était la cause du « retour
      // au début au 3e logo ». Les positions des enfants, elles, sont justes.
      const kids = track.children;
      const period = kids.length >= 8 ? kids[7].offsetLeft - kids[0].offsetLeft : 0;
      if (last != null && period > 0) {
        offset = (offset + (SPEED * Math.min(t - last, 100)) / 1000) % period;
        track.style.transform = "translate3d(" + -offset.toFixed(2) + "px,0,0)";
      }
      last = t;
      raf = requestAnimationFrame(step);
    };
    raf = requestAnimationFrame(step);
    return () => cancelAnimationFrame(raf);
  }, []);
  return (
    <section ref={heroRef} className="sp-hero">
      <BmHeroAurora />
      <div className="sp-wrap sp-hero-wrap">
        <img src="/assets/logo-cours-edgar.png" alt="Cours Edgar" className="sp-hero-logo" />
        <div className="sp-hero-eyebrow sp-seq sp-seq-1">
          <span className="sp-hero-dot" />
          Stage intensif · 20 → 28 août 2026 · en ligne · places limitées · polycopié dès l'inscription
        </div>
        <h1 className="sp-hero-title sp-seq sp-seq-2">
          Vingt heures de maths pour anticiper ta{" "}
          <em className="sp-hero-accent">rentrée en CPGE.</em>
        </h1>
        <p className="sp-hero-sub sp-seq sp-seq-3">
          Ce n'est pas une remise à niveau. C'est une masterclass pour prendre de l'avance.
          Vois le cours de prépa avant même ta rentrée, maîtrise les exercices classiques et améliore ta rédaction.
        </p>
        <div className="sp-hero-ctas sp-seq sp-seq-4">
          <div style={{ display: "flex", flexWrap: "wrap", gap: "12px", justifyContent: "center", alignItems: "center" }}>
            <button className="sp-btn sp-btn-hero" onClick={onCta}>
              Réserver ma place
            </button>
            <a
              className="sp-btn sp-btn-hero"
              href="https://discord.gg/Eb7csYKej"
              target="_blank"
              rel="noopener noreferrer"
              style={{ background: "#5865F2", color: "#fff", display: "inline-flex", alignItems: "center", gap: "9px", textDecoration: "none" }}
            >
              <svg viewBox="0 0 24 24" width="19" height="19" fill="currentColor" aria-hidden="true" style={{ flex: "none" }}>
                <path d="M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189z" />
              </svg>
              Rejoindre le Discord
            </a>
          </div>
          <div className="sp-reassure">
            Replays inclus · polycopié complet (cours et exercices de prépa corrigés) dès l'inscription
          </div>
        </div>
      </div>
      <div className="sp-hero-stats sp-seq sp-seq-5" aria-label="Le stage en chiffres">
        <div className="sp-hero-stat"><strong>20 h</strong><span>de cours en direct</span></div>
        <div className="sp-hero-stat"><strong>9</strong><span>séances du 20 au 28 août</span></div>
        <div className="sp-hero-stat"><strong>4</strong><span>semaines d'avance sur le programme</span></div>
        <div className="sp-hero-stat"><strong>∞</strong><span>replays toute ta rentrée</span></div>
      </div>
      <div className="sp-marquee">
        <div className="sp-marquee-label">Les prépas de nos élèves</div>
        <div className="sp-marquee-viewport" aria-hidden="true">
          <div className="sp-marquee-track" ref={marqueeRef} style={{ animation: "none", gap: "clamp(60px, 11vw, 320px)", paddingRight: "clamp(60px, 11vw, 320px)" }}>
            {[...SP_PREPAS, ...SP_PREPAS, ...SP_PREPAS].map((p, i) => (
              <span key={i} className="sp-marquee-logo">
                {p.img
                  ? <img src={p.img} alt={p.alt} style={{ height: "58px" }} />
                  : <em style={{ fontSize: "36px" }}>{p.text}</em>}
              </span>
            ))}
          </div>
        </div>
      </div>
    </section>
  );
}

// ---------- STRUCTURE 12/4/4 ----------
function SpStructure() {
  const [ref, revealed] = useReveal();
  const cards = [
    {
      h: 16, title: "Cours",
      body: "Huit séances qui suivent les premiers chapitres d'une première année de CPGE, dans leur ordre et à leur niveau d'exigence — de la logique formelle aux symboles Σ et Π. Aucun résultat n'est admis : chaque énoncé est posé avec ses hypothèses, puis démontré au tableau.",
    },
    {
      h: 4, red: true, title: "Analyse d'un sujet de prépa",
      body: "Un seul sujet pendant quatre heures, ouvert de la première à la dernière question. Construction de fonctions auxiliaires, récurrence forte, inégalité des accroissements finis, équations fonctionnelles, analyse-synthèse, suites adjacentes… L'arsenal qu'un problème de première année exige réellement.",
    },
  ];
  return (
    <section ref={ref} className={`sp-section sp-structure ${revealed ? "is-reveal" : ""}`}>
      <div className="sp-wrap">
        <div className="sp-eyebrow">La structure</div>
        <h2 className="sp-h2">Avance-toi sur le programme et développe ton intuition mathématique.</h2>
        <div className="sp-structure-grid">
          {cards.map((c, i) => (
            <article key={i} className="sp-structure-card" style={{ transitionDelay: `${i * 110}ms` }}>
              <div className={`sp-structure-num ${c.red ? "is-red" : ""}`}>
                <SpCountUp to={c.h} revealed={revealed} /> h
              </div>
              <h3>{c.title}</h3>
              <p>{c.body}</p>
            </article>
          ))}
        </div>
      </div>
    </section>
  );
}

// ---------- PROGRAMME (timeline + accordéons) ----------
function SpProgram({ onCta }) {
  const [ref, revealed] = useReveal(0.05);
  const [openIdx, setOpenIdx] = useS5(0);
  const [inSet, setInSet] = useS5(() => new Set());
  const [ctaLit, setCtaLit] = useS5(false);
  const daysRef = useR5(null);
  const lineRef = useR5(null);

  // Révélation séance par séance : chaque carte + son point s'illuminent
  // quand ils entrent dans le viewport (une seule fois). L'état passe par
  // React (Set d'indices) : une classe posée à la main serait effacée au
  // re-render déclenché par l'ouverture/fermeture d'un accordéon.
  useE5(() => {
    const root = daysRef.current;
    if (!root) return;
    const days = Array.from(root.querySelectorAll(".sp-day"));
    const all = () => new Set(days.map((_, i) => i));
    const reduced = window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    if (reduced) { setInSet(all()); return; }
    const io = new IntersectionObserver((entries) => {
      for (const e of entries) {
        if (e.isIntersecting) {
          const idx = Number(e.target.dataset.i);
          setInSet((prev) => { const n = new Set(prev); n.add(idx); return n; });
          io.unobserve(e.target);
        }
      }
    }, { threshold: 0.15, rootMargin: "0px 0px -10% 0px" });
    days.forEach((d) => io.observe(d));
    return () => io.disconnect();
  }, []);

  // Trait vertical lié au scroll : progresse continûment avec la lecture.
  useE5(() => {
    const root = daysRef.current;
    const line = lineRef.current;
    if (!root || !line) return;
    const reduced = window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    if (reduced) { line.style.transform = "scaleY(1)"; setCtaLit(true); return; }
    let raf = 0;
    const update = () => {
      raf = 0;
      const r = root.getBoundingClientRect();
      const readLine = window.innerHeight * 0.72; // point de lecture ~2/3 de l'écran
      const p = Math.min(1, Math.max(0, (readLine - r.top) / r.height));
      line.style.transform = `scaleY(${p})`;
      setCtaLit(p > 0.96); // la ligne a rejoint le bouton → il s'allume et pulse
    };
    const onScroll = () => { if (!raf) raf = requestAnimationFrame(update); };
    update();
    window.addEventListener("scroll", onScroll, { passive: true });
    window.addEventListener("resize", onScroll);
    return () => {
      window.removeEventListener("scroll", onScroll);
      window.removeEventListener("resize", onScroll);
      if (raf) cancelAnimationFrame(raf);
    };
  }, []);

  return (
    <section ref={ref} className={`sp-section sp-program ${revealed ? "is-reveal" : ""}`}>
      <div className="sp-wrap">
        <div className="sp-eyebrow">Le programme, séance par séance</div>
        <h2 className="sp-h2">Prends de l'avance sur le vrai programme de prépa.</h2>
        <div className="sp-legend">
          <span><i className="sp-key sp-key-new" /> Notion nouvelle en prépa</span>
          <span><i className="sp-key sp-key-rev" /> Notion de terminale reprise en profondeur</span>
        </div>
        <div className="sp-days" ref={daysRef}>
          <div className="sp-days-line" ref={lineRef} aria-hidden="true" />
          {SP_SEANCES.map((s, i) => {
            const open = openIdx === i;
            return (
              <article key={i} data-i={i} className={`sp-day ${s.max ? "sp-day-max" : ""} ${open ? "is-open" : ""} ${inSet.has(i) ? "is-in" : ""}`}>
                <div className="sp-day-marker" aria-hidden="true" />
                <button
                  className="sp-day-head"
                  onClick={() => setOpenIdx(open ? -1 : i)}
                  aria-expanded={open}
                >
                  <div className="sp-day-when">
                    <span className="sp-day-n">{s.n}</span>
                    <span className="sp-day-date">{s.date} · {s.dow}</span>
                    <span className="sp-day-slots">
                      {s.slots.map((sl, j) => <em key={j}>{sl}</em>)}
                      {s.max && <b className="sp-tag-max">4 heures</b>}
                    </span>
                  </div>
                  <div className="sp-day-titlerow">
                    <div>
                      <h3 className="sp-day-title">{s.title}</h3>
                      {s.sub && <div className="sp-day-sub">{s.sub}</div>}
                    </div>
                    <span className="sp-day-glyph" aria-hidden="true">{s.glyph}</span>
                  </div>
                  <span className={`sp-day-chevron ${open ? "is-open" : ""}`} aria-hidden="true">+</span>
                </button>
                <div className={`sp-day-body ${open ? "is-open" : ""}`}>
                  <div className="sp-day-body-inner">
                    {s.intro && <p className="sp-day-intro">{s.intro}</p>}
                    <ul className="sp-day-list">
                      {s.items.map(([kind, txt], j) => (
                        <li key={j} className={kind === "rev" ? "rev" : ""} style={{ transitionDelay: open ? `${j * 55}ms` : "0ms" }}>
                          {txt}
                        </li>
                      ))}
                    </ul>
                  </div>
                </div>
              </article>
            );
          })}
          <div className={`sp-program-cta ${ctaLit ? "is-lit" : ""}`}>
            <div className="sp-day-marker sp-cta-marker" aria-hidden="true" />
            <button className="sp-btn" onClick={onCta}>Réserver ma place</button>
            <div className="sp-reassure">20 h de cours · replays inclus · polycopié fourni</div>
          </div>
        </div>
      </div>
    </section>
  );
}

// ---------- TÉMOIGNAGES ----------
// Extraits d'avis réels (Trustpilot & Google, stage intensif de juin 2026),
// recadrés pour la longueur — voix authentiques conservées.
const SP_TESTIMONIALS = [
  {
    quote: "Un cours complet, accompagné de bonnes explications. Le stage permet d'instaurer un rythme de travail efficace qui prépare au mieux aux examens.",
    name: "Hamza", meta: "Stage intensif · juin 2026", source: "Trustpilot",
  },
  {
    quote: "Des outils qu'on sent extrêmement réfléchis en amont, des explications très précises qui aident énormément. Le professionnalisme d'Edgar m'a fait progresser énormément.",
    name: "Thomas", meta: "Stage intensif · juin 2026", source: "Trustpilot",
  },
  {
    quote: "Je n'aurais jamais pensé autant progresser. Le stage m'a vraiment aidé à comprendre les notions, combler mes lacunes et m'organiser.",
    name: "Adam", meta: "Stage intensif · juin 2026", source: "Google",
  },
  {
    quote: "Des méthodes, des conseils et des explications qui permettent de gagner en confiance. On sent qu'il y a un vrai travail pédagogique derrière.",
    name: "Milo", meta: "Stage intensif · juin 2026", source: "Trustpilot",
  },
  {
    quote: "Les exercices sont ciblés efficacement et le cours est clair et digeste. Un excellent investissement.",
    name: "Théo", meta: "Stage intensif · juin 2026", source: "Google",
  },
  {
    quote: "Il explique les notions de manière claire et simple. Les exercices et les corrections m'ont aidée à progresser et à prendre confiance.",
    name: "Naveera", meta: "Stage intensif · juin 2026", source: "Trustpilot",
  },
];

function SpStars() {
  return (
    <span className="sp-stars" aria-label="5 étoiles sur 5">
      {"★★★★★".split("").map((s, i) => <i key={i}>{s}</i>)}
    </span>
  );
}

function SpTestimonials({ onCta }) {
  const [ref, revealed] = useReveal();
  return (
    <section ref={ref} className={`sp-section sp-testimonials ${revealed ? "is-reveal" : ""}`}>
      <div className="sp-wrap">
        <div className="sp-eyebrow">Ils l'ont vécu</div>
        <h2 className="sp-h2">Les élèves du dernier stage en parlent mieux que nous.</h2>
        <div className="sp-rating-head">
          <SpStars />
          <span>Noté <strong>5/5</strong> par nos élèves</span>
        </div>
        <div className="sp-testimonials-grid">
          {SP_TESTIMONIALS.map((t, i) => (
            <figure key={i} className="sp-testimonial" style={{ transitionDelay: `${i * 90}ms` }}>
              <SpStars />
              <blockquote>« {t.quote} »</blockquote>
              <figcaption>
                <strong>{t.name}</strong>
                <span>{t.meta}</span>
              </figcaption>
            </figure>
          ))}
        </div>
        <SpCtaBlock onCta={onCta} note="Rejoins la promotion d'août 2026" />
      </div>
    </section>
  );
}

// ---------- LE PROF (bloc repris de /rentree, texte adapté au stage) ----------
function SpFounder() {
  const [imgOk, setImgOk] = useS5(true);
  const [ref, revealed] = useReveal();
  return (
    <section ref={ref} className={`sp-section sp-founder ${revealed ? "is-reveal" : ""}`}>
      <div className="wrap rentree-founder-wrap">
        <div className="rentree-founder-card">
          <div className="rentree-founder-photo">
            {imgOk ? (
              <img
                src="/assets/edgar.jpg"
                alt="Edgar Abari, ton prof pendant le stage"
                onError={() => setImgOk(false)}
              />
            ) : (
              <span className="rentree-founder-initials" aria-hidden="true">EA</span>
            )}
          </div>
          <div className="rentree-founder-text">
            <span className="sp-eyebrow">Ton professeur</span>
            <h3 className="rentree-founder-name">Edgar Abari</h3>
            <div className="rentree-founder-path">
              <em>Louis-le-Grand</em>
              <span aria-hidden="true">·</span>
              <em>I.O.G.S.</em>
              <span aria-hidden="true">·</span>
              <em>HEC Paris</em>
              <span aria-hidden="true">·</span>
              <em>Polytechnique</em>
              <span aria-hidden="true">·</span>
              <em>U.C. Berkeley</em>
            </div>
            <p className="rentree-founder-bio">
              « Depuis 7 ans, j'accompagne des élèves qui ont intégré Ginette, Pasteur ou
              Stanislas. À force de préparer leurs khôlles et leurs DS, je sais exactement ce qui
              sépare ceux qui subissent leur sup de ceux qui la dominent. Ce stage, c'est ma façon
              de rendre ces clés accessibles — celles que je donne aux élèves des meilleures
              prépas parisiennes, réservées d'habitude au cours particulier. »
            </p>
          </div>
        </div>
      </div>
    </section>
  );
}

// ---------- ACQUIS ----------
function SpOutcomes({ onCta }) {
  const [ref, revealed] = useReveal();
  return (
    <section ref={ref} className={`sp-section sp-outcomes ${revealed ? "is-reveal" : ""}`}>
      <div className="sp-wrap">
        <div className="sp-eyebrow">Ton avance</div>
        <h2 className="sp-h2">Ce que tu sauras faire avant même ton premier cours de maths en sup.</h2>
        <div className="sp-outcomes-grid">
          {SP_OUTCOMES.map((o, i) => (
            <div key={i} className="sp-outcome" style={{ transitionDelay: `${i * 60}ms` }}>
              <span className="sp-outcome-mark">→</span>
              <p>{o}</p>
            </div>
          ))}
        </div>
        <SpCtaBlock onCta={onCta} note="20 h de cours · replays et polycopié inclus" />
      </div>
    </section>
  );
}

// ---------- FILIÈRES ----------
function SpFilieres() {
  const [ref, revealed] = useReveal();
  return (
    <section ref={ref} className={`sp-section sp-filieres ${revealed ? "is-reveal" : ""}`}>
      <div className="sp-wrap">
        <div className="sp-eyebrow">Pour qui</div>
        <h2 className="sp-h2">Le socle est le même dans toutes les filières.</h2>
        <p className="sp-body">
          Logique formelle, récurrences, suites récurrentes, étude de fonctions et théorème de la
          bijection ouvrent la première année partout — en classe préparatoire scientifique comme en
          économique et commerciale.
        </p>
        <div className="sp-pills">
          <span className="sp-pill sp-pill-lead">MPSI</span>
          <span className="sp-pill sp-pill-lead">PCSI</span>
          <span className="sp-pill sp-pill-lead">PTSI</span>
          <span className="sp-pill">MP2I</span>
          <span className="sp-pill">BCPST</span>
          <span className="sp-pill">ECG · maths approfondies</span>
          <span className="sp-pill">ECG · maths appliquées</span>
          <span className="sp-pill">Prépa intégrée</span>
        </div>
      </div>
    </section>
  );
}

// ---------- OFFRE + PRIX ----------
function SpOffer({ onCta }) {
  const [ref, revealed] = useReveal();
  return (
    <section ref={ref} id="inscription" className={`sp-section sp-offer ${revealed ? "is-reveal" : ""}`}>
      <div className="sp-wrap">
        <div className="sp-eyebrow">Réserve ta place</div>
        <h2 className="sp-h2">Tout le stage, tout inclus.</h2>
        <div className="sp-offer-card">
          <div className="sp-offer-list">
            {SP_INCLUDED.map((it, i) => (
              <div key={i} className="sp-offer-row" style={{ transitionDelay: `${i * 80}ms` }}>
                <span className="sp-offer-check">✓</span>
                <div>
                  <div className="sp-offer-label">{it.label}</div>
                  <div className="sp-offer-sub">{it.sub}</div>
                </div>
              </div>
            ))}
            <div className="sp-offer-cta">
              <button className="sp-btn sp-btn-hero" onClick={onCta}>
                Confirmer mon inscription
              </button>
            </div>
          </div>
          <div className="sp-offer-price">
            <div className="sp-offer-price-num">{SP_PRICE} €</div>
            <div className="sp-offer-badge">20 h de cours intensifs</div>
          </div>
        </div>
      </div>
    </section>
  );
}

// ---------- FAQ ----------
function SpFaq() {
  const [ref, revealed] = useReveal();
  const [openIdx, setOpenIdx] = useS5(-1);
  return (
    <section ref={ref} className={`sp-section sp-faq ${revealed ? "is-reveal" : ""}`}>
      <div className="sp-wrap">
        <div className="sp-eyebrow">FAQ</div>
        <h2 className="sp-h2">Tes questions, mes réponses.</h2>
        <div className="sp-faq-list">
          {SP_FAQ.map((item, i) => {
            const open = openIdx === i;
            return (
              <div key={i} className={`sp-faq-item ${open ? "is-open" : ""}`}>
                <button className="sp-faq-q" onClick={() => setOpenIdx(open ? -1 : i)} aria-expanded={open}>
                  <span>{item.q}</span>
                  <span className={`sp-day-chevron ${open ? "is-open" : ""}`} aria-hidden="true">+</span>
                </button>
                <div className={`sp-faq-a ${open ? "is-open" : ""}`}>
                  <div className="sp-faq-a-inner">{item.a}</div>
                </div>
              </div>
            );
          })}
        </div>
      </div>
    </section>
  );
}

// ---------- FOOTER ----------
function SpFooter() {
  return (
    <footer className="sp-footer">
      <div className="sp-wrap">
        <div>© 2026 Cours Edgar · contact@cours-edgar.fr</div>
        <div>Stage Prépa Maths · 20 → 28 août 2026 · toutes filières CPGE</div>
      </div>
    </footer>
  );
}

// ---------- MODALE STRIPE EMBEDDED CHECKOUT ----------
function SpCheckoutModal({ onClose }) {
  const checkoutRef = useR5(null);
  const sessionIdRef = useR5(null);
  const [error, setError] = useS5("");
  const [paymentDone, setPaymentDone] = useS5(false);

  useE5(() => {
    let aborted = false;
    (async () => {
      try {
        const stripe = await loadStripe();
        const res = await fetch("/api/stage/checkout-session", { method: "POST" });
        if (!res.ok) throw new Error("Erreur serveur (HTTP " + res.status + ")");
        const data = await res.json();
        if (!data.clientSecret) throw new Error("Session indisponible. Réessaye dans un instant.");
        if (aborted) return;
        sessionIdRef.current = data.sessionId || null;
        const checkout = await stripe.initEmbeddedCheckout({
          clientSecret: data.clientSecret,
          onComplete: () => {
            setPaymentDone(true);
            setTimeout(() => {
              const sid = sessionIdRef.current;
              window.location.href = "/stage/merci" + (sid ? "?session_id=" + encodeURIComponent(sid) : "");
            }, 1800);
          },
        });
        if (aborted) { try { checkout.destroy(); } catch (_) {} return; }
        checkoutRef.current = checkout;
        checkout.mount("#sp-checkout-mount");
      } catch (e) {
        if (!aborted) setError(e.message || "Impossible de charger le paiement.");
      }
    })();
    document.body.style.overflow = "hidden";
    return () => {
      aborted = true;
      document.body.style.overflow = "";
      if (checkoutRef.current) {
        try { checkoutRef.current.destroy(); } catch (_) {}
      }
    };
  }, []);

  return (
    <div className="bm-checkout-overlay">
      <div className="bm-checkout-container" onClick={(e) => e.stopPropagation()}>
        {!paymentDone && (
          <button className="bm-checkout-close" onClick={onClose} aria-label="Fermer">×</button>
        )}
        {error ? (
          <div className="bm-checkout-error">
            <strong>Oups, le paiement n'a pas pu se charger.</strong>
            <p>{error}</p>
            <p>Tu peux réessayer ou nous écrire à <a href="mailto:contact@cours-edgar.fr">contact@cours-edgar.fr</a>.</p>
          </div>
        ) : (
          <div id="sp-checkout-mount" />
        )}
        {paymentDone && (
          <div className="bm-checkout-success" role="status" aria-live="polite">
            <div className="bm-checkout-success-emoji">✅</div>
            <div className="bm-checkout-success-title">Paiement confirmé !</div>
            <p className="bm-checkout-success-body">
              Tu vas recevoir dans la minute par mail : le lien Whereby des lives, l'accès aux
              replays et le polycopié du stage.
            </p>
            <p className="bm-checkout-success-redirect">Redirection en cours…</p>
          </div>
        )}
      </div>
    </div>
  );
}

// ============================================================
// LANDING ROOT
// ============================================================
function StagePrepaLanding() {
  const [checkoutOpen, setCheckoutOpen] = useS5(false);
  const heroRef = useR5(null);

  useE5(() => {
    document.title = "Stage Prépa Maths · 20 → 28 août 2026 — Cours Edgar";
    // Capture UTM
    try {
      const p = new URLSearchParams(window.location.search);
      ["utm_source", "utm_medium", "utm_campaign"].forEach((k) => {
        const v = p.get(k);
        if (v) sessionStorage.setItem("ce_" + k, v);
      });
    } catch (_) {}
    // noindex (page de paiement)
    try {
      const m = document.createElement("meta");
      m.name = "robots";
      m.content = "noindex, nofollow";
      document.head.appendChild(m);
    } catch (_) {}
  }, []);

  const openCheckout = () => setCheckoutOpen(true);
  const closeCheckout = () => setCheckoutOpen(false);
  // Tous les CTA de la page mènent au bloc offre ; seul son bouton ouvre le paiement.
  const scrollToOffer = () => {
    const el = document.getElementById("inscription");
    if (el) el.scrollIntoView({ behavior: "smooth", block: "start" });
  };

  return (
    <div className="sp-page">
      <SpStickyChrome heroRef={heroRef} onCta={scrollToOffer} />
      <SpHero onCta={scrollToOffer} heroRef={heroRef} />
      <SpStructure />
      <SpProgram onCta={scrollToOffer} />
      <SpTestimonials onCta={scrollToOffer} />
      <SpOutcomes onCta={scrollToOffer} />
      <SpFounder />
      <SpFilieres />
      <SpOffer onCta={openCheckout} />
      <SpFaq />
      <SpFooter />
      {checkoutOpen && <SpCheckoutModal onClose={closeCheckout} />}
    </div>
  );
}

// ============================================================
// THANK YOU (/stage/merci)
// ============================================================
function StagePrepaThankYou() {
  useE5(() => {
    document.title = "Inscription confirmée — Stage Prépa Maths · Cours Edgar";
    try {
      const m = document.createElement("meta");
      m.name = "robots";
      m.content = "noindex, nofollow";
      document.head.appendChild(m);
    } catch (_) {}
  }, []);

  return (
    <div className="sp-page sp-thankyou">
      <section className="sp-hero">
        <BmHeroAurora />
        <div className="sp-wrap sp-hero-wrap" style={{ textAlign: "center" }}>
          <div className="sp-hero-eyebrow sp-seq sp-seq-1" style={{ justifyContent: "center" }}>
            <span className="sp-hero-dot" />
            Paiement confirmé
          </div>
          <h1 className="sp-hero-title sp-seq sp-seq-2">
            Bienvenue au Stage <em className="sp-hero-accent">Prépa Maths</em> par{" "}
            <img src="/assets/logo-cours-edgar.png" alt="Cours Edgar" className="sp-title-logo" />
          </h1>
          <p className="sp-hero-sub sp-seq sp-seq-3">
            Ton inscription est confirmée. Voici la suite :
          </p>
          <ul className="sp-thankyou-list sp-seq sp-seq-4">
            <li><strong>1.</strong> Vérifie ta boîte mail (et tes spams) : l'e-mail de confirmation arrive dans les minutes qui viennent, avec le lien Whereby des lives et <strong>le lien de téléchargement du polycopié complet du stage</strong>.</li>
            <li><strong>2.</strong> Bloque tes soirées du 20 au 28 août, 18 h – 20 h — et les matinées des 27 et 28 août, 10 h – 12 h.</li>
            <li><strong>3.</strong> L'accès aux replays sera débloqué dès le premier cours et te sera envoyé sur ta boîte mail.</li>
            <li><strong>4.</strong> Rendez-vous le <strong>jeudi 20 août à 18 h</strong> pour la première séance : logique formelle et quantificateurs.</li>
          </ul>
          <div className="sp-seq sp-seq-5" style={{ margin: "24px 0 4px" }}>
            <a
              className="sp-btn sp-btn-hero"
              href="https://discord.gg/Eb7csYKej"
              target="_blank"
              rel="noopener noreferrer"
              style={{ background: "#5865F2", color: "#fff", display: "inline-flex", alignItems: "center", gap: "9px", textDecoration: "none" }}
            >
              <svg viewBox="0 0 24 24" width="19" height="19" fill="currentColor" aria-hidden="true" style={{ flex: "none" }}>
                <path d="M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189z" />
              </svg>
              Rejoindre le Discord
            </a>
          </div>
          <p className="sp-reassure sp-seq sp-seq-5">
            Une question ? Écris-nous à contact@cours-edgar.fr — on répond vite.
          </p>
        </div>
      </section>
    </div>
  );
}
