ARCHITECTURE

Navigation

Un seul modèle de navigation pour toutes les apps internes. Deux principes le tiennent : l'architecture d'abord (ne jamais imbriquer ce qui n'a pas à l'être), et des axes alternés (chaque niveau est perpendiculaire à son parent, donc lisible d'un coup d'œil).

Niveau 1
Top-bar horizontale
Destinations globales de l'app. Toujours présente.
Niveau 2
Sidebar verticale
Sections d'une entité dans laquelle on est entré.
Niveau 3
Onglets dans le contenu
Vues co-égales d'un item. Rare.

L'axe alterne horizontal → vertical → horizontal. On ne descend jamais plus bas que le niveau 3.

L'architecture d'abord : un niveau doit mériter d'exister

Avant de choisir comment présenter un sous-niveau, se demander s'il doit exister. La meilleure nav de niveau 2, c'est celle qu'on n'a pas à dessiner parce que l'entité n'aurait jamais dû être imbriquée.

Une entité indépendante (qui a du sens seule) va au niveau 1. Ex : les décorateurs sont une référence globale au même titre que les fournisseurs → niveau 1, pas enterrés sous « Pricing ».
Un sous-niveau n'est légitime que par possession réelle : l'enfant n'existe pas hors du parent. Ex : les Blanks/Logos/Articles d'une boutique n'existent que dans cette boutique → sidebar de niveau 2 justifiée.
Descendre d'une liste vers un item, c'est index → show (page de détail atteinte au clic, retour au breadcrumb) — pas un niveau de navigation.
Imbriquer une entité indépendante sous un parent « thématique » pour créer un faux niveau 2/3

Niveau 1 — top-bar horizontale

Barre sticky en haut, fond bg-neutral (= mc-navy). Logo à gauche, destinations globales à plat (jamais dans un dropdown), déconnexion à droite. Item actif : léger fond blanc semi-transparent bg-white/10.

<nav class="navbar bg-neutral text-neutral-content sticky top-0 z-30 shadow-sm px-4">
  <div class="navbar-start gap-4">
    <img src="/logo.svg" alt="Maisons Clothes" class="h-7 w-auto" />
    <div class="flex items-center gap-0.5">
      <!-- Item actif -->
      <a class="text-sm font-accent font-bold text-neutral-content bg-white/10 px-3 py-1.5 rounded">Boutiques</a>
      <!-- Item inactif -->
      <a class="text-sm font-accent text-neutral-content/70 hover:text-neutral-content hover:bg-white/10 px-3 py-1.5 rounded transition-colors">Équipe MC</a>
    </div>
  </div>
</nav>

Niveau 2 — sidebar contextuelle

Quand on entre dans une entité qui a plusieurs sections (une boutique, une commande), un bandeau d'identité pleine largeur (nom + statut + action contextuelle) surmonte une sidebar gauche. Le rail est transparent sur le fond gris bg-base-200 (c'est du chrome, pas du contenu : une carte blanche entrerait en concurrence avec les cartes de contenu), largeur w-56, sticky. Item actif : bg-mc-green-50 text-mc-navy font-bold — un vert doux, parce qu'un rail permanent ne doit pas crier.

Farm Active
Voir la boutique ↗
<aside class="w-56 lg:sticky lg:top-20">
  <nav class="flex flex-col gap-0.5">
    <!-- Item actif : vert doux, pas navy plein -->
    <a class="flex items-center gap-2.5 px-3 py-2 rounded-lg text-sm font-accent
              bg-mc-green-50 text-mc-navy font-bold">
      <svg class="w-4 h-4 shrink-0 text-mc-green">…</svg>
      <span class="flex-1 truncate">Articles</span>
      <span class="text-xs text-mc-navy/50 tabular-nums">64</span>
    </a>
    <!-- Item inactif -->
    <a class="flex items-center gap-2.5 px-3 py-2 rounded-lg text-sm font-accent
              text-mc-navy/60 hover:bg-mc-navy-50 hover:text-mc-navy transition-colors">
      <svg class="w-4 h-4 shrink-0 text-mc-navy/40">…</svg>
      <span class="flex-1 truncate">Blanks</span>
      <span class="text-xs text-mc-navy/30 tabular-nums">16</span>
    </a>
  </nav>
</aside>

Le rail est un langage partagé

Ce rail gauche a un seul habillage, qu'il navigue (liens vers les sections d'une entité, ci-dessus) ou qu'il sélectionne (picker master-detail intra-page : une liste à gauche, un seul panneau visible à droite sans rechargement — ex. les techniques d'un décorateur). Même largeur (w-56), même item actif (bg-mc-green-50 text-mc-navy font-bold), même survol (hover:bg-mc-navy-50), que ce soit un <a> ou un <button>.

Nav de sections (liens) et picker intra-page (boutons) partagent le même habillage de rail
Un style de rail différent selon l'app ou l'usage (navy plein, btn-active ad hoc, survol maison)

Niveau 3 — onglets dans le contenu

Rare. La plupart des « 3ᵉ niveaux » n'en sont pas : descendre dans un item d'une liste, c'est index → show. Un vrai niveau 3 n'existe que si ce détail a lui-même plusieurs vues co-égales (ex : une commande = Lignes / Historique / Documents). Alors : des onglets horizontaux en haut du panneau de contenu, à droite de la sidebar. L'axe redevient horizontal, donc visuellement distinct du rail vertical. Onglets soulignés (pas tabs-boxed), actif text-mc-navy + trait navy.

CMD-0241
Lignes Historique Documents

Contenu de l'onglet

<div role="tablist" class="border-b border-mc-navy-100 flex gap-5">
  <!-- Onglet actif -->
  <a role="tab" class="px-1 py-2 text-sm font-medium text-mc-navy border-b-2 border-mc-navy -mb-px">Lignes</a>
  <!-- Onglet inactif -->
  <a role="tab" class="px-1 py-2 text-sm text-mc-navy/50 hover:text-mc-navy border-b-2 border-transparent">Historique</a>
</div>

Breadcrumb

Un breadcrumb n'est utile que s'il expose au moins un ancêtre intermédiaire lié qui n'est pas déjà l'item de top-nav actif. Ex : Catalogue / Marque / Produit — la Marque est un saut réel absent de la top-nav. Le retour se fait toujours par un breadcrumb, jamais par un bouton « ← Retour ».

Un breadcrumb à deux niveaux « Section top-nav / Item » ne sert à rien : la Section double la top-nav (qui la surligne déjà et y ramène) et l'Item répète le H1. Dans ce cas, pas de breadcrumb — le retour se fait par la top-nav.

<nav class="text-sm text-base-content/40">
  <a href="/commandes" class="hover:text-base-content">Commandes</a>
  <span class="mx-1.5">/</span>
  <a href="/commandes/241" class="hover:text-base-content">CMD-0241</a>
  <span class="mx-1.5">/</span>
  <span class="text-base-content/70">Modifier</span>
</nav>

Listes : ligne cliquable → détail

Une ligne de table ou une carte de grille est entièrement cliquable et mène au détail (show) de l'entité — jamais directement à l'édition. L'édition se fait depuis la page détail (bouton « Éditer »). C'est le mécanisme de descente par défaut, à la place d'un niveau de nav.

FaireNe pas faire
Destination du clic Toute la ligne → /entité/[id] (détail) Un lien « Éditer » en bout de ligne
Cohérence Une seule destination par type d'entité Show pour certaines listes, edit pour d'autres
Ligne / carte entièrement cliquable → détail ; le clic ignore les a/button/input internes
Aucun lien d'action (« Éditer », « Ouvrir ») redondant dans la ligne

Sites publics (top nav)

Hors apps internes. Navbar sticky, logo à gauche (min 80px), liens au centre ou à gauche, CTA unique à droite. Fond blanc ou mc-navy.

Règles

Architecture d'abord : une entité indépendante = niveau 1 ; on n'imbrique que par possession réelle
Axes alternés : niveau 1 top-bar (horizontal), niveau 2 sidebar (vertical), niveau 3 onglets (horizontal)
Niveau 1 : bg-neutral, item actif bg-white/10
Niveau 2 : sidebar transparente sur bg-base-200, w-56, actif bg-mc-green-50 text-mc-navy font-bold
Niveau 3 : onglets soulignés, actif text-mc-navy + trait navy — seulement pour des vues co-égales
Descendre dans un item = index → show au breadcrumb, pas un niveau de nav
Ligne/carte de liste cliquable → détail ; pas de lien d'action redondant
Breadcrumb seulement s'il expose un ancêtre intermédiaire hors top-nav ; sinon retour par la top-nav
Pas de breadcrumb « Section top-nav / Item » (double la nav + répète le H1)
Jamais descendre plus bas que le niveau 3
Jamais cacher la navigation principale dans un dropdown
Jamais imbriquer une entité qui a du sens seule