SPB Git

spb/groupe-ka Public

Groupe KA — site du holding + KA ID (compte unique & SSO des 7 plateformes). Next.js 16, SQLite, Google & Apple login.

TypeScript 93.9% CSS 6%
28.5 KB · 730 lines tsx
Raw Blame History
1// Auteur : Simon-Pierre Boucher — contact@spboucher.ai2import type { ReactNode } from "react";3import {4  AggregationFigure,5  PipelineFigure,6  CycleFigure,7  InventoryBars,8  ConnectorMatrix,9  CoverageTiles,10} from "./figures";1112type Product = {13  num: string;14  markLeft: string;15  markBoxed: string;16  accent: string;   // couleur du logo (texte de la boîte)17  inkbox: string;   // fond de la boîte du logo18  domain: string;19  url: string;20  tagline: string;21  description: string;22  chips: string[];23  features: string[];24};2526const PRODUCTS: Product[] = [27  {28    num: "01",29    markLeft: "Lou",30    markBoxed: "Ka",31    accent: "#d9f26b",32    inkbox: "#141814",33    domain: "www.lou-ka.com",34    url: "https://www.lou-ka.com",35    tagline: "Tous les logements à louer du Québec. Un seul endroit.",36    description:37      "Agrégateur indépendant de logements locatifs : les annonces d'environ 74 gestionnaires immobiliers, normalisées, géolocalisées et synchronisées en continu. Une annonce retirée du site source disparaît du site — rien d'inventé, tout est traçable jusqu'à l'annonce originale.",38    chips: ["7 000+ annonces", "108 connecteurs actifs", "MàJ horaire"],39    features: [40      "Recherche unifiée : ville, secteur, taille (3½…), loyer, gestionnaire",41      "Vue carte interactive en plus de la grille de résultats",42      "Historique des baisses de prix et position face au marché",43      "Aucun traceur publicitaire, aucun témoin tiers",44    ],45  },46  {47    num: "02",48    markLeft: "Immo",49    markBoxed: "Ka",50    accent: "#e23744",51    inkbox: "#1a1214",52    domain: "www.immo-ka.com",53    url: "https://www.immo-ka.com",54    tagline: "Toutes les propriétés à vendre du Québec. Un seul endroit.",55    description:56      "L'inventaire des agences de courtage du Québec — RE/MAX, Sutton, Via Capitale, Proprio Direct et des dizaines d'autres — agrégé à la source, normalisé et géolocalisé. Chaque fiche renvoie à l'inscription originale du courtier ; une propriété vendue disparaît d'elle-même.",57    chips: ["54 000+ propriétés", "65 connecteurs", "2 370 villes"],58    features: [59      "Recherche unifiée : ville, type, prix, terrain, pièces",60      "Vue carte province entière, de Gatineau à Gaspé",61      "Détection automatique des ventes et retraits",62      "Lien direct vers l'inscription originale de l'agence",63    ],64  },65  {66    num: "03",67    markLeft: "Vrai",68    markBoxed: "Prix",69    accent: "#ff5148",70    inkbox: "#141814",71    domain: "www.vrai-prix.com",72    url: "https://www.vrai-prix.com",73    tagline: "La vraie valeur de votre propriété, en toute transparence.",74    description:75      "Estimation résidentielle pour tout le Québec, bâtie sur les rôles d'évaluation foncière du MAMH et 745 119 ventes réelles publiées de 2021 à 2026. Moteur hybride — modèle hédonique + comparables ajustés — dont chaque ajustement est affiché en dollars.",76    chips: ["3 747 008 propriétés", "745 119 ventes réelles", "MdAPE 11 %"],77    features: [78      "Fourchette honnête P10-P90 plutôt qu'un faux prix unique",79      "Indice de confiance A-D affiché sur une jauge, jamais caché",80      "Chaque comparable détaillé : marché, superficie, âge, poids",81      "Rapports PDF de marque, standard à format bancaire",82    ],83  },84  {85    num: "04",86    markLeft: "Valo",87    markBoxed: "Plex",88    accent: "#ff9f45",89    inkbox: "#141814",90    domain: "www.valoplex.com",91    url: "https://www.valoplex.com",92    tagline: "La vraie valeur de votre plex, porte par porte.",93    description:94      "Le moteur d'évaluation spécialisé pour les immeubles à revenus du Québec : entraîné exclusivement sur ~91 060 ventes réelles de plex, avec les variables qui comptent — portes, aire habitable par porte, chambres locatives, mixité commerciale.",95    chips: ["393 867 plex", "1 733 744 portes", "~337 G$ de parc"],96    features: [97      "Valeur totale et valeur par porte, l'unité d'analyse du plex",98      "Fourchette calibrée : 8 fois sur 10, le vrai prix tombe dedans",99      "« Pourquoi ce prix ? » — le calcul montré en entier",100      "Suivi de parc immobilier et rapports institutionnels",101    ],102  },103  {104    num: "05",105    markLeft: "Auto",106    markBoxed: "Ka",107    accent: "#ff5a2a",108    inkbox: "#17181c",109    domain: "www.auto-ka.com",110    url: "https://www.auto-ka.com",111    tagline: "Toutes les voitures usagées à vendre au Québec. Un seul endroit.",112    description:113      "L'inventaire de 124 concessionnaires et marchands d'occasion, lu directement sur leurs sites — jamais via les plateformes d'annonces. Photos complètes, équipements, VIN, kilométrage normalisés ; les baisses de prix et les ventes sont détectées automatiquement.",114    chips: ["15 900+ véhicules", "124 concessionnaires", "18 régions"],115    features: [116      "Filtres complets : marque, modèle, année, km, carburant, région",117      "Suivi des baisses de prix — les aubaines remontent d'elles-mêmes",118      "Fiches enrichies : galeries, équipements, moteur, Carfax",119      "Rapport PDF du marché de l'occasion, téléchargeable",120    ],121  },122  {123    num: "06",124    markLeft: "Fabri",125    markBoxed: "Ka",126    accent: "#C4532E",127    inkbox: "#1E1B16",128    domain: "www.fabri-ka.com",129    url: "https://www.fabri-ka.com",130    tagline: "Tous les produits québécois. Un seul endroit.",131    description:132      "La vitrine des fabricants et artisans d'ici : plus de 280 000 produits provenant de 1 200 boutiques en ligne québécoises, indexés par région et par catégorie. Chaque produit renvoie directement à la boutique du fabricant — acheter local n'a jamais été aussi simple.",133    chips: ["281 000+ produits", "1 204 boutiques", "17 régions"],134    features: [135      "Découverte par région, catégorie et mot-clé",136      "Lien direct vers la boutique du fabricant, sans intermédiaire",137      "Des Îles-de-la-Madeleine à l'Abitibi : tout le Québec",138      "Registre public de 3 200+ boutiques d'ici",139    ],140  },141  {142    num: "07",143    markLeft: "Food",144    markBoxed: "Ka",145    accent: "#d9f26b",146    inkbox: "#14231a",147    domain: "www.food-ka.com",148    url: "https://www.food-ka.com",149    tagline: "Tous les prix d'épicerie du Québec.",150    description:151      "Les produits et circulaires des grandes bannières d'épicerie — Metro, IGA, Maxi, Super C, Provigo et 15 autres — agrégés avec leurs prix, soldes et prix unitaires. Comparer son panier entre bannières devient un réflexe, pas une corvée.",152    chips: ["23 700+ produits", "20 bannières", "2 900+ soldes actifs"],153    features: [154      "Comparaison des prix entre bannières, produit par produit",155      "Prix unitaires normalisés ($/100 g, $/L) pour comparer vraiment",156      "Soldes et circulaires de la semaine en un seul flux",157      "Catégories d'épicerie complètes, du frais au garde-manger",158    ],159  },160];161162type Bot = {163  digit: string;164  accent: string;165  inkbox: string;166  domain: string;167  url: string;168  tagline: string;169  description: string;170  chips: string[];171  features: string[];172};173174const BOTS: Bot[] = [175  {176    digit: "2",177    accent: "#d9f26b",178    inkbox: "#141814",179    domain: "www.ka2.bot",180    url: "https://www.ka2.bot",181    tagline: "Le web québécois, cartographié entité par entité.",182    description:183      "Ka2 est un bot IA de cartographie : il parcourt le web québécois, identifie les entités — entreprises, organisations, personnes, sites web — et les documente. Propulsé par Claude Haiku 4.5 avec Firecrawl et Scrapfly, il ne copie pas les pages : il les comprend, puis les classe.",184    chips: ["4 types d'entités", "Propulsé par IA", "robots.txt respecté"],185    features: [186      "Découverte et classement : entreprises, organisations, personnes, sites web",187      "Chaque page lue est comprise par un modèle d'IA, pas seulement copiée",188      "Budget quotidien et délais entre requêtes — un crawl qui ménage les sites",189      "Données publiques seulement, Loi 25 et LPRPDE comme plancher",190    ],191  },192  {193    digit: "4",194    accent: "#ff9f45",195    inkbox: "#141814",196    domain: "www.ka4.bot",197    url: "https://www.ka4.bot",198    tagline: "Le deuxième éclaireur, avec l'activité à découvert.",199    description:200      "Ka4 double la flotte de découverte : même moteur IA — Claude Haiku 4.5 avec Firecrawl et Scrapfly —, mais une classification élargie à cinq types d'entités et un tableau de bord où l'exploration se regarde en direct. Deux bots, deux fronts, une seule carte du web québécois.",201    chips: ["5 types d'entités", "Activité en direct", "robots.txt respecté"],202    features: [203      "Classification élargie : entreprises, organisations, personnes, sites web, données",204      "Tableau de bord public : l'activité du bot et ses découvertes, en direct",205      "Bascule automatique entre backends de lecture (Firecrawl → Scrapfly)",206      "Données publiques seulement, Loi 25 et LPRPDE comme plancher",207    ],208  },209];210211const MANIFESTO = [212  {213    num: "01",214    title: "Zéro boîte noire",215    body: "Un score magique n'est pas une réponse. Chaque estimation montre ses comparables, ses ajustements en dollars et sa fourchette d'incertitude. Si le calcul ne peut pas être montré, il ne sort pas.",216  },217  {218    num: "02",219    title: "Données réelles",220    body: "Rôles d'évaluation foncière, ventes publiées, annonces vérifiées à la source. Aucun prix inventé : quand la donnée n'existe pas, on affiche qu'elle n'existe pas. Validé sur des ventes jamais vues, pas promis.",221  },222  {223    num: "03",224    title: "Indépendance",225    body: "Aucun courtier ni annonceur ne paie pour influencer un résultat. Pas de traceur publicitaire, pas de revente de données. Le français d'abord, le Québec comme terrain, la Loi 25 comme plancher.",226  },227];228229const SOCLE_ROWS: [string, string, string, string][] = [230  [231    "Lou·Ka",232    "Location résidentielle",233    "108 connecteurs sources + synchronisation horaire",234    "www.lou-ka.com",235  ],236  [237    "Immo·Ka",238    "Propriétés à vendre",239    "65 connecteurs d'agences + détection des ventes",240    "www.immo-ka.com",241  ],242  [243    "Vrai-Prix",244    "Résidentiel — tout le Québec",245    "Hédonique LightGBM + comparables réels ajustés",246    "www.vrai-prix.com",247  ],248  [249    "ValoPlex",250    "Immeubles à revenus (plex)",251    "Hédonique monotone + ventes de plex comparables",252    "www.valoplex.com",253  ],254  [255    "Auto·Ka",256    "Voitures usagées",257    "125 connecteurs concessionnaires + suivi des prix",258    "www.auto-ka.com",259  ],260  [261    "Fabri·Ka",262    "Produits québécois",263    "1 204 boutiques en ligne indexées par région",264    "www.fabri-ka.com",265  ],266  [267    "Food·Ka",268    "Épicerie",269    "20 bannières — prix, soldes et prix unitaires",270    "www.food-ka.com",271  ],272];273274function Section({275  id,276  kicker,277  title,278  children,279}: {280  id?: string;281  kicker: string;282  title: ReactNode;283  children: ReactNode;284}) {285  return (286    <section id={id} className="mt-16 scroll-mt-24 sm:mt-20">287      <p className="kicker">{kicker}</p>288      <h2 className="gk-display mt-2 text-[22px] font-bold tracking-[-0.03em] uppercase sm:text-[26px]">289        {title}290      </h2>291      {children}292    </section>293  );294}295296/* ------------------------------------------------------------------ */297/* Entrée de dictionnaire — l'allusion fondatrice : ·Ka = agréger.     */298/* ------------------------------------------------------------------ */299300function KaDefinition() {301  return (302    <aside className="gk-card gk-card-hover rise p-6 sm:p-7 [animation-delay:0.3s]">303      <p className="klabel">Le nom, expliqué</p>304      <p className="gk-display mt-3 text-[30px] font-bold tracking-[-0.03em]">305        ·Ka{" "}306        <span className="gk-mono align-middle text-[13px] font-medium text-ink-3">307          /ka/ suffixe308        </span>309      </p>310      <ol className="mt-4 space-y-3 text-[13.5px] leading-relaxed text-ink-2">311        <li className="flex gap-3">312          <span className="gk-mono font-bold text-green">1.</span>313          <span>314            <strong className="text-ink">Agréger</strong> — rassembler en un315            seul endroit ce qui était éparpillé sur des centaines de sites.316          </span>317        </li>318        <li className="flex gap-3">319          <span className="gk-mono font-bold text-green">2.</span>320          <span>321            Marque de fabrique du groupe : Lou·Ka loge, Immo·Ka vend, Auto·Ka322            roule, Fabri·Ka fabrique, Food·Ka nourrit.323          </span>324        </li>325      </ol>326      <p className="mt-5 border-t-[1.5px] border-dashed border-[rgba(20,24,20,0.25)] pt-4 text-[13px] italic text-ink-2">327        « Tout ce qui finit en <span className="gk-display font-bold not-italic">·Ka</span>{" "}328        agrège. »329      </p>330    </aside>331  );332}333334function ProductCard({ p, index }: { p: Product; index: number }) {335  return (336    <article337      className="gk-card gk-card-hover rise p-5 sm:p-7"338      style={{ animationDelay: `${0.1 + index * 0.12}s` }}339    >340      <div className="flex flex-wrap items-baseline justify-between gap-3">341        <span className="gk-mono text-[12px] font-bold text-green">342          {p.num}343        </span>344        <span className="klabel">{p.domain}</span>345      </div>346      <h3 className="gk-display mt-4 inline-flex items-baseline gap-[5px] text-[32px] font-bold tracking-[-0.04em] sm:text-[38px]">347        {p.markLeft}348        <span349          className="inline-block -rotate-2 rounded-md px-[8px] pb-[3px]"350          style={{ background: p.inkbox, color: p.accent }}351        >352          {p.markBoxed}353        </span>354      </h3>355      <p className="gk-display mt-3 text-[17px] font-bold uppercase tracking-[-0.01em]">356        {p.tagline}357      </p>358      <p className="mt-3 text-[13.5px] leading-relaxed text-ink-2">359        {p.description}360      </p>361      <div className="mt-5 flex flex-wrap gap-2">362        {p.chips.map((chip) => (363          <span key={chip} className="stat-chip !text-[11px]">364            {chip}365          </span>366        ))}367      </div>368      <ul className="mt-5 space-y-2 border-t-[1.5px] border-dashed border-[rgba(20,24,20,0.25)] pt-5">369        {p.features.map((f) => (370          <li key={f} className="flex gap-3 text-[13.5px] text-ink-2">371            <span372              aria-hidden="true"373              className="mt-[7px] h-[5px] w-[5px] flex-none rotate-45 border border-ink bg-lime"374            />375            {f}376          </li>377        ))}378      </ul>379      <a380        href={p.url}381        target="_blank"382        rel="noopener noreferrer"383        className="btn btn-primary mt-6 w-full sm:w-auto"384      >385        Visiter {p.domain} ↗386      </a>387    </article>388  );389}390391export default function Home() {392  return (393    <main className="mx-auto max-w-6xl px-4 pb-16 sm:px-6">394      {/* ---------- Héros ---------- */}395      <section className="grid items-start gap-8 pt-12 sm:pt-14 lg:grid-cols-[minmax(0,1.4fr)_minmax(0,1fr)]">396        <div className="min-w-0">397          <p className="kicker rise">398            Holding d’agrégateurs automatisés · Québec399          </p>400          <h1 className="gk-display rise mt-4 max-w-4xl text-[clamp(34px,6.4vw,68px)] leading-[0.98] font-bold tracking-[-0.035em] uppercase [animation-delay:0.08s]">401            Mille sites.{" "}402            <span className="outline-txt">Un seul</span>{" "}403            <span className="hl">·Ka.</span>404          </h1>405          <p className="rise mt-5 max-w-xl text-[16.5px] text-ink-2 [animation-delay:0.16s]">406            <strong className="text-ink">Ka, c&apos;est l&apos;agrégation.</strong>{" "}407            Groupe KA est un holding d&apos;agrégateurs entièrement408            automatisés : des centaines de connecteurs lisent les sites à la409            source, normalisent la donnée et se resynchronisent seuls, jour et410            nuit. Se loger, acheter, évaluer, rouler, consommer local, faire411            l&apos;épicerie — sept plateformes, zéro saisie manuelle, zéro412            boîte noire.413          </p>414          <div className="rise mt-7 flex gap-3 overflow-x-auto pb-2 [animation-delay:0.24s]">415            <span className="stat-chip">416              <span className="pulse-dot" aria-hidden="true" />7 agrégateurs en417              ligne418            </span>419            <span className="stat-chip">450+ connecteurs sources</span>420            <span className="stat-chip">22 M+ d&apos;observations immobilières</span>421            <span className="stat-chip">375 000+ annonces &amp; produits agrégés</span>422            <span className="stat-chip">100 % données à la source</span>423          </div>424          <div className="rise mt-6 flex flex-wrap gap-3 [animation-delay:0.3s]">425            <a href="#flux" className="btn btn-primary">426              Voir comment KA agrège ↓427            </a>428            <a href="#produits" className="btn btn-ghost">429              Les sept plateformes430            </a>431          </div>432        </div>433        <KaDefinition />434      </section>435436      {/* ---------- La figure d'agrégation ---------- */}437      <Section438        id="flux"439        kicker="Le geste fondateur · agréger"440        title={441          <>442            Plein de sites. <span className="hl">Une seule flèche.</span>443          </>444        }445      >446        <p className="mt-3 max-w-xl text-[14.5px] text-ink-2">447          Chaque plateforme du groupe fonctionne sur le même schéma : un448          faisceau de connecteurs part vers des centaines de sites sources,449          ramène la donnée brute, et KA la transforme en un seul endroit450          propre. Voici la machine, à découvert.451        </p>452        <AggregationFigure />453        <div className="mt-6 grid items-start gap-6 lg:grid-cols-2">454          <PipelineFigure />455          <CycleFigure />456        </div>457      </Section>458459      {/* ---------- Les chiffres ---------- */}460      <Section461        id="chiffres"462        kicker="La preuve par les nombres · rien de caché"463        title={464          <>465            Ce que ·Ka <span className="hl">agrège, compté</span>466          </>467        }468      >469        <p className="mt-3 max-w-xl text-[14.5px] text-ink-2">470          Un agrégateur se juge à ce qu&apos;il agrège. Voici l&apos;état des471          lieux, mesuré sur les plateformes elles-mêmes — inventaire vivant,472          flotte de connecteurs, couverture des moteurs d&apos;évaluation.473        </p>474        <div className="mt-7 grid items-stretch gap-6 lg:grid-cols-2">475          <InventoryBars />476          <ConnectorMatrix />477        </div>478        <div className="mt-6 grid items-start gap-6 lg:grid-cols-2">479          <div className="gk-card !bg-ink p-6 text-paper sm:p-7">480            <p className="kicker !text-lime">L&apos;équation ·Ka</p>481            <p className="gk-display mt-4 text-[clamp(26px,3.5vw,38px)] leading-[1.05] font-bold tracking-[-0.03em] uppercase">482              1 000+ sites lus483              <br />484              <span className="text-lime">→ 450+ connecteurs</span>485              <br />→ 7 plateformes486            </p>487            <p className="mt-4 max-w-md text-[13.5px] text-[rgba(245,243,238,0.75)]">488              La donnée entre éparpillée, elle ressort rangée. Entre les deux,489              aucune main humaine — c&apos;est le suffixe ·Ka qui travaille.490            </p>491          </div>492          <CoverageTiles />493        </div>494      </Section>495496      {/* ---------- Produits ---------- */}497      <Section498        id="produits"499        kicker="Sept agrégateurs · un écosystème"500        title={501          <>502            Ce que nous <span className="hl">agrégeons</span>503          </>504        }505      >506        <p className="mt-3 max-w-xl text-[14.5px] text-ink-2">507          Chaque agrégateur attaque un angle mort du quotidien québécois : se508          loger, acheter, évaluer, rouler, consommer local, faire509          l&apos;épicerie. Aucune saisie manuelle — les plateformes se510          maintiennent elles-mêmes, annonce par annonce, prix par prix.511        </p>512        <div className="mt-7 grid gap-5 lg:grid-cols-3">513          {PRODUCTS.map((p, i) => (514            <ProductCard key={p.num} p={p} index={i} />515          ))}516        </div>517      </Section>518519      {/* ---------- Socle commun ---------- */}520      <Section521        id="socle"522        kicker="Une seule fondation"523        title="Le socle commun"524      >525        <p className="mt-3 max-w-xl text-[14.5px] text-ink-2">526          Les sept plateformes partagent la même colonne vertébrale : données527          publiques et annonces lues directement à la source, connecteurs528          dédiés synchronisés en continu, moteurs statistiques validés, et une529          identité visuelle unique — bordures encre, lime électrique, calcul à530          découvert.531        </p>532        <div className="src-wrap mt-7">533          <table className="src-table">534            <thead>535              <tr>536                <th>Agrégateur</th>537                <th>Marché</th>538                <th>Moteur</th>539                <th>Adresse</th>540              </tr>541            </thead>542            <tbody>543              {SOCLE_ROWS.map(([produit, marche, moteur, adresse]) => (544                <tr key={produit}>545                  <td className="gk-display font-bold whitespace-nowrap">546                    {produit}547                  </td>548                  <td>{marche}</td>549                  <td>{moteur}</td>550                  <td className="gk-mono text-[12px] whitespace-nowrap">551                    <a552                      href={`https://${adresse}`}553                      target="_blank"554                      rel="noopener noreferrer"555                      className="underline decoration-[rgba(20,24,20,0.3)] underline-offset-4 hover:decoration-ink"556                    >557                      {adresse}558                    </a>559                  </td>560                </tr>561              ))}562            </tbody>563          </table>564        </div>565      </Section>566567      {/* ---------- Ka2 & Ka4 — les agents de découverte ---------- */}568      <Section569        id="bots"570        kicker="Les éclaireurs du groupe · découverte web"571        title={572          <>573            Avant d&apos;agréger, <span className="hl">les bots découvrent</span>574          </>575        }576      >577        <p className="mt-3 max-w-xl text-[14.5px] text-ink-2">578          Les connecteurs ·Ka lisent des sources connues. Mais qui trouve les579          sources ? Ka2 et Ka4, les agents de découverte web du groupe : des580          bots IA qui explorent et cartographient le web québécois, entité par581          entité, pour alimenter tout l&apos;écosystème.582        </p>583        <div className="mt-7 grid gap-5 lg:grid-cols-2">584          {BOTS.map((b) => (585            <article key={b.domain} className="gk-card gk-card-hover p-5 sm:p-7">586              <div className="flex flex-wrap items-baseline justify-between gap-3">587                <span className="gk-mono text-[12px] font-bold text-green">588                  BOT589                </span>590                <span className="klabel">{b.domain}</span>591              </div>592              <h3 className="gk-display mt-4 inline-flex items-baseline gap-[5px] text-[32px] font-bold tracking-[-0.04em] sm:text-[38px]">593                Ka594                <span595                  className="inline-block -rotate-2 rounded-md px-[8px] pb-[3px]"596                  style={{ background: b.inkbox, color: b.accent }}597                >598                  {b.digit}599                </span>600              </h3>601              <p className="gk-display mt-3 text-[17px] font-bold uppercase tracking-[-0.01em]">602                {b.tagline}603              </p>604              <p className="mt-3 text-[13.5px] leading-relaxed text-ink-2">605                {b.description}606              </p>607              <div className="mt-5 flex flex-wrap gap-2">608                {b.chips.map((chip) => (609                  <span key={chip} className="stat-chip !text-[11px]">610                    {chip}611                  </span>612                ))}613              </div>614              <ul className="mt-5 space-y-2 border-t-[1.5px] border-dashed border-[rgba(20,24,20,0.25)] pt-5">615                {b.features.map((f) => (616                  <li key={f} className="flex gap-3 text-[13.5px] text-ink-2">617                    <span618                      aria-hidden="true"619                      className="mt-[7px] h-[5px] w-[5px] flex-none rotate-45 border border-ink bg-lime"620                    />621                    {f}622                  </li>623                ))}624              </ul>625              <a626                href={b.url}627                target="_blank"628                rel="noopener noreferrer"629                className="btn btn-primary mt-6 w-full sm:w-auto"630              >631                Visiter {b.domain} ↗632              </a>633            </article>634          ))}635        </div>636        <div className="gk-card mt-6 !bg-ink p-6 text-paper sm:p-7">637          <p className="kicker !text-lime">638            Le rôle des bots dans l&apos;écosystème639          </p>640          <div className="mt-4 grid items-start gap-6 lg:grid-cols-2">641            <p className="gk-display text-[clamp(24px,3.2vw,34px)] leading-[1.05] font-bold tracking-[-0.03em] uppercase">642              Les bots découvrent643              <br />644              <span className="text-lime">→ ·Ka agrège</span>645              <br />→ vous trouvez646            </p>647            <div>648              <p className="max-w-md text-[13.5px] text-[rgba(245,243,238,0.75)]">649                Ka2 et Ka4 sont les éclaireurs du groupe : ils cartographient650                le terrain avant que les connecteurs ne s&apos;y branchent. Une651                nouvelle boutique québécoise, un nouveau gestionnaire652                immobilier, un concessionnaire qui ouvre — les bots les653                repèrent, et les plateformes ·Ka les intègrent.654              </p>655              <ul className="mt-5 space-y-2 border-t border-[rgba(245,243,238,0.15)] pt-5 text-[13px] text-[rgba(245,243,238,0.75)]">656                {[657                  "Respectent systématiquement robots.txt",658                  "Ne traitent que des données publiques",659                  "Zéro boîte noire — leur fonctionnement est documenté sur ka2.bot et ka4.bot",660                ].map((f) => (661                  <li key={f} className="flex gap-3">662                    <span663                      aria-hidden="true"664                      className="mt-[6px] h-[5px] w-[5px] flex-none rotate-45 bg-lime"665                    />666                    {f}667                  </li>668                ))}669              </ul>670            </div>671          </div>672        </div>673      </Section>674675      {/* ---------- Manifeste ---------- */}676      <Section id="mission" kicker="Notre manifeste" title="Trois principes, aucune exception">677        <div className="mt-7 grid gap-4 sm:grid-cols-3">678          {MANIFESTO.map((m) => (679            <article key={m.num} className="gk-card gk-card-hover p-5 sm:p-6">680              <span className="gk-mono text-[12px] font-bold text-green">681                {m.num}682              </span>683              <h3 className="gk-display mt-3 text-[17px] font-bold uppercase">684                {m.title}685              </h3>686              <p className="mt-3 text-[13.5px] leading-relaxed text-ink-2">687                {m.body}688              </p>689            </article>690          ))}691        </div>692      </Section>693694      {/* ---------- Appel à l'action ---------- */}695      <section className="mt-16 sm:mt-20">696        <div className="gk-card overflow-hidden !bg-ink p-7 text-paper sm:p-10">697          <p className="kicker !text-lime">Un projet · une question</p>698          <h2 className="gk-display mt-3 max-w-2xl text-[clamp(24px,4vw,40px)] leading-[1.02] font-bold tracking-[-0.03em] uppercase">699            Quelque chose à <span className="text-lime">agréger</span> ?{" "}700            Parlons-en.701          </h2>702          <p className="mt-4 max-w-xl text-[14.5px] text-[rgba(245,243,238,0.75)]">703            Partenariats, données, médias ou simple curiosité méthodologique —704            de vraies personnes au bout. C&apos;est notre spécialité : tout705            ramener à un seul endroit.706          </p>707          <div className="mt-7 flex flex-wrap gap-3">708            <a709              href="mailto:contact@groupe-ka.com"710              className="btn btn-lime !border-lime"711            >712              contact@groupe-ka.com713            </a>714            <a715              href="mailto:info@groupe-ka.com"716              className="btn !border-lime !bg-transparent !text-lime hover:!bg-[rgba(217,242,107,0.12)]"717            >718              info@groupe-ka.com719            </a>720          </div>721          <p className="gk-mono mt-5 text-[11px] text-[rgba(245,243,238,0.55)]">722            contact@ — projets &amp; partenariats · info@ — médias &amp;723            questions générales · admin@ — légal &amp; vie privée724          </p>725        </div>726      </section>727    </main>728  );729}730