const React = window.React; const { useState, useEffect, useRef } = React; /* ---- minimal UI affordances (not content icons) ---- */ const Arrow = ({ cls }) => ( ); 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 ( Node it node it ); } /* ============================================================ 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 (
Prendre rendez-vous
setOpen(false)}>Prendre rendez-vous
); } /* ============================================================ 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: , blue: , duo: , }; function Pillar({ accent, no, title, desc, rows }) { const [open, setOpen] = useState(false); return (
setOpen((o) => !o)} onMouseLeave={() => setOpen(false)} >
{PILLAR_ICONS[accent]} {no}

{title}

{desc}

Voir les prestations Nos prestations
{rows.map((r, i) => ( e.stopPropagation()}>{r} ))}
); } 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 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 (
{slots.map((logoIdx, s) => { const logo = CLIENT_LOGOS[logoIdx]; return (
{logo.name} onSlotLoad(s)} />
); })}
); } function Hero() { return (
L'agence produit, IA & growth

On conçoit vos produits, on les rend intelligents
et on les fait grandir.

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.

Prendre rendez-vous Choisissez votre créneau en ligne.

Ils nous confient leurs produits

{PILLARS.map((p, i) => )}
); } /* ============================================================ 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 (
Écosystème

On se branche à vos outils, pas l'inverse.

IA, automatisation, no-code, e-commerce, prospection : on connecte et on orchestre la stack que vous utilisez déjà.

{TOOLS.map((t) => (
{t.name {t.name}
))}
+ Votre stack
); } /* ============================================================ Approach (dark band) ============================================================ */ const WF_ICONS = { target: , code: , pulse: , }; function NodeCard({ no, label, t, p, icon, delay, first, last }) { return (
{!first &&
); } 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 (
Notre façon de faire

Une équipe, pas une chaîne de sous-traitance.

On reste avec vous de l'idée à la production. Les mêmes personnes cadrent, codent et font vivre votre produit.

workflow.nodeit · exécution
{nodes.map((n, i) => ( {i < nodes.length - 1 &&
}
))}
Réserver un premier appel 30 min, sans engagement. On vous dit par où commencer.
); } /* ============================================================ 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: ( ), "support-agent": ( ), chatbot: ( ), secu: ( ), triage: ( ), "site-claude": ( ), "gtm-immo": ( ), }; // 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 (
{PROJECT_ILLU[p.id]}
{p.cats.map((c) => REAL_CAT_LABEL[c]).join(" · ")}
{p.t}

{p.sub}

{p.tags.map((t, j) => {t})}
); } 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 (
Projets

Ce qu'on construit, rend intelligent et fait grandir.

Projets anonymisés (NDA). Glissez pour explorer.

Tout voir
{REAL_PROJECTS.map((p) => )}
); } /* ============================================================ Formation (Qualiopi) ============================================================ */ function Formation() { return (
Organisme de formation

On déploie les outils. On forme vos équipes à les piloter.

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.

Découvrir les formations Qualiopi — Processus certifié — République Française

Formations finançables par

Mon Compte Formation (CPF)
OPCO
France Travail
AGEFICE
); } /* ============================================================ 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 (
Questions fréquentes

Ce qu'on nous demande souvent.

Une autre question ? Prenez rendez-vous, on y répond de vive voix.

{items.map((it, i) => { const isOpen = open === i; return (
(refs.current[i] = el)} style={{ maxHeight: isOpen && refs.current[i] ? refs.current[i].scrollHeight + "px" : 0 }}>
{it.a}
); })}
); } /* ============================================================ Final CTA + Footer ============================================================ */ function FinalCta() { return (
Le premier pas

Dites-nous ce que vous voulez construire.

Prenez rendez-vous. On cadre votre besoin, qu'il soit produit, IA ou acquisition, et on vous dit franchement par où commencer.

Prendre rendez-vous
); } function Footer() { return ( ); } /* ---- 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 (
{name
{name}
{role}

{bio}

); } function Team() { return (
L'équipe

Une petite équipe, trois métiers complémentaires.

Travailler avec nous
{TEAM.map((m, i) => )}
); } function App() { useReveal(); return (
); } window.NodeItApp = App; window.NodeItParts = { Brand, Header, Footer, Arrow, useReveal, TeamCard, TEAM, PILLARS, PILLAR_ICONS, PROJECT_ILLU, REAL_PROJECTS, REAL_CAT_LABEL, ProjectCardStatic };