const React = window.React;
const { useState, useEffect, useRef } = React;

/* ---- minimal UI affordances (not content icons) ---- */
const Arrow = ({ cls }) => (
  <span className={cls} aria-hidden="true"><svg viewBox="0 0 16 16" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M3 8h10M9 4l4 4-4 4" /></svg></span>
);

function Brand({ dark = false }) {
  const R = (typeof window !== "undefined" && window.__resources) || {};
  const src = dark ? (R.logoViolet || "../../assets/logo-mark-violet.svg") : (R.logoInk || "../../assets/logo-mark-ink.svg");
  return (
    <a className="brand" href="index.html">
      <img src={src} alt="Node it" />
      <span className="brand__word">node<span className="it">&nbsp;it</span></span>
    </a>
  );
}

/* ============================================================
   Header — flat nav + single CTA to contact, mobile drawer
   ============================================================ */
function Header() {
  const [open, setOpen] = React.useState(false);
  React.useEffect(() => {
    document.body.style.overflow = open ? "hidden" : "";
    return () => { document.body.style.overflow = ""; };
  }, [open]);
  const links = [
    { href: "expertise.html", label: "Expertises" },
    { href: "realisations.html", label: "Projets" },
    { href: "agence.html", label: "À propos" },
  ];
  return (
    <header className="hdr">
      <div className="container">
        <div className="hdr__inner">
          <Brand />
          <nav className="nav">
            {links.map((l) => <a className="nav__link" href={l.href} key={l.href}>{l.label}</a>)}
          </nav>
          <div className="hdr__cta">
            <a className="ni-btn" data-variant="primary" href="contact.html">Prendre rendez-vous <Arrow cls="ni-btn__icon" /></a>
          </div>
          <button className="hdr__burger" aria-label="Ouvrir le menu" aria-expanded={open} onClick={() => setOpen((v) => !v)}>
            <span className="hdr__burger-bar" data-x={open ? "true" : undefined} />
            <span className="hdr__burger-bar" data-x={open ? "true" : undefined} />
            <span className="hdr__burger-bar" data-x={open ? "true" : undefined} />
          </button>
        </div>
      </div>
      <div className="mobile-menu" data-open={open ? "true" : undefined}>
        <nav className="mobile-menu__nav">
          {links.map((l) => <a className="mobile-menu__link" href={l.href} key={l.href} onClick={() => setOpen(false)}>{l.label}</a>)}
        </nav>
        <a className="ni-btn" data-variant="primary" data-size="lg" href="contact.html" onClick={() => setOpen(false)}>Prendre rendez-vous <Arrow cls="ni-btn__icon" /></a>
      </div>
    </header>
  );
}

/* ============================================================
   Hero with two pillars
   ============================================================ */
const PILLARS = [
  {
    accent: "violet", no: "01", title: "Développement",
    desc: "On construit le produit, du cadrage à la mise en production.",
    rows: ["Développement sur mesure", "Création de SaaS", "Création de site web", "Intégration API"],
  },
  {
    accent: "blue", no: "02", title: "Intelligence Artificielle",
    desc: "On rend vos outils plus intelligents, plus rapides, plus autonomes.",
    rows: ["Audit IA", "Création d'agent IA", "Chatbot", "Automation"],
  },
  {
    accent: "duo", no: "03", title: "Growth",
    desc: "On construit des tunnels d'acquisition intelligents et automatisés pour générer des leads.",
    rows: ["Go-to-market strategy", "Outbound marketing", "Achat média", "Tracking"],
  },
];

const PILLAR_ICONS = {
  violet: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><path d="m8 8-4 4 4 4M16 8l4 4-4 4M13.5 5l-3 14" /></svg>,
  blue: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><path d="M12 3v3M12 18v3M3 12h3M18 12h3M5.6 5.6l2.1 2.1M16.3 16.3l2.1 2.1M18.4 5.6l-2.1 2.1M7.7 16.3l-2.1 2.1" /><circle cx="12" cy="12" r="3.2" /></svg>,
  duo: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><path d="M3 17c3.5 0 4-9 8-9s4.5 6 8 6" /><path d="m16 11 3-3 3 3" /></svg>,
};

function Pillar({ accent, no, title, desc, rows }) {
  const [open, setOpen] = useState(false);
  return (
    <div
      className="pillar"
      data-accent={accent}
      data-open={open ? "true" : undefined}
      onClick={() => setOpen((o) => !o)}
      onMouseLeave={() => setOpen(false)}
    >
      <div className="pillar__wash" />
      <div className="pillar__head">
        <span className="pillar__icon">{PILLAR_ICONS[accent]}</span>
        <span className="pillar__no">{no}</span>
      </div>
      <h2>{title}</h2>
      <p className="pillar__desc">{desc}</p>
      <div className="pillar__toggle">
        <span className="lbl-closed">Voir les prestations</span>
        <span className="lbl-open">Nos prestations</span>
        <span className="pillar__chev"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="m6 9 6 6 6-6" /></svg></span>
      </div>
      <div className="pillar__list">
        <div className="pillar__list-inner">
          {rows.map((r, i) => (
            <a className="pillar__row" href="expertise.html" key={i} onClick={(e) => e.stopPropagation()}>{r}<Arrow cls="arr" /></a>
          ))}
        </div>
      </div>
    </div>
  );
}

const CLIENT_LOGOS = [
  { name: "Super U", file: "super-u.png" },
  { name: "Peugeot", file: "peugeot.png" },
  { name: "Arkéa", file: "arkea.png" },
  { name: "Deepreach", file: "deepreach.png" },
  { name: "Sup de Pub", file: "sup-de-pub.png" },
  { name: "OhMyDiode", file: "ohmydiode.svg" },
  { name: "Dessine-moi un Hôtel", file: "dessine-moi-un-hotel.jpg" },
  { name: "Catella", file: "catella.webp" },
  { name: "Pan Paon", file: "pan-paon.webp" },
];

function ClientLogos() {
  const COUNT = 6;
  const [slots, setSlots] = useState([0, 1, 2, 3, 4, 5]);
  const [fading, setFading] = useState(-1);
  const slotsRef = useRef(slots);
  slotsRef.current = slots;
  const turn = useRef(0);
  const pendingSlot = useRef(-1);
  useEffect(() => {
    let alive = true;
    let loop = null, tSwap = null, tFallback = null;
    const cycle = () => {
      if (!alive) return;
      loop = setTimeout(cycle, 4200);
      const cur = slotsRef.current;
      const slot = turn.current % COUNT;
      turn.current += 1;
      const used = new Set(cur);
      const pool = CLIENT_LOGOS.map((_, i) => i).filter((i) => !used.has(i));
      if (pool.length === 0) return;
      const next = pool[Math.floor(Math.random() * pool.length)];
      // Preload + decode the next logo BEFORE any visual change — no blank flash.
      const img = new Image();
      img.src = "assets/clients/" + CLIENT_LOGOS[next].file;
      const start = () => {
        if (!alive) return;
        setFading(slot);                                   // fade current out
        tSwap = setTimeout(() => {
          if (!alive) return;
          pendingSlot.current = slot;                      // unfade only once the real <img> has the new logo painted
          setSlots((c) => { const o = c.slice(); o[slot] = next; return o; }); // swap while invisible
          // fallback: cached swaps can skip the element's load event
          tFallback = setTimeout(() => { if (alive && pendingSlot.current === slot) { pendingSlot.current = -1; setFading(-1); } }, 240);
        }, 520);
      };
      const ready = img.decode ? img.decode().then(start).catch(start) : null;
      if (!ready) { if (img.complete && img.naturalWidth) start(); else { img.onload = start; img.onerror = start; } }
    };
    loop = setTimeout(cycle, 4200);
    return () => { alive = false; clearTimeout(loop); clearTimeout(tSwap); clearTimeout(tFallback); };
  }, []);
  const onSlotLoad = (s) => { if (pendingSlot.current === s) { pendingSlot.current = -1; setFading(-1); } };
  return (
    <div className="client-wall">
      {slots.map((logoIdx, s) => {
        const logo = CLIENT_LOGOS[logoIdx];
        return (
          <div className="client-slot" data-fading={fading === s ? "true" : undefined} key={s}>
            <img src={"assets/clients/" + logo.file} alt={logo.name} onLoad={() => onSlotLoad(s)} />
          </div>
        );
      })}
    </div>
  );
}

function Hero() {
  return (
    <section className="hero section">
      <div className="hero__glow" />
      <div className="container">
        <div className="hero__top reveal is-in">
          <span className="kicker">L'agence produit, IA &amp; growth</span>
          <h1>On conçoit vos <span className="v" style={{ animationDelay: ".3s" }}>produits</span>, on les rend <span className="b" style={{ animationDelay: ".9s" }}>intelligents</span><br />et on les fait <span className="v" style={{ animationDelay: "1.5s" }}>grandir</span>.</h1>
          <p className="hero__lead">Studio produit, IA et growth avec une vraie logique d'agence. On développe vos applications et vos SaaS, on y branche les agents IA et l'automatisation, puis on construit les tunnels d'acquisition qui font venir vos clients.</p>
          <div className="hero__actions">
            <a className="ni-btn" data-variant="primary" data-size="lg" href="contact.html">Prendre rendez-vous <Arrow cls="ni-btn__icon" /></a>
            <span className="meta">Choisissez votre créneau en ligne.</span>
          </div>
        </div>
        <div className="hero__clients reveal is-in">
          <p className="trust-eyebrow">Ils nous confient leurs produits</p>
          <ClientLogos />
        </div>
        <div className="pillars reveal is-in">
          {PILLARS.map((p, i) => <Pillar key={i} {...p} />)}
        </div>
      </div>
    </section>
  );
}

/* ============================================================
   Integrations / tools we connect to (right after hero)
   ============================================================ */
const TOOLS = [
  { name: "Claude", file: "claude.svg" },
  { name: "ChatGPT", file: "chatgpt.png" },
  { name: "Codex", file: "codex.png", dark: true },
  { name: "Gemini", file: "gemini.png" },
  { name: "n8n", file: "n8n.png" },
  { name: "Notion", file: "notion.png" },
  { name: "Figma", file: "figma.png" },
  { name: "HubSpot", file: "hubspot.png" },
  { name: "lemlist", file: "lemlist.png" },
  { name: "Apollo", file: "apollo.webp" },
  { name: "PhantomBuster", file: "phantombuster.png" },
  { name: "Webflow", file: "webflow.png" },
  { name: "WordPress", file: "wordpress.png" },
  { name: "Shopify", file: "shopify.png" },
  { name: "Google Agenda", file: "google-calendar.png" },
];
function Integrations() {
  return (
    <section className="band--surface section" id="integrations">
      <div className="container">
        <div className="tools-head reveal">
          <span className="kicker" style={{ justifyContent: "center" }}>Écosystème</span>
          <h2>On se branche à vos outils, pas l'inverse.</h2>
          <p>IA, automatisation, no-code, e-commerce, prospection : on connecte et on orchestre la stack que vous utilisez déjà.</p>
        </div>
        <div className="tools-grid reveal">
          {TOOLS.map((t) => (
            <div className="tool-tile" key={t.name}>
              <span className="tool-tile__chip" data-dark={t.dark ? "true" : undefined}>
                <img src={"assets/tools/" + t.file} alt={t.name + " logo"} loading="lazy" />
              </span>
              <span className="tool-tile__name">{t.name}</span>
            </div>
          ))}
          <div className="tool-tile tool-tile--ghost">
            <span className="tool-tile__chip" style={{ background: "transparent", borderStyle: "dashed", fontSize: "1.4rem", color: "var(--text-faint)" }}>+</span>
            <span className="tool-tile__name">Votre stack</span>
          </div>
        </div>
      </div>
    </section>
  );
}

/* ============================================================
   Approach (dark band)
   ============================================================ */
const WF_ICONS = {
  target: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="8" /><circle cx="12" cy="12" r="3.4" /><path d="M12 1.5v3M12 19.5v3M1.5 12h3M19.5 12h3" /></svg>,
  code: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><path d="m8 8-4 4 4 4M16 8l4 4-4 4M13.5 6l-3 12" /></svg>,
  pulse: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><path d="M3 12h4l2.5 6 4-13L16.5 12H21" /></svg>,
};

function NodeCard({ no, label, t, p, icon, delay, first, last }) {
  return (
    <div className="wf-node" style={{ "--run-delay": delay }}>
      {!first && <span className="wf-node__handle wf-node__handle--in" aria-hidden="true" />}
      {!last && <span className="wf-node__handle wf-node__handle--out" aria-hidden="true" />}
      <div className="wf-node__bar">
        <span className="wf-node__icon">{WF_ICONS[icon]}</span>
        <span className="wf-node__label">{label}</span>
        <span className="wf-node__status" aria-hidden="true" />
      </div>
      <div className="wf-node__name"><span className="wf-node__no">{no}</span>{t}</div>
      <p className="wf-node__desc">{p}</p>
    </div>
  );
}

function Approach() {
  const nodes = [
    { no: "01", label: "Trigger", t: "Cadrage", icon: "target", delay: "0s", p: "On clarifie le problème, les usages et la valeur avant la moindre ligne de code." },
    { no: "02", label: "Action", t: "Build", icon: "code", delay: "1.6s", p: "On conçoit, on développe et on intègre l'IA. Démos régulières, vous voyez le produit grandir." },
    { no: "03", label: "Action", t: "Run", icon: "pulse", delay: "3.2s", p: "On maintient, on fait évoluer et on forme vos équipes. Le produit continue de vivre." },
  ];
  return (
    <section className="band--ink on-dark section">
      <div className="ink-glow" />
      <div className="container">
        <div className="wf-head">
          <span className="kicker">Notre façon de faire</span>
          <h2 style={{ fontSize: "var(--fs-h2)", margin: "1rem 0" }}>Une équipe, pas une chaîne de sous-traitance.</h2>
          <p style={{ color: "var(--text-muted)", lineHeight: "var(--lh-relaxed)" }}>On reste avec vous de l'idée à la production. Les mêmes personnes cadrent, codent et font vivre votre produit.</p>
        </div>
        <div className="wf-canvas">
          <span className="wf-canvas__tag">workflow.nodeit · exécution</span>
          <div className="wf-flow">
            {nodes.map((n, i) => (
              <React.Fragment key={i}>
                <NodeCard {...n} first={i === 0} last={i === nodes.length - 1} />
                {i < nodes.length - 1 && <div className="wf-wire"><span className="wf-wire__pulse" /></div>}
              </React.Fragment>
            ))}
          </div>
        </div>
        <div className="wf-cta">
          <a className="ni-btn" data-variant="primary" data-size="lg" href="contact.html">Réserver un premier appel <Arrow cls="ni-btn__icon" /></a>
          <span className="wf-cta__note">30 min, sans engagement. On vous dit par où commencer.</span>
        </div>
      </div>
    </section>
  );
}

/* ============================================================
   Réalisations — shared project data + illustrations (used here + projets page)
   ============================================================ */
const REAL_CAT_LABEL = { dev: "Développement", ia: "Intelligence Artificielle", growth: "Growth" };
const ILLU_S = { fill: "none", stroke: "#fff", strokeWidth: 3, strokeLinecap: "round", strokeLinejoin: "round" };
const ILLU_SOFT = "rgba(255,255,255,.14)";
const PROJECT_ILLU = {
  sdr: (
    <svg viewBox="0 0 240 150" aria-hidden="true">
      <circle cx="66" cy="75" r="42" fill={ILLU_SOFT} /><circle cx="66" cy="75" r="42" {...ILLU_S} /><circle cx="66" cy="75" r="25" {...ILLU_S} />
      <path d="M66 75 66 33" {...ILLU_S} /><circle cx="66" cy="75" r="3.5" fill="#fff" />
      <circle cx="92" cy="54" r="3.5" fill="#fff" /><circle cx="50" cy="100" r="3.5" fill="#fff" /><circle cx="86" cy="96" r="3.5" fill="#fff" />
      <path d="M112 75 H140" {...ILLU_S} /><path d="M132 69 140 75 132 81" {...ILLU_S} />
      <rect x="150" y="46" width="62" height="58" rx="9" fill={ILLU_SOFT} /><rect x="150" y="46" width="62" height="58" rx="9" {...ILLU_S} />
      <path d="M162 66 H200 M162 78 H188" {...ILLU_S} /><path d="M163 92 169 98 180 86" {...ILLU_S} />
    </svg>
  ),
  "support-agent": (
    <svg viewBox="0 0 240 150" aria-hidden="true">
      <rect x="40" y="30" width="74" height="92" rx="10" fill={ILLU_SOFT} /><rect x="40" y="30" width="74" height="92" rx="10" {...ILLU_S} />
      <path d="M56 52 H98 M56 68 H98 M56 84 H82" {...ILLU_S} />
      <path d="M138 44 H206 a10 10 0 0 1 10 10 V92 a10 10 0 0 1 -10 10 H170 l-16 16 V102 H138 a10 10 0 0 1 -10 -10 V54 a10 10 0 0 1 10 -10 Z" fill={ILLU_SOFT} />
      <path d="M138 44 H206 a10 10 0 0 1 10 10 V92 a10 10 0 0 1 -10 10 H170 l-16 16 V102 H138 a10 10 0 0 1 -10 -10 V54 a10 10 0 0 1 10 -10 Z" {...ILLU_S} />
      <circle cx="154" cy="73" r="3.5" fill="#fff" /><circle cx="172" cy="73" r="3.5" fill="#fff" /><circle cx="190" cy="73" r="3.5" fill="#fff" />
    </svg>
  ),
  chatbot: (
    <svg viewBox="0 0 240 150" aria-hidden="true">
      <path d="M44 36 H150 a12 12 0 0 1 12 12 V86 a12 12 0 0 1 -12 12 H78 l-20 18 V98 H44 a12 12 0 0 1 -12 -12 V48 a12 12 0 0 1 12 -12 Z" fill={ILLU_SOFT} />
      <path d="M44 36 H150 a12 12 0 0 1 12 12 V86 a12 12 0 0 1 -12 12 H78 l-20 18 V98 H44 a12 12 0 0 1 -12 -12 V48 a12 12 0 0 1 12 -12 Z" {...ILLU_S} />
      <circle cx="70" cy="67" r="4" fill="#fff" /><circle cx="96" cy="67" r="4" fill="#fff" /><circle cx="122" cy="67" r="4" fill="#fff" />
      <path d="M176 78 H206 a8 8 0 0 1 8 8 V108 a8 8 0 0 1 -8 8 H196 l-14 12 V116 q-6 0 -6 -8 V86 a8 8 0 0 1 8 -8 Z" {...ILLU_S} />
    </svg>
  ),
  secu: (
    <svg viewBox="0 0 240 150" aria-hidden="true">
      <path d="M104 26 64 42 V78 c0 28 20 44 40 50 20 -6 40 -22 40 -50 V42 Z" fill={ILLU_SOFT} />
      <path d="M104 26 64 42 V78 c0 28 20 44 40 50 20 -6 40 -22 40 -50 V42 Z" {...ILLU_S} />
      <path d="M88 76 100 88 122 62" {...ILLU_S} />
      <path d="M176 58 a18 18 0 0 1 18 18 c0 20 8 24 8 24 H150 s8 -4 8 -24 a18 18 0 0 1 18 -18 Z" fill={ILLU_SOFT} />
      <path d="M176 58 a18 18 0 0 1 18 18 c0 20 8 24 8 24 H150 s8 -4 8 -24 a18 18 0 0 1 18 -18 Z" {...ILLU_S} />
      <path d="M170 108 a8 8 0 0 0 12 0" {...ILLU_S} /><path d="M176 50 V58" {...ILLU_S} />
    </svg>
  ),
  triage: (
    <svg viewBox="0 0 240 150" aria-hidden="true">
      <rect x="40" y="36" width="118" height="26" rx="7" fill={ILLU_SOFT} /><rect x="40" y="36" width="118" height="26" rx="7" {...ILLU_S} /><path d="M52 49 H120" {...ILLU_S} />
      <rect x="40" y="70" width="96" height="26" rx="7" fill={ILLU_SOFT} /><rect x="40" y="70" width="96" height="26" rx="7" {...ILLU_S} /><path d="M52 83 H104" {...ILLU_S} />
      <rect x="40" y="104" width="72" height="26" rx="7" fill={ILLU_SOFT} /><rect x="40" y="104" width="72" height="26" rx="7" {...ILLU_S} /><path d="M52 117 H92" {...ILLU_S} />
      <path d="M186 40 V126 M186 40 178 50 M186 40 194 50" {...ILLU_S} />
      <circle cx="186" cy="58" r="3.5" fill="#fff" /><circle cx="186" cy="83" r="3.5" fill="#fff" /><circle cx="186" cy="110" r="3.5" fill="#fff" />
    </svg>
  ),
  "site-claude": (
    <svg viewBox="0 0 240 150" aria-hidden="true">
      <rect x="42" y="32" width="156" height="104" rx="11" fill={ILLU_SOFT} /><rect x="42" y="32" width="156" height="104" rx="11" {...ILLU_S} />
      <path d="M42 56 H198" {...ILLU_S} /><circle cx="58" cy="44" r="3.2" fill="#fff" /><circle cx="70" cy="44" r="3.2" fill="#fff" /><circle cx="82" cy="44" r="3.2" fill="#fff" />
      <path d="M58 76 H132 M58 92 H150 M58 108 H110" {...ILLU_S} />
      <path d="M170 86 q4 -16 8 0 q16 4 0 8 q-4 16 -8 0 q-16 -4 0 -8 Z" fill="#fff" stroke="none" />
    </svg>
  ),
  "gtm-immo": (
    <svg viewBox="0 0 240 150" aria-hidden="true">
      <path d="M54 124 H190" {...ILLU_S} />
      <rect x="64" y="86" width="30" height="38" fill={ILLU_SOFT} /><rect x="64" y="86" width="30" height="38" {...ILLU_S} /><path d="M72 96 H86 M72 106 H86" {...ILLU_S} />
      <rect x="102" y="66" width="32" height="58" fill={ILLU_SOFT} /><rect x="102" y="66" width="32" height="58" {...ILLU_S} /><path d="M110 78 H126 M110 90 H126 M110 102 H126" {...ILLU_S} />
      <path d="M150 110 168 84 182 98 206 56" {...ILLU_S} /><path d="M192 56 H206 V70" {...ILLU_S} />
    </svg>
  ),
};
// Projets volontairement anonymisés (NDA). Un projet peut relever de plusieurs métiers.
const REAL_PROJECTS = [
  { id: "sdr", cats: ["ia"], t: "Agent SDR autonome", sub: "Scrape les prospects, les qualifie et les pousse dans le CRM, prêts pour le séquençage Lemlist.", tags: ["Agent IA", "Outbound", "Lemlist"] },
  { id: "support-agent", cats: ["ia"], t: "Agent support métier", sub: "Branché sur votre documentation interne, il traite et résout les tickets de support entrants.", tags: ["Agent IA", "Support"] },
  { id: "chatbot", cats: ["ia"], t: "Chatbot support", sub: "Un assistant conversationnel qui répond à vos clients en continu sur vos canaux.", tags: ["Chatbot", "Support"] },
  { id: "secu", cats: ["ia"], t: "Agent d'audit sécurité", sub: "Audite en continu la sécurité de votre application et alerte l'équipe sur Slack.", tags: ["Agent IA", "Sécurité", "Slack"] },
  { id: "triage", cats: ["ia"], t: "Agent de tri des tickets", sub: "Trie, priorise et documente vos tickets, prêts pour une validation humaine.", tags: ["Agent IA", "Ops"] },
  { id: "site-claude", cats: ["dev", "ia"], t: "Site web intelligent", sub: "Site connecté à Claude Code qui rédige automatiquement les fiches produit à partir de vos guidelines SEO et GEO.", tags: ["Web", "SEO / GEO", "Claude Code"] },
  { id: "gtm-immo", cats: ["growth"], t: "Go-to-market immobilier", sub: "Stratégie go-to-market complète pour une société d'investissement immobilier.", tags: ["Go-to-market", "Acquisition"] },
];

function ProjectCardStatic({ p }) {
  return (
    <div className="ni-project ni-project--static" data-cat={p.cats[0]}>
      <div className="ni-project__media"><div className="proj-illu">{PROJECT_ILLU[p.id]}</div></div>
      <div className="ni-project__body">
        <span className="ni-project__cat">{p.cats.map((c) => REAL_CAT_LABEL[c]).join(" · ")}</span>
        <div className="ni-project__title">{p.t}</div>
        <p style={{ color: "var(--text-muted)", fontSize: "var(--fs-sm)", margin: 0, lineHeight: "var(--lh-relaxed)" }}>{p.sub}</p>
        <div className="ni-project__tags">{p.tags.map((t, j) => <span className="ni-tag" key={j}>{t}</span>)}</div>
      </div>
    </div>
  );
}

function Realisations() {
  const trackRef = useRef(null);
  useEffect(() => {
    const el = trackRef.current;
    if (!el) return;
    const slider = el.parentElement;
    let down = false, startX = 0, startScroll = 0;
    const onDown = (e) => { down = true; startX = e.pageX; startScroll = el.scrollLeft; el.classList.add("dragging"); };
    const onMove = (e) => { if (!down) return; el.scrollLeft = startScroll - (e.pageX - startX); };
    const onUp = () => { down = false; el.classList.remove("dragging"); };
    const updateEnd = () => {
      const atEnd = el.scrollLeft + el.clientWidth >= el.scrollWidth - 4;
      if (atEnd) slider.setAttribute("data-end", ""); else slider.removeAttribute("data-end");
    };
    updateEnd();
    el.addEventListener("pointerdown", onDown);
    window.addEventListener("pointermove", onMove);
    window.addEventListener("pointerup", onUp);
    el.addEventListener("scroll", updateEnd, { passive: true });
    window.addEventListener("resize", updateEnd);
    return () => { el.removeEventListener("pointerdown", onDown); window.removeEventListener("pointermove", onMove); window.removeEventListener("pointerup", onUp); el.removeEventListener("scroll", updateEnd); window.removeEventListener("resize", updateEnd); };
  }, []);
  return (
    <section className="section" id="realisations">
      <div className="container">
        <div className="sec-top" style={{ marginBottom: "var(--space-6)" }}>
          <div className="sec-head">
            <span className="kicker">Projets</span>
            <h2>Ce qu'on construit, rend intelligent et fait grandir.</h2>
            <p style={{ color: "var(--text-muted)", fontSize: "var(--fs-base)", marginTop: ".25rem" }}>Projets anonymisés (NDA). Glissez pour explorer.</p>
          </div>
          <a className="ni-btn" data-variant="secondary" href="realisations.html">Tout voir <Arrow cls="ni-btn__icon" /></a>
        </div>
        <div className="proj-slider">
          <div className="proj-track" ref={trackRef}>
            {REAL_PROJECTS.map((p) => <ProjectCardStatic key={p.id} p={p} />)}
          </div>
        </div>
      </div>
    </section>
  );
}

/* ============================================================
   Formation (Qualiopi)
   ============================================================ */
function Formation() {
  return (
    <section className="band--surface section">
      <div className="container">
        <div className="form-single reveal is-in">
          <span className="kicker">Organisme de formation</span>
          <h2>On déploie les outils. On forme vos équipes à les piloter.</h2>
          <p>Node it est un organisme de formation certifié Qualiopi. Au-delà des produits et des automatisations qu'on met en place, on forme vos équipes pour qu'elles s'approprient leurs nouveaux outils en toute autonomie. Nos formations sont finançables.</p>
          <div className="form-actions">
            <a className="ni-btn" data-variant="primary" href="https://www.nodeit.fr" target="_blank" rel="noreferrer">Découvrir les formations <Arrow cls="ni-btn__icon" /></a>
            <span className="qualiopi-badge"><img src="assets/logo-qualiopi.png" alt="Qualiopi — Processus certifié — République Française" loading="lazy" /></span>
          </div>
          <div className="form-financeurs">
            <p className="form-financeurs__label">Formations finançables par</p>
            <div className="financeur-row">
              <div className="financeur"><img src="assets/financeurs/mon-compte-formation.jpg" alt="Mon Compte Formation (CPF)" loading="lazy" /></div>
              <div className="financeur"><img src="assets/financeurs/opco.webp" alt="OPCO" loading="lazy" /></div>
              <div className="financeur"><img src="assets/financeurs/france-travail.webp" alt="France Travail" loading="lazy" /></div>
              <div className="financeur"><img src="assets/financeurs/agefice.jpg" alt="AGEFICE" loading="lazy" /></div>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

/* ============================================================
   FAQ
   ============================================================ */
function Faq() {
  const items = [
    { q: "Vous faites du produit ou de l'IA ?", a: "Les deux, et c'est tout l'intérêt. On conçoit le produit puis on y intègre l'IA là où elle crée vraiment de la valeur." },
    { q: "Combien de temps pour un premier livrable ?", a: "Un MVP utile sort généralement en un à quatre mois. On livre en continu, pas en big bang." },
    { q: "Pouvez-vous reprendre un projet existant ?", a: "Oui. On audite, on stabilise et on fait évoluer une base de code déjà en place." },
    { q: "Travaillez-vous avec des outils no-code ?", a: "Quand c'est pertinent. On combine code sur mesure et outils comme n8n pour aller vite sans dette inutile." },
  ];
  const [open, setOpen] = useState(0);
  const refs = useRef([]);
  return (
    <section className="section">
      <div className="container faq-wrap">
        <div className="sec-head">
          <span className="kicker">Questions fréquentes</span>
          <h2>Ce qu'on nous demande souvent.</h2>
          <p>Une autre question ? Prenez rendez-vous, on y répond de vive voix.</p>
        </div>
        <div className="ni-accordion">
          {items.map((it, i) => {
            const isOpen = open === i;
            return (
              <div className="ni-acc-item" data-open={isOpen ? "true" : undefined} key={i}>
                <button className="ni-acc-trigger" onClick={() => setOpen(isOpen ? -1 : i)} aria-expanded={isOpen}>
                  <span className="ni-acc-num">{String(i + 1).padStart(2, "0")}</span>
                  <span className="ni-acc-title">{it.q}</span>
                  <span className="ni-acc-sign" />
                </button>
                <div className="ni-acc-panel" ref={(el) => (refs.current[i] = el)}
                  style={{ maxHeight: isOpen && refs.current[i] ? refs.current[i].scrollHeight + "px" : 0 }}>
                  <div className="ni-acc-panel-inner">{it.a}</div>
                </div>
              </div>
            );
          })}
        </div>
      </div>
    </section>
  );
}

/* ============================================================
   Final CTA + Footer
   ============================================================ */
function FinalCta() {
  return (
    <section className="section">
      <div className="container">
        <div className="cta-panel on-dark reveal">
          <div className="ink-glow" />
          <span className="kicker" style={{ justifyContent: "center" }}>Le premier pas</span>
          <h2>Dites-nous ce que vous voulez <span className="v">construire</span>.</h2>
          <p>Prenez rendez-vous. On cadre votre besoin, qu'il soit produit, IA ou acquisition, et on vous dit franchement par où commencer.</p>
          <a className="ni-btn" data-variant="primary" data-size="lg" href="contact.html">Prendre rendez-vous <Arrow cls="ni-btn__icon" /></a>
        </div>
      </div>
    </section>
  );
}

function Footer() {
  return (
    <footer className="ft on-dark">
      <div className="container ft__grid">
        <div className="ft__col ft__brand-about">
          <Brand dark />
          <p className="ft__about">L'agence produit et IA de Node it. On entreprend avec vous pour créer les produits digitaux de demain.</p>
          <div className="ft__cta-row">
            <a className="ft__cta" href="contact.html">Prendre rendez-vous<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><path d="M7 17 17 7" /><path d="M8 7h9v9" /></svg></a>
            <a className="ft__cta" href="https://www.nodeit.fr" target="_blank" rel="noreferrer">Se former<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><path d="M7 17 17 7" /><path d="M8 7h9v9" /></svg></a>
          </div>
        </div>
        <div className="ft__col"><p className="ft__h">Développement</p>
          <a href="expertise.html#dev">Développement sur mesure</a><a href="expertise.html#dev">Création de SaaS</a><a href="expertise.html#dev">Sites web</a><a href="expertise.html#dev">Intégration API</a></div>
        <div className="ft__col"><p className="ft__h">Intelligence Artificielle</p>
          <a href="expertise.html#ia">Audit IA</a><a href="expertise.html#ia">Agents IA</a><a href="expertise.html#ia">Chatbot</a><a href="expertise.html#ia">Automation</a></div>
        <div className="ft__col"><p className="ft__h">Studio</p>
          <a href="expertise.html">Expertises</a><a href="realisations.html">Projets</a><a href="agence.html">À propos</a><a href="contact.html">Contact</a></div>
      </div>
      <div className="container ft__bottom">
        <span>© 2026 Agence Node it. Tous droits réservés.</span>
        <span className="ft__bottom-links"><a href="#">Mentions légales</a><a href="#">Confidentialité</a></span>
      </div>
    </footer>
  );
}

/* ---- reveal-on-scroll with safety fallback ---- */
function useReveal() {
  useEffect(() => {
    const reveal = (el) => el.classList.add("is-in");
    const els = Array.from(document.querySelectorAll(".reveal:not(.is-in)"));
    document.documentElement.classList.add("reveal-on");
    if (!("IntersectionObserver" in window)) { els.forEach(reveal); return; }
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => { if (e.isIntersecting) { reveal(e.target); io.unobserve(e.target); } });
    }, { threshold: 0.12, rootMargin: "0px 0px -8% 0px" });
    els.forEach((el) => io.observe(el));
    const safety = setTimeout(() => els.forEach(reveal), 1600);
    return () => { io.disconnect(); clearTimeout(safety); };
  }, []);
}

/* ============================================================
   Team (homepage section + reused on About page)
   ============================================================ */
const TEAM = [
  { name: "Lionel", role: "CTO", photo: "lionel.jpeg", accent: "violet", bio: "Architecture, développement et intégration IA. Il transforme le besoin en produit qui tourne en production." },
  { name: "Terence", role: "Growth Manager", photo: "terence.png", accent: "duo", bio: "Acquisition, tunnels et data. Il construit les canaux qui font venir vos clients." },
  { name: "Jeremy", role: "Business Developer", photo: "jeremy.jpeg", accent: "blue", bio: "Premier contact et cadrage. Il s'assure qu'on règle le bon problème, dès le départ." },
];
function TeamCard({ name, role, photo, accent, bio }) {
  return (
    <div className="team-card" data-accent={accent}>
      <div className="team-card__avatar"><img src={"assets/team/" + photo} alt={name + ", " + role + " chez Agence Node it"} loading="lazy" /></div>
      <div className="team-card__name">{name}</div>
      <div className="team-card__role">{role}</div>
      <p className="team-card__bio">{bio}</p>
    </div>
  );
}
function Team() {
  return (
    <section className="section" id="equipe">
      <div className="container">
        <div className="sec-top" style={{ marginBottom: "var(--space-7)" }}>
          <div className="sec-head">
            <span className="kicker">L'équipe</span>
            <h2>Une petite équipe, trois métiers complémentaires.</h2>
          </div>
          <a className="ni-btn" data-variant="secondary" href="contact.html">Travailler avec nous <Arrow cls="ni-btn__icon" /></a>
        </div>
        <div className="team-grid">
          {TEAM.map((m, i) => <TeamCard key={i} {...m} />)}
        </div>
      </div>
    </section>
  );
}

function App() {
  useReveal();
  return (
    <div className="site">
      <Header />
      <Hero />
      <Integrations />
      <Approach />
      <Realisations />
      <Formation />
      <Team />
      <Faq />
      <FinalCta />
      <Footer />
    </div>
  );
}

window.NodeItApp = App;
window.NodeItParts = { Brand, Header, Footer, Arrow, useReveal, TeamCard, TEAM, PILLARS, PILLAR_ICONS, PROJECT_ILLU, REAL_PROJECTS, REAL_CAT_LABEL, ProjectCardStatic };
