Aller au contenu
OmniRoute source

OmniRoute — Design System & Visual Identity (Français)

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 :

  1. Le fond quadrillé de type papier millimétré utilisé par le site sur chaque page.
  2. 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).
  3. 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.


  • 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 #hex brute.
  • 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 »

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.

É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
  • Tailwind v4, CSS-first (aucun tailwind.config.*). Les jetons sont définis dans :root/.dark et exposés aux utilitaires via @theme inline (globals.css:130-179).
  • Mode sombre via la classe .dark sur <html> (@custom-variant dark dans globals.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ôt html[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 .dark du dashboard.
  • Un remplacement de la couleur primaire à l’exécution existe (themeStore.ts:85-97, préréglages dans COLOR_THEMES) — les utilisateurs peuvent remplacer --color-primary. Tout nouveau jeton (dégradé, etc.) qui référence --color-primary hérite automatiquement de ces remplacements. ✅
  • Noms de rayons réservés de Tailwind v4 : --radius-sm/md/lg/... sous-tendent les utilitaires rounded-*. Leur redéfinition modifie rétroactivement chaque rounded-* existant (par exemple, rounded-sm est 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) »

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.

: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);
}

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 un bg-bg opaque. Tous les éléments qu’il contient sont déjà transparents (<main>, le conteneur de défilement et le conteneur interne max-w-7xl) ; la suppression de bg-bg permet donc à la grille du corps de transparaître dans la zone de contenu (la valeur --color-bg du 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) et Sidebar (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 &lt;body&gt; (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 &lt;body&gt;), 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.

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).


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 &lt;input&gt;/&lt;textarea&gt; 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.


  • Phase 1 — Grille + jetons d’identité (CETTE PR). Grille dans globals.css + jetons --surface-2/--grad-brand/--radius ; fond d’écran body::before ; suppression du blocage causé par bg-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éfaut rounded-sm/md/lg/xl restent intactes — pas de répercussion sur 400 fichiers) ; Card/Modal → 14px, Button/Input/Select → 9px ; Button principal → --grad-brand (rouge→violet) + nouvelle variante accent ; bordures des Card → jeton border-border (0.08). Reporté : cn()→tailwind-merge (C9) nécessite de nouvelles dépendances ; le remplacement ponctuel de rounded-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 unique STATUS_HEX ; flow/edgeStyles.ts + TokenHealthBadge redirigés vers celle-ci, valeurs hexadécimales identiques). ✅ Jeton --font-mono. ✅ C3 (DataTable) — remplacement de chaque rgba en ligne ainsi que des fallbacks obsolètes var(--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.ts et 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) — le className d’un appelant remplace désormais correctement la classe conflictuelle d’une primitive au lieu de s’empiler avec elle. ✅ C7 nouvelles primitives Checkbox + 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-ring global 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 de TokenHealthBadge, 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.


  • 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-bg opaque 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 fluide max-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 (ProviderOnboardingWizard max-w-5xl, Rtk/CavemanContextPageClient max-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/20 prenait le dessus sur le bg-surface de 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-surface y serait redondant et sans effet). La grille elle-même ne nécessitait aucune modification — le body::before du 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 par tests/unit/design-grid-background.test.ts (bloc de la Phase 6).

  • 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.

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

Code source d’OmniRoute (a58000c7685f)

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.

Interface principale de HagiCode en thème clair
  • 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.
Visiter HagiCode