﻿/*
 * ============================================================
 *  APPLICATION LIGHT THEME
 *  DevExpress XAF Blazor v25.x — Fluent mode
 *
 *  File structure
 *  ──────────────
 *  1.  Design tokens (App palette)
 *  2.  DevExpress / Bootstrap variable overrides
 *  2b. DXDS color token mapping (full 172-token set)
 *  3.  Base typography
 *  4.  Global button reset
 *  5.  Primary button
 *  6.  Secondary button
 *  7.  Tertiary button
 *  8.  Danger button
 *  9.  Icon-only buttons
 *  10. XAF toolbar
 *  11. Sidebar navigation
 *  12. Tabs / detail-view nav
 *  13. Grid (DataGrid)
 *  14. Inputs / editors
 *  15. Page title / top bar
 *  16. Focus ring
 *  17. Modal / popup
 *  18. Detail View (object forms)
 *  19. Pager
 *  20. Nav-ribbon (DxTabs)
 *  21. Icon overrides (DevExpress native icons)
 *
 *  Override strategy for DevExpress components
 *  ────────────────────────────────────────────
 *  DevExpress Fluent theme relies on a two-level CSS variable chain:
 *    component variable  →  dxds token  →  value
 *  Adding !important on a property such as background-color has NO
 *  effect when the component reads its color from a CSS variable at
 *  render time.  The only reliable approach is to re-declare the
 *  component-level CSS variable on a scoped selector so the cascade
 *  resolves to our value first.
 *
 *  Example (grid selected row):
 *    core.min.css sets --dxbl-grid-selection-bg: var(--dxds-color-surface-primary-deep-rest)
 *    → we override --dxbl-grid-selection-bg directly on .dxbl-grid
 *
 *  When in doubt, search core.min.css for the component class and
 *  trace back the variable chain before writing overrides.
 * ============================================================
 */

@import url('https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700&display=swap');


/* ============================================================
   1. DESIGN TOKENS — App palette
   All colours, shadows, radii and button metrics live here.
   Every section below references these variables; raw hex
   values should never appear outside of this block.
   ============================================================ */
:root,
.dxbl-theme-fluent-mode-light,
.dxbl-theme-app-mode-light {
    /* ── Brand — Primary (vert MERCALYS) ────────────────────────
       Recoloration depuis la maquette Figma : base #018973
       (button/primary/enable/bg). Échelle générée par teintes
       (vers blanc) puis ombres (vers noir) autour de la base. */
    --app-primary-10: #e6f3f1;
    --app-primary-20: #cce7e3;
    --app-primary-30: #9ed2ca;
    --app-primary-40: #85c6bc;
    --app-primary-50: #67b8ab;
    --app-primary-60: #4dac9d;
    --app-primary-70: #34a08f;
    --app-primary-80: #209784;
    --app-primary-90: #0e8f7a;
    --app-primary-100: #018973;
    --app-primary-110: #017965;
    --app-primary-120: #016857;
    --app-primary-130: #015849;
    --app-primary-140: #01493e;
    --app-primary-160: #013930;
    /* ── Brand — Secondary (gris neutre, ex-violet) ─────────────
       Recoloration depuis la maquette Figma : le bouton tertiaire y
       est gris (button/tertiary/enable bg #eae8ee, border #dfdce5).
       L'échelle violette d'origine est remplacée par un gris neutre
       (10/20 = valeurs exactes du tertiaire Figma ; survols/foncés en
       gris au lieu de violet). Aucun violet ne subsiste. */
    --app-secondary-10: #eae8ee;
    --app-secondary-20: #dfdce5;
    --app-secondary-30: #d2d0d3;
    --app-secondary-40: #bdbbbe;
    --app-secondary-50: #a8a6a9;
    --app-secondary-60: #939196;
    --app-secondary-70: #828085;
    --app-secondary-80: #737175;
    --app-secondary-90: #6a686d;
    --app-secondary-100: #5f5d61;
    --app-secondary-110: #545256;
    --app-secondary-120: #49474b;
    /* ── Neutral (greyscale) ────────────────────────────────── */
    --app-neutral-0: #fffefd;
    --app-neutral-10: #fafafa;
    --app-neutral-20: #f3f3f3;
    --app-neutral-30: #ebebea;
    --app-neutral-40: #e1e1e0;
    --app-neutral-50: #d5d5d3;
    --app-neutral-60: #cdcdcb;
    --app-neutral-70: #b9b9b6;
    --app-neutral-80: #91918d;
    --app-neutral-90: #737370;
    --app-neutral-100: #535350;
    --app-neutral-110: #3e3e3c;
    --app-neutral-120: #2f2f2d;
    --app-neutral-130: #252523;
    --app-neutral-140: #1d1d1b;
    /* ── Accent ─────────────────────────────────────────────── */
    --app-dark-teal: #164147;
    /* ── Card / surface lime (Figma : card/bg passé de lime/10 à lime/20 ; card/border = lime/20) ── */
    --app-card-bg: #ddf3d2;
    --app-card-border: #ddf3d2;
    /* ── Lime (états de ligne de grille — Figma Lime_Green/10..40) ── */
    --app-lime-10: #f1fbe4; /* lime/10 — désormais inutilisé (survol passé en lime/20) */
    --app-lime-20: #ddf3d2; /* lime/20 */
    --app-lime-30: #d9f6bb; /* lime/30 — INTERPOLÉ entre /20 et /40, à confirmer avec la valeur Figma */
    --app-lime-40: #d4f9a3; /* sélection ligne (= lime/40) */
    /* ── Semantic — Danger ──────────────────────────────────── */
    --app-danger-10: #fceaea;
    --app-danger-20: #f7d0d0;
    --app-danger-40: #e99999;
    --app-danger-90: #be1010;
    --app-danger-110: #980c0c;
    --app-danger-130: #720808;
    /* ── Shadows ────────────────────────────────────────────── */
    --app-shadow-sm: 0 4px 10px rgba(0, 0, 0, 0.03);
    --app-shadow-focus: 0 0 0 2px rgba(1, 137, 115, 0.20);
    /* ── Radii ──────────────────────────────────────────────── */
    --app-radius-sm: 2px;
    --app-radius-md: 4px;
    --app-radius-lg: 6px;
    /* ── Typography ─────────────────────────────────────────── */
    --app-font: 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    /* ── Button metrics ─────────────────────────────────────── */
    --app-btn-font-size: 14px;
    --app-btn-font-weight: 400;
    --app-btn-padding-y: 7px;
    --app-btn-padding-x: 12px;
    --app-btn-gap: 4px;
    --app-btn-icon-size: 19px;
    --app-btn-icon-only-size: 33px;
    --app-btn-icon-only-size-sm: 26px;
    /* Compact mode (dxbl-sm) button metrics — Figma "small" size */
    --app-btn-sm-font-size: 12px;
    --app-btn-sm-padding-y: 5px;
    --app-btn-sm-padding-x: 10px;
    --app-btn-sm-line-height: 16px;
    /* ── Placeholder (Figma node 26-273) ───────────────────────── */
    --placeholder-enable-bg: #f9f9f9;
    --placeholder-enable-border: #ebebea;
    --placeholder-enable-content: #91918d;
    --placeholder-hover-bg: #f3f3f3;
    --placeholder-hover-border: #e1e1e0;
    --placeholder-hover-content: #91918d;
    --placeholder-active-bg: #f9f9f9;
    --placeholder-active-border: #018973;
    --placeholder-active-content: #164147;
    --placeholder-disabled-bg: #ebebea;
    --placeholder-disabled-border: #ebebea;
    --placeholder-disabled-content: #b9b9b6;
}

/* ============================================================
   CHAMPS DÉSACTIVÉS / LECTURE SEULE — LISIBILITÉ
   Par défaut DevExpress affiche le texte des éditeurs désactivés en gris très
   clair (#b9b9b6) sur fond gris (#ebebea) -> contraste insuffisant (gris sur gris).
   On CONSERVE le fond gris (signal visuel « désactivé ») mais on passe le TEXTE en
   gris foncé lisible (--app-neutral-100 = #535350), qui reste nettement plus discret
   que le texte normal (#1d1d1b) : l'état désactivé reste lisible ET reconnaissable.
   `-webkit-text-fill-color` + `opacity:1` sont nécessaires car les inputs désactivés
   sont éclaircis par le navigateur via ces propriétés, pas seulement via `color`.
   ============================================================ */
/* Sélecteur à haute spécificité (élément custom + classes + classe de l'input)
   pour battre la règle DevExpress qui pose `-webkit-text-fill-color` sur l'input
   désactivé. `-webkit-text-fill-color` PRIME sur `color` pour le rendu du texte :
   il faut donc impérativement le redéfinir, sinon le texte reste gris clair.
   SCOPÉ aux champs de VUE DÉTAIL uniquement (`.dxbl-fl-item` = item de form layout).
   Sans ce scope, la règle touchait aussi les cellules désactivées des GRILLES (vues
   liste) et y créait des boîtes grises parasites. */
.dxbl-fl-item dxbl-input-editor.dxbl-text-edit.dxbl-disabled input.dxbl-text-edit-input,
.dxbl-fl-item dxbl-input-editor.dxbl-text-edit.dxbl-disabled textarea.dxbl-text-edit-input,
.dxbl-fl-item .dxbl-text-edit.dxbl-disabled input.dxbl-text-edit-input,
.dxbl-fl-item .dxbl-text-edit.dxbl-disabled textarea.dxbl-text-edit-input,
.dxbl-fl-item .dxbl-text-edit.dxbl-disabled .dxbl-text-edit-static-text,
.dxbl-fl-item .dxbl-text-edit input.dxbl-text-edit-input:disabled,
.dxbl-fl-item .dxbl-text-edit textarea.dxbl-text-edit-input:disabled {
    /* Texte teal (couleur sidebar) en gras sur fond gris clair (#f0f0f0). */
    color: #164147 !important; /* teal de la sidebar (--sidebar-palette-teal-700) */
    -webkit-text-fill-color: #164147 !important;
    opacity: 1 !important;
    background-color: #f0f0f0 !important;
    font-weight: 700 !important; /* texte en gras */
}

/* Fond gris clair uniforme sur tout le conteneur de l'éditeur désactivé (et pas
   seulement l'input), pour éviter un liseré gris plus foncé autour du champ.
   Scopé vue détail (pas les grilles). */
.dxbl-fl-item dxbl-input-editor.dxbl-text-edit.dxbl-disabled,
.dxbl-fl-item .dxbl-text-edit.dxbl-disabled {
    background-color: #f0f0f0 !important;
}

/* Lookups / listes déroulantes DÉSACTIVÉS en vue détail : la valeur ne s'affiche pas
   dans un <input> mais en LIEN (`.combo-box-object-link`, couleur de lien marron +
   souligné) -> non couvert par la règle des inputs ci-dessus, et illisible sur fond gris.
   On l'aligne sur les autres champs désactivés : même teal + gras. */
.dxbl-fl-item .dxbl-text-edit.dxbl-disabled .combo-box-object-link,
.dxbl-fl-item .dxbl-text-edit.dxbl-disabled .xaf-combobox-item,
.dxbl-fl-item .dxbl-disabled .combo-box-object-link,
.dxbl-fl-item .dxbl-disabled .xaf-combobox-item {
    color: #164147 !important; /* teal de la sidebar, comme les champs désactivés */
    -webkit-text-fill-color: #164147 !important;
    font-weight: 700 !important; /* gras, comme les champs désactivés */
}


/* ============================================================
   2. DEVEXPRESS / BOOTSTRAP VARIABLE OVERRIDES
   Maps framework-level variables to App tokens so that
   DevExpress components pick up brand colours automatically,
   reducing the number of component-level overrides needed.
   ============================================================ */
:root,
[data-bs-theme=light],
.dxbl-theme-fluent-mode-light {
    /* DevExpress design system */
    --dxds-font-family-sans-serif: var(--app-font);
    --dxds-border-radius-20: var(--app-radius-sm);
    --dxds-border-radius-40: var(--app-radius-md);
    --dxds-spacing-30: 4px;
    --dxds-box-shadow-md: var(--app-shadow-sm);
    --dx-accent-color: var(--app-primary-100);
    --dx-accent-shadow-color: rgba(1, 137, 115, 0.30);
    /* Bootstrap colour system */
    --bs-primary: var(--app-primary-100);
    --bs-primary-rgb: 1, 137, 115;
    --bs-primary-text-emphasis: var(--app-primary-160);
    --bs-primary-bg-subtle: var(--app-primary-10);
    --bs-primary-border-subtle: var(--app-primary-30);
    --bs-secondary: var(--app-secondary-80);
    --bs-secondary-rgb: 115, 113, 117;
    --bs-secondary-text-emphasis: #39373b;
    --bs-secondary-bg-subtle: var(--app-secondary-10);
    --bs-secondary-border-subtle: var(--app-secondary-40);
    --bs-danger: var(--app-danger-90);
    --bs-danger-rgb: 190, 16, 16;
    --bs-danger-text-emphasis: var(--app-danger-130);
    --bs-danger-bg-subtle: var(--app-danger-10);
    --bs-danger-border-subtle: var(--app-danger-20);
    --bs-light: var(--app-neutral-10);
    --bs-light-rgb: 250, 250, 250;
    --bs-dark: var(--app-dark-teal);
    --bs-dark-rgb: 22, 65, 71;
    /* Bootstrap body */
    --bs-body-font-family: var(--app-font);
    --bs-body-font-size: 1rem;
    --bs-body-color: var(--app-neutral-100);
    --bs-body-bg: var(--app-neutral-10);
    /* Bootstrap links / borders / radii */
    --bs-link-color: var(--app-primary-100);
    --bs-link-hover-color: var(--app-primary-110);
    --bs-border-color: var(--app-neutral-40);
    --bs-border-radius: var(--app-radius-md);
    --bs-border-radius-sm: var(--app-radius-sm);
    --bs-border-radius-lg: var(--app-radius-lg);
    --bs-focus-ring-color: rgba(1, 137, 115, 0.25);
    /* Bootstrap nav */
    --bs-nav-link-color: var(--app-neutral-100);
    --bs-nav-link-hover-color: var(--app-primary-100);
    --bs-nav-tabs-link-active-color: var(--app-primary-100);
    --bs-nav-tabs-link-active-bg: transparent;
    --bs-nav-tabs-border-color: var(--app-neutral-40);
}


/* ============================================================
   2b. DXDS COLOR TOKEN MAPPING — Full 172-token set
   These tokens are consumed by core.min.css and all DevExpress
   components. Defining them here upstream removes the need for
   many !important overrides later in the file.
   ============================================================ */
:root,
.dxbl-theme-fluent-mode-light {
    /* ── Surface — Neutral ──────────────────────────────────── */
    --dxds-color-surface-neutral-default-rest: var(--app-neutral-0);
    --dxds-color-surface-neutral-default-hovered: var(--app-neutral-20);
    --dxds-color-surface-neutral-default-active: var(--app-neutral-30);
    --dxds-color-surface-neutral-default-selected: var(--app-primary-10);
    --dxds-color-surface-neutral-default-selected-hovered: var(--app-primary-20);
    --dxds-color-surface-neutral-default-disabled: var(--app-neutral-20);
    --dxds-color-surface-neutral-default-inverted-rest: var(--app-dark-teal);
    --dxds-color-surface-neutral-subdued-rest: var(--app-neutral-10);
    --dxds-color-surface-neutral-subdued-hovered: var(--app-neutral-20);
    --dxds-color-surface-neutral-subdued-active: var(--app-neutral-30);
    --dxds-color-surface-neutral-deep-rest: var(--app-neutral-20);
    --dxds-color-surface-neutral-deep-hovered: var(--app-neutral-30);
    --dxds-color-surface-neutral-default-static-light-rest: var(--app-neutral-0);
    --dxds-color-surface-neutral-default-static-light-hovered: var(--app-neutral-20);
    --dxds-color-surface-neutral-default-static-light-active: var(--app-neutral-30);
    --dxds-color-surface-neutral-default-static-light-disabled: var(--app-neutral-20);
    --dxds-color-surface-neutral-default-static-light-selected: var(--app-primary-10);
    --dxds-color-surface-neutral-default-static-dark-rest: var(--app-dark-teal);
    --dxds-color-surface-neutral-default-static-dark-hovered: rgba(255, 255, 255, 0.10);
    --dxds-color-surface-neutral-default-static-dark-active: rgba(255, 255, 255, 0.15);
    --dxds-color-surface-neutral-default-static-dark-disabled: rgba(255, 255, 255, 0.05);
    --dxds-color-surface-neutral-default-static-dark-selected: var(--app-primary-100);
    --dxds-color-surface-transparent-rest: transparent;
    /* ── Surface — Primary ──────────────────────────────────── */
    --dxds-color-surface-primary-default-rest: var(--app-primary-100);
    --dxds-color-surface-primary-default-hovered: var(--app-primary-110);
    --dxds-color-surface-primary-default-active: var(--app-primary-120);
    --dxds-color-surface-primary-default-selected: var(--app-primary-100);
    --dxds-color-surface-primary-default-disabled: var(--app-primary-20);
    --dxds-color-surface-primary-subdued-rest: var(--app-primary-10);
    --dxds-color-surface-primary-subdued-hovered: var(--app-primary-20);
    --dxds-color-surface-primary-subdued-active: var(--app-primary-30);
    --dxds-color-surface-primary-subdued-selected: var(--app-primary-20);
    --dxds-color-surface-primary-deep-rest: var(--app-primary-100);
    --dxds-color-surface-primary-deep-hovered: var(--app-primary-110);
    --dxds-color-surface-primary-deep-selected: var(--app-primary-100);
    --dxds-color-surface-primary-deep-static-light-rest: var(--app-primary-100);
    --dxds-color-surface-primary-deep-static-light-selected: var(--app-primary-100);
    /*    --dxbl-grid-font-size: 1rem !important;
    --dxbl-text-font-size: 1rem !important:*/
    /* ── Surface — Secondary ────────────────────────────────── */
    --dxds-color-surface-secondary-default-rest: var(--app-secondary-10);
    --dxds-color-surface-secondary-default-hovered: var(--app-secondary-100);
    --dxds-color-surface-secondary-default-active: var(--app-secondary-110);
    --dxds-color-surface-secondary-default-selected: var(--app-secondary-20);
    --dxds-color-surface-secondary-default-disabled: var(--app-secondary-20);
    /* ── Surface — Danger ───────────────────────────────────── */
    --dxds-color-surface-danger-default-rest: var(--app-danger-90);
    --dxds-color-surface-danger-default-hovered: var(--app-danger-110);
    --dxds-color-surface-danger-default-active: var(--app-danger-130);
    --dxds-color-surface-danger-default-selected: var(--app-danger-90);
    --dxds-color-surface-danger-deep-rest: var(--app-danger-90);
    /* ── Surface — Backdrop / Highlight ────────────────────── */
    --dxds-color-surface-backdrop-default-rest: rgba(22, 65, 71, 0.40);
    --dxds-color-surface-highlight-rest: var(--app-primary-20);
    /* ── Surface — Info ─────────────────────────────────────── */
    --dxds-color-surface-info-default-rest: #e8f4fd;
    --dxds-color-surface-info-default-hovered: #cce5f8;
    --dxds-color-surface-info-default-active: #aad2f3;
    --dxds-color-surface-info-default-selected: #cce5f8;
    --dxds-color-surface-info-subdued-rest: #f0f8fe;
    --dxds-color-surface-info-subdued-hovered: #e0f1fc;
    --dxds-color-surface-info-subdued-active: #cce5f8;
    --dxds-color-surface-info-subdued-selected: #e0f1fc;
    --dxds-color-surface-info-deep-rest: #0078d4;
    /* ── Surface — Success ──────────────────────────────────── */
    --dxds-color-surface-success-default-rest: #e6f4ea;
    --dxds-color-surface-success-default-hovered: #c8e6ce;
    --dxds-color-surface-success-default-active: #a3d6ab;
    --dxds-color-surface-success-default-selected: #c8e6ce;
    --dxds-color-surface-success-subdued-rest: #f0faf2;
    --dxds-color-surface-success-subdued-hovered: #dff0e3;
    --dxds-color-surface-success-subdued-active: #c8e6ce;
    --dxds-color-surface-success-subdued-selected: #dff0e3;
    --dxds-color-surface-success-deep-rest: #1a7f37;
    /* ── Surface — Warning ──────────────────────────────────── */
    --dxds-color-surface-warning-default-rest: #fff8e1;
    --dxds-color-surface-warning-default-hovered: #ffecb3;
    --dxds-color-surface-warning-default-active: #ffe082;
    --dxds-color-surface-warning-default-selected: #ffecb3;
    --dxds-color-surface-warning-subdued-rest: #fffde7;
    --dxds-color-surface-warning-subdued-hovered: #fff8e1;
    --dxds-color-surface-warning-subdued-active: #ffecb3;
    --dxds-color-surface-warning-subdued-selected: #fff8e1;
    --dxds-color-surface-warning-deep-rest: #b45309;
    /* ── Surface — Utility ──────────────────────────────────── */
    --dxds-color-surface-utility-blue-default-rest: #dbeafe;
    --dxds-color-surface-utility-blue-subdued-rest: #eff6ff;
    --dxds-color-surface-utility-cyan-default-rest: #cffafe;
    --dxds-color-surface-utility-cyan-subdued-rest: #ecfeff;
    --dxds-color-surface-utility-gray-subdued-rest: var(--app-neutral-20);
    --dxds-color-surface-utility-green-default-rest: #dcfce7;
    --dxds-color-surface-utility-green-subdued-rest: #f0fdf4;
    --dxds-color-surface-utility-indigo-subdued-rest: #eef2ff;
    --dxds-color-surface-utility-orange-default-rest: var(--app-primary-10);
    --dxds-color-surface-utility-orange-subdued-rest: #fff2eb;
    --dxds-color-surface-utility-pink-subdued-rest: #fdf2f8;
    --dxds-color-surface-utility-purple-subdued-rest: var(--app-secondary-10);
    --dxds-color-surface-utility-red-default-rest: var(--app-danger-10);
    --dxds-color-surface-utility-red-subdued-rest: #fef2f2;
    --dxds-color-surface-utility-teal-subdued-rest: #f0fdfa;
    --dxds-color-surface-utility-yellow-subdued-rest: #fefce8;
    /* ── Content — Neutral ──────────────────────────────────── */
    --dxds-color-content-neutral-default-rest: var(--app-neutral-100);
    --dxds-color-content-neutral-default-hovered: var(--app-neutral-110);
    --dxds-color-content-neutral-default-active: var(--app-neutral-120);
    --dxds-color-content-neutral-default-selected: var(--app-neutral-100);
    --dxds-color-content-neutral-default-selected-hovered: var(--app-neutral-110);
    --dxds-color-content-neutral-default-disabled: var(--app-neutral-70);
    --dxds-color-content-neutral-default-inverted-rest: var(--app-neutral-0);
    --dxds-color-content-neutral-subdued-rest: var(--app-neutral-80);
    --dxds-color-content-neutral-subdued-hovered: var(--app-neutral-90);
    --dxds-color-content-neutral-subdued-active: var(--app-neutral-100);
    --dxds-color-content-neutral-subdued-selected: var(--app-neutral-90);
    --dxds-color-content-neutral-subdued-disabled: var(--app-neutral-60);
    --dxds-color-content-neutral-deep-rest: var(--app-neutral-130);
    --dxds-color-content-neutral-default-static-light-rest: var(--app-neutral-100);
    --dxds-color-content-neutral-default-static-light-hovered: var(--app-neutral-110);
    --dxds-color-content-neutral-default-static-light-active: var(--app-neutral-120);
    --dxds-color-content-neutral-default-static-light-disabled: var(--app-neutral-60);
    --dxds-color-content-neutral-default-static-dark-rest: var(--app-neutral-0);
    --dxds-color-content-neutral-default-static-dark-hovered: rgba(255, 255, 255, 0.90);
    --dxds-color-content-neutral-default-static-dark-active: var(--app-neutral-0);
    --dxds-color-content-neutral-default-static-dark-disabled: rgba(255, 255, 255, 0.40);
    /* ── Content — Primary ──────────────────────────────────── */
    --dxds-color-content-primary-default-rest: var(--app-primary-100);
    --dxds-color-content-primary-default-hovered: var(--app-primary-110);
    --dxds-color-content-primary-default-active: var(--app-primary-120);
    /* compound-rest is used as the checkbox check-mark colour (icon on filled bg).
       Setting it to neutral-0 (white) makes the tick visible on an orange checkbox. */
    --dxds-color-content-primary-compound-rest: var(--app-neutral-0);
    --dxds-color-content-primary-compound-hovered: var(--app-neutral-0);
    /* ── Content — Secondary ────────────────────────────────── */
    --dxds-color-content-secondary-default-rest: var(--app-secondary-100);
    --dxds-color-content-secondary-default-hovered: var(--app-secondary-110);
    --dxds-color-content-secondary-default-active: var(--app-secondary-120);
    /* ── Content — Danger ───────────────────────────────────── */
    --dxds-color-content-danger-default-rest: var(--app-danger-90);
    --dxds-color-content-danger-default-hovered: var(--app-danger-110);
    --dxds-color-content-danger-default-active: var(--app-danger-130);
    --dxds-color-content-danger-compound-rest: var(--app-neutral-0);
    --dxds-color-content-danger-compound-hovered: var(--app-neutral-0);
    /* ── Content — Info / Success / Warning ─────────────────── */
    --dxds-color-content-info-default-rest: #0078d4;
    --dxds-color-content-info-default-hovered: #005fa3;
    --dxds-color-content-info-default-active: #004a80;
    --dxds-color-content-success-default-rest: #1a7f37;
    --dxds-color-content-success-default-hovered: #146329;
    --dxds-color-content-success-default-active: #0e4a1e;
    --dxds-color-content-success-compound-rest: var(--app-neutral-0);
    --dxds-color-content-success-compound-hovered: var(--app-neutral-0);
    --dxds-color-content-warning-default-rest: #b45309;
    --dxds-color-content-warning-default-hovered: #92400e;
    --dxds-color-content-warning-default-active: #78350f;
    --dxds-color-content-highlight-rest: var(--app-primary-100);
    /* ── Border — Neutral ───────────────────────────────────── */
    --dxds-color-border-neutral-default-rest: var(--app-neutral-40);
    --dxds-color-border-neutral-default-hovered: var(--app-neutral-60);
    --dxds-color-border-neutral-default-active: var(--app-neutral-70);
    --dxds-color-border-neutral-default-disabled: var(--app-neutral-30);
    --dxds-color-border-neutral-default-inverted-rest: rgba(255, 255, 255, 0.20);
    --dxds-color-border-neutral-accessible-rest: var(--app-neutral-70);
    --dxds-color-border-neutral-accessible-hovered: var(--app-neutral-90);
    --dxds-color-border-neutral-default-static-light-rest: var(--app-neutral-40);
    --dxds-color-border-neutral-default-static-light-hovered: var(--app-neutral-60);
    --dxds-color-border-neutral-default-static-light-active: var(--app-neutral-70);
    --dxds-color-border-neutral-default-static-light-disabled: var(--app-neutral-30);
    --dxds-color-border-neutral-default-static-dark-rest: rgba(255, 255, 255, 0.20);
    --dxds-color-border-neutral-default-static-dark-hovered: rgba(255, 255, 255, 0.30);
    --dxds-color-border-neutral-default-static-dark-active: rgba(255, 255, 255, 0.40);
    --dxds-color-border-neutral-default-static-dark-disabled: rgba(255, 255, 255, 0.10);
    --dxds-color-border-transparent-rest: transparent;
    /* ── Border — Primary ───────────────────────────────────── */
    --dxds-color-border-primary-default-rest: var(--app-primary-100);
    --dxds-color-border-primary-compound-rest: var(--app-primary-30);
    --dxds-color-border-primary-compound-hovered: var(--app-primary-100);
    /* ── Border — Secondary ─────────────────────────────────── */
    --dxds-color-border-secondary-default-rest: var(--app-secondary-20);
    /* ── Border — Danger ────────────────────────────────────── */
    --dxds-color-border-danger-compound-rest: var(--app-danger-40);
    --dxds-color-border-danger-compound-hovered: var(--app-danger-90);
    /* ── Border — Success ───────────────────────────────────── */
    --dxds-color-border-success-compound-rest: #86efac;
    --dxds-color-border-success-compound-hovered: #1a7f37;
    /* ── Border — Focus ─────────────────────────────────────── */
    --dxds-color-border-focus-default: var(--app-primary-100);
    --dxds-color-border-focus-inverted: var(--app-neutral-0);
    --dxds-color-border-focus-static-dark: var(--app-primary-100);
    --dxds-color-border-focus-static-light: var(--app-primary-100);
    /* ── Shadows ────────────────────────────────────────────── */
    --dxds-color-shadow-none: transparent;
    --dxds-color-shadow-ambient: rgba(0, 0, 0, 0.04);
    --dxds-color-shadow-key: rgba(0, 0, 0, 0.08);
    --dxds-color-shadow-ambient-darker: rgba(0, 0, 0, 0.08);
    --dxds-color-shadow-key-darker: rgba(0, 0, 0, 0.14);
}


/* ============================================================
   3. BASE TYPOGRAPHY
   ============================================================ */
html,
body,
.dxbl-theme-fluent-mode-light,
.dxbl-theme-app-mode-light {
    font-family: var(--app-font);
    font-size: 14px;
    font-weight: 400;
    color: var(--app-neutral-100);
}

/* Template display-only (ex: Type/Ouvrage) — padding + centrage */
.main.main-object-model .dxbl-text-edit-template,
.detail-view-content .dxbl-text-edit-template {
    padding: 0 10px !important;
    align-items: center !important;
}

    /* Template avec input dedans (ex: Unité) — 0 padding, c'est l'input qui gère */
    .main.main-object-model .dxbl-text-edit-template:has(.dxbl-text-edit-input),
    .detail-view-content .dxbl-text-edit-template:has(.dxbl-text-edit-input) {
        padding: 0 !important;
    }

.main.main-object-model .dxbl-text-edit-template,
.detail-view-content .dxbl-text-edit-template {
    padding: 0 10px !important;
    align-items: center !important;
}


/* ============================================================
   4. GLOBAL BUTTON RESET
   Normalises all button variants to the App spec.

   XAF toolbar button HTML structure:
     <button class="dxbl-btn dxbl-btn-secondary dxbl-sm ...">
       <img class="dxbl-image ...">
       <span>Label</span>
     </button>
   There is no .dxbl-btn-content wrapper → flex is set directly
   on the <button> element.

   Specificity note: DevExpress loads its own stylesheet into
   <body> after this file, giving .dxbl-btn.dxbl-sm a specificity
   of (0,2,0). Adding the "button" type selector raises ours to
   (0,2,1) without needing a new !important chain.
   ============================================================ */
/* Brand properties — padding from Figma spec (px-12 py-7), sizing
   (font, line-height, min-height) left to DevExpress native tokens
   so standard/compact modes work correctly out of the box.         */
.btn,
.dxbl-btn,
.dx-button,
.dx-toolbar .dx-button,
.dxbl-toolbar .dxbl-btn {


    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    gap: var(--app-btn-gap) !important;
    border-radius: var(--app-radius-md) !important;
    font-family: var(--app-font) !important;
    padding: var(--app-btn-padding-y) var(--app-btn-padding-x) !important;
    box-shadow: var(--app-shadow-sm) !important;
    transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease, opacity 0.15s ease !important;
}

    /* Focus ring */
    .btn:focus,
    .btn:focus-visible,
    .dxbl-btn:focus,
    .dxbl-btn:focus-visible,
    .dx-button:focus,
    .dx-button:focus-visible {
        outline: none !important;
        /*        box-shadow: var(--app-shadow-focus) !important;*/
    }

    /* Inner content wrapper when present */
    .dxbl-btn .dxbl-btn-content,
    .dx-button .dx-button-content,
    .btn .btn-content {
        display: inline-flex !important;
        align-items: center !important;
        justify-content: center !important;
        gap: var(--app-btn-gap) !important;
    }

    /* Icon sizing — <img class="dxbl-image"> inside XAF toolbar buttons */
    .dxbl-btn .dxbl-image,
    .dxbl-btn img.dxbl-image,
    .dx-button .dx-icon,
    .btn i,
    .dxbl-btn i {
        width: 16px !important;
        height: 16px !important;
        object-fit: contain !important;
        flex-shrink: 0 !important;
    }

    /* Disabled state — DevExpress uses .dxbl-disabled class + disabled attribute */
    .btn:disabled,
    .btn.disabled,
    .dxbl-btn:disabled,
    .dxbl-btn.dxbl-disabled,
    .dxbl-btn.dx-state-disabled,
    .dx-button.dx-state-disabled {
        opacity: 1 !important;
        cursor: not-allowed !important;
        box-shadow: none !important;
    }

dxbl-tab-list .dxbl-tabs-scroll-btn-prev[aria-hidden="true"],
dxbl-tab-list .dxbl-tabs-scroll-btn-next[aria-hidden="true"] {
    display: none !important;
}

/* Onglets de DetailView (DxFormLayoutTabPages) : flèches de défilement absentes
   quand le panneau est étroit (splitter du split view).

   Cause racine : dans la chaîne flex du form-layout, les conteneurs gardent
   min-width:auto et ne peuvent donc pas rétrécir sous la largeur totale des
   onglets. Le composant d'onglets grandit au-delà du panneau, un ancêtre le
   coupe, et son scroll-viewer ne détecte jamais de dépassement -> les flèches
   NavButtons (natives, actives par défaut sur desktop) restent masquées.

   Fix à la source : autoriser toute la chaîne flex à rétrécir (min-width:0).
   Le composant d'onglets est alors borné à la largeur réelle du panneau, le
   scroll-viewer mesure le dépassement et sort ses flèches de lui-même. */
.dxbl-fl,
.dxbl-fl .dxbl-fl-group,
.dxbl-fl .dxbl-fl-item,
.dxbl-fl .dxbl-fl-ctrl,
.dxbl-fl .dxbl-fl-ctrl-nc {
    min-width: 0 !important;
}

.dxbl-fl .dxbl-tabs {
    width: 100% !important;
    min-width: 0 !important;
    max-width: 100% !important;
}

/* Les boutons de défilement (dxbl-tabs-scroll-btn-prev/next) sont bien présents
   quand DevExpress détecte le dépassement, mais rendus 0x0 : l'icône native
   DevExpress est vide dans ce projet, donc le bouton n'a aucun contenu et se
   réduit à zéro. On leur redonne une taille et un chevron dessiné en CSS.

   On accroche l'affichage à la classe .dxbl-tabs-tablist-has-overflow que
   DevExpress pose sur la barre uniquement quand les onglets débordent : les
   flèches n'apparaissent donc que quand il y a réellement des onglets cachés,
   sans dépendre de l'attribut aria-hidden de chaque bouton. */
/* Spécificité élevée (double classe sur la barre + attribut) volontaire : il
   faut battre la règle DevExpress .dxbl-tabs-scroll-btn-next[aria-hidden="true"]
   { display:none !important } chargée après notre feuille. On affiche donc les
   flèches dès que la barre déborde, sans tenir compte de l'aria-hidden que
   DevExpress ne gère pas correctement dans ce contexte (onglets XAF). */
.dxbl-tabs-tablist.dxbl-tabs-tablist-has-overflow .dxbl-tabs-scroll-btn-prev[aria-hidden],
.dxbl-tabs-tablist.dxbl-tabs-tablist-has-overflow .dxbl-tabs-scroll-btn-next[aria-hidden] {
    flex: 0 0 24px !important;
    width: 24px !important;
    min-width: 24px !important;
    height: auto !important;
    align-self: stretch !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    padding: 0 !important;
    opacity: 1 !important;
    visibility: visible !important;
}

    /* Chevron dessiné (bordures) — remplace l'icône native vide */
    .dxbl-tabs-tablist.dxbl-tabs-tablist-has-overflow .dxbl-tabs-scroll-btn-prev[aria-hidden]::before,
    .dxbl-tabs-tablist.dxbl-tabs-tablist-has-overflow .dxbl-tabs-scroll-btn-next[aria-hidden]::before {
        content: "" !important;
        width: 7px !important;
        height: 7px !important;
        border-top: 2px solid var(--app-dark-teal) !important;
        border-right: 2px solid var(--app-dark-teal) !important;
    }

    .dxbl-tabs-tablist.dxbl-tabs-tablist-has-overflow .dxbl-tabs-scroll-btn-prev[aria-hidden]::before {
        transform: rotate(-135deg) !important; /* chevron gauche */
        margin-left: 3px !important;
    }

    .dxbl-tabs-tablist.dxbl-tabs-tablist-has-overflow .dxbl-tabs-scroll-btn-next[aria-hidden]::before {
        transform: rotate(45deg) !important;   /* chevron droit */
        margin-right: 3px !important;
    }


/* ============================================================
   5. PRIMARY BUTTON
   Figma spec: solid orange background, white text.
   ============================================================ */
.btn-primary,
.dxbl-btn.btn-primary,
.dxbl-btn.dxbl-btn-primary,
.dx-button.dx-button-mode-contained.dx-button-default,
.dxbl-toolbar .dxbl-btn.dxbl-btn-primary {
    background: var(--app-primary-100) !important;
    border: 1px solid var(--app-primary-100) !important;
    color: var(--app-neutral-0) !important;
}

    .btn-primary *,
    .dxbl-btn.dxbl-btn-primary *,
    .dx-button.dx-button-mode-contained.dx-button-default * {
        color: inherit !important;
    }

    .btn-primary:hover,
    .dxbl-btn.btn-primary:hover,
    .dxbl-btn.dxbl-btn-primary:hover,
    .dx-button.dx-button-mode-contained.dx-button-default:hover {
        background: var(--app-primary-110) !important;
        border-color: var(--app-primary-110) !important;
        color: var(--app-neutral-0) !important;
    }

    .btn-primary:active,
    .btn-primary.active,
    .dxbl-btn.dxbl-btn-primary:active,
    .dxbl-btn.dxbl-btn-primary.dx-state-active,
    .dx-button.dx-button-mode-contained.dx-button-default.dx-state-active {
        background: var(--app-primary-20) !important;
        border-color: var(--app-primary-20) !important;
        color: var(--app-dark-teal) !important;
        box-shadow: none !important;
    }

    .btn-primary:disabled,
    .btn-primary.disabled,
    .dxbl-btn.dxbl-btn-primary:disabled,
    .dxbl-btn.dxbl-btn-primary.dxbl-disabled,
    .dxbl-btn.dxbl-btn-primary.dx-state-disabled,
    .dx-button.dx-button-mode-contained.dx-button-default.dx-state-disabled {
        background: var(--app-primary-20) !important;
        border-color: var(--app-primary-20) !important;
        color: var(--app-primary-40) !important;
        cursor: not-allowed !important;
    }

    /* ── Icon colour per button state ──────────────────────────────
    img.dxbl-image ne répond pas à color → on utilise filter.
    Les icônes XAF sont des PNG sombres sur fond transparent ;
    brightness(0) les normalise en noir avant toute colorisation.
──────────────────────────────────────────────────────────────── */

    /* Enable + Hover → blanc #fffefd */
    .dxbl-btn.dxbl-btn-primary .dxbl-image,
    .dxbl-toolbar :is([data-action-name="New"],[data-action-name="Nouveau"],[data-action-name="Valider"]) .dxbl-image {
        filter: brightness(0) invert(1) !important;
    }

    /* Active / Pressed → teal foncé #164147 */
    .dxbl-btn.dxbl-btn-primary:active .dxbl-image,
    .dxbl-btn.dxbl-btn-primary.dx-state-active .dxbl-image,
    .dxbl-toolbar :is([data-action-name="New"],[data-action-name="Nouveau"],[data-action-name="Valider"]):active .dxbl-image,
    .dxbl-toolbar :is([data-action-name="New"],[data-action-name="Nouveau"],[data-action-name="Valider"]).dx-state-active .dxbl-image {
        filter: brightness(0) saturate(100%) invert(17%) sepia(55%) saturate(415%) hue-rotate(143deg) brightness(120%) contrast(104%) !important;
    }

    /* Disabled → gris neutre #bfbfbf (état désactivé, ex-pêche #ffbb99) */
    .dxbl-btn.dxbl-btn-primary:disabled .dxbl-image,
    .dxbl-btn.dxbl-btn-primary.dxbl-disabled .dxbl-image,
    .dxbl-btn.dxbl-btn-primary.dx-state-disabled .dxbl-image,
    .dxbl-toolbar :is([data-action-name="New"],[data-action-name="Nouveau"],[data-action-name="Valider"]):disabled .dxbl-image,
    .dxbl-toolbar :is([data-action-name="New"],[data-action-name="Nouveau"],[data-action-name="Valider"]).dxbl-disabled .dxbl-image {
        filter: brightness(0) saturate(100%) invert(80%) !important;
    }


/* ============================================================
   6. SECONDARY BUTTON
   Figma spec: light orange background, orange border, dark text.
   Hover: solid orange (same as primary).
   ============================================================ */
.btn-secondary,
.dxbl-btn.btn-secondary,
.dxbl-btn.dxbl-btn-secondary {
    background: var(--app-primary-10) !important;
    border: 1px solid var(--app-primary-20) !important;
    color: var(--app-dark-teal) !important;
}

    .btn-secondary *,
    .dxbl-btn.dxbl-btn-secondary * {
        color: inherit !important;
    }

    .btn-secondary:hover,
    .dxbl-btn.btn-secondary:hover,
    .dxbl-btn.dxbl-btn-secondary:hover {
        background: var(--app-primary-100) !important;
        border-color: var(--app-primary-100) !important;
        color: var(--app-neutral-0) !important;
    }

    .btn-secondary:active,
    .btn-secondary.active,
    .dxbl-btn.dxbl-btn-secondary:active,
    .dxbl-btn.dxbl-btn-secondary.dx-state-active {
        background: var(--app-primary-20) !important;
        border-color: var(--app-primary-20) !important;
        color: var(--app-dark-teal) !important;
        box-shadow: none !important;
    }

    .btn-secondary:disabled,
    .btn-secondary.disabled,
    .dxbl-btn.dxbl-btn-secondary:disabled,
    .dxbl-btn.dxbl-btn-secondary.dxbl-disabled,
    .dxbl-btn.dxbl-btn-secondary.dx-state-disabled {
        background: var(--app-primary-20) !important;
        border-color: var(--app-primary-20) !important;
        color: var(--app-primary-40) !important;
    }

    /* ── Icon colour per button state (img.dxbl-image ne répond pas à color) ── */

    /* Enable / Focus → dark teal #164147
    :not([data-action-name]) exclut New/Nouveau/Valider qui sont gérés section 10 */
    .dxbl-btn.dxbl-btn-secondary:not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]) .dxbl-image {
        filter: brightness(0) saturate(100%) invert(17%) sepia(55%) saturate(415%) hue-rotate(143deg) brightness(120%) contrast(104%) !important;
    }

    /* Hover → blanc #fffefd (disabled exclu) */
    .dxbl-btn.dxbl-btn-secondary:not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]):not(:disabled):not(.dxbl-disabled):not(.dx-state-disabled):hover .dxbl-image {
        filter: brightness(0) invert(1) !important;
    }

    /* Pressed / Active → blanc #fffefd (même état visuel que hover) */
    .dxbl-btn.dxbl-btn-secondary:not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]):active .dxbl-image,
    .dxbl-btn.dxbl-btn-secondary:not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]).dx-state-active .dxbl-image {
        filter: brightness(0) invert(1) !important;
    }

    /* Disabled → gris neutre #bfbfbf (état désactivé, ex-pêche #ffbb99) */
    .dxbl-btn.dxbl-btn-secondary:not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]):disabled .dxbl-image,
    .dxbl-btn.dxbl-btn-secondary:not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]).dxbl-disabled .dxbl-image,
    .dxbl-btn.dxbl-btn-secondary:not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]).dx-state-disabled .dxbl-image {
        filter: brightness(0) saturate(100%) invert(80%) !important;
    }


/* ============================================================
   7. TERTIARY BUTTON
   Figma spec: light violet background, violet border, dark text.
   Hover: solid violet.
   ============================================================ */
.btn-outline-secondary,
.dxbl-btn.btn-outline-secondary,
.dxbl-btn.dxbl-btn-outline,
.dxbl-btn.dxbl-btn-outline-secondary {
    background: var(--app-secondary-10) !important;
    border: 1px solid var(--app-secondary-20) !important;
    color: var(--app-dark-teal) !important;
}

    .btn-outline-secondary *,
    .dxbl-btn.dxbl-btn-outline *,
    .dxbl-btn.dxbl-btn-outline-secondary * {
        color: inherit !important;
    }

    .btn-outline-secondary:hover,
    .dxbl-btn.dxbl-btn-outline:hover,
    .dxbl-btn.dxbl-btn-outline-secondary:hover {
        background: var(--app-secondary-100) !important;
        border-color: var(--app-secondary-100) !important;
        color: var(--app-neutral-0) !important;
    }

    .btn-outline-secondary:active,
    .btn-outline-secondary.active,
    .dxbl-btn.dxbl-btn-outline:active,
    .dxbl-btn.dxbl-btn-outline.dx-state-active,
    .dxbl-btn.dxbl-btn-outline-secondary.dx-state-active {
        background: var(--app-secondary-10) !important;
        border-color: var(--app-secondary-20) !important;
        color: var(--app-dark-teal) !important;
        box-shadow: none !important;
    }

    .btn-outline-secondary:disabled,
    .btn-outline-secondary.disabled,
    .dxbl-btn.dxbl-btn-outline:disabled,
    .dxbl-btn.dxbl-btn-outline.dxbl-disabled,
    .dxbl-btn.dxbl-btn-outline.dx-state-disabled,
    .dxbl-btn.dxbl-btn-outline-secondary:disabled,
    .dxbl-btn.dxbl-btn-outline-secondary.dxbl-disabled,
    .dxbl-btn.dxbl-btn-outline-secondary.dx-state-disabled {
        background: var(--app-secondary-20) !important;
        border-color: var(--app-secondary-20) !important;
        color: var(--app-secondary-40) !important;
        cursor: not-allowed !important;
    }


/* ============================================================
   8. DANGER BUTTON
   ============================================================ */
.btn-danger,
.dxbl-btn.btn-danger,
.dxbl-btn.dxbl-btn-danger {
    background: var(--app-danger-90) !important;
    border: 1px solid var(--app-danger-90) !important;
    color: var(--app-neutral-0) !important;
}

    .btn-danger:hover,
    .dxbl-btn.dxbl-btn-danger:hover {
        background: var(--app-danger-110) !important;
        border-color: var(--app-danger-110) !important;
        color: var(--app-neutral-0) !important;
    }

    .btn-danger:active,
    .btn-danger.active,
    .dxbl-btn.dxbl-btn-danger:active,
    .dxbl-btn.dxbl-btn-danger.dx-state-active {
        background: var(--app-danger-10) !important;
        border-color: var(--app-danger-20) !important;
        color: var(--app-danger-130) !important;
        box-shadow: none !important;
    }

    .btn-danger:disabled,
    .btn-danger.disabled,
    .dxbl-btn.dxbl-btn-danger.dx-state-disabled {
        background: var(--app-danger-20) !important;
        border-color: var(--app-danger-20) !important;
        color: var(--app-danger-40) !important;
    }


/* ============================================================
   9. ICON-ONLY BUTTONS
   Figma spec: square 33×33 px.

   Detection strategy: use explicit .dxbl-btn-icon-only class or
   the structural :has() selector limited to .dxbl-btn-content
   children. Avoid :has(.dxbl-image):not(:has(.dxbl-text)) on its
   own — XAF toolbar buttons wrap label text in a raw <span>
   without a .dxbl-text class, which causes false positives.
   ============================================================ */
.dxbl-btn.dxbl-btn-icon-only,
.dxbl-btn.icon-only,
.dx-button.dx-button-has-icon:not(.dx-button-has-text),
.dxbl-toolbar .dxbl-btn:has(.dxbl-btn-content > .dxbl-image):not(:has(.dxbl-btn-content > .dxbl-text)):not(:has(.dxbl-btn-content > span)) {
    width: var(--app-btn-icon-only-size) !important;
    min-width: var(--app-btn-icon-only-size) !important;
    height: var(--app-btn-icon-only-size) !important;
    min-height: var(--app-btn-icon-only-size) !important;
    padding: 7px !important;
}

.dxbl-btn.dxbl-btn-sm.dxbl-btn-icon-only,
.dx-button.dx-button-has-icon.dx-button-sm:not(.dx-button-has-text) {
    width: var(--app-btn-icon-only-size-sm) !important;
    min-width: var(--app-btn-icon-only-size-sm) !important;
    height: var(--app-btn-icon-only-size-sm) !important;
    min-height: var(--app-btn-icon-only-size-sm) !important;
    padding: 5px !important;
}


/* ============================================================
   10. XAF TOOLBAR
   XAF generates all toolbar buttons as .dxbl-btn-secondary.
   We differentiate the "New" action visually by targeting
   data-action-name. Important: cet attribut reflète le caption
   localisé du bouton ("New" en EN, "Nouveau" en FR, etc.), donc
   on doit matcher les deux variantes. D'où l'usage de :is(...)
   sur les sélecteurs positifs et :not():not() en chaîne sur les
   sélecteurs négatifs.
   ============================================================ */
.dxbl-toolbar {
    background: transparent !important;
    padding: 4px 0 !important;
    gap: 4px !important;
}

    .dxbl-toolbar .dxbl-btn {
        margin: 0 !important;
    }

    /* "New" action → PRIMARY style (solid orange) */
    .dxbl-toolbar :is([data-action-name="New"], [data-action-name="Nouveau"], [data-action-name="Valider"]) {
        background: var(--app-primary-100) !important;
        border: 1px solid var(--app-primary-100) !important;
        color: var(--app-neutral-0) !important;
    }

        .dxbl-toolbar :is([data-action-name="New"], [data-action-name="Nouveau"], [data-action-name="Valider"]) * {
            color: var(--app-neutral-0) !important;
        }

        .dxbl-toolbar :is([data-action-name="New"], [data-action-name="Nouveau"], [data-action-name="Valider"]):hover {
            background: var(--app-primary-110) !important;
            border-color: var(--app-primary-110) !important;
            color: var(--app-neutral-0) !important;
        }

        .dxbl-toolbar :is([data-action-name="New"], [data-action-name="Nouveau"], [data-action-name="Valider"]):active,
        .dxbl-toolbar :is([data-action-name="New"], [data-action-name="Nouveau"], [data-action-name="Valider"]).dx-state-active {
            background: var(--app-primary-20) !important;
            border-color: var(--app-primary-20) !important;
            color: var(--app-dark-teal) !important;
            box-shadow: none !important;
        }

            /* Active children — écrase la règle * blanche */
            .dxbl-toolbar :is([data-action-name="New"], [data-action-name="Nouveau"], [data-action-name="Valider"]):active *,
            .dxbl-toolbar :is([data-action-name="New"], [data-action-name="Nouveau"], [data-action-name="Valider"]).dx-state-active * {
                color: var(--app-dark-teal) !important;
            }

        /* Disabled + hover suppressed — same tint as secondary disabled */
        .dxbl-toolbar :is([data-action-name="New"], [data-action-name="Nouveau"], [data-action-name="Valider"]):disabled,
        .dxbl-toolbar :is([data-action-name="New"], [data-action-name="Nouveau"], [data-action-name="Valider"]):disabled:hover,
        .dxbl-toolbar :is([data-action-name="New"], [data-action-name="Nouveau"], [data-action-name="Valider"]).dxbl-disabled,
        .dxbl-toolbar :is([data-action-name="New"], [data-action-name="Nouveau"], [data-action-name="Valider"]).dxbl-disabled:hover {
            background: var(--app-primary-20) !important;
            border-color: var(--app-primary-20) !important;
            color: var(--app-primary-40) !important;
            cursor: not-allowed !important;
            box-shadow: none !important;
        }

            /* Disabled children — force text/icon colour */
            .dxbl-toolbar :is([data-action-name="New"], [data-action-name="Nouveau"], [data-action-name="Valider"]):disabled *,
            .dxbl-toolbar :is([data-action-name="New"], [data-action-name="Nouveau"], [data-action-name="Valider"]).dxbl-disabled * {
                color: var(--app-primary-40) !important;
            }

    /* All other toolbar buttons → SECONDARY style (light orange) */
    /* :not(.dxbl-text-edit-btn) exclut le bouton de recherche (Placeholder) */
    .dxbl-toolbar .dxbl-btn.dxbl-btn-secondary:not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]):not(.dxbl-text-edit-btn),
    .dxbl-toolbar .dxbl-btn:not(.dxbl-btn-danger):not(.dxbl-btn-primary):not(.dxbl-btn-outline):not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]):not(.dxbl-text-edit-btn) {
        background: var(--app-primary-10) !important;
        border: 1px solid var(--app-primary-20) !important;
        color: var(--app-dark-teal) !important;
    }

        .dxbl-toolbar .dxbl-btn.dxbl-btn-secondary:not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]):not(.dxbl-text-edit-btn) *,
        .dxbl-toolbar .dxbl-btn:not(.dxbl-btn-danger):not(.dxbl-btn-primary):not(.dxbl-btn-outline):not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]):not(.dxbl-text-edit-btn) * {
            color: var(--app-dark-teal) !important;
        }

        .dxbl-toolbar .dxbl-btn.dxbl-btn-secondary:not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]):not(.dxbl-text-edit-btn):hover,
        .dxbl-toolbar .dxbl-btn:not(.dxbl-btn-danger):not(.dxbl-btn-primary):not(.dxbl-btn-outline):not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]):not(.dxbl-text-edit-btn):hover {
            background: var(--app-primary-100) !important;
            border-color: var(--app-primary-100) !important;
            color: var(--app-neutral-0) !important;
        }

            .dxbl-toolbar .dxbl-btn.dxbl-btn-secondary:not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]):not(.dxbl-text-edit-btn):hover *,
            .dxbl-toolbar .dxbl-btn:not(.dxbl-btn-danger):not(.dxbl-btn-primary):not(.dxbl-btn-outline):not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]):not(.dxbl-text-edit-btn):hover * {
                color: var(--app-neutral-0) !important;
            }

        /* Disabled — (0,5,0) beats the base toolbar rule (0,4,0)
DevExpress uses .dxbl-disabled class + disabled attribute.
:hover variants included so hover effects are suppressed.          */
        .dxbl-toolbar .dxbl-btn.dxbl-btn-secondary:not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]):disabled,
        .dxbl-toolbar .dxbl-btn.dxbl-btn-secondary:not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]):disabled:hover,
        .dxbl-toolbar .dxbl-btn.dxbl-btn-secondary:not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]).dxbl-disabled,
        .dxbl-toolbar .dxbl-btn.dxbl-btn-secondary:not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]).dxbl-disabled:hover,
        .dxbl-toolbar .dxbl-btn:not(.dxbl-btn-danger):not(.dxbl-btn-primary):not(.dxbl-btn-outline):not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]):not(.dxbl-text-edit-btn):disabled,
        .dxbl-toolbar .dxbl-btn:not(.dxbl-btn-danger):not(.dxbl-btn-primary):not(.dxbl-btn-outline):not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]):not(.dxbl-text-edit-btn):disabled:hover,
        .dxbl-toolbar .dxbl-btn:not(.dxbl-btn-danger):not(.dxbl-btn-primary):not(.dxbl-btn-outline):not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]):not(.dxbl-text-edit-btn).dxbl-disabled,
        .dxbl-toolbar .dxbl-btn:not(.dxbl-btn-danger):not(.dxbl-btn-primary):not(.dxbl-btn-outline):not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]):not(.dxbl-text-edit-btn).dxbl-disabled:hover {
            background: var(--app-primary-20) !important;
            border-color: var(--app-primary-20) !important;
            color: var(--app-primary-40) !important;
            cursor: not-allowed !important;
            box-shadow: none !important;
        }

            /* Disabled children — forces text/icon to peach */
            .dxbl-toolbar .dxbl-btn.dxbl-btn-secondary:not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]).dxbl-disabled *,
            .dxbl-toolbar .dxbl-btn.dxbl-btn-secondary:not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]):disabled *,
            .dxbl-toolbar .dxbl-btn:not(.dxbl-btn-danger):not(.dxbl-btn-primary):not(.dxbl-btn-outline):not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]).dxbl-disabled *,
            .dxbl-toolbar .dxbl-btn:not(.dxbl-btn-danger):not(.dxbl-btn-primary):not(.dxbl-btn-outline):not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]):disabled * {
                color: var(--app-primary-40) !important;
            }

            /* Disabled + hover children — spécificité (0,9,0) bat le hover * (0,8,0)
    Le hover * gagne à cause du :not(.dxbl-text-edit-btn) supplémentaire.
    On le neutralise en ajoutant :disabled/:dxbl-disabled + :hover.        */
            .dxbl-toolbar .dxbl-btn.dxbl-btn-secondary:not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]):not(.dxbl-text-edit-btn):disabled:hover *,
            .dxbl-toolbar .dxbl-btn.dxbl-btn-secondary:not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]):not(.dxbl-text-edit-btn).dxbl-disabled:hover *,
            .dxbl-toolbar .dxbl-btn:not(.dxbl-btn-danger):not(.dxbl-btn-primary):not(.dxbl-btn-outline):not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]):not(.dxbl-text-edit-btn):disabled:hover *,
            .dxbl-toolbar .dxbl-btn:not(.dxbl-btn-danger):not(.dxbl-btn-primary):not(.dxbl-btn-outline):not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]):not(.dxbl-text-edit-btn).dxbl-disabled:hover * {
                color: var(--app-primary-40) !important;
            }

    /* Pressed / active — same high specificity as the toolbar block above */
    .dxbl-toolbar .dxbl-btn.dxbl-btn-secondary:not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]):active,
    .dxbl-toolbar .dxbl-btn.dxbl-btn-secondary:not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]).dx-state-active,
    .dxbl-toolbar .dxbl-btn:not(.dxbl-btn-danger):not(.dxbl-btn-primary):not(.dxbl-btn-outline):not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]):active,
    .dxbl-toolbar .dxbl-btn:not(.dxbl-btn-danger):not(.dxbl-btn-primary):not(.dxbl-btn-outline):not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]).dx-state-active {
        background: var(--app-primary-20) !important;
        border-color: var(--app-primary-20) !important;
        color: var(--app-dark-teal) !important;
        box-shadow: none !important;
    }

    /* ── PRIMARY buttons in toolbar — disabled state ────────────
    The enable rule .dxbl-toolbar .dxbl-btn.dxbl-btn-primary has
    specificity (0,3,0). We need (0,4,0) to override it.        */
    .dxbl-toolbar .dxbl-btn.dxbl-btn-primary:disabled,
    .dxbl-toolbar .dxbl-btn.dxbl-btn-primary:disabled:hover,
    .dxbl-toolbar .dxbl-btn.dxbl-btn-primary.dxbl-disabled,
    .dxbl-toolbar .dxbl-btn.dxbl-btn-primary.dxbl-disabled:hover {
        background: var(--app-primary-20) !important;
        border-color: var(--app-primary-20) !important;
        color: var(--app-primary-40) !important;
        cursor: not-allowed !important;
        box-shadow: none !important;
    }

        .dxbl-toolbar .dxbl-btn.dxbl-btn-primary.dxbl-disabled *,
        .dxbl-toolbar .dxbl-btn.dxbl-btn-primary:disabled * {
            color: var(--app-primary-40) !important;
        }

    /* ── TERTIARY (outline) buttons in toolbar ──────────────────
    Explicit rules for .dxbl-btn-outline / .dxbl-btn-outline-secondary
    in a toolbar context. Outline buttons are excluded from the
    secondary block above (:not(.dxbl-btn-outline)), so they need
    their own hover / pressed / disabled declarations.            */

    /* Hover */
    .dxbl-toolbar .dxbl-btn.dxbl-btn-outline:hover,
    .dxbl-toolbar .dxbl-btn.dxbl-btn-outline-secondary:hover {
        background: var(--app-secondary-100) !important;
        border-color: var(--app-secondary-100) !important;
        color: var(--app-neutral-0) !important;
    }

    /* Pressed / active */
    .dxbl-toolbar .dxbl-btn.dxbl-btn-outline:active,
    .dxbl-toolbar .dxbl-btn.dxbl-btn-outline.dx-state-active,
    .dxbl-toolbar .dxbl-btn.dxbl-btn-outline-secondary:active,
    .dxbl-toolbar .dxbl-btn.dxbl-btn-outline-secondary.dx-state-active {
        background: var(--app-secondary-10) !important;
        border-color: var(--app-secondary-20) !important;
        color: var(--app-dark-teal) !important;
        box-shadow: none !important;
    }

    /* Disabled + hover suppressed */
    .dxbl-toolbar .dxbl-btn.dxbl-btn-outline:disabled,
    .dxbl-toolbar .dxbl-btn.dxbl-btn-outline:disabled:hover,
    .dxbl-toolbar .dxbl-btn.dxbl-btn-outline.dxbl-disabled,
    .dxbl-toolbar .dxbl-btn.dxbl-btn-outline.dxbl-disabled:hover,
    .dxbl-toolbar .dxbl-btn.dxbl-btn-outline-secondary:disabled,
    .dxbl-toolbar .dxbl-btn.dxbl-btn-outline-secondary:disabled:hover,
    .dxbl-toolbar .dxbl-btn.dxbl-btn-outline-secondary.dxbl-disabled,
    .dxbl-toolbar .dxbl-btn.dxbl-btn-outline-secondary.dxbl-disabled:hover {
        background: var(--app-secondary-20) !important;
        border-color: var(--app-secondary-20) !important;
        color: var(--app-secondary-40) !important;
        cursor: not-allowed !important;
        box-shadow: none !important;
    }

        /* Disabled children */
        .dxbl-toolbar .dxbl-btn.dxbl-btn-outline.dxbl-disabled *,
        .dxbl-toolbar .dxbl-btn.dxbl-btn-outline:disabled *,
        .dxbl-toolbar .dxbl-btn.dxbl-btn-outline-secondary.dxbl-disabled *,
        .dxbl-toolbar .dxbl-btn.dxbl-btn-outline-secondary:disabled * {
            color: var(--app-secondary-40) !important;
        }


/* ── Boutons secondaires LIME — UNIQUEMENT en détail view (maquette Figma) ──────
   Le reste de l'app garde le secondaire teal-tint (section 6/10). Scope fiable :
   `.main:has(.detail-view-content)` = le conteneur d'une vue détail (la toolbar
   `.main-toolbar` est hors de `.detail-view-content`, d'où le :has sur `.main`).
   On exclut :hover / :disabled -> survol vert et état grisé restent gérés par le
   global ; au repos : fond lime/20 (card/bg) + bordure lime/30. */
.main:has(.detail-view-content) .dxbl-toolbar .dxbl-btn.dxbl-btn-secondary:not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]):not(.dxbl-text-edit-btn):not(:hover):not(:disabled):not(.dxbl-disabled),
.main:has(.detail-view-content) .dxbl-toolbar .dxbl-btn:not(.dxbl-btn-danger):not(.dxbl-btn-primary):not(.dxbl-btn-outline):not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]):not(.dxbl-text-edit-btn):not(:hover):not(:disabled):not(.dxbl-disabled) {
    background: var(--app-card-bg) !important;
    border-color: var(--app-lime-30) !important;
}


/* ============================================================
   11. SIDEBAR NAVIGATION — VOLONTAIREMENT VIDE
   La sidebar est habillée exclusivement par sidebar.css (classe NATIVE
   `.sidebar`), chargé APRÈS ce fichier pour gagner la cascade. Ne pas
   réintroduire de règle `.sidebar` ici : elle entrerait en conflit avec
   sidebar.css.
   ============================================================ */


/* ============================================================
   12. TABS / DETAIL-VIEW NAVIGATION
   ============================================================ */
.card-header > .nav-tabs .nav-item .nav-link {
    font-family: var(--app-font) !important;
    font-size: 14px !important;
    font-weight: 400 !important;
    color: var(--app-neutral-100) !important;
    background: transparent !important;
    border: none !important;
    padding: 10px 8px !important;
    position: relative !important;
    transition: color 0.15s ease !important;
}

    .card-header > .nav-tabs .nav-item .nav-link:hover {
        color: var(--app-primary-100) !important;
    }

    .card-header > .nav-tabs .nav-item .nav-link.active {
        font-weight: 600 !important;
        color: var(--app-primary-100) !important;
        background: transparent !important;
        border-color: transparent !important;
    }


/* ============================================================
   13. GRID (DataGrid)

   IMPORTANT — CSS variable override pattern
   ─────────────────────────────────────────
   DevExpress reads row colours from CSS variables, not from
   hard-coded background-color declarations.  !important on
   background-color is silently ignored because the component
   applies colour through --dxbl-grid-selection-bg at the <tr>
   level, which cascades into the <td> cells.

   The correct approach is to override the component variable
   on a scoped ancestor selector (.dxbl-grid).

   Variable chain traced in core.min.css:
     .dxbl-grid-selected-row td
       → reads --dxbl-grid-selection-bg
       → default: var(--dxds-color-surface-primary-deep-rest)
       → which maps to primary-100 (full orange) by default

   Checkbox checked variable chain:
     dxbl-check.dxbl-checkbox-checked
       → --dxbl-checkbox-check-element-bg
       → --dxbl-checkbox-primary-checked-check-element-bg
       → --dxds-color-content-primary-compound-rest
       → neutral-0 (white on white = invisible tick)
     Fix: override the component variables directly.
   ============================================================ */

/* ── Grid variable overrides ─────────────────────────────────
   All overrides on .dxbl-grid so they cascade into the component.

   --dxbl-grid-selection-bg      → selected row (checkbox)
   --dxbl-grid-edit-row-bg       → edit row (inplace cell editing)
   --dxbl-grid-editor-cell-*     → padding around inplace editors:
     set to 0 so the editor fills the full cell height/width,
     matching DevExpress's own Fluent theme behaviour.           */
.dxbl-grid {
    --dxbl-grid-selection-bg: var(--app-primary-10);
    --dxbl-grid-selection-color: var(--app-neutral-100);
    --dxbl-grid-selection-focus-dark-bg: var(--app-primary-20);
    --dxbl-grid-selection-focus-dark-color: var(--app-neutral-100);
    --dxbl-grid-edit-row-bg: var(--app-primary-20);
    --dxbl-grid-edit-row-color: var(--app-neutral-100);
    --dxbl-grid-editor-cell-padding-x: 0;
    --dxbl-grid-editor-cell-padding-y: 0;
    --dxbl-grid-text-cell-padding-x: 0.125rem;
    --dxbl-grid-text-cell-padding-y: 0;
    --dxbl-grid-border-color: transparent;
}

/* Colonne de sélection compacte : les cases à cocher prennent trop de place
   (padding horizontal large par défaut). On réduit le padding de la cellule de
   sélection — en-tête « tout sélectionner » comprise, pour garder l'alignement —
   et on laisse la colonne se réduire à la case. */
.dxbl-grid .dxbl-grid-selection-cell {
    padding-left: 0.125rem !important;
    padding-right: 0.125rem !important;
    width: 1px;
    white-space: nowrap;
}

/* La colonne de sélection paraît « pleine de padding » parce que le contrôle
   « tout sélectionner » de l'en-tête est un split-button .dxbl-btn au padding 7/12
   + grosses marges (mesuré : ~133px de large). En table, il impose la largeur de
   TOUTE la colonne : les cases des lignes (20px) flottent alors dans une colonne
   très large. On compacte ce bouton → la colonne se réduit à la case. */
/* Boutons DANS les cellules de grille = boutons-icônes en contexte dense. Bonnes
   pratiques « table dense » (Carbon/Fluent) : bouton-icône ~28px carré, padding 6px,
   icône 16px, gap 4px — au lieu du padding 7/12 (~36px) hérité des boutons de
   formulaire. Ciblé sur les cellules (td) + la cellule de sélection (th) : les
   boutons de la barre d'outils (Nouveau, Supprimer…), hors <td>, restent en taille M. */
.dxbl-grid td .dxbl-btn,
.dxbl-grid .dxbl-grid-selection-cell button.dxbl-btn {
    padding: 0 !important;
    margin: 0 !important;
    min-width: 0 !important;
    min-height: 0 !important;
    height: 12px !important;
    line-height: 1 !important;
    gap: 2px !important;
}

    /* Marges internes du split-button « tout sélectionner » de l'en-tête. */
    .dxbl-grid .dxbl-grid-selection-cell .dxbl-btn-split,
    .dxbl-grid .dxbl-grid-selection-cell .dxbl-grid-select-all-split-btn-container {
        margin: 0 !important;
        padding: 0 !important;
    }

/* Densité verticale : DevExpress impose min-height 32px aux cellules → lignes ~40px
   pour un contenu de ~18px. On retire ce plancher + on resserre le line-height pour
   que les lignes se compactent au contenu (padding vertical déjà à 0). */
.dxbl-grid td,
.dxbl-grid th {
    min-height: 0 !important;
    line-height: 1.15 !important;
}

/* La case à cocher en grille impose la hauteur de ligne : une règle du thème
   (`.main-object-model .dxbl-checkbox` / `.detail-view-content .dxbl-checkbox`,
   3 classes) fixe min-height 36px pour le confort de clic sur formulaire. En grille
   on veut compact : on monte la spécificité (chemin .dxbl-grid-table td, 3 classes +
   1 élément) pour gagner, sans toucher aux cases des formulaires. */
.dxbl-grid .dxbl-grid-table td .dxbl-checkbox,
.dxbl-grid .dxbl-grid-table th .dxbl-checkbox {
    padding: 0 !important;
    min-height: 0 !important;
    height: 12px !important;
    align-self: center !important;
}

/* Chevron d'expansion de l'arbre : le SVG rend à 30px, on le ramène à 16px. */
.dxbl-grid .dxbl-grid-tree-node-expand-button svg,
.dxbl-grid .dxbl-grid-tree-node-expand-button .dxbl-image {
    width: 16px !important;
    height: 16px !important;
}

/* Cellules action/arbre/commande : DevExpress leur impose min-height 32px avec un
   sélecteur spécifique. On l'annule avec un sélecteur au moins aussi spécifique
   (chemin > tbody > tr > td + classe). */
.dxbl-grid .dxbl-grid-table > tbody > tr > td.xaf-action,
.dxbl-grid .dxbl-grid-table > tbody > tr > td.dxbl-grid-tree-node-expand-controls-cell,
.dxbl-grid .dxbl-grid-table > tbody > tr > td.dxbl-grid-command-cell {
    min-height: 0 !important;
    padding-left: 0.125rem !important;
    padding-right: 0.125rem !important;
}

/* Colonnes d'action (crayon, import…) : sans largeur contrainte, l'icône flotte au
   centre d'une colonne large -> gros écarts horizontaux. Même astuce que la colonne
   de sélection (width:1px) : la colonne se réduit à la largeur de son contenu.
   Ciblé th + td pour que l'en-tête ne rouvre pas la colonne. */
.dxbl-grid .dxbl-grid-table td.xaf-action,
.dxbl-grid .dxbl-grid-table th.xaf-action,
.dxbl-grid .dxbl-grid-table td.dxbl-grid-command-cell,
.dxbl-grid .dxbl-grid-table th.dxbl-grid-command-cell {
    width: 1px !important;
    white-space: nowrap !important;
}

/* Hauteur de ligne compacte FORCÉE sur la ligne (tr) et ses cellules. Le composant
   maintenait des lignes ~39px pour un contenu de ~16px ; on impose ~24px. (Levier
   manquant : les règles précédentes ne visaient que les cellules, pas la ligne.) */
.dxbl-grid .dxbl-grid-table > tbody > tr,
.dxbl-grid .dxbl-grid-table > tbody > tr > td {
    height: 16px !important;
    min-height: 0 !important;
    padding-top: 0 !important;
    padding-bottom: 0 !important;
    line-height: 1.1 !important;
}

/* Cellules « valeur modifiée » (mode batch-edit) : XAF pose en inline
   `background-color: var(--fluent-primary-transparent-bg, var(--bs-primary-transparent-bg)) !important`.
   Le défaut Bootstrap = color-mix(15% primary, white) -> teal pâle perçu bleu.
   Impossible de battre un !important inline par une règle classique : on
   redéfinit donc la variable SUR la cellule -> le var() inline résout en blanc.
   Scopé à .xaf-grid-modified-value : n'affecte aucun autre usage de ce token. */
.dxbl-grid td.xaf-grid-modified-value,
dxbl-tree-list.dxbl-grid td.xaf-grid-modified-value {
    --fluent-primary-transparent-bg: var(--app-neutral-0);
    --bs-primary-transparent-bg: var(--app-neutral-0);
}

/* Calendriers de tournées (classe posée par RoundCalendarGrid.LockToDataSourceOrder) :
   lignes fixes Lundi→Dimanche, non ouvrables. On masque la colonne de commande inline
   « Ouvrir » (action ShowObject, affichée désactivée) : contenu caché + colonne réduite
   à 0 pour ne pas laisser de gouttière. La 1re <col> = colonne de commande. width:0 !important
   bat le width inline 61px.
   ATTENTION : le même marqueur est posé sur des grilles qui, elles, ont une colonne de
   sélection (multi-select activé, ex. « Clients desservis » / CustomerRoundDay). Là, la 1re
   <col> est la colonne de sélection : la réduire à 0 écrase la case « tout sélectionner » de
   l'en-tête, qui déborde sur la colonne suivante. On exclut donc ce cas via
   :not(:has(.dxbl-grid-selection-cell)) — on ne collapse la 1re colonne que sans sélection. */
.round-calendar-grid .dxbl-grid-table:not(:has(.dxbl-grid-selection-cell)) > colgroup > col:first-child {
    width: 0 !important;
}

.round-calendar-grid .dxbl-grid-command-cell {
    padding: 0 !important;
    border: 0 !important;
}

    .round-calendar-grid .dxbl-grid-command-cell > * {
        display: none !important;
    }

/* Checkbox unchecked — primary (green) border 1.5px, transparent background.
   Figma spec: border var(--checkbox/enable/border, #018973) = primary-100,
   border-width 1.5px, border-radius 4px, bg transparent.               */
dxbl-check.dxbl-checkbox-unchecked {
    --dxbl-checkbox-check-element-border: var(--app-primary-100) !important;
    --dxbl-checkbox-check-element-bg: transparent !important;
}

    dxbl-check.dxbl-checkbox-unchecked .dxbl-checkbox-check-element,
    dxbl-check.dxbl-checkbox-indeterminate .dxbl-checkbox-check-element {
        border-color: var(--app-primary-100) !important;
        border-width: 1.5px !important;
        border-radius: 4px !important;
        background-color: transparent !important;
    }

/* Checkbox checked — orange background with white tick */
dxbl-check.dxbl-checkbox-checked {
    --dxbl-checkbox-check-element-bg: var(--app-primary-100) !important;
    --dxbl-checkbox-check-element-border: var(--app-primary-100) !important;
    --dxbl-checkbox-primary-checked-check-element-bg: var(--app-primary-100) !important;
    --dxbl-checkbox-primary-checked-check-element-border: var(--app-primary-100) !important;
}

    dxbl-check.dxbl-checkbox-checked .dxbl-checkbox-check-element {
        background-color: var(--app-primary-100) !important;
        border-color: var(--app-primary-100) !important;
        border-radius: 4px !important;
    }

        dxbl-check.dxbl-checkbox-checked .dxbl-checkbox-check-element .dxbl-image {
            color: var(--app-neutral-0) !important;
        }

/* Read-only (display-mode) checkbox in a grid cell: DevExpress renders a faint tick on a plain
   transparent background, so a TICKED box read as unticked (the user reported a checked box looking
   empty). Align it with the editable checked style: filled green box + white tick, so a checked
   read-only box is unmistakably checked. The unchecked read-only box keeps a green border only. */
.dxbl-checkbox.dxbl-checkbox-display-view-checked > div,
.dxbl-checkbox.dxbl-checkbox-display-view-indeterminate > div {
    background-color: var(--app-primary-100) !important;
    border-color: var(--app-primary-100) !important;
    border-radius: 4px !important;
}

    .dxbl-checkbox.dxbl-checkbox-display-view-checked > div > .dxbl-image,
    .dxbl-checkbox.dxbl-checkbox-display-view-indeterminate > div > .dxbl-image {
        color: var(--app-neutral-0) !important;
    }

/* Unchecked read-only box: green border + transparent fill, like the editable unchecked state. */
.dxbl-checkbox.dxbl-checkbox-display-view-unchecked > div {
    border-color: var(--app-primary-100) !important;
    border-width: 1.5px !important;
    border-radius: 4px !important;
    background-color: transparent !important;
}

/* Filet de sécurité : TOUTE case cochée (éditable ou lecture seule, dans les grilles
   comme ailleurs) -> fond vert marque + coche blanche. On cible directement l'élément
   de coche `.dxbl-checkbox-check-element` pour ne PAS dépendre de la structure interne
   (`> div`), qui peut varier selon la version DevExpress -> évite le cas « coche blanche
   sur fond blanc = invisible ». */
.dxbl-checkbox-checked .dxbl-checkbox-check-element,
.dxbl-checkbox-indeterminate .dxbl-checkbox-check-element,
.dxbl-checkbox-display-view-checked .dxbl-checkbox-check-element,
.dxbl-checkbox-display-view-indeterminate .dxbl-checkbox-check-element {
    background-color: var(--app-primary-100) !important;
    border-color: var(--app-primary-100) !important;
    border-radius: 4px !important;
}
    .dxbl-checkbox-checked .dxbl-checkbox-check-element .dxbl-image,
    .dxbl-checkbox-indeterminate .dxbl-checkbox-check-element .dxbl-image,
    .dxbl-checkbox-display-view-checked .dxbl-checkbox-check-element .dxbl-image,
    .dxbl-checkbox-display-view-indeterminate .dxbl-checkbox-check-element .dxbl-image,
    .dxbl-checkbox-checked .dxbl-checkbox-check-element svg,
    .dxbl-checkbox-display-view-checked .dxbl-checkbox-check-element svg {
        color: #ffffff !important;
        fill: #ffffff !important;
    }

/* Checkbox size — 20×20 */
dxbl-check .dxbl-checkbox-check-element {
    width: 20px !important;
    height: 20px !important;
    min-width: 20px !important;
    min-height: 20px !important;
}

    dxbl-check .dxbl-checkbox-check-element .dxbl-image {
        width: 14px !important;
        height: 14px !important;
    }

/* En grille, les cases sont plus petites que sur formulaire (contexte dense) :
   14×14 avec coche 10px. Scopé à .dxbl-grid-table pour ne pas réduire les cases
   des formulaires (règle 20×20 ci-dessus, non scopée). */
.dxbl-grid .dxbl-grid-table .dxbl-checkbox-check-element {
    width: 12px !important;
    height: 12px !important;
    min-width: 12px !important;
    min-height: 12px !important;
    box-sizing: border-box !important;
}

    .dxbl-grid .dxbl-grid-table .dxbl-checkbox-check-element .dxbl-image {
        width: 9px !important;
        height: 9px !important;
    }

/* En grille, bordure de case plus fine (1px au lieu de 1.5px) : la case en trait fin
   s'harmonise avec les icônes d'action (crayon, import) et paraît moins « lourde ». */
.dxbl-grid .dxbl-grid-table dxbl-check.dxbl-checkbox-unchecked .dxbl-checkbox-check-element,
.dxbl-grid .dxbl-grid-table dxbl-check.dxbl-checkbox-indeterminate .dxbl-checkbox-check-element {
    border-width: 1px !important;
    border-radius: 3px !important;
}

/* Icônes des boutons d'action en cellule (crayon, import…) : alignées sur la taille
   des cases (14px). Surcharge la règle globale des icônes de bouton (16px). */
.dxbl-grid .dxbl-grid-table td button .dxbl-image,
.dxbl-grid .dxbl-grid-table td button img,
.dxbl-grid .dxbl-grid-table td button svg,
.dxbl-grid .dxbl-grid-table td a .dxbl-image,
.dxbl-grid .dxbl-grid-table td a img,
.dxbl-grid .dxbl-grid-table td a svg,
.dxbl-grid .dxbl-grid-table td.dxbl-grid-command-cell img,
.dxbl-grid .dxbl-grid-table td.dxbl-grid-command-cell svg,
.dxbl-grid .dxbl-grid-table td.xaf-action img,
.dxbl-grid .dxbl-grid-table td.xaf-action svg {
    width: 12px !important;
    height: 12px !important;
    min-width: 0 !important;
    min-height: 0 !important;
}

/* Tree expand/collapse button — must NOT inherit the 33px min-height
   from the global button reset (section 4). Its size is set by the
   grid's own icon sizing, not the toolbar button spec.              */
.dxbl-grid .dxbl-grid-tree-node-expand-button.dxbl-btn {
    min-height: unset !important;
    height: 1.25rem !important;
    min-width: unset !important;
    width: 1.25rem !important;
    padding: 0 !important;
    box-shadow: none !important;
}

/* Case « tout sélectionner » (en-tête grille) : c'est un SPLIT BUTTON (case à cocher +
   chevron « modes de sélection »). Le reset bouton global (section 4) lui collait un fond
   teal (primary) + une ombre -> grosse boîte « bizarre ». On enlève UNIQUEMENT l'habillage
   visuel (fond, ombre, bordure). ⚠️ NE PAS toucher padding/min-height/géométrie : ça
   décalait la colonne de sélection (désalignement) et cassait la zone cliquable de la case. */
.dxbl-grid-select-all-split-btn-container .dxbl-btn,
.dxbl-grid-select-all-split-btn-container .dxbl-btn-split > .dxbl-btn {
    background: transparent !important;
    border-color: transparent !important;
    box-shadow: none !important;
}

/* Chevron du select-all : la règle secondary (§6) met les icônes en BLANC au survol,
   ce qui le faisait disparaître sur l'en-tête blanc. On annule ce filtre pour ce conteneur
   (icône en teal, au repos comme au survol). Sélecteur calqué sur §6 + préfixe conteneur
   pour gagner en spécificité (0,8,0 > 0,7,0). */
.dxbl-grid-select-all-split-btn-container .dxbl-image {
    filter: none !important;
    color: var(--app-dark-teal) !important;
    opacity: 0.7 !important;
}
.dxbl-grid-select-all-split-btn-container .dxbl-btn.dxbl-btn-secondary:not([data-action-name="New"]):not([data-action-name="Nouveau"]):not([data-action-name="Valider"]):hover .dxbl-image {
    filter: none !important;
    color: var(--app-dark-teal) !important;
    opacity: 0.95 !important;
}

/* Row hover (survol lime/20).
   ⚠️ L'ancienne règle `.dxbl-grid-row:hover td` ne matchait RIEN : les lignes de données
   DevExpress sont des `tbody > tr` (pas de classe `.dxbl-grid-row`), et le survol natif
   exige la classe `.dxbl-grid-row-hover-enabled` (souvent absente) + ajoute un voile noir 4%.
   On cible donc directement la vraie ligne et on force le fond lime. On exclut en-tête
   (thead), ligne de filtre, groupes, édition, vide, et lignes SÉLECTIONNÉES (gardent leur fond). */
.dxbl-grid tbody > tr:not(.dxbl-grid-filter-row):not(.dxbl-grid-group-row):not(.dxbl-grid-group-footer-row):not(.dxbl-grid-edit-row):not(.dxbl-grid-empty-row):not(.dxbl-grid-selected-row):hover > td {
    background-color: var(--app-lime-20) !important;
}

/* Column headers */
.dxbl-grid .dxbl-grid-header-cell {
    font-family: var(--app-font) !important;
    font-size: 12px !important;
    font-weight: 600 !important;
    color: var(--app-neutral-100) !important;
    background-color: var(--app-neutral-10) !important;
    border-bottom: 1px solid var(--app-neutral-40) !important;
}

/* Lignes de données : texte teal #164147 + 12px (Figma : grid/line_item/enable/content
   #164147, police s/regular 12px). On cible le rôle « gridcell » -> n'affecte NI l'en-tête
   (columnheader) NI la ligne de filtre. Même traitement que le tree-list (section 13b). */
.dxbl-grid td[role="gridcell"] {
    color: var(--app-dark-teal) !important;
    font-size: 12px !important;
}

/* Éditeur INLINE de cellule : même police que l'affichage (12px). Sans ça, la règle
   éditeur globale (§ « FORM EDITORS », font-size 14px !important sur .dxbl-text-edit / input)
   rendait le texte PLUS GRAND en modification qu'en visualisation. Scopé aux cellules de
   données (role=gridcell) -> n'affecte pas la ligne de filtre ni l'en-tête. */
.dxbl-grid td[role="gridcell"] .dxbl-text-edit,
.dxbl-grid td[role="gridcell"] .dxbl-text-edit-input,
.dxbl-grid td[role="gridcell"] .dxbl-input-editor,
.dxbl-grid td[role="gridcell"] .dxbl-combobox,
.dxbl-grid td[role="gridcell"] input,
.dxbl-grid td[role="gridcell"] textarea,
.dxbl-grid td[role="gridcell"] select {
    font-size: 12px !important;
}

/* Cellules « lien » (référence : Marque, Unité, BioCode…) et VALEUR MODIFIÉE
   (template xaf-grid-display-item, affiché plus grand car le CSS core fixe une taille
   sur le lien/wrapper, écrasant le 12px hérité du td). On force 12px sur le lien et le
   wrapper pour que l'affichage modifié == l'affichage normal. */
.dxbl-grid td[role="gridcell"] a,
.dxbl-grid td[role="gridcell"] .grid-cell-object-link,
.dxbl-grid td[role="gridcell"] .xaf-grid-display-item,
.dxbl-grid td[role="gridcell"] .xaf-grid-display-item a,
.dxbl-grid td[role="gridcell"] .xaf-wrap-ellipsis {
    font-size: 12px !important;
}

/* Éditeur INLINE (input combobox/lookup, ex. colonne « Marque ») : en édition, la cellule
   ne garde PAS role="gridcell", donc la règle ci-dessus la manquait et l'éditeur retombait
   sur la police globale 14px (§ FORM EDITORS) -> texte plus GRAND en modif qu'en affichage.
   On scope donc à la LIGNE de données (tr), indépendamment du rôle de la cellule, en
   excluant la ligne de filtre et l'en-tête (qui ont leurs propres tailles). */
.dxbl-grid tr:not(.dxbl-grid-filter-row):not(.dxbl-grid-header-row) .dxbl-text-edit-input,
.dxbl-grid tr:not(.dxbl-grid-filter-row):not(.dxbl-grid-header-row) input[type="text"],
.dxbl-grid tr:not(.dxbl-grid-filter-row):not(.dxbl-grid-header-row) input[type="search"],
.dxbl-grid tr:not(.dxbl-grid-filter-row):not(.dxbl-grid-header-row) .dxbl-text-edit,
.dxbl-grid tr:not(.dxbl-grid-filter-row):not(.dxbl-grid-header-row) .dxbl-input-editor,
.dxbl-grid tr:not(.dxbl-grid-filter-row):not(.dxbl-grid-header-row) .dxbl-combobox,
.dxbl-grid tr:not(.dxbl-grid-filter-row):not(.dxbl-grid-header-row) textarea,
.dxbl-grid tr:not(.dxbl-grid-filter-row):not(.dxbl-grid-header-row) select {
    font-size: 12px !important;
}

/* Filter / search row — secondary brand colour background */
tr.dxbl-grid-filter-row.dxbl-grid-editor-inplace-container td,
.dxbl-grid tr.dxbl-grid-filter-row td dxbl-date-edit {
    background-color: var(--app-primary-10) !important;
}

/* Editors inside filter row are transparent so the row bg shows through */
tr.dxbl-grid-filter-row .dxbl-text-edit,
tr.dxbl-grid-filter-row dxbl-input-editor,
tr.dxbl-grid-filter-row dxbl-spinedit,
tr.dxbl-grid-filter-row dxbl-date-edit {
    background: transparent !important;
    box-shadow: none !important;
}

tr.dxbl-grid-filter-row .dxbl-text-edit-input {
    background: transparent !important;
    color: var(--app-dark-teal) !important;
}

/* ============================================================
   13b. TREE LIST — Figma node 2308-47972
   ============================================================ */

dxbl-tree-list.dxbl-grid {
    width: 100% !important;
    min-width: 100% !important;
}

    dxbl-tree-list.dxbl-grid .dxbl-scroll-viewer,
    dxbl-tree-list.dxbl-grid .dxbl-scroll-viewer-content,
    dxbl-tree-list.dxbl-grid .dxbl-grid-table {
        width: 100% !important;
        min-width: 100% !important;
    }

    dxbl-tree-list.dxbl-grid .dxbl-grid-table {
        table-layout: fixed !important;
        border-collapse: separate !important;
        border-spacing: 0 2px !important;
    }

    dxbl-tree-list.dxbl-grid .dxbl-grid-header,
    dxbl-tree-list.dxbl-grid td[role="gridcell"] {
        height: 32px !important;
        min-height: 32px !important;
        padding: 0 10px !important;
        vertical-align: middle !important;
        font-size: 12px !important;
        line-height: 16px !important;
        font-weight: 400 !important;
        color: var(--app-dark-teal) !important;
    }

    dxbl-tree-list.dxbl-grid tbody tr td {
        background-color: var(--app-neutral-10) !important;
    }

    dxbl-tree-list.dxbl-grid tbody .dxbl-grid-selected-row td {
        background-color: var(--app-primary-10) !important;
    }

    dxbl-tree-list.dxbl-grid tbody tr:hover td {
        background-color: var(--app-neutral-20) !important;
    }

    dxbl-tree-list.dxbl-grid tbody tr td:first-child {
        border-radius: 4px 0 0 4px !important;
    }

    dxbl-tree-list.dxbl-grid tbody tr td:nth-last-child(2) {
        border-radius: 0 4px 4px 0 !important;
    }

    dxbl-tree-list.dxbl-grid .dxbl-grid-tree-node-expand-controls-cell {
        display: table-cell !important;
        white-space: nowrap !important;
    }

    dxbl-tree-list.dxbl-grid .dxbl-grid-tree-node-expand-controls-container {
        display: inline-flex !important;
        align-items: center !important;
        vertical-align: middle !important;
        margin-right: 4px !important;
    }

    dxbl-tree-list.dxbl-grid .dxbl-grid-bottom-panel.dxbl-pager-container {
        min-height: 52px !important;
        padding: 8px !important;
        display: flex !important;
        align-items: center !important;
    }

/* ============================================================
   13c. GRID LISTVIEW — row height / checkbox alignment
   Applies only to XAF ListView grid containers.
   Do not merge with section 18: DetailView rules also affect
   form editors, input buttons and checkbox sizing.
   ============================================================ */

/* Pas de min-height ici : le plancher 36px (confort de clic sur formulaire, cf. section 18)
   étire la case en grille et impose la hauteur de ligne. La hauteur compacte est fixée
   par la règle `.dxbl-grid .dxbl-grid-table td .dxbl-checkbox` (height 20px). */
.main-content > .grid-content.grid-virtual-scrolling-mode dxbl-grid .dxbl-checkbox,
.main-content > .grid-content.grid-virtual-scrolling-mode dxbl-tree-list .dxbl-checkbox {
    display: inline-flex !important;
    align-items: center !important;
}

.main-content > .grid-content.grid-virtual-scrolling-mode dxbl-grid .dxbl-grid-selection-cell,
.main-content > .grid-content.grid-virtual-scrolling-mode dxbl-tree-list .dxbl-grid-selection-cell {
    vertical-align: middle !important;
}

/* Décalage colonne de sélection : la case « tout sélectionner » de l'en-tête
   (bouton split = case + chevron) s'aligne plus à GAUCHE que les cases des
   lignes (centrées dans la cellule) -> elles ne forment pas une colonne propre.
   On décale la case de l'en-tête de 25px à droite pour l'aligner sur les lignes,
   en excluant le bouton dropdown (chevron) du split. */
.dxbl-grid-command-cell .dxbl-grid-header-content > .dxbl-grid-select-all-split-btn-container .dxbl-btn-split > .dxbl-btn:not(.dxbl-btn-split-dropdown),
.dxbl-grid-selection-cell .dxbl-grid-header-content > .dxbl-grid-select-all-split-btn-container .dxbl-btn-split > .dxbl-btn:not(.dxbl-btn-split-dropdown) {
    margin-left: 25px !important;
}

.main-content > .grid-content.grid-virtual-scrolling-mode dxbl-grid td,
.main-content > .grid-content.grid-virtual-scrolling-mode dxbl-tree-list td {
    vertical-align: middle !important;
}


/* ============================================================
   14. INPUTS / SEARCH / EDITORS
   General editor styles that apply outside of detail views.
   Detail-view-scoped overrides are in section 18.
   ============================================================ */
.dxbl-input-editor,
.dxbl-text-edit,
.dx-texteditor,
.form-control,
input[type="text"],
input[type="search"],
textarea,
select {
    font-family: var(--app-font) !important;
    font-size: 14px !important;
    border-radius: var(--app-radius-sm) !important;
    border-color: var(--app-neutral-40) !important;
    color: var(--app-neutral-100) !important;
    background-color: var(--app-neutral-0) !important;
}

    .dxbl-input-editor:focus,
    .dxbl-text-edit:focus,
    .dx-texteditor.dx-state-focused,
    .form-control:focus,
    input[type="text"]:focus,
    input[type="search"]:focus,
    textarea:focus,
    select:focus {
        border-color: var(--app-primary-100) !important;
        /*        box-shadow: var(--app-shadow-focus) !important;*/
        outline: none !important;
    }

/* Toolbar search box height */
.dxbl-toolbar input[type="search"],
.dxbl-toolbar .dxbl-text-edit,
.dxbl-toolbar .dx-texteditor {
    min-height: 33px !important;
}

/* ── Placeholder / Search input (Figma node 26-273) ─────────────
   Le champ de recherche XAF (.xaf-action-fulltextsearch) doit
   correspondre au composant Placeholder Figma :
   - Icône intégrée dans le champ (pas de bouton distinct)
   - États : enable / hover (champ) / focus-within (active)

   HTML :
     dxbl-input-editor.dxbl-text-edit.xaf-action-fulltextsearch
       input.dxbl-text-edit-input
       div.dxbl-btn-group-right
         button.dxbl-btn.dxbl-btn-outline-secondary.dxbl-text-edit-btn
           img.dxbl-image

   Figma tokens :
     enable  : bg neutral-10 (#f9f9f9)   border neutral-30 (#ebebea)
     hover   : bg primary-10 (#e6f3f1)   border primary-20 (#cce7e3)
     active  : bg neutral-10 (#f9f9f9)   border primary-100 (#018973)
     icon enable/hover : neutral-80 (#91918d)
     icon active       : dark-teal (#164147)
   ──────────────────────────────────────────────────────────── */

/* Container — enable */
.xaf-action-fulltextsearch.dxbl-text-edit {
    background-color: var(--placeholder-enable-bg) !important;
    border-color: var(--placeholder-enable-border) !important;
    border-radius: var(--app-radius-md) !important;
}

    /* Container — hover */
    .xaf-action-fulltextsearch.dxbl-text-edit:hover {
        background-color: var(--placeholder-hover-bg) !important;
        border-color: var(--placeholder-hover-border) !important;
        box-shadow: none !important;
    }

        /* Input — bg hover (l'input a un bg explicite, doit suivre le container) */
        .xaf-action-fulltextsearch.dxbl-text-edit:hover .dxbl-text-edit-input {
            background-color: var(--placeholder-hover-bg) !important;
        }

    /* Container — active / focus */
    .xaf-action-fulltextsearch.dxbl-text-edit:focus-within,
    .xaf-action-fulltextsearch.dxbl-text-edit.dx-state-focused {
        background-color: var(--placeholder-active-bg) !important;
        border-color: var(--placeholder-active-border) !important;
        box-shadow: none !important;
    }

/* Input — bg enable (override placé aussi après blocs génériques, cf. ci-dessous) */
.xaf-action-fulltextsearch .dxbl-text-edit-input {
    background-color: var(--placeholder-enable-bg) !important;
}

/* Bouton — transparent, intégré dans le champ
   Spécificité 0,3,0 pour battre .dxbl-toolbar .dxbl-btn.dxbl-btn-outline-secondary */
.xaf-action-fulltextsearch .dxbl-btn.dxbl-text-edit-btn {
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
    padding: 7px 10px !important;
}

    .xaf-action-fulltextsearch .dxbl-btn.dxbl-text-edit-btn:hover,
    .xaf-action-fulltextsearch .dxbl-btn.dxbl-text-edit-btn:active,
    .xaf-action-fulltextsearch .dxbl-btn.dxbl-text-edit-btn.dx-state-active {
        background: transparent !important;
        border: none !important;
        box-shadow: none !important;
    }

/* Icône — couleur enable/hover : --placeholder-enable-content (#91918d) */
.xaf-action-fulltextsearch .dxbl-text-edit-btn .dxbl-image {
    width: 14px !important;
    height: 14px !important;
    filter: brightness(0) saturate(0%) invert(57%) !important;
}

/* Icône — couleur active : --placeholder-active-content (#164147 dark-teal) */
.xaf-action-fulltextsearch.dxbl-text-edit:focus-within .dxbl-text-edit-btn .dxbl-image,
.xaf-action-fulltextsearch.dxbl-text-edit.dx-state-focused .dxbl-text-edit-btn .dxbl-image {
    filter: brightness(0) saturate(100%) invert(22%) sepia(28%) saturate(665%) hue-rotate(155deg) brightness(93%) contrast(95%) !important;
}

/* Container — disabled */
.xaf-action-fulltextsearch.dxbl-disabled.dxbl-text-edit {
    background-color: var(--placeholder-disabled-bg) !important;
    border-color: var(--placeholder-disabled-border) !important;
    box-shadow: none !important;
    cursor: not-allowed !important;
}

/* Input — bg + texte disabled */
.xaf-action-fulltextsearch.dxbl-disabled .dxbl-text-edit-input {
    background-color: var(--placeholder-disabled-bg) !important;
    color: var(--placeholder-disabled-content) !important;
    cursor: not-allowed !important;
}

/* Icône — couleur disabled : --placeholder-disabled-content (#b9b9b6) */
.xaf-action-fulltextsearch.dxbl-disabled .dxbl-text-edit-btn .dxbl-image {
    filter: brightness(0) saturate(0%) invert(73%) !important;
}


/* ============================================================
   15. PAGE TITLE / TOP BAR
   ============================================================ */
.header,
.app-header,
.dxbl-header {
    font-family: var(--app-font) !important;
}

h1, h2, h3, h4, h5, h6 {
    font-family: var(--app-font) !important;
}

/* Bandeau de page (flèche retour + titre de vue) rendu dans la zone contenu —
   remplace le header sombre masqué (maquette). Le bouton retour hérite du style
   bouton global (boîte claire) ; le titre est teal/semibold. */
.main-pagebar {
    display: flex !important;
    flex-direction: row !important;
    flex-wrap: nowrap !important;
    align-items: center !important;
    gap: 14px;   /* espace bouton retour <-> titre (maquette) : évite le « collé » */
    padding-top: 16px;
    padding-bottom: 2px;
    min-height: 44px;
    overflow: visible !important;
    flex: 0 0 auto;
}
/* Retour + titre sur la MÊME ligne : enfants en ligne, pas d'écrasement vertical. */
    .main-pagebar > * {
        flex: 0 0 auto;
        margin-left: 13px !important;
    }
/* Bouton RETOUR : flèche COMPACTE façon maquette (« ← Produit » serré), au lieu de la
   grosse boîte claire du reset bouton global (section 4) qui éloignait le titre du bord.
   Seul bouton présent dans .main-pagebar -> on le cible directement. Au repos = flèche nue ;
   au survol le style secondary lui redonne un fond teal (retour visuel conservé). */
/* Bouton RETOUR (.navigate-back-icon-container) = SECONDARY maquette : fond lime clair +
   bordure lime + flèche teal foncé. Ciblé par sa double classe pour battre les utilitaires
   Bootstrap p-0/border-0. L'icône est un masque coloré par currentColor -> on fixe `color`. */
/* IMPORTANT : préfixe #main-view-content (ID) pour passer DEVANT la règle DevExpress
   `.dxbl-btn.dxbl-btn-text-none { background: transparent }` (même spécificité 0,2,0 mais
   chargée après la nôtre, donc elle gagnait -> le bouton restait blanc/transparent).
   L'ID porte la spécificité à (1,2,0) et règle définitivement la couleur. */
#main-view-content .navigate-back-icon-container.dxbl-btn,
#main-view-content .main-pagebar .dxbl-btn {
    padding: 6px !important;
    min-width: 0 !important;
    min-height: 0 !important;
    background: var(--app-primary-10) !important;
    background-color: var(--app-primary-10) !important;
    --dxbl-btn-background-color: var(--app-primary-10) !important;
    --dxbl-btn-background-color-hovered: var(--app-primary-20) !important;
    --dxbl-btn-background-color-active: var(--app-primary-20) !important;
    border: 1px solid var(--app-primary-20) !important;
    --dxbl-btn-border-color: var(--app-primary-20) !important;
    border-radius: var(--app-radius-md) !important;
    box-shadow: none !important;
    color: var(--app-dark-teal) !important;            /* flèche (mask currentColor) -> teal foncé */
    --dxbl-btn-color: var(--app-dark-teal) !important;
}
#main-view-content .navigate-back-icon-container.dxbl-btn:hover,
#main-view-content .main-pagebar .dxbl-btn:hover {
    background: var(--app-primary-20) !important;
    background-color: var(--app-primary-20) !important;
    border-color: var(--app-primary-30) !important;
    color: var(--app-dark-teal) !important;
}
/* Titre de vue (ViewCaptionComponent). Maquette (Figma node 4090-40424) :
   - PAS d'icône ;
   - « Produit » TOUJOURS complet (jamais tronqué) ;
   - bandeau LARGE : le titre prend la largeur restante, seul un nom d'objet long ellipse ;
   - en vue DÉTAIL : « Produit » en GRIS (#91918d, Charcoal/80) + « - » + nom d'objet en teal.
   Rendu DOM DevExpress : .view-caption-root > [.xaf-caption-icon-container,
   .xaf-caption-container > (span.xaf-view-caption-sm|lg « Produit » + span.xaf-object-caption nom)].
   sm = vue détail (ObjectCaption présent) ; lg = vue liste. */
.main-pagebar-title {
    display: flex !important;
    align-items: center !important;
    flex: 1 1 auto !important;   /* large : occupe la place restante du bandeau */
    min-width: 0 !important;     /* autorise l'ellipsis du nom d'objet long */
    overflow: hidden !important;
    font-family: var(--app-font) !important;
    font-size: 18px !important;
    font-weight: 600 !important;
    color: var(--app-dark-teal) !important;
    line-height: 1.2 !important;
    margin: 0 !important;
}
.main-pagebar-title .view-caption-root,
.main-pagebar-title .xaf-caption-container {
    display: flex !important;
    flex: 1 1 auto !important;
    flex-direction: row !important;
    align-items: center !important;
    min-width: 0 !important;
    max-width: 100% !important;
    overflow: hidden !important;
}
/* Icône retirée (maquette) + annulation du retrait de largeur que DevExpress prévoit pour elle. */
.main-pagebar-title .xaf-caption-icon-container { display: none !important; }
.main-pagebar-title .xaf-caption-icon-container + .xaf-caption-container { max-width: 100% !important; }
/* « Produit » : toujours COMPLET (pas d'ellipsis, ne rétrécit jamais). Teal en vue liste. */
.main-pagebar-title .xaf-view-caption-sm,
.main-pagebar-title .xaf-view-caption-lg {
    flex: 0 0 auto !important;
    overflow: visible !important;
    text-overflow: clip !important;
    white-space: nowrap !important;
    font-size: 18px !important;
    line-height: 1.2 !important;
    color: var(--app-dark-teal) !important;
    margin: 0 !important;
}
/* Vue détail (classe xaf-view-caption-sm) : « Produit » en GRIS. */
.main-pagebar-title .xaf-view-caption-sm {
    color: var(--app-neutral-80) !important;  /* #91918d — Charcoal/80 (maquette) */
}
/* Nom de l'objet (vue détail) : teal foncé, ellipsis si trop long, séparé par « - ». */
.main-pagebar-title .xaf-object-caption {
    flex: 0 1 auto !important;
    min-width: 0 !important;
    overflow: hidden !important;
    text-overflow: ellipsis !important;
    white-space: nowrap !important;
    font-size: 18px !important;
    font-weight: 600 !important;
    line-height: 1.2 !important;
    color: var(--app-dark-teal) !important;
    margin: 0 !important;
}
/* « - » UNIQUEMENT en vue détail : il sépare le libellé de vue (xaf-view-caption-sm) du nom
   d'objet. Scopé au sibling adjacent -> sur le Dashboard (titre seul dans .xaf-object-caption,
   sans libellé de vue avant) le « - » parasite (« - Dashboard ») disparaît. */
.main-pagebar-title .xaf-view-caption-sm + .xaf-object-caption::before {
    content: "\00A0-\00A0";  /* « - » entre « Produit » et le nom (insécables pour garder les espaces) */
}


/* ============================================================
   16. FOCUS RING
   ============================================================ */
:focus-visible {
    outline: 2px solid var(--app-primary-90) !important;
    outline-offset: 1px !important;
}

/* Le grid DevExpress place le focus PAR PROGRAMME sur sa zone scrollable /
   ligne / cellule au chargement de la vue liste. Le navigateur fait alors
   matcher :focus-visible -> contour vert parasite (arrondi, débordant sous le
   grid) en bas à gauche. On neutralise le focus ring sur ces éléments
   structurels ; il reste actif sur les contrôles interactifs (boutons, champs,
   checkbox) pour la navigation clavier. */
.dxbl-grid:focus-visible,
.dxbl-grid-table:focus-visible,
.dxbl-grid-scroll-viewer:focus-visible,
.dxbl-grid-data-row:focus-visible,
.dxbl-grid-data-row > td:focus-visible,
.dxbl-grid [tabindex]:focus-visible:not(.dxbl-btn):not(input):not(.dxbl-checkbox) {
    outline: none !important;
}


/* ============================================================
   17. MODAL / POPUP
   XAF Blazor uses DevExpress popup components that render as
   .dxbl-modal-* elements.  Layout: backdrop → content →
   header / body / footer.
   ============================================================ */

/* Backdrop */
.dxbl-modal-dialog-backdrop,
.modal-backdrop {
    background-color: rgba(22, 65, 71, 0.40) !important;
    backdrop-filter: blur(2px) !important;
}

/* Sizing & centering — garder les popups dans la fenêtre, centrés, jamais plein écran.
   Les popups de DetailView XAF s'étirent sinon démesurément : on plafonne largeur/hauteur
   et on rend le corps défilant pour que header + footer restent visibles. Vaut pour TOUS
   les modals (dxbl-modal-* et dxbl-window-*). */
.dxbl-modal,
.dxbl-window-root {
    align-items: center !important;
    justify-content: center !important;
}

.dxbl-modal-dialog,
.dxbl-window {
    width: auto !important;
    max-width: min(1100px, 92vw) !important;
    max-height: 90vh !important;
    margin: 0 !important;
    /* Pas d'ombre/bordure/fond propres au conteneur : seul .dxbl-modal-content porte l'apparence
       (le centrage est géré sur .dxbl-modal-content + la règle :has ci-dessus). */
    box-shadow: none !important;
    border: none !important;
    background: transparent !important;
}

/* SUPPRESSION FORCÉE de l'ombre du modal. Le thème Fluent la pose via un sélecteur plus
   spécifique (.dxbl-theme-fluent .dxbl-window…) -> un simple .dxbl-window{box-shadow:none}
   perd la cascade. On rehausse la spécificité (préfixe .dxbl-theme-fluent + classes doublées)
   et on neutralise aussi un éventuel drop-shadow via filter. */
.dxbl-theme-fluent .dxbl-modal-content,
.dxbl-theme-fluent .dxbl-modal-dialog,
.dxbl-theme-fluent .dxbl-window,
.dxbl-theme-fluent .dxbl-window-content,
.dxbl-theme-fluent .dxbl-window-root,
.dxbl-theme-fluent .dxbl-popup,
.dxbl-theme-fluent .dxbl-popup-root,
.dxbl-modal-content.dxbl-modal-content,
.dxbl-window.dxbl-window {
    box-shadow: none !important;
    filter: none !important;
}

/* Outer container — dimensions FIXES, CENTRÉ par le parent (l'overlay .dxbl-modal /
   .dxbl-window-root est déjà en position:fixed plein écran + flex center -> le contenu est donc
   déjà épinglé au centre du viewport). On NE met PAS position:fixed sur le contenu lui-même :
   ça le détachait de son conteneur .dxbl-modal-dialog, qui restait alors comme une boîte VIDE
   affichant l'ombre par défaut DevExpress (le « shadow » fantôme vu à droite).
   - width/height FIXES (valeurs PROVISOIRES 900×600 — à ajuster) ; max-width/height = garde-fou.
   - flex column + overflow:hidden : header + footer fixes, le corps (.dxbl-modal-body) défile. */
.dxbl-modal-content {
    font-family: var(--app-font) !important;
    background-color: var(--app-neutral-10) !important;
    border: 1px solid var(--app-neutral-30) !important;
    border-radius: 10px !important;
    box-shadow: none !important;
    overflow: hidden !important;

    /* PLEIN ÉCRAN à droite du menu : le modal occupe toute la zone de contenu, du bord droit de la
       sidebar (210px) jusqu'aux bords de l'écran. position:fixed (cale sur le viewport, indépendant
       de la position de drag du parent, neutralisée par *:has(> .dxbl-modal-content) -> transform:none).
       NB : la sidebar fait 210px dépliée / 70px repliée -> valeur 210px en dur ici (à ajuster si on
       veut suivre l'état replié). */
    position: fixed !important;
    top: 20px !important;
    bottom: 20px !important;
    left: 230px !important;  /* 210px sidebar + 20px de marge */
    right: 20px !important;
    transform: none !important;
    width: auto !important;
    height: auto !important;
    max-width: none !important;
    max-height: none !important;
    border-radius: 10px !important;  /* coin arrondi -> lisible comme une popup posée */

    display: flex !important;
    flex-direction: column !important;
}

/* Le PARENT direct de .dxbl-modal-content (classe variable selon le type de popup XAF) porte la
   position de drag (left/top ou transform inline) + l'ombre/fond par défaut DevExpress -> c'est lui
   le « fantôme ». On le neutralise sans connaître sa classe via :has() : transparent, sans ombre, et
   surtout transform:none (sinon un transform sur le parent ferait que le position:fixed du contenu
   se cale sur LUI au lieu du viewport). Scopé via :has(> .dxbl-modal-content) -> n'affecte PAS les
   autres popups (dropdowns, tooltips). */
*:has(> .dxbl-modal-content) {
    transform: none !important;
    box-shadow: none !important;
    background: transparent !important;
    border: none !important;
}

/* EXCEPTION à la règle plein écran ci-dessus : les dialogues « message » (erreur, info,
   confirmation oui/non) n'ont pas de vue à afficher — juste un texte et un ou deux boutons.
   Les étaler sur toute la zone de contenu donne une grande boîte quasi vide.
   Deux familles visées :
   - .dxbl-message-box > .dxbl-modal-content : DxMessageBox (le conteneur .dxbl-message-box est le
     PARENT direct du contenu -> il est déjà neutralisé par la règle *:has() ci-dessus).
   - .dxbl-modal-content sans vue XAF à l'intérieur : les dialogues XAF (IExceptionDialogTemplate /
     IConfirmationDialogTemplate) ne portent pas de classe propre, on les reconnaît donc à l'absence
     de grille / form layout / onglets. Les popups de View en contiennent toujours au moins un et
     gardent la taille fixe (c'est le cas des lignes articles à l'origine du ticket).
   Spécificité (0,2,0) > la règle .dxbl-modal-content (0,1,0) -> l'emporte à !important égal.
   Centrage : position:fixed + translate -50% (le transform du parent est déjà neutralisé). */
.dxbl-message-box > .dxbl-modal-content,
.dxbl-modal-content:not(:has(.dxbl-grid, .dxbl-form-layout, .dxbl-tabs)) {
    top: 50% !important;
    left: 50% !important;
    right: auto !important;
    bottom: auto !important;
    transform: translate(-50%, -50%) !important;

    /* Largeur fixe -> pas de redimensionnement selon la longueur du message.
       Hauteur auto : un message court ne doit pas laisser de vide, et max-height borne
       les messages longs (le corps défile alors, header + boutons restent visibles). */
    width: min(480px, 90vw) !important;
    height: auto !important;
    max-height: 70vh !important;
}

/* Header */
.dxbl-modal-header,
dxbl-popup-header.dxbl-modal-header {
    background-color: var(--app-neutral-10) !important;
    border-bottom: 1px solid var(--app-neutral-30) !important;
    padding: 15px 20px !important;
    min-height: 56px !important;
    display: flex !important;
    align-items: center !important;
}

.dxbl-modal-header-default {
    display: flex !important;
    align-items: center !important;
    justify-content: space-between !important;
    gap: 8px !important;
    width: 100% !important;
    min-height: 20px !important;
}

/* Title */
.dxbl-modal-header .xaf-object-caption,
dxbl-popup-header .xaf-object-caption {
    font-family: var(--app-font) !important;
    font-size: 16px !important;
    font-weight: 600 !important;
    color: var(--app-dark-teal) !important;
    line-height: 1.4 !important;
    overflow: hidden !important;
    text-overflow: ellipsis !important;
    white-space: nowrap !important;
}

/* Close button */
button.dxbl-popup-header-button {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
    color: var(--app-neutral-80) !important;
    width: 28px !important;
    min-width: 28px !important;
    height: 28px !important;
    min-height: 28px !important;
    padding: 4px !important;
    border-radius: var(--app-radius-md) !important;
    flex-shrink: 0 !important;
    transition: background-color 0.15s ease, color 0.15s ease !important;
}

    button.dxbl-popup-header-button:hover {
        background-color: var(--app-neutral-20) !important;
        color: var(--app-dark-teal) !important;
    }

/* Body */
.dxbl-modal-body {
    padding: 15px 20px !important;
    background-color: var(--app-neutral-0) !important;
    overflow: auto !important;
    flex: 1 1 auto !important;
}

    .dxbl-modal-body .xaf-static-text,
    .dxbl-modal-body label {
        font-family: var(--app-font) !important;
        font-size: 14px !important;
        font-weight: 400 !important;
        color: var(--app-neutral-100) !important;
        line-height: 1.5 !important;
        white-space: pre-line !important;
    }

    /* Inputs inside popup */
    .dxbl-modal-body .dxbl-input-editor,
    .dxbl-modal-body .dxbl-text-edit,
    .dxbl-modal-body .dx-texteditor,
    .dxbl-modal-body .form-control,
    .dxbl-modal-body select {
        min-height: 34px !important;
        border-radius: var(--app-radius-md) !important;
    }

/* Footer */
.dxbl-modal-footer {
    padding: 16px 24px !important;
    min-height: 68px !important;
    border-top: 1px solid var(--app-neutral-30) !important;
    background-color: var(--app-neutral-10) !important;
    display: flex !important;
    align-items: center !important;
}

    /* Toolbar root inside footer */
    .dxbl-modal-footer .dxbl-toolbar,
    .dxbl-modal-footer dxbl-toolbar {
        width: 100% !important;
        min-width: 100% !important;
        margin: 0 !important;
        padding: 0 !important;
        background: transparent !important;
        height: auto !important;
        min-height: 36px !important;
    }

        /* DevExpress toolbar internal layout */
        .dxbl-modal-footer .dxbl-toolbar .dxbl-toolbar-items-container,
        .dxbl-modal-footer dxbl-toolbar .dxbl-toolbar-items-container {
            width: 100% !important;
            display: flex !important;
            align-items: center !important;
        }

        /* Empty before / center zones */
        .dxbl-modal-footer .dxbl-toolbar .dxbl-toolbar-before,
        .dxbl-modal-footer .dxbl-toolbar .dxbl-toolbar-center,
        .dxbl-modal-footer dxbl-toolbar .dxbl-toolbar-before,
        .dxbl-modal-footer dxbl-toolbar .dxbl-toolbar-center {
            flex: 0 0 auto !important;
            width: auto !important;
            min-width: 0 !important;
            padding: 0 !important;
            margin: 0 !important;
        }

        /* After zone — contains the action buttons, pushed to the right */
        .dxbl-modal-footer .dxbl-toolbar .dxbl-toolbar-after,
        .dxbl-modal-footer dxbl-toolbar .dxbl-toolbar-after {
            margin-left: auto !important;
            display: flex !important;
            align-items: center !important;
            justify-content: flex-end !important;
            gap: 8px !important;
            width: auto !important;
            min-width: 0 !important;
            padding: 0 !important;
        }

            .dxbl-modal-footer .dxbl-toolbar .dxbl-toolbar-after .dxbl-toolbar-item,
            .dxbl-modal-footer dxbl-toolbar .dxbl-toolbar-after .dxbl-toolbar-item {
                display: flex !important;
                align-items: center !important;
                margin: 0 !important;
                padding: 0 !important;
            }

    /* Footer buttons */
    .dxbl-modal-footer .dxbl-btn,
    .dxbl-modal-footer button.dxbl-btn.dxbl-sm {
        min-height: 36px !important;
        height: 36px !important;
        padding: 7px 14px !important;
        line-height: 1 !important;
        border-radius: 4px !important;
        display: inline-flex !important;
        align-items: center !important;
        justify-content: center !important;
        white-space: nowrap !important;
    }


/* ============================================================
   18. DETAIL VIEW — Object forms (XAF FormLayout)
   Scoped to .main.main-object-model and .detail-view-content
   to avoid touching grid cell editors and modal editors.

   Verified DOM structure (provided HTML):
     .dxbl-group
       .dxbl-group-header > .dxbl-text
       .dxbl-group-body.dxbl-fl-group-body
         .dxbl-group-body-content
           .dxbl-fl-item
             .dxbl-fl-cpt          ← field label
             .dxbl-fl-ctrl
               .dxbl-text-edit     ← editor root
                 .dxbl-text-edit-input   ← actual <input>
                 .dxbl-btn-group-right   ← attached buttons (clear/dropdown)

   Colours verified against Figma (node 301-18359):
     Card background:      neutral-0
     Card border:          primary-20
     Card header bg:       primary-10
     Card header text:     neutral-130
     Editor background:    neutral-10
     Editor border:        neutral-30
     Editor text:          dark-teal
     Label colour:         neutral-130
     Disabled background:  neutral-30
   ============================================================ */

/* Card container — corps blanc, bordure lime/20. Seul l'EN-TÊTE est lime (maquette). */
.main.main-object-model .dxbl-group,
.detail-view-content .dxbl-group {
    background: var(--app-neutral-0) !important;
    border: 1px solid var(--app-card-border) !important;
    border-radius: 10px !important;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04) !important;
    overflow: hidden !important;
}

    /* Card header — même lime que le corps (card uniforme dans la maquette) */
    .main.main-object-model .dxbl-group > .dxbl-group-header,
    .detail-view-content .dxbl-group > .dxbl-group-header {
        background: var(--app-card-bg) !important;
        border-bottom: 1px solid var(--app-card-border) !important;
        border-radius: 10px 10px 0 0 !important;
        padding: 15px 20px !important;
        min-height: 46px !important;
        display: flex !important;
        align-items: center !important;
    }

        /* Bouton de repli (chevron) de l'en-tête : nu, sans boîte (le reset bouton
           global section 4 lui pose fond/bordure/ombre arrondis -> la maquette le
           veut transparent, juste le chevron). */
        .main.main-object-model .dxbl-group > .dxbl-group-header .dxbl-btn,
        .main.main-object-model .dxbl-group > .dxbl-group-header .dxbl-btn:hover,
        .detail-view-content .dxbl-group > .dxbl-group-header .dxbl-btn,
        .detail-view-content .dxbl-group > .dxbl-group-header .dxbl-btn:hover {
            background: transparent !important;
            border: none !important;
            box-shadow: none !important;
        }

        .main.main-object-model .dxbl-group > .dxbl-group-header .dxbl-text,
        .detail-view-content .dxbl-group > .dxbl-group-header .dxbl-text {
            color: var(--app-dark-teal) !important;
            font-family: var(--app-font) !important;
            font-size: 14px !important;
            font-weight: 500 !important;
            line-height: 1.35 !important;
        }

/* Card body — blanc (seul l'en-tête est lime) */
.main.main-object-model .dxbl-group-body.dxbl-fl-group-body > .dxbl-group-body-content,
.detail-view-content .dxbl-group-body.dxbl-fl-group-body > .dxbl-group-body-content {
    background: var(--app-neutral-0) !important;
    padding: 15px !important;
}

/* Bootstrap row gutters inside groups */
.main.main-object-model .dxbl-group-body .dxbl-row,
.detail-view-content .dxbl-group-body .dxbl-row {
    --bs-gutter-x: 16px;
    --bs-gutter-y: 10px;
}

/* Field item wrapper */
.main.main-object-model .dxbl-fl-item,
.detail-view-content .dxbl-fl-item {
    margin-bottom: 8px !important;
}

/* Field labels */
.main.main-object-model .dxbl-fl-cpt,
.detail-view-content .dxbl-fl-cpt {
    color: var(--app-neutral-130) !important;
    font-family: var(--app-font) !important;
    font-size: 12px !important;
    font-weight: 400 !important;
    line-height: 1.35 !important;
    margin-bottom: 6px !important;
}

/* En layout horizontal le label est à côté de l'input — annuler le margin-bottom et centrer verticalement */
.main.main-object-model .dxbl-fl-item.dxbl-fl-item-horizontal > .dxbl-fl-cpt,
.detail-view-content .dxbl-fl-item.dxbl-fl-item-horizontal > .dxbl-fl-cpt {
    margin-bottom: 0 !important;
    align-self: center !important;
}

/* Control wrapper — full width */
.main.main-object-model .dxbl-fl-ctrl,
.detail-view-content .dxbl-fl-ctrl {
    width: 100% !important;
}

/* Editor root (.dxbl-text-edit wraps input + button groups) */
.main.main-object-model .dxbl-text-edit,
.main.main-object-model .dxbl-input-editor,
.main.main-object-model dxbl-combo-box.dxbl-text-edit,
.main.main-object-model dxbl-date-edit.dxbl-text-edit,
.detail-view-content .dxbl-text-edit,
.detail-view-content .dxbl-input-editor,
.detail-view-content dxbl-combo-box.dxbl-text-edit,
.detail-view-content dxbl-date-edit.dxbl-text-edit {
    background: var(--app-neutral-10) !important;
    border: 1px solid var(--app-neutral-30) !important;
    border-radius: var(--app-radius-md) !important;
    min-height: 34px !important;
    height: 34px !important;
    box-shadow: none !important;
    display: flex !important;
    align-items: stretch !important;
    overflow: hidden !important;
}

/* Tag box (multi-select lookup) — hauteur auto pour le wrapping des tags */
.main.main-object-model dxbl-tag-box.dxbl-text-edit,
.detail-view-content dxbl-tag-box.dxbl-text-edit {
    height: auto !important;
    min-height: 34px !important;
    overflow: visible !important;
    flex-wrap: wrap !important;
}

    /* Supprime la bordure de focus sur l'input interne du TagBox (doublon visuel) */
    .main.main-object-model dxbl-tag-box.dxbl-text-edit input.dxbl-text-edit-input,
    .detail-view-content dxbl-tag-box.dxbl-text-edit input.dxbl-text-edit-input {
        border: none !important;
        box-shadow: none !important;
        outline: none !important;
    }

/* Editor hover */
.main.main-object-model .dxbl-text-edit:hover,
.main.main-object-model .dxbl-input-editor:hover,
.detail-view-content .dxbl-text-edit:hover,
.detail-view-content .dxbl-input-editor:hover {
    background: var(--app-neutral-20) !important;
    border-color: var(--app-neutral-40) !important;
}

/* Placeholder — override hover/focus (spécificité 0,4,1 > 0,3,1) */
.main.main-object-model .xaf-action-fulltextsearch.dxbl-text-edit:hover,
.detail-view-content .xaf-action-fulltextsearch.dxbl-text-edit:hover {
    background: var(--placeholder-hover-bg) !important;
    border-color: var(--placeholder-hover-border) !important;
    box-shadow: none !important;
}

.main.main-object-model .xaf-action-fulltextsearch.dxbl-text-edit:focus-within,
.main.main-object-model .xaf-action-fulltextsearch.dxbl-text-edit.dx-state-focused,
.detail-view-content .xaf-action-fulltextsearch.dxbl-text-edit:focus-within,
.detail-view-content .xaf-action-fulltextsearch.dxbl-text-edit.dx-state-focused {
    background: var(--placeholder-active-bg) !important;
    border-color: var(--placeholder-active-border) !important;
    box-shadow: none !important;
}

/* Placeholder — override disabled (spécificité 0,4,1 > 0,3,1 de .dxbl-disabled.dxbl-text-edit) */
.main.main-object-model .dxbl-disabled.xaf-action-fulltextsearch.dxbl-text-edit,
.detail-view-content .dxbl-disabled.xaf-action-fulltextsearch.dxbl-text-edit {
    background: var(--placeholder-disabled-bg) !important;
    border-color: var(--placeholder-disabled-border) !important;
    box-shadow: none !important;
}

/* Editor focused */
.main.main-object-model .dxbl-text-edit:focus-within,
.main.main-object-model .dxbl-input-editor:focus-within,
.main.main-object-model .dxbl-text-edit.dx-state-focused,
.main.main-object-model .dxbl-input-editor.dx-state-focused,
.detail-view-content .dxbl-text-edit:focus-within,
.detail-view-content .dxbl-input-editor:focus-within,
.detail-view-content .dxbl-text-edit.dx-state-focused,
.detail-view-content .dxbl-input-editor.dx-state-focused {
    background: #ffffff !important;
    border-color: var(--app-primary-100) !important;
    /*    box-shadow: 0 0 0 2px rgba(255, 90, 0, 0.12) !important;*/
}

/* Actual <input> element */
.main.main-object-model .dxbl-text-edit-input,
.detail-view-content .dxbl-text-edit-input {
    background: transparent !important;
    border: none !important;
    color: var(--app-dark-teal) !important;
    font-family: var(--app-font) !important;
    font-size: 12px !important;
    line-height: 1.35 !important;
    min-height: 32px !important;
    height: 32px !important;
    padding: 8px 10px !important;
    box-shadow: none !important;
}

    .main.main-object-model .dxbl-text-edit-input::placeholder,
    .detail-view-content .dxbl-text-edit-input::placeholder {
        color: var(--app-neutral-80) !important;
        opacity: 1 !important;
    }

/* Read-only / disabled editors */
.main.main-object-model .dxbl-disabled.dxbl-text-edit,
.main.main-object-model .dxbl-readonly.dxbl-text-edit,
.detail-view-content .dxbl-disabled.dxbl-text-edit,
.detail-view-content .dxbl-readonly.dxbl-text-edit {
    background: var(--app-neutral-30) !important;
    border-color: var(--app-neutral-30) !important;
    cursor: not-allowed !important;
}

/* Bouton calendar/dropdown disabled directement sur le bouton lui-même */
.main.main-object-model .dxbl-edit-btn-dropdown.dxbl-disabled,
.detail-view-content .dxbl-edit-btn-dropdown.dxbl-disabled {
    background: transparent !important;
    border: none !important;
    color: var(--app-neutral-70) !important;
    cursor: not-allowed !important;
}

.main.main-object-model .dxbl-disabled .dxbl-text-edit-input,
.main.main-object-model .dxbl-readonly .dxbl-text-edit-input,
.detail-view-content .dxbl-disabled .dxbl-text-edit-input,
.detail-view-content .dxbl-readonly .dxbl-text-edit-input {
    color: var(--app-neutral-70) !important;
    cursor: not-allowed !important;
}

    .main.main-object-model .dxbl-disabled .dxbl-text-edit-input::placeholder,
    .main.main-object-model .dxbl-readonly .dxbl-text-edit-input::placeholder,
    .detail-view-content .dxbl-disabled .dxbl-text-edit-input::placeholder,
    .detail-view-content .dxbl-readonly .dxbl-text-edit-input::placeholder {
        color: var(--app-neutral-70) !important;
        opacity: 1 !important;
    }

.main.main-object-model .dxbl-disabled .dxbl-edit-btn-clear,
.main.main-object-model .dxbl-disabled .dxbl-edit-btn-dropdown,
.detail-view-content .dxbl-disabled .dxbl-edit-btn-clear,
.detail-view-content .dxbl-disabled .dxbl-edit-btn-dropdown {
    cursor: not-allowed !important;
    pointer-events: none !important;
    color: var(--app-neutral-70) !important;
}

/* Attached button group (clear / dropdown arrow) — fond transparent pour se fondre dans l'input */
.main.main-object-model .dxbl-btn-group-right,
.detail-view-content .dxbl-btn-group-right {
    display: flex !important;
    align-items: stretch !important;
    gap: 0 !important;
    border-left: none !important;
    background: transparent !important;
}

/* Individual attached buttons — transparents, fondus dans l'input */
.main.main-object-model .dxbl-edit-btn-clear,
.main.main-object-model .dxbl-edit-btn-dropdown,
.main.main-object-model .dxbl-text-edit-btn,
.detail-view-content .dxbl-edit-btn-clear,
.detail-view-content .dxbl-edit-btn-dropdown,
.detail-view-content .dxbl-text-edit-btn {
    padding: 7px 8px !important;
    border: none !important;
    border-left: none !important;
    border-radius: 0 !important;
    background: transparent !important;
    color: var(--app-neutral-80) !important;
    box-shadow: none !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    min-width: unset !important;
    width: auto !important;
    height: auto !important;
    min-height: unset !important;
}

/* ── Override Placeholder / Search — après les règles génériques ─
   Doit être déclaré APRÈS les blocs .dxbl-btn-group-right et
   .dxbl-text-edit-btn ci-dessus pour gagner à spécificité égale.
   Spécificité cible : 0,3,0 (même que les blocs concurrents).    */

/* Input — bg selon état (enable / hover / active) */
.xaf-action-fulltextsearch.dxbl-text-edit .dxbl-text-edit-input {
    background-color: var(--placeholder-enable-bg) !important;
}

.xaf-action-fulltextsearch.dxbl-text-edit:hover .dxbl-text-edit-input {
    background-color: var(--placeholder-hover-bg) !important;
}

.xaf-action-fulltextsearch.dxbl-text-edit:focus-within .dxbl-text-edit-input,
.xaf-action-fulltextsearch.dxbl-text-edit.dx-state-focused .dxbl-text-edit-input {
    background-color: var(--placeholder-active-bg) !important;
}

/* Div wrapper du bouton — pas de border, bg suit l'état du container */
.xaf-action-fulltextsearch.dxbl-text-edit .dxbl-btn-group-right {
    border-left: none !important;
    background: var(--placeholder-enable-bg) !important;
}

.xaf-action-fulltextsearch.dxbl-text-edit:hover .dxbl-btn-group-right {
    background: var(--placeholder-hover-bg) !important;
}

.xaf-action-fulltextsearch.dxbl-text-edit:focus-within .dxbl-btn-group-right,
.xaf-action-fulltextsearch.dxbl-text-edit.dx-state-focused .dxbl-btn-group-right {
    background: var(--placeholder-active-bg) !important;
}

/* Bouton lui-même — bg suit l'état du container, pas de border */
.xaf-action-fulltextsearch.dxbl-text-edit .dxbl-text-edit-btn {
    background: var(--placeholder-enable-bg) !important;
    border: none !important;
    border-left: none !important;
    box-shadow: none !important;
    min-width: unset !important;
    width: auto !important;
    height: auto !important;
    min-height: unset !important;
    padding: 7px 10px !important;
    border-radius: 0 !important;
}

.xaf-action-fulltextsearch.dxbl-text-edit:hover .dxbl-text-edit-btn {
    background: var(--placeholder-hover-bg) !important;
    border: none !important;
    box-shadow: none !important;
}

.xaf-action-fulltextsearch.dxbl-text-edit:focus-within .dxbl-text-edit-btn,
.xaf-action-fulltextsearch.dxbl-text-edit.dx-state-focused .dxbl-text-edit-btn {
    background: var(--placeholder-active-bg) !important;
    border: none !important;
    box-shadow: none !important;
}

/* Input bg — disabled */
.xaf-action-fulltextsearch.dxbl-disabled .dxbl-text-edit-input {
    background-color: var(--placeholder-disabled-bg) !important;
    color: var(--placeholder-disabled-content) !important;
}

/* Div wrapper bouton — disabled */
.xaf-action-fulltextsearch.dxbl-disabled .dxbl-btn-group-right {
    border-left: none !important;
    background: var(--placeholder-disabled-bg) !important;
}

/* Bouton — disabled */
.xaf-action-fulltextsearch.dxbl-disabled .dxbl-text-edit-btn {
    background: var(--placeholder-disabled-bg) !important;
    border: none !important;
    box-shadow: none !important;
    cursor: not-allowed !important;
}

.main.main-object-model .dxbl-edit-btn-clear:hover,
.main.main-object-model .dxbl-edit-btn-dropdown:hover,
.main.main-object-model .dxbl-text-edit-btn:hover,
.detail-view-content .dxbl-edit-btn-clear:hover,
.detail-view-content .dxbl-edit-btn-dropdown:hover,
.detail-view-content .dxbl-text-edit-btn:hover {
    background: transparent !important;
    color: var(--app-neutral-100) !important;
}

/* Remove double border on first attached button */
.main.main-object-model .dxbl-btn-group-right > :first-child,
.detail-view-content .dxbl-btn-group-right > :first-child {
    border-left: none !important;
}

/* Icons inside attached buttons */
.main.main-object-model .dxbl-edit-btn-clear .dxbl-image,
.main.main-object-model .dxbl-edit-btn-dropdown .dxbl-image,
.main.main-object-model .dxbl-text-edit-btn .dxbl-image,
.detail-view-content .dxbl-edit-btn-clear .dxbl-image,
.detail-view-content .dxbl-edit-btn-dropdown .dxbl-image,
.detail-view-content .dxbl-text-edit-btn .dxbl-image {
    width: 16px !important;
    height: 16px !important;
}

/* ============================================================
   LISTE DÉROULANTE — affordance visuelle (toute l'app)
   Sans chevron visible, un combobox/lookup ressemble à un simple
   champ texte. On force le bouton dropdown et son chevron à rester
   visibles sur TOUS les combobox de l'app (non scopé à la vue détail).
   Si un éditeur ne rend aucun bouton dropdown natif -> fallback ::after.
   ============================================================ */
.dxbl-combobox .dxbl-edit-btn-dropdown,
.dxbl-combobox .dxbl-edit-btn.dxbl-edit-btn-dropdown {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    opacity: 1 !important;
    visibility: visible !important;
}

.dxbl-combobox .dxbl-edit-btn-dropdown .dxbl-image,
.dxbl-combobox .dxbl-edit-btn-dropdown .dxbl-image use {
    opacity: 1 !important;
    /* color + fill : le chevron est un <svg class="dxbl-image"><use #dx-chevron-down-small…>.
       Un <use> de sprite ne suit pas toujours `color` (selon que le symbole peint en currentColor
       ou non) -> on force AUSSI `fill`, sinon le chevron reste blanc et disparaît sur fond clair
       (ex. sélecteur « Page Size » du pager). */
    color: var(--app-neutral-80) !important;
    fill: var(--app-neutral-80) !important;
}

/* Fallback : si le combobox n'expose pas de bouton dropdown natif, on dessine
   un chevron en ::after (purement visuel, ne capte pas le clic -> l'input gère
   l'ouverture). N'apparaît que quand .dxbl-edit-btn-dropdown est absent. */
.dxbl-combobox:not(:has(.dxbl-edit-btn-dropdown)) {
    position: relative;
}

    .dxbl-combobox:not(:has(.dxbl-edit-btn-dropdown))::after {
        content: "";
        position: absolute;
        top: 50%;
        right: 12px;
        width: 9px;
        height: 9px;
        margin-top: -3px;
        border-right: 1.5px solid var(--app-neutral-80);
        border-bottom: 1.5px solid var(--app-neutral-80);
        transform: rotate(45deg);
        pointer-events: none;
    }

/* Checkbox vertical alignment */
.main.main-object-model .dxbl-checkbox,
.detail-view-content .dxbl-checkbox {
    min-height: 36px !important;
    display: inline-flex !important;
    align-items: center !important;
}

/* Toutes les cases à cocher plus petites : la boîte visible passe de 20px à 16px
   (formulaires ET grilles). Les styles coché/décoché (bordure, coche) suivent. */
.main .dxbl-checkbox-check-element,
.detail-view-content .dxbl-checkbox-check-element {
    width: 16px !important;
    height: 16px !important;
    min-width: 16px !important;
    min-height: 16px !important;
}

/* Tab links inside detail view */
.main.main-object-model .card-header > .nav-tabs .nav-item .nav-link,
.detail-view-content .card-header > .nav-tabs .nav-item .nav-link {
    padding-top: 10px !important;
    padding-bottom: 14px !important;
}

/* Detail area background — transparent so the page bg shows through */
.main.main-object-model .main-content,
.detail-view-content {
    background: transparent !important;
}

/* Hide spin buttons on numeric editors (design decision) */
.dxbl-spin-btns,
.dxbl-text-edit > .dxbl-spin-btns,
.dxbl-text-edit > .dxbl-btn-group-vertical.dxbl-spin-btns,
.dxbl-input-editor > .dxbl-spin-btns,
.dxbl-input-editor > .dxbl-btn-group-vertical.dxbl-spin-btns {
    display: none !important;
}


/* ============================================================
   19. PAGER
   Figma nodes 166-1382 (LimitPageNumbers), 166-1984 (Pager),
   166-2022 (PageNumber).

   Page number states :
     default  : bg white, border transparent, text dark-teal
     active   : bg primary-100, border primary-100, text white
     hover    : bg primary-10, border primary-10, text dark-teal
     pressed  : bg primary-20, border primary-20, text dark-teal
   Nav buttons (prev/next/first/last) :
     padding 5px, border-radius 4px
   Gap entre éléments : 2px
   ============================================================ */

/* ── Container ──────────────────────────────────────────────── */
.dxbl-pager {
    display: inline-flex !important;
    align-items: center !important;
    gap: 2px !important;
    font-family: var(--app-font) !important;
}

    /* ── Base commune à tous les boutons du pager ───────────────── */
    /* Tous utilisent dxbl-btn dxbl-btn-outline-secondary — on scope
au pager pour ne pas toucher les vrais boutons secondaires.    */
    .dxbl-pager .dxbl-btn {
        display: inline-flex !important;
        align-items: center !important;
        justify-content: center !important;
        border-radius: 4px !important;
        border: 1px solid transparent !important;
        background: var(--app-neutral-0) !important;
        color: var(--app-dark-teal) !important;
        font-family: var(--app-font) !important;
        box-shadow: none !important;
        transition: background 0.15s, border-color 0.15s !important;
    }

        /* ── Boutons de numéro de page ──────────────────────────────── */
        .dxbl-pager .dxbl-btn.dxbl-pager-page-btn {
            min-width: 32px !important;
            height: 32px !important;
            padding: 6px !important;
            font-size: 14px !important;
            font-weight: 400 !important;
            line-height: 20px !important;
        }

        /* Page active */
        .dxbl-pager .dxbl-btn.dxbl-pager-active-page-btn {
            background: var(--app-primary-100) !important;
            border-color: var(--app-primary-100) !important;
            color: var(--app-neutral-0) !important;
        }

        /* Couleur texte — non-active (spécificité 0,4,0 pour battre les règles globales) */
        .dxbl-pager .dxbl-btn.dxbl-pager-page-btn:not(.dxbl-pager-active-page-btn) {
            color: var(--app-dark-teal) !important;
        }

            /* Hover page non-active */
            .dxbl-pager .dxbl-btn.dxbl-pager-page-btn:not(.dxbl-pager-active-page-btn):hover {
                background: var(--app-primary-10) !important;
                border-color: var(--app-primary-10) !important;
                color: var(--app-dark-teal) !important;
            }

            /* Pressed page non-active */
            .dxbl-pager .dxbl-btn.dxbl-pager-page-btn:not(.dxbl-pager-active-page-btn):active {
                background: var(--app-primary-20) !important;
                border-color: var(--app-primary-20) !important;
                color: var(--app-dark-teal) !important;
            }

        /* ── Boutons de navigation (prev / next / first / last) ─────── */
        .dxbl-pager .dxbl-btn:not(.dxbl-pager-page-btn) {
            width: 30px !important;
            height: 30px !important;
            padding: 5px !important;
            color: var(--app-dark-teal) !important;
        }

            .dxbl-pager .dxbl-btn:not(.dxbl-pager-page-btn):hover {
                background: var(--app-primary-10) !important;
                border-color: var(--app-primary-10) !important;
                color: var(--app-dark-teal) !important;
            }

            .dxbl-pager .dxbl-btn:not(.dxbl-pager-page-btn):active {
                background: var(--app-primary-20) !important;
                border-color: var(--app-primary-20) !important;
                color: var(--app-dark-teal) !important;
            }

            .dxbl-pager .dxbl-btn:not(.dxbl-pager-page-btn).dxbl-disabled,
            .dxbl-pager .dxbl-btn:not(.dxbl-pager-page-btn):disabled {
                opacity: 0.35 !important;
                cursor: not-allowed !important;
            }


/* ============================================================
   20. NAV-RIBBON (DxTabs / navigation principale)
   Figma nodes 115-715 (nav-ribbon), 115-277 (ribbon-item),
   115-317 (ribbon-bar).

   HTML vérifié :
     dxbl-tab-item.dxbl-tabs-item          ← onglet
     dxbl-tab-item.dxbl-tabs-item.dxbl-active ← onglet actif
     .dxbl-tabs-text-container > .dxbl-text > .dxbl-tabs-text-overflow

   États Figma :
     active   : SemiBold 600, underline primary-100 (3px pill)
     enable   : Regular 400, pas d'underline
     hover    : bg primary-10, radius 4px, Regular
     pressed  : bg primary-20, radius 4px, Regular
   ============================================================ */

/* ── Barre claire pleine largeur via ul::after ──────────────── */
/* bottom = même valeur que le padding DevExpress du ul          */
/* (--dxbl-tabs-tab-focus-outline-size/offset) → alignement      */
/* garanti avec le bas des li sans pixel fixe arbitraire         */
dxbl-scroll-viewer ul[role="tablist"] {
    position: relative !important;
}

    dxbl-scroll-viewer ul[role="tablist"]::after {
        content: '' !important;
        position: absolute !important;
        bottom: calc(var(--dxbl-tabs-tab-focus-outline-size, 0px) + var(--dxbl-tabs-tab-focus-outline-offset, 0px)) !important;
        left: 0 !important;
        right: 0 !important;
        height: 3px !important;
        background: var(--app-primary-10) !important;
        pointer-events: none !important;
        z-index: 0 !important;
    }

    /* ── Barre orange sur le li contenant le tab actif ─────────── */
    /* bottom: 0 sur li = coïncide avec ul::after (même bottom)     */
    dxbl-scroll-viewer ul[role="tablist"] > li {
        position: relative !important;
    }

        dxbl-scroll-viewer ul[role="tablist"] > li:has(dxbl-tab-item.dxbl-active)::after {
            content: '' !important;
            position: absolute !important;
            bottom: 0 !important;
            left: 0 !important;
            right: 0 !important;
            height: 3px !important;
            background: var(--app-primary-100) !important;
            border-radius: 9999px !important;
            pointer-events: none !important;
            z-index: 2 !important;
        }

/* ── Neutraliser l'indicateur natif DevExpress ──────────────── */
/* DevExpress utilise dxbl-tab-item::after pour son propre       */
/* indicateur (barre noire hover + barre active mal positionnée) */
dxbl-tab-item.dxbl-tabs-item::after {
    display: none !important;
}

/* ── Tab item base ──────────────────────────────────────────── */
dxbl-tab-item.dxbl-tabs-item {
    padding: 10px 7px !important;
    border-radius: 4px !important;
    background: transparent !important;
    cursor: pointer !important;
    transition: background 0.15s !important;
}

    /* ── Texte ──────────────────────────────────────────────────── */
    /* Exclure dxbl-tabs-space-reservation : ce clone caché sert    */
    /* à pré-réserver la largeur bold — y appliquer Manrope élargit */
    /* chaque onglet et déclenche les flèches du scroll viewer      */
    dxbl-tab-item.dxbl-tabs-item .dxbl-tabs-text-overflow {
        font-family: var(--app-font) !important;
        font-weight: 400 !important;
        color: var(--app-dark-teal) !important;
        line-height: normal !important;
        white-space: nowrap !important;
    }

    /* ── Actif — texte SemiBold ─────────────────────────────────── */
    dxbl-tab-item.dxbl-tabs-item.dxbl-active .dxbl-tabs-text-overflow {
        font-weight: 600 !important;
    }

    /* ── Hover — background uniquement, barre inchangée ─────────── */
    dxbl-tab-item.dxbl-tabs-item:not(.dxbl-active):hover {
        background: var(--app-primary-10) !important;
    }

    /* ── Pressed ────────────────────────────────────────────────── */
    dxbl-tab-item.dxbl-tabs-item:not(.dxbl-active):active {
        background: var(--app-primary-20) !important;
    }


/* ============================================================
   21. ICON OVERRIDES
   Stratégie : data-qa-selector identifie le composant DevExpress
   de façon stable. On masque .dxbl-image (icône native) et on
   injecte le SVG via ::before + CSS mask (couleur contrôlable
   via background-color, compatible tous navigateurs modernes).
   ============================================================ */

/* ── Popup — bouton de fermeture ─────────────────────────────── */
button[data-qa-selector="dx-popup-close-button"] .dxbl-image {
    display: none !important;
}

button[data-qa-selector="dx-popup-close-button"] {
    width: 28px !important;
    height: 28px !important;
    padding: 0 !important;
    background: transparent !important;
}

    button[data-qa-selector="dx-popup-close-button"]::before {
        content: "";
        display: block;
        width: 14px;
        height: 14px;
        margin: auto;
        background-color: var(--app-dark-teal);
        -webkit-mask: url("/images/Close.svg") center / contain no-repeat;
        mask: url("/images/Close.svg") center / contain no-repeat;
    }

/* ── TreeList — bouton expand/collapse ───────────────────────── */
button.dxbl-grid-tree-node-expand-button svg.dxbl-image use {
    display: none !important;
}

button.dxbl-grid-tree-node-expand-button svg.dxbl-image {
    width: 20px !important;
    height: 20px !important;
    transform: scale(1.5) !important;
    background-repeat: no-repeat !important;
    background-position: center !important;
    background-size: contain !important;
}

button.dxbl-grid-tree-node-expand-button[aria-label="Expand"] svg.dxbl-image,
button.dxbl-grid-tree-node-expand-button[aria-label="Déplier"] svg.dxbl-image {
    background-image: url("/images/family_filter_button_right.svg") !important;
}

button.dxbl-grid-tree-node-expand-button[aria-label="Collapse"] svg.dxbl-image,
button.dxbl-grid-tree-node-expand-button[aria-label="Réduire"] svg.dxbl-image {
    background-image: url("/images/family_filter_button.svg") !important;
}

/* ============================================================
   22. GARDE u
   La sidebar est gouvernée par app-design-system.css (.app-sidebar).
   Plusieurs règles APPLICATION sont globales et posent leurs propriétés
   en `!important` directement (et non via les variables --dxbl-*),
   ce qui les fait écraser app-design dans la sidebar — typiquement le
   champ de recherche XAF qui repassait sur fond blanc.
   On ré-impose ici l'apparence du Design System, en réutilisant ses
   tokens --app-* (définis sur :root dans app-design-system.css, donc
   disponibles globalement). Bloc placé en DERNIER pour gagner le
   cascade à spécificité égale.
   ============================================================ */
/* Champ de recherche / filtre natif XAF dans la sidebar */
.app-sidebar .dxbl-text-edit,
.app-sidebar .dxbl-input-editor,
.app-sidebar input[type="text"],
.app-sidebar input[type="search"] {
    background-color: var(--app-field-surface) !important;
    border-color: var(--app-field-border) !important;
    color: var(--app-text-on-dark) !important;
    border-radius: var(--app-radius-s) !important;
    font-family: var(--app-font-family) !important;
    font-size: var(--app-font-size-s) !important;
}

.app-sidebar .dxbl-text-edit:hover {
    background-color: var(--app-field-surface-hover) !important;
    border-color: var(--app-field-border-hover) !important;
}

.app-sidebar .dxbl-text-edit:focus-within,
.app-sidebar .dxbl-text-edit.dx-state-focused {
    border-color: var(--app-field-border-focus) !important;
}

/* Input réel : fond transparent (le fond est porté par le conteneur) */
.app-sidebar .dxbl-text-edit-input {
    background: transparent !important;
    color: var(--app-text-on-dark) !important;
    font-family: var(--app-font-family) !important;
}

.app-sidebar .dxbl-text-edit-input::placeholder {
    color: var(--app-text-placeholder) !important;
}

/* Bouton loupe natif : se fond dans le champ (pas de boîte claire) */
.app-sidebar .dxbl-text-edit .dxbl-text-edit-btn,
.app-sidebar .dxbl-text-edit .dxbl-btn-icon,
.app-sidebar .dxbl-text-edit .dxbl-btn {
    background: transparent !important;
    border-color: transparent !important;
    color: var(--app-text-placeholder) !important;
}

    .app-sidebar .dxbl-text-edit .dxbl-text-edit-btn:hover,
    .app-sidebar .dxbl-text-edit .dxbl-btn-icon:hover,
    .app-sidebar .dxbl-text-edit .dxbl-btn:hover {
        background: rgba(255, 255, 255, 0.10) !important;
        color: var(--app-text-on-dark) !important;
    }


.dxbl-grid-command-cell .dxbl-grid-header-content > .dxbl-grid-select-all-split-btn-container .dxbl-btn-split > .dxbl-btn:not(.dxbl-btn-split-dropdown), .dxbl-grid-selection-cell .dxbl-grid-header-content > .dxbl-grid-select-all-split-btn-container .dxbl-btn-split > .dxbl-btn:not(.dxbl-btn-split-dropdown)
Specificity: (0,6,0) {
    margin-left: 25px;
}


/* ============================================================
   ORDER SUMMARY CARD (résumé commande) — OrderSummaryPanel.razor
   Carte en haut de la vue : montant total + alertes détectées.
   ============================================================ */
.osum {
    font-family: var(--app-font); font-size: 12px; color: var(--app-neutral-140);
    display: flex; gap: 10px; align-items: stretch;
}
.osum-block {
    background: var(--app-neutral-0);
    border: 1px solid var(--app-neutral-30);
    border-radius: var(--app-radius-md);
    box-shadow: var(--app-shadow-sm);
    padding: 8px 14px;
    display: flex; flex-direction: column; justify-content: center;
}
.osum-total { flex: 0 0 auto; border-left: 3px solid var(--app-primary-100); min-width: 190px; }
.osum-alerts { flex: 1 1 auto; }
.osum-label {
    font-size: 10px; text-transform: uppercase; letter-spacing: .04em;
    color: var(--app-neutral-90); font-weight: 700; margin-bottom: 3px;
}
.osum-amount { font-size: 19px; font-weight: 700; color: var(--app-dark-teal); line-height: 1.2; }
.osum-sub { font-size: 11px; color: var(--app-neutral-90); margin-top: 2px; }
.osum-ok, .osum-alert { display: flex; align-items: center; gap: 7px; font-size: 12px; padding: 2px 0; }
.osum-ok { color: var(--app-neutral-70); }
.osum-ok .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--app-neutral-40); }
.osum-alert.ko { color: var(--app-danger-110); font-weight: 600; }
.osum-alert.ko .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--app-danger-90); }
.osum-alert.info { color: var(--app-neutral-110); }
.osum-alert.info .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--app-primary-100); }

/* ============================================================
   ORDER LINE DETAIL PANEL (stock + remise) — OrderLineDetailPanel.razor
   Affiché sous la liste, au clic sur une ligne. Clair, en-têtes légers,
   couleurs de l'app (--app-*).
   ============================================================ */
.oldp { font-family: var(--app-font); font-size: 12px; color: var(--app-neutral-140); height: 100%; min-height: 240px; }
.oldp-empty { display: flex; align-items: center; justify-content: center; min-height: 220px; height: 100%; padding: 16px; text-align: center; color: var(--app-neutral-70); font-style: italic; }
.oldp-detail { display: grid; grid-template-columns: 1fr 1.2fr; gap: 10px; align-items: stretch; }
@media (max-width: 720px) { .oldp-detail { grid-template-columns: 1fr; } }

.oldp-panel {
    background: var(--app-neutral-0);
    border: 1px solid var(--app-neutral-30);
    border-radius: var(--app-radius-md);
    box-shadow: var(--app-shadow-sm);
    overflow: hidden;
}
.oldp-head {
    display: flex; align-items: center; gap: 8px;
    padding: 6px 10px;
    background: var(--app-neutral-10);
    border-bottom: 1px solid var(--app-neutral-30);
}
.oldp-title { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--app-primary-110); }
.oldp-ctx { margin-left: auto; color: var(--app-neutral-90); font-size: 11px; }
.oldp-body { padding: 8px 10px; }
.oldp-muted { color: var(--app-neutral-70); font-style: italic; }
.oldp-note { padding: 8px 10px; border-radius: var(--app-radius-sm); background: var(--app-card-bg); border: 1px solid var(--app-card-border); color: var(--app-neutral-110); font-size: 11px; line-height: 1.45; }
.oldp-note b { color: var(--app-primary-110); }

/* "Calculer date de tournée" button (form item under the desired delivery date) */
/* Masque le libellé auto de l'item (le nom technique "Calculate Round Button") : le bouton se
   suffit à lui-même. visibility:hidden (et non display:none) conserve la largeur de la colonne
   de libellé -> le bouton reste aligné avec les autres champs. Classe XAF stable par item. */
.dxbl-fl-cpt.xaf-item-calculateroundbutton { visibility: hidden; }

.crb-btn { display: inline-flex; align-items: center; gap: 7px; padding: 7px 14px; border-radius: var(--app-radius-sm); border: 1px solid var(--app-primary-90); background: var(--app-primary-90); color: #fff; font-size: 13px; font-weight: 600; cursor: pointer; transition: background .12s ease; }
.crb-btn:hover { background: var(--app-primary-110); border-color: var(--app-primary-110); }
.crb-btn:active { transform: translateY(1px); }
/* Désactivé (pas de commande / pas de client) : grisé, non cliquable. */
.crb-btn:disabled,
.crb-btn[disabled] { background: var(--app-neutral-40); border-color: var(--app-neutral-40); color: var(--app-neutral-70); cursor: not-allowed; transform: none; }
.crb-btn:disabled:hover,
.crb-btn[disabled]:hover { background: var(--app-neutral-40); border-color: var(--app-neutral-40); }
.crb-ico { font-size: 14px; line-height: 1; }

/* ── Carte « Date de tournée calculée » (résumé en ligne sous le bouton) ─────────────
   Remplace l'ancien popup modal. Habillage aux couleurs de l'app : fond BLANC, accents
   VERT (primary). 3 états portés par .crb-result--ok|warn|ko, qui ne changent QUE la
   couleur d'accent (--crb-accent) : ok = date respectée, warn = reportée (tous deux verts,
   différenciés par l'icône ✓ / ↪), ko = aucune tournée (rouge danger, vrai problème).
   Bordure et liseré de statut dérivent de l'accent via color-mix, donc tout reste cohérent.
   La carte occupe toute la largeur de la cellule éditeur (alignée sur les champs date). */
.crb { display: flex; flex-direction: column; align-items: stretch; gap: 10px; }
/* Le bouton garde sa largeur naturelle ; seule la carte s'étire sur toute la colonne. */
.crb > .crb-btn { align-self: flex-start; }

.crb-result {
    --crb-accent: var(--app-primary-100);
    display: flex;
    width: 100%;
    overflow: hidden;
    border: 1px solid color-mix(in srgb, var(--crb-accent) 28%, #fff);
    border-radius: var(--app-radius-md, 4px);
    background: #fff;
    box-shadow: var(--app-shadow-sm);
    animation: crb-result-in .22s cubic-bezier(.16, .84, .44, 1) both;
}

.crb-result--ok,
.crb-result--warn { --crb-accent: var(--app-primary-100); }
.crb-result--ko   { --crb-accent: var(--app-danger-90); }

.crb-result__bar { flex: 0 0 4px; background: var(--crb-accent); }

.crb-result__body { flex: 1 1 auto; min-width: 0; padding: 12px 14px; }

.crb-result__head { display: flex; align-items: center; gap: 9px; margin-bottom: 10px; }

.crb-result__badge {
    display: inline-flex; align-items: center; justify-content: center;
    width: 22px; height: 22px; flex: 0 0 22px;
    border-radius: 50%;
    background: var(--crb-accent); color: #fff;
    font-size: 13px; font-weight: 700; line-height: 1;
}

.crb-result__title { font-size: 13px; font-weight: 700; color: var(--app-neutral-130); }

/* Paires libellé / valeur, alignées en deux colonnes. */
.crb-result__grid {
    display: grid; grid-template-columns: auto 1fr; gap: 4px 14px;
    margin: 0 0 10px;
}
.crb-result__grid dt { font-size: 11px; font-weight: 600; color: var(--app-neutral-90); text-transform: uppercase; letter-spacing: .03em; align-self: center; }
.crb-result__grid dd { margin: 0; font-size: 13px; font-weight: 600; color: var(--app-neutral-130); }

/* Ligne de statut : liseré très léger teinté à l'accent, dernier élément (pas de marge basse). */
.crb-result__status {
    margin: 0;
    padding: 8px 10px;
    border-radius: var(--app-radius-sm);
    background: color-mix(in srgb, var(--crb-accent) 8%, #fff);
    border: 1px solid color-mix(in srgb, var(--crb-accent) 20%, #fff);
    color: color-mix(in srgb, var(--crb-accent) 88%, #000);
    font-size: 12px; font-weight: 600; line-height: 1.4;
}

@keyframes crb-result-in {
    from { opacity: 0; transform: translateY(-6px); }
    to   { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
    .crb-result { animation: none; }
}

/* Round "customers served" panel (one row per customer) — styled to look like a native Dx grid */
.rcp { font-size: 13px; }
.rcp-empty { color: var(--app-neutral-70); font-style: italic; padding: 10px 12px; border: 1px solid var(--app-neutral-40); border-radius: var(--app-radius-sm); background: var(--app-card-bg); }
.rcp-table { width: 100%; border-collapse: collapse; border: 1px solid var(--app-neutral-40); border-radius: var(--app-radius-sm); overflow: hidden; background: #fff; }
.rcp-table th { text-align: left; font-size: 12px; font-weight: 600; color: var(--app-neutral-110); background: var(--app-neutral-20); border-bottom: 1px solid var(--app-neutral-40); padding: 8px 12px; }
.rcp-table td { padding: 9px 12px; border-bottom: 1px solid var(--app-neutral-30); vertical-align: middle; }
.rcp-table tbody tr:last-child td { border-bottom: none; }
.rcp-table tbody tr:hover td { background: var(--app-neutral-10); }
.rcp-cust { font-weight: 600; color: var(--app-neutral-110); white-space: nowrap; }
.rcp-days { color: var(--app-neutral-90); }
.rcp-actions { text-align: right; width: 1%; }
.rcp-remove { border: none; background: transparent; color: var(--app-danger-90); cursor: pointer; font-size: 14px; line-height: 1; padding: 4px 8px; border-radius: var(--app-radius-sm); }
.rcp-remove:hover { background: var(--app-danger-10); }

/* Stock */
.oldp-kv { display: flex; justify-content: space-between; align-items: center; padding: 4px 0; border-bottom: 1px dashed var(--app-neutral-30); }
.oldp-kv .k { color: var(--app-neutral-90); }
.oldp-kv .v { font-weight: 600; font-variant-numeric: tabular-nums; }
.oldp-kv.oldp-total { margin-top: 2px; padding-top: 6px; border-top: 1px solid var(--app-neutral-40); border-bottom: none; }
.oldp-kv.oldp-total .k { font-weight: 700; color: var(--app-neutral-140); }
.oldp-kv.oldp-total .v { font-size: 14px; }
.oldp-kv .v.pos { color: var(--app-primary-110); }
.oldp-kv .v.neg { color: var(--app-danger-90); }
.oldp-badge { margin-top: 7px; padding: 6px 9px; border-radius: var(--app-radius-sm); font-size: 11px; font-weight: 600; }
.oldp-badge.ok { background: var(--app-card-bg); border: 1px solid var(--app-card-border); color: var(--app-primary-110); }
.oldp-badge.ko { background: var(--app-danger-10); border: 1px solid var(--app-danger-40); color: var(--app-danger-110); }

/* Remise */
.oldp-disc-total { display: flex; align-items: baseline; gap: 7px; padding-bottom: 6px; margin-bottom: 4px; border-bottom: 1px solid var(--app-neutral-40); }
.oldp-disc-total .rate { font-size: 18px; font-weight: 700; color: var(--app-primary-110); }
.oldp-disc-total .lbl { font-size: 11px; color: var(--app-neutral-90); }
.oldp-cat { border: 1px solid var(--app-neutral-30); border-radius: var(--app-radius-sm); padding: 6px 8px; margin-top: 6px; }
.oldp-cat-top { display: flex; align-items: center; gap: 7px; }
.oldp-cat-name { font-weight: 600; }
.oldp-cat-rate { margin-left: auto; font-weight: 700; color: var(--app-primary-110); }
.oldp-crit {
    font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em;
    padding: 1px 6px; border-radius: 9px;
    background: var(--app-primary-10); color: var(--app-primary-110); border: 1px solid var(--app-card-border);
}
.oldp-cat-meta { font-size: 11px; color: var(--app-neutral-90); margin-top: 4px; }
.oldp-cat-meta b { color: var(--app-neutral-110); }
.oldp-why { margin-top: 5px; padding-top: 5px; border-top: 1px dashed var(--app-neutral-30); font-size: 11px; color: var(--app-neutral-90); }
.oldp-why-title { font-weight: 600; color: var(--app-neutral-110); margin-right: 4px; }
.oldp-why ul { margin: 2px 0 0; padding-left: 15px; }
.oldp-why li { margin: 1px 0; color: var(--app-neutral-70); }

/* ============================================================
   END OF APPLICATION LIGHT THEME
   ============================================================
*/
