/*
 * ============================================================
 *  SIDEBAR  (menu de navigation)
 *  DevExpress XAF Blazor 26.1 — Fluent theme
 *
 *  File structure
 *  ──────────────
 *  0.  Base / app shell (chaîne de hauteur, header masqué)
 *  1.  Colours — the charter's --ds-sidebar-* (no palette of its own)
 *  2.  Sidebar — surface + header (logo)
 *  3.  Navigation filter (native XAF search field)
 *  4.  Navigation tree (section titles, items, states)
 *  5.  Collapsed rail (manual click toggle, via sidebar.js + native XAF)
 *  6.  Tooltip
 *  7.  Rail panel (the pages of a module, collapsed menu)
 *
 *  How DevExpress components are styled here
 *  ─────────────────────────────────────────
 *  Colours, font and sizes: the theme's PUBLIC tokens (--dxds-*, dxdocs 405705),
 *  redeclared on the component's own root (.dxbl-treeview, the search field), never
 *  on .sidebar as a whole: the theme drawer (SettingsComponent) is rendered inside
 *  .sidebar and must keep the theme's look. A component resolves its internal
 *  variables on its root (core.min.css: `.dxbl-treeview { --dxbl-treeview-item-hover-bg:
 *  var(--dxds-color-surface-neutral-alpha-hovered) }`), so a token redeclared on that
 *  same element reaches the states the theme derives from it.
 *  The internal --dxbl-* variables are written only where no public token carries
 *  the value: the menu's layout (spacing between items, indent), and a few states the
 *  theme ties to another component's token or fixes outright (chevron hovered,
 *  magnifier hovered, sub-item colour). Each one says why.
 * ============================================================
 */


/* Manrope font: loaded once, by the <link> of Pages/_Host.cshtml (an @import here blocked the first paint). */


/* ============================================================
   0. BASE / APP SHELL
   Chaîne de hauteur indispensable : SANS ces règles, les conteneurs
   virtualisés DevExpress (TreeView de navigation, grilles) n'ont pas
   de hauteur bornée et lèvent « UnableToRequestItemsException » au
   démarrage, sur toutes les pages.
   ============================================================ */
html, body { height: 100%; }
app { display: block; height: 100%; }

/* Header applicatif MASQUÉ : la maquette n'a pas de bandeau supérieur sombre.
   La flèche RETOUR + le TITRE de vue sont rendus dans la zone de contenu
   (.main-pagebar, cf. template CustomApplicationWindowTemplateComponent.razor).
   Compte / réglages / déconnexion sont déplacés dans le menu. */
.app-header {
    display: none !important;
}


/* ============================================================
   1. COULEURS — la charte (design/CHARTE.md § 5.6)
   Aucune valeur ici : le menu lit les jetons d'usage --ds-sidebar-* de la charte
   (wwwroot/css/charte/ds-pim.css), ceux de la maquette et ses compléments (champ de
   recherche, gris secondaires, infobulle). Plus de palette propre depuis le 26/10/2026.
   ============================================================ */


/* ============================================================
   1b. DENSITÉ — le menu suit celle de l'utilisateur (27/10/2026)
   Standard : les tailles de la maquette (entrée 35px, texte 14px, icône 14px, titre de section 31px en
   11px), mais 4px entre entrées au lieu de 8 (refonte du 29/10/2026 : une ligne de plus à l'écran). Compact, la densité par défaut (XAF pose `xaf-size-s` sur le
   <body>) : celles de l'arbre natif du thème en petit — entrée 24px (marges 4px, ligne 16px), texte
   12px, icône 16px à 4px du texte, 2px entre entrées —, écrites avec les paliers PUBLICS du thème
   (--dxds-*), qui suivent donc une montée de version ; la maquette ne dessine pas le Compact. Le bloc
   ne peut pas être laissé au thème : la puce des sous-items et le titre de section n'y ont pas
   d'équivalent (le titre prend la hauteur d'une entrée, en 10px), et les pages s'alignent sur le texte de
   leur module. Les règles des sections 3 et 4
   lisent ces variables, jamais une taille en dur.
   ============================================================ */
.sidebar {
    --menu-font-size:          var(--dxds-font-size-140);
    --menu-line-height:        1.35;   /* hauteur automatique de Figma pour Manrope : 19px en 14px */
    --menu-icon-size:          var(--dxds-spacing-140);
    /* Les pictogrammes natifs du pied (compte, réglages, « À propos ») sont posés à 24px en style en ligne
       par XAF : ramenés à la taille des icônes du menu par `scale` (14/24), sans !important. */
    --menu-native-icon-scale:  0.5833;
    --menu-icon-gap:           var(--ds-pim-sidebar-item-content-gap-open);
    --menu-item-padding-y:     var(--ds-pim-sidebar-item-content-padding-y-open);
    --menu-item-spacing:       var(--dxds-spacing-40);
    --menu-section-padding-y:  var(--ds-sidebar-section-padding-y);
    --menu-section-font-size:  var(--ds-sidebar-section-font-size);
    --menu-section-spacing:    var(--ds-sidebar-section-spacing);
    /* Cadre du champ de recherche (section 3), que le rail replié retire (section 5). */
    --menu-search-bg:          var(--ds-sidebar-search-bg);
    --menu-search-border:      var(--ds-sidebar-search-border);
}
.xaf-size-s .sidebar {
    --menu-font-size:          var(--dxds-font-size-120);
    --menu-line-height:        var(--dxds-line-height-160);
    --menu-icon-size:          var(--dxds-spacing-160);
    --menu-native-icon-scale:  0.6667; /* 16/24 */
    --menu-icon-gap:           var(--dxds-spacing-40);
    --menu-item-padding-y:     var(--dxds-spacing-40);
    --menu-item-spacing:       var(--dxds-spacing-20);
    --menu-section-padding-y:  var(--dxds-spacing-40);
    --menu-section-font-size:  var(--dxds-font-size-100);
    --menu-section-spacing:    var(--dxds-spacing-20);
}


/* ============================================================
   2. SIDEBAR — surface + en-tête (logo)
   On cible la classe NATIVE `.sidebar` (rendue par XAF) — pas de classe
   custom — pour rester portable dans une app XAF native (autre équipe).
   Ce fichier est chargé AVANT app-theme.css (_Host.cshtml) : face à ses règles
   globales, il gagne par la spécificité de ses sélecteurs `.sidebar .X`, pas par
   l'ordre de chargement.
   ============================================================ */
.sidebar {
    /* Largeur VERROUILLÉE (width + min + max + flex:0 0 auto). Sans ça, la sidebar
       n'avait qu'un min-width et grandissait en flex pour remplir l'espace libre
       quand la zone principale était vide — d'où l'élargissement au clic sur
       « Accueil » (dashboard vide). Le rail replié rétablit 70px (section 5).
       250px : la variante Open de la maquette (6001-4315), 220px d'entrée + 2 × 15px de retrait ;
       un libellé comme « Commandes fournisseur » y tient sur une ligne (sur 2 à 210px). */
    width: 250px;
    min-width: 250px;
    max-width: 250px;
    flex: 0 0 auto !important;
    /* Panneau teal plein, à ras bord. XAF peint la sidebar par
       `.dxbl-theme-fluent .app .sidebar` (0,3,0 : fond surface-neutral-default-rest,
       bordures haute et droite, marge haute) : !important plutôt que le jeton de
       surface redéclaré ici, qui repeindrait aussi le tiroir de thème rendu dedans. */
    background: var(--ds-sidebar-bg) !important;
    border: none !important;
    border-radius: 0 !important;
    margin-top: 0 !important;
}

.sidebar a {
    text-decoration: none !important;
}

/* Pied : compte et réglages NATIFS (refonte du 29/10/2026), au-dessus de la version. Le compte
   (AccountComponent : avatar, menu « Mes détails » / « Déconnexion ») et la roue des réglages
   (SettingsComponent : tiroir d'apparence, densité, langue) remplacent les entrées « Apparence » et
   « Déconnexion » que le menu relayait par leur libellé. Un filet le sépare du menu ; il ne défile pas
   (margin-top:auto le plaque en bas de la colonne, la version dessous). Les deux boutons sont des
   boutons d'en-tête de XAF (.btn-header), habillés par leurs classes XAF : leur icône est un masque
   en currentColor, que la couleur du bouton teinte. */
.sidebar__account {
    flex: none;
    position: relative; /* repère du menu du compte, ouvert vers le haut */
    display: flex;
    align-items: center;
    gap: var(--dxds-spacing-80);
    margin-top: auto;
    border-top: 1px solid var(--ds-sidebar-separator);
    padding: var(--dxds-spacing-100) var(--ds-sidebar-inset-x) 0;
}
.sidebar .sidebar__account .account-container,
.sidebar .sidebar__account .theme-settings {
    position: static; /* le menu et le tiroir se calent sur le pied, pas sur leur bouton */
    display: flex;
    /* La feuille XAF les retire de 8px à gauche (en-tête) : l'avatar et la roue sortaient de la colonne
       des icônes du menu, de 4px à droite en rail (mesuré le 29/10/2026). */
    padding-left: 0;
}
.sidebar .sidebar__account .account-button,
.sidebar .sidebar__account .theme-button {
    width: var(--dxds-spacing-320);
    min-width: var(--dxds-spacing-320);
    height: var(--dxds-spacing-320);
    min-height: var(--dxds-spacing-320); /* le thème donne 36px à un bouton d'en-tête */
    padding: 0;
    border: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
/* Avatar : rond, sur le voile neutre du survol, l'icône claire. Plus le lime de l'entrée active
   (29/10/2026) : le lime dit « vous êtes ici », et en rail l'avatar passait pour une page ouverte. */
.sidebar .sidebar__account .account-button {
    border-radius: 50%;
    background: var(--ds-sidebar-item-hover-bg);
    color: var(--ds-sidebar-page-enable-content);
}
/* Pictogrammes natifs du pied à la taille de ceux du menu (voir --menu-native-icon-scale). */
.sidebar .sidebar__account .xaf-image,
.sidebar .about-info__icon .xaf-image {
    scale: var(--menu-native-icon-scale);
}
/* Roue : une entrée du menu, sans fond au repos, le voile au survol. */
.sidebar .sidebar__account .theme-button {
    border-radius: var(--dxds-border-radius-40);
    background: transparent;
    color: var(--ds-sidebar-page-enable-content);
}
.sidebar .sidebar__account .theme-button:hover,
.sidebar .sidebar__account .account-button:hover {
    box-shadow: 0 0 0 var(--dxds-spacing-30) var(--ds-sidebar-item-hover-bg);
}
.sidebar .sidebar__account .account-button:focus-visible,
.sidebar .sidebar__account .theme-button:focus-visible {
    outline: 2px solid var(--ds-sidebar-page-enable-content);
    outline-offset: 2px;
}
.sidebar__user {
    flex: 1;
    min-width: 0;
    color: var(--ds-sidebar-page-enable-content);
    font-size: var(--menu-font-size);
    font-weight: var(--ds-font-weight-semibold);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: pointer; /* un clic ouvre le menu du compte (sidebar.js) */
}
/* Menu du compte : XAF le cale sous le bouton de l'en-tête ; au pied, il s'ouvre vers le haut. */
.sidebar .sidebar__account .account-main {
    top: auto;
    bottom: 100%;
    left: var(--ds-sidebar-inset-x);
    right: auto;
    margin-bottom: var(--dxds-spacing-80);
}
/* Dropdowns DevExpress (langue, mode de taille) DANS le tiroir : leur liste est rendue dans
   le portail global <dxbl-popup-root> en fin de <body>, dont les cellules (dxbl-popup-cell)
   sont à z-index:0 -> la liste s'ouvre mais est peinte SOUS le tiroir (.settings-bar,
   z-index:1100 posé par XAF) = invisible et incliquable. On rehausse les cellules popup
   au-dessus du tiroir, et seulement TIROIR OUVERT (.show-dropdown, la classe XAF qui lui
   donne ses 1100) : le reste du temps, l'empilement des fenêtres et listes reste celui du
   thème. Leur ordre relatif reste l'ordre DOM (valeur égale). !important : le thème écrit
   le z-index de chaque cellule en style inline. */
body:has(.sidebar .theme-settings.show-dropdown) dxbl-popup-cell { z-index: 1150 !important; }

/* Version en bas de menu (bloc « À propos » natif XAF + date du build) : « Version 2026.10.1 bêta »
   en 10px blanc, puis « Mis à jour le … », atténué (complément). Sous le compte, dans le pied fixe dont
   le filet le sépare du menu (refonte du 29/10/2026) : sans ce filet, le menu s'arrêtait au pixel où le
   pied commence et sa dernière entrée, coupée net, semblait passer dessous.
   En rail replié, l'icône « i » seule (section 5). L'étiquette d'environnement, hors production, se
   cale en bas à droite des deux lignes. */
.sidebar .about-info {
    flex: none;
    margin: 0; /* annule aussi l'ancien mx-3/mb-4 */
    padding: var(--dxds-spacing-80) var(--ds-sidebar-inset-x) var(--ds-pim-sidebardark-content-padding-y-default);
    display: flex;
    align-items: flex-end;
    gap: var(--dxds-spacing-80);
    /* La feuille XAF pose `.about-info { opacity: 0.5 }` : les couleurs de la charte (version en blanc, date
       en gris à 5:1, pastille à 4,5:1 au moins) passaient sous le seuil de lisibilité. */
    opacity: 1;
    line-height: 1.3;
    font-family: var(--dxds-font-family-sans-serif);
}
.about-info__text {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
}
.about-info__product {
    font-size: var(--dxds-font-size-100);
    color: var(--ds-sidebar-page-enable-content);
}
.about-info__date {
    font-size: var(--dxds-font-size-100);
    color: var(--ds-sidebar-subtle-content);
}
/* Icône « i » du rail (section 5) : le menu déplié montre le texte, pas l'icône. */
.sidebar .about-info__icon {
    display: none;
}

/* En-tête de la sidebar (logo Merkial). Le wordmark est vectorisé dans le SVG
   (lettres en tracés, aucune police à charger) -> rendu fidèle à toute taille. */
.sidebar__brand {
    display: flex;
    align-items: center;
    gap: var(--dxds-spacing-80);
    /* Haut = 20px, côtés = le retrait du panneau (15px, maquette). Bas = 14px : le gap Figma
       en-tête → recherche est de 24px TOTAL. Comme la zone de recherche porte déjà
       10px de padding-top, on met 14px ici (14 + 10 = 24) pour ne pas dépasser. */
    padding: var(--dxds-spacing-200) var(--ds-sidebar-inset-x) 14px;
}
/* Le logo est un bouton (29/10/2026) : il mène à l'Accueil (sidebar.js), prend le focus et porte le
   nom de l'Accueil. Bouton remis à nu : ni fond ni bordure, le liseré de focus clavier du menu. */
.sidebar__home {
    display: inline-flex;
    align-items: center;
    gap: var(--dxds-spacing-80);
    padding: 0;
    border: none;
    border-radius: var(--dxds-border-radius-40);
    background: transparent;
    cursor: pointer;
}
.sidebar__home:focus-visible,
.sidebar__collapse-btn:focus-visible,
.sidebar .about-info__icon:focus-visible {
    outline: 2px solid var(--ds-sidebar-page-enable-content);
    outline-offset: 2px;
}
/* Sans !important (retirés le 28/10/2026, mesurés identiques) : aucune règle du thème ni de XAF ne
   vise ces images, qui ne sont pas des composants DevExpress. */
.sidebar__logo {
    height: 30px;
    width: auto;
    object-fit: contain;
    max-width: 100%;
}
/* Mot « merkial » (SVG blanc), à droite du cube. */
.sidebar__logo--full {
    height: 22px;
}
/* Cube : son SVG a preserveAspectRatio="none" -> dimensions fixes au ratio
   natif (26.76 × 31.11) pour éviter qu'il s'étire. */
.sidebar__logo--mark {
    width: 26px;
    height: 30px;
}

/* Étiquette d'environnement (« Dév », « Préprod »), hors production, au pied à droite de la version : une
   pastille du composant « Tag (color) », en capitales. Rien n'est rendu en production. */
.sidebar__env {
    flex: none;
    padding: 0 var(--dxds-spacing-40);
    border-radius: var(--dxds-border-radius-40);
    font-family: var(--dxds-font-family-sans-serif);
    font-size: var(--dxds-font-size-100);
    font-weight: var(--ds-font-weight-semibold);
    letter-spacing: 0.06em;
    line-height: var(--dxds-line-height-160);
    text-transform: uppercase;
    white-space: nowrap;
}
.sidebar__env--development {
    background: var(--ds-sidebar-env-development-bg);
    color: var(--ds-sidebar-env-development-content);
}
.sidebar__env--preproduction {
    background: var(--ds-sidebar-env-preproduction-bg);
    color: var(--ds-sidebar-env-preproduction-content);
}
.sidebar__env--other {
    background: var(--ds-sidebar-env-other-bg);
    color: var(--ds-sidebar-env-other-content);
}

/* Flèche de bascule pli/dépli (Figma : 14px, en bout de l'en-tête).
   Le clic est géré dans sidebar.js (un onclick inline serait bloqué par la CSP)
   et déclenche la bascule NATIVE XAF (pose/retire .collapse-toggle sur .app). */
.sidebar__collapse-btn {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: none;
    background: transparent;
    color: var(--ds-sidebar-page-enable-content);
    cursor: pointer;
}
.sidebar__chevron {
    /* Taille forcée en CSS (20px, maquette) : l'emporte sur les attributs
       width/height="14" du SVG inline -> ajustable sans recompiler le .razor. */
    width: 20px;
    height: 20px;
    transition: transform 0.15s ease;
}


/* ============================================================
   3. FILTRE DE NAVIGATION (champ de recherche natif XAF)
   On habille le champ « Filter… » NATIF de la navigation (il garde sa
   loupe et sa fonction de filtrage). Le champ est l'élément
   `.dxbl-navigation-filter.dxbl-text-edit` lui-même, rendu dans `.dxbl-treeview`.
   ============================================================ */

/* « Rechercher » : la maquette en faisait une ENTRÉE du menu (Sidebardark-item niveau 1, 6001-4315), sans
   fond ni bordure ; rien n'y disait qu'on pouvait taper. Depuis la refonte du 29/10/2026, il reprend
   l'allure d'un champ (fond blanc 5 %, bordure claire à 3,9:1), à la hauteur d'une entrée. Il garde sa
   fonction native (filtrer le menu, résultat sous ses parents, deux lettres au moins :
   NavigationMenuController) ; « / » y met le focus (sidebar.js). Le rail replié (section 5) le repasse
   en carré 32px, sans cadre. */
.sidebar .dxbl-navigation-filter {
    box-sizing: border-box;
    width: auto; /* le thème le met à 100% : avec le retrait, il débordait de 2 × 15px */
    margin-inline: var(--ds-sidebar-inset-x);
    /* Les 24px de la maquette entre le logo et la première entrée sont déjà faits par l'en-tête et
       la zone du menu : pas de marge haute en plus (le thème en pose 4px). */
    margin-top: 0;

    /* Jetons du champ, lus par le thème sur ce même élément (core.min.css, .dxbl-text-edit) :
       fond = surface-neutral-default-rest, texte = content-neutral-default-rest, indication =
       content-neutral-deep-rest, bordure = border-neutral-default-rest / -hovered / -active,
       loupe (et bouton d'effacement) = content-neutral-subdued-rest / -hovered. Taille et
       police : celles de l'arbre (section 4). */
    --dxds-color-surface-neutral-default-rest:    var(--menu-search-bg);
    --dxds-color-content-neutral-default-rest:    var(--ds-sidebar-page-enable-content);
    /* Texte indicatif en gris, pour ne pas se lire comme une saisie (7,0:1 sur le teal). */
    --dxds-color-content-neutral-deep-rest:       var(--ds-sidebar-muted-content);
    --dxds-color-border-neutral-default-rest:     var(--menu-search-border);
    --dxds-color-border-neutral-default-hovered:  var(--menu-search-border);
    /* Bordure inchangée au clic ; le focus garde le soulignement d'accent du thème (::after). */
    --dxds-color-border-neutral-default-active:   var(--menu-search-border);
    --dxds-color-content-neutral-subdued-rest:    var(--ds-sidebar-page-enable-content);
    --dxds-color-content-neutral-subdued-hovered: var(--ds-sidebar-item-hover-content);
    border-radius: var(--dxds-border-radius-40);

    /* Le composant natif du filtre pose un style INLINE `border-bottom-width:1px !important` ;
       sa couleur suit le soulignement du thème (content-neutral-subdued-rest, la loupe blanche
       ci-dessus), plus vif que le cadre. On lui donne la couleur du cadre. */
    border-bottom-color: var(--menu-search-border) !important;
}

/* Survol = celui d'une entrée du menu (voile blanc, texte et loupe clairs). Le thème ne change pas le
   fond d'un champ survolé, seulement sa bordure : les jetons redéclarés sur l'élément survolé. */
.sidebar .dxbl-navigation-filter:hover {
    --dxds-color-surface-neutral-default-rest: var(--ds-sidebar-item-hover-bg);
    --dxds-color-content-neutral-default-rest: var(--ds-sidebar-item-hover-content);
    --dxds-color-content-neutral-deep-rest:    var(--ds-sidebar-item-hover-content);
    --dxds-color-content-neutral-subdued-rest: var(--ds-sidebar-item-hover-content);
}

/* Loupe survolée : sans voile propre (elle est dans l'entrée survolée), claire. Le thème fixe en dur le
   survol d'un bouton icône de champ (`.dxbl-text-edit>.dxbl-btn.dxbl-btn-icon { --dxbl-btn-hover-bg:
   transparent; --dxbl-btn-hover-color: var(--dxbl-btn-color) }`, 0,3,0) sans lire de jeton : variables
   internes, à une spécificité au-dessus (0,4,0). */
.sidebar .dxbl-navigation-filter > .dxbl-btn.dxbl-btn-icon {
    --dxbl-btn-hover-bg:    transparent;
    --dxbl-btn-hover-color: var(--ds-sidebar-item-hover-content);
    /* Loupe à 10px du bord (padding-x de l'entrée), libellé 5px après (écart icône → texte).
       !important : le thème pose le retrait de la loupe d'un champ de recherche par un sélecteur
       plus spécifique qu'aucun raisonnable ici (`.dxbl-text-edit > .dxbl-btn-group-vertical >
       .dxbl-btn.dxbl-btn-icon:has(~ input[type="search"])`, voir aussi la section 5). */
    padding-inline: var(--ds-pim-sidebar-item-content-padding-x-open) 0 !important;
    /* Loupe à la taille des icônes d'entrée (section 1b) : le thème dimensionne l'image par ce palier
       public, hérité du bouton. */
    --dxds-spacing-160: var(--menu-icon-size);
}

/* Hauteur de l'entrée par ses marges internes, comme les items (35px en Standard, 24px en Compact),
   avec une ligne de 1,25 qui compense le cadre du champ. */
.sidebar .dxbl-navigation-filter .dxbl-text-edit-input {
    padding-block: var(--menu-item-padding-y);
    padding-left: var(--menu-icon-gap);
    line-height: 1.25;
}

/* Filtre sans résultat : « Aucune donnée à afficher » du thème, que la charte veut gris
   (« Empty research », ds-pim/6319-3626). Il héritait du texte sombre de la page, illisible sur
   le teal (1,4:1) : le gris des sous-items du menu, lisible sur ce fond. */
.sidebar .dxbl-treeview-empty-data {
    color: var(--ds-sidebar-muted-content);
}


/* ============================================================
   4. ARBRE DE NAVIGATION (items, états, titres de section)
   ============================================================ */

/* Jetons de l'arbre, redéclarés sur SA RACINE : le thème y résout ses variables d'état
   (core.min.css, `.dxbl-treeview`) — texte = content-neutral-subdued-rest, survol =
   surface-neutral-alpha-hovered + content-neutral-subdued-hovered (le voile neutre de la refonte du
   29/10/2026, qui ne se confond plus avec l'entrée active), item sélectionné =
   surface-neutral-alpha-selected + content-neutral-default-rest, chevron =
   content-neutral-subdued-rest / -hovered. On y met aussi le fond transparent pour
   révéler le teal. */
.sidebar .dxbl-treeview {
    background: transparent;

    --dxds-color-content-neutral-subdued-rest:    var(--ds-sidebar-page-enable-content);
    --dxds-color-surface-neutral-alpha-hovered:   var(--ds-sidebar-item-hover-bg);
    --dxds-color-content-neutral-subdued-hovered: var(--ds-sidebar-item-hover-content);
    --dxds-color-surface-neutral-alpha-selected:  var(--ds-sidebar-page-active-bg);
    --dxds-color-content-neutral-default-rest:    var(--ds-sidebar-page-active-content);
    /* Corps du menu selon la densité (section 1b) : le petit corps du thème (base-sm) y vaut 14px
       en Standard, 12px en Compact. Vaut aussi pour le champ de recherche. */
    --dxds-font-size-base-sm: var(--menu-font-size);

    /* Chevron survolé ou appuyé : le thème lui donne les jetons de survol et d'appui des
       items (`.dxbl-treeview … > .dxbl-btn { --dxbl-btn-hover-color:
       var(--dxbl-treeview-btn-hover-color) }`, lu sur content-neutral-subdued-hovered /
       -active), soit le teal posé ci-dessus pour le texte sur fond lime. Mais le chevron est
       le frère de la boîte, pas son descendant : le survoler n'allume pas le lime, et il
       deviendrait teal sur teal. Variables internes, faute de jeton propre au chevron. */
    --dxbl-treeview-btn-hover-color:  var(--ds-sidebar-page-enable-content);
    --dxbl-treeview-btn-active-color: var(--ds-sidebar-page-enable-content);

    /* Liseré de focus CLAVIER du thème (`.dxbl-treeview-item-container:focus-visible`, lu sur
       border-focus-default) : l'accent de la charte y fait 2,4:1 sur le teal, le blanc du menu
       10,4:1. Le thème le cache déjà après un clic (`data-dx-focus-hidden`) : seul le clavier le voit. */
    --dxds-color-border-focus-default: var(--ds-sidebar-page-enable-content);

    /* Mise en page du menu : aucun jeton public ne la porte (le thème lit des paliers
       d'espacement partagés par d'autres usages), d'où ces trois variables internes. */
    /* Écart vertical entre items (4px en Standard ; 2px en Compact, section 1b), rendu en
       `padding-bottom` sur CHAQUE .dxbl-treeview-item-content ; il sépare AUSSI le titre de module
       de sa 1ʳᵉ sous-page. */
    --dxbl-treeview-item-spacing: var(--menu-item-spacing);
    /* Marge BASSE du champ de recherche (entre « Recherche » et « Accueil »), comme l'écart
       inter-items. */
    --dxbl-treeview-navigation-filter-bottom-spacing: var(--menu-item-spacing);
    /* Indentation par niveau ANNULÉE : retour designer = items de même TAILLE (largeur) quel
       que soit le niveau. Les sous-pages restent repérables par leur retrait intérieur (règles
       aria-level plus bas), pas par une indentation qui les rétrécirait. */
    --dxbl-treeview-item-content-indent: 0;
}

/* STRUCTURE (maquette « Sidebardark-item », design/reference/ds-pim/6001-4419) : niveau 1 =
   titres de section repliables (« Sidebardark-section-item ») ; niveau 2 = modules à ICÔNE ;
   niveau 3 = pages, sans icône ni puce, leur texte aligné sur celui du module ; niveau 4+ =
   10px plus loin. Tous les items sont blancs au repos. La puce ◌ de la maquette est retirée le
   29/10/2026 (refonte, décision d'Adrien) : elle ne portait aucune information, et dans le rail
   elle était la seule chose visible. */

/* Retrait du panneau (15px, variante Open) porté par la liste racine, à la place des 4px du
   thème : séparateurs, titres et items font ainsi les 220px de la maquette. */
.sidebar .xaf-navmenu ul[data-is-root] {
    padding-inline: var(--ds-sidebar-inset-x);
    /* Écart « Recherche » → première entrée = l'écart entre items (8px, marge basse du champ),
       sans les 4px du thème en plus. */
    padding-top: 0;
}

/* Icône d'entrée selon la densité (section 1b) : 14px et 5px avant le libellé en Standard
   (« Sidebardark-item »), 16px et 4px en Compact (le thème) ; la feuille XAF (`.xaf-nav-menu-item-icon`)
   la fixe à 16px. L'écart : même poids que la règle du thème qui le pose (0,5,0), par les classes XAF,
   chargée après. L'écart vaut aussi pour l'icône de section (sa taille : plus bas). Le rail
   (section 5) remet l'écart à 0. */
.sidebar .xaf-navmenu.xaf-tree-view .xaf-nav-item .xaf-nav-menu-item-icon {
    width: var(--menu-icon-size);
    height: var(--menu-icon-size);
    margin-inline-end: var(--menu-icon-gap);
}

/* Pages (niveau 3+) : sans icône. L'icône que le modèle leur donne parfois est masquée ; leur
   texte s'aligne sur celui du module par le retrait (règles aria-level plus bas).
   Cible : conteneur ni niveau 1 (Accueil, titre de section) ni niveau 2 (module à icône).
   Titres de section : sans icône non plus — sans ImageName dans le modèle, XAF leur pose son dossier
   par défaut. Paramétrage a la sienne, que le rail montre quand la section est repliée : elle est masquée
   plus bas, hors rail. */
.sidebar .dxbl-treeview-item-container:not([aria-level="1"]):not([aria-level="2"]) > .xaf-nav-menu-item-icon,
.sidebar ul[data-is-root] > .dxbl-treeview-item.has-children:not(:has(img[src*="NavSectionSettings"])) > .dxbl-treeview-item-content > .dxbl-treeview-item-container > .xaf-nav-menu-item-icon {
    /* !important : XAF impose l'affichage de l'icône via sa propre feuille. */
    display: none !important;
}

/* ----- Titres de section FIXES (refonte du 29/10/2026) -----
   Le niveau 1 à enfants (enfant direct du <ul data-is-root>) : un filet au-dessus, puis une étiquette
   en capitales 11px, graisse 600 — une rubrique, pas une destination : ni chevron, ni icône, ni survol,
   ni curseur de clic. Le repli d'une section est annulé à la source (NavigationMenuController,
   BeforeCollapse) : un seul niveau se replie dans le menu, celui des modules. Remplace les titres
   repliables avec icône du 27/10/2026 (maquette « Sidebardark-section-item », 6459-3283). Les sections
   démarrent dépliées (NavigationMenuController). */
.sidebar ul[data-is-root] > .dxbl-treeview-item.has-children {
    border-top: 1px solid var(--ds-sidebar-separator);
    padding-top: var(--menu-section-spacing);
}
.sidebar ul[data-is-root] > .dxbl-treeview-item.has-children > .dxbl-treeview-item-content {
    padding: var(--menu-section-padding-y) var(--ds-sidebar-section-padding-x);
    /* L'écart titre → première entrée (5px, 2px en Compact), à la place de l'écart entre items
       (padding-bottom). */
    margin-bottom: var(--menu-section-spacing);
    cursor: default;
}
/* Pas de chevron : la section ne se replie pas. */
.sidebar ul[data-is-root] > .dxbl-treeview-item.has-children > .dxbl-treeview-item-content > .dxbl-btn {
    display: none;
}
/* La boîte du titre ne porte ni fond ni gabarit d'item. Le survol du thème ne fait que changer la
   variable de fond de la boîte : ce sélecteur, plus lourd que le sien, garde la boîte transparente.
   !important sur le padding seulement : le gabarit des items (section 4, plus bas) pose le sien en
   !important. */
.sidebar ul[data-is-root] > .dxbl-treeview-item.has-children > .dxbl-treeview-item-content > .dxbl-treeview-item-container {
    background: transparent;
    min-height: 0;
    padding: 0 !important;
    cursor: default;
    /* Ligne de 15px pour le libellé de 11px en Standard (maquette : ligne de 31px = 8 + 15 + 8), celle
       d'une entrée en Compact (16px : ligne de 24px). La taille sur la boîte aussi : la hauteur de ligne
       s'y calcule. */
    font-size: var(--menu-section-font-size);
    line-height: var(--menu-line-height);
}
/* ----- Paramétrage : la seule section qui se replie (décision d'Adrien, 29/10/2026) -----
   Sept modules qu'on ouvre rarement, repliés à l'ouverture (NavigationMenuController) pour que le menu tienne
   dans l'écran en Standard. Repérée par son icône (ImageName NavSectionSettings) : XAF ne pose aucune
   classe par entrée : la section est celle qui contient cette icône (ses modules ont les leurs), et ses éléments
   se désignent par leur place et leur rôle, sans classe interne du thème. Son titre reprend le chevron et le
   curseur de clic ; son icône reste masquée ici. */
.sidebar ul[data-is-root] > li.xaf-nav-item.has-children:has(img[src*="NavSectionSettings"]) > :first-child,
.sidebar ul[data-is-root] > li.xaf-nav-item.has-children:has(img[src*="NavSectionSettings"]) > :first-child > [role="treeitem"] {
    cursor: pointer;
}
.app:not(.collapse-toggle) .sidebar ul[data-is-root] > li.xaf-nav-item.has-children:has(img[src*="NavSectionSettings"]) > :first-child > button {
    display: inline-flex;
}
.app:not(.collapse-toggle) .sidebar ul[data-is-root] > li.xaf-nav-item.has-children img.xaf-nav-menu-item-icon[src*="NavSectionSettings"] {
    display: none;
}
.sidebar ul[data-is-root] > .dxbl-treeview-item.has-children > .dxbl-treeview-item-content .xaf-nav-link span {
    color: var(--ds-sidebar-section-content) !important;
    font-size: var(--menu-section-font-size);
    font-weight: var(--ds-font-weight-semibold);
    letter-spacing: 0.06em;
    /* En capitales, comme la maquette (« COMMERCE », « DONNÉES DE BASE ») ; le libellé du modèle reste
       en casse normale pour la recherche. Chrome expose pourtant le nom en capitales à l'arbre
       d'accessibilité (mesuré le 28/10/2026) : un lecteur d'écran le lit comme un mot ordinaire. */
    text-transform: uppercase;
}

/* Pas de soulignement sur les items de nav. GOTCHA CSS : les items navigables
   sont des <a> (.dxbl-treeview-item-container) ; un `text-decoration:underline`
   porté par le <a> est peint à travers ses descendants et ne peut PAS être
   annulé sur l'enfant -> il FAUT neutraliser sur le <a> lui-même (et au survol). */
.sidebar .dxbl-treeview-item-container,
.sidebar .dxbl-treeview-item-container:hover,
.sidebar .dxbl-treeview-item-container:focus,
.sidebar .xaf-nav-link,
.sidebar .xaf-nav-link span,
.sidebar .xaf-nav-link:hover,
.sidebar .xaf-nav-link:hover span {
    text-decoration: none !important;
}

/* Chevron d'expansion à DROITE de l'item (façon maquette) au lieu de la gauche.
   Le bouton est le .dxbl-btn enfant direct du contenu d'item. Son fond reste
   transparent dans tous les états : au survol du seul chevron, le thème le peindrait
   avec le jeton de survol de l'arbre (le lime ci-dessus), un carré clair hors de la
   boîte de l'item. Sans bordure : le thème lui en donne une de 1 px (transparente), qui
   décalerait l'icône d'autant, le chevron étant calé par `right`. Pas de liseré de focus. */
.sidebar .dxbl-treeview-item-content > .dxbl-btn,
.sidebar .dxbl-treeview-item-content > .dxbl-btn:hover,
.sidebar .dxbl-treeview-item-content > .dxbl-btn:focus,
.sidebar .dxbl-treeview-item-content > .dxbl-btn:focus-visible,
.sidebar .dxbl-treeview-item-content > .dxbl-btn:active {
    order: 10;
    margin-left: auto;
    background: transparent !important;
    border: none !important;
    outline: none !important;
}

/* Icône chevron à 12×12 (maquette), au lieu des 16 px du thème. Elle garde l'orientation du
   thème Fluent (« › » replié, « ⌄ » déplié) : la maquette la retournait (« ⌄ » / « ⌃ »), la
   refonte du 29/10/2026 rend la main au composant (CHARTE.md § 1). Au repos il est blanc (jeton
   du chevron, ci-dessus). */
.sidebar .dxbl-treeview-item-content > .dxbl-btn .dxbl-image {
    width: var(--dxds-spacing-120) !important;
    height: var(--dxds-spacing-120) !important;
    flex-shrink: 0;
    aspect-ratio: 1 / 1;
}

/* Libellés : RETOUR À LA LIGNE autorisé, PAS d'ellipsis « … » (choix utilisateur).
   Un libellé long (« Identifiant de connecteur », « Statut de synchronisation »…)
   passe sur deux lignes plutôt que d'être tronqué. On retire donc le `nowrap` +
   `text-overflow:ellipsis` + `overflow:hidden` qui forçaient la troncature.
   Le flex reste pour que le lien occupe la largeur ; `overflow-wrap:break-word`
   gère les très longs mots isolés. */
.sidebar .dxbl-treeview-item-text-container,
.sidebar .dxbl-text {
    min-width: 0;
}
.sidebar .xaf-nav-link {
    flex: 1 1 auto;
    min-width: 0;
}
.sidebar .xaf-nav-link span {
    display: block;
    white-space: normal;
    overflow-wrap: break-word;
    /* Ligne selon la densité (section 1b) : avec les marges internes de la boîte, elle fait seule la
       hauteur de l'entrée — 8 + 19 + 8 = 35px en Standard, 4 + 16 + 4 = 24px en Compact. */
    line-height: var(--menu-line-height);
    /* Plafond à 2 lignes ; au-delà on tronque (overflow hidden) : 54px max en Standard. */
    max-height: 2.7em;
    overflow: hidden;
}

/* Ligne de la boîte = celle du libellé : le thème lui en pose une de 20px en Standard, résolue
   au-dessus de l'arbre, qui faisait l'entrée de 36px au lieu de 35. Même poids que sa règle (0,5,0),
   par les classes XAF et le rôle de la boîte, chargée après. */
.sidebar .xaf-navmenu.xaf-tree-view .xaf-nav-item > * > [role="treeitem"] {
    line-height: var(--menu-line-height);
}

/* Hauteur d'item = HUG (maquette Figma « … × 54 Hug ») : marges internes + ligne du libellé
   (.xaf-nav-link span), 1 ou 2 lignes — aucune hauteur forcée. Le rail replié (section 5) repose
   32px, plus spécifique -> non impacté. */
.sidebar .dxbl-treeview-item-container {
    align-items: center;
    /* Largeur : toute la ligne, soit les 220px de la maquette (250px moins le retrait de 15px de la
       liste racine, section 4 en tête) — le thème étire déjà la boîte (`flex: 1 1 auto`). */
    /* Padding interne : vertical selon la densité (section 1b), 10px horizontal (maquette). Le
       niveau 3+ surcharge padding-left (règles aria-level plus spécifiques). */
    box-sizing: border-box !important;
    padding-top: var(--menu-item-padding-y) !important;
    padding-bottom: var(--menu-item-padding-y) !important;
    padding-left: var(--ds-pim-sidebar-item-content-padding-x-open) !important;
    padding-right: var(--ds-pim-sidebar-item-content-padding-right-open) !important;
    /* Curseur « main » : signale au survol que la zone (toute la boîte, pas juste le
       texte) est cliquable. */
    cursor: pointer;
}
/* !important + couverture du lien interne ET du chevron : un module (« Produits ») est un
   <a> SANS href (il déplie au lieu de naviguer) -> curseur `auto` par défaut, et le thème
   DevExpress pose sa propre règle plus spécifique. On force donc le curseur main sur toute
   la boîte cliquable — sauf un titre de section, qui ne réagit pas au clic. */
.sidebar .xaf-nav-item:not(ul[data-is-root] > .has-children) > * > .dxbl-treeview-item-container,
.sidebar .xaf-nav-item:not(ul[data-is-root] > .has-children) > * > .dxbl-treeview-item-container .xaf-nav-link,
.sidebar .xaf-nav-item:not(ul[data-is-root] > .has-children) > * > .dxbl-treeview-item-container .xaf-navigation-link-click-area,
.sidebar .dxbl-treeview-item-content > .dxbl-btn {
    cursor: pointer !important;
}
/* Retrait PAR NIVEAU : le texte d'une page commence sous celui de son module (marge de la boîte +
   icône + écart, selon la densité) ; un niveau de plus (Gencod › Palettisation) le décale encore de
   10px.
     - aria-level 2 (module à icône, ex. Produits)  -> 10px (base, plus haut)
     - aria-level 3 (page, ex. Marque)              -> 10px + icône + écart
     - aria-level 4+ (page profonde, Palettisation) -> 10px de plus
   Spécificités : [aria-level] = 0,3,0 ; les 3 :not = 0,5,0 -> tous > base (0,2,0). */
.sidebar .dxbl-treeview-item-container[aria-level="3"] {
    padding-left: calc(var(--ds-pim-sidebar-item-content-padding-x-open) + var(--menu-icon-size) + var(--menu-icon-gap)) !important;
}
.sidebar .dxbl-treeview-item-container:not([aria-level="1"]):not([aria-level="2"]):not([aria-level="3"]) {
    padding-left: calc(var(--ds-pim-sidebar-item-content-padding-x-open) + var(--menu-icon-size) + var(--menu-icon-gap) + var(--dxds-spacing-100)) !important;
}
/* La ligne d'item occupe toute la largeur de la zone de nav et sert de repère de position
   (position: relative) pour caler le chevron en absolu. */
.sidebar .dxbl-treeview-item-content {
    width: 100%;
    position: relative;
}
/* Le libellé d'une entrée à sous-menus s'arrête 5px avant son chevron (maquette : 164px de texte sur
   220), au lieu de passer dessous — le chevron, sorti du flux (ci-dessous), ne réserve pas sa place.
   Pas pour un titre de section : son chevron est dans le flux. */
.sidebar .has-children:not(ul[data-is-root] > .has-children) > * > * .xaf-nav-link {
    margin-right: calc(var(--dxds-spacing-120) + var(--menu-icon-gap));
}

/* Chevron des modules SORTI DU FLUX (absolu) : sinon, en flux, il décalait la boîte et cassait
   l'alignement (pages sans chevron vs modules avec). La boîte occupe toute la ligne : le chevron se
   cale à 10px de son bord droit (padding-right de la boîte, maquette). Même poids que la règle du
   thème qui remet le bouton en `position: relative` (0,4,0), chargée après : sans ce poids, le bouton
   restait dans le flux et rognait la boîte de ses 22px. */
.sidebar .dxbl-treeview-item > .dxbl-treeview-item-content > .dxbl-btn {
    position: absolute;
    /* 10px du bord jusqu'à l'icône, moins les 5px de marge interne du bouton du thème. */
    right: calc(var(--ds-pim-sidebar-item-content-padding-right-open) - var(--dxds-spacing-50));
    /* Calé sur la boîte d'item, PAS `bottom:0` : .dxbl-treeview-item-content porte en plus l'écart
       inter-items en padding-bottom (--dxbl-treeview-item-spacing) -> un `bottom:0` étirerait le
       chevron sous la boîte et le décentrerait. Bas = cet écart : centré dans les deux densités. */
    top: 0;
    bottom: var(--menu-item-spacing);
    margin: 0 !important;
    /* z-index : le chevron (absolu) PRÉCÈDE le <a> dans le DOM ; sans empilement explicite, le <a>
       (position:relative, z auto) et son FOND lime de survol/sélection se peignent PAR-DESSUS et
       masquent le chevron. z-index:1 le ramène devant la boîte. */
    z-index: 1;
}
/* Le volet de nav (treeview + scroll viewer) ajoutait ses paddings horizontaux par défaut
   (DevExpress) au retrait de la liste racine. On les annule : seul le retrait de 15px de la maquette
   reste. (.xaf-navigation-link-click-area, l'overlay de clic que rend XAF en position:absolute
   inset:0 dans la boîte, l'épouse seul : aucune largeur à forcer.) */
.sidebar .dxbl-treeview,
.sidebar .dxbl-scroll-viewer,
.sidebar .dxbl-scroll-viewer > .dxbl-scroll-viewer-content {
    padding-left: 0 !important;
    padding-right: 0 !important;
}

/* Espacement vertical = l'écart entre items PARTOUT (8px en Standard, 2px en Compact, section 1b).
   Il est déjà donné par --dxbl-treeview-item-spacing ; ici on neutralise tout retrait vertical que
   DevExpress poserait sur la LISTE IMBRIQUÉE des sous-pages, afin que l'écart « nom du module →
   1ʳᵉ sous-page » reste le même. No-op si aucune marge n'est posée. (La classe
   `dxbl-treeview-item-nodes`, absente de DevExpress 26.1.3, est retirée le 28/10/2026.) */
.sidebar .dxbl-treeview-item ul:not([data-is-root]) {
    margin-top: 0 !important;
    padding-top: 0 !important;
    margin-bottom: 0 !important;
    padding-bottom: 0 !important;
}
/* Fond de SÉLECTION (item actif) = la boîte arrondie (comme le survol et la maquette), PAS la ligne.
   DevExpress peint le fond de sélection sur la LIGNE (.dxbl-treeview-item-content) -> on la rend
   transparente et on porte le lime sur la boîte active. Sauf la ligne d'un titre de section, qui
   porte elle-même son voile de survol et d'appui (plus haut). */
.sidebar .dxbl-treeview-item:not(ul[data-is-root] > .has-children) > .dxbl-treeview-item-content {
    background-color: transparent !important;
}
.sidebar .dxbl-treeview-item-container.dxbl-active {
    background-color: var(--ds-sidebar-page-active-bg) !important;
    /* Second repère de la page ouverte, indépendant de la couleur (WCAG 1.4.1). L'ombre « standard »
       de la maquette (3 % de noir) ne se voyait pas sur le teal : retirée le 29/10/2026. */
    font-weight: var(--ds-font-weight-semibold);
}
/* Le module qui contient la page ouverte (refonte du 29/10/2026) : liseré lime à gauche et graisse,
   pour qu'on sache où l'on est même quand le module est replié ou la page hors champ (Fluent 2 fait
   remonter l'indicateur sur la catégorie). Pas sur un titre de section, ni sur l'entrée active elle-même. */
.sidebar .dxbl-treeview-item.has-children:not(ul[data-is-root] > .has-children):has(.dxbl-treeview-item-container.dxbl-active)
    > .dxbl-treeview-item-content > .dxbl-treeview-item-container:not(.dxbl-active) {
    font-weight: var(--ds-font-weight-semibold);
    box-shadow: inset var(--dxds-spacing-30) 0 0 var(--ds-sidebar-ancestor-indicator);
}
/* Item enfoncé : le fond de l'item actif ; le texte reste le teal du survol (variantes « Pressed »
   de la maquette, qui n'utilisent pas le jeton sidebar/page/pressed — vert foncé, texte blanc). */
.sidebar .dxbl-treeview-item-container:active {
    background-color: var(--ds-sidebar-page-active-bg);
}

/* Pas de liseré de focus au CLIC. La maquette ne définit que 4 états d'item
   (enable / hover / pressed / selected) : aucun état « focus ». Le focus CLAVIER, lui, se voit
   (ui.md § 8, plan § 2.4) : le liseré du thème, teinté en tête de section 4. Il est tracé HORS
   de la boîte (le thème le rentre de 2px) pour se lire aussi sur une entrée lime, active : il
   tombe alors sur le teal, dans l'écart entre entrées. Pas de `box-shadow: none` ici : il
   effacerait le liseré du module de la page ouverte, qui en est un. */
.sidebar .dxbl-treeview-item-container:focus:not(:focus-visible),
.sidebar .xaf-nav-link:focus:not(:focus-visible) {
    outline: none !important;
}
/* Le thème pose son retrait (-2px) par `.dxbl-treeview .dxbl-treeview-container:not([data-dx-focus-hidden])
   .dxbl-treeview-item-container:focus-visible` (0,5,0) : dépassé par les classes XAF du menu (0,6,0). */
.sidebar .xaf-navmenu.xaf-tree-view .xaf-nav-item > * > [role="treeitem"]:focus-visible {
    outline-offset: 0;
}

/* Cale d'indentation NATIVE DevExpress (une par niveau, rendue DANS la boîte avant
   l'icône/puce). Même avec --dxbl-treeview-item-content-indent:0 elle pouvait conserver
   une largeur résiduelle -> l'écart « bord de boîte → icône » dépassait les 10px de
   padding-left. On la supprime en déplié (elle n'était masquée qu'en rail replié).
   L'indentation VOULUE des sous-items profonds (niveau 4+) reste portée par padding-left. */
.sidebar .dxbl-treeview-item-indent {
    display: none !important;
}

/* Icône (img de niveau 2) de l'entrée active : sur le lime, une icône blanche serait invisible.
   La maquette la veut TEAL. L'icône est un <img> (élément remplacé) : on la recolore via `filter`
   (≈ #164147 teal). Le survol, un voile sombre depuis le 29/10/2026, la laisse blanche. */
.sidebar .dxbl-treeview-item-container.dxbl-active > .xaf-nav-menu-item-icon {
    filter: var(--ds-sidebar-icon-on-light-filter);
}

/* Chevron d'un module ACTIF (boîte lime) : le passer en TEAL pour qu'il reste visible. Le chevron
   est calé sur le bord droit de la boîte (z-index:1, donc DESSUS). Au repos et au survol (voile
   sombre) il reste BLANC. L'état est celui de la boîte voisine, que le thème ne relie pas au
   bouton : variable interne posée sur la ligne, plus `color` et `fill` sur le <use> SVG. */
.sidebar .dxbl-treeview-item:not(ul[data-is-root] > .has-children) > .dxbl-treeview-item-content:has(> .dxbl-treeview-item-container.dxbl-active) {
    --dxbl-treeview-btn-color: var(--ds-sidebar-page-active-content);
}
.sidebar .dxbl-treeview-item:not(ul[data-is-root] > .has-children) > .dxbl-treeview-item-content:has(> .dxbl-treeview-item-container.dxbl-active) > .dxbl-btn .dxbl-image,
.sidebar .dxbl-treeview-item:not(ul[data-is-root] > .has-children) > .dxbl-treeview-item-content:has(> .dxbl-treeview-item-container.dxbl-active) > .dxbl-btn .dxbl-image use {
    color: var(--ds-sidebar-page-active-content) !important;
    fill: var(--ds-sidebar-page-active-content) !important;
}

/* Alignement d'Accueil. Accueil est le SEUL item de niveau 1 sans enfants (les autres
   items de niveau 1 sont les titres de section : « Exploitation », « Tiers »…).
   Indentation par niveau = 0 (section 4) -> Accueil n'a plus besoin de compensation (sinon
   décalé à droite). Cible : enfant direct de la racine, sans .has-children -> uniquement Accueil. */
.sidebar ul[data-is-root] > .dxbl-treeview-item:not(.has-children) > .dxbl-treeview-item-content {
    padding-left: 0;
}

/* ----- Scrollbar NATIF masqué dans la sidebar --------------------------------
   Le scroll interne du menu s'affiche ici via le scrollbar NATIF du navigateur,
   et le poste affiche les scrollbars « classiques » Windows AVEC boutons-flèches
   ▲▼ (laids et hors maquette). On masque ce scrollbar natif partout dans la
   sidebar SANS supprimer le défilement (molette/tactile conservés). Le scrollbar
   custom DevExpress (élément DOM, fin, sans flèches) n'est pas un scrollbar natif
   et n'est donc pas affecté. */
.sidebar *::-webkit-scrollbar {
    width: 0 !important;
    height: 0 !important;
}
.sidebar *::-webkit-scrollbar-button {
    display: none !important;
    width: 0 !important;
    height: 0 !important;
}
.sidebar * {
    scrollbar-width: none !important;        /* Firefox */
    -ms-overflow-style: none !important;     /* anciens Edge/IE */
}


/* ============================================================
   5. RAIL REPLIÉ (bascule manuelle au clic — pas au survol)
   La bascule est NATIVE XAF : le hamburger (masqué avec le header) pose
   `.collapse-toggle` sur `.app` et XAF persiste l'état. sidebar.js relaie le
   clic de la flèche vers ce hamburger. Depuis le 29/10/2026 (refonte), le rail ne
   montre que les modules : un clic sur une page de premier rang (Accueil) navigue
   sans déplier ; un clic sur un module déplie le menu, ce module ouvert.
   Le défaut XAF masque la sidebar repliée (`.collapse-toggle .sidebar
   {display:none}`) -> on le bat ici pour en faire un rail d'icônes 70px.
   ============================================================ */
.collapse-toggle .sidebar {
    /* !important : la feuille XAF masque la sidebar repliée par
       `.collapse-toggle .sidebar { display: none !important }` ; seul un !important la rétablit. */
    display: flex !important;
    width: 70px;
    min-width: 70px;
    /* Le champ de recherche n'y est qu'une loupe : sans le cadre du menu déplié (section 3). */
    --menu-search-bg:     transparent;
    --menu-search-border: transparent;
}

/* Icônes seules, libellés masqués À L'ŒIL seulement : un `display: none` retirait aussi le nom de
   chaque entrée au lecteur d'écran (entrées du rail sans nom, mesuré le 28/10/2026). Le libellé reste
   dans l'arbre d'accessibilité, sur 1px découpé. */
.collapse-toggle .sidebar .dxbl-treeview-item-text-container,
.collapse-toggle .sidebar .dxbl-treeview-item-text {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}
/* Chaque item = carré 32×32 centré (le fond de sélection/hover devient un
   carré lime, façon maquette). La ligne d'item, pleine largeur en déplié, se
   resserre sur le carré ; le thème la met déjà en flex, centrée en hauteur. */
.collapse-toggle .sidebar .dxbl-treeview-item-content {
    min-width: var(--dxds-spacing-320);
    max-width: var(--dxds-spacing-320);
    padding: 0;
    margin: 0 auto var(--dxds-spacing-80);
    justify-content: center;
    border-radius: var(--dxds-border-radius-40);
}
/* Le contenu (div) contient un <a.dxbl-treeview-item-container> qui PORTE le fond de
   sélection (lime) ET l'icône. On le resserre en CARRÉ 32px centré : sinon le fond lime
   s'étire en rectangle (toute la ligne en déplié) et l'icône reste callée à gauche. */
.collapse-toggle .sidebar .dxbl-treeview-item-container {
    min-width: var(--dxds-spacing-320);
    max-width: var(--dxds-spacing-320);
    height: var(--dxds-spacing-320);
    /* min-height reset : en déplié le conteneur a min-height:35px (hug 2 lignes) ; sans ce reset
       il forcerait le carré du rail à 35px au lieu de 32 (min-height > height l'emporte). */
    min-height: var(--dxds-spacing-320);
    margin: 0 auto;
    /* Padding REMIS À 0 : en déplié le conteneur a un padding de 8 × 10px posé en !important
       (section 4) ; seul un !important le bat, sinon il pousse l'icône hors du centre du carré. */
    padding: 0 !important;
    justify-content: center;
}
.collapse-toggle .sidebar .dxbl-treeview-item-content > .dxbl-btn { display: none; }
/* Le rail ne montre que les modules : les pages d'un module déplié n'y ont pas de place (elles
   étaient vingt pastilles identiques, mesuré le 28/10/2026). Leur liste est le conteneur dépliable
   du module (section › conteneur › liste › module › conteneur). */
.collapse-toggle .sidebar ul[data-is-root] > .dxbl-treeview-item > dxbl-expandable-container > ul > .dxbl-treeview-item > dxbl-expandable-container {
    display: none;
}
/* En rail, la page ouverte est cachée avec son module : c'est le module qui prend le carré lime de
   l'entrée active (et son icône teal), à la place du liseré du menu déplié. */
.collapse-toggle .sidebar .dxbl-treeview-item.has-children:not(ul[data-is-root] > .has-children):has(.dxbl-treeview-item-container.dxbl-active)
    > .dxbl-treeview-item-content > .dxbl-treeview-item-container {
    background-color: var(--ds-sidebar-page-active-bg);
    box-shadow: none;
}
.collapse-toggle .sidebar .dxbl-treeview-item.has-children:not(ul[data-is-root] > .has-children):has(.dxbl-treeview-item-container.dxbl-active)
    > .dxbl-treeview-item-content > .dxbl-treeview-item-container > .xaf-nav-menu-item-icon {
    filter: var(--ds-sidebar-icon-on-light-filter);
}
/* Pied du rail : l'avatar et la roue l'un sous l'autre, sans le nom ; le menu du compte s'ouvre à
   droite du rail, au ras du pied. */
.collapse-toggle .sidebar .sidebar__account {
    flex-direction: column;
    padding-inline: 0;
}
.collapse-toggle .sidebar .sidebar__user {
    display: none;
}
.collapse-toggle .sidebar .sidebar__account .account-main {
    bottom: 0;
    left: calc(100% + var(--dxds-spacing-80));
    margin-bottom: 0;
}
/* Pied du rail : l'icône « i » seule, au carré des entrées ; la version et la date passent dans son
   nom et son infobulle (sidebar.js). L'étiquette d'environnement reste, sous l'icône. */
.collapse-toggle .sidebar .about-info {
    flex-direction: column;
    align-items: center;
    gap: var(--dxds-spacing-40);
    padding-inline: 0;
}
.collapse-toggle .sidebar .about-info__text { display: none; }
.collapse-toggle .sidebar .about-info__icon { order: -1; }
.collapse-toggle .sidebar .about-info__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--dxds-spacing-320);
    height: var(--dxds-spacing-320);
    padding: 0;
    border: none;
    border-radius: var(--dxds-border-radius-40);
    background: transparent;
    color: var(--ds-sidebar-page-enable-content);
    cursor: pointer;
}
.collapse-toggle .sidebar .about-info__icon:hover {
    background: var(--ds-sidebar-item-hover-bg);
}
/* Rail : la liste racine perd son retrait (les carrés sont centrés) ; un titre de section n'y est
   plus qu'un filet de la largeur du carré, sans ligne cliquable (un clic le repliait : n° 87). */
.collapse-toggle .sidebar .xaf-navmenu ul[data-is-root] {
    padding-inline: 0;
}
.collapse-toggle .sidebar ul[data-is-root] > .dxbl-treeview-item.has-children {
    width: var(--dxds-spacing-320);
    margin-inline: auto;
}
.collapse-toggle .sidebar ul[data-is-root] > .dxbl-treeview-item.has-children > .dxbl-treeview-item-content {
    display: none;
}
/* Paramétrage replié : ses modules ne sont pas rendus (DevExpress ne rend pas les enfants d'un nœud
   replié). Son titre redevient donc une entrée du rail, à son icône, qui ouvre ses modules et leurs pages
   dans le volet (sidebar.js, RailModulePanel). Dépliée, la section reste un filet comme les autres. */
.collapse-toggle .sidebar ul[data-is-root] > li.xaf-nav-item.has-children:has(img[src*="NavSectionSettings"]):has(> :first-child > [aria-expanded="false"]) > :first-child {
    display: flex;
    padding: 0;
    margin: 0 auto var(--dxds-spacing-80);
}
.collapse-toggle .sidebar ul[data-is-root] > li.xaf-nav-item.has-children:has(img[src*="NavSectionSettings"]) > :first-child > [role="treeitem"]:hover {
    background: var(--ds-sidebar-item-hover-bg);
}
/* En rail : ANNULE le retrait par niveau des pages (niveau 3+). En déplié il aligne leur texte
   sur celui du module ; en replié il décalerait le contenu hors du centre du carré 32px. On couvre TOUS les sous-items (aria-level 3+) via :not(1):not(2).
   !important : l'indentation dépliée l'est aussi ; spécificité 0,5,0 >= à ses règles, et
   postérieure en source -> gagne. */
.collapse-toggle .sidebar .dxbl-treeview-item-container:not([aria-level="1"]):not([aria-level="2"]) {
    padding-left: 0 !important;
}

/* CENTRAGE des icônes en rail. Le texte étant masqué, l'écart après l'icône restait et la
   décalait vers la GAUCHE du carré 32px. On le met à 0 pour un centrage parfait, aligné avec le
   carré recherche. Le thème pose l'écart en margin-inline-end par `.dxbl-treeview .dxbl-treeview-item >
   .dxbl-treeview-item-content > .dxbl-treeview-item-container > .dxbl-image` (0,5,0) ; même
   spécificité ici par les classes XAF (menu, entrée, icône), chargée après -> gagne. */
.collapse-toggle .sidebar .xaf-navmenu .xaf-nav-item .xaf-nav-menu-item-icon {
    margin-inline-end: 0;
}

/* Filtre en rail = l'entrée « Recherche » de la variante Collapsed : un carré de 32px, loupe
   seule centrée (l'input est masqué), sans fond ni bordure au repos comme les autres entrées. */
.collapse-toggle .sidebar .dxbl-navigation-filter {
    width: var(--dxds-spacing-320);
    margin: 0 auto var(--dxds-spacing-80);
}
.collapse-toggle .sidebar .dxbl-navigation-filter .dxbl-text-edit-input {
    display: none;
}
/* Bouton loupe (et bouton d'effacement) : remplit le carré et centre l'icône (pas de
   largeur/padding propres). */
.collapse-toggle .sidebar .dxbl-navigation-filter .dxbl-btn {
    width: 100%;
    min-width: 0;
    /* !important : le thème pose le retrait de la loupe d'un champ de recherche par
       `.dxbl-text-edit > .dxbl-btn-group-vertical > .dxbl-btn.dxbl-btn-icon:has(~ input[type="search"])`,
       plus spécifique qu'aucun sélecteur raisonnable ici. */
    padding: 0 !important;
    justify-content: center;
}

/* En-tête en rail : le cube reste en tête (maquette « liste, sidebar repliée », produits/4030-2058),
   le mot est masqué ; la FLÈCHE DE RÉOUVERTURE (>) passe dessous, centrée. */
.collapse-toggle .sidebar .sidebar__logo--full { display: none; }
.collapse-toggle .sidebar .sidebar__brand {
    flex-direction: column;
    justify-content: center;
    padding-left: 0;
    padding-right: 0;
}
/* Flèche affichée en rail, centrée, pointant à DROITE (>) = « rouvrir la sidebar ».
   Le clic est relayé vers la bascule native XAF par sidebar.js (même handler qu'en déplié).
   margin-left:0 annule le margin-left:auto de l'état déplié -> centrage réel dans le rail.
   La taille (20×20) est portée par .sidebar__chevron, identique dans les deux états. */
.collapse-toggle .sidebar .sidebar__collapse-btn {
    margin-left: 0;
}
.collapse-toggle .sidebar .sidebar__chevron {
    transform: scaleX(-1); /* le chevron « < » (repli) devient « > » (réouverture) */
}


/* ============================================================
   6. INFOBULLE (tooltip stylé du rail : entrées, logo, version)
   Au survol comme au focus clavier, fermée par Échap (WCAG 1.4.13).
   Rendu par sidebar.js dans un élément flottant ancré au <body> (HORS de
   .sidebar) : c'est volontaire, sinon le scroll du TreeView le rognerait.
   Il ne peut donc PAS être scopé sous .sidebar. Position calculée en JS
   (fixed, à droite de la sidebar) ; apparence = maquette Figma (node 1027-2148) :
   carré clair, texte teal, ombre « standard ». Remplace l'infobulle native
   (sombre) de XAF, retirée au survol par sidebar.js.
   ============================================================ */
.sidebar-tooltip {
    position: fixed;
    transform: translateY(-50%);          /* centré sur le milieu de l'item */
    z-index: 1100;
    pointer-events: none;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.1s ease;

    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: var(--dxds-spacing-80);
    border-radius: var(--dxds-border-radius-40);
    border: 1px solid var(--ds-sidebar-tooltip-border);
    background: var(--ds-sidebar-tooltip-bg);
    box-shadow: var(--ds-shadow-standard);

    color: var(--ds-sidebar-tooltip-content);
    font-family: var(--dxds-font-family-sans-serif);
    font-size: var(--dxds-font-size-140);    /* 14px (md/regular) */
    font-weight: var(--dxds-font-weight-400);
    white-space: nowrap;
}
.sidebar-tooltip--visible {
    opacity: 1;
    visibility: visible;
}


/* ============================================================
   7. VOLET DU RAIL (pages d'un module, menu replié — lot 6, 29/10/2026)
   Le volet est un DxFlyout natif (RailModulePanel.razor) : sa surface, son titre,
   son ombre et sa fermeture (Échap, clic à côté) sont ceux du thème. Seule la liste
   des pages est à nous ; elle reprend les états d'un élément de liste ouverte de la
   charte (survol, élément choisi). Rendu hors de .sidebar (couche des popups).
   ============================================================ */
.rail-panel__pages {
    display: flex;
    flex-direction: column;
    gap: var(--dxds-spacing-20);
    margin: 0;
    padding: 0;
    list-style: none;
}
.rail-panel__pages .rail-panel__pages {
    padding-inline-start: var(--dxds-spacing-80);
}
.rail-panel__group {
    display: block;
    padding: var(--dxds-spacing-80) var(--dxds-spacing-80) var(--dxds-spacing-20);
    color: var(--ds-input-item-disabled-content);
    font-size: var(--dxds-font-size-100);
    font-weight: var(--ds-font-weight-semibold);
    letter-spacing: 0.06em;
    text-transform: uppercase;
}
.rail-panel__page {
    display: block;
    width: 100%;
    padding: var(--dxds-spacing-50) var(--dxds-spacing-80);
    border: none;
    border-radius: var(--dxds-border-radius-40);
    background: transparent;
    color: var(--ds-input-item-enable-content);
    font: inherit;
    text-align: start;
    cursor: pointer;
}
.rail-panel__page:hover {
    background: var(--ds-input-item-hover-bg);
    color: var(--ds-input-item-hover-content);
}
.rail-panel__page[aria-current="page"] {
    background: var(--ds-input-item-active-bg);
    color: var(--ds-input-item-active-content);
    font-weight: var(--ds-font-weight-semibold);
}
.rail-panel__page:focus-visible {
    outline: 2px solid var(--ds-input-item-active-content);
    outline-offset: -2px;
}
.rail-panel__page:disabled {
    color: var(--ds-input-item-disabled-content);
    cursor: default;
}
