// ============================================================
// Monarch — L'Encyclopédie patrimoniale du dirigeant (composant)
// Définit window.EncyclopediePage. Requiert React + window.MONARCH_ENCYCLO.
// ============================================================
(function () {
  const { useState, useEffect, useRef } = React;

  const C = {
    vert: "#1E3A2B", ivoire: "#F7F3E9", encre: "#222222", or: "#C8A45C",
    fond: "#FDFCF9", gris: "#6B6B66", grisC: "#9A9A92", trait: "#E6E1D4", blanc: "#FFFFFF"
  };
  const SERIF = "'Fraunces', Georgia, serif";
  const BODY = "'Archivo', system-ui, sans-serif";
  const CAL_URL = "https://cal.eu/hugo-groslambert/diagnostic1h";

  const TYPES = {
    notion: { label: "Notion", color: C.vert, bg: "#E8EEEA" },
    dispositif: { label: "Dispositif", color: "#9A7B22", bg: "#F4ECD7" },
    montage: { label: "Montage", color: "#3D5468", bg: "#E7EDF2" },
    cas: { label: "Cas pratique", color: "#5C6F5C", bg: "#E9EEE9" },
    glossaire: { label: "Glossaire", color: "#6B6B66", bg: "#ECEAE3" }
  };

  function injectStyles() {
    if (document.getElementById("encyclo-styles")) return;
    const s = document.createElement("style");
    s.id = "encyclo-styles";
    s.textContent = `
      .enc-body h2 { font-family:${SERIF}; font-size:clamp(22px,2.6vw,28px); font-weight:500; color:${C.vert}; letter-spacing:-0.01em; margin:40px 0 14px; }
      .enc-body h3 { font-family:${SERIF}; font-size:20px; font-weight:500; color:${C.vert}; margin:28px 0 10px; }
      .enc-body p { font-family:${BODY}; font-size:17px; line-height:1.7; color:${C.encre}; margin:0 0 18px; }
      .enc-body ul { font-family:${BODY}; font-size:17px; line-height:1.7; color:${C.encre}; padding-left:22px; margin:0 0 18px; }
      .enc-body li { margin-bottom:8px; }
      .enc-body strong { color:${C.encre}; font-weight:700; }
      .enc-body a[data-entry] { color:${C.vert}; text-decoration:none; border-bottom:1px solid ${C.or}; cursor:pointer; padding-bottom:1px; }
      .enc-body a[data-entry]:hover { background:${C.ivoire}; }
      .enc-body span[data-def] { border-bottom:1px dotted ${C.or}; cursor:help; position:relative; }
      .enc-body span[data-def]:hover::after { content:attr(data-def); position:absolute; left:0; top:calc(100% + 8px); width:260px; background:${C.vert}; color:#fff; font-family:${BODY}; font-size:12.5px; font-weight:400; line-height:1.5; letter-spacing:0; text-transform:none; padding:10px 12px; border-radius:3px; z-index:40; box-shadow:0 12px 30px -12px rgba(0,0,0,.4); }
      .enc-toc a.on { color:${C.vert} !important; font-weight:600 !important; }
      .enc-toc a.on { color:${C.vert} !important; font-weight:600 !important; }
      .enc-mobilebar { display:none; }
      @media (max-width:1040px){ .enc-toc { display:none !important; } }
      @media (max-width:900px){
        .enc-sidebar { display:none !important; }
        .enc-grid { grid-template-columns:1fr !important; }
        .enc-entry-grid { grid-template-columns:1fr !important; gap:0 !important; }
        .enc-shell { grid-template-columns:1fr !important; gap:0 !important; }
        .enc-mobilebar { display:block !important; }
      }
    `;
    document.head.appendChild(s);
  }

  function slugifyH(s) {
    return (s || "").toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 60);
  }

  function Badge({ type }) {
    const t = TYPES[type] || TYPES.notion;
    return <span style={{ fontFamily: BODY, fontSize: 11, fontWeight: 700, letterSpacing: "0.08em", textTransform: "uppercase", color: t.color, background: t.bg, padding: "4px 10px", borderRadius: 2 }}>{t.label}</span>;
  }

  // ---------- Sidebar ----------
  function Sidebar({ data, current, onOpen, query, setQuery }) {
    const q = query.trim().toLowerCase();
    const TYPE_ORDER = ["notion", "dispositif", "montage", "cas", "glossaire"];
    // modules dans l'ordre déclaré, + tout module utilisé non listé
    const modNames = (data.modules || []).map((m) => m.name);
    (data.entries || []).forEach((e) => { if (e.module && !modNames.includes(e.module)) modNames.push(e.module); });
    return (
      <aside className="enc-sidebar" style={{ position: "sticky", top: 96, alignSelf: "start", maxHeight: "calc(100vh - 120px)", overflowY: "auto", paddingRight: 8 }}>
        <div style={{ position: "relative", marginBottom: 22 }}>
          <span style={{ position: "absolute", left: 12, top: "50%", transform: "translateY(-50%)", color: C.grisC, fontSize: 14 }}>⌕</span>
          <input value={query} onChange={(e) => setQuery(e.target.value)} placeholder="Rechercher…"
            style={{ width: "100%", fontFamily: BODY, fontSize: 14, color: C.encre, background: "#fff", border: `1px solid ${C.trait}`, borderRadius: 2, padding: "10px 12px 10px 32px", outline: "none" }} />
        </div>
        {modNames.map((modName) => {
          const inMod = (data.entries || []).filter((e) => e.module === modName && (!q || (e.title + " " + e.definition).toLowerCase().includes(q)));
          if (!inMod.length) return null;
          const groups = TYPE_ORDER.map((tp) => ({ tp, list: inMod.filter((e) => e.type === tp) })).filter((g) => g.list.length);
          return (
            <div key={modName} style={{ marginBottom: 26 }}>
              <div style={{ fontFamily: BODY, fontSize: 11, letterSpacing: "0.16em", textTransform: "uppercase", color: C.or, fontWeight: 700, marginBottom: 12 }}>{modName}</div>
              {groups.map((g) =>
                <div key={g.tp} style={{ marginBottom: 14 }}>
                  <div style={{ fontFamily: BODY, fontSize: 12, color: C.grisC, fontWeight: 600, marginBottom: 6 }}>{(TYPES[g.tp] || {}).label || g.tp}</div>
                  <ul style={{ listStyle: "none", margin: 0, padding: 0, borderLeft: `1px solid ${C.trait}` }}>
                    {g.list.map((e) => {
                      const on = current === e.slug;
                      return (
                        <li key={e.slug}>
                          <button onClick={() => onOpen(e.slug)}
                            style={{ display: "block", width: "100%", textAlign: "left", fontFamily: BODY, fontSize: 13.5, lineHeight: 1.4, padding: "6px 0 6px 14px", marginLeft: "-1px", borderLeft: `2px solid ${on ? C.vert : "transparent"}`, color: on ? C.vert : C.encre, fontWeight: on ? 600 : 500, background: "none", border: "none", borderLeftWidth: 2, borderLeftStyle: "solid", cursor: "pointer" }}>
                            {e.title}
                          </button>
                        </li>);
                    })}
                  </ul>
                </div>
              )}
            </div>);
        })}
      </aside>);
  }

  // ---------- Overview (index) ----------
  function Overview({ data, onOpen, query }) {
    const q = (query || "").trim().toLowerCase();
    const azList = data.entries.slice().sort((a, b) => a.title.localeCompare(b.title, "fr"));

    // Mode recherche : liste plate filtrée
    if (q) {
      const hits = data.entries.filter((e) => (e.title + " " + e.definition + " " + (e.body || "").replace(/<[^>]+>/g, " ")).toLowerCase().includes(q));
      return (
        <div>
          <span style={{ fontFamily: BODY, fontSize: 11.5, letterSpacing: "0.2em", textTransform: "uppercase", color: C.or, fontWeight: 700 }}>Recherche</span>
          <h1 style={{ fontFamily: SERIF, fontSize: "clamp(26px,3.4vw,38px)", fontWeight: 500, lineHeight: 1.1, letterSpacing: "-0.015em", color: C.vert, margin: "12px 0 6px" }}>{hits.length} résultat{hits.length > 1 ? "s" : ""}</h1>
          <p style={{ fontFamily: BODY, fontSize: 14.5, color: C.gris, margin: "0 0 24px" }}>pour «&nbsp;{query.trim()}&nbsp;»</p>
          {hits.length === 0 ?
            <p style={{ fontFamily: BODY, fontSize: 16, color: C.grisC, fontStyle: "italic" }}>Aucune entrée ne correspond. Essayez un autre terme.</p> :
            <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
              {hits.map((e) =>
                <button key={e.slug} onClick={() => onOpen(e.slug)}
                  style={{ textAlign: "left", background: "#fff", border: `1px solid ${C.trait}`, borderRadius: 2, padding: "18px 20px", cursor: "pointer" }}
                  onMouseEnter={(ev) => ev.currentTarget.style.borderColor = C.or}
                  onMouseLeave={(ev) => ev.currentTarget.style.borderColor = C.trait}>
                  <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 8, flexWrap: "wrap" }}>
                    <Badge type={e.type} />
                    <span style={{ fontFamily: BODY, fontSize: 12, color: C.grisC }}>{e.module}</span>
                  </div>
                  <div style={{ fontFamily: SERIF, fontSize: 19, fontWeight: 500, color: C.vert, marginBottom: 4 }}>{e.title}</div>
                  <div style={{ fontFamily: BODY, fontSize: 14, color: C.gris, lineHeight: 1.55 }}>{e.definition}</div>
                </button>)}
            </div>}
        </div>);
    }

    return (
      <div>
        <span style={{ fontFamily: BODY, fontSize: 11.5, letterSpacing: "0.2em", textTransform: "uppercase", color: C.or, fontWeight: 700 }}>L'Encyclopédie patrimoniale</span>
        <h1 style={{ fontFamily: SERIF, fontSize: "clamp(34px,4.6vw,58px)", fontWeight: 500, lineHeight: 1.06, letterSpacing: "-0.018em", color: C.vert, margin: "14px 0 0", maxWidth: "13em" }}>L'Encyclopédie patrimoniale du dirigeant</h1>
        <p style={{ fontFamily: SERIF, fontSize: "clamp(17px,2vw,21px)", fontStyle: "italic", color: C.gris, margin: "16px 0 0" }}>Le dirigeant, souverain sur son patrimoine.</p>
        <p style={{ fontFamily: BODY, fontSize: 18, lineHeight: 1.65, color: C.encre, margin: "24px 0 0", maxWidth: "40em" }}>
          Un corpus de référence interconnecté et pédagogique sur les holdings, la structuration de groupe, la fiscalité et la transmission du patrimoine des dirigeants. Chaque entrée va à l'essentiel — en euros et en conséquences concrètes.
        </p>

        {data.modules.map((mod) => {
          const entries = data.entries.filter((e) => e.module === mod.name);
          return (
            <section key={mod.name} style={{ marginTop: 50, borderTop: `2px solid ${C.vert}`, paddingTop: 24 }}>
              <h2 style={{ fontFamily: SERIF, fontSize: "clamp(24px,3vw,32px)", fontWeight: 500, color: C.vert, letterSpacing: "-0.01em", margin: 0 }}>{mod.name}</h2>
              <p style={{ fontFamily: BODY, fontSize: 15.5, color: C.gris, lineHeight: 1.6, margin: "8px 0 22px", maxWidth: "42em" }}>{mod.intro}</p>
              <div className="enc-grid" style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16 }}>
                {entries.map((e) =>
                  <button key={e.slug} onClick={() => onOpen(e.slug)}
                    style={{ textAlign: "left", background: "#fff", border: `1px solid ${C.trait}`, borderRadius: 2, padding: "20px 22px", cursor: "pointer", transition: "border-color .2s, box-shadow .2s" }}
                    onMouseEnter={(ev) => { ev.currentTarget.style.borderColor = C.or; ev.currentTarget.style.boxShadow = "0 10px 30px -18px rgba(0,0,0,.3)"; }}
                    onMouseLeave={(ev) => { ev.currentTarget.style.borderColor = C.trait; ev.currentTarget.style.boxShadow = "none"; }}>
                    <Badge type={e.type} />
                    <div style={{ fontFamily: SERIF, fontSize: 20, fontWeight: 500, color: C.vert, margin: "12px 0 6px", letterSpacing: "-0.01em" }}>{e.title}</div>
                    <div style={{ fontFamily: BODY, fontSize: 14, color: C.gris, lineHeight: 1.55 }}>{e.definition}</div>
                  </button>
                )}
              </div>
            </section>);
        })}

        {/* Index A–Z */}
        <section style={{ marginTop: 50, borderTop: `1px solid ${C.trait}`, paddingTop: 24 }}>
          <div style={{ fontFamily: BODY, fontSize: 11.5, letterSpacing: "0.2em", textTransform: "uppercase", color: C.or, fontWeight: 700, marginBottom: 14 }}>Index A–Z</div>
          <div style={{ display: "flex", flexWrap: "wrap", gap: "8px 22px" }}>
            {azList.map((e) =>
              <button key={e.slug} onClick={() => onOpen(e.slug)} style={{ fontFamily: BODY, fontSize: 14.5, color: C.encre, background: "none", border: "none", cursor: "pointer", padding: 0, borderBottom: `1px solid ${C.or}` }}>{e.title}</button>
            )}
          </div>
        </section>

        <p style={{ fontFamily: BODY, fontSize: 12.5, color: C.grisC, marginTop: 44, fontStyle: "italic" }}>Information générale à vocation pédagogique — ne constitue pas une consultation juridique.</p>
        {data.publishedAt &&
          <p style={{ fontFamily: BODY, fontSize: 12.5, color: C.grisC, marginTop: 6 }}>Encyclopédie mise à jour le {new Date(data.publishedAt).toLocaleDateString("fr-FR", { day: "numeric", month: "long", year: "numeric" })}.</p>}
      </div>);
  }

  // ---------- Entry ----------
  function Entry({ data, entry, onOpen, goHome }) {
    const bodyRef = useRef(null);
    const [toc, setToc] = useState([]);
    const [activeId, setActiveId] = useState("");

    useEffect(() => {
      const root = bodyRef.current;
      if (!root) return;
      // liens internes
      root.querySelectorAll("a[data-entry]").forEach((a) => {
        a.onclick = (ev) => { ev.preventDefault(); onOpen(a.getAttribute("data-entry")); };
      });
      // sommaire
      const hs = Array.from(root.querySelectorAll("h2"));
      const items = hs.map((h, i) => { const id = h.id || slugifyH(h.textContent) || "s" + i; h.id = id; h.style.scrollMarginTop = "100px"; return { id, text: h.textContent }; });
      setToc(items);
      const obs = new IntersectionObserver((es) => es.forEach((e) => { if (e.isIntersecting) setActiveId(e.target.id); }), { rootMargin: "-90px 0px -65% 0px" });
      hs.forEach((h) => obs.observe(h));
      return () => obs.disconnect();
    }, [entry.slug]);

    // JSON-LD
    useEffect(() => {
      const isTerm = entry.type === "notion" || entry.type === "glossaire";
      const graph = [{
        "@type": isTerm ? "DefinedTerm" : "Article",
        "name": entry.title, "headline": entry.title, "description": entry.definition,
        "inDefinedTermSet": isTerm ? "L'Encyclopédie patrimoniale du dirigeant — Monarch" : undefined,
        "author": { "@type": "Person", "name": "Hugo Groslambert" },
        "publisher": { "@type": "LegalService", "name": "Monarch", "areaServed": "Toulouse" }
      }];
      const old = document.getElementById("enc-jsonld"); if (old) old.remove();
      const el = document.createElement("script"); el.type = "application/ld+json"; el.id = "enc-jsonld";
      el.textContent = JSON.stringify({ "@context": "https://schema.org", "@graph": graph });
      document.head.appendChild(el);
      return () => { el.remove(); };
    }, [entry.slug]);

    const related = (entry.voirAussi || []).map((s) => data.entries.find((e) => e.slug === s)).filter(Boolean);
    const crumb = { color: C.gris };

    return (
      <div>
        {/* fil d'Ariane */}
        <div style={{ fontFamily: BODY, fontSize: 13, color: C.gris, marginBottom: 20, display: "flex", gap: 8, flexWrap: "wrap", alignItems: "center" }}>
          <button onClick={goHome} style={{ ...crumb, background: "none", border: "none", cursor: "pointer", padding: 0, fontFamily: BODY, fontSize: 13 }}>Encyclopédie</button>
          <span style={{ color: C.grisC }}>/</span>
          <span style={{ color: C.gris }}>{entry.module}</span>
          <span style={{ color: C.grisC }}>/</span>
          <span style={{ color: C.encre, fontWeight: 600 }}>{entry.title}</span>
        </div>

        <div className="enc-entry-grid" style={{ display: "grid", gridTemplateColumns: "minmax(0,1fr) 220px", gap: 50, alignItems: "start" }}>
          <article style={{ maxWidth: 720 }}>
            <div style={{ display: "flex", gap: 12, alignItems: "center", marginBottom: 16 }}>
              <Badge type={entry.type} />
              <span style={{ fontFamily: BODY, fontSize: 12, letterSpacing: "0.08em", textTransform: "uppercase", color: C.gris, fontWeight: 600 }}>Niveau&nbsp;: {entry.niveau}</span>
            </div>
            <h1 style={{ fontFamily: SERIF, fontSize: "clamp(32px,4.4vw,52px)", fontWeight: 500, lineHeight: 1.08, letterSpacing: "-0.018em", color: C.vert, margin: "0 0 22px" }}>{entry.title}</h1>

            {/* Définition canonique — liseré or */}
            <div style={{ background: C.ivoire, borderLeft: `3px solid ${C.or}`, padding: "20px 24px", marginBottom: 26 }}>
              <div style={{ fontFamily: BODY, fontSize: 11, letterSpacing: "0.18em", textTransform: "uppercase", color: C.or, fontWeight: 700, marginBottom: 8 }}>Définition</div>
              <p style={{ fontFamily: SERIF, fontSize: "clamp(18px,2.1vw,22px)", lineHeight: 1.5, color: C.vert, margin: 0, fontWeight: 500 }}>{entry.definition}</p>
            </div>

            {/* En bref */}
            {entry.enBref && entry.enBref.length > 0 &&
              <div style={{ marginBottom: 30 }}>
                <div style={{ fontFamily: BODY, fontSize: 11.5, letterSpacing: "0.18em", textTransform: "uppercase", color: C.vert, fontWeight: 700, marginBottom: 12 }}>En bref</div>
                <ul style={{ listStyle: "none", margin: 0, padding: 0, display: "flex", flexDirection: "column", gap: 10 }}>
                  {entry.enBref.map((b, i) =>
                    <li key={i} style={{ display: "flex", gap: 12, alignItems: "flex-start", fontFamily: BODY, fontSize: 16, lineHeight: 1.6, color: C.encre }}>
                      <span style={{ color: C.or, fontWeight: 700, marginTop: 1 }}>—</span><span>{b}</span>
                    </li>)}
                </ul>
              </div>}

            {/* Corps */}
            <div ref={bodyRef} className="enc-body" dangerouslySetInnerHTML={{ __html: entry.body || "" }} />

            {/* À ne pas confondre */}
            {entry.confusion &&
              <div style={{ marginTop: 36, border: `1px solid ${C.trait}`, background: "#fff", padding: "20px 24px" }}>
                <div style={{ fontFamily: BODY, fontSize: 11.5, letterSpacing: "0.16em", textTransform: "uppercase", color: "#9A7B22", fontWeight: 700, marginBottom: 10 }}>À ne pas confondre</div>
                <p className="enc-body" style={{ margin: 0, fontSize: 15.5 }} dangerouslySetInnerHTML={{ __html: entry.confusion }} />
              </div>}

            {/* Voir aussi */}
            {related.length > 0 &&
              <div style={{ marginTop: 40 }}>
                <div style={{ fontFamily: BODY, fontSize: 11.5, letterSpacing: "0.18em", textTransform: "uppercase", color: C.vert, fontWeight: 700, marginBottom: 14 }}>Voir aussi</div>
                <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }} className="enc-grid">
                  {related.map((e) =>
                    <button key={e.slug} onClick={() => onOpen(e.slug)}
                      style={{ textAlign: "left", background: "#fff", border: `1px solid ${C.trait}`, borderRadius: 2, padding: "14px 16px", cursor: "pointer" }}
                      onMouseEnter={(ev) => ev.currentTarget.style.borderColor = C.or}
                      onMouseLeave={(ev) => ev.currentTarget.style.borderColor = C.trait}>
                      <Badge type={e.type} />
                      <div style={{ fontFamily: SERIF, fontSize: 16.5, fontWeight: 500, color: C.vert, marginTop: 8 }}>{e.title}</div>
                    </button>)}
                </div>
              </div>}

            {/* Fondements */}
            {entry.fondements && entry.fondements.length > 0 &&
              <div style={{ marginTop: 40, paddingTop: 20, borderTop: `1px solid ${C.trait}` }}>
                <div style={{ fontFamily: BODY, fontSize: 11.5, letterSpacing: "0.16em", textTransform: "uppercase", color: C.gris, fontWeight: 700, marginBottom: 10 }}>Fondements</div>
                <ul style={{ listStyle: "none", margin: 0, padding: 0, display: "flex", flexDirection: "column", gap: 6 }}>
                  {entry.fondements.map((f, i) =>
                    <li key={i} style={{ fontFamily: BODY, fontSize: 13.5, color: C.gris, lineHeight: 1.5 }}>{f}</li>)}
                </ul>
              </div>}

            {/* CTA discret */}
            <div style={{ marginTop: 36, paddingTop: 22, borderTop: `1px solid ${C.trait}`, display: "flex", flexWrap: "wrap", alignItems: "center", justifyContent: "space-between", gap: 14 }}>
              <span style={{ fontFamily: BODY, fontSize: 14.5, color: C.gris }}>Une question sur l'application à votre situation&nbsp;?</span>
              <a href={CAL_URL} target="_blank" rel="noopener noreferrer" style={{ fontFamily: BODY, fontSize: 14, fontWeight: 600, color: C.vert, textDecoration: "none", borderBottom: `1px solid ${C.or}`, paddingBottom: 2 }}>Pré-audit avec le cabinet →</a>
            </div>

            <div style={{ fontFamily: BODY, fontSize: 12.5, color: C.grisC, marginTop: 26 }}>Dernière mise à jour&nbsp;: {entry.maj}</div>
            <p style={{ fontFamily: BODY, fontSize: 12, color: C.grisC, marginTop: 8, fontStyle: "italic" }}>Information générale à vocation pédagogique — ne constitue pas une consultation juridique.</p>
          </article>

          {/* ToC sticky droite */}
          <aside className="enc-toc" style={{ position: "sticky", top: 100 }}>
            {toc.length > 0 &&
              <nav style={{ borderLeft: `1px solid ${C.trait}`, paddingLeft: 16 }}>
                <div style={{ fontFamily: BODY, fontSize: 11, letterSpacing: "0.16em", textTransform: "uppercase", color: C.grisC, fontWeight: 700, marginBottom: 12 }}>Sur cette page</div>
                <ul style={{ listStyle: "none", margin: 0, padding: 0, display: "flex", flexDirection: "column", gap: 10 }}>
                  {toc.map((it) =>
                    <li key={it.id}>
                      <a href={"#" + it.id} className={activeId === it.id ? "on" : ""} onClick={(e) => { e.preventDefault(); const el = document.getElementById(it.id); if (el) window.scrollTo({ top: el.getBoundingClientRect().top + window.scrollY - 90, behavior: "smooth" }); }}
                        style={{ fontFamily: BODY, fontSize: 13, lineHeight: 1.4, color: C.gris, textDecoration: "none", display: "block" }}>{it.text}</a>
                    </li>)}
                </ul>
              </nav>}
          </aside>
        </div>
      </div>);
  }

  // ---------- Page ----------
  function EncyclopediePage({ go, slug }) {
    useEffect(injectStyles, []);
    const data = window.MONARCH_ENCYCLO || { modules: [], entries: [] };
    const [query, setQuery] = useState("");
    const [navOpen, setNavOpen] = useState(false);
    const entry = slug ? data.entries.find((e) => e.slug === slug) : null;
    const open = (s) => { setNavOpen(false); go("encyclo", s); window.scrollTo({ top: 0 }); };
    const home = () => { go("encyclo"); window.scrollTo({ top: 0 }); };

    // recherche depuis le mobile : on revient à l'index (qui affiche les résultats)
    const onMobileSearch = (v) => {
      setQuery(v);
      if (entry && v.trim()) { go("encyclo"); window.scrollTo({ top: 0 }); }
    };

    // liste des modules pour le tiroir mobile
    const modNames = (data.modules || []).map((m) => m.name);
    (data.entries || []).forEach((e) => { if (e.module && !modNames.includes(e.module)) modNames.push(e.module); });

    return (
      <main style={{ background: C.fond, minHeight: "100vh", paddingTop: 88, paddingBottom: 60 }}>
        {/* Barre mobile : recherche + tiroir de navigation */}
        <div className="enc-mobilebar" style={{ position: "sticky", top: 64, zIndex: 30, background: C.fond, borderBottom: `1px solid ${C.trait}`, padding: "12px 20px" }}>
          <div style={{ position: "relative" }}>
            <span style={{ position: "absolute", left: 13, top: "50%", transform: "translateY(-50%)", color: C.grisC, fontSize: 15 }}>⌕</span>
            <input value={query} onChange={(e) => onMobileSearch(e.target.value)} placeholder="Rechercher dans l'encyclopédie…"
              style={{ width: "100%", fontFamily: BODY, fontSize: 15, color: C.encre, background: "#fff", border: `1px solid ${C.trait}`, borderRadius: 2, padding: "12px 38px 12px 36px", outline: "none" }} />
            {query && <button onClick={() => setQuery("")} aria-label="Effacer" style={{ position: "absolute", right: 8, top: "50%", transform: "translateY(-50%)", background: "none", border: "none", color: C.grisC, fontSize: 18, cursor: "pointer", padding: 6 }}>×</button>}
          </div>
          <button onClick={() => setNavOpen((o) => !o)} style={{ marginTop: 10, width: "100%", display: "flex", alignItems: "center", justifyContent: "space-between", fontFamily: BODY, fontSize: 14, fontWeight: 600, color: C.vert, background: "#fff", border: `1px solid ${C.trait}`, borderRadius: 2, padding: "11px 14px", cursor: "pointer" }}>
            <span>Parcourir par module</span>
            <span style={{ transition: "transform .25s", transform: navOpen ? "rotate(180deg)" : "none" }}>▾</span>
          </button>
          {navOpen &&
            <div style={{ marginTop: 8, background: "#fff", border: `1px solid ${C.trait}`, borderRadius: 2, padding: "6px 0", maxHeight: "60vh", overflowY: "auto" }}>
              {modNames.map((mod) => {
                const inMod = (data.entries || []).filter((e) => e.module === mod);
                if (!inMod.length) return null;
                return (
                  <div key={mod} style={{ padding: "8px 16px 12px" }}>
                    <div style={{ fontFamily: BODY, fontSize: 11, letterSpacing: "0.12em", textTransform: "uppercase", color: C.or, fontWeight: 700, marginBottom: 8 }}>{mod}</div>
                    {inMod.map((e) =>
                      <button key={e.slug} onClick={() => open(e.slug)}
                        style={{ display: "block", width: "100%", textAlign: "left", fontFamily: BODY, fontSize: 14.5, lineHeight: 1.4, padding: "8px 0", color: slug === e.slug ? C.vert : C.encre, fontWeight: slug === e.slug ? 600 : 500, background: "none", border: "none", borderBottom: `1px solid ${C.trait}`, cursor: "pointer" }}>
                        {e.title}
                      </button>)}
                  </div>);
              })}
            </div>}
        </div>

        <div style={{ maxWidth: 1280, margin: "0 auto", padding: "0 32px" }}>
          <div className="enc-shell" style={{ display: "grid", gridTemplateColumns: "260px minmax(0,1fr)", gap: 48, alignItems: "start" }}>
            <Sidebar data={data} current={slug} onOpen={open} query={query} setQuery={setQuery} />
            <div>
              {entry ? <Entry data={data} entry={entry} onOpen={open} goHome={home} /> : <Overview data={data} onOpen={open} query={query} />}
            </div>
          </div>
        </div>
      </main>);
  }

  window.EncyclopediePage = EncyclopediePage;
})();
