﻿html, body {
    height: 100%;
}

app {
    display: block;
    height: 100%;
}

div.header-logo {
    vertical-align: middle;
    /* Icône MERCALYS (cube), + le mot « MERCALYS » en texte dur à côté.
       Le SVG du cube est en preserveAspectRatio="none" (il s'étire) : on lui
       impose donc une taille au ratio natif (26.76 × 31.11) pour ne PAS le déformer.
       À 32px de haut -> largeur = 32 × 26.76/31.11 ≈ 27.5px. */
    background-image: url('../images/mercalys-mark.svg');
    background-size: 27.5px 32px;
    background-repeat: no-repeat;
    background-position: left center;
    width: 200px;
    height: 36px;
    position:relative;
}

div.header-logo::after {
    content: "MERCALYS";
    font-family: var(--app-font); /* même police que toute l'app (Manrope) */
    font-weight: bold;
    color: #8CC63F; /* vert du logo MERCALYS (cube) */
    font-size: 20px;
    position:absolute;
    left:36px; /* juste après le cube (~27.5px) + petit espace, pas d'espace vide */
    top:50%;
    transform: translateY(-50%);
}

/* Page de connexion : forcer la police de l'app (Manrope) sur tout le formulaire
   de login (titre « Log In », libellés, boutons…). Toute l'app étant en Manrope,
   c'est purement une harmonisation. */
.dxbl-card,
.dxbl-card * {
    font-family: var(--app-font) !important;
}

.header-logo-container {
    display: flex;
    align-items: center;
    gap: 10px;
}

.header-logo-container img.header-logo {
    height: 29px;
    width: auto;
    object-fit: contain;
}

.header-logo-text {
    font-weight: bold;
    color: #000;
    font-size: 20px;
}

#blazor-error-ui {
    background: inherit;
    bottom: 0;
    display: none;
    position: fixed;
    width: 100%;
    height: 100%;
    z-index: 100001;
}
.detail-view-content .xaf-component-image {
    max-width: 300px;
    max-height: 200px;
}
.detail-view-content .xaf-component-image img {
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
    object-fit: contain;
}

.sidebar {
    min-width: 210px !important;
}
.xaf-tree-view{
    padding : 10px !important;
}

/* Style pour afficher les messages multilignes dans les notifications XAF */
.xaf-multiline-message {
    white-space: pre-line;
}

/* Force nested grids in the Notification Preferences tab to fill available height */
.notification-preferences-tab .dxbl-scroll-viewer-content {
    min-height: calc(60vh - 150px);
}

/* Hide only the checkbox content inside the cell, preserve the cell's border */
.hidden-checkbox * {
    visibility: hidden;
}

/* Badge des règles de style conditionnelles (ex. « Promo »).
   Le texte est porté par l'attribut data-style-badge posé par ConditionalStyleController.
   Les couleurs proviennent des variables --style-badge-bg / --style-badge-fg posées sur la
   cellule (couleurs choisies dans la règle) ; à défaut, repli sur le vert par défaut. */
.style-rule-badge::after {
    content: attr(data-style-badge);
    display: inline-block;
    margin-left: 6px;
    padding: 0 6px;
    border-radius: 8px;
    font-size: 0.75em;
    font-weight: 600;
    line-height: 1.4;
    background-color: var(--style-badge-bg, #1e8e3e);
    color: var(--style-badge-fg, #fff);
    vertical-align: middle;
}

/* Force dashboard split view items to align to top, removing unwanted vertical spacing */
.dxbl-fl .dxbl-fl-item .dxbl-fl-ctrl-nc, .dxbl-fl .dxbl-fl-item .dxbl-fl-empty-caption + .dxbl-fl-ctrl {
    margin-top: 0;
}

/* Allow manual vertical resize on auto-resizing memo editors */
.dxbl-auto-resize {
    resize: vertical !important;
}

/* ===== Dashboard Splitter Handles ===== */

/* Resizable groups need overflow visible and proper flex behavior */
.dashboard-resizable-group {
    overflow: visible !important;
}

.dashboard-resizable-item {
    overflow: auto;
    min-height: 50px;
    min-width: 50px;
}

/* Horizontal groups: override dxbl-col-md-* columns so the splitter handle
   has room. Without this, col-md-6 + col-md-6 = 100%, leaving 0px for the handle. */
.dashboard-resizable-horizontal > .dxbl-row {
    flex-wrap: nowrap !important;
}

.dashboard-resizable-horizontal > .dxbl-row > [class*="dxbl-col"] {
    flex: 1 1 0% !important;
    max-width: none !important;
    min-width: 50px;
}

/* Vertical splitter handle (horizontal bar between top/bottom panels).
   In a flex-direction:row wrapping layout, flex:0 0 100% forces a new row. */
.dashboard-splitter-handle.dashboard-splitter-vertical {
    flex: 0 0 100%;
    height: 6px;
    cursor: row-resize;
    background-color: transparent;
    position: relative;
    z-index: 10;
    transition: background-color 0.15s ease;
}

.dashboard-splitter-handle.dashboard-splitter-vertical::after {
    content: '';
    position: absolute;
    left: 25%;
    right: 25%;
    top: 50%;
    transform: translateY(-50%);
    height: 2px;
    background-color: #ccc;
    border-radius: 1px;
    transition: background-color 0.15s ease;
}

.dashboard-splitter-handle.dashboard-splitter-vertical:hover,
.dashboard-splitter-handle.dashboard-splitter-vertical.dashboard-splitter-active {
    background-color: rgba(0, 0, 0, 0.04);
}

.dashboard-splitter-handle.dashboard-splitter-vertical:hover::after,
.dashboard-splitter-handle.dashboard-splitter-vertical.dashboard-splitter-active::after {
    background-color: #1976d2;
    height: 3px;
}

/* Horizontal splitter handle (vertical bar between left/right panels) */
.dashboard-splitter-handle.dashboard-splitter-horizontal {
    flex: 0 0 6px;
    cursor: col-resize;
    background-color: transparent;
    position: relative;
    z-index: 10;
    align-self: stretch;
    transition: background-color 0.15s ease;
}

.dashboard-splitter-handle.dashboard-splitter-horizontal::after {
    content: '';
    position: absolute;
    top: 25%;
    bottom: 25%;
    left: 50%;
    transform: translateX(-50%);
    width: 2px;
    background-color: #ccc;
    border-radius: 1px;
    transition: background-color 0.15s ease;
}

.dashboard-splitter-handle.dashboard-splitter-horizontal:hover,
.dashboard-splitter-handle.dashboard-splitter-horizontal.dashboard-splitter-active {
    background-color: rgba(0, 0, 0, 0.04);
}

.dashboard-splitter-handle.dashboard-splitter-horizontal:hover::after,
.dashboard-splitter-handle.dashboard-splitter-horizontal.dashboard-splitter-active::after {
    background-color: #1976d2;
    width: 3px;
}

/* Carte « planning prévu » de la commande — rendue par DeliveryRecapPanelPropertyEditor.
   Ce n'est pas un champ : c'est le résumé de ce que le calcul a retenu (départ, livraison,
   tournée, et le motif quand une date a été reportée). Petites cellules libellé/valeur sur
   deux lignes, dans les tons de l'application. */
.drecap {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding: 2px 0;
}

.drecap-cell {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 132px;
    padding: 6px 10px;
    background: #f5f8fc;
    border: 1px solid #e3eaf3;
    border-radius: 4px;
    line-height: 1.25;
}

.drecap-key {
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: #7a8899;
}

.drecap-val {
    font-size: 0.82rem;
    font-weight: 600;
    color: #2b3d4f;
    white-space: nowrap;
}

/* Motif de report, échec de planification, forçage manuel : une note, pas une donnée.
   Accent ambre pour attirer l'œil sans crier. */
.drecap-cell.note {
    justify-content: center;
    background: #fff8e8;
    border-color: #f3e0b5;
}

.drecap-cell.note .drecap-val {
    font-weight: 500;
    color: #7a5a12;
    white-space: normal;
}

/* Hide clear (✕) button on lookup/select editors */
/*.dxbl-edit-btn-clear {
    display: none !important;
}*/

/* Neutralize the default blue focused-row highlight on grids where FocusedRowEnabled is
   used only for arrow-key tracking of the F4 shortcut target (sales/purchase order lines,
   price list items). The highlight reads like a selection and diverges from the rest of
   the app, where rows don't visually change on keyboard navigation. The class is applied
   per data row via CustomizeElement in the F4 shortcut controllers.
   Background is reset on the row; `color` is reset only on non-selection cells. The
   selection cell is excluded because its checkbox renders the check icon via currentColor —
   touching `color` there makes the check disappear.

   ⚠️ La ligne est repeinte à la couleur des lignes normales, PAS en `transparent`. La version
   précédente posait `transparent` : visuellement identique — le fond de la grille se voit à
   travers — mais elle laissait la ligne focalisée sans fond opaque. Or DevExpress donne aux
   cellules figées `background-color: inherit` (cf. CONTRAT DE PEINTURE DES LIGNES dans
   app-theme.css) : sur cette ligne, une colonne gelée héritait donc de rgba(0,0,0,0) et
   laissait défiler le contenu à travers. C'est la cause mesurée le 2026-09-10 sur la
   mercuriale, qui est l'une des trois vues à FocusedRowEnabled.
   --dxbl-grid-row-bg est la variable dont DevExpress peint lui-même les lignes : la ligne
   focalisée prend exactement la teinte de ses voisines, quel que soit le thème.

   ⚠️ :not(.dxbl-grid-selected-row) — cette règle neutralise le repère de FOCUS, pas celui de
   SÉLECTION. Sans l'exclusion elle écrasait aussi l'aplat vert d'une ligne cochée dès que
   celle-ci portait le focus, ce qui est le cas normal après un clic : sur ces trois vues, la
   sélection ne se voyait donc pas. Mesuré le 2026-09-10 sur la mercuriale (fond rendu
   rgba(0,0,0,0) au lieu de --dxbl-grid-selection-bg). */
.f4-shortcut-no-focus-highlight.dxbl-grid-focused-row:not(.pim-line-stock-issue):not(.pim-line-partial-shortage):not(.dxbl-grid-selected-row) {
    background-color: var(--dxbl-grid-row-bg) !important;
}
/* Les cellules qui portent leur propre signalement sont EXCLUES : la neutralisation du focus est
   plus specifique que .pim-coef-below-min et l'emporte, donc la ligne focalisee -- la premiere de
   la grille par defaut, XAF y posant CurrentObject -- perdait son alerte de marge. Meme exclusion
   que pour la mise en avant de ligne plus bas.
   La rupture de stock, elle, s'exclut au niveau de la LIGNE (:not(.pim-line-stock-issue) ci-dessus
   et ici) : c'est la ligne entiere qui porte l'alerte, pas une cellule. */
.f4-shortcut-no-focus-highlight.dxbl-grid-focused-row:not(.pim-line-stock-issue):not(.pim-line-partial-shortage):not(.dxbl-grid-selected-row) > td:not(.dxbl-grid-selection-cell):not(.pim-coef-below-min):not(.pim-general-tariff-cell) {
    color: #212529 !important;
}
/* Selection cell defaults to `background: inherit`, so it picked up the transparent we set
   on the row. The check icon stays painted in white (DX focused state) — restoring the
   blue background here keeps the check visible.

   ⚠️ :not(.dxbl-grid-selected-row) — la rustine ne vaut que pour la case VIDE d'une ligne
   focalisée non cochée : c'est elle qui se dessine en blanc et a besoin d'un fond soutenu.
   Une case COCHÉE porte son propre aplat teal opaque (--dxbl-checkbox-*-checked, mesuré
   rgb(1,137,115) le 2026-09-10) et n'a besoin de rien ; le fond bleu ne faisait qu'y trouer
   l'aplat de sélection de la ligne. Sans l'exclusion, la cellule de sélection restait bleue
   au milieu d'une ligne verte — et, une fois la colonne de sélection figée, c'est ce bleu qui
   serait resté ancré à gauche. */
    .f4-shortcut-no-focus-highlight.dxbl-grid-focused-row:not(.dxbl-grid-selected-row) > td.dxbl-grid-selection-cell {
        background-color: var(--dxbl-grid-row-focused-bg-color, var(--dxbl-primary, #E7EFF9)) !important;
    }

/* ── Document-flow breadcrumb (PieceChainFlow editor) ───────────────────────────
   A clickable stepper of the chain Devis → Commande → BL → Facture, at the top of the
   piece detail. Type is the primary label (the lifecycle stage); number + status are secondary. */
.pcf {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    padding: 4px 2px 14px;
}
.pcf-label {
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .8px;
    text-transform: uppercase;
    color: #8a9a90;
}
/* État vide du flux : le bandeau reste en place et s'explique, au lieu de disparaître. Volontairement
   discret — c'est une note, pas une étape : ni cadre, ni puce, ni couleur d'alerte. */
.pcf-empty {
    font-size: 12px;
    font-style: italic;
    color: #8a9a90;
}
.pcf-track {
    display: flex;
    /* flex-start, not stretch: the delivery-note cell is taller than the others because it carries
       the credit branch, and stretching would drag every other step down with it. */
    align-items: flex-start;
    flex-wrap: wrap;
    gap: 4px;
    margin: 0;
    padding: 0;
    list-style: none;
    min-width: 0;
}
.pcf-item {
    display: flex;
    align-items: center;
    gap: 4px;
}
.pcf-step {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 2px;
    padding: 7px 14px;
    min-width: 92px;
    border: 1px solid #e0e8e1;
    border-radius: 10px;
    background: #fff;
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: border-color .12s ease, transform .12s ease, box-shadow .12s ease;
}
.pcf-step:hover {
    border-color: var(--dxbl-primary, #2f7d4f);
    transform: translateY(-1px);
    box-shadow: 0 3px 10px rgba(47, 125, 79, .16);
}
.pcf-step:focus-visible {
    outline: 2px solid var(--dxbl-primary, #2f7d4f);
    outline-offset: 2px;
}
.pcf-type {
    font-size: 12.5px;
    font-weight: 600;
    color: #1b2a24;
    line-height: 1.25;
}
.pcf-meta {
    font-size: 10.5px;
    color: #7f9086;
    font-variant-numeric: tabular-nums;
    line-height: 1.2;
}
/* current stage: filled, emphasised, not clickable */
.pcf-step--current {
    background: var(--dxbl-primary, #2f7d4f);
    border-color: var(--dxbl-primary, #2f7d4f);
    cursor: default;
    box-shadow: 0 4px 12px rgba(47, 125, 79, .26);
}
.pcf-step--current .pcf-type { color: #fff; }
.pcf-step--current .pcf-meta { color: #d3ecda; }
/* connector between stages */
.pcf-sep {
    width: 20px;
    height: 2px;
    border-radius: 2px;
    background: #cdd9d0;
    flex: none;
}
/* wrapper so the expandable group panel sits below the stepper track */
.pcf-wrap {
    display: flex;
    flex-direction: column;
}
/* single downstream child of the current piece: dashed to read as "produced by this document" */
.pcf-step--child {
    border-style: dashed;
}
.pcf-step--child:hover {
    border-style: solid;
}
/* aggregated stage node ("N Commandes"): a distinct, dashed accent so it reads as a group toggle */
.pcf-step--group {
    border-style: dashed;
    border-color: #a9d3ba;
}
.pcf-step--group .pcf-type {
    display: flex;
    align-items: center;
    gap: 5px;
    color: var(--dxbl-primary, #2f7d4f);
}
.pcf-step--group:hover {
    border-color: var(--dxbl-primary, #2f7d4f);
    box-shadow: 0 3px 10px rgba(47, 125, 79, .16);
}
/* the group toggle stays coloured even when it is the current stage */
.pcf-step--group.pcf-step--current {
    background: #eef6f0;
    border-color: var(--dxbl-primary, #2f7d4f);
    box-shadow: 0 4px 12px rgba(47, 125, 79, .22);
}
.pcf-step--group.pcf-step--current .pcf-type { color: #26663f; }
.pcf-step--group.pcf-step--current .pcf-meta { color: #4f8a68; }
/* disclosure caret, rotates when the group is open */
.pcf-caret {
    width: 0;
    height: 0;
    border-left: 4px solid transparent;
    border-right: 4px solid transparent;
    border-top: 5px solid currentColor;
    transition: transform .15s ease;
}
.pcf-step--open .pcf-caret {
    transform: rotate(180deg);
}
/* expanded list of the group's documents */
.pcf-panel {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin: 2px 0 10px;
    padding: 8px;
    border-radius: 12px;
    background: #eef6f0;
    border-left: 3px solid var(--dxbl-primary, #2f7d4f);
}
.pcf-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 12px;
    border: 1px solid transparent;
    border-radius: 8px;
    background: transparent;
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: background .12s ease, border-color .12s ease;
}
.pcf-row:hover {
    background: #fff;
    border-color: #bfe0cc;
}
.pcf-row--current {
    background: #fff;
    border-color: #a9d3ba;
}
.pcf-row-num {
    font-size: 13px;
    font-weight: 700;
    color: #1b2a24;
    font-variant-numeric: tabular-nums;
}
.pcf-row-info {
    font-size: 12px;
    color: #7f9086;
    font-variant-numeric: tabular-nums;
    flex: 1 1 auto;
}
/* status pill (right of each row) */
.pcf-pill {
    flex: none;
    padding: 2px 10px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    line-height: 1.5;
    white-space: nowrap;
}
.pcf-pill--done { background: #e6f4ea; color: #1e7a3d; }
.pcf-pill--inprogress { background: #fdf3e2; color: #a86a12; }
.pcf-pill--active { background: #e7f0fd; color: #1f5fb0; }
.pcf-pill--expired { background: #f0eef2; color: #7a6d84; }
.pcf-pill--neutral { background: #eef1f0; color: #63736b; }
/* Each stage of the flow is a CELL. The cell of the delivery note also carries the credit branch
   underneath it, so the fork points at the document the avoir answers instead of at the left edge
   of the row (where it read as if it descended from the Devis). */
.pcf-cell {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
}
.pcf-cell--forked {
    padding-left: 18px;   /* room for the fork elbow, which is pulled back into it */
}
.pcf-track--branch {
    margin-top: 2px;
}
.pcf-fork {
    flex: none;
    align-self: center;
    width: 12px;
    height: 12px;
    margin: 0 7px 9px -18px;
    border-left: 2px solid #cdd9d0;
    border-bottom: 2px solid #cdd9d0;
    border-bottom-left-radius: 5px;
}
/* chevron (›) separator between lifecycle stages */
.pcf-chevron {
    flex: none;
    align-self: flex-start;
    margin-top: 22px;     /* centred on the FIRST row of steps, not on the tallest cell */
    width: 7px;
    height: 7px;
    border-top: 2px solid #cdd9d0;
    border-right: 2px solid #cdd9d0;
    transform: rotate(45deg);
    margin: 0 6px;
}
/* removable filter chip shown when the flow is focused on a single order line */
.pcf-chip {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-left: 10px;
    padding: 5px 6px 5px 12px;
    border: 1px solid #a9d3ba;
    border-radius: 999px;
    background: #eef6f0;
    color: #26663f;
    font: inherit;
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
    transition: border-color .12s ease, background .12s ease;
}
.pcf-chip:hover {
    border-color: var(--dxbl-primary, #2f7d4f);
    background: #e3f0e8;
}
.pcf-chip-label {
    white-space: nowrap;
    max-width: 220px;
    overflow: hidden;
    text-overflow: ellipsis;
}
.pcf-chip-x {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    border-radius: 999px;
    background: #cfe6d8;
    color: #26663f;
    font-size: 10px;
    line-height: 1;
}
.pcf-chip:hover .pcf-chip-x {
    background: var(--dxbl-primary, #2f7d4f);
    color: #fff;
}

/* Marge sous le seuil : coefficient inférieur au coef mini de sa catégorie de tarif.
   La classe est posée par PriceListItemDynamicPricesColumnController sur la seule cellule
   concernée — coefficient et prix de la colonne fautive — pour que l'opérateur voie QUEL
   tarif pose problème, et pas seulement que la ligne en a un.
   Alerte, jamais blocage : la saisie et l'enregistrement restent possibles. */
.pim-coef-below-min {
    background-color: var(--pim-coef-alert-bg, #ede4f7) !important;
    color: var(--pim-coef-alert-fg, #5b3f96) !important;
    font-weight: 600;
}

/* Ligne en tarif général : les colonnes de calcul (coefficient et prix) restent visibles et à leur
   place — les masquer casserait l'alignement du tableau sur quatre cents lignes — mais grisées,
   pour dire qu'elles ne se saisissent pas ici. Le prix affiché reste le prix réel. */
.pim-general-tariff-cell {
    background-color: var(--pim-general-tariff-bg, #f2f2f2) !important;
    color: var(--pim-general-tariff-fg, #6b6b6b) !important;
}

/* Mise en avant de la ligne de mercuriale — classe posée sur la ligne par
   PriceListItemHighlightStyleController d'après PriceListItem.Highlight.
   Deux niveaux, ceux de la liste déroulante historique : GRAS et BON COUP.

   Le fond s'arrête aux cellules qui n'ont pas déjà leur propre alerte : sans le :not(),
   la mise en avant recouvrirait le signalement de marge insuffisante, qui est l'information
   la plus importante des deux. L'exclusion évite d'en faire dépendre l'ordre des règles. */
.pim-highlight-bold td:not(.pim-coef-below-min),
.pim-highlight-good-deal td:not(.pim-coef-below-min) {
    font-weight: 700 !important;
}

/* Le FOND se pose sur la ligne, la COULEUR DE TEXTE sur les cellules — cf. CONTRAT DE PEINTURE
   DES LIGNES dans app-theme.css. C'est toute la ligne qui est mise en avant, donc le fond lui
   revient ; le posait-on sur les td qu'une colonne gelée resterait transparente dessus.
   Le :not(.pim-coef-below-min) n'a plus à porter le fond : la cellule d'alerte de marge pose
   le sien en !important et repeint par-dessus celui de la ligne. Il reste sur `color`, où il
   sert toujours (le violet de l'alerte doit survivre au vert de la mise en avant). */
.pim-highlight-good-deal {
    background-color: var(--pim-good-deal-bg, #e3f4ea) !important;
}

.pim-highlight-good-deal td:not(.pim-coef-below-min) {
    color: var(--pim-good-deal-fg, #1e6b40) !important;
}

/* Ligne de pièce en rupture théorique de stock — classe posée sur la ligne par
   PieceLineStockIssueRowStyleController d'après BasePieceLine.HasStockIssue.

   Reprend à l'identique les teintes de l'ancienne ConditionalAppearance « OrderLineStockIssue »
   (MistyRose sur Firebrick), qui les appliquait cellule par cellule : 16 colonnes × N lignes de
   critères réévalués à chaque frappe dans la grille. Le rendu est le même, le coût non.

   La cellule de sélection est exclue : sa case à cocher dessine son icône avec currentColor,
   toucher `color` là la fait disparaître (même raison que pour la ligne focalisée plus haut).

   Le FOND se pose sur la ligne, la COULEUR DE TEXTE sur les cellules — cf. CONTRAT DE PEINTURE
   DES LIGNES dans app-theme.css. L'exclusion de la cellule de sélection ne concernait QUE
   `color` ; en la laissant porter aussi le fond, la colonne gelée d'une ligne en alerte serait
   restée transparente. Effet visible : la cellule de sélection prend désormais le rose de
   l'alerte au lieu de rester blanche — c'est la ligne entière qui alerte — et sa coche reste
   lisible, sa couleur de texte n'ayant pas bougé. */
/* Préparation partielle (PIM-352) : la ligne de vente dont la quantité à préparer est en dessous
   du commandé. Une réduction VOULUE, pas un déficit : orange, pas rouge, même contrat de peinture
   (fond sur la ligne, texte sur les cellules) et même exclusion de la cellule de sélection.
   Déclaré AVANT le déficit de stock : une ligne qui cumule les deux porte les deux classes, et à
   spécificité égale c'est la dernière déclaration qui peint — le rouge gagne. */
.pim-line-partial-shortage {
    background-color: var(--pim-partial-shortage-bg, #fff3e0) !important;
}

.pim-line-partial-shortage > td:not(.dxbl-grid-selection-cell) {
    color: var(--pim-partial-shortage-fg, #b35a00) !important;
}

.pim-line-stock-issue {
    background-color: var(--pim-stock-issue-bg, #ffe4e1) !important;
}

.pim-line-stock-issue > td:not(.dxbl-grid-selection-cell) {
    color: var(--pim-stock-issue-fg, #b22222) !important;
}

/* ── Dernier enregistrement de la mercuriale (PIM-329) ─────────────────────────────────────────
   Une pastille, pas une ligne de texte nue. Posée entre la barre d'actions de la fiche et celle de
   la grille, une phrase grise sans contour flottait sans appartenir à aucune des deux : un fond
   léger et un filet discret lui donnent un bord, donc une place.

   Trois niveaux de lecture dans un seul objet : l'icône et le préfixe s'effacent, l'AUTEUR ressort
   en gras et en foncé, la date revient en gris. L'œil trouve « qui » avant « quand », ce qui est
   l'ordre dans lequel la question se pose.

   Teintes dérivées du vert de l'application (--dxbl-primary) plutôt qu'un gris neutre : la pastille
   appartient visiblement à cet écran-là. */
/* PLACEMENT : sur la ligne de la barre d'outils de la grille, calee a droite.

   Mesure faite sur l'ecran reel : la barre d'ACTIONS du haut (Supprimer, Envoyer la mercuriale...)
   n'offre que 196 px libres entre son groupe de gauche et celui de droite, pour une pastille de
   320 px -- s'y poser chevaucherait des boutons. La barre d'outils de la grille, juste en dessous,
   en laisse 551 : c'est la qu'elle tient, sans rien recouvrir.

   La pastille sort du flux pour ne plus couter sa propre ligne : le conteneur de l'element de
   disposition est ramene a une hauteur nulle, et la grille remonte d'autant.

   :has() plutot qu'une classe posee sur le conteneur : celui-ci est genere par XAF, on ne peut pas
   lui en ajouter une. Le selecteur ne mord que sur les ecrans qui portent la pastille. */
.detail-view-content:has(.pim-lastsaved) {
    position: relative;
}

.dxbl-fl-ctrl:has(> .pim-lastsaved) {
    height: 0;
    overflow: visible;
}

.dxbl-fl-item:has(.pim-lastsaved) {
    margin-top: 0 !important;
    margin-bottom: 0 !important;
}

.pim-lastsaved {
    position: absolute;
    /* Centre la pastille (23 px) sur la barre d'outils de la grille (34 px). */
    top: 6px;
    right: 0;
    z-index: 3;
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    padding: .2rem .6rem .2rem .5rem;
    border: 1px solid var(--pim-lastsaved-border, #d8e6dd);
    border-radius: 999px;
    background: var(--pim-lastsaved-bg, #f4f9f6);
    font-size: .78rem;
    line-height: 1.45;
    color: var(--pim-lastsaved-fg, #6b7c73);
    /* La pastille se dimensionne sur son contenu ; l'élément de disposition XAF qui la porte occupe
       toute la largeur, d'où l'alignement explicite à gauche. */
    max-width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.pim-lastsaved__icon {
    width: .85rem;
    height: .85rem;
    flex: 0 0 auto;
    /* currentColor : l'icône suit la couleur du texte, y compris si les teintes changent. */
    color: var(--pim-lastsaved-icon, #8aa89a);
}

.pim-lastsaved__user {
    font-weight: 600;
    color: var(--pim-lastsaved-user, #2f4f3f);
}

.pim-lastsaved__prefix,
.pim-lastsaved__when {
    font-weight: 400;
}

/* Les espaces entre les trois morceaux viennent d'ici et non du balisage : Razor supprime les blancs
   entre deux balises, et « par Admin le » se lisait « parAdminle ». */
.pim-lastsaved__user,
.pim-lastsaved__when {
    margin-left: .3em;
}

/* Fenetre etroite : les deux groupes de boutons de la barre d'outils se rapprochent et finiraient
   par passer sous la pastille. En dessous du seuil, elle retourne dans le flux et reprend sa ligne
   -- une ligne de plus vaut mieux qu'un chevauchement. Seuil pose a partir des 231 px de marge
   mesures sur une fenetre de 1326 px. */
@media (max-width: 1200px) {
    .pim-lastsaved {
        position: static;
    }

    .dxbl-fl-ctrl:has(> .pim-lastsaved) {
        height: auto;
    }
}

/* ============================================================
   EN-TÊTE DE DIFFUSION DE LA MERCURIALE (.pim-diffusion-header)

   Trois valeurs en LECTURE SEULE — état de l'envoi, date d'envoi, nombre de
   destinataires. Elles répondent à une question, elles ne se saisissent pas.

   Le thème applicatif rend tout champ désactivé de vue détail sur un fond gris
   #f0f0f0 (voir app-theme.css, section 1) : c'est le bon choix PARTOUT AILLEURS,
   où le gris signale « ce champ existe mais tu ne peux pas y toucher ». Ici il
   n'y a rien à toucher du tout, et trois boîtes grises vides — dont un chevron
   de liste déroulante et un bouton calendrier qui n'ouvrent rien — donnent
   l'impression d'un formulaire cassé plutôt que d'un bandeau d'information.

   On neutralise donc le décor de saisie DANS CE SEUL GROUPE, et on laisse le
   texte : le teal gras vient de la règle globale, on le garde.
   Scope obligatoire : sans lui, on toucherait tous les champs désactivés de
   l'application. site.css est chargé APRÈS app-theme.css, d'où les !important
   qui suffisent à battre les règles globales sans monter la spécificité.
   ============================================================ */

/* 1 · Le conteneur de l'éditeur perd fond, bordure et ombre. */
.pim-diffusion-header .dxbl-fl-item dxbl-input-editor.dxbl-text-edit,
.pim-diffusion-header .dxbl-fl-item dxbl-input-editor.dxbl-text-edit.dxbl-disabled,
.pim-diffusion-header .dxbl-fl-item .dxbl-text-edit,
.pim-diffusion-header .dxbl-fl-item .dxbl-text-edit.dxbl-disabled {
    background-color: transparent !important;
    border-color: transparent !important;
    box-shadow: none !important;
    min-height: 0 !important;
}

/* 2 · L'input lui-même : plus de fond, plus de retrait à gauche. La valeur doit
       s'aligner sur son libellé, pas flotter au milieu d'une boîte. */
.pim-diffusion-header .dxbl-fl-item .dxbl-text-edit input.dxbl-text-edit-input,
.pim-diffusion-header .dxbl-fl-item .dxbl-text-edit .dxbl-text-edit-static-text,
.pim-diffusion-header .dxbl-fl-item .dxbl-text-edit input.dxbl-text-edit-input:disabled {
    background-color: transparent !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
    height: auto !important;
}

/* 3 · Les boutons de fin de champ — chevron de liste, icône calendrier — n'ouvrent
       rien sur un champ en lecture seule. Ils promettent une action qui n'existe pas. */
.pim-diffusion-header .dxbl-text-edit-btn,
.pim-diffusion-header .dxbl-edit-btn-dropdown {
    display: none !important;
}

/* 4 · Le libellé passe au second plan : c'est la valeur qui porte l'information.
       Casse haute et interlettrage pour qu'il se lise comme une étiquette. */
.pim-diffusion-header .dxbl-fl-item > label,
.pim-diffusion-header .dxbl-fl-cpt {
    font-size: .72rem !important;
    letter-spacing: .04em !important;
    text-transform: uppercase !important;
    font-weight: 500 !important;
    color: #8fa3a6 !important;
}

/* 5 · Le bandeau se resserre : sans boîtes de saisie, la hauteur d'un formulaire
       n'a plus lieu d'être. */
.pim-diffusion-header .dxbl-fl-item {
    margin-top: 0 !important;
    margin-bottom: 0 !important;
}
