/* ==========================================================================================
   LES ÉCRANS DE CONNECTEUR — LA PILE D'ÉTAPES (.cnx-*)

   SIX ÉCRANS LA PARTAGENT : Odoo, Sage 100, SAP Business One, Dynamics, Sage X3 et
   S/4HANA. La règle du dépôt dit qu'une classe servie par deux écrans monte dans le
   gabarit ; sa RAISON est qu'un écran ne doit jamais dépendre de la feuille d'un AUTRE
   écran pour s'afficher. Ici, les six dépendent d'une feuille COMMUNE qui ne décrit
   qu'eux — c'est une feuille de famille, pas la feuille d'un écran empruntée par un
   voisin, et aucun ne tombe si les autres disparaissent.

   Le jour où un écran NON-connecteur en aurait besoin, la question changerait de nature
   et ces classes monteraient dans modele-erp.css §11.

   L'écran présentait deux colonnes de cartes de même poids : connexion et critères à gauche,
   sources et rapport à droite. Rien ne disait par où commencer, alors que ces gestes ne sont
   pas parallèles — on ne choisit pas ce qu'on reprend avant de savoir si la connexion répond.
   Les cartes ont d'abord été EMPILÉES et numérotées, toutes visibles.

   ELLES SONT MAINTENANT UNE ÉTAPE À LA FOIS, et le numéro est devenu une permission. Ce qui
   a tranché n'est pas le goût du parcours guidé : c'est que les OPTIONS venaient avant le
   choix de la source, si bien que l'écran montrait deux champs de dates à qui reprenait un
   référentiel — où une date n'a aucun sens. Choisir d'abord, régler ensuite, c'est ne
   montrer que ce qui a un effet.

   LE RETOUR EN ARRIÈRE RESTE GRATUIT sur toute étape franchie, et l'étape finale propose
   « tranche suivante » et « source suivante » : la crainte d'origine — un opérateur qui
   refait sa cinquième tranche et rejoue trois écrans — est traitée là, et non en laissant
   tout ouvert. Le fil d'étapes lui-même est un composant partagé (.mx-etapes, gabarit §11).

   UN FICHIER POUR LA FAMILLE, RÈGLE DU DÉPÔT : ces classes servent DEUX écrans qui sont le
   même écran à la source près. À la queue de modele-erp.css, la dernière ligne et la clé de
   cache seraient devenues un point de collision pour toute branche ajoutant un écran.

   AUCUNE COULEUR EN DUR : tout passe par les jetons --et-*.
   ========================================================================================== */

.cnx-etapes {
    display: flex;
    flex-direction: column;
    gap: 14px;
    max-width: 1100px;
}

/* L'ÉTAPE VISIBLE EST L'ÉTAPE COURANTE, et elle le dit.

   Une seule carte est rendue à la fois (`@if (Etat.Pas == n)` dans chaque écran) : le
   filet bleu de tête n'a donc besoin d'aucune classe d'état côté Razor, il suffit qu'il
   soit sur .cnx-etape. Deux pixels remplacent le filet gris du gabarit — assez pour que
   l'œil sache où il est en arrivant sur l'écran, trop peu pour peser sur la page.

   EN THÈME SOMBRE, CE BLEU-LÀ NE TIENT PAS. --et-form-blue (#0057B8) est délibérément
   hors du bloc sombre — le fichier de jetons le dit ligne 154 — et sur la surface sombre
   (#111A2B) il tombe à 2,5:1 : le filet existe et ne se voit pas. Le thème prévoit le
   remplaçant et le nomme au même endroit (ligne ~893) : --et-form-blue-l, qui rend 7,0:1
   sur cette même surface. C'est le geste que fait déjà --et-lien.

   La bascule passe par .appgrid[data-theme="dark"], pas par prefers-color-scheme : dans
   cette application le thème sombre est porté par l'attribut de la coquille, et AUCUN
   jeton --et-* ne bascule sur la préférence système. Une règle média ici ne s'appliquerait
   donc jamais en même temps que les jetons qu'elle prétend accompagner. */
.cnx-etape { border-top: 2px solid var(--et-form-blue); }

.appgrid[data-theme="dark"] .cnx-etape { border-top-color: var(--et-form-blue-l); }

/* La pastille du rang. Ronde et non carrée : c'est le seul endroit de l'écran où l'angle
   droit de la charte cède, parce qu'un numéro dans un carré se lit comme un bouton. */
.cnx-num {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--et-form-blue);
    color: var(--et-sur-aplat);
    font-size: 12px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

/* Il n'y a plus de « à part » : les images des fiches article étaient la seule étape hors
   chaîne, avec sa pastille de texte et sa bordure pointillée. Elles sont devenues une SOURCE
   comme les autres, à leur rang, juste après les articles qu'elles illustrent — vues de
   l'opérateur, c'est bien une donnée d'article à reprendre, et la ranger ailleurs faisait
   qu'on l'oubliait. Ce qu'elles ont de particulier est dit là où ça se voit, dans le
   parcours : leur aperçu EST leur simulation, et leur écriture a une barre d'avancement. */

/* La note de tête dit CE QUE L'ÉTAPE ENGAGE, en un souffle : « la clé n'est jamais
   enregistrée », « les référentiels avant les pièces ». Repoussée à droite, elle se lit
   sans gêner le titre. */
.cnx-tete-note {
    margin-left: auto;
    font-size: 12px;
    color: var(--et-muted);
    text-align: right;
}

/* ------------------------------------------------------------------------------------------
   LE PIED D'ÉTAPE (.cnx-pied) — retour à gauche, engagement à droite, la raison entre les deux.

   UN SEUL BOUTON D'ENGAGEMENT PAR ÉCRAN, comme le veut la charte : c'est celui de droite, et
   il est le seul en orange. Le retour est un bouton ordinaire — le proposer aussi fort que
   l'avancée ferait hésiter là où il n'y a pas à hésiter.

   LA NOTE DU MILIEU dit ce que le bouton va faire, ou ce qui manque pour qu'il le fasse.
   Elle occupe l'espace libre, donc elle ne pousse jamais les boutons hors de l'écran.
   ------------------------------------------------------------------------------------------ */
.cnx-pied {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    padding: 10px 14px;
    border-top: 1px solid var(--et-hairline);
    background: var(--et-surface-2);
}

.cnx-pied-note {
    flex: 1 1 200px;
    min-width: 0;
    font-size: 12px;
    line-height: 1.45;
    color: var(--et-muted);
}

/* L'engagement est TOUJOURS le dernier enfant : posé à droite quelle que soit la note. */
.cnx-pied > .mx-btn-cta { margin-left: auto; }

/* L'atelier apporte sa propre carte ; l'étape qui l'accueille ne referme donc pas son corps
   avant le pied. Le corps garde sa marge basse pour ne pas coller le pied aux données. */
.cnx-etape-lecture > .mx-carte-corps { padding-bottom: 4px; }

/* ------------------------------------------------------------------------------------------
   LES COMPTEURS D'UN RÉSULTAT (.cnx-cpt) — un chiffre, son unité, et rien d'autre.

   ILS SE LISENT ENSEMBLE, JAMAIS SEULS. « 3 images » sur deux mille articles ne veut rien
   dire tant qu'on ignore combien étaient déjà pourvus et combien n'en ont pas chez Odoo ;
   « 501 créés » ne veut rien dire sans le nombre d'erreurs à côté. C'est pourquoi ils sont
   une RANGÉE et non des paragraphes : on ne peut pas en montrer un sans les autres.

   La couleur ne dit rien que le libellé ne dise déjà — elle appuie, elle n'informe pas.
   ------------------------------------------------------------------------------------------ */
.cnx-compteurs {
    display: flex;
    flex-wrap: wrap;
    gap: 0;
    border: 1px solid var(--et-hairline);
}

.cnx-cpt {
    flex: 1 1 120px;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 9px 12px;
    border-right: 1px solid var(--et-hairline);
}
.cnx-cpt:last-child { border-right: 0; }

/* LE CHIFFRE EST EN CHASSE FIXE, comme la valeur d'une vignette EasyCompta
   (easycompta-vignette.css) : c'est l'idiome de la maison pour un nombre qu'on lit en
   colonne, et il aligne les unités d'un compteur à l'autre. 20 px et non 19 : l'échelle
   de la charte ne porte plus de 19 depuis la révision du 2026-09-02 (19 → 20). */
.cnx-cpt-n {
    font-family: var(--et-font-mono);
    font-size: 20px;
    font-weight: 600;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
    color: var(--et-ink);
}

.cnx-cpt-l { font-size: 12px; line-height: 1.3; color: var(--et-muted); }

/* ------------------------------------------------------------------------------------------
   LES DEUX COMPTEURS QUI PORTENT UN ÉTAT — et pourquoi ils le portent en DEUX endroits.

   Ces deux compteurs se tenaient côte à côte en écrivant leur état de DEUX FAÇONS :
   `--et-danger-ink` sur celui en échec, `--et-ok` brut sur celui en succès. Deux voisins,
   deux rangs. C'est cette asymétrie qu'on retire — non l'usage de `--et-ok`, qui est un
   jeton distinct des trois couleurs d'état et vit encore en `color:` dans dix autres
   feuilles ; le trancher relève de la charte, pas de cet écran.

   La forme retenue est celle que la charte décrit pour un état : la couleur est une
   MARQUE, et l'encre posée à côté prend le rang `-ink`.

   La marque est donc une BARRE (3 px, la couleur d'état, qui passe le seuil graphique de
   3:1 : succès 3,30 et danger 4,83 sur blanc), et l'encre du chiffre est le rang `-ink`
   (succès 5,87 et danger au-delà — AA franchi pour un nombre de 20 px).

   SEULS ces deux-là portent une barre. Les compteurs neutres n'en ont pas, et c'est le
   sujet : dans une rangée de quatre, l'œil doit aller aux deux qui décident. Le retrait
   gauche compense l'épaisseur de la barre (3 + 9 = 12 px) pour que les chiffres restent
   alignés d'une colonne à l'autre.
   ------------------------------------------------------------------------------------------ */
.cnx-cpt-ok,
.cnx-cpt-ko { border-left: 3px solid; padding-left: 9px; }

.cnx-cpt-ok { border-left-color: var(--et-succes); }
.cnx-cpt-ko { border-left-color: var(--et-danger); }

.cnx-cpt-ok .cnx-cpt-n { color: var(--et-succes-ink); }
.cnx-cpt-ko .cnx-cpt-n { color: var(--et-danger-ink); }

/* Sous 640 px, deux compteurs par ligne : quatre colonnes de 19 px de chiffre sur un
   téléphone donnent quatre colonnes illisibles. Géométrie seule. */
@media (max-width: 640px) {
    .cnx-cpt { flex: 1 1 45%; border-bottom: 1px solid var(--et-hairline); }
}

/* Sous 720 px, la note de tête passe à la ligne : collée au titre sur une largeur de
   téléphone, elle le tronquait. Géométrie seule, aucune couleur. */
@media (max-width: 720px) {
    .cnx-etapes > .mx-carte > .mx-carte-tete { flex-wrap: wrap; }
    .cnx-tete-note { margin-left: 0; width: 100%; text-align: left; }
}

/* ===========================================================================
   LE RAIL DE FILTRES DU RAPPORT — trois entrées de lecture sur les mêmes lignes.

   POURQUOI UN RAIL ET NON DES ONGLETS
     Les onglets tenaient trois rangs. Le rail en tient trois FAMILLES — rang,
     statut, cause —, et la troisième est une liste ouverte : autant d'entrées
     que le lot porte de problèmes distincts. En onglets, elle aurait débordé
     sur la deuxième cause.

     C'est aussi la grammaire de la liste des documents de vente (.dev-filtre) :
     un opérateur qui a filtré une liste de pièces sait déjà lire celle-ci. Les
     classes, elles, ne sont PAS partagées — .dev-* appartient à la feuille de
     l'écran de vente, et deux familles homonymes dans deux feuilles fusionnent
     en silence (docs/conventions-nommage.md).

   AUCUNE COULEUR D'ÉTAT EN « color: ». Le rang se dit par une PASTILLE — une
   marque, ce que la charte autorise —, et l'ambre y passe par
   --et-avertissement-mark, un ambre pur ne tenant pas le seuil de 3:1.
   =========================================================================== */
.cnx-rapport { display: flex; align-items: flex-start; gap: 14px; margin-top: 12px; }
.cnx-rapport-corps { flex: 1 1 0; min-width: 0; }

.cnx-tri-rail {
    flex: 0 0 232px; width: 232px;
    border: 1px solid var(--et-hairline); background: var(--et-surface);
    padding: 10px 0 8px;
}

.cnx-tri-tete, .cnx-tri-groupe {
    font-family: var(--et-font-mono); font-size: 12px; font-weight: 600;
    text-transform: uppercase; letter-spacing: .12em; color: var(--et-muted);
    padding: 0 12px 6px;
}
.cnx-tri-groupe { margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--et-rang); }

.cnx-facette {
    display: flex; align-items: center; gap: 8px; width: 100%;
    padding: 6px 12px; border: 0; background: transparent;
    font-family: inherit; font-size: 13px; color: var(--et-ink);
    text-align: left; cursor: pointer;
}
.cnx-facette:hover { background: var(--et-rang); }

/* Le filet INTÉRIEUR à gauche marque la facette retenue sans décaler son texte
   d'un pixel par rapport aux autres — une bordure le ferait. */
.cnx-facette.est-active {
    background: var(--et-tint); font-weight: 600;
    box-shadow: inset 3px 0 0 0 var(--et-form-blue);
}

.cnx-facette-txt {
    flex: 1 1 auto; min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cnx-facette-n {
    font-family: var(--et-font-mono); font-size: 12px; font-variant-numeric: tabular-nums;
    color: var(--et-muted);
}
.cnx-facette.est-active .cnx-facette-n { color: var(--et-ink); }

/* Une cause est une PHRASE, pas une étiquette : deux lignes au plus, et le
   titre complet reste au survol. Tronquée sur une seule ligne, « dépôt « … »
   inconnu » et « dépôt « … » interdit » se ressemblaient trop. */
.cnx-facette.est-cause .cnx-facette-txt {
    white-space: normal; overflow: hidden; text-overflow: clip;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    line-height: 1.3;
}

/* LE DÉFAUT D'ABORD, LES MODIFICATEURS ENSUITE — à spécificité égale c'est le
   dernier qui gagne, et la règle nue écrite en bas repeindrait les trois autres
   en vert sans qu'aucun outil ne le signale. */
.cnx-facette-puce {
    flex: 0 0 auto; width: 8px; height: 8px; border-radius: 50%;
    background: var(--et-succes);
}
.cnx-facette-puce.est-erreur { background: var(--et-danger); }
.cnx-facette-puce.est-avertissement { background: var(--et-avertissement-mark); }
.cnx-facette-puce.est-ignore { background: var(--et-inerte); }

.cnx-tri-note { padding: 4px 12px 0; font-size: 12px; color: var(--et-inerte); }

.cnx-tri-barre { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.cnx-tri-titre { font-size: 13px; font-weight: 600; color: var(--et-ink); }
.cnx-tri-gestes { margin-left: auto; display: flex; gap: 6px; }
.cnx-tri-aide { margin-top: 6px; }

/* Sous 1024 px, le rail passe AU-DESSUS de la table plutôt que de lui voler
   232 px de largeur : la table du rapport porte quatre colonnes dont un message,
   qui est la plus longue. Géométrie seule. */
@media (max-width: 1024px) {
    .cnx-rapport { flex-direction: column; }
    .cnx-tri-rail { flex: 1 1 auto; width: 100%; }
    .cnx-tri-gestes { margin-left: 0; width: 100%; }
    .cnx-tri-gestes .mx-btn { flex: 1 1 0; justify-content: center; }
}

/* ══════════════════════════════════════════════════════════════════════════════
   LA LIGNE SOURCE, SOUS SON VERDICT (.cnx-src-*)

   « Tiers inconnu » appelle immédiatement une seconde question : inconnu SOUS
   QUEL CODE ? La réponse était dans le fichier envoyé, à un numéro de ligne
   qu'il fallait aller compter dans un tableur. Elle est ici.

   Un dépli et non une colonne de plus : les lots portent de dix à trente
   colonnes, et les montrer toutes en permanence enterrerait le message, qui
   est ce qu'on vient lire. Le chevron n'apparaît que sur les rapports qui
   portent leur source — voir RapportRepriseTri.AttacherSource.
   ══════════════════════════════════════════════════════════════════════════════ */

.cnx-src-bt {
    display: inline-flex; align-items: center; justify-content: center;
    width: 26px; height: 26px; padding: 0;
    border: 1px solid var(--et-hairline); background: var(--et-surface);
    color: var(--et-muted); font-size: 12px; cursor: pointer;
}
.cnx-src-bt:hover { background: var(--et-rang); color: var(--et-ink); }
.cnx-src-bt.est-ouverte {
    background: var(--et-tint); border-color: var(--et-form-blue); color: var(--et-form-blue);
}

/* Le rang du dépli se distingue de la ligne au-dessus par un aplat et non par
   un filet : deux filets consécutifs se lisent comme deux lignes de tableau
   séparées, alors que celle-ci APPARTIENT à la précédente. */
.cnx-src-rang > td { background: var(--et-surface-2); padding: 8px 10px; }

.cnx-src {
    display: grid; gap: 4px 18px;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
}

/* Étiquette au-dessus de la valeur et non à sa gauche : les noms de colonnes
   d'un export Odoo vont de « id » à « Lignes de commande/Description », et une
   colonne d'étiquettes assez large pour la seconde rendrait la première
   illisible de loin. */
.cnx-src-champ { display: flex; flex-direction: column; min-width: 0; }

.cnx-src-lbl {
    font-size: 12px; color: var(--et-muted);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cnx-src-val {
    font-family: var(--et-font-mono); font-size: 12px; color: var(--et-ink);
    overflow-wrap: anywhere;
}

/* UNE COLONNE VIDE SE MONTRE — c'est souvent la cause elle-même. En encre
   inerte, pour qu'elle ne se confonde pas avec une valeur. */
.cnx-src-val.est-vide { font-style: italic; color: var(--et-inerte); }

/* Sous 640 px la grille retombe sur une colonne : à deux colonnes, une valeur
   longue coupée en trois lignes désaligne tout ce qui suit. */
@media (max-width: 640px) {
    .cnx-src { grid-template-columns: 1fr; }
}
