// PARCOURS D'IDENTIFICATION DE TERRAIN
// On part de ce qu'un promeneur observe — couleur de la fleur, mois, hauteur —
// et on resserre vers une courte liste de fiches candidates. Chaque critère est
// sautable (« Peu importe ») et le nombre de candidates descend en direct.
//
// ── Extension : ajouter un critère « Emplacement du jardin » plus tard ──
// Les critères sont une simple liste de config (CRITERES). Pour en ajouter un :
//   1. exposer le champ dans api/list.js (light list),
//   2. pousser un objet { key, numero, question, kind, options(), matches() } ici.
// Rien d'autre à toucher (le tunnel, le compteur live et la grille s'adaptent).
// Aujourd'hui l'emplacement est différé : données encore creuses (47 fiches dans
// le même « Jardin Médicinal »), donc sans pouvoir discriminant.

(function () {
  // Minuscules + sans accents, pour comparer les libellés couleur sales en base.
  function norm(s) {
    return (s == null ? "" : String(s)).normalize("NFD").replace(/[̀-ͯ]/g, "").toLowerCase().trim();
  }

  // — Couleur — palette de base + table de normalisation des valeurs composites
  // réellement présentes en base (« blanc rosé » → blanc, « mauve » → violet…).
  const PALETTE = [
    { key: "jaune", label: "Jaune", sw: "#e0bd3a" },
    { key: "orange", label: "Orange", sw: "#dd8a3c" },
    { key: "rouge", label: "Rouge", sw: "#b5402f" },
    { key: "rose", label: "Rose", sw: "#d98aab" },
    { key: "violet", label: "Violet / mauve", sw: "#8a6bb0" },
    { key: "bleu", label: "Bleu", sw: "#5b7fb0" },
    { key: "vert", label: "Vert", sw: "#7a9750" },
    { key: "blanc", label: "Blanc", sw: "#f4f0e4" },
    { key: "brun", label: "Brun", sw: "#8a6a4a" },
  ];
  const COULEUR_BASE = {
    "mauve": "violet",
    "blanc rose": "blanc",
    "jaune-vert": "jaune",
    "vert-bleute": "vert",
    "jaune pale": "jaune",
    "vert argente": "vert",
  };
  // Ramène une couleur de fiche à une couleur de base (ou null si inclassable).
  function baseColor(raw) {
    const n = norm(raw);
    if (!n) return null;
    if (COULEUR_BASE[n]) return COULEUR_BASE[n];
    for (const c of PALETTE) if (n.includes(c.key)) return c.key; // filet pour futurs composites
    return null;
  }

  const MOIS = ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"];
  function enFleurAuMois(plant, mois) {
    const f = plant.floraison;
    if (Array.isArray(f)) return f.includes(mois);
    return typeof f === "string" && f.includes(mois);
  }

  // — Hauteur — tranches observables (cm). hMax vient d'api/list (parsé serveur).
  const TRANCHES = [
    { key: "basse", label: "Basse", hint: "moins de 30 cm", test: (cm) => cm < 30 },
    { key: "moyenne", label: "Moyenne", hint: "30 cm à 1 m", test: (cm) => cm >= 30 && cm <= 100 },
    { key: "haute", label: "Haute", hint: "1 à 3 m", test: (cm) => cm > 100 && cm <= 300 },
    { key: "arbre", label: "Arbre", hint: "plus de 3 m", test: (cm) => cm > 300 },
  ];

  // — Critères feuille (mode avancé) — silhouettes SVG cliquables.
  // Les données viennent de p.feuille (backfill scripts/seed-feuilles.mjs),
  // tableaux multi-valeurs : une plante peut être « rosette ET alterne ».
  // Petite feuille d'appoint pour les schémas de disposition sur la tige.
  const fol = (cx, cy, rot) => (
    <ellipse key={`${cx}-${cy}-${rot}`} cx={cx} cy={cy} rx="3.1" ry="1.7" transform={`rotate(${rot} ${cx} ${cy})`} />
  );

  const FORMES_FEUILLE = [
    { key: "lineaire", label: "Linéaire", svg: <g><path d="M12 2 C13.6 9 13.6 20 12 26 C10.4 20 10.4 9 12 2 Z" /><line x1="12" y1="26" x2="12" y2="30" fill="none" /></g> },
    { key: "lanceolee", label: "Lancéolée", svg: <g><path d="M12 2 C16.5 8 16.5 17 12 26 C7.5 17 7.5 8 12 2 Z" /><line x1="12" y1="26" x2="12" y2="30" fill="none" /></g> },
    { key: "ovale", label: "Ovale", svg: <g><path d="M12 3 C18 6 18.5 14 12 26 C5.5 14 6 6 12 3 Z" /><line x1="12" y1="26" x2="12" y2="30" fill="none" /></g> },
    { key: "elliptique", label: "Elliptique", svg: <g><ellipse cx="12" cy="14.5" rx="6.2" ry="11.8" /><line x1="12" y1="26.3" x2="12" y2="30" fill="none" /></g> },
    { key: "spatulee", label: "Spatulée", svg: <g><path d="M12 26 C10.8 21 7.5 16 7.5 9.5 C7.5 5.5 9.5 3 12 3 C14.5 3 16.5 5.5 16.5 9.5 C16.5 16 13.2 21 12 26 Z" /><line x1="12" y1="26" x2="12" y2="30" fill="none" /></g> },
    { key: "cordiforme", label: "Cordiforme", svg: <g><path d="M12 3 C17.5 6.5 19.5 12 18.5 16.5 C17.5 21 14.8 24 13.2 24 C12.6 24 12.2 23.2 12 22.4 C11.8 23.2 11.4 24 10.8 24 C9.2 24 6.5 21 5.5 16.5 C4.5 12 6.5 6.5 12 3 Z" /><line x1="12" y1="23.5" x2="12" y2="30" fill="none" /></g> },
    { key: "reniforme", label: "Réniforme", svg: <g><path d="M13 22 C18 21.5 21 17.5 21 13.5 C21 9 17.5 6.5 12 6.5 C6.5 6.5 3 9 3 13.5 C3 17.5 6 21.5 11 22 L12 20.5 L13 22 Z" /><line x1="12" y1="21" x2="12" y2="30" fill="none" /></g> },
    { key: "decoupee", label: "Découpée", svg: <g fill="none"><path d="M12 4 L12 30" /><path d="M12 8 C9 7 7 5.5 6 4 M12 8 C15 7 17 5.5 18 4 M12 13 C9 12 6.5 10.5 5 9.5 M12 13 C15 12 17.5 10.5 19 9.5 M12 18 C9.5 17.5 7 16 5.5 15 M12 18 C14.5 17.5 17 16 18.5 15 M12 23 C10 22.5 8 21.5 7 20.5 M12 23 C14 22.5 16 21.5 17 20.5" /></g> },
    { key: "composee", label: "Composée", svg: <g><line x1="12" y1="5" x2="12" y2="30" fill="none" />{fol(12, 4.5, -90)}{fol(7.8, 10, -35)}{fol(16.2, 10, 35)}{fol(7.8, 16, -35)}{fol(16.2, 16, 35)}{fol(7.8, 22, -35)}{fol(16.2, 22, 35)}</g> },
    { key: "ecaille-aiguille", label: "Aiguille", svg: <g fill="none"><path d="M12 30 L12 5 M12 30 L6.5 9 M12 30 L17.5 9 M12 30 L9 6.5 M12 30 L15 6.5" /></g> },
  ];

  const MARGES_FEUILLE = [
    { key: "entiere", label: "Entière", svg: <g><path d="M12 3 C18 6 18.5 14 12 26 C5.5 14 6 6 12 3 Z" /><line x1="12" y1="26" x2="12" y2="30" fill="none" /></g> },
    { key: "dentee", label: "Dentée", svg: <g><path d="M12 3 L15 5.5 L14 8 L17 10 L15.5 12.5 L17.5 15 L15.5 17 L16 20 L13.5 22 L12 26 L10.5 22 L8 20 L8.5 17 L6.5 15 L8.5 12.5 L7 10 L10 8 L9 5.5 Z" /><line x1="12" y1="26" x2="12" y2="30" fill="none" /></g> },
    { key: "crenelee", label: "Crénelée", svg: <g><path d="M12 3 Q16 4 16.5 7 Q18.5 8.5 17.5 11 Q19 13 17 15.5 Q18 18 15.5 19.5 Q16 22.5 13.5 23 Q13 25.5 12 26 Q11 25.5 10.5 23 Q8 22.5 8.5 19.5 Q6 18 7 15.5 Q5 13 6.5 11 Q5.5 8.5 7.5 7 Q8 4 12 3 Z" /><line x1="12" y1="26" x2="12" y2="30" fill="none" /></g> },
    { key: "lobee", label: "Lobée", svg: <g><path d="M12 3 C14 4 15 5.5 14 7 C17 7.5 18 10 16 11.5 C19 12.5 19 16 16.5 16.5 C18 18.5 16.5 21 14 20.5 C14.5 23 13 25 12 26 C11 25 9.5 23 10 20.5 C7.5 21 6 18.5 7.5 16.5 C5 16 5 12.5 8 11.5 C6 10 7 7.5 10 7 C9 5.5 10 4 12 3 Z" /><line x1="12" y1="26" x2="12" y2="30" fill="none" /></g> },
    { key: "epineuse", label: "Épineuse", svg: <g><path d="M12 3 L14.5 5.5 L17.5 4.5 L16.2 8 L19.5 9 L16.8 11.2 L19.5 13.5 L16.5 14.5 L18 18 L15 17.8 L15.5 21.5 L13 20.5 L12 26 L11 20.5 L8.5 21.5 L9 17.8 L6 18 L7.5 14.5 L4.5 13.5 L7.2 11.2 L4.5 9 L7.8 8 L6.5 4.5 L9.5 5.5 Z" /><line x1="12" y1="26" x2="12" y2="30" fill="none" /></g> },
  ];

  const NERVATIONS_FEUILLE = [
    { key: "pennee", label: "Pennée", svg: <g><path d="M12 3 C18 6 18.5 14 12 26 C5.5 14 6 6 12 3 Z" /><path d="M12 4.5 L12 24 M12 9 L8.2 12.5 M12 9 L15.8 12.5 M12 14 L8.6 17.5 M12 14 L15.4 17.5 M12 19 L9.5 21.8 M12 19 L14.5 21.8" fill="none" /></g> },
    { key: "palmee", label: "Palmée", svg: <g><path d="M12 3 C19 6 19.5 15 12 26 C4.5 15 5 6 12 3 Z" /><path d="M12 24 L12 4.5 M12 24 L6.8 9.5 M12 24 L17.2 9.5 M12 24 L8.2 16 M12 24 L15.8 16" fill="none" /></g> },
    { key: "parallele", label: "Parallèle", svg: <g><path d="M10 2 C14 9 15 19 12.5 30 C9 21 7.5 10 10 2 Z" /><path d="M10.8 4 C13 11 13.8 19 12.6 26 M9.7 5 C11.5 12 12.2 19 11.4 25" fill="none" /></g> },
  ];

  const DISPOSITIONS_FEUILLE = [
    { key: "alterne", label: "Alterne", svg: <g><line x1="12" y1="2" x2="12" y2="30" fill="none" />{fol(8.2, 8, -38)}{fol(15.8, 13, 38)}{fol(8.2, 18, -38)}{fol(15.8, 23, 38)}</g> },
    { key: "opposee", label: "Opposée", svg: <g><line x1="12" y1="2" x2="12" y2="30" fill="none" />{fol(8.2, 9, -38)}{fol(15.8, 9, 38)}{fol(8.2, 18, -38)}{fol(15.8, 18, 38)}</g> },
    { key: "verticillee", label: "Verticillée", svg: <g><line x1="12" y1="2" x2="12" y2="30" fill="none" />{fol(7.8, 10, 0)}{fol(16.2, 10, 0)}{fol(8.8, 7.4, -45)}{fol(15.2, 7.4, 45)}{fol(7.8, 21, 0)}{fol(16.2, 21, 0)}{fol(8.8, 18.4, -45)}{fol(15.2, 18.4, 45)}</g> },
    { key: "rosette", label: "Rosette", svg: <g>{fol(12, 21.5, -90)}{fol(7.5, 23.5, -45)}{fol(16.5, 23.5, 45)}{fol(5, 27, -12)}{fol(19, 27, 12)}</g> },
  ];

  const CRITERES_FEUILLE = [
    { key: "feuille-forme", numero: "04", question: "Quelle silhouette de feuille ?", kind: "svg", champ: "forme", defs: FORMES_FEUILLE },
    { key: "feuille-marge", numero: "05", question: "Quel bord de feuille ?", kind: "svg", champ: "marge", defs: MARGES_FEUILLE },
    { key: "feuille-nervation", numero: "06", question: "Quelles nervures ?", kind: "svg", champ: "nervation", defs: NERVATIONS_FEUILLE },
    { key: "feuille-disposition", numero: "07", question: "Comment les feuilles s'attachent-elles ?", kind: "svg", champ: "disposition", defs: DISPOSITIONS_FEUILLE },
  ].map((c) => ({
    ...c,
    options: (plants) => {
      const present = new Set();
      for (const p of plants) for (const v of (p.feuille && p.feuille[c.champ]) || []) present.add(v);
      return c.defs.filter((o) => present.has(o.key));
    },
    matches: (p, value) => !!(p.feuille && Array.isArray(p.feuille[c.champ]) && p.feuille[c.champ].includes(value)),
  }));

  // — Définition modulaire des critères du parcours —
  // options(plants) ne renvoie que les choix réellement présents dans le recueil
  // (pas de chip morte). matches(plant, value) = prédicat de filtrage.
  const CRITERES = [
    {
      key: "couleur",
      numero: "01",
      question: "De quelle couleur est la fleur ?",
      kind: "swatch",
      options: (plants) => {
        const present = new Set(plants.map((p) => baseColor(p.couleur)).filter(Boolean));
        return PALETTE.filter((c) => present.has(c.key));
      },
      matches: (p, value) => baseColor(p.couleur) === value,
    },
    {
      key: "mois",
      numero: "02",
      question: "À quel mois l'avez-vous observée ?",
      kind: "chip",
      options: (plants) => {
        const present = new Set();
        for (const p of plants) for (const m of MOIS) if (enFleurAuMois(p, m)) present.add(m);
        return MOIS.filter((m) => present.has(m)).map((m) => ({ key: m, label: m }));
      },
      matches: (p, value) => enFleurAuMois(p, value),
    },
    {
      key: "hauteur",
      numero: "03",
      question: "Quelle taille fait la plante ?",
      kind: "chip",
      options: (plants) => {
        const present = new Set();
        for (const p of plants) {
          if (typeof p.hMax !== "number") continue;
          for (const t of TRANCHES) if (t.test(p.hMax)) present.add(t.key);
        }
        return TRANCHES.filter((t) => present.has(t.key)).map((t) => ({ key: t.key, label: t.label, hint: t.hint }));
      },
      matches: (p, value) => {
        if (typeof p.hMax !== "number") return false;
        const t = TRANCHES.find((x) => x.key === value);
        return t ? t.test(p.hMax) : false;
      },
    },
    // ⇩ Futur : { key:"emplacement", numero:"04", question:"Dans quel carré du jardin ?", … }
  ];

  function ClassicParcours({ setRoute, setPlantId }) {
    const isMobile = useMobile();
    const plants = window.PLANTS || [];
    const [sel, setSel] = React.useState({}); // { couleur:"jaune", mois:"Juin", "feuille-forme":"ovale", … }
    // Mode avancé : critères botaniques de la feuille (replié par défaut).
    const [avance, setAvance] = React.useState(false);

    const goFiche = (id) => { setPlantId(id); setRoute("fiche"); };
    const choisir = (cle, valeur) => setSel((s) => ({ ...s, [cle]: s[cle] === valeur ? null : valeur }));
    const reset = () => setSel({});
    // Refermer le mode avancé efface ses sélections — sinon des filtres
    // invisibles resteraient actifs et les résultats seraient incompréhensibles.
    const toggleAvance = () => {
      setAvance((a) => {
        if (a) setSel((s) => {
          const c = { ...s };
          for (const cr of CRITERES_FEUILLE) c[cr.key] = null;
          return c;
        });
        return !a;
      });
    };

    // Filtrage cumulatif (dans l'ordre des critères) → compteur live par étape.
    // Les critères feuille sont toujours dans la chaîne : leurs sélections sont
    // nulles quand le mode avancé est fermé (remises à zéro au toggle).
    const TOUS = [...CRITERES, ...CRITERES_FEUILLE];
    const { filtered, stepCounts } = React.useMemo(() => {
      let running = plants;
      const counts = {};
      for (const c of TOUS) {
        if (sel[c.key] != null) running = running.filter((p) => c.matches(p, sel[c.key]));
        counts[c.key] = running.length;
      }
      const sorted = [...running].sort((a, b) => a.nom.localeCompare(b.nom, "fr"));
      return { filtered: sorted, stepCounts: counts };
    }, [sel, plants.length]);

    const nbActifs = TOUS.filter((c) => sel[c.key] != null).length;
    const pad = isMobile ? "0 20px" : "0 40px";

    return (
      <main className="page-enter">
        {/* En-tête */}
        <section style={{ padding: isMobile ? "44px 0 24px" : "80px 0 36px" }}>
          <div style={{ maxWidth: 1100, margin: "0 auto", padding: pad }}>
            <div className="kicker" style={{ marginBottom: 18 }}>Parcours · Identification de terrain</div>
            <h1 className="h-display" style={{ fontSize: isMobile ? "clamp(40px, 10vw, 64px)" : "clamp(60px, 8vw, 100px)", lineHeight: 0.97, margin: isMobile ? "0 0 16px" : "0 0 22px", letterSpacing: "-0.02em" }}>
              Quelle plante <span className="h-italic" style={{ color: "var(--moss-deep)" }}>avez-vous croisée</span> ?
            </h1>
            <p style={{ fontFamily: "var(--serif)", fontSize: isMobile ? 16 : 21, lineHeight: 1.5, color: "var(--ink-soft)", maxWidth: 640, margin: 0 }}>
              Renseignez ce que vous voyez — couleur, saison, taille. Chaque réponse resserre la liste. Sautez librement les critères que vous ignorez : c'est une aide à la reconnaissance, pas une clé stricte.
            </p>
          </div>
        </section>

        {/* Étapes */}
        <section style={{ maxWidth: 1100, margin: "0 auto", padding: pad }}>
          {(() => {
            const renderCritere = (c) => {
              const opts = c.options(plants);
              const actif = sel[c.key] != null;
              return (
                <div key={c.key} style={{ borderTop: "1px solid var(--line)", padding: isMobile ? "24px 0" : "34px 0" }}>
                  <div style={{ display: "flex", alignItems: "baseline", gap: 14, marginBottom: 18, flexWrap: "wrap" }}>
                    <span style={{ fontFamily: "var(--mono)", fontSize: 12, letterSpacing: ".18em", color: "var(--moss-deep)" }}>{c.numero}</span>
                    <span className="h-display" style={{ fontSize: isMobile ? 24 : 30, lineHeight: 1.05 }}>{c.question}</span>
                    <span style={{ fontFamily: "var(--serif)", fontStyle: "italic", fontSize: isMobile ? 14 : 16, color: "var(--ink-mute)", marginLeft: "auto" }}>
                      {stepCounts[c.key]} plante{stepCounts[c.key] > 1 ? "s" : ""}
                    </span>
                  </div>

                  <div style={{ display: "flex", gap: 10, alignItems: "stretch", flexWrap: isMobile ? "nowrap" : "wrap", overflowX: isMobile ? "auto" : "visible", paddingBottom: isMobile ? 4 : 0, scrollbarWidth: "none" }}>
                    {opts.map((o) =>
                      c.kind === "swatch" ? (
                        <SwatchBtn key={o.key} sw={o.sw} label={o.label} active={sel[c.key] === o.key} onClick={() => choisir(c.key, o.key)} />
                      ) : c.kind === "svg" ? (
                        <SvgBtn key={o.key} svg={o.svg} label={o.label} active={sel[c.key] === o.key} onClick={() => choisir(c.key, o.key)} />
                      ) : (
                        <ChipBtn key={o.key} label={o.label} hint={o.hint} active={sel[c.key] === o.key} onClick={() => choisir(c.key, o.key)} />
                      )
                    )}
                    <PeuImporte active={!actif} onClick={() => setSel((s) => ({ ...s, [c.key]: null }))} />
                  </div>
                </div>
              );
            };

            return (
              <>
                {CRITERES.map(renderCritere)}

                {/* Mode avancé — critères botaniques de la feuille */}
                <div style={{ borderTop: "1px solid var(--line)", padding: isMobile ? "20px 0" : "26px 0" }}>
                  <button
                    onClick={toggleAvance}
                    aria-expanded={avance}
                    style={{
                      display: "inline-flex", alignItems: "center", gap: 12,
                      background: "transparent", border: "1px dashed " + (avance ? "var(--moss-deep)" : "var(--line)"),
                      padding: "11px 22px", borderRadius: 100, cursor: "pointer",
                      fontFamily: "var(--mono)", fontSize: 11, letterSpacing: ".14em", textTransform: "uppercase",
                      color: avance ? "var(--moss-deep)" : "var(--ink-mute)", transition: "all 200ms var(--ease)",
                    }}
                  >
                    <span style={{ fontSize: 14, lineHeight: 1 }}>{avance ? "−" : "+"}</span>
                    Mode avancé · la feuille à la loupe
                  </button>
                  {avance && (
                    <p style={{ fontFamily: "var(--serif)", fontStyle: "italic", fontSize: isMobile ? 14 : 16, color: "var(--ink-mute)", margin: "14px 0 0", maxWidth: 560, lineHeight: 1.5 }}>
                      Observez une feuille de près — sa silhouette, son bord, ses nervures, son attache sur la tige. Cliquez le dessin qui ressemble le plus.
                    </p>
                  )}
                </div>

                {avance && CRITERES_FEUILLE.map(renderCritere)}
              </>
            );
          })()}
        </section>

        {/* Résultats */}
        <section style={{ maxWidth: 1400, margin: isMobile ? "10px auto 0" : "20px auto 0", padding: pad }}>
          <div style={{ borderTop: "1px solid var(--line)", paddingTop: isMobile ? 24 : 34, marginBottom: isMobile ? 22 : 32, display: "flex", justifyContent: "space-between", alignItems: "baseline", gap: 16, flexWrap: "wrap" }}>
            <h2 className="h-display" style={{ fontSize: isMobile ? 28 : 40, lineHeight: 1 }}>
              {filtered.length === 0 ? "Aucune correspondance" : <>{filtered.length} <span className="h-italic" style={{ color: "var(--moss-deep)" }}>candidate{filtered.length > 1 ? "s" : ""}</span></>}
            </h2>
            {nbActifs > 0 && (
              <button onClick={reset} style={{ fontFamily: "var(--mono)", fontSize: 11, letterSpacing: ".14em", textTransform: "uppercase", color: "var(--ink-mute)", background: "transparent", border: "1px solid var(--line)", borderRadius: 100, padding: "8px 18px", cursor: "pointer" }}>
                Réinitialiser
              </button>
            )}
          </div>

          {filtered.length === 0 ? (
            <p style={{ fontFamily: "var(--serif)", fontSize: isMobile ? 16 : 19, fontStyle: "italic", color: "var(--ink-soft)", maxWidth: 560, marginBottom: 80 }}>
              Aucune plante du recueil ne réunit ces critères. Élargissez-en un — repassez par exemple une étape en « Peu importe ».
            </p>
          ) : (
            <div style={{ display: "grid", gridTemplateColumns: isMobile ? "repeat(2, 1fr)" : "repeat(4, 1fr)", gap: isMobile ? 14 : 24, marginBottom: 60 }}>
              {filtered.map((p, i) => (
                <ResultCard key={p.id} plant={p} delay={Math.min(i, 8) * 50} onClick={() => goFiche(p.id)} />
              ))}
            </div>
          )}
        </section>
      </main>
    );
  }

  // — Boutons de choix — pilules arrondies, même grammaire que les .tag du site.
  function SwatchBtn({ sw, label, active, onClick }) {
    const [hover, setHover] = React.useState(false);
    return (
      <button
        onClick={onClick}
        onMouseEnter={() => setHover(true)}
        onMouseLeave={() => setHover(false)}
        style={{
          display: "flex", alignItems: "center", gap: 9, flexShrink: 0,
          padding: "6px 16px 6px 7px", borderRadius: 100,
          border: `1px solid ${active ? "var(--moss-deep)" : "var(--line)"}`,
          background: active ? "var(--moss-deep)" : (hover ? "var(--tint)" : "transparent"),
          cursor: "pointer", transition: "all 200ms var(--ease)",
        }}
      >
        <span style={{ width: 19, height: 19, borderRadius: "50%", background: sw, border: "1px solid rgba(0,0,0,0.18)", flexShrink: 0 }} />
        <span style={{ fontFamily: "var(--serif)", fontSize: 15.5, color: active ? "#f1ead9" : "var(--ink)" }}>{label}</span>
      </button>
    );
  }

  function ChipBtn({ label, hint, active, onClick }) {
    const [hover, setHover] = React.useState(false);
    return (
      <button
        onClick={onClick}
        onMouseEnter={() => setHover(true)}
        onMouseLeave={() => setHover(false)}
        style={{
          display: "flex", alignItems: "baseline", gap: 8, flexShrink: 0,
          padding: "8px 18px", borderRadius: 100,
          border: `1px solid ${active ? "var(--moss-deep)" : "var(--line)"}`,
          background: active ? "var(--moss-deep)" : (hover ? "var(--tint)" : "transparent"),
          cursor: "pointer", transition: "all 200ms var(--ease)",
        }}
      >
        <span style={{ fontFamily: "var(--serif)", fontSize: 15.5, color: active ? "#f1ead9" : "var(--ink)" }}>{label}</span>
        {hint && <span style={{ fontFamily: "var(--mono)", fontSize: 9, letterSpacing: ".04em", color: active ? "rgba(241,234,217,0.75)" : "var(--ink-mute)", whiteSpace: "nowrap" }}>{hint}</span>}
      </button>
    );
  }

  // Bouton silhouette (mode avancé) : dessin SVG au trait + libellé dessous.
  // Le trait suit currentColor → s'inverse proprement sur fond moss à l'état actif.
  function SvgBtn({ svg, label, active, onClick }) {
    const [hover, setHover] = React.useState(false);
    return (
      <button
        onClick={onClick}
        onMouseEnter={() => setHover(true)}
        onMouseLeave={() => setHover(false)}
        style={{
          display: "flex", flexDirection: "column", alignItems: "center", gap: 6, flexShrink: 0,
          padding: "10px 12px 8px", minWidth: 76, borderRadius: 14,
          border: `1px solid ${active ? "var(--moss-deep)" : "var(--line)"}`,
          background: active ? "var(--moss-deep)" : (hover ? "var(--tint)" : "transparent"),
          cursor: "pointer", transition: "all 200ms var(--ease)",
        }}
      >
        <svg
          width="28" height="36" viewBox="0 0 24 32"
          style={{ color: active ? "#f1ead9" : "var(--moss-deep)", display: "block" }}
          fill="currentColor" fillOpacity="0.14"
          stroke="currentColor" strokeWidth="1.2" strokeLinecap="round" strokeLinejoin="round"
        >
          {svg}
        </svg>
        <span style={{ fontFamily: "var(--serif)", fontSize: 13.5, color: active ? "#f1ead9" : "var(--ink)" }}>{label}</span>
      </button>
    );
  }

  function PeuImporte({ active, onClick }) {
    return (
      <button
        onClick={onClick}
        style={{
          flexShrink: 0, padding: "8px 18px", borderRadius: 100,
          border: `1px dashed ${active ? "var(--ink-soft)" : "var(--line)"}`,
          background: "transparent",
          fontFamily: "var(--mono)", fontSize: 10, letterSpacing: ".12em", textTransform: "uppercase",
          color: active ? "var(--ink-soft)" : "var(--ink-mute)", cursor: "pointer", transition: "all 200ms var(--ease)",
          alignSelf: "center",
        }}
      >
        Peu importe
      </button>
    );
  }

  // Carte résultat — vignette + nom + latin + famille (réutilise Plate, comme EnFleurCard).
  function ResultCard({ plant, onClick, delay }) {
    const [hover, setHover] = React.useState(false);
    const fromWiki = !!plant.thumbFromWikipedia;
    const attribution = fromWiki && plant.latin
      ? `https://fr.wikipedia.org/wiki/${encodeURIComponent(plant.latin.replace(/ /g, "_"))}`
      : null;
    return (
      <Reveal delay={delay}>
        <article
          onClick={onClick}
          onMouseEnter={() => setHover(true)}
          onMouseLeave={() => setHover(false)}
          style={{ cursor: "pointer", background: "var(--cream)", border: "1px solid var(--line-soft)", display: "flex", flexDirection: "column" }}
        >
          <div style={{ overflow: "hidden", borderBottom: "1px solid var(--line-soft)" }}>
            <Plate
              src={plant.thumb || null}
              frame={false}
              attribution={attribution}
              label={(plant.nom || "").toUpperCase()}
              aspect="4/5"
              style={{ transition: "transform 1000ms var(--ease)", transform: hover ? "scale(1.04)" : "scale(1)" }}
            />
          </div>
          <div style={{ padding: "14px 16px" }}>
            <div className="kicker" style={{ marginBottom: 6 }}>{plant.famille}</div>
            <h3 className="h-display" style={{ fontSize: 20, lineHeight: 1.05, margin: "0 0 3px" }}>{plant.nom}</h3>
            <div className="h-italic" style={{ fontSize: 14, color: "var(--moss-deep)" }}>{plant.latin}</div>
          </div>
        </article>
      </Reveal>
    );
  }

  // Wrapper : propose le choix entre le parcours classique (déroulé) et le
  // parcours immersif (Folio clair / Veillée nocturne, components/IdentifierImmersive.jsx).
  // Immersif par défaut ; pas de mémorisation (on repart sur le défaut à chaque ouverture).
  function Identifier({ setRoute, setPlantId, theme }) {
    const [mode, setMode] = React.useState("immersif");
    const immersifDispo = !!window.IdentifierImmersive;
    const showImmersif = mode === "immersif" && immersifDispo;
    return (
      <main className="page-enter">
        {immersifDispo && (
          <div className="cle-switch" role="group" aria-label="Type de parcours">
            <div className="cle-switch-pill">
              <button className={showImmersif ? "on" : ""} onClick={() => setMode("immersif")} title="Une question à la fois">
                Immersif
              </button>
              <button className={!showImmersif ? "on" : ""} onClick={() => setMode("classique")} title="Tous les critères sur une page">
                Classique
              </button>
            </div>
          </div>
        )}
        {showImmersif
          ? <window.IdentifierImmersive setRoute={setRoute} setPlantId={setPlantId} theme={theme} />
          : <ClassicParcours setRoute={setRoute} setPlantId={setPlantId} />}
      </main>
    );
  }

  window.Identifier = Identifier;
})();
