SPB Git forge

spb/groupe-ka

Public

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

81commits 1branches 0releases
89.2 MBsize
maindefault branch
22 days agolast push
TypeScript 70.4% HTML 18.4% JavaScript 4% Python 3.8% CSS 3.4%

feat: 3 nouveaux agrégateurs (Resto·Ka, Sorti·Ka, Créa·Ka) + refonte des cartes produits

- 10 agrégateurs présentés (cartes 08-09-10 avec badge Nouveau, données réelles des APIs)
- Cartes produits améliorées : bande d'accent de marque, numéro en pastille encre/accent,
  étiquette de marché, puces aux couleurs de la marque, 10e carte pleine largeur
- Figures mises à jour : sablier à 10 plateformes + 13 sources, inventaire (8 barres),
  matrice 340 connecteurs
- Socle (11 plateformes), ticker, footer, métadonnées OG et compteurs héros à jour

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Simon-Pierre Boucher committed 1 mo ago (Aug 17, 2026) parent 1659dd0

3 changed files +230 −69

modified src/app/figures.tsx +17 −5
@@ -19,6 +19,9 @@ export const FIG_PLATFORMS: {
19 19 { name: "Auto·Ka", accent: "#ff5a2a", domain: "auto-ka.com" },
20 20 { name: "Fabri·Ka", accent: "#C4532E", domain: "fabri-ka.com" },
21 21 { name: "Food·Ka", accent: "#d9f26b", domain: "food-ka.com" },
22 + { name: "Resto·Ka", accent: "#ffc53d", domain: "resto-ka.com" },
23 + { name: "Sorti·Ka", accent: "#ff6a00", domain: "sorti-ka.com" },
24 + { name: "Créa·Ka", accent: "#7da2ff", domain: "crea-ka.com" },
22 25 ];
23 26
24 27 const ACCENT: Record<string, string> = Object.fromEntries(
@@ -63,6 +66,9 @@ const FIG_SOURCES = [
63 66 "Sites de fabricants",
64 67 "Bannières d'épicerie",
65 68 "Circulaires & soldes",
69 + "Menus de restaurants",
70 + "Billetteries d'événements",
71 + "Profils de créateurs",
66 72 ];
67 73
68 74 export function AggregationFigure() {
@@ -87,7 +93,7 @@ export function AggregationFigure() {
87 93 <svg
88 94 viewBox={`0 0 ${W} ${H}`}
89 95 role="img"
90 − aria-label="Schéma de l'agrégation KA : des centaines de sites sources sont lus par des connecteurs, la donnée converge vers KA qui la redistribue vers les sept plateformes."
96 + aria-label="Schéma de l'agrégation KA : des centaines de sites sources sont lus par des connecteurs, la donnée converge vers KA qui la redistribue vers les dix plateformes."
91 97 className="block min-w-[760px]"
92 98 >
93 99 <defs>
@@ -320,14 +326,14 @@ export function AggregationFigure() {
320 326 letterSpacing="1.5"
321 327 fill="#8b928c"
322 328 >
323 − SEPT PLATEFORMES
329 + DIX PLATEFORMES
324 330 </text>
325 331 </svg>
326 332 </div>
327 333 <FigCaption lead="LE SABLIER ·KA">
328 334 des centaines de sites éparpillés, lus à la source par des connecteurs
329 335 dédiés ; tout converge vers KA, qui normalise, dédoublonne et
330 − redistribue vers sept plateformes. Une flèche entre, sept flèches
336 + redistribue vers dix plateformes. Une flèche entre, dix flèches
331 337 sortent : c&apos;est ça, agréger.
332 338 </FigCaption>
333 339 </figure>
@@ -671,10 +677,13 @@ export function CycleFigure() {
671 677
672 678 const INVENTORY: { name: string; value: number; unit: string }[] = [
673 679 { name: "Fabri·Ka", value: 281000, unit: "produits québécois" },
680 + { name: "Resto·Ka", value: 61000, unit: "plats & prix réels" },
674 681 { name: "Immo·Ka", value: 54000, unit: "propriétés à vendre" },
675 682 { name: "Food·Ka", value: 23700, unit: "prix d'épicerie" },
676 683 { name: "Auto·Ka", value: 15900, unit: "véhicules d'occasion" },
684 + { name: "Sorti·Ka", value: 11100, unit: "événements & sorties" },
677 685 { name: "Lou·Ka", value: 7000, unit: "logements à louer" },
686 + { name: "Créa·Ka", value: 2200, unit: "créateurs d'ici" },
678 687 ];
679 688
680 689 const fmt = (n: number) => n.toLocaleString("fr-CA").replace(/ /g, " ");
@@ -731,6 +740,8 @@ const CONNECTORS: { name: string; count: number; kind: string }[] = [
731 740 { name: "Lou·Ka", count: 108, kind: "gestionnaires" },
732 741 { name: "Immo·Ka", count: 65, kind: "agences" },
733 742 { name: "Food·Ka", count: 20, kind: "bannières" },
743 + { name: "Resto·Ka", count: 19, kind: "chaînes de restos" },
744 + { name: "Sorti·Ka", count: 4, kind: "billetteries & données ouvertes" },
734 745 ];
735 746
736 747 export function ConnectorMatrix() {
@@ -739,7 +750,7 @@ export function ConnectorMatrix() {
739 750 <div className="p-5 sm:p-7">
740 751 <p className="klabel">La flotte · un point = un connecteur</p>
741 752 <h3 className="gk-display mt-2 text-[17px] font-bold uppercase">
742 − 317 connecteurs, dessinés un par un
753 + 340 connecteurs, dessinés un par un
743 754 </h3>
744 755 <div className="mt-6 space-y-6">
745 756 {CONNECTORS.map((c) => (
@@ -771,7 +782,8 @@ export function ConnectorMatrix() {
771 782 <FigCaption lead="LA FLOTTE">
772 783 chaque point est un petit programme qui connaît un site par cœur et le
773 784 relit sans arrêt. S&apos;y ajoutent les flux des 1 204 boutiques de
774 − Fabri·Ka et les données publiques qui alimentent Vrai-Prix et ValoPlex.
785 + Fabri·Ka, les données publiques qui alimentent Vrai-Prix et ValoPlex,
786 + et l&apos;annuaire multi-plateformes de Créa·Ka.
775 787 </FigCaption>
776 788 </figure>
777 789 );
modified src/app/layout.tsx +11 −4
@@ -18,11 +18,11 @@ export const metadata: Metadata = {
18 18 metadataBase: new URL("https://www.groupe-ka.com"),
19 19 title: "Groupe KA — holding d’agrégateurs automatisés, sans boîte noire",
20 20 description:
21 − "Groupe KA est un holding québécois d’agrégateurs de produits et services entièrement automatisés : Trouve·Ka (moteur de recherche du web québécois), Lou·Ka (location), Immo·Ka (propriétés à vendre), Vrai-Prix (valeur résidentielle), ValoPlex (plex), Auto·Ka (voitures usagées), Fabri·Ka (produits québécois) et Food·Ka (épicerie). Zéro saisie manuelle.",
21 + "Groupe KA est un holding québécois d’agrégateurs de produits et services entièrement automatisés : Trouve·Ka (moteur de recherche du web québécois), Lou·Ka (location), Immo·Ka (propriétés à vendre), Vrai-Prix (valeur résidentielle), ValoPlex (plex), Auto·Ka (voitures usagées), Fabri·Ka (produits québécois), Food·Ka (épicerie), Resto·Ka (restaurants, menus et prix), Sorti·Ka (sorties et événements) et Créa·Ka (créateurs d’ici). Zéro saisie manuelle.",
22 22 openGraph: {
23 23 title: "Groupe KA — holding d’agrégateurs automatisés, sans boîte noire",
24 24 description:
25 − "Ka, c’est l’agrégation : des centaines de connecteurs, sept plateformes — Lou·Ka, Immo·Ka, Vrai-Prix, ValoPlex, Auto·Ka, Fabri·Ka et Food·Ka.",
25 + "Ka, c’est l’agrégation : des centaines de connecteurs, dix plateformes — Lou·Ka, Immo·Ka, Vrai-Prix, ValoPlex, Auto·Ka, Fabri·Ka, Food·Ka, Resto·Ka, Sorti·Ka et Créa·Ka.",
26 26 url: "https://www.groupe-ka.com",
27 27 siteName: "Groupe KA",
28 28 locale: "fr_CA",
@@ -44,13 +44,16 @@ const NAV_ITEMS = [
44 44 const TICKER_ITEMS = [
45 45 "·Ka = agréger — mille sites, un seul endroit",
46 46 "Trouve·Ka cherche le Québec — le moteur de recherche du web d'ici",
47 − "Sept agrégateurs · une obsession : la transparence",
47 + "Dix agrégateurs · une obsession : la transparence",
48 48 "450+ connecteurs lisent les sources jour et nuit",
49 49 "7 000+ logements à louer agrégés en continu",
50 50 "54 000+ propriétés à vendre, lues à la source",
51 51 "15 900+ voitures usagées chez 124 concessionnaires",
52 52 "281 000+ produits québécois de 1 204 boutiques",
53 53 "23 700+ prix d'épicerie suivis chez 20 bannières",
54 + "61 000+ plats et prix réels chez 540+ restos — resto-ka.com",
55 + "11 100+ sorties et événements dans les 17 régions — sorti-ka.com",
56 + "2 200+ créateurs québécois, tous leurs liens regroupés — crea-ka.com",
54 57 "3 747 008 propriétés évaluées au Québec",
55 58 "393 867 plex · 1 733 744 portes",
56 59 "Ka2 & Ka4 cartographient le web québécois — ka2.bot · ka4.bot",
@@ -198,7 +201,8 @@ export default function RootLayout({
198 201 entièrement automatisés. Des centaines de connecteurs lisent les
199 202 sites à la source, normalisent la donnée et se resynchronisent
200 203 seuls — logements, propriétés, autos, produits d&apos;ici,
201 − épicerie. Rien d&apos;inventé, tout est traçable.{" "}
204 + épicerie, restos, sorties, créateurs. Rien d&apos;inventé, tout
205 + est traçable.{" "}
202 206 <span className="text-lime">
203 207 ·Ka, c&apos;est le suffixe qui veut dire agréger.
204 208 </span>
@@ -225,6 +229,9 @@ export default function RootLayout({
225 229 ["Auto·Ka", "https://www.auto-ka.com"],
226 230 ["Fabri·Ka", "https://www.fabri-ka.com"],
227 231 ["Food·Ka", "https://www.food-ka.com"],
232 + ["Resto·Ka", "https://www.resto-ka.com"],
233 + ["Sorti·Ka", "https://www.sorti-ka.com"],
234 + ["Créa·Ka", "https://www.crea-ka.com"],
228 235 ["Ka2", "https://www.ka2.bot"],
229 236 ["Ka4", "https://www.ka4.bot"],
230 237 ["Ka6", "https://www.ka6.bot"],
modified src/app/page.tsx +202 −60
@@ -15,12 +15,14 @@ type Product = {
15 15 markBoxed: string;
16 16 accent: string; // couleur du logo (texte de la boîte)
17 17 inkbox: string; // fond de la boîte du logo
18 + field: string; // le marché couvert, en un mot
18 19 domain: string;
19 20 url: string;
20 21 tagline: string;
21 22 description: string;
22 23 chips: string[];
23 24 features: string[];
25 + isNew?: boolean;
24 26 };
25 27
26 28 const PRODUCTS: Product[] = [
@@ -30,6 +32,7 @@ const PRODUCTS: Product[] = [
30 32 markBoxed: "Ka",
31 33 accent: "#d9f26b",
32 34 inkbox: "#141814",
35 + field: "Location",
33 36 domain: "www.lou-ka.com",
34 37 url: "https://www.lou-ka.com",
35 38 tagline: "Tous les logements à louer du Québec. Un seul endroit.",
@@ -49,6 +52,7 @@ const PRODUCTS: Product[] = [
49 52 markBoxed: "Ka",
50 53 accent: "#e23744",
51 54 inkbox: "#1a1214",
55 + field: "Immobilier",
52 56 domain: "www.immo-ka.com",
53 57 url: "https://www.immo-ka.com",
54 58 tagline: "Toutes les propriétés à vendre du Québec. Un seul endroit.",
@@ -68,6 +72,7 @@ const PRODUCTS: Product[] = [
68 72 markBoxed: "Prix",
69 73 accent: "#ff5148",
70 74 inkbox: "#141814",
75 + field: "Évaluation",
71 76 domain: "www.vrai-prix.com",
72 77 url: "https://www.vrai-prix.com",
73 78 tagline: "La vraie valeur de votre propriété, en toute transparence.",
@@ -87,6 +92,7 @@ const PRODUCTS: Product[] = [
87 92 markBoxed: "Plex",
88 93 accent: "#ff9f45",
89 94 inkbox: "#141814",
95 + field: "Évaluation plex",
90 96 domain: "www.valoplex.com",
91 97 url: "https://www.valoplex.com",
92 98 tagline: "La vraie valeur de votre plex, porte par porte.",
@@ -106,6 +112,7 @@ const PRODUCTS: Product[] = [
106 112 markBoxed: "Ka",
107 113 accent: "#ff5a2a",
108 114 inkbox: "#17181c",
115 + field: "Automobile",
109 116 domain: "www.auto-ka.com",
110 117 url: "https://www.auto-ka.com",
111 118 tagline: "Toutes les voitures usagées à vendre au Québec. Un seul endroit.",
@@ -125,6 +132,7 @@ const PRODUCTS: Product[] = [
125 132 markBoxed: "Ka",
126 133 accent: "#C4532E",
127 134 inkbox: "#1E1B16",
135 + field: "Achat local",
128 136 domain: "www.fabri-ka.com",
129 137 url: "https://www.fabri-ka.com",
130 138 tagline: "Tous les produits québécois. Un seul endroit.",
@@ -144,6 +152,7 @@ const PRODUCTS: Product[] = [
144 152 markBoxed: "Ka",
145 153 accent: "#d9f26b",
146 154 inkbox: "#14231a",
155 + field: "Épicerie",
147 156 domain: "www.food-ka.com",
148 157 url: "https://www.food-ka.com",
149 158 tagline: "Tous les prix d'épicerie du Québec.",
@@ -157,6 +166,69 @@ const PRODUCTS: Product[] = [
157 166 "Catégories d'épicerie complètes, du frais au garde-manger",
158 167 ],
159 168 },
169 + {
170 + num: "08",
171 + markLeft: "Resto",
172 + markBoxed: "Ka",
173 + accent: "#ffc53d",
174 + inkbox: "#1a1410",
175 + field: "Restaurants",
176 + domain: "www.resto-ka.com",
177 + url: "https://www.resto-ka.com",
178 + tagline: "Tous les restaurants du Québec. Menus et prix réels.",
179 + description:
180 + "L'agrégateur des menus de restaurants : 19 chaînes intégrées — Sushi Shop, Valentine, Normandin, Ashton, Scores, Allô mon Coco et d'autres — lues via leurs systèmes de commande. Chaque plat, chaque option, chaque prix réel ; l'historique est conservé plat par plat, alors quand le trio monte d'un dollar, ça se voit.",
181 + chips: ["540+ restaurants", "61 000+ plats & prix", "14 régions"],
182 + features: [
183 + "Recherche par plat, groupée par chaîne — qui fait quoi, à quel prix",
184 + "Prix réels lus dans les systèmes de commande, jamais des PDF périmés",
185 + "Historique des prix par plat et alertes de dérive",
186 + "98 % des plats en photo, options et suppléments détaillés",
187 + ],
188 + isNew: true,
189 + },
190 + {
191 + num: "09",
192 + markLeft: "Sorti",
193 + markBoxed: "Ka",
194 + accent: "#ff6a00",
195 + inkbox: "#0b1330",
196 + field: "Sorties",
197 + domain: "www.sorti-ka.com",
198 + url: "https://www.sorti-ka.com",
199 + tagline: "Toutes les sorties du Québec. Un seul endroit.",
200 + description:
201 + "Agrégateur de sorties et d'événements — concerts, festivals, humour, théâtre, expositions, famille — bâti sur des billetteries au robots.txt permissif et des données ouvertes officielles (SIT Québec, Montréal, Laval). Chaque fiche est datée, géolocalisée et renvoie à la billetterie ou à la source originale.",
202 + chips: ["11 100+ événements", "3 000+ sorties gratuites", "17 régions"],
203 + features: [
204 + "Filtres par région, catégorie et moment : aujourd'hui, ce week-end, 30 jours",
205 + "La gratuité affichée — plus de 3 000 événements gratuits identifiés",
206 + "Données ouvertes officielles (CC 4.0) + billetteries, attribution systématique",
207 + "Mise à jour horaire — un événement annulé disparaît de lui-même",
208 + ],
209 + isNew: true,
210 + },
211 + {
212 + num: "10",
213 + markLeft: "Créa",
214 + markBoxed: "Ka",
215 + accent: "#7da2ff",
216 + inkbox: "#10162b",
217 + field: "Créateurs",
218 + domain: "www.crea-ka.com",
219 + url: "https://www.crea-ka.com",
220 + tagline: "Tous les créateurs québécois. Tous leurs liens.",
221 + description:
222 + "L'annuaire public des créateurs de contenu d'ici : YouTube, Instagram, TikTok, Twitch, balados et plus, regroupés créateur par créateur. La résolution d'identité relie les comptes d'une même personne — jamais par le nom seul, les homonymes existent — et l'annuaire se retire sur simple demande, mineurs exclus d'office.",
223 + chips: ["2 200+ créateurs", "2 700+ comptes reliés", "10 plateformes"],
224 + features: [
225 + "Recherche par niche, région, langue et taille d'audience (nano → méga)",
226 + "Tous les comptes d'un créateur regroupés sur une seule page",
227 + "Retrait immédiat et persistant sur demande — l'éthique avant l'index",
228 + "Données publiques seulement, mineurs exclus de l'annuaire",
229 + ],
230 + isNew: true,
231 + },
160 232 ];
161 233
162 234 type Bot = {
@@ -275,6 +347,24 @@ const SOCLE_ROWS: [string, string, string, string][] = [
275 347 "20 bannières — prix, soldes et prix unitaires",
276 348 "www.food-ka.com",
277 349 ],
350 + [
351 + "Resto·Ka",
352 + "Restaurants — menus & prix",
353 + "19 chaînes intégrées — 61 000+ plats suivis",
354 + "www.resto-ka.com",
355 + ],
356 + [
357 + "Sorti·Ka",
358 + "Sorties & événements",
359 + "Billetteries + données ouvertes — MàJ horaire",
360 + "www.sorti-ka.com",
361 + ],
362 + [
363 + "Créa·Ka",
364 + "Créateurs de contenu",
365 + "Annuaire multi-plateformes + résolution d'identité",
366 + "www.crea-ka.com",
367 + ],
278 368 ];
279 369
280 370 function Section({
@@ -325,7 +415,8 @@ function KaDefinition() {
325 415 <span className="gk-mono font-bold text-green">2.</span>
326 416 <span>
327 417 Marque de fabrique du groupe : Lou·Ka loge, Immo·Ka vend, Auto·Ka
328 − roule, Fabri·Ka fabrique, Food·Ka nourrit.
418 + roule, Fabri·Ka fabrique, Food·Ka nourrit, Resto·Ka régale,
419 + Sorti·Ka divertit, Créa·Ka rassemble.
329 420 </span>
330 421 </li>
331 422 </ol>
@@ -337,59 +428,103 @@ function KaDefinition() {
337 428 );
338 429 }
339 430
340 −function ProductCard({ p, index }: { p: Product; index: number }) {
431 +function ProductCard({
432 + p,
433 + index,
434 + wide = false,
435 +}: {
436 + p: Product;
437 + index: number;
438 + wide?: boolean;
439 +}) {
341 440 return (
342 441 <article
343 − className="gk-card gk-card-hover rise p-5 sm:p-7"
344 − style={{ animationDelay: `${0.1 + index * 0.12}s` }}
442 + className={`gk-card gk-card-hover rise relative overflow-hidden p-5 pt-6 sm:p-7 sm:pt-8 ${
443 + wide ? "sm:col-span-2 lg:col-span-3" : ""
444 + }`}
445 + style={{ animationDelay: `${0.1 + index * 0.1}s` }}
345 446 >
346 − <div className="flex flex-wrap items-baseline justify-between gap-3">
347 − <span className="gk-mono text-[12px] font-bold text-green">
348 − {p.num}
447 + {/* bande d'accent de la marque, en tête de carte */}
448 + <span
449 + aria-hidden="true"
450 + className="absolute inset-x-0 top-0 h-[6px]"
451 + style={{ background: p.accent }}
452 + />
453 + <div className="flex flex-wrap items-center justify-between gap-x-3 gap-y-2">
454 + <span className="flex flex-wrap items-center gap-2">
455 + <span
456 + className="gk-mono inline-block -rotate-2 rounded-[5px] px-[7px] py-[2px] text-[11px] font-bold"
457 + style={{ background: p.inkbox, color: p.accent }}
458 + >
459 + {p.num}
460 + </span>
461 + <span className="klabel">{p.field}</span>
462 + {p.isNew && (
463 + <span className="gk-mono inline-block rotate-1 rounded-[5px] border border-ink bg-lime px-[7px] py-[2px] text-[10px] font-bold tracking-[0.08em] uppercase">
464 + Nouveau
465 + </span>
466 + )}
349 467 </span>
350 468 <span className="klabel">{p.domain}</span>
351 469 </div>
352 − <h3 className="gk-display mt-4 inline-flex items-baseline gap-[5px] text-[32px] font-bold tracking-[-0.04em] sm:text-[38px]">
353 − {p.markLeft}
354 − <span
355 − className="inline-block -rotate-2 rounded-md px-[8px] pb-[3px]"
356 − style={{ background: p.inkbox, color: p.accent }}
357 − >
358 − {p.markBoxed}
359 − </span>
360 − </h3>
361 − <p className="gk-display mt-3 text-[17px] font-bold uppercase tracking-[-0.01em]">
362 − {p.tagline}
363 − </p>
364 − <p className="mt-3 text-[13.5px] leading-relaxed text-ink-2">
365 − {p.description}
366 − </p>
367 − <div className="mt-5 flex flex-wrap gap-2">
368 − {p.chips.map((chip) => (
369 − <span key={chip} className="stat-chip !text-[11px]">
370 − {chip}
371 − </span>
372 − ))}
373 − </div>
374 − <ul className="mt-5 space-y-2 border-t-[1.5px] border-dashed border-[rgba(20,24,20,0.25)] pt-5">
375 − {p.features.map((f) => (
376 − <li key={f} className="flex gap-3 text-[13.5px] text-ink-2">
377 − <span
378 − aria-hidden="true"
379 − className="mt-[7px] h-[5px] w-[5px] flex-none rotate-45 border border-ink bg-lime"
380 − />
381 − {f}
382 − </li>
383 − ))}
384 − </ul>
385 − <a
386 − href={p.url}
387 − target="_blank"
388 − rel="noopener noreferrer"
389 − className="btn btn-primary mt-6 w-full sm:w-auto"
470 + <div
471 + className={
472 + wide
473 + ? "lg:grid lg:grid-cols-[minmax(0,1.15fr)_minmax(0,1fr)] lg:gap-x-10"
474 + : ""
475 + }
390 476 >
391 − Visiter {p.domain} ↗
392 − </a>
477 + <div>
478 + <h3 className="gk-display mt-4 inline-flex items-baseline gap-[5px] text-[32px] font-bold tracking-[-0.04em] sm:text-[38px]">
479 + {p.markLeft}
480 + <span
481 + className="inline-block -rotate-2 rounded-md px-[8px] pb-[3px]"
482 + style={{ background: p.inkbox, color: p.accent }}
483 + >
484 + {p.markBoxed}
485 + </span>
486 + </h3>
487 + <p className="gk-display mt-3 text-[17px] font-bold uppercase tracking-[-0.01em]">
488 + {p.tagline}
489 + </p>
490 + <p className="mt-3 text-[13.5px] leading-relaxed text-ink-2">
491 + {p.description}
492 + </p>
493 + <div className="mt-5 flex flex-wrap gap-2">
494 + {p.chips.map((chip) => (
495 + <span key={chip} className="stat-chip !text-[11px]">
496 + {chip}
497 + </span>
498 + ))}
499 + </div>
500 + </div>
501 + <div>
502 + <ul
503 + className={`mt-5 space-y-2 border-t-[1.5px] border-dashed border-[rgba(20,24,20,0.25)] pt-5 ${
504 + wide ? "lg:mt-4 lg:border-t-0 lg:pt-0" : ""
505 + }`}
506 + >
507 + {p.features.map((f) => (
508 + <li key={f} className="flex gap-3 text-[13.5px] text-ink-2">
509 + <span
510 + aria-hidden="true"
511 + className="mt-[7px] h-[5px] w-[5px] flex-none rotate-45 border border-ink"
512 + style={{ background: p.accent }}
513 + />
514 + {f}
515 + </li>
516 + ))}
517 + </ul>
518 + <a
519 + href={p.url}
520 + target="_blank"
521 + rel="noopener noreferrer"
522 + className="btn btn-primary mt-6 w-full sm:w-auto"
523 + >
524 + Visiter {p.domain} ↗
525 + </a>
526 + </div>
527 + </div>
393 528 </article>
394 529 );
395 530 }
@@ -414,18 +549,19 @@ export default function Home() {
414 549 automatisés : des centaines de connecteurs lisent les sites à la
415 550 source, normalisent la donnée et se resynchronisent seuls, jour et
416 551 nuit. Se loger, acheter, évaluer, rouler, consommer local, faire
417 − l&apos;épicerie, chercher — sept agrégateurs et un moteur de
418 − recherche, zéro saisie manuelle, zéro boîte noire.
552 + l&apos;épicerie, manger au resto, sortir, suivre les créateurs
553 + d&apos;ici, chercher — dix agrégateurs et un moteur de recherche,
554 + zéro saisie manuelle, zéro boîte noire.
419 555 </p>
420 556 <div className="rise mt-7 flex gap-3 overflow-x-auto pb-2 [animation-delay:0.24s]">
421 557 <span className="stat-chip">
422 − <span className="pulse-dot" aria-hidden="true" />7 agrégateurs en
423 − ligne
558 + <span className="pulse-dot" aria-hidden="true" />
559 + 10 agrégateurs en ligne
424 560 </span>
425 561 <span className="stat-chip">1 moteur de recherche québécois</span>
426 562 <span className="stat-chip">450+ connecteurs sources</span>
427 563 <span className="stat-chip">22 M+ d&apos;observations immobilières</span>
428 − <span className="stat-chip">375 000+ annonces &amp; produits agrégés</span>
564 + <span className="stat-chip">450 000+ annonces, produits &amp; événements</span>
429 565 <span className="stat-chip">100 % données à la source</span>
430 566 </div>
431 567 <div className="rise mt-6 flex flex-wrap gap-3 [animation-delay:0.3s]">
@@ -433,7 +569,7 @@ export default function Home() {
433 569 Voir comment KA agrège ↓
434 570 </a>
435 571 <a href="#produits" className="btn btn-ghost">
436 − Les sept plateformes
572 + Les dix plateformes
437 573 </a>
438 574 </div>
439 575 </div>
@@ -612,7 +748,7 @@ export default function Home() {
612 748 1 000+ sites lus
613 749 <br />
614 750 <span className="text-lime">→ 450+ connecteurs</span>
615 − <br />→ 7 plateformes
751 + <br />→ 10 plateformes
616 752 </p>
617 753 <p className="mt-4 max-w-md text-[13.5px] text-[rgba(245,243,238,0.75)]">
618 754 La donnée entre éparpillée, elle ressort rangée. Entre les deux,
@@ -626,7 +762,7 @@ export default function Home() {
626 762 {/* ---------- Produits ---------- */}
627 763 <Section
628 764 id="produits"
629 − kicker="Sept agrégateurs · un écosystème"
765 + kicker="Dix agrégateurs · un écosystème"
630 766 title={
631 767 <>
632 768 Ce que nous <span className="hl">agrégeons</span>
@@ -636,12 +772,18 @@ export default function Home() {
636 772 <p className="mt-3 max-w-xl text-[14.5px] text-ink-2">
637 773 Chaque agrégateur attaque un angle mort du quotidien québécois : se
638 774 loger, acheter, évaluer, rouler, consommer local, faire
639 − l&apos;épicerie. Aucune saisie manuelle — les plateformes se
640 − maintiennent elles-mêmes, annonce par annonce, prix par prix.
775 + l&apos;épicerie, manger au resto, sortir, suivre les créateurs
776 + d&apos;ici. Aucune saisie manuelle — les plateformes se maintiennent
777 + elles-mêmes, annonce par annonce, prix par prix.
641 778 </p>
642 − <div className="mt-7 grid gap-5 lg:grid-cols-3">
779 + <div className="mt-7 grid gap-5 sm:grid-cols-2 lg:grid-cols-3">
643 780 {PRODUCTS.map((p, i) => (
644 − <ProductCard key={p.num} p={p} index={i} />
781 + <ProductCard
782 + key={p.num}
783 + p={p}
784 + index={i}
785 + wide={i === PRODUCTS.length - 1}
786 + />
645 787 ))}
646 788 </div>
647 789 </Section>
@@ -653,7 +795,7 @@ export default function Home() {
653 795 title="Le socle commun"
654 796 >
655 797 <p className="mt-3 max-w-xl text-[14.5px] text-ink-2">
656 − Les huit plateformes partagent la même colonne vertébrale : données
798 + Les onze plateformes partagent la même colonne vertébrale : données
657 799 publiques et annonces lues directement à la source, connecteurs
658 800 dédiés synchronisés en continu, moteurs statistiques validés, et une
659 801 identité visuelle unique — bordures encre, lime électrique, calcul à
660 802