SPB Git forge

spb/crea-ka

Public

Créa·Ka — annuaire public cross-plateforme des créateurs de contenu québécois (crea-ka.com)

52commits 1branches 0releases
11.3 MBsize
maindefault branch
19 days agolast push
Python 73.6% HTML 13.2% TypeScript 6% JavaScript 4.5% CSS 1.7% Dockerfile 0.6%

design: harmonisation « éditorial sharp » Groupe KA (ka-ui) — accent violet, footer commun, page /contact

- Vendorisation du package ka-ui dans frontend/src/ka/ (tokens.css, ecosystem.json,
  KaFooter.tsx, GroupeKaBadge.tsx) ; tokens.css injecté EN PREMIER dans le <head>
  via le nouveau marqueur __KA_TOKENS__, écosystème via __KA_ECO__
  (scripts/build_frontend.py gère désormais les 3 marqueurs)
- Accent attribué à Créa-Ka : VIOLET (--accent:#7048e8, --accent-soft:#ece5fc,
  --accent-deep:#5433b8, --on-accent:#ffffff) + alias --lime/--lime-soft ;
  socle dédupliqué (body, grain, sélection, boutons) ; couleurs codées en dur
  (#c9a3ff, #5b34a8, rgba violettes) pointées vers les variables du groupe ;
  textes posés sur accent passés à --on-accent, textes sur encre à --accent-soft
- Header : badge « Un service Groupe KA » cliquable vers le hub (desktop +
  mobile, préfixe replié sous 560 px) ; bouton « Se connecter avec KA » ;
  « Créer un compte KA ID » vers groupe-ka.com/connexion sur /compte
- Footer : remplacement par le footer commun KaFooter (fond encre, avertissement
  agrégateur, 3 courriels, 15 liens de l'écosystème, mentions légales du hub +
  /retrait local) ; nav locale conservée au-dessus
- Nouvelle route SPA /contact : courriels & rôles du groupe, avertissement,
  lien hub et liste des 12 plateformes (ecosystem.json)
- SEO : <title> « Créa-Ka — Un service Groupe KA »
- Responsive : cibles tactiles >=44 px (header, nav footer, cartes contact),
  aucun débordement horizontal (overflow-x:clip du socle), breakpoints
  360/768/1024/1440 du design system

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

7 changed files +1,219 −244

modified frontend/dist/index.html +637 −120
@@ -1,88 +1,519 @@
1 1 <!--
2 2 Author: Simon-Pierre Boucher <contact@spboucher.ai>
3 3 File: frontend/src/index.template.html
4 − Desc: Gabarit du frontend Créa-Ka — {"_author":"Simon-Pierre Boucher <contact@spboucher.ai>","_file":"frontend/src/icons.json","_desc":"Trac\u00e9s SVG des marques de plateformes (simple-icons v13, CC0) + glyphes maison (linkedin/site-web/autre)","instagram":"M7.0301.084c-1.2768.0602-2.1487.264-2.911.5634-.7888.3075-1.4575.72-2.1228 1.3877-.6652.6677-1.075 1.3368-1.3802 2.127-.2954.7638-.4956 1.6365-.552 2.914-.0564 1.2775-.0689 1.6882-.0626 4.947.0062 3.2586.0206 3.6671.0825 4.9473.061 1.2765.264 2.1482.5635 2.9107.308.7889.72 1.4573 1.388 2.1228.6679.6655 1.3365 1.0743 2.1285 1.38.7632.295 1.6361.4961 2.9134.552 1.2773.056 1.6884.069 4.9462.0627 3.2578-.0062 3.668-.0207 4.9478-.0814 1.28-.0607 2.147-.2652 2.9098-.5633.7889-.3086 1.4578-.72 2.1228-1.3881.665-.6682 1.0745-1.3378 1.3795-2.1284.2957-.7632.4966-1.636.552-2.9124.056-1.2809.0692-1.6898.063-4.948-.0063-3.2583-.021-3.6668-.0817-4.9465-.0607-1.2797-.264-2.1487-.5633-2.9117-.3084-.7889-.72-1.4568-1.3876-2.1228C21.2982 1.33 20.628.9208 19.8378.6165 19.074.321 18.2017.1197 16.9244.0645 15.6471.0093 15.236-.005 11.977.0014 8.718.0076 8.31.0215 7.0301.0839m.1402 21.6932c-1.17-.0509-1.8053-.2453-2.2287-.408-.5606-.216-.96-.4771-1.3819-.895-.422-.4178-.6811-.8186-.9-1.378-.1644-.4234-.3624-1.058-.4171-2.228-.0595-1.2645-.072-1.6442-.079-4.848-.007-3.2037.0053-3.583.0607-4.848.05-1.169.2456-1.805.408-2.2282.216-.5613.4762-.96.895-1.3816.4188-.4217.8184-.6814 1.3783-.9003.423-.1651 1.0575-.3614 2.227-.4171 1.2655-.06 1.6447-.072 4.848-.079 3.2033-.007 3.5835.005 4.8495.0608 1.169.0508 1.8053.2445 2.228.408.5608.216.96.4754 1.3816.895.4217.4194.6816.8176.9005 1.3787.1653.4217.3617 1.056.4169 2.2263.0602 1.2655.0739 1.645.0796 4.848.0058 3.203-.0055 3.5834-.061 4.848-.051 1.17-.245 1.8055-.408 2.2294-.216.5604-.4763.96-.8954 1.3814-.419.4215-.8181.6811-1.3783.9-.4224.1649-1.0577.3617-2.2262.4174-1.2656.0595-1.6448.072-4.8493.079-3.2045.007-3.5825-.006-4.848-.0608M16.953 5.5864A1.44 1.44 0 1 0 18.39 4.144a1.44 1.44 0 0 0-1.437 1.4424M5.8385 12.012c.0067 3.4032 2.7706 6.1557 6.173 6.1493 3.4026-.0065 6.157-2.7701 6.1506-6.1733-.0065-3.4032-2.771-6.1565-6.174-6.1498-3.403.0067-6.156 2.771-6.1496 6.1738M8 12.0077a4 4 0 1 1 4.008 3.9921A3.9996 3.9996 0 0 1 8 12.0077","tiktok":"M12.525.02c1.31-.02 2.61-.01 3.91-.02.08 1.53.63 3.09 1.75 4.17 1.12 1.11 2.7 1.62 4.24 1.79v4.03c-1.44-.05-2.89-.35-4.2-.97-.57-.26-1.1-.59-1.62-.93-.01 2.92.01 5.84-.02 8.75-.08 1.4-.54 2.79-1.35 3.94-1.31 1.92-3.58 3.17-5.91 3.21-1.43.08-2.86-.31-4.08-1.03-2.02-1.19-3.44-3.37-3.65-5.71-.02-.5-.03-1-.01-1.49.18-1.9 1.12-3.72 2.58-4.96 1.66-1.44 3.98-2.13 6.15-1.72.02 1.48-.04 2.96-.04 4.44-.99-.32-2.15-.23-3.02.37-.63.41-1.11 1.04-1.36 1.75-.21.51-.15 1.07-.14 1.61.24 1.64 1.82 3.02 3.5 2.87 1.12-.01 2.19-.66 2.77-1.61.19-.33.4-.67.41-1.06.1-1.79.06-3.57.07-5.36.01-4.03-.01-8.05.02-12.07z","youtube":"M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z","twitch":"M11.571 4.714h1.715v5.143H11.57zm4.715 0H18v5.143h-1.714zM6 0L1.714 4.286v15.428h5.143V24l4.286-4.286h3.428L22.286 12V0zm14.571 11.143l-3.428 3.428h-3.429l-3 3v-3H6.857V1.714h13.714Z","kick":"M1.333 0h8v5.333H12V2.667h2.667V0h8v8H20v2.667h-2.667v2.666H20V16h2.667v8h-8v-2.667H12v-2.666H9.333V24h-8Z","x":"M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z","facebook":"M9.101 23.691v-7.98H6.627v-3.667h2.474v-1.58c0-4.085 1.848-5.978 5.858-5.978.401 0 .955.042 1.468.103a8.68 8.68 0 0 1 1.141.195v3.325a8.623 8.623 0 0 0-.653-.036 26.805 26.805 0 0 0-.733-.009c-.707 0-1.259.096-1.675.309a1.686 1.686 0 0 0-.679.622c-.258.42-.374.995-.374 1.752v1.297h3.919l-.386 2.103-.287 1.564h-3.246v8.245C19.396 23.238 24 18.179 24 12.044c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.628 3.874 10.35 9.101 11.647Z","snapchat":"M12.206.793c.99 0 4.347.276 5.93 3.821.529 1.193.403 3.219.299 4.847l-.003.06c-.012.18-.022.345-.03.51.075.045.203.09.401.09.3-.016.659-.12 1.033-.301.165-.088.344-.104.464-.104.182 0 .359.029.509.09.45.149.734.479.734.838.015.449-.39.839-1.213 1.168-.089.029-.209.075-.344.119-.45.135-1.139.36-1.333.81-.09.224-.061.524.12.868l.015.015c.06.136 1.526 3.475 4.791 4.014.255.044.435.27.42.509 0 .075-.015.149-.045.225-.24.569-1.273.988-3.146 1.271-.059.091-.12.375-.164.57-.029.179-.074.36-.134.553-.076.271-.27.405-.555.405h-.03c-.135 0-.313-.031-.538-.074-.36-.075-.765-.135-1.273-.135-.3 0-.599.015-.913.074-.6.104-1.123.464-1.723.884-.853.599-1.826 1.288-3.294 1.288-.06 0-.119-.015-.18-.015h-.149c-1.468 0-2.427-.675-3.279-1.288-.599-.42-1.107-.779-1.707-.884-.314-.045-.629-.074-.928-.074-.54 0-.958.089-1.272.149-.211.043-.391.074-.54.074-.374 0-.523-.224-.583-.42-.061-.192-.09-.389-.135-.567-.046-.181-.105-.494-.166-.57-1.918-.222-2.95-.642-3.189-1.226-.031-.063-.052-.15-.055-.225-.015-.243.165-.465.42-.509 3.264-.54 4.73-3.879 4.791-4.02l.016-.029c.18-.345.224-.645.119-.869-.195-.434-.884-.658-1.332-.809-.121-.029-.24-.074-.346-.119-1.107-.435-1.257-.93-1.197-1.273.09-.479.674-.793 1.168-.793.146 0 .27.029.383.074.42.194.789.3 1.104.3.234 0 .384-.06.465-.105l-.046-.569c-.098-1.626-.225-3.651.307-4.837C7.392 1.077 10.739.807 11.727.807l.419-.015h.06z","substack":"M22.539 8.242H1.46V5.406h21.08v2.836zM1.46 10.812V24L12 18.11 22.54 24V10.812H1.46zM22.54 0H1.46v2.836h21.08V0z","patreon":"M22.957 7.21c-.004-3.064-2.391-5.576-5.191-6.482-3.478-1.125-8.064-.962-11.384.604C2.357 3.231 1.093 7.391 1.046 11.54c-.039 3.411.302 12.396 5.369 12.46 3.765.047 4.326-4.804 6.068-7.141 1.24-1.662 2.836-2.132 4.801-2.618 3.376-.836 5.678-3.501 5.673-7.031Z","onlyfans":"M24 4.003h-4.015c-3.45 0-5.3.197-6.748 1.957a7.996 7.996 0 1 0 2.103 9.211c3.182-.231 5.39-2.134 6.085-5.173 0 0-2.399.585-4.43 0 4.018-.777 6.333-3.037 7.005-5.995zM5.61 11.999A2.391 2.391 0 0 1 9.28 9.97a2.966 2.966 0 0 1 2.998-2.528h.008c-.92 1.778-1.407 3.352-1.998 5.263A2.392 2.392 0 0 1 5.61 12Zm2.386-7.996a7.996 7.996 0 1 0 7.996 7.996 7.996 7.996 0 0 0-7.996-7.996Zm0 10.394A2.399 2.399 0 1 1 10.395 12a2.396 2.396 0 0 1-2.399 2.398Z","threads":"M12.186 24h-.007c-3.581-.024-6.334-1.205-8.184-3.509C2.35 18.44 1.5 15.586 1.472 12.01v-.017c.03-3.579.879-6.43 2.525-8.482C5.845 1.205 8.6.024 12.18 0h.014c2.746.02 5.043.725 6.826 2.098 1.677 1.29 2.858 3.13 3.509 5.467l-2.04.569c-1.104-3.96-3.898-5.984-8.304-6.015-2.91.022-5.11.936-6.54 2.717C4.307 6.504 3.616 8.914 3.589 12c.027 3.086.718 5.496 2.057 7.164 1.43 1.783 3.631 2.698 6.54 2.717 2.623-.02 4.358-.631 5.8-2.045 1.647-1.613 1.618-3.593 1.09-4.798-.31-.71-.873-1.3-1.634-1.75-.192 1.352-.622 2.446-1.284 3.272-.886 1.102-2.14 1.704-3.73 1.79-1.202.065-2.361-.218-3.259-.801-1.063-.689-1.685-1.74-1.752-2.964-.065-1.19.408-2.285 1.33-3.082.88-.76 2.119-1.207 3.583-1.291a13.853 13.853 0 0 1 3.02.142c-.126-.742-.375-1.332-.75-1.757-.513-.586-1.308-.883-2.359-.89h-.029c-.844 0-1.992.232-2.721 1.32L7.734 7.847c.98-1.454 2.568-2.256 4.478-2.256h.044c3.194.02 5.097 1.975 5.287 5.388.108.046.216.094.321.142 1.49.7 2.58 1.761 3.154 3.07.797 1.82.871 4.79-1.548 7.158-1.85 1.81-4.094 2.628-7.277 2.65Zm1.003-11.69c-.242 0-.487.007-.739.021-1.836.103-2.98.946-2.916 2.143.067 1.256 1.452 1.839 2.784 1.767 1.224-.065 2.818-.543 3.086-3.71a10.5 10.5 0 0 0-2.215-.221z","podcast":"M5.34 0A5.328 5.328 0 000 5.34v13.32A5.328 5.328 0 005.34 24h13.32A5.328 5.328 0 0024 18.66V5.34A5.328 5.328 0 0018.66 0zm6.525 2.568c2.336 0 4.448.902 6.056 2.587 1.224 1.272 1.912 2.619 2.264 4.392.12.59.12 2.2.007 2.864a8.506 8.506 0 01-3.24 5.296c-.608.46-2.096 1.261-2.336 1.261-.088 0-.096-.091-.056-.46.072-.592.144-.715.48-.856.536-.224 1.448-.874 2.008-1.435a7.644 7.644 0 002.008-3.536c.208-.824.184-2.656-.048-3.504-.728-2.696-2.928-4.792-5.624-5.352-.784-.16-2.208-.16-3 0-2.728.56-4.984 2.76-5.672 5.528-.184.752-.184 2.584 0 3.336.456 1.832 1.64 3.512 3.192 4.512.304.2.672.408.824.472.336.144.408.264.472.856.04.36.03.464-.056.464-.056 0-.464-.176-.896-.384l-.04-.03c-2.472-1.216-4.056-3.274-4.632-6.012-.144-.706-.168-2.392-.03-3.04.36-1.74 1.048-3.1 2.192-4.304 1.648-1.737 3.768-2.656 6.128-2.656zm.134 2.81c.409.004.803.04 1.106.106 2.784.62 4.76 3.408 4.376 6.174-.152 1.114-.536 2.03-1.216 2.88-.336.43-1.152 1.15-1.296 1.15-.023 0-.048-.272-.048-.603v-.605l.416-.496c1.568-1.878 1.456-4.502-.256-6.224-.664-.67-1.432-1.064-2.424-1.246-.64-.118-.776-.118-1.448-.008-1.02.167-1.81.562-2.512 1.256-1.72 1.704-1.832 4.342-.264 6.222l.413.496v.608c0 .336-.027.608-.06.608-.03 0-.264-.16-.512-.36l-.034-.011c-.832-.664-1.568-1.842-1.872-2.997-.184-.698-.184-2.024.008-2.72.504-1.878 1.888-3.335 3.808-4.019.41-.145 1.133-.22 1.814-.211zm-.13 2.99c.31 0 .62.06.844.178.488.253.888.745 1.04 1.259.464 1.578-1.208 2.96-2.72 2.254h-.015c-.712-.331-1.096-.956-1.104-1.77 0-.733.408-1.371 1.112-1.745.224-.117.534-.176.844-.176zm-.011 4.728c.988-.004 1.706.349 1.97.97.198.464.124 1.932-.218 4.302-.232 1.656-.36 2.074-.68 2.356-.44.39-1.064.498-1.656.288h-.003c-.716-.257-.87-.605-1.164-2.644-.341-2.37-.416-3.838-.218-4.302.262-.616.974-.966 1.97-.97z","linktree":"m13.73635 5.85251 4.00467-4.11665 2.3248 2.3808-4.20064 4.00466h5.9085v3.30473h-5.9365l4.22865 4.10766-2.3248 2.3338L12.0005 12.099l-5.74052 5.76852-2.3248-2.3248 4.22864-4.10766h-5.9375V8.12132h5.9085L3.93417 4.11666l2.3248-2.3808 4.00468 4.11665V0h3.4727zm-3.4727 10.30614h3.4727V24h-3.4727z","linkedin":"M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.225 0z","site-web":"M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12 12-5.373 12-12S18.627 0 12 0zm7.938 9h-3.243a15.6 15.6 0 00-1.4-4.653A8.03 8.03 0 0119.938 9zM12 2.05c.9 1.2 1.9 3.2 2.5 6.95h-5C10.1 5.25 11.1 3.25 12 2.05zM4.062 15A8.06 8.06 0 013.75 12c0-1.05.15-2.05.312-3h3.55A25 25 0 007.5 12c0 1.05.05 2.05.113 3zm.643 2h3.243c.35 1.8.85 3.35 1.4 4.653A8.03 8.03 0 014.705 17zm3.243-10H4.705a8.03 8.03 0 014.643-4.653A15.6 15.6 0 007.948 7zM12 21.95c-.9-1.2-1.9-3.2-2.5-6.95h5c-.6 3.75-1.6 5.75-2.5 6.95zM14.787 13H9.213A23 23 0 019.1 12c0-1.05.037-2.05.113-3h5.574c.076.95.113 1.95.113 3s-.037 2.05-.113 3zm.508 8.653c.55-1.303 1.05-2.853 1.4-4.653h3.243a8.03 8.03 0 01-4.643 4.653zM16.388 15c.062-.95.112-1.95.112-3s-.05-2.05-.112-3h3.55c.162.95.312 1.95.312 3s-.15 2.05-.312 3z","autre":"M10.59 13.41a1 1 0 010-1.41l2.83-2.83a3 3 0 114.24 4.24l-1.41 1.42a1 1 0 11-1.42-1.42l1.42-1.41a1 1 0 10-1.42-1.42L12 13.41a1 1 0 01-1.41 0zm2.82-2.82a1 1 0 010 1.41l-2.82 2.83a3 3 0 11-4.25-4.24l1.42-1.42a1 1 0 111.41 1.42L7.76 12a1 1 0 101.41 1.41L12 10.59a1 1 0 011.41 0z"} est remplacé par les tracés
5 − SVG des marques (simple-icons, CC0) via scripts/build_frontend.py.
6 − Système de design « éditorial sharp » du Groupe KA (identité partagée
7 − avec groupe-ka.com, Vrai-Prix, ValoPlex : papier grainé #f5f3ee, encre
8 − #141814, bordures encre + ombres décalées dures, Space Grotesk / Inter
9 − / JetBrains Mono) — accent propre Créa-Ka : VIOLET ÉLECTRIQUE.
10 − Patrons mobiles calqués sur Lou-Ka (tab bar 4 onglets, filtres
11 − défilants, anti-zoom iOS). Routes : / · /createur/{id} · /stats · /retrait
4 + Desc: Gabarit du frontend Créa-Ka — marqueurs remplacés par
5 + scripts/build_frontend.py : {"_author":"Simon-Pierre Boucher <contact@spboucher.ai>","_file":"frontend/src/icons.json","_desc":"Trac\u00e9s SVG des marques de plateformes (simple-icons v13, CC0) + glyphes maison (linkedin/site-web/autre)","instagram":"M7.0301.084c-1.2768.0602-2.1487.264-2.911.5634-.7888.3075-1.4575.72-2.1228 1.3877-.6652.6677-1.075 1.3368-1.3802 2.127-.2954.7638-.4956 1.6365-.552 2.914-.0564 1.2775-.0689 1.6882-.0626 4.947.0062 3.2586.0206 3.6671.0825 4.9473.061 1.2765.264 2.1482.5635 2.9107.308.7889.72 1.4573 1.388 2.1228.6679.6655 1.3365 1.0743 2.1285 1.38.7632.295 1.6361.4961 2.9134.552 1.2773.056 1.6884.069 4.9462.0627 3.2578-.0062 3.668-.0207 4.9478-.0814 1.28-.0607 2.147-.2652 2.9098-.5633.7889-.3086 1.4578-.72 2.1228-1.3881.665-.6682 1.0745-1.3378 1.3795-2.1284.2957-.7632.4966-1.636.552-2.9124.056-1.2809.0692-1.6898.063-4.948-.0063-3.2583-.021-3.6668-.0817-4.9465-.0607-1.2797-.264-2.1487-.5633-2.9117-.3084-.7889-.72-1.4568-1.3876-2.1228C21.2982 1.33 20.628.9208 19.8378.6165 19.074.321 18.2017.1197 16.9244.0645 15.6471.0093 15.236-.005 11.977.0014 8.718.0076 8.31.0215 7.0301.0839m.1402 21.6932c-1.17-.0509-1.8053-.2453-2.2287-.408-.5606-.216-.96-.4771-1.3819-.895-.422-.4178-.6811-.8186-.9-1.378-.1644-.4234-.3624-1.058-.4171-2.228-.0595-1.2645-.072-1.6442-.079-4.848-.007-3.2037.0053-3.583.0607-4.848.05-1.169.2456-1.805.408-2.2282.216-.5613.4762-.96.895-1.3816.4188-.4217.8184-.6814 1.3783-.9003.423-.1651 1.0575-.3614 2.227-.4171 1.2655-.06 1.6447-.072 4.848-.079 3.2033-.007 3.5835.005 4.8495.0608 1.169.0508 1.8053.2445 2.228.408.5608.216.96.4754 1.3816.895.4217.4194.6816.8176.9005 1.3787.1653.4217.3617 1.056.4169 2.2263.0602 1.2655.0739 1.645.0796 4.848.0058 3.203-.0055 3.5834-.061 4.848-.051 1.17-.245 1.8055-.408 2.2294-.216.5604-.4763.96-.8954 1.3814-.419.4215-.8181.6811-1.3783.9-.4224.1649-1.0577.3617-2.2262.4174-1.2656.0595-1.6448.072-4.8493.079-3.2045.007-3.5825-.006-4.848-.0608M16.953 5.5864A1.44 1.44 0 1 0 18.39 4.144a1.44 1.44 0 0 0-1.437 1.4424M5.8385 12.012c.0067 3.4032 2.7706 6.1557 6.173 6.1493 3.4026-.0065 6.157-2.7701 6.1506-6.1733-.0065-3.4032-2.771-6.1565-6.174-6.1498-3.403.0067-6.156 2.771-6.1496 6.1738M8 12.0077a4 4 0 1 1 4.008 3.9921A3.9996 3.9996 0 0 1 8 12.0077","tiktok":"M12.525.02c1.31-.02 2.61-.01 3.91-.02.08 1.53.63 3.09 1.75 4.17 1.12 1.11 2.7 1.62 4.24 1.79v4.03c-1.44-.05-2.89-.35-4.2-.97-.57-.26-1.1-.59-1.62-.93-.01 2.92.01 5.84-.02 8.75-.08 1.4-.54 2.79-1.35 3.94-1.31 1.92-3.58 3.17-5.91 3.21-1.43.08-2.86-.31-4.08-1.03-2.02-1.19-3.44-3.37-3.65-5.71-.02-.5-.03-1-.01-1.49.18-1.9 1.12-3.72 2.58-4.96 1.66-1.44 3.98-2.13 6.15-1.72.02 1.48-.04 2.96-.04 4.44-.99-.32-2.15-.23-3.02.37-.63.41-1.11 1.04-1.36 1.75-.21.51-.15 1.07-.14 1.61.24 1.64 1.82 3.02 3.5 2.87 1.12-.01 2.19-.66 2.77-1.61.19-.33.4-.67.41-1.06.1-1.79.06-3.57.07-5.36.01-4.03-.01-8.05.02-12.07z","youtube":"M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z","twitch":"M11.571 4.714h1.715v5.143H11.57zm4.715 0H18v5.143h-1.714zM6 0L1.714 4.286v15.428h5.143V24l4.286-4.286h3.428L22.286 12V0zm14.571 11.143l-3.428 3.428h-3.429l-3 3v-3H6.857V1.714h13.714Z","kick":"M1.333 0h8v5.333H12V2.667h2.667V0h8v8H20v2.667h-2.667v2.666H20V16h2.667v8h-8v-2.667H12v-2.666H9.333V24h-8Z","x":"M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z","facebook":"M9.101 23.691v-7.98H6.627v-3.667h2.474v-1.58c0-4.085 1.848-5.978 5.858-5.978.401 0 .955.042 1.468.103a8.68 8.68 0 0 1 1.141.195v3.325a8.623 8.623 0 0 0-.653-.036 26.805 26.805 0 0 0-.733-.009c-.707 0-1.259.096-1.675.309a1.686 1.686 0 0 0-.679.622c-.258.42-.374.995-.374 1.752v1.297h3.919l-.386 2.103-.287 1.564h-3.246v8.245C19.396 23.238 24 18.179 24 12.044c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.628 3.874 10.35 9.101 11.647Z","snapchat":"M12.206.793c.99 0 4.347.276 5.93 3.821.529 1.193.403 3.219.299 4.847l-.003.06c-.012.18-.022.345-.03.51.075.045.203.09.401.09.3-.016.659-.12 1.033-.301.165-.088.344-.104.464-.104.182 0 .359.029.509.09.45.149.734.479.734.838.015.449-.39.839-1.213 1.168-.089.029-.209.075-.344.119-.45.135-1.139.36-1.333.81-.09.224-.061.524.12.868l.015.015c.06.136 1.526 3.475 4.791 4.014.255.044.435.27.42.509 0 .075-.015.149-.045.225-.24.569-1.273.988-3.146 1.271-.059.091-.12.375-.164.57-.029.179-.074.36-.134.553-.076.271-.27.405-.555.405h-.03c-.135 0-.313-.031-.538-.074-.36-.075-.765-.135-1.273-.135-.3 0-.599.015-.913.074-.6.104-1.123.464-1.723.884-.853.599-1.826 1.288-3.294 1.288-.06 0-.119-.015-.18-.015h-.149c-1.468 0-2.427-.675-3.279-1.288-.599-.42-1.107-.779-1.707-.884-.314-.045-.629-.074-.928-.074-.54 0-.958.089-1.272.149-.211.043-.391.074-.54.074-.374 0-.523-.224-.583-.42-.061-.192-.09-.389-.135-.567-.046-.181-.105-.494-.166-.57-1.918-.222-2.95-.642-3.189-1.226-.031-.063-.052-.15-.055-.225-.015-.243.165-.465.42-.509 3.264-.54 4.73-3.879 4.791-4.02l.016-.029c.18-.345.224-.645.119-.869-.195-.434-.884-.658-1.332-.809-.121-.029-.24-.074-.346-.119-1.107-.435-1.257-.93-1.197-1.273.09-.479.674-.793 1.168-.793.146 0 .27.029.383.074.42.194.789.3 1.104.3.234 0 .384-.06.465-.105l-.046-.569c-.098-1.626-.225-3.651.307-4.837C7.392 1.077 10.739.807 11.727.807l.419-.015h.06z","substack":"M22.539 8.242H1.46V5.406h21.08v2.836zM1.46 10.812V24L12 18.11 22.54 24V10.812H1.46zM22.54 0H1.46v2.836h21.08V0z","patreon":"M22.957 7.21c-.004-3.064-2.391-5.576-5.191-6.482-3.478-1.125-8.064-.962-11.384.604C2.357 3.231 1.093 7.391 1.046 11.54c-.039 3.411.302 12.396 5.369 12.46 3.765.047 4.326-4.804 6.068-7.141 1.24-1.662 2.836-2.132 4.801-2.618 3.376-.836 5.678-3.501 5.673-7.031Z","onlyfans":"M24 4.003h-4.015c-3.45 0-5.3.197-6.748 1.957a7.996 7.996 0 1 0 2.103 9.211c3.182-.231 5.39-2.134 6.085-5.173 0 0-2.399.585-4.43 0 4.018-.777 6.333-3.037 7.005-5.995zM5.61 11.999A2.391 2.391 0 0 1 9.28 9.97a2.966 2.966 0 0 1 2.998-2.528h.008c-.92 1.778-1.407 3.352-1.998 5.263A2.392 2.392 0 0 1 5.61 12Zm2.386-7.996a7.996 7.996 0 1 0 7.996 7.996 7.996 7.996 0 0 0-7.996-7.996Zm0 10.394A2.399 2.399 0 1 1 10.395 12a2.396 2.396 0 0 1-2.399 2.398Z","threads":"M12.186 24h-.007c-3.581-.024-6.334-1.205-8.184-3.509C2.35 18.44 1.5 15.586 1.472 12.01v-.017c.03-3.579.879-6.43 2.525-8.482C5.845 1.205 8.6.024 12.18 0h.014c2.746.02 5.043.725 6.826 2.098 1.677 1.29 2.858 3.13 3.509 5.467l-2.04.569c-1.104-3.96-3.898-5.984-8.304-6.015-2.91.022-5.11.936-6.54 2.717C4.307 6.504 3.616 8.914 3.589 12c.027 3.086.718 5.496 2.057 7.164 1.43 1.783 3.631 2.698 6.54 2.717 2.623-.02 4.358-.631 5.8-2.045 1.647-1.613 1.618-3.593 1.09-4.798-.31-.71-.873-1.3-1.634-1.75-.192 1.352-.622 2.446-1.284 3.272-.886 1.102-2.14 1.704-3.73 1.79-1.202.065-2.361-.218-3.259-.801-1.063-.689-1.685-1.74-1.752-2.964-.065-1.19.408-2.285 1.33-3.082.88-.76 2.119-1.207 3.583-1.291a13.853 13.853 0 0 1 3.02.142c-.126-.742-.375-1.332-.75-1.757-.513-.586-1.308-.883-2.359-.89h-.029c-.844 0-1.992.232-2.721 1.32L7.734 7.847c.98-1.454 2.568-2.256 4.478-2.256h.044c3.194.02 5.097 1.975 5.287 5.388.108.046.216.094.321.142 1.49.7 2.58 1.761 3.154 3.07.797 1.82.871 4.79-1.548 7.158-1.85 1.81-4.094 2.628-7.277 2.65Zm1.003-11.69c-.242 0-.487.007-.739.021-1.836.103-2.98.946-2.916 2.143.067 1.256 1.452 1.839 2.784 1.767 1.224-.065 2.818-.543 3.086-3.71a10.5 10.5 0 0 0-2.215-.221z","podcast":"M5.34 0A5.328 5.328 0 000 5.34v13.32A5.328 5.328 0 005.34 24h13.32A5.328 5.328 0 0024 18.66V5.34A5.328 5.328 0 0018.66 0zm6.525 2.568c2.336 0 4.448.902 6.056 2.587 1.224 1.272 1.912 2.619 2.264 4.392.12.59.12 2.2.007 2.864a8.506 8.506 0 01-3.24 5.296c-.608.46-2.096 1.261-2.336 1.261-.088 0-.096-.091-.056-.46.072-.592.144-.715.48-.856.536-.224 1.448-.874 2.008-1.435a7.644 7.644 0 002.008-3.536c.208-.824.184-2.656-.048-3.504-.728-2.696-2.928-4.792-5.624-5.352-.784-.16-2.208-.16-3 0-2.728.56-4.984 2.76-5.672 5.528-.184.752-.184 2.584 0 3.336.456 1.832 1.64 3.512 3.192 4.512.304.2.672.408.824.472.336.144.408.264.472.856.04.36.03.464-.056.464-.056 0-.464-.176-.896-.384l-.04-.03c-2.472-1.216-4.056-3.274-4.632-6.012-.144-.706-.168-2.392-.03-3.04.36-1.74 1.048-3.1 2.192-4.304 1.648-1.737 3.768-2.656 6.128-2.656zm.134 2.81c.409.004.803.04 1.106.106 2.784.62 4.76 3.408 4.376 6.174-.152 1.114-.536 2.03-1.216 2.88-.336.43-1.152 1.15-1.296 1.15-.023 0-.048-.272-.048-.603v-.605l.416-.496c1.568-1.878 1.456-4.502-.256-6.224-.664-.67-1.432-1.064-2.424-1.246-.64-.118-.776-.118-1.448-.008-1.02.167-1.81.562-2.512 1.256-1.72 1.704-1.832 4.342-.264 6.222l.413.496v.608c0 .336-.027.608-.06.608-.03 0-.264-.16-.512-.36l-.034-.011c-.832-.664-1.568-1.842-1.872-2.997-.184-.698-.184-2.024.008-2.72.504-1.878 1.888-3.335 3.808-4.019.41-.145 1.133-.22 1.814-.211zm-.13 2.99c.31 0 .62.06.844.178.488.253.888.745 1.04 1.259.464 1.578-1.208 2.96-2.72 2.254h-.015c-.712-.331-1.096-.956-1.104-1.77 0-.733.408-1.371 1.112-1.745.224-.117.534-.176.844-.176zm-.011 4.728c.988-.004 1.706.349 1.97.97.198.464.124 1.932-.218 4.302-.232 1.656-.36 2.074-.68 2.356-.44.39-1.064.498-1.656.288h-.003c-.716-.257-.87-.605-1.164-2.644-.341-2.37-.416-3.838-.218-4.302.262-.616.974-.966 1.97-.97z","linktree":"m13.73635 5.85251 4.00467-4.11665 2.3248 2.3808-4.20064 4.00466h5.9085v3.30473h-5.9365l4.22865 4.10766-2.3248 2.3338L12.0005 12.099l-5.74052 5.76852-2.3248-2.3248 4.22864-4.10766h-5.9375V8.12132h5.9085L3.93417 4.11666l2.3248-2.3808 4.00468 4.11665V0h3.4727zm-3.4727 10.30614h3.4727V24h-3.4727z","linkedin":"M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.225 0z","site-web":"M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12 12-5.373 12-12S18.627 0 12 0zm7.938 9h-3.243a15.6 15.6 0 00-1.4-4.653A8.03 8.03 0 0119.938 9zM12 2.05c.9 1.2 1.9 3.2 2.5 6.95h-5C10.1 5.25 11.1 3.25 12 2.05zM4.062 15A8.06 8.06 0 013.75 12c0-1.05.15-2.05.312-3h3.55A25 25 0 007.5 12c0 1.05.05 2.05.113 3zm.643 2h3.243c.35 1.8.85 3.35 1.4 4.653A8.03 8.03 0 014.705 17zm3.243-10H4.705a8.03 8.03 0 014.643-4.653A15.6 15.6 0 007.948 7zM12 21.95c-.9-1.2-1.9-3.2-2.5-6.95h5c-.6 3.75-1.6 5.75-2.5 6.95zM14.787 13H9.213A23 23 0 019.1 12c0-1.05.037-2.05.113-3h5.574c.076.95.113 1.95.113 3s-.037 2.05-.113 3zm.508 8.653c.55-1.303 1.05-2.853 1.4-4.653h3.243a8.03 8.03 0 01-4.643 4.653zM16.388 15c.062-.95.112-1.95.112-3s-.05-2.05-.112-3h3.55c.162.95.312 1.95.312 3s-.15 2.05-.312 3z","autre":"M10.59 13.41a1 1 0 010-1.41l2.83-2.83a3 3 0 114.24 4.24l-1.41 1.42a1 1 0 11-1.42-1.42l1.42-1.41a1 1 0 10-1.42-1.42L12 13.41a1 1 0 01-1.41 0zm2.82-2.82a1 1 0 010 1.41l-2.82 2.83a3 3 0 11-4.25-4.24l1.42-1.42a1 1 0 111.41 1.42L7.76 12a1 1 0 101.41 1.41L12 10.59a1 1 0 011.41 0z"} (tracés SVG simple-icons, CC0),
6 + /* -----------------------------------------------------------------------------
7 + Auteur : Simon-Pierre Boucher — contact@spboucher.ai
8 + Fichier : ka-ui/tokens.css — SOURCE CANONIQUE (repo ka-ui sur spbgit)
9 + Desc. : Design system commun GROUPE KA « éditorial sharp » — tokens + socle
10 + de composants partagés par les 12 plateformes. Chaque site importe ce
11 + fichier PUIS surcharge uniquement son accent (voir accents.css).
12 +
13 + · Typo : display Space Grotesk / texte Inter / micro-étiquettes JetBrains Mono
14 + · Palette: papier #f5f3ee · encre #141814 · vert profond #1c5c41 + ACCENT du site
15 + · Signature : bordures encre 1,5–2 px + ombres décalées dures, grain de film,
16 + surlignés d'accent inclinés (néo-brutalisme raffiné)
17 + · Breakpoints communs : 360 / 768 / 1024 / 1440 px (mobile-first)
18 + · Zones tactiles ≥ 44×44 px, safe-areas iOS, typographie fluide (clamp)
19 +----------------------------------------------------------------------------- */
20 +
21 +:root {
22 + /* ---- Palette fixe Groupe KA (identique sur les 12 sites) ---- */
23 + --paper: #f5f3ee;
24 + --surface: #ffffff;
25 + --surface-2: #faf9f5;
26 + --ink: #141814;
27 + --ink-2: #4d5551;
28 + --ink-3: #8b928c;
29 + --line: rgba(20, 24, 20, 0.14);
30 + --line-strong: rgba(20, 24, 20, 0.85);
31 + --green: #1c5c41;
32 + --green-deep: #123f2e;
33 + --amber: #e8a33d;
34 + --amber-soft: #fdf3e2;
35 + --danger: #b3423a;
36 + --danger-soft: #fbe9e7;
37 +
38 + /* ---- ACCENT du site — SEULES variables surchargées par marque ---- */
39 + --accent: #d9f26b; /* défaut : lime Groupe KA */
40 + --accent-soft: #f0f9d2;
41 + --accent-deep: #123f2e;
42 + --on-accent: var(--ink); /* couleur du texte posé SUR l'accent */
43 +
44 + /* alias rétro-compatibles (les satellites historiques utilisent --lime) */
45 + --lime: var(--accent);
46 + --lime-soft: var(--accent-soft);
47 +
48 + /* ---- Géométrie sharp ---- */
49 + --r-card: 10px;
50 + --r-ctl: 6px;
51 + --r-pill: 999px;
52 +
53 + /* ---- Ombres décalées — la signature du groupe ---- */
54 + --shadow-flat: 0 1px 2px rgba(20, 24, 20, 0.05);
55 + --shadow-off: 6px 6px 0 var(--ink);
56 + --shadow-off-soft: 8px 8px 0 rgba(20, 24, 20, 0.08);
57 + --shadow-off-mid: 4px 4px 0 rgba(20, 24, 20, 0.18);
58 +
59 + /* ---- Typographie ---- */
60 + --font-display: "Space Grotesk", system-ui, sans-serif;
61 + --font-body: "Inter", system-ui, sans-serif;
62 + --font-mono: "JetBrains Mono", ui-monospace, monospace;
63 +
64 + /* Échelle fluide (mobile-first, clamp) */
65 + --fs-h1: clamp(30px, 3.2vw + 18px, 54px);
66 + --fs-h2: clamp(23px, 1.8vw + 14px, 34px);
67 + --fs-h3: clamp(17px, 0.9vw + 12px, 22px);
68 + --fs-body: 15px;
69 + --fs-small: 13px;
70 +
71 + /* Espacements */
72 + --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px;
73 + --sp-5: 24px; --sp-6: 32px; --sp-7: 48px; --sp-8: 64px;
74 +
75 + /* Cible tactile minimale */
76 + --touch: 44px;
77 +}
78 +
79 +/* ---- Socle ---- */
80 +* { box-sizing: border-box; }
81 +html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
82 +body {
83 + margin: 0;
84 + background: var(--paper);
85 + color: var(--ink);
86 + font-family: var(--font-body);
87 + font-size: var(--fs-body);
88 + line-height: 1.55;
89 + -webkit-font-smoothing: antialiased;
90 + padding-bottom: env(safe-area-inset-bottom);
91 + overflow-x: clip; /* jamais de débordement horizontal */
92 +}
93 +img, svg, video { max-width: 100%; height: auto; display: block; }
94 +h1, h2, h3, h4 { font-family: var(--font-display); letter-spacing: -0.03em; margin: 0 0 0.5em; }
95 +h1 { font-size: var(--fs-h1); line-height: 1.06; }
96 +h2 { font-size: var(--fs-h2); line-height: 1.15; }
97 +h3 { font-size: var(--fs-h3); line-height: 1.25; }
98 +a { color: inherit; }
99 +::selection { background: var(--accent); color: var(--on-accent); }
100 +:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; }
101 +
102 +/* Grain de film pleine page — ⚠️ jamais de z-index sur body > * (position:
103 + relative seulement), sinon les utilitaires z-* sont écrasés. */
104 +body::before {
105 + content: "";
106 + position: fixed; inset: 0; pointer-events: none; opacity: 0.35; z-index: 9999;
107 + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='linear' slope='0.06'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)'/%3E%3C/svg%3E");
108 +}
109 +body > * { position: relative; }
110 +
111 +/* ---- Conteneur commun ---- */
112 +.container { max-width: 1152px; margin: 0 auto; padding: 0 var(--sp-4); }
113 +@media (min-width: 768px) { .container { padding: 0 var(--sp-5); } }
114 +
115 +/* ---- Micro-typographie signature ---- */
116 +.kicker {
117 + display: inline-flex; align-items: center; gap: 10px;
118 + font-family: var(--font-mono); font-size: 11.5px; font-weight: 500;
119 + text-transform: uppercase; letter-spacing: 0.12em; color: var(--green);
120 +}
121 +.kicker::before { content: ""; width: 22px; height: 2px; background: var(--green); }
122 +.klabel {
123 + font-family: var(--font-mono); font-size: 10px; font-weight: 700;
124 + text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-3);
125 +}
126 +.hl {
127 + display: inline-block; background: var(--accent); color: var(--on-accent);
128 + border-radius: 8px; padding: 0 10px 2px; transform: rotate(-1deg);
129 +}
130 +.outline-txt { color: transparent; -webkit-text-stroke: 2px var(--ink); }
131 +
132 +/* ---- Boutons (cible ≥ 44 px) ---- */
133 +.btn {
134 + display: inline-flex; align-items: center; justify-content: center; gap: 8px;
135 + min-height: var(--touch); padding: 10px 18px;
136 + font-family: var(--font-display); font-weight: 700; font-size: 14px;
137 + border: 1.5px solid var(--ink); border-radius: var(--r-ctl);
138 + background: var(--surface); color: var(--ink);
139 + cursor: pointer; text-decoration: none;
140 + transition: transform 0.15s, box-shadow 0.15s, background 0.15s, color 0.15s;
141 +}
142 +.btn:hover { transform: translate(-2px, -2px); box-shadow: var(--shadow-off-mid); }
143 +.btn:active { transform: translate(0, 0); box-shadow: none; }
144 +.btn:disabled { opacity: 0.45; pointer-events: none; }
145 +.btn-primary { background: var(--ink); color: var(--accent); }
146 +.btn-primary:hover { background: var(--accent-deep); }
147 +.btn-accent { background: var(--accent); color: var(--on-accent); }
148 +.btn-ghost { background: transparent; border-color: var(--line); }
149 +.btn-ghost:hover { border-color: var(--ink); }
150 +
151 +/* ---- Cartes ---- */
152 +.card {
153 + background: var(--surface); border: 1.5px solid var(--ink);
154 + border-radius: var(--r-card); box-shadow: var(--shadow-off-soft);
155 + overflow: hidden;
156 +}
157 +.card-hover { transition: transform 0.15s, box-shadow 0.15s; }
158 +.card-hover:hover { transform: translate(-2px, -2px); box-shadow: var(--shadow-off); }
159 +
160 +/* ---- Chips / badges ---- */
161 +.chip {
162 + display: inline-flex; align-items: center; gap: 6px;
163 + padding: 4px 11px; font-family: var(--font-mono); font-size: 11px; font-weight: 700;
164 + text-transform: uppercase; letter-spacing: 0.06em;
165 + border: 1.5px solid var(--ink); border-radius: var(--r-pill);
166 + background: var(--surface); color: var(--ink);
167 +}
168 +.chip-accent { background: var(--accent); color: var(--on-accent); }
169 +.chip-soft { background: var(--accent-soft); border-color: var(--line); }
170 +
171 +/* ---- Champs ---- */
172 +.input, .select, .textarea {
173 + width: 100%; min-height: var(--touch); padding: 10px 14px;
174 + font: inherit; color: var(--ink); background: var(--surface);
175 + border: 1.5px solid var(--ink); border-radius: var(--r-ctl);
176 +}
177 +.input:focus, .select:focus, .textarea:focus {
178 + outline: none; box-shadow: 3px 3px 0 var(--accent); border-color: var(--ink);
179 +}
180 +.input::placeholder { color: var(--ink-3); }
181 +
182 +/* ---- Badge « Un service Groupe KA » (header, cliquable → hub) ---- */
183 +.gk-badge {
184 + display: inline-flex; align-items: center; gap: 7px;
185 + min-height: 30px; padding: 3px 10px 4px;
186 + font-family: var(--font-mono); font-size: 10px; font-weight: 700;
187 + letter-spacing: 0.08em; text-transform: uppercase; text-decoration: none;
188 + border: 1.5px solid var(--ink); border-radius: var(--r-pill);
189 + background: var(--surface); color: var(--ink-2); white-space: nowrap;
190 +}
191 +.gk-badge b {
192 + font-family: var(--font-display); font-size: 12px; letter-spacing: -0.02em;
193 + text-transform: none; color: var(--ink);
194 +}
195 +.gk-badge b .ka {
196 + display: inline-block; background: var(--ink); color: var(--accent);
197 + border-radius: 5px; padding: 0 5px 1px; margin-left: 3px; transform: rotate(-2deg);
198 +}
199 +.gk-badge:hover .ka { transform: rotate(0); }
200 +.gk-badge--dark { background: transparent; border-color: rgba(245,243,238,0.4); color: rgba(245,243,238,0.75); }
201 +.gk-badge--dark b { color: var(--paper); }
202 +
203 +/* ---- Footer commun (fond encre — voir react/KaFooter.tsx) ---- */
204 +.ka-footer { margin-top: var(--sp-8); background: var(--ink); padding: 44px 0; font-size: 13px; color: rgba(245,243,238,0.75); }
205 +.ka-footer a { text-decoration: none; }
206 +.ka-footer .wordmark { font-family: var(--font-display); font-weight: 700; font-size: 30px; letter-spacing: -0.04em; color: var(--paper); text-decoration: none; }
207 +.ka-footer .wordmark .ka { color: var(--accent); }
208 +.ka-footer .desc { max-width: 640px; margin-top: var(--sp-4); }
209 +.ka-footer .notice { max-width: 640px; margin-top: var(--sp-4); border-left: 2px solid var(--accent); padding-left: var(--sp-4); }
210 +.ka-footer .notice b { color: var(--paper); }
211 +.ka-footer .sites { list-style: none; display: flex; flex-wrap: wrap; gap: 10px 26px; margin: 26px 0 0; padding: 0; font-family: var(--font-mono); font-size: 11px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; }
212 +.ka-footer .sites a { color: rgba(245,243,238,0.65); }
213 +.ka-footer .sites a:hover { color: var(--accent); text-decoration: underline; text-underline-offset: 4px; }
214 +.ka-footer .contacts { display: grid; gap: 14px 32px; border-top: 1px solid rgba(245,243,238,0.15); margin-top: 30px; padding-top: 26px; }
215 +@media (min-width: 768px) { .ka-footer .contacts { grid-template-columns: repeat(3, 1fr); } }
216 +.ka-footer .contacts a { font-family: var(--font-mono); font-weight: 700; font-size: 12px; color: rgba(245,243,238,0.85); }
217 +.ka-footer .contacts a:hover { color: var(--accent); text-decoration: underline; text-underline-offset: 4px; }
218 +.ka-footer .contacts span { display: block; margin-top: 3px; font-size: 11px; color: rgba(245,243,238,0.5); }
219 +.ka-footer .legal { margin-top: 30px; font-family: var(--font-mono); font-size: 11px; color: rgba(245,243,238,0.45); }
220 +.ka-footer .legal a { color: inherit; }
221 +.ka-footer .legal a:hover { color: var(--accent); text-decoration: underline; text-underline-offset: 4px; }
222 +
223 +/* ---- Tableaux → cartes empilées sous 768 px ---- */
224 +.tbl-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
225 +@media (max-width: 767px) {
226 + .tbl-stack thead { display: none; }
227 + .tbl-stack tr { display: block; border: 1.5px solid var(--ink); border-radius: var(--r-card); margin-bottom: var(--sp-3); background: var(--surface); }
228 + .tbl-stack td { display: flex; justify-content: space-between; gap: var(--sp-3); padding: 8px 12px; border: 0; }
229 + .tbl-stack td::before { content: attr(data-label); font-family: var(--font-mono); font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-3); }
230 +}
231 +
232 +/* ---- Utilitaires responsive ---- */
233 +.only-mobile { display: initial; } .only-desktop { display: none; }
234 +@media (min-width: 768px) { .only-mobile { display: none; } .only-desktop { display: initial; } }
235 + (ka/tokens.css — design system commun Groupe KA,
236 + importé EN PREMIER) et {"org":{"name":"Groupe KA","legalName":"Groupe KA — Simon-Pierre Boucher","tagline":"Holding québécois d'agrégateurs de produits et services entièrement automatisés.","disclaimer":"Groupe KA est un agrégateur de contenu : nous ne vendons rien, ne louons rien et ne sommes partie à aucune transaction.","copyrightHolder":"Groupe KA — Simon-Pierre Boucher"},"hub":{"url":"https://www.groupe-ka.com","loginPath":"/connexion","signupNote":"La création de compte KA ID se fait sur le hub groupe-ka.com ; chaque site délègue sa connexion via /api/auth/ka/login."},"contacts":[{"email":"contact@groupe-ka.com","role":"Projets, partenariats & données"},{"email":"info@groupe-ka.com","role":"Médias & questions générales"},{"email":"admin@groupe-ka.com","role":"Légal, vie privée & Loi 25"}],"legal":[{"label":"Conditions d'utilisation","href":"https://www.groupe-ka.com/conditions"},{"label":"Politique de confidentialité","href":"https://www.groupe-ka.com/confidentialite"},{"label":"Protection des renseignements personnels (Loi 25)","href":"https://www.groupe-ka.com/loi-25"},{"label":"Transparence des robots d'indexation","href":"https://www.groupe-ka.com/bots"}],"sites":[{"id":"groupe-ka","wordmark":"Groupe KA","domain":"www.groupe-ka.com","accent":"#d9f26b","accentSoft":"#f0f9d2","accentDeep":"#123f2e","onAccent":"#141814","tagline":"Le portail de l'écosystème ·Ka"},{"id":"trouve-ka","wordmark":"Trouve·Ka","domain":"www.trouve-ka.com","accent":"#1c7ed6","accentSoft":"#e7f2fd","accentDeep":"#14508f","onAccent":"#ffffff","tagline":"Le moteur de recherche du web québécois"},{"id":"lou-ka","wordmark":"Lou·Ka","domain":"www.lou-ka.com","accent":"#ff6a00","accentSoft":"#fff1e6","accentDeep":"#cc5500","onAccent":"#ffffff","tagline":"Tous les logements à louer"},{"id":"immo-ka","wordmark":"Immo·Ka","domain":"www.immo-ka.com","accent":"#e23744","accentSoft":"#fbe0e2","accentDeep":"#a8232e","onAccent":"#ffffff","tagline":"Toutes les propriétés à vendre"},{"id":"vrai-prix","wordmark":"Vrai-Prix","domain":"www.vrai-prix.com","accent":"#ff5148","accentSoft":"#ffe3e0","accentDeep":"#9e2a25","onAccent":"#ffffff","tagline":"La valeur réelle de chaque propriété"},{"id":"auto-ka","wordmark":"Auto·Ka","domain":"www.auto-ka.com","accent":"#ff5a2a","accentSoft":"#ffe8de","accentDeep":"#cc3f16","onAccent":"#ffffff","tagline":"Les voitures usagées du Québec"},{"id":"fabri-ka","wordmark":"Fabri·Ka","domain":"www.fabri-ka.com","accent":"#c4532e","accentSoft":"#f7e3da","accentDeep":"#a94525","onAccent":"#ffffff","tagline":"Les produits fabriqués au Québec"},{"id":"food-ka","wordmark":"Food·Ka","domain":"www.food-ka.com","accent":"#1f9d55","accentSoft":"#e2f5ea","accentDeep":"#157a40","onAccent":"#ffffff","tagline":"Les prix d'épicerie, suivis à la source"},{"id":"resto-ka","wordmark":"Resto·Ka","domain":"www.resto-ka.com","accent":"#f08c00","accentSoft":"#fdeed7","accentDeep":"#b96a00","onAccent":"#141814","tagline":"Chaque resto, chaque plat, chaque prix"},{"id":"sorti-ka","wordmark":"Sorti·Ka","domain":"www.sorti-ka.com","accent":"#d6336c","accentSoft":"#fbe0eb","accentDeep":"#a12551","onAccent":"#ffffff","tagline":"Toutes les sorties, dans les 17 régions"},{"id":"crea-ka","wordmark":"Créa·Ka","domain":"www.crea-ka.com","accent":"#7048e8","accentSoft":"#ece5fc","accentDeep":"#5433b8","onAccent":"#ffffff","tagline":"Les créateurs d'ici, tous leurs liens"},{"id":"api-ka","wordmark":"API·Ka","domain":"www.api-ka.com","accent":"#3b5bdb","accentSoft":"#e4eafb","accentDeep":"#2b44a8","onAccent":"#ffffff","tagline":"La donnée de l'écosystème, par API"}],"extraFooterLinks":[{"label":"ValoPlex","href":"https://www.valoplex.com"},{"label":"Ka2","href":"https://www.ka2.bot"},{"label":"Ka4","href":"https://www.ka4.bot"},{"label":"Ka6","href":"https://www.ka6.bot"}]} (ka/ecosystem.json — contacts,
237 + sites, mentions légales du groupe : footer commun + page /contact).
238 + Système « éditorial sharp » du Groupe KA (papier grainé #f5f3ee,
239 + encre #141814, bordures encre + ombres décalées dures, Space Grotesk
240 + / Inter / JetBrains Mono) — accent attribué à Créa-Ka : VIOLET
241 + (--accent:#7048e8). Patrons mobiles calqués sur Lou-Ka (tab bar
242 + 4 onglets, filtres défilants, anti-zoom iOS).
243 + Routes : / · /createur/{id} · /stats · /retrait · /compte · /contact
12 244 -->
13 245 <!DOCTYPE html>
14 246 <html lang="fr">
15 247 <head>
16 248 <meta charset="utf-8">
17 249 <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
18 −<title>Créa-Ka — Tous les créateurs québécois. Tous leurs liens.</title>
250 +<title>Créa-Ka — Un service Groupe KA</title>
19 251 <meta name="description" content="Annuaire public des créateurs de contenu et influenceurs québécois : tous leurs comptes (Instagram, TikTok, YouTube, Twitch…) regroupés, cherchables par niche, région, langue et taille d'audience.">
20 252 <meta name="theme-color" content="#141814">
21 253 <link rel="preconnect" href="https://fonts.googleapis.com">
22 254 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
23 255 <link rel="preconnect" href="https://unavatar.io">
24 256 <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;600;700&family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@500;700&display=swap" rel="stylesheet">
25 −<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='10' fill='%23141814'/%3E%3Ccircle cx='32' cy='23' r='9' fill='%23c9a3ff'/%3E%3Cpath d='M14 52c3-10 9-15 18-15s15 5 18 15' stroke='%23c9a3ff' stroke-width='6' fill='none' stroke-linecap='round'/%3E%3C/svg%3E">
257 +<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='10' fill='%23141814'/%3E%3Ccircle cx='32' cy='23' r='9' fill='%237048e8'/%3E%3Cpath d='M14 52c3-10 9-15 18-15s15 5 18 15' stroke='%237048e8' stroke-width='6' fill='none' stroke-linecap='round'/%3E%3C/svg%3E">
26 258 <style>
27 −/* système « éditorial sharp » Groupe KA — accent Créa-Ka : violet électrique.
28 − Convention du groupe : les NOMS de variables (--green/--lime) sont partagés
29 − entre les apps, seules les VALEURS changent. */
259 +/* ka/tokens.css — design system commun Groupe KA, importé EN PREMIER
260 + (injecté au build par scripts/build_frontend.py) */
261 +/* -----------------------------------------------------------------------------
262 + Auteur : Simon-Pierre Boucher — contact@spboucher.ai
263 + Fichier : ka-ui/tokens.css — SOURCE CANONIQUE (repo ka-ui sur spbgit)
264 + Desc. : Design system commun GROUPE KA « éditorial sharp » — tokens + socle
265 + de composants partagés par les 12 plateformes. Chaque site importe ce
266 + fichier PUIS surcharge uniquement son accent (voir accents.css).
267 +
268 + · Typo : display Space Grotesk / texte Inter / micro-étiquettes JetBrains Mono
269 + · Palette: papier #f5f3ee · encre #141814 · vert profond #1c5c41 + ACCENT du site
270 + · Signature : bordures encre 1,5–2 px + ombres décalées dures, grain de film,
271 + surlignés d'accent inclinés (néo-brutalisme raffiné)
272 + · Breakpoints communs : 360 / 768 / 1024 / 1440 px (mobile-first)
273 + · Zones tactiles ≥ 44×44 px, safe-areas iOS, typographie fluide (clamp)
274 +----------------------------------------------------------------------------- */
275 +
276 +:root {
277 + /* ---- Palette fixe Groupe KA (identique sur les 12 sites) ---- */
278 + --paper: #f5f3ee;
279 + --surface: #ffffff;
280 + --surface-2: #faf9f5;
281 + --ink: #141814;
282 + --ink-2: #4d5551;
283 + --ink-3: #8b928c;
284 + --line: rgba(20, 24, 20, 0.14);
285 + --line-strong: rgba(20, 24, 20, 0.85);
286 + --green: #1c5c41;
287 + --green-deep: #123f2e;
288 + --amber: #e8a33d;
289 + --amber-soft: #fdf3e2;
290 + --danger: #b3423a;
291 + --danger-soft: #fbe9e7;
292 +
293 + /* ---- ACCENT du site — SEULES variables surchargées par marque ---- */
294 + --accent: #d9f26b; /* défaut : lime Groupe KA */
295 + --accent-soft: #f0f9d2;
296 + --accent-deep: #123f2e;
297 + --on-accent: var(--ink); /* couleur du texte posé SUR l'accent */
298 +
299 + /* alias rétro-compatibles (les satellites historiques utilisent --lime) */
300 + --lime: var(--accent);
301 + --lime-soft: var(--accent-soft);
302 +
303 + /* ---- Géométrie sharp ---- */
304 + --r-card: 10px;
305 + --r-ctl: 6px;
306 + --r-pill: 999px;
307 +
308 + /* ---- Ombres décalées — la signature du groupe ---- */
309 + --shadow-flat: 0 1px 2px rgba(20, 24, 20, 0.05);
310 + --shadow-off: 6px 6px 0 var(--ink);
311 + --shadow-off-soft: 8px 8px 0 rgba(20, 24, 20, 0.08);
312 + --shadow-off-mid: 4px 4px 0 rgba(20, 24, 20, 0.18);
313 +
314 + /* ---- Typographie ---- */
315 + --font-display: "Space Grotesk", system-ui, sans-serif;
316 + --font-body: "Inter", system-ui, sans-serif;
317 + --font-mono: "JetBrains Mono", ui-monospace, monospace;
318 +
319 + /* Échelle fluide (mobile-first, clamp) */
320 + --fs-h1: clamp(30px, 3.2vw + 18px, 54px);
321 + --fs-h2: clamp(23px, 1.8vw + 14px, 34px);
322 + --fs-h3: clamp(17px, 0.9vw + 12px, 22px);
323 + --fs-body: 15px;
324 + --fs-small: 13px;
325 +
326 + /* Espacements */
327 + --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px;
328 + --sp-5: 24px; --sp-6: 32px; --sp-7: 48px; --sp-8: 64px;
329 +
330 + /* Cible tactile minimale */
331 + --touch: 44px;
332 +}
333 +
334 +/* ---- Socle ---- */
335 +* { box-sizing: border-box; }
336 +html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
337 +body {
338 + margin: 0;
339 + background: var(--paper);
340 + color: var(--ink);
341 + font-family: var(--font-body);
342 + font-size: var(--fs-body);
343 + line-height: 1.55;
344 + -webkit-font-smoothing: antialiased;
345 + padding-bottom: env(safe-area-inset-bottom);
346 + overflow-x: clip; /* jamais de débordement horizontal */
347 +}
348 +img, svg, video { max-width: 100%; height: auto; display: block; }
349 +h1, h2, h3, h4 { font-family: var(--font-display); letter-spacing: -0.03em; margin: 0 0 0.5em; }
350 +h1 { font-size: var(--fs-h1); line-height: 1.06; }
351 +h2 { font-size: var(--fs-h2); line-height: 1.15; }
352 +h3 { font-size: var(--fs-h3); line-height: 1.25; }
353 +a { color: inherit; }
354 +::selection { background: var(--accent); color: var(--on-accent); }
355 +:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; }
356 +
357 +/* Grain de film pleine page — ⚠️ jamais de z-index sur body > * (position:
358 + relative seulement), sinon les utilitaires z-* sont écrasés. */
359 +body::before {
360 + content: "";
361 + position: fixed; inset: 0; pointer-events: none; opacity: 0.35; z-index: 9999;
362 + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='linear' slope='0.06'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)'/%3E%3C/svg%3E");
363 +}
364 +body > * { position: relative; }
365 +
366 +/* ---- Conteneur commun ---- */
367 +.container { max-width: 1152px; margin: 0 auto; padding: 0 var(--sp-4); }
368 +@media (min-width: 768px) { .container { padding: 0 var(--sp-5); } }
369 +
370 +/* ---- Micro-typographie signature ---- */
371 +.kicker {
372 + display: inline-flex; align-items: center; gap: 10px;
373 + font-family: var(--font-mono); font-size: 11.5px; font-weight: 500;
374 + text-transform: uppercase; letter-spacing: 0.12em; color: var(--green);
375 +}
376 +.kicker::before { content: ""; width: 22px; height: 2px; background: var(--green); }
377 +.klabel {
378 + font-family: var(--font-mono); font-size: 10px; font-weight: 700;
379 + text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-3);
380 +}
381 +.hl {
382 + display: inline-block; background: var(--accent); color: var(--on-accent);
383 + border-radius: 8px; padding: 0 10px 2px; transform: rotate(-1deg);
384 +}
385 +.outline-txt { color: transparent; -webkit-text-stroke: 2px var(--ink); }
386 +
387 +/* ---- Boutons (cible ≥ 44 px) ---- */
388 +.btn {
389 + display: inline-flex; align-items: center; justify-content: center; gap: 8px;
390 + min-height: var(--touch); padding: 10px 18px;
391 + font-family: var(--font-display); font-weight: 700; font-size: 14px;
392 + border: 1.5px solid var(--ink); border-radius: var(--r-ctl);
393 + background: var(--surface); color: var(--ink);
394 + cursor: pointer; text-decoration: none;
395 + transition: transform 0.15s, box-shadow 0.15s, background 0.15s, color 0.15s;
396 +}
397 +.btn:hover { transform: translate(-2px, -2px); box-shadow: var(--shadow-off-mid); }
398 +.btn:active { transform: translate(0, 0); box-shadow: none; }
399 +.btn:disabled { opacity: 0.45; pointer-events: none; }
400 +.btn-primary { background: var(--ink); color: var(--accent); }
401 +.btn-primary:hover { background: var(--accent-deep); }
402 +.btn-accent { background: var(--accent); color: var(--on-accent); }
403 +.btn-ghost { background: transparent; border-color: var(--line); }
404 +.btn-ghost:hover { border-color: var(--ink); }
405 +
406 +/* ---- Cartes ---- */
407 +.card {
408 + background: var(--surface); border: 1.5px solid var(--ink);
409 + border-radius: var(--r-card); box-shadow: var(--shadow-off-soft);
410 + overflow: hidden;
411 +}
412 +.card-hover { transition: transform 0.15s, box-shadow 0.15s; }
413 +.card-hover:hover { transform: translate(-2px, -2px); box-shadow: var(--shadow-off); }
414 +
415 +/* ---- Chips / badges ---- */
416 +.chip {
417 + display: inline-flex; align-items: center; gap: 6px;
418 + padding: 4px 11px; font-family: var(--font-mono); font-size: 11px; font-weight: 700;
419 + text-transform: uppercase; letter-spacing: 0.06em;
420 + border: 1.5px solid var(--ink); border-radius: var(--r-pill);
421 + background: var(--surface); color: var(--ink);
422 +}
423 +.chip-accent { background: var(--accent); color: var(--on-accent); }
424 +.chip-soft { background: var(--accent-soft); border-color: var(--line); }
425 +
426 +/* ---- Champs ---- */
427 +.input, .select, .textarea {
428 + width: 100%; min-height: var(--touch); padding: 10px 14px;
429 + font: inherit; color: var(--ink); background: var(--surface);
430 + border: 1.5px solid var(--ink); border-radius: var(--r-ctl);
431 +}
432 +.input:focus, .select:focus, .textarea:focus {
433 + outline: none; box-shadow: 3px 3px 0 var(--accent); border-color: var(--ink);
434 +}
435 +.input::placeholder { color: var(--ink-3); }
436 +
437 +/* ---- Badge « Un service Groupe KA » (header, cliquable → hub) ---- */
438 +.gk-badge {
439 + display: inline-flex; align-items: center; gap: 7px;
440 + min-height: 30px; padding: 3px 10px 4px;
441 + font-family: var(--font-mono); font-size: 10px; font-weight: 700;
442 + letter-spacing: 0.08em; text-transform: uppercase; text-decoration: none;
443 + border: 1.5px solid var(--ink); border-radius: var(--r-pill);
444 + background: var(--surface); color: var(--ink-2); white-space: nowrap;
445 +}
446 +.gk-badge b {
447 + font-family: var(--font-display); font-size: 12px; letter-spacing: -0.02em;
448 + text-transform: none; color: var(--ink);
449 +}
450 +.gk-badge b .ka {
451 + display: inline-block; background: var(--ink); color: var(--accent);
452 + border-radius: 5px; padding: 0 5px 1px; margin-left: 3px; transform: rotate(-2deg);
453 +}
454 +.gk-badge:hover .ka { transform: rotate(0); }
455 +.gk-badge--dark { background: transparent; border-color: rgba(245,243,238,0.4); color: rgba(245,243,238,0.75); }
456 +.gk-badge--dark b { color: var(--paper); }
457 +
458 +/* ---- Footer commun (fond encre — voir react/KaFooter.tsx) ---- */
459 +.ka-footer { margin-top: var(--sp-8); background: var(--ink); padding: 44px 0; font-size: 13px; color: rgba(245,243,238,0.75); }
460 +.ka-footer a { text-decoration: none; }
461 +.ka-footer .wordmark { font-family: var(--font-display); font-weight: 700; font-size: 30px; letter-spacing: -0.04em; color: var(--paper); text-decoration: none; }
462 +.ka-footer .wordmark .ka { color: var(--accent); }
463 +.ka-footer .desc { max-width: 640px; margin-top: var(--sp-4); }
464 +.ka-footer .notice { max-width: 640px; margin-top: var(--sp-4); border-left: 2px solid var(--accent); padding-left: var(--sp-4); }
465 +.ka-footer .notice b { color: var(--paper); }
466 +.ka-footer .sites { list-style: none; display: flex; flex-wrap: wrap; gap: 10px 26px; margin: 26px 0 0; padding: 0; font-family: var(--font-mono); font-size: 11px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; }
467 +.ka-footer .sites a { color: rgba(245,243,238,0.65); }
468 +.ka-footer .sites a:hover { color: var(--accent); text-decoration: underline; text-underline-offset: 4px; }
469 +.ka-footer .contacts { display: grid; gap: 14px 32px; border-top: 1px solid rgba(245,243,238,0.15); margin-top: 30px; padding-top: 26px; }
470 +@media (min-width: 768px) { .ka-footer .contacts { grid-template-columns: repeat(3, 1fr); } }
471 +.ka-footer .contacts a { font-family: var(--font-mono); font-weight: 700; font-size: 12px; color: rgba(245,243,238,0.85); }
472 +.ka-footer .contacts a:hover { color: var(--accent); text-decoration: underline; text-underline-offset: 4px; }
473 +.ka-footer .contacts span { display: block; margin-top: 3px; font-size: 11px; color: rgba(245,243,238,0.5); }
474 +.ka-footer .legal { margin-top: 30px; font-family: var(--font-mono); font-size: 11px; color: rgba(245,243,238,0.45); }
475 +.ka-footer .legal a { color: inherit; }
476 +.ka-footer .legal a:hover { color: var(--accent); text-decoration: underline; text-underline-offset: 4px; }
477 +
478 +/* ---- Tableaux → cartes empilées sous 768 px ---- */
479 +.tbl-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
480 +@media (max-width: 767px) {
481 + .tbl-stack thead { display: none; }
482 + .tbl-stack tr { display: block; border: 1.5px solid var(--ink); border-radius: var(--r-card); margin-bottom: var(--sp-3); background: var(--surface); }
483 + .tbl-stack td { display: flex; justify-content: space-between; gap: var(--sp-3); padding: 8px 12px; border: 0; }
484 + .tbl-stack td::before { content: attr(data-label); font-family: var(--font-mono); font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-3); }
485 +}
486 +
487 +/* ---- Utilitaires responsive ---- */
488 +.only-mobile { display: initial; } .only-desktop { display: none; }
489 +@media (min-width: 768px) { .only-mobile { display: none; } .only-desktop { display: initial; } }
490 +
491 +</style>
492 +<style>
493 +/* Surcharges Créa-Ka par-dessus ka/tokens.css. Convention du groupe : les
494 + NOMS de variables sont partagés (--accent/--lime), seules les VALEURS
495 + changent — accent attribué à Créa-Ka : VIOLET. */
30 496 :root{
31 − --paper:#f5f3ee; --surface:#fff; --surface-2:#faf9f5;
32 − --ink:#141814; --ink-2:#4d5551; --ink-3:#8b928c;
33 − --line:rgba(20,24,20,.14); --line-strong:rgba(20,24,20,.85);
34 − --green:#5b34a8; /* violet profond (primaire) */
497 + --accent:#7048e8; --accent-soft:#ece5fc; --accent-deep:#5433b8; --on-accent:#ffffff;
498 + /* alias rétro-compatibles (le CSS historique du site utilise --lime) */
499 + --lime:var(--accent); --lime-soft:var(--accent-soft);
500 + --green:var(--accent-deep); /* primaire du site = violet profond */
35 501 --green-deep:#3d2178;
36 − --lime:#c9a3ff; /* violet électrique (accent) */
37 − --lime-soft:#efe6ff;
38 − --amber:#e8a33d; --amber-soft:#fdf3e2;
39 − --danger:#b3423a;
40 − --r-card:10px; --r-ctl:6px; --r-pill:999px;
41 − --shadow-flat:0 1px 2px rgba(20,24,20,.05);
42 − --shadow-off:6px 6px 0 var(--ink);
43 − --shadow-off-soft:8px 8px 0 rgba(20,24,20,.08);
44 − --font-display:"Space Grotesk",system-ui,sans-serif;
45 − --font-body:"Inter",system-ui,sans-serif;
46 − --font-mono:"JetBrains Mono",ui-monospace,monospace;
47 −}
48 −*{box-sizing:border-box}
49 −html{scroll-behavior:smooth}
50 −body{margin:0;background:var(--paper);color:var(--ink);font-family:var(--font-body);
51 − font-size:15px;line-height:1.55;-webkit-font-smoothing:antialiased;
52 − padding-bottom:env(safe-area-inset-bottom)}
53 −/* grain de film pleine page (signature du groupe) — aucun z-index sur body>* */
54 −body::before{content:"";position:fixed;inset:0;pointer-events:none;opacity:.35;z-index:9999;
55 − background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='linear' slope='0.06'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)'/%3E%3C/svg%3E")}
56 −body>*{position:relative}
57 −h1,h2,h3,h4{font-family:var(--font-display);letter-spacing:-.03em;margin:0}
58 −a{color:inherit;text-decoration:none} button{font-family:inherit;cursor:pointer} img{display:block}
59 −::selection{background:var(--lime);color:var(--ink)}
60 −:focus-visible{outline:2px solid var(--green);outline-offset:2px}
502 +}
503 +/* le layout du site est calibré sur des titres sans marge basse */
504 +h1,h2,h3,h4{margin:0}
505 +a{text-decoration:none} button{font-family:inherit;cursor:pointer}
61 506 .icn{width:1em;height:1em;display:block;fill:currentColor}
62 507 .container{max-width:1240px;margin:0 auto;padding:0 24px}
63 508 @media(max-width:640px){.container{padding:0 16px}}
64 −.kicker{display:inline-flex;align-items:center;gap:10px;font-family:var(--font-mono);
65 − font-size:11.5px;font-weight:500;text-transform:uppercase;letter-spacing:.12em;color:var(--green)}
66 −.kicker::before{content:"";width:22px;height:2px;background:var(--green)}
67 −.klabel{font-family:var(--font-mono);font-size:10px;font-weight:700;
68 − text-transform:uppercase;letter-spacing:.1em;color:var(--ink-3)}
69 −.hl{display:inline-block;background:var(--lime);border-radius:8px;padding:0 10px 2px;transform:rotate(-1deg)}
70 −.outline-txt{color:transparent;-webkit-text-stroke:2px var(--ink)}
71 509
72 510 /* ---------- cartes & boutons (langage du groupe) ---------- */
73 511 .gk-card{background:var(--surface);border:1.5px solid var(--ink);
74 512 border-radius:var(--r-card);box-shadow:var(--shadow-off-soft)}
75 513 .gk-hover{transition:transform .18s ease,box-shadow .18s ease}
76 514 .gk-hover:hover{transform:translate(-3px,-3px);box-shadow:var(--shadow-off)}
77 −.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:44px;
78 − padding:10px 20px;border:1.5px solid var(--ink);border-radius:var(--r-ctl);
79 − font-family:var(--font-display);font-size:14px;font-weight:700;cursor:pointer;
80 − transition:background .15s ease,transform .1s ease,box-shadow .1s ease}
81 515 .btn:active{transform:translate(2px,2px);box-shadow:none!important}
82 −.btn-primary{background:var(--ink);color:var(--lime);box-shadow:4px 4px 0 rgba(20,24,20,.25)}
83 −.btn-primary:hover{background:var(--green-deep)}
84 −.btn-ghost{background:transparent;color:var(--ink)}
85 −.btn-ghost:hover{background:var(--lime)}
516 +.btn-primary{box-shadow:4px 4px 0 rgba(20,24,20,.25)}
86 517
87 518 /* ===== header ===== */
88 519 .header{position:sticky;top:0;z-index:50;background:rgba(245,243,238,.9);
@@ -91,26 +522,35 @@ a{color:inherit;text-decoration:none} button{font-family:inherit;cursor:pointer}
91 522 .brand{font-family:var(--font-display);font-weight:700;font-size:23px;letter-spacing:-.03em;
92 523 display:flex;align-items:center;line-height:1;color:var(--ink)}
93 524 .brand svg{margin-right:11px;flex:none}
94 −.brand .ka{background:var(--lime);border-radius:6px;padding:0 6px 1px;margin-left:2px;transform:rotate(-1deg)}
525 +.brand .ka{background:var(--accent);color:var(--on-accent);border-radius:6px;padding:0 6px 1px;margin-left:2px;transform:rotate(-1deg)}
95 526 .brand-tag{font-family:var(--font-mono);font-size:10px;font-weight:500;color:var(--ink-3);
96 527 line-height:1.5;text-transform:uppercase;letter-spacing:.08em}
97 528 @media(max-width:900px){.brand-tag{display:none}}
98 529 .header-spacer{flex:1}
99 530 .hbtn{border:1.5px solid var(--ink);background:var(--surface);color:var(--ink);
100 − border-radius:var(--r-ctl);padding:8px 16px;font-family:var(--font-display);
531 + border-radius:var(--r-ctl);padding:8px 16px;min-height:44px;font-family:var(--font-display);
101 532 font-size:13px;font-weight:700;transition:.15s;display:inline-flex;align-items:center;
102 533 gap:8px;white-space:nowrap;box-shadow:3px 3px 0 rgba(20,24,20,.12)}
103 −.hbtn:hover{background:var(--lime)}
534 +.hbtn:hover{background:var(--accent);color:var(--on-accent)}
104 535 .hbtn:active{transform:translate(2px,2px);box-shadow:none}
105 −.hbtn.primary{background:var(--ink);color:var(--lime)}
106 −.hbtn.primary:hover{background:var(--green-deep)}
536 +.hbtn.primary{background:var(--ink);color:var(--accent)}
537 +.hbtn.primary:hover{background:var(--accent-deep);color:var(--on-accent)}
107 538 @media(max-width:760px){.header .hbtn:not(.acct){display:none}}
108 539 /* bouton / jeton de compte KA ID — toujours visible, même sur mobile */
109 540 .hbtn.acct{padding:7px 14px}
110 541 .hbtn.acct img{width:22px;height:22px;border-radius:50%;object-fit:cover;
111 542 border:1.5px solid var(--ink);margin-left:-4px}
112 −.hbtn.acct .ka-badge{background:var(--lime);border-radius:4px;padding:0 5px;
543 +.hbtn.acct .ka-badge{background:var(--accent);color:var(--on-accent);border-radius:4px;padding:0 5px;
113 544 font-family:var(--font-mono);font-size:10px;font-weight:700}
545 +.hbtn:hover .ka-badge{background:var(--on-accent);color:var(--accent)}
546 +/* badge « Un service Groupe KA » (ka/GroupeKaBadge — styles dans tokens.css) */
547 +.header .gk-badge{flex:none}
548 +.hbtn .acct-short{display:none}
549 +@media(max-width:560px){
550 + .header-inner{gap:10px}
551 + .header .gk-badge .pfx{display:none}
552 + .hbtn .acct-long{display:none}.hbtn .acct-short{display:inline}}
553 +@media(max-width:400px){.brand svg{width:26px;height:26px;margin-right:8px}.brand{font-size:20px}}
114 554
115 555 /* ===== page compte (carte de membre Groupe KA) ===== */
116 556 .compte-page{max-width:640px;margin:0 auto;padding:44px 0 70px}
@@ -118,18 +558,18 @@ a{color:inherit;text-decoration:none} button{font-family:inherit;cursor:pointer}
118 558 padding:28px;color:var(--paper);box-shadow:var(--shadow-off);margin-top:24px;
119 559 position:relative;overflow:hidden}
120 560 .membercard::after{content:"";position:absolute;right:-40px;top:-40px;width:160px;
121 − height:160px;border-radius:50%;background:rgba(201,163,255,.14)}
561 + height:160px;border-radius:50%;background:rgba(112,72,232,.18)}
122 562 .mc-brand{font-family:var(--font-mono);font-size:10px;font-weight:700;
123 − text-transform:uppercase;letter-spacing:.14em;color:var(--lime)}
563 + text-transform:uppercase;letter-spacing:.14em;color:var(--accent-soft)}
124 564 .mc-row{display:flex;gap:18px;align-items:center;margin-top:18px}
125 −.mc-avatar{width:72px;height:72px;border-radius:14px;border:2px solid var(--lime);
565 +.mc-avatar{width:72px;height:72px;border-radius:14px;border:2px solid var(--accent);
126 566 background:var(--green-deep);overflow:hidden;flex:none;display:flex;
127 567 align-items:center;justify-content:center;font-family:var(--font-display);
128 − font-weight:700;font-size:26px;color:var(--lime)}
568 + font-weight:700;font-size:26px;color:var(--accent-soft)}
129 569 .mc-avatar img{width:100%;height:100%;object-fit:cover}
130 570 .mc-name{font-family:var(--font-display);font-size:22px;font-weight:700;color:var(--paper)}
131 −.mc-kaid{font-family:var(--font-mono);font-size:12px;color:var(--lime);margin-top:2px;letter-spacing:.04em}
132 −.mc-role{display:inline-flex;background:var(--lime);color:var(--ink);border-radius:5px;
571 +.mc-kaid{font-family:var(--font-mono);font-size:12px;color:var(--accent-soft);margin-top:2px;letter-spacing:.04em}
572 +.mc-role{display:inline-flex;background:var(--accent);color:var(--on-accent);border-radius:5px;
133 573 padding:2px 10px;font-family:var(--font-mono);font-size:10px;font-weight:700;
134 574 text-transform:uppercase;letter-spacing:.06em;margin-top:8px}
135 575 .mc-meta{margin-top:20px;display:grid;gap:6px;font-size:12.5px;color:rgba(245,243,238,.75)}
@@ -153,8 +593,9 @@ a{color:inherit;text-decoration:none} button{font-family:inherit;cursor:pointer}
153 593 .adv{background:var(--surface);border:1.5px solid var(--ink);border-radius:var(--r-card);
154 594 padding:16px;box-shadow:var(--shadow-off-soft)}
155 595 .adv .ico{width:36px;height:36px;border-radius:8px;border:1.5px solid var(--ink);
156 − background:var(--lime);color:var(--ink);display:flex;align-items:center;
596 + background:var(--accent);color:var(--on-accent);display:flex;align-items:center;
157 597 justify-content:center;margin-bottom:10px;font-size:15px}
598 +.adv:nth-child(2n) .ico{color:var(--ink)}
158 599 .adv:nth-child(2n) .ico{background:var(--amber-soft)}
159 600 .adv h3{font-size:14px;margin-bottom:3px}
160 601 .adv p{margin:0;font-size:12px;color:var(--ink-3);line-height:1.45}
@@ -167,7 +608,7 @@ a{color:inherit;text-decoration:none} button{font-family:inherit;cursor:pointer}
167 608 .search-input{flex:1 1 auto;display:flex;align-items:center;gap:10px;background:var(--surface);
168 609 border:1.5px solid var(--ink);border-radius:var(--r-ctl);padding:10px 15px;
169 610 transition:.15s;min-width:0;box-shadow:3px 3px 0 rgba(20,24,20,.08)}
170 −.search-input:focus-within{box-shadow:3px 3px 0 rgba(91,52,168,.3)}
611 +.search-input:focus-within{box-shadow:3px 3px 0 rgba(112,72,232,.35)}
171 612 .search-input input{border:0;background:none;outline:none;font:inherit;flex:1;color:var(--ink);min-width:0}
172 613 .search-input svg{flex:none;color:var(--ink-3)}
173 614 .filters{display:flex;gap:8px;flex-wrap:wrap}
@@ -177,7 +618,7 @@ select.f{appearance:none;-webkit-appearance:none;border:1.5px solid var(--ink);
177 618 font-size:13px;font-weight:700;color:var(--ink-2);max-width:170px;
178 619 box-shadow:3px 3px 0 rgba(20,24,20,.08)}
179 620 select.f:focus{outline:2px solid var(--green);outline-offset:1px}
180 −select.f.active{background-color:var(--lime);color:var(--ink)}
621 +select.f.active{background-color:var(--accent-soft);color:var(--ink);border-color:var(--accent-deep)}
181 622 @media(max-width:760px){
182 623 .search-wrap{flex-wrap:wrap}
183 624 .search-input{flex-basis:100%}
@@ -200,18 +641,18 @@ select.f.active{background-color:var(--lime);color:var(--ink)}
200 641 repeating-linear-gradient(-45deg,var(--green-deep) 0 14px,#33195f 14px 28px);
201 642 display:flex;align-items:center;justify-content:center;overflow:hidden;
202 643 border-bottom:1.5px solid var(--ink)}
203 −.card-photo .init{color:var(--lime);font-family:var(--font-display);font-weight:700;
644 +.card-photo .init{color:var(--accent-soft);font-family:var(--font-display);font-weight:700;
204 645 font-size:46px;letter-spacing:.02em}
205 646 .card-photo img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
206 647 .card-photo .tier{position:absolute;top:10px;left:10px;z-index:2}
207 648 .card-photo .nplat{position:absolute;top:10px;right:10px;z-index:2;background:var(--ink);
208 − color:var(--lime);border:1.5px solid var(--ink);border-radius:var(--r-ctl);
649 + color:var(--accent-soft);border:1.5px solid var(--ink);border-radius:var(--r-ctl);
209 650 padding:2px 8px;font-family:var(--font-mono);font-size:9.5px;font-weight:700;
210 651 text-transform:uppercase;letter-spacing:.05em}
211 652 .tier{display:inline-flex;padding:2px 9px;border:1.5px solid var(--ink);
212 653 border-radius:var(--r-ctl);font-family:var(--font-mono);font-size:9.5px;
213 654 font-weight:700;text-transform:uppercase;letter-spacing:.06em;background:var(--surface);color:var(--ink)}
214 −.tier.mega{background:var(--lime)}
655 +.tier.mega{background:var(--accent);color:var(--on-accent)}
215 656 .tier.macro{background:var(--amber-soft)}
216 657 .card-body{padding:14px 15px 15px;display:flex;flex-direction:column;gap:9px;flex:1}
217 658 .card-name{font-family:var(--font-display);font-size:16px;font-weight:700;
@@ -221,7 +662,8 @@ select.f.active{background-color:var(--lime);color:var(--ink)}
221 662 text-transform:uppercase;letter-spacing:.05em;display:flex;gap:6px;align-items:center;flex-wrap:wrap;margin-top:-4px}
222 663 .chips{display:flex;gap:6px;flex-wrap:wrap}
223 664 .chip{background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r-ctl);
224 − padding:2px 10px;font-size:11px;font-weight:600;color:var(--ink-2);white-space:nowrap}
665 + padding:2px 10px;font-family:var(--font-body);font-size:11px;font-weight:600;color:var(--ink-2);
666 + white-space:nowrap;text-transform:none;letter-spacing:0}
225 667 .reach{font-size:12px;color:var(--ink-2)}
226 668 .reach b{font-family:var(--font-display);color:var(--ink);font-size:15.5px;font-weight:700}
227 669 .platrow{display:flex;gap:6px;flex-wrap:wrap;margin-top:auto;padding-top:2px}
@@ -248,22 +690,22 @@ select.f.active{background-color:var(--lime);color:var(--ink)}
248 690 @media(max-width:640px){.cpage-head{padding:22px 18px;gap:16px}}
249 691 .cavatar{width:104px;height:104px;border-radius:var(--r-card);
250 692 background:repeating-linear-gradient(-45deg,var(--green-deep) 0 14px,#33195f 14px 28px);
251 − color:var(--lime);flex:none;display:flex;align-items:center;justify-content:center;
693 + color:var(--accent-soft);flex:none;display:flex;align-items:center;justify-content:center;
252 694 font-family:var(--font-display);font-weight:700;font-size:36px;overflow:hidden;
253 − position:relative;border:2px solid var(--lime)}
695 + position:relative;border:2px solid var(--accent)}
254 696 @media(max-width:640px){.cavatar{width:76px;height:76px;font-size:26px}}
255 697 .cavatar img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
256 698 .cpage-head h1{font-size:clamp(24px,4vw,40px);font-weight:700;color:var(--paper);
257 699 line-height:1.1;display:flex;align-items:center;gap:10px;flex-wrap:wrap;text-transform:uppercase}
258 −.cpage-head h1 .vbadge{width:22px;height:22px;color:var(--lime)}
700 +.cpage-head h1 .vbadge{width:22px;height:22px;color:var(--accent-soft)}
259 701 .cpage-head .meta{display:flex;gap:7px;flex-wrap:wrap;margin-top:12px}
260 702 .mchip{background:rgba(245,243,238,.12);border:1px solid rgba(245,243,238,.3);
261 703 border-radius:var(--r-ctl);padding:3px 11px;font-family:var(--font-mono);
262 704 font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--paper)}
263 −.mchip.o{background:var(--lime);border-color:var(--lime);color:var(--ink)}
705 +.mchip.o{background:var(--accent);border-color:var(--accent);color:var(--on-accent)}
264 706 .cpage-reach{margin-left:auto;text-align:right}
265 707 .cpage-reach b{display:block;font-family:var(--font-display);
266 − font-size:clamp(28px,3.6vw,40px);font-weight:700;color:var(--lime);letter-spacing:-.02em}
708 + font-size:clamp(28px,3.6vw,40px);font-weight:700;color:var(--accent-soft);letter-spacing:-.02em}
267 709 .cpage-reach span{font-family:var(--font-mono);font-size:10px;color:rgba(245,243,238,.6);
268 710 text-transform:uppercase;letter-spacing:.08em;font-weight:700}
269 711 @media(max-width:760px){.cpage-reach{margin-left:0;text-align:left;flex-basis:100%}}
@@ -293,10 +735,10 @@ select.f.active{background-color:var(--lime);color:var(--ink)}
293 735 .conf.hi{background:var(--lime-soft);color:var(--green-deep)}
294 736 .conf.mid{background:var(--amber-soft);color:#8a5a12}
295 737 .linkinbio{display:inline-flex;align-items:center;gap:10px;margin-top:22px;
296 − background:var(--lime);color:var(--ink);border:1.5px solid var(--ink);
738 + background:var(--accent);color:var(--on-accent);border:1.5px solid var(--ink);
297 739 border-radius:var(--r-ctl);padding:11px 20px;font-family:var(--font-display);
298 740 font-weight:700;font-size:13.5px;transition:.15s;box-shadow:4px 4px 0 rgba(20,24,20,.25)}
299 −.linkinbio:hover{background:var(--lime-soft)}
741 +.linkinbio:hover{background:var(--accent-soft);color:var(--ink)}
300 742 .linkinbio:active{transform:translate(2px,2px);box-shadow:none}
301 743 .linkinbio svg{width:16px;height:16px;fill:currentColor}
302 744 .cpage-foot{margin-top:38px;font-size:12px;color:var(--ink-3);
@@ -313,7 +755,7 @@ select.f.active{background-color:var(--lime);color:var(--ink)}
313 755 .tile-k{font-family:var(--font-mono);font-size:9.5px;font-weight:700;text-transform:uppercase;
314 756 letter-spacing:.1em;color:var(--ink-3);margin-top:7px}
315 757 .tile.hero-tile{background:var(--ink)}
316 −.tile.hero-tile .tile-v{color:var(--lime)}
758 +.tile.hero-tile .tile-v{color:var(--accent-soft)}
317 759 .tile.hero-tile .tile-k{color:rgba(245,243,238,.55)}
318 760 .viz-card{background:var(--surface);border:1.5px solid var(--ink);border-radius:var(--r-card);
319 761 box-shadow:var(--shadow-off-soft);padding:24px 26px 18px;margin-bottom:22px}
@@ -343,27 +785,47 @@ select.f.active{background-color:var(--lime);color:var(--ink)}
343 785 padding:11px 14px;font:inherit;background:var(--surface);color:var(--ink);
344 786 box-shadow:3px 3px 0 rgba(20,24,20,.08);transition:box-shadow .15s ease}
345 787 .field input:focus,.field textarea:focus{outline:2px solid var(--green);outline-offset:1px;
346 − box-shadow:3px 3px 0 rgba(91,52,168,.25)}
788 + box-shadow:3px 3px 0 rgba(112,72,232,.25)}
347 789 @media(max-width:900px){.field input,.field textarea{font-size:16px}}
348 790 .optout-ok{background:var(--lime-soft);color:var(--green-deep);border:1.5px solid var(--ink);
349 791 border-radius:var(--r-card);padding:16px 20px;font-weight:600;margin-top:20px;
350 792 box-shadow:var(--shadow-off-soft)}
351 793 .optout-ok.warn{background:var(--amber-soft);color:#8a5a12}
352 794
353 −/* ===== footer + tab bar mobile (patron Lou-Ka) ===== */
354 −.footer{border-top:1.5px solid var(--ink);margin-top:40px;padding:32px 0 44px;background:var(--ink);color:var(--paper)}
355 −.footer-inner{display:flex;gap:26px;flex-wrap:wrap;align-items:flex-start;justify-content:space-between}
356 −.footer .brand{font-size:19px;color:var(--paper)}
357 −.footer .brand .ka{color:var(--ink)}
358 −.footer p{font-size:12px;color:rgba(245,243,238,.55);max-width:460px;margin:10px 0 0}
359 −.footer-links{display:flex;flex-direction:column;gap:9px;font-family:var(--font-mono);
360 − font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;
361 − color:rgba(245,243,238,.8)}
362 −.footer-links a:hover{color:var(--lime)}
363 −.fam-row{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px}
364 −.fam{border:1px solid rgba(245,243,238,.3);border-radius:var(--r-ctl);padding:3px 10px;
365 − font-family:var(--font-mono);font-size:10px;font-weight:700;color:rgba(245,243,238,.7)}
366 −.fam:hover{background:var(--lime);color:var(--ink);border-color:var(--lime)}
795 +/* ===== footer : nav locale + footer commun Groupe KA (ka/KaFooter) ===== */
796 +.footer-local{margin-top:56px;border-top:1.5px solid var(--ink);background:var(--surface);padding:16px 0}
797 +.footer-local nav{display:flex;gap:10px 26px;flex-wrap:wrap;align-items:center;
798 + font-family:var(--font-mono);font-size:11px;font-weight:700;
799 + text-transform:uppercase;letter-spacing:.08em;color:var(--ink-2)}
800 +.footer-local .klabel{color:var(--ink-3)}
801 +.footer-local a{display:inline-flex;align-items:center;min-height:44px}
802 +.footer-local a:hover{color:var(--accent-deep);text-decoration:underline;text-underline-offset:4px}
803 +.footer-local+.ka-footer{margin-top:0}
804 +.ka-footer .brand{font-size:19px;color:var(--paper)}
805 +
806 +/* ===== contact ===== */
807 +.contact-page{max-width:880px;margin:0 auto;padding:44px 0 70px}
808 +.contact-page h1{font-size:clamp(26px,4vw,38px);margin:12px 0;text-transform:uppercase}
809 +.contact-page .lead{color:var(--ink-2);max-width:640px}
810 +.contact-notice{background:var(--accent-soft);border:1.5px solid var(--ink);border-radius:var(--r-card);
811 + padding:16px 20px;margin:22px 0;box-shadow:var(--shadow-off-soft);font-weight:600;color:var(--ink)}
812 +.contact-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:14px;margin:8px 0 4px}
813 +.contact-card{display:block;background:var(--surface);border:1.5px solid var(--ink);
814 + border-radius:var(--r-card);padding:16px 18px;box-shadow:var(--shadow-off-soft);
815 + transition:transform .16s ease,box-shadow .16s ease;min-height:44px}
816 +.contact-card:hover{transform:translate(-2px,-2px);box-shadow:var(--shadow-off)}
817 +.contact-card b{display:block;font-family:var(--font-mono);font-size:13px;font-weight:700;
818 + color:var(--accent-deep);word-break:break-all}
819 +.contact-card span{display:block;margin-top:5px;font-size:12px;color:var(--ink-2)}
820 +.site-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:10px;margin:14px 0 0}
821 +.site-item{display:flex;align-items:center;gap:10px;background:var(--surface);
822 + border:1.5px solid var(--ink);border-radius:var(--r-ctl);padding:10px 13px;min-height:44px;
823 + transition:transform .15s ease,box-shadow .15s ease}
824 +.site-item:hover{transform:translate(-2px,-2px);box-shadow:3px 3px 0 var(--ink)}
825 +.site-item i{width:10px;height:10px;border-radius:3px;border:1px solid var(--ink);flex:none}
826 +.site-item b{font-family:var(--font-display);font-size:13.5px;font-weight:700}
827 +.site-item span{font-size:11px;color:var(--ink-3);margin-left:auto;font-family:var(--font-mono)}
828 +@media(max-width:480px){.site-item span{display:none}}
367 829 .tabbar{display:none}
368 830 @media(max-width:760px){
369 831 .tabbar{display:grid;grid-template-columns:repeat(4,1fr);
@@ -381,7 +843,7 @@ select.f.active{background-color:var(--lime);color:var(--ink)}
381 843 .tabbar a svg{display:block;width:20px;height:20px;fill:none;stroke:currentColor;
382 844 stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
383 845 body{padding-bottom:calc(64px + env(safe-area-inset-bottom))}
384 − .footer{padding-bottom:calc(76px + env(safe-area-inset-bottom))}
846 + .ka-footer{padding-bottom:calc(76px + env(safe-area-inset-bottom))}
385 847 }
386 848 .spin{width:26px;height:26px;border:3px solid var(--line);border-top-color:var(--green);
387 849 border-radius:50%;margin:50px auto;animation:sp .8s linear infinite}
@@ -392,8 +854,11 @@ select.f.active{background-color:var(--lime);color:var(--ink)}
392 854 <div id="app"></div>
393 855 <script>
394 856 "use strict";
395 −/* Créa-Ka SPA — routes : / · /createur/{id} · /stats · /retrait */
857 +/* Créa-Ka SPA — routes : / · /createur/{id} · /stats · /retrait · /compte · /contact */
396 858 const ICONS={"_author":"Simon-Pierre Boucher <contact@spboucher.ai>","_file":"frontend/src/icons.json","_desc":"Trac\u00e9s SVG des marques de plateformes (simple-icons v13, CC0) + glyphes maison (linkedin/site-web/autre)","instagram":"M7.0301.084c-1.2768.0602-2.1487.264-2.911.5634-.7888.3075-1.4575.72-2.1228 1.3877-.6652.6677-1.075 1.3368-1.3802 2.127-.2954.7638-.4956 1.6365-.552 2.914-.0564 1.2775-.0689 1.6882-.0626 4.947.0062 3.2586.0206 3.6671.0825 4.9473.061 1.2765.264 2.1482.5635 2.9107.308.7889.72 1.4573 1.388 2.1228.6679.6655 1.3365 1.0743 2.1285 1.38.7632.295 1.6361.4961 2.9134.552 1.2773.056 1.6884.069 4.9462.0627 3.2578-.0062 3.668-.0207 4.9478-.0814 1.28-.0607 2.147-.2652 2.9098-.5633.7889-.3086 1.4578-.72 2.1228-1.3881.665-.6682 1.0745-1.3378 1.3795-2.1284.2957-.7632.4966-1.636.552-2.9124.056-1.2809.0692-1.6898.063-4.948-.0063-3.2583-.021-3.6668-.0817-4.9465-.0607-1.2797-.264-2.1487-.5633-2.9117-.3084-.7889-.72-1.4568-1.3876-2.1228C21.2982 1.33 20.628.9208 19.8378.6165 19.074.321 18.2017.1197 16.9244.0645 15.6471.0093 15.236-.005 11.977.0014 8.718.0076 8.31.0215 7.0301.0839m.1402 21.6932c-1.17-.0509-1.8053-.2453-2.2287-.408-.5606-.216-.96-.4771-1.3819-.895-.422-.4178-.6811-.8186-.9-1.378-.1644-.4234-.3624-1.058-.4171-2.228-.0595-1.2645-.072-1.6442-.079-4.848-.007-3.2037.0053-3.583.0607-4.848.05-1.169.2456-1.805.408-2.2282.216-.5613.4762-.96.895-1.3816.4188-.4217.8184-.6814 1.3783-.9003.423-.1651 1.0575-.3614 2.227-.4171 1.2655-.06 1.6447-.072 4.848-.079 3.2033-.007 3.5835.005 4.8495.0608 1.169.0508 1.8053.2445 2.228.408.5608.216.96.4754 1.3816.895.4217.4194.6816.8176.9005 1.3787.1653.4217.3617 1.056.4169 2.2263.0602 1.2655.0739 1.645.0796 4.848.0058 3.203-.0055 3.5834-.061 4.848-.051 1.17-.245 1.8055-.408 2.2294-.216.5604-.4763.96-.8954 1.3814-.419.4215-.8181.6811-1.3783.9-.4224.1649-1.0577.3617-2.2262.4174-1.2656.0595-1.6448.072-4.8493.079-3.2045.007-3.5825-.006-4.848-.0608M16.953 5.5864A1.44 1.44 0 1 0 18.39 4.144a1.44 1.44 0 0 0-1.437 1.4424M5.8385 12.012c.0067 3.4032 2.7706 6.1557 6.173 6.1493 3.4026-.0065 6.157-2.7701 6.1506-6.1733-.0065-3.4032-2.771-6.1565-6.174-6.1498-3.403.0067-6.156 2.771-6.1496 6.1738M8 12.0077a4 4 0 1 1 4.008 3.9921A3.9996 3.9996 0 0 1 8 12.0077","tiktok":"M12.525.02c1.31-.02 2.61-.01 3.91-.02.08 1.53.63 3.09 1.75 4.17 1.12 1.11 2.7 1.62 4.24 1.79v4.03c-1.44-.05-2.89-.35-4.2-.97-.57-.26-1.1-.59-1.62-.93-.01 2.92.01 5.84-.02 8.75-.08 1.4-.54 2.79-1.35 3.94-1.31 1.92-3.58 3.17-5.91 3.21-1.43.08-2.86-.31-4.08-1.03-2.02-1.19-3.44-3.37-3.65-5.71-.02-.5-.03-1-.01-1.49.18-1.9 1.12-3.72 2.58-4.96 1.66-1.44 3.98-2.13 6.15-1.72.02 1.48-.04 2.96-.04 4.44-.99-.32-2.15-.23-3.02.37-.63.41-1.11 1.04-1.36 1.75-.21.51-.15 1.07-.14 1.61.24 1.64 1.82 3.02 3.5 2.87 1.12-.01 2.19-.66 2.77-1.61.19-.33.4-.67.41-1.06.1-1.79.06-3.57.07-5.36.01-4.03-.01-8.05.02-12.07z","youtube":"M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z","twitch":"M11.571 4.714h1.715v5.143H11.57zm4.715 0H18v5.143h-1.714zM6 0L1.714 4.286v15.428h5.143V24l4.286-4.286h3.428L22.286 12V0zm14.571 11.143l-3.428 3.428h-3.429l-3 3v-3H6.857V1.714h13.714Z","kick":"M1.333 0h8v5.333H12V2.667h2.667V0h8v8H20v2.667h-2.667v2.666H20V16h2.667v8h-8v-2.667H12v-2.666H9.333V24h-8Z","x":"M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z","facebook":"M9.101 23.691v-7.98H6.627v-3.667h2.474v-1.58c0-4.085 1.848-5.978 5.858-5.978.401 0 .955.042 1.468.103a8.68 8.68 0 0 1 1.141.195v3.325a8.623 8.623 0 0 0-.653-.036 26.805 26.805 0 0 0-.733-.009c-.707 0-1.259.096-1.675.309a1.686 1.686 0 0 0-.679.622c-.258.42-.374.995-.374 1.752v1.297h3.919l-.386 2.103-.287 1.564h-3.246v8.245C19.396 23.238 24 18.179 24 12.044c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.628 3.874 10.35 9.101 11.647Z","snapchat":"M12.206.793c.99 0 4.347.276 5.93 3.821.529 1.193.403 3.219.299 4.847l-.003.06c-.012.18-.022.345-.03.51.075.045.203.09.401.09.3-.016.659-.12 1.033-.301.165-.088.344-.104.464-.104.182 0 .359.029.509.09.45.149.734.479.734.838.015.449-.39.839-1.213 1.168-.089.029-.209.075-.344.119-.45.135-1.139.36-1.333.81-.09.224-.061.524.12.868l.015.015c.06.136 1.526 3.475 4.791 4.014.255.044.435.27.42.509 0 .075-.015.149-.045.225-.24.569-1.273.988-3.146 1.271-.059.091-.12.375-.164.57-.029.179-.074.36-.134.553-.076.271-.27.405-.555.405h-.03c-.135 0-.313-.031-.538-.074-.36-.075-.765-.135-1.273-.135-.3 0-.599.015-.913.074-.6.104-1.123.464-1.723.884-.853.599-1.826 1.288-3.294 1.288-.06 0-.119-.015-.18-.015h-.149c-1.468 0-2.427-.675-3.279-1.288-.599-.42-1.107-.779-1.707-.884-.314-.045-.629-.074-.928-.074-.54 0-.958.089-1.272.149-.211.043-.391.074-.54.074-.374 0-.523-.224-.583-.42-.061-.192-.09-.389-.135-.567-.046-.181-.105-.494-.166-.57-1.918-.222-2.95-.642-3.189-1.226-.031-.063-.052-.15-.055-.225-.015-.243.165-.465.42-.509 3.264-.54 4.73-3.879 4.791-4.02l.016-.029c.18-.345.224-.645.119-.869-.195-.434-.884-.658-1.332-.809-.121-.029-.24-.074-.346-.119-1.107-.435-1.257-.93-1.197-1.273.09-.479.674-.793 1.168-.793.146 0 .27.029.383.074.42.194.789.3 1.104.3.234 0 .384-.06.465-.105l-.046-.569c-.098-1.626-.225-3.651.307-4.837C7.392 1.077 10.739.807 11.727.807l.419-.015h.06z","substack":"M22.539 8.242H1.46V5.406h21.08v2.836zM1.46 10.812V24L12 18.11 22.54 24V10.812H1.46zM22.54 0H1.46v2.836h21.08V0z","patreon":"M22.957 7.21c-.004-3.064-2.391-5.576-5.191-6.482-3.478-1.125-8.064-.962-11.384.604C2.357 3.231 1.093 7.391 1.046 11.54c-.039 3.411.302 12.396 5.369 12.46 3.765.047 4.326-4.804 6.068-7.141 1.24-1.662 2.836-2.132 4.801-2.618 3.376-.836 5.678-3.501 5.673-7.031Z","onlyfans":"M24 4.003h-4.015c-3.45 0-5.3.197-6.748 1.957a7.996 7.996 0 1 0 2.103 9.211c3.182-.231 5.39-2.134 6.085-5.173 0 0-2.399.585-4.43 0 4.018-.777 6.333-3.037 7.005-5.995zM5.61 11.999A2.391 2.391 0 0 1 9.28 9.97a2.966 2.966 0 0 1 2.998-2.528h.008c-.92 1.778-1.407 3.352-1.998 5.263A2.392 2.392 0 0 1 5.61 12Zm2.386-7.996a7.996 7.996 0 1 0 7.996 7.996 7.996 7.996 0 0 0-7.996-7.996Zm0 10.394A2.399 2.399 0 1 1 10.395 12a2.396 2.396 0 0 1-2.399 2.398Z","threads":"M12.186 24h-.007c-3.581-.024-6.334-1.205-8.184-3.509C2.35 18.44 1.5 15.586 1.472 12.01v-.017c.03-3.579.879-6.43 2.525-8.482C5.845 1.205 8.6.024 12.18 0h.014c2.746.02 5.043.725 6.826 2.098 1.677 1.29 2.858 3.13 3.509 5.467l-2.04.569c-1.104-3.96-3.898-5.984-8.304-6.015-2.91.022-5.11.936-6.54 2.717C4.307 6.504 3.616 8.914 3.589 12c.027 3.086.718 5.496 2.057 7.164 1.43 1.783 3.631 2.698 6.54 2.717 2.623-.02 4.358-.631 5.8-2.045 1.647-1.613 1.618-3.593 1.09-4.798-.31-.71-.873-1.3-1.634-1.75-.192 1.352-.622 2.446-1.284 3.272-.886 1.102-2.14 1.704-3.73 1.79-1.202.065-2.361-.218-3.259-.801-1.063-.689-1.685-1.74-1.752-2.964-.065-1.19.408-2.285 1.33-3.082.88-.76 2.119-1.207 3.583-1.291a13.853 13.853 0 0 1 3.02.142c-.126-.742-.375-1.332-.75-1.757-.513-.586-1.308-.883-2.359-.89h-.029c-.844 0-1.992.232-2.721 1.32L7.734 7.847c.98-1.454 2.568-2.256 4.478-2.256h.044c3.194.02 5.097 1.975 5.287 5.388.108.046.216.094.321.142 1.49.7 2.58 1.761 3.154 3.07.797 1.82.871 4.79-1.548 7.158-1.85 1.81-4.094 2.628-7.277 2.65Zm1.003-11.69c-.242 0-.487.007-.739.021-1.836.103-2.98.946-2.916 2.143.067 1.256 1.452 1.839 2.784 1.767 1.224-.065 2.818-.543 3.086-3.71a10.5 10.5 0 0 0-2.215-.221z","podcast":"M5.34 0A5.328 5.328 0 000 5.34v13.32A5.328 5.328 0 005.34 24h13.32A5.328 5.328 0 0024 18.66V5.34A5.328 5.328 0 0018.66 0zm6.525 2.568c2.336 0 4.448.902 6.056 2.587 1.224 1.272 1.912 2.619 2.264 4.392.12.59.12 2.2.007 2.864a8.506 8.506 0 01-3.24 5.296c-.608.46-2.096 1.261-2.336 1.261-.088 0-.096-.091-.056-.46.072-.592.144-.715.48-.856.536-.224 1.448-.874 2.008-1.435a7.644 7.644 0 002.008-3.536c.208-.824.184-2.656-.048-3.504-.728-2.696-2.928-4.792-5.624-5.352-.784-.16-2.208-.16-3 0-2.728.56-4.984 2.76-5.672 5.528-.184.752-.184 2.584 0 3.336.456 1.832 1.64 3.512 3.192 4.512.304.2.672.408.824.472.336.144.408.264.472.856.04.36.03.464-.056.464-.056 0-.464-.176-.896-.384l-.04-.03c-2.472-1.216-4.056-3.274-4.632-6.012-.144-.706-.168-2.392-.03-3.04.36-1.74 1.048-3.1 2.192-4.304 1.648-1.737 3.768-2.656 6.128-2.656zm.134 2.81c.409.004.803.04 1.106.106 2.784.62 4.76 3.408 4.376 6.174-.152 1.114-.536 2.03-1.216 2.88-.336.43-1.152 1.15-1.296 1.15-.023 0-.048-.272-.048-.603v-.605l.416-.496c1.568-1.878 1.456-4.502-.256-6.224-.664-.67-1.432-1.064-2.424-1.246-.64-.118-.776-.118-1.448-.008-1.02.167-1.81.562-2.512 1.256-1.72 1.704-1.832 4.342-.264 6.222l.413.496v.608c0 .336-.027.608-.06.608-.03 0-.264-.16-.512-.36l-.034-.011c-.832-.664-1.568-1.842-1.872-2.997-.184-.698-.184-2.024.008-2.72.504-1.878 1.888-3.335 3.808-4.019.41-.145 1.133-.22 1.814-.211zm-.13 2.99c.31 0 .62.06.844.178.488.253.888.745 1.04 1.259.464 1.578-1.208 2.96-2.72 2.254h-.015c-.712-.331-1.096-.956-1.104-1.77 0-.733.408-1.371 1.112-1.745.224-.117.534-.176.844-.176zm-.011 4.728c.988-.004 1.706.349 1.97.97.198.464.124 1.932-.218 4.302-.232 1.656-.36 2.074-.68 2.356-.44.39-1.064.498-1.656.288h-.003c-.716-.257-.87-.605-1.164-2.644-.341-2.37-.416-3.838-.218-4.302.262-.616.974-.966 1.97-.97z","linktree":"m13.73635 5.85251 4.00467-4.11665 2.3248 2.3808-4.20064 4.00466h5.9085v3.30473h-5.9365l4.22865 4.10766-2.3248 2.3338L12.0005 12.099l-5.74052 5.76852-2.3248-2.3248 4.22864-4.10766h-5.9375V8.12132h5.9085L3.93417 4.11666l2.3248-2.3808 4.00468 4.11665V0h3.4727zm-3.4727 10.30614h3.4727V24h-3.4727z","linkedin":"M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.225 0z","site-web":"M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12 12-5.373 12-12S18.627 0 12 0zm7.938 9h-3.243a15.6 15.6 0 00-1.4-4.653A8.03 8.03 0 0119.938 9zM12 2.05c.9 1.2 1.9 3.2 2.5 6.95h-5C10.1 5.25 11.1 3.25 12 2.05zM4.062 15A8.06 8.06 0 013.75 12c0-1.05.15-2.05.312-3h3.55A25 25 0 007.5 12c0 1.05.05 2.05.113 3zm.643 2h3.243c.35 1.8.85 3.35 1.4 4.653A8.03 8.03 0 014.705 17zm3.243-10H4.705a8.03 8.03 0 014.643-4.653A15.6 15.6 0 007.948 7zM12 21.95c-.9-1.2-1.9-3.2-2.5-6.95h5c-.6 3.75-1.6 5.75-2.5 6.95zM14.787 13H9.213A23 23 0 019.1 12c0-1.05.037-2.05.113-3h5.574c.076.95.113 1.95.113 3s-.037 2.05-.113 3zm.508 8.653c.55-1.303 1.05-2.853 1.4-4.653h3.243a8.03 8.03 0 01-4.643 4.653zM16.388 15c.062-.95.112-1.95.112-3s-.05-2.05-.112-3h3.55c.162.95.312 1.95.312 3s-.15 2.05-.312 3z","autre":"M10.59 13.41a1 1 0 010-1.41l2.83-2.83a3 3 0 114.24 4.24l-1.41 1.42a1 1 0 11-1.42-1.42l1.42-1.41a1 1 0 10-1.42-1.42L12 13.41a1 1 0 01-1.41 0zm2.82-2.82a1 1 0 010 1.41l-2.82 2.83a3 3 0 11-4.25-4.24l1.42-1.42a1 1 0 111.41 1.42L7.76 12a1 1 0 101.41 1.41L12 10.59a1 1 0 011.41 0z"};
859 +/* écosystème Groupe KA (ka/ecosystem.json, injecté au build) — footer commun + /contact */
860 +const KA_ECO={"org":{"name":"Groupe KA","legalName":"Groupe KA — Simon-Pierre Boucher","tagline":"Holding québécois d'agrégateurs de produits et services entièrement automatisés.","disclaimer":"Groupe KA est un agrégateur de contenu : nous ne vendons rien, ne louons rien et ne sommes partie à aucune transaction.","copyrightHolder":"Groupe KA — Simon-Pierre Boucher"},"hub":{"url":"https://www.groupe-ka.com","loginPath":"/connexion","signupNote":"La création de compte KA ID se fait sur le hub groupe-ka.com ; chaque site délègue sa connexion via /api/auth/ka/login."},"contacts":[{"email":"contact@groupe-ka.com","role":"Projets, partenariats & données"},{"email":"info@groupe-ka.com","role":"Médias & questions générales"},{"email":"admin@groupe-ka.com","role":"Légal, vie privée & Loi 25"}],"legal":[{"label":"Conditions d'utilisation","href":"https://www.groupe-ka.com/conditions"},{"label":"Politique de confidentialité","href":"https://www.groupe-ka.com/confidentialite"},{"label":"Protection des renseignements personnels (Loi 25)","href":"https://www.groupe-ka.com/loi-25"},{"label":"Transparence des robots d'indexation","href":"https://www.groupe-ka.com/bots"}],"sites":[{"id":"groupe-ka","wordmark":"Groupe KA","domain":"www.groupe-ka.com","accent":"#d9f26b","accentSoft":"#f0f9d2","accentDeep":"#123f2e","onAccent":"#141814","tagline":"Le portail de l'écosystème ·Ka"},{"id":"trouve-ka","wordmark":"Trouve·Ka","domain":"www.trouve-ka.com","accent":"#1c7ed6","accentSoft":"#e7f2fd","accentDeep":"#14508f","onAccent":"#ffffff","tagline":"Le moteur de recherche du web québécois"},{"id":"lou-ka","wordmark":"Lou·Ka","domain":"www.lou-ka.com","accent":"#ff6a00","accentSoft":"#fff1e6","accentDeep":"#cc5500","onAccent":"#ffffff","tagline":"Tous les logements à louer"},{"id":"immo-ka","wordmark":"Immo·Ka","domain":"www.immo-ka.com","accent":"#e23744","accentSoft":"#fbe0e2","accentDeep":"#a8232e","onAccent":"#ffffff","tagline":"Toutes les propriétés à vendre"},{"id":"vrai-prix","wordmark":"Vrai-Prix","domain":"www.vrai-prix.com","accent":"#ff5148","accentSoft":"#ffe3e0","accentDeep":"#9e2a25","onAccent":"#ffffff","tagline":"La valeur réelle de chaque propriété"},{"id":"auto-ka","wordmark":"Auto·Ka","domain":"www.auto-ka.com","accent":"#ff5a2a","accentSoft":"#ffe8de","accentDeep":"#cc3f16","onAccent":"#ffffff","tagline":"Les voitures usagées du Québec"},{"id":"fabri-ka","wordmark":"Fabri·Ka","domain":"www.fabri-ka.com","accent":"#c4532e","accentSoft":"#f7e3da","accentDeep":"#a94525","onAccent":"#ffffff","tagline":"Les produits fabriqués au Québec"},{"id":"food-ka","wordmark":"Food·Ka","domain":"www.food-ka.com","accent":"#1f9d55","accentSoft":"#e2f5ea","accentDeep":"#157a40","onAccent":"#ffffff","tagline":"Les prix d'épicerie, suivis à la source"},{"id":"resto-ka","wordmark":"Resto·Ka","domain":"www.resto-ka.com","accent":"#f08c00","accentSoft":"#fdeed7","accentDeep":"#b96a00","onAccent":"#141814","tagline":"Chaque resto, chaque plat, chaque prix"},{"id":"sorti-ka","wordmark":"Sorti·Ka","domain":"www.sorti-ka.com","accent":"#d6336c","accentSoft":"#fbe0eb","accentDeep":"#a12551","onAccent":"#ffffff","tagline":"Toutes les sorties, dans les 17 régions"},{"id":"crea-ka","wordmark":"Créa·Ka","domain":"www.crea-ka.com","accent":"#7048e8","accentSoft":"#ece5fc","accentDeep":"#5433b8","onAccent":"#ffffff","tagline":"Les créateurs d'ici, tous leurs liens"},{"id":"api-ka","wordmark":"API·Ka","domain":"www.api-ka.com","accent":"#3b5bdb","accentSoft":"#e4eafb","accentDeep":"#2b44a8","onAccent":"#ffffff","tagline":"La donnée de l'écosystème, par API"}],"extraFooterLinks":[{"label":"ValoPlex","href":"https://www.valoplex.com"},{"label":"Ka2","href":"https://www.ka2.bot"},{"label":"Ka4","href":"https://www.ka4.bot"},{"label":"Ka6","href":"https://www.ka6.bot"}]};
861 +const KA_SITE=KA_ECO.sites.find(s=>s.id==="crea-ka");
397 862 const $=s=>document.querySelector(s);
398 863 const app=$("#app");
399 864 const fmt=new Intl.NumberFormat("fr-CA",{notation:"compact",maximumFractionDigits:1});
@@ -413,7 +878,7 @@ const PLAT={
413 878 linkedin:{label:"LinkedIn",color:"#0a66c2"},
414 879 threads:{label:"Threads",color:"#141814"},
415 880 podcast:{label:"Balado",color:"#8940fa"},
416 − "site-web":{label:"Site web",color:"#5b34a8"},
881 + "site-web":{label:"Site web",color:"#7048e8"},
417 882 autre:{label:"Autre",color:"#8b928c"}};
418 883 const NICHE_LBL={"humour":"Humour","mode":"Mode","beaute":"Beauté","lifestyle":"Lifestyle",
419 884 "famille-parentalite":"Famille","cuisine":"Cuisine","gaming":"Gaming","tech":"Tech",
@@ -453,15 +918,18 @@ function photoImg(c){
453 918 return `<img loading="lazy" alt="${esc(c.display_name)}" src="${srcs[0]}"
454 919 data-srcs='${esc(JSON.stringify(srcs))}' data-i="0" onerror="nextSrc(this)">`;
455 920 }
456 −const brandSvg=`<svg width="30" height="30" viewBox="0 0 64 64"><rect width="64" height="64" rx="10" fill="#141814"/><circle cx="32" cy="23" r="9" fill="#c9a3ff"/><path d="M14 52c3-10 9-15 18-15s15 5 18 15" stroke="#c9a3ff" stroke-width="6" fill="none" stroke-linecap="round"/></svg>`;
921 +const brandSvg=`<svg width="30" height="30" viewBox="0 0 64 64"><rect width="64" height="64" rx="10" fill="#141814"/><circle cx="32" cy="23" r="9" fill="#7048e8"/><path d="M14 52c3-10 9-15 18-15s15 5 18 15" stroke="#7048e8" stroke-width="6" fill="none" stroke-linecap="round"/></svg>`;
457 922
458 923 function header(){
459 924 return `<header class="header"><div class="container header-inner">
460 925 <a href="/" data-nav class="brand">${brandSvg}Créa<span class="ka">Ka</span></a>
926 + <a class="gk-badge" href="https://www.groupe-ka.com" target="_blank" rel="noopener noreferrer"
927 + aria-label="Un service Groupe KA — visiter le portail de l'écosystème"><span class="pfx">Un service</span>
928 + <b>Groupe<span class="ka">KA</span></b></a>
461 929 <span class="brand-tag">Tous les créateurs québécois.<br>Tous leurs liens.</span>
462 930 <span class="header-spacer"></span>
463 931 <a class="hbtn" href="/stats" data-nav>Statistiques</a>
464 − <a class="hbtn" href="/retrait" data-nav>Retrait</a>
932 + <a class="hbtn" href="/contact" data-nav>Contact</a>
465 933 <a class="hbtn primary" href="/#annuaire" data-nav>Explorer l'annuaire</a>
466 934 <span id="acct-slot"></span>
467 935 </div></header>`;
@@ -479,7 +947,7 @@ async function loadAccount(){
479 947 <span class="ka-badge">KA</span></a>`;
480 948 }else{
481 949 slot.innerHTML=`<a class="hbtn acct" href="/api/auth/ka/login"
482 − title="Se connecter avec KA ID">Se connecter <span class="ka-badge">KA</span></a>`;
950 + title="Se connecter avec KA ID"><span class="acct-long">Se connecter avec</span><span class="acct-short">Connexion</span> <span class="ka-badge">KA</span></a>`;
483 951 }
484 952 bindNav(slot);
485 953 }
@@ -492,26 +960,41 @@ function tabbar(active){
492 960 ${t("/retrait","Retrait",`<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="9"/><path d="M8 12h8"/></svg>`,"optout")}
493 961 </nav>`;
494 962 }
963 +/* footer commun Groupe KA (équivalent vanilla de ka/KaFooter.tsx, siteId
964 + "crea-ka", localLegal = /retrait) — nav locale conservée au-dessus */
495 965 function footer(){
496 − return `<footer class="footer"><div class="container footer-inner">
497 − <div><span class="brand">${brandSvg}Créa<span class="ka" style="background:var(--lime)">Ka</span></span>
498 − <p>Annuaire public des créateurs de contenu québécois. Uniquement des profils publics
499 − et professionnels ; aucune donnée privée. Retrait simple et respecté (Loi 25).
500 − — Simon-Pierre Boucher</p>
501 − <div class="fam-row"><span class="klabel" style="color:rgba(245,243,238,.5);align-self:center">Groupe KA :</span>
502 − <a class="fam" href="https://www.groupe-ka.com" target="_blank" rel="noopener">KA ID</a>
503 − <a class="fam" href="https://www.lou-ka.com" target="_blank" rel="noopener">Lou-Ka</a>
504 − <a class="fam" href="https://www.immo-ka.com" target="_blank" rel="noopener">Immo-Ka</a>
505 − <a class="fam" href="https://www.auto-ka.com" target="_blank" rel="noopener">Auto-Ka</a>
506 − <a class="fam" href="https://www.food-ka.com" target="_blank" rel="noopener">Food-Ka</a>
507 − <a class="fam" href="https://www.fabri-ka.com" target="_blank" rel="noopener">Fabri-Ka</a></div></div>
508 − <div class="footer-links">
966 + const year=new Date().getFullYear();
967 + const others=KA_ECO.sites.filter(s=>s.id!=="crea-ka");
968 + const localLegal=[{label:"Retrait (opt-out)",href:"/retrait",nav:true}];
969 + return `<div class="footer-local"><div class="container"><nav>
970 + <span class="klabel">Créa·Ka</span>
509 971 <a href="/compte" data-nav>Mon compte KA ID</a>
510 972 <a href="/stats" data-nav>Statistiques</a>
511 973 <a href="/retrait" data-nav>Demander un retrait</a>
974 + <a href="/contact" data-nav>Contact</a>
512 975 <a href="/api/stats" target="_blank" rel="noopener">API publique</a>
976 + </nav></div></div>
977 + <footer class="ka-footer" id="contact-footer">
978 + <div class="container">
979 + <a class="wordmark" href="${esc(KA_ECO.hub.url)}" target="_blank" rel="noopener noreferrer"
980 + aria-label="Groupe KA — le portail de l'écosystème">Groupe <span class="ka">KA</span></a>
981 + <p class="desc">${esc(KA_ECO.org.tagline)} Des centaines de connecteurs lisent les sites à la
982 + source, normalisent la donnée et se resynchronisent seuls.
983 + <b style="color:var(--paper)">${esc(KA_SITE.wordmark)}</b> — ${esc(KA_SITE.tagline)} — est un service Groupe KA.</p>
984 + <p class="notice"><b>${esc(KA_ECO.org.disclaimer)}</b></p>
985 + <ul class="sites">
986 + ${others.map(s=>`<li><a href="https://${esc(s.domain)}" target="_blank" rel="noopener noreferrer">${esc(s.wordmark)}</a></li>`).join("")}
987 + ${(KA_ECO.extraFooterLinks||[]).map(l=>`<li><a href="${esc(l.href)}" target="_blank" rel="noopener noreferrer">${esc(l.label)}</a></li>`).join("")}
988 + </ul>
989 + <div class="contacts">
990 + ${KA_ECO.contacts.map(c=>`<p style="margin:0"><a href="mailto:${esc(c.email)}">${esc(c.email)}</a><span>${esc(c.role)}</span></p>`).join("")}
991 + </div>
992 + <p class="legal">© ${year} ${esc(KA_ECO.org.copyrightHolder)}
993 + ${localLegal.map(l=>` · <a href="${esc(l.href)}"${l.nav?" data-nav":""}>${esc(l.label)}</a>`).join("")}
994 + ${KA_ECO.legal.map(l=>` · <a href="${esc(l.href)}" target="_blank" rel="noopener noreferrer">${esc(l.label)}</a>`).join("")}
995 + </p>
513 996 </div>
514 − </div></footer>`;
997 + </footer>`;
515 998 }
516 999
517 1000 /* ---------- annuaire ---------- */
@@ -542,7 +1025,7 @@ function selectHtml(id,label,opts,val,lbls){
542 1025 return `<select class="f${val?" active":""}" id="${id}"><option value="">${label}</option>${o}</select>`;
543 1026 }
544 1027 async function renderHome(){
545 − document.title="Créa-Ka — Tous les créateurs québécois. Tous leurs liens.";
1028 + document.title="Créa-Ka — Un service Groupe KA";
546 1029 if(!state.tax)state.tax=await api("/api/taxonomies");
547 1030 if(!state.stats)state.stats=await api("/api/stats").catch(()=>null);
548 1031 const s=state.stats||{creators:0,accounts:0,by_platform:{}};
@@ -703,6 +1186,7 @@ async function renderCompte(){
703 1186 les autres plateformes du Groupe KA. Créez-le en une minute si vous n'en avez pas.</p>
704 1187 <div class="compte-actions">
705 1188 <a class="btn btn-primary" href="/api/auth/ka/login">Se connecter avec KA ID</a>
1189 + <a class="btn btn-accent" href="https://www.groupe-ka.com/connexion" target="_blank" rel="noopener">Créer un compte KA ID ↗</a>
706 1190 <a class="btn btn-ghost" href="https://www.groupe-ka.com" target="_blank" rel="noopener">Qu'est-ce que KA ID ?</a>
707 1191 </div>
708 1192 </div>`+footer()+tabbar("");
@@ -742,6 +1226,38 @@ async function renderCompte(){
742 1226 state.me=null;history.pushState(null,"","/");route();});
743 1227 }
744 1228
1229 +/* ---------- page contact (écosystème Groupe KA — ka/ecosystem.json) ---------- */
1230 +function renderContact(){
1231 + document.title="Contact — Créa-Ka, un service Groupe KA";
1232 + const sites=KA_ECO.sites.map(s=>{
1233 + const cur=s.id==="crea-ka";
1234 + return `<a class="site-item" href="https://${esc(s.domain)}"${cur?"":' target="_blank" rel="noopener noreferrer"'}
1235 + title="${esc(s.tagline)}"><i style="background:${esc(s.accent)}"></i><b>${esc(s.wordmark)}${cur?" (ici)":""}</b><span>${esc(s.domain)}</span></a>`;
1236 + }).join("");
1237 + app.innerHTML=header()+`
1238 + <div class="container contact-page">
1239 + <span class="kicker">Contact — Groupe KA</span>
1240 + <h1>Nous <span class="hl">joindre.</span></h1>
1241 + <p class="lead">${esc(KA_SITE.wordmark)} — ${esc(KA_SITE.tagline)} — est un service du
1242 + <b>Groupe KA</b>. ${esc(KA_ECO.org.tagline)} Les contacts ci-dessous valent pour
1243 + l'ensemble des plateformes du groupe.</p>
1244 + <div class="contact-notice">${esc(KA_ECO.org.disclaimer)}</div>
1245 + <h2 class="sect-title" style="margin-top:26px">Courriels</h2>
1246 + <div class="contact-grid">
1247 + ${KA_ECO.contacts.map(c=>`<a class="contact-card" href="mailto:${esc(c.email)}">
1248 + <b>${esc(c.email)}</b><span>${esc(c.role)}</span></a>`).join("")}
1249 + </div>
1250 + <div class="compte-actions" style="margin-top:22px">
1251 + <a class="btn btn-primary" href="${esc(KA_ECO.hub.url)}" target="_blank" rel="noopener noreferrer">Visiter le hub groupe-ka.com ↗</a>
1252 + <a class="btn btn-ghost" href="/retrait" data-nav>Demander un retrait (Loi 25)</a>
1253 + </div>
1254 + <h2 class="sect-title">Les plateformes du groupe</h2>
1255 + <div class="site-list">${sites}</div>
1256 + <p style="font-size:12px;color:var(--ink-3);margin-top:20px">${esc(KA_ECO.hub.signupNote)}</p>
1257 + </div>`+footer()+tabbar("");
1258 + bindNav();window.scrollTo(0,0);
1259 +}
1260 +
745 1261 /* ---------- retrait / opt-out ---------- */
746 1262 function renderOptout(){
747 1263 document.title="Retrait (opt-out) — Créa-Ka";
@@ -793,6 +1309,7 @@ function route(){
793 1309 else if(p==="/retrait")r=renderOptout();
794 1310 else if(p==="/stats")r=renderStats();
795 1311 else if(p==="/compte")r=renderCompte();
1312 + else if(p==="/contact")r=renderContact();
796 1313 else r=renderHome();
797 1314 Promise.resolve(r).then(()=>loadAccount()).catch(()=>{});
798 1315 }
modified frontend/src/index.template.html +178 −119
@@ -1,88 +1,61 @@
1 1 <!--
2 2 Author: Simon-Pierre Boucher <contact@spboucher.ai>
3 3 File: frontend/src/index.template.html
4 − Desc: Gabarit du frontend Créa-Ka — __ICONS__ est remplacé par les tracés
5 − SVG des marques (simple-icons, CC0) via scripts/build_frontend.py.
6 − Système de design « éditorial sharp » du Groupe KA (identité partagée
7 − avec groupe-ka.com, Vrai-Prix, ValoPlex : papier grainé #f5f3ee, encre
8 − #141814, bordures encre + ombres décalées dures, Space Grotesk / Inter
9 − / JetBrains Mono) — accent propre Créa-Ka : VIOLET ÉLECTRIQUE.
10 − Patrons mobiles calqués sur Lou-Ka (tab bar 4 onglets, filtres
11 − défilants, anti-zoom iOS). Routes : / · /createur/{id} · /stats · /retrait
4 + Desc: Gabarit du frontend Créa-Ka — marqueurs remplacés par
5 + scripts/build_frontend.py : __ICONS__ (tracés SVG simple-icons, CC0),
6 + __KA_TOKENS__ (ka/tokens.css — design system commun Groupe KA,
7 + importé EN PREMIER) et __KA_ECO__ (ka/ecosystem.json — contacts,
8 + sites, mentions légales du groupe : footer commun + page /contact).
9 + Système « éditorial sharp » du Groupe KA (papier grainé #f5f3ee,
10 + encre #141814, bordures encre + ombres décalées dures, Space Grotesk
11 + / Inter / JetBrains Mono) — accent attribué à Créa-Ka : VIOLET
12 + (--accent:#7048e8). Patrons mobiles calqués sur Lou-Ka (tab bar
13 + 4 onglets, filtres défilants, anti-zoom iOS).
14 + Routes : / · /createur/{id} · /stats · /retrait · /compte · /contact
12 15 -->
13 16 <!DOCTYPE html>
14 17 <html lang="fr">
15 18 <head>
16 19 <meta charset="utf-8">
17 20 <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
18 −<title>Créa-Ka — Tous les créateurs québécois. Tous leurs liens.</title>
21 +<title>Créa-Ka — Un service Groupe KA</title>
19 22 <meta name="description" content="Annuaire public des créateurs de contenu et influenceurs québécois : tous leurs comptes (Instagram, TikTok, YouTube, Twitch…) regroupés, cherchables par niche, région, langue et taille d'audience.">
20 23 <meta name="theme-color" content="#141814">
21 24 <link rel="preconnect" href="https://fonts.googleapis.com">
22 25 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
23 26 <link rel="preconnect" href="https://unavatar.io">
24 27 <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;600;700&family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@500;700&display=swap" rel="stylesheet">
25 −<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='10' fill='%23141814'/%3E%3Ccircle cx='32' cy='23' r='9' fill='%23c9a3ff'/%3E%3Cpath d='M14 52c3-10 9-15 18-15s15 5 18 15' stroke='%23c9a3ff' stroke-width='6' fill='none' stroke-linecap='round'/%3E%3C/svg%3E">
28 +<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='10' fill='%23141814'/%3E%3Ccircle cx='32' cy='23' r='9' fill='%237048e8'/%3E%3Cpath d='M14 52c3-10 9-15 18-15s15 5 18 15' stroke='%237048e8' stroke-width='6' fill='none' stroke-linecap='round'/%3E%3C/svg%3E">
26 29 <style>
27 −/* système « éditorial sharp » Groupe KA — accent Créa-Ka : violet électrique.
28 − Convention du groupe : les NOMS de variables (--green/--lime) sont partagés
29 − entre les apps, seules les VALEURS changent. */
30 +/* ka/tokens.css — design system commun Groupe KA, importé EN PREMIER
31 + (injecté au build par scripts/build_frontend.py) */
32 +__KA_TOKENS__
33 +</style>
34 +<style>
35 +/* Surcharges Créa-Ka par-dessus ka/tokens.css. Convention du groupe : les
36 + NOMS de variables sont partagés (--accent/--lime), seules les VALEURS
37 + changent — accent attribué à Créa-Ka : VIOLET. */
30 38 :root{
31 − --paper:#f5f3ee; --surface:#fff; --surface-2:#faf9f5;
32 − --ink:#141814; --ink-2:#4d5551; --ink-3:#8b928c;
33 − --line:rgba(20,24,20,.14); --line-strong:rgba(20,24,20,.85);
34 − --green:#5b34a8; /* violet profond (primaire) */
39 + --accent:#7048e8; --accent-soft:#ece5fc; --accent-deep:#5433b8; --on-accent:#ffffff;
40 + /* alias rétro-compatibles (le CSS historique du site utilise --lime) */
41 + --lime:var(--accent); --lime-soft:var(--accent-soft);
42 + --green:var(--accent-deep); /* primaire du site = violet profond */
35 43 --green-deep:#3d2178;
36 − --lime:#c9a3ff; /* violet électrique (accent) */
37 − --lime-soft:#efe6ff;
38 − --amber:#e8a33d; --amber-soft:#fdf3e2;
39 − --danger:#b3423a;
40 − --r-card:10px; --r-ctl:6px; --r-pill:999px;
41 − --shadow-flat:0 1px 2px rgba(20,24,20,.05);
42 − --shadow-off:6px 6px 0 var(--ink);
43 − --shadow-off-soft:8px 8px 0 rgba(20,24,20,.08);
44 − --font-display:"Space Grotesk",system-ui,sans-serif;
45 − --font-body:"Inter",system-ui,sans-serif;
46 − --font-mono:"JetBrains Mono",ui-monospace,monospace;
47 44 }
48 −*{box-sizing:border-box}
49 −html{scroll-behavior:smooth}
50 −body{margin:0;background:var(--paper);color:var(--ink);font-family:var(--font-body);
51 − font-size:15px;line-height:1.55;-webkit-font-smoothing:antialiased;
52 − padding-bottom:env(safe-area-inset-bottom)}
53 −/* grain de film pleine page (signature du groupe) — aucun z-index sur body>* */
54 −body::before{content:"";position:fixed;inset:0;pointer-events:none;opacity:.35;z-index:9999;
55 − background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='linear' slope='0.06'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)'/%3E%3C/svg%3E")}
56 −body>*{position:relative}
57 −h1,h2,h3,h4{font-family:var(--font-display);letter-spacing:-.03em;margin:0}
58 −a{color:inherit;text-decoration:none} button{font-family:inherit;cursor:pointer} img{display:block}
59 −::selection{background:var(--lime);color:var(--ink)}
60 −:focus-visible{outline:2px solid var(--green);outline-offset:2px}
45 +/* le layout du site est calibré sur des titres sans marge basse */
46 +h1,h2,h3,h4{margin:0}
47 +a{text-decoration:none} button{font-family:inherit;cursor:pointer}
61 48 .icn{width:1em;height:1em;display:block;fill:currentColor}
62 49 .container{max-width:1240px;margin:0 auto;padding:0 24px}
63 50 @media(max-width:640px){.container{padding:0 16px}}
64 −.kicker{display:inline-flex;align-items:center;gap:10px;font-family:var(--font-mono);
65 − font-size:11.5px;font-weight:500;text-transform:uppercase;letter-spacing:.12em;color:var(--green)}
66 −.kicker::before{content:"";width:22px;height:2px;background:var(--green)}
67 −.klabel{font-family:var(--font-mono);font-size:10px;font-weight:700;
68 − text-transform:uppercase;letter-spacing:.1em;color:var(--ink-3)}
69 −.hl{display:inline-block;background:var(--lime);border-radius:8px;padding:0 10px 2px;transform:rotate(-1deg)}
70 −.outline-txt{color:transparent;-webkit-text-stroke:2px var(--ink)}
71 51
72 52 /* ---------- cartes & boutons (langage du groupe) ---------- */
73 53 .gk-card{background:var(--surface);border:1.5px solid var(--ink);
74 54 border-radius:var(--r-card);box-shadow:var(--shadow-off-soft)}
75 55 .gk-hover{transition:transform .18s ease,box-shadow .18s ease}
76 56 .gk-hover:hover{transform:translate(-3px,-3px);box-shadow:var(--shadow-off)}
77 −.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:44px;
78 − padding:10px 20px;border:1.5px solid var(--ink);border-radius:var(--r-ctl);
79 − font-family:var(--font-display);font-size:14px;font-weight:700;cursor:pointer;
80 − transition:background .15s ease,transform .1s ease,box-shadow .1s ease}
81 57 .btn:active{transform:translate(2px,2px);box-shadow:none!important}
82 −.btn-primary{background:var(--ink);color:var(--lime);box-shadow:4px 4px 0 rgba(20,24,20,.25)}
83 −.btn-primary:hover{background:var(--green-deep)}
84 −.btn-ghost{background:transparent;color:var(--ink)}
85 −.btn-ghost:hover{background:var(--lime)}
58 +.btn-primary{box-shadow:4px 4px 0 rgba(20,24,20,.25)}
86 59
87 60 /* ===== header ===== */
88 61 .header{position:sticky;top:0;z-index:50;background:rgba(245,243,238,.9);
@@ -91,26 +64,35 @@ a{color:inherit;text-decoration:none} button{font-family:inherit;cursor:pointer}
91 64 .brand{font-family:var(--font-display);font-weight:700;font-size:23px;letter-spacing:-.03em;
92 65 display:flex;align-items:center;line-height:1;color:var(--ink)}
93 66 .brand svg{margin-right:11px;flex:none}
94 −.brand .ka{background:var(--lime);border-radius:6px;padding:0 6px 1px;margin-left:2px;transform:rotate(-1deg)}
67 +.brand .ka{background:var(--accent);color:var(--on-accent);border-radius:6px;padding:0 6px 1px;margin-left:2px;transform:rotate(-1deg)}
95 68 .brand-tag{font-family:var(--font-mono);font-size:10px;font-weight:500;color:var(--ink-3);
96 69 line-height:1.5;text-transform:uppercase;letter-spacing:.08em}
97 70 @media(max-width:900px){.brand-tag{display:none}}
98 71 .header-spacer{flex:1}
99 72 .hbtn{border:1.5px solid var(--ink);background:var(--surface);color:var(--ink);
100 − border-radius:var(--r-ctl);padding:8px 16px;font-family:var(--font-display);
73 + border-radius:var(--r-ctl);padding:8px 16px;min-height:44px;font-family:var(--font-display);
101 74 font-size:13px;font-weight:700;transition:.15s;display:inline-flex;align-items:center;
102 75 gap:8px;white-space:nowrap;box-shadow:3px 3px 0 rgba(20,24,20,.12)}
103 −.hbtn:hover{background:var(--lime)}
76 +.hbtn:hover{background:var(--accent);color:var(--on-accent)}
104 77 .hbtn:active{transform:translate(2px,2px);box-shadow:none}
105 −.hbtn.primary{background:var(--ink);color:var(--lime)}
106 −.hbtn.primary:hover{background:var(--green-deep)}
78 +.hbtn.primary{background:var(--ink);color:var(--accent)}
79 +.hbtn.primary:hover{background:var(--accent-deep);color:var(--on-accent)}
107 80 @media(max-width:760px){.header .hbtn:not(.acct){display:none}}
108 81 /* bouton / jeton de compte KA ID — toujours visible, même sur mobile */
109 82 .hbtn.acct{padding:7px 14px}
110 83 .hbtn.acct img{width:22px;height:22px;border-radius:50%;object-fit:cover;
111 84 border:1.5px solid var(--ink);margin-left:-4px}
112 −.hbtn.acct .ka-badge{background:var(--lime);border-radius:4px;padding:0 5px;
85 +.hbtn.acct .ka-badge{background:var(--accent);color:var(--on-accent);border-radius:4px;padding:0 5px;
113 86 font-family:var(--font-mono);font-size:10px;font-weight:700}
87 +.hbtn:hover .ka-badge{background:var(--on-accent);color:var(--accent)}
88 +/* badge « Un service Groupe KA » (ka/GroupeKaBadge — styles dans tokens.css) */
89 +.header .gk-badge{flex:none}
90 +.hbtn .acct-short{display:none}
91 +@media(max-width:560px){
92 + .header-inner{gap:10px}
93 + .header .gk-badge .pfx{display:none}
94 + .hbtn .acct-long{display:none}.hbtn .acct-short{display:inline}}
95 +@media(max-width:400px){.brand svg{width:26px;height:26px;margin-right:8px}.brand{font-size:20px}}
114 96
115 97 /* ===== page compte (carte de membre Groupe KA) ===== */
116 98 .compte-page{max-width:640px;margin:0 auto;padding:44px 0 70px}
@@ -118,18 +100,18 @@ a{color:inherit;text-decoration:none} button{font-family:inherit;cursor:pointer}
118 100 padding:28px;color:var(--paper);box-shadow:var(--shadow-off);margin-top:24px;
119 101 position:relative;overflow:hidden}
120 102 .membercard::after{content:"";position:absolute;right:-40px;top:-40px;width:160px;
121 − height:160px;border-radius:50%;background:rgba(201,163,255,.14)}
103 + height:160px;border-radius:50%;background:rgba(112,72,232,.18)}
122 104 .mc-brand{font-family:var(--font-mono);font-size:10px;font-weight:700;
123 − text-transform:uppercase;letter-spacing:.14em;color:var(--lime)}
105 + text-transform:uppercase;letter-spacing:.14em;color:var(--accent-soft)}
124 106 .mc-row{display:flex;gap:18px;align-items:center;margin-top:18px}
125 −.mc-avatar{width:72px;height:72px;border-radius:14px;border:2px solid var(--lime);
107 +.mc-avatar{width:72px;height:72px;border-radius:14px;border:2px solid var(--accent);
126 108 background:var(--green-deep);overflow:hidden;flex:none;display:flex;
127 109 align-items:center;justify-content:center;font-family:var(--font-display);
128 − font-weight:700;font-size:26px;color:var(--lime)}
110 + font-weight:700;font-size:26px;color:var(--accent-soft)}
129 111 .mc-avatar img{width:100%;height:100%;object-fit:cover}
130 112 .mc-name{font-family:var(--font-display);font-size:22px;font-weight:700;color:var(--paper)}
131 −.mc-kaid{font-family:var(--font-mono);font-size:12px;color:var(--lime);margin-top:2px;letter-spacing:.04em}
132 −.mc-role{display:inline-flex;background:var(--lime);color:var(--ink);border-radius:5px;
113 +.mc-kaid{font-family:var(--font-mono);font-size:12px;color:var(--accent-soft);margin-top:2px;letter-spacing:.04em}
114 +.mc-role{display:inline-flex;background:var(--accent);color:var(--on-accent);border-radius:5px;
133 115 padding:2px 10px;font-family:var(--font-mono);font-size:10px;font-weight:700;
134 116 text-transform:uppercase;letter-spacing:.06em;margin-top:8px}
135 117 .mc-meta{margin-top:20px;display:grid;gap:6px;font-size:12.5px;color:rgba(245,243,238,.75)}
@@ -153,8 +135,9 @@ a{color:inherit;text-decoration:none} button{font-family:inherit;cursor:pointer}
153 135 .adv{background:var(--surface);border:1.5px solid var(--ink);border-radius:var(--r-card);
154 136 padding:16px;box-shadow:var(--shadow-off-soft)}
155 137 .adv .ico{width:36px;height:36px;border-radius:8px;border:1.5px solid var(--ink);
156 − background:var(--lime);color:var(--ink);display:flex;align-items:center;
138 + background:var(--accent);color:var(--on-accent);display:flex;align-items:center;
157 139 justify-content:center;margin-bottom:10px;font-size:15px}
140 +.adv:nth-child(2n) .ico{color:var(--ink)}
158 141 .adv:nth-child(2n) .ico{background:var(--amber-soft)}
159 142 .adv h3{font-size:14px;margin-bottom:3px}
160 143 .adv p{margin:0;font-size:12px;color:var(--ink-3);line-height:1.45}
@@ -167,7 +150,7 @@ a{color:inherit;text-decoration:none} button{font-family:inherit;cursor:pointer}
167 150 .search-input{flex:1 1 auto;display:flex;align-items:center;gap:10px;background:var(--surface);
168 151 border:1.5px solid var(--ink);border-radius:var(--r-ctl);padding:10px 15px;
169 152 transition:.15s;min-width:0;box-shadow:3px 3px 0 rgba(20,24,20,.08)}
170 −.search-input:focus-within{box-shadow:3px 3px 0 rgba(91,52,168,.3)}
153 +.search-input:focus-within{box-shadow:3px 3px 0 rgba(112,72,232,.35)}
171 154 .search-input input{border:0;background:none;outline:none;font:inherit;flex:1;color:var(--ink);min-width:0}
172 155 .search-input svg{flex:none;color:var(--ink-3)}
173 156 .filters{display:flex;gap:8px;flex-wrap:wrap}
@@ -177,7 +160,7 @@ select.f{appearance:none;-webkit-appearance:none;border:1.5px solid var(--ink);
177 160 font-size:13px;font-weight:700;color:var(--ink-2);max-width:170px;
178 161 box-shadow:3px 3px 0 rgba(20,24,20,.08)}
179 162 select.f:focus{outline:2px solid var(--green);outline-offset:1px}
180 −select.f.active{background-color:var(--lime);color:var(--ink)}
163 +select.f.active{background-color:var(--accent-soft);color:var(--ink);border-color:var(--accent-deep)}
181 164 @media(max-width:760px){
182 165 .search-wrap{flex-wrap:wrap}
183 166 .search-input{flex-basis:100%}
@@ -200,18 +183,18 @@ select.f.active{background-color:var(--lime);color:var(--ink)}
200 183 repeating-linear-gradient(-45deg,var(--green-deep) 0 14px,#33195f 14px 28px);
201 184 display:flex;align-items:center;justify-content:center;overflow:hidden;
202 185 border-bottom:1.5px solid var(--ink)}
203 −.card-photo .init{color:var(--lime);font-family:var(--font-display);font-weight:700;
186 +.card-photo .init{color:var(--accent-soft);font-family:var(--font-display);font-weight:700;
204 187 font-size:46px;letter-spacing:.02em}
205 188 .card-photo img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
206 189 .card-photo .tier{position:absolute;top:10px;left:10px;z-index:2}
207 190 .card-photo .nplat{position:absolute;top:10px;right:10px;z-index:2;background:var(--ink);
208 − color:var(--lime);border:1.5px solid var(--ink);border-radius:var(--r-ctl);
191 + color:var(--accent-soft);border:1.5px solid var(--ink);border-radius:var(--r-ctl);
209 192 padding:2px 8px;font-family:var(--font-mono);font-size:9.5px;font-weight:700;
210 193 text-transform:uppercase;letter-spacing:.05em}
211 194 .tier{display:inline-flex;padding:2px 9px;border:1.5px solid var(--ink);
212 195 border-radius:var(--r-ctl);font-family:var(--font-mono);font-size:9.5px;
213 196 font-weight:700;text-transform:uppercase;letter-spacing:.06em;background:var(--surface);color:var(--ink)}
214 −.tier.mega{background:var(--lime)}
197 +.tier.mega{background:var(--accent);color:var(--on-accent)}
215 198 .tier.macro{background:var(--amber-soft)}
216 199 .card-body{padding:14px 15px 15px;display:flex;flex-direction:column;gap:9px;flex:1}
217 200 .card-name{font-family:var(--font-display);font-size:16px;font-weight:700;
@@ -221,7 +204,8 @@ select.f.active{background-color:var(--lime);color:var(--ink)}
221 204 text-transform:uppercase;letter-spacing:.05em;display:flex;gap:6px;align-items:center;flex-wrap:wrap;margin-top:-4px}
222 205 .chips{display:flex;gap:6px;flex-wrap:wrap}
223 206 .chip{background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r-ctl);
224 − padding:2px 10px;font-size:11px;font-weight:600;color:var(--ink-2);white-space:nowrap}
207 + padding:2px 10px;font-family:var(--font-body);font-size:11px;font-weight:600;color:var(--ink-2);
208 + white-space:nowrap;text-transform:none;letter-spacing:0}
225 209 .reach{font-size:12px;color:var(--ink-2)}
226 210 .reach b{font-family:var(--font-display);color:var(--ink);font-size:15.5px;font-weight:700}
227 211 .platrow{display:flex;gap:6px;flex-wrap:wrap;margin-top:auto;padding-top:2px}
@@ -248,22 +232,22 @@ select.f.active{background-color:var(--lime);color:var(--ink)}
248 232 @media(max-width:640px){.cpage-head{padding:22px 18px;gap:16px}}
249 233 .cavatar{width:104px;height:104px;border-radius:var(--r-card);
250 234 background:repeating-linear-gradient(-45deg,var(--green-deep) 0 14px,#33195f 14px 28px);
251 − color:var(--lime);flex:none;display:flex;align-items:center;justify-content:center;
235 + color:var(--accent-soft);flex:none;display:flex;align-items:center;justify-content:center;
252 236 font-family:var(--font-display);font-weight:700;font-size:36px;overflow:hidden;
253 − position:relative;border:2px solid var(--lime)}
237 + position:relative;border:2px solid var(--accent)}
254 238 @media(max-width:640px){.cavatar{width:76px;height:76px;font-size:26px}}
255 239 .cavatar img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
256 240 .cpage-head h1{font-size:clamp(24px,4vw,40px);font-weight:700;color:var(--paper);
257 241 line-height:1.1;display:flex;align-items:center;gap:10px;flex-wrap:wrap;text-transform:uppercase}
258 −.cpage-head h1 .vbadge{width:22px;height:22px;color:var(--lime)}
242 +.cpage-head h1 .vbadge{width:22px;height:22px;color:var(--accent-soft)}
259 243 .cpage-head .meta{display:flex;gap:7px;flex-wrap:wrap;margin-top:12px}
260 244 .mchip{background:rgba(245,243,238,.12);border:1px solid rgba(245,243,238,.3);
261 245 border-radius:var(--r-ctl);padding:3px 11px;font-family:var(--font-mono);
262 246 font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--paper)}
263 −.mchip.o{background:var(--lime);border-color:var(--lime);color:var(--ink)}
247 +.mchip.o{background:var(--accent);border-color:var(--accent);color:var(--on-accent)}
264 248 .cpage-reach{margin-left:auto;text-align:right}
265 249 .cpage-reach b{display:block;font-family:var(--font-display);
266 − font-size:clamp(28px,3.6vw,40px);font-weight:700;color:var(--lime);letter-spacing:-.02em}
250 + font-size:clamp(28px,3.6vw,40px);font-weight:700;color:var(--accent-soft);letter-spacing:-.02em}
267 251 .cpage-reach span{font-family:var(--font-mono);font-size:10px;color:rgba(245,243,238,.6);
268 252 text-transform:uppercase;letter-spacing:.08em;font-weight:700}
269 253 @media(max-width:760px){.cpage-reach{margin-left:0;text-align:left;flex-basis:100%}}
@@ -293,10 +277,10 @@ select.f.active{background-color:var(--lime);color:var(--ink)}
293 277 .conf.hi{background:var(--lime-soft);color:var(--green-deep)}
294 278 .conf.mid{background:var(--amber-soft);color:#8a5a12}
295 279 .linkinbio{display:inline-flex;align-items:center;gap:10px;margin-top:22px;
296 − background:var(--lime);color:var(--ink);border:1.5px solid var(--ink);
280 + background:var(--accent);color:var(--on-accent);border:1.5px solid var(--ink);
297 281 border-radius:var(--r-ctl);padding:11px 20px;font-family:var(--font-display);
298 282 font-weight:700;font-size:13.5px;transition:.15s;box-shadow:4px 4px 0 rgba(20,24,20,.25)}
299 −.linkinbio:hover{background:var(--lime-soft)}
283 +.linkinbio:hover{background:var(--accent-soft);color:var(--ink)}
300 284 .linkinbio:active{transform:translate(2px,2px);box-shadow:none}
301 285 .linkinbio svg{width:16px;height:16px;fill:currentColor}
302 286 .cpage-foot{margin-top:38px;font-size:12px;color:var(--ink-3);
@@ -313,7 +297,7 @@ select.f.active{background-color:var(--lime);color:var(--ink)}
313 297 .tile-k{font-family:var(--font-mono);font-size:9.5px;font-weight:700;text-transform:uppercase;
314 298 letter-spacing:.1em;color:var(--ink-3);margin-top:7px}
315 299 .tile.hero-tile{background:var(--ink)}
316 −.tile.hero-tile .tile-v{color:var(--lime)}
300 +.tile.hero-tile .tile-v{color:var(--accent-soft)}
317 301 .tile.hero-tile .tile-k{color:rgba(245,243,238,.55)}
318 302 .viz-card{background:var(--surface);border:1.5px solid var(--ink);border-radius:var(--r-card);
319 303 box-shadow:var(--shadow-off-soft);padding:24px 26px 18px;margin-bottom:22px}
@@ -343,27 +327,47 @@ select.f.active{background-color:var(--lime);color:var(--ink)}
343 327 padding:11px 14px;font:inherit;background:var(--surface);color:var(--ink);
344 328 box-shadow:3px 3px 0 rgba(20,24,20,.08);transition:box-shadow .15s ease}
345 329 .field input:focus,.field textarea:focus{outline:2px solid var(--green);outline-offset:1px;
346 − box-shadow:3px 3px 0 rgba(91,52,168,.25)}
330 + box-shadow:3px 3px 0 rgba(112,72,232,.25)}
347 331 @media(max-width:900px){.field input,.field textarea{font-size:16px}}
348 332 .optout-ok{background:var(--lime-soft);color:var(--green-deep);border:1.5px solid var(--ink);
349 333 border-radius:var(--r-card);padding:16px 20px;font-weight:600;margin-top:20px;
350 334 box-shadow:var(--shadow-off-soft)}
351 335 .optout-ok.warn{background:var(--amber-soft);color:#8a5a12}
352 336
353 −/* ===== footer + tab bar mobile (patron Lou-Ka) ===== */
354 −.footer{border-top:1.5px solid var(--ink);margin-top:40px;padding:32px 0 44px;background:var(--ink);color:var(--paper)}
355 −.footer-inner{display:flex;gap:26px;flex-wrap:wrap;align-items:flex-start;justify-content:space-between}
356 −.footer .brand{font-size:19px;color:var(--paper)}
357 −.footer .brand .ka{color:var(--ink)}
358 −.footer p{font-size:12px;color:rgba(245,243,238,.55);max-width:460px;margin:10px 0 0}
359 −.footer-links{display:flex;flex-direction:column;gap:9px;font-family:var(--font-mono);
360 − font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;
361 − color:rgba(245,243,238,.8)}
362 −.footer-links a:hover{color:var(--lime)}
363 −.fam-row{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px}
364 −.fam{border:1px solid rgba(245,243,238,.3);border-radius:var(--r-ctl);padding:3px 10px;
365 − font-family:var(--font-mono);font-size:10px;font-weight:700;color:rgba(245,243,238,.7)}
366 −.fam:hover{background:var(--lime);color:var(--ink);border-color:var(--lime)}
337 +/* ===== footer : nav locale + footer commun Groupe KA (ka/KaFooter) ===== */
338 +.footer-local{margin-top:56px;border-top:1.5px solid var(--ink);background:var(--surface);padding:16px 0}
339 +.footer-local nav{display:flex;gap:10px 26px;flex-wrap:wrap;align-items:center;
340 + font-family:var(--font-mono);font-size:11px;font-weight:700;
341 + text-transform:uppercase;letter-spacing:.08em;color:var(--ink-2)}
342 +.footer-local .klabel{color:var(--ink-3)}
343 +.footer-local a{display:inline-flex;align-items:center;min-height:44px}
344 +.footer-local a:hover{color:var(--accent-deep);text-decoration:underline;text-underline-offset:4px}
345 +.footer-local+.ka-footer{margin-top:0}
346 +.ka-footer .brand{font-size:19px;color:var(--paper)}
347 +
348 +/* ===== contact ===== */
349 +.contact-page{max-width:880px;margin:0 auto;padding:44px 0 70px}
350 +.contact-page h1{font-size:clamp(26px,4vw,38px);margin:12px 0;text-transform:uppercase}
351 +.contact-page .lead{color:var(--ink-2);max-width:640px}
352 +.contact-notice{background:var(--accent-soft);border:1.5px solid var(--ink);border-radius:var(--r-card);
353 + padding:16px 20px;margin:22px 0;box-shadow:var(--shadow-off-soft);font-weight:600;color:var(--ink)}
354 +.contact-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:14px;margin:8px 0 4px}
355 +.contact-card{display:block;background:var(--surface);border:1.5px solid var(--ink);
356 + border-radius:var(--r-card);padding:16px 18px;box-shadow:var(--shadow-off-soft);
357 + transition:transform .16s ease,box-shadow .16s ease;min-height:44px}
358 +.contact-card:hover{transform:translate(-2px,-2px);box-shadow:var(--shadow-off)}
359 +.contact-card b{display:block;font-family:var(--font-mono);font-size:13px;font-weight:700;
360 + color:var(--accent-deep);word-break:break-all}
361 +.contact-card span{display:block;margin-top:5px;font-size:12px;color:var(--ink-2)}
362 +.site-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:10px;margin:14px 0 0}
363 +.site-item{display:flex;align-items:center;gap:10px;background:var(--surface);
364 + border:1.5px solid var(--ink);border-radius:var(--r-ctl);padding:10px 13px;min-height:44px;
365 + transition:transform .15s ease,box-shadow .15s ease}
366 +.site-item:hover{transform:translate(-2px,-2px);box-shadow:3px 3px 0 var(--ink)}
367 +.site-item i{width:10px;height:10px;border-radius:3px;border:1px solid var(--ink);flex:none}
368 +.site-item b{font-family:var(--font-display);font-size:13.5px;font-weight:700}
369 +.site-item span{font-size:11px;color:var(--ink-3);margin-left:auto;font-family:var(--font-mono)}
370 +@media(max-width:480px){.site-item span{display:none}}
367 371 .tabbar{display:none}
368 372 @media(max-width:760px){
369 373 .tabbar{display:grid;grid-template-columns:repeat(4,1fr);
@@ -381,7 +385,7 @@ select.f.active{background-color:var(--lime);color:var(--ink)}
381 385 .tabbar a svg{display:block;width:20px;height:20px;fill:none;stroke:currentColor;
382 386 stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
383 387 body{padding-bottom:calc(64px + env(safe-area-inset-bottom))}
384 − .footer{padding-bottom:calc(76px + env(safe-area-inset-bottom))}
388 + .ka-footer{padding-bottom:calc(76px + env(safe-area-inset-bottom))}
385 389 }
386 390 .spin{width:26px;height:26px;border:3px solid var(--line);border-top-color:var(--green);
387 391 border-radius:50%;margin:50px auto;animation:sp .8s linear infinite}
@@ -392,8 +396,11 @@ select.f.active{background-color:var(--lime);color:var(--ink)}
392 396 <div id="app"></div>
393 397 <script>
394 398 "use strict";
395 −/* Créa-Ka SPA — routes : / · /createur/{id} · /stats · /retrait */
399 +/* Créa-Ka SPA — routes : / · /createur/{id} · /stats · /retrait · /compte · /contact */
396 400 const ICONS=__ICONS__;
401 +/* écosystème Groupe KA (ka/ecosystem.json, injecté au build) — footer commun + /contact */
402 +const KA_ECO=__KA_ECO__;
403 +const KA_SITE=KA_ECO.sites.find(s=>s.id==="crea-ka");
397 404 const $=s=>document.querySelector(s);
398 405 const app=$("#app");
399 406 const fmt=new Intl.NumberFormat("fr-CA",{notation:"compact",maximumFractionDigits:1});
@@ -413,7 +420,7 @@ const PLAT={
413 420 linkedin:{label:"LinkedIn",color:"#0a66c2"},
414 421 threads:{label:"Threads",color:"#141814"},
415 422 podcast:{label:"Balado",color:"#8940fa"},
416 − "site-web":{label:"Site web",color:"#5b34a8"},
423 + "site-web":{label:"Site web",color:"#7048e8"},
417 424 autre:{label:"Autre",color:"#8b928c"}};
418 425 const NICHE_LBL={"humour":"Humour","mode":"Mode","beaute":"Beauté","lifestyle":"Lifestyle",
419 426 "famille-parentalite":"Famille","cuisine":"Cuisine","gaming":"Gaming","tech":"Tech",
@@ -453,15 +460,18 @@ function photoImg(c){
453 460 return `<img loading="lazy" alt="${esc(c.display_name)}" src="${srcs[0]}"
454 461 data-srcs='${esc(JSON.stringify(srcs))}' data-i="0" onerror="nextSrc(this)">`;
455 462 }
456 −const brandSvg=`<svg width="30" height="30" viewBox="0 0 64 64"><rect width="64" height="64" rx="10" fill="#141814"/><circle cx="32" cy="23" r="9" fill="#c9a3ff"/><path d="M14 52c3-10 9-15 18-15s15 5 18 15" stroke="#c9a3ff" stroke-width="6" fill="none" stroke-linecap="round"/></svg>`;
463 +const brandSvg=`<svg width="30" height="30" viewBox="0 0 64 64"><rect width="64" height="64" rx="10" fill="#141814"/><circle cx="32" cy="23" r="9" fill="#7048e8"/><path d="M14 52c3-10 9-15 18-15s15 5 18 15" stroke="#7048e8" stroke-width="6" fill="none" stroke-linecap="round"/></svg>`;
457 464
458 465 function header(){
459 466 return `<header class="header"><div class="container header-inner">
460 467 <a href="/" data-nav class="brand">${brandSvg}Créa<span class="ka">Ka</span></a>
468 + <a class="gk-badge" href="https://www.groupe-ka.com" target="_blank" rel="noopener noreferrer"
469 + aria-label="Un service Groupe KA — visiter le portail de l'écosystème"><span class="pfx">Un service</span>
470 + <b>Groupe<span class="ka">KA</span></b></a>
461 471 <span class="brand-tag">Tous les créateurs québécois.<br>Tous leurs liens.</span>
462 472 <span class="header-spacer"></span>
463 473 <a class="hbtn" href="/stats" data-nav>Statistiques</a>
464 − <a class="hbtn" href="/retrait" data-nav>Retrait</a>
474 + <a class="hbtn" href="/contact" data-nav>Contact</a>
465 475 <a class="hbtn primary" href="/#annuaire" data-nav>Explorer l'annuaire</a>
466 476 <span id="acct-slot"></span>
467 477 </div></header>`;
@@ -479,7 +489,7 @@ async function loadAccount(){
479 489 <span class="ka-badge">KA</span></a>`;
480 490 }else{
481 491 slot.innerHTML=`<a class="hbtn acct" href="/api/auth/ka/login"
482 − title="Se connecter avec KA ID">Se connecter <span class="ka-badge">KA</span></a>`;
492 + title="Se connecter avec KA ID"><span class="acct-long">Se connecter avec</span><span class="acct-short">Connexion</span> <span class="ka-badge">KA</span></a>`;
483 493 }
484 494 bindNav(slot);
485 495 }
@@ -492,26 +502,41 @@ function tabbar(active){
492 502 ${t("/retrait","Retrait",`<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="9"/><path d="M8 12h8"/></svg>`,"optout")}
493 503 </nav>`;
494 504 }
505 +/* footer commun Groupe KA (équivalent vanilla de ka/KaFooter.tsx, siteId
506 + "crea-ka", localLegal = /retrait) — nav locale conservée au-dessus */
495 507 function footer(){
496 − return `<footer class="footer"><div class="container footer-inner">
497 − <div><span class="brand">${brandSvg}Créa<span class="ka" style="background:var(--lime)">Ka</span></span>
498 − <p>Annuaire public des créateurs de contenu québécois. Uniquement des profils publics
499 − et professionnels ; aucune donnée privée. Retrait simple et respecté (Loi 25).
500 − — Simon-Pierre Boucher</p>
501 − <div class="fam-row"><span class="klabel" style="color:rgba(245,243,238,.5);align-self:center">Groupe KA :</span>
502 − <a class="fam" href="https://www.groupe-ka.com" target="_blank" rel="noopener">KA ID</a>
503 − <a class="fam" href="https://www.lou-ka.com" target="_blank" rel="noopener">Lou-Ka</a>
504 − <a class="fam" href="https://www.immo-ka.com" target="_blank" rel="noopener">Immo-Ka</a>
505 − <a class="fam" href="https://www.auto-ka.com" target="_blank" rel="noopener">Auto-Ka</a>
506 − <a class="fam" href="https://www.food-ka.com" target="_blank" rel="noopener">Food-Ka</a>
507 − <a class="fam" href="https://www.fabri-ka.com" target="_blank" rel="noopener">Fabri-Ka</a></div></div>
508 − <div class="footer-links">
508 + const year=new Date().getFullYear();
509 + const others=KA_ECO.sites.filter(s=>s.id!=="crea-ka");
510 + const localLegal=[{label:"Retrait (opt-out)",href:"/retrait",nav:true}];
511 + return `<div class="footer-local"><div class="container"><nav>
512 + <span class="klabel">Créa·Ka</span>
509 513 <a href="/compte" data-nav>Mon compte KA ID</a>
510 514 <a href="/stats" data-nav>Statistiques</a>
511 515 <a href="/retrait" data-nav>Demander un retrait</a>
516 + <a href="/contact" data-nav>Contact</a>
512 517 <a href="/api/stats" target="_blank" rel="noopener">API publique</a>
518 + </nav></div></div>
519 + <footer class="ka-footer" id="contact-footer">
520 + <div class="container">
521 + <a class="wordmark" href="${esc(KA_ECO.hub.url)}" target="_blank" rel="noopener noreferrer"
522 + aria-label="Groupe KA — le portail de l'écosystème">Groupe <span class="ka">KA</span></a>
523 + <p class="desc">${esc(KA_ECO.org.tagline)} Des centaines de connecteurs lisent les sites à la
524 + source, normalisent la donnée et se resynchronisent seuls.
525 + <b style="color:var(--paper)">${esc(KA_SITE.wordmark)}</b> — ${esc(KA_SITE.tagline)} — est un service Groupe KA.</p>
526 + <p class="notice"><b>${esc(KA_ECO.org.disclaimer)}</b></p>
527 + <ul class="sites">
528 + ${others.map(s=>`<li><a href="https://${esc(s.domain)}" target="_blank" rel="noopener noreferrer">${esc(s.wordmark)}</a></li>`).join("")}
529 + ${(KA_ECO.extraFooterLinks||[]).map(l=>`<li><a href="${esc(l.href)}" target="_blank" rel="noopener noreferrer">${esc(l.label)}</a></li>`).join("")}
530 + </ul>
531 + <div class="contacts">
532 + ${KA_ECO.contacts.map(c=>`<p style="margin:0"><a href="mailto:${esc(c.email)}">${esc(c.email)}</a><span>${esc(c.role)}</span></p>`).join("")}
533 + </div>
534 + <p class="legal">© ${year} ${esc(KA_ECO.org.copyrightHolder)}
535 + ${localLegal.map(l=>` · <a href="${esc(l.href)}"${l.nav?" data-nav":""}>${esc(l.label)}</a>`).join("")}
536 + ${KA_ECO.legal.map(l=>` · <a href="${esc(l.href)}" target="_blank" rel="noopener noreferrer">${esc(l.label)}</a>`).join("")}
537 + </p>
513 538 </div>
514 − </div></footer>`;
539 + </footer>`;
515 540 }
516 541
517 542 /* ---------- annuaire ---------- */
@@ -542,7 +567,7 @@ function selectHtml(id,label,opts,val,lbls){
542 567 return `<select class="f${val?" active":""}" id="${id}"><option value="">${label}</option>${o}</select>`;
543 568 }
544 569 async function renderHome(){
545 − document.title="Créa-Ka — Tous les créateurs québécois. Tous leurs liens.";
570 + document.title="Créa-Ka — Un service Groupe KA";
546 571 if(!state.tax)state.tax=await api("/api/taxonomies");
547 572 if(!state.stats)state.stats=await api("/api/stats").catch(()=>null);
548 573 const s=state.stats||{creators:0,accounts:0,by_platform:{}};
@@ -703,6 +728,7 @@ async function renderCompte(){
703 728 les autres plateformes du Groupe KA. Créez-le en une minute si vous n'en avez pas.</p>
704 729 <div class="compte-actions">
705 730 <a class="btn btn-primary" href="/api/auth/ka/login">Se connecter avec KA ID</a>
731 + <a class="btn btn-accent" href="https://www.groupe-ka.com/connexion" target="_blank" rel="noopener">Créer un compte KA ID ↗</a>
706 732 <a class="btn btn-ghost" href="https://www.groupe-ka.com" target="_blank" rel="noopener">Qu'est-ce que KA ID ?</a>
707 733 </div>
708 734 </div>`+footer()+tabbar("");
@@ -742,6 +768,38 @@ async function renderCompte(){
742 768 state.me=null;history.pushState(null,"","/");route();});
743 769 }
744 770
771 +/* ---------- page contact (écosystème Groupe KA — ka/ecosystem.json) ---------- */
772 +function renderContact(){
773 + document.title="Contact — Créa-Ka, un service Groupe KA";
774 + const sites=KA_ECO.sites.map(s=>{
775 + const cur=s.id==="crea-ka";
776 + return `<a class="site-item" href="https://${esc(s.domain)}"${cur?"":' target="_blank" rel="noopener noreferrer"'}
777 + title="${esc(s.tagline)}"><i style="background:${esc(s.accent)}"></i><b>${esc(s.wordmark)}${cur?" (ici)":""}</b><span>${esc(s.domain)}</span></a>`;
778 + }).join("");
779 + app.innerHTML=header()+`
780 + <div class="container contact-page">
781 + <span class="kicker">Contact — Groupe KA</span>
782 + <h1>Nous <span class="hl">joindre.</span></h1>
783 + <p class="lead">${esc(KA_SITE.wordmark)} — ${esc(KA_SITE.tagline)} — est un service du
784 + <b>Groupe KA</b>. ${esc(KA_ECO.org.tagline)} Les contacts ci-dessous valent pour
785 + l'ensemble des plateformes du groupe.</p>
786 + <div class="contact-notice">${esc(KA_ECO.org.disclaimer)}</div>
787 + <h2 class="sect-title" style="margin-top:26px">Courriels</h2>
788 + <div class="contact-grid">
789 + ${KA_ECO.contacts.map(c=>`<a class="contact-card" href="mailto:${esc(c.email)}">
790 + <b>${esc(c.email)}</b><span>${esc(c.role)}</span></a>`).join("")}
791 + </div>
792 + <div class="compte-actions" style="margin-top:22px">
793 + <a class="btn btn-primary" href="${esc(KA_ECO.hub.url)}" target="_blank" rel="noopener noreferrer">Visiter le hub groupe-ka.com ↗</a>
794 + <a class="btn btn-ghost" href="/retrait" data-nav>Demander un retrait (Loi 25)</a>
795 + </div>
796 + <h2 class="sect-title">Les plateformes du groupe</h2>
797 + <div class="site-list">${sites}</div>
798 + <p style="font-size:12px;color:var(--ink-3);margin-top:20px">${esc(KA_ECO.hub.signupNote)}</p>
799 + </div>`+footer()+tabbar("");
800 + bindNav();window.scrollTo(0,0);
801 +}
802 +
745 803 /* ---------- retrait / opt-out ---------- */
746 804 function renderOptout(){
747 805 document.title="Retrait (opt-out) — Créa-Ka";
@@ -793,6 +851,7 @@ function route(){
793 851 else if(p==="/retrait")r=renderOptout();
794 852 else if(p==="/stats")r=renderStats();
795 853 else if(p==="/compte")r=renderCompte();
854 + else if(p==="/contact")r=renderContact();
796 855 else r=renderHome();
797 856 Promise.resolve(r).then(()=>loadAccount()).catch(()=>{});
798 857 }
added frontend/src/ka/GroupeKaBadge.tsx +21 −0
@@ -0,0 +1,21 @@
1 +// Auteur : Simon-Pierre Boucher — contact@spboucher.ai
2 +// ka-ui/react/GroupeKaBadge.tsx — badge « Un service Groupe KA », cliquable
3 +// vers le hub. À placer dans le header de chaque site (à côté du logo de la
4 +// marque). Variante dark pour les surfaces encre. Zone de protection : le
5 +// padding interne du badge suffit ; ne rien coller à moins de 8 px du badge.
6 +export default function GroupeKaBadge({ dark = false }: { dark?: boolean }) {
7 + return (
8 + <a
9 + className={`gk-badge${dark ? " gk-badge--dark" : ""}`}
10 + href="https://www.groupe-ka.com"
11 + target="_blank"
12 + rel="noopener noreferrer"
13 + aria-label="Un service Groupe KA — visiter le portail de l'écosystème"
14 + >
15 + Un service
16 + <b>
17 + Groupe<span className="ka">KA</span>
18 + </b>
19 + </a>
20 + );
21 +}
added frontend/src/ka/KaFooter.tsx +91 −0
@@ -0,0 +1,91 @@
1 +// Auteur : Simon-Pierre Boucher — contact@spboucher.ai
2 +// ka-ui/react/KaFooter.tsx — footer commun Groupe KA (fond encre), à vendorer
3 +// dans chaque app Vite/React sous frontend/src/ka/. Consomme ecosystem.json :
4 +// toute modification des infos de contact se fait dans ka-ui/ecosystem.json
5 +// puis se resynchronise sur les 12 sites (voir ka-ui/README.md).
6 +import eco from "./ecosystem.json";
7 +
8 +type LocalLink = { label: string; href: string };
9 +
10 +export default function KaFooter({
11 + siteId,
12 + localLegal = [],
13 +}: {
14 + /** id du site courant dans ecosystem.json (ex. "resto-ka") */
15 + siteId: string;
16 + /** pages légales PROPRES au site (ex. /conditions), affichées avant celles du hub */
17 + localLegal?: LocalLink[];
18 +}) {
19 + const year = new Date().getFullYear();
20 + const site = eco.sites.find((s) => s.id === siteId);
21 + const others = eco.sites.filter((s) => s.id !== siteId);
22 + return (
23 + <footer className="ka-footer" id="contact">
24 + <div className="container">
25 + <a
26 + className="wordmark"
27 + href={eco.hub.url}
28 + target={siteId === "groupe-ka" ? undefined : "_blank"}
29 + rel="noopener noreferrer"
30 + aria-label="Groupe KA — le portail de l'écosystème"
31 + >
32 + Groupe <span className="ka">KA</span>
33 + </a>
34 + <p className="desc">
35 + {eco.org.tagline} Des centaines de connecteurs lisent les sites à la
36 + source, normalisent la donnée et se resynchronisent seuls.{" "}
37 + {site ? (
38 + <>
39 + <b style={{ color: "var(--paper)" }}>{site.wordmark}</b> —{" "}
40 + {site.tagline} — est un service Groupe KA.
41 + </>
42 + ) : null}
43 + </p>
44 + <p className="notice">
45 + <b>{eco.org.disclaimer}</b>
46 + </p>
47 + <ul className="sites">
48 + {others.map((s) => (
49 + <li key={s.id}>
50 + <a href={`https://${s.domain}`} target="_blank" rel="noopener noreferrer">
51 + {s.wordmark}
52 + </a>
53 + </li>
54 + ))}
55 + {eco.extraFooterLinks.map((l) => (
56 + <li key={l.href}>
57 + <a href={l.href} target="_blank" rel="noopener noreferrer">
58 + {l.label}
59 + </a>
60 + </li>
61 + ))}
62 + </ul>
63 + <div className="contacts">
64 + {eco.contacts.map((c) => (
65 + <p key={c.email} style={{ margin: 0 }}>
66 + <a href={`mailto:${c.email}`}>{c.email}</a>
67 + <span>{c.role}</span>
68 + </p>
69 + ))}
70 + </div>
71 + <p className="legal">
72 + © {year} {eco.org.copyrightHolder}
73 + {localLegal.map((l) => (
74 + <span key={l.href}>
75 + {" · "}
76 + <a href={l.href}>{l.label}</a>
77 + </span>
78 + ))}
79 + {eco.legal.map((l) => (
80 + <span key={l.href}>
81 + {" · "}
82 + <a href={l.href} target="_blank" rel="noopener noreferrer">
83 + {l.label}
84 + </a>
85 + </span>
86 + ))}
87 + </p>
88 + </div>
89 + </footer>
90 + );
91 +}
added frontend/src/ka/ecosystem.json +45 −0
@@ -0,0 +1,45 @@
1 +{
2 + "org": {
3 + "name": "Groupe KA",
4 + "legalName": "Groupe KA — Simon-Pierre Boucher",
5 + "tagline": "Holding québécois d'agrégateurs de produits et services entièrement automatisés.",
6 + "disclaimer": "Groupe KA est un agrégateur de contenu : nous ne vendons rien, ne louons rien et ne sommes partie à aucune transaction.",
7 + "copyrightHolder": "Groupe KA — Simon-Pierre Boucher"
8 + },
9 + "hub": {
10 + "url": "https://www.groupe-ka.com",
11 + "loginPath": "/connexion",
12 + "signupNote": "La création de compte KA ID se fait sur le hub groupe-ka.com ; chaque site délègue sa connexion via /api/auth/ka/login."
13 + },
14 + "contacts": [
15 + { "email": "contact@groupe-ka.com", "role": "Projets, partenariats & données" },
16 + { "email": "info@groupe-ka.com", "role": "Médias & questions générales" },
17 + { "email": "admin@groupe-ka.com", "role": "Légal, vie privée & Loi 25" }
18 + ],
19 + "legal": [
20 + { "label": "Conditions d'utilisation", "href": "https://www.groupe-ka.com/conditions" },
21 + { "label": "Politique de confidentialité", "href": "https://www.groupe-ka.com/confidentialite" },
22 + { "label": "Protection des renseignements personnels (Loi 25)", "href": "https://www.groupe-ka.com/loi-25" },
23 + { "label": "Transparence des robots d'indexation", "href": "https://www.groupe-ka.com/bots" }
24 + ],
25 + "sites": [
26 + { "id": "groupe-ka", "wordmark": "Groupe KA", "domain": "www.groupe-ka.com", "accent": "#d9f26b", "accentSoft": "#f0f9d2", "accentDeep": "#123f2e", "onAccent": "#141814", "tagline": "Le portail de l'écosystème ·Ka" },
27 + { "id": "trouve-ka", "wordmark": "Trouve·Ka", "domain": "www.trouve-ka.com", "accent": "#1c7ed6", "accentSoft": "#e7f2fd", "accentDeep": "#14508f", "onAccent": "#ffffff", "tagline": "Le moteur de recherche du web québécois" },
28 + { "id": "lou-ka", "wordmark": "Lou·Ka", "domain": "www.lou-ka.com", "accent": "#ff6a00", "accentSoft": "#fff1e6", "accentDeep": "#cc5500", "onAccent": "#ffffff", "tagline": "Tous les logements à louer" },
29 + { "id": "immo-ka", "wordmark": "Immo·Ka", "domain": "www.immo-ka.com", "accent": "#e23744", "accentSoft": "#fbe0e2", "accentDeep": "#a8232e", "onAccent": "#ffffff", "tagline": "Toutes les propriétés à vendre" },
30 + { "id": "vrai-prix", "wordmark": "Vrai-Prix", "domain": "www.vrai-prix.com", "accent": "#ff5148", "accentSoft": "#ffe3e0", "accentDeep": "#9e2a25", "onAccent": "#ffffff", "tagline": "La valeur réelle de chaque propriété" },
31 + { "id": "auto-ka", "wordmark": "Auto·Ka", "domain": "www.auto-ka.com", "accent": "#ff5a2a", "accentSoft": "#ffe8de", "accentDeep": "#cc3f16", "onAccent": "#ffffff", "tagline": "Les voitures usagées du Québec" },
32 + { "id": "fabri-ka", "wordmark": "Fabri·Ka", "domain": "www.fabri-ka.com", "accent": "#c4532e", "accentSoft": "#f7e3da", "accentDeep": "#a94525", "onAccent": "#ffffff", "tagline": "Les produits fabriqués au Québec" },
33 + { "id": "food-ka", "wordmark": "Food·Ka", "domain": "www.food-ka.com", "accent": "#1f9d55", "accentSoft": "#e2f5ea", "accentDeep": "#157a40", "onAccent": "#ffffff", "tagline": "Les prix d'épicerie, suivis à la source" },
34 + { "id": "resto-ka", "wordmark": "Resto·Ka", "domain": "www.resto-ka.com", "accent": "#f08c00", "accentSoft": "#fdeed7", "accentDeep": "#b96a00", "onAccent": "#141814", "tagline": "Chaque resto, chaque plat, chaque prix" },
35 + { "id": "sorti-ka", "wordmark": "Sorti·Ka", "domain": "www.sorti-ka.com", "accent": "#d6336c", "accentSoft": "#fbe0eb", "accentDeep": "#a12551", "onAccent": "#ffffff", "tagline": "Toutes les sorties, dans les 17 régions" },
36 + { "id": "crea-ka", "wordmark": "Créa·Ka", "domain": "www.crea-ka.com", "accent": "#7048e8", "accentSoft": "#ece5fc", "accentDeep": "#5433b8", "onAccent": "#ffffff", "tagline": "Les créateurs d'ici, tous leurs liens" },
37 + { "id": "api-ka", "wordmark": "API·Ka", "domain": "www.api-ka.com", "accent": "#3b5bdb", "accentSoft": "#e4eafb", "accentDeep": "#2b44a8", "onAccent": "#ffffff", "tagline": "La donnée de l'écosystème, par API" }
38 + ],
39 + "extraFooterLinks": [
40 + { "label": "ValoPlex", "href": "https://www.valoplex.com" },
41 + { "label": "Ka2", "href": "https://www.ka2.bot" },
42 + { "label": "Ka4", "href": "https://www.ka4.bot" },
43 + { "label": "Ka6", "href": "https://www.ka6.bot" }
44 + ]
45 +}
added frontend/src/ka/tokens.css +229 −0
@@ -0,0 +1,229 @@
1 +/* -----------------------------------------------------------------------------
2 + Auteur : Simon-Pierre Boucher — contact@spboucher.ai
3 + Fichier : ka-ui/tokens.css — SOURCE CANONIQUE (repo ka-ui sur spbgit)
4 + Desc. : Design system commun GROUPE KA « éditorial sharp » — tokens + socle
5 + de composants partagés par les 12 plateformes. Chaque site importe ce
6 + fichier PUIS surcharge uniquement son accent (voir accents.css).
7 +
8 + · Typo : display Space Grotesk / texte Inter / micro-étiquettes JetBrains Mono
9 + · Palette: papier #f5f3ee · encre #141814 · vert profond #1c5c41 + ACCENT du site
10 + · Signature : bordures encre 1,5–2 px + ombres décalées dures, grain de film,
11 + surlignés d'accent inclinés (néo-brutalisme raffiné)
12 + · Breakpoints communs : 360 / 768 / 1024 / 1440 px (mobile-first)
13 + · Zones tactiles ≥ 44×44 px, safe-areas iOS, typographie fluide (clamp)
14 +----------------------------------------------------------------------------- */
15 +
16 +:root {
17 + /* ---- Palette fixe Groupe KA (identique sur les 12 sites) ---- */
18 + --paper: #f5f3ee;
19 + --surface: #ffffff;
20 + --surface-2: #faf9f5;
21 + --ink: #141814;
22 + --ink-2: #4d5551;
23 + --ink-3: #8b928c;
24 + --line: rgba(20, 24, 20, 0.14);
25 + --line-strong: rgba(20, 24, 20, 0.85);
26 + --green: #1c5c41;
27 + --green-deep: #123f2e;
28 + --amber: #e8a33d;
29 + --amber-soft: #fdf3e2;
30 + --danger: #b3423a;
31 + --danger-soft: #fbe9e7;
32 +
33 + /* ---- ACCENT du site — SEULES variables surchargées par marque ---- */
34 + --accent: #d9f26b; /* défaut : lime Groupe KA */
35 + --accent-soft: #f0f9d2;
36 + --accent-deep: #123f2e;
37 + --on-accent: var(--ink); /* couleur du texte posé SUR l'accent */
38 +
39 + /* alias rétro-compatibles (les satellites historiques utilisent --lime) */
40 + --lime: var(--accent);
41 + --lime-soft: var(--accent-soft);
42 +
43 + /* ---- Géométrie sharp ---- */
44 + --r-card: 10px;
45 + --r-ctl: 6px;
46 + --r-pill: 999px;
47 +
48 + /* ---- Ombres décalées — la signature du groupe ---- */
49 + --shadow-flat: 0 1px 2px rgba(20, 24, 20, 0.05);
50 + --shadow-off: 6px 6px 0 var(--ink);
51 + --shadow-off-soft: 8px 8px 0 rgba(20, 24, 20, 0.08);
52 + --shadow-off-mid: 4px 4px 0 rgba(20, 24, 20, 0.18);
53 +
54 + /* ---- Typographie ---- */
55 + --font-display: "Space Grotesk", system-ui, sans-serif;
56 + --font-body: "Inter", system-ui, sans-serif;
57 + --font-mono: "JetBrains Mono", ui-monospace, monospace;
58 +
59 + /* Échelle fluide (mobile-first, clamp) */
60 + --fs-h1: clamp(30px, 3.2vw + 18px, 54px);
61 + --fs-h2: clamp(23px, 1.8vw + 14px, 34px);
62 + --fs-h3: clamp(17px, 0.9vw + 12px, 22px);
63 + --fs-body: 15px;
64 + --fs-small: 13px;
65 +
66 + /* Espacements */
67 + --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px;
68 + --sp-5: 24px; --sp-6: 32px; --sp-7: 48px; --sp-8: 64px;
69 +
70 + /* Cible tactile minimale */
71 + --touch: 44px;
72 +}
73 +
74 +/* ---- Socle ---- */
75 +* { box-sizing: border-box; }
76 +html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
77 +body {
78 + margin: 0;
79 + background: var(--paper);
80 + color: var(--ink);
81 + font-family: var(--font-body);
82 + font-size: var(--fs-body);
83 + line-height: 1.55;
84 + -webkit-font-smoothing: antialiased;
85 + padding-bottom: env(safe-area-inset-bottom);
86 + overflow-x: clip; /* jamais de débordement horizontal */
87 +}
88 +img, svg, video { max-width: 100%; height: auto; display: block; }
89 +h1, h2, h3, h4 { font-family: var(--font-display); letter-spacing: -0.03em; margin: 0 0 0.5em; }
90 +h1 { font-size: var(--fs-h1); line-height: 1.06; }
91 +h2 { font-size: var(--fs-h2); line-height: 1.15; }
92 +h3 { font-size: var(--fs-h3); line-height: 1.25; }
93 +a { color: inherit; }
94 +::selection { background: var(--accent); color: var(--on-accent); }
95 +:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; }
96 +
97 +/* Grain de film pleine page — ⚠️ jamais de z-index sur body > * (position:
98 + relative seulement), sinon les utilitaires z-* sont écrasés. */
99 +body::before {
100 + content: "";
101 + position: fixed; inset: 0; pointer-events: none; opacity: 0.35; z-index: 9999;
102 + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='linear' slope='0.06'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)'/%3E%3C/svg%3E");
103 +}
104 +body > * { position: relative; }
105 +
106 +/* ---- Conteneur commun ---- */
107 +.container { max-width: 1152px; margin: 0 auto; padding: 0 var(--sp-4); }
108 +@media (min-width: 768px) { .container { padding: 0 var(--sp-5); } }
109 +
110 +/* ---- Micro-typographie signature ---- */
111 +.kicker {
112 + display: inline-flex; align-items: center; gap: 10px;
113 + font-family: var(--font-mono); font-size: 11.5px; font-weight: 500;
114 + text-transform: uppercase; letter-spacing: 0.12em; color: var(--green);
115 +}
116 +.kicker::before { content: ""; width: 22px; height: 2px; background: var(--green); }
117 +.klabel {
118 + font-family: var(--font-mono); font-size: 10px; font-weight: 700;
119 + text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-3);
120 +}
121 +.hl {
122 + display: inline-block; background: var(--accent); color: var(--on-accent);
123 + border-radius: 8px; padding: 0 10px 2px; transform: rotate(-1deg);
124 +}
125 +.outline-txt { color: transparent; -webkit-text-stroke: 2px var(--ink); }
126 +
127 +/* ---- Boutons (cible ≥ 44 px) ---- */
128 +.btn {
129 + display: inline-flex; align-items: center; justify-content: center; gap: 8px;
130 + min-height: var(--touch); padding: 10px 18px;
131 + font-family: var(--font-display); font-weight: 700; font-size: 14px;
132 + border: 1.5px solid var(--ink); border-radius: var(--r-ctl);
133 + background: var(--surface); color: var(--ink);
134 + cursor: pointer; text-decoration: none;
135 + transition: transform 0.15s, box-shadow 0.15s, background 0.15s, color 0.15s;
136 +}
137 +.btn:hover { transform: translate(-2px, -2px); box-shadow: var(--shadow-off-mid); }
138 +.btn:active { transform: translate(0, 0); box-shadow: none; }
139 +.btn:disabled { opacity: 0.45; pointer-events: none; }
140 +.btn-primary { background: var(--ink); color: var(--accent); }
141 +.btn-primary:hover { background: var(--accent-deep); }
142 +.btn-accent { background: var(--accent); color: var(--on-accent); }
143 +.btn-ghost { background: transparent; border-color: var(--line); }
144 +.btn-ghost:hover { border-color: var(--ink); }
145 +
146 +/* ---- Cartes ---- */
147 +.card {
148 + background: var(--surface); border: 1.5px solid var(--ink);
149 + border-radius: var(--r-card); box-shadow: var(--shadow-off-soft);
150 + overflow: hidden;
151 +}
152 +.card-hover { transition: transform 0.15s, box-shadow 0.15s; }
153 +.card-hover:hover { transform: translate(-2px, -2px); box-shadow: var(--shadow-off); }
154 +
155 +/* ---- Chips / badges ---- */
156 +.chip {
157 + display: inline-flex; align-items: center; gap: 6px;
158 + padding: 4px 11px; font-family: var(--font-mono); font-size: 11px; font-weight: 700;
159 + text-transform: uppercase; letter-spacing: 0.06em;
160 + border: 1.5px solid var(--ink); border-radius: var(--r-pill);
161 + background: var(--surface); color: var(--ink);
162 +}
163 +.chip-accent { background: var(--accent); color: var(--on-accent); }
164 +.chip-soft { background: var(--accent-soft); border-color: var(--line); }
165 +
166 +/* ---- Champs ---- */
167 +.input, .select, .textarea {
168 + width: 100%; min-height: var(--touch); padding: 10px 14px;
169 + font: inherit; color: var(--ink); background: var(--surface);
170 + border: 1.5px solid var(--ink); border-radius: var(--r-ctl);
171 +}
172 +.input:focus, .select:focus, .textarea:focus {
173 + outline: none; box-shadow: 3px 3px 0 var(--accent); border-color: var(--ink);
174 +}
175 +.input::placeholder { color: var(--ink-3); }
176 +
177 +/* ---- Badge « Un service Groupe KA » (header, cliquable → hub) ---- */
178 +.gk-badge {
179 + display: inline-flex; align-items: center; gap: 7px;
180 + min-height: 30px; padding: 3px 10px 4px;
181 + font-family: var(--font-mono); font-size: 10px; font-weight: 700;
182 + letter-spacing: 0.08em; text-transform: uppercase; text-decoration: none;
183 + border: 1.5px solid var(--ink); border-radius: var(--r-pill);
184 + background: var(--surface); color: var(--ink-2); white-space: nowrap;
185 +}
186 +.gk-badge b {
187 + font-family: var(--font-display); font-size: 12px; letter-spacing: -0.02em;
188 + text-transform: none; color: var(--ink);
189 +}
190 +.gk-badge b .ka {
191 + display: inline-block; background: var(--ink); color: var(--accent);
192 + border-radius: 5px; padding: 0 5px 1px; margin-left: 3px; transform: rotate(-2deg);
193 +}
194 +.gk-badge:hover .ka { transform: rotate(0); }
195 +.gk-badge--dark { background: transparent; border-color: rgba(245,243,238,0.4); color: rgba(245,243,238,0.75); }
196 +.gk-badge--dark b { color: var(--paper); }
197 +
198 +/* ---- Footer commun (fond encre — voir react/KaFooter.tsx) ---- */
199 +.ka-footer { margin-top: var(--sp-8); background: var(--ink); padding: 44px 0; font-size: 13px; color: rgba(245,243,238,0.75); }
200 +.ka-footer a { text-decoration: none; }
201 +.ka-footer .wordmark { font-family: var(--font-display); font-weight: 700; font-size: 30px; letter-spacing: -0.04em; color: var(--paper); text-decoration: none; }
202 +.ka-footer .wordmark .ka { color: var(--accent); }
203 +.ka-footer .desc { max-width: 640px; margin-top: var(--sp-4); }
204 +.ka-footer .notice { max-width: 640px; margin-top: var(--sp-4); border-left: 2px solid var(--accent); padding-left: var(--sp-4); }
205 +.ka-footer .notice b { color: var(--paper); }
206 +.ka-footer .sites { list-style: none; display: flex; flex-wrap: wrap; gap: 10px 26px; margin: 26px 0 0; padding: 0; font-family: var(--font-mono); font-size: 11px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; }
207 +.ka-footer .sites a { color: rgba(245,243,238,0.65); }
208 +.ka-footer .sites a:hover { color: var(--accent); text-decoration: underline; text-underline-offset: 4px; }
209 +.ka-footer .contacts { display: grid; gap: 14px 32px; border-top: 1px solid rgba(245,243,238,0.15); margin-top: 30px; padding-top: 26px; }
210 +@media (min-width: 768px) { .ka-footer .contacts { grid-template-columns: repeat(3, 1fr); } }
211 +.ka-footer .contacts a { font-family: var(--font-mono); font-weight: 700; font-size: 12px; color: rgba(245,243,238,0.85); }
212 +.ka-footer .contacts a:hover { color: var(--accent); text-decoration: underline; text-underline-offset: 4px; }
213 +.ka-footer .contacts span { display: block; margin-top: 3px; font-size: 11px; color: rgba(245,243,238,0.5); }
214 +.ka-footer .legal { margin-top: 30px; font-family: var(--font-mono); font-size: 11px; color: rgba(245,243,238,0.45); }
215 +.ka-footer .legal a { color: inherit; }
216 +.ka-footer .legal a:hover { color: var(--accent); text-decoration: underline; text-underline-offset: 4px; }
217 +
218 +/* ---- Tableaux → cartes empilées sous 768 px ---- */
219 +.tbl-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
220 +@media (max-width: 767px) {
221 + .tbl-stack thead { display: none; }
222 + .tbl-stack tr { display: block; border: 1.5px solid var(--ink); border-radius: var(--r-card); margin-bottom: var(--sp-3); background: var(--surface); }
223 + .tbl-stack td { display: flex; justify-content: space-between; gap: var(--sp-3); padding: 8px 12px; border: 0; }
224 + .tbl-stack td::before { content: attr(data-label); font-family: var(--font-mono); font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-3); }
225 +}
226 +
227 +/* ---- Utilitaires responsive ---- */
228 +.only-mobile { display: initial; } .only-desktop { display: none; }
229 +@media (min-width: 768px) { .only-mobile { display: none; } .only-desktop { display: initial; } }
modified scripts/build_frontend.py +18 −5
@@ -1,13 +1,18 @@
1 1 # ==============================================================================
2 2 # Author: Simon-Pierre Boucher <contact@spboucher.ai>
3 3 # File: scripts/build_frontend.py
4 −# Desc: Construit frontend/dist/index.html à partir du gabarit en injectant
5 −# les tracés SVG des marques (simple-icons, licence CC0)
4 +# Desc: Construit frontend/dist/index.html à partir du gabarit en injectant :
5 +# __ICONS__ — tracés SVG des marques (simple-icons, licence CC0)
6 +# __KA_TOKENS__ — ka/tokens.css (design system commun Groupe KA,
7 +# importé EN PREMIER dans le <head>)
8 +# __KA_ECO__ — ka/ecosystem.json (contacts, sites & mentions légales
9 +# du groupe : footer commun + page /contact)
6 10 # ==============================================================================
7 11 """Usage : python3 scripts/build_frontend.py
8 12
9 −Lit frontend/src/index.template.html + frontend/src/icons.json et produit
10 −frontend/dist/index.html (remplacement du marqueur __ICONS__)."""
13 +Lit frontend/src/index.template.html + frontend/src/icons.json +
14 +frontend/src/ka/{tokens.css,ecosystem.json} et produit frontend/dist/index.html
15 +(remplacement des marqueurs __ICONS__, __KA_TOKENS__ et __KA_ECO__)."""
11 16 from __future__ import annotations
12 17
13 18 import json
@@ -15,17 +20,25 @@ from pathlib import Path
15 20
16 21 ROOT = Path(__file__).resolve().parent.parent
17 22 SRC = ROOT / "frontend" / "src"
23 +KA = SRC / "ka"
18 24 DIST = ROOT / "frontend" / "dist"
19 25
20 26
21 27 def main() -> None:
22 28 icons = json.loads((SRC / "icons.json").read_text(encoding="utf-8"))
29 + tokens = (KA / "tokens.css").read_text(encoding="utf-8")
30 + eco = json.loads((KA / "ecosystem.json").read_text(encoding="utf-8"))
23 31 html = (SRC / "index.template.html").read_text(encoding="utf-8")
32 + for marker in ("__ICONS__", "__KA_TOKENS__", "__KA_ECO__"):
33 + if marker not in html:
34 + raise SystemExit(f"[crea-ka] marqueur manquant dans le gabarit : {marker}")
24 35 html = html.replace("__ICONS__", json.dumps(icons, separators=(",", ":")))
36 + html = html.replace("__KA_TOKENS__", tokens)
37 + html = html.replace("__KA_ECO__", json.dumps(eco, ensure_ascii=False, separators=(",", ":")))
25 38 DIST.mkdir(parents=True, exist_ok=True)
26 39 (DIST / "index.html").write_text(html, encoding="utf-8")
27 40 print(f"[crea-ka] frontend construit → {DIST/'index.html'} "
28 − f"({len(html)//1024} Ko, {len(icons)} icônes)")
41 + f"({len(html)//1024} Ko, {len(icons)} icônes, tokens ka-ui + écosystème injectés)")
29 42
30 43
31 44 if __name__ == "__main__":
32 45