OmniRoute — Design System & Visual Identity (Français)
1. Objectif
Section intitulée « 1. Objectif »Le site marketing (viral.omniroute.online, why.omniroute.online, omniroute.online) et le tableau de bord du produit doivent donner l’impression de faire partie d’un seul et même produit. Le site a déjà repris sa palette du tableau de bord — son fichier css/tokens.css indique même « La palette reflète celle du tableau de bord OmniRoute (src/app/globals.css) ». Les deux sont donc déjà alignés à environ 80 % au niveau des couleurs. Voici ce qui manque au tableau de bord :
- Le fond quadrillé de type papier millimétré utilisé par le site sur chaque page.
- Quelques jetons de conception partagés présents sur le site mais absents du tableau de bord (échelle des rayons, dégradé de marque,
surface-2, police mono). - Une cohérence au niveau des composants — plusieurs composants du tableau de bord contournent les jetons du thème avec des valeurs hex/rgba codées en dur.
Ce document présente l’analyse et le plan.
2. Principes
Section intitulée « 2. Principes »- Source unique de vérité =
src/app/globals.css. Le site reflète le tableau de bord, jamais l’inverse. Les nouveaux jetons sont d’abord ajoutés àglobals.css. - Des jetons, jamais des valeurs littérales. Les composants utilisent des jetons sémantiques (
bg-surface,text-primary,border-border), jamais de valeur#hexbrute. - Subtil, pas criard. La grille est un fond d’écran discret placé derrière le contenu — elle ne doit jamais réduire le contraste du texte ni concurrencer visuellement l’interface.
- Adapté au thème. Tout fonctionne aussi bien avec
.dark(l’apparence emblématique du produit) qu’avec le thème clair. - Déploiement ciblé. Livrer d’abord la grille et les jetons (faible risque, forte visibilité), puis nettoyer les composants par vagues successives.
3. État actuel — ce qui est déjà aligné et ce qui ne l’est pas
Section intitulée « 3. État actuel — ce qui est déjà aligné et ce qui ne l’est pas »3.1 Couleurs — déjà unifiées ✅
Section intitulée « 3.1 Couleurs — déjà unifiées ✅ »Toutes les couleurs de marque et de surface correspondent déjà à celles du site en valeur (seuls les noms diffèrent — le tableau de bord utilise le préfixe --color-). Vérification effectuée dans src/app/globals.css:30-128 :
| Concept | Jeton du site (tokens.css) |
Jeton du tableau de bord (globals.css) |
Correspondance |
|---|---|---|---|
| principale | --primary #e54d5e |
--color-primary #e54d5e |
✅ |
| principale-survol | --primary-hover #c93d4e |
--color-primary-hover #c93d4e |
✅ |
| accentuation | --accent #6366f1 |
--color-accent #6366f1 |
✅ |
| accentuation-2 | --accent-2 #8b5cf6 |
--color-accent-hover #8b5cf6 |
✅ (renommé) |
| accentuation-3 | --accent-3 #a855f7 |
--color-accent-light #a855f7 |
✅ (renommé) |
| succès / avertissement / erreur | #22c55e / #f59e0b / #ef4444 |
identique | ✅ |
| feux de signalisation | #ff5f56 / #ffbd2e / #27c93f |
identique | ✅ |
| arrière-plan / surface / bordure sombres | #0b0e14 / #161b22 / rgba(255,255,255,.08) |
identique | ✅ |
| arrière-plan / surface / texte clairs | #f9f9fb / #fff / #1a1a2e |
identique | ✅ |
Conclusion : aucune migration de couleurs n’est nécessaire. L’identité est déjà partagée ; nous sommes en train de la finaliser, pas de la reconstruire.
3.2 Écarts — ce qui manque au tableau de bord
Section intitulée « 3.2 Écarts — ce qui manque au tableau de bord »| Écart | Le site possède | Dashboard | Action |
|---|---|---|---|
| Papier peint quadrillé | Papier millimétré body::before, --grid-line, --grid-size 32px, --section-alt |
✅ ajouté (Phase 1) | Partie A |
| Échelle des rayons | --radius 14px, --radius-sm 9px |
--radius 14px ajouté ; -sm + réaffectation des composants en attente |
Partie B / Phase 2 |
| Dégradé de marque | --grad-brand 135deg primary→accent-3 |
✅ jeton ajouté (Phase 1) ; utilisé en Phase 2 | Partie B |
| Surface imbriquée | --surface-2 #1c2230 |
✅ ajouté (Phase 1) | Partie B |
| Police à chasse fixe | --font-mono (pile ui-monospace) |
en attente (Phase 4, avec les éléments qui l’utilisent) | Partie B |
text-muted (sombre) |
#8b8b9e |
#a1a1aa (zinc-400) |
harmoniser — Partie B |
3.3 Mécanismes de thème (pour ne rien casser)
Section intitulée « 3.3 Mécanismes de thème (pour ne rien casser) »- Tailwind v4, CSS-first (aucun
tailwind.config.*). Les jetons sont définis dans:root/.darket exposés aux utilitaires via@theme inline(globals.css:130-179). - Mode sombre via la classe
.darksur<html>(@custom-variant darkdansglobals.css:22), activé par un store Zustand personnalisé (src/store/themeStore.ts), thème par défaut =system(src/shared/constants/appConfig.ts:11). Le site utilise plutôthtml[data-theme="light"]— les mécanismes diffèrent, mais ne se rencontrent jamais (origines distinctes), il n’y a donc aucun conflit. Nous conservons le mécanisme.darkdu dashboard. - Un remplacement de la couleur primaire à l’exécution existe (
themeStore.ts:85-97, préréglages dansCOLOR_THEMES) — les utilisateurs peuvent remplacer--color-primary. Tout nouveau jeton (dégradé, etc.) qui référence--color-primaryhérite automatiquement de ces remplacements. ✅ - Noms de rayons réservés de Tailwind v4 :
--radius-sm/md/lg/...sous-tendent les utilitairesrounded-*. Leur redéfinition modifie rétroactivement chaquerounded-*existant (par exemple,rounded-smest utilisé dans 12 fichiers). La valeur du petit rayon et la réaffectation des composants sont donc délibérément reportées à la Phase 2, où les éléments qui les utilisent seront modifiés en même temps.
4. Partie A — L’arrière-plan quadrillé façon papier millimétré (demande principale) — IMPLÉMENTÉ (Phase 1)
Section intitulée « 4. Partie A — L’arrière-plan quadrillé façon papier millimétré (demande principale) — IMPLÉMENTÉ (Phase 1) »4.1 Description
Section intitulée « 4.1 Description »La recette exacte du site (_mono_repo/omnirouteSite/css/base.css) : un pseudo-élément fixe couvrant toute la fenêtre d’affichage, qui dessine deux dégradés sous forme de lignes de 1px et se place derrière tout le contenu avec z-index:-1.
body::before { content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none; background-image: linear-gradient(to right, var(--grid-line) 1px, transparent 1px), linear-gradient(to bottom, var(--grid-line) 1px, transparent 1px); background-size: var(--grid-size) var(--grid-size);}Pourquoi cela fonctionne même si body possède un background-color opaque : un ::before avec z-index:-1 est rendu au-dessus de l’arrière-plan propre à l’élément, mais en dessous de son contenu dans le flux. Ainsi, --color-bg constitue la couleur de fond de base, la grille se superpose à celle-ci et l’application s’affiche au-dessus de la grille.
4.2 Précédent déjà présent dans la base de code
Section intitulée « 4.2 Précédent déjà présent dans la base de code »src/app/landing/page.tsx:16-26 implémente déjà cette même grille au niveau de la page, mais avec des lignes rouges (#E54D5E, opacité 0.06) espacées de 50px, ainsi que des orbes animés. Ce motif a donc déjà fait ses preuves dans le produit ; ce travail le transforme en un fond d’écran global et adapté au thème.
4.3 Jetons ajoutés (dans globals.css)
Section intitulée « 4.3 Jetons ajoutés (dans globals.css) »:root { /* clair — opacité de la grille augmentée par rapport à la valeur 0.045 du site afin que le fond soit réellement visible sur le tableau de bord dense (les cartes et l’interface couvrent la majeure partie de la fenêtre d’affichage) */ --grid-line: rgba(0, 0, 0, 0.07); --grid-size: 32px; --section-alt: rgba(0, 0, 0, 0.022);}.dark { /* sombre — valeur augmentée par rapport à 0.035 pour la même raison */ --grid-line: rgba(255, 255, 255, 0.06); --section-alt: rgba(255, 255, 255, 0.018);}4.4 L’unique obstacle — supprimé
Section intitulée « 4.4 L’unique obstacle — supprimé »La grille est globale par conception (elle couvre simultanément le panneau, auth/login, les pages d’erreur — toutes les routes). Un seul élément la masquait à l’intérieur du panneau :
-
src/shared/components/layouts/DashboardLayout.tsx— le conteneur externe affichait unbg-bgopaque. Tous les éléments qu’il contient sont déjà transparents (<main>, le conteneur de défilement et le conteneur internemax-w-7xl) ; la suppression debg-bgpermet donc à la grille du corps de transparaître dans la zone de contenu (la valeur--color-bgdu corps reste la couleur de fond de base).<div className="flex h-dvh min-h-0 w-full overflow-hidden bg-bg"><div className="flex h-dvh min-h-0 w-full overflow-hidden">
4.5 Interaction avec l’interface (barre latérale / en-tête)
Section intitulée « 4.5 Interaction avec l’interface (barre latérale / en-tête) »Header(Header.tsx:207,bg-bg) etSidebar(Sidebar.tsx:430,bg-sidebar) restent opaques → la grille apparaît uniquement dans la zone de contenu, encadrée par une interface unie. Il s’agit d’un rendu sobre par défaut, conforme à la manière dont le site sépare l’interface de la zone de travail (décision D3 = uni).
4.6 Pages de connexion / d’authentification / d’erreur
Section intitulée « 4.6 Pages de connexion / d’authentification / d’erreur »Ces pages s’affichent directement sous <body> (sans l’interface du panneau), de sorte que la grille globale devrait apparaître automatiquement derrière elles. Phase 5 — TERMINÉE : les conteneurs autonomes en plein écran étaient en réalité opaques (min-h-screen … bg-bg, où bg-bg correspond au même fond uni que <body>), ce qui masquait la grille sur tous les écrans autres que le tableau de bord — pas uniquement sur la page de connexion. Ils sont désormais tous transparents afin que le fond d’écran partagé soit visible : login, forgot-password, callback, maintenance, offline, status, terms, privacy, onboarding et ErrorPageScaffold (qui couvre 400/401). Cela clôt la D4 (étendue de la seule page de connexion à tous les écrans autonomes). Ce comportement est couvert par tests/unit/design-grid-background.test.ts.
4.7 Page de destination
Section intitulée « 4.7 Page de destination »landing/page.tsx conserve son arrière-plan animé plus riche (orbes + vignette) — sa propre présentation marketing (décision D5 = conserver en l’état).
5. Partie B — Unification des jetons
Section intitulée « 5. Partie B — Unification des jetons »La phase 1 ajoute les jetons d’identité inertes et sans collision (--surface-2/--color-surface-2, --grad-brand, --radius). La phase 2 intègre l’échelle des rayons à Tailwind et redirige les composants vers celle-ci ; la phase 4 ajoute --font-mono ainsi que ses consommateurs.
| Jeton | Raison | Phase |
|---|---|---|
--radius / --radius-sm |
Une seule échelle de rayons (14/9) au lieu de valeurs ponctuelles 6/8/12 | 1 (valeur) / 2 (intégration + migration) |
--grad-brand |
Dégradé de marque pour les CTA principaux (rouge→violet), assorti au site | 1 (jeton) / 2 (Button) |
--surface-2 |
Panneaux imbriqués / en-têtes de tableaux / lignes en retrait | 1 |
--font-mono |
Blocs de code, terminal, identifiants, endpoints | 4 |
Harmonisation de --text-muted |
Choisir une valeur unique site↔panneau (#a1a1aa recommandé) |
2 |
D2 (text-muted) : site #8b8b9e contre tableau de bord #a1a1aa. Il est recommandé de conserver le #a1a1aa du tableau de bord et de mettre à jour le site pour qu’il corresponde. Modification cosmétique.
6. Partie C — Standardisation des composants (phases 2 à 4)
Section intitulée « 6. Partie C — Standardisation des composants (phases 2 à 4) »Composants personnalisés (sans shadcn/Radix), Tailwind v4, jetons sémantiques majoritairement adoptés (195 fichiers importent le fichier d’exports partagé). Le travail consiste à supprimer les contournements. Emplacement principal : src/shared/components/.
| # | Élément | Fichier(s) | Problème → Cible | Phase |
|---|---|---|---|---|
| C1 | Alignement des rayons | Button.tsx:14-18, Card.tsx:39, Modal.tsx, Input.tsx, Select.tsx |
mélange de 6/8/12px → --radius/--radius-sm (14/9) |
2 |
| C2 | Dégradé du bouton + variante accent |
Button.tsx:5-12 |
le bouton principal utilise un rouge→rouge uniforme ; l’aligner sur --grad-brand ; ajouter la variante accent manquante. Environ 195 importateurs — visibilité maximale |
2 |
| C3 | Tableaux | DataTable.tsx:122-176, logTableStyles.ts, globals.css:405-414 |
styles intégralement en ligne avec des valeurs rgba codées en dur + variables inexistantes ; migrer vers les jetons et supprimer les styles divergents | 3 |
| C4 | Centralisation des couleurs d’état | flow/edgeStyles.ts, TokenHealthBadge.tsx, DegradationBadge.tsx, ProviderCascadeNode.tsx, Badge.tsx + 5 helpers |
plus de 6 copies des mêmes valeurs hexadécimales → un seul module basé sur --color-success/warning/error |
3 |
| C5 | Bordure de Card |
Card.tsx:39 |
border-white/5 → marque /8 |
2 |
| C6 | Harmonisation de l’anneau de focus ✅ TERMINÉE | globals.css --focus-ring (accent) contre ring-primary/30 des contrôles de formulaire |
unifié sur accent (violet) pour correspondre à l’anneau global et le distinguer de l’anneau d’erreur rouge ; l’erreur reste rouge | 4 |
| C7 | Ajout de Checkbox + Textarea |
<input>/<textarea> bruts avec accentColor:#6366f1 en ligne |
primitives pilotées par des jetons | 4 |
| C8 | Élimination des valeurs hexadécimales codées en dur | ConsoleLogViewer.tsx:240, ComboLiveStudio.tsx:306, points de Modal, environ 14 fichiers de graphiques |
valeurs littérales → jetons | 4 |
| C9 | cn() → clsx + tailwind-merge |
src/shared/utils/cn.ts |
accumulation de classes conflictuelles ; nécessaire pour les substitutions de C1 | 2 |
Déjà conformes à la marque (pilotés par des jetons, seul le rayon doit être ajusté) : Badge, Toggle, SegmentedControl, Input, Select.
7. Plan de déploiement
Section intitulée « 7. Plan de déploiement »- Phase 1 — Grille + jetons d’identité (CETTE PR). Grille dans
globals.css+ jetons--surface-2/--grad-brand/--radius; fond d’écranbody::before; suppression du blocage causé parbg-bg; test de garde statique. Faible risque, réversible en un seul commit. - Phase 2 — Primitives (C1, C2, C5) — TERMINÉE dans cette PR. Utilitaires sémantiques de rayon
rounded-card(14px) /rounded-control(9px) ajoutés via@theme(noms personnalisés, donc les valeurs par défautrounded-sm/md/lg/xlrestent intactes — pas de répercussion sur 400 fichiers) ; Card/Modal → 14px, Button/Input/Select → 9px ; Button principal →--grad-brand(rouge→violet) + nouvelle varianteaccent; bordures des Card → jetonborder-border(0.08). Reporté :cn()→tailwind-merge (C9) nécessite de nouvelles dépendances ; le remplacement ponctuel derounded-lg(326 fichiers) est laissé en l’état, puisque les primitives couvrent l’essentiel de la surface. - Phase 3 — Couleurs d’état + tableaux (C3, C4) — TERMINÉE dans cette PR. ✅ C4 (
src/shared/constants/statusColors.ts— source uniqueSTATUS_HEX;flow/edgeStyles.ts+TokenHealthBadgeredirigés vers celle-ci, valeurs hexadécimales identiques). ✅ Jeton--font-mono. ✅ C3 (DataTable) — remplacement de chaque rgba en ligne ainsi que des fallbacks obsolètesvar(--bg-table-header)/var(--text-secondary)par un ensemble de jetons--table-*(--table-header-bg/-row-zebra/-row-hover/-cell-border/-row-selected) dont les valeurs sombres correspondent exactement aux anciens rgba codés en dur (mode sombre identique au niveau des octets) et dont les valeurs claires corrigent le thème clair, auparavant toujours sombre. Bordure d’en-tête →--color-border, texte secondaire →--color-text-muted. Nécessite une vérification visuelle avant la fusion. (Non modifiés :logTableStyles.tset les anciennes règles Ant.ant-table— traitement séparé, de priorité moindre.) - Phase 4 — Nettoyage (C6, C7, C9 terminés ; C8 en attente). ✅ C9
cn()→twMerge(clsx(...))(clsx + tailwind-merge ajoutés comme dépendances) — leclassNamed’un appelant remplace désormais correctement la classe conflictuelle d’une primitive au lieu de s’empiler avec elle. ✅ C7 nouvelles primitivesCheckbox+Textarea(pilotées par des jetons, exportées depuis le barrel ; ajout non destructif — l’adoption des 32 cases à cocher brutes / 41 zones de texte brutes pourra se faire progressivement). ✅ C6 harmonisation de l’anneau de focus — les contrôles de formulaire (Input/Select/Textarea/Toggle/Checkbox) utilisent désormais au focus l’anneau accent (violet) afin de correspondre au--focus-ringglobal et d’éviter tout conflit avec l’anneau d’erreur rouge ; l’état d’erreur rouge reste inchangé. ⏳ Le balayage des valeurs hexadécimales C8 N’EST PAS un rechercher/remplacer aveugle — éléments problématiques confirmés comme intentionnels et devant être conservés :ConsoleLogViewer.tsx:240(terminal toujours sombre), fenêtre contextuelle deTokenHealthBadge, contours SVG de ReactFlow. Ne migrer que les valeurs hexadécimales réellement destinées à s’adapter au thème.
Pour chaque phase : npm run lint + npm run typecheck:core + une vérification visuelle.
8. Décisions en suspens (recommandations)
Section intitulée « 8. Décisions en suspens (recommandations) »- D1 — Bouton principal : conserver rouge→rouge ou passer à rouge→violet
--grad-brand? Recommandation : rouge→violet (Phase 2). - D2 — Couleur des lignes de la grille : neutre (style du site) — choix retenu — plutôt que rouge de la marque. Taille : 32px (réduite d’environ 30 % par rapport aux 46px d’origine à la suite des retours du propriétaire — les cellules de 46px paraissaient trop grandes dans la mise en page du tableau de bord).
- D3 — Vivacité du chrome : barre latérale/en-tête opaques — choix retenu.
- D4 — Grille d’authentification/connexion : ✅ TERMINÉ (Phase 5) —
bg-bgopaque supprimé de chaque wrapper plein écran autonome (pas seulement celui de la connexion), afin que la grille apparaisse sur tous les écrans. Voir §4.6. - D5 — Page d’accueil : conserver l’écran d’introduction animé en l’état. Choix retenu.
- D6 — Rayons 14/9 dans l’ensemble du produit : recommandation : oui (Phase 2).
- D7 — La Phase 1 est livrée en premier : choix retenu.
- D8 — Largeur de la mise en page (Phase 5) : le conteneur de contenu du tableau de bord était limité à
max-w-7xl(1280px), avec un centrage créant de larges marges latérales vides sur les grands écrans. ✅ TERMINÉ — limite relevée à une valeur fluidemax-w-[3840px](vraie 4K) : le contenu suit désormais la largeur de la fenêtre jusqu’à environ 4K et n’est centré qu’au-delà (DashboardLayout.tsx). Les pages volontairement étroites le restent par conception (ProviderOnboardingWizardmax-w-5xl,Rtk/CavemanContextPageClientmax-w-6xl). - D9 — Tableaux de données opaques (Phase 6) : la zone de contenu du tableau de bord étant désormais transparente (afin que le fond d’écran quadrillé soit visible, Phase 5), les tableaux de données dont le conteneur n’était pas une surface opaque laissaient transparaître la grille à travers leurs lignes paires transparentes / leur alternance à faible alpha. ✅ TERMINÉ — chaque tableau sans Card applique désormais
bg-surface(ou, pour la primitive<DataTable>,background: var(--color-surface)sur son conteneur de défilement). Éléments corrigés :DataTable(primitive),ProxyLogger/RequestLoggerV2(leur teinte<Card>bg-black/5 dark:bg-black/20prenait le dessus sur lebg-surfacede la Card via tailwind-merge → transparence d’environ 95 %),BatchListTab/FilesListTab/CacheEntriesTab/ReasoningCacheTab/cache page/FreePoolTab/ModelMappingTable/HeaderTable, ainsi que les deux « tableaux » en grille CSS dans les vues du cache (bg-surface/35→bg-surface). Les tableaux déjà placés dans une<Card>/Modal ont été vérifiés comme opaques et laissés volontairement intacts (bg-surfacey serait redondant et sans effet). La grille elle-même ne nécessitait aucune modification — lebody::beforedu tableau de bord est identique au niveau des octets à celui du site (--grid-size: 32px) ; toute « grille plus grande » observée sur une instance en cours d’exécution provient d’un build obsolète antérieur à#4143, et non du code. Protection assurée partests/unit/design-grid-background.test.ts(bloc de la Phase 6).
9. Hors périmètre / risques
Section intitulée « 9. Hors périmètre / risques »- Aucune modification de la palette — les couleurs correspondent déjà ; nous ajoutons uniquement les tokens manquants. Aucun risque de modifier les couleurs du produit.
- Aucune modification du moteur de thème — conserver
.dark+ le store Zustand. - La modification des rayons (phase 2) est vaste — elle touche chaque carte/bouton/champ de saisie ; vérifier visuellement les écrans chargés (tableaux, fenêtres modales) avant la fusion.
- Les tableaux (C3) concentrent le plus de styles codés en dur et présentent la plus grande surface de régression — les isoler dans leur propre PR.
10. Index des références
Section intitulée « 10. Index des références »| Zone | Chemin |
|---|---|
| Tokens du tableau de bord | src/app/globals.css (:root, .dark, @theme inline, body, body::before) |
| Store de thème | src/store/themeStore.ts, src/shared/components/ThemeProvider.tsx, src/shared/constants/appConfig.ts:9-11 |
| Structure du panneau (grille débloquée ici) | src/shared/components/layouts/DashboardLayout.tsx |
| Éléments d’interface | src/shared/components/Header.tsx:207, src/shared/components/Sidebar.tsx:430 |
| Précédent pour la grille | src/app/landing/page.tsx:16-26 |
| Composants primitifs | src/shared/components/{Button,Card,Input,Select,Badge,Modal,Toggle,SegmentedControl,Loading,Tooltip,DataTable}.tsx |
| Sources des couleurs d’état | flow/edgeStyles.ts, TokenHealthBadge.tsx, DegradationBadge.tsx, logTableStyles.ts |
Utilitaire cn |
src/shared/utils/cn.ts |
| Test de garde de la phase 1 | tests/unit/design-grid-background.test.ts |
| Référence du site | _mono_repo/omnirouteSite/css/tokens.css, css/base.css |
HagiCode
HagiCode est un espace de développement agentique qui associe workflows structurés, exécution multi-agent et vues Hero Dungeon.
Transformez vos idées en logiciels utiles grâce à un workflow agentique plus intelligent, rapide et agréable.

- SmartDes workflows structurés transforment une intention en parcours exécutable, de l’idée à la livraison.
- EfficientLes workflows multi-agents font avancer recherche, réalisation et revue en parallèle.
- FunHero Dungeon rend les longues sessions de code plus visuelles et collaboratives.