# ka-ui — design system commun Groupe KA Identité « éditorial sharp » partagée par les 12 plateformes de l'écosystème (groupe-ka, trouve-ka, lou-ka, immo-ka, vrai-prix, auto-ka, fabri-ka, food-ka, resto-ka, sorti-ka, crea-ka, api-ka). Repo canonique : `spbgit` → `https://git.spboucher.ai/ka-ui` (bare : `M3U96a:~/srv/git/ka-ui.git`). ## Contenu | Fichier | Rôle | |---|---| | `tokens.css` | Tokens + socle de composants communs (typo, grille, boutons, cartes, chips, champs, badge Groupe KA, footer, tableaux responsive). Seules les variables `--accent*` changent d'un site à l'autre. | | `accents.css` | Palette de référence : le bloc `:root` de chaque marque. | | `ecosystem.json` | **Infos centralisées** : raison sociale, courriels de contact + rôles, avertissement d'agrégateur, pages légales du hub, liste des 12 sites (domaine, wordmark, accent, tagline), liens additionnels du footer. | | `react/KaFooter.tsx` | Footer commun (fond encre) consommant `ecosystem.json`. | | `react/GroupeKaBadge.tsx` | Badge « Un service Groupe KA » cliquable → hub (header). | | `sync.sh` | Redistribue les fichiers vendorés dans les 12 apps SUR LES NŒUDS. | ## Principes - **Design system identique partout** : papier `#f5f3ee`, encre `#141814`, Space Grotesk (titres) / Inter (texte) / JetBrains Mono (étiquettes), bordures encre + ombres décalées, rayons 10/6 px, grain de film. - **Un seul degré de liberté par site : l'accent** (`--accent`, `--accent-soft`, `--accent-deep`, `--on-accent`). Alias rétro-compat : `--lime → var(--accent)`. - **Breakpoints communs** : 360 / 768 / 1024 / 1440 px, mobile-first, zones tactiles ≥ 44 px, safe-areas iOS, `overflow-x: clip` sur body. - **Logo Groupe KA** : wordmark typographique « Groupe KA » (KA sur puce encre, teinté accent) — déclinaison claire (`.gk-badge`) et sombre (`.gk-badge--dark`, footer encre). Toujours cliquable vers https://www.groupe-ka.com. Zone de protection : ≥ 8 px autour du badge, jamais moins haut que 30 px. - **Titres SEO** : « {Marque} — Un service Groupe KA ». - **KA ID** : la connexion de chaque site passe par `/api/auth/ka/login` (redirection vers `groupe-ka.com/sso/authorize`) ; la **création de compte se fait sur le hub** (`groupe-ka.com/connexion`). Registre des clients autorisés : `groupe-ka/src/lib/sso.ts` (+ secrets `KA_SSO_SECRET_` dans le .env du hub). ## Modifier les infos de contact (courriels, mentions, sites) 1. Éditer `ecosystem.json` **dans ce repo** (une seule source de vérité). 2. Committer/pousser, puis exécuter `./sync.sh` depuis le laptop : il rsync `tokens.css` + `ecosystem.json` (+ composants) dans le dossier vendoré de chaque app sur son nœud (`frontend/src/ka/` pour les apps Vite, `src/ka/` pour les apps Next). 3. Rebuilder chaque app touchée (`npm run build` du frontend) et `pm2 restart ` — voir `~/Desktop/cluster-skill/KA-REMOTE-DEV.md`. ## Ajouter un futur site à l'écosystème 1. Ajouter son entrée dans `ecosystem.json` → `sites[]` (id, wordmark, domaine, accent choisi dans une teinte libre de la roue, tagline) et son bloc dans `accents.css`. 2. Dans la nouvelle app : importer `tokens.css`, coller son bloc `:root` d'accent, monter `KaFooter` + `GroupeKaBadge`, titre « {Marque} — Un service Groupe KA ». 3. KA ID : ajouter le client dans `groupe-ka/src/lib/sso.ts` + secret `KA_SSO_SECRET_` dans le .env du hub ET de l'app ; implémenter `/api/auth/ka/login|callback` (modèle : `creaka/auth.py` pour FastAPI, `vrai-prix/src/lib/ka-auth.ts` pour Next). 4. `./sync.sh` ajoutera le site aux footers des autres apps au prochain rebuild (la liste vient d'`ecosystem.json`). ## Règles mobiles OBLIGATOIRES (2026-08-19 — tout composant, présent et futur) Le socle correspondant vit dans `tokens.css` (section « SOCLE MOBILE OBLIGATOIRE »). 1. **Tap, jamais `:hover`** pour ouvrir un menu/sous-menu (le survol n'existe pas au doigt). Le `:hover` est réservé aux effets décoratifs, idéalement sous `@media (hover: hover)`. Sous-menus mobiles = accordéon ou navigation par niveaux, pas de cascade au survol. Fermeture toujours possible : tap extérieur + bouton fermer + Escape. 2. **`viewport-fit=cover` requis** dans la meta viewport de CHAQUE site, sinon `env(safe-area-inset-*)` vaut 0 sur iPhone et toutes les safe-areas sont inertes : `width=device-width, initial-scale=1, viewport-fit=cover`. 3. **Jamais `100vh`** pour un élément calé sur le viewport (la barre d'adresse mobile se replie au scroll et change la hauteur) : utiliser `var(--vh100)`, les classes `.h-viewport`/`.min-h-viewport`, ou le doublet `height:100vh; height:100dvh;` (repli navigateurs anciens). 4. **`position:fixed` fiable** : aucun ancêtre avec `transform`, `filter`, `backdrop-filter`, `perspective` ou `will-change` (ils re-parentent le fixed → barres qui « suivent » le scroll). En cas de doute, monter l'élément directement sous `` (portal). 5. **Barre basse fixe** = classe `.ka-bottombar` (safe-area incluse) + classe `has-bottombar` sur `` (+ `--bottombar-h` si ≠ 64px) pour réserver l'espace sous le contenu. 6. **Menu/panneau/modale ouvert** = `.ka-scroll-lock` sur `` (gel du scroll d'arrière-plan) ; liste longue = scroll interne (`.ka-menu` : max-height dvh + `overscroll-behavior: contain`). 7. **z-index** : uniquement l'échelle `--z-*` de tokens.css (content 1, sticky 300, header 500, bottombar 600, dropdown 700, overlay 800, modal 900, toast 950 ; grain de film 9999 non interactif). Aucune valeur arbitraire. 8. **Zones tactiles ≥ 44×44 px** (`--touch`) pour tout item interactif de menu. 9. **Champs ≥ 16 px** sur mobile (sinon zoom automatique iOS au focus) — filet de sécurité global dans tokens.css (`@media (hover:none) and (pointer:coarse)`), mais viser 16 px dans le style du composant lui-même. 10. **Un menu déroulant ne sort jamais de l'écran** : repositionnement (ouvrir vers le haut si pas de place) ou `.ka-menu` ancré avec `left/right` bornés ; sélecteur natif (`